refactor: Initial working framework of node encapsulation works- polymorphic implementation of nodes in creating and connecting calls correct functions

ref: N25B-294
This commit is contained in:
Björn Otgaar
2025-11-17 14:25:01 +01:00
parent b7eb0cb5ec
commit c5dc825ca3
13 changed files with 605 additions and 662 deletions

View File

@@ -0,0 +1,93 @@
import {
Handle,
type NodeProps,
Position,
type Connection,
type Edge,
useReactFlow,
type Node,
} from '@xyflow/react';
import { Toolbar } from './NodeDefinitions';
import styles from '../../VisProg.module.css';
/* ---------------------------------------------------------
* 1. THE DATA SHAPE FOR THIS NODE TYPE
* -------------------------------------------------------*/
export type StartNodeData = {
label: string;
droppable: boolean;
hasReduce: boolean;
};
/* ---------------------------------------------------------
* 2. DEFAULT DATA FOR NEW INSTANCES OF THIS NODE
* -------------------------------------------------------*/
export const StartNodeDefaults: StartNodeData = {
label: "Start Node",
droppable: false,
hasReduce: true,
};
export type StartNode = Node<StartNodeData>
/* ---------------------------------------------------------
* 3. CUSTOM CONNECTION LOGIC FOR THIS NODE
* -------------------------------------------------------*/
export function startNodeCanConnect(connection: Connection | Edge): boolean {
// connection has: { source, sourceHandle, target, targetHandle }
// Example rules:
// ❌ Cannot connect to itself
if (connection.source === connection.target) return false;
// ❌ Only allow incoming connections on input slots "a" or "b"
if (connection.targetHandle && !["a", "b"].includes(connection.targetHandle)) {
return false;
}
// ❌ Only allow outgoing connections from "result"
if (connection.sourceHandle && connection.sourceHandle !== "result") {
return false;
}
// If all rules pass
return true;
}
/* ---------------------------------------------------------
* 4. OPTIONAL: Node execution logic
* If your system evaluates nodes, this is where that lives.
* -------------------------------------------------------*/
/* ---------------------------------------------------------
* 5. THE NODE COMPONENT (UI)
* -------------------------------------------------------*/
export default function StartNode(props: NodeProps<Node>) {
const reactFlow = useReactFlow();
const label_input_id = `phase_${props.id}_label_input`;
return (
<>
<Toolbar nodeId={props.id} allowDelete={true}/>
<div className={`${styles.defaultNode} ${styles.nodeStart}`}>
<div className={"flex-row gap-sm"}>
Start
</div>
<Handle type="target" position={Position.Left} id="target"/>
<Handle type="target" position={Position.Bottom} id="norms"/>
<Handle type="source" position={Position.Right} id="source"/>
</div>
</>
);
}
export function StartReduce(node: Node, nodes: Node[]) {
return {
id: node.id
}
}
export function StartConnects(thisNode: Node, otherNode: Node, isThisSource: boolean) {
}