From 82a616589b39ef15d328babfdb2c087974f06fd5 Mon Sep 17 00:00:00 2001 From: balibabu Date: Fri, 6 Mar 2026 20:17:21 +0800 Subject: [PATCH] Feat: Add PublishConfirmDialog (#13447) ### What problem does this PR solve? Feat: Add PublishConfirmDialog ### Type of change - [x] New Feature (non-breaking change which adds functionality) --- web/src/hooks/use-agent-request.ts | 1 + web/src/locales/en.ts | 5 + .../components/publish-confirm-dialog.tsx | 103 ++++++++++++++++++ web/src/pages/agent/hooks/use-save-graph.ts | 15 ++- web/src/pages/agent/index.tsx | 46 ++++---- 5 files changed, 147 insertions(+), 23 deletions(-) create mode 100644 web/src/pages/agent/components/publish-confirm-dialog.tsx diff --git a/web/src/hooks/use-agent-request.ts b/web/src/hooks/use-agent-request.ts index a385c8b87d..df577530e2 100644 --- a/web/src/hooks/use-agent-request.ts +++ b/web/src/hooks/use-agent-request.ts @@ -306,6 +306,7 @@ export const useSetAgent = (showMessage: boolean = true) => { dsl?: Record; avatar?: string; canvas_category?: string; + release?: string; }) => { const { data = {} } = await agentService.setCanvas(params); if (data.code === 0) { diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts index b928d8496e..0977e4eddc 100644 --- a/web/src/locales/en.ts +++ b/web/src/locales/en.ts @@ -2180,6 +2180,10 @@ This process aggregates variables from multiple branches into a single variable 'Write your SQL query here. You can use variables, raw SQL, or mix both using variable syntax.', frameworkPrompts: 'Framework', release: 'Publish', + confirmPublish: 'Confirm Publish', + publishDescription: 'You are about to publish this data pipeline.', + linkedDataset: 'Linked dataset', + lastPublished: 'Last published', createFromBlank: 'Create from blank', createFromTemplate: 'Create from template', importJsonFile: 'Import JSON file', @@ -2554,6 +2558,7 @@ Important structured information may include: names, dates, locations, events, k import: 'Import', description: 'Description', noDescription: 'No description', + none: 'None', resourceType: { dataset: 'Dataset', diff --git a/web/src/pages/agent/components/publish-confirm-dialog.tsx b/web/src/pages/agent/components/publish-confirm-dialog.tsx new file mode 100644 index 0000000000..a058bef9cb --- /dev/null +++ b/web/src/pages/agent/components/publish-confirm-dialog.tsx @@ -0,0 +1,103 @@ +import { Button, ButtonLoading } from '@/components/ui/button'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from '@/components/ui/dialog'; +import { Operator } from '@/pages/agent/constant'; +import useGraphStore from '@/pages/agent/store'; +import { formatDate } from '@/utils/date'; +import { BookPlus } from 'lucide-react'; +import { useMemo, useState } from 'react'; +import { useTranslation } from 'react-i18next'; + +interface PublishConfirmDialogProps { + agentDetail: { title: string; update_time?: number }; + loading: boolean; + onPublish: () => void; +} + +export function PublishConfirmDialog({ + agentDetail, + loading, + onPublish, +}: PublishConfirmDialogProps) { + const { t } = useTranslation(); + const [open, setOpen] = useState(false); + const nodes = useGraphStore((state) => state.nodes); + + const linkedDatasets = useMemo(() => { + const datasets: string[] = []; + nodes.forEach((node) => { + if (node.data.label === Operator.Retrieval) { + const kbIds = node.data.form?.kb_ids || []; + datasets.push(...kbIds); + } + }); + return [...new Set(datasets)]; + }, [nodes]); + + const lastPublished = useMemo(() => { + if (agentDetail?.update_time) { + return formatDate(agentDetail.update_time); + } + return '-'; + }, [agentDetail?.update_time]); + + const handleConfirmPublish = () => { + onPublish(); + setOpen(false); + }; + + return ( + + + + {t('flow.release')} + + + + + {t('flow.confirmPublish')} + + +
+
+ + {agentDetail.title} + +
+
+
+ + {t('flow.linkedDataset')} + + + {linkedDatasets.length > 0 + ? linkedDatasets.join(', ') + : t('common.none')} + +
+
+ + {t('flow.lastPublished')} + + {lastPublished} +
+
+
+
+ + + + +
+
+ ); +} diff --git a/web/src/pages/agent/hooks/use-save-graph.ts b/web/src/pages/agent/hooks/use-save-graph.ts index d308c21e0d..ac764605d5 100644 --- a/web/src/pages/agent/hooks/use-save-graph.ts +++ b/web/src/pages/agent/hooks/use-save-graph.ts @@ -21,13 +21,22 @@ export const useSaveGraph = (showMessage: boolean = true) => { const saveGraph = useCallback( async ( currentNodes?: RAGFlowNodeType[], - otherParam?: { globalVariables: Record }, + otherParam?: { + globalVariables: Record; + }, + release?: boolean, ) => { - return setAgent({ + const params: Record = { id, title: data.title, dsl: buildDslData(currentNodes, otherParam), - }); + }; + + if (release) { + params.release = 'true'; + } + + return setAgent(params); }, [setAgent, data, id, buildDslData], ); diff --git a/web/src/pages/agent/index.tsx b/web/src/pages/agent/index.tsx index f53c6a2ee5..1623b91d87 100644 --- a/web/src/pages/agent/index.tsx +++ b/web/src/pages/agent/index.tsx @@ -17,6 +17,7 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; +import message from '@/components/ui/message'; import { SharedFrom } from '@/constants/chat'; import { useSetModalState } from '@/hooks/common-hooks'; import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks'; @@ -38,6 +39,7 @@ import { useTranslation } from 'react-i18next'; import { useParams } from 'react-router'; import AgentCanvas from './canvas'; import { DropdownProvider } from './canvas/context'; +import { PublishConfirmDialog } from './components/publish-confirm-dialog'; import { Operator } from './constant'; import { GlobalParamSheet } from './gobal-variable-sheet'; import { useCancelCurrentDataflow } from './hooks/use-cancel-dataflow'; @@ -238,13 +240,6 @@ export default function Agent() { > {t('flow.save')} - showGlobalParamSheet()} - loading={loading} - > - {t('flow.conversationVariable')} - - - {isPipeline || ( - - )} {isConversationMode && ( + showGlobalParamSheet()}> + + {t('flow.conversationVariable')} + + + + + {t('flow.historyVersion')} + + + {isPipeline || ( + navigateToAgentLogs(id as string)()} + > + + {t('flow.log')} + + )} + {t('flow.export')}