diff --git a/web/app/components/sub-graph/components/sub-graph-main.tsx b/web/app/components/sub-graph/components/sub-graph-main.tsx index 15627b8642..727693162c 100644 --- a/web/app/components/sub-graph/components/sub-graph-main.tsx +++ b/web/app/components/sub-graph/components/sub-graph-main.tsx @@ -1,7 +1,8 @@ import type { FC } from 'react' import type { Viewport } from 'reactflow' import type { Edge, Node } from '@/app/components/workflow/types' -import { useMemo } from 'react' +import { useCallback, useMemo } from 'react' +import { useStoreApi } from 'reactflow' import { WorkflowWithInnerContext } from '@/app/components/workflow' import { useAvailableNodesMetaData, useSubGraphPersistence } from '../hooks' import SubGraphChildren from './sub-graph-children' @@ -12,6 +13,7 @@ type SubGraphMainProps = { viewport: Viewport toolNodeId: string paramKey: string + onSave?: (nodes: Node[], edges: Edge[]) => void } const SubGraphMain: FC = ({ @@ -20,49 +22,25 @@ const SubGraphMain: FC = ({ viewport, toolNodeId, paramKey, + onSave, }) => { + const reactFlowStore = useStoreApi() const availableNodesMetaData = useAvailableNodesMetaData() const { updateSubGraphConfig } = useSubGraphPersistence({ toolNodeId, paramKey }) - const hooksStore = useMemo(() => { - return { - interactionMode: 'subgraph', - availableNodesMetaData, - doSyncWorkflowDraft: async () => {}, - syncWorkflowDraftWhenPageClose: () => {}, - handleRefreshWorkflowDraft: () => {}, - handleBackupDraft: () => {}, - handleLoadBackupDraft: () => {}, - handleRestoreFromPublishedWorkflow: () => {}, - handleRun: () => {}, - handleStopRun: () => {}, - handleStartWorkflowRun: () => {}, - handleWorkflowStartRunInWorkflow: () => {}, - handleWorkflowStartRunInChatflow: () => {}, - handleWorkflowTriggerScheduleRunInWorkflow: () => {}, - handleWorkflowTriggerWebhookRunInWorkflow: () => {}, - handleWorkflowTriggerPluginRunInWorkflow: () => {}, - handleWorkflowRunAllTriggersInWorkflow: () => {}, - getWorkflowRunAndTraceUrl: () => ({ runUrl: '', traceUrl: '' }), - exportCheck: async () => {}, - handleExportDSL: async () => {}, - fetchInspectVars: async () => {}, - hasNodeInspectVars: () => false, - hasSetInspectVar: () => false, - fetchInspectVarValue: async () => {}, - editInspectVarValue: async () => {}, - renameInspectVarName: async () => {}, - appendNodeInspectVars: () => {}, - deleteInspectVar: async () => {}, - deleteNodeInspectorVars: async () => {}, - deleteAllInspectorVars: async () => {}, - isInspectVarEdited: () => false, - resetToLastRunVar: async () => {}, - invalidateSysVarValues: () => {}, - resetConversationVar: async () => {}, - invalidateConversationVarValues: () => {}, - } - }, [availableNodesMetaData]) + const handleSyncSubGraphDraft = useCallback(() => { + const { getNodes, edges } = reactFlowStore.getState() + onSave?.(getNodes() as Node[], edges as Edge[]) + }, [onSave, reactFlowStore]) + + const hooksStore = useMemo(() => ({ + interactionMode: 'subgraph', + availableNodesMetaData, + doSyncWorkflowDraft: async () => { + handleSyncSubGraphDraft() + }, + syncWorkflowDraftWhenPageClose: handleSyncSubGraphDraft, + }), [availableNodesMetaData, handleSyncSubGraphDraft]) return ( = (props) => { agentNodeId, extractorNode, toolParamValue, + onSave, } = props const promptText = useMemo(() => { @@ -132,6 +133,7 @@ const SubGraph: FC = (props) => { viewport={defaultViewport} toolNodeId={toolNodeId} paramKey={paramKey} + onSave={onSave} /> ) diff --git a/web/app/components/workflow/nodes/tool/components/sub-graph-modal/index.tsx b/web/app/components/workflow/nodes/tool/components/sub-graph-modal/index.tsx index 68a985dccc..3ee27c3b54 100644 --- a/web/app/components/workflow/nodes/tool/components/sub-graph-modal/index.tsx +++ b/web/app/components/workflow/nodes/tool/components/sub-graph-modal/index.tsx @@ -28,6 +28,7 @@ const SubGraphModal: FC = ({ const { t } = useTranslation() const reactflowStore = useStoreApi() const workflowNodes = useStore(state => state.nodes) + const setControlPromptEditorRerenderKey = useStore(state => state.setControlPromptEditorRerenderKey) const { handleSyncWorkflowDraft } = useNodesSyncDraft() const extractorNodeId = `${toolNodeId}_ext_${paramKey}` @@ -94,8 +95,9 @@ const SubGraphModal: FC = ({ }) setNodes(nextNodes) // Trigger main graph draft sync to persist changes to backend - handleSyncWorkflowDraft() - }, [agentNodeId, extractorNodeId, getSystemPromptText, handleSyncWorkflowDraft, paramKey, reactflowStore, toolNodeId]) + handleSyncWorkflowDraft(true) + setControlPromptEditorRerenderKey(Date.now()) + }, [agentNodeId, extractorNodeId, getSystemPromptText, handleSyncWorkflowDraft, paramKey, reactflowStore, setControlPromptEditorRerenderKey, toolNodeId]) return (