@pipelex/mthds-ui 0.13.0 → 0.14.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/dist/{chunk-IMQ7MVYL.js → chunk-GS2KODND.js} +1 -1
- package/dist/{chunk-IMQ7MVYL.js.map → chunk-GS2KODND.js.map} +1 -1
- package/dist/chunk-LJQS5ZNA.js +1 -0
- package/dist/{chunk-XCZLRCEJ.js → chunk-V4FKGLKA.js} +61 -2
- package/dist/chunk-V4FKGLKA.js.map +1 -0
- package/dist/graph/index.d.ts +37 -3
- package/dist/graph/index.js +9 -3
- package/dist/graph/react/graph-core.css +71 -2
- package/dist/graph/react/index.d.ts +8 -2
- package/dist/graph/react/index.js +282 -143
- package/dist/graph/react/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +9 -3
- package/dist/standalone/graph-standalone.html +82 -12
- package/dist/standalone/graph-viewer.css +71 -2
- package/dist/standalone/graph-viewer.js +11 -10
- package/dist/static-graph/index.d.ts +4 -1
- package/dist/static-graph/index.js +12 -3
- package/dist/static-graph/index.js.map +1 -1
- package/dist/{types-Cm4147S5.d.ts → types-CIH1Ae16.d.ts} +38 -4
- package/package.json +1 -1
- package/dist/chunk-L24K3TZU.js +0 -1
- package/dist/chunk-XCZLRCEJ.js.map +0 -1
- /package/dist/{chunk-L24K3TZU.js.map → chunk-LJQS5ZNA.js.map} +0 -0
|
@@ -4,14 +4,18 @@ import {
|
|
|
4
4
|
MAX_VISIBLE_CONTROLLER_CHILDREN,
|
|
5
5
|
applyControllers,
|
|
6
6
|
applyFolds,
|
|
7
|
+
applyValidationDecorations,
|
|
8
|
+
buildChildToControllerMap,
|
|
7
9
|
buildGraph,
|
|
10
|
+
buildValidationDecorations,
|
|
8
11
|
findCousinControllers,
|
|
9
12
|
getLayoutedElements,
|
|
10
13
|
getPaletteForTheme,
|
|
11
14
|
getPipeBlueprint,
|
|
12
15
|
resolveConceptRef,
|
|
16
|
+
resolveIssueTargetNodeId,
|
|
13
17
|
validateGraphSpec
|
|
14
|
-
} from "../../chunk-
|
|
18
|
+
} from "../../chunk-V4FKGLKA.js";
|
|
15
19
|
import {
|
|
16
20
|
EDGE_TYPE,
|
|
17
21
|
FOLD_MODE,
|
|
@@ -27,7 +31,7 @@ import {
|
|
|
27
31
|
stuffDigestFromId,
|
|
28
32
|
toolbarOrientation,
|
|
29
33
|
toolbarSide
|
|
30
|
-
} from "../../chunk-
|
|
34
|
+
} from "../../chunk-GS2KODND.js";
|
|
31
35
|
import {
|
|
32
36
|
__spreadProps,
|
|
33
37
|
__spreadValues
|
|
@@ -2187,26 +2191,31 @@ function GraphToolbar({
|
|
|
2187
2191
|
position,
|
|
2188
2192
|
validationState,
|
|
2189
2193
|
validationIssues = [],
|
|
2190
|
-
onValidationIssueClick
|
|
2194
|
+
onValidationIssueClick,
|
|
2195
|
+
validationOpen = false,
|
|
2196
|
+
onValidationOpenChange
|
|
2191
2197
|
}) {
|
|
2192
2198
|
const themeToggleEnabled = themeMode !== void 0 && onThemeModeChange !== void 0;
|
|
2193
2199
|
const orientation = toolbarOrientation(position);
|
|
2194
|
-
const
|
|
2200
|
+
const setValidationOpen = onValidationOpenChange != null ? onValidationOpenChange : (() => {
|
|
2201
|
+
});
|
|
2202
|
+
const setValidationOpenRef = React8.useRef(setValidationOpen);
|
|
2203
|
+
setValidationOpenRef.current = setValidationOpen;
|
|
2195
2204
|
const validationRef = React8.useRef(null);
|
|
2196
2205
|
const validationPanelId = React8.useId();
|
|
2197
2206
|
React8.useEffect(() => {
|
|
2198
|
-
if (validationState === void 0)
|
|
2207
|
+
if (validationState === void 0) setValidationOpenRef.current(false);
|
|
2199
2208
|
}, [validationState]);
|
|
2200
2209
|
React8.useEffect(() => {
|
|
2201
2210
|
if (!validationOpen) return;
|
|
2202
2211
|
const onPointerDown = (event) => {
|
|
2203
2212
|
const wrapper = validationRef.current;
|
|
2204
2213
|
if (wrapper && event.target instanceof Node && !wrapper.contains(event.target)) {
|
|
2205
|
-
|
|
2214
|
+
setValidationOpenRef.current(false);
|
|
2206
2215
|
}
|
|
2207
2216
|
};
|
|
2208
2217
|
const onKeyDown = (event) => {
|
|
2209
|
-
if (event.key === "Escape")
|
|
2218
|
+
if (event.key === "Escape") setValidationOpenRef.current(false);
|
|
2210
2219
|
};
|
|
2211
2220
|
document.addEventListener("mousedown", onPointerDown);
|
|
2212
2221
|
document.addEventListener("keydown", onKeyDown);
|
|
@@ -2231,7 +2240,7 @@ function GraphToolbar({
|
|
|
2231
2240
|
{
|
|
2232
2241
|
type: "button",
|
|
2233
2242
|
className: `graph-toolbar-btn graph-toolbar-validation-btn graph-toolbar-validation-btn--${validationState}`,
|
|
2234
|
-
onClick: () => setValidationOpen(
|
|
2243
|
+
onClick: () => setValidationOpen(!validationOpen),
|
|
2235
2244
|
title: validationLabel(validationState, validationIssues.length),
|
|
2236
2245
|
"aria-label": validationLabel(validationState, validationIssues.length),
|
|
2237
2246
|
"aria-expanded": validationOpen,
|
|
@@ -2354,8 +2363,40 @@ function GraphToolbar({
|
|
|
2354
2363
|
] }) });
|
|
2355
2364
|
}
|
|
2356
2365
|
|
|
2366
|
+
// src/graph/react/nodes/NodeValidationBadge.tsx
|
|
2367
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
2368
|
+
function NodeValidationBadge({
|
|
2369
|
+
validation,
|
|
2370
|
+
onClick
|
|
2371
|
+
}) {
|
|
2372
|
+
const label = `${validation.count} validation ${validation.count === 1 ? "issue" : "issues"}`;
|
|
2373
|
+
const tooltip = validation.lines.join("\n");
|
|
2374
|
+
const className = `node-validation-badge node-validation-badge--${validation.severity}`;
|
|
2375
|
+
const text = validation.count > 99 ? "99+" : String(validation.count);
|
|
2376
|
+
if (!onClick) {
|
|
2377
|
+
return /* @__PURE__ */ jsx19("span", { className, title: tooltip, "aria-label": label, children: text });
|
|
2378
|
+
}
|
|
2379
|
+
return /* @__PURE__ */ jsx19(
|
|
2380
|
+
"button",
|
|
2381
|
+
{
|
|
2382
|
+
type: "button",
|
|
2383
|
+
className,
|
|
2384
|
+
title: tooltip,
|
|
2385
|
+
"aria-label": `${label} \u2014 open validation panel`,
|
|
2386
|
+
onClick: (e) => {
|
|
2387
|
+
e.stopPropagation();
|
|
2388
|
+
onClick();
|
|
2389
|
+
},
|
|
2390
|
+
children: text
|
|
2391
|
+
}
|
|
2392
|
+
);
|
|
2393
|
+
}
|
|
2394
|
+
function validationRingClass(validation) {
|
|
2395
|
+
return validation ? ` node-validation-ring--${validation.severity}` : "";
|
|
2396
|
+
}
|
|
2397
|
+
|
|
2357
2398
|
// src/graph/react/nodes/controller/ControllerGroupNode.tsx
|
|
2358
|
-
import { jsx as
|
|
2399
|
+
import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2359
2400
|
var CONTROLLER_CONFIG = {
|
|
2360
2401
|
PipeSequence: { badge: "Sequence", icon: "\u2192" },
|
|
2361
2402
|
PipeParallel: { badge: "Parallel", icon: "//" },
|
|
@@ -2377,12 +2418,12 @@ function ControllerGroupNode({ data }) {
|
|
|
2377
2418
|
const modifier = getControllerModifier(data.pipeType);
|
|
2378
2419
|
const isCollapsible = (data.pipeType === "PipeParallel" || data.pipeType === "PipeBatch") && ((_a = data.childCount) != null ? _a : 0) > MAX_VISIBLE_CONTROLLER_CHILDREN;
|
|
2379
2420
|
const hiddenCount = isCollapsible ? ((_b = data.childCount) != null ? _b : 0) - MAX_VISIBLE_CONTROLLER_CHILDREN : 0;
|
|
2380
|
-
return /* @__PURE__ */ jsxs19("div", { className: `controller-group-node ${modifier}`, children: [
|
|
2421
|
+
return /* @__PURE__ */ jsxs19("div", { className: `controller-group-node ${modifier}${validationRingClass(data.validation)}`, children: [
|
|
2381
2422
|
/* @__PURE__ */ jsxs19("div", { className: "controller-group-header", children: [
|
|
2382
|
-
/* @__PURE__ */
|
|
2383
|
-
/* @__PURE__ */
|
|
2384
|
-
data.label && /* @__PURE__ */
|
|
2385
|
-
data.onToggleFold && /* @__PURE__ */
|
|
2423
|
+
/* @__PURE__ */ jsx20("span", { className: "controller-group-icon", children: config.icon }),
|
|
2424
|
+
/* @__PURE__ */ jsx20("span", { className: "controller-group-badge", children: config.badge }),
|
|
2425
|
+
data.label && /* @__PURE__ */ jsx20("span", { className: "controller-group-label", children: data.label }),
|
|
2426
|
+
data.onToggleFold && /* @__PURE__ */ jsx20(
|
|
2386
2427
|
"button",
|
|
2387
2428
|
{
|
|
2388
2429
|
type: "button",
|
|
@@ -2396,9 +2437,10 @@ function ControllerGroupNode({ data }) {
|
|
|
2396
2437
|
},
|
|
2397
2438
|
children: "\u2921"
|
|
2398
2439
|
}
|
|
2399
|
-
)
|
|
2440
|
+
),
|
|
2441
|
+
data.validation && /* @__PURE__ */ jsx20(NodeValidationBadge, { validation: data.validation, onClick: data.onValidationBadgeClick })
|
|
2400
2442
|
] }),
|
|
2401
|
-
isCollapsible && /* @__PURE__ */
|
|
2443
|
+
isCollapsible && /* @__PURE__ */ jsx20(
|
|
2402
2444
|
"button",
|
|
2403
2445
|
{
|
|
2404
2446
|
className: "controller-group-collapse",
|
|
@@ -2419,7 +2461,7 @@ import { Handle, Position } from "@xyflow/react";
|
|
|
2419
2461
|
|
|
2420
2462
|
// src/graph/react/nodes/pipe/PipeCardBase.tsx
|
|
2421
2463
|
import { useState as useState2 } from "react";
|
|
2422
|
-
import { jsx as
|
|
2464
|
+
import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2423
2465
|
var PIPE_TYPE_BADGES2 = {
|
|
2424
2466
|
PipeLLM: "LLM",
|
|
2425
2467
|
PipeExtract: "Extract",
|
|
@@ -2474,94 +2516,102 @@ function PipeCardBase({ data, children }) {
|
|
|
2474
2516
|
const signatureClass = isSignature ? " pipe-card--signature" : "";
|
|
2475
2517
|
const staticClass = isStatic ? " pipe-card--static" : "";
|
|
2476
2518
|
const badgeClass = isController ? "pipe-card-badge pipe-card-badge--controller" : isSignature ? "pipe-card-badge pipe-card-badge--signature" : "pipe-card-badge";
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
{
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
children: /* @__PURE__ */ jsx20(
|
|
2519
|
+
const ringClass = validationRingClass(data.validation);
|
|
2520
|
+
return /* @__PURE__ */ jsxs20(
|
|
2521
|
+
"div",
|
|
2522
|
+
{
|
|
2523
|
+
className: `pipe-card ${dirClass}${controllerClass}${signatureClass}${staticClass}${ringClass}`,
|
|
2524
|
+
children: [
|
|
2525
|
+
/* @__PURE__ */ jsxs20("div", { className: "pipe-card-header", children: [
|
|
2526
|
+
/* @__PURE__ */ jsx21("span", { className: badgeClass, children: badge }),
|
|
2527
|
+
/* @__PURE__ */ jsx21("span", { className: "pipe-card-code", title: data.pipeCode, children: data.pipeCode }),
|
|
2528
|
+
!isStatic && /* @__PURE__ */ jsx21(
|
|
2488
2529
|
"span",
|
|
2489
2530
|
{
|
|
2490
|
-
className:
|
|
2491
|
-
style: {
|
|
2531
|
+
className: "pipe-card-status",
|
|
2532
|
+
style: { color: statusConfig.color },
|
|
2533
|
+
title: statusConfig.label,
|
|
2534
|
+
children: /* @__PURE__ */ jsx21(
|
|
2535
|
+
"span",
|
|
2536
|
+
{
|
|
2537
|
+
className: `pipe-card-status-dot ${isRunning ? "pipe-card-status-dot--pulse" : ""}`,
|
|
2538
|
+
style: { background: statusConfig.color }
|
|
2539
|
+
}
|
|
2540
|
+
)
|
|
2492
2541
|
}
|
|
2493
|
-
)
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
+
),
|
|
2543
|
+
data.onExpand && /* @__PURE__ */ jsx21(
|
|
2544
|
+
"button",
|
|
2545
|
+
{
|
|
2546
|
+
type: "button",
|
|
2547
|
+
className: "pipe-card-expand",
|
|
2548
|
+
title: "Expand controller (alt/option: only this one)",
|
|
2549
|
+
"aria-label": "Expand controller",
|
|
2550
|
+
onClick: (e) => {
|
|
2551
|
+
var _a2;
|
|
2552
|
+
e.stopPropagation();
|
|
2553
|
+
(_a2 = data.onExpand) == null ? void 0 : _a2.call(data, { soloMode: e.altKey });
|
|
2554
|
+
},
|
|
2555
|
+
children: "\u2922"
|
|
2556
|
+
}
|
|
2557
|
+
),
|
|
2558
|
+
data.validation && /* @__PURE__ */ jsx21(NodeValidationBadge, { validation: data.validation, onClick: data.onValidationBadgeClick })
|
|
2559
|
+
] }),
|
|
2560
|
+
(outcome || batchMultiplicity) && /* @__PURE__ */ jsxs20("div", { className: "pipe-card-annotations", children: [
|
|
2561
|
+
outcome && /* @__PURE__ */ jsxs20("span", { className: "pipe-card-annotation pipe-card-annotation--outcome", children: [
|
|
2562
|
+
"outcome: ",
|
|
2563
|
+
outcome
|
|
2564
|
+
] }),
|
|
2565
|
+
batchMultiplicity && /* @__PURE__ */ jsx21("span", { className: "pipe-card-annotation pipe-card-annotation--batch", children: batchMultiplicity })
|
|
2566
|
+
] }),
|
|
2567
|
+
data.description && /* @__PURE__ */ jsx21("span", { className: "pipe-card-description", title: data.description, children: data.description }),
|
|
2568
|
+
data.inputs.length > 0 && /* @__PURE__ */ jsxs20("div", { className: "pipe-card-io", children: [
|
|
2569
|
+
/* @__PURE__ */ jsx21("span", { className: "pipe-card-io-label", children: "INPUTS" }),
|
|
2570
|
+
/* @__PURE__ */ jsxs20("div", { className: "pipe-card-io-pills", children: [
|
|
2571
|
+
visibleInputs.map((input) => /* @__PURE__ */ jsxs20(
|
|
2572
|
+
"span",
|
|
2573
|
+
{
|
|
2574
|
+
className: "pipe-card-io-pill",
|
|
2575
|
+
title: `${input.name}: ${input.concept}`,
|
|
2576
|
+
children: [
|
|
2577
|
+
/* @__PURE__ */ jsx21("span", { className: "pipe-card-io-pill-name", children: input.name }),
|
|
2578
|
+
/* @__PURE__ */ jsx21("span", { className: "pipe-card-io-pill-concept", children: input.concept })
|
|
2579
|
+
]
|
|
2580
|
+
},
|
|
2581
|
+
input.name
|
|
2582
|
+
)),
|
|
2583
|
+
hasMany && /* @__PURE__ */ jsx21(
|
|
2584
|
+
"button",
|
|
2585
|
+
{
|
|
2586
|
+
className: "pipe-card-io-more",
|
|
2587
|
+
onClick: (e) => {
|
|
2588
|
+
e.stopPropagation();
|
|
2589
|
+
setInputsExpanded((v) => !v);
|
|
2590
|
+
},
|
|
2591
|
+
children: inputsExpanded ? "show less" : `+${hiddenCount} more`
|
|
2592
|
+
}
|
|
2593
|
+
)
|
|
2594
|
+
] })
|
|
2595
|
+
] }),
|
|
2596
|
+
data.outputs.length > 0 && /* @__PURE__ */ jsxs20("div", { className: "pipe-card-io", children: [
|
|
2597
|
+
/* @__PURE__ */ jsx21("span", { className: "pipe-card-io-label", children: "OUTPUT" }),
|
|
2598
|
+
/* @__PURE__ */ jsx21("div", { className: "pipe-card-io-pills", children: data.outputs.map((output) => /* @__PURE__ */ jsxs20(
|
|
2599
|
+
"span",
|
|
2600
|
+
{
|
|
2601
|
+
className: "pipe-card-io-pill",
|
|
2602
|
+
title: `${output.name}: ${output.concept}`,
|
|
2603
|
+
children: [
|
|
2604
|
+
/* @__PURE__ */ jsx21("span", { className: "pipe-card-io-pill-name", children: output.name }),
|
|
2605
|
+
/* @__PURE__ */ jsx21("span", { className: "pipe-card-io-pill-concept", children: output.concept })
|
|
2606
|
+
]
|
|
2542
2607
|
},
|
|
2543
|
-
|
|
2544
|
-
}
|
|
2545
|
-
)
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
/* @__PURE__ */ jsx20("div", { className: "pipe-card-io-pills", children: data.outputs.map((output) => /* @__PURE__ */ jsxs20(
|
|
2551
|
-
"span",
|
|
2552
|
-
{
|
|
2553
|
-
className: "pipe-card-io-pill",
|
|
2554
|
-
title: `${output.name}: ${output.concept}`,
|
|
2555
|
-
children: [
|
|
2556
|
-
/* @__PURE__ */ jsx20("span", { className: "pipe-card-io-pill-name", children: output.name }),
|
|
2557
|
-
/* @__PURE__ */ jsx20("span", { className: "pipe-card-io-pill-concept", children: output.concept })
|
|
2558
|
-
]
|
|
2559
|
-
},
|
|
2560
|
-
output.name
|
|
2561
|
-
)) })
|
|
2562
|
-
] }),
|
|
2563
|
-
children
|
|
2564
|
-
] });
|
|
2608
|
+
output.name
|
|
2609
|
+
)) })
|
|
2610
|
+
] }),
|
|
2611
|
+
children
|
|
2612
|
+
]
|
|
2613
|
+
}
|
|
2614
|
+
);
|
|
2565
2615
|
}
|
|
2566
2616
|
|
|
2567
2617
|
// src/graph/react/nodes/pipe/pipeCardRegistry.ts
|
|
@@ -2584,11 +2634,11 @@ function getPipeCardComponent(pipeType) {
|
|
|
2584
2634
|
}
|
|
2585
2635
|
|
|
2586
2636
|
// src/graph/react/nodes/pipe/PipeCardNode.tsx
|
|
2587
|
-
import { Fragment as Fragment13, jsx as
|
|
2637
|
+
import { Fragment as Fragment13, jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
2588
2638
|
function PipeCardNode({ data }) {
|
|
2589
2639
|
var _a;
|
|
2590
2640
|
const Card = (_a = getPipeCardComponent(data.pipeType)) != null ? _a : PipeCardBase;
|
|
2591
|
-
return /* @__PURE__ */
|
|
2641
|
+
return /* @__PURE__ */ jsx22(Card, { data });
|
|
2592
2642
|
}
|
|
2593
2643
|
function PipeCardRFNode({
|
|
2594
2644
|
data,
|
|
@@ -2598,14 +2648,14 @@ function PipeCardRFNode({
|
|
|
2598
2648
|
const payload = data.pipeCardData;
|
|
2599
2649
|
if (!payload) return null;
|
|
2600
2650
|
return /* @__PURE__ */ jsxs21(Fragment13, { children: [
|
|
2601
|
-
/* @__PURE__ */
|
|
2602
|
-
/* @__PURE__ */
|
|
2603
|
-
/* @__PURE__ */
|
|
2651
|
+
/* @__PURE__ */ jsx22(Handle, { type: "target", position: targetPosition }),
|
|
2652
|
+
/* @__PURE__ */ jsx22(PipeCardNode, { data: payload }),
|
|
2653
|
+
/* @__PURE__ */ jsx22(Handle, { type: "source", position: sourcePosition })
|
|
2604
2654
|
] });
|
|
2605
2655
|
}
|
|
2606
2656
|
|
|
2607
2657
|
// src/graph/react/viewer/GraphViewer.tsx
|
|
2608
|
-
import { Fragment as Fragment14, jsx as
|
|
2658
|
+
import { Fragment as Fragment14, jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2609
2659
|
var nodeTypes = __spreadProps(__spreadValues({}, controllerNodeTypes), {
|
|
2610
2660
|
pipeCard: PipeCardRFNode
|
|
2611
2661
|
});
|
|
@@ -2619,7 +2669,7 @@ function StuffNodeDetail({
|
|
|
2619
2669
|
}) {
|
|
2620
2670
|
const conceptInfo = stuffData.concept && graphspec ? resolveConceptRef(graphspec, stuffData.concept) : void 0;
|
|
2621
2671
|
const isDryRun = graphSpecMode(graphspec) === GRAPH_SPEC_MODE.DRY;
|
|
2622
|
-
return /* @__PURE__ */
|
|
2672
|
+
return /* @__PURE__ */ jsx23(Fragment14, { children: conceptInfo ? /* @__PURE__ */ jsx23(
|
|
2623
2673
|
ConceptDetailPanel,
|
|
2624
2674
|
{
|
|
2625
2675
|
concept: conceptInfo,
|
|
@@ -2630,9 +2680,9 @@ function StuffNodeDetail({
|
|
|
2630
2680
|
canEmbedPdf,
|
|
2631
2681
|
onOpenExternally
|
|
2632
2682
|
}
|
|
2633
|
-
) : isDryRun ? /* @__PURE__ */
|
|
2683
|
+
) : isDryRun ? /* @__PURE__ */ jsx23("div", { className: "detail-not-available", children: "Dry run data hidden" }) : (
|
|
2634
2684
|
/* Fallback: just show the StuffViewer if no concept info */
|
|
2635
|
-
/* @__PURE__ */
|
|
2685
|
+
/* @__PURE__ */ jsx23(
|
|
2636
2686
|
StuffViewer,
|
|
2637
2687
|
{
|
|
2638
2688
|
stuff: stuffData,
|
|
@@ -2658,6 +2708,9 @@ function resolveToolbarPosition(positionProp, configPosition) {
|
|
|
2658
2708
|
var _a;
|
|
2659
2709
|
return (_a = positionProp != null ? positionProp : configPosition) != null ? _a : DEFAULT_GRAPH_CONFIG.toolbarPosition;
|
|
2660
2710
|
}
|
|
2711
|
+
function stripFlash(className) {
|
|
2712
|
+
return (className == null ? void 0 : className.replace(/\s*\bnode-validation-flash\b/, "")) || void 0;
|
|
2713
|
+
}
|
|
2661
2714
|
function cloneCachedNodes(nodes) {
|
|
2662
2715
|
return nodes.map((n) => __spreadProps(__spreadValues({}, n), {
|
|
2663
2716
|
position: __spreadValues({}, n.position),
|
|
@@ -2839,6 +2892,84 @@ function GraphViewer(props) {
|
|
|
2839
2892
|
const skipNextFoldEffectRef = React10.useRef(false);
|
|
2840
2893
|
const statusMapRef = React10.useRef(statusMap);
|
|
2841
2894
|
statusMapRef.current = statusMap;
|
|
2895
|
+
const validationIssuesRef = React10.useRef(validationIssues);
|
|
2896
|
+
validationIssuesRef.current = validationIssues;
|
|
2897
|
+
const [validationOpen, setValidationOpen] = React10.useState(false);
|
|
2898
|
+
const openValidationPanel = React10.useCallback(() => setValidationOpen(true), []);
|
|
2899
|
+
const validationWidgetAvailable = validationState !== void 0 && !hideToolbar;
|
|
2900
|
+
const validationWidgetAvailableRef = React10.useRef(validationWidgetAvailable);
|
|
2901
|
+
validationWidgetAvailableRef.current = validationWidgetAvailable;
|
|
2902
|
+
const decorateNodes = React10.useCallback(
|
|
2903
|
+
(nodes2) => {
|
|
2904
|
+
var _a2, _b2;
|
|
2905
|
+
const raw = rawGraphDataRef.current;
|
|
2906
|
+
const decorations = buildValidationDecorations(
|
|
2907
|
+
validationIssuesRef.current,
|
|
2908
|
+
(_a2 = raw == null ? void 0 : raw.graphspec) != null ? _a2 : null,
|
|
2909
|
+
(_b2 = raw == null ? void 0 : raw.childToCtrl) != null ? _b2 : {},
|
|
2910
|
+
foldedRef.current
|
|
2911
|
+
);
|
|
2912
|
+
return applyValidationDecorations(
|
|
2913
|
+
applyStatusOverrides(toAppNodes(hydrateLabels(nodes2)), statusMapRef.current),
|
|
2914
|
+
decorations,
|
|
2915
|
+
validationWidgetAvailableRef.current ? openValidationPanel : void 0
|
|
2916
|
+
);
|
|
2917
|
+
},
|
|
2918
|
+
[openValidationPanel]
|
|
2919
|
+
);
|
|
2920
|
+
const nodesRef = React10.useRef([]);
|
|
2921
|
+
nodesRef.current = nodes;
|
|
2922
|
+
const onValidationIssueClickRef = React10.useRef(onValidationIssueClick);
|
|
2923
|
+
onValidationIssueClickRef.current = onValidationIssueClick;
|
|
2924
|
+
const flashTimeoutRef = React10.useRef(null);
|
|
2925
|
+
React10.useEffect(
|
|
2926
|
+
() => () => {
|
|
2927
|
+
if (flashTimeoutRef.current) clearTimeout(flashTimeoutRef.current);
|
|
2928
|
+
},
|
|
2929
|
+
[]
|
|
2930
|
+
);
|
|
2931
|
+
const handleValidationIssueClick = React10.useCallback(
|
|
2932
|
+
(index, issue) => {
|
|
2933
|
+
var _a2, _b2;
|
|
2934
|
+
(_a2 = onValidationIssueClickRef.current) == null ? void 0 : _a2.call(onValidationIssueClickRef, index, issue);
|
|
2935
|
+
const raw = rawGraphDataRef.current;
|
|
2936
|
+
if (!(raw == null ? void 0 : raw.graphspec) || !raw.analysis) return;
|
|
2937
|
+
const targetId = resolveIssueTargetNodeId(
|
|
2938
|
+
issue,
|
|
2939
|
+
raw.graphspec,
|
|
2940
|
+
raw.childToCtrl,
|
|
2941
|
+
foldedRef.current,
|
|
2942
|
+
new Set(nodesRef.current.map((n) => n.id))
|
|
2943
|
+
);
|
|
2944
|
+
if (!targetId) return;
|
|
2945
|
+
void ((_b2 = reactFlowRef.current) == null ? void 0 : _b2.fitView({
|
|
2946
|
+
nodes: [{ id: targetId }],
|
|
2947
|
+
duration: 500,
|
|
2948
|
+
padding: 0.4
|
|
2949
|
+
}));
|
|
2950
|
+
if (flashTimeoutRef.current) clearTimeout(flashTimeoutRef.current);
|
|
2951
|
+
setNodes(
|
|
2952
|
+
(nds) => nds.map((n) => {
|
|
2953
|
+
const base = stripFlash(n.className);
|
|
2954
|
+
if (n.id === targetId) {
|
|
2955
|
+
return __spreadProps(__spreadValues({}, n), {
|
|
2956
|
+
className: base ? `${base} node-validation-flash` : "node-validation-flash"
|
|
2957
|
+
});
|
|
2958
|
+
}
|
|
2959
|
+
return base === n.className ? n : __spreadProps(__spreadValues({}, n), { className: base });
|
|
2960
|
+
})
|
|
2961
|
+
);
|
|
2962
|
+
flashTimeoutRef.current = setTimeout(() => {
|
|
2963
|
+
setNodes(
|
|
2964
|
+
(nds) => nds.map((n) => {
|
|
2965
|
+
const base = stripFlash(n.className);
|
|
2966
|
+
return base === n.className ? n : __spreadProps(__spreadValues({}, n), { className: base });
|
|
2967
|
+
})
|
|
2968
|
+
);
|
|
2969
|
+
}, 1800);
|
|
2970
|
+
},
|
|
2971
|
+
[setNodes]
|
|
2972
|
+
);
|
|
2842
2973
|
React10.useEffect(() => {
|
|
2843
2974
|
if (!initialDataRef.current) return;
|
|
2844
2975
|
let cancelled = false;
|
|
@@ -2858,7 +2989,8 @@ function GraphViewer(props) {
|
|
|
2858
2989
|
layoutCacheRef.current = {
|
|
2859
2990
|
nodes: relayouted.nodes,
|
|
2860
2991
|
edges: relayouted.edges,
|
|
2861
|
-
controllerPositions: relayouted.controllerPositions
|
|
2992
|
+
controllerPositions: relayouted.controllerPositions,
|
|
2993
|
+
graphspec: data._graphspec
|
|
2862
2994
|
};
|
|
2863
2995
|
const withControllers = applyControllers(
|
|
2864
2996
|
cloneCachedNodes(relayouted.nodes),
|
|
@@ -2871,12 +3003,7 @@ function GraphViewer(props) {
|
|
|
2871
3003
|
relayouted.controllerPositions,
|
|
2872
3004
|
toggleFoldRef.current
|
|
2873
3005
|
);
|
|
2874
|
-
setNodes(
|
|
2875
|
-
applyStatusOverrides(
|
|
2876
|
-
toAppNodes(hydrateLabels(withControllers.nodes)),
|
|
2877
|
-
statusMapRef.current
|
|
2878
|
-
)
|
|
2879
|
-
);
|
|
3006
|
+
setNodes(decorateNodes(withControllers.nodes));
|
|
2880
3007
|
setEdges(toAppEdges(withControllers.edges));
|
|
2881
3008
|
setTimeout(() => {
|
|
2882
3009
|
if (!cancelled && reactFlowRef.current) {
|
|
@@ -2893,6 +3020,7 @@ function GraphViewer(props) {
|
|
|
2893
3020
|
}, [direction, layoutConfig]);
|
|
2894
3021
|
React10.useEffect(() => {
|
|
2895
3022
|
if (!layoutCacheRef.current || !initialDataRef.current) return;
|
|
3023
|
+
if (layoutCacheRef.current.graphspec !== initialDataRef.current._graphspec) return;
|
|
2896
3024
|
const cachedNodes = cloneCachedNodes(layoutCacheRef.current.nodes);
|
|
2897
3025
|
const cachedEdges = layoutCacheRef.current.edges;
|
|
2898
3026
|
const withControllers = applyControllers(
|
|
@@ -2906,11 +3034,9 @@ function GraphViewer(props) {
|
|
|
2906
3034
|
layoutCacheRef.current.controllerPositions,
|
|
2907
3035
|
toggleFold
|
|
2908
3036
|
);
|
|
2909
|
-
setNodes(
|
|
2910
|
-
applyStatusOverrides(toAppNodes(hydrateLabels(withControllers.nodes)), statusMapRef.current)
|
|
2911
|
-
);
|
|
3037
|
+
setNodes(decorateNodes(withControllers.nodes));
|
|
2912
3038
|
setEdges(toAppEdges(withControllers.edges));
|
|
2913
|
-
}, [showControllers, expandedControllers, toggleCollapse, toggleFold]);
|
|
3039
|
+
}, [showControllers, expandedControllers, toggleCollapse, toggleFold, decorateNodes]);
|
|
2914
3040
|
React10.useEffect(() => {
|
|
2915
3041
|
if (!graphspec) {
|
|
2916
3042
|
initialDataRef.current = null;
|
|
@@ -2928,7 +3054,8 @@ function GraphViewer(props) {
|
|
|
2928
3054
|
nodes: graphData.nodes,
|
|
2929
3055
|
edges: graphData.edges,
|
|
2930
3056
|
analysis,
|
|
2931
|
-
graphspec
|
|
3057
|
+
graphspec,
|
|
3058
|
+
childToCtrl: analysis ? buildChildToControllerMap(graphspec, analysis) : {}
|
|
2932
3059
|
};
|
|
2933
3060
|
const seedSet = analysis ? seedFoldedControllers(foldModeRef.current, analysis.controllerNodeIds) : /* @__PURE__ */ new Set();
|
|
2934
3061
|
setFoldedControllers(seedSet);
|
|
@@ -2975,7 +3102,8 @@ function GraphViewer(props) {
|
|
|
2975
3102
|
layoutCacheRef.current = {
|
|
2976
3103
|
nodes: layouted.nodes,
|
|
2977
3104
|
edges: layouted.edges,
|
|
2978
|
-
controllerPositions: layouted.controllerPositions
|
|
3105
|
+
controllerPositions: layouted.controllerPositions,
|
|
3106
|
+
graphspec
|
|
2979
3107
|
};
|
|
2980
3108
|
const withControllers = applyControllers(
|
|
2981
3109
|
cloneCachedNodes(layouted.nodes),
|
|
@@ -2988,12 +3116,7 @@ function GraphViewer(props) {
|
|
|
2988
3116
|
layouted.controllerPositions,
|
|
2989
3117
|
toggleFoldRef.current
|
|
2990
3118
|
);
|
|
2991
|
-
setNodes(
|
|
2992
|
-
applyStatusOverrides(
|
|
2993
|
-
toAppNodes(hydrateLabels(withControllers.nodes)),
|
|
2994
|
-
statusMapRef.current
|
|
2995
|
-
)
|
|
2996
|
-
);
|
|
3119
|
+
setNodes(decorateNodes(withControllers.nodes));
|
|
2997
3120
|
setEdges(toAppEdges(withControllers.edges));
|
|
2998
3121
|
setTimeout(() => {
|
|
2999
3122
|
if (!cancelled && reactFlowRef.current) {
|
|
@@ -3062,7 +3185,8 @@ function GraphViewer(props) {
|
|
|
3062
3185
|
layoutCacheRef.current = {
|
|
3063
3186
|
nodes: layouted.nodes,
|
|
3064
3187
|
edges: layouted.edges,
|
|
3065
|
-
controllerPositions: layouted.controllerPositions
|
|
3188
|
+
controllerPositions: layouted.controllerPositions,
|
|
3189
|
+
graphspec: currentGraphspec
|
|
3066
3190
|
};
|
|
3067
3191
|
const withControllers = applyControllers(
|
|
3068
3192
|
cloneCachedNodes(layouted.nodes),
|
|
@@ -3075,12 +3199,7 @@ function GraphViewer(props) {
|
|
|
3075
3199
|
layouted.controllerPositions,
|
|
3076
3200
|
toggleFoldRef.current
|
|
3077
3201
|
);
|
|
3078
|
-
setNodes(
|
|
3079
|
-
applyStatusOverrides(
|
|
3080
|
-
toAppNodes(hydrateLabels(withControllers.nodes)),
|
|
3081
|
-
statusMapRef.current
|
|
3082
|
-
)
|
|
3083
|
-
);
|
|
3202
|
+
setNodes(decorateNodes(withControllers.nodes));
|
|
3084
3203
|
setEdges(toAppEdges(withControllers.edges));
|
|
3085
3204
|
setTimeout(() => {
|
|
3086
3205
|
if (!cancelled && reactFlowRef.current) {
|
|
@@ -3097,6 +3216,7 @@ function GraphViewer(props) {
|
|
|
3097
3216
|
}, [foldedControllers, toggleFold]);
|
|
3098
3217
|
React10.useEffect(() => {
|
|
3099
3218
|
if (!layoutCacheRef.current || !initialDataRef.current) return;
|
|
3219
|
+
if (layoutCacheRef.current.graphspec !== initialDataRef.current._graphspec) return;
|
|
3100
3220
|
const cachedNodes = cloneCachedNodes(layoutCacheRef.current.nodes);
|
|
3101
3221
|
const cachedEdges = layoutCacheRef.current.edges;
|
|
3102
3222
|
const withControllers = applyControllers(
|
|
@@ -3110,9 +3230,26 @@ function GraphViewer(props) {
|
|
|
3110
3230
|
layoutCacheRef.current.controllerPositions,
|
|
3111
3231
|
toggleFoldRef.current
|
|
3112
3232
|
);
|
|
3113
|
-
setNodes(
|
|
3233
|
+
setNodes(decorateNodes(withControllers.nodes));
|
|
3114
3234
|
setEdges(toAppEdges(withControllers.edges));
|
|
3115
|
-
}, [statusMap]);
|
|
3235
|
+
}, [statusMap, decorateNodes]);
|
|
3236
|
+
React10.useEffect(() => {
|
|
3237
|
+
if (!layoutCacheRef.current || !initialDataRef.current) return;
|
|
3238
|
+
if (layoutCacheRef.current.graphspec !== initialDataRef.current._graphspec) return;
|
|
3239
|
+
const cachedNodes = cloneCachedNodes(layoutCacheRef.current.nodes);
|
|
3240
|
+
const withControllers = applyControllers(
|
|
3241
|
+
cachedNodes,
|
|
3242
|
+
layoutCacheRef.current.edges,
|
|
3243
|
+
initialDataRef.current._graphspec,
|
|
3244
|
+
initialDataRef.current._analysis,
|
|
3245
|
+
showControllersRef.current,
|
|
3246
|
+
expandedRef.current,
|
|
3247
|
+
toggleCollapseRef.current,
|
|
3248
|
+
layoutCacheRef.current.controllerPositions,
|
|
3249
|
+
toggleFoldRef.current
|
|
3250
|
+
);
|
|
3251
|
+
setNodes(decorateNodes(withControllers.nodes));
|
|
3252
|
+
}, [validationIssues, validationWidgetAvailable, decorateNodes]);
|
|
3116
3253
|
const onNodeClick = React10.useCallback(
|
|
3117
3254
|
(event, node) => {
|
|
3118
3255
|
var _a2;
|
|
@@ -3226,7 +3363,7 @@ function GraphViewer(props) {
|
|
|
3226
3363
|
proOptions: { hideAttribution: true },
|
|
3227
3364
|
panActivationKeyCode: null,
|
|
3228
3365
|
children: [
|
|
3229
|
-
/* @__PURE__ */
|
|
3366
|
+
/* @__PURE__ */ jsx23(
|
|
3230
3367
|
Background,
|
|
3231
3368
|
{
|
|
3232
3369
|
variant: BackgroundVariant.Dots,
|
|
@@ -3235,7 +3372,7 @@ function GraphViewer(props) {
|
|
|
3235
3372
|
color: "var(--color-bg-dots)"
|
|
3236
3373
|
}
|
|
3237
3374
|
),
|
|
3238
|
-
!hideToolbar && /* @__PURE__ */
|
|
3375
|
+
!hideToolbar && /* @__PURE__ */ jsx23(
|
|
3239
3376
|
GraphToolbar,
|
|
3240
3377
|
{
|
|
3241
3378
|
direction,
|
|
@@ -3264,7 +3401,9 @@ function GraphViewer(props) {
|
|
|
3264
3401
|
position: effectiveToolbarPosition,
|
|
3265
3402
|
validationState,
|
|
3266
3403
|
validationIssues,
|
|
3267
|
-
onValidationIssueClick
|
|
3404
|
+
onValidationIssueClick: onValidationIssueClick ? handleValidationIssueClick : void 0,
|
|
3405
|
+
validationOpen,
|
|
3406
|
+
onValidationOpenChange: setValidationOpen
|
|
3268
3407
|
}
|
|
3269
3408
|
)
|
|
3270
3409
|
]
|
|
@@ -3279,14 +3418,14 @@ function GraphViewer(props) {
|
|
|
3279
3418
|
isDragging: isPanelDragging,
|
|
3280
3419
|
onResizeHandleMouseDown: onResizeMouseDown,
|
|
3281
3420
|
children: [
|
|
3282
|
-
conceptOverride ? /* @__PURE__ */
|
|
3421
|
+
conceptOverride ? /* @__PURE__ */ jsx23(ConceptDetailPanel, { concept: conceptOverride }) : selectedSpecNode && graphspec ? /* @__PURE__ */ jsx23(
|
|
3283
3422
|
PipeDetailPanel,
|
|
3284
3423
|
{
|
|
3285
3424
|
node: selectedSpecNode,
|
|
3286
3425
|
spec: graphspec,
|
|
3287
3426
|
onConceptClick: handleConceptClick
|
|
3288
3427
|
}
|
|
3289
|
-
) : (detailSelection == null ? void 0 : detailSelection.stuffData) ? /* @__PURE__ */
|
|
3428
|
+
) : (detailSelection == null ? void 0 : detailSelection.stuffData) ? /* @__PURE__ */ jsx23(
|
|
3290
3429
|
StuffNodeDetail,
|
|
3291
3430
|
{
|
|
3292
3431
|
nodeId: detailSelection.nodeId,
|