@dilipod/ui 0.4.34 → 0.4.36
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/components/file-preview.d.ts +1 -0
- package/dist/components/file-preview.d.ts.map +1 -1
- package/dist/components/flowchart-diagram.d.ts.map +1 -1
- package/dist/components/sidebar.d.ts +2 -1
- package/dist/components/sidebar.d.ts.map +1 -1
- package/dist/index.js +369 -164
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +370 -165
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/file-preview.tsx +29 -15
- package/src/components/flowchart-diagram.tsx +446 -216
- package/src/components/sidebar.tsx +24 -10
package/dist/index.mjs
CHANGED
|
@@ -10,7 +10,7 @@ import { clsx } from 'clsx';
|
|
|
10
10
|
import { twMerge } from 'tailwind-merge';
|
|
11
11
|
import * as SheetPrimitive from '@radix-ui/react-dialog';
|
|
12
12
|
import * as react_star from '@phosphor-icons/react';
|
|
13
|
-
import { X, CaretDown, Circle, CaretLeft, DotsThree, CaretRight, Check, House, Info, WarningCircle, Play, Download, Folder, ArrowSquareOut,
|
|
13
|
+
import { X, CaretDown, Circle, CaretLeft, DotsThree, CaretRight, Check, House, Info, WarningCircle, CircleNotch, Play, Download, Folder, ArrowSquareOut, File, FileVideo, Lightning, CheckCircle, CaretUp, Plus, PaperPlaneTilt, Eye, TreeStructure, Code, PencilSimple, WebhooksLogo, Copy, CloudArrowUp, CloudArrowDown, ArrowsClockwise, DownloadSimple, ClockCounterClockwise, ArrowsLeftRight, Minus, Pencil, Robot, MagnifyingGlass, FilmStrip, FileText, ImageSquare, TextT, Target, Crosshair, ListNumbers, Wrench, Clock, TrendUp, CurrencyEur, Sparkle, Plugs, ShieldCheck, FileImage, FilePdf, FileDoc, Question, Warning, Trash, Globe, GitBranch, Package, Timer, VideoCamera, Lightbulb } from '@phosphor-icons/react';
|
|
14
14
|
import 'react-dom';
|
|
15
15
|
import * as SwitchPrimitive from '@radix-ui/react-switch';
|
|
16
16
|
import * as SliderPrimitive from '@radix-ui/react-slider';
|
|
@@ -2358,7 +2358,18 @@ var Sidebar = React51.forwardRef(
|
|
|
2358
2358
|
]
|
|
2359
2359
|
}
|
|
2360
2360
|
),
|
|
2361
|
-
helpLink && /* @__PURE__ */ jsxs(
|
|
2361
|
+
helpLink && (helpLink.onClick ? /* @__PURE__ */ jsxs(
|
|
2362
|
+
"button",
|
|
2363
|
+
{
|
|
2364
|
+
type: "button",
|
|
2365
|
+
onClick: helpLink.onClick,
|
|
2366
|
+
className: "flex w-full items-center gap-3 rounded-sm px-3 py-2 text-sm text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors",
|
|
2367
|
+
children: [
|
|
2368
|
+
helpLink.icon && /* @__PURE__ */ jsx(helpLink.icon, { className: "h-4 w-4" }),
|
|
2369
|
+
helpLink.label
|
|
2370
|
+
]
|
|
2371
|
+
}
|
|
2372
|
+
) : /* @__PURE__ */ jsxs(
|
|
2362
2373
|
"a",
|
|
2363
2374
|
{
|
|
2364
2375
|
href: helpLink.href,
|
|
@@ -2368,7 +2379,7 @@ var Sidebar = React51.forwardRef(
|
|
|
2368
2379
|
helpLink.label
|
|
2369
2380
|
]
|
|
2370
2381
|
}
|
|
2371
|
-
)
|
|
2382
|
+
))
|
|
2372
2383
|
] })
|
|
2373
2384
|
]
|
|
2374
2385
|
}
|
|
@@ -3957,7 +3968,8 @@ function FilePreview({
|
|
|
3957
3968
|
const FileIcon = getFileIcon(file.type);
|
|
3958
3969
|
const typeLabel = getTypeLabel(file.type);
|
|
3959
3970
|
const sizeLabel = formatSize(file.size);
|
|
3960
|
-
const
|
|
3971
|
+
const isProcessing = file.processing === true;
|
|
3972
|
+
const isPreviewable = !isProcessing && canPreview(file);
|
|
3961
3973
|
const previewType = getPreviewType(file);
|
|
3962
3974
|
return /* @__PURE__ */ jsxs(
|
|
3963
3975
|
"div",
|
|
@@ -3967,20 +3979,20 @@ function FilePreview({
|
|
|
3967
3979
|
children: [
|
|
3968
3980
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
|
|
3969
3981
|
/* @__PURE__ */ jsxs("div", { className: "relative shrink-0", children: [
|
|
3970
|
-
/* @__PURE__ */ jsx("div", { className: "w-10 h-10 rounded-sm bg-white border border-gray-200 flex items-center justify-center", children: /* @__PURE__ */ jsx(FileIcon, { className: "w-5 h-5 text-[var(--cyan)]", weight: "fill" }) }),
|
|
3971
|
-
previewType === "video" && /* @__PURE__ */ jsx(Play, { className: "absolute -bottom-0.5 -right-0.5 w-3.5 h-3.5 text-[var(--cyan)] bg-white rounded-full", weight: "fill" })
|
|
3982
|
+
/* @__PURE__ */ jsx("div", { className: "w-10 h-10 rounded-sm bg-white border border-gray-200 flex items-center justify-center", children: isProcessing ? /* @__PURE__ */ jsx(CircleNotch, { className: "w-5 h-5 text-[var(--cyan)] animate-spin" }) : /* @__PURE__ */ jsx(FileIcon, { className: "w-5 h-5 text-[var(--cyan)]", weight: "fill" }) }),
|
|
3983
|
+
!isProcessing && previewType === "video" && /* @__PURE__ */ jsx(Play, { className: "absolute -bottom-0.5 -right-0.5 w-3.5 h-3.5 text-[var(--cyan)] bg-white rounded-full", weight: "fill" })
|
|
3972
3984
|
] }),
|
|
3973
3985
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
3974
3986
|
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-[var(--black)] truncate", children: file.filename }),
|
|
3975
|
-
/* @__PURE__ */
|
|
3987
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: isProcessing ? /* @__PURE__ */ jsx("span", { className: "text-amber-600", children: "Processing video \u2014 this takes about a minute" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3976
3988
|
typeLabel,
|
|
3977
3989
|
" \xB7 ",
|
|
3978
3990
|
sizeLabel,
|
|
3979
3991
|
isPreviewable && /* @__PURE__ */ jsx("span", { className: "text-[var(--cyan)] ml-1", children: "\xB7 Click to preview" })
|
|
3980
|
-
] })
|
|
3992
|
+
] }) })
|
|
3981
3993
|
] })
|
|
3982
3994
|
] }),
|
|
3983
|
-
/* @__PURE__ */ jsx(
|
|
3995
|
+
!isProcessing && /* @__PURE__ */ jsx(
|
|
3984
3996
|
"button",
|
|
3985
3997
|
{
|
|
3986
3998
|
onClick: (e) => handleDownload(e, file),
|
|
@@ -6253,190 +6265,383 @@ function WorkflowViewer({
|
|
|
6253
6265
|
] })
|
|
6254
6266
|
] });
|
|
6255
6267
|
}
|
|
6256
|
-
|
|
6257
|
-
|
|
6258
|
-
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
6267
|
-
|
|
6268
|
+
var NODE_WIDTH = 180;
|
|
6269
|
+
var NODE_HEIGHT = 44;
|
|
6270
|
+
var DIAMOND_SIZE = 72;
|
|
6271
|
+
var X_GAP = 50;
|
|
6272
|
+
var Y_GAP = 64;
|
|
6273
|
+
var PADDING = 40;
|
|
6274
|
+
var FONT_SIZE = 11;
|
|
6275
|
+
var CHAR_WIDTH = 6.2;
|
|
6276
|
+
var LINE_HEIGHT = 14;
|
|
6277
|
+
function stripQuotes(s) {
|
|
6278
|
+
const t = s.trim();
|
|
6279
|
+
if (t.startsWith('"') && t.endsWith('"') || t.startsWith("'") && t.endsWith("'")) {
|
|
6280
|
+
return t.slice(1, -1);
|
|
6281
|
+
}
|
|
6282
|
+
return t;
|
|
6283
|
+
}
|
|
6284
|
+
function parseNodeRef(raw) {
|
|
6285
|
+
const s = raw.trim();
|
|
6286
|
+
const decision = s.match(/^([A-Za-z0-9_]+)\{(.+)\}$/);
|
|
6287
|
+
if (decision) return { id: decision[1], label: stripQuotes(decision[2]), type: "decision" };
|
|
6288
|
+
const stadium = s.match(/^([A-Za-z0-9_]+)\(\[(.+)\]\)$/);
|
|
6289
|
+
if (stadium) return { id: stadium[1], label: stripQuotes(stadium[2]), type: "terminal" };
|
|
6290
|
+
const circle = s.match(/^([A-Za-z0-9_]+)\(\((.+)\)\)$/);
|
|
6291
|
+
if (circle) return { id: circle[1], label: stripQuotes(circle[2]), type: "terminal" };
|
|
6292
|
+
const rounded = s.match(/^([A-Za-z0-9_]+)\(([^[(].+?)\)$/);
|
|
6293
|
+
if (rounded) return { id: rounded[1], label: stripQuotes(rounded[2]), type: "action" };
|
|
6294
|
+
const rect = s.match(/^([A-Za-z0-9_]+)\[([^(].+?)\]$/);
|
|
6295
|
+
if (rect) {
|
|
6296
|
+
const label = stripQuotes(rect[2]);
|
|
6297
|
+
const isTerminal = /^(start|end|begin|finish|done|stop)$/i.test(label);
|
|
6298
|
+
return { id: rect[1], label, type: isTerminal ? "terminal" : "action" };
|
|
6299
|
+
}
|
|
6300
|
+
const bareId = s.match(/^([A-Za-z0-9_]+)$/);
|
|
6301
|
+
if (bareId) return { id: bareId[1] };
|
|
6302
|
+
return { id: s };
|
|
6303
|
+
}
|
|
6304
|
+
function registerNode(map, ref) {
|
|
6305
|
+
if (!ref.id) return;
|
|
6306
|
+
const existing = map.get(ref.id);
|
|
6307
|
+
if (existing) {
|
|
6308
|
+
if (ref.label && existing.label === existing.id) {
|
|
6309
|
+
existing.label = ref.label;
|
|
6268
6310
|
}
|
|
6269
|
-
|
|
6311
|
+
if (ref.type && ref.type !== "action" && existing.type === "action") {
|
|
6312
|
+
existing.type = ref.type;
|
|
6313
|
+
}
|
|
6314
|
+
return;
|
|
6270
6315
|
}
|
|
6316
|
+
map.set(ref.id, {
|
|
6317
|
+
id: ref.id,
|
|
6318
|
+
label: ref.label || ref.id,
|
|
6319
|
+
type: ref.type || "action"
|
|
6320
|
+
});
|
|
6321
|
+
}
|
|
6322
|
+
function parseMermaidFlowchart(mermaid) {
|
|
6323
|
+
const nodeMap = /* @__PURE__ */ new Map();
|
|
6324
|
+
const edges = [];
|
|
6325
|
+
const lines = mermaid.split(/\\n|\n/).map((l) => l.trim()).filter((l) => l && !l.startsWith("%%"));
|
|
6271
6326
|
for (const line of lines) {
|
|
6272
|
-
|
|
6273
|
-
|
|
6274
|
-
|
|
6275
|
-
|
|
6276
|
-
|
|
6277
|
-
|
|
6278
|
-
|
|
6279
|
-
|
|
6280
|
-
|
|
6327
|
+
if (/^(flowchart|graph|subgraph|end|style|classDef|class|click|linkStyle)\b/i.test(line)) continue;
|
|
6328
|
+
const edgeMatch = line.match(
|
|
6329
|
+
/^(.+?)\s*(?:-->|==>|-\.->|---)\s*(?:\|([^|]*)\|)?\s*(.+)$/
|
|
6330
|
+
);
|
|
6331
|
+
if (edgeMatch) {
|
|
6332
|
+
const leftNode = parseNodeRef(edgeMatch[1].trim());
|
|
6333
|
+
const edgeLabel = edgeMatch[2]?.trim() || void 0;
|
|
6334
|
+
const rightNode = parseNodeRef(edgeMatch[3].trim());
|
|
6335
|
+
registerNode(nodeMap, leftNode);
|
|
6336
|
+
registerNode(nodeMap, rightNode);
|
|
6337
|
+
edges.push({ from: leftNode.id, to: rightNode.id, label: edgeLabel });
|
|
6338
|
+
continue;
|
|
6281
6339
|
}
|
|
6282
|
-
|
|
6283
|
-
|
|
6340
|
+
const nodeDef = parseNodeRef(line);
|
|
6341
|
+
if (nodeDef.label) {
|
|
6342
|
+
registerNode(nodeMap, nodeDef);
|
|
6284
6343
|
}
|
|
6285
|
-
|
|
6286
|
-
|
|
6344
|
+
}
|
|
6345
|
+
return { nodes: Array.from(nodeMap.values()), edges };
|
|
6346
|
+
}
|
|
6347
|
+
function computeLayout(nodes, edges) {
|
|
6348
|
+
if (nodes.length === 0) return { layoutNodes: [], svgWidth: 0, svgHeight: 0 };
|
|
6349
|
+
const forward = /* @__PURE__ */ new Map();
|
|
6350
|
+
const backward = /* @__PURE__ */ new Map();
|
|
6351
|
+
for (const e of edges) {
|
|
6352
|
+
if (!forward.has(e.from)) forward.set(e.from, []);
|
|
6353
|
+
forward.get(e.from).push(e.to);
|
|
6354
|
+
if (!backward.has(e.to)) backward.set(e.to, []);
|
|
6355
|
+
backward.get(e.to).push(e.from);
|
|
6356
|
+
}
|
|
6357
|
+
const roots = nodes.filter((n) => !backward.has(n.id) || backward.get(n.id).length === 0);
|
|
6358
|
+
if (roots.length === 0) roots.push(nodes[0]);
|
|
6359
|
+
const layers = /* @__PURE__ */ new Map();
|
|
6360
|
+
const queue = [];
|
|
6361
|
+
for (const r of roots) {
|
|
6362
|
+
layers.set(r.id, 0);
|
|
6363
|
+
queue.push(r.id);
|
|
6364
|
+
}
|
|
6365
|
+
const visited = /* @__PURE__ */ new Set();
|
|
6366
|
+
while (queue.length > 0) {
|
|
6367
|
+
const id = queue.shift();
|
|
6368
|
+
if (visited.has(id)) continue;
|
|
6369
|
+
visited.add(id);
|
|
6370
|
+
const myLayer = layers.get(id) || 0;
|
|
6371
|
+
for (const child of forward.get(id) || []) {
|
|
6372
|
+
const childLayer = layers.get(child);
|
|
6373
|
+
if (childLayer === void 0 || myLayer + 1 > childLayer) {
|
|
6374
|
+
layers.set(child, myLayer + 1);
|
|
6375
|
+
}
|
|
6376
|
+
if (!visited.has(child)) queue.push(child);
|
|
6287
6377
|
}
|
|
6288
|
-
|
|
6289
|
-
|
|
6378
|
+
}
|
|
6379
|
+
const maxLayer = Math.max(0, ...Array.from(layers.values()));
|
|
6380
|
+
for (const n of nodes) {
|
|
6381
|
+
if (!layers.has(n.id)) layers.set(n.id, maxLayer + 1);
|
|
6382
|
+
}
|
|
6383
|
+
const nodesByLayer = /* @__PURE__ */ new Map();
|
|
6384
|
+
for (const n of nodes) {
|
|
6385
|
+
const layer = layers.get(n.id);
|
|
6386
|
+
if (!nodesByLayer.has(layer)) nodesByLayer.set(layer, []);
|
|
6387
|
+
nodesByLayer.get(layer).push(n);
|
|
6388
|
+
}
|
|
6389
|
+
const sortedLayers = Array.from(nodesByLayer.keys()).sort((a, b) => a - b);
|
|
6390
|
+
const posInLayer = /* @__PURE__ */ new Map();
|
|
6391
|
+
for (let li = 0; li < sortedLayers.length; li++) {
|
|
6392
|
+
const layer = sortedLayers[li];
|
|
6393
|
+
const nodesInLayer = nodesByLayer.get(layer);
|
|
6394
|
+
if (li > 0) {
|
|
6395
|
+
nodesInLayer.sort((a, b) => {
|
|
6396
|
+
const parentsA = backward.get(a.id) || [];
|
|
6397
|
+
const parentsB = backward.get(b.id) || [];
|
|
6398
|
+
const avgA = parentsA.length > 0 ? parentsA.reduce((s, p) => s + (posInLayer.get(p) ?? 0), 0) / parentsA.length : 0;
|
|
6399
|
+
const avgB = parentsB.length > 0 ? parentsB.reduce((s, p) => s + (posInLayer.get(p) ?? 0), 0) / parentsB.length : 0;
|
|
6400
|
+
return avgA - avgB;
|
|
6401
|
+
});
|
|
6290
6402
|
}
|
|
6291
|
-
|
|
6403
|
+
nodesInLayer.forEach((n, i) => posInLayer.set(n.id, i));
|
|
6404
|
+
}
|
|
6405
|
+
const layoutNodes = [];
|
|
6406
|
+
for (const layer of sortedLayers) {
|
|
6407
|
+
const nodesInLayer = nodesByLayer.get(layer);
|
|
6408
|
+
const widths = nodesInLayer.map((n) => nodeWidth(n));
|
|
6409
|
+
const heights = nodesInLayer.map((n) => nodeHeight(n));
|
|
6410
|
+
const totalWidth = widths.reduce((s, w) => s + w, 0) + (nodesInLayer.length - 1) * X_GAP;
|
|
6411
|
+
let startX = -totalWidth / 2;
|
|
6412
|
+
nodesInLayer.forEach((n, i) => {
|
|
6413
|
+
layoutNodes.push({
|
|
6414
|
+
id: n.id,
|
|
6415
|
+
x: startX + widths[i] / 2,
|
|
6416
|
+
y: layer * (NODE_HEIGHT + Y_GAP),
|
|
6417
|
+
width: widths[i],
|
|
6418
|
+
height: heights[i],
|
|
6419
|
+
layer,
|
|
6420
|
+
node: n
|
|
6421
|
+
});
|
|
6422
|
+
startX += widths[i] + X_GAP;
|
|
6423
|
+
});
|
|
6292
6424
|
}
|
|
6293
|
-
|
|
6425
|
+
const minX = Math.min(...layoutNodes.map((n) => n.x - n.width / 2));
|
|
6426
|
+
const minY = Math.min(...layoutNodes.map((n) => n.y - n.height / 2));
|
|
6427
|
+
const offsetX = PADDING - minX;
|
|
6428
|
+
const offsetY = PADDING - minY;
|
|
6429
|
+
for (const n of layoutNodes) {
|
|
6430
|
+
n.x += offsetX;
|
|
6431
|
+
n.y += offsetY;
|
|
6432
|
+
}
|
|
6433
|
+
const svgWidth = Math.max(...layoutNodes.map((n) => n.x + n.width / 2)) + PADDING;
|
|
6434
|
+
const svgHeight = Math.max(...layoutNodes.map((n) => n.y + n.height / 2)) + PADDING;
|
|
6435
|
+
return { layoutNodes, svgWidth, svgHeight };
|
|
6436
|
+
}
|
|
6437
|
+
function nodeWidth(n) {
|
|
6438
|
+
if (n.type === "decision") return Math.max(DIAMOND_SIZE * 1.4, 100);
|
|
6439
|
+
const textWidth = n.label.length * CHAR_WIDTH + 32;
|
|
6440
|
+
return Math.max(100, Math.min(NODE_WIDTH, textWidth));
|
|
6294
6441
|
}
|
|
6295
|
-
function
|
|
6296
|
-
|
|
6297
|
-
|
|
6298
|
-
|
|
6299
|
-
|
|
6300
|
-
|
|
6301
|
-
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
|
|
6305
|
-
|
|
6306
|
-
|
|
6307
|
-
|
|
6442
|
+
function nodeHeight(n) {
|
|
6443
|
+
if (n.type === "decision") return DIAMOND_SIZE;
|
|
6444
|
+
const w = nodeWidth(n);
|
|
6445
|
+
const lines = wrapText(n.label, w - 24);
|
|
6446
|
+
return Math.max(NODE_HEIGHT, lines.length * LINE_HEIGHT + 16);
|
|
6447
|
+
}
|
|
6448
|
+
function wrapText(text, maxPixelWidth) {
|
|
6449
|
+
const charsPerLine = Math.max(8, Math.floor(maxPixelWidth / CHAR_WIDTH));
|
|
6450
|
+
if (text.length <= charsPerLine) return [text];
|
|
6451
|
+
const words = text.split(" ");
|
|
6452
|
+
const lines = [];
|
|
6453
|
+
let cur = "";
|
|
6454
|
+
for (const word of words) {
|
|
6455
|
+
const test = cur ? `${cur} ${word}` : word;
|
|
6456
|
+
if (test.length > charsPerLine && cur) {
|
|
6457
|
+
lines.push(cur);
|
|
6458
|
+
cur = word;
|
|
6459
|
+
} else {
|
|
6460
|
+
cur = test;
|
|
6308
6461
|
}
|
|
6309
6462
|
}
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
|
|
6463
|
+
if (cur) lines.push(cur);
|
|
6464
|
+
if (lines.length > 3) {
|
|
6465
|
+
lines.length = 3;
|
|
6466
|
+
lines[2] = lines[2].slice(0, -1) + "\u2026";
|
|
6467
|
+
}
|
|
6468
|
+
return lines;
|
|
6469
|
+
}
|
|
6470
|
+
function computeEdgePath(from, to) {
|
|
6471
|
+
let startX = from.x;
|
|
6472
|
+
let startY = from.y + from.height / 2;
|
|
6473
|
+
if (from.node.type === "decision") {
|
|
6474
|
+
const dx = to.x - from.x;
|
|
6475
|
+
const halfDiamond = DIAMOND_SIZE / 2;
|
|
6476
|
+
if (Math.abs(dx) > halfDiamond) {
|
|
6477
|
+
startX = from.x + (dx > 0 ? halfDiamond : -halfDiamond);
|
|
6478
|
+
startY = from.y;
|
|
6319
6479
|
}
|
|
6320
|
-
const outs = outgoing.get(id) || [];
|
|
6321
|
-
for (const e of outs) q.push(e.to);
|
|
6322
6480
|
}
|
|
6323
|
-
|
|
6481
|
+
const endX = to.x;
|
|
6482
|
+
const endY = to.y - to.height / 2;
|
|
6483
|
+
const midY = (startY + endY) / 2;
|
|
6484
|
+
return `M ${startX} ${startY} C ${startX} ${midY}, ${endX} ${midY}, ${endX} ${endY}`;
|
|
6324
6485
|
}
|
|
6325
|
-
function
|
|
6326
|
-
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
|
|
6330
|
-
|
|
6331
|
-
|
|
6332
|
-
|
|
6333
|
-
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
if (visited.has(nextId)) break;
|
|
6339
|
-
items.push({ type: "arrow", label: outs[0].label });
|
|
6340
|
-
currentId = nextId;
|
|
6341
|
-
} else {
|
|
6342
|
-
currentId = null;
|
|
6343
|
-
}
|
|
6344
|
-
} else {
|
|
6345
|
-
visited.add(currentId);
|
|
6346
|
-
items.push({ type: "node", nodeId: currentId });
|
|
6347
|
-
const branchStarts = outs.map((e) => e.to);
|
|
6348
|
-
const mergeId = findMergePoint(branchStarts, outgoing);
|
|
6349
|
-
const branches = [];
|
|
6350
|
-
for (const edge of outs) {
|
|
6351
|
-
if (visited.has(edge.to) && edge.to !== mergeId) {
|
|
6352
|
-
branches.push({ label: edge.label, items: [] });
|
|
6353
|
-
continue;
|
|
6354
|
-
}
|
|
6355
|
-
const branchItems = buildLayout(edge.to, outgoing, incoming, nodeMap, visited);
|
|
6356
|
-
branches.push({ label: edge.label, items: branchItems });
|
|
6357
|
-
}
|
|
6358
|
-
items.push({ type: "branch", decision: currentId, branches, mergeId });
|
|
6359
|
-
if (mergeId && !visited.has(mergeId)) {
|
|
6360
|
-
items.push({ type: "arrow" });
|
|
6361
|
-
currentId = mergeId;
|
|
6362
|
-
} else {
|
|
6363
|
-
currentId = null;
|
|
6486
|
+
function SvgDefs() {
|
|
6487
|
+
return /* @__PURE__ */ jsxs("defs", { children: [
|
|
6488
|
+
/* @__PURE__ */ jsx(
|
|
6489
|
+
"marker",
|
|
6490
|
+
{
|
|
6491
|
+
id: "fc-arrowhead",
|
|
6492
|
+
viewBox: "0 0 10 7",
|
|
6493
|
+
refX: "10",
|
|
6494
|
+
refY: "3.5",
|
|
6495
|
+
markerWidth: "8",
|
|
6496
|
+
markerHeight: "6",
|
|
6497
|
+
orient: "auto-start-reverse",
|
|
6498
|
+
children: /* @__PURE__ */ jsx("polygon", { points: "0 0, 10 3.5, 0 7", fill: "#D1D5DB" })
|
|
6364
6499
|
}
|
|
6500
|
+
),
|
|
6501
|
+
/* @__PURE__ */ jsx("filter", { id: "fc-shadow", x: "-4%", y: "-4%", width: "108%", height: "116%", children: /* @__PURE__ */ jsx("feDropShadow", { dx: "0", dy: "1", stdDeviation: "1.5", floodOpacity: "0.07" }) })
|
|
6502
|
+
] });
|
|
6503
|
+
}
|
|
6504
|
+
function TextBlock({ lines, x, y, fill, fontSize }) {
|
|
6505
|
+
const startY = y - (lines.length - 1) * LINE_HEIGHT / 2;
|
|
6506
|
+
return /* @__PURE__ */ jsx(
|
|
6507
|
+
"text",
|
|
6508
|
+
{
|
|
6509
|
+
x,
|
|
6510
|
+
textAnchor: "middle",
|
|
6511
|
+
fill,
|
|
6512
|
+
style: { fontSize: `${fontSize}px`, fontFamily: "var(--font-outfit, system-ui, sans-serif)", fontWeight: 500 },
|
|
6513
|
+
children: lines.map((line, i) => /* @__PURE__ */ jsx("tspan", { x, y: startY + i * LINE_HEIGHT, children: line }, i))
|
|
6365
6514
|
}
|
|
6366
|
-
|
|
6367
|
-
return items;
|
|
6515
|
+
);
|
|
6368
6516
|
}
|
|
6369
|
-
function
|
|
6370
|
-
|
|
6371
|
-
|
|
6372
|
-
/* @__PURE__ */ jsx(
|
|
6373
|
-
|
|
6517
|
+
function ActionNodeSvg({ n }) {
|
|
6518
|
+
const lines = wrapText(n.node.label, n.width - 24);
|
|
6519
|
+
return /* @__PURE__ */ jsxs("g", { children: [
|
|
6520
|
+
/* @__PURE__ */ jsx(
|
|
6521
|
+
"rect",
|
|
6522
|
+
{
|
|
6523
|
+
x: n.x - n.width / 2,
|
|
6524
|
+
y: n.y - n.height / 2,
|
|
6525
|
+
width: n.width,
|
|
6526
|
+
height: n.height,
|
|
6527
|
+
rx: 3,
|
|
6528
|
+
fill: "white",
|
|
6529
|
+
stroke: "#E5E7EB",
|
|
6530
|
+
strokeWidth: 1,
|
|
6531
|
+
filter: "url(#fc-shadow)"
|
|
6532
|
+
}
|
|
6533
|
+
),
|
|
6534
|
+
/* @__PURE__ */ jsx(TextBlock, { lines, x: n.x, y: n.y, fill: "#0A0A0A", fontSize: FONT_SIZE })
|
|
6374
6535
|
] });
|
|
6375
6536
|
}
|
|
6376
|
-
function
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6537
|
+
function DecisionNodeSvg({ n }) {
|
|
6538
|
+
const half = DIAMOND_SIZE / 2;
|
|
6539
|
+
const points = `${n.x},${n.y - half} ${n.x + half},${n.y} ${n.x},${n.y + half} ${n.x - half},${n.y}`;
|
|
6540
|
+
const lines = wrapText(n.node.label, DIAMOND_SIZE - 16);
|
|
6541
|
+
return /* @__PURE__ */ jsxs("g", { children: [
|
|
6542
|
+
/* @__PURE__ */ jsx(
|
|
6543
|
+
"polygon",
|
|
6380
6544
|
{
|
|
6381
|
-
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
node.label
|
|
6386
|
-
]
|
|
6545
|
+
points,
|
|
6546
|
+
fill: "#FFFBEB",
|
|
6547
|
+
stroke: "#FCD34D",
|
|
6548
|
+
strokeWidth: 2
|
|
6387
6549
|
}
|
|
6388
|
-
)
|
|
6389
|
-
|
|
6390
|
-
|
|
6391
|
-
return /* @__PURE__ */ jsx("div", { className: "bg-gray-100 border border-gray-200 rounded-full px-5 py-1.5 text-xs font-medium text-gray-500 text-center my-1", children: node.label });
|
|
6392
|
-
}
|
|
6393
|
-
return /* @__PURE__ */ jsx("div", { className: "bg-white border border-gray-200 rounded-sm px-4 py-2 text-xs font-medium text-[var(--black)] text-center shadow-sm my-1 max-w-[220px]", children: node.label });
|
|
6550
|
+
),
|
|
6551
|
+
/* @__PURE__ */ jsx(TextBlock, { lines, x: n.x, y: n.y, fill: "#92400E", fontSize: 10 })
|
|
6552
|
+
] });
|
|
6394
6553
|
}
|
|
6395
|
-
function
|
|
6396
|
-
return /* @__PURE__ */
|
|
6397
|
-
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
|
|
6419
|
-
|
|
6554
|
+
function TerminalNodeSvg({ n }) {
|
|
6555
|
+
return /* @__PURE__ */ jsxs("g", { children: [
|
|
6556
|
+
/* @__PURE__ */ jsx(
|
|
6557
|
+
"rect",
|
|
6558
|
+
{
|
|
6559
|
+
x: n.x - n.width / 2,
|
|
6560
|
+
y: n.y - n.height / 2,
|
|
6561
|
+
width: n.width,
|
|
6562
|
+
height: n.height,
|
|
6563
|
+
rx: n.height / 2,
|
|
6564
|
+
fill: "#F3F4F6",
|
|
6565
|
+
stroke: "#E5E7EB",
|
|
6566
|
+
strokeWidth: 1
|
|
6567
|
+
}
|
|
6568
|
+
),
|
|
6569
|
+
/* @__PURE__ */ jsx(TextBlock, { lines: [n.node.label], x: n.x, y: n.y, fill: "#6B7280", fontSize: FONT_SIZE })
|
|
6570
|
+
] });
|
|
6571
|
+
}
|
|
6572
|
+
function EdgeSvg({ from, to, label }) {
|
|
6573
|
+
const path = computeEdgePath(from, to);
|
|
6574
|
+
const midX = (from.x + to.x) / 2;
|
|
6575
|
+
const midY = (from.y + from.height / 2 + to.y - to.height / 2) / 2;
|
|
6576
|
+
return /* @__PURE__ */ jsxs("g", { children: [
|
|
6577
|
+
/* @__PURE__ */ jsx(
|
|
6578
|
+
"path",
|
|
6579
|
+
{
|
|
6580
|
+
d: path,
|
|
6581
|
+
fill: "none",
|
|
6582
|
+
stroke: "#D1D5DB",
|
|
6583
|
+
strokeWidth: 1.5,
|
|
6584
|
+
markerEnd: "url(#fc-arrowhead)"
|
|
6585
|
+
}
|
|
6586
|
+
),
|
|
6587
|
+
label && /* @__PURE__ */ jsxs("g", { children: [
|
|
6588
|
+
/* @__PURE__ */ jsx(
|
|
6589
|
+
"rect",
|
|
6590
|
+
{
|
|
6591
|
+
x: midX - label.length * CHAR_WIDTH / 2 - 6,
|
|
6592
|
+
y: midY - 9,
|
|
6593
|
+
width: label.length * CHAR_WIDTH + 12,
|
|
6594
|
+
height: 18,
|
|
6595
|
+
rx: 9,
|
|
6596
|
+
fill: "#F5F3FF"
|
|
6597
|
+
}
|
|
6598
|
+
),
|
|
6599
|
+
/* @__PURE__ */ jsx(
|
|
6600
|
+
"text",
|
|
6601
|
+
{
|
|
6602
|
+
x: midX,
|
|
6603
|
+
y: midY + 1,
|
|
6604
|
+
textAnchor: "middle",
|
|
6605
|
+
dominantBaseline: "central",
|
|
6606
|
+
fill: "#7C3AED",
|
|
6607
|
+
style: { fontSize: "10px", fontFamily: "var(--font-outfit, system-ui, sans-serif)", fontWeight: 500 },
|
|
6608
|
+
children: label
|
|
6609
|
+
}
|
|
6610
|
+
)
|
|
6611
|
+
] })
|
|
6612
|
+
] });
|
|
6420
6613
|
}
|
|
6421
6614
|
function FlowchartDiagram({ mermaid, className }) {
|
|
6422
6615
|
const { nodes, edges } = parseMermaidFlowchart(mermaid);
|
|
6423
6616
|
if (nodes.length === 0) {
|
|
6424
6617
|
return /* @__PURE__ */ jsx("pre", { className: "text-xs bg-white border border-gray-100 rounded-sm p-3 overflow-x-auto whitespace-pre-wrap", children: mermaid });
|
|
6425
6618
|
}
|
|
6426
|
-
const
|
|
6427
|
-
const
|
|
6428
|
-
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6619
|
+
const { layoutNodes, svgWidth, svgHeight } = computeLayout(nodes, edges);
|
|
6620
|
+
const nodeById = new Map(layoutNodes.map((n) => [n.id, n]));
|
|
6621
|
+
return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs(
|
|
6622
|
+
"svg",
|
|
6623
|
+
{
|
|
6624
|
+
width: svgWidth,
|
|
6625
|
+
height: svgHeight,
|
|
6626
|
+
viewBox: `0 0 ${svgWidth} ${svgHeight}`,
|
|
6627
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
6628
|
+
className: "block",
|
|
6629
|
+
children: [
|
|
6630
|
+
/* @__PURE__ */ jsx(SvgDefs, {}),
|
|
6631
|
+
edges.map((e, i) => {
|
|
6632
|
+
const fromNode = nodeById.get(e.from);
|
|
6633
|
+
const toNode = nodeById.get(e.to);
|
|
6634
|
+
if (!fromNode || !toNode) return null;
|
|
6635
|
+
return /* @__PURE__ */ jsx(EdgeSvg, { from: fromNode, to: toNode, label: e.label }, `e-${i}`);
|
|
6636
|
+
}),
|
|
6637
|
+
layoutNodes.map((n) => {
|
|
6638
|
+
if (n.node.type === "decision") return /* @__PURE__ */ jsx(DecisionNodeSvg, { n }, n.id);
|
|
6639
|
+
if (n.node.type === "terminal") return /* @__PURE__ */ jsx(TerminalNodeSvg, { n }, n.id);
|
|
6640
|
+
return /* @__PURE__ */ jsx(ActionNodeSvg, { n }, n.id);
|
|
6641
|
+
})
|
|
6642
|
+
]
|
|
6643
|
+
}
|
|
6644
|
+
) }) });
|
|
6440
6645
|
}
|
|
6441
6646
|
var frequencyLabels = {
|
|
6442
6647
|
multiple_daily: "occurrence",
|