Skip to content

Commit

Permalink
fix(Flow): set node handle id to correctly validate connections
Browse files Browse the repository at this point in the history
  • Loading branch information
MEsteves22 authored and plagoa committed Jan 16, 2024
1 parent a136a3a commit fdcf253
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 44 deletions.
11 changes: 7 additions & 4 deletions packages/lab/src/Flow/DroppableFlow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,13 @@ const validateEdge = (
const inputs = nodeMetaRegistry[edge.target]?.inputs || [];
const outputs = nodeMetaRegistry[edge.source]?.outputs || [];

const sourceProvides = outputs[edge.sourceHandle]?.provides || "";
const targetAccepts = inputs[edge.targetHandle]?.accepts || [];
const sourceMaxConnections = outputs[edge.sourceHandle]?.maxConnections;
const targetMaxConnections = inputs[edge.targetHandle]?.maxConnections;
const source = outputs.find((out) => out.id === edge.sourceHandle);
const target = inputs.find((inp) => inp.id === edge.targetHandle);

const sourceProvides = source?.provides || "";
const targetAccepts = target?.accepts || [];
const sourceMaxConnections = source?.maxConnections;
const targetMaxConnections = target?.maxConnections;

let isValid =
targetAccepts.length === 0 || targetAccepts.includes(sourceProvides);
Expand Down
101 changes: 61 additions & 40 deletions packages/lab/src/Flow/Node/BaseNode.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import React, { isValidElement, useCallback, useEffect, useState } from "react";
import React, {
isValidElement,
useCallback,
useEffect,
useMemo,
useState,
} from "react";
import {
Edge,
Handle,
Expand Down Expand Up @@ -89,17 +95,38 @@ export const HvFlowBaseNode = ({
headerItems,
icon,
color: colorProp,
inputs,
outputs,
inputs: inputsProp,
outputs: outputsProp,
nodeActions = defaultActions,
footer,
classes: classesProp,
className,
children,
}: HvFlowBaseNodeProps<unknown>) => {
const { registerNode, unregisterNode } = useNodeMetaRegistry();

const inputs = useMemo(
() =>
inputsProp?.map((input, idx) =>
input.id != null ? input : { ...input, id: String(idx) }
),
[inputsProp]
);

const outputs = useMemo(
() =>
outputsProp?.map((output, idx) =>
output.id != null ? output : { ...output, id: String(idx) }
),
[outputsProp]
);

useEffect(() => {
registerNode(id, { label: title || "", inputs, outputs });
registerNode(id, {
label: title || "",
inputs,
outputs,
});
return () => unregisterNode(id);
}, [id, title, inputs, outputs, registerNode, unregisterNode]);

Expand Down Expand Up @@ -204,24 +231,21 @@ export const HvFlowBaseNode = ({
</div>

<div className={classes.inputsContainer}>
{inputs?.map((input, idx) => {
const handleId = input.id ?? idx.toString();
return (
<div className={classes.inputContainer} key={idx}>
<Handle
type="target"
isConnectableStart={false}
id={handleId}
position={Position.Left}
/>
<HvTypography>{input.label}</HvTypography>
{input.isMandatory &&
!isInputConnected(id, "target", handleId, inputEdges) && (
<div className={classes.mandatory} />
)}
</div>
);
})}
{inputs?.map((input) => (
<div className={classes.inputContainer} key={input.id}>
<Handle
type="target"
isConnectableStart={false}
id={input.id}
position={Position.Left}
/>
<HvTypography>{input.label}</HvTypography>
{input.isMandatory &&
!isInputConnected(id, "target", input.id!, inputEdges) && (
<div className={classes.mandatory} />
)}
</div>
))}
</div>
</>
)}
Expand All @@ -231,24 +255,21 @@ export const HvFlowBaseNode = ({
<HvTypography>Outputs</HvTypography>
</div>
<div className={classes.outputsContainer}>
{outputs?.map((output, idx) => {
const handleId = output.id ?? idx.toString();
return (
<div className={classes.outputContainer} key={idx}>
<Handle
type="source"
isConnectableEnd={false}
id={handleId}
position={Position.Right}
/>
{output.isMandatory &&
!isInputConnected(id, "source", handleId, outputEdges) && (
<div className={classes.mandatory} />
)}
<HvTypography>{output.label}</HvTypography>
</div>
);
})}
{outputs?.map((output) => (
<div className={classes.outputContainer} key={output.id}>
<Handle
type="source"
isConnectableEnd={false}
id={output.id}
position={Position.Right}
/>
{output.isMandatory &&
!isInputConnected(id, "source", output.id!, outputEdges) && (
<div className={classes.mandatory} />
)}
<HvTypography>{output.label}</HvTypography>
</div>
))}
</div>
</>
)}
Expand Down

0 comments on commit fdcf253

Please sign in to comment.