From a31ad7f96056efa9cd5d21c8955d061e50a208bc Mon Sep 17 00:00:00 2001 From: Stephen Hu Date: Fri, 30 May 2025 09:38:50 +0800 Subject: [PATCH] Fix: File selection in Retrieval testing causes other options to disappear (#7759) ### What problem does this PR solve? https://github.com/infiniflow/ragflow/issues/7753 The internal is due to when the selected row keys change will trigger a testing, but I do not know why. ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue) --- api/db/services/common_service.py | 2 +- .../components/retrieval-documents/index.tsx | 12 +++- .../retrieval-documents/select-files.tsx | 10 ++- web/src/hooks/knowledge-hooks.ts | 69 +++++++++++++++++++ .../components/knowledge-testing/index.tsx | 21 +++++- .../testing-control/index.tsx | 15 +++- .../testing-result/index.tsx | 18 +++-- .../testing-result/select-files.tsx | 6 +- web/src/pages/search/hooks.ts | 15 +++- 9 files changed, 150 insertions(+), 18 deletions(-) diff --git a/api/db/services/common_service.py b/api/db/services/common_service.py index 95f5d759f..7645b43d4 100644 --- a/api/db/services/common_service.py +++ b/api/db/services/common_service.py @@ -254,7 +254,7 @@ class CommonService: # Returns: # Number of records deleted return cls.model.delete().where(cls.model.id == pid).execute() - + @classmethod @DB.connection_context() def delete_by_ids(cls, pids): diff --git a/web/src/components/retrieval-documents/index.tsx b/web/src/components/retrieval-documents/index.tsx index f73f0f709..b41e9e020 100644 --- a/web/src/components/retrieval-documents/index.tsx +++ b/web/src/components/retrieval-documents/index.tsx @@ -2,7 +2,10 @@ import { ReactComponent as SelectedFilesCollapseIcon } from '@/assets/svg/select import { Collapse, Flex, Space } from 'antd'; import SelectFiles from './select-files'; -import { useSelectTestingResult } from '@/hooks/knowledge-hooks'; +import { + useAllTestingResult, + useSelectTestingResult, +} from '@/hooks/knowledge-hooks'; import { useTranslation } from 'react-i18next'; import styles from './index.less'; @@ -18,7 +21,12 @@ const RetrievalDocuments = ({ setSelectedDocumentIds, }: IProps) => { const { t } = useTranslation(); + const { documents: documentsAll } = useAllTestingResult(); const { documents } = useSelectTestingResult(); + const { documents: useDocuments } = { + documents: + documentsAll?.length > documents?.length ? documentsAll : documents, + }; return ( - {selectedDocumentIds?.length ?? 0}/{documents?.length ?? 0} + {selectedDocumentIds?.length ?? 0}/{useDocuments?.length ?? 0} {t('knowledgeDetails.filesSelected')} diff --git a/web/src/components/retrieval-documents/select-files.tsx b/web/src/components/retrieval-documents/select-files.tsx index 07647b501..68d9171d8 100644 --- a/web/src/components/retrieval-documents/select-files.tsx +++ b/web/src/components/retrieval-documents/select-files.tsx @@ -1,6 +1,9 @@ import NewDocumentLink from '@/components/new-document-link'; import { useTranslate } from '@/hooks/common-hooks'; -import { useSelectTestingResult } from '@/hooks/knowledge-hooks'; +import { + useAllTestingResult, + useSelectTestingResult, +} from '@/hooks/knowledge-hooks'; import { ITestingDocument } from '@/interfaces/database/knowledge'; import { EyeOutlined } from '@ant-design/icons'; import { Button, Table, TableProps, Tooltip } from 'antd'; @@ -12,6 +15,9 @@ interface IProps { const SelectFiles = ({ setSelectedDocumentIds, handleTesting }: IProps) => { const { documents } = useSelectTestingResult(); + const { documents: documentsAll } = useAllTestingResult(); + const useDocuments = + documentsAll?.length > documents?.length ? documentsAll : documents; const { t } = useTranslate('fileManager'); const columns: TableProps['columns'] = [ @@ -62,7 +68,7 @@ const SelectFiles = ({ setSelectedDocumentIds, handleTesting }: IProps) => { return ( & { }; }; +export const useTestChunkAllRetrieval = (): ResponsePostType & { + testChunkAll: (...params: any[]) => void; +} => { + const knowledgeBaseId = useKnowledgeBaseId(); + const { page, size: pageSize } = useSetPaginationParams(); + + const { + data, + isPending: loading, + mutateAsync, + } = useMutation({ + mutationKey: ['testChunkAll'], // This method is invalid + gcTime: 0, + mutationFn: async (values: any) => { + const { data } = await kbService.retrieval_test({ + ...values, + kb_id: values.kb_id ?? knowledgeBaseId, + doc_ids: [], + page, + size: pageSize, + }); + if (data.code === 0) { + const res = data.data; + return { + ...res, + documents: res.doc_aggs, + }; + } + return ( + data?.data ?? { + chunks: [], + documents: [], + total: 0, + } + ); + }, + }); + + return { + data: data ?? { chunks: [], documents: [], total: 0 }, + loading, + testChunkAll: mutateAsync, + }; +}; + export const useChunkIsTesting = () => { return useIsMutating({ mutationKey: ['testChunk'] }) > 0; }; @@ -288,6 +333,30 @@ export const useSelectIsTestingSuccess = () => { }); return status.at(-1) === 'success'; }; + +export const useAllTestingSuccess = () => { + const status = useMutationState({ + filters: { mutationKey: ['testChunkAll'] }, + select: (mutation) => { + return mutation.state.status; + }, + }); + return status.at(-1) === 'success'; +}; + +export const useAllTestingResult = (): ITestingResult => { + const data = useMutationState({ + filters: { mutationKey: ['testChunkAll'] }, + select: (mutation) => { + return mutation.state.data; + }, + }); + return (data.at(-1) ?? { + chunks: [], + documents: [], + total: 0, + }) as ITestingResult; +}; //#endregion //#region tags diff --git a/web/src/pages/add-knowledge/components/knowledge-testing/index.tsx b/web/src/pages/add-knowledge/components/knowledge-testing/index.tsx index e5a22f135..d7140c926 100644 --- a/web/src/pages/add-knowledge/components/knowledge-testing/index.tsx +++ b/web/src/pages/add-knowledge/components/knowledge-testing/index.tsx @@ -1,13 +1,19 @@ -import { useTestChunkRetrieval } from '@/hooks/knowledge-hooks'; +import { + useTestChunkAllRetrieval, + useTestChunkRetrieval, +} from '@/hooks/knowledge-hooks'; import { Flex, Form } from 'antd'; import TestingControl from './testing-control'; import TestingResult from './testing-result'; +import { useState } from 'react'; import styles from './index.less'; const KnowledgeTesting = () => { const [form] = Form.useForm(); const { testChunk } = useTestChunkRetrieval(); + const { testChunkAll } = useTestChunkAllRetrieval(); + const [selectedDocumentIds, setSelectedDocumentIds] = useState([]); const handleTesting = async (documentIds: string[] = []) => { const values = await form.validateFields(); @@ -16,6 +22,12 @@ const KnowledgeTesting = () => { doc_ids: Array.isArray(documentIds) ? documentIds : [], vector_similarity_weight: 1 - values.vector_similarity_weight, }); + + testChunkAll({ + ...values, + doc_ids: [], + vector_similarity_weight: 1 - values.vector_similarity_weight, + }); }; return ( @@ -23,8 +35,13 @@ const KnowledgeTesting = () => { - + ); }; diff --git a/web/src/pages/add-knowledge/components/knowledge-testing/testing-control/index.tsx b/web/src/pages/add-knowledge/components/knowledge-testing/testing-control/index.tsx index 18f347051..8efb4c195 100644 --- a/web/src/pages/add-knowledge/components/knowledge-testing/testing-control/index.tsx +++ b/web/src/pages/add-knowledge/components/knowledge-testing/testing-control/index.tsx @@ -18,10 +18,15 @@ type FieldType = { interface IProps { form: FormInstance; - handleTesting: () => Promise; + handleTesting: (documentIds?: string[]) => Promise; + selectedDocumentIds: string[]; } -const TestingControl = ({ form, handleTesting }: IProps) => { +const TestingControl = ({ + form, + handleTesting, + selectedDocumentIds, +}: IProps) => { const question = Form.useWatch('question', { form, preserve: true }); const loading = useChunkIsTesting(); const { t } = useTranslate('knowledgeDetails'); @@ -29,6 +34,10 @@ const TestingControl = ({ form, handleTesting }: IProps) => { const buttonDisabled = !question || (typeof question === 'string' && question.trim() === ''); + const onClick = () => { + handleTesting(selectedDocumentIds); + }; + return (
@@ -53,7 +62,7 @@ const TestingControl = ({ form, handleTesting }: IProps) => {