@principal-ai/subsystems-react 0.21.0 → 0.21.1

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 (201) hide show
  1. package/package.json +1 -1
  2. package/dist/components/ConfigurationSelector.d.ts +0 -35
  3. package/dist/components/ConfigurationSelector.d.ts.map +0 -1
  4. package/dist/components/ConfigurationSelector.js +0 -63
  5. package/dist/components/ConfigurationSelector.js.map +0 -1
  6. package/dist/components/GraphRenderer.d.ts +0 -295
  7. package/dist/components/GraphRenderer.d.ts.map +0 -1
  8. package/dist/components/GraphRenderer.js +0 -2008
  9. package/dist/components/GraphRenderer.js.map +0 -1
  10. package/dist/components/MultiCanvasRenderer.d.ts +0 -75
  11. package/dist/components/MultiCanvasRenderer.d.ts.map +0 -1
  12. package/dist/components/MultiCanvasRenderer.js +0 -203
  13. package/dist/components/MultiCanvasRenderer.js.map +0 -1
  14. package/dist/components/NodeTooltip.d.ts +0 -24
  15. package/dist/components/NodeTooltip.d.ts.map +0 -1
  16. package/dist/components/NodeTooltip.js +0 -160
  17. package/dist/components/NodeTooltip.js.map +0 -1
  18. package/dist/components/SelectionSidebar.d.ts +0 -18
  19. package/dist/components/SelectionSidebar.d.ts.map +0 -1
  20. package/dist/components/SelectionSidebar.js +0 -190
  21. package/dist/components/SelectionSidebar.js.map +0 -1
  22. package/dist/components/SequenceDiagramRenderer.d.ts +0 -77
  23. package/dist/components/SequenceDiagramRenderer.d.ts.map +0 -1
  24. package/dist/components/SequenceDiagramRenderer.js +0 -604
  25. package/dist/components/SequenceDiagramRenderer.js.map +0 -1
  26. package/dist/components/WorkflowSequenceDiagram.d.ts +0 -63
  27. package/dist/components/WorkflowSequenceDiagram.d.ts.map +0 -1
  28. package/dist/components/WorkflowSequenceDiagram.js +0 -147
  29. package/dist/components/WorkflowSequenceDiagram.js.map +0 -1
  30. package/dist/components/dashboard/DashboardRenderer.d.ts +0 -10
  31. package/dist/components/dashboard/DashboardRenderer.d.ts.map +0 -1
  32. package/dist/components/dashboard/DashboardRenderer.js +0 -179
  33. package/dist/components/dashboard/DashboardRenderer.js.map +0 -1
  34. package/dist/components/dashboard/MetricPanel.d.ts +0 -10
  35. package/dist/components/dashboard/MetricPanel.d.ts.map +0 -1
  36. package/dist/components/dashboard/MetricPanel.js +0 -103
  37. package/dist/components/dashboard/MetricPanel.js.map +0 -1
  38. package/dist/components/dashboard/MockDataProvider.d.ts +0 -30
  39. package/dist/components/dashboard/MockDataProvider.d.ts.map +0 -1
  40. package/dist/components/dashboard/MockDataProvider.js +0 -270
  41. package/dist/components/dashboard/MockDataProvider.js.map +0 -1
  42. package/dist/components/dashboard/components/BarChart.d.ts +0 -10
  43. package/dist/components/dashboard/components/BarChart.d.ts.map +0 -1
  44. package/dist/components/dashboard/components/BarChart.js +0 -167
  45. package/dist/components/dashboard/components/BarChart.js.map +0 -1
  46. package/dist/components/dashboard/components/LineChart.d.ts +0 -10
  47. package/dist/components/dashboard/components/LineChart.d.ts.map +0 -1
  48. package/dist/components/dashboard/components/LineChart.js +0 -141
  49. package/dist/components/dashboard/components/LineChart.js.map +0 -1
  50. package/dist/components/dashboard/components/MetricCard.d.ts +0 -9
  51. package/dist/components/dashboard/components/MetricCard.d.ts.map +0 -1
  52. package/dist/components/dashboard/components/MetricCard.js +0 -163
  53. package/dist/components/dashboard/components/MetricCard.js.map +0 -1
  54. package/dist/components/dashboard/components/SourceLink.d.ts +0 -9
  55. package/dist/components/dashboard/components/SourceLink.d.ts.map +0 -1
  56. package/dist/components/dashboard/components/SourceLink.js +0 -39
  57. package/dist/components/dashboard/components/SourceLink.js.map +0 -1
  58. package/dist/components/dashboard/components/TimeRangeSelector.d.ts +0 -9
  59. package/dist/components/dashboard/components/TimeRangeSelector.d.ts.map +0 -1
  60. package/dist/components/dashboard/components/TimeRangeSelector.js +0 -167
  61. package/dist/components/dashboard/components/TimeRangeSelector.js.map +0 -1
  62. package/dist/components/dashboard/components/index.d.ts +0 -6
  63. package/dist/components/dashboard/components/index.d.ts.map +0 -1
  64. package/dist/components/dashboard/components/index.js +0 -6
  65. package/dist/components/dashboard/components/index.js.map +0 -1
  66. package/dist/components/dashboard/index.d.ts +0 -6
  67. package/dist/components/dashboard/index.d.ts.map +0 -1
  68. package/dist/components/dashboard/index.js +0 -8
  69. package/dist/components/dashboard/index.js.map +0 -1
  70. package/dist/components/dashboard/types.d.ts +0 -74
  71. package/dist/components/dashboard/types.d.ts.map +0 -1
  72. package/dist/components/dashboard/types.js +0 -8
  73. package/dist/components/dashboard/types.js.map +0 -1
  74. package/dist/components/state-view/PipelineView.d.ts +0 -14
  75. package/dist/components/state-view/PipelineView.d.ts.map +0 -1
  76. package/dist/components/state-view/PipelineView.js +0 -195
  77. package/dist/components/state-view/PipelineView.js.map +0 -1
  78. package/dist/components/state-view/index.d.ts +0 -14
  79. package/dist/components/state-view/index.d.ts.map +0 -1
  80. package/dist/components/state-view/index.js +0 -12
  81. package/dist/components/state-view/index.js.map +0 -1
  82. package/dist/components/state-view/types.d.ts +0 -188
  83. package/dist/components/state-view/types.d.ts.map +0 -1
  84. package/dist/components/state-view/types.js +0 -10
  85. package/dist/components/state-view/types.js.map +0 -1
  86. package/dist/components/state-view/useStateView.d.ts +0 -32
  87. package/dist/components/state-view/useStateView.d.ts.map +0 -1
  88. package/dist/components/state-view/useStateView.js +0 -129
  89. package/dist/components/state-view/useStateView.js.map +0 -1
  90. package/dist/contexts/GraphEditContext.d.ts +0 -20
  91. package/dist/contexts/GraphEditContext.d.ts.map +0 -1
  92. package/dist/contexts/GraphEditContext.js +0 -8
  93. package/dist/contexts/GraphEditContext.js.map +0 -1
  94. package/dist/contexts/TooltipPortalContext.d.ts +0 -8
  95. package/dist/contexts/TooltipPortalContext.d.ts.map +0 -1
  96. package/dist/contexts/TooltipPortalContext.js +0 -8
  97. package/dist/contexts/TooltipPortalContext.js.map +0 -1
  98. package/dist/edges/CustomEdge.d.ts +0 -24
  99. package/dist/edges/CustomEdge.d.ts.map +0 -1
  100. package/dist/edges/CustomEdge.js +0 -222
  101. package/dist/edges/CustomEdge.js.map +0 -1
  102. package/dist/edges/GenericEdge.d.ts +0 -18
  103. package/dist/edges/GenericEdge.d.ts.map +0 -1
  104. package/dist/edges/GenericEdge.js +0 -10
  105. package/dist/edges/GenericEdge.js.map +0 -1
  106. package/dist/graphify/kind.d.ts +0 -23
  107. package/dist/graphify/kind.d.ts.map +0 -1
  108. package/dist/graphify/kind.js +0 -77
  109. package/dist/graphify/kind.js.map +0 -1
  110. package/dist/hooks/usePathBasedEvents.d.ts +0 -42
  111. package/dist/hooks/usePathBasedEvents.d.ts.map +0 -1
  112. package/dist/hooks/usePathBasedEvents.js +0 -119
  113. package/dist/hooks/usePathBasedEvents.js.map +0 -1
  114. package/dist/hooks/useSequenceLayout.d.ts +0 -186
  115. package/dist/hooks/useSequenceLayout.d.ts.map +0 -1
  116. package/dist/hooks/useSequenceLayout.js +0 -327
  117. package/dist/hooks/useSequenceLayout.js.map +0 -1
  118. package/dist/hooks/useUndoRedo.d.ts +0 -80
  119. package/dist/hooks/useUndoRedo.d.ts.map +0 -1
  120. package/dist/hooks/useUndoRedo.js +0 -70
  121. package/dist/hooks/useUndoRedo.js.map +0 -1
  122. package/dist/nodes/CustomNode.d.ts +0 -28
  123. package/dist/nodes/CustomNode.d.ts.map +0 -1
  124. package/dist/nodes/CustomNode.js +0 -820
  125. package/dist/nodes/CustomNode.js.map +0 -1
  126. package/dist/nodes/GenericNode.d.ts +0 -20
  127. package/dist/nodes/GenericNode.d.ts.map +0 -1
  128. package/dist/nodes/GenericNode.js +0 -20
  129. package/dist/nodes/GenericNode.js.map +0 -1
  130. package/dist/nodes/otel/OtelBoundaryNode.d.ts +0 -55
  131. package/dist/nodes/otel/OtelBoundaryNode.d.ts.map +0 -1
  132. package/dist/nodes/otel/OtelBoundaryNode.js +0 -81
  133. package/dist/nodes/otel/OtelBoundaryNode.js.map +0 -1
  134. package/dist/nodes/otel/OtelEventNode.d.ts +0 -59
  135. package/dist/nodes/otel/OtelEventNode.d.ts.map +0 -1
  136. package/dist/nodes/otel/OtelEventNode.js +0 -82
  137. package/dist/nodes/otel/OtelEventNode.js.map +0 -1
  138. package/dist/nodes/otel/OtelResourceNode.d.ts +0 -53
  139. package/dist/nodes/otel/OtelResourceNode.d.ts.map +0 -1
  140. package/dist/nodes/otel/OtelResourceNode.js +0 -105
  141. package/dist/nodes/otel/OtelResourceNode.js.map +0 -1
  142. package/dist/nodes/otel/OtelScopeNode.d.ts +0 -53
  143. package/dist/nodes/otel/OtelScopeNode.d.ts.map +0 -1
  144. package/dist/nodes/otel/OtelScopeNode.js +0 -81
  145. package/dist/nodes/otel/OtelScopeNode.js.map +0 -1
  146. package/dist/nodes/otel/OtelSpanConventionNode.d.ts +0 -61
  147. package/dist/nodes/otel/OtelSpanConventionNode.d.ts.map +0 -1
  148. package/dist/nodes/otel/OtelSpanConventionNode.js +0 -131
  149. package/dist/nodes/otel/OtelSpanConventionNode.js.map +0 -1
  150. package/dist/nodes/otel/index.d.ts +0 -17
  151. package/dist/nodes/otel/index.d.ts.map +0 -1
  152. package/dist/nodes/otel/index.js +0 -13
  153. package/dist/nodes/otel/index.js.map +0 -1
  154. package/dist/nodes/otel/shared/NodeBadges.d.ts +0 -10
  155. package/dist/nodes/otel/shared/NodeBadges.d.ts.map +0 -1
  156. package/dist/nodes/otel/shared/NodeBadges.js +0 -178
  157. package/dist/nodes/otel/shared/NodeBadges.js.map +0 -1
  158. package/dist/nodes/otel/shared/NodeContent.d.ts +0 -10
  159. package/dist/nodes/otel/shared/NodeContent.d.ts.map +0 -1
  160. package/dist/nodes/otel/shared/NodeContent.js +0 -96
  161. package/dist/nodes/otel/shared/NodeContent.js.map +0 -1
  162. package/dist/nodes/otel/shared/index.d.ts +0 -8
  163. package/dist/nodes/otel/shared/index.d.ts.map +0 -1
  164. package/dist/nodes/otel/shared/index.js +0 -8
  165. package/dist/nodes/otel/shared/index.js.map +0 -1
  166. package/dist/nodes/otel/shared/types.d.ts +0 -129
  167. package/dist/nodes/otel/shared/types.d.ts.map +0 -1
  168. package/dist/nodes/otel/shared/types.js +0 -5
  169. package/dist/nodes/otel/shared/types.js.map +0 -1
  170. package/dist/nodes/otel/shared/useNodeBehavior.d.ts +0 -42
  171. package/dist/nodes/otel/shared/useNodeBehavior.d.ts.map +0 -1
  172. package/dist/nodes/otel/shared/useNodeBehavior.js +0 -61
  173. package/dist/nodes/otel/shared/useNodeBehavior.js.map +0 -1
  174. package/dist/pierre/PierreThroughlineCodeView.d.ts +0 -22
  175. package/dist/pierre/PierreThroughlineCodeView.d.ts.map +0 -1
  176. package/dist/pierre/PierreThroughlineCodeView.js +0 -206
  177. package/dist/pierre/PierreThroughlineCodeView.js.map +0 -1
  178. package/dist/subsystem/SubsystemCarousel.d.ts +0 -36
  179. package/dist/subsystem/SubsystemCarousel.d.ts.map +0 -1
  180. package/dist/subsystem/SubsystemCarousel.js +0 -163
  181. package/dist/subsystem/SubsystemCarousel.js.map +0 -1
  182. package/dist/utils/animationMapping.d.ts +0 -53
  183. package/dist/utils/animationMapping.d.ts.map +0 -1
  184. package/dist/utils/animationMapping.js +0 -126
  185. package/dist/utils/animationMapping.js.map +0 -1
  186. package/dist/utils/canvasBounds.d.ts +0 -50
  187. package/dist/utils/canvasBounds.d.ts.map +0 -1
  188. package/dist/utils/canvasBounds.js +0 -88
  189. package/dist/utils/canvasBounds.js.map +0 -1
  190. package/dist/utils/graphConverter.d.ts +0 -18
  191. package/dist/utils/graphConverter.d.ts.map +0 -1
  192. package/dist/utils/graphConverter.js +0 -114
  193. package/dist/utils/graphConverter.js.map +0 -1
  194. package/dist/utils/iconResolver.d.ts +0 -29
  195. package/dist/utils/iconResolver.d.ts.map +0 -1
  196. package/dist/utils/iconResolver.js +0 -30
  197. package/dist/utils/iconResolver.js.map +0 -1
  198. package/dist/utils/orientationUtils.d.ts +0 -19
  199. package/dist/utils/orientationUtils.d.ts.map +0 -1
  200. package/dist/utils/orientationUtils.js +0 -62
  201. package/dist/utils/orientationUtils.js.map +0 -1
@@ -1,820 +0,0 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState, useRef, useCallback } from 'react';
3
- import { Handle, Position, NodeResizer, useNodeId } from '@xyflow/react';
4
- import { useTheme } from '@principal-ade/industry-theme';
5
- import { resolveIcon } from '../utils/iconResolver';
6
- import { NodeTooltip } from '../components/NodeTooltip';
7
- import { useGraphEdit } from '../contexts/GraphEditContext';
8
- // OTEL node components
9
- import { OtelSpanConventionNode, OtelEventNode, OtelScopeNode, OtelResourceNode, OtelBoundaryNode, } from './otel';
10
- /**
11
- * Custom node component for xyflow that renders based on NodeTypeDefinition
12
- *
13
- * This component now delegates to specialized OTEL node components when the
14
- * node type matches an OTEL concept. This allows each OTEL node type to have
15
- * its own specialized rendering and features (e.g., workflow chips on span nodes).
16
- */
17
- export const CustomNode = (props) => {
18
- const { data, selected, dragging } = props;
19
- // Determine the OTEL node type from nodeData.nodeType (pv.nodeType in canvas)
20
- // The typeDefinition.shape can also hint at OTEL types but nodeType is authoritative
21
- const nodeType = data.data?.nodeType;
22
- // Delegate to specialized OTEL node components
23
- switch (nodeType) {
24
- case 'otel-span-convention':
25
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
- return _jsx(OtelSpanConventionNode, { ...props });
27
- case 'otel-event':
28
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
- return _jsx(OtelEventNode, { ...props });
30
- case 'otel-scope':
31
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
- return _jsx(OtelScopeNode, { ...props });
33
- case 'otel-resource':
34
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
- return _jsx(OtelResourceNode, { ...props });
36
- case 'otel-boundary':
37
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
- return _jsx(OtelBoundaryNode, { ...props });
39
- }
40
- // Fall through to legacy rendering for non-OTEL nodes
41
- const { theme } = useTheme();
42
- const { onNodeResizeEnd, onNodeTextChange, onToggleNodeHidden, onHideUnconnectedNodes } = useGraphEdit();
43
- const nodeId = useNodeId();
44
- const [isHovered, setIsHovered] = useState(false);
45
- const [isEditing, setIsEditing] = useState(false);
46
- const [editingText, setEditingText] = useState('');
47
- const nodeRef = useRef(null);
48
- const textareaRef = useRef(null);
49
- const nodeProps = data;
50
- const { typeDefinition, state, hasViolations, data: nodeData, animationType, animationDuration = 1000, editable = false, tooltipsEnabled = true, shiftKeyPressed = false, isHighlighted = false, isActive = true, // Default to active if not specified
51
- isHidden = false, // Default to not hidden
52
- } = nodeProps;
53
- // Calculate opacity based on node state
54
- // Hidden nodes (shift-clicked) are dimmed to 0.4
55
- // Inactive nodes (scenario filtering) are dimmed to 0.1
56
- const nodeOpacity = isHidden ? 0.4 : isActive ? 1 : 0.1;
57
- // Handle resize end - notify parent to track the dimension change
58
- const handleResizeEnd = useCallback((_event, params) => {
59
- if (nodeId && onNodeResizeEnd && params.width && params.height) {
60
- onNodeResizeEnd(nodeId, {
61
- width: Math.round(params.width),
62
- height: Math.round(params.height),
63
- });
64
- }
65
- }, [nodeId, onNodeResizeEnd]);
66
- // Handle Cmd/Ctrl+mousedown to toggle hidden state
67
- // We use mousedown instead of click because in edit mode with draggable nodes,
68
- // ReactFlow's drag system intercepts Cmd+click before it becomes a click event
69
- // - Cmd/Ctrl+Shift+click: hide all nodes not directly connected to this node
70
- // - Cmd/Ctrl+click: toggle this single node's hidden state
71
- const handleMouseDown = useCallback((event) => {
72
- if ((event.metaKey || event.ctrlKey) && nodeId) {
73
- event.preventDefault();
74
- event.stopPropagation();
75
- if (event.shiftKey && onHideUnconnectedNodes) {
76
- // Cmd/Ctrl+Shift+click: hide unconnected nodes
77
- onHideUnconnectedNodes(nodeId);
78
- }
79
- else if (onToggleNodeHidden) {
80
- // Cmd/Ctrl+click: toggle single node
81
- onToggleNodeHidden(nodeId);
82
- }
83
- }
84
- }, [nodeId, onToggleNodeHidden, onHideUnconnectedNodes]);
85
- // Show tooltip when:
86
- // 1. Hovering + not dragging + shift key pressed (always works), OR
87
- // 2. Node is selected AND not in edit mode (read-only selection shows tooltip)
88
- const showTooltip = (isHovered && !dragging && shiftKeyPressed) || (!editable && !!selected);
89
- // Extract OTEL info, description, sources/files, and references for tooltip
90
- const otelInfo = nodeData?.otel;
91
- const description = nodeData?.description;
92
- const sources = nodeData?.sources; // deprecated
93
- const references = nodeData?.references;
94
- // Files from otel.files - these are source code files where the event is instrumented
95
- const files = otelInfo?.files;
96
- // Get badge shape styles based on node shape
97
- const getBadgeShapeStyles = () => {
98
- const shape = typeDefinition.shape;
99
- const baseSize = 18;
100
- switch (shape) {
101
- case 'circle':
102
- return {
103
- width: baseSize,
104
- height: baseSize,
105
- borderRadius: '50%',
106
- };
107
- case 'diamond':
108
- return {
109
- width: baseSize - 4,
110
- height: baseSize - 4,
111
- borderRadius: 0,
112
- transform: 'rotate(45deg)',
113
- };
114
- case 'hexagon':
115
- return {
116
- width: baseSize,
117
- height: baseSize,
118
- borderRadius: 0,
119
- clipPath: 'polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%)',
120
- };
121
- case 'rectangle':
122
- default:
123
- return {
124
- width: baseSize,
125
- height: baseSize,
126
- borderRadius: 0,
127
- };
128
- }
129
- };
130
- // Get badge position based on shape - diamonds need badges at their points, not bounding box corners
131
- const getBadgePosition = (position) => {
132
- const isDiamondShape = typeDefinition.shape === 'diamond';
133
- if (isDiamondShape) {
134
- // Diamond points are at the middle of each edge of the bounding box
135
- switch (position) {
136
- case 'top-left':
137
- case 'left':
138
- // Position at the LEFT point of the diamond (center-left)
139
- return { top: '50%', left: 0, transform: 'translate(-50%, -50%)' };
140
- case 'top-right':
141
- case 'right':
142
- // Position at the RIGHT point of the diamond (center-right)
143
- return { top: '50%', right: 0, transform: 'translate(50%, -50%)' };
144
- case 'top':
145
- // Position at the TOP point of the diamond
146
- return { top: 0, left: '50%', transform: 'translate(-50%, -50%)' };
147
- case 'bottom':
148
- case 'bottom-left':
149
- case 'bottom-right':
150
- // Position at the BOTTOM point of the diamond
151
- return { bottom: 0, left: '50%', transform: 'translate(-50%, 50%)' };
152
- }
153
- }
154
- // Default positioning for rectangles, circles, hexagons (bounding box corners)
155
- switch (position) {
156
- case 'top-left':
157
- return { top: -6, left: -6 };
158
- case 'top-right':
159
- return { top: -6, right: -6 };
160
- case 'bottom-left':
161
- return { bottom: -6, left: -6 };
162
- case 'bottom-right':
163
- return { bottom: -6, right: -6 };
164
- case 'left':
165
- return { top: -6, left: -6 };
166
- case 'right':
167
- return { top: -6, right: -6 };
168
- case 'top':
169
- return { top: -6, left: '50%', transform: 'translateX(-50%)' };
170
- case 'bottom':
171
- return { bottom: -6, left: '50%', transform: 'translateX(-50%)' };
172
- }
173
- };
174
- // Render Sources badge (top-right) - shows "S" for files where event is instrumented
175
- const renderSourcesBadge = () => {
176
- // Use otel.files (source code files where event is instrumented)
177
- // Fall back to deprecated sources field for backwards compatibility
178
- const sourceFiles = files || sources;
179
- if (!sourceFiles || sourceFiles.length === 0)
180
- return null;
181
- const shapeStyles = getBadgeShapeStyles();
182
- const positionStyles = getBadgePosition('top-right');
183
- return (_jsx("div", { style: {
184
- position: 'absolute',
185
- ...positionStyles,
186
- ...shapeStyles,
187
- // Override transform if shape has rotation but we already have a position transform
188
- ...(typeDefinition.shape === 'diamond' ? { transform: `${positionStyles.transform} rotate(45deg)` } : {}),
189
- backgroundColor: '#10b981',
190
- color: 'white',
191
- fontSize: theme.fontSizes[0],
192
- fontWeight: theme.fontWeights.bold,
193
- fontFamily: theme.fonts.body,
194
- display: 'flex',
195
- alignItems: 'center',
196
- justifyContent: 'center',
197
- boxShadow: '0 1px 3px rgba(0,0,0,0.3)',
198
- zIndex: 10,
199
- opacity: nodeOpacity,
200
- }, title: `Source files: ${sourceFiles.join(', ')}`, children: _jsx("span", { style: { transform: shapeStyles.transform ? 'rotate(-45deg)' : undefined }, children: "S" }) }));
201
- };
202
- // Render References badge (bottom-left for rectangles, bottom for diamonds) - shows "R" for external references
203
- const renderReferencesBadge = () => {
204
- if (!references || references.length === 0)
205
- return null;
206
- const shapeStyles = getBadgeShapeStyles();
207
- const positionStyles = getBadgePosition('bottom-left');
208
- return (_jsx("div", { style: {
209
- position: 'absolute',
210
- ...positionStyles,
211
- ...shapeStyles,
212
- // Override transform if shape has rotation but we already have a position transform
213
- ...(typeDefinition.shape === 'diamond' ? { transform: `${positionStyles.transform} rotate(45deg)` } : {}),
214
- backgroundColor: '#8b5cf6',
215
- color: 'white',
216
- fontSize: theme.fontSizes[0],
217
- fontWeight: theme.fontWeights.bold,
218
- fontFamily: theme.fonts.body,
219
- display: 'flex',
220
- alignItems: 'center',
221
- justifyContent: 'center',
222
- boxShadow: '0 1px 3px rgba(0,0,0,0.3)',
223
- zIndex: 10,
224
- opacity: nodeOpacity,
225
- }, title: `References: ${references.join(', ')}`, children: _jsx("span", { style: { transform: shapeStyles.transform ? 'rotate(-45deg)' : undefined }, children: "R" }) }));
226
- };
227
- // Render Boundary badge (right/left points) - shown instead of sources badge for boundary nodes
228
- const renderBoundaryBadge = () => {
229
- const boundary = nodeData?.boundary;
230
- if (!boundary)
231
- return null;
232
- const direction = boundary.direction || 'outbound';
233
- const isOutbound = direction === 'outbound';
234
- // Direction indicators
235
- const directionIcon = isOutbound ? '↗' : '↙';
236
- const directionTitle = isOutbound ? 'Outbound boundary (calls external system)' : 'Inbound boundary (called by external system)';
237
- const positionStyles = getBadgePosition(isOutbound ? 'right' : 'left');
238
- return (_jsx("div", { style: {
239
- position: 'absolute',
240
- ...positionStyles,
241
- width: 18,
242
- height: 18,
243
- borderRadius: '50%',
244
- backgroundColor: '#06b6d4',
245
- color: 'white',
246
- fontSize: 12,
247
- fontWeight: theme.fontWeights.bold,
248
- fontFamily: theme.fonts.body,
249
- display: 'flex',
250
- alignItems: 'center',
251
- justifyContent: 'center',
252
- boxShadow: '0 1px 3px rgba(0,0,0,0.3)',
253
- zIndex: 10,
254
- opacity: nodeOpacity,
255
- }, title: directionTitle, children: directionIcon }));
256
- };
257
- // Check if this is a boundary node
258
- const isBoundaryNode = nodeData?.nodeType === 'boundary';
259
- // Render Status badge (top-left, or top point for diamonds)
260
- const renderStatusBadge = () => {
261
- const status = nodeData?.status;
262
- if (!status)
263
- return null;
264
- // Color mapping for status
265
- const statusColors = {
266
- draft: '#6b7280',
267
- approved: '#3b82f6',
268
- implemented: '#10b981', // Green
269
- };
270
- const statusLabels = {
271
- draft: 'D',
272
- approved: 'A',
273
- implemented: 'I',
274
- };
275
- const statusTitles = {
276
- draft: 'Draft - Design phase',
277
- approved: 'Approved - Ready for implementation',
278
- implemented: 'Implemented - Code exists',
279
- };
280
- const shapeStyles = getBadgeShapeStyles();
281
- const positionStyles = getBadgePosition('top-left');
282
- return (_jsx("div", { style: {
283
- position: 'absolute',
284
- ...positionStyles,
285
- ...shapeStyles,
286
- // Override transform if shape has rotation but we already have a position transform
287
- ...(typeDefinition.shape === 'diamond' ? { transform: `${positionStyles.transform} rotate(45deg)` } : {}),
288
- backgroundColor: statusColors[status],
289
- color: 'white',
290
- fontSize: theme.fontSizes[0],
291
- fontWeight: theme.fontWeights.bold,
292
- fontFamily: theme.fonts.body,
293
- display: 'flex',
294
- alignItems: 'center',
295
- justifyContent: 'center',
296
- boxShadow: '0 1px 3px rgba(0,0,0,0.3)',
297
- zIndex: 10,
298
- opacity: nodeOpacity,
299
- }, title: statusTitles[status], children: _jsx("span", { style: { transform: shapeStyles.transform ? 'rotate(-45deg)' : undefined }, children: statusLabels[status] }) }));
300
- };
301
- // Guard against missing typeDefinition
302
- if (!typeDefinition) {
303
- return (_jsx("div", { style: { padding: '10px', border: '2px solid red', borderRadius: '4px' }, children: _jsx("div", { style: { fontSize: '12px', color: 'red' }, children: "Error: Missing node type definition" }) }));
304
- }
305
- // Color Contract:
306
- // - scopeColor: Used as FILL/background color (from library.yaml scopes)
307
- // - spanColor: Used as BORDER color in workflow context (from .spans.canvas)
308
- // - For non-event canvases, falls back to legacy behavior (node color or type color)
309
- // Get colors from node data (injected by GraphRenderer)
310
- const nodeDataColor = nodeData.color;
311
- const scopeColor = nodeData.scopeColor;
312
- const spanColor = nodeData.spanColor;
313
- // Check node's own states first (from pv.states), then fall back to type definition states
314
- const nodeDataStates = nodeData.states;
315
- const stateColor = state && (nodeDataStates?.[state]?.color || typeDefinition.states?.[state]?.color);
316
- // Fill color priority: state color > node data color > scope color > type definition color > default
317
- // scopeColor provides background color from the scope definition in library.yaml
318
- const baseFillColor = nodeDataColor || scopeColor || typeDefinition.color || '#888';
319
- const fillColor = stateColor || baseFillColor;
320
- // Stroke/border color priority: explicit stroke > span color (workflow context) > fill color
321
- // spanColor provides border color in workflow context (from .spans.canvas)
322
- const nodeDataStroke = nodeData.stroke;
323
- const baseStrokeColor = nodeDataStroke || spanColor || fillColor;
324
- // Apply status-based border styling
325
- const status = nodeData?.status;
326
- const strokeColor = baseStrokeColor;
327
- // Use fillColor as the primary "color" for backwards compatibility
328
- const color = fillColor;
329
- // Get display name - use pending text if available, otherwise use name from props
330
- const displayName = nodeProps.pendingText ?? nodeProps.name;
331
- // Extract identifier based on node type (for display below the label)
332
- // Supports: event.name, otel.spanPattern, otel.scope, otel.resourceMatch, boundary.direction
333
- const eventData = nodeData?.event;
334
- const otelData = nodeData?.otel;
335
- const boundaryData = nodeData?.boundary;
336
- // Get identifier from multiple sources
337
- const getNodeIdentifier = () => {
338
- // Event name (for otel-event nodes)
339
- if (eventData?.name)
340
- return eventData.name;
341
- // Event ref (for nodes using library events)
342
- if (nodeData?.eventRef)
343
- return nodeData.eventRef;
344
- // Span pattern (for otel-span-convention nodes)
345
- if (otelData?.spanPattern)
346
- return otelData.spanPattern;
347
- // Scope name (for otel-scope nodes)
348
- if (otelData?.scope)
349
- return otelData.scope;
350
- // Resource match (for otel-resource nodes) - show first key:value
351
- if (otelData?.resourceMatch) {
352
- const entries = Object.entries(otelData.resourceMatch);
353
- if (entries.length > 0) {
354
- const [key, value] = entries[0];
355
- return `${key}: ${Array.isArray(value) ? value[0] : value}`;
356
- }
357
- }
358
- // Boundary direction (for otel-boundary nodes)
359
- if (boundaryData?.direction)
360
- return boundaryData.direction;
361
- return undefined;
362
- };
363
- const identifier = getNodeIdentifier();
364
- // Show identifier if it differs from display name
365
- const showIdentifier = identifier && identifier !== displayName;
366
- // Helper to render text with word break opportunities after dots
367
- const renderWithDotBreaks = (text) => {
368
- const parts = text.split('.');
369
- return parts.map((part, i) => (_jsxs("span", { children: [part, i < parts.length - 1 && (_jsxs(_Fragment, { children: [".", _jsx("wbr", {})] }))] }, i)));
370
- };
371
- // Helper component for rendering name with optional identifier
372
- // Identifiers can come from: event.name, eventRef, otel.spanPattern, otel.scope, otel.resourceMatch, boundary.direction
373
- const renderNameWithIdentifier = (centered = true) => (_jsxs("div", { style: { textAlign: centered ? 'center' : 'left', wordBreak: 'break-word' }, children: [_jsx("div", { children: displayName }), showIdentifier && (_jsx("div", { style: {
374
- fontSize: theme.fontSizes[0] * 0.75,
375
- color: 'rgba(0, 0, 0, 0.5)',
376
- marginTop: '2px',
377
- fontFamily: theme.fonts.monospace,
378
- }, children: renderWithDotBreaks(identifier) }))] }));
379
- // Icon priority: node data override > state icon (node data states first) > type definition icon
380
- const icon = nodeData.icon ||
381
- (state && (nodeDataStates?.[state]?.icon || typeDefinition.states?.[state]?.icon)) ||
382
- typeDefinition.icon;
383
- // Get animation class based on type
384
- const getAnimationClass = () => {
385
- switch (animationType) {
386
- case 'pulse':
387
- return 'node-pulse';
388
- case 'flash':
389
- return 'node-flash';
390
- case 'shake':
391
- return 'node-shake';
392
- case 'entry':
393
- return 'node-entry';
394
- default:
395
- return '';
396
- }
397
- };
398
- const animationClass = getAnimationClass();
399
- // Check if this is a group node or text node (canvas types that support inline editing)
400
- const isGroup = nodeData.canvasType === 'group';
401
- const isTextNode = nodeData.canvasType === 'text';
402
- const isInlineEditable = (isGroup || isTextNode) && editable;
403
- // Double-click handler for inline text editing
404
- const lastClickTimeRef = useRef(0);
405
- const handleNodeDoubleClick = useCallback((event) => {
406
- if (!isInlineEditable || !nodeId || !onNodeTextChange)
407
- return;
408
- event.stopPropagation();
409
- event.preventDefault();
410
- setEditingText(displayName || '');
411
- setIsEditing(true);
412
- // Focus the textarea after state update
413
- setTimeout(() => {
414
- textareaRef.current?.focus();
415
- textareaRef.current?.select();
416
- }, 0);
417
- }, [isInlineEditable, nodeId, onNodeTextChange, displayName]);
418
- // Single click tracking for double-click detection
419
- const handleNodeClick = useCallback((event) => {
420
- const now = Date.now();
421
- const timeSinceLastClick = now - lastClickTimeRef.current;
422
- if (timeSinceLastClick < 300) {
423
- // Double-click detected
424
- handleNodeDoubleClick(event);
425
- }
426
- lastClickTimeRef.current = now;
427
- }, [handleNodeDoubleClick]);
428
- // Save text changes
429
- const handleSaveText = useCallback(() => {
430
- if (!nodeId || !onNodeTextChange)
431
- return;
432
- if (editingText !== displayName) {
433
- onNodeTextChange(nodeId, editingText);
434
- }
435
- setIsEditing(false);
436
- }, [nodeId, onNodeTextChange, editingText, displayName]);
437
- // Cancel text editing
438
- const handleCancelEdit = useCallback(() => {
439
- setIsEditing(false);
440
- setEditingText('');
441
- }, []);
442
- // Shape-specific styles
443
- const getShapeStyles = () => {
444
- const borderStyle = status === 'draft' ? 'dotted' : status === 'approved' ? 'dashed' : 'solid';
445
- const baseStyles = {
446
- padding: '12px 16px',
447
- backgroundColor: isGroup ? 'rgba(255, 255, 255, 0.7)' : fillColor,
448
- color: '#000',
449
- border: `2px ${borderStyle} ${hasViolations ? '#D0021B' : strokeColor}`,
450
- fontSize: theme.fontSizes[0],
451
- fontWeight: theme.fontWeights.medium,
452
- fontFamily: theme.fonts.body,
453
- // Use 100% width/height to fill the node container (for resizing support)
454
- width: '100%',
455
- height: '100%',
456
- // Use small absolute minimums - typeDefinition.size is the default, not the minimum
457
- minWidth: 20,
458
- minHeight: 20,
459
- display: 'flex',
460
- flexDirection: 'column',
461
- alignItems: 'center',
462
- justifyContent: isGroup ? 'flex-start' : 'center',
463
- gap: '4px',
464
- boxShadow: isHighlighted
465
- ? `0 0 0 3px #3b82f6, 0 0 20px rgba(59, 130, 246, 0.5)`
466
- : selected
467
- ? `0 0 0 2px ${strokeColor}`
468
- : '0 2px 4px rgba(0,0,0,0.1)',
469
- opacity: nodeOpacity,
470
- transition: 'box-shadow 0.2s ease, opacity 0.3s ease',
471
- animationDuration: animationType ? `${animationDuration}ms` : undefined,
472
- boxSizing: 'border-box',
473
- };
474
- switch (typeDefinition.shape) {
475
- case 'circle':
476
- return {
477
- ...baseStyles,
478
- borderRadius: '50%',
479
- padding: '8px',
480
- };
481
- case 'hexagon':
482
- // Hexagon uses wrapper approach for proper border - styles returned here are for inner fill
483
- // The outer border wrapper is rendered separately in the JSX
484
- return {
485
- ...baseStyles,
486
- border: 'none',
487
- clipPath: 'polygon(20% 0%, 80% 0%, 100% 50%, 80% 100%, 20% 100%, 0% 50%)',
488
- width: '100%',
489
- height: '100%',
490
- minWidth: 'unset',
491
- minHeight: 'unset',
492
- padding: '8px 20px',
493
- boxShadow: 'none', // Shadow handled by wrapper
494
- };
495
- case 'diamond':
496
- // Diamond uses wrapper approach for proper border - styles returned here are for inner fill
497
- // The outer border wrapper is rendered separately in the JSX
498
- return {
499
- ...baseStyles,
500
- border: 'none',
501
- clipPath: 'polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)',
502
- width: '100%',
503
- height: '100%',
504
- minWidth: 'unset',
505
- minHeight: 'unset',
506
- padding: '8px 16px',
507
- boxShadow: 'none', // Shadow handled by wrapper
508
- };
509
- case 'rectangle':
510
- default:
511
- return {
512
- ...baseStyles,
513
- // Boundary nodes get rounded corners, regular rectangles get sharp corners
514
- borderRadius: isBoundaryNode ? '8px' : '0',
515
- };
516
- }
517
- };
518
- const isDiamond = typeDefinition.shape === 'diamond';
519
- const isHexagon = typeDefinition.shape === 'hexagon';
520
- const isCircle = typeDefinition.shape === 'circle';
521
- // Determine if aspect ratio should be locked (circles should maintain square aspect)
522
- const keepAspectRatio = isCircle;
523
- // Minimum dimensions for resizing - use small absolute values, not typeDefinition.size
524
- const minWidth = 40;
525
- const minHeight = isCircle ? 40 : 30;
526
- // Hexagon border wrapper styles (outer shape that acts as border)
527
- // Hexagon with gentle diagonals
528
- const hexagonClipPath = 'polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%)';
529
- // Note: Dotted/dashed borders not supported for hexagon shape (CSS limitation with clip-path)
530
- // All statuses use 2px solid border for hexagons
531
- const hexagonBorderWidth = 2;
532
- const hexagonBorderStyle = isHexagon
533
- ? {
534
- position: 'relative',
535
- clipPath: hexagonClipPath,
536
- backgroundColor: hasViolations ? '#D0021B' : strokeColor,
537
- // Use 100% to fill container for resizing support
538
- width: '100%',
539
- height: '100%',
540
- // Use small absolute minimums - typeDefinition.size is the default, not the minimum
541
- minWidth: 20,
542
- minHeight: 20,
543
- boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
544
- opacity: nodeOpacity,
545
- transition: 'opacity 0.3s ease',
546
- boxSizing: 'border-box',
547
- }
548
- : {};
549
- // Hexagon inner fill styles (light color background inset from border)
550
- const hexagonInnerStyle = isHexagon
551
- ? {
552
- position: 'absolute',
553
- top: hexagonBorderWidth,
554
- left: hexagonBorderWidth,
555
- right: hexagonBorderWidth,
556
- bottom: hexagonBorderWidth,
557
- clipPath: hexagonClipPath,
558
- backgroundColor: fillColor,
559
- color: '#000',
560
- display: 'flex',
561
- flexDirection: 'column',
562
- alignItems: 'center',
563
- justifyContent: 'center',
564
- fontSize: theme.fontSizes[0],
565
- fontWeight: theme.fontWeights.medium,
566
- fontFamily: theme.fonts.body,
567
- gap: '4px',
568
- }
569
- : {};
570
- // Diamond clip-path
571
- const diamondClipPath = 'polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)';
572
- // Note: Dotted/dashed borders not supported for diamond shape (CSS limitation with clip-path)
573
- // All statuses use 2px solid border for diamonds
574
- const diamondBorderWidth = 2;
575
- // Diamond border wrapper styles (outer shape that acts as border)
576
- const diamondBorderStyle = isDiamond
577
- ? {
578
- position: 'relative',
579
- clipPath: diamondClipPath,
580
- backgroundColor: hasViolations ? '#D0021B' : strokeColor,
581
- width: '100%',
582
- height: '100%',
583
- // Use small absolute minimums - typeDefinition.size is the default, not the minimum
584
- minWidth: 20,
585
- minHeight: 20,
586
- boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
587
- opacity: nodeOpacity,
588
- transition: 'opacity 0.3s ease',
589
- boxSizing: 'border-box',
590
- }
591
- : {};
592
- // Diamond inner fill styles (light color background inset from border)
593
- const diamondInnerStyle = isDiamond
594
- ? {
595
- position: 'absolute',
596
- top: diamondBorderWidth,
597
- left: diamondBorderWidth,
598
- right: diamondBorderWidth,
599
- bottom: diamondBorderWidth,
600
- clipPath: diamondClipPath,
601
- backgroundColor: fillColor,
602
- color: '#000',
603
- display: 'flex',
604
- flexDirection: 'column',
605
- alignItems: 'center',
606
- justifyContent: 'center',
607
- fontSize: theme.fontSizes[0],
608
- fontWeight: theme.fontWeights.medium,
609
- fontFamily: theme.fonts.body,
610
- gap: '4px',
611
- }
612
- : {};
613
- // Handle styles - larger and more visible in edit mode, hidden otherwise
614
- const baseHandleStyle = editable
615
- ? {
616
- background: color,
617
- width: 12,
618
- height: 12,
619
- border: '2px solid white',
620
- boxShadow: '0 0 0 1px ' + color,
621
- }
622
- : {
623
- background: color,
624
- width: 8,
625
- height: 8,
626
- opacity: 0,
627
- pointerEvents: 'none',
628
- };
629
- const getHandleStyle = (_position) => {
630
- if (!isDiamond && !isHexagon)
631
- return baseHandleStyle;
632
- const offsetStyle = { ...baseHandleStyle };
633
- // Bring handles above the clip-path layers for hexagon and diamond
634
- if (isHexagon || isDiamond) {
635
- offsetStyle.zIndex = 10;
636
- }
637
- return offsetStyle;
638
- };
639
- return (_jsxs(_Fragment, { children: [editable && (_jsx(NodeResizer, { color: strokeColor, isVisible: selected, minWidth: minWidth, minHeight: minHeight, keepAspectRatio: keepAspectRatio, onResizeEnd: handleResizeEnd, handleStyle: {
640
- width: 8,
641
- height: 8,
642
- borderRadius: 2,
643
- zIndex: 20,
644
- }, lineStyle: {
645
- borderWidth: 1,
646
- zIndex: 20,
647
- } })), _jsx(Handle, { type: "target", position: Position.Top, id: "top", style: getHandleStyle('top') }), _jsx(Handle, { type: "target", position: Position.Bottom, id: "bottom", style: getHandleStyle('bottom') }), _jsx(Handle, { type: "target", position: Position.Left, id: "left", style: getHandleStyle('left') }), _jsx(Handle, { type: "target", position: Position.Right, id: "right", style: getHandleStyle('right') }), isHexagon ? (_jsxs("div", { ref: nodeRef, style: {
648
- position: 'relative',
649
- width: '100%',
650
- height: '100%',
651
- boxShadow: isHighlighted
652
- ? `0 0 0 3px #3b82f6, 0 0 20px rgba(59, 130, 246, 0.5)`
653
- : selected
654
- ? `0 0 0 2px ${strokeColor}`
655
- : 'none',
656
- transition: 'box-shadow 0.2s ease',
657
- }, onMouseDown: handleMouseDown, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), children: [renderStatusBadge(), isBoundaryNode ? renderBoundaryBadge() : (_jsxs(_Fragment, { children: [renderSourcesBadge(), renderReferencesBadge()] })), _jsx("div", { style: hexagonBorderStyle, className: animationClass, children: _jsxs("div", { style: hexagonInnerStyle, children: [icon && (_jsx("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center' }, children: resolveIcon(icon, 20) })), renderNameWithIdentifier(), state && (_jsx("div", { style: {
658
- fontSize: theme.fontSizes[0],
659
- fontFamily: theme.fonts.body,
660
- backgroundColor: color,
661
- color: 'white',
662
- padding: '2px 6px',
663
- borderRadius: '4px',
664
- textAlign: 'center',
665
- }, children: nodeDataStates?.[state]?.label || typeDefinition.states?.[state]?.label || state })), hasViolations && (_jsx("div", { style: {
666
- fontSize: theme.fontSizes[0],
667
- fontFamily: theme.fonts.body,
668
- color: '#D0021B',
669
- fontWeight: theme.fontWeights.bold,
670
- }, children: "\u26A0\uFE0F" }))] }) }), tooltipsEnabled && (_jsx(NodeTooltip, { description: description, otel: otelInfo, sources: sources, references: references, visible: showTooltip, nodeRef: nodeRef }))] })) : isDiamond ? (_jsxs("div", { ref: nodeRef, style: {
671
- position: 'relative',
672
- width: '100%',
673
- height: '100%',
674
- boxShadow: isHighlighted
675
- ? `0 0 0 3px #3b82f6, 0 0 20px rgba(59, 130, 246, 0.5)`
676
- : selected
677
- ? `0 0 0 2px ${strokeColor}`
678
- : 'none',
679
- transition: 'box-shadow 0.2s ease',
680
- }, onMouseDown: handleMouseDown, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), children: [renderStatusBadge(), isBoundaryNode ? renderBoundaryBadge() : (_jsxs(_Fragment, { children: [renderSourcesBadge(), renderReferencesBadge()] })), _jsx("div", { style: diamondBorderStyle, className: animationClass, children: _jsxs("div", { style: diamondInnerStyle, children: [icon && (_jsx("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center' }, children: resolveIcon(icon, 20) })), renderNameWithIdentifier(), state && (_jsx("div", { style: {
681
- fontSize: theme.fontSizes[0],
682
- fontFamily: theme.fonts.body,
683
- backgroundColor: color,
684
- color: 'white',
685
- padding: '2px 6px',
686
- borderRadius: '4px',
687
- textAlign: 'center',
688
- }, children: nodeDataStates?.[state]?.label || typeDefinition.states?.[state]?.label || state })), hasViolations && (_jsx("div", { style: {
689
- fontSize: theme.fontSizes[0],
690
- fontFamily: theme.fonts.body,
691
- color: '#D0021B',
692
- fontWeight: theme.fontWeights.bold,
693
- }, children: "\u26A0\uFE0F" }))] }) }), tooltipsEnabled && (_jsx(NodeTooltip, { description: description, otel: otelInfo, sources: sources, references: references, visible: showTooltip, nodeRef: nodeRef }))] })) : (_jsxs("div", { ref: nodeRef, style: { position: 'relative', width: '100%', height: '100%' }, onMouseDown: handleMouseDown, onClick: handleNodeClick, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), children: [renderStatusBadge(), isBoundaryNode ? renderBoundaryBadge() : (_jsxs(_Fragment, { children: [renderSourcesBadge(), renderReferencesBadge()] })), _jsx("div", { style: getShapeStyles(), className: animationClass, children: _jsxs("div", { style: {
694
- ...(isGroup ? { width: '100%' } : {}),
695
- }, children: [isGroup ? (_jsxs("div", { style: {
696
- display: 'flex',
697
- alignItems: 'center',
698
- justifyContent: 'center',
699
- gap: '6px',
700
- width: '100%',
701
- }, children: [icon && resolveIcon(icon, 18), renderNameWithIdentifier(false)] })) : (_jsxs(_Fragment, { children: [icon && (_jsx("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center' }, children: resolveIcon(icon, 20) })), renderNameWithIdentifier()] })), state && (_jsx("div", { style: {
702
- fontSize: theme.fontSizes[0],
703
- fontFamily: theme.fonts.body,
704
- backgroundColor: color,
705
- color: 'white',
706
- padding: '2px 6px',
707
- borderRadius: '4px',
708
- textAlign: 'center',
709
- }, children: nodeDataStates?.[state]?.label || typeDefinition.states?.[state]?.label || state })), hasViolations && (_jsx("div", { style: {
710
- fontSize: theme.fontSizes[0],
711
- fontFamily: theme.fonts.body,
712
- color: '#D0021B',
713
- fontWeight: theme.fontWeights.bold,
714
- }, children: "\u26A0\uFE0F" }))] }) }), isEditing && isInlineEditable && (_jsx("div", { style: {
715
- position: 'absolute',
716
- top: 0,
717
- left: 0,
718
- width: '100%',
719
- height: '100%',
720
- zIndex: 1000,
721
- display: 'flex',
722
- flexDirection: 'column',
723
- padding: theme.space[1],
724
- boxSizing: 'border-box',
725
- }, onClick: (e) => e.stopPropagation(), children: _jsx("textarea", { ref: textareaRef, value: editingText, onChange: (e) => setEditingText(e.target.value), placeholder: "Enter text...", style: {
726
- flex: 1,
727
- width: '100%',
728
- padding: theme.space[2],
729
- fontSize: theme.fontSizes[1],
730
- fontFamily: theme.fonts.body,
731
- color: theme.colors.text,
732
- backgroundColor: theme.colors.background,
733
- border: `3px solid ${theme.colors.primary}`,
734
- borderRadius: theme.radii[1],
735
- outline: 'none',
736
- resize: 'none',
737
- boxSizing: 'border-box',
738
- boxShadow: '0 8px 24px rgba(0, 0, 0, 0.3)',
739
- }, onKeyDown: (e) => {
740
- if (e.key === 'Enter' && !e.shiftKey) {
741
- e.preventDefault();
742
- handleSaveText();
743
- }
744
- else if (e.key === 'Escape') {
745
- e.preventDefault();
746
- handleCancelEdit();
747
- }
748
- }, onBlur: handleSaveText }) })), tooltipsEnabled && (_jsx(NodeTooltip, { description: description, otel: otelInfo, sources: sources, references: references, visible: showTooltip, nodeRef: nodeRef }))] })), _jsx(Handle, { type: "source", position: Position.Top, id: "top-out", style: getHandleStyle('top') }), _jsx(Handle, { type: "source", position: Position.Bottom, id: "bottom-out", style: getHandleStyle('bottom') }), _jsx(Handle, { type: "source", position: Position.Left, id: "left-out", style: getHandleStyle('left') }), _jsx(Handle, { type: "source", position: Position.Right, id: "right-out", style: getHandleStyle('right') }), _jsx("style", { children: `
749
- /* Processing pulse - continuous breathing effect */
750
- .node-pulse {
751
- animation: node-pulse ease-in-out infinite;
752
- }
753
-
754
- @keyframes node-pulse {
755
- 0%, 100% {
756
- transform: scale(1);
757
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
758
- }
759
- 50% {
760
- transform: scale(1.05);
761
- box-shadow: 0 4px 12px rgba(0,0,0,0.2), 0 0 0 4px rgba(59, 130, 246, 0.3);
762
- }
763
- }
764
-
765
- /* Success flash - brief green glow */
766
- .node-flash {
767
- animation: node-flash ease-out forwards;
768
- }
769
-
770
- @keyframes node-flash {
771
- 0% {
772
- box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.8);
773
- background-color: rgba(34, 197, 94, 0.1);
774
- }
775
- 50% {
776
- box-shadow: 0 0 0 8px rgba(34, 197, 94, 0);
777
- background-color: rgba(34, 197, 94, 0.2);
778
- }
779
- 100% {
780
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
781
- background-color: white;
782
- }
783
- }
784
-
785
- /* Error shake - vibrate effect */
786
- .node-shake {
787
- animation: node-shake ease-in-out;
788
- }
789
-
790
- @keyframes node-shake {
791
- 0%, 100% {
792
- transform: translateX(0);
793
- }
794
- 10%, 30%, 50%, 70%, 90% {
795
- transform: translateX(-4px);
796
- }
797
- 20%, 40%, 60%, 80% {
798
- transform: translateX(4px);
799
- }
800
- }
801
-
802
- /* Entry animation - scale up and fade in */
803
- .node-entry {
804
- animation: node-entry ease-out forwards;
805
- }
806
-
807
- @keyframes node-entry {
808
- 0% {
809
- opacity: 0;
810
- transform: scale(0.8);
811
- }
812
- 100% {
813
- opacity: 1;
814
- transform: scale(1);
815
- }
816
- }
817
-
818
- ` })] }));
819
- };
820
- //# sourceMappingURL=CustomNode.js.map