Skip to content

Commit d1ad079

Browse files
committed
Fix inability to delete edges
1 parent a1c4d21 commit d1ad079

File tree

11 files changed

+151
-140
lines changed

11 files changed

+151
-140
lines changed

src/components/shared/ReactFlow/FlowCanvas/IONode/IONode.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ interface IONodeProps {
2828
}
2929

3030
const IONode = ({ type, data, selected = false }: IONodeProps) => {
31-
const { getInputNodeId, getOutputNodeId } = useNodeManager();
31+
const { getNodeId, getHandleNodeId } = useNodeManager();
3232
const { graphSpec, componentSpec } = useComponentSpec();
3333
const { setContent, clearContent } = useContextPanel();
3434

@@ -59,11 +59,13 @@ const IONode = ({ type, data, selected = false }: IONodeProps) => {
5959
[componentSpec.outputs, spec.name],
6060
);
6161

62-
const nodeId = isInput
63-
? getInputNodeId(inputNameToInputId(spec.name))
64-
: getOutputNodeId(outputNameToOutputId(spec.name));
62+
const inputId = inputNameToInputId(spec.name);
63+
const outputId = outputNameToOutputId(spec.name);
64+
const id = isInput ? inputId : outputId;
6565

66-
const nodeHandleId = `${nodeId}_handle`;
66+
const nodeId = getNodeId(id, type);
67+
const handleNodeType = isInput ? "outputHandle" : "inputHandle";
68+
const nodeHandleId = getHandleNodeId(id, "handle", handleNodeType);
6769

6870
const handleHandleClick = useCallback(() => {
6971
if (ENABLE_DEBUG_MODE) {

src/components/shared/ReactFlow/FlowCanvas/TaskNode/TaskNodeCard/Handles.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export const InputHandle = ({
3434
onLabelClick,
3535
onHandleSelectionChange,
3636
}: InputHandleProps) => {
37-
const { getTaskInputNodeId } = useNodeManager();
37+
const { getInputHandleNodeId } = useNodeManager();
3838
const { taskId, nodeId, state, name } = useTaskNode();
3939

4040
const fromHandle = useConnection((connection) => connection.fromHandle?.id);
@@ -47,7 +47,7 @@ export const InputHandle = ({
4747
const [selected, setSelected] = useState(false);
4848
const [active, setActive] = useState(false);
4949

50-
const handleId = getTaskInputNodeId(taskId, input.name);
50+
const handleId = getInputHandleNodeId(taskId, input.name);
5151

5252
const missing = invalid ? "bg-red-700!" : "bg-gray-500!";
5353
const hasValue = value !== undefined && value !== null;
@@ -230,7 +230,7 @@ export const OutputHandle = ({
230230
onLabelClick,
231231
onHandleSelectionChange,
232232
}: OutputHandleProps) => {
233-
const { getTaskOutputNodeId } = useNodeManager();
233+
const { getOutputHandleNodeId } = useNodeManager();
234234
const { taskId, nodeId, state, name } = useTaskNode();
235235

236236
const fromHandle = useConnection((connection) => connection.fromHandle?.id);
@@ -243,7 +243,7 @@ export const OutputHandle = ({
243243
const [selected, setSelected] = useState(false);
244244
const [active, setActive] = useState(false);
245245

246-
const handleId = getTaskOutputNodeId(taskId, output.name);
246+
const handleId = getOutputHandleNodeId(taskId, output.name);
247247
const hasValue = value !== undefined && value !== "" && value !== null;
248248

249249
const handleHandleClick = useCallback(

src/components/shared/ReactFlow/FlowCanvas/TaskNode/TaskNodeCard/TaskNodeInputs.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export function TaskNodeInputs({
2727
expanded,
2828
onBackgroundClick,
2929
}: TaskNodeInputsProps) {
30-
const { getTaskInputNodeId } = useNodeManager();
30+
const { getInputHandleNodeId } = useNodeManager();
3131
const { taskId, inputs, taskSpec, state, select } = useTaskNode();
3232
const { graphSpec } = useComponentSpec();
3333
const {
@@ -146,7 +146,7 @@ export function TaskNodeInputs({
146146
}
147147

148148
const input = inputs.find(
149-
(i) => getTaskInputNodeId(taskId, i.name) === fromHandle?.id,
149+
(i) => getInputHandleNodeId(taskId, i.name) === fromHandle?.id,
150150
);
151151

152152
if (!input) return;

src/components/shared/ReactFlow/FlowCanvas/TaskNode/TaskNodeCard/TaskNodeOutputs.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export function TaskNodeOutputs({
2323
expanded,
2424
onBackgroundClick,
2525
}: TaskNodeOutputsProps) {
26-
const { getTaskOutputNodeId } = useNodeManager();
26+
const { getOutputHandleNodeId } = useNodeManager();
2727
const { taskId, nodeId, outputs, state, select } = useTaskNode();
2828
const {
2929
highlightSearchFilter,
@@ -41,7 +41,7 @@ export function TaskNodeOutputs({
4141
edges.some(
4242
(edge) =>
4343
edge.source === nodeId &&
44-
edge.sourceHandle === getTaskOutputNodeId(taskId, output.name),
44+
edge.sourceHandle === getOutputHandleNodeId(taskId, output.name),
4545
),
4646
);
4747

@@ -139,7 +139,7 @@ export function TaskNodeOutputs({
139139
}
140140

141141
const output = outputs.find(
142-
(o) => getTaskOutputNodeId(taskId, o.name) === fromHandle?.id,
142+
(o) => getOutputHandleNodeId(taskId, o.name) === fromHandle?.id,
143143
);
144144

145145
if (!output) return;

src/components/shared/ReactFlow/FlowCanvas/utils/addAndConnectNode.ts

Lines changed: 55 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Connection, Handle } from "@xyflow/react";
22

3-
import type { NodeManager } from "@/nodeManager";
3+
import type { NodeManager, NodeType } from "@/nodeManager";
44
import {
55
type ComponentReference,
66
type ComponentSpec,
@@ -48,57 +48,44 @@ export function addAndConnectNode({
4848
return componentSpec;
4949
}
5050

51-
const isTaskHandle = nodeManager.isManaged(fromHandle.id);
52-
let fromHandleType: "input" | "output";
53-
let fromHandleName: string | undefined;
54-
let fromTaskId: string | undefined;
51+
const fromNodeId = fromHandle.nodeId;
52+
const fromNodeType = nodeManager.getNodeType(fromNodeId);
53+
const fromTaskId = nodeManager.getRefId(fromNodeId);
5554

56-
if (isTaskHandle) {
57-
// Handle is managed by NodeManager (task handle)
58-
const fromHandleInfo = nodeManager.getHandleInfo(fromHandle.id);
59-
const fromNodeType = nodeManager.getNodeType(fromHandle.id);
55+
if (!fromTaskId) {
56+
return componentSpec;
57+
}
6058

61-
if (!fromHandleInfo || !fromNodeType) {
62-
return componentSpec;
63-
}
59+
let fromHandleType: NodeType | undefined;
60+
let fromHandleName: string | undefined;
6461

65-
fromHandleType = fromNodeType === "taskInput" ? "input" : "output";
66-
fromHandleName = fromHandleInfo.handleName;
67-
fromTaskId = fromHandleInfo.taskId;
62+
if (fromNodeType === "task") {
63+
const fromHandleInfo = nodeManager.getHandleInfo(fromHandle.id);
64+
fromHandleName = fromHandleInfo?.handleName;
65+
fromHandleType = nodeManager.getNodeType(fromHandle.id);
66+
} else if (fromNodeType === "input") {
67+
fromHandleType = "outputHandle";
68+
fromHandleName = inputIdToInputName(fromTaskId);
69+
} else if (fromNodeType === "output") {
70+
fromHandleType = "inputHandle";
71+
fromHandleName = outputIdToOutputName(fromTaskId);
6872
} else {
69-
// Simple IO node handle - get info from the source node, not the handle
70-
const fromNodeId = fromHandle.nodeId;
71-
const fromNodeType = nodeManager.getNodeType(fromNodeId);
72-
73-
if (!fromNodeType) {
74-
return componentSpec;
75-
}
76-
77-
if (fromNodeType === "input") {
78-
fromHandleType = "output";
79-
const inputId = nodeManager.getTaskId(fromNodeId);
80-
if (inputId) {
81-
fromHandleName = inputIdToInputName(inputId);
82-
fromTaskId = inputId;
83-
}
84-
} else if (fromNodeType === "output") {
85-
fromHandleType = "input";
86-
const outputId = nodeManager.getTaskId(fromNodeId);
87-
if (outputId) {
88-
fromHandleName = outputIdToOutputName(outputId);
89-
fromTaskId = outputId;
90-
}
91-
} else {
92-
return componentSpec;
93-
}
73+
return componentSpec;
74+
}
75+
76+
if (!fromHandleName) {
77+
return componentSpec;
9478
}
9579

96-
if (!fromTaskId || !fromHandleName) {
80+
if (
81+
!fromHandleType ||
82+
(fromHandleType !== "inputHandle" && fromHandleType !== "outputHandle")
83+
) {
9784
return componentSpec;
9885
}
9986

10087
const adjustedPosition =
101-
fromHandleType === "input"
88+
fromHandleType === "inputHandle"
10289
? { ...position, x: position.x - DEFAULT_NODE_DIMENSIONS.w }
10390
: position;
10491

@@ -129,7 +116,7 @@ export function addAndConnectNode({
129116
// 3. Determine the connection data type and find the first matching handle on the new node
130117
let fromComponentSpec: ComponentSpec | undefined;
131118

132-
if (isTaskHandle) {
119+
if (fromNodeType === "task") {
133120
// Get spec from task
134121
const fromTaskSpec = graphSpec.tasks[fromTaskId];
135122
fromComponentSpec = fromTaskSpec?.componentRef.spec;
@@ -139,55 +126,48 @@ export function addAndConnectNode({
139126
}
140127

141128
let connectionType: TypeSpecType | undefined;
142-
if (fromHandleType === "input") {
129+
if (fromHandleType === "inputHandle") {
143130
connectionType = fromComponentSpec?.inputs?.find(
144131
(io) => io.name === fromHandleName,
145132
)?.type;
146-
} else if (fromHandleType === "output") {
133+
} else if (fromHandleType === "outputHandle") {
147134
connectionType = fromComponentSpec?.outputs?.find(
148135
(io) => io.name === fromHandleName,
149136
)?.type;
150137
}
151138

152139
// Find the first matching handle on the new node
153-
const toHandleType = fromHandleType === "input" ? "output" : "input";
154-
let targetHandleId: string | undefined;
155-
156-
if (toHandleType === "input") {
157-
const handleName = componentRef.spec?.inputs?.find(
158-
(io) => io.type === connectionType,
159-
)?.name;
160-
if (!handleName) {
161-
return newComponentSpec;
162-
}
163-
164-
targetHandleId = nodeManager.getTaskHandleNodeId(
165-
newTaskId,
166-
handleName,
167-
"taskInput",
168-
);
169-
} else if (toHandleType === "output") {
170-
const handleName = componentRef.spec?.outputs?.find(
171-
(io) => io.type === connectionType,
172-
)?.name;
173-
if (!handleName) {
174-
return newComponentSpec;
175-
}
176-
177-
targetHandleId = nodeManager.getTaskHandleNodeId(
178-
newTaskId,
179-
handleName,
180-
"taskOutput",
181-
);
140+
const toHandleType =
141+
fromHandleType === "inputHandle" ? "outputHandle" : "inputHandle";
142+
143+
const inputHandleName = componentRef.spec?.inputs?.find(
144+
(io) => io.type === connectionType,
145+
)?.name;
146+
147+
const outputHandleName = componentRef.spec?.outputs?.find(
148+
(io) => io.type === connectionType,
149+
)?.name;
150+
151+
const toHandleName =
152+
toHandleType === "inputHandle" ? inputHandleName : outputHandleName;
153+
154+
if (!toHandleName) {
155+
return newComponentSpec;
182156
}
183157

158+
const targetHandleId = nodeManager.getHandleNodeId(
159+
newTaskId,
160+
toHandleName,
161+
toHandleType,
162+
);
163+
184164
// 4. Build a Connection object and use handleConnection to add the edge
185165
if (targetHandleId) {
186166
const fromNodeId = fromHandle.nodeId;
187167
const fromHandleId = fromHandle.id;
188168

189169
const isReversedConnection =
190-
fromHandleType === "input" && toHandleType === "output";
170+
fromHandleType === "inputHandle" && toHandleType === "outputHandle";
191171

192172
const connection: Connection = isReversedConnection
193173
? // Drawing from an input handle to a new output handle

src/components/shared/ReactFlow/FlowCanvas/utils/duplicateNodes.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export const duplicateNodes = (
7272
const oldNodeId = node.id;
7373

7474
if (node.type === "task") {
75-
const oldTaskId = nodeManager.getTaskId(oldNodeId);
75+
const oldTaskId = nodeManager.getRefId(oldNodeId);
7676
if (!oldTaskId) {
7777
console.warn("Could not find taskId for node:", node);
7878
return;
@@ -215,7 +215,7 @@ export const duplicateNodes = (
215215
return;
216216
}
217217

218-
const oldOutputId = nodeManager.getTaskId(oldNodeId);
218+
const oldOutputId = nodeManager.getRefId(oldNodeId);
219219

220220
if (!graphSpec.outputValues || !oldOutputId) {
221221
return;
@@ -240,7 +240,7 @@ export const duplicateNodes = (
240240
const oldTaskId = updatedOutputValue.taskOutput.taskId;
241241
const oldTaskNodeId = nodeManager.getNodeId(oldTaskId, "task");
242242
if (oldTaskNodeId in nodeIdMap) {
243-
const newTaskId = nodeManager.getTaskId(nodeIdMap[oldTaskNodeId]);
243+
const newTaskId = nodeManager.getRefId(nodeIdMap[oldTaskNodeId]);
244244
if (!newTaskId) {
245245
return;
246246
}
@@ -295,7 +295,7 @@ export const duplicateNodes = (
295295
return null;
296296
}
297297

298-
const newId = nodeManager.getTaskId(newNodeId);
298+
const newId = nodeManager.getRefId(newNodeId);
299299

300300
if (!newId) {
301301
return null;
@@ -412,7 +412,7 @@ export const duplicateNodes = (
412412
y: node.position.y + offset.y,
413413
};
414414

415-
const newId = nodeManager.getTaskId(node.id);
415+
const newId = nodeManager.getRefId(node.id);
416416

417417
if (!newId) {
418418
return null;
@@ -537,7 +537,7 @@ function reconfigureConnections(
537537
return reconfigureExternalConnection(taskSpec, argKey, mode);
538538
}
539539

540-
const newTaskId = nodeManager.getTaskId(newNodeId);
540+
const newTaskId = nodeManager.getRefId(newNodeId);
541541

542542
newArgId = newTaskId;
543543
} else if ("graphInput" in argument) {
@@ -557,7 +557,7 @@ function reconfigureConnections(
557557
return reconfigureExternalConnection(taskSpec, argKey, mode);
558558
}
559559

560-
const newInputId = nodeManager.getTaskId(newNodeId);
560+
const newInputId = nodeManager.getRefId(newNodeId);
561561

562562
newArgId = newInputId;
563563
}

src/components/shared/ReactFlow/FlowCanvas/utils/handleConnection.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Connection } from "@xyflow/react";
22

3-
import type { NodeManager, NodeType } from "@/nodeManager";
3+
import type { HandleInfo, NodeManager, NodeType } from "@/nodeManager";
44
import type {
55
GraphInputArgument,
66
GraphSpec,
@@ -17,21 +17,18 @@ import { setTaskArgument } from "./setTaskArgument";
1717
type NodeInfo = {
1818
id: string;
1919
type?: NodeType;
20-
handle?: {
21-
taskId: string;
22-
handleName: string;
23-
};
20+
handle?: HandleInfo;
2421
};
2522

2623
export const handleConnection = (
2724
graphSpec: GraphSpec,
2825
connection: Connection,
2926
nodeManager: NodeManager,
3027
) => {
31-
const sourceId = nodeManager.getTaskId(connection.source!);
28+
const sourceId = nodeManager.getRefId(connection.source!);
3229
const sourceType = nodeManager.getNodeType(connection.source!);
3330

34-
const targetId = nodeManager.getTaskId(connection.target!);
31+
const targetId = nodeManager.getRefId(connection.target!);
3532
const targetType = nodeManager.getNodeType(connection.target!);
3633

3734
if (!sourceId || !targetId || !sourceType || !targetType) {
@@ -49,8 +46,8 @@ export const handleConnection = (
4946
return graphSpec;
5047
}
5148

52-
let sourceHandleInfo: { taskId: string; handleName: string } | undefined;
53-
let targetHandleInfo: { taskId: string; handleName: string } | undefined;
49+
let sourceHandleInfo: HandleInfo | undefined;
50+
let targetHandleInfo: HandleInfo | undefined;
5451

5552
if (connection.sourceHandle) {
5653
sourceHandleInfo = nodeManager.getHandleInfo(connection.sourceHandle);

0 commit comments

Comments
 (0)