From 93b1c61f5ed4644bf5318f380bf0fa6c139e84f8 Mon Sep 17 00:00:00 2001 From: twwu Date: Mon, 15 Sep 2025 11:41:39 +0800 Subject: [PATCH 1/8] refactor: Update knowledge pipeline terminology and permissions in the RAG pipeline header --- .../rag-pipeline-header/publisher/popup.tsx | 12 ++++++------ web/context/provider-context.tsx | 10 +++++----- web/i18n/en-US/pipeline.ts | 2 +- web/i18n/zh-Hans/pipeline.ts | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/web/app/components/rag-pipeline/components/rag-pipeline-header/publisher/popup.tsx b/web/app/components/rag-pipeline/components/rag-pipeline-header/publisher/popup.tsx index 66109a26ce..f246d5e849 100644 --- a/web/app/components/rag-pipeline/components/rag-pipeline-header/publisher/popup.tsx +++ b/web/app/components/rag-pipeline/components/rag-pipeline-header/publisher/popup.tsx @@ -62,7 +62,7 @@ const Popup = () => { const { mutateAsync: publishWorkflow } = usePublishWorkflow() const { notify } = useToastContext() const workflowStore = useWorkflowStore() - const { isAllowPublishAsKnowledgePipeline } = useProviderContext() + const { isAllowPublishAsCustomKnowledgePipelineTemplate } = useProviderContext() const setShowPricingModal = useModalContextSelector(s => s.setShowPricingModal) const [confirmVisible, { @@ -206,16 +206,16 @@ const Popup = () => { ]) const handleClickPublishAsKnowledgePipeline = useCallback(() => { - if (!isAllowPublishAsKnowledgePipeline) + if (!isAllowPublishAsCustomKnowledgePipelineTemplate) setShowPricingModal() else setShowPublishAsKnowledgePipelineModal() - }, [isAllowPublishAsKnowledgePipeline, setShowPublishAsKnowledgePipelineModal, setShowPricingModal]) + }, [isAllowPublishAsCustomKnowledgePipelineTemplate, setShowPublishAsKnowledgePipelineModal, setShowPricingModal]) return (
@@ -293,12 +293,12 @@ const Popup = () => { onClick={handleClickPublishAsKnowledgePipeline} disabled={!publishedAt || isPublishingAsCustomizedPipeline} > -
+
{t('pipeline.common.publishAs')} - {!isAllowPublishAsKnowledgePipeline && ( + {!isAllowPublishAsCustomKnowledgePipelineTemplate && ( diff --git a/web/context/provider-context.tsx b/web/context/provider-context.tsx index 902e5baf99..09019d3024 100644 --- a/web/context/provider-context.tsx +++ b/web/context/provider-context.tsx @@ -61,7 +61,7 @@ type ProviderContextState = { }, refreshLicenseLimit: () => void isAllowTransferWorkspace: boolean - isAllowPublishAsKnowledgePipeline: boolean + isAllowPublishAsCustomKnowledgePipelineTemplate: boolean } const ProviderContext = createContext({ modelProviders: [], @@ -108,7 +108,7 @@ const ProviderContext = createContext({ }, refreshLicenseLimit: noop, isAllowTransferWorkspace: false, - isAllowPublishAsKnowledgePipeline: false, + isAllowPublishAsCustomKnowledgePipelineTemplate: false, }) export const useProviderContext = () => useContext(ProviderContext) @@ -147,7 +147,7 @@ export const ProviderContextProvider = ({ const [isEducationWorkspace, setIsEducationWorkspace] = useState(false) const { data: educationAccountInfo, isLoading: isLoadingEducationAccountInfo, isFetching: isFetchingEducationAccountInfo } = useEducationStatus(!enableEducationPlan) const [isAllowTransferWorkspace, setIsAllowTransferWorkspace] = useState(false) - const [isAllowPublishAsKnowledgePipeline, setIsAllowPublishAsKnowledgePipeline] = useState(false) + const [isAllowPublishAsCustomKnowledgePipelineTemplate, setIsAllowPublishAsCustomKnowledgePipelineTemplate] = useState(false) const fetchPlan = async () => { try { @@ -179,7 +179,7 @@ export const ProviderContextProvider = ({ if (data.is_allow_transfer_workspace) setIsAllowTransferWorkspace(data.is_allow_transfer_workspace) if (data.knowledge_pipeline?.publish_enabled) - setIsAllowPublishAsKnowledgePipeline(data.knowledge_pipeline?.publish_enabled) + setIsAllowPublishAsCustomKnowledgePipelineTemplate(data.knowledge_pipeline?.publish_enabled) } catch (error) { console.error('Failed to fetch plan info:', error) @@ -245,7 +245,7 @@ export const ProviderContextProvider = ({ licenseLimit, refreshLicenseLimit: fetchPlan, isAllowTransferWorkspace, - isAllowPublishAsKnowledgePipeline, + isAllowPublishAsCustomKnowledgePipelineTemplate, }}> {children} diff --git a/web/i18n/en-US/pipeline.ts b/web/i18n/en-US/pipeline.ts index e906d615f7..4b29bdbb00 100644 --- a/web/i18n/en-US/pipeline.ts +++ b/web/i18n/en-US/pipeline.ts @@ -1,7 +1,7 @@ const translation = { common: { goToAddDocuments: 'Go to add documents', - publishAs: 'Publish as a Knowledge Pipeline', + publishAs: 'Publish as a Customized Pipeline Template', confirmPublish: 'Confirm Publish', confirmPublishContent: 'After successfully publishing the knowledge pipeline, the chunk structure of this knowledge base cannot be modified. Are you sure you want to publish it?', publishAsPipeline: { diff --git a/web/i18n/zh-Hans/pipeline.ts b/web/i18n/zh-Hans/pipeline.ts index 0bba075196..3c3a7a6506 100644 --- a/web/i18n/zh-Hans/pipeline.ts +++ b/web/i18n/zh-Hans/pipeline.ts @@ -1,7 +1,7 @@ const translation = { common: { goToAddDocuments: '去添加文档', - publishAs: '发布为知识流水线', + publishAs: '发布为自定义流水线模板', confirmPublish: '确认发布', confirmPublishContent: '成功发布知识流水线后,此知识库的分段结构将无法修改。您确定要发布吗?', publishAsPipeline: { From 01beb59aa7a65b25f60b7ad046bddb82cc51a68b Mon Sep 17 00:00:00 2001 From: twwu Date: Mon, 15 Sep 2025 11:48:50 +0800 Subject: [PATCH 2/8] feat: Add documentation link to step three of dataset creation process --- .../components/datasets/create/step-three/index.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/web/app/components/datasets/create/step-three/index.tsx b/web/app/components/datasets/create/step-three/index.tsx index 10ff33979d..7498fde7fd 100644 --- a/web/app/components/datasets/create/step-three/index.tsx +++ b/web/app/components/datasets/create/step-three/index.tsx @@ -8,6 +8,7 @@ import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import type { FullDocumentDetail, createDocumentResponse } from '@/models/datasets' import AppIcon from '@/app/components/base/app-icon' import Divider from '@/app/components/base/divider' +import { useDocLink } from '@/context/i18n' type StepThreeProps = { datasetId?: string @@ -19,6 +20,7 @@ type StepThreeProps = { const StepThree = ({ datasetId, datasetName, indexingType, creationCache, retrievalMethod }: StepThreeProps) => { const { t } = useTranslation() + const docLink = useDocLink() const media = useBreakpoints() const isMobile = media === MediaType.mobile @@ -83,6 +85,14 @@ const StepThree = ({ datasetId, datasetName, indexingType, creationCache, retrie
{t('datasetCreation.stepThree.sideTipTitle')}
{t('datasetCreation.stepThree.sideTipContent')}
+ + {t('datasetPipeline.addDocuments.stepThree.learnMore')} +
)} From ab24af9c947e95941a930e54ae4f3b35a21c3809 Mon Sep 17 00:00:00 2001 From: twwu Date: Mon, 15 Sep 2025 21:42:35 +0800 Subject: [PATCH 3/8] feat: Implement reranking model enable/disable functionality in knowledge base panel --- .../retrieval-setting/reranking-model-selector.tsx | 4 ++-- .../retrieval-setting/search-method-option.tsx | 12 +++++++----- .../nodes/knowledge-base/hooks/use-config.ts | 11 +++++++++++ .../workflow/nodes/knowledge-base/panel.tsx | 3 +++ 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/reranking-model-selector.tsx b/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/reranking-model-selector.tsx index 81e131b2a2..e1eccaf309 100644 --- a/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/reranking-model-selector.tsx +++ b/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/reranking-model-selector.tsx @@ -19,8 +19,8 @@ const RerankingModelSelector = ({ readonly = false, }: RerankingModelSelectorProps) => { const { - modelList: rerankModelList, - } = useModelListAndDefaultModel(ModelTypeEnum.rerank) + modelList: rerankModelList, + } = useModelListAndDefaultModel(ModelTypeEnum.rerank) const rerankModel = useMemo(() => { if (!rerankingModel) return undefined diff --git a/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/search-method-option.tsx b/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/search-method-option.tsx index 74629f47ae..40d44f3135 100644 --- a/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/search-method-option.tsx +++ b/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/search-method-option.tsx @@ -178,11 +178,13 @@ const SearchMethodOption = ({
) } - + {rerankingModelEnabled && ( + + )}
) } diff --git a/web/app/components/workflow/nodes/knowledge-base/hooks/use-config.ts b/web/app/components/workflow/nodes/knowledge-base/hooks/use-config.ts index 215ef85559..d5c810cbc4 100644 --- a/web/app/components/workflow/nodes/knowledge-base/hooks/use-config.ts +++ b/web/app/components/workflow/nodes/knowledge-base/hooks/use-config.ts @@ -114,6 +114,16 @@ export const useConfig = (id: string) => { }) }, [getNodeData, handleNodeDataUpdate]) + const handleRerankingModelEnabledChange = useCallback((rerankingModelEnabled: boolean) => { + const nodeData = getNodeData() + handleNodeDataUpdate({ + retrieval_model: { + ...nodeData?.data.retrieval_model, + reranking_enable: rerankingModelEnabled, + }, + }) + }, [getNodeData, handleNodeDataUpdate]) + const handleWeighedScoreChange = useCallback((weightedScore: { value: number[] }) => { const nodeData = getNodeData() handleNodeDataUpdate({ @@ -190,6 +200,7 @@ export const useConfig = (id: string) => { handleEmbeddingModelChange, handleRetrievalSearchMethodChange, handleHybridSearchModeChange, + handleRerankingModelEnabledChange, handleWeighedScoreChange, handleRerankingModelChange, handleTopKChange, diff --git a/web/app/components/workflow/nodes/knowledge-base/panel.tsx b/web/app/components/workflow/nodes/knowledge-base/panel.tsx index 7014e12558..9eaf4ef39f 100644 --- a/web/app/components/workflow/nodes/knowledge-base/panel.tsx +++ b/web/app/components/workflow/nodes/knowledge-base/panel.tsx @@ -39,6 +39,7 @@ const Panel: FC> = ({ handleEmbeddingModelChange, handleRetrievalSearchMethodChange, handleHybridSearchModeChange, + handleRerankingModelEnabledChange, handleWeighedScoreChange, handleRerankingModelChange, handleTopKChange, @@ -150,6 +151,8 @@ const Panel: FC> = ({ onHybridSearchModeChange={handleHybridSearchModeChange} weightedScore={data.retrieval_model.weights} onWeightedScoreChange={handleWeighedScoreChange} + rerankingModelEnabled={data.retrieval_model.reranking_enable} + onRerankingModelEnabledChange={handleRerankingModelEnabledChange} rerankingModel={data.retrieval_model.reranking_model} onRerankingModelChange={handleRerankingModelChange} topK={data.retrieval_model.top_k} From 8b139087e4a0b0a1c03e5b8833aa00b3bd3721e9 Mon Sep 17 00:00:00 2001 From: twwu Date: Tue, 16 Sep 2025 10:45:00 +0800 Subject: [PATCH 4/8] feat: Enhance drawer components with modal and overlay options for improved user experience --- .../detail/completed/child-segment-list.tsx | 14 ++- .../detail/completed/common/drawer.tsx | 104 ++++++++++++++++++ .../completed/common/full-screen-drawer.tsx | 35 +++--- .../documents/detail/completed/index.tsx | 19 +++- .../detail/completed/segment-card/index.tsx | 2 +- 5 files changed, 149 insertions(+), 25 deletions(-) create mode 100644 web/app/components/datasets/documents/detail/completed/common/drawer.tsx diff --git a/web/app/components/datasets/documents/detail/completed/child-segment-list.tsx b/web/app/components/datasets/documents/detail/completed/child-segment-list.tsx index 48f63ae994..b19356cac7 100644 --- a/web/app/components/datasets/documents/detail/completed/child-segment-list.tsx +++ b/web/app/components/datasets/documents/detail/completed/child-segment-list.tsx @@ -95,12 +95,13 @@ const ChildSegmentList: FC = ({ )}> {isFullDocMode ? : null}
-
{ event.stopPropagation() toggleCollapse() @@ -162,6 +163,7 @@ const ChildSegmentList: FC = ({ label={`C-${childChunk.position}${edited ? ` · ${t('datasetDocuments.segment.edited')}` : ''}`} text={childChunk.content} onDelete={() => onDelete?.(childChunk.segment_id, childChunk.id)} + className='child-chunk' labelClassName={focused ? 'bg-state-accent-solid text-text-primary-on-surface' : ''} labelInnerClassName={'text-[10px] font-semibold align-bottom leading-6'} contentClassName={cn('!leading-6', focused ? 'bg-state-accent-hover-alt text-text-primary' : 'text-text-secondary')} diff --git a/web/app/components/datasets/documents/detail/completed/common/drawer.tsx b/web/app/components/datasets/documents/detail/completed/common/drawer.tsx new file mode 100644 index 0000000000..59ac9d76f1 --- /dev/null +++ b/web/app/components/datasets/documents/detail/completed/common/drawer.tsx @@ -0,0 +1,104 @@ +import React, { useCallback, useEffect, useRef } from 'react' +import { createPortal } from 'react-dom' +import cn from '@/utils/classnames' +import { useKeyPress } from 'ahooks' +import { useSegmentListContext } from '..' + +type DrawerProps = { + open: boolean + onClose: () => void + side?: 'right' | 'left' | 'bottom' | 'top' + showOverlay?: boolean + modal?: boolean // click outside event can pass through if modal is false + closeOnOutsideClick?: boolean + panelClassName?: string + panelContentClassName?: string + needCheckChunks?: boolean +} + +const Drawer = ({ + open, + onClose, + side = 'right', + showOverlay = true, + modal = false, + needCheckChunks = false, + children, + panelClassName, + panelContentClassName, +}: React.PropsWithChildren) => { + const panelContentRef = useRef(null) + const currSegment = useSegmentListContext(s => s.currSegment) + const currChildChunk = useSegmentListContext(s => s.currChildChunk) + + useKeyPress('esc', (e) => { + e.preventDefault() + onClose() + }, { exactMatch: true, useCapture: true }) + + const onDownCapture = useCallback((e: PointerEvent) => { + if (!open || modal) return + const panelContent = panelContentRef.current + if (!panelContent) return + const target = e.target as Node | null + const chunks = document.querySelectorAll('.chunk-card') + const childChunks = document.querySelectorAll('.child-chunk') + const isClickOnChunk = Array.from(chunks).some((chunk) => { + return chunk && chunk.contains(target) + }) + const isClickOnChildChunk = Array.from(childChunks).some((chunk) => { + return chunk && chunk.contains(target) + }) + const reopenChunkDetail = (currSegment.showModal && isClickOnChildChunk) + || (currChildChunk.showModal && isClickOnChunk && !isClickOnChildChunk) + if (target && !panelContent.contains(target) && (!needCheckChunks || reopenChunkDetail)) + queueMicrotask(onClose) + }, [currSegment, currChildChunk, needCheckChunks, onClose, open]) + + useEffect(() => { + window.addEventListener('pointerdown', onDownCapture, { capture: true }) + return () => + window.removeEventListener('pointerdown', onDownCapture, { capture: true }) + }, [onDownCapture]) + + const isHorizontal = side === 'left' || side === 'right' + + const content = ( +
+ {showOverlay ? ( + + ) + + return open && createPortal(content, document.body) +} + +export default Drawer diff --git a/web/app/components/datasets/documents/detail/completed/common/full-screen-drawer.tsx b/web/app/components/datasets/documents/detail/completed/common/full-screen-drawer.tsx index cb19aff534..58a9539110 100644 --- a/web/app/components/datasets/documents/detail/completed/common/full-screen-drawer.tsx +++ b/web/app/components/datasets/documents/detail/completed/common/full-screen-drawer.tsx @@ -1,33 +1,42 @@ -import React, { type FC } from 'react' -import Drawer from '@/app/components/base/drawer' -import classNames from '@/utils/classnames' +import React from 'react' +import Drawer from './drawer' +import cn from '@/utils/classnames' import { noop } from 'lodash-es' type IFullScreenDrawerProps = { isOpen: boolean onClose?: () => void fullScreen: boolean - children: React.ReactNode + showOverlay?: boolean + needCheckChunks?: boolean + modal?: boolean } -const FullScreenDrawer: FC = ({ +const FullScreenDrawer = ({ isOpen, onClose = noop, fullScreen, children, -}) => { + showOverlay = true, + needCheckChunks = false, + modal = false, +}: React.PropsWithChildren) => { return ( {children} ) diff --git a/web/app/components/datasets/documents/detail/completed/index.tsx b/web/app/components/datasets/documents/detail/completed/index.tsx index 894671f79e..726be7519a 100644 --- a/web/app/components/datasets/documents/detail/completed/index.tsx +++ b/web/app/components/datasets/documents/detail/completed/index.tsx @@ -153,7 +153,7 @@ const Completed: FC = ({ return docForm === ChunkingMode.parentChild && parentMode === 'full-doc' }, [docForm, parentMode]) - const { isFetching: isLoadingSegmentList, data: segmentListData } = useSegmentList( + const { isLoading: isLoadingSegmentList, data: segmentListData } = useSegmentList( { datasetId, documentId, @@ -183,7 +183,7 @@ const Completed: FC = ({ } }, [segments]) - const { isFetching: isLoadingChildSegmentList, data: childChunkListData } = useChildSegmentList( + const { isLoading: isLoadingChildSegmentList, data: childChunkListData } = useChildSegmentList( { datasetId, documentId, @@ -664,8 +664,11 @@ const Completed: FC = ({ isOpen={currSegment.showModal} fullScreen={fullScreen} onClose={onCloseSegmentDetail} + showOverlay={false} + needCheckChunks > = ({ isOpen={showNewSegmentModal} fullScreen={fullScreen} onClose={onCloseNewSegmentModal} + modal > = ({ isOpen={currChildChunk.showModal} fullScreen={fullScreen} onClose={onCloseChildSegmentDetail} + showOverlay={false} + needCheckChunks > = ({ isOpen={showNewChildSegmentModal} fullScreen={fullScreen} onClose={onCloseNewChildChunkModal} + modal > = ({ /> {/* Batch Action Buttons */} - {selectedSegmentIds.length > 0 - && 0 && ( + } + /> + )} ) } diff --git a/web/app/components/datasets/documents/detail/completed/segment-card/index.tsx b/web/app/components/datasets/documents/detail/completed/segment-card/index.tsx index 80dced041e..f15f3dbd11 100644 --- a/web/app/components/datasets/documents/detail/completed/segment-card/index.tsx +++ b/web/app/components/datasets/documents/detail/completed/segment-card/index.tsx @@ -118,7 +118,7 @@ const SegmentCard: FC = ({ return (
Date: Tue, 16 Sep 2025 11:21:48 +0800 Subject: [PATCH 5/8] feat: Update help links in useAvailableNodesMetaData hook for improved localization support --- .../hooks/use-available-nodes-meta-data.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/web/app/components/rag-pipeline/hooks/use-available-nodes-meta-data.ts b/web/app/components/rag-pipeline/hooks/use-available-nodes-meta-data.ts index 6ce4524c8e..d995de0ce1 100644 --- a/web/app/components/rag-pipeline/hooks/use-available-nodes-meta-data.ts +++ b/web/app/components/rag-pipeline/hooks/use-available-nodes-meta-data.ts @@ -24,11 +24,13 @@ export const useAvailableNodesMetaData = () => { dataSourceEmptyDefault, ], []) - const prefixLink = useMemo(() => { + const helpLinkUri = useMemo(() => { if (language === 'zh_Hans') - return 'https://docs.dify.ai/zh-hans/guides/workflow/node/' + return 'https://docs.dify.ai/zh-hans/guides/knowledge-base/knowledge-pipeline/knowledge-pipeline-orchestration#%E6%AD%A5%E9%AA%A4%E4%B8%80%EF%BC%9A%E6%95%B0%E6%8D%AE%E6%BA%90%E9%85%8D%E7%BD%AE' + if (language === 'ja_JP') + return 'https://docs.dify.ai/ja-jp/guides/knowledge-base/knowledge-pipeline/knowledge-pipeline-orchestration#%E3%82%B9%E3%83%86%E3%83%83%E3%83%971%EF%BC%9A%E3%83%87%E3%83%BC%E3%82%BF%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%AE%E8%A8%AD%E5%AE%9A' - return 'https://docs.dify.ai/guides/workflow/node/' + return 'https://docs.dify.ai/en/guides/knowledge-base/knowledge-pipeline/knowledge-pipeline-orchestration#step-1%3A-data-source' }, [language]) const availableNodesMetaData = useMemo(() => mergedNodesMetaData.map((node) => { @@ -41,7 +43,7 @@ export const useAvailableNodesMetaData = () => { ...metaData, title, description, - helpLinkUri: `${prefixLink}${metaData.helpLinkUri}`, + helpLinkUri, }, defaultValue: { ...node.defaultValue, @@ -49,7 +51,7 @@ export const useAvailableNodesMetaData = () => { title, }, } - }), [mergedNodesMetaData, t, prefixLink]) + }), [mergedNodesMetaData, t]) const availableNodesMetaDataMap = useMemo(() => availableNodesMetaData.reduce((acc, node) => { acc![node.metaData.type] = node From 6440be9f3524578c669eadcc3329d0b661d76395 Mon Sep 17 00:00:00 2001 From: twwu Date: Tue, 16 Sep 2025 11:38:29 +0800 Subject: [PATCH 6/8] feat: Update documentation links in OnlineDocuments, OnlineDrive, and WebsiteCrawl components for improved localization support --- .../data-source/online-documents/index.tsx | 6 ++++-- .../create-from-pipeline/data-source/online-drive/index.tsx | 6 ++++-- .../data-source/website-crawl/index.tsx | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/web/app/components/datasets/documents/create-from-pipeline/data-source/online-documents/index.tsx b/web/app/components/datasets/documents/create-from-pipeline/data-source/online-documents/index.tsx index 92fe6f2e19..f5cbac909d 100644 --- a/web/app/components/datasets/documents/create-from-pipeline/data-source/online-documents/index.tsx +++ b/web/app/components/datasets/documents/create-from-pipeline/data-source/online-documents/index.tsx @@ -15,6 +15,7 @@ import { useModalContextSelector } from '@/context/modal-context' import Title from './title' import { useGetDataSourceAuth } from '@/service/use-datasource' import Loading from '@/app/components/base/loading' +import { useDocLink } from '@/context/i18n' type OnlineDocumentsProps = { isInPipeline?: boolean @@ -29,6 +30,7 @@ const OnlineDocuments = ({ isInPipeline = false, onCredentialChange, }: OnlineDocumentsProps) => { + const docLink = useDocLink() const pipelineId = useDatasetDetailContextWithSelector(s => s.dataset?.pipeline_id) const setShowAccountSettingModal = useModalContextSelector(s => s.setShowAccountSettingModal) const { @@ -125,8 +127,8 @@ const OnlineDocuments = ({ return (
{ + const docLink = useDocLink() const [isInitialMount, setIsInitialMount] = useState(true) const pipelineId = useDatasetDetailContextWithSelector(s => s.dataset?.pipeline_id) const setShowAccountSettingModal = useModalContextSelector(s => s.setShowAccountSettingModal) @@ -185,8 +187,8 @@ const OnlineDrive = ({ return (
{ const { t } = useTranslation() + const docLink = useDocLink() const [totalNum, setTotalNum] = useState(0) const [crawledNum, setCrawledNum] = useState(0) const [crawlErrorMessage, setCrawlErrorMessage] = useState('') @@ -151,8 +153,8 @@ const WebsiteCrawl = ({ return (
Date: Tue, 16 Sep 2025 11:46:43 +0800 Subject: [PATCH 7/8] Update web/app/components/datasets/documents/detail/completed/common/drawer.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../datasets/documents/detail/completed/common/drawer.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/web/app/components/datasets/documents/detail/completed/common/drawer.tsx b/web/app/components/datasets/documents/detail/completed/common/drawer.tsx index 59ac9d76f1..b9d82e4e3a 100644 --- a/web/app/components/datasets/documents/detail/completed/common/drawer.tsx +++ b/web/app/components/datasets/documents/detail/completed/common/drawer.tsx @@ -32,6 +32,7 @@ const Drawer = ({ const currChildChunk = useSegmentListContext(s => s.currChildChunk) useKeyPress('esc', (e) => { + if (!open) return e.preventDefault() onClose() }, { exactMatch: true, useCapture: true }) From 713bd7c326bf0e916f5b3fe48ab676e6a409f1c0 Mon Sep 17 00:00:00 2001 From: twwu Date: Tue, 16 Sep 2025 11:52:07 +0800 Subject: [PATCH 8/8] refactor: Simplify drawer component logic by extracting shouldCloseDrawer function for better readability and maintainability --- .../detail/completed/common/drawer.tsx | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/web/app/components/datasets/documents/detail/completed/common/drawer.tsx b/web/app/components/datasets/documents/detail/completed/common/drawer.tsx index 59ac9d76f1..34170595db 100644 --- a/web/app/components/datasets/documents/detail/completed/common/drawer.tsx +++ b/web/app/components/datasets/documents/detail/completed/common/drawer.tsx @@ -36,11 +36,9 @@ const Drawer = ({ onClose() }, { exactMatch: true, useCapture: true }) - const onDownCapture = useCallback((e: PointerEvent) => { - if (!open || modal) return + const shouldCloseDrawer = useCallback((target: Node | null) => { const panelContent = panelContentRef.current - if (!panelContent) return - const target = e.target as Node | null + if (!panelContent) return false const chunks = document.querySelectorAll('.chunk-card') const childChunks = document.querySelectorAll('.child-chunk') const isClickOnChunk = Array.from(chunks).some((chunk) => { @@ -51,9 +49,17 @@ const Drawer = ({ }) const reopenChunkDetail = (currSegment.showModal && isClickOnChildChunk) || (currChildChunk.showModal && isClickOnChunk && !isClickOnChildChunk) - if (target && !panelContent.contains(target) && (!needCheckChunks || reopenChunkDetail)) + return target && !panelContent.contains(target) && (!needCheckChunks || reopenChunkDetail) + }, [currSegment, currChildChunk, needCheckChunks]) + + const onDownCapture = useCallback((e: PointerEvent) => { + if (!open || modal) return + const panelContent = panelContentRef.current + if (!panelContent) return + const target = e.target as Node | null + if (shouldCloseDrawer(target)) queueMicrotask(onClose) - }, [currSegment, currChildChunk, needCheckChunks, onClose, open]) + }, [shouldCloseDrawer, onClose, open, modal]) useEffect(() => { window.addEventListener('pointerdown', onDownCapture, { capture: true })