@principal-ai/principal-view-react 0.7.10 → 0.7.11

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.
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect } from 'react';
1
+ import React, { useState } from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react';
3
3
  import { GraphRenderer } from '../components/GraphRenderer';
4
4
  import { TestEventPanel } from '../components/TestEventPanel';
@@ -183,156 +183,18 @@ const testExecutionCanvas: ExtendedCanvas = {
183
183
  };
184
184
 
185
185
  // ============================================================================
186
- // Convert Test Spans to Graph Events
187
- // ============================================================================
188
-
189
- function convertSpansToEvents(spans: typeof testSpans): GraphEvent[] {
190
- const events: GraphEvent[] = [];
191
- let time = 0;
192
-
193
- spans.forEach((testSpan) => {
194
- // Pulse test suite node at start of each test
195
- events.push({
196
- timestamp: time,
197
- category: 'node',
198
- operation: 'animate',
199
- payload: {
200
- nodeId: 'test-suite',
201
- animation: { type: 'pulse', duration: 500 },
202
- },
203
- });
204
- time += 600;
205
-
206
- // Animate through events in the span
207
- testSpan.events.forEach((event) => {
208
- const eventName = event.name;
209
-
210
- // Determine which phase based on event name
211
- let nodeId = '';
212
- let edgeId = '';
213
-
214
- if (eventName.startsWith('setup.')) {
215
- nodeId = 'setup-phase';
216
- edgeId = 'suite-to-setup';
217
- } else if (eventName.startsWith('execution.')) {
218
- nodeId = 'execution-phase';
219
- edgeId = 'setup-to-execution';
220
- } else if (eventName.startsWith('assertion.')) {
221
- nodeId = 'assertion-phase';
222
- edgeId = 'execution-to-assertion';
223
- }
224
-
225
- // Animate edge when phase starts
226
- if (eventName.endsWith('.started') && edgeId) {
227
- events.push({
228
- timestamp: time,
229
- category: 'edge',
230
- operation: 'animate',
231
- payload: {
232
- edgeId,
233
- animation: { type: 'particle', duration: 500 },
234
- },
235
- });
236
- time += 600;
237
- }
238
-
239
- // Pulse node
240
- if (nodeId) {
241
- events.push({
242
- timestamp: time,
243
- category: 'node',
244
- operation: 'animate',
245
- payload: {
246
- nodeId,
247
- animation: { type: 'pulse', duration: 600 },
248
- },
249
- });
250
- time += 700;
251
- }
252
- });
253
-
254
- // Animate to result
255
- events.push({
256
- timestamp: time,
257
- category: 'edge',
258
- operation: 'animate',
259
- payload: {
260
- edgeId: 'assertion-to-result',
261
- animation: { type: 'particle', duration: 500 },
262
- },
263
- });
264
- time += 600;
265
-
266
- events.push({
267
- timestamp: time,
268
- category: 'node',
269
- operation: 'animate',
270
- payload: {
271
- nodeId: 'test-result',
272
- animation: { type: 'pulse', duration: 800 },
273
- },
274
- });
275
- time += 1200; // Pause between tests
276
- });
277
-
278
- return events;
279
- }
280
-
281
- // ============================================================================
282
- // Animated Story
186
+ // Interactive Story (No Animation)
283
187
  // ============================================================================
284
188
 
285
189
  const AnimatedTestExecution = () => {
286
- const [events, setEvents] = useState<GraphEvent[]>([]);
287
- const [currentSpanIndex, setCurrentSpanIndex] = useState(0);
288
- const [currentEventIndex, setCurrentEventIndex] = useState(0);
190
+ const [events] = useState<GraphEvent[]>([]);
191
+ const [currentSpanIndex] = useState(0);
192
+ // Show all events by default - set to a large number
193
+ const [currentEventIndex] = useState(999);
289
194
  const [highlightedPhase, setHighlightedPhase] = useState<string | undefined>();
290
195
 
291
- useEffect(() => {
292
- const graphEvents = convertSpansToEvents(testSpans);
293
- const timers: NodeJS.Timeout[] = [];
294
-
295
- let spanIndex = 0;
296
- let eventIndex = 0;
297
- let eventsPerTest = testSpans[0].events.length * 2 + 2; // ~2 graph events per span event + suite + result
298
-
299
- graphEvents.forEach((event, index) => {
300
- const timer = setTimeout(() => {
301
- setEvents((prev) => [...prev, event]);
302
-
303
- // Track which span and event we're on
304
- spanIndex = Math.floor(index / eventsPerTest);
305
- eventIndex = Math.floor((index % eventsPerTest) / 2);
306
-
307
- setCurrentSpanIndex(Math.min(spanIndex, testSpans.length - 1));
308
- setCurrentEventIndex(eventIndex);
309
- }, event.timestamp);
310
- timers.push(timer);
311
- });
312
-
313
- // Reset animation
314
- const resetTimer = setTimeout(() => {
315
- setEvents([]);
316
- setCurrentSpanIndex(0);
317
- setCurrentEventIndex(0);
318
- }, graphEvents[graphEvents.length - 1].timestamp + 2000);
319
-
320
- return () => {
321
- timers.forEach(clearTimeout);
322
- clearTimeout(resetTimer);
323
- };
324
- }, []);
325
-
326
- // Map node IDs to phase names
327
- const getPhaseFromNodeId = (nodeId: string): string | undefined => {
328
- if (nodeId === 'setup-phase') return 'setup';
329
- if (nodeId === 'execution-phase') return 'execution';
330
- if (nodeId === 'assertion-phase') return 'assertion';
331
- return undefined;
332
- };
333
-
334
196
  return (
335
- <div style={{ display: 'flex', width: '100%', height: '100%' }}>
197
+ <div style={{ display: 'flex', width: '100vw', height: '100vh' }}>
336
198
  {/* Graph Visualization - Left Side */}
337
199
  <div
338
200
  style={{ flex: '0 0 60%', height: '100%', position: 'relative' }}
@@ -351,7 +213,6 @@ const AnimatedTestExecution = () => {
351
213
  >
352
214
  <GraphRenderer
353
215
  canvas={testExecutionCanvas}
354
- showMinimap={true}
355
216
  showControls={true}
356
217
  events={events}
357
218
  />
@@ -359,7 +220,7 @@ const AnimatedTestExecution = () => {
359
220
  </div>
360
221
 
361
222
  {/* Event Panel - Right Side */}
362
- <div style={{ flex: '0 0 40%', height: '100%', borderLeft: '1px solid #333' }}>
223
+ <div style={{ flex: '0 0 40%', height: '100%', borderLeft: `1px solid #333`, overflow: 'hidden' }}>
363
224
  <TestEventPanel
364
225
  spans={testSpans as any}
365
226
  currentSpanIndex={currentSpanIndex}
@@ -372,7 +233,7 @@ const AnimatedTestExecution = () => {
372
233
  };
373
234
 
374
235
  /**
375
- * Animated visualization of real test execution data using the "wide event" pattern.
236
+ * Interactive visualization of real test execution data using the "wide event" pattern.
376
237
  *
377
238
  * This demonstrates the key concept from loggingsucks.com:
378
239
  * - ONE comprehensive span per test (not multiple child spans)
@@ -383,7 +244,7 @@ const AnimatedTestExecution = () => {
383
244
  * **Interaction:**
384
245
  * - Hover over graph nodes (Setup, Execution, Assertion) to highlight related events
385
246
  * - Watch the code journey: blue = test file, green = code under test
386
- * - See how context builds up through events as the animation plays
247
+ * - All events are shown immediately for easy review
387
248
  */
388
249
  export const Animated: Story = {
389
250
  render: () => <AnimatedTestExecution />,
@@ -395,7 +256,6 @@ export const Animated: Story = {
395
256
  export const StaticView: Story = {
396
257
  args: {
397
258
  canvas: testExecutionCanvas,
398
- showMinimap: true,
399
259
  showControls: true,
400
260
  },
401
261
  };
@@ -412,7 +272,7 @@ export const EventPanelOnly: StoryObj = {
412
272
  <TestEventPanel
413
273
  spans={testSpans as any}
414
274
  currentSpanIndex={0}
415
- currentEventIndex={5} // Show all events
275
+ currentEventIndex={999} // Show all events
416
276
  highlightedPhase={undefined}
417
277
  />
418
278
  </div>
@@ -52,7 +52,6 @@ type Story = StoryObj<typeof meta>;
52
52
  export const ExecutionFlow: Story = {
53
53
  args: {
54
54
  canvas: executionCanvas as ExtendedCanvas,
55
- showMinimap: true,
56
55
  showControls: true,
57
56
  },
58
57
  };
@@ -68,7 +67,7 @@ export const ExecutionFlow: Story = {
68
67
  *
69
68
  * All events in this panel passed schema validation.
70
69
  */
71
- export const ValidatedEvents: StoryObj = {
70
+ export const ValidatedEvents: Story = {
72
71
  render: () => (
73
72
  <div style={{ width: '800px', height: '100vh' }}>
74
73
  <TestEventPanel
@@ -93,14 +92,13 @@ export const ValidatedEvents: StoryObj = {
93
92
  *
94
93
  * This ensures production code emits events that match the architecture.
95
94
  */
96
- export const FlowWithValidation: StoryObj = {
95
+ export const FlowWithValidation: Story = {
97
96
  render: () => (
98
97
  <div style={{ display: 'flex', width: '100%', height: '100%' }}>
99
98
  {/* Graph Visualization - Left Side */}
100
99
  <div style={{ flex: '0 0 60%', height: '100%', position: 'relative' }}>
101
100
  <GraphRenderer
102
101
  canvas={executionCanvas as ExtendedCanvas}
103
- showMinimap={true}
104
102
  showControls={true}
105
103
  />
106
104
  </div>
@@ -136,7 +134,7 @@ export const FlowWithValidation: StoryObj = {
136
134
  * - Event descriptions
137
135
  * - Field schemas with types and requirements
138
136
  */
139
- export const CanvasSchema: StoryObj = {
137
+ export const CanvasSchema: Story = {
140
138
  render: () => (
141
139
  <div
142
140
  style={{