@principal-ai/principal-view-react 0.13.20 → 0.13.22
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/dist/components/GraphRenderer.d.ts.map +1 -1
- package/dist/components/GraphRenderer.js +35 -24
- package/dist/components/GraphRenderer.js.map +1 -1
- package/dist/components/NodeTooltip.d.ts +4 -1
- package/dist/components/NodeTooltip.d.ts.map +1 -1
- package/dist/components/NodeTooltip.js +20 -13
- package/dist/components/NodeTooltip.js.map +1 -1
- package/dist/contexts/GraphEditContext.d.ts +14 -0
- package/dist/contexts/GraphEditContext.d.ts.map +1 -0
- package/dist/contexts/GraphEditContext.js +8 -0
- package/dist/contexts/GraphEditContext.js.map +1 -0
- package/dist/nodes/CustomNode.d.ts.map +1 -1
- package/dist/nodes/CustomNode.js +76 -19
- package/dist/nodes/CustomNode.js.map +1 -1
- package/package.json +2 -2
- package/src/components/GraphRenderer.tsx +46 -32
- package/src/components/NodeTooltip.tsx +40 -21
- package/src/contexts/GraphEditContext.tsx +21 -0
- package/src/nodes/CustomNode.tsx +107 -18
- package/src/stories/DiamondBadges.stories.tsx +184 -0
- package/src/stories/GraphRenderer.stories.tsx +0 -4
- package/src/stories/NodeDefinitionComparison.stories.tsx +2 -4
- package/src/stories/OtelComponents.stories.tsx +1 -4
- package/src/stories/data/graph-converter-test-execution.json +48 -48
package/src/nodes/CustomNode.tsx
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import React, { useState, useRef } from 'react';
|
|
2
|
-
import { Handle, Position, NodeResizer } from '@xyflow/react';
|
|
1
|
+
import React, { useState, useRef, useCallback } from 'react';
|
|
2
|
+
import { Handle, Position, NodeResizer, useNodeId } from '@xyflow/react';
|
|
3
3
|
import type { NodeProps, Node } from '@xyflow/react';
|
|
4
4
|
import type { NodeTypeDefinition } from '@principal-ai/principal-view-core';
|
|
5
5
|
import { useTheme } from '@principal-ade/industry-theme';
|
|
6
6
|
import { resolveIcon } from '../utils/iconResolver';
|
|
7
7
|
import { NodeTooltip } from '../components/NodeTooltip';
|
|
8
8
|
import type { OtelInfo } from '../components/NodeTooltip';
|
|
9
|
+
import { useGraphEdit } from '../contexts/GraphEditContext';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Converts a hex color to a lighter/tinted version (opaque, not transparent)
|
|
@@ -63,6 +64,8 @@ export interface CustomNodeData extends Record<string, unknown> {
|
|
|
63
64
|
*/
|
|
64
65
|
export const CustomNode: React.FC<NodeProps<Node<CustomNodeData>>> = ({ data, selected, dragging }) => {
|
|
65
66
|
const { theme } = useTheme();
|
|
67
|
+
const { onNodeResizeEnd } = useGraphEdit();
|
|
68
|
+
const nodeId = useNodeId();
|
|
66
69
|
const [isHovered, setIsHovered] = useState(false);
|
|
67
70
|
const nodeRef = useRef<HTMLDivElement>(null);
|
|
68
71
|
const nodeProps = data;
|
|
@@ -86,10 +89,26 @@ export const CustomNode: React.FC<NodeProps<Node<CustomNodeData>>> = ({ data, se
|
|
|
86
89
|
// Inactive nodes (scenario filtering) are dimmed to 0.1
|
|
87
90
|
const nodeOpacity = isHidden ? 0.4 : isActive ? 1 : 0.1;
|
|
88
91
|
|
|
92
|
+
// Handle resize end - notify parent to track the dimension change
|
|
93
|
+
const handleResizeEnd = useCallback(
|
|
94
|
+
(_event: unknown, params: { width: number; height: number }) => {
|
|
95
|
+
if (nodeId && onNodeResizeEnd && params.width && params.height) {
|
|
96
|
+
onNodeResizeEnd(nodeId, {
|
|
97
|
+
width: Math.round(params.width),
|
|
98
|
+
height: Math.round(params.height),
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
[nodeId, onNodeResizeEnd]
|
|
103
|
+
);
|
|
104
|
+
|
|
89
105
|
// DEBUG: Log ALL node data to understand structure
|
|
90
106
|
console.log('[CustomNode] Node data:', {
|
|
91
107
|
name: nodeProps.name,
|
|
92
108
|
nodeDataKeys: nodeData ? Object.keys(nodeData).join(', ') : 'undefined',
|
|
109
|
+
references: nodeData?.references,
|
|
110
|
+
otelFiles: (nodeData?.otel as { files?: string[] })?.files,
|
|
111
|
+
sources: nodeData?.sources,
|
|
93
112
|
fullNodeData: nodeData,
|
|
94
113
|
});
|
|
95
114
|
|
|
@@ -99,10 +118,13 @@ export const CustomNode: React.FC<NodeProps<Node<CustomNodeData>>> = ({ data, se
|
|
|
99
118
|
const showTooltip =
|
|
100
119
|
(isHovered && !dragging && shiftKeyPressed) || (!editable && !!selected);
|
|
101
120
|
|
|
102
|
-
// Extract OTEL info, description, and
|
|
103
|
-
const otelInfo = nodeData?.otel as OtelInfo | undefined;
|
|
121
|
+
// Extract OTEL info, description, sources/files, and references for tooltip
|
|
122
|
+
const otelInfo = nodeData?.otel as (OtelInfo & { files?: string[] }) | undefined;
|
|
104
123
|
const description = nodeData?.description as string | undefined;
|
|
105
|
-
const sources = nodeData?.sources as string[] | undefined;
|
|
124
|
+
const sources = nodeData?.sources as string[] | undefined; // deprecated
|
|
125
|
+
const references = nodeData?.references as string[] | undefined;
|
|
126
|
+
// Files from otel.files - these are source code files where the event is instrumented
|
|
127
|
+
const files = otelInfo?.files;
|
|
106
128
|
|
|
107
129
|
// Get badge shape styles based on node shape
|
|
108
130
|
const getBadgeShapeStyles = (): React.CSSProperties => {
|
|
@@ -141,24 +163,28 @@ export const CustomNode: React.FC<NodeProps<Node<CustomNodeData>>> = ({ data, se
|
|
|
141
163
|
};
|
|
142
164
|
|
|
143
165
|
// Get badge position based on shape - diamonds need badges at their points, not bounding box corners
|
|
144
|
-
const getBadgePosition = (position: 'top-left' | 'top-right' | 'left' | 'right'): React.CSSProperties => {
|
|
166
|
+
const getBadgePosition = (position: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'left' | 'right' | 'top' | 'bottom'): React.CSSProperties => {
|
|
145
167
|
const isDiamondShape = typeDefinition.shape === 'diamond';
|
|
146
168
|
|
|
147
169
|
if (isDiamondShape) {
|
|
148
170
|
// Diamond points are at the middle of each edge of the bounding box
|
|
149
171
|
switch (position) {
|
|
150
172
|
case 'top-left':
|
|
151
|
-
// Position at the LEFT point of the diamond (center-left)
|
|
152
|
-
return { top: '50%', left: 0, transform: 'translate(-50%, -50%)' };
|
|
153
|
-
case 'top-right':
|
|
154
|
-
// Position at the RIGHT point of the diamond (center-right)
|
|
155
|
-
return { top: '50%', right: 0, transform: 'translate(50%, -50%)' };
|
|
156
173
|
case 'left':
|
|
157
174
|
// Position at the LEFT point of the diamond (center-left)
|
|
158
175
|
return { top: '50%', left: 0, transform: 'translate(-50%, -50%)' };
|
|
176
|
+
case 'top-right':
|
|
159
177
|
case 'right':
|
|
160
178
|
// Position at the RIGHT point of the diamond (center-right)
|
|
161
179
|
return { top: '50%', right: 0, transform: 'translate(50%, -50%)' };
|
|
180
|
+
case 'top':
|
|
181
|
+
// Position at the TOP point of the diamond
|
|
182
|
+
return { top: 0, left: '50%', transform: 'translate(-50%, -50%)' };
|
|
183
|
+
case 'bottom':
|
|
184
|
+
case 'bottom-left':
|
|
185
|
+
case 'bottom-right':
|
|
186
|
+
// Position at the BOTTOM point of the diamond
|
|
187
|
+
return { bottom: 0, left: '50%', transform: 'translate(-50%, 50%)' };
|
|
162
188
|
}
|
|
163
189
|
}
|
|
164
190
|
|
|
@@ -168,17 +194,27 @@ export const CustomNode: React.FC<NodeProps<Node<CustomNodeData>>> = ({ data, se
|
|
|
168
194
|
return { top: -6, left: -6 };
|
|
169
195
|
case 'top-right':
|
|
170
196
|
return { top: -6, right: -6 };
|
|
197
|
+
case 'bottom-left':
|
|
198
|
+
return { bottom: -6, left: -6 };
|
|
199
|
+
case 'bottom-right':
|
|
200
|
+
return { bottom: -6, right: -6 };
|
|
171
201
|
case 'left':
|
|
172
202
|
return { top: -6, left: -6 };
|
|
173
203
|
case 'right':
|
|
174
204
|
return { top: -6, right: -6 };
|
|
205
|
+
case 'top':
|
|
206
|
+
return { top: -6, left: '50%', transform: 'translateX(-50%)' };
|
|
207
|
+
case 'bottom':
|
|
208
|
+
return { bottom: -6, left: '50%', transform: 'translateX(-50%)' };
|
|
175
209
|
}
|
|
176
210
|
};
|
|
177
211
|
|
|
178
|
-
// Render Sources badge (top-right
|
|
212
|
+
// Render Sources badge (top-right) - shows "S" for files where event is instrumented
|
|
179
213
|
const renderSourcesBadge = () => {
|
|
180
|
-
|
|
181
|
-
|
|
214
|
+
// Use otel.files (source code files where event is instrumented)
|
|
215
|
+
// Fall back to deprecated sources field for backwards compatibility
|
|
216
|
+
const sourceFiles = files || sources;
|
|
217
|
+
if (!sourceFiles || sourceFiles.length === 0) return null;
|
|
182
218
|
|
|
183
219
|
const shapeStyles = getBadgeShapeStyles();
|
|
184
220
|
const positionStyles = getBadgePosition('top-right');
|
|
@@ -203,13 +239,47 @@ export const CustomNode: React.FC<NodeProps<Node<CustomNodeData>>> = ({ data, se
|
|
|
203
239
|
zIndex: 10,
|
|
204
240
|
opacity: nodeOpacity,
|
|
205
241
|
}}
|
|
206
|
-
title={`
|
|
242
|
+
title={`Source files: ${sourceFiles.join(', ')}`}
|
|
207
243
|
>
|
|
208
244
|
<span style={{ transform: shapeStyles.transform ? 'rotate(-45deg)' : undefined }}>S</span>
|
|
209
245
|
</div>
|
|
210
246
|
);
|
|
211
247
|
};
|
|
212
248
|
|
|
249
|
+
// Render References badge (bottom-left for rectangles, bottom for diamonds) - shows "R" for external references
|
|
250
|
+
const renderReferencesBadge = () => {
|
|
251
|
+
if (!references || references.length === 0) return null;
|
|
252
|
+
|
|
253
|
+
const shapeStyles = getBadgeShapeStyles();
|
|
254
|
+
const positionStyles = getBadgePosition('bottom-left');
|
|
255
|
+
|
|
256
|
+
return (
|
|
257
|
+
<div
|
|
258
|
+
style={{
|
|
259
|
+
position: 'absolute',
|
|
260
|
+
...positionStyles,
|
|
261
|
+
...shapeStyles,
|
|
262
|
+
// Override transform if shape has rotation but we already have a position transform
|
|
263
|
+
...(typeDefinition.shape === 'diamond' ? { transform: `${positionStyles.transform} rotate(45deg)` } : {}),
|
|
264
|
+
backgroundColor: '#8b5cf6', // Purple for references
|
|
265
|
+
color: 'white',
|
|
266
|
+
fontSize: theme.fontSizes[0],
|
|
267
|
+
fontWeight: theme.fontWeights.bold,
|
|
268
|
+
fontFamily: theme.fonts.body,
|
|
269
|
+
display: 'flex',
|
|
270
|
+
alignItems: 'center',
|
|
271
|
+
justifyContent: 'center',
|
|
272
|
+
boxShadow: '0 1px 3px rgba(0,0,0,0.3)',
|
|
273
|
+
zIndex: 10,
|
|
274
|
+
opacity: nodeOpacity,
|
|
275
|
+
}}
|
|
276
|
+
title={`References: ${references.join(', ')}`}
|
|
277
|
+
>
|
|
278
|
+
<span style={{ transform: shapeStyles.transform ? 'rotate(-45deg)' : undefined }}>R</span>
|
|
279
|
+
</div>
|
|
280
|
+
);
|
|
281
|
+
};
|
|
282
|
+
|
|
213
283
|
// Render Boundary badge (right/left points) - shown instead of sources badge for boundary nodes
|
|
214
284
|
const renderBoundaryBadge = () => {
|
|
215
285
|
const boundary = nodeData?.boundary as { direction?: 'outbound' | 'inbound'; node?: Record<string, string> } | undefined;
|
|
@@ -619,6 +689,7 @@ export const CustomNode: React.FC<NodeProps<Node<CustomNodeData>>> = ({ data, se
|
|
|
619
689
|
minWidth={minWidth}
|
|
620
690
|
minHeight={minHeight}
|
|
621
691
|
keepAspectRatio={keepAspectRatio}
|
|
692
|
+
onResizeEnd={handleResizeEnd}
|
|
622
693
|
handleStyle={{
|
|
623
694
|
width: 8,
|
|
624
695
|
height: 8,
|
|
@@ -662,7 +733,12 @@ export const CustomNode: React.FC<NodeProps<Node<CustomNodeData>>> = ({ data, se
|
|
|
662
733
|
onMouseLeave={() => setIsHovered(false)}
|
|
663
734
|
>
|
|
664
735
|
{renderStatusBadge()}
|
|
665
|
-
{isBoundaryNode ? renderBoundaryBadge() :
|
|
736
|
+
{isBoundaryNode ? renderBoundaryBadge() : (
|
|
737
|
+
<>
|
|
738
|
+
{renderSourcesBadge()}
|
|
739
|
+
{renderReferencesBadge()}
|
|
740
|
+
</>
|
|
741
|
+
)}
|
|
666
742
|
<div style={hexagonBorderStyle} className={animationClass}>
|
|
667
743
|
<div style={hexagonInnerStyle}>
|
|
668
744
|
{icon && (
|
|
@@ -705,6 +781,7 @@ export const CustomNode: React.FC<NodeProps<Node<CustomNodeData>>> = ({ data, se
|
|
|
705
781
|
description={description}
|
|
706
782
|
otel={otelInfo}
|
|
707
783
|
sources={sources}
|
|
784
|
+
references={references}
|
|
708
785
|
visible={showTooltip}
|
|
709
786
|
nodeRef={nodeRef}
|
|
710
787
|
/>
|
|
@@ -728,7 +805,12 @@ export const CustomNode: React.FC<NodeProps<Node<CustomNodeData>>> = ({ data, se
|
|
|
728
805
|
onMouseLeave={() => setIsHovered(false)}
|
|
729
806
|
>
|
|
730
807
|
{renderStatusBadge()}
|
|
731
|
-
{isBoundaryNode ? renderBoundaryBadge() :
|
|
808
|
+
{isBoundaryNode ? renderBoundaryBadge() : (
|
|
809
|
+
<>
|
|
810
|
+
{renderSourcesBadge()}
|
|
811
|
+
{renderReferencesBadge()}
|
|
812
|
+
</>
|
|
813
|
+
)}
|
|
732
814
|
<div style={diamondBorderStyle} className={animationClass}>
|
|
733
815
|
<div style={diamondInnerStyle}>
|
|
734
816
|
{icon && (
|
|
@@ -771,6 +853,7 @@ export const CustomNode: React.FC<NodeProps<Node<CustomNodeData>>> = ({ data, se
|
|
|
771
853
|
description={description}
|
|
772
854
|
otel={otelInfo}
|
|
773
855
|
sources={sources}
|
|
856
|
+
references={references}
|
|
774
857
|
visible={showTooltip}
|
|
775
858
|
nodeRef={nodeRef}
|
|
776
859
|
/>
|
|
@@ -784,7 +867,12 @@ export const CustomNode: React.FC<NodeProps<Node<CustomNodeData>>> = ({ data, se
|
|
|
784
867
|
onMouseLeave={() => setIsHovered(false)}
|
|
785
868
|
>
|
|
786
869
|
{renderStatusBadge()}
|
|
787
|
-
{isBoundaryNode ? renderBoundaryBadge() :
|
|
870
|
+
{isBoundaryNode ? renderBoundaryBadge() : (
|
|
871
|
+
<>
|
|
872
|
+
{renderSourcesBadge()}
|
|
873
|
+
{renderReferencesBadge()}
|
|
874
|
+
</>
|
|
875
|
+
)}
|
|
788
876
|
<div style={getShapeStyles()} className={animationClass}>
|
|
789
877
|
{/* Inner content */}
|
|
790
878
|
<div
|
|
@@ -852,6 +940,7 @@ export const CustomNode: React.FC<NodeProps<Node<CustomNodeData>>> = ({ data, se
|
|
|
852
940
|
description={description}
|
|
853
941
|
otel={otelInfo}
|
|
854
942
|
sources={sources}
|
|
943
|
+
references={references}
|
|
855
944
|
visible={showTooltip}
|
|
856
945
|
nodeRef={nodeRef}
|
|
857
946
|
/>
|
|
@@ -443,3 +443,187 @@ The badges on diamond nodes are positioned at the actual points of the diamond s
|
|
|
443
443
|
},
|
|
444
444
|
},
|
|
445
445
|
};
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Canvas demonstrating the new files (S) and references (R) badges
|
|
449
|
+
*/
|
|
450
|
+
const filesAndReferencesCanvas: ExtendedCanvas = {
|
|
451
|
+
nodes: [
|
|
452
|
+
// Node with otel.files only (S badge)
|
|
453
|
+
{
|
|
454
|
+
id: 'files-only',
|
|
455
|
+
type: 'text',
|
|
456
|
+
x: 100,
|
|
457
|
+
y: 100,
|
|
458
|
+
width: 140,
|
|
459
|
+
height: 80,
|
|
460
|
+
text: 'Files Only',
|
|
461
|
+
color: 4, // green
|
|
462
|
+
pv: {
|
|
463
|
+
nodeType: 'event',
|
|
464
|
+
shape: 'rectangle',
|
|
465
|
+
icon: 'FileCode',
|
|
466
|
+
otel: {
|
|
467
|
+
kind: 'type',
|
|
468
|
+
files: ['src/auth/login.ts', 'src/auth/logout.ts'],
|
|
469
|
+
},
|
|
470
|
+
},
|
|
471
|
+
},
|
|
472
|
+
// Node with references only (R badge)
|
|
473
|
+
{
|
|
474
|
+
id: 'refs-only',
|
|
475
|
+
type: 'text',
|
|
476
|
+
x: 300,
|
|
477
|
+
y: 100,
|
|
478
|
+
width: 140,
|
|
479
|
+
height: 80,
|
|
480
|
+
text: 'Refs Only',
|
|
481
|
+
color: 6, // purple
|
|
482
|
+
pv: {
|
|
483
|
+
nodeType: 'event',
|
|
484
|
+
shape: 'rectangle',
|
|
485
|
+
icon: 'ExternalLink',
|
|
486
|
+
references: ['@opentelemetry/api', 'https://opentelemetry.io/docs'],
|
|
487
|
+
},
|
|
488
|
+
},
|
|
489
|
+
// Node with both files and references (S + R badges)
|
|
490
|
+
{
|
|
491
|
+
id: 'both-badges',
|
|
492
|
+
type: 'text',
|
|
493
|
+
x: 500,
|
|
494
|
+
y: 100,
|
|
495
|
+
width: 140,
|
|
496
|
+
height: 80,
|
|
497
|
+
text: 'Both Badges',
|
|
498
|
+
color: 2, // orange
|
|
499
|
+
pv: {
|
|
500
|
+
nodeType: 'event',
|
|
501
|
+
shape: 'rectangle',
|
|
502
|
+
icon: 'Layers',
|
|
503
|
+
otel: {
|
|
504
|
+
kind: 'service',
|
|
505
|
+
files: ['src/api/handler.ts'],
|
|
506
|
+
},
|
|
507
|
+
references: ['@principal-ai/core'],
|
|
508
|
+
},
|
|
509
|
+
},
|
|
510
|
+
// Diamond with files
|
|
511
|
+
{
|
|
512
|
+
id: 'diamond-files',
|
|
513
|
+
type: 'text',
|
|
514
|
+
x: 100,
|
|
515
|
+
y: 250,
|
|
516
|
+
width: 100,
|
|
517
|
+
height: 100,
|
|
518
|
+
text: 'Files',
|
|
519
|
+
color: 4,
|
|
520
|
+
pv: {
|
|
521
|
+
nodeType: 'decision',
|
|
522
|
+
shape: 'diamond',
|
|
523
|
+
icon: 'FileCode',
|
|
524
|
+
otel: {
|
|
525
|
+
kind: 'type',
|
|
526
|
+
files: ['src/router.ts'],
|
|
527
|
+
},
|
|
528
|
+
},
|
|
529
|
+
},
|
|
530
|
+
// Diamond with references
|
|
531
|
+
{
|
|
532
|
+
id: 'diamond-refs',
|
|
533
|
+
type: 'text',
|
|
534
|
+
x: 280,
|
|
535
|
+
y: 250,
|
|
536
|
+
width: 100,
|
|
537
|
+
height: 100,
|
|
538
|
+
text: 'Refs',
|
|
539
|
+
color: 6,
|
|
540
|
+
pv: {
|
|
541
|
+
nodeType: 'decision',
|
|
542
|
+
shape: 'diamond',
|
|
543
|
+
icon: 'ExternalLink',
|
|
544
|
+
references: ['https://docs.example.com'],
|
|
545
|
+
},
|
|
546
|
+
},
|
|
547
|
+
// Diamond with both
|
|
548
|
+
{
|
|
549
|
+
id: 'diamond-both',
|
|
550
|
+
type: 'text',
|
|
551
|
+
x: 460,
|
|
552
|
+
y: 250,
|
|
553
|
+
width: 100,
|
|
554
|
+
height: 100,
|
|
555
|
+
text: 'Both',
|
|
556
|
+
color: 2,
|
|
557
|
+
pv: {
|
|
558
|
+
nodeType: 'decision',
|
|
559
|
+
shape: 'diamond',
|
|
560
|
+
icon: 'Layers',
|
|
561
|
+
otel: {
|
|
562
|
+
kind: 'instance',
|
|
563
|
+
files: ['src/decision.ts'],
|
|
564
|
+
},
|
|
565
|
+
references: ['@some/package'],
|
|
566
|
+
},
|
|
567
|
+
},
|
|
568
|
+
// Circle with both badges
|
|
569
|
+
{
|
|
570
|
+
id: 'circle-both',
|
|
571
|
+
type: 'text',
|
|
572
|
+
x: 640,
|
|
573
|
+
y: 250,
|
|
574
|
+
width: 100,
|
|
575
|
+
height: 100,
|
|
576
|
+
text: 'Circle',
|
|
577
|
+
color: 5,
|
|
578
|
+
pv: {
|
|
579
|
+
nodeType: 'event',
|
|
580
|
+
shape: 'circle',
|
|
581
|
+
icon: 'Circle',
|
|
582
|
+
otel: {
|
|
583
|
+
kind: 'service',
|
|
584
|
+
files: ['src/service.ts'],
|
|
585
|
+
},
|
|
586
|
+
references: ['https://api.docs.com'],
|
|
587
|
+
},
|
|
588
|
+
},
|
|
589
|
+
],
|
|
590
|
+
edges: [],
|
|
591
|
+
pv: {
|
|
592
|
+
version: '1.0.0',
|
|
593
|
+
name: 'Files and References Badges',
|
|
594
|
+
description: 'Demonstrates otel.files (S) and references (R) badges',
|
|
595
|
+
edgeTypes: {},
|
|
596
|
+
},
|
|
597
|
+
};
|
|
598
|
+
|
|
599
|
+
export const FilesAndReferences: Story = {
|
|
600
|
+
args: {
|
|
601
|
+
canvas: filesAndReferencesCanvas,
|
|
602
|
+
width: 850,
|
|
603
|
+
height: 450,
|
|
604
|
+
},
|
|
605
|
+
parameters: {
|
|
606
|
+
docs: {
|
|
607
|
+
description: {
|
|
608
|
+
story: `
|
|
609
|
+
**Files (S) and References (R) Badges**
|
|
610
|
+
|
|
611
|
+
Two types of badges indicate different metadata:
|
|
612
|
+
|
|
613
|
+
- **S badge** (green): Shows source files where the event is instrumented (\`pv.otel.files\`)
|
|
614
|
+
- **R badge** (purple): Shows external references like packages or documentation (\`pv.references\`)
|
|
615
|
+
|
|
616
|
+
**Row 1 - Rectangles:**
|
|
617
|
+
- Files Only: Has \`otel.files\` → shows S badge
|
|
618
|
+
- Refs Only: Has \`references\` → shows R badge
|
|
619
|
+
- Both Badges: Has both → shows S and R badges side by side
|
|
620
|
+
|
|
621
|
+
**Row 2 - Other Shapes:**
|
|
622
|
+
- Diamond, Circle shapes with various badge combinations
|
|
623
|
+
|
|
624
|
+
Hover over nodes to see the full file paths and reference URLs in the tooltip.
|
|
625
|
+
`,
|
|
626
|
+
},
|
|
627
|
+
},
|
|
628
|
+
},
|
|
629
|
+
};
|
|
@@ -676,7 +676,6 @@ const otelLogAssociationCanvas: ExtendedCanvas = {
|
|
|
676
676
|
otel: {
|
|
677
677
|
kind: 'type',
|
|
678
678
|
category: 'log',
|
|
679
|
-
isNew: true,
|
|
680
679
|
},
|
|
681
680
|
shape: 'rectangle',
|
|
682
681
|
icon: 'FileText',
|
|
@@ -737,7 +736,6 @@ const otelLogAssociationCanvas: ExtendedCanvas = {
|
|
|
737
736
|
otel: {
|
|
738
737
|
kind: 'service',
|
|
739
738
|
category: 'router',
|
|
740
|
-
isNew: true,
|
|
741
739
|
},
|
|
742
740
|
shape: 'hexagon',
|
|
743
741
|
icon: 'GitBranch',
|
|
@@ -861,7 +859,6 @@ const otelLogAssociationCanvas: ExtendedCanvas = {
|
|
|
861
859
|
otel: {
|
|
862
860
|
kind: 'service',
|
|
863
861
|
category: 'collector',
|
|
864
|
-
isNew: true,
|
|
865
862
|
},
|
|
866
863
|
shape: 'hexagon',
|
|
867
864
|
icon: 'BarChart2',
|
|
@@ -884,7 +881,6 @@ const otelLogAssociationCanvas: ExtendedCanvas = {
|
|
|
884
881
|
otel: {
|
|
885
882
|
kind: 'type',
|
|
886
883
|
category: 'audit',
|
|
887
|
-
isNew: true,
|
|
888
884
|
},
|
|
889
885
|
shape: 'rectangle',
|
|
890
886
|
icon: 'AlertTriangle',
|
|
@@ -149,8 +149,7 @@ export const BasicOtelEventNode: Story = {
|
|
|
149
149
|
icon: "Play",
|
|
150
150
|
otel: {
|
|
151
151
|
kind: "event",
|
|
152
|
-
category: "lifecycle"
|
|
153
|
-
isNew: true
|
|
152
|
+
category: "lifecycle"
|
|
154
153
|
},
|
|
155
154
|
event: {
|
|
156
155
|
name: "analysis.started",
|
|
@@ -343,8 +342,7 @@ export const NodeWithStateAndViolations: Story = {
|
|
|
343
342
|
icon: "XCircle",
|
|
344
343
|
otel: {
|
|
345
344
|
kind: "event",
|
|
346
|
-
category: "error"
|
|
347
|
-
isNew: false
|
|
345
|
+
category: "error"
|
|
348
346
|
},
|
|
349
347
|
event: {
|
|
350
348
|
name: "validation.error",
|
|
@@ -37,7 +37,6 @@ interface OtelLog {
|
|
|
37
37
|
otel: {
|
|
38
38
|
kind: 'type',
|
|
39
39
|
category: 'log',
|
|
40
|
-
isNew: true,
|
|
41
40
|
},
|
|
42
41
|
shape: 'rectangle',
|
|
43
42
|
icon: 'FileText',
|
|
@@ -69,7 +68,6 @@ Routes incoming OTEL logs to canvas nodes based on matching criteria.
|
|
|
69
68
|
otel: {
|
|
70
69
|
kind: 'service',
|
|
71
70
|
category: 'router',
|
|
72
|
-
isNew: true,
|
|
73
71
|
},
|
|
74
72
|
shape: 'hexagon',
|
|
75
73
|
icon: 'GitBranch',
|
|
@@ -92,7 +90,6 @@ Routes incoming OTEL logs to canvas nodes based on matching criteria.
|
|
|
92
90
|
otel: {
|
|
93
91
|
kind: 'type',
|
|
94
92
|
category: 'audit',
|
|
95
|
-
isNew: true,
|
|
96
93
|
},
|
|
97
94
|
shape: 'rectangle',
|
|
98
95
|
icon: 'AlertTriangle',
|
|
@@ -210,7 +207,7 @@ export const TooltipVariants: StoryObj = {
|
|
|
210
207
|
</div>
|
|
211
208
|
<NodeTooltip
|
|
212
209
|
description="OpenTelemetry log record with timestamp, severity, body"
|
|
213
|
-
otel={{ kind: 'type', category: 'log'
|
|
210
|
+
otel={{ kind: 'type', category: 'log' }}
|
|
214
211
|
visible={true}
|
|
215
212
|
/>
|
|
216
213
|
</div>
|