From 4c8da850500f2cc3730fba04b403c98621881124 Mon Sep 17 00:00:00 2001 From: zhaoying Date: Thu, 15 Jan 2026 13:38:27 +0800 Subject: [PATCH] fix(web): Calculation logic adjustment of variableList --- web/src/i18n/en.ts | 3 ++ web/src/i18n/zh.ts | 3 ++ .../Workflow/components/Nodes/AddNode.tsx | 4 +- .../Workflow/components/Nodes/LoopNode.tsx | 13 +++--- .../Workflow/components/PortClickHandler.tsx | 4 +- .../Workflow/components/Properties/index.tsx | 41 ++++++++++++++++--- .../views/Workflow/hooks/useWorkflowGraph.ts | 9 ++-- web/src/views/Workflow/index.tsx | 1 + 8 files changed, 55 insertions(+), 23 deletions(-) diff --git a/web/src/i18n/en.ts b/web/src/i18n/en.ts index 2d2d96a2..6923e5fb 100644 --- a/web/src/i18n/en.ts +++ b/web/src/i18n/en.ts @@ -1960,6 +1960,9 @@ Memory Bear: After the rebellion, regional warlordism intensified for several re addMessage: 'Add Message', answerDesc: 'Reply', addNode: 'Add Node', + arrange: 'Arrange', + redo: 'Redo', + undo: 'Undo', }, emotionEngine: { emotionEngineConfig: 'Emotion Engine Configuration', diff --git a/web/src/i18n/zh.ts b/web/src/i18n/zh.ts index 53e71c84..92804d3c 100644 --- a/web/src/i18n/zh.ts +++ b/web/src/i18n/zh.ts @@ -2057,6 +2057,9 @@ export const zh = { addMessage: '添加消息', answerDesc: '回复', addNode: '添加节点', + arrange: '整理', + redo: '重做', + undo: '撤销', }, emotionEngine: { emotionEngineConfig: '情感引擎配置', diff --git a/web/src/views/Workflow/components/Nodes/AddNode.tsx b/web/src/views/Workflow/components/Nodes/AddNode.tsx index a37da651..d2d1d15c 100644 --- a/web/src/views/Workflow/components/Nodes/AddNode.tsx +++ b/web/src/views/Workflow/components/Nodes/AddNode.tsx @@ -36,7 +36,7 @@ const AddNode: ReactShapeConfig['component'] = ({ node, graph }) => { if (cycleId) { const parentNode = graph.getNodes().find((n: any) => n.getData()?.id === cycleId); if (parentNode) { - parentNode.insertChild(newNode); + parentNode.addChild(newNode); } } @@ -48,7 +48,6 @@ const AddNode: ReactShapeConfig['component'] = ({ node, graph }) => { source: { cell: edge.getSourceCellId(), port: edge.getSourcePortId() }, target: { cell: newNode.id, port: newNode.getPorts().find((port: any) => port.group === 'left')?.id || 'left' }, attrs: edge.getAttrs(), - zIndex: 1, }); }); @@ -59,7 +58,6 @@ const AddNode: ReactShapeConfig['component'] = ({ node, graph }) => { source: { cell: newNode.id, port: newNode.getPorts().find((port: any) => port.group === 'right')?.id || 'right' }, target: { cell: edge.getTargetCellId(), port: targetPortId }, attrs: edge.getAttrs(), - zIndex: 1, }); }); diff --git a/web/src/views/Workflow/components/Nodes/LoopNode.tsx b/web/src/views/Workflow/components/Nodes/LoopNode.tsx index 71f4dc44..26109d58 100644 --- a/web/src/views/Workflow/components/Nodes/LoopNode.tsx +++ b/web/src/views/Workflow/components/Nodes/LoopNode.tsx @@ -18,7 +18,7 @@ const LoopNode: ReactShapeConfig['component'] = ({ node, graph }) => { }, 50) return () => clearTimeout(timer) - }, []) + }, [graph]) const checkAndAddAddNode = () => { if (!graph) return; @@ -44,15 +44,15 @@ const LoopNode: ReactShapeConfig['component'] = ({ node, graph }) => { }, }); - node.insertChild(addNode); + node.addChild(addNode); // 连接cycle-start和add-node const sourcePorts = cycleStartNode.getPorts(); const targetPorts = addNode.getPorts(); const sourcePort = sourcePorts.find((port: any) => port.group === 'right')?.id || 'right'; const targetPort = targetPorts.find((port: any) => port.group === 'left')?.id || 'left'; - - // 直接创建连线,不使用异步 + + // 然后创建连线 graph.addEdge({ source: { cell: cycleStartNode.id, port: sourcePort }, target: { cell: addNode.id, port: targetPort }, @@ -107,8 +107,8 @@ const LoopNode: ReactShapeConfig['component'] = ({ node, graph }) => { cycle: data.id, }, }); - node.insertChild(cycleStartNode) - node.insertChild(addNode) + node.addChild(cycleStartNode) + node.addChild(addNode) const sourcePorts = cycleStartNode.getPorts() const targetPorts = addNode.getPorts() let sourcePort = sourcePorts.find((port: any) => port.group === 'right')?.id || 'right'; @@ -133,7 +133,6 @@ const LoopNode: ReactShapeConfig['component'] = ({ node, graph }) => { }, }, } - graph.addEdge(edgeConfig) } diff --git a/web/src/views/Workflow/components/PortClickHandler.tsx b/web/src/views/Workflow/components/PortClickHandler.tsx index 8342ae6a..050ed35d 100644 --- a/web/src/views/Workflow/components/PortClickHandler.tsx +++ b/web/src/views/Workflow/components/PortClickHandler.tsx @@ -129,7 +129,7 @@ const PortClickHandler: React.FC = ({ graph }) => { if (sourceNodeData.cycle) { const parentNode = graph.getNodes().find((n: any) => n.getData()?.id === sourceNodeData.cycle); if (parentNode) { - parentNode.insertChild(newNode); + parentNode.addChild(newNode); } } @@ -159,7 +159,7 @@ const PortClickHandler: React.FC = ({ graph }) => { }, }, }, - zIndex: sourceNodeData.cycle && sourceNodeType == 'cycle-start' ? 1 : sourceNodeData.cycle ? 2 : 0 + // zIndex: sourceNodeData.cycle && sourceNodeType == 'cycle-start' ? 1 : sourceNodeData.cycle ? 2 : 0 }); // 循环节点内子节点通过连接桩添加时,调整循环节点大小 diff --git a/web/src/views/Workflow/components/Properties/index.tsx b/web/src/views/Workflow/components/Properties/index.tsx index 77c3414f..f9fbad63 100644 --- a/web/src/views/Workflow/components/Properties/index.tsx +++ b/web/src/views/Workflow/components/Properties/index.tsx @@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next' import { Graph, Node } from '@antv/x6'; import { Form, Input, Button, Select, InputNumber, Slider, Space, Divider, App, Switch } from 'antd' -import type { NodeConfig, NodeProperties, StartVariableItem, VariableEditModalRef } from '../../types' +import type { NodeConfig, NodeProperties, StartVariableItem, VariableEditModalRef, ChatVariable } from '../../types' import Empty from '@/components/Empty'; import emptyIcon from '@/assets/images/workflow/empty.png' import CustomSelect from "@/components/CustomSelect"; @@ -34,11 +34,12 @@ interface PropertiesProps { copyEvent: () => void; parseEvent: () => void; config?: any; + chatVariables: ChatVariable[]; } const Properties: FC = ({ selectedNode, graphRef, - config: workflowConfig, + chatVariables }) => { const { t } = useTranslation() const { modal } = App.useApp() @@ -47,6 +48,7 @@ const Properties: FC = ({ const values = Form.useWatch([], form); const variableModalRef = useRef(null) const [editIndex, setEditIndex] = useState(null) + const [graphUpdateTrigger, setGraphUpdateTrigger] = useState(0) const prevMappingNamesRef = useRef([]) const prevTemplateVarsRef = useRef([]) const syncTimeoutRef = useRef(null) @@ -349,11 +351,9 @@ const Properties: FC = ({ const parentPreviousNodeIds = getAllPreviousNodes(parentLoopNode.id); allRelevantNodeIds.push(...parentPreviousNodeIds); } - - // Add conversation variables from global config - const conversationVariables = workflowConfig?.variables || []; + const conversationVariables = chatVariables || []; conversationVariables.forEach((variable: any) => { const key = `CONVERSATION_${variable.name}`; @@ -763,7 +763,36 @@ const Properties: FC = ({ } return variableList; - }, [selectedNode, graphRef, workflowConfig?.variables]); + }, [selectedNode, graphRef, graphUpdateTrigger, chatVariables]); + + // Trigger variableList update when graph edges or nodes change + useEffect(() => { + if (!graphRef?.current) return; + + const graph = graphRef.current; + const handleGraphChange = () => { + console.log('handleGraphChange') + // Force variableList recalculation by updating trigger + setGraphUpdateTrigger(prev => prev + 1); + }; + + // Listen to graph changes + graph.on('edge:added', handleGraphChange); + graph.on('edge:removed', handleGraphChange); + graph.on('edge:changed', handleGraphChange); + graph.on('node:added', handleGraphChange); + graph.on('node:removed', handleGraphChange); + graph.on('node:change:data', handleGraphChange); + + return () => { + graph.off('edge:added', handleGraphChange); + graph.off('edge:removed', handleGraphChange); + graph.off('edge:changed', handleGraphChange); + graph.off('node:added', handleGraphChange); + graph.off('node:removed', handleGraphChange); + graph.off('node:change:data', handleGraphChange); + }; + }, [graphRef]); // Filter out boolean type variables for loop and llm nodes const getFilteredVariableList = (nodeType?: string, key?: string) => { diff --git a/web/src/views/Workflow/hooks/useWorkflowGraph.ts b/web/src/views/Workflow/hooks/useWorkflowGraph.ts index f3439571..87ee80fc 100644 --- a/web/src/views/Workflow/hooks/useWorkflowGraph.ts +++ b/web/src/views/Workflow/hooks/useWorkflowGraph.ts @@ -54,7 +54,7 @@ export const useWorkflowGraph = ({ const historyRef = useRef<{ undoStack: string[], redoStack: string[] }>({ undoStack: [], redoStack: [] }); const [canUndo, setCanUndo] = useState(false); const [canRedo, setCanRedo] = useState(false); - const [isHandMode, setIsHandMode] = useState(false); + const [isHandMode, setIsHandMode] = useState(true); const [config, setConfig] = useState(null); const [chatVariables, setChatVariables] = useState([]) @@ -235,7 +235,7 @@ export const useWorkflowGraph = ({ if (parentNode) { const addedChild = graphRef.current?.addNode(childNode) if (addedChild) { - parentNode.insertChild(addedChild) + parentNode.addChild(addedChild) } } } @@ -354,7 +354,7 @@ export const useWorkflowGraph = ({ }, }, }, - zIndex: loopIterationCount + // zIndex: loopIterationCount } return edgeConfig @@ -694,10 +694,9 @@ export const useWorkflowGraph = ({ thickness: 1, // 网点大小 } }, - panning: false, + panning: isHandMode, mousewheel: { enabled: true, - modifiers: ['ctrl', 'meta'], }, connecting: { // router: 'orth', diff --git a/web/src/views/Workflow/index.tsx b/web/src/views/Workflow/index.tsx index ba17a63a..506fd3c4 100644 --- a/web/src/views/Workflow/index.tsx +++ b/web/src/views/Workflow/index.tsx @@ -107,6 +107,7 @@ const Workflow = forwardRef((_props, ref) => { copyEvent={copyEvent} parseEvent={parseEvent} config={config} + chatVariables={chatVariables} />