mirror of
https://github.com/Nikhil-Doye/workflow-builder.git
synced 2026-07-22 02:01:56 +02:00
Refactor WorkflowEditor to streamline node and edge management
- Removed local state management for nodes and edges, syncing directly with the workflow store for improved consistency. - Introduced new updateNodePosition and updateNodeData methods in the workflow store to handle node position and data updates. - Simplified edge and node change handling by utilizing callbacks for direct store updates, enhancing performance and maintainability. - Cleaned up unused code related to local state management, improving overall code clarity.
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import React, { useCallback, useRef, useState, useEffect } from "react";
|
||||
import React, { useCallback, useRef, useState } from "react";
|
||||
import ReactFlow, {
|
||||
Node,
|
||||
Edge,
|
||||
Connection,
|
||||
useNodesState,
|
||||
useEdgesState,
|
||||
NodeChange,
|
||||
EdgeChange,
|
||||
Controls,
|
||||
Background,
|
||||
BackgroundVariant,
|
||||
@@ -66,18 +66,10 @@ export const WorkflowEditor: React.FC<WorkflowEditorProps> = ({ onClose }) => {
|
||||
selectedNodeId,
|
||||
panelStates,
|
||||
togglePanel,
|
||||
updateNodePosition,
|
||||
} = useWorkflowStore();
|
||||
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState([]);
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
|
||||
|
||||
// Sync local state with store when currentWorkflow changes
|
||||
useEffect(() => {
|
||||
if (currentWorkflow) {
|
||||
setNodes(currentWorkflow.nodes);
|
||||
setEdges(currentWorkflow.edges);
|
||||
}
|
||||
}, [currentWorkflow, setNodes, setEdges]);
|
||||
const nodes = currentWorkflow?.nodes || [];
|
||||
const edges = currentWorkflow?.edges || [];
|
||||
const [showConfig, setShowConfig] = useState(false);
|
||||
const [showCopilot, setShowCopilot] = useState(false);
|
||||
const reactFlowWrapper = useRef<HTMLDivElement>(null);
|
||||
@@ -87,27 +79,53 @@ export const WorkflowEditor: React.FC<WorkflowEditorProps> = ({ onClose }) => {
|
||||
const onConnect = useCallback(
|
||||
(params: Connection) => {
|
||||
if (params.source && params.target) {
|
||||
// Add edge to workflow store
|
||||
addEdge(
|
||||
params.source,
|
||||
params.target,
|
||||
params.sourceHandle || undefined,
|
||||
params.targetHandle || undefined
|
||||
);
|
||||
|
||||
// Add edge to local state
|
||||
const newEdge = {
|
||||
id: `edge-${Date.now()}`,
|
||||
source: params.source,
|
||||
target: params.target,
|
||||
sourceHandle: params.sourceHandle,
|
||||
targetHandle: params.targetHandle,
|
||||
};
|
||||
|
||||
setEdges((eds) => [...eds, newEdge]);
|
||||
}
|
||||
},
|
||||
[addEdge, setEdges]
|
||||
[addEdge]
|
||||
);
|
||||
|
||||
const onNodesChange = useCallback(
|
||||
(changes: NodeChange[]) => {
|
||||
changes.forEach((change) => {
|
||||
switch (change.type) {
|
||||
case "position":
|
||||
if (change.id && change.position) {
|
||||
updateNodePosition(change.id, change.position);
|
||||
}
|
||||
break;
|
||||
case "select":
|
||||
if (change.id) {
|
||||
selectNode(change.selected ? change.id : null);
|
||||
}
|
||||
break;
|
||||
case "remove":
|
||||
if (change.id) {
|
||||
deleteNode(change.id);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
},
|
||||
[updateNodePosition, selectNode, deleteNode]
|
||||
);
|
||||
|
||||
const onEdgesChange = useCallback(
|
||||
(changes: EdgeChange[]) => {
|
||||
changes.forEach((change) => {
|
||||
if (change.type === "remove" && change.id) {
|
||||
deleteEdge(change.id);
|
||||
}
|
||||
});
|
||||
},
|
||||
[deleteEdge]
|
||||
);
|
||||
|
||||
const onNodeClick = useCallback(
|
||||
@@ -157,51 +175,23 @@ export const WorkflowEditor: React.FC<WorkflowEditorProps> = ({ onClose }) => {
|
||||
y: event.clientY - reactFlowBounds.top,
|
||||
});
|
||||
|
||||
// Add node to the workflow store
|
||||
addNode(type, position);
|
||||
|
||||
// Create a new node for the local state
|
||||
const newNode = {
|
||||
id: `node-${Date.now()}`,
|
||||
type,
|
||||
position,
|
||||
data: {
|
||||
id: `node-${Date.now()}`,
|
||||
type: type as any,
|
||||
label: `${type} Node`,
|
||||
status: "idle" as const,
|
||||
config: {},
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
},
|
||||
};
|
||||
|
||||
// Add to local state
|
||||
setNodes((nds) => [...nds, newNode]);
|
||||
},
|
||||
[reactFlowInstance, addNode, setNodes]
|
||||
[reactFlowInstance, addNode]
|
||||
);
|
||||
|
||||
const onNodesDelete = useCallback(
|
||||
(nodesToDelete: Node[]) => {
|
||||
nodesToDelete.forEach((node) => deleteNode(node.id));
|
||||
// Update local state
|
||||
setNodes((nds) =>
|
||||
nds.filter((node) => !nodesToDelete.some((n) => n.id === node.id))
|
||||
);
|
||||
},
|
||||
[deleteNode, setNodes]
|
||||
[deleteNode]
|
||||
);
|
||||
|
||||
const onEdgesDelete = useCallback(
|
||||
(edgesToDelete: Edge[]) => {
|
||||
edgesToDelete.forEach((edge) => deleteEdge(edge.id));
|
||||
// Update local state
|
||||
setEdges((eds) =>
|
||||
eds.filter((edge) => !edgesToDelete.some((e) => e.id === edge.id))
|
||||
);
|
||||
},
|
||||
[deleteEdge, setEdges]
|
||||
[deleteEdge]
|
||||
);
|
||||
|
||||
const onInit = useCallback((instance: ReactFlowInstance) => {
|
||||
|
||||
@@ -104,6 +104,11 @@ interface WorkflowStore {
|
||||
// Node management
|
||||
addNode: (type: string, position: { x: number; y: number }) => void;
|
||||
updateNode: (nodeId: string, data: Partial<NodeData>) => void;
|
||||
updateNodePosition: (
|
||||
nodeId: string,
|
||||
position: { x: number; y: number }
|
||||
) => void;
|
||||
updateNodeData: (nodeId: string, data: Partial<NodeData>) => void;
|
||||
deleteNode: (nodeId: string) => void;
|
||||
clearAllNodes: () => void;
|
||||
selectNode: (nodeId: string | null) => void;
|
||||
@@ -335,6 +340,36 @@ export const useWorkflowStore = create<WorkflowStore>((set, get) => ({
|
||||
}));
|
||||
},
|
||||
|
||||
updateNodePosition: (nodeId: string, position: { x: number; y: number }) => {
|
||||
set((state) => ({
|
||||
currentWorkflow: state.currentWorkflow
|
||||
? {
|
||||
...state.currentWorkflow,
|
||||
nodes: state.currentWorkflow.nodes.map((node) =>
|
||||
node.id === nodeId ? { ...node, position } : node
|
||||
),
|
||||
updatedAt: new Date(),
|
||||
}
|
||||
: null,
|
||||
}));
|
||||
},
|
||||
|
||||
updateNodeData: (nodeId: string, data: Partial<NodeData>) => {
|
||||
set((state) => ({
|
||||
currentWorkflow: state.currentWorkflow
|
||||
? {
|
||||
...state.currentWorkflow,
|
||||
nodes: state.currentWorkflow.nodes.map((node) =>
|
||||
node.id === nodeId
|
||||
? { ...node, data: { ...node.data, ...data } }
|
||||
: node
|
||||
),
|
||||
updatedAt: new Date(),
|
||||
}
|
||||
: null,
|
||||
}));
|
||||
},
|
||||
|
||||
deleteNode: (nodeId: string) => {
|
||||
set((state) => ({
|
||||
currentWorkflow: state.currentWorkflow
|
||||
|
||||
Reference in New Issue
Block a user