From 2ddd2616ec6361ce12fad8242b967025927e41c0 Mon Sep 17 00:00:00 2001 From: zxhlyh Date: Fri, 6 Jun 2025 14:21:23 +0800 Subject: [PATCH] confirm publish --- .../rag-pipeline-header/publisher/popup.tsx | 73 ++++++++++++++----- .../workflow/nodes/data-source/constants.ts | 22 +++++- .../workflow/nodes/data-source/default.ts | 19 +++-- .../workflow/nodes/data-source/panel.tsx | 23 ++++-- .../workflow/nodes/data-source/types.ts | 5 +- web/i18n/en-US/pipeline.ts | 2 + web/i18n/zh-Hans/pipeline.ts | 2 + 7 files changed, 113 insertions(+), 33 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 85a1cf9266..3349192087 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 @@ -9,7 +9,10 @@ import { RiPlayCircleLine, RiTerminalBoxLine, } from '@remixicon/react' -import { useKeyPress } from 'ahooks' +import { + useBoolean, + useKeyPress, +} from 'ahooks' import { useTranslation } from 'react-i18next' import { useStore, @@ -29,6 +32,7 @@ import { useParams, useRouter } from 'next/navigation' import { useDatasetDetailContextWithSelector } from '@/context/dataset-detail' import { useInvalid } from '@/service/use-base' import { publishedPipelineInfoQueryKeyPrefix } from '@/service/use-pipeline' +import Confirm from '@/app/components/base/confirm' const PUBLISH_SHORTCUT = ['⌘', '⇧', 'P'] @@ -46,29 +50,52 @@ const Popup = () => { const { mutateAsync: publishWorkflow } = usePublishWorkflow() const { notify } = useToastContext() const workflowStore = useWorkflowStore() + const [confirmVisible, { + setFalse: hideConfirm, + setTrue: showConfirm, + }] = useBoolean(false) + const [publishing, { + setFalse: hidePublishing, + setTrue: showPublishing, + }] = useBoolean(false) const invalidPublishedPipelineInfo = useInvalid([...publishedPipelineInfoQueryKeyPrefix, pipelineId]) const handlePublish = useCallback(async (params?: PublishWorkflowParams) => { - if (await handleCheckBeforePublish()) { - const res = await publishWorkflow({ - url: `/rag/pipelines/${pipelineId}/workflows/publish`, - title: params?.title || '', - releaseNotes: params?.releaseNotes || '', - }) - setPublished(true) + if (publishing) + return + try { + const checked = await handleCheckBeforePublish() - if (res) { - notify({ type: 'success', message: t('common.api.actionSuccess') }) - workflowStore.getState().setPublishedAt(res.created_at) - mutateDatasetRes?.() - invalidPublishedPipelineInfo() + if (checked) { + if (!publishedAt && !confirmVisible) { + showConfirm() + return + } + showPublishing() + const res = await publishWorkflow({ + url: `/rag/pipelines/${pipelineId}/workflows/publish`, + title: params?.title || '', + releaseNotes: params?.releaseNotes || '', + }) + setPublished(true) + if (res) { + notify({ type: 'success', message: t('common.api.actionSuccess') }) + workflowStore.getState().setPublishedAt(res.created_at) + mutateDatasetRes?.() + invalidPublishedPipelineInfo() + } } } - else { - throw new Error('Checklist failed') + catch { } - }, [handleCheckBeforePublish, publishWorkflow, pipelineId, notify, t, workflowStore, mutateDatasetRes, invalidPublishedPipelineInfo]) + finally { + if (publishing) + hidePublishing() + if (confirmVisible) + hideConfirm() + } + }, [handleCheckBeforePublish, publishWorkflow, pipelineId, notify, t, workflowStore, mutateDatasetRes, invalidPublishedPipelineInfo, showConfirm, publishedAt, confirmVisible, hidePublishing, showPublishing, hideConfirm, publishing]) useKeyPress(`${getKeyboardKeyCodeBySystem('ctrl')}.shift.p`, (e) => { e.preventDefault() @@ -108,7 +135,7 @@ const Popup = () => { variant='primary' className='mt-3 w-full' onClick={() => handlePublish()} - disabled={published} + disabled={published || publishing} > { published @@ -163,6 +190,18 @@ const Popup = () => { + { + confirmVisible && ( + + ) + } ) } diff --git a/web/app/components/workflow/nodes/data-source/constants.ts b/web/app/components/workflow/nodes/data-source/constants.ts index c80b7d4f62..e18879be9e 100644 --- a/web/app/components/workflow/nodes/data-source/constants.ts +++ b/web/app/components/workflow/nodes/data-source/constants.ts @@ -30,7 +30,7 @@ export const COMMON_OUTPUT = [ }, ] -export const FILE_OUTPUT = [ +export const LOCAL_FILE_OUTPUT = [ { name: 'file', type: VarType.file, @@ -80,7 +80,7 @@ export const FILE_OUTPUT = [ }, ] -export const WEBSITE_OUTPUT = [ +export const WEBSITE_CRAWL_OUTPUT = [ { name: 'source_url', type: VarType.string, @@ -102,3 +102,21 @@ export const WEBSITE_OUTPUT = [ description: 'The description of the crawled website', }, ] + +export const ONLINE_DOCUMENT_OUTPUT = [ + { + name: 'workspace_id', + type: VarType.string, + description: 'The ID of the workspace where the document is stored', + }, + { + name: 'page_id', + type: VarType.string, + description: 'The ID of the page in the document', + }, + { + name: 'content', + type: VarType.string, + description: 'The content of the online document', + }, +] diff --git a/web/app/components/workflow/nodes/data-source/default.ts b/web/app/components/workflow/nodes/data-source/default.ts index bb5c9375b1..2319757d48 100644 --- a/web/app/components/workflow/nodes/data-source/default.ts +++ b/web/app/components/workflow/nodes/data-source/default.ts @@ -5,8 +5,9 @@ import { genNodeMetaData } from '@/app/components/workflow/utils' import { BlockEnum } from '@/app/components/workflow/types' import { COMMON_OUTPUT, - FILE_OUTPUT, - WEBSITE_OUTPUT, + LOCAL_FILE_OUTPUT, + ONLINE_DOCUMENT_OUTPUT, + WEBSITE_CRAWL_OUTPUT, } from './constants' import { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types' @@ -58,18 +59,24 @@ const nodeDefault: NodeDefault = { const { provider_type, } = payload - const isLocalFile = provider_type === DataSourceClassification.file - const isWebsiteCrawl = provider_type === DataSourceClassification.website + const isLocalFile = provider_type === DataSourceClassification.localFile + const isWebsiteCrawl = provider_type === DataSourceClassification.websiteCrawl + const isOnlineDocument = provider_type === DataSourceClassification.onlineDocument return [ ...COMMON_OUTPUT.map(item => ({ variable: item.name, type: item.type })), ...( isLocalFile - ? FILE_OUTPUT.map(item => ({ variable: item.name, type: item.type })) + ? LOCAL_FILE_OUTPUT.map(item => ({ variable: item.name, type: item.type })) : [] ), ...( isWebsiteCrawl - ? WEBSITE_OUTPUT.map(item => ({ variable: item.name, type: item.type })) + ? WEBSITE_CRAWL_OUTPUT.map(item => ({ variable: item.name, type: item.type })) + : [] + ), + ...( + isOnlineDocument + ? ONLINE_DOCUMENT_OUTPUT.map(item => ({ variable: item.name, type: item.type })) : [] ), ...ragVars, diff --git a/web/app/components/workflow/nodes/data-source/panel.tsx b/web/app/components/workflow/nodes/data-source/panel.tsx index c043de9df1..1148efc2bd 100644 --- a/web/app/components/workflow/nodes/data-source/panel.tsx +++ b/web/app/components/workflow/nodes/data-source/panel.tsx @@ -20,8 +20,9 @@ import { useNodesReadOnly } from '@/app/components/workflow/hooks' import { useConfig } from './hooks/use-config' import { COMMON_OUTPUT, - FILE_OUTPUT, - WEBSITE_OUTPUT, + LOCAL_FILE_OUTPUT, + ONLINE_DOCUMENT_OUTPUT, + WEBSITE_CRAWL_OUTPUT, } from './constants' import { useStore } from '@/app/components/workflow/store' import Button from '@/app/components/base/button' @@ -48,8 +49,9 @@ const Panel: FC> = ({ id, data }) => { handleFileExtensionsChange, handleParametersChange, } = useConfig(id) - const isLocalFile = provider_type === DataSourceClassification.file - const isWebsiteCrawl = provider_type === DataSourceClassification.website + const isLocalFile = provider_type === DataSourceClassification.localFile + const isWebsiteCrawl = provider_type === DataSourceClassification.websiteCrawl + const isOnlineDocument = provider_type === DataSourceClassification.onlineDocument const currentDataSource = dataSourceList?.find(ds => ds.plugin_id === plugin_id) const isAuthorized = !!currentDataSource?.is_authorized const [showAuthModal, { @@ -166,7 +168,7 @@ const Panel: FC> = ({ id, data }) => { )) } { - isLocalFile && FILE_OUTPUT.map(item => ( + isLocalFile && LOCAL_FILE_OUTPUT.map(item => ( > = ({ id, data }) => { )) } { - isWebsiteCrawl && WEBSITE_OUTPUT.map(item => ( + isWebsiteCrawl && WEBSITE_CRAWL_OUTPUT.map(item => ( + + )) + } + { + isOnlineDocument && ONLINE_DOCUMENT_OUTPUT.map(item => (