floating was used as edgetype whilst floating wasn't available, ReactFlow automatically fell back to default. now it is changed to default in the code preventing potential unexpected behavior ref: N25B-114
132 lines
3.5 KiB
TypeScript
132 lines
3.5 KiB
TypeScript
import './VisProgUI.css'
|
|
|
|
import {
|
|
useCallback,
|
|
useRef
|
|
} from 'react';
|
|
import {
|
|
Background,
|
|
Controls,
|
|
ReactFlow,
|
|
ReactFlowProvider,
|
|
useNodesState,
|
|
useEdgesState,
|
|
reconnectEdge,
|
|
addEdge,
|
|
MarkerType,
|
|
type Edge,
|
|
type Connection,
|
|
} from '@xyflow/react';
|
|
import '@xyflow/react/dist/style.css';
|
|
import {
|
|
StartNode,
|
|
EndNode,
|
|
PhaseNode,
|
|
NormNode
|
|
} from "./components/NodeDefinitions.tsx";
|
|
|
|
import { Sidebar } from './components/DragDropSidebar.tsx';
|
|
|
|
const nodeTypes = {
|
|
start: StartNode,
|
|
end: EndNode,
|
|
phase: PhaseNode,
|
|
norm: NormNode
|
|
};
|
|
|
|
const initialNodes = [
|
|
{
|
|
id: 'start',
|
|
type: 'start',
|
|
position: {x: 0, y: 0},
|
|
data: {label: 'start'}
|
|
},
|
|
{
|
|
id: 'genericPhase',
|
|
type: 'phase',
|
|
position: {x: 0, y: 150},
|
|
data: {label: 'Generic Phase', number: 1},
|
|
},
|
|
{
|
|
id: 'end',
|
|
type: 'end',
|
|
position: {x: 0, y: 300},
|
|
data: {label: 'End'}
|
|
}
|
|
];
|
|
const initialEdges = [{id: 'start-end', source: 'start', target: 'end'}];
|
|
|
|
const defaultEdgeOptions = {
|
|
type: 'default',
|
|
markerEnd: {
|
|
type: MarkerType.ArrowClosed,
|
|
color: '#505050',
|
|
},
|
|
};
|
|
|
|
const VisProgUI = ()=> {
|
|
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={{marginInline: 'auto',display: 'flex',justifySelf: 'center', padding:'10px', alignItems: 'center', width: '80vw', height: '60vh'}}>
|
|
<div style={{outlineStyle: 'solid', borderRadius: '10pt', marginInline: '1em',width: '70%', height:'100%' }}>
|
|
<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>
|
|
<div style={{width: '20%', height: '100%'}}>
|
|
<Sidebar />
|
|
</div>
|
|
</div>
|
|
|
|
);
|
|
};
|
|
|
|
function VisualProgrammingUI(){
|
|
return (
|
|
<ReactFlowProvider>
|
|
<VisProgUI />
|
|
</ReactFlowProvider>
|
|
);
|
|
}
|
|
|
|
export default VisualProgrammingUI; |