From 70ae25fc7b7617b5ef176a3a9420857973095706 Mon Sep 17 00:00:00 2001 From: balibabu Date: Thu, 11 Jun 2026 16:36:05 +0800 Subject: [PATCH] Fix: Remove the pagination from the search and retrieval pages. (#15942) ### What problem does this PR solve? Fix: Remove the pagination from the search and retrieval pages. ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue) --- api/apps/services/dataset_api_service.py | 1 + web/src/components/top-select.tsx | 38 ++++++++++++++++++ web/src/hooks/use-knowledge-request.ts | 26 +------------ web/src/locales/en.ts | 2 + web/src/locales/zh.ts | 2 + web/src/pages/dataset/testing/index.tsx | 22 +---------- .../pages/dataset/testing/testing-form.tsx | 5 ++- .../pages/dataset/testing/testing-result.tsx | 25 +++--------- web/src/pages/next-search/hooks.ts | 39 ++++++++++--------- web/src/pages/next-search/search-view.tsx | 33 +++++++--------- 10 files changed, 91 insertions(+), 102 deletions(-) create mode 100644 web/src/components/top-select.tsx diff --git a/api/apps/services/dataset_api_service.py b/api/apps/services/dataset_api_service.py index dd1309db21..41dc55e2fc 100644 --- a/api/apps/services/dataset_api_service.py +++ b/api/apps/services/dataset_api_service.py @@ -1440,6 +1440,7 @@ async def search_datasets(tenant_id: str, req: dict): except Exception: logging.warning("search_datasets KG retrieval failed: datasets=%s tenant=%s", kb_ids, tenant_id, exc_info=True) ranks["chunks"] = settings.retriever.retrieval_by_children(ranks["chunks"], tenant_ids) + ranks["total"] = len(ranks["chunks"]) for c in ranks["chunks"]: c.pop("vector", None) diff --git a/web/src/components/top-select.tsx b/web/src/components/top-select.tsx new file mode 100644 index 0000000000..e969f703ce --- /dev/null +++ b/web/src/components/top-select.tsx @@ -0,0 +1,38 @@ +import { useMemo } from 'react'; +import { useTranslation } from 'react-i18next'; +import { SelectWithSearch } from './originui/select-with-search'; +import { RAGFlowFormItem } from './ragflow-form'; + +type TopSelectProps = { + value?: number; + onChange?(value: number): void; +}; + +export function TopSelect({ value = 10, onChange }: TopSelectProps) { + const { t } = useTranslation(); + + const sizeChangerOptions = useMemo(() => { + return [10, 20, 50, 100].map((x) => ({ + label: {t('common.top', { top: x })}, + value: x.toString(), + })); + }, [t]); + + return ( + onChange?.(Number(val))} + > + ); +} + +export function TopSelectFormItem() { + const { t } = useTranslation(); + + return ( + + + + ); +} diff --git a/web/src/hooks/use-knowledge-request.ts b/web/src/hooks/use-knowledge-request.ts index d894771ade..c218d391d0 100644 --- a/web/src/hooks/use-knowledge-request.ts +++ b/web/src/hooks/use-knowledge-request.ts @@ -64,19 +64,15 @@ export const useTestRetrieval = () => { const [values, setValues] = useState(); const { filterValue, setFilterValue } = useHandleFilterSubmit(); - const [page, setPage] = useState(1); - const [pageSize, setPageSize] = useState(10); - const queryParams = useMemo(() => { return { ...values, kb_id: values?.kb_id || knowledgeBaseId, - page, - size: pageSize, + page: 1, doc_ids: filterValue.doc_ids, highlight: true, }; - }, [filterValue, knowledgeBaseId, page, pageSize, values]); + }, [filterValue, knowledgeBaseId, values]); const mutation = useMutation({ mutationFn: async (params) => { @@ -87,30 +83,15 @@ export const useTestRetrieval = () => { }); const refetch = useCallback(() => { - setPage(1); if (queryParams.question) { const newParams = { ...queryParams, page: 1 }; mutation.mutate(newParams); } }, [mutation, queryParams]); - const onPaginationChange = useCallback( - (newPage: number, newPageSize: number) => { - const nextPage = newPageSize !== pageSize ? 1 : newPage; - setPage(nextPage); - setPageSize(newPageSize); - if (mutation.data && queryParams.question) { - const newParams = { ...queryParams, page: nextPage, size: newPageSize }; - mutation.mutate(newParams); - } - }, - [mutation, queryParams, pageSize], - ); - const handleFilterSubmit = useCallback( (value: { doc_ids?: string[] }) => { setFilterValue(value); - setPage(1); if (mutation.data && queryParams.question) { const newParams = { ...queryParams, @@ -139,9 +120,6 @@ export const useTestRetrieval = () => { loading: mutation.isPending, setValues, refetch, - onPaginationChange, - page, - pageSize, handleFilterSubmit, filterValue, }; diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts index 79c4a297df..9d087d0749 100644 --- a/web/src/locales/en.ts +++ b/web/src/locales/en.ts @@ -14,6 +14,7 @@ export default { yes: 'Yes', no: 'No', total: 'Total', + top: 'Top {{top}}', rename: 'Rename', name: 'Name', save: 'Save', @@ -914,6 +915,7 @@ This auto-tagging feature enhances retrieval by adding another layer of domain-s theDocumentBeingParsedCannotBeDeleted: 'The document being parsed cannot be deleted', lastWeek: 'from last week', + top: 'Top', }, chunk: { type: 'Type', diff --git a/web/src/locales/zh.ts b/web/src/locales/zh.ts index 372c44f7f9..312ccf95dd 100644 --- a/web/src/locales/zh.ts +++ b/web/src/locales/zh.ts @@ -14,6 +14,7 @@ export default { yes: '是', no: '否', total: '总共', + top: '前 {{top}} 条', rename: '重命名', name: '名称', save: '保存', @@ -826,6 +827,7 @@ NER:使用 spaCy NER 和基于规则的关键词提取来抽取实体和关系 community: '社区报告生成', communityTip: '区块被聚集成层次化的社区,实体和关系通过更高抽象层次将每个部分连接起来。然后,我们使用 LLM 生成每个社区的摘要,称为社区报告。更多信息:https://www.microsoft.com/en-us/research/blog/graphrag-improving-global-search-via-dynamic-community-selection/', + top: '前n条', }, chunk: { chunk: '解析块', diff --git a/web/src/pages/dataset/testing/index.tsx b/web/src/pages/dataset/testing/index.tsx index effb13a00d..743cb1fbd1 100644 --- a/web/src/pages/dataset/testing/index.tsx +++ b/web/src/pages/dataset/testing/index.tsx @@ -12,17 +12,8 @@ import TestingForm from './testing-form'; import { TestingResult } from './testing-result'; export default function RetrievalTesting() { - const { - loading, - setValues, - refetch, - data, - onPaginationChange, - page, - pageSize, - handleFilterSubmit, - filterValue, - } = useTestRetrieval(); + const { loading, setValues, refetch, data, handleFilterSubmit, filterValue } = + useTestRetrieval(); const [count] = useState(1); // TODO: Different layouts are needed; if they are no longer required, consider deleting them. @@ -62,12 +53,9 @@ export default function RetrievalTesting() {
@@ -81,12 +69,9 @@ export default function RetrievalTesting() { >
@@ -97,12 +82,9 @@ export default function RetrievalTesting() { >
diff --git a/web/src/pages/dataset/testing/testing-form.tsx b/web/src/pages/dataset/testing/testing-form.tsx index 57890a1d2c..7437500b20 100644 --- a/web/src/pages/dataset/testing/testing-form.tsx +++ b/web/src/pages/dataset/testing/testing-form.tsx @@ -22,6 +22,7 @@ import { similarityThresholdSchema, vectorSimilarityWeightSchema, } from '@/components/similarity-slider'; +import { TopSelectFormItem } from '@/components/top-select'; import { ButtonLoading } from '@/components/ui/button'; import { Form, @@ -64,6 +65,7 @@ export default function TestingForm({ use_kg: z.boolean().optional(), dataset_ids: z.array(z.string()).optional(), ...MetadataFilterSchema, + size: z.number().optional(), }); const form = useForm>({ @@ -74,6 +76,7 @@ export default function TestingForm({ ...initialTopKValue, use_kg: false, dataset_ids: [knowledgeBaseId], + size: 10, }, }); @@ -106,6 +109,7 @@ export default function TestingForm({ name={'cross_languages'} > + @@ -115,7 +119,6 @@ export default function TestingForm({ name="question" render={({ field }) => ( - {/* {t('knowledgeDetails.testText')} */} diff --git a/web/src/pages/dataset/testing/testing-result.tsx b/web/src/pages/dataset/testing/testing-result.tsx index 5534831c32..05b7e679b6 100644 --- a/web/src/pages/dataset/testing/testing-result.tsx +++ b/web/src/pages/dataset/testing/testing-result.tsx @@ -4,7 +4,6 @@ import { FilterButton } from '@/components/list-filter-bar'; import { FilterPopover } from '@/components/list-filter-bar/filter-popover'; import { FilterCollection } from '@/components/list-filter-bar/interface'; import { Card } from '@/components/ui/card'; -import { RAGFlowPagination } from '@/components/ui/ragflow-pagination'; import { useTranslate } from '@/hooks/common-hooks'; import { useTestRetrieval } from '@/hooks/use-knowledge-request'; import { ITestingChunk } from '@/interfaces/database/dataset'; @@ -34,22 +33,13 @@ const ChunkTitle = ({ item }: { item: ITestingChunk }) => { type TestingResultProps = Pick< ReturnType, - | 'data' - | 'filterValue' - | 'handleFilterSubmit' - | 'page' - | 'pageSize' - | 'onPaginationChange' - | 'loading' + 'data' | 'filterValue' | 'handleFilterSubmit' | 'loading' >; export function TestingResult({ filterValue, handleFilterSubmit, - page, - pageSize, loading, - onPaginationChange, data, }: TestingResultProps) { const filters: FilterCollection[] = useMemo(() => { @@ -69,10 +59,13 @@ export function TestingResult({ return (
-
+

{t('knowledgeDetails.testResults')}

+ + {t('common.total')}: {data.total} + ))} -
- -
)} {!data.chunks?.length && !loading && ( diff --git a/web/src/pages/next-search/hooks.ts b/web/src/pages/next-search/hooks.ts index a165ed24ba..b3e1e69f27 100644 --- a/web/src/pages/next-search/hooks.ts +++ b/web/src/pages/next-search/hooks.ts @@ -148,10 +148,10 @@ export const useTestChunkRetrieval = ( gcTime: 0, mutationFn: async (values: any) => { const { data } = await retrievalTestFunc({ - ...values, - kb_id: values.kb_id ?? knowledgeBaseId, page, size: pageSize, + ...values, + kb_id: values.kb_id ?? knowledgeBaseId, tenant_id: tenantId, }); if (data.code === 0) { @@ -199,11 +199,10 @@ export const useTestChunkAllRetrieval = ( gcTime: 0, mutationFn: async (values: any) => { const { data } = await retrievalTestFunc({ - ...values, - kb_id: values.kb_id ?? knowledgeBaseId, - doc_ids: [], page, size: pageSize, + ...values, + kb_id: values.kb_id ?? knowledgeBaseId, tenant_id: tenantId, }); if (data.code === 0) { @@ -324,14 +323,12 @@ export const useSendQuestion = ( const [searchStr, setSearchStr] = useState(''); const [isFirstRender, setIsFirstRender] = useState(true); const [selectedDocumentIds, setSelectedDocumentIds] = useState([]); - - const { pagination, setPagination } = useGetPaginationWithRouter(); + const [pageSize, setPageSize] = useState(10); const sendQuestion = useCallback( (question: string, enableAI: boolean = true) => { const q = trim(question); if (isEmpty(q)) return; - setPagination({ page: 1 }); setIsFirstRender(false); setCurrentAnswer({} as IAnswer); if (enableAI) { @@ -352,7 +349,7 @@ export const useSendQuestion = ( highlight: true, question: q, page: 1, - size: pagination.pageSize, + size: pageSize, search_id: searchId, }); @@ -366,8 +363,7 @@ export const useSendQuestion = ( askUrl, kbIds, fetchRelatedQuestions, - setPagination, - pagination.pageSize, + pageSize, tenantId, searchId, sharedId, @@ -455,6 +451,8 @@ export const useSendQuestion = ( selectedDocumentIds, isSearchStrEmpty: isEmpty(trim(searchStr)), stopOutputMessage, + pageSize, + setPageSize, }; }; @@ -479,6 +477,8 @@ export const useSearching = ({ isSearchStrEmpty, setSearchStr, stopOutputMessage, + pageSize, + setPageSize, } = useSendQuestion( searchData.search_config.kb_ids, tenantId as string, @@ -537,14 +537,15 @@ export const useSearching = ({ ], ); - const { pagination, setPagination } = useGetPaginationWithRouter(); - const onChange = (pageNumber: number, pageSize: number) => { - setPagination({ page: pageNumber, pageSize }); - handleTestChunk(selectedDocumentIds, pageNumber, pageSize); - }; + const handleTopChange = useCallback( + (size: number) => { + setPageSize(size); + handleTestChunk(selectedDocumentIds, 1, size); + }, + [handleTestChunk, selectedDocumentIds, setPageSize], + ); return { - sendQuestion, handleClickRelatedQuestion, handleSearchStrChange, handleTestChunk, @@ -573,8 +574,8 @@ export const useSearching = ({ chunks, total, handleSearch, - pagination, - onChange, + pageSize, + handleTopChange, }; }; diff --git a/web/src/pages/next-search/search-view.tsx b/web/src/pages/next-search/search-view.tsx index 9b89cbf73b..3325fadaaa 100644 --- a/web/src/pages/next-search/search-view.tsx +++ b/web/src/pages/next-search/search-view.tsx @@ -5,13 +5,13 @@ import { FileIcon } from '@/components/icon-font'; import { ImageWithPopover } from '@/components/image'; import { Input } from '@/components/originui/input'; import { SkeletonCard } from '@/components/skeleton-card'; +import { TopSelect } from '@/components/top-select'; import { Button } from '@/components/ui/button'; import { Popover, PopoverContent, PopoverTrigger, } from '@/components/ui/popover'; -import { RAGFlowPagination } from '@/components/ui/ragflow-pagination'; import { IReference } from '@/interfaces/database/chat'; import { cn } from '@/lib/utils'; import { isEmpty } from 'lodash'; @@ -61,8 +61,8 @@ export default function SearchingView({ chunks, total, handleSearch, - pagination, - onChange, + pageSize, + handleTopChange, showEmbedLogo, }: ISearchReturnProps & { setIsSearching?: Dispatch>; @@ -183,8 +183,8 @@ export default function SearchingView({ )} {/* retrieval documents */} {!isSearchStrEmpty && !sendingLoading && ( - <> -
+
+
- {/*
*/} - +
+ +
+ + {t('common.total')}: {total} + +
)}
{chunks?.length > 0 && ( @@ -293,17 +301,6 @@ export default function SearchingView({ )}
- {total > 0 && ( -
- -
- )} - {!mindMapVisible && !isFirstRender && !isSearchStrEmpty &&