@pipelex/mthds-ui 0.32.0 → 0.33.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/README.md +3 -0
- package/dist/{chunk-T5Y7KNCZ.js → chunk-ABUDTHWF.js} +2 -2
- package/dist/{chunk-T5Y7KNCZ.js.map → chunk-ABUDTHWF.js.map} +1 -1
- package/dist/graph/index.js +1 -1
- package/dist/graph/react/graph-core.css +13 -0
- package/dist/graph/react/index.d.ts +14 -0
- package/dist/graph/react/index.js +191 -90
- package/dist/graph/react/index.js.map +1 -1
- package/dist/graph/react/styles/simple/SimpleStyle.css +9 -0
- package/dist/index.js +1 -1
- package/dist/standalone/graph-standalone.html +130 -108
- package/dist/standalone/graph-viewer.css +22 -0
- package/dist/standalone/graph-viewer.js +108 -108
- package/package.json +1 -1
package/dist/graph/index.js
CHANGED
|
@@ -105,6 +105,19 @@
|
|
|
105
105
|
inset: 0;
|
|
106
106
|
background: var(--color-bg);
|
|
107
107
|
}
|
|
108
|
+
/* The still presentation (`GraphViewer`'s `interactive={false}`): the drawing
|
|
109
|
+
is laid in the page like a picture. The container flows in its parent at the
|
|
110
|
+
height `StillFit` sets inline rather than filling a sized parent, shows the
|
|
111
|
+
host's surface through it, and takes no pointer event, so a click or the
|
|
112
|
+
wheel reaches the page beneath. `GraphViewer` also makes it `inert`, which no
|
|
113
|
+
descendant's own `pointer-events: auto` (a fold button's) can override. */
|
|
114
|
+
.react-flow-container--still {
|
|
115
|
+
position: relative;
|
|
116
|
+
inset: auto;
|
|
117
|
+
width: 100%;
|
|
118
|
+
background: transparent;
|
|
119
|
+
pointer-events: none;
|
|
120
|
+
}
|
|
108
121
|
.react-flow__node {
|
|
109
122
|
font-family: var(--font-sans);
|
|
110
123
|
cursor: pointer;
|
|
@@ -134,6 +134,20 @@ interface GraphViewerProps {
|
|
|
134
134
|
initialFoldMode?: FoldMode;
|
|
135
135
|
/** Hide the built-in floating toolbar (direction + controllers toggle). */
|
|
136
136
|
hideToolbar?: boolean;
|
|
137
|
+
/**
|
|
138
|
+
* `false` draws the graph as a still picture laid in the page, for a host
|
|
139
|
+
* that shows a method's flowchart before anyone asks to explore it: nothing
|
|
140
|
+
* pans, zooms, drags or selects, the drawing is `inert` so no button in it
|
|
141
|
+
* takes a click or the keyboard, a click opens no detail panel and fires no
|
|
142
|
+
* callback, the wheel scrolls the page, and there is no background, no toolbar
|
|
143
|
+
* and no detail panel. The drawing is fitted to the container's width, never
|
|
144
|
+
* past its natural size, and the container takes the height the drawing
|
|
145
|
+
* needs, so the host gives it a width and no height. Defaults to `true`, the
|
|
146
|
+
* interactive canvas. Reactive: a host switching to `true` gets the canvas,
|
|
147
|
+
* fitted to view, and must then size its parent as for any canvas. See
|
|
148
|
+
* `docs/still-presentation.md`.
|
|
149
|
+
*/
|
|
150
|
+
interactive?: boolean;
|
|
137
151
|
/**
|
|
138
152
|
* Theme *mode*: `dark | light | system`. Reactive: passing it as a prop drives
|
|
139
153
|
* the active mode, and clearing it back to `undefined` hands control back to
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
roundedPolylinePath,
|
|
22
22
|
routeLabelCenter,
|
|
23
23
|
validateGraphSpec
|
|
24
|
-
} from "../../chunk-
|
|
24
|
+
} from "../../chunk-ABUDTHWF.js";
|
|
25
25
|
import {
|
|
26
26
|
parsePipeRef
|
|
27
27
|
} from "../../chunk-2N65P32H.js";
|
|
@@ -68,7 +68,7 @@ import "./viewer/GraphToolbar.css";
|
|
|
68
68
|
import "./styles/simple/SimpleStyle.css";
|
|
69
69
|
|
|
70
70
|
// src/graph/react/viewer/GraphViewer.tsx
|
|
71
|
-
import
|
|
71
|
+
import React13 from "react";
|
|
72
72
|
import {
|
|
73
73
|
ReactFlow,
|
|
74
74
|
useNodesState,
|
|
@@ -2556,6 +2556,71 @@ function GraphToolbar({
|
|
|
2556
2556
|
] }) });
|
|
2557
2557
|
}
|
|
2558
2558
|
|
|
2559
|
+
// src/graph/react/viewer/StillFit.tsx
|
|
2560
|
+
import React11 from "react";
|
|
2561
|
+
import { useEdges, useNodes, useNodesInitialized, useReactFlow, useStore } from "@xyflow/react";
|
|
2562
|
+
|
|
2563
|
+
// src/graph/react/viewer/stillViewport.ts
|
|
2564
|
+
var STILL_PADDING_PX = 16;
|
|
2565
|
+
var STILL_PLACEHOLDER_HEIGHT_PX = 120;
|
|
2566
|
+
function stillContentBounds(nodeBounds, routes) {
|
|
2567
|
+
let minX = nodeBounds.x;
|
|
2568
|
+
let minY = nodeBounds.y;
|
|
2569
|
+
let maxX = nodeBounds.x + nodeBounds.width;
|
|
2570
|
+
let maxY = nodeBounds.y + nodeBounds.height;
|
|
2571
|
+
const take = (x, y) => {
|
|
2572
|
+
if (!Number.isFinite(x) || !Number.isFinite(y)) return;
|
|
2573
|
+
minX = Math.min(minX, x);
|
|
2574
|
+
minY = Math.min(minY, y);
|
|
2575
|
+
maxX = Math.max(maxX, x);
|
|
2576
|
+
maxY = Math.max(maxY, y);
|
|
2577
|
+
};
|
|
2578
|
+
for (const route of routes) {
|
|
2579
|
+
if (!route) continue;
|
|
2580
|
+
for (const point of route.points) take(point.x, point.y);
|
|
2581
|
+
if (route.label) {
|
|
2582
|
+
take(route.label.x, route.label.y);
|
|
2583
|
+
take(route.label.x + route.label.width, route.label.y + route.label.height);
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
|
|
2587
|
+
}
|
|
2588
|
+
function stillViewport(bounds, containerWidth, padding = STILL_PADDING_PX) {
|
|
2589
|
+
if (!(containerWidth > 0) || !(bounds.width > 0) || !(bounds.height > 0)) return null;
|
|
2590
|
+
const room = Math.max(containerWidth - 2 * padding, 1);
|
|
2591
|
+
const zoom = Math.min(1, room / bounds.width);
|
|
2592
|
+
return {
|
|
2593
|
+
x: (containerWidth - bounds.width * zoom) / 2 - bounds.x * zoom,
|
|
2594
|
+
y: padding - bounds.y * zoom,
|
|
2595
|
+
zoom,
|
|
2596
|
+
height: Math.ceil(bounds.height * zoom + 2 * padding)
|
|
2597
|
+
};
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2600
|
+
// src/graph/react/viewer/StillFit.tsx
|
|
2601
|
+
function StillFit({ onHeight }) {
|
|
2602
|
+
const width = useStore((s) => s.width);
|
|
2603
|
+
const nodesInitialized = useNodesInitialized();
|
|
2604
|
+
const nodes = useNodes();
|
|
2605
|
+
const edges = useEdges();
|
|
2606
|
+
const { getNodesBounds, setViewport } = useReactFlow();
|
|
2607
|
+
React11.useLayoutEffect(() => {
|
|
2608
|
+
if (!nodesInitialized || nodes.length === 0) return;
|
|
2609
|
+
const bounds = stillContentBounds(
|
|
2610
|
+
getNodesBounds(nodes),
|
|
2611
|
+
edges.map((e) => {
|
|
2612
|
+
var _a;
|
|
2613
|
+
return (_a = e.data) == null ? void 0 : _a.route;
|
|
2614
|
+
})
|
|
2615
|
+
);
|
|
2616
|
+
const view = stillViewport(bounds, width);
|
|
2617
|
+
if (!view) return;
|
|
2618
|
+
void setViewport({ x: view.x, y: view.y, zoom: view.zoom });
|
|
2619
|
+
onHeight(view.height);
|
|
2620
|
+
}, [nodesInitialized, nodes, edges, width, getNodesBounds, setViewport, onHeight]);
|
|
2621
|
+
return null;
|
|
2622
|
+
}
|
|
2623
|
+
|
|
2559
2624
|
// src/graph/react/nodes/NodeValidationBadge.tsx
|
|
2560
2625
|
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
2561
2626
|
function NodeValidationBadge({
|
|
@@ -3213,6 +3278,19 @@ var nodeTypes = __spreadValues(__spreadProps(__spreadValues({}, controllerNodeTy
|
|
|
3213
3278
|
pipeCard: PipeCardRFNode
|
|
3214
3279
|
}), simpleNodeTypes);
|
|
3215
3280
|
var edgeTypes = { [EDGE_TYPE_ROUTED]: RoutedEdge };
|
|
3281
|
+
var STILL_FLOW_PROPS = {
|
|
3282
|
+
panOnDrag: false,
|
|
3283
|
+
zoomOnScroll: false,
|
|
3284
|
+
zoomOnPinch: false,
|
|
3285
|
+
zoomOnDoubleClick: false,
|
|
3286
|
+
preventScrolling: false,
|
|
3287
|
+
nodesDraggable: false,
|
|
3288
|
+
nodesConnectable: false,
|
|
3289
|
+
nodesFocusable: false,
|
|
3290
|
+
edgesFocusable: false,
|
|
3291
|
+
elementsSelectable: false,
|
|
3292
|
+
disableKeyboardA11y: true
|
|
3293
|
+
};
|
|
3216
3294
|
function StuffNodeDetail({
|
|
3217
3295
|
nodeId,
|
|
3218
3296
|
stuffData,
|
|
@@ -3316,6 +3394,7 @@ function GraphViewer(props) {
|
|
|
3316
3394
|
initialShowControllers,
|
|
3317
3395
|
initialFoldMode,
|
|
3318
3396
|
hideToolbar = false,
|
|
3397
|
+
interactive = true,
|
|
3319
3398
|
theme: themeProp,
|
|
3320
3399
|
graphStyle: graphStyleProp,
|
|
3321
3400
|
onGraphStyleChange,
|
|
@@ -3340,20 +3419,20 @@ function GraphViewer(props) {
|
|
|
3340
3419
|
onValidationIssueClick
|
|
3341
3420
|
} = props;
|
|
3342
3421
|
const graphspecProp = (_a = graph == null ? void 0 : graph.graphSpec) != null ? _a : null;
|
|
3343
|
-
const graphspec =
|
|
3422
|
+
const graphspec = React13.useMemo(
|
|
3344
3423
|
() => graphspecProp === null ? null : validateGraphSpec(graphspecProp),
|
|
3345
3424
|
[graphspecProp]
|
|
3346
3425
|
);
|
|
3347
|
-
const [direction, setDirection] =
|
|
3426
|
+
const [direction, setDirection] = React13.useState(
|
|
3348
3427
|
() => {
|
|
3349
3428
|
var _a2, _b2;
|
|
3350
3429
|
return (_b2 = (_a2 = initialDirection != null ? initialDirection : config.direction) != null ? _a2 : DEFAULT_GRAPH_CONFIG.direction) != null ? _b2 : GRAPH_DIRECTION.TB;
|
|
3351
3430
|
}
|
|
3352
3431
|
);
|
|
3353
3432
|
const externalMode = resolveExternalThemeMode(themeProp, config.theme);
|
|
3354
|
-
const [mode, setMode] =
|
|
3355
|
-
const prevExternalModeRef =
|
|
3356
|
-
|
|
3433
|
+
const [mode, setMode] = React13.useState(externalMode);
|
|
3434
|
+
const prevExternalModeRef = React13.useRef(externalMode);
|
|
3435
|
+
React13.useEffect(() => {
|
|
3357
3436
|
if (externalMode !== prevExternalModeRef.current) {
|
|
3358
3437
|
prevExternalModeRef.current = externalMode;
|
|
3359
3438
|
setMode(externalMode);
|
|
@@ -3361,13 +3440,13 @@ function GraphViewer(props) {
|
|
|
3361
3440
|
}, [externalMode]);
|
|
3362
3441
|
const systemTheme = useSystemTheme(systemThemeProp);
|
|
3363
3442
|
const resolvedTheme = resolveActiveTheme(mode, systemTheme);
|
|
3364
|
-
const onThemeChangeRef =
|
|
3443
|
+
const onThemeChangeRef = React13.useRef(onThemeChange);
|
|
3365
3444
|
onThemeChangeRef.current = onThemeChange;
|
|
3366
|
-
const prevReportedRef =
|
|
3445
|
+
const prevReportedRef = React13.useRef({
|
|
3367
3446
|
mode,
|
|
3368
3447
|
resolvedTheme
|
|
3369
3448
|
});
|
|
3370
|
-
|
|
3449
|
+
React13.useEffect(() => {
|
|
3371
3450
|
var _a2;
|
|
3372
3451
|
const prev = prevReportedRef.current;
|
|
3373
3452
|
if (prev.mode !== mode || prev.resolvedTheme !== resolvedTheme) {
|
|
@@ -3376,48 +3455,48 @@ function GraphViewer(props) {
|
|
|
3376
3455
|
}
|
|
3377
3456
|
}, [mode, resolvedTheme]);
|
|
3378
3457
|
const externalStyle = resolveGraphStyle(graphStyleProp, config.graphStyle);
|
|
3379
|
-
const [graphStyle, setGraphStyle] =
|
|
3380
|
-
const prevExternalStyleRef =
|
|
3381
|
-
|
|
3458
|
+
const [graphStyle, setGraphStyle] = React13.useState(externalStyle);
|
|
3459
|
+
const prevExternalStyleRef = React13.useRef(externalStyle);
|
|
3460
|
+
React13.useEffect(() => {
|
|
3382
3461
|
if (externalStyle !== prevExternalStyleRef.current) {
|
|
3383
3462
|
prevExternalStyleRef.current = externalStyle;
|
|
3384
3463
|
setGraphStyle(externalStyle);
|
|
3385
3464
|
}
|
|
3386
3465
|
}, [externalStyle]);
|
|
3387
|
-
const onGraphStyleChangeRef =
|
|
3466
|
+
const onGraphStyleChangeRef = React13.useRef(onGraphStyleChange);
|
|
3388
3467
|
onGraphStyleChangeRef.current = onGraphStyleChange;
|
|
3389
|
-
const prevReportedStyleRef =
|
|
3390
|
-
|
|
3468
|
+
const prevReportedStyleRef = React13.useRef(graphStyle);
|
|
3469
|
+
React13.useEffect(() => {
|
|
3391
3470
|
var _a2;
|
|
3392
3471
|
if (prevReportedStyleRef.current !== graphStyle) {
|
|
3393
3472
|
prevReportedStyleRef.current = graphStyle;
|
|
3394
3473
|
(_a2 = onGraphStyleChangeRef.current) == null ? void 0 : _a2.call(onGraphStyleChangeRef, graphStyle);
|
|
3395
3474
|
}
|
|
3396
3475
|
}, [graphStyle]);
|
|
3397
|
-
const graphStyleRef =
|
|
3476
|
+
const graphStyleRef = React13.useRef(graphStyle);
|
|
3398
3477
|
graphStyleRef.current = graphStyle;
|
|
3399
3478
|
const styleCapabilities = GRAPH_STYLES[graphStyle].capabilities;
|
|
3400
3479
|
const effectiveFoldMode = (_c = (_b = initialFoldMode != null ? initialFoldMode : config.foldMode) != null ? _b : DEFAULT_GRAPH_CONFIG.foldMode) != null ? _c : FOLD_MODE.EXPANDED;
|
|
3401
|
-
const [showControllers, setShowControllers] =
|
|
3480
|
+
const [showControllers, setShowControllers] = React13.useState(() => {
|
|
3402
3481
|
var _a2, _b2;
|
|
3403
3482
|
if (effectiveFoldMode === FOLD_MODE.FOLDED) return true;
|
|
3404
3483
|
return (_b2 = (_a2 = initialShowControllers != null ? initialShowControllers : config.showControllers) != null ? _a2 : DEFAULT_GRAPH_CONFIG.showControllers) != null ? _b2 : false;
|
|
3405
3484
|
});
|
|
3406
|
-
const foldModeRef =
|
|
3485
|
+
const foldModeRef = React13.useRef(effectiveFoldMode);
|
|
3407
3486
|
foldModeRef.current = effectiveFoldMode;
|
|
3408
|
-
const containerRef =
|
|
3409
|
-
const [detailSelection, setDetailSelection] =
|
|
3410
|
-
const [conceptOverride, setConceptOverride] =
|
|
3487
|
+
const containerRef = React13.useRef(null);
|
|
3488
|
+
const [detailSelection, setDetailSelection] = React13.useState(null);
|
|
3489
|
+
const [conceptOverride, setConceptOverride] = React13.useState(null);
|
|
3411
3490
|
const {
|
|
3412
3491
|
width: panelWidth,
|
|
3413
3492
|
isDragging: isPanelDragging,
|
|
3414
3493
|
handleMouseDown: onResizeMouseDown
|
|
3415
3494
|
} = useResizable({ defaultWidth: 380, minWidth: 280, maxWidth: 800, containerRef });
|
|
3416
|
-
|
|
3495
|
+
React13.useEffect(() => {
|
|
3417
3496
|
setDetailSelection(null);
|
|
3418
3497
|
setConceptOverride(null);
|
|
3419
3498
|
}, [graphspec]);
|
|
3420
|
-
|
|
3499
|
+
React13.useEffect(() => {
|
|
3421
3500
|
const el = containerRef.current;
|
|
3422
3501
|
if (!el) return;
|
|
3423
3502
|
const themePalette = getPaletteForTheme(resolvedTheme);
|
|
@@ -3432,14 +3511,15 @@ function GraphViewer(props) {
|
|
|
3432
3511
|
}
|
|
3433
3512
|
};
|
|
3434
3513
|
}, [config.paletteColors, resolvedTheme]);
|
|
3514
|
+
const [stillHeight, setStillHeight] = React13.useState(STILL_PLACEHOLDER_HEIGHT_PX);
|
|
3435
3515
|
const [nodes, setNodes, onNodesChange] = useNodesState([]);
|
|
3436
3516
|
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
|
|
3437
|
-
const reactFlowRef =
|
|
3438
|
-
const initialDataRef =
|
|
3439
|
-
const rawGraphDataRef =
|
|
3440
|
-
const layoutCacheRef =
|
|
3441
|
-
const [expandedControllers, setExpandedControllers] =
|
|
3442
|
-
const toggleCollapse =
|
|
3517
|
+
const reactFlowRef = React13.useRef(null);
|
|
3518
|
+
const initialDataRef = React13.useRef(null);
|
|
3519
|
+
const rawGraphDataRef = React13.useRef(null);
|
|
3520
|
+
const layoutCacheRef = React13.useRef(null);
|
|
3521
|
+
const [expandedControllers, setExpandedControllers] = React13.useState(/* @__PURE__ */ new Set());
|
|
3522
|
+
const toggleCollapse = React13.useCallback((controllerId) => {
|
|
3443
3523
|
setExpandedControllers((prev) => {
|
|
3444
3524
|
const next = new Set(prev);
|
|
3445
3525
|
if (next.has(controllerId)) next.delete(controllerId);
|
|
@@ -3447,17 +3527,17 @@ function GraphViewer(props) {
|
|
|
3447
3527
|
return next;
|
|
3448
3528
|
});
|
|
3449
3529
|
}, []);
|
|
3450
|
-
const [foldedControllers, setFoldedControllers] =
|
|
3451
|
-
const styleDefaultFoldsRef =
|
|
3452
|
-
const readerOpenedRef =
|
|
3453
|
-
const markReaderFolds =
|
|
3530
|
+
const [foldedControllers, setFoldedControllers] = React13.useState(/* @__PURE__ */ new Set());
|
|
3531
|
+
const styleDefaultFoldsRef = React13.useRef(/* @__PURE__ */ new Set());
|
|
3532
|
+
const readerOpenedRef = React13.useRef(/* @__PURE__ */ new Set());
|
|
3533
|
+
const markReaderFolds = React13.useCallback((ids, folded) => {
|
|
3454
3534
|
for (const id of ids) {
|
|
3455
3535
|
styleDefaultFoldsRef.current.delete(id);
|
|
3456
3536
|
if (folded) readerOpenedRef.current.delete(id);
|
|
3457
3537
|
else readerOpenedRef.current.add(id);
|
|
3458
3538
|
}
|
|
3459
3539
|
}, []);
|
|
3460
|
-
const toggleFold =
|
|
3540
|
+
const toggleFold = React13.useCallback(
|
|
3461
3541
|
(controllerId, options) => {
|
|
3462
3542
|
setFoldedControllers((prev) => {
|
|
3463
3543
|
const next = new Set(prev);
|
|
@@ -3475,43 +3555,45 @@ function GraphViewer(props) {
|
|
|
3475
3555
|
[markReaderFolds]
|
|
3476
3556
|
);
|
|
3477
3557
|
const edgeType = config.edgeType || EDGE_TYPE.DEFAULT;
|
|
3478
|
-
const layoutConfig =
|
|
3558
|
+
const layoutConfig = React13.useMemo(
|
|
3479
3559
|
() => ({ nodesep: config.nodesep, ranksep: config.ranksep }),
|
|
3480
3560
|
[config.nodesep, config.ranksep]
|
|
3481
3561
|
);
|
|
3482
|
-
const showControllersRef =
|
|
3562
|
+
const showControllersRef = React13.useRef(showControllers);
|
|
3483
3563
|
showControllersRef.current = showControllers;
|
|
3484
|
-
const directionRef =
|
|
3564
|
+
const directionRef = React13.useRef(direction);
|
|
3485
3565
|
directionRef.current = direction;
|
|
3486
|
-
const layoutConfigRef =
|
|
3566
|
+
const layoutConfigRef = React13.useRef(layoutConfig);
|
|
3487
3567
|
layoutConfigRef.current = layoutConfig;
|
|
3488
|
-
const initialZoomRef =
|
|
3568
|
+
const initialZoomRef = React13.useRef(config.initialZoom);
|
|
3489
3569
|
initialZoomRef.current = config.initialZoom;
|
|
3490
|
-
const panToTopRef =
|
|
3570
|
+
const panToTopRef = React13.useRef(config.panToTop);
|
|
3491
3571
|
panToTopRef.current = config.panToTop;
|
|
3492
|
-
const
|
|
3572
|
+
const interactiveRef = React13.useRef(interactive);
|
|
3573
|
+
interactiveRef.current = interactive;
|
|
3574
|
+
const expandedRef = React13.useRef(expandedControllers);
|
|
3493
3575
|
expandedRef.current = expandedControllers;
|
|
3494
|
-
const toggleCollapseRef =
|
|
3576
|
+
const toggleCollapseRef = React13.useRef(toggleCollapse);
|
|
3495
3577
|
toggleCollapseRef.current = toggleCollapse;
|
|
3496
|
-
const foldedRef =
|
|
3578
|
+
const foldedRef = React13.useRef(foldedControllers);
|
|
3497
3579
|
foldedRef.current = foldedControllers;
|
|
3498
|
-
const toggleFoldRef =
|
|
3580
|
+
const toggleFoldRef = React13.useRef(toggleFold);
|
|
3499
3581
|
toggleFoldRef.current = toggleFold;
|
|
3500
|
-
const isFirstFoldEffect =
|
|
3501
|
-
const prevFoldSizeRef =
|
|
3502
|
-
const skipNextFoldEffectRef =
|
|
3503
|
-
const statusMapRef =
|
|
3582
|
+
const isFirstFoldEffect = React13.useRef(true);
|
|
3583
|
+
const prevFoldSizeRef = React13.useRef(0);
|
|
3584
|
+
const skipNextFoldEffectRef = React13.useRef(false);
|
|
3585
|
+
const statusMapRef = React13.useRef(statusMap);
|
|
3504
3586
|
statusMapRef.current = statusMap;
|
|
3505
|
-
const validationIssuesRef =
|
|
3587
|
+
const validationIssuesRef = React13.useRef(validationIssues);
|
|
3506
3588
|
validationIssuesRef.current = validationIssues;
|
|
3507
|
-
const selectedNodeIdRef =
|
|
3589
|
+
const selectedNodeIdRef = React13.useRef(null);
|
|
3508
3590
|
selectedNodeIdRef.current = (_d = detailSelection == null ? void 0 : detailSelection.nodeId) != null ? _d : null;
|
|
3509
|
-
const [validationOpen, setValidationOpen] =
|
|
3510
|
-
const openValidationPanel =
|
|
3511
|
-
const validationWidgetAvailable = validationState !== void 0 && !hideToolbar;
|
|
3512
|
-
const validationWidgetAvailableRef =
|
|
3591
|
+
const [validationOpen, setValidationOpen] = React13.useState(false);
|
|
3592
|
+
const openValidationPanel = React13.useCallback(() => setValidationOpen(true), []);
|
|
3593
|
+
const validationWidgetAvailable = validationState !== void 0 && !hideToolbar && interactive;
|
|
3594
|
+
const validationWidgetAvailableRef = React13.useRef(validationWidgetAvailable);
|
|
3513
3595
|
validationWidgetAvailableRef.current = validationWidgetAvailable;
|
|
3514
|
-
const decorateNodes =
|
|
3596
|
+
const decorateNodes = React13.useCallback(
|
|
3515
3597
|
(nodes2) => {
|
|
3516
3598
|
var _a2, _b2, _c2;
|
|
3517
3599
|
const raw = rawGraphDataRef.current;
|
|
@@ -3532,7 +3614,7 @@ function GraphViewer(props) {
|
|
|
3532
3614
|
},
|
|
3533
3615
|
[openValidationPanel]
|
|
3534
3616
|
);
|
|
3535
|
-
const frameLayout =
|
|
3617
|
+
const frameLayout = React13.useCallback(
|
|
3536
3618
|
(style, layout, graphspec2, analysis) => GRAPH_STYLE_PIPELINES[style].frame({
|
|
3537
3619
|
nodes: cloneCachedNodes(layout.nodes),
|
|
3538
3620
|
edges: layout.edges,
|
|
@@ -3551,18 +3633,18 @@ function GraphViewer(props) {
|
|
|
3551
3633
|
const data = initialDataRef.current;
|
|
3552
3634
|
return cache !== null && data !== null && cache.graphspec === data._graphspec && cache.graphStyle === data._graphStyle;
|
|
3553
3635
|
};
|
|
3554
|
-
const nodesRef =
|
|
3636
|
+
const nodesRef = React13.useRef([]);
|
|
3555
3637
|
nodesRef.current = nodes;
|
|
3556
|
-
const onValidationIssueClickRef =
|
|
3638
|
+
const onValidationIssueClickRef = React13.useRef(onValidationIssueClick);
|
|
3557
3639
|
onValidationIssueClickRef.current = onValidationIssueClick;
|
|
3558
|
-
const flashTimeoutRef =
|
|
3559
|
-
|
|
3640
|
+
const flashTimeoutRef = React13.useRef(null);
|
|
3641
|
+
React13.useEffect(
|
|
3560
3642
|
() => () => {
|
|
3561
3643
|
if (flashTimeoutRef.current) clearTimeout(flashTimeoutRef.current);
|
|
3562
3644
|
},
|
|
3563
3645
|
[]
|
|
3564
3646
|
);
|
|
3565
|
-
const handleValidationIssueClick =
|
|
3647
|
+
const handleValidationIssueClick = React13.useCallback(
|
|
3566
3648
|
(index, issue) => {
|
|
3567
3649
|
var _a2, _b2, _c2;
|
|
3568
3650
|
(_a2 = onValidationIssueClickRef.current) == null ? void 0 : _a2.call(onValidationIssueClickRef, index, issue);
|
|
@@ -3605,7 +3687,7 @@ function GraphViewer(props) {
|
|
|
3605
3687
|
},
|
|
3606
3688
|
[setNodes]
|
|
3607
3689
|
);
|
|
3608
|
-
|
|
3690
|
+
React13.useEffect(() => {
|
|
3609
3691
|
if (!initialDataRef.current) return;
|
|
3610
3692
|
let cancelled = false;
|
|
3611
3693
|
void (async () => {
|
|
@@ -3638,7 +3720,7 @@ function GraphViewer(props) {
|
|
|
3638
3720
|
setNodes(decorateNodes(withControllers.nodes));
|
|
3639
3721
|
setEdges(toAppEdges(withControllers.edges));
|
|
3640
3722
|
setTimeout(() => {
|
|
3641
|
-
if (!cancelled && reactFlowRef.current) {
|
|
3723
|
+
if (!cancelled && reactFlowRef.current && interactiveRef.current) {
|
|
3642
3724
|
void reactFlowRef.current.fitView({ padding: 0.1 });
|
|
3643
3725
|
}
|
|
3644
3726
|
}, 50);
|
|
@@ -3650,7 +3732,7 @@ function GraphViewer(props) {
|
|
|
3650
3732
|
cancelled = true;
|
|
3651
3733
|
};
|
|
3652
3734
|
}, [direction, layoutConfig]);
|
|
3653
|
-
|
|
3735
|
+
React13.useEffect(() => {
|
|
3654
3736
|
const cache = layoutCacheRef.current;
|
|
3655
3737
|
const data = initialDataRef.current;
|
|
3656
3738
|
if (!cache || !data || !cacheMatchesData()) return;
|
|
@@ -3658,7 +3740,7 @@ function GraphViewer(props) {
|
|
|
3658
3740
|
setNodes(decorateNodes(withControllers.nodes));
|
|
3659
3741
|
setEdges(toAppEdges(withControllers.edges));
|
|
3660
3742
|
}, [showControllers, expandedControllers, toggleCollapse, toggleFold, decorateNodes]);
|
|
3661
|
-
|
|
3743
|
+
React13.useEffect(() => {
|
|
3662
3744
|
var _a2;
|
|
3663
3745
|
if (!graphspec) {
|
|
3664
3746
|
initialDataRef.current = null;
|
|
@@ -3758,7 +3840,7 @@ function GraphViewer(props) {
|
|
|
3758
3840
|
setNodes(decorateNodes(withControllers.nodes));
|
|
3759
3841
|
setEdges(toAppEdges(withControllers.edges));
|
|
3760
3842
|
setTimeout(() => {
|
|
3761
|
-
if (!cancelled && reactFlowRef.current) {
|
|
3843
|
+
if (!cancelled && reactFlowRef.current && interactiveRef.current) {
|
|
3762
3844
|
void reactFlowRef.current.fitView({ padding: 0.1 });
|
|
3763
3845
|
if (initialZoomRef.current !== void 0 && initialZoomRef.current !== null) {
|
|
3764
3846
|
void reactFlowRef.current.zoomTo(initialZoomRef.current);
|
|
@@ -3777,7 +3859,7 @@ function GraphViewer(props) {
|
|
|
3777
3859
|
cancelled = true;
|
|
3778
3860
|
};
|
|
3779
3861
|
}, [graphspec, edgeType, graphStyle]);
|
|
3780
|
-
|
|
3862
|
+
React13.useEffect(() => {
|
|
3781
3863
|
if (isFirstFoldEffect.current) {
|
|
3782
3864
|
isFirstFoldEffect.current = false;
|
|
3783
3865
|
prevFoldSizeRef.current = foldedControllers.size;
|
|
@@ -3842,7 +3924,7 @@ function GraphViewer(props) {
|
|
|
3842
3924
|
setNodes(decorateNodes(withControllers.nodes));
|
|
3843
3925
|
setEdges(toAppEdges(withControllers.edges));
|
|
3844
3926
|
setTimeout(() => {
|
|
3845
|
-
if (!cancelled && reactFlowRef.current) {
|
|
3927
|
+
if (!cancelled && reactFlowRef.current && interactiveRef.current) {
|
|
3846
3928
|
void reactFlowRef.current.fitView({ padding: 0.1 });
|
|
3847
3929
|
}
|
|
3848
3930
|
}, 50);
|
|
@@ -3854,7 +3936,7 @@ function GraphViewer(props) {
|
|
|
3854
3936
|
cancelled = true;
|
|
3855
3937
|
};
|
|
3856
3938
|
}, [foldedControllers, toggleFold]);
|
|
3857
|
-
|
|
3939
|
+
React13.useEffect(() => {
|
|
3858
3940
|
const cache = layoutCacheRef.current;
|
|
3859
3941
|
const data = initialDataRef.current;
|
|
3860
3942
|
if (!cache || !data || !cacheMatchesData()) return;
|
|
@@ -3862,14 +3944,14 @@ function GraphViewer(props) {
|
|
|
3862
3944
|
setNodes(decorateNodes(withControllers.nodes));
|
|
3863
3945
|
setEdges(toAppEdges(withControllers.edges));
|
|
3864
3946
|
}, [statusMap, decorateNodes]);
|
|
3865
|
-
|
|
3947
|
+
React13.useEffect(() => {
|
|
3866
3948
|
const cache = layoutCacheRef.current;
|
|
3867
3949
|
const data = initialDataRef.current;
|
|
3868
3950
|
if (!cache || !data || !cacheMatchesData()) return;
|
|
3869
3951
|
const withControllers = frameLayout(cache.graphStyle, cache, data._graphspec, data._analysis);
|
|
3870
3952
|
setNodes(decorateNodes(withControllers.nodes));
|
|
3871
3953
|
}, [validationIssues, validationWidgetAvailable, decorateNodes]);
|
|
3872
|
-
const onNodeClick =
|
|
3954
|
+
const onNodeClick = React13.useCallback(
|
|
3873
3955
|
(event, node) => {
|
|
3874
3956
|
const nodeData = node.data;
|
|
3875
3957
|
onNodeSelect == null ? void 0 : onNodeSelect(node.id, nodeData, event);
|
|
@@ -3910,7 +3992,7 @@ function GraphViewer(props) {
|
|
|
3910
3992
|
conceptOverride
|
|
3911
3993
|
]
|
|
3912
3994
|
);
|
|
3913
|
-
const onInit =
|
|
3995
|
+
const onInit = React13.useCallback(
|
|
3914
3996
|
(reactFlowInstance) => {
|
|
3915
3997
|
reactFlowRef.current = reactFlowInstance;
|
|
3916
3998
|
if (onReactFlowInit) {
|
|
@@ -3919,12 +4001,28 @@ function GraphViewer(props) {
|
|
|
3919
4001
|
},
|
|
3920
4002
|
[onReactFlowInit]
|
|
3921
4003
|
);
|
|
3922
|
-
const
|
|
4004
|
+
const prevInteractiveRef = React13.useRef(interactive);
|
|
4005
|
+
React13.useEffect(() => {
|
|
4006
|
+
if (prevInteractiveRef.current === interactive) return;
|
|
4007
|
+
prevInteractiveRef.current = interactive;
|
|
4008
|
+
if (!interactive) {
|
|
4009
|
+
setDetailSelection(null);
|
|
4010
|
+
setConceptOverride(null);
|
|
4011
|
+
setValidationOpen(false);
|
|
4012
|
+
return;
|
|
4013
|
+
}
|
|
4014
|
+
const timer = setTimeout(() => {
|
|
4015
|
+
var _a2;
|
|
4016
|
+
void ((_a2 = reactFlowRef.current) == null ? void 0 : _a2.fitView({ padding: 0.1 }));
|
|
4017
|
+
}, 50);
|
|
4018
|
+
return () => clearTimeout(timer);
|
|
4019
|
+
}, [interactive]);
|
|
4020
|
+
const handlePaneClick = React13.useCallback(() => {
|
|
3923
4021
|
setDetailSelection(null);
|
|
3924
4022
|
setConceptOverride(null);
|
|
3925
4023
|
onPaneClick == null ? void 0 : onPaneClick();
|
|
3926
4024
|
}, [onPaneClick]);
|
|
3927
|
-
const handleConceptClick =
|
|
4025
|
+
const handleConceptClick = React13.useCallback(
|
|
3928
4026
|
(conceptCode) => {
|
|
3929
4027
|
if (!graphspec) return;
|
|
3930
4028
|
const info = resolveConceptRef(graphspec, conceptCode);
|
|
@@ -3941,7 +4039,7 @@ function GraphViewer(props) {
|
|
|
3941
4039
|
const rawAnalysis = (_e = rawGraphDataRef.current) == null ? void 0 : _e.analysis;
|
|
3942
4040
|
const allControllerIds = rawAnalysis == null ? void 0 : rawAnalysis.controllerNodeIds;
|
|
3943
4041
|
const foldControlsAvailable = styleCapabilities.foldAll && (!styleCapabilities.controllerFrameToggle || showControllers);
|
|
3944
|
-
const foldAllProps =
|
|
4042
|
+
const foldAllProps = React13.useMemo(() => {
|
|
3945
4043
|
if (!foldControlsAvailable || !allControllerIds || allControllerIds.size === 0) {
|
|
3946
4044
|
return {
|
|
3947
4045
|
onFoldAll: void 0,
|
|
@@ -3963,34 +4061,37 @@ function GraphViewer(props) {
|
|
|
3963
4061
|
expandAllDisabled: foldedControllers.size === 0
|
|
3964
4062
|
};
|
|
3965
4063
|
}, [foldControlsAvailable, allControllerIds, foldedControllers, markReaderFolds]);
|
|
3966
|
-
const styleMenuOptions =
|
|
4064
|
+
const styleMenuOptions = React13.useMemo(() => resolveStyleMenu(styleMenu), [styleMenu]);
|
|
3967
4065
|
return /* @__PURE__ */ jsxs27(
|
|
3968
4066
|
"div",
|
|
3969
4067
|
{
|
|
3970
4068
|
ref: containerRef,
|
|
3971
|
-
className: `react-flow-container react-flow-container--theme-${resolvedTheme} react-flow-container--mode-${mode}`,
|
|
4069
|
+
className: `react-flow-container react-flow-container--theme-${resolvedTheme} react-flow-container--mode-${mode}${interactive ? "" : " react-flow-container--still"}`,
|
|
4070
|
+
style: interactive ? void 0 : { height: stillHeight },
|
|
4071
|
+
inert: !interactive,
|
|
3972
4072
|
children: [
|
|
3973
4073
|
/* @__PURE__ */ jsxs27(
|
|
3974
4074
|
ReactFlow,
|
|
3975
|
-
{
|
|
4075
|
+
__spreadProps(__spreadValues({
|
|
3976
4076
|
nodes,
|
|
3977
4077
|
edges,
|
|
3978
4078
|
nodeTypes,
|
|
3979
4079
|
edgeTypes,
|
|
3980
4080
|
onNodesChange,
|
|
3981
4081
|
onEdgesChange,
|
|
3982
|
-
onNodeClick,
|
|
3983
|
-
onPaneClick: handlePaneClick,
|
|
4082
|
+
onNodeClick: interactive ? onNodeClick : void 0,
|
|
4083
|
+
onPaneClick: interactive ? handlePaneClick : void 0,
|
|
3984
4084
|
onInit,
|
|
3985
|
-
fitView:
|
|
4085
|
+
fitView: interactive,
|
|
3986
4086
|
fitViewOptions: { padding: 0.1 },
|
|
3987
4087
|
defaultEdgeOptions: { type: edgeType },
|
|
3988
|
-
panOnScroll:
|
|
3989
|
-
minZoom: 0.1,
|
|
4088
|
+
panOnScroll: interactive,
|
|
4089
|
+
minZoom: interactive ? 0.1 : 0.01,
|
|
3990
4090
|
proOptions: { hideAttribution: true },
|
|
3991
|
-
panActivationKeyCode: null
|
|
4091
|
+
panActivationKeyCode: null
|
|
4092
|
+
}, interactive ? {} : STILL_FLOW_PROPS), {
|
|
3992
4093
|
children: [
|
|
3993
|
-
/* @__PURE__ */ jsx29(
|
|
4094
|
+
interactive ? /* @__PURE__ */ jsx29(
|
|
3994
4095
|
Background,
|
|
3995
4096
|
{
|
|
3996
4097
|
variant: BackgroundVariant.Dots,
|
|
@@ -3998,8 +4099,8 @@ function GraphViewer(props) {
|
|
|
3998
4099
|
size: 1,
|
|
3999
4100
|
color: "var(--color-bg-dots)"
|
|
4000
4101
|
}
|
|
4001
|
-
),
|
|
4002
|
-
!hideToolbar && /* @__PURE__ */ jsx29(
|
|
4102
|
+
) : /* @__PURE__ */ jsx29(StillFit, { onHeight: setStillHeight }),
|
|
4103
|
+
interactive && !hideToolbar && /* @__PURE__ */ jsx29(
|
|
4003
4104
|
GraphToolbar,
|
|
4004
4105
|
{
|
|
4005
4106
|
direction,
|
|
@@ -4037,9 +4138,9 @@ function GraphViewer(props) {
|
|
|
4037
4138
|
}
|
|
4038
4139
|
)
|
|
4039
4140
|
]
|
|
4040
|
-
}
|
|
4141
|
+
})
|
|
4041
4142
|
),
|
|
4042
|
-
/* @__PURE__ */ jsxs27(
|
|
4143
|
+
interactive && /* @__PURE__ */ jsxs27(
|
|
4043
4144
|
DetailPanel,
|
|
4044
4145
|
{
|
|
4045
4146
|
isOpen: detailOpen,
|