Skip to content

Commit caf7378

Browse files
committed
refactor(workflow): improve edge handling and node creation logic
- Filter edges more precisely for switch nodes in useEdgeConnection - Reorder timeout assignment in workflowConverter for better clarity - Clean up whitespace and improve consistency in useWorkflowActions - Enhance event node creation with proper conditions and timeouts
1 parent 5a3fc0c commit caf7378

File tree

4 files changed

+57
-43
lines changed

4 files changed

+57
-43
lines changed

src/lib/src/hooks/useEdgeConnection.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,14 @@ export const useEdgeConnection = (edges, updateEdges, setHistoryState, nodes, wo
105105
let filteredEdges = edges;
106106
if (sourceNode?.type === 'switch') {
107107
// For switch nodes, only remove edges from the same source handle
108-
filteredEdges = edges.filter(edge =>
108+
filteredEdges = edges.filter(edge =>
109109
!(edge.source === connection.source && edge.sourceHandle === connection.sourceHandle)
110110
);
111111
} else {
112112
// For non-switch nodes, remove all existing outgoing edges
113113
filteredEdges = edges.filter(edge => edge.source !== connection.source);
114114
}
115-
115+
116116
const updatedEdges = addEdge(newEdge, filteredEdges);
117117
updateEdges(updatedEdges);
118118

src/lib/src/hooks/useWorkflowActions.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export function useWorkflowActions(workflowState, historyCallback) {
2323
const addNodeToWorkflow = useCallback((newNode) => {
2424
const updatedNodes = [...nodes, newNode];
2525
updateNodes(updatedNodes);
26-
26+
2727
// Update history if callback provided
2828
if (historyCallback) {
2929
historyCallback({
@@ -32,7 +32,7 @@ export function useWorkflowActions(workflowState, historyCallback) {
3232
workflowMetadata
3333
});
3434
}
35-
35+
3636
return newNode;
3737
}, [nodes, edges, workflowMetadata, updateNodes, historyCallback]);
3838

@@ -89,12 +89,12 @@ export function useWorkflowActions(workflowState, historyCallback) {
8989
const removeNode = useCallback((nodeId) => {
9090
const updatedNodes = nodes.filter(node => node.id !== nodeId);
9191
// Also remove edges connected to this node
92-
const updatedEdges = edges.filter(edge =>
92+
const updatedEdges = edges.filter(edge =>
9393
edge.source !== nodeId && edge.target !== nodeId
9494
);
95-
95+
9696
updateNodes(updatedNodes);
97-
97+
9898
// Update history if callback provided
9999
if (historyCallback) {
100100
historyCallback({
@@ -103,7 +103,7 @@ export function useWorkflowActions(workflowState, historyCallback) {
103103
workflowMetadata
104104
});
105105
}
106-
106+
107107
return { nodes: updatedNodes, edges: updatedEdges };
108108
}, [nodes, edges, workflowMetadata, updateNodes, historyCallback]);
109109

@@ -132,7 +132,7 @@ export function useWorkflowActions(workflowState, historyCallback) {
132132
// Clear all nodes
133133
const clearAllNodes = useCallback(() => {
134134
updateNodes([]);
135-
135+
136136
// Update history if callback provided
137137
if (historyCallback) {
138138
historyCallback({
@@ -151,13 +151,13 @@ export function useWorkflowActions(workflowState, historyCallback) {
151151
addSwitchNode,
152152
addEndNode,
153153
addStartNode,
154-
154+
155155
// Generic functions
156156
addNode,
157157
removeNode,
158158
duplicateNode,
159159
clearAllNodes,
160-
160+
161161
// Utility
162162
getDefaultPosition: () => getDefaultPosition(nodes)
163163
};

src/lib/src/utils/nodeFactory.js

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,21 @@ export function generateNodeId(nodeType) {
2222
export function generateUniqueNodeName(baseNodeType, existingNodes = []) {
2323
const baseName = baseNodeType;
2424
const existingNames = existingNodes.map(node => node.data?.name || node.data?.label || '').filter(Boolean);
25-
25+
2626
// If base name doesn't exist, use it
2727
if (!existingNames.includes(baseName)) {
2828
return baseName;
2929
}
30-
30+
3131
// Find the next available number
3232
let counter = 1;
3333
let candidateName;
34-
34+
3535
do {
3636
candidateName = `${baseName} ${counter}`;
3737
counter++;
3838
} while (existingNames.includes(candidateName));
39-
39+
4040
return candidateName;
4141
}
4242

@@ -54,24 +54,24 @@ export function getDefaultPosition(existingNodes = []) {
5454
// Find a position that doesn't overlap with existing nodes
5555
const gridSize = 200;
5656
const maxAttempts = 50;
57-
57+
5858
for (let attempt = 0; attempt < maxAttempts; attempt++) {
5959
const x = 100 + (attempt % 5) * gridSize + Math.random() * 50;
6060
const y = 100 + Math.floor(attempt / 5) * gridSize + Math.random() * 50;
61-
61+
6262
// Check if this position is too close to existing nodes
6363
const tooClose = existingNodes.some(node => {
6464
const distance = Math.sqrt(
6565
Math.pow(node.position.x - x, 2) + Math.pow(node.position.y - y, 2)
6666
);
6767
return distance < 150; // Minimum distance between nodes
6868
});
69-
69+
7070
if (!tooClose) {
7171
return { x, y };
7272
}
7373
}
74-
74+
7575
// Fallback to random position if no good spot found
7676
return {
7777
x: Math.random() * 400 + 100,
@@ -103,11 +103,11 @@ export function createOperationNode(options = {}) {
103103
metadata = {},
104104
existingNodes = []
105105
} = options;
106-
106+
107107
const nodeName = name || generateUniqueNodeName('Operation', existingNodes);
108108

109109
const nodeId = generateNodeId('operation');
110-
110+
111111
return {
112112
id: nodeId,
113113
type: 'operation',
@@ -138,10 +138,10 @@ export function createSleepNode(options = {}) {
138138
metadata = {},
139139
existingNodes = []
140140
} = options;
141-
141+
142142
const nodeName = name || generateUniqueNodeName('Sleep', existingNodes);
143143
const nodeId = generateNodeId('sleep');
144-
144+
145145
return {
146146
id: nodeId,
147147
type: 'sleep',
@@ -156,10 +156,11 @@ export function createSleepNode(options = {}) {
156156
}
157157

158158
/**
159-
* Create a new event node
159+
* Create a new event node (event-based switch state)
160160
* @param {Object} options - Configuration options
161161
* @param {string} options.name - Node name
162-
* @param {Array} options.onEvents - Array of event configurations
162+
* @param {Array} options.eventConditions - Array of event conditions for switching
163+
* @param {Object} options.defaultCondition - Default condition when no events match
163164
* @param {Object} options.timeouts - Timeout configurations
164165
* @param {Object} options.position - Position coordinates
165166
* @param {Object} options.metadata - Additional metadata
@@ -168,28 +169,40 @@ export function createSleepNode(options = {}) {
168169
export function createEventNode(options = {}) {
169170
const {
170171
name,
171-
onEvents = [{
172-
eventRefs: ['sample-event']
172+
eventConditions = [{
173+
eventRef: 'sample-event',
174+
transition: {
175+
nextState: 'NextState'
176+
}
173177
}],
174-
timeouts = {},
178+
defaultCondition = {
179+
transition: {
180+
nextState: 'DefaultState'
181+
}
182+
},
183+
timeouts = {
184+
eventTimeout: 'PT30S'
185+
},
175186
position,
176187
metadata = {},
177188
existingNodes = []
178189
} = options;
179-
190+
180191
const nodeName = name || generateUniqueNodeName('Event', existingNodes);
181-
const nodeId = generateNodeId('event');
182-
192+
const nodeId = generateNodeId('switch');
193+
183194
return {
184195
id: nodeId,
185-
type: 'event',
196+
type: 'switch',
186197
position: position || getDefaultPosition(),
187198
data: {
188199
name: nodeName,
189-
onEvents,
200+
eventConditions,
201+
defaultCondition,
190202
timeouts,
191203
metadata,
192-
label: nodeName
204+
label: nodeName,
205+
conditionType: 'event'
193206
}
194207
};
195208
}
@@ -224,11 +237,11 @@ export function createSwitchNode(options = {}) {
224237
metadata = {},
225238
existingNodes = []
226239
} = options;
227-
240+
228241
const nodeName = name || generateUniqueNodeName('Switch', existingNodes);
229242

230243
const nodeId = generateNodeId('switch');
231-
244+
232245
return {
233246
id: nodeId,
234247
type: 'switch',
@@ -261,10 +274,10 @@ export function createEndNode(options = {}) {
261274
metadata = {},
262275
existingNodes = []
263276
} = options;
264-
277+
265278
const nodeName = name || generateUniqueNodeName('End', existingNodes);
266279
const nodeId = generateNodeId('end');
267-
280+
268281
return {
269282
id: nodeId,
270283
type: 'end',
@@ -294,7 +307,7 @@ export function createStartNode(options = {}) {
294307
} = options;
295308

296309
const nodeId = generateNodeId('start');
297-
310+
298311
return {
299312
id: nodeId,
300313
type: 'start',

src/lib/src/utils/workflowConverter.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,17 +114,18 @@ export function convertNodeToState(node, edges, allNodes, workflowMetadata) {
114114
defaultCondition: node.data.defaultCondition || { transition: { nextState: '' } },
115115
};
116116

117-
// Add timeouts for event conditions
118-
if (node.data.conditionType === 'event' && node.data.timeouts && node.data.timeouts.eventTimeout) {
119-
switchState.timeouts = node.data.timeouts;
120-
}
121117

122118
// Determine condition type and handle accordingly
123119
const conditionType = node.data.conditionType || 'data';
124120
const dataConditions = node.data.dataConditions || [];
125121
const eventConditions = node.data.eventConditions || [];
126122
const conditions = conditionType === 'data' ? dataConditions : eventConditions;
127123

124+
// Add timeouts for event conditions
125+
if (conditionType === 'event' && node.data.timeouts && node.data.timeouts.eventTimeout) {
126+
switchState.timeouts = node.data.timeouts;
127+
}
128+
128129
if (conditionType === 'data') {
129130
switchState.dataConditions = [];
130131
conditions.forEach((condition, index) => {

0 commit comments

Comments
 (0)