@pipelex/mthds-ui 0.6.4 → 0.7.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-FHRUYFGV.js → chunk-ILX53OYM.js} +374 -98
- package/dist/chunk-ILX53OYM.js.map +1 -0
- package/dist/chunk-L24K3TZU.js +1 -0
- package/dist/graph/index.d.ts +62 -7
- package/dist/graph/index.js +20 -4
- package/dist/graph/react/detail/DetailPanel.css +146 -87
- package/dist/graph/react/graph-core.css +153 -76
- package/dist/graph/react/index.css +169 -168
- package/dist/graph/react/index.css.map +1 -1
- package/dist/graph/react/index.d.ts +32 -3
- package/dist/graph/react/index.js +392 -215
- package/dist/graph/react/index.js.map +1 -1
- package/dist/graph/react/stuff/StuffViewer.css +38 -11
- package/dist/graph/react/viewer/GraphToolbar.css +22 -24
- package/dist/index.d.ts +2 -2
- package/dist/index.js +20 -4
- package/dist/shiki/index.d.ts +16 -3
- package/dist/shiki/index.js +226 -15
- package/dist/shiki/index.js.map +1 -1
- package/dist/standalone/graph-standalone.html +368 -207
- package/dist/standalone/graph-viewer.css +359 -198
- package/dist/standalone/graph-viewer.js +9 -9
- package/dist/{types-C7rr1Egj.d.ts → types-DJTrDxjV.d.ts} +29 -10
- package/package.json +3 -1
- package/dist/chunk-FHRUYFGV.js.map +0 -1
- package/dist/chunk-IZ4FH2WM.js +0 -1
- /package/dist/{chunk-IZ4FH2WM.js.map → chunk-L24K3TZU.js.map} +0 -0
|
@@ -4,16 +4,19 @@ import {
|
|
|
4
4
|
EDGE_TYPE,
|
|
5
5
|
FOLD_MODE,
|
|
6
6
|
GRAPH_DIRECTION,
|
|
7
|
+
GRAPH_THEME,
|
|
7
8
|
MAX_VISIBLE_CONTROLLER_CHILDREN,
|
|
8
9
|
applyControllers,
|
|
9
10
|
applyFolds,
|
|
10
11
|
buildGraph,
|
|
11
12
|
findCousinControllers,
|
|
12
13
|
getLayoutedElements,
|
|
14
|
+
getPaletteForTheme,
|
|
13
15
|
getPipeBlueprint,
|
|
14
16
|
resolveConceptRef,
|
|
15
|
-
stuffDigestFromId
|
|
16
|
-
|
|
17
|
+
stuffDigestFromId,
|
|
18
|
+
validateGraphSpec
|
|
19
|
+
} from "../../chunk-ILX53OYM.js";
|
|
17
20
|
import {
|
|
18
21
|
__spreadProps,
|
|
19
22
|
__spreadValues
|
|
@@ -26,7 +29,7 @@ import "./stuff/StuffViewer.css";
|
|
|
26
29
|
import "./viewer/GraphToolbar.css";
|
|
27
30
|
|
|
28
31
|
// src/graph/react/viewer/GraphViewer.tsx
|
|
29
|
-
import
|
|
32
|
+
import React8 from "react";
|
|
30
33
|
import {
|
|
31
34
|
ReactFlow,
|
|
32
35
|
useNodesState,
|
|
@@ -186,7 +189,7 @@ function StuffViewer({
|
|
|
186
189
|
canEmbedPdf,
|
|
187
190
|
onOpenExternally
|
|
188
191
|
}) {
|
|
189
|
-
var _a;
|
|
192
|
+
var _a, _b;
|
|
190
193
|
const [activeTab, setActiveTab] = React.useState("html");
|
|
191
194
|
const [copied, setCopied] = React.useState(false);
|
|
192
195
|
const contentRef = React.useRef(null);
|
|
@@ -220,12 +223,12 @@ function StuffViewer({
|
|
|
220
223
|
const isPdf = effectiveMime === "application/pdf";
|
|
221
224
|
const isImage = (_a = effectiveMime == null ? void 0 : effectiveMime.startsWith("image/")) != null ? _a : false;
|
|
222
225
|
const htmlTabLabel = getHtmlTabLabel(effectiveMime != null ? effectiveMime : stuff.contentType);
|
|
223
|
-
const jsonString = React.useMemo(() => {
|
|
224
|
-
if (stuff.data == null) return null;
|
|
226
|
+
const { jsonString, jsonError } = React.useMemo(() => {
|
|
227
|
+
if (stuff.data == null) return { jsonString: null, jsonError: null };
|
|
225
228
|
try {
|
|
226
|
-
return JSON.stringify(stuff.data, null, 2);
|
|
227
|
-
} catch (
|
|
228
|
-
return
|
|
229
|
+
return { jsonString: JSON.stringify(stuff.data, null, 2), jsonError: null };
|
|
230
|
+
} catch (err) {
|
|
231
|
+
return { jsonString: null, jsonError: err instanceof Error ? err.message : String(err) };
|
|
229
232
|
}
|
|
230
233
|
}, [stuff.data]);
|
|
231
234
|
React.useEffect(() => {
|
|
@@ -248,7 +251,14 @@ function StuffViewer({
|
|
|
248
251
|
] })
|
|
249
252
|
] });
|
|
250
253
|
}
|
|
254
|
+
function renderJsonError(detail) {
|
|
255
|
+
return /* @__PURE__ */ jsxs("div", { className: "stuff-viewer-error", role: "alert", children: [
|
|
256
|
+
/* @__PURE__ */ jsx("div", { className: "stuff-viewer-error-title", children: "Unable to serialize data" }),
|
|
257
|
+
/* @__PURE__ */ jsx("div", { className: "stuff-viewer-error-detail", children: detail })
|
|
258
|
+
] });
|
|
259
|
+
}
|
|
251
260
|
function renderContent() {
|
|
261
|
+
var _a2;
|
|
252
262
|
if (activeTab === "html") {
|
|
253
263
|
if (isPdf) {
|
|
254
264
|
const canEmbed = canEmbedPdf !== false;
|
|
@@ -278,7 +288,7 @@ function StuffViewer({
|
|
|
278
288
|
}
|
|
279
289
|
if (isImage) {
|
|
280
290
|
if (inlineUrl) {
|
|
281
|
-
return /* @__PURE__ */ jsx("div", { className: "stuff-viewer-image", children: /* @__PURE__ */ jsx("img", { src: inlineUrl, alt: stuff.name
|
|
291
|
+
return /* @__PURE__ */ jsx("div", { className: "stuff-viewer-image", children: /* @__PURE__ */ jsx("img", { src: inlineUrl, alt: (_a2 = stuff.name) != null ? _a2 : "(unnamed stuff)" }) });
|
|
282
292
|
}
|
|
283
293
|
return renderMediaFallback("Image");
|
|
284
294
|
}
|
|
@@ -300,6 +310,7 @@ function StuffViewer({
|
|
|
300
310
|
}
|
|
301
311
|
);
|
|
302
312
|
}
|
|
313
|
+
if (jsonError) return renderJsonError(jsonError);
|
|
303
314
|
return /* @__PURE__ */ jsx("div", { className: "stuff-viewer-placeholder", children: "No content available" });
|
|
304
315
|
}
|
|
305
316
|
if (activeTab === "json") {
|
|
@@ -312,6 +323,7 @@ function StuffViewer({
|
|
|
312
323
|
}
|
|
313
324
|
);
|
|
314
325
|
}
|
|
326
|
+
if (jsonError) return renderJsonError(jsonError);
|
|
315
327
|
return /* @__PURE__ */ jsx("div", { className: "stuff-viewer-placeholder", children: "No JSON data available" });
|
|
316
328
|
}
|
|
317
329
|
if (stuff.dataText) {
|
|
@@ -332,6 +344,7 @@ function StuffViewer({
|
|
|
332
344
|
}
|
|
333
345
|
);
|
|
334
346
|
}
|
|
347
|
+
if (jsonError) return renderJsonError(jsonError);
|
|
335
348
|
return /* @__PURE__ */ jsx("div", { className: "stuff-viewer-placeholder", children: "No text data available" });
|
|
336
349
|
}
|
|
337
350
|
function handleCopy() {
|
|
@@ -389,7 +402,7 @@ function StuffViewer({
|
|
|
389
402
|
const rootClass = ["stuff-viewer", className].filter(Boolean).join(" ");
|
|
390
403
|
return /* @__PURE__ */ jsxs("div", { className: rootClass, children: [
|
|
391
404
|
/* @__PURE__ */ jsxs("div", { className: "stuff-viewer-header", children: [
|
|
392
|
-
/* @__PURE__ */ jsx("h3", { className: "stuff-viewer-title", children: stuff.name
|
|
405
|
+
/* @__PURE__ */ jsx("h3", { className: "stuff-viewer-title", children: (_b = stuff.name) != null ? _b : "(unnamed stuff)" }),
|
|
393
406
|
stuff.concept && /* @__PURE__ */ jsx("p", { className: "stuff-viewer-subtitle", children: stuff.concept })
|
|
394
407
|
] }),
|
|
395
408
|
/* @__PURE__ */ jsxs("div", { className: "stuff-viewer-toolbar", children: [
|
|
@@ -483,8 +496,10 @@ function DetailPanel({
|
|
|
483
496
|
"aria-label": "Resize panel"
|
|
484
497
|
}
|
|
485
498
|
),
|
|
486
|
-
/* @__PURE__ */
|
|
487
|
-
|
|
499
|
+
/* @__PURE__ */ jsxs2("div", { className: "detail-panel-content", children: [
|
|
500
|
+
/* @__PURE__ */ jsx2("div", { className: "detail-panel-close-row", children: /* @__PURE__ */ jsx2("button", { className: "detail-panel-close", onClick: onClose, "aria-label": "Close panel", children: "x" }) }),
|
|
501
|
+
children
|
|
502
|
+
] })
|
|
488
503
|
] });
|
|
489
504
|
}
|
|
490
505
|
|
|
@@ -1134,15 +1149,16 @@ var STATUS_COLORS = {
|
|
|
1134
1149
|
failed: "#FF5555",
|
|
1135
1150
|
running: "#8BE9FD",
|
|
1136
1151
|
scheduled: "#6272a4",
|
|
1137
|
-
skipped: "#6272a4"
|
|
1152
|
+
skipped: "#6272a4",
|
|
1153
|
+
canceled: "#6272a4"
|
|
1138
1154
|
};
|
|
1139
1155
|
function PipeDetailPanel({ node, spec, onConceptClick }) {
|
|
1140
|
-
var _a, _b, _c, _d, _e, _f, _g
|
|
1141
|
-
const pipeType =
|
|
1156
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1157
|
+
const pipeType = node.pipe_type;
|
|
1142
1158
|
const isController = CONTROLLER_TYPES.has(pipeType);
|
|
1143
|
-
const badge =
|
|
1144
|
-
const status =
|
|
1145
|
-
const statusColor = (
|
|
1159
|
+
const badge = PIPE_TYPE_BADGES[pipeType];
|
|
1160
|
+
const status = node.status;
|
|
1161
|
+
const statusColor = (_a = STATUS_COLORS[status]) != null ? _a : "#6272a4";
|
|
1146
1162
|
const blueprint = React5.useMemo(() => {
|
|
1147
1163
|
var _a2, _b2;
|
|
1148
1164
|
if (!node.pipe_code || !spec.pipe_registry) return void 0;
|
|
@@ -1154,9 +1170,9 @@ function PipeDetailPanel({ node, spec, onConceptClick }) {
|
|
|
1154
1170
|
}
|
|
1155
1171
|
return void 0;
|
|
1156
1172
|
}, [node.pipe_code, spec]);
|
|
1157
|
-
const inputs = (
|
|
1158
|
-
const outputs = (
|
|
1159
|
-
const description = (
|
|
1173
|
+
const inputs = (_c = (_b = node.io) == null ? void 0 : _b.inputs) != null ? _c : [];
|
|
1174
|
+
const outputs = (_e = (_d = node.io) == null ? void 0 : _d.outputs) != null ? _e : [];
|
|
1175
|
+
const description = (_f = blueprint == null ? void 0 : blueprint.description) != null ? _f : node.description;
|
|
1160
1176
|
return /* @__PURE__ */ jsxs13(Fragment9, { children: [
|
|
1161
1177
|
/* @__PURE__ */ jsxs13("div", { className: "detail-sticky-header", children: [
|
|
1162
1178
|
/* @__PURE__ */ jsxs13("div", { className: "detail-header", children: [
|
|
@@ -1171,53 +1187,47 @@ function PipeDetailPanel({ node, spec, onConceptClick }) {
|
|
|
1171
1187
|
"span",
|
|
1172
1188
|
{
|
|
1173
1189
|
className: `detail-pipe-code ${isController ? "detail-pipe-code--controller" : ""}`,
|
|
1174
|
-
children:
|
|
1190
|
+
children: node.pipe_code
|
|
1175
1191
|
}
|
|
1176
1192
|
)
|
|
1177
1193
|
] }),
|
|
1178
1194
|
/* @__PURE__ */ jsxs13("div", { className: "detail-status", children: [
|
|
1179
1195
|
/* @__PURE__ */ jsx13("span", { className: "detail-status-dot", style: { background: statusColor } }),
|
|
1180
1196
|
/* @__PURE__ */ jsx13("span", { className: "detail-status-label", style: { color: statusColor }, children: status }),
|
|
1181
|
-
((
|
|
1197
|
+
((_g = node.timing) == null ? void 0 : _g.duration) != null && /* @__PURE__ */ jsx13("span", { className: "detail-duration", children: formatDuration(node.timing.duration) })
|
|
1182
1198
|
] }),
|
|
1183
1199
|
description && /* @__PURE__ */ jsx13("div", { className: "detail-description", children: description }),
|
|
1184
1200
|
inputs.length > 0 && /* @__PURE__ */ jsxs13("div", { children: [
|
|
1185
1201
|
/* @__PURE__ */ jsx13("div", { className: "detail-section-label", children: "Inputs" }),
|
|
1186
|
-
/* @__PURE__ */ jsx13("div", { className: "detail-io-list", children: inputs.map((input, idx) =>
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
"
|
|
1190
|
-
{
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
children:
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
idx
|
|
1200
|
-
);
|
|
1201
|
-
}) })
|
|
1202
|
+
/* @__PURE__ */ jsx13("div", { className: "detail-io-list", children: inputs.map((input, idx) => /* @__PURE__ */ jsxs13(
|
|
1203
|
+
"div",
|
|
1204
|
+
{
|
|
1205
|
+
className: "detail-io-pill",
|
|
1206
|
+
style: { cursor: input.concept && onConceptClick ? "pointer" : void 0 },
|
|
1207
|
+
onClick: () => input.concept && (onConceptClick == null ? void 0 : onConceptClick(input.concept)),
|
|
1208
|
+
children: [
|
|
1209
|
+
/* @__PURE__ */ jsx13("span", { className: "detail-io-name", children: input.name }),
|
|
1210
|
+
input.concept && /* @__PURE__ */ jsx13("span", { className: "detail-io-concept", children: input.concept })
|
|
1211
|
+
]
|
|
1212
|
+
},
|
|
1213
|
+
idx
|
|
1214
|
+
)) })
|
|
1202
1215
|
] }),
|
|
1203
1216
|
outputs.length > 0 && /* @__PURE__ */ jsxs13("div", { children: [
|
|
1204
1217
|
/* @__PURE__ */ jsx13("div", { className: "detail-section-label", children: "Output" }),
|
|
1205
|
-
/* @__PURE__ */ jsx13("div", { className: "detail-io-list", children: outputs.map((output, idx) =>
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
"
|
|
1209
|
-
{
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
children:
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
idx
|
|
1219
|
-
);
|
|
1220
|
-
}) })
|
|
1218
|
+
/* @__PURE__ */ jsx13("div", { className: "detail-io-list", children: outputs.map((output, idx) => /* @__PURE__ */ jsxs13(
|
|
1219
|
+
"div",
|
|
1220
|
+
{
|
|
1221
|
+
className: "detail-io-pill",
|
|
1222
|
+
style: { cursor: output.concept && onConceptClick ? "pointer" : void 0 },
|
|
1223
|
+
onClick: () => output.concept && (onConceptClick == null ? void 0 : onConceptClick(output.concept)),
|
|
1224
|
+
children: [
|
|
1225
|
+
/* @__PURE__ */ jsx13("span", { className: "detail-io-name", children: output.name }),
|
|
1226
|
+
output.concept && /* @__PURE__ */ jsx13("span", { className: "detail-io-concept", children: output.concept })
|
|
1227
|
+
]
|
|
1228
|
+
},
|
|
1229
|
+
idx
|
|
1230
|
+
)) })
|
|
1221
1231
|
] }),
|
|
1222
1232
|
(inputs.length > 0 || outputs.length > 0) && /* @__PURE__ */ jsx13("div", { style: { borderTop: "1px solid rgba(255,255,255,0.06)", margin: "4px 0" } })
|
|
1223
1233
|
] }),
|
|
@@ -1316,6 +1326,7 @@ function GenericExecutionData({ data }) {
|
|
|
1316
1326
|
}
|
|
1317
1327
|
|
|
1318
1328
|
// src/graph/react/detail/ConceptDetailPanel.tsx
|
|
1329
|
+
import React6 from "react";
|
|
1319
1330
|
import { Fragment as Fragment10, jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1320
1331
|
function ConceptDetailPanel({
|
|
1321
1332
|
concept,
|
|
@@ -1323,8 +1334,10 @@ function ConceptDetailPanel({
|
|
|
1323
1334
|
isDryRun,
|
|
1324
1335
|
resolveStorageUrl,
|
|
1325
1336
|
canEmbedPdf,
|
|
1326
|
-
onOpenExternally
|
|
1337
|
+
onOpenExternally,
|
|
1338
|
+
instanceKey
|
|
1327
1339
|
}) {
|
|
1340
|
+
var _a;
|
|
1328
1341
|
return /* @__PURE__ */ jsxs14(Fragment10, { children: [
|
|
1329
1342
|
/* @__PURE__ */ jsxs14("div", { className: "detail-header", children: [
|
|
1330
1343
|
/* @__PURE__ */ jsx14("span", { className: "detail-concept-code", children: concept.code }),
|
|
@@ -1335,22 +1348,88 @@ function ConceptDetailPanel({
|
|
|
1335
1348
|
"refines ",
|
|
1336
1349
|
/* @__PURE__ */ jsx14("span", { className: "detail-refines-code", children: concept.refines })
|
|
1337
1350
|
] }),
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1351
|
+
/* @__PURE__ */ jsx14(
|
|
1352
|
+
ConceptBody,
|
|
1353
|
+
{
|
|
1354
|
+
concept,
|
|
1355
|
+
ioData,
|
|
1356
|
+
isDryRun,
|
|
1357
|
+
resolveStorageUrl,
|
|
1358
|
+
canEmbedPdf,
|
|
1359
|
+
onOpenExternally
|
|
1360
|
+
},
|
|
1361
|
+
instanceKey != null ? instanceKey : `${concept.code}:${ioData && "digest" in ioData ? ioData.digest : (_a = ioData == null ? void 0 : ioData.name) != null ? _a : ""}`
|
|
1362
|
+
)
|
|
1363
|
+
] });
|
|
1364
|
+
}
|
|
1365
|
+
function ConceptBody({
|
|
1366
|
+
concept,
|
|
1367
|
+
ioData,
|
|
1368
|
+
isDryRun,
|
|
1369
|
+
resolveStorageUrl,
|
|
1370
|
+
canEmbedPdf,
|
|
1371
|
+
onOpenExternally
|
|
1372
|
+
}) {
|
|
1373
|
+
const hasData = Boolean(ioData) && !isDryRun;
|
|
1374
|
+
const [activeTab, setActiveTab] = React6.useState(hasData ? "data" : "structure");
|
|
1375
|
+
const baseId = React6.useId();
|
|
1376
|
+
const tabId = (tab) => `${baseId}-tab-${tab}`;
|
|
1377
|
+
const panelId = (tab) => `${baseId}-tabpanel-${tab}`;
|
|
1378
|
+
const structure = concept.json_schema ? /* @__PURE__ */ jsxs14("div", { children: [
|
|
1379
|
+
/* @__PURE__ */ jsx14("div", { className: "detail-section-label", children: "Structure" }),
|
|
1380
|
+
/* @__PURE__ */ jsx14(SchemaTable, { schema: concept.json_schema, isDryRun })
|
|
1381
|
+
] }) : /* @__PURE__ */ jsx14("div", { className: "detail-not-available", children: "Schema not available" });
|
|
1382
|
+
if (!hasData) return structure;
|
|
1383
|
+
const onTabKeyDown = (event) => {
|
|
1384
|
+
var _a;
|
|
1385
|
+
let next;
|
|
1386
|
+
switch (event.key) {
|
|
1387
|
+
case "ArrowLeft":
|
|
1388
|
+
case "ArrowRight":
|
|
1389
|
+
next = activeTab === "data" ? "structure" : "data";
|
|
1390
|
+
break;
|
|
1391
|
+
case "Home":
|
|
1392
|
+
next = "data";
|
|
1393
|
+
break;
|
|
1394
|
+
case "End":
|
|
1395
|
+
next = "structure";
|
|
1396
|
+
break;
|
|
1397
|
+
default:
|
|
1398
|
+
return;
|
|
1399
|
+
}
|
|
1400
|
+
event.preventDefault();
|
|
1401
|
+
setActiveTab(next);
|
|
1402
|
+
(_a = document.getElementById(tabId(next))) == null ? void 0 : _a.focus();
|
|
1403
|
+
};
|
|
1404
|
+
const renderTab = (tab, label) => /* @__PURE__ */ jsx14(
|
|
1405
|
+
"button",
|
|
1406
|
+
{
|
|
1407
|
+
type: "button",
|
|
1408
|
+
role: "tab",
|
|
1409
|
+
id: tabId(tab),
|
|
1410
|
+
"aria-selected": activeTab === tab,
|
|
1411
|
+
"aria-controls": panelId(tab),
|
|
1412
|
+
tabIndex: activeTab === tab ? 0 : -1,
|
|
1413
|
+
className: `detail-tab ${activeTab === tab ? "detail-tab--active" : ""}`,
|
|
1414
|
+
onClick: () => setActiveTab(tab),
|
|
1415
|
+
onKeyDown: onTabKeyDown,
|
|
1416
|
+
children: label
|
|
1417
|
+
}
|
|
1418
|
+
);
|
|
1419
|
+
return /* @__PURE__ */ jsxs14(Fragment10, { children: [
|
|
1420
|
+
/* @__PURE__ */ jsxs14("div", { className: "detail-tabs", role: "tablist", "aria-label": "Concept views", children: [
|
|
1421
|
+
renderTab("data", "Data"),
|
|
1422
|
+
renderTab("structure", "Structure")
|
|
1423
|
+
] }),
|
|
1424
|
+
/* @__PURE__ */ jsx14("div", { role: "tabpanel", id: panelId(activeTab), "aria-labelledby": tabId(activeTab), children: activeTab === "data" ? /* @__PURE__ */ jsx14(
|
|
1425
|
+
StuffViewer,
|
|
1426
|
+
{
|
|
1427
|
+
stuff: toStuffViewerData(ioData),
|
|
1428
|
+
resolveStorageUrl,
|
|
1429
|
+
canEmbedPdf,
|
|
1430
|
+
onOpenExternally
|
|
1431
|
+
}
|
|
1432
|
+
) : structure })
|
|
1354
1433
|
] });
|
|
1355
1434
|
}
|
|
1356
1435
|
function SchemaTable({
|
|
@@ -1390,9 +1469,9 @@ function extractType(schema) {
|
|
|
1390
1469
|
if (schema.allOf) return "all";
|
|
1391
1470
|
if (schema.$ref) {
|
|
1392
1471
|
const ref = String(schema.$ref);
|
|
1393
|
-
return (_a = ref.split("/").pop()) != null ? _a : "
|
|
1472
|
+
return (_a = ref.split("/").pop()) != null ? _a : "(unresolved type)";
|
|
1394
1473
|
}
|
|
1395
|
-
return "
|
|
1474
|
+
return "(unresolved type)";
|
|
1396
1475
|
}
|
|
1397
1476
|
function toStuffViewerData(ioData) {
|
|
1398
1477
|
var _a;
|
|
@@ -1539,7 +1618,7 @@ function hydrateLabels(nodes) {
|
|
|
1539
1618
|
}
|
|
1540
1619
|
|
|
1541
1620
|
// src/graph/react/viewer/GraphToolbar.tsx
|
|
1542
|
-
import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1621
|
+
import { Fragment as Fragment11, jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1543
1622
|
var ARROW_RIGHT_ICON = /* @__PURE__ */ jsxs16(
|
|
1544
1623
|
"svg",
|
|
1545
1624
|
{
|
|
@@ -1691,6 +1770,44 @@ var EXPAND_ALL_ICON = /* @__PURE__ */ jsxs16(
|
|
|
1691
1770
|
]
|
|
1692
1771
|
}
|
|
1693
1772
|
);
|
|
1773
|
+
var SUN_ICON = /* @__PURE__ */ jsxs16(
|
|
1774
|
+
"svg",
|
|
1775
|
+
{
|
|
1776
|
+
viewBox: "0 0 24 24",
|
|
1777
|
+
width: "14",
|
|
1778
|
+
height: "14",
|
|
1779
|
+
fill: "none",
|
|
1780
|
+
stroke: "currentColor",
|
|
1781
|
+
strokeWidth: "2",
|
|
1782
|
+
strokeLinecap: "round",
|
|
1783
|
+
strokeLinejoin: "round",
|
|
1784
|
+
children: [
|
|
1785
|
+
/* @__PURE__ */ jsx16("circle", { cx: "12", cy: "12", r: "4" }),
|
|
1786
|
+
/* @__PURE__ */ jsx16("line", { x1: "12", y1: "2", x2: "12", y2: "4" }),
|
|
1787
|
+
/* @__PURE__ */ jsx16("line", { x1: "12", y1: "20", x2: "12", y2: "22" }),
|
|
1788
|
+
/* @__PURE__ */ jsx16("line", { x1: "4.93", y1: "4.93", x2: "6.34", y2: "6.34" }),
|
|
1789
|
+
/* @__PURE__ */ jsx16("line", { x1: "17.66", y1: "17.66", x2: "19.07", y2: "19.07" }),
|
|
1790
|
+
/* @__PURE__ */ jsx16("line", { x1: "2", y1: "12", x2: "4", y2: "12" }),
|
|
1791
|
+
/* @__PURE__ */ jsx16("line", { x1: "20", y1: "12", x2: "22", y2: "12" }),
|
|
1792
|
+
/* @__PURE__ */ jsx16("line", { x1: "4.93", y1: "19.07", x2: "6.34", y2: "17.66" }),
|
|
1793
|
+
/* @__PURE__ */ jsx16("line", { x1: "17.66", y1: "6.34", x2: "19.07", y2: "4.93" })
|
|
1794
|
+
]
|
|
1795
|
+
}
|
|
1796
|
+
);
|
|
1797
|
+
var MOON_ICON = /* @__PURE__ */ jsx16(
|
|
1798
|
+
"svg",
|
|
1799
|
+
{
|
|
1800
|
+
viewBox: "0 0 24 24",
|
|
1801
|
+
width: "14",
|
|
1802
|
+
height: "14",
|
|
1803
|
+
fill: "none",
|
|
1804
|
+
stroke: "currentColor",
|
|
1805
|
+
strokeWidth: "2",
|
|
1806
|
+
strokeLinecap: "round",
|
|
1807
|
+
strokeLinejoin: "round",
|
|
1808
|
+
children: /* @__PURE__ */ jsx16("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" })
|
|
1809
|
+
}
|
|
1810
|
+
);
|
|
1694
1811
|
function GraphToolbar({
|
|
1695
1812
|
direction,
|
|
1696
1813
|
onDirectionChange,
|
|
@@ -1703,8 +1820,12 @@ function GraphToolbar({
|
|
|
1703
1820
|
onExpandAll,
|
|
1704
1821
|
foldAllDisabled = false,
|
|
1705
1822
|
expandAllDisabled = false,
|
|
1823
|
+
theme,
|
|
1824
|
+
onThemeChange,
|
|
1706
1825
|
rightOffset = 0
|
|
1707
1826
|
}) {
|
|
1827
|
+
const themeToggleEnabled = theme !== void 0 && onThemeChange !== void 0;
|
|
1828
|
+
const themeLabel = theme === GRAPH_THEME.LIGHT ? "Switch to dark theme" : "Switch to light theme";
|
|
1708
1829
|
const isVertical = direction === GRAPH_DIRECTION.TB || direction === GRAPH_DIRECTION.BT;
|
|
1709
1830
|
const directionLabel = isVertical ? "Switch to horizontal layout" : "Switch to vertical layout";
|
|
1710
1831
|
const controllersLabel = showControllers ? "Hide pipe controllers" : "Show pipe controllers \u2014 groups pipes by their controlling pipe";
|
|
@@ -1792,7 +1913,21 @@ function GraphToolbar({
|
|
|
1792
1913
|
"aria-label": "Fit view",
|
|
1793
1914
|
children: FIT_VIEW_ICON
|
|
1794
1915
|
}
|
|
1795
|
-
)
|
|
1916
|
+
),
|
|
1917
|
+
themeToggleEnabled && /* @__PURE__ */ jsxs16(Fragment11, { children: [
|
|
1918
|
+
/* @__PURE__ */ jsx16("div", { className: "graph-toolbar-separator" }),
|
|
1919
|
+
/* @__PURE__ */ jsx16(
|
|
1920
|
+
"button",
|
|
1921
|
+
{
|
|
1922
|
+
type: "button",
|
|
1923
|
+
className: "graph-toolbar-btn",
|
|
1924
|
+
onClick: () => onThemeChange(theme === GRAPH_THEME.LIGHT ? GRAPH_THEME.DARK : GRAPH_THEME.LIGHT),
|
|
1925
|
+
title: themeLabel,
|
|
1926
|
+
"aria-label": themeLabel,
|
|
1927
|
+
children: theme === GRAPH_THEME.LIGHT ? MOON_ICON : SUN_ICON
|
|
1928
|
+
}
|
|
1929
|
+
)
|
|
1930
|
+
] })
|
|
1796
1931
|
] });
|
|
1797
1932
|
}
|
|
1798
1933
|
|
|
@@ -1888,16 +2023,16 @@ var STATUS_CONFIG = {
|
|
|
1888
2023
|
failed: { color: "#FF5555", label: "Failed" },
|
|
1889
2024
|
running: { color: "#8BE9FD", label: "Running" },
|
|
1890
2025
|
scheduled: { color: "#6272a4", label: "Scheduled" },
|
|
1891
|
-
skipped: { color: "#6272a4", label: "Skipped" }
|
|
2026
|
+
skipped: { color: "#6272a4", label: "Skipped" },
|
|
2027
|
+
canceled: { color: "#6272a4", label: "Canceled" }
|
|
1892
2028
|
};
|
|
1893
2029
|
var MAX_VISIBLE_INPUTS = 4;
|
|
1894
2030
|
function getBadge(pipeType) {
|
|
1895
2031
|
return PIPE_TYPE_BADGES2[pipeType];
|
|
1896
2032
|
}
|
|
1897
2033
|
function PipeCardBase({ data, children }) {
|
|
1898
|
-
var _a;
|
|
1899
2034
|
const badge = getBadge(data.pipeType);
|
|
1900
|
-
const statusConfig =
|
|
2035
|
+
const statusConfig = STATUS_CONFIG[data.status];
|
|
1901
2036
|
const isRunning = data.status === "running";
|
|
1902
2037
|
const isController = isControllerType(data.pipeType);
|
|
1903
2038
|
const [inputsExpanded, setInputsExpanded] = useState2(false);
|
|
@@ -1934,9 +2069,9 @@ function PipeCardBase({ data, children }) {
|
|
|
1934
2069
|
title: "Expand controller (alt/option: only this one)",
|
|
1935
2070
|
"aria-label": "Expand controller",
|
|
1936
2071
|
onClick: (e) => {
|
|
1937
|
-
var
|
|
2072
|
+
var _a;
|
|
1938
2073
|
e.stopPropagation();
|
|
1939
|
-
(
|
|
2074
|
+
(_a = data.onExpand) == null ? void 0 : _a.call(data, { soloMode: e.altKey });
|
|
1940
2075
|
},
|
|
1941
2076
|
children: "\u2922"
|
|
1942
2077
|
}
|
|
@@ -2008,7 +2143,7 @@ function getPipeCardComponent(pipeType) {
|
|
|
2008
2143
|
}
|
|
2009
2144
|
|
|
2010
2145
|
// src/graph/react/nodes/pipe/PipeCardNode.tsx
|
|
2011
|
-
import { Fragment as
|
|
2146
|
+
import { Fragment as Fragment12, jsx as jsx19, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2012
2147
|
function PipeCardNode({ data }) {
|
|
2013
2148
|
var _a;
|
|
2014
2149
|
const Card = (_a = getPipeCardComponent(data.pipeType)) != null ? _a : PipeCardBase;
|
|
@@ -2021,7 +2156,7 @@ function PipeCardRFNode({
|
|
|
2021
2156
|
}) {
|
|
2022
2157
|
const payload = data.pipeCardData;
|
|
2023
2158
|
if (!payload) return null;
|
|
2024
|
-
return /* @__PURE__ */ jsxs19(
|
|
2159
|
+
return /* @__PURE__ */ jsxs19(Fragment12, { children: [
|
|
2025
2160
|
/* @__PURE__ */ jsx19(Handle, { type: "target", position: targetPosition }),
|
|
2026
2161
|
/* @__PURE__ */ jsx19(PipeCardNode, { data: payload }),
|
|
2027
2162
|
/* @__PURE__ */ jsx19(Handle, { type: "source", position: sourcePosition })
|
|
@@ -2029,11 +2164,12 @@ function PipeCardRFNode({
|
|
|
2029
2164
|
}
|
|
2030
2165
|
|
|
2031
2166
|
// src/graph/react/viewer/GraphViewer.tsx
|
|
2032
|
-
import { Fragment as
|
|
2167
|
+
import { Fragment as Fragment13, jsx as jsx20, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2033
2168
|
var nodeTypes = __spreadProps(__spreadValues({}, controllerNodeTypes), {
|
|
2034
2169
|
pipeCard: PipeCardRFNode
|
|
2035
2170
|
});
|
|
2036
2171
|
function StuffNodeDetail({
|
|
2172
|
+
nodeId,
|
|
2037
2173
|
stuffData,
|
|
2038
2174
|
graphspec,
|
|
2039
2175
|
resolveStorageUrl,
|
|
@@ -2041,11 +2177,12 @@ function StuffNodeDetail({
|
|
|
2041
2177
|
onOpenExternally
|
|
2042
2178
|
}) {
|
|
2043
2179
|
const conceptInfo = stuffData.concept && graphspec ? resolveConceptRef(graphspec, stuffData.concept) : void 0;
|
|
2044
|
-
return /* @__PURE__ */ jsx20(
|
|
2180
|
+
return /* @__PURE__ */ jsx20(Fragment13, { children: conceptInfo ? /* @__PURE__ */ jsx20(
|
|
2045
2181
|
ConceptDetailPanel,
|
|
2046
2182
|
{
|
|
2047
2183
|
concept: conceptInfo,
|
|
2048
2184
|
ioData: stuffData,
|
|
2185
|
+
instanceKey: nodeId,
|
|
2049
2186
|
resolveStorageUrl,
|
|
2050
2187
|
canEmbedPdf,
|
|
2051
2188
|
onOpenExternally
|
|
@@ -2067,6 +2204,10 @@ function seedFoldedControllers(mode, controllerIds) {
|
|
|
2067
2204
|
if (mode === FOLD_MODE.FOLDED) return new Set(controllerIds);
|
|
2068
2205
|
return /* @__PURE__ */ new Set();
|
|
2069
2206
|
}
|
|
2207
|
+
function resolveExternalTheme(themeProp, configTheme) {
|
|
2208
|
+
var _a, _b;
|
|
2209
|
+
return (_b = (_a = themeProp != null ? themeProp : configTheme) != null ? _a : DEFAULT_GRAPH_CONFIG.theme) != null ? _b : GRAPH_THEME.DARK;
|
|
2210
|
+
}
|
|
2070
2211
|
function cloneCachedNodes(nodes) {
|
|
2071
2212
|
return nodes.map((n) => __spreadProps(__spreadValues({}, n), {
|
|
2072
2213
|
position: __spreadValues({}, n.position),
|
|
@@ -2093,12 +2234,15 @@ function applyStatusOverrides(nodes, statusMap) {
|
|
|
2093
2234
|
function GraphViewer(props) {
|
|
2094
2235
|
var _a, _b, _c;
|
|
2095
2236
|
const {
|
|
2096
|
-
graphspec,
|
|
2237
|
+
graphspec: graphspecProp,
|
|
2097
2238
|
config = DEFAULT_GRAPH_CONFIG,
|
|
2098
2239
|
initialDirection,
|
|
2099
2240
|
initialShowControllers,
|
|
2100
2241
|
initialFoldMode,
|
|
2101
2242
|
hideToolbar = false,
|
|
2243
|
+
theme: themeProp,
|
|
2244
|
+
showThemeToggle = true,
|
|
2245
|
+
onThemeChange,
|
|
2102
2246
|
onNavigateToPipe,
|
|
2103
2247
|
onStuffNodeClick,
|
|
2104
2248
|
onReactFlowInit,
|
|
@@ -2110,38 +2254,61 @@ function GraphViewer(props) {
|
|
|
2110
2254
|
canEmbedPdf,
|
|
2111
2255
|
onOpenExternally
|
|
2112
2256
|
} = props;
|
|
2113
|
-
const
|
|
2257
|
+
const graphspec = React8.useMemo(
|
|
2258
|
+
() => graphspecProp === null ? null : validateGraphSpec(graphspecProp),
|
|
2259
|
+
[graphspecProp]
|
|
2260
|
+
);
|
|
2261
|
+
const [direction, setDirection] = React8.useState(
|
|
2114
2262
|
() => {
|
|
2115
2263
|
var _a2, _b2;
|
|
2116
2264
|
return (_b2 = (_a2 = initialDirection != null ? initialDirection : config.direction) != null ? _a2 : DEFAULT_GRAPH_CONFIG.direction) != null ? _b2 : GRAPH_DIRECTION.TB;
|
|
2117
2265
|
}
|
|
2118
2266
|
);
|
|
2267
|
+
const externalTheme = resolveExternalTheme(themeProp, config.theme);
|
|
2268
|
+
const [theme, setTheme] = React8.useState(externalTheme);
|
|
2269
|
+
const prevExternalThemeRef = React8.useRef(externalTheme);
|
|
2270
|
+
React8.useEffect(() => {
|
|
2271
|
+
if (externalTheme !== prevExternalThemeRef.current) {
|
|
2272
|
+
prevExternalThemeRef.current = externalTheme;
|
|
2273
|
+
setTheme(externalTheme);
|
|
2274
|
+
}
|
|
2275
|
+
}, [externalTheme]);
|
|
2276
|
+
const onThemeChangeRef = React8.useRef(onThemeChange);
|
|
2277
|
+
onThemeChangeRef.current = onThemeChange;
|
|
2278
|
+
const prevReportedThemeRef = React8.useRef(theme);
|
|
2279
|
+
React8.useEffect(() => {
|
|
2280
|
+
var _a2;
|
|
2281
|
+
if (theme !== prevReportedThemeRef.current) {
|
|
2282
|
+
prevReportedThemeRef.current = theme;
|
|
2283
|
+
(_a2 = onThemeChangeRef.current) == null ? void 0 : _a2.call(onThemeChangeRef, theme);
|
|
2284
|
+
}
|
|
2285
|
+
}, [theme]);
|
|
2119
2286
|
const effectiveFoldMode = (_b = (_a = initialFoldMode != null ? initialFoldMode : config.foldMode) != null ? _a : DEFAULT_GRAPH_CONFIG.foldMode) != null ? _b : FOLD_MODE.EXPANDED;
|
|
2120
|
-
const [showControllers, setShowControllers] =
|
|
2287
|
+
const [showControllers, setShowControllers] = React8.useState(() => {
|
|
2121
2288
|
var _a2, _b2;
|
|
2122
2289
|
if (effectiveFoldMode === FOLD_MODE.FOLDED) return true;
|
|
2123
2290
|
return (_b2 = (_a2 = initialShowControllers != null ? initialShowControllers : config.showControllers) != null ? _a2 : DEFAULT_GRAPH_CONFIG.showControllers) != null ? _b2 : false;
|
|
2124
2291
|
});
|
|
2125
|
-
const foldModeRef =
|
|
2292
|
+
const foldModeRef = React8.useRef(effectiveFoldMode);
|
|
2126
2293
|
foldModeRef.current = effectiveFoldMode;
|
|
2127
|
-
const containerRef =
|
|
2128
|
-
const [detailSelection, setDetailSelection] =
|
|
2129
|
-
const [conceptOverride, setConceptOverride] =
|
|
2294
|
+
const containerRef = React8.useRef(null);
|
|
2295
|
+
const [detailSelection, setDetailSelection] = React8.useState(null);
|
|
2296
|
+
const [conceptOverride, setConceptOverride] = React8.useState(null);
|
|
2130
2297
|
const {
|
|
2131
2298
|
width: panelWidth,
|
|
2132
2299
|
isDragging: isPanelDragging,
|
|
2133
2300
|
handleMouseDown: onResizeMouseDown
|
|
2134
2301
|
} = useResizable({ defaultWidth: 380, minWidth: 280, maxWidth: 800, containerRef });
|
|
2135
|
-
|
|
2302
|
+
React8.useEffect(() => {
|
|
2136
2303
|
setDetailSelection(null);
|
|
2137
2304
|
setConceptOverride(null);
|
|
2138
2305
|
}, [graphspec]);
|
|
2139
|
-
|
|
2140
|
-
var _a2;
|
|
2306
|
+
React8.useEffect(() => {
|
|
2141
2307
|
const el = containerRef.current;
|
|
2142
2308
|
if (!el) return;
|
|
2143
|
-
const
|
|
2144
|
-
|
|
2309
|
+
const themePalette = getPaletteForTheme(theme);
|
|
2310
|
+
const overrides = config.paletteColors;
|
|
2311
|
+
const palette = overrides ? __spreadValues(__spreadValues({}, themePalette), overrides) : themePalette;
|
|
2145
2312
|
for (const [cssVar, value] of Object.entries(palette)) {
|
|
2146
2313
|
el.style.setProperty(cssVar, value);
|
|
2147
2314
|
}
|
|
@@ -2150,15 +2317,15 @@ function GraphViewer(props) {
|
|
|
2150
2317
|
el.style.removeProperty(cssVar);
|
|
2151
2318
|
}
|
|
2152
2319
|
};
|
|
2153
|
-
}, [config.paletteColors]);
|
|
2320
|
+
}, [config.paletteColors, theme]);
|
|
2154
2321
|
const [nodes, setNodes, onNodesChange] = useNodesState([]);
|
|
2155
2322
|
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
|
|
2156
|
-
const reactFlowRef =
|
|
2157
|
-
const initialDataRef =
|
|
2158
|
-
const rawGraphDataRef =
|
|
2159
|
-
const layoutCacheRef =
|
|
2160
|
-
const [expandedControllers, setExpandedControllers] =
|
|
2161
|
-
const toggleCollapse =
|
|
2323
|
+
const reactFlowRef = React8.useRef(null);
|
|
2324
|
+
const initialDataRef = React8.useRef(null);
|
|
2325
|
+
const rawGraphDataRef = React8.useRef(null);
|
|
2326
|
+
const layoutCacheRef = React8.useRef(null);
|
|
2327
|
+
const [expandedControllers, setExpandedControllers] = React8.useState(/* @__PURE__ */ new Set());
|
|
2328
|
+
const toggleCollapse = React8.useCallback((controllerId) => {
|
|
2162
2329
|
setExpandedControllers((prev) => {
|
|
2163
2330
|
const next = new Set(prev);
|
|
2164
2331
|
if (next.has(controllerId)) next.delete(controllerId);
|
|
@@ -2166,8 +2333,8 @@ function GraphViewer(props) {
|
|
|
2166
2333
|
return next;
|
|
2167
2334
|
});
|
|
2168
2335
|
}, []);
|
|
2169
|
-
const [foldedControllers, setFoldedControllers] =
|
|
2170
|
-
const toggleFold =
|
|
2336
|
+
const [foldedControllers, setFoldedControllers] = React8.useState(/* @__PURE__ */ new Set());
|
|
2337
|
+
const toggleFold = React8.useCallback((controllerId, options) => {
|
|
2171
2338
|
setFoldedControllers((prev) => {
|
|
2172
2339
|
const next = new Set(prev);
|
|
2173
2340
|
const shouldFold = !next.has(controllerId);
|
|
@@ -2181,34 +2348,34 @@ function GraphViewer(props) {
|
|
|
2181
2348
|
});
|
|
2182
2349
|
}, []);
|
|
2183
2350
|
const edgeType = config.edgeType || EDGE_TYPE.DEFAULT;
|
|
2184
|
-
const layoutConfig =
|
|
2351
|
+
const layoutConfig = React8.useMemo(
|
|
2185
2352
|
() => ({ nodesep: config.nodesep, ranksep: config.ranksep }),
|
|
2186
2353
|
[config.nodesep, config.ranksep]
|
|
2187
2354
|
);
|
|
2188
|
-
const showControllersRef =
|
|
2355
|
+
const showControllersRef = React8.useRef(showControllers);
|
|
2189
2356
|
showControllersRef.current = showControllers;
|
|
2190
|
-
const directionRef =
|
|
2357
|
+
const directionRef = React8.useRef(direction);
|
|
2191
2358
|
directionRef.current = direction;
|
|
2192
|
-
const layoutConfigRef =
|
|
2359
|
+
const layoutConfigRef = React8.useRef(layoutConfig);
|
|
2193
2360
|
layoutConfigRef.current = layoutConfig;
|
|
2194
|
-
const initialZoomRef =
|
|
2361
|
+
const initialZoomRef = React8.useRef(config.initialZoom);
|
|
2195
2362
|
initialZoomRef.current = config.initialZoom;
|
|
2196
|
-
const panToTopRef =
|
|
2363
|
+
const panToTopRef = React8.useRef(config.panToTop);
|
|
2197
2364
|
panToTopRef.current = config.panToTop;
|
|
2198
|
-
const expandedRef =
|
|
2365
|
+
const expandedRef = React8.useRef(expandedControllers);
|
|
2199
2366
|
expandedRef.current = expandedControllers;
|
|
2200
|
-
const toggleCollapseRef =
|
|
2367
|
+
const toggleCollapseRef = React8.useRef(toggleCollapse);
|
|
2201
2368
|
toggleCollapseRef.current = toggleCollapse;
|
|
2202
|
-
const foldedRef =
|
|
2369
|
+
const foldedRef = React8.useRef(foldedControllers);
|
|
2203
2370
|
foldedRef.current = foldedControllers;
|
|
2204
|
-
const toggleFoldRef =
|
|
2371
|
+
const toggleFoldRef = React8.useRef(toggleFold);
|
|
2205
2372
|
toggleFoldRef.current = toggleFold;
|
|
2206
|
-
const isFirstFoldEffect =
|
|
2207
|
-
const prevFoldSizeRef =
|
|
2208
|
-
const skipNextFoldEffectRef =
|
|
2209
|
-
const statusMapRef =
|
|
2373
|
+
const isFirstFoldEffect = React8.useRef(true);
|
|
2374
|
+
const prevFoldSizeRef = React8.useRef(0);
|
|
2375
|
+
const skipNextFoldEffectRef = React8.useRef(false);
|
|
2376
|
+
const statusMapRef = React8.useRef(statusMap);
|
|
2210
2377
|
statusMapRef.current = statusMap;
|
|
2211
|
-
|
|
2378
|
+
React8.useEffect(() => {
|
|
2212
2379
|
if (!initialDataRef.current) return;
|
|
2213
2380
|
let cancelled = false;
|
|
2214
2381
|
(async () => {
|
|
@@ -2260,7 +2427,7 @@ function GraphViewer(props) {
|
|
|
2260
2427
|
cancelled = true;
|
|
2261
2428
|
};
|
|
2262
2429
|
}, [direction, layoutConfig]);
|
|
2263
|
-
|
|
2430
|
+
React8.useEffect(() => {
|
|
2264
2431
|
if (!layoutCacheRef.current || !initialDataRef.current) return;
|
|
2265
2432
|
const cachedNodes = cloneCachedNodes(layoutCacheRef.current.nodes);
|
|
2266
2433
|
const cachedEdges = layoutCacheRef.current.edges;
|
|
@@ -2280,7 +2447,7 @@ function GraphViewer(props) {
|
|
|
2280
2447
|
);
|
|
2281
2448
|
setEdges(toAppEdges(withControllers.edges));
|
|
2282
2449
|
}, [showControllers, expandedControllers, toggleCollapse, toggleFold]);
|
|
2283
|
-
|
|
2450
|
+
React8.useEffect(() => {
|
|
2284
2451
|
if (!graphspec) {
|
|
2285
2452
|
initialDataRef.current = null;
|
|
2286
2453
|
rawGraphDataRef.current = null;
|
|
@@ -2384,7 +2551,7 @@ function GraphViewer(props) {
|
|
|
2384
2551
|
cancelled = true;
|
|
2385
2552
|
};
|
|
2386
2553
|
}, [graphspec, edgeType]);
|
|
2387
|
-
|
|
2554
|
+
React8.useEffect(() => {
|
|
2388
2555
|
if (isFirstFoldEffect.current) {
|
|
2389
2556
|
isFirstFoldEffect.current = false;
|
|
2390
2557
|
prevFoldSizeRef.current = foldedControllers.size;
|
|
@@ -2464,7 +2631,7 @@ function GraphViewer(props) {
|
|
|
2464
2631
|
cancelled = true;
|
|
2465
2632
|
};
|
|
2466
2633
|
}, [foldedControllers, toggleFold]);
|
|
2467
|
-
|
|
2634
|
+
React8.useEffect(() => {
|
|
2468
2635
|
if (!layoutCacheRef.current || !initialDataRef.current) return;
|
|
2469
2636
|
const cachedNodes = cloneCachedNodes(layoutCacheRef.current.nodes);
|
|
2470
2637
|
const cachedEdges = layoutCacheRef.current.edges;
|
|
@@ -2482,7 +2649,7 @@ function GraphViewer(props) {
|
|
|
2482
2649
|
setNodes(applyStatusOverrides(toAppNodes(hydrateLabels(withControllers.nodes)), statusMap));
|
|
2483
2650
|
setEdges(toAppEdges(withControllers.edges));
|
|
2484
2651
|
}, [statusMap]);
|
|
2485
|
-
const onNodeClick =
|
|
2652
|
+
const onNodeClick = React8.useCallback(
|
|
2486
2653
|
(event, node) => {
|
|
2487
2654
|
var _a2;
|
|
2488
2655
|
const nodeData = node.data;
|
|
@@ -2524,7 +2691,7 @@ function GraphViewer(props) {
|
|
|
2524
2691
|
conceptOverride
|
|
2525
2692
|
]
|
|
2526
2693
|
);
|
|
2527
|
-
const onInit =
|
|
2694
|
+
const onInit = React8.useCallback(
|
|
2528
2695
|
(reactFlowInstance) => {
|
|
2529
2696
|
reactFlowRef.current = reactFlowInstance;
|
|
2530
2697
|
if (onReactFlowInit) {
|
|
@@ -2533,12 +2700,12 @@ function GraphViewer(props) {
|
|
|
2533
2700
|
},
|
|
2534
2701
|
[onReactFlowInit]
|
|
2535
2702
|
);
|
|
2536
|
-
const handlePaneClick =
|
|
2703
|
+
const handlePaneClick = React8.useCallback(() => {
|
|
2537
2704
|
setDetailSelection(null);
|
|
2538
2705
|
setConceptOverride(null);
|
|
2539
2706
|
onPaneClick == null ? void 0 : onPaneClick();
|
|
2540
2707
|
}, [onPaneClick]);
|
|
2541
|
-
const handleConceptClick =
|
|
2708
|
+
const handleConceptClick = React8.useCallback(
|
|
2542
2709
|
(conceptCode) => {
|
|
2543
2710
|
if (!graphspec) return;
|
|
2544
2711
|
const info = resolveConceptRef(graphspec, conceptCode);
|
|
@@ -2550,7 +2717,7 @@ function GraphViewer(props) {
|
|
|
2550
2717
|
const detailOpen = detailSelection !== null || conceptOverride !== null;
|
|
2551
2718
|
const rawAnalysis = (_c = rawGraphDataRef.current) == null ? void 0 : _c.analysis;
|
|
2552
2719
|
const allControllerIds = rawAnalysis == null ? void 0 : rawAnalysis.controllerNodeIds;
|
|
2553
|
-
const foldAllProps =
|
|
2720
|
+
const foldAllProps = React8.useMemo(() => {
|
|
2554
2721
|
if (!showControllers || !allControllerIds || allControllerIds.size === 0) {
|
|
2555
2722
|
return {
|
|
2556
2723
|
onFoldAll: void 0,
|
|
@@ -2566,93 +2733,103 @@ function GraphViewer(props) {
|
|
|
2566
2733
|
expandAllDisabled: foldedControllers.size === 0
|
|
2567
2734
|
};
|
|
2568
2735
|
}, [showControllers, allControllerIds, foldedControllers]);
|
|
2569
|
-
return /* @__PURE__ */ jsxs20(
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2736
|
+
return /* @__PURE__ */ jsxs20(
|
|
2737
|
+
"div",
|
|
2738
|
+
{
|
|
2739
|
+
ref: containerRef,
|
|
2740
|
+
className: `react-flow-container react-flow-container--theme-${theme}`,
|
|
2741
|
+
children: [
|
|
2742
|
+
/* @__PURE__ */ jsx20(
|
|
2743
|
+
ReactFlow,
|
|
2744
|
+
{
|
|
2745
|
+
nodes,
|
|
2746
|
+
edges,
|
|
2747
|
+
nodeTypes,
|
|
2748
|
+
onNodesChange,
|
|
2749
|
+
onEdgesChange,
|
|
2750
|
+
onNodeClick,
|
|
2751
|
+
onPaneClick: handlePaneClick,
|
|
2752
|
+
onInit,
|
|
2753
|
+
fitView: true,
|
|
2754
|
+
fitViewOptions: { padding: 0.1 },
|
|
2755
|
+
defaultEdgeOptions: { type: edgeType },
|
|
2756
|
+
panOnScroll: true,
|
|
2757
|
+
minZoom: 0.1,
|
|
2758
|
+
proOptions: { hideAttribution: true },
|
|
2759
|
+
panActivationKeyCode: null,
|
|
2760
|
+
children: /* @__PURE__ */ jsx20(
|
|
2761
|
+
Background,
|
|
2762
|
+
{
|
|
2763
|
+
variant: BackgroundVariant.Dots,
|
|
2764
|
+
gap: 20,
|
|
2765
|
+
size: 1,
|
|
2766
|
+
color: "var(--color-bg-dots)"
|
|
2767
|
+
}
|
|
2768
|
+
)
|
|
2769
|
+
}
|
|
2770
|
+
),
|
|
2771
|
+
/* @__PURE__ */ jsxs20(
|
|
2772
|
+
DetailPanel,
|
|
2590
2773
|
{
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2774
|
+
isOpen: detailOpen,
|
|
2775
|
+
onClose: handlePaneClick,
|
|
2776
|
+
width: panelWidth,
|
|
2777
|
+
isDragging: isPanelDragging,
|
|
2778
|
+
onResizeHandleMouseDown: onResizeMouseDown,
|
|
2779
|
+
children: [
|
|
2780
|
+
conceptOverride ? /* @__PURE__ */ jsx20(ConceptDetailPanel, { concept: conceptOverride }) : selectedSpecNode && graphspec ? /* @__PURE__ */ jsx20(
|
|
2781
|
+
PipeDetailPanel,
|
|
2782
|
+
{
|
|
2783
|
+
node: selectedSpecNode,
|
|
2784
|
+
spec: graphspec,
|
|
2785
|
+
onConceptClick: handleConceptClick
|
|
2786
|
+
}
|
|
2787
|
+
) : (detailSelection == null ? void 0 : detailSelection.stuffData) ? /* @__PURE__ */ jsx20(
|
|
2788
|
+
StuffNodeDetail,
|
|
2789
|
+
{
|
|
2790
|
+
nodeId: detailSelection.nodeId,
|
|
2791
|
+
stuffData: detailSelection.stuffData,
|
|
2792
|
+
graphspec,
|
|
2793
|
+
resolveStorageUrl,
|
|
2794
|
+
canEmbedPdf,
|
|
2795
|
+
onOpenExternally
|
|
2796
|
+
}
|
|
2797
|
+
) : null,
|
|
2798
|
+
renderDetailExtra && detailSelection && !conceptOverride && renderDetailExtra(detailSelection.nodeId, detailSelection.nodeData)
|
|
2799
|
+
]
|
|
2800
|
+
}
|
|
2801
|
+
),
|
|
2802
|
+
!hideToolbar && /* @__PURE__ */ jsx20(
|
|
2803
|
+
GraphToolbar,
|
|
2804
|
+
{
|
|
2805
|
+
direction,
|
|
2806
|
+
onDirectionChange: setDirection,
|
|
2807
|
+
showControllers,
|
|
2808
|
+
onShowControllersChange: setShowControllers,
|
|
2809
|
+
onZoomIn: () => {
|
|
2810
|
+
var _a2;
|
|
2811
|
+
return (_a2 = reactFlowRef.current) == null ? void 0 : _a2.zoomIn();
|
|
2812
|
+
},
|
|
2813
|
+
onZoomOut: () => {
|
|
2814
|
+
var _a2;
|
|
2815
|
+
return (_a2 = reactFlowRef.current) == null ? void 0 : _a2.zoomOut();
|
|
2816
|
+
},
|
|
2817
|
+
onFitView: () => {
|
|
2818
|
+
var _a2;
|
|
2819
|
+
return (_a2 = reactFlowRef.current) == null ? void 0 : _a2.fitView({ padding: 0.1 });
|
|
2820
|
+
},
|
|
2821
|
+
onFoldAll: foldAllProps.onFoldAll,
|
|
2822
|
+
onExpandAll: foldAllProps.onExpandAll,
|
|
2823
|
+
foldAllDisabled: foldAllProps.foldAllDisabled,
|
|
2824
|
+
expandAllDisabled: foldAllProps.expandAllDisabled,
|
|
2825
|
+
theme: showThemeToggle ? theme : void 0,
|
|
2826
|
+
onThemeChange: showThemeToggle ? setTheme : void 0,
|
|
2827
|
+
rightOffset: detailOpen ? panelWidth : 0
|
|
2595
2828
|
}
|
|
2596
2829
|
)
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
DetailPanel,
|
|
2601
|
-
{
|
|
2602
|
-
isOpen: detailOpen,
|
|
2603
|
-
onClose: handlePaneClick,
|
|
2604
|
-
width: panelWidth,
|
|
2605
|
-
isDragging: isPanelDragging,
|
|
2606
|
-
onResizeHandleMouseDown: onResizeMouseDown,
|
|
2607
|
-
children: [
|
|
2608
|
-
conceptOverride ? /* @__PURE__ */ jsx20(ConceptDetailPanel, { concept: conceptOverride }) : selectedSpecNode && graphspec ? /* @__PURE__ */ jsx20(
|
|
2609
|
-
PipeDetailPanel,
|
|
2610
|
-
{
|
|
2611
|
-
node: selectedSpecNode,
|
|
2612
|
-
spec: graphspec,
|
|
2613
|
-
onConceptClick: handleConceptClick
|
|
2614
|
-
}
|
|
2615
|
-
) : (detailSelection == null ? void 0 : detailSelection.stuffData) ? /* @__PURE__ */ jsx20(
|
|
2616
|
-
StuffNodeDetail,
|
|
2617
|
-
{
|
|
2618
|
-
stuffData: detailSelection.stuffData,
|
|
2619
|
-
graphspec,
|
|
2620
|
-
resolveStorageUrl,
|
|
2621
|
-
canEmbedPdf,
|
|
2622
|
-
onOpenExternally
|
|
2623
|
-
}
|
|
2624
|
-
) : null,
|
|
2625
|
-
renderDetailExtra && detailSelection && !conceptOverride && renderDetailExtra(detailSelection.nodeId, detailSelection.nodeData)
|
|
2626
|
-
]
|
|
2627
|
-
}
|
|
2628
|
-
),
|
|
2629
|
-
!hideToolbar && /* @__PURE__ */ jsx20(
|
|
2630
|
-
GraphToolbar,
|
|
2631
|
-
{
|
|
2632
|
-
direction,
|
|
2633
|
-
onDirectionChange: setDirection,
|
|
2634
|
-
showControllers,
|
|
2635
|
-
onShowControllersChange: setShowControllers,
|
|
2636
|
-
onZoomIn: () => {
|
|
2637
|
-
var _a2;
|
|
2638
|
-
return (_a2 = reactFlowRef.current) == null ? void 0 : _a2.zoomIn();
|
|
2639
|
-
},
|
|
2640
|
-
onZoomOut: () => {
|
|
2641
|
-
var _a2;
|
|
2642
|
-
return (_a2 = reactFlowRef.current) == null ? void 0 : _a2.zoomOut();
|
|
2643
|
-
},
|
|
2644
|
-
onFitView: () => {
|
|
2645
|
-
var _a2;
|
|
2646
|
-
return (_a2 = reactFlowRef.current) == null ? void 0 : _a2.fitView({ padding: 0.1 });
|
|
2647
|
-
},
|
|
2648
|
-
onFoldAll: foldAllProps.onFoldAll,
|
|
2649
|
-
onExpandAll: foldAllProps.onExpandAll,
|
|
2650
|
-
foldAllDisabled: foldAllProps.foldAllDisabled,
|
|
2651
|
-
expandAllDisabled: foldAllProps.expandAllDisabled,
|
|
2652
|
-
rightOffset: detailOpen ? panelWidth : 0
|
|
2653
|
-
}
|
|
2654
|
-
)
|
|
2655
|
-
] });
|
|
2830
|
+
]
|
|
2831
|
+
}
|
|
2832
|
+
);
|
|
2656
2833
|
}
|
|
2657
2834
|
export {
|
|
2658
2835
|
ConceptDetailPanel,
|