From 313e92dd9bd8f25b3c9cd0f657990181e312d89f Mon Sep 17 00:00:00 2001 From: balibabu Date: Sat, 11 Oct 2025 15:24:27 +0800 Subject: [PATCH] Fix: Fixed the issue where the connection lines of placeholder nodes in the agent canvas could not be displayed #9869 (#10485) ### What problem does this PR solve? Fix: Fixed the issue where the connection lines of placeholder nodes in the agent canvas could not be displayed #9869 ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue) --- web/src/locales/zh.ts | 4 ++-- web/src/pages/agent/canvas/edge/index.tsx | 20 ++++++++++------- .../pages/agent/hooks/use-connection-drag.ts | 22 ++++--------------- .../agent/hooks/use-placeholder-manager.ts | 18 ++------------- web/src/pages/agent/store.ts | 6 ----- 5 files changed, 20 insertions(+), 50 deletions(-) diff --git a/web/src/locales/zh.ts b/web/src/locales/zh.ts index 3c15e2df7..e9e0db3ce 100644 --- a/web/src/locales/zh.ts +++ b/web/src/locales/zh.ts @@ -1619,12 +1619,12 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于 tokenizerRequired: '请先添加Tokenizer节点', tokenizerDescription: '根据所选的搜索方法,将文本转换为所需的数据结构(例如,用于嵌入搜索的向量嵌入)。', - splitter: '分词器拆分器', + splitter: '按字符分割', splitterDescription: '根据分词器长度将文本拆分成块,并带有可选的分隔符和重叠。', hierarchicalMergerDescription: '使用正则表达式规则按标题层次结构将文档拆分成多个部分,以实现更精细的控制。', - hierarchicalMerger: '标题拆分器', + hierarchicalMerger: '按标题分割', extractor: '提取器', extractorDescription: '使用 LLM 从文档块(例如摘要、分类等)中提取结构化见解。', diff --git a/web/src/pages/agent/canvas/edge/index.tsx b/web/src/pages/agent/canvas/edge/index.tsx index 725409aed..3c39fbdac 100644 --- a/web/src/pages/agent/canvas/edge/index.tsx +++ b/web/src/pages/agent/canvas/edge/index.tsx @@ -29,9 +29,8 @@ function InnerButtonEdge({ data, sourceHandleId, }: EdgeProps>) { - const deleteEdgeById = useGraphStore((state) => state.deleteEdgeById); - const highlightedPlaceholderEdgeId = useGraphStore( - (state) => state.highlightedPlaceholderEdgeId, + const { deleteEdgeById, getOperatorTypeFromId } = useGraphStore( + (state) => state, ); const [edgePath, labelX, labelY] = getBezierPath({ @@ -48,12 +47,16 @@ function InnerButtonEdge({ : {}; }, [selected]); + const isTargetPlaceholder = useMemo(() => { + return getOperatorTypeFromId(target) === Operator.Placeholder; + }, [getOperatorTypeFromId, target]); + const placeholderHighlightStyle = useMemo(() => { - const isHighlighted = highlightedPlaceholderEdgeId === id; + const isHighlighted = isTargetPlaceholder; return isHighlighted - ? { strokeWidth: 2, stroke: 'var(--accent-primary)' } + ? { strokeWidth: 2, stroke: 'rgb(var(--accent-primary))' } : {}; - }, [highlightedPlaceholderEdgeId, id]); + }, [isTargetPlaceholder]); const onEdgeClick = () => { deleteEdgeById(id); @@ -83,9 +86,10 @@ function InnerButtonEdge({ data?.isHovered && sourceHandleId !== NodeHandleId.Tool && sourceHandleId !== NodeHandleId.AgentBottom && // The connection between the agent node and the tool node does not need to display the delete button - !target.startsWith(Operator.Tool) + !target.startsWith(Operator.Tool) && + !isTargetPlaceholder ); - }, [data?.isHovered, sourceHandleId, target]); + }, [data?.isHovered, isTargetPlaceholder, sourceHandleId, target]); return ( <> diff --git a/web/src/pages/agent/hooks/use-connection-drag.ts b/web/src/pages/agent/hooks/use-connection-drag.ts index 48ec99986..1c8832f9b 100644 --- a/web/src/pages/agent/hooks/use-connection-drag.ts +++ b/web/src/pages/agent/hooks/use-connection-drag.ts @@ -1,8 +1,7 @@ -import { Connection, Position } from '@xyflow/react'; +import { Connection, OnConnectEnd, Position } from '@xyflow/react'; import { useCallback, useRef } from 'react'; import { useDropdownManager } from '../canvas/context'; import { Operator, PREVENT_CLOSE_DELAY } from '../constant'; -import useGraphStore from '../store'; import { useAddNode } from './use-add-node'; interface ConnectionStartParams { @@ -40,7 +39,6 @@ export const useConnectionDrag = ( const { addCanvasNode } = useAddNode(reactFlowInstance); const { setActiveDropdown } = useDropdownManager(); - const { setHighlightedPlaceholderEdgeId } = useGraphStore(); /** * Connection start handler function @@ -66,8 +64,8 @@ export const useConnectionDrag = ( /** * Connection end handler function */ - const onConnectEnd = useCallback( - (event: MouseEvent | TouchEvent) => { + const onConnectEnd: OnConnectEnd = useCallback( + (event) => { if ('clientX' in event && 'clientY' in event) { const { clientX, clientY } = event; setDropdownPosition({ x: clientX, y: clientY }); @@ -113,11 +111,6 @@ export const useConnectionDrag = ( if (newNodeId) { setCreatedPlaceholderRef(newNodeId); - - if (connectionStartRef.current) { - const edgeId = `xy-edge__${connectionStartRef.current.nodeId}${connectionStartRef.current.handleId}-${newNodeId}end`; - setHighlightedPlaceholderEdgeId(edgeId); - } } // Calculate placeholder node position and display dropdown menu @@ -154,7 +147,6 @@ export const useConnectionDrag = ( calculateDropdownPosition, setActiveDropdown, showModal, - setHighlightedPlaceholderEdgeId, checkAndRemoveExistingPlaceholder, removePlaceholderNode, hideModal, @@ -206,13 +198,7 @@ export const useConnectionDrag = ( removePlaceholderNode(); hideModal(); clearActiveDropdown(); - setHighlightedPlaceholderEdgeId(null); - }, [ - removePlaceholderNode, - hideModal, - clearActiveDropdown, - setHighlightedPlaceholderEdgeId, - ]); + }, [removePlaceholderNode, hideModal, clearActiveDropdown]); return { onConnectStart, diff --git a/web/src/pages/agent/hooks/use-placeholder-manager.ts b/web/src/pages/agent/hooks/use-placeholder-manager.ts index 9738cfb4a..e970908db 100644 --- a/web/src/pages/agent/hooks/use-placeholder-manager.ts +++ b/web/src/pages/agent/hooks/use-placeholder-manager.ts @@ -42,9 +42,6 @@ export const usePlaceholderManager = (reactFlowInstance: any) => { }); } - // Clear highlighted placeholder edge - useGraphStore.getState().setHighlightedPlaceholderEdgeId(null); - // Update ref reference if (createdPlaceholderRef.current === existingPlaceholder.id) { createdPlaceholderRef.current = null; @@ -62,8 +59,7 @@ export const usePlaceholderManager = (reactFlowInstance: any) => { reactFlowInstance && !userSelectedNodeRef.current ) { - const { nodes, edges, setHighlightedPlaceholderEdgeId } = - useGraphStore.getState(); + const { nodes, edges } = useGraphStore.getState(); // Remove edges related to placeholder const edgesToRemove = edges.filter( @@ -84,8 +80,6 @@ export const usePlaceholderManager = (reactFlowInstance: any) => { }); } - setHighlightedPlaceholderEdgeId(null); - createdPlaceholderRef.current = null; } @@ -101,13 +95,7 @@ export const usePlaceholderManager = (reactFlowInstance: any) => { (newNodeId: string) => { // First establish connection between new node and source, then delete placeholder if (createdPlaceholderRef.current && reactFlowInstance) { - const { - nodes, - edges, - addEdge, - updateNode, - setHighlightedPlaceholderEdgeId, - } = useGraphStore.getState(); + const { nodes, edges, addEdge, updateNode } = useGraphStore.getState(); // Find placeholder node to get its position const placeholderNode = nodes.find( @@ -157,8 +145,6 @@ export const usePlaceholderManager = (reactFlowInstance: any) => { edges: edgesToRemove, }); } - - setHighlightedPlaceholderEdgeId(null); } // Mark that user has selected a node diff --git a/web/src/pages/agent/store.ts b/web/src/pages/agent/store.ts index 16f341b96..69b118a98 100644 --- a/web/src/pages/agent/store.ts +++ b/web/src/pages/agent/store.ts @@ -39,7 +39,6 @@ export type RFState = { selectedEdgeIds: string[]; clickedNodeId: string; // currently selected node clickedToolId: string; // currently selected tool id - highlightedPlaceholderEdgeId: string | null; onNodesChange: OnNodesChange; onEdgesChange: OnEdgesChange; onEdgeMouseEnter?: EdgeMouseHandler; @@ -90,7 +89,6 @@ export type RFState = { ) => void; // Deleting a condition of a classification operator will delete the related edge findAgentToolNodeById: (id: string | null) => string | undefined; selectNodeIds: (nodeIds: string[]) => void; - setHighlightedPlaceholderEdgeId: (edgeId: string | null) => void; }; // this is our useStore hook that we can use in our components to get parts of the store and call actions @@ -103,7 +101,6 @@ const useGraphStore = create()( selectedEdgeIds: [] as string[], clickedNodeId: '', clickedToolId: '', - highlightedPlaceholderEdgeId: null, onNodesChange: (changes) => { set({ nodes: applyNodeChanges(changes, get().nodes), @@ -530,9 +527,6 @@ const useGraphStore = create()( })), ); }, - setHighlightedPlaceholderEdgeId: (edgeId) => { - set({ highlightedPlaceholderEdgeId: edgeId }); - }, })), { name: 'graph', trace: true }, ),