feat: added ReactFlow-based node graph #11
@@ -1,40 +1,40 @@
|
|||||||
import { create } from 'zustand';
|
import {create} from 'zustand';
|
||||||
import {
|
import {
|
||||||
applyNodeChanges,
|
applyNodeChanges,
|
||||||
applyEdgeChanges,
|
applyEdgeChanges,
|
||||||
addEdge,
|
addEdge,
|
||||||
reconnectEdge, type Edge, type Connection
|
reconnectEdge, type Edge, type Connection
|
||||||
} from '@xyflow/react';
|
} from '@xyflow/react';
|
||||||
|
|
||||||
import { type FlowState } from './VisProgTypes.tsx';
|
import {type FlowState} from './VisProgTypes.tsx';
|
||||||
|
|
||||||
const initialNodes = [
|
const initialNodes = [
|
||||||
{
|
{
|
||||||
id: 'start',
|
id: 'start',
|
||||||
type: 'start',
|
type: 'start',
|
||||||
position: {x: 0, y: 0},
|
position: {x: 0, y: 0},
|
||||||
data: {label: 'start'}
|
data: {label: 'start'}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'genericPhase',
|
id: 'genericPhase',
|
||||||
type: 'phase',
|
type: 'phase',
|
||||||
position: {x: 0, y: 150},
|
position: {x: 0, y: 150},
|
||||||
data: {label: 'Generic Phase', number: 1},
|
data: {label: 'Generic Phase', number: 1},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'end',
|
id: 'end',
|
||||||
type: 'end',
|
type: 'end',
|
||||||
position: {x: 0, y: 300},
|
position: {x: 0, y: 300},
|
||||||
data: {label: 'End'}
|
data: {label: 'End'}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const initialEdges = [
|
const initialEdges = [
|
||||||
{
|
{
|
||||||
id: 'start-end',
|
id: 'start-end',
|
||||||
source: 'start',
|
source: 'start',
|
||||||
target: 'end'
|
target: 'end'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
// this is our useStore hook that we can use in our components to get parts of the store and call actions
|
// this is our useStore hook that we can use in our components to get parts of the store and call actions
|
||||||
@@ -43,52 +43,52 @@ const useFlowStore = create<FlowState>((set, get) => ({
|
|||||||
edges: initialEdges,
|
edges: initialEdges,
|
||||||
edgeReconnectSuccessful: true,
|
edgeReconnectSuccessful: true,
|
||||||
onNodesChange: (changes) => {
|
onNodesChange: (changes) => {
|
||||||
set({
|
set({
|
||||||
nodes: applyNodeChanges(changes, get().nodes)
|
nodes: applyNodeChanges(changes, get().nodes)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onEdgesChange: (changes) => {
|
onEdgesChange: (changes) => {
|
||||||
set({
|
set({
|
||||||
edges: applyEdgeChanges(changes, get().edges)
|
edges: applyEdgeChanges(changes, get().edges)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
// handles connection of newly created edges
|
// handles connection of newly created edges
|
||||||
onConnect: (connection) => {
|
onConnect: (connection) => {
|
||||||
set({
|
set({
|
||||||
edges: addEdge(connection, get().edges)
|
edges: addEdge(connection, get().edges)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
// handles attempted reconnections of a previously disconnected edge
|
// handles attempted reconnections of a previously disconnected edge
|
||||||
onReconnect: (oldEdge: Edge, newConnection: Connection) => {
|
onReconnect: (oldEdge: Edge, newConnection: Connection) => {
|
||||||
get().edgeReconnectSuccessful = true;
|
get().edgeReconnectSuccessful = true;
|
||||||
set({
|
set({
|
||||||
edges: reconnectEdge(oldEdge, newConnection, get().edges)
|
edges: reconnectEdge(oldEdge, newConnection, get().edges)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
// Handles initiation of reconnection of edges that are manually disconnected from a node
|
// Handles initiation of reconnection of edges that are manually disconnected from a node
|
||||||
onReconnectStart: () => {
|
onReconnectStart: () => {
|
||||||
set({
|
set({
|
||||||
edgeReconnectSuccessful: false
|
edgeReconnectSuccessful: false
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
// Drops the edge from the set of edges, removing it from the flow, if no successful reconnection occurred
|
// Drops the edge from the set of edges, removing it from the flow, if no successful reconnection occurred
|
||||||
onReconnectEnd: (_: unknown, edge: { id: string; }) => {
|
onReconnectEnd: (_: unknown, edge: { id: string; }) => {
|
||||||
if (!get().edgeReconnectSuccessful) {
|
if (!get().edgeReconnectSuccessful) {
|
||||||
set({
|
|
||||||
edges: get().edges.filter((e) => e.id !== edge.id),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
set({
|
set({
|
||||||
edgeReconnectSuccessful: true
|
edges: get().edges.filter((e) => e.id !== edge.id),
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
set({
|
||||||
|
edgeReconnectSuccessful: true
|
||||||
|
});
|
||||||
},
|
},
|
||||||
setNodes: (nodes) => {
|
setNodes: (nodes) => {
|
||||||
set({ nodes });
|
set({nodes});
|
||||||
},
|
},
|
||||||
setEdges: (edges) => {
|
setEdges: (edges) => {
|
||||||
set({ edges });
|
set({edges});
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
export default useFlowStore;
|
export default useFlowStore;
|
||||||
Reference in New Issue
Block a user