Skip to content

Commit e4855f3

Browse files
committed
feat(workflow): creates connection on edge dragged over node
1 parent 75f475e commit e4855f3

File tree

1 file changed

+45
-2
lines changed

1 file changed

+45
-2
lines changed

components/workflow/workflow-canvas.tsx

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ export function WorkflowCanvas() {
101101
useReactFlow();
102102

103103
const connectingNodeId = useRef<string | null>(null);
104+
const connectingHandleType = useRef<"source" | "target" | null>(null);
104105
const justCreatedNodeFromConnection = useRef(false);
105106
const viewportInitialized = useRef(false);
106107
const [isCanvasReady, setIsCanvasReady] = useState(false);
@@ -227,6 +228,18 @@ export function WorkflowCanvas() {
227228
[]
228229
);
229230

231+
const nodeHasHandle = useCallback(
232+
(nodeId: string, handleType: "source" | "target") => {
233+
const node = nodes.find((node) => node.id === nodeId);
234+
235+
if (!node) return false;
236+
if (handleType === "target") return node.type !== "trigger";
237+
238+
return node.type !== "add";
239+
},
240+
[nodes]
241+
);
242+
230243
const isValidConnection = useCallback(
231244
(connection: XYFlowConnection | XYFlowEdge) => {
232245
// Ensure we have both source and target
@@ -272,6 +285,7 @@ export function WorkflowCanvas() {
272285
const onConnectStart = useCallback(
273286
(_event: MouseEvent | TouchEvent, params: OnConnectStartParams) => {
274287
connectingNodeId.current = params.nodeId;
288+
connectingHandleType.current = params.handleType;
275289
},
276290
[]
277291
);
@@ -327,10 +341,36 @@ export function WorkflowCanvas() {
327341
return;
328342
}
329343

330-
const isNode = target.closest(".react-flow__node");
344+
const nodeElement = target.closest(".react-flow__node");
331345
const isHandle = target.closest(".react-flow__handle");
332346

333-
if (!(isNode || isHandle)) {
347+
// Create connection on edge dragged over node release
348+
if (nodeElement && !isHandle && connectingHandleType.current) {
349+
const targetNodeId = nodeElement.getAttribute("data-id");
350+
const fromSource = connectingHandleType.current === "source";
351+
const requiredHandle = fromSource ? "target" : "source";
352+
const sourceId = fromSource ? connectingNodeId.current! : targetNodeId!;
353+
const targetId = fromSource ? targetNodeId! : connectingNodeId.current!;
354+
355+
if (
356+
targetNodeId &&
357+
targetNodeId !== connectingNodeId.current &&
358+
nodeHasHandle(targetNodeId, requiredHandle)
359+
) {
360+
onConnect({
361+
source: sourceId,
362+
target: targetId,
363+
sourceHandle: null,
364+
targetHandle: null,
365+
});
366+
}
367+
368+
connectingNodeId.current = null;
369+
connectingHandleType.current = null;
370+
return;
371+
}
372+
373+
if (!nodeElement && !isHandle) {
334374
const { adjustedX, adjustedY } = calculateMenuPosition(
335375
event,
336376
clientX,
@@ -404,12 +444,15 @@ export function WorkflowCanvas() {
404444
}
405445

406446
connectingNodeId.current = null;
447+
connectingHandleType.current = null;
407448
},
408449
[
409450
getClientPosition,
410451
calculateMenuPosition,
411452
screenToFlowPosition,
412453
addNode,
454+
nodeHasHandle,
455+
onConnect,
413456
edges,
414457
setEdges,
415458
setNodes,

0 commit comments

Comments
 (0)