@principal-ai/subsystems-react 0.17.0 → 0.19.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.
Files changed (108) hide show
  1. package/README.md +11 -85
  2. package/dist/index.d.ts +7 -44
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +6 -32
  5. package/dist/index.js.map +1 -1
  6. package/dist/subsystem/SubsystemCarousel.d.ts +36 -0
  7. package/dist/subsystem/SubsystemCarousel.d.ts.map +1 -0
  8. package/dist/subsystem/SubsystemCarousel.js +163 -0
  9. package/dist/subsystem/SubsystemCarousel.js.map +1 -0
  10. package/dist/subsystem/SubsystemComponentGraph.d.ts +25 -0
  11. package/dist/subsystem/SubsystemComponentGraph.d.ts.map +1 -1
  12. package/dist/subsystem/SubsystemComponentGraph.js +329 -68
  13. package/dist/subsystem/SubsystemComponentGraph.js.map +1 -1
  14. package/package.json +4 -4
  15. package/src/index.ts +9 -199
  16. package/src/subsystem/SubsystemComponentGraph.tsx +396 -50
  17. package/src/components/ConfigurationSelector.tsx +0 -133
  18. package/src/components/GraphRenderer.tsx +0 -3195
  19. package/src/components/MultiCanvasRenderer.tsx +0 -295
  20. package/src/components/NodeTooltip.tsx +0 -279
  21. package/src/components/PendingChanges.test.tsx +0 -375
  22. package/src/components/SelectionSidebar.tsx +0 -352
  23. package/src/components/SequenceDiagramRenderer.tsx +0 -1156
  24. package/src/components/WorkflowSequenceDiagram.tsx +0 -270
  25. package/src/components/dashboard/DashboardRenderer.tsx +0 -317
  26. package/src/components/dashboard/MetricPanel.tsx +0 -254
  27. package/src/components/dashboard/MockDataProvider.ts +0 -330
  28. package/src/components/dashboard/components/BarChart.tsx +0 -299
  29. package/src/components/dashboard/components/LineChart.tsx +0 -279
  30. package/src/components/dashboard/components/MetricCard.tsx +0 -270
  31. package/src/components/dashboard/components/SourceLink.tsx +0 -63
  32. package/src/components/dashboard/components/TimeRangeSelector.tsx +0 -280
  33. package/src/components/dashboard/components/index.ts +0 -5
  34. package/src/components/dashboard/index.ts +0 -47
  35. package/src/components/dashboard/types.ts +0 -126
  36. package/src/components/state-view/PipelineView.tsx +0 -347
  37. package/src/components/state-view/index.ts +0 -14
  38. package/src/components/state-view/types.ts +0 -261
  39. package/src/components/state-view/useStateView.ts +0 -205
  40. package/src/contexts/GraphEditContext.tsx +0 -27
  41. package/src/contexts/TooltipPortalContext.ts +0 -8
  42. package/src/edges/CustomEdge.tsx +0 -402
  43. package/src/edges/GenericEdge.tsx +0 -36
  44. package/src/hooks/usePathBasedEvents.ts +0 -192
  45. package/src/hooks/useSequenceLayout.ts +0 -543
  46. package/src/hooks/useUndoRedo.ts +0 -144
  47. package/src/nodes/CustomNode.tsx +0 -1231
  48. package/src/nodes/GenericNode.tsx +0 -55
  49. package/src/nodes/otel/OtelBoundaryNode.tsx +0 -224
  50. package/src/nodes/otel/OtelEventNode.tsx +0 -225
  51. package/src/nodes/otel/OtelResourceNode.tsx +0 -251
  52. package/src/nodes/otel/OtelScopeNode.tsx +0 -221
  53. package/src/nodes/otel/OtelSpanConventionNode.tsx +0 -295
  54. package/src/nodes/otel/index.ts +0 -23
  55. package/src/nodes/otel/shared/NodeBadges.tsx +0 -295
  56. package/src/nodes/otel/shared/NodeContent.tsx +0 -204
  57. package/src/nodes/otel/shared/index.ts +0 -8
  58. package/src/nodes/otel/shared/types.ts +0 -138
  59. package/src/nodes/otel/shared/useNodeBehavior.ts +0 -114
  60. package/src/stories/Audit/BoundaryNodes.stories.tsx +0 -385
  61. package/src/stories/Audit/CanvasEdgeTypes.stories.tsx +0 -1448
  62. package/src/stories/Audit/CanvasNodeTypes.stories.tsx +0 -1049
  63. package/src/stories/Audit/ColorPriority.stories.tsx +0 -895
  64. package/src/stories/Audit/DiamondBadges.stories.tsx +0 -629
  65. package/src/stories/Audit/NodeDimensionsTesting.stories.tsx +0 -724
  66. package/src/stories/Audit/NodeFieldsAudit.stories.tsx +0 -996
  67. package/src/stories/Audit/NodeFontSizeTesting.stories.tsx +0 -715
  68. package/src/stories/Audit/NodeShapes.stories.tsx +0 -1208
  69. package/src/stories/Audit/WideNodesTesting.stories.tsx +0 -1045
  70. package/src/stories/Components/DashboardRenderer.stories.tsx +0 -263
  71. package/src/stories/Components/GraphRenderer.stories.tsx +0 -3236
  72. package/src/stories/Components/MultiCanvasRenderer.stories.tsx +0 -370
  73. package/src/stories/Components/SequenceDiagram.stories.tsx +0 -255
  74. package/src/stories/Components/StateView.stories.tsx +0 -417
  75. package/src/stories/Components/TraceViewer.stories.tsx +0 -442
  76. package/src/stories/Components/WorkflowSequenceDiagram.stories.tsx +0 -802
  77. package/src/stories/Features/AnimationWorkshop.stories.tsx +0 -727
  78. package/src/stories/Features/ChangeTypeVisual.stories.tsx +0 -67
  79. package/src/stories/Features/EventDrivenAnimations.stories.tsx +0 -513
  80. package/src/stories/Features/MultiConfig.stories.tsx +0 -539
  81. package/src/stories/Layout/ElkEdgeRouting.stories.tsx +0 -539
  82. package/src/stories/Layout/GraphOrientation.stories.tsx +0 -500
  83. package/src/stories/Layout/MultiDirectionalConnections.stories.tsx +0 -352
  84. package/src/stories/Nodes/NodeDefinitionComparison.stories.tsx +0 -560
  85. package/src/stories/Nodes/NodeNameFallbacks.stories.tsx +0 -491
  86. package/src/stories/Nodes/NumericColors.stories.tsx +0 -440
  87. package/src/stories/OTEL/EventNameDisplay.stories.tsx +0 -694
  88. package/src/stories/OTEL/EventNameFallback.stories.tsx +0 -578
  89. package/src/stories/OTEL/OtelComponents.stories.tsx +0 -422
  90. package/src/stories/OTEL/OtelNodeTypesPrototype.stories.tsx +0 -806
  91. package/src/stories/OTEL/RawEventCards.stories.tsx +0 -57
  92. package/src/stories/OTEL/SpanBadges.stories.tsx +0 -840
  93. package/src/stories/OTEL/ValidationEventsCanvas.stories.tsx +0 -209
  94. package/src/stories/RealWorld/BacklogMdCanvases.stories.tsx +0 -721
  95. package/src/stories/RealWorld/FileCitySequence.stories.tsx +0 -516
  96. package/src/stories/RealWorld/RealCanvasFiles.stories.tsx +0 -336
  97. package/src/stories/__traces__/test-run.canvas.json +0 -241
  98. package/src/stories/data/activity-feed-analytics.dashboard.json +0 -300
  99. package/src/stories/data/file-city-images-transformed.otel.canvas.json +0 -295
  100. package/src/stories/data/file-city-workflows.json +0 -269
  101. package/src/stories/data/graph-converter-test-execution.json +0 -443
  102. package/src/stories/data/graph-converter-test.workflow.json +0 -105
  103. package/src/stories/data/graph-converter-validated-execution.json +0 -58
  104. package/src/utils/animationMapping.ts +0 -166
  105. package/src/utils/canvasBounds.ts +0 -146
  106. package/src/utils/graphConverter.ts +0 -148
  107. package/src/utils/iconResolver.tsx +0 -53
  108. package/src/utils/orientationUtils.ts +0 -73
@@ -1,840 +0,0 @@
1
- import React, { useState } from 'react';
2
- import type { Meta, StoryObj } from '@storybook/react';
3
- import { GraphRenderer } from '../../components/GraphRenderer';
4
- import type { ExtendedCanvas, WorkflowChip } from '@principal-ai/subsystems-core';
5
- import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
6
-
7
- const meta = {
8
- title: 'OTEL/SpanBadges',
9
- component: GraphRenderer,
10
- parameters: {
11
- layout: 'centered',
12
- },
13
- tags: ['autodocs'],
14
- decorators: [
15
- (Story) => (
16
- <ThemeProvider theme={defaultEditorTheme}>
17
- <Story />
18
- </ThemeProvider>
19
- ),
20
- ],
21
- } satisfies Meta<typeof GraphRenderer>;
22
-
23
- export default meta;
24
- type Story = StoryObj<typeof meta>;
25
-
26
- /**
27
- * Canvas demonstrating all badge types on span convention nodes (hexagons)
28
- */
29
- const spanBadgesCanvas: ExtendedCanvas = {
30
- nodes: [
31
- // Status: Draft (gray D badge)
32
- {
33
- id: 'span-draft',
34
- type: 'text',
35
- x: 50,
36
- y: 50,
37
- width: 180,
38
- height: 100,
39
- text: 'Draft Span',
40
- color: 0, // gray
41
- pv: {
42
- nodeType: 'otel-span-convention',
43
- name: 'Draft Span',
44
- description: 'Status: draft - shows gray "D" badge at top-left',
45
- shape: 'hexagon',
46
- icon: 'GitCommit',
47
- status: 'draft',
48
- otel: {
49
- spanPattern: 'feature.design',
50
- spanKind: 'INTERNAL',
51
- },
52
- },
53
- },
54
- // Status: Approved (blue A badge)
55
- {
56
- id: 'span-approved',
57
- type: 'text',
58
- x: 280,
59
- y: 50,
60
- width: 180,
61
- height: 100,
62
- text: 'Approved Span',
63
- color: 5, // cyan
64
- pv: {
65
- nodeType: 'otel-span-convention',
66
- name: 'Approved Span',
67
- description: 'Status: approved - shows blue "A" badge at top-left',
68
- shape: 'hexagon',
69
- icon: 'GitCommit',
70
- status: 'approved',
71
- otel: {
72
- spanPattern: 'feature.approved',
73
- spanKind: 'INTERNAL',
74
- },
75
- },
76
- },
77
- // Status: Implemented (green I badge)
78
- {
79
- id: 'span-implemented',
80
- type: 'text',
81
- x: 510,
82
- y: 50,
83
- width: 180,
84
- height: 100,
85
- text: 'Implemented Span',
86
- color: 4, // green
87
- pv: {
88
- nodeType: 'otel-span-convention',
89
- name: 'Implemented Span',
90
- description: 'Status: implemented - shows green "I" badge at top-left',
91
- shape: 'hexagon',
92
- icon: 'GitCommit',
93
- status: 'implemented',
94
- otel: {
95
- spanPattern: 'feature.implemented',
96
- spanKind: 'INTERNAL',
97
- },
98
- },
99
- },
100
- // Implemented + Sources (I + S badges)
101
- {
102
- id: 'span-with-sources',
103
- type: 'text',
104
- x: 50,
105
- y: 200,
106
- width: 180,
107
- height: 100,
108
- text: 'With Sources',
109
- color: 4, // green
110
- pv: {
111
- nodeType: 'otel-span-convention',
112
- name: 'With Sources',
113
- description: 'Implemented with source files - shows "I" badge at top-left and green "S" badge at top-right. Hover to see file paths.',
114
- shape: 'hexagon',
115
- icon: 'FileCode',
116
- status: 'implemented',
117
- otel: {
118
- spanPattern: 'feature.process',
119
- spanKind: 'INTERNAL',
120
- files: ['src/features/process.ts', 'src/features/handler.ts'],
121
- },
122
- },
123
- },
124
- // Approved + References (A + R badges)
125
- {
126
- id: 'span-with-refs',
127
- type: 'text',
128
- x: 280,
129
- y: 200,
130
- width: 180,
131
- height: 100,
132
- text: 'With References',
133
- color: 6, // purple
134
- pv: {
135
- nodeType: 'otel-span-convention',
136
- name: 'With References',
137
- description: 'Approved with references - shows "A" badge at top-left and purple "R" badge at bottom-left. Hover to see reference URLs.',
138
- shape: 'hexagon',
139
- icon: 'ExternalLink',
140
- status: 'approved',
141
- references: ['https://opentelemetry.io/docs/specs/otel/trace/api/', '@opentelemetry/api'],
142
- otel: {
143
- spanPattern: 'http.client.request',
144
- spanKind: 'CLIENT',
145
- },
146
- },
147
- },
148
- // All badges: I + S + R
149
- {
150
- id: 'span-all-badges',
151
- type: 'text',
152
- x: 510,
153
- y: 200,
154
- width: 180,
155
- height: 100,
156
- text: 'All Badges',
157
- color: 2, // orange
158
- pv: {
159
- nodeType: 'otel-span-convention',
160
- name: 'All Badges',
161
- description: 'Implemented with sources and references - shows all three badges: "I" (top-left), "S" (top-right), "R" (bottom-left)',
162
- shape: 'hexagon',
163
- icon: 'Layers',
164
- status: 'implemented',
165
- references: ['https://docs.example.com/api'],
166
- otel: {
167
- spanPattern: 'api.handler',
168
- spanKind: 'SERVER',
169
- files: ['src/api/handler.ts'],
170
- },
171
- },
172
- },
173
- // Boundary: Outbound (arrow badge pointing up-right)
174
- {
175
- id: 'boundary-outbound',
176
- type: 'text',
177
- x: 50,
178
- y: 350,
179
- width: 180,
180
- height: 100,
181
- text: 'Outbound Boundary',
182
- color: 5, // cyan
183
- pv: {
184
- nodeType: 'otel-boundary',
185
- name: 'Outbound Boundary',
186
- description: 'Outbound boundary span - shows cyan arrow badge pointing up-right on the right edge, indicating calls TO external systems',
187
- shape: 'hexagon',
188
- icon: 'ArrowUpRight',
189
- status: 'implemented',
190
- boundary: {
191
- direction: 'outbound',
192
- node: { 'pv.event.name': 'external.api.response' },
193
- },
194
- otel: {
195
- spanPattern: 'http.client.request',
196
- spanKind: 'CLIENT',
197
- },
198
- },
199
- },
200
- // Boundary: Inbound (arrow badge pointing down-left)
201
- {
202
- id: 'boundary-inbound',
203
- type: 'text',
204
- x: 280,
205
- y: 350,
206
- width: 180,
207
- height: 100,
208
- text: 'Inbound Boundary',
209
- color: 5, // cyan
210
- pv: {
211
- nodeType: 'otel-boundary',
212
- name: 'Inbound Boundary',
213
- description: 'Inbound boundary span - shows cyan arrow badge pointing down-left on the left edge, indicating calls FROM external systems',
214
- shape: 'hexagon',
215
- icon: 'ArrowDownLeft',
216
- status: 'approved',
217
- boundary: {
218
- direction: 'inbound',
219
- node: { 'pv.event.name': 'webhook.payload' },
220
- },
221
- otel: {
222
- spanPattern: 'http.server.request',
223
- spanKind: 'SERVER',
224
- },
225
- },
226
- },
227
- // Draft with references only (D + R)
228
- {
229
- id: 'span-draft-with-refs',
230
- type: 'text',
231
- x: 510,
232
- y: 350,
233
- width: 180,
234
- height: 100,
235
- text: 'Draft + Refs',
236
- color: 0, // gray
237
- pv: {
238
- nodeType: 'otel-span-convention',
239
- name: 'Draft + Refs',
240
- description: 'Draft span with references - shows "D" badge and "R" badge but no "S" badge since not yet implemented',
241
- shape: 'hexagon',
242
- icon: 'BookOpen',
243
- status: 'draft',
244
- references: ['https://opentelemetry.io/docs/specs/semconv/database/'],
245
- otel: {
246
- spanPattern: 'db.query',
247
- spanKind: 'CLIENT',
248
- },
249
- },
250
- },
251
- ],
252
- edges: [],
253
- pv: {
254
- version: '1.0.0',
255
- name: 'Span Badges Demo',
256
- description: 'Demonstrates badge types on span convention nodes',
257
- edgeTypes: {},
258
- },
259
- };
260
-
261
- export const AllBadgeTypes: Story = {
262
- args: {
263
- canvas: spanBadgesCanvas,
264
- width: 750,
265
- height: 520,
266
- },
267
- parameters: {
268
- docs: {
269
- description: {
270
- story: `
271
- **Span Badges Overview**
272
-
273
- Badges provide at-a-glance status information on span convention nodes:
274
-
275
- | Position | Badge | Color | Meaning |
276
- |----------|-------|-------|---------|
277
- | Top-Left | **D** | Gray | Draft - being designed |
278
- | Top-Left | **A** | Blue | Approved - ready to implement |
279
- | Top-Left | **I** | Green | Implemented - code exists |
280
- | Top-Right | **S** | Green | Has source files linked |
281
- | Bottom-Left | **R** | Purple | Has external references |
282
- | Right Edge | **↗** | Cyan | Outbound boundary |
283
- | Left Edge | **↙** | Cyan | Inbound boundary |
284
-
285
- **Row 1**: Status badges only (D, A, I)
286
- **Row 2**: Status + metadata badges (I+S, A+R, I+S+R)
287
- **Row 3**: Boundary badges and combinations
288
- `,
289
- },
290
- },
291
- },
292
- };
293
-
294
- /**
295
- * Canvas showing implementation lifecycle progression
296
- */
297
- const lifecycleCanvas: ExtendedCanvas = {
298
- nodes: [
299
- {
300
- id: 'lifecycle-draft',
301
- type: 'text',
302
- x: 50,
303
- y: 100,
304
- width: 160,
305
- height: 90,
306
- text: 'Planning',
307
- color: 0,
308
- pv: {
309
- nodeType: 'otel-span-convention',
310
- name: 'Planning',
311
- description: 'Step 1: Span is being designed',
312
- shape: 'hexagon',
313
- icon: 'PenTool',
314
- status: 'draft',
315
- otel: {
316
- spanPattern: 'user.action',
317
- spanKind: 'INTERNAL',
318
- },
319
- },
320
- },
321
- {
322
- id: 'lifecycle-approved',
323
- type: 'text',
324
- x: 260,
325
- y: 100,
326
- width: 160,
327
- height: 90,
328
- text: 'Approved',
329
- color: 5,
330
- pv: {
331
- nodeType: 'otel-span-convention',
332
- name: 'Approved',
333
- description: 'Step 2: Design reviewed and approved',
334
- shape: 'hexagon',
335
- icon: 'CheckCircle',
336
- status: 'approved',
337
- references: ['https://otel.spec/trace'],
338
- otel: {
339
- spanPattern: 'user.action',
340
- spanKind: 'INTERNAL',
341
- },
342
- },
343
- },
344
- {
345
- id: 'lifecycle-implemented',
346
- type: 'text',
347
- x: 470,
348
- y: 100,
349
- width: 160,
350
- height: 90,
351
- text: 'Implemented',
352
- color: 4,
353
- pv: {
354
- nodeType: 'otel-span-convention',
355
- name: 'Implemented',
356
- description: 'Step 3: Code written and linked',
357
- shape: 'hexagon',
358
- icon: 'Code',
359
- status: 'implemented',
360
- references: ['https://otel.spec/trace'],
361
- otel: {
362
- spanPattern: 'user.action',
363
- spanKind: 'INTERNAL',
364
- files: ['src/handlers/user.ts'],
365
- },
366
- },
367
- },
368
- ],
369
- edges: [
370
- {
371
- id: 'e1',
372
- fromNode: 'lifecycle-draft',
373
- toNode: 'lifecycle-approved',
374
- fromSide: 'right',
375
- toSide: 'left',
376
- label: 'review',
377
- },
378
- {
379
- id: 'e2',
380
- fromNode: 'lifecycle-approved',
381
- toNode: 'lifecycle-implemented',
382
- fromSide: 'right',
383
- toSide: 'left',
384
- label: 'implement',
385
- },
386
- ],
387
- pv: {
388
- version: '1.0.0',
389
- name: 'Implementation Lifecycle',
390
- description: 'Shows badge progression through implementation phases',
391
- edgeTypes: {
392
- default: {
393
- style: 'solid',
394
- color: '#888',
395
- directed: true,
396
- },
397
- },
398
- },
399
- };
400
-
401
- export const ImplementationLifecycle: Story = {
402
- args: {
403
- canvas: lifecycleCanvas,
404
- width: 700,
405
- height: 280,
406
- },
407
- parameters: {
408
- docs: {
409
- description: {
410
- story: `
411
- **Implementation Lifecycle**
412
-
413
- Shows how badges evolve as a span moves through the implementation process:
414
-
415
- 1. **Planning** (D badge) - Span convention is being designed
416
- 2. **Approved** (A + R badges) - Design reviewed, references added
417
- 3. **Implemented** (I + S + R badges) - Code written, source files linked
418
-
419
- The badges provide immediate visual feedback on implementation progress.
420
- `,
421
- },
422
- },
423
- },
424
- };
425
-
426
- /**
427
- * Canvas showing boundary spans in a system context
428
- */
429
- const boundaryCanvas: ExtendedCanvas = {
430
- nodes: [
431
- {
432
- id: 'internal-service',
433
- type: 'text',
434
- x: 250,
435
- y: 120,
436
- width: 180,
437
- height: 90,
438
- text: 'Internal Service',
439
- color: 4,
440
- pv: {
441
- nodeType: 'otel-span-convention',
442
- name: 'Internal Service',
443
- description: 'Internal service span - no boundary badges',
444
- shape: 'hexagon',
445
- icon: 'Server',
446
- status: 'implemented',
447
- otel: {
448
- spanPattern: 'service.process',
449
- spanKind: 'INTERNAL',
450
- files: ['src/service.ts'],
451
- },
452
- },
453
- },
454
- {
455
- id: 'outbound-api',
456
- type: 'text',
457
- x: 500,
458
- y: 50,
459
- width: 180,
460
- height: 90,
461
- text: 'External API',
462
- color: 5,
463
- pv: {
464
- nodeType: 'otel-boundary',
465
- name: 'External API',
466
- description: 'Outbound call to external API',
467
- shape: 'hexagon',
468
- icon: 'Cloud',
469
- status: 'implemented',
470
- boundary: {
471
- direction: 'outbound',
472
- node: { 'pv.event.name': 'api.response' },
473
- },
474
- otel: {
475
- spanPattern: 'http.client',
476
- spanKind: 'CLIENT',
477
- files: ['src/api/client.ts'],
478
- },
479
- },
480
- },
481
- {
482
- id: 'outbound-db',
483
- type: 'text',
484
- x: 500,
485
- y: 190,
486
- width: 180,
487
- height: 90,
488
- text: 'Database',
489
- color: 5,
490
- pv: {
491
- nodeType: 'otel-boundary',
492
- name: 'Database',
493
- description: 'Outbound call to database',
494
- shape: 'hexagon',
495
- icon: 'Database',
496
- status: 'implemented',
497
- boundary: {
498
- direction: 'outbound',
499
- node: { 'pv.event.name': 'db.result' },
500
- },
501
- otel: {
502
- spanPattern: 'db.query',
503
- spanKind: 'CLIENT',
504
- files: ['src/db/client.ts'],
505
- },
506
- },
507
- },
508
- {
509
- id: 'inbound-webhook',
510
- type: 'text',
511
- x: 0,
512
- y: 120,
513
- width: 180,
514
- height: 90,
515
- text: 'Webhook Handler',
516
- color: 5,
517
- pv: {
518
- nodeType: 'otel-boundary',
519
- name: 'Webhook Handler',
520
- description: 'Inbound webhook from external system',
521
- shape: 'hexagon',
522
- icon: 'Webhook',
523
- status: 'approved',
524
- boundary: {
525
- direction: 'inbound',
526
- node: { 'pv.event.name': 'webhook.received' },
527
- },
528
- otel: {
529
- spanPattern: 'http.server',
530
- spanKind: 'SERVER',
531
- },
532
- },
533
- },
534
- ],
535
- edges: [
536
- {
537
- id: 'e1',
538
- fromNode: 'inbound-webhook',
539
- toNode: 'internal-service',
540
- fromSide: 'right',
541
- toSide: 'left',
542
- },
543
- {
544
- id: 'e2',
545
- fromNode: 'internal-service',
546
- toNode: 'outbound-api',
547
- fromSide: 'right',
548
- toSide: 'left',
549
- },
550
- {
551
- id: 'e3',
552
- fromNode: 'internal-service',
553
- toNode: 'outbound-db',
554
- fromSide: 'right',
555
- toSide: 'left',
556
- },
557
- ],
558
- pv: {
559
- version: '1.0.0',
560
- name: 'Boundary Spans',
561
- description: 'Shows boundary badges for system edge spans',
562
- edgeTypes: {
563
- default: {
564
- style: 'dashed',
565
- color: '#06b6d4',
566
- directed: true,
567
- },
568
- },
569
- },
570
- };
571
-
572
- export const BoundarySpans: Story = {
573
- args: {
574
- canvas: boundaryCanvas,
575
- width: 750,
576
- height: 350,
577
- },
578
- parameters: {
579
- docs: {
580
- description: {
581
- story: `
582
- **Boundary Span Badges**
583
-
584
- Boundary spans mark where your system interacts with external systems:
585
-
586
- - **↗ Outbound** (right edge): Calls TO external systems (APIs, databases)
587
- - **↙ Inbound** (left edge): Calls FROM external systems (webhooks, events)
588
-
589
- Boundary badges **replace** the source badge position since the direction indicator is more important for understanding system topology.
590
-
591
- Use boundary spans to identify integration points that need:
592
- - Contract tests
593
- - Timeout handling
594
- - Circuit breakers
595
- - Error recovery strategies
596
- `,
597
- },
598
- },
599
- },
600
- };
601
-
602
- /**
603
- * Canvas demonstrating workflow chips - showing which workflow.json scenarios
604
- * reference each span convention
605
- */
606
- const workflowChipsCanvas = {
607
- nodes: [
608
- // Span with multiple workflow associations
609
- {
610
- id: 'user-login',
611
- type: 'otel-span-convention' as const,
612
- x: 50,
613
- y: 50,
614
- width: 200,
615
- height: 120,
616
- color: '#8b5cf6',
617
- label: 'User Login',
618
- otel: {
619
- status: 'implemented' as const,
620
- spanPattern: 'auth.login',
621
- spanKind: 'SERVER' as const,
622
- files: ['src/auth/login.ts'],
623
- },
624
- workflowChips: [
625
- { id: 'happy-path', label: 'Happy Path', color: '#22c55e' },
626
- { id: 'error-handling', label: 'Error Handling', color: '#ef4444' },
627
- { id: 'rate-limiting', label: 'Rate Limiting', color: '#f97316' },
628
- ],
629
- },
630
- // Span with single workflow
631
- {
632
- id: 'token-validate',
633
- type: 'otel-span-convention' as const,
634
- x: 300,
635
- y: 50,
636
- width: 200,
637
- height: 120,
638
- color: '#3b82f6',
639
- label: 'Token Validation',
640
- otel: {
641
- status: 'implemented' as const,
642
- spanPattern: 'auth.token.validate',
643
- spanKind: 'INTERNAL' as const,
644
- files: ['src/auth/token.ts'],
645
- },
646
- workflowChips: [
647
- { id: 'happy-path', label: 'Happy Path', color: '#22c55e' },
648
- ],
649
- },
650
- // Span with many workflows (shows +N more)
651
- {
652
- id: 'api-request',
653
- type: 'otel-span-convention' as const,
654
- x: 550,
655
- y: 50,
656
- width: 200,
657
- height: 120,
658
- color: '#06b6d4',
659
- label: 'API Request',
660
- otel: {
661
- status: 'implemented' as const,
662
- spanPattern: 'http.server.request',
663
- spanKind: 'SERVER' as const,
664
- files: ['src/api/handler.ts'],
665
- },
666
- workflowChips: [
667
- { id: 'crud-create', label: 'Create', color: '#22c55e' },
668
- { id: 'crud-read', label: 'Read', color: '#3b82f6' },
669
- { id: 'crud-update', label: 'Update', color: '#f97316' },
670
- { id: 'crud-delete', label: 'Delete', color: '#ef4444' },
671
- { id: 'batch-ops', label: 'Batch Operations', color: '#8b5cf6' },
672
- ],
673
- },
674
- // Span with no workflow associations
675
- {
676
- id: 'db-query',
677
- type: 'otel-span-convention' as const,
678
- x: 50,
679
- y: 220,
680
- width: 200,
681
- height: 100,
682
- color: '#6b7280',
683
- label: 'Database Query',
684
- otel: {
685
- status: 'draft' as const,
686
- spanPattern: 'db.query',
687
- spanKind: 'CLIENT' as const,
688
- },
689
- // No workflowChips - this span isn't referenced by any workflow yet
690
- },
691
- // Span with default colored chips (no color specified)
692
- {
693
- id: 'cache-lookup',
694
- type: 'otel-span-convention' as const,
695
- x: 300,
696
- y: 220,
697
- width: 200,
698
- height: 100,
699
- color: '#10b981',
700
- label: 'Cache Lookup',
701
- otel: {
702
- status: 'implemented' as const,
703
- spanPattern: 'cache.get',
704
- spanKind: 'INTERNAL' as const,
705
- files: ['src/cache/client.ts'],
706
- },
707
- workflowChips: [
708
- { id: 'perf-test', label: 'Perf Testing' },
709
- { id: 'cache-miss', label: 'Cache Miss' },
710
- ],
711
- },
712
- ],
713
- edges: [
714
- {
715
- id: 'e1',
716
- fromNode: 'user-login',
717
- toNode: 'token-validate',
718
- fromSide: 'right',
719
- toSide: 'left',
720
- },
721
- {
722
- id: 'e2',
723
- fromNode: 'token-validate',
724
- toNode: 'api-request',
725
- fromSide: 'right',
726
- toSide: 'left',
727
- },
728
- {
729
- id: 'e3',
730
- fromNode: 'api-request',
731
- toNode: 'db-query',
732
- fromSide: 'bottom',
733
- toSide: 'right',
734
- },
735
- {
736
- id: 'e4',
737
- fromNode: 'api-request',
738
- toNode: 'cache-lookup',
739
- fromSide: 'bottom',
740
- toSide: 'top',
741
- },
742
- ],
743
- pv: {
744
- version: '1.0.0',
745
- name: 'Workflow Chips Demo',
746
- description: 'Demonstrates workflow.json associations on span convention nodes',
747
- edgeTypes: {
748
- default: {
749
- style: 'solid',
750
- color: '#888',
751
- directed: true,
752
- },
753
- },
754
- },
755
- };
756
-
757
- /**
758
- * Interactive story showing workflow chip selection
759
- */
760
- const WorkflowChipsInteractive = () => {
761
- const [selectedWorkflow, setSelectedWorkflow] = useState<string | null>(null);
762
-
763
- // Create canvas with click handlers and selection state
764
- const canvasWithHandlers: ExtendedCanvas = {
765
- ...workflowChipsCanvas,
766
- nodes: workflowChipsCanvas.nodes.map((node) => ({
767
- ...node,
768
- onWorkflowChipClick: (chipId: string) => {
769
- setSelectedWorkflow(selectedWorkflow === chipId ? null : chipId);
770
- },
771
- selectedWorkflowId: selectedWorkflow,
772
- })),
773
- };
774
-
775
- return (
776
- <div>
777
- <div style={{ marginBottom: '12px', padding: '8px', backgroundColor: '#f3f4f6', borderRadius: '6px' }}>
778
- <strong>Selected workflow:</strong>{' '}
779
- {selectedWorkflow ? (
780
- <span style={{ color: '#3b82f6' }}>{selectedWorkflow}</span>
781
- ) : (
782
- <span style={{ color: '#9ca3af' }}>Click a chip to select</span>
783
- )}
784
- </div>
785
- <GraphRenderer
786
- canvas={canvasWithHandlers}
787
- width={800}
788
- height={400}
789
- />
790
- </div>
791
- );
792
- };
793
-
794
- export const WorkflowChips: Story = {
795
- args: {
796
- canvas: workflowChipsCanvas as unknown as ExtendedCanvas,
797
- width: 800,
798
- height: 400,
799
- },
800
- parameters: {
801
- docs: {
802
- description: {
803
- story: `
804
- **Workflow Chips - Associating Spans with Scenarios**
805
-
806
- Workflow chips show which \`workflow.json\` scenarios reference each span convention.
807
- This creates a visual link between your span architecture (\`.spans.canvas\`) and
808
- your workflow scenarios (\`.workflow.json\`).
809
-
810
- **Features:**
811
- - Colored chips indicate different workflow scenarios
812
- - Max 3 chips shown, with "+N more" for additional workflows
813
- - Chips can be clicked to filter/highlight related spans
814
- - Spans with no workflows appear without chips
815
-
816
- **Use cases:**
817
- - See at-a-glance which spans are covered by scenarios
818
- - Identify orphan spans not covered by any workflow
819
- - Navigate between span definitions and their usage
820
- `,
821
- },
822
- },
823
- },
824
- };
825
-
826
- export const WorkflowChipsInteractiveStory: StoryObj = {
827
- render: () => <WorkflowChipsInteractive />,
828
- parameters: {
829
- docs: {
830
- description: {
831
- story: `
832
- **Interactive Workflow Selection**
833
-
834
- Click on workflow chips to select them. This demonstrates the selection state
835
- that can be used to filter or highlight spans belonging to a specific workflow.
836
- `,
837
- },
838
- },
839
- },
840
- };