@principal-ai/subsystems-react 0.17.0 → 0.18.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.
- package/dist/index.d.ts +7 -44
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -32
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +9 -199
- package/src/components/ConfigurationSelector.tsx +0 -133
- package/src/components/GraphRenderer.tsx +0 -3195
- package/src/components/MultiCanvasRenderer.tsx +0 -295
- package/src/components/NodeTooltip.tsx +0 -279
- package/src/components/PendingChanges.test.tsx +0 -375
- package/src/components/SelectionSidebar.tsx +0 -352
- package/src/components/SequenceDiagramRenderer.tsx +0 -1156
- package/src/components/WorkflowSequenceDiagram.tsx +0 -270
- package/src/components/dashboard/DashboardRenderer.tsx +0 -317
- package/src/components/dashboard/MetricPanel.tsx +0 -254
- package/src/components/dashboard/MockDataProvider.ts +0 -330
- package/src/components/dashboard/components/BarChart.tsx +0 -299
- package/src/components/dashboard/components/LineChart.tsx +0 -279
- package/src/components/dashboard/components/MetricCard.tsx +0 -270
- package/src/components/dashboard/components/SourceLink.tsx +0 -63
- package/src/components/dashboard/components/TimeRangeSelector.tsx +0 -280
- package/src/components/dashboard/components/index.ts +0 -5
- package/src/components/dashboard/index.ts +0 -47
- package/src/components/dashboard/types.ts +0 -126
- package/src/components/state-view/PipelineView.tsx +0 -347
- package/src/components/state-view/index.ts +0 -14
- package/src/components/state-view/types.ts +0 -261
- package/src/components/state-view/useStateView.ts +0 -205
- package/src/contexts/GraphEditContext.tsx +0 -27
- package/src/contexts/TooltipPortalContext.ts +0 -8
- package/src/edges/CustomEdge.tsx +0 -402
- package/src/edges/GenericEdge.tsx +0 -36
- package/src/hooks/usePathBasedEvents.ts +0 -192
- package/src/hooks/useSequenceLayout.ts +0 -543
- package/src/hooks/useUndoRedo.ts +0 -144
- package/src/nodes/CustomNode.tsx +0 -1231
- package/src/nodes/GenericNode.tsx +0 -55
- package/src/nodes/otel/OtelBoundaryNode.tsx +0 -224
- package/src/nodes/otel/OtelEventNode.tsx +0 -225
- package/src/nodes/otel/OtelResourceNode.tsx +0 -251
- package/src/nodes/otel/OtelScopeNode.tsx +0 -221
- package/src/nodes/otel/OtelSpanConventionNode.tsx +0 -295
- package/src/nodes/otel/index.ts +0 -23
- package/src/nodes/otel/shared/NodeBadges.tsx +0 -295
- package/src/nodes/otel/shared/NodeContent.tsx +0 -204
- package/src/nodes/otel/shared/index.ts +0 -8
- package/src/nodes/otel/shared/types.ts +0 -138
- package/src/nodes/otel/shared/useNodeBehavior.ts +0 -114
- package/src/stories/Audit/BoundaryNodes.stories.tsx +0 -385
- package/src/stories/Audit/CanvasEdgeTypes.stories.tsx +0 -1448
- package/src/stories/Audit/CanvasNodeTypes.stories.tsx +0 -1049
- package/src/stories/Audit/ColorPriority.stories.tsx +0 -895
- package/src/stories/Audit/DiamondBadges.stories.tsx +0 -629
- package/src/stories/Audit/NodeDimensionsTesting.stories.tsx +0 -724
- package/src/stories/Audit/NodeFieldsAudit.stories.tsx +0 -996
- package/src/stories/Audit/NodeFontSizeTesting.stories.tsx +0 -715
- package/src/stories/Audit/NodeShapes.stories.tsx +0 -1208
- package/src/stories/Audit/WideNodesTesting.stories.tsx +0 -1045
- package/src/stories/Components/DashboardRenderer.stories.tsx +0 -263
- package/src/stories/Components/GraphRenderer.stories.tsx +0 -3236
- package/src/stories/Components/MultiCanvasRenderer.stories.tsx +0 -370
- package/src/stories/Components/SequenceDiagram.stories.tsx +0 -255
- package/src/stories/Components/StateView.stories.tsx +0 -417
- package/src/stories/Components/TraceViewer.stories.tsx +0 -442
- package/src/stories/Components/WorkflowSequenceDiagram.stories.tsx +0 -802
- package/src/stories/Features/AnimationWorkshop.stories.tsx +0 -727
- package/src/stories/Features/ChangeTypeVisual.stories.tsx +0 -67
- package/src/stories/Features/EventDrivenAnimations.stories.tsx +0 -513
- package/src/stories/Features/MultiConfig.stories.tsx +0 -539
- package/src/stories/Layout/ElkEdgeRouting.stories.tsx +0 -539
- package/src/stories/Layout/GraphOrientation.stories.tsx +0 -500
- package/src/stories/Layout/MultiDirectionalConnections.stories.tsx +0 -352
- package/src/stories/Nodes/NodeDefinitionComparison.stories.tsx +0 -560
- package/src/stories/Nodes/NodeNameFallbacks.stories.tsx +0 -491
- package/src/stories/Nodes/NumericColors.stories.tsx +0 -440
- package/src/stories/OTEL/EventNameDisplay.stories.tsx +0 -694
- package/src/stories/OTEL/EventNameFallback.stories.tsx +0 -578
- package/src/stories/OTEL/OtelComponents.stories.tsx +0 -422
- package/src/stories/OTEL/OtelNodeTypesPrototype.stories.tsx +0 -806
- package/src/stories/OTEL/RawEventCards.stories.tsx +0 -57
- package/src/stories/OTEL/SpanBadges.stories.tsx +0 -840
- package/src/stories/OTEL/ValidationEventsCanvas.stories.tsx +0 -209
- package/src/stories/RealWorld/BacklogMdCanvases.stories.tsx +0 -721
- package/src/stories/RealWorld/FileCitySequence.stories.tsx +0 -516
- package/src/stories/RealWorld/RealCanvasFiles.stories.tsx +0 -336
- package/src/stories/__traces__/test-run.canvas.json +0 -241
- package/src/stories/data/activity-feed-analytics.dashboard.json +0 -300
- package/src/stories/data/file-city-images-transformed.otel.canvas.json +0 -295
- package/src/stories/data/file-city-workflows.json +0 -269
- package/src/stories/data/graph-converter-test-execution.json +0 -443
- package/src/stories/data/graph-converter-test.workflow.json +0 -105
- package/src/stories/data/graph-converter-validated-execution.json +0 -58
- package/src/utils/animationMapping.ts +0 -166
- package/src/utils/canvasBounds.ts +0 -146
- package/src/utils/graphConverter.ts +0 -148
- package/src/utils/iconResolver.tsx +0 -53
- package/src/utils/orientationUtils.ts +0 -73
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OTEL Resource Node
|
|
3
|
-
*
|
|
4
|
-
* Renders resource nodes as diamonds with:
|
|
5
|
-
* - Resource match identifier (key: value)
|
|
6
|
-
* - Status, sources, and references badges
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import React from 'react';
|
|
10
|
-
import { Handle, Position, NodeResizer } from '@xyflow/react';
|
|
11
|
-
import type { NodeProps, Node } from '@xyflow/react';
|
|
12
|
-
import { useTheme } from '@principal-ade/industry-theme';
|
|
13
|
-
import { NodeTooltip } from '../../components/NodeTooltip';
|
|
14
|
-
import type { OtelInfo } from '../../components/NodeTooltip';
|
|
15
|
-
import { NodeBadges } from './shared/NodeBadges';
|
|
16
|
-
import { NodeContent } from './shared/NodeContent';
|
|
17
|
-
import { useNodeBehavior } from './shared/useNodeBehavior';
|
|
18
|
-
|
|
19
|
-
export interface OtelResourceNodeData extends Record<string, unknown> {
|
|
20
|
-
name: string;
|
|
21
|
-
typeDefinition: {
|
|
22
|
-
color?: string;
|
|
23
|
-
icon?: string;
|
|
24
|
-
states?: Record<string, { color?: string; label?: string; icon?: string }>;
|
|
25
|
-
};
|
|
26
|
-
state?: string;
|
|
27
|
-
hasViolations?: boolean;
|
|
28
|
-
data: {
|
|
29
|
-
color?: string;
|
|
30
|
-
scopeColor?: string;
|
|
31
|
-
spanColor?: string;
|
|
32
|
-
stroke?: string;
|
|
33
|
-
icon?: string;
|
|
34
|
-
status?: 'draft' | 'approved' | 'implemented';
|
|
35
|
-
description?: string;
|
|
36
|
-
sources?: string[];
|
|
37
|
-
references?: string[];
|
|
38
|
-
states?: Record<string, { color?: string; label?: string; icon?: string }>;
|
|
39
|
-
otel?: {
|
|
40
|
-
resourceMatch?: Record<string, string | string[]>;
|
|
41
|
-
files?: string[];
|
|
42
|
-
};
|
|
43
|
-
};
|
|
44
|
-
editable?: boolean;
|
|
45
|
-
tooltipsEnabled?: boolean;
|
|
46
|
-
shiftKeyPressed?: boolean;
|
|
47
|
-
isHighlighted?: boolean;
|
|
48
|
-
isActive?: boolean;
|
|
49
|
-
isHidden?: boolean;
|
|
50
|
-
animationType?: 'pulse' | 'flash' | 'shake' | 'entry' | null;
|
|
51
|
-
animationDuration?: number;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export const OtelResourceNode: React.FC<NodeProps<Node<OtelResourceNodeData>>> = ({
|
|
55
|
-
data,
|
|
56
|
-
selected,
|
|
57
|
-
dragging,
|
|
58
|
-
}) => {
|
|
59
|
-
const { theme } = useTheme();
|
|
60
|
-
const nodeProps = data;
|
|
61
|
-
const {
|
|
62
|
-
typeDefinition,
|
|
63
|
-
state,
|
|
64
|
-
hasViolations,
|
|
65
|
-
data: nodeData,
|
|
66
|
-
editable = false,
|
|
67
|
-
tooltipsEnabled = true,
|
|
68
|
-
shiftKeyPressed = false,
|
|
69
|
-
isHighlighted = false,
|
|
70
|
-
isActive = true,
|
|
71
|
-
isHidden = false,
|
|
72
|
-
animationType,
|
|
73
|
-
animationDuration: _animationDuration = 1000,
|
|
74
|
-
} = nodeProps;
|
|
75
|
-
|
|
76
|
-
const {
|
|
77
|
-
nodeRef,
|
|
78
|
-
showTooltip,
|
|
79
|
-
handleMouseDown,
|
|
80
|
-
handleMouseEnter,
|
|
81
|
-
handleMouseLeave,
|
|
82
|
-
handleResizeEnd,
|
|
83
|
-
} = useNodeBehavior({ editable, tooltipsEnabled, shiftKeyPressed, selected, dragging });
|
|
84
|
-
|
|
85
|
-
const nodeOpacity = isHidden ? 0.4 : isActive ? 1 : 0.1;
|
|
86
|
-
|
|
87
|
-
// Color resolution
|
|
88
|
-
const scopeColor = nodeData.scopeColor as string | undefined;
|
|
89
|
-
const spanColor = nodeData.spanColor as string | undefined;
|
|
90
|
-
const nodeDataColor = nodeData.color as string | undefined;
|
|
91
|
-
// Fill color priority: explicit color > scope color > type definition color > default orange
|
|
92
|
-
const baseFillColor = nodeDataColor || scopeColor || typeDefinition.color || '#f97316';
|
|
93
|
-
const fillColor = baseFillColor;
|
|
94
|
-
// Stroke color priority: explicit stroke > span color (workflow context) > fill color
|
|
95
|
-
const nodeDataStroke = nodeData.stroke as string | undefined;
|
|
96
|
-
const strokeColor = nodeDataStroke || spanColor || fillColor;
|
|
97
|
-
|
|
98
|
-
// Display info
|
|
99
|
-
const displayName = nodeProps.name;
|
|
100
|
-
const otelData = nodeData.otel;
|
|
101
|
-
|
|
102
|
-
// Get identifier from resourceMatch
|
|
103
|
-
let identifier: string | undefined;
|
|
104
|
-
if (otelData?.resourceMatch) {
|
|
105
|
-
const entries = Object.entries(otelData.resourceMatch);
|
|
106
|
-
if (entries.length > 0) {
|
|
107
|
-
const [key, value] = entries[0];
|
|
108
|
-
identifier = `${key}: ${Array.isArray(value) ? value[0] : value}`;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Badge data
|
|
113
|
-
const status = nodeData.status;
|
|
114
|
-
const sourceFiles = otelData?.files || nodeData.sources;
|
|
115
|
-
const references = nodeData.references;
|
|
116
|
-
const description = nodeData.description;
|
|
117
|
-
|
|
118
|
-
// Icon
|
|
119
|
-
const icon =
|
|
120
|
-
(nodeData.icon as string) ||
|
|
121
|
-
(state && nodeData.states?.[state]?.icon) ||
|
|
122
|
-
typeDefinition.icon;
|
|
123
|
-
|
|
124
|
-
const stateDefinitions = nodeData.states || typeDefinition.states;
|
|
125
|
-
|
|
126
|
-
const getAnimationClass = () => {
|
|
127
|
-
switch (animationType) {
|
|
128
|
-
case 'pulse': return 'node-pulse';
|
|
129
|
-
case 'flash': return 'node-flash';
|
|
130
|
-
case 'shake': return 'node-shake';
|
|
131
|
-
case 'entry': return 'node-entry';
|
|
132
|
-
default: return '';
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
// Diamond styles
|
|
137
|
-
const diamondClipPath = 'polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)';
|
|
138
|
-
const diamondBorderWidth = 2;
|
|
139
|
-
|
|
140
|
-
const diamondBorderStyle: React.CSSProperties = {
|
|
141
|
-
position: 'relative',
|
|
142
|
-
clipPath: diamondClipPath,
|
|
143
|
-
backgroundColor: hasViolations ? '#D0021B' : strokeColor,
|
|
144
|
-
width: '100%',
|
|
145
|
-
height: '100%',
|
|
146
|
-
minWidth: 20,
|
|
147
|
-
minHeight: 20,
|
|
148
|
-
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
|
|
149
|
-
opacity: nodeOpacity,
|
|
150
|
-
transition: 'opacity 0.3s ease',
|
|
151
|
-
boxSizing: 'border-box',
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
const diamondInnerStyle: React.CSSProperties = {
|
|
155
|
-
position: 'absolute',
|
|
156
|
-
top: diamondBorderWidth,
|
|
157
|
-
left: diamondBorderWidth,
|
|
158
|
-
right: diamondBorderWidth,
|
|
159
|
-
bottom: diamondBorderWidth,
|
|
160
|
-
clipPath: diamondClipPath,
|
|
161
|
-
backgroundColor: fillColor,
|
|
162
|
-
color: '#000',
|
|
163
|
-
display: 'flex',
|
|
164
|
-
flexDirection: 'column',
|
|
165
|
-
alignItems: 'center',
|
|
166
|
-
justifyContent: 'center',
|
|
167
|
-
fontSize: theme.fontSizes[0],
|
|
168
|
-
fontWeight: theme.fontWeights.medium,
|
|
169
|
-
fontFamily: theme.fonts.body,
|
|
170
|
-
gap: '4px',
|
|
171
|
-
padding: '8px 16px',
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
const handleStyle = editable
|
|
175
|
-
? { background: fillColor, width: 12, height: 12, border: '2px solid white', boxShadow: '0 0 0 1px ' + fillColor, zIndex: 10 }
|
|
176
|
-
: { background: fillColor, width: 8, height: 8, opacity: 0, pointerEvents: 'none' as const, zIndex: 10 };
|
|
177
|
-
|
|
178
|
-
return (
|
|
179
|
-
<>
|
|
180
|
-
{editable && (
|
|
181
|
-
<NodeResizer
|
|
182
|
-
color={strokeColor}
|
|
183
|
-
isVisible={selected}
|
|
184
|
-
minWidth={40}
|
|
185
|
-
minHeight={30}
|
|
186
|
-
onResizeEnd={handleResizeEnd}
|
|
187
|
-
handleStyle={{ width: 8, height: 8, borderRadius: 2, zIndex: 20 }}
|
|
188
|
-
lineStyle={{ borderWidth: 1, zIndex: 20 }}
|
|
189
|
-
/>
|
|
190
|
-
)}
|
|
191
|
-
|
|
192
|
-
<Handle type="target" position={Position.Top} id="top" style={handleStyle} />
|
|
193
|
-
<Handle type="target" position={Position.Bottom} id="bottom" style={handleStyle} />
|
|
194
|
-
<Handle type="target" position={Position.Left} id="left" style={handleStyle} />
|
|
195
|
-
<Handle type="target" position={Position.Right} id="right" style={handleStyle} />
|
|
196
|
-
|
|
197
|
-
<div
|
|
198
|
-
ref={nodeRef}
|
|
199
|
-
style={{
|
|
200
|
-
position: 'relative',
|
|
201
|
-
width: '100%',
|
|
202
|
-
height: '100%',
|
|
203
|
-
boxShadow: isHighlighted
|
|
204
|
-
? '0 0 0 3px #3b82f6, 0 0 20px rgba(59, 130, 246, 0.5)'
|
|
205
|
-
: selected
|
|
206
|
-
? `0 0 0 2px ${strokeColor}`
|
|
207
|
-
: 'none',
|
|
208
|
-
transition: 'box-shadow 0.2s ease',
|
|
209
|
-
}}
|
|
210
|
-
onMouseDown={handleMouseDown}
|
|
211
|
-
onMouseEnter={handleMouseEnter}
|
|
212
|
-
onMouseLeave={handleMouseLeave}
|
|
213
|
-
>
|
|
214
|
-
<NodeBadges
|
|
215
|
-
shape="diamond"
|
|
216
|
-
status={status}
|
|
217
|
-
sourceFiles={sourceFiles}
|
|
218
|
-
references={references}
|
|
219
|
-
opacity={nodeOpacity}
|
|
220
|
-
/>
|
|
221
|
-
<div style={diamondBorderStyle} className={getAnimationClass()}>
|
|
222
|
-
<div style={diamondInnerStyle}>
|
|
223
|
-
<NodeContent
|
|
224
|
-
displayName={displayName}
|
|
225
|
-
identifier={identifier}
|
|
226
|
-
icon={icon}
|
|
227
|
-
state={state}
|
|
228
|
-
stateDefinitions={stateDefinitions}
|
|
229
|
-
hasViolations={hasViolations}
|
|
230
|
-
/>
|
|
231
|
-
</div>
|
|
232
|
-
</div>
|
|
233
|
-
{tooltipsEnabled && (
|
|
234
|
-
<NodeTooltip
|
|
235
|
-
description={description}
|
|
236
|
-
otel={nodeData.otel as OtelInfo}
|
|
237
|
-
sources={nodeData.sources}
|
|
238
|
-
references={references}
|
|
239
|
-
visible={showTooltip}
|
|
240
|
-
nodeRef={nodeRef}
|
|
241
|
-
/>
|
|
242
|
-
)}
|
|
243
|
-
</div>
|
|
244
|
-
|
|
245
|
-
<Handle type="source" position={Position.Top} id="top-out" style={handleStyle} />
|
|
246
|
-
<Handle type="source" position={Position.Bottom} id="bottom-out" style={handleStyle} />
|
|
247
|
-
<Handle type="source" position={Position.Left} id="left-out" style={handleStyle} />
|
|
248
|
-
<Handle type="source" position={Position.Right} id="right-out" style={handleStyle} />
|
|
249
|
-
</>
|
|
250
|
-
);
|
|
251
|
-
};
|
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OTEL Scope Node
|
|
3
|
-
*
|
|
4
|
-
* Renders scope nodes as rounded rectangles with:
|
|
5
|
-
* - Scope name identifier
|
|
6
|
-
* - Status, sources, and references badges
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import React from 'react';
|
|
10
|
-
import { Handle, Position, NodeResizer } from '@xyflow/react';
|
|
11
|
-
import type { NodeProps, Node } from '@xyflow/react';
|
|
12
|
-
import { useTheme } from '@principal-ade/industry-theme';
|
|
13
|
-
import { NodeTooltip } from '../../components/NodeTooltip';
|
|
14
|
-
import type { OtelInfo } from '../../components/NodeTooltip';
|
|
15
|
-
import { NodeBadges } from './shared/NodeBadges';
|
|
16
|
-
import { NodeContent } from './shared/NodeContent';
|
|
17
|
-
import { useNodeBehavior } from './shared/useNodeBehavior';
|
|
18
|
-
|
|
19
|
-
export interface OtelScopeNodeData extends Record<string, unknown> {
|
|
20
|
-
name: string;
|
|
21
|
-
typeDefinition: {
|
|
22
|
-
color?: string;
|
|
23
|
-
icon?: string;
|
|
24
|
-
states?: Record<string, { color?: string; label?: string; icon?: string }>;
|
|
25
|
-
};
|
|
26
|
-
state?: string;
|
|
27
|
-
hasViolations?: boolean;
|
|
28
|
-
data: {
|
|
29
|
-
color?: string;
|
|
30
|
-
scopeColor?: string;
|
|
31
|
-
spanColor?: string;
|
|
32
|
-
stroke?: string;
|
|
33
|
-
icon?: string;
|
|
34
|
-
status?: 'draft' | 'approved' | 'implemented';
|
|
35
|
-
description?: string;
|
|
36
|
-
sources?: string[];
|
|
37
|
-
references?: string[];
|
|
38
|
-
states?: Record<string, { color?: string; label?: string; icon?: string }>;
|
|
39
|
-
otel?: { scope?: string; files?: string[] };
|
|
40
|
-
};
|
|
41
|
-
editable?: boolean;
|
|
42
|
-
tooltipsEnabled?: boolean;
|
|
43
|
-
shiftKeyPressed?: boolean;
|
|
44
|
-
isHighlighted?: boolean;
|
|
45
|
-
isActive?: boolean;
|
|
46
|
-
isHidden?: boolean;
|
|
47
|
-
animationType?: 'pulse' | 'flash' | 'shake' | 'entry' | null;
|
|
48
|
-
animationDuration?: number;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export const OtelScopeNode: React.FC<NodeProps<Node<OtelScopeNodeData>>> = ({
|
|
52
|
-
data,
|
|
53
|
-
selected,
|
|
54
|
-
dragging,
|
|
55
|
-
}) => {
|
|
56
|
-
const { theme } = useTheme();
|
|
57
|
-
const nodeProps = data;
|
|
58
|
-
const {
|
|
59
|
-
typeDefinition,
|
|
60
|
-
state,
|
|
61
|
-
hasViolations,
|
|
62
|
-
data: nodeData,
|
|
63
|
-
editable = false,
|
|
64
|
-
tooltipsEnabled = true,
|
|
65
|
-
shiftKeyPressed = false,
|
|
66
|
-
isHighlighted = false,
|
|
67
|
-
isActive = true,
|
|
68
|
-
isHidden = false,
|
|
69
|
-
animationType,
|
|
70
|
-
animationDuration = 1000,
|
|
71
|
-
} = nodeProps;
|
|
72
|
-
|
|
73
|
-
const {
|
|
74
|
-
nodeRef,
|
|
75
|
-
showTooltip,
|
|
76
|
-
handleMouseDown,
|
|
77
|
-
handleMouseEnter,
|
|
78
|
-
handleMouseLeave,
|
|
79
|
-
handleResizeEnd,
|
|
80
|
-
} = useNodeBehavior({ editable, tooltipsEnabled, shiftKeyPressed, selected, dragging });
|
|
81
|
-
|
|
82
|
-
const nodeOpacity = isHidden ? 0.4 : isActive ? 1 : 0.1;
|
|
83
|
-
|
|
84
|
-
// Color resolution
|
|
85
|
-
const scopeColor = nodeData.scopeColor as string | undefined;
|
|
86
|
-
const spanColor = nodeData.spanColor as string | undefined;
|
|
87
|
-
const nodeDataColor = nodeData.color as string | undefined;
|
|
88
|
-
// Fill color priority: explicit color > scope color > type definition color > default green
|
|
89
|
-
const baseFillColor = nodeDataColor || scopeColor || typeDefinition.color || '#22c55e';
|
|
90
|
-
const fillColor = baseFillColor;
|
|
91
|
-
// Stroke color priority: explicit stroke > span color (workflow context) > fill color
|
|
92
|
-
const nodeDataStroke = nodeData.stroke as string | undefined;
|
|
93
|
-
const strokeColor = nodeDataStroke || spanColor || fillColor;
|
|
94
|
-
|
|
95
|
-
// Display info
|
|
96
|
-
const displayName = nodeProps.name;
|
|
97
|
-
const otelData = nodeData.otel;
|
|
98
|
-
const identifier = otelData?.scope;
|
|
99
|
-
|
|
100
|
-
// Badge data
|
|
101
|
-
const status = nodeData.status;
|
|
102
|
-
const sourceFiles = otelData?.files || nodeData.sources;
|
|
103
|
-
const references = nodeData.references;
|
|
104
|
-
const description = nodeData.description;
|
|
105
|
-
|
|
106
|
-
// Icon
|
|
107
|
-
const icon =
|
|
108
|
-
(nodeData.icon as string) ||
|
|
109
|
-
(state && nodeData.states?.[state]?.icon) ||
|
|
110
|
-
typeDefinition.icon;
|
|
111
|
-
|
|
112
|
-
const stateDefinitions = nodeData.states || typeDefinition.states;
|
|
113
|
-
|
|
114
|
-
const getAnimationClass = () => {
|
|
115
|
-
switch (animationType) {
|
|
116
|
-
case 'pulse': return 'node-pulse';
|
|
117
|
-
case 'flash': return 'node-flash';
|
|
118
|
-
case 'shake': return 'node-shake';
|
|
119
|
-
case 'entry': return 'node-entry';
|
|
120
|
-
default: return '';
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
const borderStyle = status === 'draft' ? 'dotted' : status === 'approved' ? 'dashed' : 'solid';
|
|
125
|
-
|
|
126
|
-
const circleStyle: React.CSSProperties = {
|
|
127
|
-
padding: '8px',
|
|
128
|
-
backgroundColor: fillColor,
|
|
129
|
-
color: '#000',
|
|
130
|
-
border: `2px ${borderStyle} ${hasViolations ? '#D0021B' : strokeColor}`,
|
|
131
|
-
fontSize: theme.fontSizes[0],
|
|
132
|
-
fontWeight: theme.fontWeights.medium,
|
|
133
|
-
fontFamily: theme.fonts.body,
|
|
134
|
-
width: '100%',
|
|
135
|
-
height: '100%',
|
|
136
|
-
minWidth: 20,
|
|
137
|
-
minHeight: 20,
|
|
138
|
-
display: 'flex',
|
|
139
|
-
flexDirection: 'column',
|
|
140
|
-
alignItems: 'center',
|
|
141
|
-
justifyContent: 'center',
|
|
142
|
-
gap: '4px',
|
|
143
|
-
boxShadow: isHighlighted
|
|
144
|
-
? '0 0 0 3px #3b82f6, 0 0 20px rgba(59, 130, 246, 0.5)'
|
|
145
|
-
: selected
|
|
146
|
-
? `0 0 0 2px ${strokeColor}`
|
|
147
|
-
: '0 2px 4px rgba(0,0,0,0.1)',
|
|
148
|
-
opacity: nodeOpacity,
|
|
149
|
-
transition: 'box-shadow 0.2s ease, opacity 0.3s ease',
|
|
150
|
-
animationDuration: animationType ? `${animationDuration}ms` : undefined,
|
|
151
|
-
boxSizing: 'border-box',
|
|
152
|
-
borderRadius: '12px',
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
const handleStyle = editable
|
|
156
|
-
? { background: fillColor, width: 12, height: 12, border: '2px solid white', boxShadow: '0 0 0 1px ' + fillColor }
|
|
157
|
-
: { background: fillColor, width: 8, height: 8, opacity: 0, pointerEvents: 'none' as const };
|
|
158
|
-
|
|
159
|
-
return (
|
|
160
|
-
<>
|
|
161
|
-
{editable && (
|
|
162
|
-
<NodeResizer
|
|
163
|
-
color={strokeColor}
|
|
164
|
-
isVisible={selected}
|
|
165
|
-
minWidth={40}
|
|
166
|
-
minHeight={40}
|
|
167
|
-
keepAspectRatio={false}
|
|
168
|
-
onResizeEnd={handleResizeEnd}
|
|
169
|
-
handleStyle={{ width: 8, height: 8, borderRadius: 2, zIndex: 20 }}
|
|
170
|
-
lineStyle={{ borderWidth: 1, zIndex: 20 }}
|
|
171
|
-
/>
|
|
172
|
-
)}
|
|
173
|
-
|
|
174
|
-
<Handle type="target" position={Position.Top} id="top" style={handleStyle} />
|
|
175
|
-
<Handle type="target" position={Position.Bottom} id="bottom" style={handleStyle} />
|
|
176
|
-
<Handle type="target" position={Position.Left} id="left" style={handleStyle} />
|
|
177
|
-
<Handle type="target" position={Position.Right} id="right" style={handleStyle} />
|
|
178
|
-
|
|
179
|
-
<div
|
|
180
|
-
ref={nodeRef}
|
|
181
|
-
style={{ position: 'relative', width: '100%', height: '100%' }}
|
|
182
|
-
onMouseDown={handleMouseDown}
|
|
183
|
-
onMouseEnter={handleMouseEnter}
|
|
184
|
-
onMouseLeave={handleMouseLeave}
|
|
185
|
-
>
|
|
186
|
-
<NodeBadges
|
|
187
|
-
shape="rectangle"
|
|
188
|
-
status={status}
|
|
189
|
-
sourceFiles={sourceFiles}
|
|
190
|
-
references={references}
|
|
191
|
-
opacity={nodeOpacity}
|
|
192
|
-
/>
|
|
193
|
-
<div style={circleStyle} className={getAnimationClass()}>
|
|
194
|
-
<NodeContent
|
|
195
|
-
displayName={displayName}
|
|
196
|
-
identifier={identifier}
|
|
197
|
-
icon={icon}
|
|
198
|
-
state={state}
|
|
199
|
-
stateDefinitions={stateDefinitions}
|
|
200
|
-
hasViolations={hasViolations}
|
|
201
|
-
/>
|
|
202
|
-
</div>
|
|
203
|
-
{tooltipsEnabled && (
|
|
204
|
-
<NodeTooltip
|
|
205
|
-
description={description}
|
|
206
|
-
otel={nodeData.otel as OtelInfo}
|
|
207
|
-
sources={nodeData.sources}
|
|
208
|
-
references={references}
|
|
209
|
-
visible={showTooltip}
|
|
210
|
-
nodeRef={nodeRef}
|
|
211
|
-
/>
|
|
212
|
-
)}
|
|
213
|
-
</div>
|
|
214
|
-
|
|
215
|
-
<Handle type="source" position={Position.Top} id="top-out" style={handleStyle} />
|
|
216
|
-
<Handle type="source" position={Position.Bottom} id="bottom-out" style={handleStyle} />
|
|
217
|
-
<Handle type="source" position={Position.Left} id="left-out" style={handleStyle} />
|
|
218
|
-
<Handle type="source" position={Position.Right} id="right-out" style={handleStyle} />
|
|
219
|
-
</>
|
|
220
|
-
);
|
|
221
|
-
};
|