@principal-ai/principal-view-react 0.6.6

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 (96) hide show
  1. package/README.md +111 -0
  2. package/dist/components/ConfigurationSelector.d.ts +37 -0
  3. package/dist/components/ConfigurationSelector.d.ts.map +1 -0
  4. package/dist/components/ConfigurationSelector.js +67 -0
  5. package/dist/components/ConfigurationSelector.js.map +1 -0
  6. package/dist/components/EdgeInfoPanel.d.ts +16 -0
  7. package/dist/components/EdgeInfoPanel.d.ts.map +1 -0
  8. package/dist/components/EdgeInfoPanel.js +85 -0
  9. package/dist/components/EdgeInfoPanel.js.map +1 -0
  10. package/dist/components/EventLog.d.ts +20 -0
  11. package/dist/components/EventLog.d.ts.map +1 -0
  12. package/dist/components/EventLog.js +13 -0
  13. package/dist/components/EventLog.js.map +1 -0
  14. package/dist/components/EventLog.test.d.ts +2 -0
  15. package/dist/components/EventLog.test.d.ts.map +1 -0
  16. package/dist/components/EventLog.test.js +73 -0
  17. package/dist/components/EventLog.test.js.map +1 -0
  18. package/dist/components/GraphRenderer.d.ts +121 -0
  19. package/dist/components/GraphRenderer.d.ts.map +1 -0
  20. package/dist/components/GraphRenderer.js +809 -0
  21. package/dist/components/GraphRenderer.js.map +1 -0
  22. package/dist/components/GraphRenderer.test.d.ts +2 -0
  23. package/dist/components/GraphRenderer.test.d.ts.map +1 -0
  24. package/dist/components/GraphRenderer.test.js +88 -0
  25. package/dist/components/GraphRenderer.test.js.map +1 -0
  26. package/dist/components/MetricsDashboard.d.ts +14 -0
  27. package/dist/components/MetricsDashboard.d.ts.map +1 -0
  28. package/dist/components/MetricsDashboard.js +13 -0
  29. package/dist/components/MetricsDashboard.js.map +1 -0
  30. package/dist/components/NodeInfoPanel.d.ts +21 -0
  31. package/dist/components/NodeInfoPanel.d.ts.map +1 -0
  32. package/dist/components/NodeInfoPanel.js +217 -0
  33. package/dist/components/NodeInfoPanel.js.map +1 -0
  34. package/dist/edges/CustomEdge.d.ts +16 -0
  35. package/dist/edges/CustomEdge.d.ts.map +1 -0
  36. package/dist/edges/CustomEdge.js +200 -0
  37. package/dist/edges/CustomEdge.js.map +1 -0
  38. package/dist/edges/GenericEdge.d.ts +18 -0
  39. package/dist/edges/GenericEdge.d.ts.map +1 -0
  40. package/dist/edges/GenericEdge.js +14 -0
  41. package/dist/edges/GenericEdge.js.map +1 -0
  42. package/dist/hooks/usePathBasedEvents.d.ts +42 -0
  43. package/dist/hooks/usePathBasedEvents.d.ts.map +1 -0
  44. package/dist/hooks/usePathBasedEvents.js +122 -0
  45. package/dist/hooks/usePathBasedEvents.js.map +1 -0
  46. package/dist/index.d.ts +33 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +41 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/nodes/CustomNode.d.ts +18 -0
  51. package/dist/nodes/CustomNode.d.ts.map +1 -0
  52. package/dist/nodes/CustomNode.js +298 -0
  53. package/dist/nodes/CustomNode.js.map +1 -0
  54. package/dist/nodes/GenericNode.d.ts +20 -0
  55. package/dist/nodes/GenericNode.d.ts.map +1 -0
  56. package/dist/nodes/GenericNode.js +24 -0
  57. package/dist/nodes/GenericNode.js.map +1 -0
  58. package/dist/utils/animationMapping.d.ts +53 -0
  59. package/dist/utils/animationMapping.d.ts.map +1 -0
  60. package/dist/utils/animationMapping.js +133 -0
  61. package/dist/utils/animationMapping.js.map +1 -0
  62. package/dist/utils/graphConverter.d.ts +22 -0
  63. package/dist/utils/graphConverter.d.ts.map +1 -0
  64. package/dist/utils/graphConverter.js +176 -0
  65. package/dist/utils/graphConverter.js.map +1 -0
  66. package/dist/utils/iconResolver.d.ts +29 -0
  67. package/dist/utils/iconResolver.d.ts.map +1 -0
  68. package/dist/utils/iconResolver.js +68 -0
  69. package/dist/utils/iconResolver.js.map +1 -0
  70. package/package.json +61 -0
  71. package/src/components/ConfigurationSelector.tsx +147 -0
  72. package/src/components/EdgeInfoPanel.tsx +198 -0
  73. package/src/components/EventLog.test.tsx +85 -0
  74. package/src/components/EventLog.tsx +51 -0
  75. package/src/components/GraphRenderer.test.tsx +118 -0
  76. package/src/components/GraphRenderer.tsx +1222 -0
  77. package/src/components/MetricsDashboard.tsx +40 -0
  78. package/src/components/NodeInfoPanel.tsx +425 -0
  79. package/src/edges/CustomEdge.tsx +344 -0
  80. package/src/edges/GenericEdge.tsx +40 -0
  81. package/src/hooks/usePathBasedEvents.ts +182 -0
  82. package/src/index.ts +67 -0
  83. package/src/nodes/CustomNode.tsx +432 -0
  84. package/src/nodes/GenericNode.tsx +54 -0
  85. package/src/stories/AnimationWorkshop.stories.tsx +608 -0
  86. package/src/stories/EventDrivenAnimations.stories.tsx +499 -0
  87. package/src/stories/EventLog.stories.tsx +161 -0
  88. package/src/stories/GraphRenderer.stories.tsx +628 -0
  89. package/src/stories/Introduction.mdx +51 -0
  90. package/src/stories/MetricsDashboard.stories.tsx +227 -0
  91. package/src/stories/MultiConfig.stories.tsx +531 -0
  92. package/src/stories/MultiDirectionalConnections.stories.tsx +345 -0
  93. package/src/stories/NodeShapes.stories.tsx +769 -0
  94. package/src/utils/animationMapping.ts +170 -0
  95. package/src/utils/graphConverter.ts +218 -0
  96. package/src/utils/iconResolver.tsx +49 -0
@@ -0,0 +1,531 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { useState } from 'react';
3
+ import { GraphRenderer } from '../components/GraphRenderer';
4
+ import type { ExtendedCanvas } from '@principal-ai/principal-view-core';
5
+ import React from 'react';
6
+
7
+ const meta: Meta<typeof GraphRenderer> = {
8
+ title: 'Multi-Config/Configuration Switcher',
9
+ component: GraphRenderer,
10
+ parameters: {
11
+ layout: 'fullscreen',
12
+ },
13
+ tags: ['autodocs'],
14
+ };
15
+
16
+ export default meta;
17
+ type Story = StoryObj<typeof GraphRenderer>;
18
+
19
+ // ============================================================================
20
+ // Sample Canvas Configurations
21
+ // ============================================================================
22
+
23
+ /**
24
+ * Simple Service Architecture Canvas
25
+ */
26
+ const simpleServiceCanvas: ExtendedCanvas = {
27
+ nodes: [
28
+ {
29
+ id: 'api-1',
30
+ type: 'text',
31
+ x: 100,
32
+ y: 150,
33
+ width: 120,
34
+ height: 70,
35
+ text: 'API',
36
+ color: '#4A90E2',
37
+ vv: {
38
+ nodeType: 'api',
39
+ shape: 'rectangle',
40
+ icon: 'Globe',
41
+ },
42
+ },
43
+ {
44
+ id: 'service-1',
45
+ type: 'text',
46
+ x: 300,
47
+ y: 150,
48
+ width: 100,
49
+ height: 100,
50
+ text: 'Service',
51
+ color: '#7ED321',
52
+ vv: {
53
+ nodeType: 'service',
54
+ shape: 'hexagon',
55
+ icon: 'Cog',
56
+ },
57
+ },
58
+ {
59
+ id: 'database-1',
60
+ type: 'text',
61
+ x: 500,
62
+ y: 150,
63
+ width: 80,
64
+ height: 80,
65
+ text: 'Database',
66
+ color: '#BD10E0',
67
+ vv: {
68
+ nodeType: 'database',
69
+ shape: 'circle',
70
+ icon: 'Database',
71
+ },
72
+ },
73
+ ],
74
+ edges: [
75
+ {
76
+ id: 'edge-1',
77
+ fromNode: 'api-1',
78
+ toNode: 'service-1',
79
+ vv: { edgeType: 'api_call' },
80
+ },
81
+ {
82
+ id: 'edge-2',
83
+ fromNode: 'service-1',
84
+ toNode: 'database-1',
85
+ vv: { edgeType: 'data_access' },
86
+ },
87
+ ],
88
+ vv: {
89
+ version: '1.0.0',
90
+ name: 'Simple Service',
91
+ description: 'Basic 3-tier service architecture',
92
+ edgeTypes: {
93
+ api_call: {
94
+ style: 'solid',
95
+ color: '#4A90E2',
96
+ width: 2,
97
+ directed: true,
98
+ },
99
+ data_access: {
100
+ style: 'dashed',
101
+ color: '#BD10E0',
102
+ width: 2,
103
+ directed: true,
104
+ },
105
+ },
106
+ },
107
+ };
108
+
109
+ /**
110
+ * Microservices Architecture Canvas
111
+ */
112
+ const microservicesCanvas: ExtendedCanvas = {
113
+ nodes: [
114
+ {
115
+ id: 'gateway-1',
116
+ type: 'text',
117
+ x: 300,
118
+ y: 50,
119
+ width: 120,
120
+ height: 70,
121
+ text: 'Gateway',
122
+ color: '#00C853',
123
+ vv: {
124
+ nodeType: 'gateway',
125
+ shape: 'rectangle',
126
+ icon: 'Network',
127
+ },
128
+ },
129
+ {
130
+ id: 'auth-1',
131
+ type: 'text',
132
+ x: 100,
133
+ y: 200,
134
+ width: 120,
135
+ height: 70,
136
+ text: 'Auth Service',
137
+ color: '#FF6B6B',
138
+ vv: {
139
+ nodeType: 'auth_service',
140
+ shape: 'rectangle',
141
+ icon: 'Lock',
142
+ },
143
+ },
144
+ {
145
+ id: 'user-1',
146
+ type: 'text',
147
+ x: 300,
148
+ y: 200,
149
+ width: 120,
150
+ height: 70,
151
+ text: 'User Service',
152
+ color: '#4A90E2',
153
+ vv: {
154
+ nodeType: 'user_service',
155
+ shape: 'rectangle',
156
+ icon: 'Users',
157
+ },
158
+ },
159
+ {
160
+ id: 'cache-1',
161
+ type: 'text',
162
+ x: 100,
163
+ y: 350,
164
+ width: 80,
165
+ height: 80,
166
+ text: 'Cache',
167
+ color: '#3498DB',
168
+ vv: {
169
+ nodeType: 'cache',
170
+ shape: 'circle',
171
+ icon: 'Zap',
172
+ },
173
+ },
174
+ {
175
+ id: 'db-1',
176
+ type: 'text',
177
+ x: 300,
178
+ y: 350,
179
+ width: 80,
180
+ height: 80,
181
+ text: 'Database',
182
+ color: '#27AE60',
183
+ vv: {
184
+ nodeType: 'database',
185
+ shape: 'circle',
186
+ icon: 'Database',
187
+ },
188
+ },
189
+ ],
190
+ edges: [
191
+ {
192
+ id: 'edge-1',
193
+ fromNode: 'gateway-1',
194
+ toNode: 'auth-1',
195
+ vv: { edgeType: 'http_request' },
196
+ },
197
+ {
198
+ id: 'edge-2',
199
+ fromNode: 'gateway-1',
200
+ toNode: 'user-1',
201
+ vv: { edgeType: 'http_request' },
202
+ },
203
+ {
204
+ id: 'edge-3',
205
+ fromNode: 'auth-1',
206
+ toNode: 'cache-1',
207
+ vv: { edgeType: 'cache_access' },
208
+ },
209
+ {
210
+ id: 'edge-4',
211
+ fromNode: 'user-1',
212
+ toNode: 'db-1',
213
+ vv: { edgeType: 'http_request' },
214
+ },
215
+ ],
216
+ vv: {
217
+ version: '2.0.0',
218
+ name: 'Microservices',
219
+ description: 'Distributed microservices architecture',
220
+ edgeTypes: {
221
+ http_request: {
222
+ style: 'solid',
223
+ color: '#4A90E2',
224
+ width: 2,
225
+ directed: true,
226
+ animation: {
227
+ type: 'flow',
228
+ duration: 1500,
229
+ },
230
+ },
231
+ cache_access: {
232
+ style: 'dotted',
233
+ color: '#3498DB',
234
+ width: 2,
235
+ directed: true,
236
+ },
237
+ },
238
+ },
239
+ };
240
+
241
+ /**
242
+ * Data Pipeline Canvas
243
+ */
244
+ const dataPipelineCanvas: ExtendedCanvas = {
245
+ nodes: [
246
+ {
247
+ id: 'source-1',
248
+ type: 'text',
249
+ x: 100,
250
+ y: 150,
251
+ width: 120,
252
+ height: 70,
253
+ text: 'Data Source',
254
+ color: '#6C5CE7',
255
+ vv: {
256
+ nodeType: 'data_source',
257
+ shape: 'rectangle',
258
+ icon: 'FileInput',
259
+ },
260
+ },
261
+ {
262
+ id: 'validator-1',
263
+ type: 'text',
264
+ x: 280,
265
+ y: 150,
266
+ width: 90,
267
+ height: 90,
268
+ text: 'Validator',
269
+ color: '#00B894',
270
+ vv: {
271
+ nodeType: 'validator',
272
+ shape: 'diamond',
273
+ icon: 'CheckCircle',
274
+ },
275
+ },
276
+ {
277
+ id: 'transformer-1',
278
+ type: 'text',
279
+ x: 450,
280
+ y: 150,
281
+ width: 100,
282
+ height: 100,
283
+ text: 'Transformer',
284
+ color: '#FD79A8',
285
+ vv: {
286
+ nodeType: 'transformer',
287
+ shape: 'hexagon',
288
+ icon: 'RefreshCw',
289
+ },
290
+ },
291
+ {
292
+ id: 'warehouse-1',
293
+ type: 'text',
294
+ x: 620,
295
+ y: 150,
296
+ width: 80,
297
+ height: 80,
298
+ text: 'Warehouse',
299
+ color: '#0984E3',
300
+ vv: {
301
+ nodeType: 'data_warehouse',
302
+ shape: 'circle',
303
+ icon: 'Database',
304
+ },
305
+ },
306
+ ],
307
+ edges: [
308
+ {
309
+ id: 'edge-1',
310
+ fromNode: 'source-1',
311
+ toNode: 'validator-1',
312
+ vv: { edgeType: 'validation_flow' },
313
+ },
314
+ {
315
+ id: 'edge-2',
316
+ fromNode: 'validator-1',
317
+ toNode: 'transformer-1',
318
+ vv: { edgeType: 'data_flow' },
319
+ },
320
+ {
321
+ id: 'edge-3',
322
+ fromNode: 'transformer-1',
323
+ toNode: 'warehouse-1',
324
+ vv: { edgeType: 'data_flow' },
325
+ },
326
+ ],
327
+ vv: {
328
+ version: '1.0.0',
329
+ name: 'Data Pipeline',
330
+ description: 'ETL data processing pipeline',
331
+ edgeTypes: {
332
+ data_flow: {
333
+ style: 'solid',
334
+ color: '#0984E3',
335
+ width: 3,
336
+ directed: true,
337
+ animation: {
338
+ type: 'flow',
339
+ duration: 2000,
340
+ },
341
+ },
342
+ validation_flow: {
343
+ style: 'solid',
344
+ color: '#00B894',
345
+ width: 2,
346
+ directed: true,
347
+ },
348
+ },
349
+ },
350
+ };
351
+
352
+ // Available configurations
353
+ const configurations = [
354
+ { name: 'Simple Service', canvas: simpleServiceCanvas },
355
+ { name: 'Microservices', canvas: microservicesCanvas },
356
+ { name: 'Data Pipeline', canvas: dataPipelineCanvas },
357
+ ];
358
+
359
+ // Multi-config switcher component
360
+ function MultiConfigDemo() {
361
+ const [selectedConfigName, setSelectedConfigName] = useState(configurations[0].name);
362
+
363
+ const selectedConfig = configurations.find((c) => c.name === selectedConfigName);
364
+
365
+ if (!selectedConfig) {
366
+ return <div>No configuration selected</div>;
367
+ }
368
+
369
+ return (
370
+ <div style={{ width: '100vw', height: '100vh', display: 'flex', flexDirection: 'column' }}>
371
+ {/* Header with configuration selector */}
372
+ <div
373
+ style={{
374
+ padding: '16px',
375
+ backgroundColor: '#f5f5f5',
376
+ borderBottom: '1px solid #ddd',
377
+ }}
378
+ >
379
+ <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
380
+ <label style={{ fontWeight: 'bold' }}>Configuration:</label>
381
+ <select
382
+ value={selectedConfigName}
383
+ onChange={(e) => setSelectedConfigName(e.target.value)}
384
+ style={{
385
+ padding: '8px 12px',
386
+ borderRadius: '4px',
387
+ border: '1px solid #ccc',
388
+ fontSize: '14px',
389
+ minWidth: '200px',
390
+ }}
391
+ >
392
+ {configurations.map((config) => (
393
+ <option key={config.name} value={config.name}>
394
+ {config.name}
395
+ </option>
396
+ ))}
397
+ </select>
398
+ <span style={{ color: '#666', fontSize: '12px' }}>
399
+ v{selectedConfig.canvas.vv?.version} - {selectedConfig.canvas.vv?.description}
400
+ </span>
401
+ </div>
402
+ </div>
403
+
404
+ {/* Graph visualization */}
405
+ <div style={{ flex: 1 }}>
406
+ <GraphRenderer canvas={selectedConfig.canvas} showMinimap showControls showBackground />
407
+ </div>
408
+ </div>
409
+ );
410
+ }
411
+
412
+ // Story: Basic multi-config switcher
413
+ export const ConfigurationSwitcher: Story = {
414
+ render: () => <MultiConfigDemo />,
415
+ parameters: {
416
+ docs: {
417
+ description: {
418
+ story:
419
+ 'Demonstrates switching between multiple graph configurations. Each configuration has different node types, edge types, and visual styles. Use the dropdown to switch between configurations.',
420
+ },
421
+ },
422
+ },
423
+ };
424
+
425
+ // Side-by-side comparison component
426
+ function SideBySideDemo() {
427
+ const [leftConfigName, setLeftConfigName] = useState(configurations[0].name);
428
+ const [rightConfigName, setRightConfigName] = useState(configurations[1].name);
429
+
430
+ const leftConfig = configurations.find((c) => c.name === leftConfigName);
431
+ const rightConfig = configurations.find((c) => c.name === rightConfigName);
432
+
433
+ return (
434
+ <div style={{ width: '100vw', height: '100vh', display: 'flex', flexDirection: 'column' }}>
435
+ {/* Header */}
436
+ <div
437
+ style={{
438
+ padding: '16px',
439
+ backgroundColor: '#f5f5f5',
440
+ borderBottom: '1px solid #ddd',
441
+ display: 'flex',
442
+ gap: '16px',
443
+ }}
444
+ >
445
+ <div style={{ flex: 1 }}>
446
+ <label style={{ fontWeight: 'bold', display: 'block', marginBottom: '4px' }}>
447
+ Left Configuration
448
+ </label>
449
+ <select
450
+ value={leftConfigName}
451
+ onChange={(e) => setLeftConfigName(e.target.value)}
452
+ style={{
453
+ padding: '8px 12px',
454
+ borderRadius: '4px',
455
+ border: '1px solid #ccc',
456
+ fontSize: '14px',
457
+ width: '100%',
458
+ }}
459
+ >
460
+ {configurations.map((config) => (
461
+ <option key={config.name} value={config.name}>
462
+ {config.name}
463
+ </option>
464
+ ))}
465
+ </select>
466
+ </div>
467
+ <div style={{ flex: 1 }}>
468
+ <label style={{ fontWeight: 'bold', display: 'block', marginBottom: '4px' }}>
469
+ Right Configuration
470
+ </label>
471
+ <select
472
+ value={rightConfigName}
473
+ onChange={(e) => setRightConfigName(e.target.value)}
474
+ style={{
475
+ padding: '8px 12px',
476
+ borderRadius: '4px',
477
+ border: '1px solid #ccc',
478
+ fontSize: '14px',
479
+ width: '100%',
480
+ }}
481
+ >
482
+ {configurations.map((config) => (
483
+ <option key={config.name} value={config.name}>
484
+ {config.name}
485
+ </option>
486
+ ))}
487
+ </select>
488
+ </div>
489
+ </div>
490
+
491
+ {/* Side by side graphs */}
492
+ <div style={{ flex: 1, display: 'flex' }}>
493
+ {leftConfig && (
494
+ <div style={{ flex: 1, borderRight: '1px solid #ddd' }}>
495
+ <GraphRenderer
496
+ canvas={leftConfig.canvas}
497
+ configName={leftConfigName}
498
+ showMinimap={false}
499
+ showControls
500
+ showBackground
501
+ />
502
+ </div>
503
+ )}
504
+ {rightConfig && (
505
+ <div style={{ flex: 1 }}>
506
+ <GraphRenderer
507
+ canvas={rightConfig.canvas}
508
+ configName={rightConfigName}
509
+ showMinimap={false}
510
+ showControls
511
+ showBackground
512
+ />
513
+ </div>
514
+ )}
515
+ </div>
516
+ </div>
517
+ );
518
+ }
519
+
520
+ // Story: Side-by-side comparison
521
+ export const SideBySideComparison: Story = {
522
+ render: () => <SideBySideDemo />,
523
+ parameters: {
524
+ docs: {
525
+ description: {
526
+ story:
527
+ 'Compare two different graph configurations side-by-side. Useful for understanding architectural differences or analyzing multiple aspects of your system simultaneously.',
528
+ },
529
+ },
530
+ },
531
+ };