@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,491 +0,0 @@
1
- import React from 'react';
2
- import type { Meta, StoryObj } from '@storybook/react';
3
- import { GraphRenderer } from '../../components/GraphRenderer';
4
- import type { ExtendedCanvas, ExtendedCanvasNode } from '@principal-ai/subsystems-core';
5
- import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
6
-
7
- const meta = {
8
- title: 'Nodes/NodeNameFallbacks',
9
- component: GraphRenderer,
10
- parameters: {
11
- layout: 'fullscreen',
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
- * Component to show node definition and explain the fallback
28
- */
29
- const FallbackExample: React.FC<{
30
- title: string;
31
- scenario: string;
32
- nodeDefinition: ExtendedCanvasNode;
33
- expectedDisplay: string;
34
- explanation: string;
35
- }> = ({ title, scenario, nodeDefinition, expectedDisplay, explanation }) => {
36
- const theme = defaultEditorTheme;
37
-
38
- const canvas: ExtendedCanvas = {
39
- nodes: [nodeDefinition],
40
- edges: [],
41
- };
42
-
43
- return (
44
- <div style={{
45
- marginBottom: '32px',
46
- padding: '24px',
47
- backgroundColor: theme.colors.surface,
48
- border: `1px solid ${theme.colors.border}`,
49
- borderRadius: '8px',
50
- }}>
51
- <h3 style={{
52
- marginBottom: '8px',
53
- fontSize: theme.fontSizes[3],
54
- fontWeight: theme.fontWeights.semibold,
55
- color: theme.colors.text,
56
- }}>
57
- {title}
58
- </h3>
59
- <p style={{
60
- marginBottom: '16px',
61
- fontSize: theme.fontSizes[1],
62
- color: theme.colors.textSecondary,
63
- fontStyle: 'italic',
64
- }}>
65
- {scenario}
66
- </p>
67
-
68
- <div style={{
69
- display: 'grid',
70
- gridTemplateColumns: '1fr 300px 1fr',
71
- gap: '24px',
72
- alignItems: 'start',
73
- }}>
74
- {/* Left: JSON */}
75
- <div>
76
- <div style={{
77
- marginBottom: '8px',
78
- fontSize: theme.fontSizes[1],
79
- fontWeight: theme.fontWeights.semibold,
80
- color: theme.colors.textSecondary,
81
- }}>
82
- Node Definition
83
- </div>
84
- <pre style={{
85
- backgroundColor: theme.colors.background,
86
- border: `1px solid ${theme.colors.border}`,
87
- borderRadius: '6px',
88
- padding: '12px',
89
- fontSize: theme.fontSizes[0],
90
- fontFamily: theme.fonts.monospace,
91
- color: theme.colors.text,
92
- overflow: 'auto',
93
- lineHeight: 1.5,
94
- }}>
95
- {JSON.stringify(nodeDefinition, null, 2)}
96
- </pre>
97
- </div>
98
-
99
- {/* Middle: Explanation */}
100
- <div>
101
- <div style={{
102
- marginBottom: '8px',
103
- fontSize: theme.fontSizes[1],
104
- fontWeight: theme.fontWeights.semibold,
105
- color: theme.colors.textSecondary,
106
- }}>
107
- Fallback Logic
108
- </div>
109
- <div style={{
110
- backgroundColor: theme.colors.backgroundSecondary,
111
- border: `1px solid ${theme.colors.border}`,
112
- borderRadius: '6px',
113
- padding: '12px',
114
- fontSize: theme.fontSizes[0],
115
- color: theme.colors.textMuted,
116
- lineHeight: 1.6,
117
- }}>
118
- {explanation}
119
- </div>
120
- <div style={{
121
- marginTop: '12px',
122
- padding: '12px',
123
- backgroundColor: theme.colors.backgroundTertiary,
124
- border: `2px solid ${theme.colors.primary}`,
125
- borderRadius: '6px',
126
- }}>
127
- <div style={{
128
- fontSize: theme.fontSizes[0],
129
- fontWeight: theme.fontWeights.bold,
130
- color: theme.colors.primary,
131
- marginBottom: '4px',
132
- }}>
133
- Expected Display:
134
- </div>
135
- <div style={{
136
- fontSize: theme.fontSizes[2],
137
- fontFamily: theme.fonts.monospace,
138
- color: theme.colors.text,
139
- }}>
140
- "{expectedDisplay}"
141
- </div>
142
- </div>
143
- </div>
144
-
145
- {/* Right: Rendered */}
146
- <div>
147
- <div style={{
148
- marginBottom: '8px',
149
- fontSize: theme.fontSizes[1],
150
- fontWeight: theme.fontWeights.semibold,
151
- color: theme.colors.textSecondary,
152
- }}>
153
- Rendered Node
154
- </div>
155
- <div style={{
156
- backgroundColor: theme.colors.background,
157
- border: `2px solid ${theme.colors.border}`,
158
- borderRadius: '6px',
159
- padding: '24px',
160
- height: '200px',
161
- display: 'flex',
162
- alignItems: 'center',
163
- justifyContent: 'center',
164
- }}>
165
- <GraphRenderer
166
- canvas={canvas}
167
- height={200}
168
- width="100%"
169
- />
170
- </div>
171
- </div>
172
- </div>
173
- </div>
174
- );
175
- };
176
-
177
- /**
178
- * Shows all name fallback scenarios
179
- */
180
- export const AllFallbackScenarios: Story = {
181
- render: () => {
182
- const theme = defaultEditorTheme;
183
-
184
- return (
185
- <div style={{ padding: '32px', fontFamily: theme.fonts.body }}>
186
- <h1 style={{
187
- marginBottom: '16px',
188
- fontFamily: theme.fonts.heading,
189
- fontSize: theme.fontSizes[7],
190
- color: theme.colors.text,
191
- }}>
192
- Node Name Fallback Chain
193
- </h1>
194
- <p style={{
195
- marginBottom: '32px',
196
- fontSize: theme.fontSizes[2],
197
- color: theme.colors.textSecondary,
198
- maxWidth: '900px',
199
- }}>
200
- This demonstrates the priority order for determining what text displays on a node.
201
- The system uses a fallback chain: <strong>pv.name → text (first line) → "Text" → node.id</strong>
202
- </p>
203
-
204
- <FallbackExample
205
- title="Scenario 1: Both pv.name and text present"
206
- scenario="pv.name takes priority"
207
- nodeDefinition={{
208
- id: "both-present",
209
- type: "text",
210
- text: "This Text is Ignored",
211
- x: 100,
212
- y: 50,
213
- width: 180,
214
- height: 100,
215
- color: "#4CAF50",
216
- pv: {
217
- name: "Custom Name Wins",
218
- shape: "roundedRect",
219
- icon: "CheckCircle2"
220
- }
221
- }}
222
- expectedDisplay="Custom Name Wins"
223
- explanation="When both pv.name and text exist, pv.name takes priority. The text field is ignored for display purposes."
224
- />
225
-
226
- <FallbackExample
227
- title="Scenario 2: Only pv.name present"
228
- scenario="pv.name is used"
229
- nodeDefinition={{
230
- id: "only-pv-name",
231
- type: "text",
232
- x: 100,
233
- y: 50,
234
- width: 180,
235
- height: 100,
236
- color: "#2196F3",
237
- pv: {
238
- name: "Only PV Name",
239
- shape: "roundedRect",
240
- icon: "Tag"
241
- }
242
- }}
243
- expectedDisplay="Only PV Name"
244
- explanation="When only pv.name exists (text is undefined), pv.name is used directly for display."
245
- />
246
-
247
- <FallbackExample
248
- title="Scenario 3: Only text present (single line)"
249
- scenario="First line of text is used"
250
- nodeDefinition={{
251
- id: "only-text",
252
- type: "text",
253
- text: "Text Field Name",
254
- x: 100,
255
- y: 50,
256
- width: 180,
257
- height: 100,
258
- color: "#FF9800",
259
- pv: {
260
- shape: "roundedRect",
261
- icon: "FileText"
262
- }
263
- }}
264
- expectedDisplay="Text Field Name"
265
- explanation="When pv.name is missing but text exists, the first line of text is used as the name."
266
- />
267
-
268
- <FallbackExample
269
- title="Scenario 4: Only text present (multi-line markdown)"
270
- scenario="First line extracted, markdown stripped"
271
- nodeDefinition={{
272
- id: "multiline-text",
273
- type: "text",
274
- text: "# Main Title\n\nThis description is ignored for the name",
275
- x: 100,
276
- y: 50,
277
- width: 180,
278
- height: 100,
279
- color: "#9C27B0",
280
- pv: {
281
- shape: "roundedRect",
282
- icon: "Hash"
283
- }
284
- }}
285
- expectedDisplay="Main Title"
286
- explanation="For multi-line text, only the first line is used as the name. Markdown headers (# symbols) are stripped out."
287
- />
288
-
289
- <FallbackExample
290
- title="Scenario 5: Neither pv.name nor text present"
291
- scenario="Hardcoded fallback 'Text' is used"
292
- nodeDefinition={{
293
- id: "neither-present",
294
- type: "text",
295
- x: 100,
296
- y: 50,
297
- width: 180,
298
- height: 100,
299
- color: "#F44336",
300
- pv: {
301
- shape: "roundedRect",
302
- icon: "AlertCircle"
303
- }
304
- }}
305
- expectedDisplay="Text"
306
- explanation="When both pv.name and text are missing/undefined, the hardcoded fallback 'Text' is used as the name."
307
- />
308
-
309
- <div style={{
310
- marginTop: '32px',
311
- padding: '24px',
312
- backgroundColor: theme.colors.backgroundSecondary,
313
- border: `2px solid ${theme.colors.border}`,
314
- borderRadius: '8px',
315
- }}>
316
- <h2 style={{
317
- marginBottom: '16px',
318
- fontSize: theme.fontSizes[4],
319
- color: theme.colors.text,
320
- }}>
321
- Complete Fallback Chain
322
- </h2>
323
- <div style={{
324
- fontFamily: theme.fonts.monospace,
325
- fontSize: theme.fontSizes[1],
326
- color: theme.colors.text,
327
- lineHeight: 2,
328
- }}>
329
- <div style={{ color: theme.colors.primary }}>
330
- 1. <strong>pv.name</strong> (highest priority)
331
- </div>
332
- <div style={{ paddingLeft: '20px', color: theme.colors.textSecondary }}>
333
- ↓ if missing
334
- </div>
335
- <div style={{ color: theme.colors.primary }}>
336
- 2. <strong>text</strong> (first line, markdown stripped, max 50 chars)
337
- </div>
338
- <div style={{ paddingLeft: '20px', color: theme.colors.textSecondary }}>
339
- ↓ if missing
340
- </div>
341
- <div style={{ color: theme.colors.primary }}>
342
- 3. <strong>"Text"</strong> (hardcoded fallback for text nodes)
343
- </div>
344
- <div style={{ paddingLeft: '20px', color: theme.colors.textSecondary }}>
345
- ↓ if NodeState.name somehow missing
346
- </div>
347
- <div style={{ color: theme.colors.primary }}>
348
- 4. <strong>node.id</strong> (ultimate fallback in renderer)
349
- </div>
350
- </div>
351
-
352
- <div style={{
353
- marginTop: '20px',
354
- padding: '16px',
355
- backgroundColor: theme.colors.backgroundTertiary,
356
- borderRadius: '6px',
357
- fontSize: theme.fontSizes[1],
358
- color: theme.colors.textMuted,
359
- }}>
360
- <strong style={{ color: theme.colors.text }}>Code Reference:</strong>
361
- <div style={{ marginTop: '8px' }}>
362
- • CanvasConverter.ts:285-307 (text → NodeState.name conversion)
363
- <br />
364
- • graphConverter.ts:42 (NodeState.name → node.id fallback)
365
- <br />
366
- • CustomNode.tsx:201 (final display)
367
- </div>
368
- </div>
369
- </div>
370
- </div>
371
- );
372
- },
373
- };
374
-
375
- /**
376
- * Shows the difference between text and pv.name with identical values
377
- */
378
- export const TextVsPvName: Story = {
379
- render: () => {
380
- const theme = defaultEditorTheme;
381
-
382
- const bothSame: ExtendedCanvas = {
383
- nodes: [{
384
- id: "same-value",
385
- type: "text",
386
- text: "Analysis Started",
387
- x: 150,
388
- y: 100,
389
- width: 200,
390
- height: 100,
391
- color: "#4CAF50",
392
- pv: {
393
- name: "Analysis Started",
394
- shape: "roundedRect",
395
- icon: "Play"
396
- }
397
- }],
398
- edges: [],
399
- };
400
-
401
- const different: ExtendedCanvas = {
402
- nodes: [{
403
- id: "different-values",
404
- type: "text",
405
- text: "Long technical description that gets truncated",
406
- x: 150,
407
- y: 100,
408
- width: 200,
409
- height: 100,
410
- color: "#2196F3",
411
- pv: {
412
- name: "Short Name",
413
- shape: "roundedRect",
414
- icon: "Zap"
415
- }
416
- }],
417
- edges: [],
418
- };
419
-
420
- return (
421
- <div style={{ padding: '32px' }}>
422
- <h2 style={{
423
- marginBottom: '24px',
424
- fontSize: theme.fontSizes[6],
425
- color: theme.colors.text,
426
- }}>
427
- Text vs PV.Name Comparison
428
- </h2>
429
-
430
- <div style={{
431
- display: 'grid',
432
- gridTemplateColumns: '1fr 1fr',
433
- gap: '32px',
434
- marginBottom: '32px',
435
- }}>
436
- <div>
437
- <h3 style={{
438
- marginBottom: '16px',
439
- fontSize: theme.fontSizes[3],
440
- color: theme.colors.text,
441
- }}>
442
- When They're the Same
443
- </h3>
444
- <p style={{
445
- marginBottom: '16px',
446
- fontSize: theme.fontSizes[1],
447
- color: theme.colors.textSecondary,
448
- }}>
449
- In your OTEL canvases, text and pv.name often have the same value. This is redundant but harmless - pv.name takes priority anyway.
450
- </p>
451
- <div style={{
452
- backgroundColor: theme.colors.background,
453
- border: `2px solid ${theme.colors.border}`,
454
- borderRadius: '8px',
455
- padding: '24px',
456
- height: '250px',
457
- }}>
458
- <GraphRenderer canvas={bothSame} height={250} width="100%" />
459
- </div>
460
- </div>
461
-
462
- <div>
463
- <h3 style={{
464
- marginBottom: '16px',
465
- fontSize: theme.fontSizes[3],
466
- color: theme.colors.text,
467
- }}>
468
- When They're Different
469
- </h3>
470
- <p style={{
471
- marginBottom: '16px',
472
- fontSize: theme.fontSizes[1],
473
- color: theme.colors.textSecondary,
474
- }}>
475
- When they differ, pv.name always wins. The text field can contain longer content while pv.name provides a concise display name.
476
- </p>
477
- <div style={{
478
- backgroundColor: theme.colors.background,
479
- border: `2px solid ${theme.colors.border}`,
480
- borderRadius: '8px',
481
- padding: '24px',
482
- height: '250px',
483
- }}>
484
- <GraphRenderer canvas={different} height={250} width="100%" />
485
- </div>
486
- </div>
487
- </div>
488
- </div>
489
- );
490
- },
491
- };