@industry-theme/principal-view-panels 0.12.54 → 0.12.56

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.
@@ -1 +1 @@
1
- {"version":3,"file":"CanvasEditorPanel.d.ts","sourceRoot":"","sources":["../../src/panels/CanvasEditorPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AACjF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAC;AAI5D,OAAO,KAAK,EAAyE,gBAAgB,EAA+C,MAAM,mCAAmC,CAAC;AAC9L,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAKxE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAiCrE;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,2BAA2B;IACzE;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,cAAc,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAEjC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAE3C;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnC;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE7B;;OAEG;IACH,gBAAgB,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAEnC;;;OAGG;IACH,cAAc,CAAC,EAAE,KAAK,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;QAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC,CAAC;IAEH;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnC;;;;OAIG;IACH,aAAa,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAEvC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CA+gD9D,CAAC"}
1
+ {"version":3,"file":"CanvasEditorPanel.d.ts","sourceRoot":"","sources":["../../src/panels/CanvasEditorPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AACjF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAC;AAI5D,OAAO,KAAK,EAAyE,gBAAgB,EAA+C,MAAM,mCAAmC,CAAC;AAC9L,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAKxE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAiCrE;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,2BAA2B;IACzE;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,cAAc,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAEjC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAE3C;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnC;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE7B;;OAEG;IACH,gBAAgB,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAEnC;;;OAGG;IACH,cAAc,CAAC,EAAE,KAAK,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;QAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC,CAAC;IAEH;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnC;;;;OAIG;IACH,aAAa,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAEvC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAqhD9D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"StoryboardListPanel.d.ts","sourceRoot":"","sources":["../../src/panels/StoryboardListPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AACjF,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,UAAU,CAAC;AAsE9D;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,6BAA6B,CA+pCvE,CAAC"}
1
+ {"version":3,"file":"StoryboardListPanel.d.ts","sourceRoot":"","sources":["../../src/panels/StoryboardListPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAEjF,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,UAAU,CAAC;AAsE9D;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,6BAA6B,CA4yCvE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"WorkflowRenderer.d.ts","sourceRoot":"","sources":["../../../src/panels/execution-viewer/WorkflowRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,cAAc,EAAoC,MAAM,mCAAmC,CAAC;AAKvI,MAAM,WAAW,qBAAqB;IACpC,6CAA6C;IAC7C,QAAQ,EAAE,gBAAgB,CAAC;IAE3B,4BAA4B;IAC5B,MAAM,EAAE,SAAS,EAAE,CAAC;IAEpB,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAC;IAEnB,8BAA8B;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAE5B,0BAA0B;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,sFAAsF;IACtF,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAE9D,gFAAgF;IAChF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,kFAAkF;IAClF,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,yCAAyC;IACzC,MAAM,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAE/B,6CAA6C;IAC7C,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAEzC,6CAA6C;IAC7C,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAinB5D,CAAC"}
1
+ {"version":3,"file":"WorkflowRenderer.d.ts","sourceRoot":"","sources":["../../../src/panels/execution-viewer/WorkflowRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,cAAc,EAAoC,MAAM,mCAAmC,CAAC;AAKvI,MAAM,WAAW,qBAAqB;IACpC,6CAA6C;IAC7C,QAAQ,EAAE,gBAAgB,CAAC;IAE3B,4BAA4B;IAC5B,MAAM,EAAE,SAAS,EAAE,CAAC;IAEpB,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAC;IAEnB,8BAA8B;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAE5B,0BAA0B;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,sFAAsF;IACtF,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAE9D,gFAAgF;IAChF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,kFAAkF;IAClF,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,yCAAyC;IACzC,MAAM,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAE/B,6CAA6C;IAC7C,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAEzC,6CAA6C;IAC7C,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAmnB5D,CAAC"}
@@ -14,7 +14,7 @@ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
14
14
  import * as React from "react";
15
15
  import React__default, { createContext, useContext, useState, useCallback, useMemo, memo, forwardRef, useRef, useEffect, useLayoutEffect, createElement, useImperativeHandle } from "react";
16
16
  import { createPortal } from "react-dom";
17
- import { CanvasConverter, buildScopeColorMap, DRAFT_NODE_COLOR, renderEventTemplate, CanvasDiscovery, ExecutionValidator, renderWorkflow, LibraryDiscovery, getSpanDuration } from "@principal-ai/principal-view-core";
17
+ import { CanvasConverter, buildScopeColorMap, buildSpanColorMap, resolveEventSpanColor, DEFAULT_SPAN_COLOR, DRAFT_NODE_COLOR, renderEventTemplate, CanvasDiscovery, ExecutionValidator, renderWorkflow, LibraryDiscovery, getSpanDuration } from "@principal-ai/principal-view-core";
18
18
  import { StoryboardWorkflowsTreeCore, CanvasListTreeCore, hasWorkflowContent } from "@principal-ade/dynamic-file-tree";
19
19
  import { trace, context, SpanStatusCode } from "@opentelemetry/api";
20
20
  import { SpanStatusCode as SpanStatusCode2 } from "@opentelemetry/api";
@@ -86701,12 +86701,13 @@ const CustomNode = ({ data, selected: selected2, dragging }) => {
86701
86701
  }
86702
86702
  const nodeDataColor = nodeData.color;
86703
86703
  const scopeColor = nodeData.scopeColor;
86704
- const baseColor = scopeColor || nodeDataColor || typeDefinition.color || "#888";
86704
+ const spanColor = nodeData.spanColor;
86705
86705
  const nodeDataStates = nodeData.states;
86706
86706
  const stateColor = state && (((_a = nodeDataStates == null ? void 0 : nodeDataStates[state]) == null ? void 0 : _a.color) || ((_c = (_b = typeDefinition.states) == null ? void 0 : _b[state]) == null ? void 0 : _c.color));
86707
- const fillColor = stateColor || baseColor;
86707
+ const baseFillColor = spanColor || nodeDataColor || typeDefinition.color || "#888";
86708
+ const fillColor = stateColor || baseFillColor;
86708
86709
  const nodeDataStroke = nodeData.stroke;
86709
- const baseStrokeColor = nodeDataStroke || typeDefinition.stroke || fillColor;
86710
+ const baseStrokeColor = nodeDataStroke || scopeColor || fillColor;
86710
86711
  const status = nodeData == null ? void 0 : nodeData.status;
86711
86712
  const strokeColor = baseStrokeColor;
86712
86713
  const color2 = fillColor;
@@ -88505,28 +88506,29 @@ const GraphRendererInner = ({ configuration, nodes: propNodes, edges: propEdges,
88505
88506
  fontSize: "12px"
88506
88507
  }, children: "Cancel" })] })] });
88507
88508
  };
88508
- function useCanvasToLegacy(canvas, library) {
88509
+ function useCanvasToLegacy(canvas, library, spansCanvas, workflowSpanPattern) {
88509
88510
  return useMemo(() => {
88510
- var _a, _b, _c, _d, _e2, _f, _g, _h, _i, _j, _k, _l, _m;
88511
+ var _a, _b, _c, _d, _e2, _f, _g, _h, _i, _j, _k, _l;
88511
88512
  if (!canvas)
88512
88513
  return null;
88513
88514
  const { nodes, edges } = CanvasConverter.canvasToGraph(canvas);
88514
88515
  const scopeColorMap = buildScopeColorMap(library == null ? void 0 : library.resources);
88516
+ const spanColorMap = buildSpanColorMap(spansCanvas);
88517
+ const spanColor = resolveEventSpanColor(workflowSpanPattern, spanColorMap);
88515
88518
  for (const node2 of nodes) {
88516
88519
  const otel = (_a = node2.data) == null ? void 0 : _a.otel;
88517
88520
  const scope = otel == null ? void 0 : otel.scope;
88518
- const status = (_b = node2.data) == null ? void 0 : _b.status;
88521
+ let nodeScopeColor;
88519
88522
  if (scope && scopeColorMap[scope]) {
88520
- node2.data = {
88521
- ...node2.data,
88522
- scopeColor: scopeColorMap[scope]
88523
- };
88524
- } else if (status === "draft" || !scope) {
88525
- node2.data = {
88526
- ...node2.data,
88527
- scopeColor: DRAFT_NODE_COLOR
88528
- };
88523
+ nodeScopeColor = scopeColorMap[scope];
88524
+ } else {
88525
+ nodeScopeColor = DRAFT_NODE_COLOR;
88529
88526
  }
88527
+ node2.data = {
88528
+ ...node2.data,
88529
+ scopeColor: nodeScopeColor,
88530
+ spanColor: workflowSpanPattern ? spanColor : DEFAULT_SPAN_COLOR
88531
+ };
88530
88532
  }
88531
88533
  const nodeTypes2 = {};
88532
88534
  const edgeTypes2 = {};
@@ -88555,7 +88557,7 @@ function useCanvasToLegacy(canvas, library) {
88555
88557
  };
88556
88558
  }
88557
88559
  }
88558
- if ((_c = canvas.pv) == null ? void 0 : _c.nodeTypes) {
88560
+ if ((_b = canvas.pv) == null ? void 0 : _b.nodeTypes) {
88559
88561
  for (const [id2, def] of Object.entries(canvas.pv.nodeTypes)) {
88560
88562
  nodeTypes2[id2] = {
88561
88563
  description: def.description,
@@ -88570,7 +88572,7 @@ function useCanvasToLegacy(canvas, library) {
88570
88572
  const vv = node2.pv;
88571
88573
  const nodeType = (vv == null ? void 0 : vv.nodeType) || node2.type;
88572
88574
  if (!nodeTypes2[nodeType]) {
88573
- const fillColor = (vv == null ? void 0 : vv.fill) || (typeof node2.color === "string" ? node2.color : void 0) || ((_e2 = (_d = vv == null ? void 0 : vv.states) == null ? void 0 : _d.idle) == null ? void 0 : _e2.color);
88575
+ const fillColor = (vv == null ? void 0 : vv.fill) || (typeof node2.color === "string" ? node2.color : void 0) || ((_d = (_c = vv == null ? void 0 : vv.states) == null ? void 0 : _c.idle) == null ? void 0 : _d.color);
88574
88576
  let nodeDescription = `${nodeType} node`;
88575
88577
  if (node2.type === "text" && "text" in node2) {
88576
88578
  const lines = node2.text.split("\n");
@@ -88592,7 +88594,7 @@ function useCanvasToLegacy(canvas, library) {
88592
88594
  };
88593
88595
  }
88594
88596
  }
88595
- if ((_f = canvas.pv) == null ? void 0 : _f.edgeTypes) {
88597
+ if ((_e2 = canvas.pv) == null ? void 0 : _e2.edgeTypes) {
88596
88598
  for (const [id2, def] of Object.entries(canvas.pv.edgeTypes)) {
88597
88599
  edgeTypes2[id2] = {
88598
88600
  style: def.style || "solid",
@@ -88606,12 +88608,12 @@ function useCanvasToLegacy(canvas, library) {
88606
88608
  }
88607
88609
  const allowedConnections = [];
88608
88610
  for (const edge of canvas.edges || []) {
88609
- const edgeType = ((_g = edge.pv) == null ? void 0 : _g.edgeType) || "default";
88611
+ const edgeType = ((_f = edge.pv) == null ? void 0 : _f.edgeType) || "default";
88610
88612
  if (!edgeTypes2[edgeType]) {
88611
88613
  edgeTypes2[edgeType] = {
88612
- style: ((_h = edge.pv) == null ? void 0 : _h.style) || "solid",
88614
+ style: ((_g = edge.pv) == null ? void 0 : _g.style) || "solid",
88613
88615
  color: typeof edge.color === "string" ? edge.color : void 0,
88614
- width: (_i = edge.pv) == null ? void 0 : _i.width,
88616
+ width: (_h = edge.pv) == null ? void 0 : _h.width,
88615
88617
  directed: true
88616
88618
  };
88617
88619
  }
@@ -88621,16 +88623,16 @@ function useCanvasToLegacy(canvas, library) {
88621
88623
  via: edgeType
88622
88624
  });
88623
88625
  }
88624
- const display = ((_j = canvas.pv) == null ? void 0 : _j.display) ? {
88626
+ const display = ((_i = canvas.pv) == null ? void 0 : _i.display) ? {
88625
88627
  layout: canvas.pv.display.layout || "manual",
88626
88628
  theme: canvas.pv.display.theme,
88627
88629
  animations: canvas.pv.display.animations
88628
88630
  } : { layout: "manual" };
88629
88631
  const configuration = {
88630
88632
  metadata: {
88631
- name: ((_k = canvas.pv) == null ? void 0 : _k.name) || "Untitled",
88632
- version: ((_l = canvas.pv) == null ? void 0 : _l.version) || "1.0.0",
88633
- description: (_m = canvas.pv) == null ? void 0 : _m.description
88633
+ name: ((_j = canvas.pv) == null ? void 0 : _j.name) || "Untitled",
88634
+ version: ((_k = canvas.pv) == null ? void 0 : _k.version) || "1.0.0",
88635
+ description: (_l = canvas.pv) == null ? void 0 : _l.description
88634
88636
  },
88635
88637
  nodeTypes: nodeTypes2,
88636
88638
  edgeTypes: edgeTypes2,
@@ -88638,17 +88640,17 @@ function useCanvasToLegacy(canvas, library) {
88638
88640
  display
88639
88641
  };
88640
88642
  return { configuration, nodes, edges };
88641
- }, [canvas, library]);
88643
+ }, [canvas, library, spansCanvas, workflowSpanPattern]);
88642
88644
  }
88643
88645
  const GraphRenderer = forwardRef((props2, ref) => {
88644
- const { canvas, library, className, width = "100%", height = "100%" } = props2;
88646
+ const { canvas, library, spansCanvas, workflowSpanPattern, className, width = "100%", height = "100%" } = props2;
88645
88647
  const { theme: theme2 } = useTheme();
88646
88648
  const containerRef = useRef(null);
88647
88649
  const [portalTarget, setPortalTarget] = useState(null);
88648
88650
  useEffect(() => {
88649
88651
  setPortalTarget(containerRef.current);
88650
88652
  }, []);
88651
- const canvasData = useCanvasToLegacy(canvas, library);
88653
+ const canvasData = useCanvasToLegacy(canvas, library, spansCanvas, workflowSpanPattern);
88652
88654
  const editStateRef = useRef(createEmptyEditState());
88653
88655
  const resetVisualStateRef = useRef(null);
88654
88656
  const { canUndo: canUndoState, canRedo: canRedoState, undo: undoFromStack, redo: redoFromStack, pushHistory, clearHistory } = useUndoRedo();
@@ -95383,7 +95385,7 @@ const CanvasEditorPanel = ({
95383
95385
  setIsCarouselExpanded(false);
95384
95386
  }, []);
95385
95387
  const saveAllChanges = useCallback(async () => {
95386
- var _a2;
95388
+ var _a2, _b2;
95387
95389
  if (!state.canvas || !canvasPath) return;
95388
95390
  const pendingChanges = (_a2 = graphRef.current) == null ? void 0 : _a2.getPendingChanges();
95389
95391
  const hasGraphChanges = (pendingChanges == null ? void 0 : pendingChanges.hasChanges) ?? false;
@@ -95410,6 +95412,7 @@ const CanvasEditorPanel = ({
95410
95412
  isSaving: false,
95411
95413
  hasUnsavedChanges: false
95412
95414
  }));
95415
+ (_b2 = graphRef.current) == null ? void 0 : _b2.resetEditState();
95413
95416
  } catch (error) {
95414
95417
  console.error("[PrincipalView] Error saving changes:", error);
95415
95418
  setState((prev) => ({
@@ -95899,13 +95902,15 @@ const CanvasEditorPanel = ({
95899
95902
  }
95900
95903
  ) }) : /* @__PURE__ */ jsx("div", {}),
95901
95904
  rightPanel: /* @__PURE__ */ jsxs("div", { style: { height: "100%", display: "flex", flexDirection: "column", background: theme2.colors.background, position: "relative" }, children: [
95902
- /* @__PURE__ */ jsxs("div", { style: { flex: 1, position: "relative", minHeight: 0 }, children: [
95905
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, position: "relative", minHeight: 0, width: "100%", height: "100%" }, children: [
95903
95906
  /* @__PURE__ */ jsx(
95904
95907
  GraphRenderer,
95905
95908
  {
95906
95909
  ref: graphRef,
95907
95910
  canvas: state.canvas,
95908
95911
  library: state.library ?? void 0,
95912
+ width: "100%",
95913
+ height: "100%",
95909
95914
  editable: state.isEditMode,
95910
95915
  onPendingChangesChange: (hasChanges) => {
95911
95916
  setState((prev) => ({ ...prev, hasUnsavedChanges: hasChanges }));
@@ -99690,6 +99695,9 @@ const StoryboardListPanel = ({
99690
99695
  const [showHelp, setShowHelp] = useState(false);
99691
99696
  const [cliCommandCopied, setCliCommandCopied] = useState(false);
99692
99697
  const [canvasTypeFilter, setCanvasTypeFilter] = useState(null);
99698
+ const [contextMenu, setContextMenu] = useState(null);
99699
+ const [contextMenuCopied, setContextMenuCopied] = useState(false);
99700
+ const contextMenuRef = useRef(null);
99693
99701
  const { storyboards, workflows, testTraces, isLoading, error, discovery } = useCanvasWorkflowData({ context: context2, actions });
99694
99702
  useEffect(() => {
99695
99703
  if (!events) return;
@@ -99858,7 +99866,8 @@ const StoryboardListPanel = ({
99858
99866
  let draft = 0;
99859
99867
  for (const node2 of canvas.nodes) {
99860
99868
  const pv = node2.pv;
99861
- const status = (pv == null ? void 0 : pv.status) ?? "draft";
99869
+ if (!pv) continue;
99870
+ const status = pv.status ?? "draft";
99862
99871
  if (status === "implemented") {
99863
99872
  implemented++;
99864
99873
  } else if (status === "approved") {
@@ -99980,6 +99989,63 @@ const StoryboardListPanel = ({
99980
99989
  }
99981
99990
  }
99982
99991
  }, [events, getCanvasFileInfo, workflows]);
99992
+ const getNodeFilePath = useCallback((node2) => {
99993
+ var _a, _b, _c, _d, _e2;
99994
+ if (node2.type === "canvas" && ((_a = node2.canvas) == null ? void 0 : _a.path)) {
99995
+ return node2.canvas.path;
99996
+ } else if (node2.type === "workflow" && "workflow" in node2 && ((_b = node2.workflow) == null ? void 0 : _b.path)) {
99997
+ return node2.workflow.path;
99998
+ } else if (node2.type === "overview" && node2.markdownPath) {
99999
+ return node2.markdownPath;
100000
+ } else if (node2.type === "storyboard" && "storyboard" in node2 && ((_d = (_c = node2.storyboard) == null ? void 0 : _c.canvas) == null ? void 0 : _d.path)) {
100001
+ return node2.storyboard.canvas.path;
100002
+ } else if (node2.type === "canvas-folder" && ((_e2 = node2.canvas) == null ? void 0 : _e2.path)) {
100003
+ return node2.canvas.path;
100004
+ }
100005
+ return void 0;
100006
+ }, []);
100007
+ const handleContextMenu = useCallback((event, node2) => {
100008
+ event.preventDefault();
100009
+ const path2 = getNodeFilePath(node2);
100010
+ if (path2) {
100011
+ setContextMenu({ x: event.clientX, y: event.clientY, node: node2 });
100012
+ setContextMenuCopied(false);
100013
+ }
100014
+ }, [getNodeFilePath]);
100015
+ const handleCopyPath = useCallback(async () => {
100016
+ if (!contextMenu) return;
100017
+ const path2 = getNodeFilePath(contextMenu.node);
100018
+ if (path2) {
100019
+ try {
100020
+ await navigator.clipboard.writeText(path2);
100021
+ setContextMenuCopied(true);
100022
+ setTimeout(() => {
100023
+ setContextMenu(null);
100024
+ setContextMenuCopied(false);
100025
+ }, 800);
100026
+ } catch {
100027
+ console.error("Failed to copy path to clipboard");
100028
+ setContextMenu(null);
100029
+ }
100030
+ }
100031
+ }, [contextMenu, getNodeFilePath]);
100032
+ useEffect(() => {
100033
+ if (!contextMenu) return;
100034
+ const handleClickOutside = (e) => {
100035
+ if (contextMenuRef.current && !contextMenuRef.current.contains(e.target)) {
100036
+ setContextMenu(null);
100037
+ }
100038
+ };
100039
+ const handleKeyDown = (e) => {
100040
+ if (e.key === "Escape") setContextMenu(null);
100041
+ };
100042
+ document.addEventListener("mousedown", handleClickOutside);
100043
+ document.addEventListener("keydown", handleKeyDown);
100044
+ return () => {
100045
+ document.removeEventListener("mousedown", handleClickOutside);
100046
+ document.removeEventListener("keydown", handleKeyDown);
100047
+ };
100048
+ }, [contextMenu]);
99983
100049
  useEffect(() => {
99984
100050
  handleTreeNodeClickRef.current = handleTreeNodeClick;
99985
100051
  }, [handleTreeNodeClick]);
@@ -100478,6 +100544,7 @@ const StoryboardListPanel = ({
100478
100544
  storyboards: filteredStoryboards,
100479
100545
  theme: theme2,
100480
100546
  onClick: handleTreeNodeClick,
100547
+ onContextMenu: handleContextMenu,
100481
100548
  selectedNodeId: selectedNodeId ?? void 0,
100482
100549
  defaultOpen: filteredStoryboards.length <= 2,
100483
100550
  openState,
@@ -100495,6 +100562,7 @@ const StoryboardListPanel = ({
100495
100562
  canvases: filteredCanvases,
100496
100563
  theme: theme2,
100497
100564
  onClick: handleTreeNodeClick,
100565
+ onContextMenu: handleContextMenu,
100498
100566
  selectedNodeId: selectedNodeId ?? void 0,
100499
100567
  defaultOpen: filteredCanvases.length <= 2,
100500
100568
  openState,
@@ -100650,7 +100718,66 @@ const StoryboardListPanel = ({
100650
100718
  @keyframes spin {
100651
100719
  to { transform: rotate(360deg); }
100652
100720
  }
100653
- ` })
100721
+ ` }),
100722
+ contextMenu && createPortal(
100723
+ /* @__PURE__ */ jsxs(
100724
+ "div",
100725
+ {
100726
+ ref: contextMenuRef,
100727
+ style: {
100728
+ position: "fixed",
100729
+ top: contextMenu.y,
100730
+ left: contextMenu.x,
100731
+ backgroundColor: theme2.colors.background,
100732
+ border: `1px solid ${theme2.colors.border}`,
100733
+ borderRadius: "6px",
100734
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
100735
+ zIndex: 1e3,
100736
+ minWidth: "180px",
100737
+ padding: "4px 0",
100738
+ fontFamily: theme2.fonts.body
100739
+ },
100740
+ children: [
100741
+ /* @__PURE__ */ jsx("style", { children: `
100742
+ .storyboard-context-menu-item {
100743
+ transition: background-color 0.15s ease;
100744
+ }
100745
+ .storyboard-context-menu-item:hover {
100746
+ background-color: ${theme2.colors.backgroundTertiary} !important;
100747
+ }
100748
+ ` }),
100749
+ /* @__PURE__ */ jsx(
100750
+ "button",
100751
+ {
100752
+ onClick: handleCopyPath,
100753
+ className: "storyboard-context-menu-item",
100754
+ style: {
100755
+ display: "flex",
100756
+ alignItems: "center",
100757
+ gap: "8px",
100758
+ width: "100%",
100759
+ padding: "8px 12px",
100760
+ border: "none",
100761
+ background: "none",
100762
+ cursor: "pointer",
100763
+ fontSize: theme2.fontSizes[1],
100764
+ color: theme2.colors.text,
100765
+ textAlign: "left"
100766
+ },
100767
+ children: contextMenuCopied ? /* @__PURE__ */ jsxs(Fragment, { children: [
100768
+ /* @__PURE__ */ jsx(Check, { size: 14, style: { color: theme2.colors.success || "#22c55e" } }),
100769
+ /* @__PURE__ */ jsx("span", { children: "Copied!" })
100770
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
100771
+ /* @__PURE__ */ jsx(Copy, { size: 14 }),
100772
+ /* @__PURE__ */ jsx("span", { children: "Copy Path" })
100773
+ ] })
100774
+ }
100775
+ )
100776
+ ]
100777
+ }
100778
+ ),
100779
+ document.body
100780
+ )
100654
100781
  ]
100655
100782
  }
100656
100783
  );