diff --git a/web/app/components/workflow/constants.ts b/web/app/components/workflow/constants.ts index a7f56d645d..975a8d5ed5 100644 --- a/web/app/components/workflow/constants.ts +++ b/web/app/components/workflow/constants.ts @@ -159,6 +159,7 @@ export const X_OFFSET = 64 export const NODE_WIDTH_X_OFFSET = NODE_WIDTH + X_OFFSET export const Y_OFFSET = 39 export const TREE_DEEPTH = 20 +export const START_INITIAL_POSITION = { x: 80, y: 282 } export const RETRIEVAL_OUTPUT_STRUCT = `{ "content": "", diff --git a/web/app/components/workflow/hooks/use-workflow.ts b/web/app/components/workflow/hooks/use-workflow.ts index 82dbbbc386..7cb8dab283 100644 --- a/web/app/components/workflow/hooks/use-workflow.ts +++ b/web/app/components/workflow/hooks/use-workflow.ts @@ -86,9 +86,12 @@ export const useWorkflow = () => { edges, } = store.getState() const nodes = getNodes() - const currentNode = nodes.find(node => node.id === nodeId)! + const currentNode = nodes.find(node => node.id === nodeId) const list: Node[] = [] + if (!currentNode) + return list + const traverse = (root: Node, callback: (node: Node) => void) => { const incomers = getIncomers(root, nodes, edges) diff --git a/web/app/components/workflow/index.tsx b/web/app/components/workflow/index.tsx index d2cca2afd3..513c7c4391 100644 --- a/web/app/components/workflow/index.tsx +++ b/web/app/components/workflow/index.tsx @@ -38,6 +38,7 @@ import { initialEdges, initialNodes, } from './utils' +import { START_INITIAL_POSITION } from './constants' import { fetchWorkflowDraft, syncWorkflowDraft, @@ -168,11 +169,11 @@ const WorkflowWrap: FC = ({ return { id: `${Date.now()}`, type: 'custom', - data: nodesInitialData.start, - position: { - x: 100, - y: 200, + data: { + ...nodesInitialData.start, + selected: true, }, + position: START_INITIAL_POSITION, } }, [nodesInitialData]) @@ -214,6 +215,7 @@ const WorkflowWrap: FC = ({ if (error && error.json && !error.bodyUsed && appDetail) { error.json().then((err: any) => { if (err.code === 'draft_workflow_not_exist') { + useStore.setState({ notInitialWorkflow: true }) syncWorkflowDraft({ url: `/apps/${appDetail.id}/workflows/draft`, params: { diff --git a/web/app/components/workflow/nodes/_base/components/node-handle.tsx b/web/app/components/workflow/nodes/_base/components/node-handle.tsx index 164ec9822a..5803ae8ec4 100644 --- a/web/app/components/workflow/nodes/_base/components/node-handle.tsx +++ b/web/app/components/workflow/nodes/_base/components/node-handle.tsx @@ -1,6 +1,7 @@ import type { MouseEvent } from 'react' import { useCallback, + useEffect, useState, } from 'react' import type { NodeProps } from 'reactflow' @@ -15,6 +16,7 @@ import type { Node } from '../../../types' import BlockSelector from '../../../block-selector' import type { ToolDefaultValue } from '../../../block-selector/types' import { useNodesInteractions } from '../../../hooks' +import { useStore } from '../../../store' type NodeHandleProps = { handleId: string @@ -87,10 +89,12 @@ export const NodeTargetHandle = ({ export const NodeSourceHandle = ({ id, + data, handleId, handleClassName, nodeSelectorClassName, }: NodeHandleProps) => { + const notInitialWorkflow = useStore(s => s.notInitialWorkflow) const [open, setOpen] = useState(false) const { handleNodeAddNext } = useNodesInteractions() const edges = useEdges() @@ -108,6 +112,11 @@ export const NodeSourceHandle = ({ handleNodeAddNext(id, type, handleId, toolDefaultValue) }, [handleNodeAddNext, id, handleId]) + useEffect(() => { + if (notInitialWorkflow && data.type === BlockEnum.Start) + setOpen(true) + }, [notInitialWorkflow, data.type]) + return ( <> void setInputs: (inputs: Record) => void setBackupDraft: (backupDraft?: State['backupDraft']) => void + setNotInitialWorkflow: (notInitialWorkflow: boolean) => void } export const useStore = create(set => ({ @@ -91,4 +93,6 @@ export const useStore = create(set => ({ setInputs: inputs => set(() => ({ inputs })), backupDraft: undefined, setBackupDraft: backupDraft => set(() => ({ backupDraft })), + notInitialWorkflow: false, + setNotInitialWorkflow: notInitialWorkflow => set(() => ({ notInitialWorkflow })), }))