@evenicanpm/admin-integrate 2.0.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/documents/ConfigImport/configuration-import.ts +1 -1
- package/documents/Endpoint/list.ts +3 -3
- package/documents/Process/list.ts +3 -3
- package/documents/ProcessExecution/list.ts +2 -2
- package/documents/ProcessExport/read.ts +1 -1
- package/documents/ProcessSchedule/read.ts +1 -1
- package/documents/ProcessScheduleGroup/read.ts +3 -3
- package/documents/ProcessTemplate/read.ts +1 -1
- package/documents/ScheduledProcess/list.ts +1 -1
- package/package.json +2 -2
- package/src/components/integration-view/animated-svg.tsx +0 -1
- package/src/components/integration-view/elk-types.ts +1 -1
- package/src/components/integration-view/integration-view.tsx +267 -175
- package/src/components/integration-view/nodes/execution-entry-node.tsx +3 -2
- package/src/components/integration-view/nodes/group-node.tsx +1 -1
- package/src/components/integration-view/types.ts +2 -0
- package/src/components/integration-view/utils/mapping.ts +62 -41
- package/src/components/list-filter/list-filter-types.ts +6 -0
- package/src/components/list-filter/list-filter.tsx +19 -15
- package/src/components/list-filter/multi-select-filter.tsx +7 -7
- package/src/components/list-filter/select-filter.tsx +6 -6
- package/src/components/scheduler/day-selector.tsx +1 -1
- package/src/components/templatesV2/inputs/form-type.ts +7 -1
- package/src/components/templatesV2/inputs/renderers/renderFormControl.tsx +19 -11
- package/src/components/templatesV2/inputs/renderers/renderSearchInput.tsx +3 -4
- package/src/components/templatesV2/inputs/search/useSearchInput.ts +12 -7
- package/src/components/templatesV2/inputs/table/InputTable.tsx +20 -11
- package/src/components/templatesV2/inputs/utils/arrangeInputs.ts +4 -3
- package/src/components/templatesV2/pageForm.tsx +9 -7
- package/src/components/templatesV2/validation/buildZodSchema.ts +0 -4
- package/src/components/templatesV2/wizard.tsx +5 -3
- package/src/pages/dashboard/dashboard-link-cards.tsx +0 -1
- package/src/pages/dashboard/dashboard-list-sections.tsx +1 -1
- package/src/pages/dashboard/dashboard.tsx +0 -1
- package/src/pages/executions/executions-list/executions-list-table.tsx +0 -1
- package/src/pages/executions/executions.tsx +1 -1
- package/src/pages/integration-create/integration-create.tsx +20 -14
- package/src/pages/integration-create/pre-creation-step.tsx +9 -9
- package/src/pages/integration-details/import-process/copy-tasks-list.tsx +1 -3
- package/src/pages/integration-details/integration-details.tsx +1 -1
- package/src/pages/integration-details/task-drawer/edit-task.tsx +2 -2
- package/src/pages/integration-details/task-drawer/task-drawer.tsx +2 -2
|
@@ -15,6 +15,7 @@ import "@xyflow/react/dist/style.css";
|
|
|
15
15
|
import {
|
|
16
16
|
Background,
|
|
17
17
|
Controls,
|
|
18
|
+
type Edge,
|
|
18
19
|
type Node,
|
|
19
20
|
ReactFlow,
|
|
20
21
|
ReactFlowProvider,
|
|
@@ -25,6 +26,7 @@ import {
|
|
|
25
26
|
import _ from "lodash";
|
|
26
27
|
import type {
|
|
27
28
|
ConfigExport,
|
|
29
|
+
Maybe,
|
|
28
30
|
ProcessExecutionDetails,
|
|
29
31
|
ProcessTask,
|
|
30
32
|
ProcessTaskExecution,
|
|
@@ -35,6 +37,7 @@ import type { ElkExtendedEdgeWithFlow, ElkNodeWithFlow } from "./elk-types";
|
|
|
35
37
|
import { edgeTypes, nodeTypes } from "./flow-types";
|
|
36
38
|
|
|
37
39
|
import {
|
|
40
|
+
type AddHandler,
|
|
38
41
|
mapEmptyNodesAndEdges,
|
|
39
42
|
mapProcessConfigToNodesAndEdges,
|
|
40
43
|
mapProcessTasksToNodesAndEdges,
|
|
@@ -42,6 +45,16 @@ import {
|
|
|
42
45
|
} from "./utils/mapping";
|
|
43
46
|
|
|
44
47
|
const elk = new ELK();
|
|
48
|
+
type VerticalOverlapRect = { y: number; height: number };
|
|
49
|
+
type HorizontalOverlapRect = { x: number; width: number };
|
|
50
|
+
type ZoneY = { sort: number; y: number; height: number };
|
|
51
|
+
type ZoneX = { parallelProcessingGroup: number; x: number; width: number };
|
|
52
|
+
type FlowNode = Node<Record<string, unknown>>;
|
|
53
|
+
type FlowEdge = Edge<Record<string, unknown>>;
|
|
54
|
+
type FlowDirectionProps = {
|
|
55
|
+
targetPosition?: "top" | "bottom" | "left" | "right";
|
|
56
|
+
sourcePosition?: "top" | "bottom" | "left" | "right";
|
|
57
|
+
};
|
|
45
58
|
|
|
46
59
|
const calculateMaxWidth = (
|
|
47
60
|
processTasks: ProcessTask[] | ProcessTaskExecution[],
|
|
@@ -57,15 +70,19 @@ const calculateMaxWidth = (
|
|
|
57
70
|
return Math.ceil(maxCharCount * 14 + 28 + 8 + 24); // Approximate width calculation
|
|
58
71
|
};
|
|
59
72
|
|
|
60
|
-
const getLayoutedElements = (
|
|
73
|
+
const getLayoutedElements = (
|
|
74
|
+
nodes: ElkNodeWithFlow[],
|
|
75
|
+
edges: ElkExtendedEdgeWithFlow[],
|
|
76
|
+
options: Record<string, string> = {},
|
|
77
|
+
) => {
|
|
61
78
|
const graph: ElkNodeWithFlow = {
|
|
62
79
|
id: "root",
|
|
63
|
-
children: nodes.map((node:
|
|
80
|
+
children: nodes.map((node: ElkNodeWithFlow) => ({
|
|
64
81
|
...node,
|
|
65
82
|
targetPosition: "top",
|
|
66
83
|
sourcePosition: "bottom",
|
|
67
84
|
// Hardcoded until width and height calculation is implemented
|
|
68
|
-
})),
|
|
85
|
+
})) as ElkNodeWithFlow[],
|
|
69
86
|
layoutOptions: {
|
|
70
87
|
"org.eclipse.elk.algorithm": "org.eclipse.elk.layered",
|
|
71
88
|
"org.eclipse.elk.layered.spacing.nodeNodeBetweenLayers": "120", // bigger vertical gap
|
|
@@ -75,53 +92,64 @@ const getLayoutedElements = (nodes: any, edges: any, options: any = {}) => {
|
|
|
75
92
|
|
|
76
93
|
return elk
|
|
77
94
|
.layout(graph, { layoutOptions: options })
|
|
78
|
-
.then((layoutedGraph:
|
|
79
|
-
const nodeItems:
|
|
95
|
+
.then((layoutedGraph: ElkNodeWithFlow) => {
|
|
96
|
+
const nodeItems: ElkNodeWithFlow[] = [];
|
|
80
97
|
|
|
81
|
-
layoutedGraph.children
|
|
98
|
+
layoutedGraph.children?.forEach((node: ElkNodeWithFlow) => {
|
|
99
|
+
const nx = node.x ?? 0;
|
|
100
|
+
const ny = node.y ?? 0;
|
|
82
101
|
nodeItems.push({
|
|
83
102
|
...node,
|
|
84
103
|
// React Flow expects a position property on the node instead of `x`
|
|
85
104
|
// and `y` fields.
|
|
86
105
|
height:
|
|
87
|
-
node.height +
|
|
88
|
-
(node.children && node.children.length > 0 ? calcYOffset() :
|
|
106
|
+
(node.height ?? 0) +
|
|
107
|
+
(node.children && node.children.length > 0 ? calcYOffset() : 0),
|
|
89
108
|
width: node.width,
|
|
90
|
-
x:
|
|
91
|
-
y:
|
|
92
|
-
position: { x:
|
|
109
|
+
x: nx,
|
|
110
|
+
y: ny,
|
|
111
|
+
position: { x: nx, y: ny },
|
|
93
112
|
});
|
|
94
113
|
|
|
95
114
|
if (node.children) {
|
|
96
|
-
node.children.forEach((node2:
|
|
115
|
+
node.children.forEach((node2: ElkNodeWithFlow) => {
|
|
116
|
+
const n2x = node2.x ?? 0;
|
|
117
|
+
const n2y = (node2.y ?? 0) + calcYOffset();
|
|
97
118
|
nodeItems.push({
|
|
98
119
|
...node2,
|
|
99
120
|
// React Flow expects a position property on the node instead of `x`
|
|
100
121
|
// and `y` fields.
|
|
101
122
|
targetPosition: "top",
|
|
102
123
|
sourcePosition: "bottom",
|
|
103
|
-
x:
|
|
104
|
-
y:
|
|
105
|
-
position: { x:
|
|
124
|
+
x: n2x,
|
|
125
|
+
y: n2y,
|
|
126
|
+
position: { x: n2x, y: n2y },
|
|
106
127
|
parentId: node.id,
|
|
107
|
-
});
|
|
128
|
+
} as ElkNodeWithFlow & FlowDirectionProps);
|
|
108
129
|
});
|
|
109
130
|
}
|
|
110
131
|
});
|
|
111
132
|
|
|
112
|
-
layoutedGraph.edges
|
|
133
|
+
const layoutEdges = layoutedGraph.edges ?? [];
|
|
134
|
+
layoutEdges.forEach((edge: ElkExtendedEdgeWithFlow) => {
|
|
113
135
|
edge.source = edge.sources[0];
|
|
114
136
|
edge.target = edge.targets[0];
|
|
115
137
|
});
|
|
116
138
|
|
|
117
139
|
return {
|
|
118
140
|
nodes: nodeItems,
|
|
119
|
-
edges:
|
|
141
|
+
edges: layoutEdges.map((edge: ElkExtendedEdgeWithFlow) => ({
|
|
120
142
|
...edge,
|
|
121
143
|
})),
|
|
122
144
|
};
|
|
123
145
|
})
|
|
124
|
-
.catch(
|
|
146
|
+
.catch((err: unknown) => {
|
|
147
|
+
console.error(err);
|
|
148
|
+
return {
|
|
149
|
+
nodes: [] as ElkNodeWithFlow[],
|
|
150
|
+
edges: [] as ElkExtendedEdgeWithFlow[],
|
|
151
|
+
};
|
|
152
|
+
});
|
|
125
153
|
};
|
|
126
154
|
|
|
127
155
|
const calcYOffset = () => {
|
|
@@ -136,15 +164,16 @@ interface Props {
|
|
|
136
164
|
variant?: "process" | "process-execution";
|
|
137
165
|
onTaskClick?:
|
|
138
166
|
| ((id: string) => void)
|
|
167
|
+
| ((processTask: ProcessTask) => void)
|
|
139
168
|
| ((processTaskExecution: ProcessTaskExecution) => void);
|
|
140
169
|
drawerOpen?: boolean;
|
|
141
170
|
processTaskId?: string;
|
|
142
171
|
onConfigChange?: (processConfig: ConfigExport) => void;
|
|
143
|
-
onAdd?:
|
|
172
|
+
onAdd?: AddHandler;
|
|
144
173
|
canEdit?: boolean;
|
|
145
174
|
}
|
|
146
175
|
|
|
147
|
-
function getOverlapY(rect1:
|
|
176
|
+
function getOverlapY(rect1: VerticalOverlapRect, rect2: VerticalOverlapRect) {
|
|
148
177
|
// Calculate intersection coordinates
|
|
149
178
|
//const intersectX1 = Math.max(rect1.x, rect2.x);
|
|
150
179
|
const intersectY1 = Math.max(rect1.y, rect2.y);
|
|
@@ -159,7 +188,10 @@ function getOverlapY(rect1: any, rect2: any) {
|
|
|
159
188
|
}
|
|
160
189
|
}
|
|
161
190
|
|
|
162
|
-
function getOverlapX(
|
|
191
|
+
function getOverlapX(
|
|
192
|
+
rect1: HorizontalOverlapRect,
|
|
193
|
+
rect2: HorizontalOverlapRect,
|
|
194
|
+
) {
|
|
163
195
|
// Calculate intersection coordinates
|
|
164
196
|
//const intersectX1 = Math.max(rect1.x, rect2.x);
|
|
165
197
|
const intersectX1 = Math.max(rect1.x, rect2.x);
|
|
@@ -189,45 +221,60 @@ const IntegrationView: React.FC<Props> = ({
|
|
|
189
221
|
ProcessExecutionDetails | undefined
|
|
190
222
|
>(processExecutionInput);
|
|
191
223
|
|
|
192
|
-
const [nodes, setNodes, onNodesChange] = useNodesState<
|
|
193
|
-
const [edges, setEdges, onEdgesChange] = useEdgesState<
|
|
194
|
-
const [zonesY, setZonesY] =
|
|
195
|
-
const [zonesX, setZonesX] =
|
|
224
|
+
const [nodes, setNodes, onNodesChange] = useNodesState<FlowNode>([]);
|
|
225
|
+
const [edges, setEdges, onEdgesChange] = useEdgesState<FlowEdge>([]);
|
|
226
|
+
const [zonesY, setZonesY] = useState<ZoneY[]>([]);
|
|
227
|
+
const [zonesX, setZonesX] = useState<ZoneX[]>([]);
|
|
196
228
|
|
|
197
229
|
const { setCenter, fitView } = useReactFlow();
|
|
198
230
|
|
|
199
231
|
const onConnect = useCallback(() => {}, []);
|
|
200
232
|
const onLayout = useCallback(
|
|
201
|
-
(processInput:
|
|
202
|
-
let tasks:
|
|
233
|
+
(processInput: unknown) => {
|
|
234
|
+
let tasks: (ProcessTask | ProcessTaskExecution)[] | undefined;
|
|
203
235
|
|
|
204
236
|
if (variant === "process") {
|
|
205
|
-
tasks =
|
|
206
|
-
|
|
207
|
-
)
|
|
237
|
+
tasks = (
|
|
238
|
+
processInput as ConfigExport | undefined
|
|
239
|
+
)?.Processes?.[0]?.ProcessTasks?.filter(
|
|
240
|
+
(t): t is ProcessTaskExport => t != null,
|
|
241
|
+
).map((processTask) => mapToCamelCase(processTask));
|
|
208
242
|
} else {
|
|
209
|
-
|
|
210
|
-
|
|
243
|
+
const executionInput =
|
|
244
|
+
(processInput as ProcessExecutionDetails | undefined) ??
|
|
245
|
+
processExecutionDetails;
|
|
246
|
+
tasks = executionInput?.processTaskExecutions?.filter(
|
|
247
|
+
(t): t is ProcessTaskExecution => t != null,
|
|
248
|
+
);
|
|
211
249
|
}
|
|
212
250
|
|
|
213
251
|
if (
|
|
214
252
|
(tasks && tasks.length > 0) ||
|
|
215
|
-
(processInput &&
|
|
253
|
+
(processInput &&
|
|
254
|
+
((processInput as { processTasks?: unknown[] })?.processTasks
|
|
255
|
+
?.length ?? 0) > 0)
|
|
216
256
|
) {
|
|
217
257
|
const width = calculateMaxWidth(
|
|
218
258
|
tasks as ProcessTask[] | ProcessTaskExecution[],
|
|
219
259
|
);
|
|
220
260
|
|
|
261
|
+
const executionDetails =
|
|
262
|
+
(processInput as ProcessExecutionDetails | undefined) ??
|
|
263
|
+
processExecutionDetails;
|
|
264
|
+
if (variant !== "process" && !executionDetails) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
|
|
221
268
|
const mapped =
|
|
222
269
|
variant === "process"
|
|
223
270
|
? mapProcessConfigToNodesAndEdges(
|
|
224
|
-
processInput,
|
|
271
|
+
processInput as ConfigExport,
|
|
225
272
|
width,
|
|
226
273
|
variant,
|
|
227
274
|
onAdd,
|
|
228
275
|
)
|
|
229
276
|
: mapProcessTasksToNodesAndEdges(
|
|
230
|
-
|
|
277
|
+
executionDetails as ProcessExecutionDetails,
|
|
231
278
|
width,
|
|
232
279
|
variant as "process" | "process-execution",
|
|
233
280
|
);
|
|
@@ -237,28 +284,42 @@ const IntegrationView: React.FC<Props> = ({
|
|
|
237
284
|
const es = mapped.edges;
|
|
238
285
|
|
|
239
286
|
getLayoutedElements(ns, es, opts).then(
|
|
240
|
-
({
|
|
241
|
-
|
|
242
|
-
|
|
287
|
+
({
|
|
288
|
+
nodes: layoutedNodes,
|
|
289
|
+
edges: layoutedEdges,
|
|
290
|
+
}: {
|
|
291
|
+
nodes: ElkNodeWithFlow[];
|
|
292
|
+
edges: ElkExtendedEdgeWithFlow[];
|
|
293
|
+
}) => {
|
|
294
|
+
setNodes(layoutedNodes as FlowNode[]);
|
|
295
|
+
setEdges(layoutedEdges as FlowEdge[]);
|
|
243
296
|
|
|
244
297
|
const zonesY = _.uniqBy(
|
|
245
|
-
layoutedNodes.filter(
|
|
298
|
+
layoutedNodes.filter(
|
|
299
|
+
(n: ElkNodeWithFlow) => n.type === "task-node",
|
|
300
|
+
),
|
|
246
301
|
"data.processTask.sort",
|
|
247
|
-
).map((n:
|
|
248
|
-
sort:
|
|
249
|
-
|
|
250
|
-
|
|
302
|
+
).map((n: ElkNodeWithFlow) => ({
|
|
303
|
+
sort:
|
|
304
|
+
(n?.data as { processTask?: ProcessTask })?.processTask?.sort ??
|
|
305
|
+
0,
|
|
306
|
+
y: n.position?.y ?? 0,
|
|
307
|
+
height: n.height ?? 0,
|
|
251
308
|
}));
|
|
252
309
|
|
|
253
310
|
setZonesY(zonesY);
|
|
254
311
|
|
|
255
312
|
const zonesX = _.uniqBy(
|
|
256
|
-
layoutedNodes.filter(
|
|
313
|
+
layoutedNodes.filter(
|
|
314
|
+
(n: ElkNodeWithFlow) => n.type === "group-node",
|
|
315
|
+
),
|
|
257
316
|
"data.parallelProcessingGroup",
|
|
258
|
-
).map((n:
|
|
259
|
-
parallelProcessingGroup:
|
|
260
|
-
|
|
261
|
-
|
|
317
|
+
).map((n: ElkNodeWithFlow) => ({
|
|
318
|
+
parallelProcessingGroup:
|
|
319
|
+
(n?.data as { parallelProcessingGroup?: number })
|
|
320
|
+
?.parallelProcessingGroup ?? 0,
|
|
321
|
+
x: n.position?.x ?? 0,
|
|
322
|
+
width: n.width ?? 0,
|
|
262
323
|
}));
|
|
263
324
|
|
|
264
325
|
setZonesX(zonesX);
|
|
@@ -268,18 +329,32 @@ const IntegrationView: React.FC<Props> = ({
|
|
|
268
329
|
);
|
|
269
330
|
} else if (
|
|
270
331
|
tasks?.length === 0 ||
|
|
271
|
-
(processInput &&
|
|
332
|
+
(processInput &&
|
|
333
|
+
((processInput as { processTasks?: unknown[] })?.processTasks
|
|
334
|
+
?.length ?? 0) === 0)
|
|
272
335
|
) {
|
|
273
|
-
const
|
|
336
|
+
const emptyLayoutData =
|
|
337
|
+
(processInput as ProcessExecutionDetails | undefined) ??
|
|
338
|
+
processExecutionDetails;
|
|
339
|
+
if (!emptyLayoutData) {
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
const mapped = mapEmptyNodesAndEdges(emptyLayoutData, 400);
|
|
274
343
|
|
|
275
344
|
const opts = { ...elkOptions };
|
|
276
345
|
const ns = mapped.nodes;
|
|
277
346
|
const es = mapped.edges;
|
|
278
347
|
|
|
279
348
|
getLayoutedElements(ns, es, opts).then(
|
|
280
|
-
({
|
|
281
|
-
|
|
282
|
-
|
|
349
|
+
({
|
|
350
|
+
nodes: layoutedNodes,
|
|
351
|
+
edges: layoutedEdges,
|
|
352
|
+
}: {
|
|
353
|
+
nodes: ElkNodeWithFlow[];
|
|
354
|
+
edges: ElkExtendedEdgeWithFlow[];
|
|
355
|
+
}) => {
|
|
356
|
+
setNodes(layoutedNodes as FlowNode[]);
|
|
357
|
+
setEdges(layoutedEdges as FlowEdge[]);
|
|
283
358
|
fitView();
|
|
284
359
|
},
|
|
285
360
|
);
|
|
@@ -288,22 +363,30 @@ const IntegrationView: React.FC<Props> = ({
|
|
|
288
363
|
[nodes, edges],
|
|
289
364
|
);
|
|
290
365
|
|
|
291
|
-
const handleNodeClick = (
|
|
292
|
-
_event: any,
|
|
293
|
-
node: {
|
|
294
|
-
id: React.SetStateAction<string>;
|
|
295
|
-
position: { x: number; y: number };
|
|
296
|
-
width: number;
|
|
297
|
-
height: number;
|
|
298
|
-
data: any;
|
|
299
|
-
parentId?: string;
|
|
300
|
-
},
|
|
301
|
-
) => {
|
|
366
|
+
const handleNodeClick = (_event: ReactMouseEvent, node: FlowNode) => {
|
|
302
367
|
if (!drawerOpen) {
|
|
368
|
+
const nodeData = node.data as {
|
|
369
|
+
processTask?: ProcessTask;
|
|
370
|
+
processTaskExecution?: ProcessTaskExecution;
|
|
371
|
+
};
|
|
303
372
|
if (onTaskClick) {
|
|
304
|
-
if (variant === "process")
|
|
305
|
-
|
|
306
|
-
|
|
373
|
+
if (variant === "process") {
|
|
374
|
+
const processTask = nodeData.processTask;
|
|
375
|
+
if (processTask) {
|
|
376
|
+
(onTaskClick as unknown as (processTask: ProcessTask) => void)(
|
|
377
|
+
processTask,
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
} else if (variant === "process-execution") {
|
|
381
|
+
const processTaskExecution = nodeData.processTaskExecution;
|
|
382
|
+
if (processTaskExecution) {
|
|
383
|
+
(
|
|
384
|
+
onTaskClick as unknown as (
|
|
385
|
+
processTaskExecution: ProcessTaskExecution,
|
|
386
|
+
) => void
|
|
387
|
+
)(processTaskExecution);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
307
390
|
}
|
|
308
391
|
|
|
309
392
|
setTimeout(() => {
|
|
@@ -318,8 +401,8 @@ const IntegrationView: React.FC<Props> = ({
|
|
|
318
401
|
}
|
|
319
402
|
}
|
|
320
403
|
|
|
321
|
-
const centerX = parentx + node.position.x + node.width / 2;
|
|
322
|
-
const centerY = parenty + node.position.y + node.height / 2;
|
|
404
|
+
const centerX = parentx + node.position.x + (node.width ?? 0) / 2;
|
|
405
|
+
const centerY = parenty + node.position.y + (node.height ?? 0) / 2;
|
|
323
406
|
|
|
324
407
|
setCenter(centerX, centerY, { zoom: 1.2, duration: 800 });
|
|
325
408
|
}, 300);
|
|
@@ -332,28 +415,31 @@ const IntegrationView: React.FC<Props> = ({
|
|
|
332
415
|
}, [configInput, processExecutionInput]);
|
|
333
416
|
|
|
334
417
|
useLayoutEffect(() => {
|
|
335
|
-
setNodes((prevNodes
|
|
336
|
-
prevNodes.map((node
|
|
418
|
+
setNodes((prevNodes) =>
|
|
419
|
+
prevNodes.map((node) => ({
|
|
337
420
|
...node,
|
|
338
421
|
data: {
|
|
339
422
|
...node.data,
|
|
340
423
|
disabled: drawerOpen,
|
|
341
424
|
selected:
|
|
342
|
-
selectedProcessTaskId ===
|
|
343
|
-
|
|
425
|
+
selectedProcessTaskId ===
|
|
426
|
+
(node.data as { processTask?: ProcessTask })?.processTask?.id ||
|
|
427
|
+
selectedProcessTaskId ===
|
|
428
|
+
(node.data as { processTaskExecution?: ProcessTaskExecution })
|
|
429
|
+
?.processTaskExecution?.id,
|
|
344
430
|
},
|
|
345
431
|
})),
|
|
346
432
|
);
|
|
347
433
|
}, [drawerOpen, selectedProcessTaskId]);
|
|
348
434
|
|
|
349
|
-
const handleNodeDragStart = (_e: ReactMouseEvent, node: Node)
|
|
435
|
+
const handleNodeDragStart = (_e: ReactMouseEvent, node: Node) => {
|
|
350
436
|
let edgesFiltered = [];
|
|
351
437
|
|
|
352
|
-
const edgeList:
|
|
438
|
+
const edgeList: FlowEdge[] = [];
|
|
353
439
|
|
|
354
|
-
let nodeIds:
|
|
440
|
+
let nodeIds: string[] = [];
|
|
355
441
|
|
|
356
|
-
edges.forEach((edge
|
|
442
|
+
edges.forEach((edge) => {
|
|
357
443
|
if (edge.source === node.id) {
|
|
358
444
|
nodeIds.push(edge.target);
|
|
359
445
|
}
|
|
@@ -367,15 +453,15 @@ const IntegrationView: React.FC<Props> = ({
|
|
|
367
453
|
|
|
368
454
|
nodeIds = _.uniq(nodeIds);
|
|
369
455
|
|
|
370
|
-
let edgeIds:
|
|
456
|
+
let edgeIds: string[] = [];
|
|
371
457
|
|
|
372
|
-
edgeList.forEach((edge
|
|
458
|
+
edgeList.forEach((edge) => {
|
|
373
459
|
edgeIds.push(edge.source, edge.target);
|
|
374
460
|
});
|
|
375
461
|
|
|
376
462
|
edgeIds = _.uniq(edgeIds);
|
|
377
463
|
|
|
378
|
-
edgesFiltered = edges.filter((edge
|
|
464
|
+
edgesFiltered = edges.filter((edge) => {
|
|
379
465
|
return (
|
|
380
466
|
edgeIds.includes(edge.source) === false &&
|
|
381
467
|
edgeIds.includes(edge.target) === false
|
|
@@ -383,58 +469,58 @@ const IntegrationView: React.FC<Props> = ({
|
|
|
383
469
|
});
|
|
384
470
|
|
|
385
471
|
edgesFiltered = edgesFiltered.filter(
|
|
386
|
-
(edge
|
|
387
|
-
!edge.id.includes((node?.data?.processTask as ProcessTask)?.id),
|
|
472
|
+
(edge) => !edge.id.includes((node?.data?.processTask as ProcessTask)?.id),
|
|
388
473
|
);
|
|
389
474
|
|
|
390
|
-
const nodesFiltered = nodes.filter(
|
|
391
|
-
(node: any) => !nodeIds.includes(node?.id),
|
|
392
|
-
);
|
|
475
|
+
const nodesFiltered = nodes.filter((node) => !nodeIds.includes(node?.id));
|
|
393
476
|
|
|
394
477
|
setEdges(edgesFiltered);
|
|
395
478
|
|
|
396
479
|
setNodes(nodesFiltered);
|
|
397
480
|
};
|
|
398
481
|
|
|
399
|
-
const handleNodeDragEnd = (_e: ReactMouseEvent, node: Node)
|
|
482
|
+
const handleNodeDragEnd = (_e: ReactMouseEvent, node: Node) => {
|
|
483
|
+
const nodeY = node?.position?.y ?? 0;
|
|
484
|
+
const nodeH = node?.height ?? 0;
|
|
485
|
+
|
|
400
486
|
let zoneY = zonesY.find(
|
|
401
|
-
(z
|
|
402
|
-
getOverlapY(
|
|
403
|
-
|
|
404
|
-
{ y: node?.position?.y, height: node.height },
|
|
405
|
-
) > 0,
|
|
487
|
+
(z) =>
|
|
488
|
+
getOverlapY({ y: z.y, height: z.height }, { y: nodeY, height: nodeH }) >
|
|
489
|
+
0,
|
|
406
490
|
);
|
|
407
491
|
|
|
408
|
-
if (!zoneY) {
|
|
492
|
+
if (!zoneY && zonesY.length > 0) {
|
|
409
493
|
const maxZone = _.maxBy(zonesY, "y");
|
|
410
494
|
const minZone = _.minBy(zonesY, "y");
|
|
411
495
|
|
|
412
|
-
if (
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
496
|
+
if (minZone && maxZone) {
|
|
497
|
+
if (nodeH && nodeY + nodeH < minZone.y) {
|
|
498
|
+
zoneY = {
|
|
499
|
+
...minZone,
|
|
500
|
+
sort: minZone.sort - 1,
|
|
501
|
+
};
|
|
502
|
+
} else if (nodeY > maxZone.y + maxZone.height) {
|
|
503
|
+
zoneY = {
|
|
504
|
+
...maxZone,
|
|
505
|
+
sort: maxZone.sort + 1,
|
|
506
|
+
};
|
|
507
|
+
} else {
|
|
508
|
+
const localZones = _.sortBy(zonesY, "y");
|
|
509
|
+
|
|
510
|
+
for (let i = 0; i < localZones.length - 1; i++) {
|
|
511
|
+
const currentZone = localZones[i];
|
|
512
|
+
const nextZone = localZones[i + 1];
|
|
513
|
+
|
|
514
|
+
if (
|
|
515
|
+
nodeY > currentZone.y + currentZone.height &&
|
|
516
|
+
nodeY < nextZone.y
|
|
517
|
+
) {
|
|
518
|
+
zoneY = {
|
|
519
|
+
...currentZone,
|
|
520
|
+
sort: currentZone.sort + 0.5,
|
|
521
|
+
};
|
|
522
|
+
break;
|
|
523
|
+
}
|
|
438
524
|
}
|
|
439
525
|
}
|
|
440
526
|
}
|
|
@@ -444,13 +530,16 @@ const IntegrationView: React.FC<Props> = ({
|
|
|
444
530
|
? nodes.find((n) => n.id === node?.parentId)
|
|
445
531
|
: null;
|
|
446
532
|
|
|
447
|
-
let zoneX:
|
|
533
|
+
let zoneX: ZoneX | undefined;
|
|
448
534
|
let overlapX = 0;
|
|
449
535
|
|
|
450
536
|
for (const zone of zonesX) {
|
|
451
537
|
const overlap = getOverlapX(
|
|
452
538
|
{ x: zone.x, width: zone.width },
|
|
453
|
-
{
|
|
539
|
+
{
|
|
540
|
+
x: (currentGroup?.position?.x ?? 0) + node.position.x,
|
|
541
|
+
width: node.width ?? 0,
|
|
542
|
+
},
|
|
454
543
|
);
|
|
455
544
|
|
|
456
545
|
if (overlap > overlapX) {
|
|
@@ -459,47 +548,48 @@ const IntegrationView: React.FC<Props> = ({
|
|
|
459
548
|
}
|
|
460
549
|
}
|
|
461
550
|
|
|
462
|
-
if (!zoneX) {
|
|
551
|
+
if (!zoneX && zonesX.length > 0) {
|
|
463
552
|
const maxZone = _.maxBy(zonesX, "x");
|
|
464
553
|
const minZone = _.minBy(zonesX, "x");
|
|
465
554
|
|
|
466
|
-
if (
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
555
|
+
if (minZone && maxZone) {
|
|
556
|
+
const groupX = (currentGroup?.position?.x ?? 0) + node.position.x;
|
|
557
|
+
|
|
558
|
+
if (groupX + (node.width ?? 0) < minZone.x) {
|
|
559
|
+
zoneX = {
|
|
560
|
+
...minZone,
|
|
561
|
+
parallelProcessingGroup: minZone.parallelProcessingGroup - 1,
|
|
562
|
+
};
|
|
563
|
+
} else if (groupX > maxZone.x + maxZone.width) {
|
|
564
|
+
zoneX = {
|
|
565
|
+
...maxZone,
|
|
566
|
+
parallelProcessingGroup: maxZone.parallelProcessingGroup + 1,
|
|
567
|
+
};
|
|
568
|
+
} else {
|
|
569
|
+
const localZones = _.sortBy(zonesX, "x");
|
|
570
|
+
|
|
571
|
+
for (let i = 0; i < localZones.length - 1; i++) {
|
|
572
|
+
const currentZone = localZones[i];
|
|
573
|
+
const nextZone = localZones[i + 1];
|
|
574
|
+
|
|
575
|
+
if (
|
|
576
|
+
groupX > currentZone.x &&
|
|
577
|
+
groupX < nextZone.x + nextZone.width
|
|
578
|
+
) {
|
|
579
|
+
zoneX = {
|
|
580
|
+
...currentZone,
|
|
581
|
+
parallelProcessingGroup:
|
|
582
|
+
currentZone.parallelProcessingGroup + 0.5,
|
|
583
|
+
};
|
|
584
|
+
break;
|
|
585
|
+
}
|
|
496
586
|
}
|
|
497
587
|
}
|
|
498
588
|
}
|
|
499
589
|
}
|
|
500
590
|
|
|
501
591
|
if (!zoneY && !zoneX) {
|
|
502
|
-
onLayout(
|
|
592
|
+
onLayout(processExecutionDetails);
|
|
503
593
|
return;
|
|
504
594
|
}
|
|
505
595
|
|
|
@@ -512,13 +602,12 @@ const IntegrationView: React.FC<Props> = ({
|
|
|
512
602
|
|
|
513
603
|
let updatedTasks = modifiedProcess.Processes?.[0]?.ProcessTasks?.map(
|
|
514
604
|
(task) => {
|
|
515
|
-
if (task) {
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
) {
|
|
605
|
+
if (task && zoneX) {
|
|
606
|
+
const pt = (node?.data as { processTask?: ProcessTask })?.processTask;
|
|
607
|
+
const matches = pt?.id
|
|
608
|
+
? task.ProcessTaskId === pt.id
|
|
609
|
+
: task.Name === pt?.name;
|
|
610
|
+
if (matches) {
|
|
522
611
|
return {
|
|
523
612
|
...task,
|
|
524
613
|
ParallelProcessingGroup: zoneX.parallelProcessingGroup,
|
|
@@ -530,13 +619,12 @@ const IntegrationView: React.FC<Props> = ({
|
|
|
530
619
|
);
|
|
531
620
|
|
|
532
621
|
updatedTasks = updatedTasks?.map((task) => {
|
|
533
|
-
if (task) {
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
) {
|
|
622
|
+
if (task && zoneY) {
|
|
623
|
+
const pt = (node?.data as { processTask?: ProcessTask })?.processTask;
|
|
624
|
+
const matches = pt?.id
|
|
625
|
+
? task.ProcessTaskId === pt.id
|
|
626
|
+
: task.Name === pt?.name;
|
|
627
|
+
if (matches) {
|
|
540
628
|
return {
|
|
541
629
|
...task,
|
|
542
630
|
Sort: zoneY.sort,
|
|
@@ -546,7 +634,7 @@ const IntegrationView: React.FC<Props> = ({
|
|
|
546
634
|
return task;
|
|
547
635
|
});
|
|
548
636
|
|
|
549
|
-
let prevParallelProcessingGroup:
|
|
637
|
+
let prevParallelProcessingGroup: number | null = null;
|
|
550
638
|
let index = 0;
|
|
551
639
|
|
|
552
640
|
updatedTasks = _.sortBy(updatedTasks, [
|
|
@@ -554,8 +642,9 @@ const IntegrationView: React.FC<Props> = ({
|
|
|
554
642
|
"Sort",
|
|
555
643
|
])?.map((task) => {
|
|
556
644
|
if (task) {
|
|
557
|
-
|
|
558
|
-
|
|
645
|
+
const ppg = task.ParallelProcessingGroup ?? null;
|
|
646
|
+
if (ppg !== prevParallelProcessingGroup) {
|
|
647
|
+
prevParallelProcessingGroup = ppg;
|
|
559
648
|
index++;
|
|
560
649
|
}
|
|
561
650
|
|
|
@@ -569,17 +658,18 @@ const IntegrationView: React.FC<Props> = ({
|
|
|
569
658
|
_.groupBy(updatedTasks, "ParallelProcessingGroup"),
|
|
570
659
|
);
|
|
571
660
|
|
|
572
|
-
let processTaskValue:
|
|
661
|
+
let processTaskValue: Maybe<ProcessTaskExport>[] = [];
|
|
573
662
|
|
|
574
663
|
partitionedTasks.forEach((partition) => {
|
|
575
664
|
index = 0;
|
|
576
|
-
let prevSort:
|
|
665
|
+
let prevSort: number | null = null;
|
|
577
666
|
|
|
578
667
|
const sortedPartition = _.sortBy(partition, ["Sort", "Name"]).map(
|
|
579
668
|
(task) => {
|
|
580
669
|
if (task) {
|
|
581
|
-
|
|
582
|
-
|
|
670
|
+
const sortVal = task.Sort ?? null;
|
|
671
|
+
if (sortVal !== prevSort) {
|
|
672
|
+
prevSort = sortVal;
|
|
583
673
|
index++;
|
|
584
674
|
}
|
|
585
675
|
|
|
@@ -590,7 +680,9 @@ const IntegrationView: React.FC<Props> = ({
|
|
|
590
680
|
},
|
|
591
681
|
);
|
|
592
682
|
|
|
593
|
-
processTaskValue = processTaskValue.concat(
|
|
683
|
+
processTaskValue = processTaskValue.concat(
|
|
684
|
+
sortedPartition as Maybe<ProcessTaskExport>[],
|
|
685
|
+
);
|
|
594
686
|
});
|
|
595
687
|
|
|
596
688
|
if (modifiedProcess?.Processes?.[0])
|