From 912a72874eb5f9b805af6802d3f37c727347ecf5 Mon Sep 17 00:00:00 2001 From: chanx <1243304602@qq.com> Date: Tue, 4 Aug 2026 15:16:16 +0800 Subject: [PATCH] fix(file-manager): resolve knowledge base names in link-to-dataset dialog for correct optimistic update (#17781) --- web/src/pages/files/hooks.ts | 28 ++----------- .../pages/files/link-to-dataset-dialog.tsx | 42 +++++++++++++++++-- 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/web/src/pages/files/hooks.ts b/web/src/pages/files/hooks.ts index b74fa97f36..eb8e321196 100644 --- a/web/src/pages/files/hooks.ts +++ b/web/src/pages/files/hooks.ts @@ -1,6 +1,5 @@ import { useSetModalState } from '@/hooks/common-hooks'; import { useConnectToKnowledge, useRenameFile } from '@/hooks/use-file-request'; -import { useSelectKnowledgeOptions } from '@/hooks/use-knowledge-request'; import { TableRowSelection } from '@/interfaces/antd-compat'; import { IFile } from '@/interfaces/database/file-manager'; import { ConnectFileToKnowledgeMode } from '@/interfaces/request/file-manager'; @@ -86,7 +85,6 @@ export const useHandleConnectToKnowledge = () => { const [record, setRecord] = useState({} as IFile); const [documentIds, setDocumentIds] = useState([]); const [mode, setMode] = useState('replace'); - const { options: knowledgeOptions } = useSelectKnowledgeOptions(); const initialValue = useMemo(() => { return Array.isArray(record?.kbs_info) @@ -94,25 +92,13 @@ export const useHandleConnectToKnowledge = () => { : []; }, [record?.kbs_info]); - const knowledgeNameMap = useMemo(() => { - return new Map( - knowledgeOptions?.map((option) => [ - option.value, - typeof option.label === 'string' ? option.label : String(option.label), - ]) ?? [], - ); - }, [knowledgeOptions]); - const onConnectToKnowledgeOk = useCallback( - async (knowledgeIds: string[]) => { + async (kbsInfo: { kb_id: string; kb_name: string }[]) => { const ret = await connectToKnowledge({ fileIds: documentIds, - kbIds: knowledgeIds, + kbIds: kbsInfo.map((kb) => kb.kb_id), mode, - kbsInfo: knowledgeIds.map((id) => ({ - kb_id: id, - kb_name: knowledgeNameMap.get(id) ?? id, - })), + kbsInfo, }); if (ret === 0) { @@ -120,13 +106,7 @@ export const useHandleConnectToKnowledge = () => { } return ret; }, - [ - connectToKnowledge, - hideConnectToKnowledgeModal, - documentIds, - mode, - knowledgeNameMap, - ], + [connectToKnowledge, hideConnectToKnowledgeModal, documentIds, mode], ); const handleShowConnectToKnowledgeModal = useCallback( diff --git a/web/src/pages/files/link-to-dataset-dialog.tsx b/web/src/pages/files/link-to-dataset-dialog.tsx index 42ac659c22..e85cb26945 100644 --- a/web/src/pages/files/link-to-dataset-dialog.tsx +++ b/web/src/pages/files/link-to-dataset-dialog.tsx @@ -15,12 +15,16 @@ import { FormMessage, } from '@/components/ui/form'; import { MultiSelect } from '@/components/ui/multi-select'; -import { useFetchKnowledgeList } from '@/hooks/use-knowledge-request'; +import { + useFetchDatasetsByIds, + useFetchKnowledgeList, +} from '@/hooks/use-knowledge-request'; import { IModalProps } from '@/interfaces/common'; +import { IDataset } from '@/interfaces/database/dataset'; import { useDebounce } from 'ahooks'; import { zodResolver } from '@hookform/resolvers/zod'; import { Link2 } from 'lucide-react'; -import { useMemo, useState } from 'react'; +import { useEffect, useMemo, useRef, useState } from 'react'; import { useForm } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { z } from 'zod'; @@ -56,6 +60,31 @@ function LinkToDatasetForm({ debouncedSearchString, ); + const selectedIds = form.watch('knowledgeIds'); + + // Cache all datasets the user has seen so names survive across searches + // and scroll. The paginated list may not contain every selected dataset + // (e.g. initially-connected ones), so resolve the rest by ID. + const datasetCacheRef = useRef(new Map()); + + const missingIds = useMemo(() => { + const loadedIds = new Set(list.map((d) => d.id)); + return selectedIds.filter( + (id) => !loadedIds.has(id) && !datasetCacheRef.current.has(id), + ); + }, [list, selectedIds]); + + const { data: missingDatasets } = useFetchDatasetsByIds(missingIds); + + useEffect(() => { + list.forEach((item) => { + datasetCacheRef.current.set(item.id, item); + }); + missingDatasets?.forEach((item) => { + datasetCacheRef.current.set(item.id, item); + }); + }, [list, missingDatasets]); + const options = useMemo( () => list.map((item) => ({ @@ -66,7 +95,14 @@ function LinkToDatasetForm({ ); function onSubmit(data: z.infer) { - onConnectToKnowledgeOk(data.knowledgeIds); + const kbsInfo = data.knowledgeIds.map((id) => { + const dataset = datasetCacheRef.current.get(id); + return { + kb_id: id, + kb_name: dataset?.name ?? id, + }; + }); + onConnectToKnowledgeOk(kbsInfo); } // useEffect(() => {