feat: Await sub-graph save before syncing workflow draft

This commit is contained in:
zhsama
2026-01-15 17:53:28 +08:00
parent d641c845dd
commit f247ebfbe1
2 changed files with 17 additions and 18 deletions

View File

@ -51,21 +51,21 @@ const SubGraphMain: FC<SubGraphMainProps> = ({
flowId, flowId,
}) })
const handleSyncSubGraphDraft = useCallback(() => { const handleSyncSubGraphDraft = useCallback(async () => {
const { getNodes, edges } = reactFlowStore.getState() const { getNodes, edges } = reactFlowStore.getState()
onSave?.(getNodes() as Node[], edges as Edge[]) await onSave?.(getNodes() as Node[], edges as Edge[])
}, [onSave, reactFlowStore]) }, [onSave, reactFlowStore])
const handleSyncWorkflowDraft = useCallback(async ( const handleSyncWorkflowDraft = useCallback(async (
notRefreshWhenSyncError?: boolean, notRefreshWhenSyncError?: boolean,
callback?: SyncWorkflowDraftCallback, callback?: SyncWorkflowDraftCallback,
) => { ) => {
handleSyncSubGraphDraft()
if (onSyncWorkflowDraft) {
await onSyncWorkflowDraft(notRefreshWhenSyncError, callback)
return
}
try { try {
await handleSyncSubGraphDraft()
if (onSyncWorkflowDraft) {
await onSyncWorkflowDraft(notRefreshWhenSyncError, callback)
return
}
callback?.onSuccess?.() callback?.onSuccess?.()
} }
catch { catch {

View File

@ -4,7 +4,7 @@ import type { SubGraphModalProps } from './types'
import type { MentionConfig } from '@/app/components/workflow/nodes/_base/types' import type { MentionConfig } from '@/app/components/workflow/nodes/_base/types'
import type { LLMNodeType } from '@/app/components/workflow/nodes/llm/types' import type { LLMNodeType } from '@/app/components/workflow/nodes/llm/types'
import type { ToolNodeType } from '@/app/components/workflow/nodes/tool/types' import type { ToolNodeType } from '@/app/components/workflow/nodes/tool/types'
import type { Node, PromptItem } from '@/app/components/workflow/types' import type { Node, PromptItem, PromptTemplateItem } from '@/app/components/workflow/types'
import { Dialog, DialogPanel, Transition, TransitionChild } from '@headlessui/react' import { Dialog, DialogPanel, Transition, TransitionChild } from '@headlessui/react'
import { RiCloseLine } from '@remixicon/react' import { RiCloseLine } from '@remixicon/react'
import { noop } from 'es-toolkit/function' import { noop } from 'es-toolkit/function'
@ -16,7 +16,7 @@ import { useIsChatMode, useNodesSyncDraft, useWorkflow, useWorkflowVariables } f
import { useHooksStore } from '@/app/components/workflow/hooks-store' import { useHooksStore } from '@/app/components/workflow/hooks-store'
import { VarKindType } from '@/app/components/workflow/nodes/_base/types' import { VarKindType } from '@/app/components/workflow/nodes/_base/types'
import { useStore as useWorkflowStore } from '@/app/components/workflow/store' import { useStore as useWorkflowStore } from '@/app/components/workflow/store'
import { BlockEnum, EditionType, PromptRole } from '@/app/components/workflow/types' import { BlockEnum, EditionType, isPromptMessageContext, PromptRole } from '@/app/components/workflow/types'
import SubGraphCanvas from './sub-graph-canvas' import SubGraphCanvas from './sub-graph-canvas'
const SubGraphModal: FC<SubGraphModalProps> = ({ const SubGraphModal: FC<SubGraphModalProps> = ({
@ -129,7 +129,7 @@ const SubGraphModal: FC<SubGraphModalProps> = ({
handleMentionConfigChange(mentionConfig) handleMentionConfigChange(mentionConfig)
}, [handleMentionConfigChange, mentionConfig, toolParam]) }, [handleMentionConfigChange, mentionConfig, toolParam])
const getUserPromptText = useCallback((promptTemplate?: PromptItem[] | PromptItem) => { const getUserPromptText = useCallback((promptTemplate?: PromptTemplateItem[] | PromptItem) => {
if (!promptTemplate) if (!promptTemplate)
return '' return ''
const resolveText = (item?: PromptItem) => { const resolveText = (item?: PromptItem) => {
@ -140,17 +140,18 @@ const SubGraphModal: FC<SubGraphModalProps> = ({
return item.text || '' return item.text || ''
} }
if (Array.isArray(promptTemplate)) { if (Array.isArray(promptTemplate)) {
const userPrompt = promptTemplate.find(item => item.role === PromptRole.user) for (const item of promptTemplate) {
if (userPrompt) if (!isPromptMessageContext(item) && item.role === PromptRole.user)
return resolveText(userPrompt) return resolveText(item)
}
return '' return ''
} }
return resolveText(promptTemplate) return resolveText(promptTemplate)
}, []) }, [])
// TODO: handle external workflow updates while sub-graph modal is open. // TODO: handle external workflow updates while sub-graph modal is open.
const handleSave = useCallback((subGraphNodes: any[], _edges: any[]) => { const handleSave = useCallback((subGraphNodes: Node[]) => {
const extractorNodeData = subGraphNodes.find(node => node.id === extractorNodeId) const extractorNodeData = subGraphNodes.find(node => node.id === extractorNodeId) as Node<LLMNodeType> | undefined
if (!extractorNodeData) if (!extractorNodeData)
return return
@ -193,10 +194,8 @@ const SubGraphModal: FC<SubGraphModalProps> = ({
return node return node
}) })
setNodes(nextNodes) setNodes(nextNodes)
// Trigger main graph draft sync to persist changes to backend
handleSyncWorkflowDraft()
setControlPromptEditorRerenderKey(Date.now()) setControlPromptEditorRerenderKey(Date.now())
}, [agentNodeId, extractorNodeId, getUserPromptText, handleSyncWorkflowDraft, paramKey, reactflowStore, setControlPromptEditorRerenderKey, toolNodeId]) }, [agentNodeId, extractorNodeId, getUserPromptText, paramKey, reactflowStore, setControlPromptEditorRerenderKey, toolNodeId])
return ( return (
<Transition appear show={isOpen} as={Fragment}> <Transition appear show={isOpen} as={Fragment}>