@industry-theme/principal-view-panels 0.1.49 → 0.1.51

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":"ExecutionViewerPanel.d.ts","sourceRoot":"","sources":["../../src/panels/ExecutionViewerPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AA8B/E;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAgmB9D,CAAC"}
1
+ {"version":3,"file":"ExecutionViewerPanel.d.ts","sourceRoot":"","sources":["../../src/panels/ExecutionViewerPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAoI/E;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAooB9D,CAAC"}
@@ -10,6 +10,18 @@ export interface ExecutionFile {
10
10
  /** Package name for monorepos (e.g., 'core' from 'packages/core/__executions__/') */
11
11
  packageName?: string;
12
12
  }
13
+ export interface CanvasFile {
14
+ /** Unique identifier for this canvas (derived from filename) */
15
+ id: string;
16
+ /** Display name for this canvas */
17
+ name: string;
18
+ /** Full file path */
19
+ path: string;
20
+ /** Whether this is from a config folder or standalone */
21
+ source: 'folder' | 'standalone';
22
+ /** Canvas basename (without .otel.canvas or .canvas extension) */
23
+ basename: string;
24
+ }
13
25
  export interface ExecutionMetadata {
14
26
  /** Execution name */
15
27
  name: string;
@@ -76,6 +88,14 @@ export declare class ExecutionLoader {
76
88
  relativePath?: string;
77
89
  name?: string;
78
90
  }>): ExecutionFile[];
91
+ /**
92
+ * Find all .otel.canvas and .canvas files in the file tree
93
+ */
94
+ static findCanvasFiles(files: Array<{
95
+ path?: string;
96
+ relativePath?: string;
97
+ name?: string;
98
+ }>): CanvasFile[];
79
99
  /**
80
100
  * Find execution artifact for a given canvas file path
81
101
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ExecutionLoader.d.ts","sourceRoot":"","sources":["../../../src/panels/execution-viewer/ExecutionLoader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ExecutionLoader.d.ts","sourceRoot":"","sources":["../../../src/panels/execution-viewer/ExecutionLoader.ts"],"names":[],"mappings":"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"}
@@ -55853,12 +55853,35 @@ class ExecutionLoader {
55853
55853
  return a.name.localeCompare(b.name);
55854
55854
  });
55855
55855
  }
55856
+ /**
55857
+ * Find all .otel.canvas and .canvas files in the file tree
55858
+ */
55859
+ static findCanvasFiles(files) {
55860
+ const canvasFiles = [];
55861
+ const VGC_FOLDER = ".principal-views";
55862
+ for (const file of files) {
55863
+ const filePath = file.relativePath || file.path || "";
55864
+ const fileName = file.name || filePath.split("/").pop() || "";
55865
+ if (filePath.startsWith(`${VGC_FOLDER}/`) && (fileName.endsWith(".otel.canvas") || fileName.endsWith(".canvas"))) {
55866
+ const basename = fileName.replace(/\.otel\.canvas$/, "").replace(/\.canvas$/, "");
55867
+ const displayName = basename.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
55868
+ canvasFiles.push({
55869
+ id: basename,
55870
+ name: displayName,
55871
+ path: filePath,
55872
+ source: "folder",
55873
+ basename
55874
+ });
55875
+ }
55876
+ }
55877
+ return canvasFiles.sort((a, b) => a.name.localeCompare(b.name));
55878
+ }
55856
55879
  /**
55857
55880
  * Find execution artifact for a given canvas file path
55858
55881
  */
55859
55882
  static findExecutionForCanvas(canvasPath, files) {
55860
55883
  const canvasFilename = canvasPath.split("/").pop() || "";
55861
- const canvasBasename = canvasFilename.replace(/\.otel\.canvas$/, "");
55884
+ const canvasBasename = canvasFilename.replace(/\.otel\.canvas$/, "").replace(/\.canvas$/, "");
55862
55885
  const executions = ExecutionLoader.findExecutionFiles(files);
55863
55886
  return executions.find((exec) => exec.canvasBasename === canvasBasename) || null;
55864
55887
  }
@@ -56032,6 +56055,93 @@ function buildEventToNodeMap(canvas) {
56032
56055
  }
56033
56056
  return map2;
56034
56057
  }
56058
+ const TestEventPanelWrapper = ({ spans, currentSpanIndex, currentEventIndex, onSpanIndexChange }) => {
56059
+ const isSingleSpan = spans.length === 1;
56060
+ const wrapperId = "event-panel-" + (isSingleSpan ? "single" : "multi");
56061
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
56062
+ /* @__PURE__ */ jsx("style", { children: `
56063
+ /* Reorder elements in TestEventPanel */
56064
+ #${wrapperId} > div > div:first-child {
56065
+ display: flex;
56066
+ flex-direction: column;
56067
+ }
56068
+
56069
+ /* Test name/description - move to top (order 1) */
56070
+ #${wrapperId} > div > div:first-child > div:first-child {
56071
+ order: 1;
56072
+ }
56073
+
56074
+ /* Filter buttons (All, Events, Logs) - move below test name (order 2) */
56075
+ #${wrapperId} > div > div:first-child > div:nth-child(2) {
56076
+ order: 2;
56077
+ }
56078
+
56079
+ /* Timeline/content - keep at bottom (order 3) */
56080
+ #${wrapperId} > div > div:first-child > div:nth-child(3) {
56081
+ order: 3;
56082
+ }
56083
+
56084
+ ${isSingleSpan ? `
56085
+ /* Hide navigation for single span */
56086
+ #${wrapperId} button:disabled {
56087
+ display: none;
56088
+ }
56089
+ #${wrapperId} div:has(> button:disabled) {
56090
+ display: none;
56091
+ }
56092
+
56093
+ /* Hide "Execution Timeline" title */
56094
+ #${wrapperId} h3,
56095
+ #${wrapperId} h2,
56096
+ #${wrapperId} div[style*="fontSize: 16px"] {
56097
+ display: none !important;
56098
+ }
56099
+
56100
+ /* Hide filter buttons (All, Events, Logs) */
56101
+ #${wrapperId} div:has(> button):not(:has(svg[class*="HelpCircle"])) button {
56102
+ display: none !important;
56103
+ }
56104
+
56105
+ /* Hide event/log counts (e.g., "1 events, 0 logs") */
56106
+ #${wrapperId} div[style*="fontSize: 12px"][style*="marginLeft: auto"] {
56107
+ display: none !important;
56108
+ }
56109
+
56110
+ /* Keep only the status badge and help button visible in header */
56111
+ #${wrapperId} > div > div:first-child > div:first-child {
56112
+ display: flex !important;
56113
+ align-items: center;
56114
+ justify-content: space-between;
56115
+ padding: 12px 16px;
56116
+ }
56117
+
56118
+ /* Hide all children except status badge and help button */
56119
+ #${wrapperId} > div > div:first-child > div:first-child > * {
56120
+ display: none !important;
56121
+ }
56122
+
56123
+ /* Show status badge */
56124
+ #${wrapperId} > div > div:first-child > div:first-child > div:has([style*="background"]) {
56125
+ display: flex !important;
56126
+ }
56127
+
56128
+ /* Show help button */
56129
+ #${wrapperId} > div > div:first-child > div:first-child > button {
56130
+ display: flex !important;
56131
+ }
56132
+ ` : ""}
56133
+ ` }),
56134
+ /* @__PURE__ */ jsx("div", { id: wrapperId, style: { height: "100%" }, children: /* @__PURE__ */ jsx(
56135
+ distExports.TestEventPanel,
56136
+ {
56137
+ spans,
56138
+ currentSpanIndex,
56139
+ currentEventIndex,
56140
+ onSpanIndexChange
56141
+ }
56142
+ ) })
56143
+ ] });
56144
+ };
56035
56145
  const ExecutionViewerPanel = ({
56036
56146
  context,
56037
56147
  actions,
@@ -56045,9 +56155,10 @@ const ExecutionViewerPanel = ({
56045
56155
  metadata: null,
56046
56156
  loading: true,
56047
56157
  error: null,
56048
- availableExecutions: [],
56049
- selectedExecutionId: null,
56050
- showExecutionSelector: false,
56158
+ availableCanvases: [],
56159
+ selectedCanvasId: null,
56160
+ linkedExecution: null,
56161
+ showCanvasSelector: false,
56051
56162
  isPlaying: false,
56052
56163
  currentSpanIndex: 0,
56053
56164
  currentEventIndex: 0,
@@ -56059,11 +56170,11 @@ const ExecutionViewerPanel = ({
56059
56170
  contextRef.current = context;
56060
56171
  actionsRef.current = actions;
56061
56172
  eventsRef.current = events;
56062
- const selectedExecutionIdRef = useRef(null);
56063
- selectedExecutionIdRef.current = state.selectedExecutionId;
56173
+ const selectedCanvasIdRef = useRef(null);
56174
+ selectedCanvasIdRef.current = state.selectedCanvasId;
56064
56175
  const playbackTimerRef = useRef(null);
56065
56176
  const eventNodeMapRef = useRef(/* @__PURE__ */ new Map());
56066
- const loadExecution = useCallback(async (executionId) => {
56177
+ const loadCanvas = useCallback(async (canvasId) => {
56067
56178
  setState((prev) => ({ ...prev, loading: prev.canvas === null, error: null }));
56068
56179
  try {
56069
56180
  const ctx = contextRef.current;
@@ -56084,13 +56195,14 @@ const ExecutionViewerPanel = ({
56084
56195
  metadata: null,
56085
56196
  loading: false,
56086
56197
  error: null,
56087
- availableExecutions: [],
56088
- selectedExecutionId: null
56198
+ availableCanvases: [],
56199
+ selectedCanvasId: null,
56200
+ linkedExecution: null
56089
56201
  }));
56090
56202
  return;
56091
56203
  }
56092
- const availableExecutions = ExecutionLoader.findExecutionFiles(fileTreeData.allFiles);
56093
- if (availableExecutions.length === 0) {
56204
+ const availableCanvases = ExecutionLoader.findCanvasFiles(fileTreeData.allFiles);
56205
+ if (availableCanvases.length === 0) {
56094
56206
  setState((prev) => ({
56095
56207
  ...prev,
56096
56208
  canvas: null,
@@ -56098,23 +56210,24 @@ const ExecutionViewerPanel = ({
56098
56210
  metadata: null,
56099
56211
  loading: false,
56100
56212
  error: null,
56101
- availableExecutions: [],
56102
- selectedExecutionId: null
56213
+ availableCanvases: [],
56214
+ selectedCanvasId: null,
56215
+ linkedExecution: null
56103
56216
  }));
56104
56217
  return;
56105
56218
  }
56106
- let selectedExecution2;
56107
- if (executionId) {
56108
- const found = availableExecutions.find((e) => e.id === executionId);
56219
+ let selectedCanvas2;
56220
+ if (canvasId) {
56221
+ const found = availableCanvases.find((c) => c.id === canvasId);
56109
56222
  if (!found) {
56110
- throw new Error(`Execution with ID '${executionId}' not found`);
56223
+ throw new Error(`Canvas with ID '${canvasId}' not found`);
56111
56224
  }
56112
- selectedExecution2 = found;
56113
- } else if (selectedExecutionIdRef.current) {
56114
- const found = availableExecutions.find((e) => e.id === selectedExecutionIdRef.current);
56115
- selectedExecution2 = found || availableExecutions[0];
56225
+ selectedCanvas2 = found;
56226
+ } else if (selectedCanvasIdRef.current) {
56227
+ const found = availableCanvases.find((c) => c.id === selectedCanvasIdRef.current);
56228
+ selectedCanvas2 = found || availableCanvases[0];
56116
56229
  } else {
56117
- selectedExecution2 = availableExecutions[0];
56230
+ selectedCanvas2 = availableCanvases[0];
56118
56231
  }
56119
56232
  const readFile = acts.readFile;
56120
56233
  if (!readFile) {
@@ -56124,34 +56237,31 @@ const ExecutionViewerPanel = ({
56124
56237
  if (!repositoryPath) {
56125
56238
  throw new Error("Repository path not available");
56126
56239
  }
56127
- const fullExecutionPath = `${repositoryPath}/${selectedExecution2.path}`;
56128
- const executionContent = await readFile(fullExecutionPath);
56129
- if (!executionContent || typeof executionContent !== "string") {
56130
- throw new Error("Failed to read execution file");
56240
+ const fullCanvasPath = `${repositoryPath}/${selectedCanvas2.path}`;
56241
+ const canvasContent = await readFile(fullCanvasPath);
56242
+ if (!canvasContent || typeof canvasContent !== "string") {
56243
+ throw new Error("Failed to read canvas file");
56131
56244
  }
56132
- const execution = ExecutionLoader.parseExecutionArtifact(executionContent);
56133
- const metadata = ExecutionLoader.getExecutionMetadata(execution);
56134
- const canvasPath = ExecutionLoader.findCanvasForExecution(
56135
- selectedExecution2.path,
56245
+ const canvas = JSON.parse(canvasContent);
56246
+ const linkedExecution = ExecutionLoader.findExecutionForCanvas(
56247
+ selectedCanvas2.path,
56136
56248
  fileTreeData.allFiles
56137
56249
  );
56138
- let canvas = null;
56139
- if (canvasPath) {
56250
+ let execution = null;
56251
+ let metadata = null;
56252
+ if (linkedExecution) {
56140
56253
  try {
56141
- const fullCanvasPath = `${repositoryPath}/${canvasPath}`;
56142
- const canvasContent = await readFile(fullCanvasPath);
56143
- if (canvasContent && typeof canvasContent === "string") {
56144
- canvas = JSON.parse(canvasContent);
56254
+ const fullExecutionPath = `${repositoryPath}/${linkedExecution.path}`;
56255
+ const executionContent = await readFile(fullExecutionPath);
56256
+ if (executionContent && typeof executionContent === "string") {
56257
+ execution = ExecutionLoader.parseExecutionArtifact(executionContent);
56258
+ metadata = ExecutionLoader.getExecutionMetadata(execution);
56145
56259
  }
56146
56260
  } catch (error) {
56147
- console.warn("[ExecutionViewer] Failed to load canvas:", error);
56261
+ console.warn("[ExecutionViewer] Failed to load linked execution:", error);
56148
56262
  }
56149
56263
  }
56150
- if (canvas) {
56151
- eventNodeMapRef.current = buildEventToNodeMap(canvas);
56152
- } else {
56153
- eventNodeMapRef.current = /* @__PURE__ */ new Map();
56154
- }
56264
+ eventNodeMapRef.current = buildEventToNodeMap(canvas);
56155
56265
  setState((prev) => ({
56156
56266
  ...prev,
56157
56267
  canvas,
@@ -56159,14 +56269,15 @@ const ExecutionViewerPanel = ({
56159
56269
  metadata,
56160
56270
  loading: false,
56161
56271
  error: null,
56162
- availableExecutions,
56163
- selectedExecutionId: selectedExecution2.id,
56272
+ availableCanvases,
56273
+ selectedCanvasId: selectedCanvas2.id,
56274
+ linkedExecution,
56164
56275
  currentSpanIndex: 0,
56165
56276
  currentEventIndex: 0,
56166
56277
  highlightedNodeId: null
56167
56278
  }));
56168
56279
  } catch (error) {
56169
- console.error("[ExecutionViewer] Error loading execution:", error);
56280
+ console.error("[ExecutionViewer] Error loading canvas:", error);
56170
56281
  setState((prev) => ({
56171
56282
  ...prev,
56172
56283
  loading: false,
@@ -56175,16 +56286,16 @@ const ExecutionViewerPanel = ({
56175
56286
  }
56176
56287
  }, []);
56177
56288
  useEffect(() => {
56178
- loadExecution();
56179
- }, [loadExecution]);
56289
+ loadCanvas();
56290
+ }, [loadCanvas]);
56180
56291
  useEffect(() => {
56181
56292
  if (!events) return;
56182
56293
  const handleEvent = (event) => {
56183
56294
  var _a2;
56184
- if (event.type === "custom" && event.action === "selectExecution") {
56185
- const executionId = (_a2 = event.payload) == null ? void 0 : _a2.executionId;
56186
- if (executionId) {
56187
- loadExecution(executionId);
56295
+ if (event.type === "custom" && event.action === "selectCanvas") {
56296
+ const canvasId = (_a2 = event.payload) == null ? void 0 : _a2.canvasId;
56297
+ if (canvasId) {
56298
+ loadCanvas(canvasId);
56188
56299
  }
56189
56300
  }
56190
56301
  };
@@ -56192,7 +56303,7 @@ const ExecutionViewerPanel = ({
56192
56303
  return () => {
56193
56304
  events.off("custom", handleEvent);
56194
56305
  };
56195
- }, [events, loadExecution]);
56306
+ }, [events, loadCanvas]);
56196
56307
  const handlePlayPause = useCallback(() => {
56197
56308
  setState((prev) => ({ ...prev, isPlaying: !prev.isPlaying }));
56198
56309
  }, []);
@@ -56268,7 +56379,7 @@ const ExecutionViewerPanel = ({
56268
56379
  }
56269
56380
  };
56270
56381
  }, [state.isPlaying, state.execution]);
56271
- if (!state.loading && state.availableExecutions.length === 0) {
56382
+ if (!state.loading && state.availableCanvases.length === 0) {
56272
56383
  return /* @__PURE__ */ jsx(
56273
56384
  "div",
56274
56385
  {
@@ -56282,7 +56393,7 @@ const ExecutionViewerPanel = ({
56282
56393
  },
56283
56394
  children: /* @__PURE__ */ jsxs("div", { style: { textAlign: "center", maxWidth: "600px", padding: "20px" }, children: [
56284
56395
  /* @__PURE__ */ jsx(Activity, { size: 48, style: { margin: "0 auto 20px", opacity: 0.3 } }),
56285
- /* @__PURE__ */ jsx("h2", { style: { margin: "0 0 10px 0", fontSize: "18px", fontWeight: 600 }, children: "No Execution Artifacts Found" }),
56396
+ /* @__PURE__ */ jsx("h2", { style: { margin: "0 0 10px 0", fontSize: "18px", fontWeight: 600 }, children: "No Canvas Files Found" }),
56286
56397
  /* @__PURE__ */ jsxs("p", { style: { margin: "0 0 20px 0", color: theme.colors.textSecondary, lineHeight: 1.5 }, children: [
56287
56398
  "Execution artifacts should be saved to ",
56288
56399
  /* @__PURE__ */ jsx("code", { children: "__executions__/*.spans.json" }),
@@ -56355,8 +56466,8 @@ const ExecutionViewerPanel = ({
56355
56466
  }
56356
56467
  );
56357
56468
  }
56358
- const selectedExecution = state.availableExecutions.find(
56359
- (e) => e.id === state.selectedExecutionId
56469
+ const selectedCanvas = state.availableCanvases.find(
56470
+ (c) => c.id === state.selectedCanvasId
56360
56471
  );
56361
56472
  return /* @__PURE__ */ jsxs(
56362
56473
  "div",
@@ -56381,11 +56492,11 @@ const ExecutionViewerPanel = ({
56381
56492
  gap: "12px"
56382
56493
  },
56383
56494
  children: [
56384
- /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
56495
+ state.availableCanvases.length > 0 && /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
56385
56496
  /* @__PURE__ */ jsxs(
56386
56497
  "button",
56387
56498
  {
56388
- onClick: () => setState((prev) => ({ ...prev, showExecutionSelector: !prev.showExecutionSelector })),
56499
+ onClick: () => setState((prev) => ({ ...prev, showCanvasSelector: !prev.showCanvasSelector })),
56389
56500
  style: {
56390
56501
  display: "flex",
56391
56502
  alignItems: "center",
@@ -56400,25 +56511,25 @@ const ExecutionViewerPanel = ({
56400
56511
  },
56401
56512
  children: [
56402
56513
  /* @__PURE__ */ jsx(Activity, { size: 16 }),
56403
- /* @__PURE__ */ jsx("span", { children: (selectedExecution == null ? void 0 : selectedExecution.name) || "Select Execution" }),
56404
- (selectedExecution == null ? void 0 : selectedExecution.packageName) && /* @__PURE__ */ jsx(
56514
+ /* @__PURE__ */ jsx("span", { children: (selectedCanvas == null ? void 0 : selectedCanvas.name) || "Select Canvas" }),
56515
+ state.linkedExecution && /* @__PURE__ */ jsx(
56405
56516
  "span",
56406
56517
  {
56407
56518
  style: {
56408
56519
  padding: "2px 6px",
56409
- background: "#3b82f6",
56520
+ background: "#22c55e",
56410
56521
  borderRadius: "3px",
56411
56522
  fontSize: "11px",
56412
56523
  fontWeight: 600
56413
56524
  },
56414
- children: selectedExecution.packageName
56525
+ children: "has execution"
56415
56526
  }
56416
56527
  ),
56417
56528
  /* @__PURE__ */ jsx(ChevronDown, { size: 16 })
56418
56529
  ]
56419
56530
  }
56420
56531
  ),
56421
- state.showExecutionSelector && /* @__PURE__ */ jsxs(Fragment, { children: [
56532
+ state.showCanvasSelector && /* @__PURE__ */ jsxs(Fragment, { children: [
56422
56533
  /* @__PURE__ */ jsx(
56423
56534
  "div",
56424
56535
  {
@@ -56427,7 +56538,7 @@ const ExecutionViewerPanel = ({
56427
56538
  inset: 0,
56428
56539
  zIndex: 999
56429
56540
  },
56430
- onClick: () => setState((prev) => ({ ...prev, showExecutionSelector: false }))
56541
+ onClick: () => setState((prev) => ({ ...prev, showCanvasSelector: false }))
56431
56542
  }
56432
56543
  ),
56433
56544
  /* @__PURE__ */ jsx(
@@ -56447,17 +56558,17 @@ const ExecutionViewerPanel = ({
56447
56558
  boxShadow: "0 4px 12px rgba(0,0,0,0.3)",
56448
56559
  zIndex: 1e3
56449
56560
  },
56450
- children: state.availableExecutions.map((execution) => /* @__PURE__ */ jsxs(
56561
+ children: state.availableCanvases.map((canvas) => /* @__PURE__ */ jsxs(
56451
56562
  "button",
56452
56563
  {
56453
56564
  onClick: () => {
56454
- loadExecution(execution.id);
56455
- setState((prev) => ({ ...prev, showExecutionSelector: false }));
56565
+ loadCanvas(canvas.id);
56566
+ setState((prev) => ({ ...prev, showCanvasSelector: false }));
56456
56567
  },
56457
56568
  style: {
56458
56569
  width: "100%",
56459
56570
  padding: "10px 16px",
56460
- background: execution.id === state.selectedExecutionId ? "#3b82f6" : "transparent",
56571
+ background: canvas.id === state.selectedCanvasId ? "#3b82f6" : "transparent",
56461
56572
  border: "none",
56462
56573
  borderBottom: "1px solid #3a3a3a",
56463
56574
  color: "#fff",
@@ -56470,33 +56581,20 @@ const ExecutionViewerPanel = ({
56470
56581
  },
56471
56582
  children: [
56472
56583
  /* @__PURE__ */ jsx(Activity, { size: 14 }),
56473
- /* @__PURE__ */ jsx("span", { style: { flex: 1 }, children: execution.name }),
56474
- execution.packageName && /* @__PURE__ */ jsx(
56475
- "span",
56476
- {
56477
- style: {
56478
- padding: "2px 6px",
56479
- background: execution.id === state.selectedExecutionId ? "#2563eb" : "#3b82f6",
56480
- borderRadius: "3px",
56481
- fontSize: "11px",
56482
- fontWeight: 600
56483
- },
56484
- children: execution.packageName
56485
- }
56486
- )
56584
+ /* @__PURE__ */ jsx("span", { style: { flex: 1 }, children: canvas.name })
56487
56585
  ]
56488
56586
  },
56489
- execution.id
56587
+ canvas.id
56490
56588
  ))
56491
56589
  }
56492
56590
  )
56493
56591
  ] })
56494
56592
  ] }),
56495
56593
  /* @__PURE__ */ jsxs("div", { style: { flex: 1 }, children: [
56496
- /* @__PURE__ */ jsx("div", { style: { fontSize: "14px", fontWeight: 600 }, children: ((_a = state.metadata) == null ? void 0 : _a.name) || "Execution Viewer" }),
56497
- selectedExecution && /* @__PURE__ */ jsx("div", { style: { fontSize: "11px", color: "#999", marginTop: "2px" }, children: selectedExecution.path })
56594
+ /* @__PURE__ */ jsx("div", { style: { fontSize: "14px", fontWeight: 600 }, children: ((_a = state.metadata) == null ? void 0 : _a.name) || (state.canvas ? "Canvas Viewer" : "Execution Viewer") }),
56595
+ selectedCanvas && /* @__PURE__ */ jsx("div", { style: { fontSize: "11px", color: "#999", marginTop: "2px" }, children: selectedCanvas.path })
56498
56596
  ] }),
56499
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px" }, children: [
56597
+ state.execution && /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px" }, children: [
56500
56598
  /* @__PURE__ */ jsx(
56501
56599
  "button",
56502
56600
  {
@@ -56543,11 +56641,58 @@ const ExecutionViewerPanel = ({
56543
56641
  }
56544
56642
  ),
56545
56643
  /* @__PURE__ */ jsxs("div", { style: { flex: 1, display: "flex", overflow: "hidden" }, children: [
56644
+ /* @__PURE__ */ jsx("div", { style: { flex: "0 0 40%", borderRight: "1px solid #333", overflow: "hidden" }, children: state.execution ? /* @__PURE__ */ jsx(
56645
+ TestEventPanelWrapper,
56646
+ {
56647
+ spans: ExecutionLoader.getSpans(state.execution),
56648
+ currentSpanIndex: state.currentSpanIndex,
56649
+ currentEventIndex: state.currentEventIndex,
56650
+ onSpanIndexChange: handleSpanIndexChange
56651
+ }
56652
+ ) : /* @__PURE__ */ jsx(
56653
+ "div",
56654
+ {
56655
+ style: {
56656
+ display: "flex",
56657
+ alignItems: "center",
56658
+ justifyContent: "center",
56659
+ height: "100%",
56660
+ background: "#0a0a0a",
56661
+ padding: "20px"
56662
+ },
56663
+ children: /* @__PURE__ */ jsxs("div", { style: { textAlign: "center", maxWidth: "400px" }, children: [
56664
+ /* @__PURE__ */ jsx(Activity, { size: 48, style: { margin: "0 auto 20px", opacity: 0.3, color: "#666" } }),
56665
+ /* @__PURE__ */ jsx("h3", { style: { margin: "0 0 10px 0", fontSize: "16px", fontWeight: 600, color: "#fff" }, children: "No Execution Artifacts Found" }),
56666
+ /* @__PURE__ */ jsx("p", { style: { margin: "0 0 16px 0", color: "#999", lineHeight: 1.5, fontSize: "13px" }, children: "The canvas is displayed, but execution data is missing. Run tests to generate execution artifacts." }),
56667
+ /* @__PURE__ */ jsxs(
56668
+ "div",
56669
+ {
56670
+ style: {
56671
+ background: "#1e1e1e",
56672
+ padding: "10px",
56673
+ borderRadius: "4px",
56674
+ fontFamily: "monospace",
56675
+ fontSize: "11px",
56676
+ textAlign: "left",
56677
+ color: "#d4d4d4",
56678
+ marginBottom: "12px"
56679
+ },
56680
+ children: [
56681
+ /* @__PURE__ */ jsx("div", { children: "# Save execution artifacts to:" }),
56682
+ /* @__PURE__ */ jsx("div", { style: { marginTop: "4px" }, children: "__executions__/*.spans.json" }),
56683
+ /* @__PURE__ */ jsx("div", { children: "packages/*/__executions__/*.spans.json" })
56684
+ ]
56685
+ }
56686
+ ),
56687
+ /* @__PURE__ */ jsx("p", { style: { margin: 0, color: "#666", fontSize: "11px", fontStyle: "italic" }, children: "Tip: Use exportExecutionArtifact() in your tests" })
56688
+ ] })
56689
+ }
56690
+ ) }),
56546
56691
  state.canvas ? /* @__PURE__ */ jsx("div", { style: { flex: "0 0 60%", position: "relative" }, children: /* @__PURE__ */ jsx(
56547
56692
  distExports.GraphRenderer,
56548
56693
  {
56549
56694
  canvas: state.canvas,
56550
- showMinimap: true,
56695
+ showMinimap: false,
56551
56696
  showControls: true,
56552
56697
  showBackground: true,
56553
56698
  backgroundVariant: "lines",
@@ -56566,24 +56711,11 @@ const ExecutionViewerPanel = ({
56566
56711
  color: "#666"
56567
56712
  },
56568
56713
  children: /* @__PURE__ */ jsxs("div", { style: { textAlign: "center" }, children: [
56569
- /* @__PURE__ */ jsx("p", { children: "No matching canvas found" }),
56570
- /* @__PURE__ */ jsxs("p", { style: { fontSize: "12px", marginTop: "8px" }, children: [
56571
- "Expected: ",
56572
- selectedExecution == null ? void 0 : selectedExecution.canvasBasename,
56573
- ".otel.canvas"
56574
- ] })
56714
+ /* @__PURE__ */ jsx("p", { children: "Canvas not loaded" }),
56715
+ /* @__PURE__ */ jsx("p", { style: { fontSize: "12px", marginTop: "8px" }, children: (selectedCanvas == null ? void 0 : selectedCanvas.path) || "No canvas selected" })
56575
56716
  ] })
56576
56717
  }
56577
- ),
56578
- /* @__PURE__ */ jsx("div", { style: { flex: "0 0 40%", borderLeft: "1px solid #333", overflow: "hidden" }, children: /* @__PURE__ */ jsx(
56579
- distExports.TestEventPanel,
56580
- {
56581
- spans: state.execution ? ExecutionLoader.getSpans(state.execution) : [],
56582
- currentSpanIndex: state.currentSpanIndex,
56583
- currentEventIndex: state.currentEventIndex,
56584
- onSpanIndexChange: handleSpanIndexChange
56585
- }
56586
- ) })
56718
+ )
56587
56719
  ] }),
56588
56720
  state.metadata && /* @__PURE__ */ jsx(ExecutionStats, { metadata: state.metadata })
56589
56721
  ]