diff --git a/web/app/dashboard/ai-workflows/_components/workflow-editor.tsx b/web/app/dashboard/ai-workflows/_components/workflow-editor.tsx index 6d44423..8830265 100644 --- a/web/app/dashboard/ai-workflows/_components/workflow-editor.tsx +++ b/web/app/dashboard/ai-workflows/_components/workflow-editor.tsx @@ -81,6 +81,10 @@ type WorkflowNodeData = Record & { type WorkflowFlowNode = Node type WorkflowFlowEdge = Edge type WorkflowEdgeCondition = NonNullable["condition"] +type WorkflowEdgeRenderData = WorkflowEditorEdge["data"] & { + active?: boolean + onSelect?: (edgeId: string) => void +} type PendingNodeDrag = { spec: AIWorkflowNodeSpec @@ -448,6 +452,28 @@ export function WorkflowEditor({ ) } + const selectEdge = useCallback((edgeId: string) => { + setSelectedNodeId(null) + setSelectedEdgeId(edgeId) + }, []) + + const renderedEdges = useMemo( + () => + edges.map((edge) => { + const active = edge.id === selectedEdgeId + return { + ...edge, + selected: active, + data: { + ...((edge.data ?? {}) as WorkflowEditorEdge["data"]), + active, + onSelect: selectEdge, + } satisfies WorkflowEdgeRenderData, + } + }), + [edges, selectedEdgeId, selectEdge] + ) + const updateEdgeCondition = (edgeId: string, condition?: WorkflowEdgeCondition) => { setEdges((current) => current.map((edge) => @@ -597,7 +623,7 @@ export function WorkflowEditor({ ) : null} { event.stopPropagation() - setSelectedNodeId(null) - setSelectedEdgeId(edge.id) + selectEdge(edge.id) }} onPaneClick={() => { setSelectedNodeId(null) @@ -959,6 +984,8 @@ function WorkflowCanvasEdge({ curvature: 0.18, }) const condition = (data as WorkflowEditorEdge["data"] | undefined)?.condition + const edgeData = data as WorkflowEdgeRenderData | undefined + const active = selected || edgeData?.active return ( <> @@ -967,17 +994,37 @@ function WorkflowCanvasEdge({ path={edgePath} markerEnd={markerEnd} className={cn( - "!stroke-[1.8px] transition-colors", - selected ? "!stroke-primary" : "!stroke-muted-foreground/45" + "transition-all", + active ? "!stroke-primary !stroke-[2.4px]" : "!stroke-muted-foreground/45 !stroke-[1.8px]" )} /> {condition ? (
{ + event.stopPropagation() + edgeData?.onSelect?.(id) + }} + onKeyDown={(event) => { + if (event.key !== "Enter" && event.key !== " ") { + return + } + event.preventDefault() + event.stopPropagation() + edgeData?.onSelect?.(id) + }} > 条件