@principal-ai/principal-view-react 0.7.14 → 0.7.16

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 (138) hide show
  1. package/README.md +9 -24
  2. package/dist/components/ConfigurationSelector.d.ts +1 -1
  3. package/dist/components/ConfigurationSelector.d.ts.map +1 -1
  4. package/dist/components/ConfigurationSelector.js +6 -10
  5. package/dist/components/ConfigurationSelector.js.map +1 -1
  6. package/dist/components/EdgeInfoPanel.d.ts +1 -1
  7. package/dist/components/EdgeInfoPanel.d.ts.map +1 -1
  8. package/dist/components/EdgeInfoPanel.js +14 -18
  9. package/dist/components/EdgeInfoPanel.js.map +1 -1
  10. package/dist/components/GraphRenderer.d.ts +1 -1
  11. package/dist/components/GraphRenderer.d.ts.map +1 -1
  12. package/dist/components/GraphRenderer.js +89 -92
  13. package/dist/components/GraphRenderer.js.map +1 -1
  14. package/dist/components/NarrativeRenderer.d.ts +19 -0
  15. package/dist/components/NarrativeRenderer.d.ts.map +1 -0
  16. package/dist/components/NarrativeRenderer.js +103 -0
  17. package/dist/components/NarrativeRenderer.js.map +1 -0
  18. package/dist/components/NodeInfoPanel.d.ts +1 -1
  19. package/dist/components/NodeInfoPanel.d.ts.map +1 -1
  20. package/dist/components/NodeInfoPanel.js +33 -37
  21. package/dist/components/NodeInfoPanel.js.map +1 -1
  22. package/dist/components/NodeTooltip.js +15 -19
  23. package/dist/components/NodeTooltip.js.map +1 -1
  24. package/dist/components/SelectionSidebar.d.ts +1 -1
  25. package/dist/components/SelectionSidebar.d.ts.map +1 -1
  26. package/dist/components/SelectionSidebar.js +26 -30
  27. package/dist/components/SelectionSidebar.js.map +1 -1
  28. package/dist/components/TestEventPanel.d.ts +6 -0
  29. package/dist/components/TestEventPanel.d.ts.map +1 -1
  30. package/dist/components/TestEventPanel.js +157 -160
  31. package/dist/components/TestEventPanel.js.map +1 -1
  32. package/dist/edges/CustomEdge.d.ts +1 -1
  33. package/dist/edges/CustomEdge.d.ts.map +1 -1
  34. package/dist/edges/CustomEdge.js +18 -22
  35. package/dist/edges/CustomEdge.js.map +1 -1
  36. package/dist/edges/GenericEdge.d.ts +1 -1
  37. package/dist/edges/GenericEdge.d.ts.map +1 -1
  38. package/dist/edges/GenericEdge.js +3 -7
  39. package/dist/edges/GenericEdge.js.map +1 -1
  40. package/dist/hooks/usePathBasedEvents.d.ts +1 -1
  41. package/dist/hooks/usePathBasedEvents.d.ts.map +1 -1
  42. package/dist/hooks/usePathBasedEvents.js +14 -18
  43. package/dist/hooks/usePathBasedEvents.js.map +1 -1
  44. package/dist/index.d.ts +1 -5
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +12 -33
  47. package/dist/index.js.map +1 -1
  48. package/dist/nodes/CustomNode.d.ts +1 -1
  49. package/dist/nodes/CustomNode.d.ts.map +1 -1
  50. package/dist/nodes/CustomNode.js +22 -26
  51. package/dist/nodes/CustomNode.js.map +1 -1
  52. package/dist/nodes/GenericNode.d.ts +1 -1
  53. package/dist/nodes/GenericNode.d.ts.map +1 -1
  54. package/dist/nodes/GenericNode.js +4 -8
  55. package/dist/nodes/GenericNode.js.map +1 -1
  56. package/dist/utils/animationMapping.d.ts +1 -1
  57. package/dist/utils/animationMapping.d.ts.map +1 -1
  58. package/dist/utils/animationMapping.js +6 -13
  59. package/dist/utils/animationMapping.js.map +1 -1
  60. package/dist/utils/graphConverter.d.ts +1 -1
  61. package/dist/utils/graphConverter.d.ts.map +1 -1
  62. package/dist/utils/graphConverter.js +4 -8
  63. package/dist/utils/graphConverter.js.map +1 -1
  64. package/dist/utils/iconResolver.js +7 -45
  65. package/dist/utils/iconResolver.js.map +1 -1
  66. package/dist/utils/narrative-converter.d.ts +45 -0
  67. package/dist/utils/narrative-converter.d.ts.map +1 -0
  68. package/dist/utils/narrative-converter.js +113 -0
  69. package/dist/utils/narrative-converter.js.map +1 -0
  70. package/dist/utils/narrative-loader.d.ts +53 -0
  71. package/dist/utils/narrative-loader.d.ts.map +1 -0
  72. package/dist/utils/narrative-loader.js +163 -0
  73. package/dist/utils/narrative-loader.js.map +1 -0
  74. package/package.json +22 -25
  75. package/src/components/ConfigurationSelector.tsx +1 -1
  76. package/src/components/EdgeInfoPanel.tsx +1 -1
  77. package/src/components/GraphRenderer.test.tsx +1 -1
  78. package/src/components/GraphRenderer.tsx +2 -2
  79. package/src/components/NarrativeRenderer.tsx +171 -0
  80. package/src/components/NodeInfoPanel.tsx +1 -1
  81. package/src/components/NodeTooltip.tsx +3 -3
  82. package/src/components/PendingChanges.test.tsx +1 -1
  83. package/src/components/SelectionSidebar.tsx +1 -1
  84. package/src/components/TestEventPanel.tsx +145 -121
  85. package/src/edges/CustomEdge.tsx +1 -1
  86. package/src/edges/GenericEdge.tsx +1 -1
  87. package/src/hooks/usePathBasedEvents.ts +1 -1
  88. package/src/index.ts +1 -7
  89. package/src/nodes/CustomNode.tsx +1 -1
  90. package/src/nodes/GenericNode.tsx +1 -1
  91. package/src/stories/AnimationWorkshop.stories.tsx +1 -1
  92. package/src/stories/CanvasEdgeTypes.stories.tsx +1 -1
  93. package/src/stories/CanvasNodeTypes.stories.tsx +1 -1
  94. package/src/stories/ColorPriority.stories.tsx +1 -1
  95. package/src/stories/EventDrivenAnimations.stories.tsx +1 -1
  96. package/src/stories/GraphRenderer.stories.tsx +1 -1
  97. package/src/stories/Introduction.mdx +4 -21
  98. package/src/stories/MultiConfig.stories.tsx +1 -1
  99. package/src/stories/MultiDirectionalConnections.stories.tsx +1 -1
  100. package/src/stories/NodeFieldsAudit.stories.tsx +1 -1
  101. package/src/stories/NodeShapes.stories.tsx +1 -1
  102. package/src/stories/OtelComponents.stories.tsx +1 -1
  103. package/src/stories/RealTestExecution.stories.tsx +111 -1
  104. package/src/stories/TraceViewer.stories.tsx +1 -1
  105. package/src/stories/ValidatedExecution.stories.tsx +1 -1
  106. package/src/stories/data/graph-converter-test-execution.json +204 -326
  107. package/src/stories/data/graph-converter-test.narrative.json +106 -0
  108. package/src/stories/data/graph-converter-validated-execution.json +6 -6
  109. package/src/utils/animationMapping.ts +1 -1
  110. package/src/utils/graphConverter.ts +1 -1
  111. package/src/utils/narrative-converter.ts +147 -0
  112. package/src/utils/narrative-loader.ts +172 -0
  113. package/dist/components/EventLog.d.ts +0 -20
  114. package/dist/components/EventLog.d.ts.map +0 -1
  115. package/dist/components/EventLog.js +0 -13
  116. package/dist/components/EventLog.js.map +0 -1
  117. package/dist/components/EventLog.test.d.ts +0 -2
  118. package/dist/components/EventLog.test.d.ts.map +0 -1
  119. package/dist/components/EventLog.test.js +0 -73
  120. package/dist/components/EventLog.test.js.map +0 -1
  121. package/dist/components/GraphRenderer.test.d.ts +0 -2
  122. package/dist/components/GraphRenderer.test.d.ts.map +0 -1
  123. package/dist/components/GraphRenderer.test.js +0 -88
  124. package/dist/components/GraphRenderer.test.js.map +0 -1
  125. package/dist/components/LayerPanel.d.ts +0 -31
  126. package/dist/components/LayerPanel.d.ts.map +0 -1
  127. package/dist/components/LayerPanel.js +0 -207
  128. package/dist/components/LayerPanel.js.map +0 -1
  129. package/dist/components/MetricsDashboard.d.ts +0 -14
  130. package/dist/components/MetricsDashboard.d.ts.map +0 -1
  131. package/dist/components/MetricsDashboard.js +0 -13
  132. package/dist/components/MetricsDashboard.js.map +0 -1
  133. package/src/components/EventLog.test.tsx +0 -85
  134. package/src/components/EventLog.tsx +0 -51
  135. package/src/components/MetricsDashboard.tsx +0 -40
  136. package/src/stories/EventLog.stories.tsx +0 -161
  137. package/src/stories/IndustryThemes.stories.tsx +0 -483
  138. package/src/stories/MetricsDashboard.stories.tsx +0 -227
@@ -2,6 +2,9 @@ import React, { useState, useMemo } from 'react';
2
2
  import { useTheme } from '@principal-ade/industry-theme';
3
3
  import { HelpCircle } from 'lucide-react';
4
4
  import yaml from 'js-yaml';
5
+ import type { NarrativeTemplate } from '@principal-ai/principal-view-core';
6
+ import { NarrativeRenderer } from './NarrativeRenderer';
7
+ import { convertToOtelEvents } from '../utils/narrative-converter';
5
8
 
6
9
  interface SpanEvent {
7
10
  time: number;
@@ -47,6 +50,9 @@ interface TimelineItem {
47
50
  resource?: Record<string, string | number>;
48
51
  }
49
52
 
53
+ // View mode type
54
+ export type ViewMode = 'raw' | 'narrative';
55
+
50
56
  export interface TestEventPanelProps {
51
57
  spans: TestSpan[];
52
58
  logs?: OtelLog[]; // Optional for backward compatibility
@@ -54,6 +60,12 @@ export interface TestEventPanelProps {
54
60
  currentEventIndex: number;
55
61
  highlightedPhase?: string; // 'setup' | 'execution' | 'assertion'
56
62
  onSpanIndexChange?: (index: number) => void;
63
+
64
+ // Narrative view props
65
+ viewMode?: ViewMode;
66
+ narrativeTemplate?: NarrativeTemplate;
67
+ onViewModeChange?: (mode: ViewMode) => void;
68
+ showNarrativeMetadata?: boolean;
57
69
  }
58
70
 
59
71
  // Helper functions for log severity
@@ -88,13 +100,22 @@ export const TestEventPanel: React.FC<TestEventPanelProps> = ({
88
100
  currentEventIndex,
89
101
  highlightedPhase,
90
102
  onSpanIndexChange,
103
+ viewMode = 'raw',
104
+ narrativeTemplate,
105
+ onViewModeChange,
106
+ showNarrativeMetadata = false,
91
107
  }) => {
92
108
  const { theme } = useTheme();
93
109
  const [showHelp, setShowHelp] = useState(false);
94
- const [viewMode, setViewMode] = useState<'all' | 'events' | 'logs'>('all');
95
110
 
96
111
  const currentSpan = spans[currentSpanIndex];
97
112
 
113
+ // Convert current span to OtelEvents for narrative rendering
114
+ const otelEvents = useMemo(() => {
115
+ if (!currentSpan || viewMode !== 'narrative') return [];
116
+ return convertToOtelEvents(currentSpan, logs);
117
+ }, [currentSpan, logs, viewMode]);
118
+
98
119
  const handlePrevTest = () => {
99
120
  if (currentSpanIndex > 0 && onSpanIndexChange) {
100
121
  onSpanIndexChange(currentSpanIndex - 1);
@@ -136,15 +157,6 @@ export const TestEventPanel: React.FC<TestEventPanelProps> = ({
136
157
  return items;
137
158
  }, [currentSpan, currentEventIndex, logs]);
138
159
 
139
- // Filter timeline based on view mode
140
- const filteredTimeline = useMemo(() => {
141
- if (viewMode === 'all') return timeline;
142
- return timeline.filter((item) => item.type === viewMode.slice(0, -1)); // 'events' -> 'event', 'logs' -> 'log'
143
- }, [timeline, viewMode]);
144
-
145
- const eventCount = timeline.filter((i) => i.type === 'event').length;
146
- const logCount = timeline.filter((i) => i.type === 'log').length;
147
-
148
160
  return (
149
161
  <div
150
162
  style={{
@@ -168,9 +180,44 @@ export const TestEventPanel: React.FC<TestEventPanelProps> = ({
168
180
  flexShrink: 0,
169
181
  }}
170
182
  >
183
+ {/* Test Navigation - replacing title */}
171
184
  <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '12px' }}>
172
- <div style={{ fontWeight: 'bold', fontSize: '18px' }}>
173
- Execution Timeline
185
+ <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
186
+ <button
187
+ onClick={handlePrevTest}
188
+ disabled={currentSpanIndex === 0}
189
+ style={{
190
+ padding: '4px 12px',
191
+ background: theme.colors.surface,
192
+ border: `1px solid ${theme.colors.border}`,
193
+ borderRadius: '4px',
194
+ color: currentSpanIndex === 0 ? theme.colors.textMuted : theme.colors.text,
195
+ cursor: currentSpanIndex === 0 ? 'not-allowed' : 'pointer',
196
+ fontSize: '14px',
197
+ opacity: currentSpanIndex === 0 ? 0.5 : 1,
198
+ }}
199
+ >
200
+ ← Prev
201
+ </button>
202
+ <div style={{ fontSize: '14px', fontWeight: 'bold' }}>
203
+ Test {currentSpanIndex + 1} of {spans.length}
204
+ </div>
205
+ <button
206
+ onClick={handleNextTest}
207
+ disabled={currentSpanIndex === spans.length - 1}
208
+ style={{
209
+ padding: '4px 12px',
210
+ background: theme.colors.surface,
211
+ border: `1px solid ${theme.colors.border}`,
212
+ borderRadius: '4px',
213
+ color: currentSpanIndex === spans.length - 1 ? theme.colors.textMuted : theme.colors.text,
214
+ cursor: currentSpanIndex === spans.length - 1 ? 'not-allowed' : 'pointer',
215
+ fontSize: '14px',
216
+ opacity: currentSpanIndex === spans.length - 1 ? 0.5 : 1,
217
+ }}
218
+ >
219
+ Next →
220
+ </button>
174
221
  </div>
175
222
  <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
176
223
  <div style={{ fontSize: '13px', color: theme.colors.textMuted }}>
@@ -199,96 +246,41 @@ export const TestEventPanel: React.FC<TestEventPanelProps> = ({
199
246
  </div>
200
247
  </div>
201
248
 
202
- {/* Test Navigation */}
203
- <div style={{ display: 'flex', alignItems: 'center', gap: '12px', marginBottom: '12px' }}>
204
- <button
205
- onClick={handlePrevTest}
206
- disabled={currentSpanIndex === 0}
207
- style={{
208
- padding: '4px 12px',
209
- background: theme.colors.surface,
210
- border: `1px solid ${theme.colors.border}`,
211
- borderRadius: '4px',
212
- color: currentSpanIndex === 0 ? theme.colors.textMuted : theme.colors.text,
213
- cursor: currentSpanIndex === 0 ? 'not-allowed' : 'pointer',
214
- fontSize: '14px',
215
- opacity: currentSpanIndex === 0 ? 0.5 : 1,
216
- }}
217
- >
218
- Prev
219
- </button>
220
- <div style={{ fontSize: '13px', color: theme.colors.textMuted }}>
221
- Test {currentSpanIndex + 1} of {spans.length}
222
- </div>
223
- <button
224
- onClick={handleNextTest}
225
- disabled={currentSpanIndex === spans.length - 1}
226
- style={{
227
- padding: '4px 12px',
228
- background: theme.colors.surface,
229
- border: `1px solid ${theme.colors.border}`,
230
- borderRadius: '4px',
231
- color: currentSpanIndex === spans.length - 1 ? theme.colors.textMuted : theme.colors.text,
232
- cursor: currentSpanIndex === spans.length - 1 ? 'not-allowed' : 'pointer',
233
- fontSize: '14px',
234
- opacity: currentSpanIndex === spans.length - 1 ? 0.5 : 1,
235
- }}
236
- >
237
- Next →
238
- </button>
239
- <div style={{ fontSize: '12px', color: theme.colors.textMuted, marginLeft: 'auto' }}>
240
- {eventCount} events, {logCount} logs
249
+ {/* View Mode Toggle */}
250
+ {narrativeTemplate && onViewModeChange && (
251
+ <div style={{ display: 'flex', gap: '8px', marginBottom: '12px' }}>
252
+ <button
253
+ onClick={() => onViewModeChange('raw')}
254
+ style={{
255
+ padding: '6px 12px',
256
+ background: viewMode === 'raw' ? theme.colors.primary : theme.colors.surface,
257
+ border: `1px solid ${theme.colors.border}`,
258
+ borderRadius: '4px',
259
+ color: viewMode === 'raw' ? '#ffffff' : theme.colors.text,
260
+ cursor: 'pointer',
261
+ fontSize: '13px',
262
+ fontWeight: viewMode === 'raw' ? 'bold' : 'normal',
263
+ }}
264
+ >
265
+ Raw Events
266
+ </button>
267
+ <button
268
+ onClick={() => onViewModeChange('narrative')}
269
+ style={{
270
+ padding: '6px 12px',
271
+ background: viewMode === 'narrative' ? theme.colors.primary : theme.colors.surface,
272
+ border: `1px solid ${theme.colors.border}`,
273
+ borderRadius: '4px',
274
+ color: viewMode === 'narrative' ? '#ffffff' : theme.colors.text,
275
+ cursor: 'pointer',
276
+ fontSize: '13px',
277
+ fontWeight: viewMode === 'narrative' ? 'bold' : 'normal',
278
+ }}
279
+ >
280
+ Narrative
281
+ </button>
241
282
  </div>
242
- </div>
243
-
244
- {/* Filter Tabs */}
245
- <div style={{ display: 'flex', gap: '8px', marginBottom: '12px' }}>
246
- <button
247
- onClick={() => setViewMode('all')}
248
- style={{
249
- padding: '6px 12px',
250
- background: viewMode === 'all' ? theme.colors.primary : 'transparent',
251
- border: `1px solid ${theme.colors.border}`,
252
- borderRadius: '4px',
253
- color: viewMode === 'all' ? '#ffffff' : theme.colors.text,
254
- cursor: 'pointer',
255
- fontSize: '12px',
256
- fontWeight: 500,
257
- }}
258
- >
259
- All ({timeline.length})
260
- </button>
261
- <button
262
- onClick={() => setViewMode('events')}
263
- style={{
264
- padding: '6px 12px',
265
- background: viewMode === 'events' ? theme.colors.primary : 'transparent',
266
- border: `1px solid ${theme.colors.border}`,
267
- borderRadius: '4px',
268
- color: viewMode === 'events' ? '#ffffff' : theme.colors.text,
269
- cursor: 'pointer',
270
- fontSize: '12px',
271
- fontWeight: 500,
272
- }}
273
- >
274
- Events ({eventCount})
275
- </button>
276
- <button
277
- onClick={() => setViewMode('logs')}
278
- style={{
279
- padding: '6px 12px',
280
- background: viewMode === 'logs' ? theme.colors.primary : 'transparent',
281
- border: `1px solid ${theme.colors.border}`,
282
- borderRadius: '4px',
283
- color: viewMode === 'logs' ? '#ffffff' : theme.colors.text,
284
- cursor: 'pointer',
285
- fontSize: '12px',
286
- fontWeight: 500,
287
- }}
288
- >
289
- Logs ({logCount})
290
- </button>
291
- </div>
283
+ )}
292
284
 
293
285
  <div style={{ fontSize: '13px', color: theme.colors.textMuted, marginBottom: '15px' }}>
294
286
  Test: {currentSpan?.name || 'Loading...'}
@@ -344,14 +336,6 @@ export const TestEventPanel: React.FC<TestEventPanelProps> = ({
344
336
  <span style={{ color: '#4ade80' }}>Green → Code under test</span>
345
337
  </li>
346
338
  </ul>
347
- <p style={{ marginBottom: '12px' }}>
348
- <strong>Use filter tabs to focus:</strong>
349
- </p>
350
- <ul style={{ marginLeft: '20px' }}>
351
- <li>All - Interleaved timeline</li>
352
- <li>Events - Span events only</li>
353
- <li>Logs - OTEL logs only</li>
354
- </ul>
355
339
  </div>
356
340
  <button
357
341
  onClick={() => setShowHelp(false)}
@@ -377,13 +361,52 @@ export const TestEventPanel: React.FC<TestEventPanelProps> = ({
377
361
  style={{
378
362
  flex: 1,
379
363
  overflow: 'auto',
380
- padding: '20px',
364
+ padding: viewMode === 'narrative' ? '0' : '20px',
381
365
  }}
382
366
  >
383
- {/* Timeline Items */}
384
- {currentSpan && (
367
+ {/* Narrative View */}
368
+ {viewMode === 'narrative' && narrativeTemplate && currentSpan ? (
369
+ <NarrativeRenderer
370
+ template={narrativeTemplate}
371
+ events={otelEvents}
372
+ showMetadata={showNarrativeMetadata}
373
+ />
374
+ ) : viewMode === 'narrative' && !narrativeTemplate ? (
375
+ <div
376
+ style={{
377
+ padding: '40px 20px',
378
+ textAlign: 'center',
379
+ color: theme.colors.textMuted,
380
+ }}
381
+ >
382
+ <div style={{ fontSize: '16px', marginBottom: '12px' }}>ⓘ No narrative template available</div>
383
+ <div style={{ fontSize: '14px', lineHeight: '1.6' }}>
384
+ Create a narrative template to see a human-readable
385
+ <br />
386
+ summary of this test execution.
387
+ </div>
388
+ <button
389
+ onClick={() => onViewModeChange?.('raw')}
390
+ style={{
391
+ marginTop: '20px',
392
+ padding: '8px 16px',
393
+ background: theme.colors.primary,
394
+ color: '#ffffff',
395
+ border: 'none',
396
+ borderRadius: '4px',
397
+ cursor: 'pointer',
398
+ fontSize: '14px',
399
+ }}
400
+ >
401
+ View Raw Events
402
+ </button>
403
+ </div>
404
+ ) : null}
405
+
406
+ {/* Raw Events View (Timeline) */}
407
+ {viewMode === 'raw' && currentSpan && (
385
408
  <div>
386
- {filteredTimeline.map((item, idx) => {
409
+ {timeline.map((item, idx) => {
387
410
  if (item.type === 'event') {
388
411
  // SPAN EVENT RENDERING
389
412
  const filepath = item.attributes?.['code.filepath'] as string;
@@ -401,7 +424,7 @@ export const TestEventPanel: React.FC<TestEventPanelProps> = ({
401
424
  marginBottom: '12px',
402
425
  paddingBottom: '12px',
403
426
  paddingLeft: '12px',
404
- borderBottom: idx < filteredTimeline.length - 1 ? `1px solid ${theme.colors.border}` : 'none',
427
+ borderBottom: idx < timeline.length - 1 ? `1px solid ${theme.colors.border}` : 'none',
405
428
  borderLeft: '3px solid #f59e0b',
406
429
  opacity: highlightedPhase && !isHighlighted ? 0.4 : 1,
407
430
  transition: 'opacity 0.2s ease',
@@ -450,8 +473,8 @@ export const TestEventPanel: React.FC<TestEventPanelProps> = ({
450
473
  padding: '8px',
451
474
  borderRadius: '4px',
452
475
  margin: 0,
453
- fontSize: '12px',
454
- lineHeight: '1.4',
476
+ fontSize: '13px',
477
+ lineHeight: '1.5',
455
478
  overflow: 'auto',
456
479
  maxWidth: '100%',
457
480
  }}
@@ -479,7 +502,7 @@ export const TestEventPanel: React.FC<TestEventPanelProps> = ({
479
502
  marginBottom: '12px',
480
503
  paddingBottom: '12px',
481
504
  paddingLeft: '12px',
482
- borderBottom: idx < filteredTimeline.length - 1 ? `1px solid ${theme.colors.border}` : 'none',
505
+ borderBottom: idx < timeline.length - 1 ? `1px solid ${theme.colors.border}` : 'none',
483
506
  borderLeft: `3px solid ${severityColor}`,
484
507
  }}
485
508
  >
@@ -531,7 +554,7 @@ export const TestEventPanel: React.FC<TestEventPanelProps> = ({
531
554
  {typeof item.body === 'string' ? (
532
555
  item.body
533
556
  ) : (
534
- <pre style={{ margin: 0, fontSize: '12px' }}>
557
+ <pre style={{ margin: 0, fontSize: '13px', lineHeight: '1.5' }}>
535
558
  {yaml.dump(item.body, { indent: 2, lineWidth: -1 })}
536
559
  </pre>
537
560
  )}
@@ -545,7 +568,8 @@ export const TestEventPanel: React.FC<TestEventPanelProps> = ({
545
568
  padding: '8px',
546
569
  borderRadius: '4px',
547
570
  margin: 0,
548
- fontSize: '11px',
571
+ fontSize: '12px',
572
+ lineHeight: '1.5',
549
573
  opacity: 0.8,
550
574
  }}
551
575
  >
@@ -556,8 +580,8 @@ export const TestEventPanel: React.FC<TestEventPanelProps> = ({
556
580
  );
557
581
  }
558
582
  })}
559
- </div>
560
- )}
583
+ </div>
584
+ )}
561
585
  </div>
562
586
  </div>
563
587
  );
@@ -1,7 +1,7 @@
1
1
  import React, { useState, useEffect, useRef } from 'react';
2
2
  import { BaseEdge, EdgeLabelRenderer, getBezierPath } from '@xyflow/react';
3
3
  import type { EdgeProps } from '@xyflow/react';
4
- import type { EdgeTypeDefinition } from '@principal-ai/principal-view-core';
4
+ import type { EdgeTypeDefinition } from '@principal-ai/principal-view-core/browser';
5
5
 
6
6
  export interface CustomEdgeData extends Record<string, unknown> {
7
7
  typeDefinition: EdgeTypeDefinition;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import type { EdgeTypeDefinition } from '@principal-ai/principal-view-core';
2
+ import type { EdgeTypeDefinition } from '@principal-ai/principal-view-core/browser';
3
3
 
4
4
  export interface GenericEdgeProps {
5
5
  /** Edge ID */
@@ -11,7 +11,7 @@ import type {
11
11
  ComponentActionEvent,
12
12
  EdgeAnimationEvent,
13
13
  PathBasedEvent,
14
- } from '@principal-ai/principal-view-core';
14
+ } from '@principal-ai/principal-view-core/browser';
15
15
  import {
16
16
  logLevelToNodeAnimation,
17
17
  actionToNodeAnimation,
package/src/index.ts CHANGED
@@ -26,7 +26,7 @@ export type {
26
26
  ComponentLibrary,
27
27
  LibraryNodeComponent,
28
28
  LibraryEdgeComponent,
29
- } from '@principal-ai/principal-view-core';
29
+ } from '@principal-ai/principal-view-core/browser';
30
30
 
31
31
  // Export components
32
32
  export { GraphRenderer } from './components/GraphRenderer';
@@ -37,12 +37,6 @@ export type {
37
37
  PendingChanges,
38
38
  } from './components/GraphRenderer';
39
39
 
40
- export { EventLog } from './components/EventLog';
41
- export type { EventLogProps } from './components/EventLog';
42
-
43
- export { MetricsDashboard } from './components/MetricsDashboard';
44
- export type { MetricsDashboardProps } from './components/MetricsDashboard';
45
-
46
40
  export { EdgeInfoPanel } from './components/EdgeInfoPanel';
47
41
  export type { EdgeInfoPanelProps } from './components/EdgeInfoPanel';
48
42
 
@@ -1,7 +1,7 @@
1
1
  import React, { useState, useRef } from 'react';
2
2
  import { Handle, Position, NodeResizer } from '@xyflow/react';
3
3
  import type { NodeProps } from '@xyflow/react';
4
- import type { NodeTypeDefinition } from '@principal-ai/principal-view-core';
4
+ import type { NodeTypeDefinition } from '@principal-ai/principal-view-core/browser';
5
5
  import { resolveIcon } from '../utils/iconResolver';
6
6
  import { NodeTooltip } from '../components/NodeTooltip';
7
7
  import type { OtelInfo } from '../components/NodeTooltip';
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import type { NodeTypeDefinition } from '@principal-ai/principal-view-core';
2
+ import type { NodeTypeDefinition } from '@principal-ai/principal-view-core/browser';
3
3
 
4
4
  export interface GenericNodeProps {
5
5
  /** Node ID */
@@ -5,7 +5,7 @@ import { CustomNode } from '../nodes/CustomNode';
5
5
  import { CustomEdge } from '../edges/CustomEdge';
6
6
  import type { CustomNodeData } from '../nodes/CustomNode';
7
7
  import type { CustomEdgeData } from '../edges/CustomEdge';
8
- import type { NodeTypeDefinition, EdgeTypeDefinition } from '@principal-ai/principal-view-core';
8
+ import type { NodeTypeDefinition, EdgeTypeDefinition } from '@principal-ai/principal-view-core/browser';
9
9
  import React from 'react';
10
10
 
11
11
  const meta = {
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react';
3
3
  import { GraphRenderer } from '../components/GraphRenderer';
4
- import type { ExtendedCanvas } from '@principal-ai/principal-view-core';
4
+ import type { ExtendedCanvas } from '@principal-ai/principal-view-core/browser';
5
5
  import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
6
6
 
7
7
  const meta = {
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react';
3
3
  import { GraphRenderer } from '../components/GraphRenderer';
4
- import type { ExtendedCanvas } from '@principal-ai/principal-view-core';
4
+ import type { ExtendedCanvas } from '@principal-ai/principal-view-core/browser';
5
5
  import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
6
6
 
7
7
  const meta = {
@@ -1,7 +1,7 @@
1
1
  import React, { useState, useEffect } from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react';
3
3
  import { GraphRenderer } from '../components/GraphRenderer';
4
- import type { ExtendedCanvas, GraphEvent } from '@principal-ai/principal-view-core';
4
+ import type { ExtendedCanvas, GraphEvent } from '@principal-ai/principal-view-core/browser';
5
5
  import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
6
6
 
7
7
  // Helper component that sets initial node states via events
@@ -1,6 +1,6 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react';
2
2
  import { GraphRenderer } from '../components/GraphRenderer';
3
- import type { GraphEvent, ExtendedCanvas } from '@principal-ai/principal-view-core';
3
+ import type { GraphEvent, ExtendedCanvas } from '@principal-ai/principal-view-core/browser';
4
4
  import { useState, useEffect } from 'react';
5
5
  import React from 'react';
6
6
  import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react';
3
3
  import { GraphRenderer } from '../components/GraphRenderer';
4
4
  import type { GraphRendererHandle, PendingChanges } from '../components/GraphRenderer';
5
- import type { ExtendedCanvas } from '@principal-ai/principal-view-core';
5
+ import type { ExtendedCanvas } from '@principal-ai/principal-view-core/browser';
6
6
  import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
7
7
 
8
8
  const meta = {
@@ -14,32 +14,15 @@ The core graph visualization component that displays nodes and edges based on yo
14
14
  - Configure node and edge types
15
15
  - Define validation rules
16
16
  - Visualize graph structures
17
-
18
- ### EventLog
19
- Display a log of graph events with violation highlighting.
20
-
21
- - Track all graph operations
22
- - Highlight violations and warnings
23
- - Filter and search events
24
-
25
- ### MetricsDashboard
26
- Show metrics and statistics about your validation graph.
27
-
28
- - Node and edge counts
29
- - Event rates
30
- - Validation health score
31
- - Performance metrics
17
+ - Interactive pan, zoom, and drag controls
18
+ - Auto-layout algorithms
32
19
 
33
20
  ## Getting Started
34
21
 
35
22
  ```tsx
36
- import {
37
- GraphRenderer,
38
- EventLog,
39
- MetricsDashboard,
40
- } from '@principal-ai/visual-validation-react';
23
+ import { GraphRenderer } from '@principal-ai/visual-validation-react';
41
24
 
42
- // Use the components in your application
25
+ // Use the component in your application
43
26
  ```
44
27
 
45
28
  ## Examples
@@ -1,7 +1,7 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react';
2
2
  import { useState } from 'react';
3
3
  import { GraphRenderer } from '../components/GraphRenderer';
4
- import type { ExtendedCanvas } from '@principal-ai/principal-view-core';
4
+ import type { ExtendedCanvas } from '@principal-ai/principal-view-core/browser';
5
5
  import React from 'react';
6
6
  import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
7
7
 
@@ -1,6 +1,6 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react';
2
2
  import { GraphRenderer } from '../components/GraphRenderer';
3
- import type { ExtendedCanvas } from '@principal-ai/principal-view-core';
3
+ import type { ExtendedCanvas } from '@principal-ai/principal-view-core/browser';
4
4
  import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
5
5
 
6
6
  const meta = {
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react';
3
3
  import { GraphRenderer } from '../components/GraphRenderer';
4
- import type { ExtendedCanvas } from '@principal-ai/principal-view-core';
4
+ import type { ExtendedCanvas } from '@principal-ai/principal-view-core/browser';
5
5
  import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
6
6
 
7
7
  const meta = {
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react';
3
3
  import { GraphRenderer } from '../components/GraphRenderer';
4
- import type { ExtendedCanvas } from '@principal-ai/principal-view-core';
4
+ import type { ExtendedCanvas } from '@principal-ai/principal-view-core/browser';
5
5
  import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
6
6
 
7
7
  const meta = {
@@ -4,7 +4,7 @@ import { ThemeProvider } from '@principal-ade/industry-theme';
4
4
  import { GraphRenderer } from '../components/GraphRenderer';
5
5
  import { NodeInfoPanel } from '../components/NodeInfoPanel';
6
6
  import { NodeTooltip } from '../components/NodeTooltip';
7
- import type { NodeState, NodeTypeDefinition } from '@principal-ai/principal-view-core';
7
+ import type { NodeState, NodeTypeDefinition } from '@principal-ai/principal-view-core/browser';
8
8
 
9
9
  // OTEL Log Association canvas data
10
10
  const otelCanvas = {