@canmingir/link 1.2.7 → 1.2.10
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/.github/workflows/publish.yml +64 -7
- package/package.json +1 -1
- package/src/layouts/DashboardLayout/nav-mini.jsx +1 -1
- package/src/lib/Flow/DraggableNode.jsx +68 -2
- package/src/lib/Flow/DynamicConnector.jsx +192 -121
- package/src/lib/Flow/FlowNode.jsx +167 -19
- package/src/lib/Flow/SelectionContext.jsx +123 -0
- package/src/lib/Flow/layouts/InfoNode.jsx +115 -56
- package/src/lib/Flow/styles.js +59 -19
- package/src/theme/index.jsx +38 -1
- package/.idea/codeStyles/Project.xml +0 -84
- package/.idea/codeStyles/codeStyleConfig.xml +0 -5
- package/.idea/copilot.data.migration.agent.xml +0 -6
- package/.idea/copilot.data.migration.ask.xml +0 -6
- package/.idea/copilot.data.migration.ask2agent.xml +0 -6
- package/.idea/copilot.data.migration.edit.xml +0 -6
- package/.idea/inspectionProfiles/Project_Default.xml +0 -6
- package/.idea/misc.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/platform.iml +0 -9
- package/.idea/vcs.xml +0 -6
|
@@ -4,6 +4,7 @@ import { getContentParts } from "./flowUtils";
|
|
|
4
4
|
|
|
5
5
|
import { Box, Card, Typography } from "@mui/material";
|
|
6
6
|
import React, { useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
7
|
+
import { SelectionProvider, useSelection } from "./SelectionContext";
|
|
7
8
|
import {
|
|
8
9
|
applySemanticTokens,
|
|
9
10
|
getBaseStyleForVariant,
|
|
@@ -61,6 +62,7 @@ const NodeContent = ({
|
|
|
61
62
|
const nodeStyle = applySemanticTokens(rawNodeStyle, baseStyle);
|
|
62
63
|
|
|
63
64
|
const {
|
|
65
|
+
direction = "vertical",
|
|
64
66
|
lineColor = baseStyle.lineColor,
|
|
65
67
|
lineWidth = baseStyle.lineWidth,
|
|
66
68
|
lineStyle = baseStyle.lineStyle,
|
|
@@ -73,9 +75,20 @@ const NodeContent = ({
|
|
|
73
75
|
shape,
|
|
74
76
|
shadowLevel,
|
|
75
77
|
minHeight,
|
|
76
|
-
|
|
78
|
+
showDots = baseStyle.showDots ?? false,
|
|
79
|
+
dotRadius = baseStyle.dotRadius ?? 4,
|
|
80
|
+
dotColor = baseStyle.dotColor,
|
|
81
|
+
showArrow = baseStyle.showArrow ?? true,
|
|
82
|
+
arrowSize = baseStyle.arrowSize ?? 6,
|
|
83
|
+
animated = baseStyle.animated ?? false,
|
|
84
|
+
animationSpeed = baseStyle.animationSpeed ?? 1,
|
|
85
|
+
gradient = baseStyle.gradient ?? null,
|
|
86
|
+
curvature = baseStyle.curvature ?? 0.5,
|
|
87
|
+
selectionColor = baseStyle.selectionColor ?? "#64748b",
|
|
77
88
|
} = nodeStyle;
|
|
78
89
|
|
|
90
|
+
const isHorizontal = direction === "horizontal";
|
|
91
|
+
|
|
79
92
|
const strokeWidth = toPxNumber(lineWidth, 1.5);
|
|
80
93
|
const dashStyle =
|
|
81
94
|
lineStyle === "dashed" || lineStyle === "dotted" ? lineStyle : "solid";
|
|
@@ -220,7 +233,7 @@ const NodeContent = ({
|
|
|
220
233
|
ref={containerRef}
|
|
221
234
|
sx={{
|
|
222
235
|
display: "inline-flex",
|
|
223
|
-
flexDirection: "column",
|
|
236
|
+
flexDirection: isHorizontal ? "row" : "column",
|
|
224
237
|
alignItems: "center",
|
|
225
238
|
position: "relative",
|
|
226
239
|
}}
|
|
@@ -231,6 +244,8 @@ const NodeContent = ({
|
|
|
231
244
|
if (registerRef) registerRef(el);
|
|
232
245
|
}}
|
|
233
246
|
onDrag={handleDrag}
|
|
247
|
+
nodeId={node.id}
|
|
248
|
+
selectionColor={selectionColor}
|
|
234
249
|
>
|
|
235
250
|
{renderContent()}
|
|
236
251
|
</DraggableNode>
|
|
@@ -244,16 +259,32 @@ const NodeContent = ({
|
|
|
244
259
|
stroke={lineColor}
|
|
245
260
|
strokeWidth={strokeWidth}
|
|
246
261
|
lineStyle={dashStyle}
|
|
247
|
-
connectorType={connectorType}
|
|
248
262
|
tick={connectorTick}
|
|
263
|
+
orientation={direction}
|
|
264
|
+
showDots={showDots}
|
|
265
|
+
dotRadius={dotRadius}
|
|
266
|
+
dotColor={dotColor}
|
|
267
|
+
showArrow={showArrow}
|
|
268
|
+
arrowSize={arrowSize}
|
|
269
|
+
animated={animated}
|
|
270
|
+
animationSpeed={animationSpeed}
|
|
271
|
+
gradient={gradient}
|
|
272
|
+
curvature={curvature}
|
|
249
273
|
/>
|
|
250
274
|
|
|
251
275
|
<Box
|
|
252
276
|
sx={{
|
|
253
277
|
display: "flex",
|
|
254
|
-
flexDirection: "row",
|
|
255
|
-
|
|
256
|
-
|
|
278
|
+
flexDirection: isHorizontal ? "column" : "row",
|
|
279
|
+
...(isHorizontal
|
|
280
|
+
? {
|
|
281
|
+
marginLeft: levelGap,
|
|
282
|
+
rowGap: gap,
|
|
283
|
+
}
|
|
284
|
+
: {
|
|
285
|
+
marginTop: levelGap,
|
|
286
|
+
columnGap: gap,
|
|
287
|
+
}),
|
|
257
288
|
position: "relative",
|
|
258
289
|
alignItems: "flex-start",
|
|
259
290
|
justifyContent: "center",
|
|
@@ -279,15 +310,49 @@ const NodeContent = ({
|
|
|
279
310
|
);
|
|
280
311
|
};
|
|
281
312
|
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
313
|
+
const hexToRgba = (hex, alpha) => {
|
|
314
|
+
const r = parseInt(hex.slice(1, 3), 16);
|
|
315
|
+
const g = parseInt(hex.slice(3, 5), 16);
|
|
316
|
+
const b = parseInt(hex.slice(5, 7), 16);
|
|
317
|
+
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
const SelectionBox = ({ box, selectionColor = "#64748b" }) => {
|
|
321
|
+
if (!box) return null;
|
|
286
322
|
|
|
323
|
+
const { startX, startY, currentX, currentY } = box;
|
|
324
|
+
const left = Math.min(startX, currentX);
|
|
325
|
+
const top = Math.min(startY, currentY);
|
|
326
|
+
const width = Math.abs(currentX - startX);
|
|
327
|
+
const height = Math.abs(currentY - startY);
|
|
328
|
+
|
|
329
|
+
return (
|
|
330
|
+
<Box
|
|
331
|
+
sx={{
|
|
332
|
+
position: "fixed",
|
|
333
|
+
left,
|
|
334
|
+
top,
|
|
335
|
+
width,
|
|
336
|
+
height,
|
|
337
|
+
border: `2px solid ${selectionColor}`,
|
|
338
|
+
backgroundColor: hexToRgba(selectionColor, 0.1),
|
|
339
|
+
pointerEvents: "none",
|
|
340
|
+
zIndex: 9999,
|
|
341
|
+
borderRadius: "4px",
|
|
342
|
+
}}
|
|
343
|
+
/>
|
|
344
|
+
);
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
const FlowCanvas = ({ children, selectionColor = "#64748b" }) => {
|
|
287
348
|
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
|
288
349
|
const [isDragging, setIsDragging] = useState(false);
|
|
289
|
-
|
|
290
350
|
const [zoom, setZoom] = useState(1);
|
|
351
|
+
const [selectionBox, setSelectionBox] = useState(null);
|
|
352
|
+
const containerRef = useRef(null);
|
|
353
|
+
const selectionBoxRef = useRef(null);
|
|
354
|
+
|
|
355
|
+
const { clearSelection, selectMultiple, addToSelection } = useSelection();
|
|
291
356
|
|
|
292
357
|
const clampZoom = (z) => Math.min(2.5, Math.max(0.25, z));
|
|
293
358
|
|
|
@@ -295,28 +360,92 @@ const FlowNode = ({ isRoot = false, ...props }) => {
|
|
|
295
360
|
const onWheel = (e) => {
|
|
296
361
|
const wantsZoom = e.ctrlKey || e.metaKey;
|
|
297
362
|
if (!wantsZoom) return;
|
|
298
|
-
|
|
299
363
|
e.preventDefault();
|
|
300
|
-
|
|
301
364
|
const direction = e.deltaY > 0 ? -1 : 1;
|
|
302
365
|
const factor = direction > 0 ? 1.1 : 1 / 1.1;
|
|
303
|
-
|
|
304
366
|
setZoom((z) => clampZoom(z * factor));
|
|
305
367
|
};
|
|
306
|
-
|
|
307
368
|
window.addEventListener("wheel", onWheel, { passive: false });
|
|
308
369
|
return () => window.removeEventListener("wheel", onWheel);
|
|
309
370
|
}, []);
|
|
310
371
|
|
|
311
372
|
const handleCanvasMouseDown = (e) => {
|
|
312
|
-
if (e.target?.closest?.(
|
|
373
|
+
if (e.target?.closest?.(".MuiCard-root") || e.target?.closest?.("button"))
|
|
374
|
+
return;
|
|
313
375
|
|
|
314
376
|
if (e.button !== 0) return;
|
|
315
377
|
|
|
316
|
-
setIsDragging(true);
|
|
317
|
-
|
|
318
378
|
const startX = e.clientX;
|
|
319
379
|
const startY = e.clientY;
|
|
380
|
+
|
|
381
|
+
if (e.shiftKey || e.ctrlKey || e.metaKey) {
|
|
382
|
+
setSelectionBox({ startX, startY, currentX: startX, currentY: startY });
|
|
383
|
+
selectionBoxRef.current = {
|
|
384
|
+
startX,
|
|
385
|
+
startY,
|
|
386
|
+
currentX: startX,
|
|
387
|
+
currentY: startY,
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
const onMove = (ev) => {
|
|
391
|
+
const newBox = {
|
|
392
|
+
startX,
|
|
393
|
+
startY,
|
|
394
|
+
currentX: ev.clientX,
|
|
395
|
+
currentY: ev.clientY,
|
|
396
|
+
};
|
|
397
|
+
setSelectionBox(newBox);
|
|
398
|
+
selectionBoxRef.current = newBox;
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
const onUp = () => {
|
|
402
|
+
if (containerRef.current && selectionBoxRef.current) {
|
|
403
|
+
const box = selectionBoxRef.current;
|
|
404
|
+
const nodes = containerRef.current.querySelectorAll("[data-node-id]");
|
|
405
|
+
const selectedNodeIds = [];
|
|
406
|
+
|
|
407
|
+
const boxLeft = Math.min(box.startX, box.currentX);
|
|
408
|
+
const boxRight = Math.max(box.startX, box.currentX);
|
|
409
|
+
const boxTop = Math.min(box.startY, box.currentY);
|
|
410
|
+
const boxBottom = Math.max(box.startY, box.currentY);
|
|
411
|
+
|
|
412
|
+
nodes.forEach((node) => {
|
|
413
|
+
const rect = node.getBoundingClientRect();
|
|
414
|
+
|
|
415
|
+
if (
|
|
416
|
+
rect.left < boxRight &&
|
|
417
|
+
rect.right > boxLeft &&
|
|
418
|
+
rect.top < boxBottom &&
|
|
419
|
+
rect.bottom > boxTop
|
|
420
|
+
) {
|
|
421
|
+
const nodeId = node.getAttribute("data-node-id");
|
|
422
|
+
if (nodeId) selectedNodeIds.push(nodeId);
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
if (selectedNodeIds.length > 0) {
|
|
427
|
+
if (e.shiftKey) {
|
|
428
|
+
addToSelection(selectedNodeIds);
|
|
429
|
+
} else {
|
|
430
|
+
selectMultiple(selectedNodeIds);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
setSelectionBox(null);
|
|
436
|
+
selectionBoxRef.current = null;
|
|
437
|
+
window.removeEventListener("mousemove", onMove);
|
|
438
|
+
window.removeEventListener("mouseup", onUp);
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
window.addEventListener("mousemove", onMove);
|
|
442
|
+
window.addEventListener("mouseup", onUp);
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
clearSelection();
|
|
447
|
+
|
|
448
|
+
setIsDragging(true);
|
|
320
449
|
const startOffset = { ...offset };
|
|
321
450
|
|
|
322
451
|
const onMove = (ev) => {
|
|
@@ -338,6 +467,7 @@ const FlowNode = ({ isRoot = false, ...props }) => {
|
|
|
338
467
|
|
|
339
468
|
return (
|
|
340
469
|
<Box
|
|
470
|
+
ref={containerRef}
|
|
341
471
|
onMouseDown={handleCanvasMouseDown}
|
|
342
472
|
sx={{
|
|
343
473
|
width: "100vw",
|
|
@@ -349,6 +479,7 @@ const FlowNode = ({ isRoot = false, ...props }) => {
|
|
|
349
479
|
position: "relative",
|
|
350
480
|
}}
|
|
351
481
|
>
|
|
482
|
+
<SelectionBox box={selectionBox} selectionColor={selectionColor} />
|
|
352
483
|
<Box
|
|
353
484
|
sx={{
|
|
354
485
|
transform: `translate(${offset.x}px, ${offset.y}px) scale(${zoom})`,
|
|
@@ -362,10 +493,27 @@ const FlowNode = ({ isRoot = false, ...props }) => {
|
|
|
362
493
|
pointerEvents: "auto",
|
|
363
494
|
}}
|
|
364
495
|
>
|
|
365
|
-
|
|
496
|
+
{children}
|
|
366
497
|
</Box>
|
|
367
498
|
</Box>
|
|
368
499
|
);
|
|
369
500
|
};
|
|
370
501
|
|
|
502
|
+
const FlowNode = ({ isRoot = false, onAddNode, variant, ...props }) => {
|
|
503
|
+
if (!isRoot) {
|
|
504
|
+
return <NodeContent onAddNode={onAddNode} variant={variant} {...props} />;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
const baseStyle = getBaseStyleForVariant(variant);
|
|
508
|
+
const selectionColor = baseStyle.selectionColor ?? "#64748b";
|
|
509
|
+
|
|
510
|
+
return (
|
|
511
|
+
<SelectionProvider>
|
|
512
|
+
<FlowCanvas selectionColor={selectionColor}>
|
|
513
|
+
<NodeContent onAddNode={onAddNode} variant={variant} {...props} />
|
|
514
|
+
</FlowCanvas>
|
|
515
|
+
</SelectionProvider>
|
|
516
|
+
);
|
|
517
|
+
};
|
|
518
|
+
|
|
371
519
|
export default FlowNode;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
createContext,
|
|
3
|
+
useCallback,
|
|
4
|
+
useContext,
|
|
5
|
+
useRef,
|
|
6
|
+
useState,
|
|
7
|
+
} from "react";
|
|
8
|
+
|
|
9
|
+
const SelectionContext = createContext(null);
|
|
10
|
+
|
|
11
|
+
export const SelectionProvider = ({ children }) => {
|
|
12
|
+
const [selectedIds, setSelectedIds] = useState(new Set());
|
|
13
|
+
const nodeHandlersRef = useRef(new Map());
|
|
14
|
+
|
|
15
|
+
const selectNode = useCallback((id, addToSelection = false) => {
|
|
16
|
+
setSelectedIds((prev) => {
|
|
17
|
+
const next = new Set(addToSelection ? prev : []);
|
|
18
|
+
next.add(id);
|
|
19
|
+
return next;
|
|
20
|
+
});
|
|
21
|
+
}, []);
|
|
22
|
+
|
|
23
|
+
const deselectNode = useCallback((id) => {
|
|
24
|
+
setSelectedIds((prev) => {
|
|
25
|
+
const next = new Set(prev);
|
|
26
|
+
next.delete(id);
|
|
27
|
+
return next;
|
|
28
|
+
});
|
|
29
|
+
}, []);
|
|
30
|
+
|
|
31
|
+
const toggleSelection = useCallback((id) => {
|
|
32
|
+
setSelectedIds((prev) => {
|
|
33
|
+
const next = new Set(prev);
|
|
34
|
+
if (next.has(id)) {
|
|
35
|
+
next.delete(id);
|
|
36
|
+
} else {
|
|
37
|
+
next.add(id);
|
|
38
|
+
}
|
|
39
|
+
return next;
|
|
40
|
+
});
|
|
41
|
+
}, []);
|
|
42
|
+
|
|
43
|
+
const clearSelection = useCallback(() => {
|
|
44
|
+
setSelectedIds(new Set());
|
|
45
|
+
}, []);
|
|
46
|
+
|
|
47
|
+
const selectMultiple = useCallback((ids) => {
|
|
48
|
+
setSelectedIds(new Set(ids));
|
|
49
|
+
}, []);
|
|
50
|
+
|
|
51
|
+
const addToSelection = useCallback((ids) => {
|
|
52
|
+
setSelectedIds((prev) => new Set([...prev, ...ids]));
|
|
53
|
+
}, []);
|
|
54
|
+
|
|
55
|
+
const isSelected = useCallback((id) => selectedIds.has(id), [selectedIds]);
|
|
56
|
+
|
|
57
|
+
const registerNodeHandlers = useCallback((id, handlers) => {
|
|
58
|
+
nodeHandlersRef.current.set(id, handlers);
|
|
59
|
+
return () => nodeHandlersRef.current.delete(id);
|
|
60
|
+
}, []);
|
|
61
|
+
|
|
62
|
+
const moveSelectedNodes = useCallback(
|
|
63
|
+
(deltaX, deltaY, excludeId = null) => {
|
|
64
|
+
selectedIds.forEach((id) => {
|
|
65
|
+
if (id !== excludeId) {
|
|
66
|
+
const handlers = nodeHandlersRef.current.get(id);
|
|
67
|
+
if (handlers) {
|
|
68
|
+
if (handlers.setOffset) {
|
|
69
|
+
handlers.setOffset((prev) => ({
|
|
70
|
+
x: prev.x + deltaX,
|
|
71
|
+
y: prev.y + deltaY,
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
if (handlers.onDrag) {
|
|
75
|
+
handlers.onDrag();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
},
|
|
81
|
+
[selectedIds]
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<SelectionContext.Provider
|
|
86
|
+
value={{
|
|
87
|
+
selectedIds,
|
|
88
|
+
selectNode,
|
|
89
|
+
deselectNode,
|
|
90
|
+
toggleSelection,
|
|
91
|
+
clearSelection,
|
|
92
|
+
selectMultiple,
|
|
93
|
+
addToSelection,
|
|
94
|
+
isSelected,
|
|
95
|
+
registerNodeHandlers,
|
|
96
|
+
moveSelectedNodes,
|
|
97
|
+
}}
|
|
98
|
+
>
|
|
99
|
+
{children}
|
|
100
|
+
</SelectionContext.Provider>
|
|
101
|
+
);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export const useSelection = () => {
|
|
105
|
+
const context = useContext(SelectionContext);
|
|
106
|
+
if (!context) {
|
|
107
|
+
return {
|
|
108
|
+
selectedIds: new Set(),
|
|
109
|
+
selectNode: () => {},
|
|
110
|
+
deselectNode: () => {},
|
|
111
|
+
toggleSelection: () => {},
|
|
112
|
+
clearSelection: () => {},
|
|
113
|
+
selectMultiple: () => {},
|
|
114
|
+
addToSelection: () => {},
|
|
115
|
+
isSelected: () => false,
|
|
116
|
+
registerNodeHandlers: () => () => {},
|
|
117
|
+
moveSelectedNodes: () => {},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
return context;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export default SelectionContext;
|
|
@@ -9,12 +9,12 @@ const MainContainer = styled("div", {
|
|
|
9
9
|
shouldForwardProp: (prop) => prop !== "$style",
|
|
10
10
|
})(({ theme, $style = {} }) => {
|
|
11
11
|
const {
|
|
12
|
-
minWidth =
|
|
13
|
-
minHeight =
|
|
14
|
-
maxWidth =
|
|
15
|
-
maxHeight =
|
|
16
|
-
borderRadius =
|
|
17
|
-
borderColor = "rgba(255, 255, 255, 0.
|
|
12
|
+
minWidth = 280,
|
|
13
|
+
minHeight = 220,
|
|
14
|
+
maxWidth = 320,
|
|
15
|
+
maxHeight = "auto",
|
|
16
|
+
borderRadius = 20,
|
|
17
|
+
borderColor = "rgba(255, 255, 255, 0.08)",
|
|
18
18
|
bgFrom,
|
|
19
19
|
bgTo,
|
|
20
20
|
} = $style;
|
|
@@ -28,10 +28,11 @@ const MainContainer = styled("div", {
|
|
|
28
28
|
return {
|
|
29
29
|
display: "flex",
|
|
30
30
|
flexDirection: "column",
|
|
31
|
-
alignItems: "
|
|
31
|
+
alignItems: "flex-start",
|
|
32
|
+
justifyContent: "flex-start",
|
|
32
33
|
color: "#ffffff",
|
|
33
34
|
borderRadius,
|
|
34
|
-
padding: "
|
|
35
|
+
padding: "24px",
|
|
35
36
|
border: `1px solid ${borderColor}`,
|
|
36
37
|
backdropFilter: "blur(10px)",
|
|
37
38
|
transition: "all 0.4s cubic-bezier(0.4, 0, 0.2, 1)",
|
|
@@ -56,26 +57,38 @@ const MainContainer = styled("div", {
|
|
|
56
57
|
};
|
|
57
58
|
});
|
|
58
59
|
|
|
60
|
+
const HeaderRow = styled("div")({
|
|
61
|
+
display: "flex",
|
|
62
|
+
flexDirection: "row",
|
|
63
|
+
alignItems: "center",
|
|
64
|
+
width: "100%",
|
|
65
|
+
gap: "16px",
|
|
66
|
+
marginBottom: "16px",
|
|
67
|
+
minHeight: "44px",
|
|
68
|
+
});
|
|
69
|
+
|
|
59
70
|
const IconContainer = styled("div", {
|
|
60
71
|
shouldForwardProp: (prop) => prop !== "$style",
|
|
61
72
|
})(({ $style = {} }) => {
|
|
62
73
|
const {
|
|
63
74
|
bg = "rgba(255, 255, 255, 0.1)",
|
|
64
|
-
hoverBg = "rgba(255, 255, 255, 0.
|
|
65
|
-
borderRadius =
|
|
66
|
-
padding =
|
|
67
|
-
borderColor = "rgba(255, 255, 255, 0.
|
|
68
|
-
marginBottom = 12,
|
|
75
|
+
hoverBg = "rgba(255, 255, 255, 0.2)",
|
|
76
|
+
borderRadius = 14,
|
|
77
|
+
padding = 10,
|
|
78
|
+
borderColor = "rgba(255, 255, 255, 0.1)",
|
|
69
79
|
} = $style;
|
|
70
80
|
|
|
71
81
|
return {
|
|
72
82
|
backgroundColor: bg,
|
|
73
83
|
borderRadius,
|
|
74
84
|
padding,
|
|
75
|
-
marginBottom,
|
|
76
85
|
transition: "all 0.4s ease",
|
|
77
86
|
backdropFilter: "blur(5px)",
|
|
78
87
|
border: `1px solid ${borderColor}`,
|
|
88
|
+
flexShrink: 0,
|
|
89
|
+
display: "flex",
|
|
90
|
+
alignItems: "center",
|
|
91
|
+
justifyContent: "center",
|
|
79
92
|
|
|
80
93
|
'[data-hovered="true"] &': {
|
|
81
94
|
backgroundColor: hoverBg,
|
|
@@ -88,44 +101,90 @@ const LabelText = styled("div", {
|
|
|
88
101
|
})(({ $style = {} }) => {
|
|
89
102
|
const {
|
|
90
103
|
color = "#ffffff",
|
|
91
|
-
fontWeight =
|
|
92
|
-
fontSize =
|
|
93
|
-
letterSpacing = 0.
|
|
104
|
+
fontWeight = 700,
|
|
105
|
+
fontSize = 15,
|
|
106
|
+
letterSpacing = 0.3,
|
|
94
107
|
} = $style;
|
|
95
108
|
|
|
96
109
|
return {
|
|
97
110
|
fontWeight,
|
|
98
111
|
fontSize,
|
|
99
112
|
letterSpacing: `${letterSpacing}px`,
|
|
100
|
-
textAlign: "
|
|
113
|
+
textAlign: "left",
|
|
101
114
|
transition: "all 0.5s cubic-bezier(0.4, 0, 0.2, 1)",
|
|
102
|
-
|
|
103
|
-
lineHeight: "1.4",
|
|
115
|
+
lineHeight: "1.2",
|
|
104
116
|
opacity: 0,
|
|
105
|
-
transform: "
|
|
117
|
+
transform: "translateX(10px)",
|
|
106
118
|
color,
|
|
119
|
+
flex: 1,
|
|
107
120
|
|
|
108
121
|
'&[data-animated="true"]': {
|
|
109
122
|
opacity: 1,
|
|
110
|
-
transform: "
|
|
123
|
+
transform: "translateX(0)",
|
|
111
124
|
},
|
|
112
125
|
};
|
|
113
126
|
});
|
|
114
127
|
|
|
128
|
+
const DescriptionText = styled("div")(({ theme }) => ({
|
|
129
|
+
fontSize: "12px",
|
|
130
|
+
fontWeight: 400,
|
|
131
|
+
color: alpha("#fff", 0.6),
|
|
132
|
+
textAlign: "left",
|
|
133
|
+
lineHeight: "1.5",
|
|
134
|
+
width: "100%",
|
|
135
|
+
flex: 1,
|
|
136
|
+
opacity: 0,
|
|
137
|
+
transform: "translateY(10px)",
|
|
138
|
+
transition: "all 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s",
|
|
139
|
+
marginBottom: "16px",
|
|
140
|
+
display: "-webkit-box",
|
|
141
|
+
WebkitLineClamp: 4,
|
|
142
|
+
WebkitBoxOrient: "vertical",
|
|
143
|
+
overflow: "hidden",
|
|
144
|
+
|
|
145
|
+
'&[data-animated="true"]': {
|
|
146
|
+
opacity: 1,
|
|
147
|
+
transform: "translateY(0)",
|
|
148
|
+
},
|
|
149
|
+
}));
|
|
150
|
+
|
|
151
|
+
const ActionText = styled("div")(({ theme }) => ({
|
|
152
|
+
fontSize: "10px",
|
|
153
|
+
fontWeight: 700,
|
|
154
|
+
textTransform: "uppercase",
|
|
155
|
+
letterSpacing: "1px",
|
|
156
|
+
color: alpha("#fff", 0.4),
|
|
157
|
+
marginTop: "auto",
|
|
158
|
+
textAlign: "left",
|
|
159
|
+
width: "100%",
|
|
160
|
+
fontFamily: "monospace",
|
|
161
|
+
opacity: 0,
|
|
162
|
+
transform: "translateY(5px)",
|
|
163
|
+
transition: "all 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.2s",
|
|
164
|
+
|
|
165
|
+
'&[data-animated="true"]': {
|
|
166
|
+
opacity: 1,
|
|
167
|
+
transform: "translateY(0)",
|
|
168
|
+
},
|
|
169
|
+
}));
|
|
170
|
+
|
|
115
171
|
const getIcon = (node) => {
|
|
116
172
|
if (node.icon) return node.icon;
|
|
117
173
|
if (node.type === "CONDITION" || node.type === "decision")
|
|
118
174
|
return "mdi:help-circle-outline";
|
|
119
175
|
if (node.type === "NORMAL") return "mdi:checkbox-blank-circle-outline";
|
|
120
|
-
return "mdi:
|
|
176
|
+
return "mdi:map-marker";
|
|
121
177
|
};
|
|
122
178
|
|
|
123
|
-
const InfoNode = ({ node, nodeStyle = {} }) => {
|
|
179
|
+
const InfoNode = ({ node, nodeStyle = {}, children }) => {
|
|
124
180
|
const [animated, setAnimated] = useState(false);
|
|
125
181
|
const [isHovered, setIsHovered] = useState(false);
|
|
126
182
|
|
|
127
|
-
const label =
|
|
128
|
-
|
|
183
|
+
const label = node.label || node.title || node.name || node.id || "Get Data";
|
|
184
|
+
|
|
185
|
+
const action = node.action || "SYSTEM:DEFAULT_ACTION";
|
|
186
|
+
const description =
|
|
187
|
+
node.description || "Description of the operation goes here.";
|
|
129
188
|
|
|
130
189
|
useEffect(() => {
|
|
131
190
|
const timer = setTimeout(() => setAnimated(true), ANIMATION_DELAY_MS);
|
|
@@ -133,14 +192,9 @@ const InfoNode = ({ node, nodeStyle = {} }) => {
|
|
|
133
192
|
}, []);
|
|
134
193
|
|
|
135
194
|
const layoutStyle = {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
maxHeight: nodeStyle.maxHeight || 160,
|
|
140
|
-
borderRadius: typeof nodeStyle.shape === "number" ? nodeStyle.shape : 16,
|
|
141
|
-
borderColor: nodeStyle.borderColor || "rgba(255, 255, 255, 0.2)",
|
|
142
|
-
bgFrom: nodeStyle.bgFrom,
|
|
143
|
-
bgTo: nodeStyle.bgTo,
|
|
195
|
+
...nodeStyle,
|
|
196
|
+
minWidth: nodeStyle.cardWidth || nodeStyle.minWidth || 280,
|
|
197
|
+
minHeight: nodeStyle.minHeight || 220,
|
|
144
198
|
};
|
|
145
199
|
|
|
146
200
|
const iconContainerStyle = {
|
|
@@ -149,7 +203,6 @@ const InfoNode = ({ node, nodeStyle = {} }) => {
|
|
|
149
203
|
iconBorderRadius: nodeStyle.iconRadius,
|
|
150
204
|
iconPadding: nodeStyle.iconPadding,
|
|
151
205
|
iconBorderColor: nodeStyle.iconBorderColor,
|
|
152
|
-
iconMarginBottom: nodeStyle.iconMarginBottom,
|
|
153
206
|
};
|
|
154
207
|
|
|
155
208
|
const labelStyle = {
|
|
@@ -168,27 +221,33 @@ const InfoNode = ({ node, nodeStyle = {} }) => {
|
|
|
168
221
|
onMouseEnter={() => setIsHovered(true)}
|
|
169
222
|
onMouseLeave={() => setIsHovered(false)}
|
|
170
223
|
>
|
|
171
|
-
<
|
|
172
|
-
<
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
</
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
{
|
|
191
|
-
|
|
224
|
+
<HeaderRow>
|
|
225
|
+
<IconContainer $style={iconContainerStyle}>
|
|
226
|
+
<Iconify
|
|
227
|
+
icon={icon}
|
|
228
|
+
width={24}
|
|
229
|
+
height={24}
|
|
230
|
+
sx={{
|
|
231
|
+
filter: "none",
|
|
232
|
+
color: nodeStyle.iconColor || "#ffffff",
|
|
233
|
+
}}
|
|
234
|
+
/>
|
|
235
|
+
</IconContainer>
|
|
236
|
+
|
|
237
|
+
<LabelText data-animated={animated} $style={labelStyle}>
|
|
238
|
+
{label}
|
|
239
|
+
</LabelText>
|
|
240
|
+
</HeaderRow>
|
|
241
|
+
|
|
242
|
+
{description && (
|
|
243
|
+
<DescriptionText data-animated={animated}>
|
|
244
|
+
{description}
|
|
245
|
+
</DescriptionText>
|
|
246
|
+
)}
|
|
247
|
+
|
|
248
|
+
{action && <ActionText data-animated={animated}>{action}</ActionText>}
|
|
249
|
+
|
|
250
|
+
{children}
|
|
192
251
|
</MainContainer>
|
|
193
252
|
);
|
|
194
253
|
};
|