Files
pepperplus-ui/src/visualProgrammingUI/VisProgUI.tsx
JGerla e098ffebd6 feat: added a custom start node
Defined a basic start node; it does not contain any further functionality but does provide a basis for implementing future custom nodes.

ref: N25B-114
2025-09-30 16:13:48 +02:00

109 lines
2.8 KiB
TypeScript

import './VisProgUI.css'
import {
useCallback,
useRef
} from 'react';
import {
Background,
Controls,
ReactFlow,
useNodesState,
useEdgesState,
reconnectEdge,
addEdge,
MarkerType,
type Edge,
type Connection,
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import StartNode from './components/StartNode.tsx';
const nodeTypes = {
startNode: StartNode,
};
const initialNodes = [
{
id: 'start',
type: 'startNode',
position: {x: 0, y: 0},
data: {label: 'Start'},
},
{
id: 'genericPhase',
type: 'default',
position: {x: 0, y: 150},
data: {label: 'Generic Phase'},
},
{
id: 'end',
type: 'output',
position: {x: 0, y: 300},
data: {label: 'End'}
}
];
const initialEdges = [{id: 'start-end', source: 'start', target: 'end'}];
const defaultEdgeOptions = {
type: 'floating',
markerEnd: {
type: MarkerType.ArrowClosed,
color: '#505050',
},
};
const VisualProgrammingUI = ()=> {
const edgeReconnectSuccessful = useRef(true);
const [nodes, , onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect = useCallback(
(params: Edge | Connection) => setEdges((els) => addEdge(params, els)),
[setEdges],
);
const onReconnectStart = useCallback(() => {
edgeReconnectSuccessful.current = false;
}, []);
const onReconnect = useCallback((oldEdge: Edge, newConnection: Connection) => {
edgeReconnectSuccessful.current = true;
setEdges((els) => reconnectEdge(oldEdge, newConnection, els));
}, [setEdges]);
const onReconnectEnd = useCallback((_: unknown, edge: { id: string; }) => {
if (!edgeReconnectSuccessful.current) {
setEdges((eds) => eds.filter((e) => e.id !== edge.id));
}
edgeReconnectSuccessful.current = true;
}, [setEdges]);
return (
<div style={{outlineStyle: 'solid', borderRadius: '10pt' ,marginInline: 'auto',width: '60vw', height: '60vh' }}>
<ReactFlow
nodes={nodes}
edges={edges}
defaultEdgeOptions={defaultEdgeOptions}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
nodeTypes={nodeTypes}
snapToGrid
onReconnect={onReconnect}
onReconnectStart={onReconnectStart}
onReconnectEnd={onReconnectEnd}
onConnect={onConnect}
fitView
proOptions={{hideAttribution: true }}
>
<Controls />
<Background />
</ReactFlow>
</div>
);
};
export default VisualProgrammingUI