@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.
- package/README.md +11 -85
- package/dist/index.d.ts +7 -44
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -32
- package/dist/index.js.map +1 -1
- package/dist/subsystem/SubsystemCarousel.d.ts +36 -0
- package/dist/subsystem/SubsystemCarousel.d.ts.map +1 -0
- package/dist/subsystem/SubsystemCarousel.js +163 -0
- package/dist/subsystem/SubsystemCarousel.js.map +1 -0
- package/dist/subsystem/SubsystemComponentGraph.d.ts +25 -0
- package/dist/subsystem/SubsystemComponentGraph.d.ts.map +1 -1
- package/dist/subsystem/SubsystemComponentGraph.js +329 -68
- package/dist/subsystem/SubsystemComponentGraph.js.map +1 -1
- package/package.json +4 -4
- package/src/index.ts +9 -199
- package/src/subsystem/SubsystemComponentGraph.tsx +396 -50
- package/src/components/ConfigurationSelector.tsx +0 -133
- package/src/components/GraphRenderer.tsx +0 -3195
- package/src/components/MultiCanvasRenderer.tsx +0 -295
- package/src/components/NodeTooltip.tsx +0 -279
- package/src/components/PendingChanges.test.tsx +0 -375
- package/src/components/SelectionSidebar.tsx +0 -352
- package/src/components/SequenceDiagramRenderer.tsx +0 -1156
- package/src/components/WorkflowSequenceDiagram.tsx +0 -270
- package/src/components/dashboard/DashboardRenderer.tsx +0 -317
- package/src/components/dashboard/MetricPanel.tsx +0 -254
- package/src/components/dashboard/MockDataProvider.ts +0 -330
- package/src/components/dashboard/components/BarChart.tsx +0 -299
- package/src/components/dashboard/components/LineChart.tsx +0 -279
- package/src/components/dashboard/components/MetricCard.tsx +0 -270
- package/src/components/dashboard/components/SourceLink.tsx +0 -63
- package/src/components/dashboard/components/TimeRangeSelector.tsx +0 -280
- package/src/components/dashboard/components/index.ts +0 -5
- package/src/components/dashboard/index.ts +0 -47
- package/src/components/dashboard/types.ts +0 -126
- package/src/components/state-view/PipelineView.tsx +0 -347
- package/src/components/state-view/index.ts +0 -14
- package/src/components/state-view/types.ts +0 -261
- package/src/components/state-view/useStateView.ts +0 -205
- package/src/contexts/GraphEditContext.tsx +0 -27
- package/src/contexts/TooltipPortalContext.ts +0 -8
- package/src/edges/CustomEdge.tsx +0 -402
- package/src/edges/GenericEdge.tsx +0 -36
- package/src/hooks/usePathBasedEvents.ts +0 -192
- package/src/hooks/useSequenceLayout.ts +0 -543
- package/src/hooks/useUndoRedo.ts +0 -144
- package/src/nodes/CustomNode.tsx +0 -1231
- package/src/nodes/GenericNode.tsx +0 -55
- package/src/nodes/otel/OtelBoundaryNode.tsx +0 -224
- package/src/nodes/otel/OtelEventNode.tsx +0 -225
- package/src/nodes/otel/OtelResourceNode.tsx +0 -251
- package/src/nodes/otel/OtelScopeNode.tsx +0 -221
- package/src/nodes/otel/OtelSpanConventionNode.tsx +0 -295
- package/src/nodes/otel/index.ts +0 -23
- package/src/nodes/otel/shared/NodeBadges.tsx +0 -295
- package/src/nodes/otel/shared/NodeContent.tsx +0 -204
- package/src/nodes/otel/shared/index.ts +0 -8
- package/src/nodes/otel/shared/types.ts +0 -138
- package/src/nodes/otel/shared/useNodeBehavior.ts +0 -114
- package/src/stories/Audit/BoundaryNodes.stories.tsx +0 -385
- package/src/stories/Audit/CanvasEdgeTypes.stories.tsx +0 -1448
- package/src/stories/Audit/CanvasNodeTypes.stories.tsx +0 -1049
- package/src/stories/Audit/ColorPriority.stories.tsx +0 -895
- package/src/stories/Audit/DiamondBadges.stories.tsx +0 -629
- package/src/stories/Audit/NodeDimensionsTesting.stories.tsx +0 -724
- package/src/stories/Audit/NodeFieldsAudit.stories.tsx +0 -996
- package/src/stories/Audit/NodeFontSizeTesting.stories.tsx +0 -715
- package/src/stories/Audit/NodeShapes.stories.tsx +0 -1208
- package/src/stories/Audit/WideNodesTesting.stories.tsx +0 -1045
- package/src/stories/Components/DashboardRenderer.stories.tsx +0 -263
- package/src/stories/Components/GraphRenderer.stories.tsx +0 -3236
- package/src/stories/Components/MultiCanvasRenderer.stories.tsx +0 -370
- package/src/stories/Components/SequenceDiagram.stories.tsx +0 -255
- package/src/stories/Components/StateView.stories.tsx +0 -417
- package/src/stories/Components/TraceViewer.stories.tsx +0 -442
- package/src/stories/Components/WorkflowSequenceDiagram.stories.tsx +0 -802
- package/src/stories/Features/AnimationWorkshop.stories.tsx +0 -727
- package/src/stories/Features/ChangeTypeVisual.stories.tsx +0 -67
- package/src/stories/Features/EventDrivenAnimations.stories.tsx +0 -513
- package/src/stories/Features/MultiConfig.stories.tsx +0 -539
- package/src/stories/Layout/ElkEdgeRouting.stories.tsx +0 -539
- package/src/stories/Layout/GraphOrientation.stories.tsx +0 -500
- package/src/stories/Layout/MultiDirectionalConnections.stories.tsx +0 -352
- package/src/stories/Nodes/NodeDefinitionComparison.stories.tsx +0 -560
- package/src/stories/Nodes/NodeNameFallbacks.stories.tsx +0 -491
- package/src/stories/Nodes/NumericColors.stories.tsx +0 -440
- package/src/stories/OTEL/EventNameDisplay.stories.tsx +0 -694
- package/src/stories/OTEL/EventNameFallback.stories.tsx +0 -578
- package/src/stories/OTEL/OtelComponents.stories.tsx +0 -422
- package/src/stories/OTEL/OtelNodeTypesPrototype.stories.tsx +0 -806
- package/src/stories/OTEL/RawEventCards.stories.tsx +0 -57
- package/src/stories/OTEL/SpanBadges.stories.tsx +0 -840
- package/src/stories/OTEL/ValidationEventsCanvas.stories.tsx +0 -209
- package/src/stories/RealWorld/BacklogMdCanvases.stories.tsx +0 -721
- package/src/stories/RealWorld/FileCitySequence.stories.tsx +0 -516
- package/src/stories/RealWorld/RealCanvasFiles.stories.tsx +0 -336
- package/src/stories/__traces__/test-run.canvas.json +0 -241
- package/src/stories/data/activity-feed-analytics.dashboard.json +0 -300
- package/src/stories/data/file-city-images-transformed.otel.canvas.json +0 -295
- package/src/stories/data/file-city-workflows.json +0 -269
- package/src/stories/data/graph-converter-test-execution.json +0 -443
- package/src/stories/data/graph-converter-test.workflow.json +0 -105
- package/src/stories/data/graph-converter-validated-execution.json +0 -58
- package/src/utils/animationMapping.ts +0 -166
- package/src/utils/canvasBounds.ts +0 -146
- package/src/utils/graphConverter.ts +0 -148
- package/src/utils/iconResolver.tsx +0 -53
- 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
|
-
};
|