@elevasis/ui 2.34.0 → 2.36.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.
Files changed (116) hide show
  1. package/dist/api/index.js +3 -3
  2. package/dist/app/index.d.ts +37 -30
  3. package/dist/app/index.js +25 -23
  4. package/dist/charts/index.js +3 -5
  5. package/dist/{chunk-ND5TDV2J.js → chunk-57OZ3AEG.js} +1 -1
  6. package/dist/{chunk-E4WQGJNS.js → chunk-7FPLLSHN.js} +14 -1
  7. package/dist/{chunk-RQA2EVN3.js → chunk-AKW7KISS.js} +39 -3
  8. package/dist/chunk-AUDNF2Q7.js +2050 -0
  9. package/dist/chunk-F6EFC2MJ.js +41101 -0
  10. package/dist/{chunk-TYRUKGGD.js → chunk-GX6XBRRF.js} +1 -2
  11. package/dist/{chunk-RIAXZ6AH.js → chunk-K4UZU3TU.js} +2 -2
  12. package/dist/{chunk-V6SZ4ECN.js → chunk-LUYVRATI.js} +257 -6
  13. package/dist/{chunk-DTFKWZ7A.js → chunk-O2Q4VMRN.js} +589 -932
  14. package/dist/{chunk-X4WBGKJQ.js → chunk-R3VCBZDC.js} +50 -3
  15. package/dist/chunk-SIQ3P4OR.js +1764 -0
  16. package/dist/{chunk-3FV6HBXS.js → chunk-WF7CONXF.js} +23 -23
  17. package/dist/{chunk-3QXJK5IY.js → chunk-YYX7OPZQ.js} +1 -1
  18. package/dist/components/index.d.ts +74 -71
  19. package/dist/components/index.js +20 -2795
  20. package/dist/components/navigation/index.js +25 -5
  21. package/dist/execution/index.d.ts +11 -11
  22. package/dist/execution/index.js +1 -2
  23. package/dist/features/auth/index.d.ts +3 -0
  24. package/dist/features/auth/index.js +23 -2
  25. package/dist/features/clients/index.js +20 -26
  26. package/dist/features/crm/index.d.ts +3 -0
  27. package/dist/features/crm/index.js +20 -30
  28. package/dist/features/dashboard/index.d.ts +69 -69
  29. package/dist/features/dashboard/index.js +20 -28
  30. package/dist/features/delivery/index.d.ts +3 -0
  31. package/dist/features/delivery/index.js +20 -30
  32. package/dist/features/knowledge/index.js +25 -9
  33. package/dist/features/lead-gen/index.d.ts +295 -57
  34. package/dist/features/lead-gen/index.js +20 -31
  35. package/dist/features/monitoring/index.js +20 -30
  36. package/dist/features/monitoring/requests/index.js +20 -25
  37. package/dist/features/operations/index.d.ts +183 -183
  38. package/dist/features/operations/index.js +18 -37
  39. package/dist/features/seo/index.js +3 -4
  40. package/dist/features/settings/index.d.ts +3 -0
  41. package/dist/features/settings/index.js +20 -27
  42. package/dist/graph/index.js +1 -1
  43. package/dist/hooks/delivery/index.d.ts +3 -0
  44. package/dist/hooks/delivery/index.js +30 -2
  45. package/dist/hooks/index.d.ts +112 -99
  46. package/dist/hooks/index.js +20 -21
  47. package/dist/hooks/operations/command-view/utils/transformCommandViewData.d.ts +46 -46
  48. package/dist/hooks/published.d.ts +112 -99
  49. package/dist/hooks/published.js +20 -20
  50. package/dist/index.css +532 -532
  51. package/dist/index.d.ts +9385 -5915
  52. package/dist/index.js +22 -26
  53. package/dist/initialization/index.d.ts +3 -0
  54. package/dist/knowledge/index.d.ts +42 -42
  55. package/dist/knowledge/index.js +10 -17
  56. package/dist/{knowledge-search-index-ORIJCEZX.js → knowledge-search-index-NBCTFIOH.js} +2 -2
  57. package/dist/layout/index.js +4 -10
  58. package/dist/organization/index.js +27 -1
  59. package/dist/profile/index.d.ts +3 -0
  60. package/dist/provider/index.d.ts +72 -39
  61. package/dist/provider/index.js +20 -15
  62. package/dist/provider/published.d.ts +40 -34
  63. package/dist/provider/published.js +20 -11
  64. package/dist/sse/index.js +26 -5
  65. package/dist/supabase/index.d.ts +6 -0
  66. package/dist/test-utils/index.js +3 -3
  67. package/dist/theme/index.js +2 -3
  68. package/dist/theme/presets/index.d.ts +28 -3
  69. package/dist/theme/presets/index.js +1 -1
  70. package/dist/typeform/index.js +1 -2049
  71. package/dist/types/index.d.ts +82 -79
  72. package/dist/utils/index.d.ts +47 -47
  73. package/dist/utils/index.js +1 -1
  74. package/dist/zustand/index.d.ts +6 -6
  75. package/dist/zustand/index.js +0 -3
  76. package/package.json +5 -5
  77. package/dist/chunk-3AJVNMY5.js +0 -4769
  78. package/dist/chunk-3MEXPLWT.js +0 -265
  79. package/dist/chunk-3ZMAGTWF.js +0 -18
  80. package/dist/chunk-4O4MII5S.js +0 -4716
  81. package/dist/chunk-5EYJ2GIN.js +0 -122
  82. package/dist/chunk-7M2VOCYN.js +0 -1
  83. package/dist/chunk-BPQVTIUP.js +0 -105
  84. package/dist/chunk-BZZCNLT6.js +0 -12
  85. package/dist/chunk-CLDCYJQT.js +0 -1
  86. package/dist/chunk-E565XMTQ.js +0 -17
  87. package/dist/chunk-HRWLKKWM.js +0 -758
  88. package/dist/chunk-IGDYWFNE.js +0 -5198
  89. package/dist/chunk-IIMU5YAJ.js +0 -53
  90. package/dist/chunk-IVGI4GDL.js +0 -1593
  91. package/dist/chunk-JFL3GRD4.js +0 -39
  92. package/dist/chunk-LAWLB6CT.js +0 -951
  93. package/dist/chunk-LGKLC5MG.js +0 -44
  94. package/dist/chunk-LRWTWOGP.js +0 -1778
  95. package/dist/chunk-MP3GPBPX.js +0 -1874
  96. package/dist/chunk-N55DVMAG.js +0 -14
  97. package/dist/chunk-NLBQTDOW.js +0 -12051
  98. package/dist/chunk-O6JXQ6UQ.js +0 -468
  99. package/dist/chunk-OBBQ2JCM.js +0 -68
  100. package/dist/chunk-PDHTXPSF.js +0 -12
  101. package/dist/chunk-PLP3NYPL.js +0 -356
  102. package/dist/chunk-R2XR4FCV.js +0 -48
  103. package/dist/chunk-R66W5UDG.js +0 -26
  104. package/dist/chunk-RYTEQBAO.js +0 -37
  105. package/dist/chunk-SDXSB3HN.js +0 -425
  106. package/dist/chunk-TKAYX2SP.js +0 -204
  107. package/dist/chunk-TUMSNGTX.js +0 -35
  108. package/dist/chunk-VNAZTCHA.js +0 -65
  109. package/dist/chunk-VNFR57DF.js +0 -87
  110. package/dist/chunk-VTXTZXAU.js +0 -539
  111. package/dist/chunk-W73ZABT6.js +0 -85
  112. package/dist/chunk-WU4FNWCW.js +0 -2281
  113. package/dist/chunk-XZGSCABI.js +0 -383
  114. package/dist/chunk-YNWZIWJL.js +0 -1863
  115. /package/dist/{chunk-2RJMVWFJ.js → chunk-GEFWMU26.js} +0 -0
  116. /package/dist/{chunk-22UVE3RA.js → chunk-HENXLGVD.js} +0 -0
@@ -1,1874 +0,0 @@
1
- import { ZodFormRenderer } from './chunk-3MEXPLWT.js';
2
- import { ResourceHealthChart } from './chunk-LGKLC5MG.js';
3
- import { useCyberColors, HeroStatsRow } from './chunk-LAWLB6CT.js';
4
- import { AppShellCenteredContainer, AppShellLoader } from './chunk-RYTEQBAO.js';
5
- import { Graph_module_css_default, useDirectedChainHighlighting, useNodeSelection, useFitViewTrigger } from './chunk-22UVE3RA.js';
6
- import { STATUS_COLORS, getStatusIcon, formatDuration, getStatusColors, AGENT_CONSTANTS, shouldAnimateEdge, TIMELINE_CONSTANTS, calculateBarPosition, CONTAINER_CONSTANTS, useExecutionPath, useUnifiedWorkflowLayout, WORKFLOW_CONSTANTS, useReactFlowAgent } from './chunk-E4WQGJNS.js';
7
- import { useExecuteResource, useDashboardMetrics, useResources, useTimeRangeDates, useUnresolvedErrors, useRecentExecutionsByResource, useCommandQueue, useScheduledTasks, useResourcesHealth } from './chunk-IGDYWFNE.js';
8
- import { glassBase } from './chunk-RQA2EVN3.js';
9
- import { GlowDot, CardHeader, EmptyState, PageTitleCaption, TabCountBadge } from './chunk-HRWLKKWM.js';
10
- import { formatTimeAgo, getTimeRangeDates, formatRelativeTime } from './chunk-2RJMVWFJ.js';
11
- import { ResourceStatusColors } from './chunk-KRWALB24.js';
12
- import { useInitialization } from './chunk-533DUEQY.js';
13
- import { memo, useMemo, useEffect, useState, useCallback, Fragment } from 'react';
14
- import { Paper, Stack, Text, Group, Badge, Box, useComputedColorScheme, Card, ActionIcon, Loader, SegmentedControl, Button, Modal, Center, SimpleGrid, Title, Tabs, Grid, ThemeIcon } from '@mantine/core';
15
- import { jsxs, jsx, Fragment as Fragment$1 } from 'react/jsx-runtime';
16
- import { Position, Handle, getSmoothStepPath, BaseEdge as BaseEdge$1, EdgeLabelRenderer, Panel, useReactFlow, Controls, ReactFlowProvider, ReactFlow } from '@xyflow/react';
17
- import { IconPlayerPlay, IconPlayerStop, IconArrowsSplit, IconSquare, IconFocus2, IconArrowUpRight, IconLayoutDashboard, IconActivity, IconAlertTriangle, IconHandStop, IconCalendarEvent, IconCircleCheck, IconBrain, IconGitBranch } from '@tabler/icons-react';
18
- import '@xyflow/react/dist/style.css';
19
- import { z } from 'zod';
20
- import { notifications } from '@mantine/notifications';
21
- import '@mantine/charts/styles.css';
22
-
23
- var DOMAIN_COLORS = {
24
- primary: "var(--color-primary)",
25
- agent: "#8b5cf6",
26
- workflow: "#3b82f6",
27
- trigger: "#f97316",
28
- integration: "#14b8a6",
29
- approval: "#f59e0b"
30
- };
31
- function fill(color, isDark) {
32
- return isDark ? `color-mix(in srgb, ${color} 80%, black)` : `color-mix(in srgb, ${color} 60%, white)`;
33
- }
34
- function glow(color) {
35
- return `color-mix(in srgb, ${color} 40%, transparent)`;
36
- }
37
- function useGraphTheme() {
38
- const isDark = useComputedColorScheme("dark") === "dark";
39
- return useMemo(
40
- () => ({
41
- primary: fill(DOMAIN_COLORS.primary, isDark),
42
- primaryGlow: glow(DOMAIN_COLORS.primary),
43
- agent: fill(DOMAIN_COLORS.agent, isDark),
44
- workflow: fill(DOMAIN_COLORS.workflow, isDark),
45
- trigger: fill(DOMAIN_COLORS.trigger, isDark),
46
- integration: fill(DOMAIN_COLORS.integration, isDark),
47
- approval: fill(DOMAIN_COLORS.approval, isDark),
48
- agentGlow: glow(DOMAIN_COLORS.agent),
49
- workflowGlow: glow(DOMAIN_COLORS.workflow),
50
- triggerGlow: glow(DOMAIN_COLORS.trigger),
51
- integrationGlow: glow(DOMAIN_COLORS.integration),
52
- approvalGlow: glow(DOMAIN_COLORS.approval),
53
- edgeTriggers: fill(DOMAIN_COLORS.workflow, isDark),
54
- edgeUses: fill(DOMAIN_COLORS.integration, isDark),
55
- edgeApproval: fill(DOMAIN_COLORS.approval, isDark),
56
- edgeTriggersGlow: glow(DOMAIN_COLORS.workflow),
57
- edgeUsesGlow: glow(DOMAIN_COLORS.integration),
58
- edgeApprovalGlow: glow(DOMAIN_COLORS.approval)
59
- }),
60
- [isDark]
61
- );
62
- }
63
- function getGraphBackgroundStyles(isDark) {
64
- const pct = isDark ? 5 : 3;
65
- const glowPct = isDark ? 8 : 5;
66
- const mix = (percent) => `color-mix(in srgb, var(--color-primary) ${percent}%, transparent)`;
67
- return {
68
- backgroundImage: `
69
- linear-gradient(${mix(pct)} 1px, transparent 1px),
70
- linear-gradient(90deg, ${mix(pct)} 1px, transparent 1px),
71
- radial-gradient(ellipse at 50% 50%, ${mix(glowPct)} 0%, transparent 70%)
72
- `,
73
- backgroundColor: "color-mix(in srgb, var(--color-background) 50%, var(--glass-background))",
74
- backdropFilter: "var(--glass-blur)",
75
- backgroundSize: "40px 40px, 40px 40px, 100% 100%"
76
- };
77
- }
78
- function useGraphBackgroundStyles() {
79
- const isDark = useComputedColorScheme("dark") === "dark";
80
- return useMemo(() => getGraphBackgroundStyles(isDark), [isDark]);
81
- }
82
- function GraphContainer({ children, height = 600 }) {
83
- const backgroundStyles = useGraphBackgroundStyles();
84
- return /* @__PURE__ */ jsx(
85
- Box,
86
- {
87
- style: {
88
- width: "100%",
89
- height,
90
- border: "1px solid var(--color-border)",
91
- borderRadius: "var(--mantine-radius-md)",
92
- overflow: "hidden",
93
- position: "relative",
94
- ...backgroundStyles
95
- },
96
- children
97
- }
98
- );
99
- }
100
- function GraphBackground() {
101
- return null;
102
- }
103
- function LegendDot({ color }) {
104
- return /* @__PURE__ */ jsx(
105
- Box,
106
- {
107
- style: {
108
- width: 10,
109
- height: 10,
110
- borderRadius: "50%",
111
- backgroundColor: `var(--mantine-color-${color}-5)`
112
- }
113
- }
114
- );
115
- }
116
- function LegendLine({ color }) {
117
- return /* @__PURE__ */ jsx(
118
- Box,
119
- {
120
- style: {
121
- width: 20,
122
- height: 3,
123
- borderRadius: 2,
124
- background: `linear-gradient(90deg, var(--mantine-color-${color}-5), var(--mantine-color-${color}-6))`
125
- }
126
- }
127
- );
128
- }
129
- function GraphLegend({ title = "Legend", items, position = "bottom-right" }) {
130
- const margins = {
131
- marginBottom: position.includes("bottom") ? 12 : void 0,
132
- marginTop: position.includes("top") ? 12 : void 0,
133
- marginRight: position.includes("right") ? 60 : 12,
134
- marginLeft: position.includes("left") ? 12 : void 0
135
- };
136
- return /* @__PURE__ */ jsx(Panel, { position, style: margins, children: /* @__PURE__ */ jsx(Card, { p: "xs", className: Graph_module_css_default.legend, children: /* @__PURE__ */ jsxs(Group, { children: [
137
- /* @__PURE__ */ jsx(
138
- Text,
139
- {
140
- size: "xs",
141
- fw: 600,
142
- style: {
143
- letterSpacing: "0.5px",
144
- textTransform: "uppercase",
145
- fontFamily: "var(--mantine-font-family-headings)"
146
- },
147
- children: title
148
- }
149
- ),
150
- items.map((item) => /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
151
- item.type === "line" ? /* @__PURE__ */ jsx(LegendLine, { color: item.color }) : /* @__PURE__ */ jsx(LegendDot, { color: item.color }),
152
- /* @__PURE__ */ jsx(Text, { size: "xs", children: item.label })
153
- ] }, item.label))
154
- ] }) }) });
155
- }
156
- function GraphFitViewButton({ padding = 0.2, variant = "reactflow", duration = 300 }) {
157
- const { fitView } = useReactFlow();
158
- const handleFitView = () => {
159
- fitView({ padding, duration });
160
- };
161
- if (variant === "mantine") {
162
- return /* @__PURE__ */ jsx(
163
- ActionIcon,
164
- {
165
- onClick: handleFitView,
166
- variant: "default",
167
- size: "lg",
168
- title: "Fit view",
169
- style: {
170
- position: "absolute",
171
- bottom: 12,
172
- right: 12,
173
- zIndex: 5,
174
- background: "var(--color-surface)",
175
- border: "1px solid var(--color-border)"
176
- },
177
- children: /* @__PURE__ */ jsx(IconFocus2, { size: 18 })
178
- }
179
- );
180
- }
181
- return /* @__PURE__ */ jsx(Controls, { position: "bottom-right", showZoom: false, showFitView: false, showInteractive: false, children: /* @__PURE__ */ jsx(
182
- "button",
183
- {
184
- className: "react-flow__controls-button react-flow__controls-fitview",
185
- onClick: handleFitView,
186
- title: "Fit view",
187
- children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { d: "M8 3H5C3.89 3 3 3.89 3 5V8H5V5H8V3M19 3H16V5H19V8H21V5C21 3.89 20.11 3 19 3M19 19H16V21H19C20.11 21 21 20.11 21 19V16H19V19M5 19H8V21H5C3.89 21 3 20.11 3 19V16H5V19Z" }) })
188
- }
189
- ) });
190
- }
191
- function GraphFitViewHandler({
192
- trigger,
193
- padding = 0.15,
194
- duration = 300,
195
- delay = 250
196
- }) {
197
- const { fitView } = useReactFlow();
198
- useEffect(() => {
199
- if (trigger && trigger > 0) {
200
- const timeout = setTimeout(() => {
201
- fitView({ padding, duration });
202
- }, delay);
203
- return () => clearTimeout(timeout);
204
- }
205
- return void 0;
206
- }, [trigger, fitView, padding, duration, delay]);
207
- return null;
208
- }
209
- var colorClassMap = {
210
- violet: Graph_module_css_default.nodeAgent,
211
- blue: Graph_module_css_default.nodeWorkflow,
212
- orange: Graph_module_css_default.nodeTrigger,
213
- teal: Graph_module_css_default.nodeIntegration,
214
- gray: Graph_module_css_default.nodeExternal,
215
- yellow: Graph_module_css_default.nodeHuman
216
- };
217
- var BaseNode = memo(function BaseNode2({
218
- children,
219
- color,
220
- selected = false,
221
- highlighted = false,
222
- width = 220,
223
- className = "",
224
- handleDirection = "horizontal",
225
- showSourceHandle = true,
226
- showTargetHandle = true
227
- }) {
228
- const typeClass = colorClassMap[color] || Graph_module_css_default.nodeAgent;
229
- const highlightClass = highlighted ? Graph_module_css_default.nodeHighlighted : "";
230
- const targetPosition = handleDirection === "horizontal" ? Position.Left : Position.Top;
231
- const sourcePosition = handleDirection === "horizontal" ? Position.Right : Position.Bottom;
232
- return /* @__PURE__ */ jsxs("div", { className: `${Graph_module_css_default.node} ${typeClass} ${highlightClass} ${className}`, children: [
233
- showTargetHandle && /* @__PURE__ */ jsx(Handle, { type: "target", position: targetPosition, style: { opacity: 0, pointerEvents: "none" } }),
234
- showSourceHandle && /* @__PURE__ */ jsx(Handle, { type: "source", position: sourcePosition, style: { opacity: 0, pointerEvents: "none" } }),
235
- /* @__PURE__ */ jsx(
236
- Paper,
237
- {
238
- p: "sm",
239
- className: `${Graph_module_css_default.nodeCard} ${selected ? Graph_module_css_default.nodeCardSelected : ""}`,
240
- style: {
241
- width,
242
- ...glassBase,
243
- border: `1px solid ${selected ? `var(--mantine-color-${color}-5)` : "var(--color-border)"}`,
244
- backgroundColor: "var(--color-surface)",
245
- cursor: "pointer",
246
- boxShadow: selected ? `0 0 15px var(--mantine-color-${color}-5), var(--standard-box-shadow)` : "var(--standard-box-shadow)"
247
- },
248
- children
249
- }
250
- )
251
- ] });
252
- });
253
- var BaseEdge = memo(function BaseEdge2({
254
- id,
255
- sourceX,
256
- sourceY,
257
- targetX,
258
- targetY,
259
- sourcePosition,
260
- targetPosition,
261
- color,
262
- glowColor,
263
- label,
264
- selected,
265
- animated = true,
266
- dimmed = false,
267
- edgeIndex = 0,
268
- totalEdges = 1
269
- }) {
270
- const edgeSpacing = 10;
271
- const baseOffset = 15;
272
- const offsetAmount = totalEdges > 1 ? (edgeIndex - (totalEdges - 1) / 2) * edgeSpacing : 0;
273
- const [edgePath, labelX, labelY] = getSmoothStepPath({
274
- sourceX,
275
- sourceY: sourceY + offsetAmount,
276
- sourcePosition,
277
- targetX,
278
- targetY: targetY + offsetAmount,
279
- targetPosition,
280
- borderRadius: 8,
281
- offset: baseOffset + Math.abs(offsetAmount)
282
- // Stagger the turn points horizontally
283
- });
284
- const edgeOpacity = dimmed ? 0.25 : 1;
285
- return /* @__PURE__ */ jsxs("g", { style: { opacity: edgeOpacity }, children: [
286
- /* @__PURE__ */ jsx(
287
- "path",
288
- {
289
- d: edgePath,
290
- fill: "none",
291
- stroke: color,
292
- strokeWidth: selected ? 8 : 6,
293
- strokeOpacity: 0.2,
294
- style: { filter: "blur(4px)" }
295
- }
296
- ),
297
- animated && !dimmed && /* @__PURE__ */ jsx(
298
- "path",
299
- {
300
- d: edgePath,
301
- fill: "none",
302
- stroke: color,
303
- strokeWidth: selected ? 4 : 3,
304
- strokeOpacity: 0.3,
305
- strokeDasharray: "12 6",
306
- className: Graph_module_css_default.edgeAnimated,
307
- style: { filter: `drop-shadow(0 0 3px ${glowColor})` }
308
- }
309
- ),
310
- /* @__PURE__ */ jsx(
311
- BaseEdge$1,
312
- {
313
- id,
314
- path: edgePath,
315
- style: {
316
- stroke: color,
317
- strokeWidth: selected ? 3 : 2,
318
- filter: dimmed ? "none" : selected ? `drop-shadow(0 0 6px ${glowColor})` : `drop-shadow(0 0 2px ${glowColor})`
319
- }
320
- }
321
- ),
322
- animated && !dimmed && /* @__PURE__ */ jsx(
323
- "path",
324
- {
325
- d: edgePath,
326
- fill: "none",
327
- stroke: "white",
328
- strokeWidth: 2,
329
- strokeOpacity: 0.6,
330
- strokeDasharray: "4 20",
331
- className: Graph_module_css_default.edgeAnimated,
332
- style: { filter: "drop-shadow(0 0 2px white)" }
333
- }
334
- ),
335
- label && /* @__PURE__ */ jsx(EdgeLabelRenderer, { children: /* @__PURE__ */ jsx(
336
- "div",
337
- {
338
- className: `${Graph_module_css_default.edgeLabel} ${dimmed ? Graph_module_css_default.edgeLabelDimmed : ""}`,
339
- style: {
340
- position: "absolute",
341
- transform: `translate(-50%, -50%) translate(${labelX}px, ${labelY}px)`,
342
- pointerEvents: "all",
343
- fontSize: 10,
344
- fontWeight: 600,
345
- textTransform: "uppercase",
346
- letterSpacing: "0.5px",
347
- padding: "3px 8px",
348
- borderRadius: 6,
349
- background: `linear-gradient(135deg, ${color}, ${color}dd)`,
350
- color: "var(--color-text)",
351
- boxShadow: "0 2px 8px rgba(0,0,0,0.2)",
352
- opacity: dimmed ? 0.25 : 1
353
- },
354
- children: label
355
- }
356
- ) })
357
- ] });
358
- });
359
- function ExecutionStatusBadge({
360
- status,
361
- size = "sm",
362
- variant = "light",
363
- showLoader = true
364
- }) {
365
- const statusColors = STATUS_COLORS[status];
366
- const isRunning = status === "running" && showLoader;
367
- return /* @__PURE__ */ jsx(
368
- Badge,
369
- {
370
- color: statusColors.badge,
371
- size,
372
- variant,
373
- leftSection: isRunning ? /* @__PURE__ */ jsx(Loader, { size: 10, color: statusColors.badge }) : void 0,
374
- children: status.charAt(0).toUpperCase() + status.slice(1)
375
- }
376
- );
377
- }
378
- function getRateColor(rate) {
379
- if (rate >= 95) return "var(--color-success)";
380
- if (rate >= 80) return "var(--color-warning)";
381
- return "var(--color-error)";
382
- }
383
- function getMantineRateColor(rate) {
384
- if (rate >= 95) return "green";
385
- if (rate >= 80) return "yellow";
386
- return "red";
387
- }
388
- function ExecutionStats({
389
- totalExecutions,
390
- successCount,
391
- failureCount,
392
- warningCount,
393
- successRate,
394
- align = "flex-end",
395
- compact = false
396
- }) {
397
- const cyberColors = useCyberColors();
398
- if (totalExecutions === 0 && !compact) {
399
- return null;
400
- }
401
- if (compact && totalExecutions === 0) {
402
- return /* @__PURE__ */ jsxs(Group, { gap: 10, wrap: "nowrap", style: { width: "100%" }, children: [
403
- /* @__PURE__ */ jsx(Text, { size: "md", fw: 700, ff: "monospace", c: "dimmed", style: { minWidth: 42 }, children: "\u2014" }),
404
- /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", style: { whiteSpace: "nowrap" }, children: "No recent executions" })
405
- ] });
406
- }
407
- if (compact) {
408
- return /* @__PURE__ */ jsxs(Group, { gap: 10, wrap: "nowrap", style: { width: "100%" }, children: [
409
- /* @__PURE__ */ jsxs(Group, { gap: 8, wrap: "nowrap", children: [
410
- /* @__PURE__ */ jsxs(Text, { size: "md", fw: 700, ff: "monospace", style: { color: getRateColor(successRate), minWidth: 42 }, children: [
411
- successRate,
412
- "%"
413
- ] }),
414
- /* @__PURE__ */ jsxs(Group, { gap: 5, wrap: "nowrap", children: [
415
- /* @__PURE__ */ jsx(GlowDot, { size: "sm", color: cyberColors.green }),
416
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, c: "green", children: successCount })
417
- ] }),
418
- failureCount > 0 && /* @__PURE__ */ jsxs(Group, { gap: 5, wrap: "nowrap", children: [
419
- /* @__PURE__ */ jsx(GlowDot, { size: "sm", color: cyberColors.red }),
420
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, c: "red", children: failureCount })
421
- ] })
422
- ] }),
423
- /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", style: { whiteSpace: "nowrap" }, children: [
424
- totalExecutions,
425
- " ",
426
- totalExecutions === 1 ? "run" : "runs"
427
- ] })
428
- ] });
429
- }
430
- return /* @__PURE__ */ jsxs(Stack, { gap: 2, align, style: { whiteSpace: "nowrap" }, children: [
431
- /* @__PURE__ */ jsxs(Text, { size: "xs", c: "blue", children: [
432
- totalExecutions,
433
- " ",
434
- totalExecutions === 1 ? "execution" : "executions"
435
- ] }),
436
- /* @__PURE__ */ jsxs(Text, { size: "xs", c: "green", children: [
437
- successCount,
438
- " success"
439
- ] }),
440
- warningCount != null && warningCount > 0 && /* @__PURE__ */ jsxs(Text, { size: "xs", c: "yellow", children: [
441
- warningCount,
442
- " warning"
443
- ] }),
444
- failureCount > 0 && /* @__PURE__ */ jsxs(Text, { size: "xs", c: "red", children: [
445
- failureCount,
446
- " failed"
447
- ] }),
448
- /* @__PURE__ */ jsxs(Text, { size: "xs", fw: 600, c: getMantineRateColor(successRate), children: [
449
- successRate,
450
- "% Success Rate"
451
- ] })
452
- ] });
453
- }
454
- function TimelineAxis({ totalDuration }) {
455
- const markers = [
456
- { position: 0, time: 0 },
457
- { position: 25, time: totalDuration * 0.25 },
458
- { position: 50, time: totalDuration * 0.5 },
459
- { position: 75, time: totalDuration * 0.75 },
460
- { position: 100, time: totalDuration }
461
- ];
462
- return /* @__PURE__ */ jsx(
463
- Box,
464
- {
465
- style: {
466
- position: "relative",
467
- height: 20
468
- },
469
- children: markers.map((marker, idx) => /* @__PURE__ */ jsx(
470
- Box,
471
- {
472
- style: {
473
- position: "absolute",
474
- left: `${marker.position}%`,
475
- transform: marker.position === 100 ? "translateX(-100%)" : marker.position === 0 ? "none" : "translateX(-50%)",
476
- top: 4
477
- },
478
- children: /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatDuration(marker.time) })
479
- },
480
- idx
481
- ))
482
- }
483
- );
484
- }
485
- function TimelineContainer({ executionStart, executionEnd, children }) {
486
- const totalDuration = executionEnd - executionStart;
487
- return /* @__PURE__ */ jsxs(
488
- Box,
489
- {
490
- style: {
491
- borderBottom: "1px solid var(--color-border)",
492
- backgroundColor: "var(--color-background)",
493
- padding: "var(--mantine-spacing-xs)"
494
- },
495
- children: [
496
- /* @__PURE__ */ jsx(
497
- Box,
498
- {
499
- style: {
500
- position: "relative"
501
- },
502
- children: /* @__PURE__ */ jsx(Box, { style: { position: "relative", zIndex: 1 }, children })
503
- }
504
- ),
505
- /* @__PURE__ */ jsx(Box, { style: { paddingLeft: TIMELINE_CONSTANTS.LABEL_WIDTH + 12, paddingRight: 16 }, children: /* @__PURE__ */ jsx(TimelineAxis, { totalDuration }) })
506
- ]
507
- }
508
- );
509
- }
510
- function TimelineBar({
511
- startTime,
512
- endTime,
513
- executionStart,
514
- executionEnd,
515
- status,
516
- label,
517
- onClick,
518
- isSelected = false,
519
- hasSelection = false
520
- }) {
521
- const colors = getStatusColors(status);
522
- const { left, width } = calculateBarPosition(startTime, endTime, executionStart, executionEnd);
523
- const opacity = hasSelection && !isSelected ? 0.5 : 1;
524
- return /* @__PURE__ */ jsx(
525
- Box,
526
- {
527
- style: {
528
- position: "absolute",
529
- left: `${left}%`,
530
- width: `${width}%`,
531
- top: 4,
532
- height: TIMELINE_CONSTANTS.BAR_HEIGHT / 2,
533
- backgroundColor: colors.color,
534
- opacity,
535
- borderRadius: 4,
536
- cursor: onClick ? "pointer" : "default",
537
- display: "flex",
538
- alignItems: "center",
539
- justifyContent: "center",
540
- overflow: "hidden"
541
- },
542
- onClick,
543
- children: label && /* @__PURE__ */ jsx(Text, { size: "xs", c: "white", style: { whiteSpace: "nowrap" }, children: label })
544
- }
545
- );
546
- }
547
- function TimelineRow({
548
- label,
549
- bars,
550
- executionStart,
551
- executionEnd,
552
- indent = 0,
553
- selectedNodeId
554
- }) {
555
- const labelMatch = label.match(/^(.+?)\s*\((.+?)\)$/);
556
- const labelName = labelMatch ? labelMatch[1] : label;
557
- const labelDuration = labelMatch ? labelMatch[2] : null;
558
- const statusColor = bars.length > 0 ? getStatusColors(bars[0].status).color : "var(--color-text-dimmed)";
559
- const hasSelection = selectedNodeId !== null && selectedNodeId !== void 0;
560
- return /* @__PURE__ */ jsxs(
561
- Box,
562
- {
563
- style: {
564
- display: "flex",
565
- gap: 0,
566
- height: TIMELINE_CONSTANTS.BAR_HEIGHT
567
- // paddingLeft: indent * TIMELINE_CONSTANTS.INDENT_SIZE
568
- },
569
- children: [
570
- /* @__PURE__ */ jsxs(
571
- Box,
572
- {
573
- style: {
574
- height: TIMELINE_CONSTANTS.BAR_HEIGHT,
575
- width: TIMELINE_CONSTANTS.LABEL_WIDTH,
576
- flexShrink: 0,
577
- display: "flex",
578
- alignItems: "center",
579
- gap: 6,
580
- paddingRight: 12,
581
- paddingLeft: 8 + indent * TIMELINE_CONSTANTS.INDENT_SIZE,
582
- // Indent only the label, not the timeline bars
583
- overflow: "hidden"
584
- },
585
- children: [
586
- /* @__PURE__ */ jsx(
587
- Box,
588
- {
589
- style: {
590
- width: 6,
591
- height: 6,
592
- borderRadius: "50%",
593
- backgroundColor: statusColor,
594
- flexShrink: 0
595
- }
596
- }
597
- ),
598
- /* @__PURE__ */ jsx(Text, { size: "sm", truncate: true, style: { flexShrink: 1, minWidth: 0 }, children: labelName }),
599
- labelDuration && /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", ff: "monospace", style: { flexShrink: 0 }, children: [
600
- "(",
601
- labelDuration,
602
- ")"
603
- ] })
604
- ]
605
- }
606
- ),
607
- /* @__PURE__ */ jsx(
608
- Box,
609
- {
610
- style: {
611
- position: "relative",
612
- flex: 1,
613
- height: TIMELINE_CONSTANTS.BAR_HEIGHT,
614
- marginLeft: 12,
615
- marginRight: 16
616
- // Right margin to match grid padding
617
- },
618
- children: bars.map((bar, idx) => {
619
- const isSelected = bar.nodeId !== void 0 && bar.nodeId === selectedNodeId;
620
- return /* @__PURE__ */ jsx(
621
- TimelineBar,
622
- {
623
- ...bar,
624
- executionStart,
625
- executionEnd,
626
- isSelected,
627
- hasSelection
628
- },
629
- idx
630
- );
631
- })
632
- }
633
- )
634
- ]
635
- }
636
- );
637
- }
638
- var VisualizerContainer = ({ children, handleContainerClick, height }) => {
639
- const containerHeight = height ?? CONTAINER_CONSTANTS.CONTAINER_HEIGHT;
640
- return /* @__PURE__ */ jsx(Box, { onClick: handleContainerClick, children: /* @__PURE__ */ jsx(
641
- "div",
642
- {
643
- className: `elevasis-graph-root ${Graph_module_css_default.graphContainer}`,
644
- style: {
645
- width: "100%",
646
- height: `${containerHeight}px`,
647
- overflow: "hidden"
648
- },
649
- children
650
- }
651
- ) });
652
- };
653
- var EmptyVisualizer = ({ message = "Select an execution to view timeline" }) => {
654
- return /* @__PURE__ */ jsx(
655
- Box,
656
- {
657
- h: CONTAINER_CONSTANTS.CONTAINER_HEIGHT,
658
- bg: "var(--color-background)",
659
- style: {
660
- borderBottom: "1px solid var(--color-border)",
661
- borderRadius: "var(--mantine-radius-default)",
662
- display: "flex",
663
- alignItems: "center",
664
- justifyContent: "center"
665
- },
666
- children: /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: message })
667
- }
668
- );
669
- };
670
- var UnifiedWorkflowNode = memo(function UnifiedWorkflowNode2({ data }) {
671
- const selected = data.isSelected ?? false;
672
- const primaryColor = data.isEntryPoint ? "teal" : data.isEndNode ? "violet" : data.isConditional ? "orange" : "blue";
673
- const statusColors = data.executionStatus ? STATUS_COLORS[data.executionStatus] : void 0;
674
- const showExecutionStatus = data.isExecuted && data.executionStatus;
675
- return /* @__PURE__ */ jsx(
676
- BaseNode,
677
- {
678
- color: primaryColor,
679
- selected,
680
- highlighted: Boolean(data.highlighted),
681
- width: 220,
682
- className: data.isDimmed ? "dimmed-node" : "",
683
- showSourceHandle: !data.isEndNode,
684
- children: /* @__PURE__ */ jsx("div", { style: { opacity: data.isDimmed ? 0.3 : 1 }, children: /* @__PURE__ */ jsxs(Stack, { gap: 6, children: [
685
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, lineClamp: 1, style: { fontFamily: "var(--mantine-font-family-headings)" }, children: data.name }),
686
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
687
- data.isEntryPoint && /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "teal", leftSection: /* @__PURE__ */ jsx(IconPlayerPlay, { size: 10 }), children: "Entry" }),
688
- data.isEndNode && /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "violet", leftSection: /* @__PURE__ */ jsx(IconPlayerStop, { size: 10 }), children: "End" }),
689
- data.isConditional && /* @__PURE__ */ jsxs(Badge, { size: "xs", variant: "light", color: "orange", leftSection: /* @__PURE__ */ jsx(IconArrowsSplit, { size: 10 }), children: [
690
- data.routeCount,
691
- " routes"
692
- ] }),
693
- !data.isEntryPoint && !data.isEndNode && !data.isConditional && /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", leftSection: /* @__PURE__ */ jsx(IconSquare, { size: 10 }), children: "Step" }),
694
- /* @__PURE__ */ jsx(Text, { size: "xs", ff: "monospace", c: "dimmed", truncate: true, children: data.id })
695
- ] }),
696
- !data.isDimmed && data.description && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 2, children: data.description }),
697
- showExecutionStatus && statusColors && /* @__PURE__ */ jsx(Box, { mt: 4, children: /* @__PURE__ */ jsxs(Group, { gap: 8, align: "center", children: [
698
- /* @__PURE__ */ jsx(Box, { children: getStatusIcon({
699
- status: data.executionStatus,
700
- colors: { icon: statusColors.color },
701
- iconSize: 16,
702
- spinDuration: "1s"
703
- }) }),
704
- /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: statusColors.badge, children: data.executionStatus }),
705
- data.duration !== void 0 && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatDuration(data.duration) })
706
- ] }) })
707
- ] }) })
708
- }
709
- );
710
- });
711
- var UnifiedWorkflowEdge = memo(function UnifiedWorkflowEdge2({
712
- id,
713
- sourceX,
714
- sourceY,
715
- targetX,
716
- targetY,
717
- selected,
718
- data
719
- }) {
720
- const colors = useGraphTheme();
721
- const edgeType = data?.edgeType || "linear";
722
- const isDimmed = data?.isDimmed ?? false;
723
- const isAnimated = data?.isAnimated ?? false;
724
- let edgeColor;
725
- let glowColor;
726
- let label;
727
- switch (edgeType) {
728
- case "conditional":
729
- edgeColor = colors.trigger;
730
- glowColor = colors.triggerGlow;
731
- label = data?.label || "route";
732
- break;
733
- case "default":
734
- edgeColor = colors.integration;
735
- glowColor = colors.integrationGlow;
736
- label = data?.label || "default";
737
- break;
738
- case "linear":
739
- default:
740
- edgeColor = colors.workflow;
741
- glowColor = colors.workflowGlow;
742
- label = void 0;
743
- break;
744
- }
745
- return /* @__PURE__ */ jsx(
746
- BaseEdge,
747
- {
748
- id,
749
- sourceX,
750
- sourceY,
751
- targetX,
752
- targetY,
753
- sourcePosition: Position.Right,
754
- targetPosition: Position.Left,
755
- color: edgeColor,
756
- glowColor,
757
- label,
758
- selected,
759
- animated: isAnimated,
760
- dimmed: isDimmed
761
- }
762
- );
763
- });
764
- var nodeTypes = {
765
- unifiedWorkflowNode: UnifiedWorkflowNode
766
- };
767
- var edgeTypes = {
768
- unifiedWorkflowEdge: UnifiedWorkflowEdge
769
- };
770
- var NODE_LEGEND_ITEMS = [
771
- { color: "teal", label: "Entry" },
772
- { color: "blue", label: "Step" },
773
- { color: "orange", label: "Conditional" },
774
- { color: "violet", label: "End" }
775
- ];
776
- var EDGE_LEGEND_ITEMS = [
777
- { color: "blue", label: "Next", type: "line" },
778
- { color: "orange", label: "Route", type: "line" },
779
- { color: "teal", label: "Default", type: "line" }
780
- ];
781
- function UnifiedWorkflowGraph({
782
- resourceDefinition,
783
- executionLogs,
784
- selectedStepId,
785
- onStepSelect,
786
- fitViewTrigger: externalFitViewTrigger
787
- }) {
788
- const hasExecutionData = executionLogs && executionLogs.length > 0;
789
- const [mode, setMode] = useState(hasExecutionData ? "execution" : "definition");
790
- useEffect(() => {
791
- setMode(hasExecutionData ? "execution" : "definition");
792
- }, [hasExecutionData]);
793
- const isDefinitionMode = mode === "definition";
794
- const executionPath = useExecutionPath(
795
- isDefinitionMode ? void 0 : executionLogs,
796
- isDefinitionMode ? void 0 : resourceDefinition
797
- );
798
- const workflowInput = useMemo(
799
- () => resourceDefinition ? { entryPoint: resourceDefinition.entryPoint, steps: resourceDefinition.steps } : void 0,
800
- [resourceDefinition]
801
- );
802
- const {
803
- nodes: layoutNodes,
804
- edges: layoutEdges,
805
- graphHeight
806
- } = useUnifiedWorkflowLayout(workflowInput, executionPath, isDefinitionMode ? null : selectedStepId, mode);
807
- const {
808
- nodes: highlightedNodes,
809
- edges: highlightedEdges,
810
- handleNodeMouseEnter,
811
- handleNodeMouseLeave
812
- } = useDirectedChainHighlighting(layoutNodes, layoutEdges);
813
- const nodes = isDefinitionMode ? highlightedNodes : layoutNodes;
814
- const edges = isDefinitionMode ? highlightedEdges : layoutEdges;
815
- const [internalFitViewTrigger, setInternalFitViewTrigger] = useState(0);
816
- const executedStepsCount = executionPath?.executedSteps.size ?? 0;
817
- const nodesCount = nodes.length;
818
- useEffect(() => {
819
- if (nodesCount > 0) {
820
- setInternalFitViewTrigger((prev) => prev + 1);
821
- }
822
- }, [nodesCount, executedStepsCount]);
823
- const fitViewTrigger = (externalFitViewTrigger ?? 0) + internalFitViewTrigger;
824
- const { handleNodeClick, handlePaneClick, handleContainerClick } = useNodeSelection(
825
- selectedStepId || null,
826
- onStepSelect || (() => {
827
- })
828
- );
829
- if (!resourceDefinition || !resourceDefinition.steps.length) {
830
- return /* @__PURE__ */ jsx(EmptyVisualizer, {});
831
- }
832
- return /* @__PURE__ */ jsx(
833
- VisualizerContainer,
834
- {
835
- handleContainerClick: isDefinitionMode ? void 0 : handleContainerClick,
836
- height: graphHeight,
837
- children: /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsxs(
838
- ReactFlow,
839
- {
840
- nodes,
841
- edges,
842
- nodeTypes,
843
- edgeTypes,
844
- onNodeClick: isDefinitionMode ? void 0 : handleNodeClick,
845
- onPaneClick: isDefinitionMode ? void 0 : handlePaneClick,
846
- onNodeMouseEnter: isDefinitionMode ? handleNodeMouseEnter : void 0,
847
- onNodeMouseLeave: isDefinitionMode ? handleNodeMouseLeave : void 0,
848
- fitView: true,
849
- fitViewOptions: {
850
- padding: WORKFLOW_CONSTANTS.FIT_VIEW_PADDING
851
- },
852
- proOptions: { hideAttribution: true },
853
- minZoom: WORKFLOW_CONSTANTS.MIN_ZOOM,
854
- maxZoom: WORKFLOW_CONSTANTS.MAX_ZOOM,
855
- defaultViewport: { x: 0, y: 0, zoom: 1 },
856
- nodesDraggable: false,
857
- nodesConnectable: false,
858
- elementsSelectable: !isDefinitionMode,
859
- selectNodesOnDrag: false,
860
- zoomOnScroll: true,
861
- panOnDrag: true,
862
- children: [
863
- /* @__PURE__ */ jsx(GraphBackground, {}),
864
- /* @__PURE__ */ jsx(Panel, { position: "top-right", style: { marginTop: 12, marginRight: 12 }, children: /* @__PURE__ */ jsx(
865
- SegmentedControl,
866
- {
867
- size: "xs",
868
- value: mode,
869
- onChange: (value) => setMode(value),
870
- data: [
871
- { label: "Definition", value: "definition" },
872
- { label: "Execution", value: "execution" }
873
- ],
874
- styles: {
875
- root: {
876
- backgroundColor: "var(--color-surface)",
877
- border: "1px solid var(--color-border)"
878
- }
879
- }
880
- }
881
- ) }),
882
- /* @__PURE__ */ jsx(GraphLegend, { title: "Legend", items: NODE_LEGEND_ITEMS, position: "bottom-right" }),
883
- /* @__PURE__ */ jsx(GraphLegend, { title: "Flow", items: EDGE_LEGEND_ITEMS, position: "bottom-left" }),
884
- /* @__PURE__ */ jsx(GraphFitViewButton, { padding: WORKFLOW_CONSTANTS.FIT_VIEW_PADDING, variant: "mantine" }),
885
- /* @__PURE__ */ jsx(GraphFitViewHandler, { trigger: fitViewTrigger, padding: WORKFLOW_CONSTANTS.FIT_VIEW_PADDING })
886
- ]
887
- }
888
- ) })
889
- }
890
- );
891
- }
892
- function WorkflowExecutionTimeline({ timelineData, selectedStepId }) {
893
- const { steps } = timelineData;
894
- const executionStart = steps[0]?.startTime || 0;
895
- const executionEnd = steps[steps.length - 1]?.endTime || executionStart;
896
- return /* @__PURE__ */ jsx(TimelineContainer, { executionStart, executionEnd, children: steps.map(
897
- (step) => step.startTime && step.endTime && /* @__PURE__ */ jsx(
898
- TimelineRow,
899
- {
900
- label: step.stepName,
901
- bars: [
902
- {
903
- startTime: step.startTime,
904
- endTime: step.endTime,
905
- status: step.status,
906
- nodeId: step.stepId
907
- }
908
- ],
909
- executionStart,
910
- executionEnd,
911
- selectedNodeId: selectedStepId
912
- },
913
- step.stepId
914
- )
915
- ) });
916
- }
917
- var statusColorMap = {
918
- running: "blue",
919
- completed: "teal",
920
- failed: "orange",
921
- pending: "violet",
922
- warning: "yellow"
923
- };
924
- var AgentIterationNode = memo(function AgentIterationNode2({ data, selected }) {
925
- const { nodeType, label, iterationNumber, status, reasoningCount, actionCount, duration, isLive } = data;
926
- const colors = getStatusColors(status);
927
- const nodeColor = statusColorMap[status];
928
- return /* @__PURE__ */ jsxs(BaseNode, { color: nodeColor, selected, width: AGENT_CONSTANTS.NODE_WIDTH, children: [
929
- /* @__PURE__ */ jsxs(Box, { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
930
- /* @__PURE__ */ jsx(
931
- Box,
932
- {
933
- style: {
934
- width: AGENT_CONSTANTS.CIRCLE_SIZE,
935
- height: AGENT_CONSTANTS.CIRCLE_SIZE,
936
- borderRadius: "50%",
937
- border: `2px solid ${colors.color}`,
938
- display: "flex",
939
- alignItems: "center",
940
- justifyContent: "center"
941
- },
942
- children: getStatusIcon({
943
- status,
944
- colors: { icon: colors.color },
945
- iconSize: AGENT_CONSTANTS.STATUS_ICON_SIZE,
946
- spinDuration: "1s"
947
- })
948
- }
949
- ),
950
- /* @__PURE__ */ jsx(
951
- Text,
952
- {
953
- size: "sm",
954
- fw: status === "running" ? 500 : 400,
955
- ta: "center",
956
- mt: 4,
957
- style: { maxWidth: 150, fontFamily: "var(--mantine-font-family-headings)" },
958
- children: nodeType === "iteration" ? `Iteration ${iterationNumber}` : label
959
- }
960
- ),
961
- /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: colors.badge, mt: 4, children: status.toUpperCase() }),
962
- /* @__PURE__ */ jsxs(Stack, { gap: 2, mt: 2, align: "center", children: [
963
- nodeType === "iteration" && reasoningCount !== void 0 && reasoningCount > 0 && /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
964
- reasoningCount,
965
- " reasoning"
966
- ] }),
967
- nodeType === "iteration" && actionCount !== void 0 && actionCount > 0 && /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
968
- actionCount,
969
- " ",
970
- actionCount === 1 ? "action" : "actions"
971
- ] }),
972
- duration !== void 0 && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatDuration(duration) })
973
- ] })
974
- ] }),
975
- isLive && /* @__PURE__ */ jsx(
976
- Badge,
977
- {
978
- size: "xs",
979
- variant: "filled",
980
- style: {
981
- position: "absolute",
982
- top: 4,
983
- right: 4
984
- },
985
- children: /* @__PURE__ */ jsx("span", { className: Graph_module_css_default.livePulse, children: "LIVE" })
986
- }
987
- )
988
- ] });
989
- });
990
- var statusEdgeColors = {
991
- running: {
992
- color: "var(--mantine-color-blue-5)",
993
- glow: "rgba(59, 130, 246, 0.5)"
994
- },
995
- completed: {
996
- color: "var(--mantine-color-teal-5)",
997
- glow: "rgba(20, 184, 166, 0.5)"
998
- },
999
- failed: {
1000
- color: "var(--mantine-color-orange-5)",
1001
- glow: "rgba(249, 115, 22, 0.5)"
1002
- },
1003
- pending: {
1004
- color: "var(--mantine-color-gray-5)",
1005
- glow: "rgba(156, 163, 175, 0.3)"
1006
- },
1007
- warning: {
1008
- color: "var(--mantine-color-yellow-5)",
1009
- glow: "rgba(234, 179, 8, 0.5)"
1010
- }
1011
- };
1012
- var AgentIterationEdge = memo(function AgentIterationEdge2({
1013
- id,
1014
- sourceX,
1015
- sourceY,
1016
- targetX,
1017
- targetY,
1018
- data,
1019
- selected
1020
- }) {
1021
- const edgeData = data;
1022
- const sourceStatus = edgeData?.sourceStatus || "pending";
1023
- const targetStatus = edgeData?.targetStatus || "pending";
1024
- const edgeColors = statusEdgeColors[sourceStatus];
1025
- const isAnimated = shouldAnimateEdge(sourceStatus, targetStatus);
1026
- return /* @__PURE__ */ jsx(
1027
- BaseEdge,
1028
- {
1029
- id,
1030
- sourceX,
1031
- sourceY,
1032
- targetX,
1033
- targetY,
1034
- sourcePosition: Position.Right,
1035
- targetPosition: Position.Left,
1036
- color: edgeColors.color,
1037
- glowColor: edgeColors.glow,
1038
- animated: isAnimated,
1039
- selected
1040
- }
1041
- );
1042
- });
1043
- var nodeTypes2 = {
1044
- agentIteration: AgentIterationNode
1045
- };
1046
- var edgeTypes2 = {
1047
- agentIteration: AgentIterationEdge
1048
- };
1049
- function AgentExecutionVisualizer({
1050
- resourceDefinition,
1051
- iterationData,
1052
- selectedExecutionId,
1053
- liveExecutions,
1054
- selectedIterationId,
1055
- onIterationSelect
1056
- }) {
1057
- const { nodes, edges } = useReactFlowAgent(
1058
- iterationData,
1059
- resourceDefinition,
1060
- selectedIterationId,
1061
- liveExecutions,
1062
- selectedExecutionId
1063
- );
1064
- const fitViewTrigger = useFitViewTrigger(iterationData, nodes);
1065
- const handleIterationSelect = useCallback(
1066
- (id) => {
1067
- onIterationSelect(id);
1068
- },
1069
- [onIterationSelect]
1070
- );
1071
- const { handlePaneClick, handleContainerClick } = useNodeSelection(selectedIterationId, handleIterationSelect);
1072
- const handleNodeClick = useCallback(
1073
- (_event, node) => {
1074
- if (node.id === "initialization" || node.id === "completion") {
1075
- handleIterationSelect(selectedIterationId === node.id ? null : node.id);
1076
- return;
1077
- }
1078
- const iterationNumber = Number.parseInt(node.id.replace("iteration-", ""), 10);
1079
- if (!Number.isNaN(iterationNumber)) {
1080
- handleIterationSelect(iterationNumber === selectedIterationId ? null : iterationNumber);
1081
- }
1082
- },
1083
- [selectedIterationId, handleIterationSelect]
1084
- );
1085
- if (!iterationData || nodes.length === 0) {
1086
- return /* @__PURE__ */ jsx(EmptyVisualizer, {});
1087
- }
1088
- return /* @__PURE__ */ jsx(VisualizerContainer, { handleContainerClick, children: /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsxs(
1089
- ReactFlow,
1090
- {
1091
- nodes,
1092
- edges,
1093
- nodeTypes: nodeTypes2,
1094
- edgeTypes: edgeTypes2,
1095
- onNodeClick: handleNodeClick,
1096
- onPaneClick: handlePaneClick,
1097
- fitView: true,
1098
- fitViewOptions: {
1099
- padding: AGENT_CONSTANTS.FIT_VIEW_PADDING
1100
- },
1101
- proOptions: { hideAttribution: true },
1102
- minZoom: AGENT_CONSTANTS.MIN_ZOOM,
1103
- maxZoom: AGENT_CONSTANTS.MAX_ZOOM,
1104
- nodesDraggable: false,
1105
- nodesConnectable: false,
1106
- elementsSelectable: true,
1107
- selectNodesOnDrag: false,
1108
- zoomOnScroll: false,
1109
- panOnDrag: false,
1110
- children: [
1111
- /* @__PURE__ */ jsx(GraphBackground, {}),
1112
- /* @__PURE__ */ jsx(GraphFitViewButton, { padding: AGENT_CONSTANTS.FIT_VIEW_PADDING, variant: "mantine", duration: 300 }),
1113
- /* @__PURE__ */ jsx(GraphFitViewHandler, { trigger: fitViewTrigger, padding: AGENT_CONSTANTS.FIT_VIEW_PADDING })
1114
- ]
1115
- }
1116
- ) }) });
1117
- }
1118
- function AgentExecutionTimeline({ iterationData, selectedIterationId }) {
1119
- const { initialization, iterations, completion } = iterationData;
1120
- const executionStart = initialization.startTime;
1121
- const executionEnd = completion.endTime;
1122
- return /* @__PURE__ */ jsxs(TimelineContainer, { executionStart, executionEnd, children: [
1123
- initialization.startTime && initialization.endTime && /* @__PURE__ */ jsx(
1124
- TimelineRow,
1125
- {
1126
- label: `Initialization (${formatDuration(initialization.duration || 0)})`,
1127
- bars: [
1128
- {
1129
- startTime: initialization.startTime,
1130
- endTime: initialization.endTime,
1131
- status: initialization.status,
1132
- nodeId: "initialization"
1133
- }
1134
- ],
1135
- executionStart,
1136
- executionEnd,
1137
- selectedNodeId: selectedIterationId
1138
- }
1139
- ),
1140
- iterations.map((iteration) => /* @__PURE__ */ jsxs(Fragment, { children: [
1141
- iteration.startTime && iteration.endTime && /* @__PURE__ */ jsx(
1142
- TimelineRow,
1143
- {
1144
- label: `Iteration ${iteration.iterationNumber} (${formatDuration(iteration.duration || 0)})`,
1145
- bars: [
1146
- {
1147
- startTime: iteration.startTime,
1148
- endTime: iteration.endTime,
1149
- status: iteration.status,
1150
- nodeId: iteration.iterationNumber
1151
- }
1152
- ],
1153
- executionStart,
1154
- executionEnd,
1155
- selectedNodeId: selectedIterationId
1156
- }
1157
- ),
1158
- iteration.subActivities.map((activity, activityIndex) => /* @__PURE__ */ jsx(
1159
- TimelineRow,
1160
- {
1161
- label: `${activity.type} (${formatDuration(activity.duration)})`,
1162
- bars: [
1163
- {
1164
- startTime: activity.startTime,
1165
- endTime: activity.endTime,
1166
- status: "completed",
1167
- nodeId: iteration.iterationNumber
1168
- }
1169
- ],
1170
- executionStart,
1171
- executionEnd,
1172
- indent: 1,
1173
- selectedNodeId: selectedIterationId
1174
- },
1175
- `${iteration.iterationNumber}-${activity.type}-${activity.startTime}-${activityIndex}`
1176
- ))
1177
- ] }, iteration.iterationNumber)),
1178
- completion.startTime && completion.endTime && /* @__PURE__ */ jsx(
1179
- TimelineRow,
1180
- {
1181
- label: `Completion (${formatDuration(completion.duration || 0)})`,
1182
- bars: [
1183
- {
1184
- startTime: completion.startTime,
1185
- endTime: completion.endTime,
1186
- status: completion.status,
1187
- nodeId: "completion"
1188
- }
1189
- ],
1190
- executionStart,
1191
- executionEnd,
1192
- selectedNodeId: selectedIterationId
1193
- }
1194
- )
1195
- ] });
1196
- }
1197
- var isZodSchema = (value) => value instanceof z.ZodType;
1198
- function RunResourceButton({
1199
- resourceId,
1200
- resourceType,
1201
- getInput,
1202
- label,
1203
- icon,
1204
- color,
1205
- onSuccess,
1206
- onError
1207
- }) {
1208
- const [modalState, setModalState] = useState(null);
1209
- const { execute, isPending } = useExecuteResource({ resourceId, resourceType });
1210
- const resolvedLabel = label ?? "Run";
1211
- const resolvedColor = color ?? void 0;
1212
- const handleExecute = useCallback(
1213
- async (input) => {
1214
- try {
1215
- const result = await execute(input);
1216
- setModalState(null);
1217
- notifications.show({
1218
- title: "Execution started",
1219
- message: `Execution ${result.executionId} started`,
1220
- color: "green"
1221
- });
1222
- onSuccess?.(result);
1223
- } catch (err) {
1224
- const error = err instanceof Error ? err : new Error(String(err));
1225
- notifications.show({
1226
- title: "Execution failed",
1227
- message: error.message,
1228
- color: "red"
1229
- });
1230
- onError?.(error);
1231
- }
1232
- },
1233
- [execute, onSuccess, onError]
1234
- );
1235
- const handleClick = useCallback(() => {
1236
- const result = getInput();
1237
- const maybeSchema = result.schema;
1238
- if (isZodSchema(maybeSchema)) {
1239
- const defaults = result.defaults;
1240
- setModalState({ schema: maybeSchema, defaults });
1241
- } else {
1242
- void handleExecute(result);
1243
- }
1244
- }, [getInput, handleExecute]);
1245
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [
1246
- /* @__PURE__ */ jsx(Button, { leftSection: icon, color: resolvedColor, loading: isPending, onClick: handleClick, children: resolvedLabel }),
1247
- /* @__PURE__ */ jsx(Modal, { opened: modalState !== null, onClose: () => setModalState(null), children: modalState !== null && /* @__PURE__ */ jsx(
1248
- ZodFormRenderer,
1249
- {
1250
- schema: modalState.schema,
1251
- defaults: modalState.defaults,
1252
- isPending,
1253
- submitLabel: resolvedLabel,
1254
- onSubmit: (data) => handleExecute(data)
1255
- }
1256
- ) })
1257
- ] });
1258
- }
1259
- var DEFAULT_LIMIT = 6;
1260
- var typeIcons = {
1261
- workflow: IconGitBranch,
1262
- agent: IconBrain
1263
- };
1264
- function ResourceCard({ resource, onClick }) {
1265
- const [hovered, setHovered] = useState(false);
1266
- const Icon = typeIcons[resource.type] ?? IconActivity;
1267
- const cyberColors = useCyberColors();
1268
- return /* @__PURE__ */ jsxs(
1269
- Card,
1270
- {
1271
- withBorder: true,
1272
- style: {
1273
- cursor: "pointer",
1274
- transition: "all 150ms ease",
1275
- borderColor: hovered ? "var(--border-primary-strong)" : "var(--color-border)",
1276
- boxShadow: hovered ? "var(--card-shadow), 0 0 12px color-mix(in srgb, var(--color-primary) 25%, transparent)" : "var(--card-shadow)",
1277
- transform: hovered ? "translateY(-1px)" : "none"
1278
- },
1279
- onMouseEnter: () => setHovered(true),
1280
- onMouseLeave: () => setHovered(false),
1281
- onClick,
1282
- children: [
1283
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: "sm", wrap: "nowrap", align: "flex-start", children: [
1284
- /* @__PURE__ */ jsxs(Group, { gap: "sm", wrap: "nowrap", style: { minWidth: 0 }, children: [
1285
- /* @__PURE__ */ jsx(ThemeIcon, { size: 32, radius: "md", variant: "light", children: /* @__PURE__ */ jsx(Icon, { size: 18 }) }),
1286
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, truncate: true, children: resource.name })
1287
- ] }),
1288
- resource.active && resource.execution ? (() => {
1289
- const rate = resource.execution.successRate;
1290
- const color = rate >= 95 ? cyberColors.green : rate >= 80 ? cyberColors.yellow : cyberColors.red;
1291
- return /* @__PURE__ */ jsxs(Group, { gap: 8, wrap: "nowrap", style: { flexShrink: 0 }, children: [
1292
- /* @__PURE__ */ jsxs(Text, { size: "xs", fw: 500, style: { color, letterSpacing: "0.03em" }, children: [
1293
- rate.toFixed(0),
1294
- "%"
1295
- ] }),
1296
- /* @__PURE__ */ jsx(GlowDot, { size: "md", color })
1297
- ] });
1298
- })() : null
1299
- ] }),
1300
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
1301
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1302
- /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", children: resource.type }),
1303
- /* @__PURE__ */ jsx(
1304
- Badge,
1305
- {
1306
- size: "xs",
1307
- variant: "light",
1308
- color: ResourceStatusColors[resource.status],
1309
- children: resource.status
1310
- }
1311
- )
1312
- ] }),
1313
- resource.active && resource.execution ? /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", style: { flexShrink: 0 }, children: [
1314
- /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
1315
- resource.execution.totalExecutions,
1316
- " runs"
1317
- ] }),
1318
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "\xB7" }),
1319
- /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
1320
- "Last run ",
1321
- formatTimeAgo(resource.execution.lastExecution)
1322
- ] })
1323
- ] }) : /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No recent activity" })
1324
- ] })
1325
- ]
1326
- }
1327
- );
1328
- }
1329
- function ResourceOverview({
1330
- recentExecutions,
1331
- allResources,
1332
- isLoading,
1333
- limit = DEFAULT_LIMIT,
1334
- onResourceClick
1335
- }) {
1336
- const { displayResources, totalCount } = useMemo(() => {
1337
- const items = [];
1338
- const seenIds = /* @__PURE__ */ new Set();
1339
- const resourceLookup = /* @__PURE__ */ new Map();
1340
- if (allResources) {
1341
- for (const r of [...allResources.workflows, ...allResources.agents]) {
1342
- resourceLookup.set(r.resourceId, r);
1343
- }
1344
- }
1345
- if (recentExecutions) {
1346
- for (const exec of recentExecutions) {
1347
- const def = resourceLookup.get(exec.resourceId);
1348
- items.push({
1349
- resourceId: exec.resourceId,
1350
- name: def?.name ?? exec.resourceName ?? exec.resourceId,
1351
- type: def?.type ?? exec.resourceType ?? "",
1352
- status: def?.status ?? "dev",
1353
- active: true,
1354
- execution: exec
1355
- });
1356
- seenIds.add(exec.resourceId);
1357
- }
1358
- }
1359
- if (allResources) {
1360
- for (const r of [...allResources.workflows, ...allResources.agents]) {
1361
- if (!seenIds.has(r.resourceId)) {
1362
- items.push({
1363
- resourceId: r.resourceId,
1364
- name: r.name,
1365
- type: r.type,
1366
- status: r.status,
1367
- active: false
1368
- });
1369
- seenIds.add(r.resourceId);
1370
- }
1371
- }
1372
- }
1373
- return { displayResources: items.slice(0, limit), totalCount: items.length };
1374
- }, [recentExecutions, allResources, limit]);
1375
- const handleClick = (resource) => {
1376
- onResourceClick?.(resource);
1377
- };
1378
- return /* @__PURE__ */ jsxs(Paper, { withBorder: true, children: [
1379
- /* @__PURE__ */ jsx(
1380
- CardHeader,
1381
- {
1382
- icon: /* @__PURE__ */ jsx(IconLayoutDashboard, { size: 18 }),
1383
- title: "Resources",
1384
- subtitle: totalCount > limit ? `Showing ${limit} of ${totalCount}` : void 0,
1385
- rightSection: /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1386
- totalCount > 0 && /* @__PURE__ */ jsxs(Badge, { variant: "light", size: "sm", children: [
1387
- totalCount,
1388
- " total"
1389
- ] }),
1390
- /* @__PURE__ */ jsx(ActionIcon, { variant: "subtle", size: "sm", onClick: () => onResourceClick?.(displayResources[0]), children: /* @__PURE__ */ jsx(IconArrowUpRight, { size: 16 }) })
1391
- ] })
1392
- }
1393
- ),
1394
- isLoading ? /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) }) : displayResources.length === 0 ? /* @__PURE__ */ jsx(EmptyState, { icon: IconLayoutDashboard, title: "No resources registered" }) : /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, sm: 2, lg: 3 }, children: displayResources.map((resource) => /* @__PURE__ */ jsx(ResourceCard, { resource, onClick: () => handleClick(resource) }, resource.resourceId)) })
1395
- ] });
1396
- }
1397
- var severityColor = {
1398
- critical: "red",
1399
- warning: "yellow",
1400
- info: "blue"
1401
- };
1402
- function OperationsOverview({
1403
- timeRange,
1404
- onResourceClick,
1405
- onErrorsNavigate,
1406
- onCommandQueueNavigate,
1407
- onScheduledTasksNavigate,
1408
- renderTrendChart,
1409
- renderOperationalOverview
1410
- }) {
1411
- const { organizationReady, error: initError } = useInitialization();
1412
- const { data: dashboardDataRaw, isLoading, error } = useDashboardMetrics(timeRange);
1413
- const dashboardData = dashboardDataRaw;
1414
- const { data: resourcesData, isLoading: resourcesLoading } = useResources();
1415
- const { startDate, endDate } = useTimeRangeDates(timeRange);
1416
- const { data: errorData, isLoading: errorsLoading } = useUnresolvedErrors({ startDate, endDate });
1417
- const { data: recentExecData, isLoading: recentExecLoading } = useRecentExecutionsByResource({
1418
- timeRange,
1419
- limit: 6
1420
- });
1421
- if (initError?.layer === "organization") {
1422
- return /* @__PURE__ */ jsx(AppShellCenteredContainer, { children: /* @__PURE__ */ jsxs(Stack, { align: "center", justify: "center", children: [
1423
- /* @__PURE__ */ jsx(Title, { order: 3, c: "dimmed", children: "No organization detected" }),
1424
- /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: initError?.message })
1425
- ] }) });
1426
- }
1427
- if (!organizationReady || isLoading || resourcesLoading) return /* @__PURE__ */ jsx(AppShellLoader, {});
1428
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [
1429
- /* @__PURE__ */ jsx(PageTitleCaption, { title: "Overview", caption: "AI Operations Health & Performance" }),
1430
- /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
1431
- /* @__PURE__ */ jsx(
1432
- HeroStatsRow,
1433
- {
1434
- resourcesData,
1435
- resourcesLoading,
1436
- dashboardData,
1437
- dashboardLoading: isLoading,
1438
- unresolvedErrorCount: errorData?.total ?? null,
1439
- errorsLoading
1440
- }
1441
- ),
1442
- renderTrendChart?.(dashboardData?.executionHealth, isLoading, error ?? void 0)
1443
- ] }),
1444
- /* @__PURE__ */ jsx(
1445
- ResourceOverview,
1446
- {
1447
- recentExecutions: recentExecData?.resources,
1448
- allResources: resourcesData,
1449
- isLoading: resourcesLoading || recentExecLoading,
1450
- limit: 6,
1451
- onResourceClick: onResourceClick ? (resource) => onResourceClick({
1452
- resourceId: resource.resourceId,
1453
- resourceType: resource.type
1454
- }) : void 0
1455
- }
1456
- ),
1457
- renderOperationalOverview ? renderOperationalOverview({
1458
- timeRange,
1459
- onErrorsNavigate,
1460
- onCommandQueueNavigate,
1461
- onScheduledTasksNavigate
1462
- }) : /* @__PURE__ */ jsx(
1463
- DashboardOperationsOverview,
1464
- {
1465
- timeRange,
1466
- onErrorsNavigate,
1467
- onCommandQueueNavigate,
1468
- onScheduledTasksNavigate
1469
- }
1470
- )
1471
- ] });
1472
- }
1473
- var Dashboard = OperationsOverview;
1474
- function DashboardOperationsOverview({
1475
- timeRange,
1476
- onErrorsNavigate,
1477
- onCommandQueueNavigate,
1478
- onScheduledTasksNavigate
1479
- }) {
1480
- const { startDate, endDate } = useTimeRangeDates(timeRange);
1481
- const { data: errorData, isLoading: errorsLoading } = useUnresolvedErrors({ startDate, endDate });
1482
- const errors = errorData?.errors ?? [];
1483
- const errorCount = errorData?.total ?? 0;
1484
- const { data: allCommands } = useCommandQueue({ status: "pending", limit: 100 });
1485
- const commands = allCommands?.tasks ?? [];
1486
- const commandCount = commands.length;
1487
- const { data: allTasks, isLoading: tasksLoading } = useScheduledTasks();
1488
- const tasks = allTasks ?? [];
1489
- const now = /* @__PURE__ */ new Date();
1490
- const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
1491
- const { totalScheduled, upcomingTasks } = useMemo(() => {
1492
- const totalScheduled2 = tasks.filter((t) => t.status === "active").length;
1493
- const upcomingTasks2 = tasks.filter((t) => t.status === "active" && t.nextRunAt).sort((a, b) => new Date(a.nextRunAt).getTime() - new Date(b.nextRunAt).getTime()).slice(0, 5);
1494
- return { totalScheduled: totalScheduled2, upcomingTasks: upcomingTasks2 };
1495
- }, [tasks]);
1496
- const defaultTab = useMemo(() => {
1497
- if (errorCount > 0) return "errors";
1498
- if (commandCount > 0) return "commands";
1499
- if (totalScheduled > 0) return "scheduled";
1500
- return "errors";
1501
- }, [errorCount, commandCount, totalScheduled]);
1502
- const [activeTab, setActiveTab] = useState(null);
1503
- const effectiveTab = activeTab ?? defaultTab;
1504
- const formatDaysUntil = (runAt) => {
1505
- const diffMs = runAt.getTime() - now.getTime();
1506
- const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
1507
- const diffHours = Math.floor(diffMs / (1e3 * 60 * 60));
1508
- if (diffHours < 0) return "Overdue";
1509
- if (diffHours < 1) return "Soon";
1510
- if (diffDays === 0) return "Today";
1511
- if (diffDays === 1) return "Tomorrow";
1512
- if (diffDays <= 7) return `In ${diffDays}d`;
1513
- return `In ${Math.floor(diffDays / 7)}w`;
1514
- };
1515
- return /* @__PURE__ */ jsxs(Paper, { withBorder: true, children: [
1516
- /* @__PURE__ */ jsx(CardHeader, { icon: /* @__PURE__ */ jsx(IconActivity, { size: 18 }), title: "Operational Overview" }),
1517
- /* @__PURE__ */ jsxs(Tabs, { value: effectiveTab, onChange: setActiveTab, variant: "default", children: [
1518
- /* @__PURE__ */ jsxs(Tabs.List, { children: [
1519
- /* @__PURE__ */ jsx(
1520
- Tabs.Tab,
1521
- {
1522
- value: "errors",
1523
- leftSection: /* @__PURE__ */ jsx(IconAlertTriangle, { size: 16 }),
1524
- rightSection: /* @__PURE__ */ jsx(TabCountBadge, { count: errorCount, isLoading: errorsLoading }),
1525
- children: "Unresolved Errors"
1526
- }
1527
- ),
1528
- /* @__PURE__ */ jsx(
1529
- Tabs.Tab,
1530
- {
1531
- value: "commands",
1532
- leftSection: /* @__PURE__ */ jsx(IconHandStop, { size: 16 }),
1533
- rightSection: /* @__PURE__ */ jsx(TabCountBadge, { count: commandCount }),
1534
- children: "Command Queue"
1535
- }
1536
- ),
1537
- /* @__PURE__ */ jsx(
1538
- Tabs.Tab,
1539
- {
1540
- value: "scheduled",
1541
- leftSection: /* @__PURE__ */ jsx(IconCalendarEvent, { size: 16 }),
1542
- rightSection: /* @__PURE__ */ jsx(TabCountBadge, { count: totalScheduled, isLoading: tasksLoading }),
1543
- children: "Scheduled Tasks"
1544
- }
1545
- )
1546
- ] }),
1547
- /* @__PURE__ */ jsx(Tabs.Panel, { value: "errors", pt: "sm", children: errorsLoading ? /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) }) : errors.length === 0 ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No unresolved errors" }) : /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
1548
- errors.map((error) => /* @__PURE__ */ jsx(
1549
- Box,
1550
- {
1551
- px: "sm",
1552
- py: 6,
1553
- onClick: onErrorsNavigate,
1554
- style: {
1555
- borderRadius: 4,
1556
- cursor: onErrorsNavigate ? "pointer" : "default"
1557
- },
1558
- children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
1559
- /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", style: { minWidth: 200, width: 200, flexShrink: 0 }, children: [
1560
- /* @__PURE__ */ jsx(
1561
- Box,
1562
- {
1563
- style: {
1564
- width: 8,
1565
- height: 8,
1566
- borderRadius: "50%",
1567
- backgroundColor: `var(--mantine-color-${severityColor[error.severity]}-6)`,
1568
- flexShrink: 0
1569
- }
1570
- }
1571
- ),
1572
- /* @__PURE__ */ jsxs(Stack, { gap: 0, style: { minWidth: 0 }, children: [
1573
- /* @__PURE__ */ jsx(Text, { size: "xs", lineClamp: 1, children: error.resourceName || error.resourceId }),
1574
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 1, children: error.errorType })
1575
- ] })
1576
- ] }),
1577
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 1, style: { flex: "1 1 auto", minWidth: 0 }, children: error.message }),
1578
- /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", style: { flexShrink: 0 }, children: [
1579
- /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: severityColor[error.severity], children: error.severity }),
1580
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatTimeAgo(error.timestamp) })
1581
- ] })
1582
- ] })
1583
- },
1584
- error.id
1585
- )),
1586
- errorCount > 5 && /* @__PURE__ */ jsx(
1587
- Group,
1588
- {
1589
- gap: 4,
1590
- justify: "center",
1591
- pt: 4,
1592
- onClick: onErrorsNavigate,
1593
- style: { cursor: onErrorsNavigate ? "pointer" : "default" },
1594
- children: /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "See all errors" })
1595
- }
1596
- )
1597
- ] }) }),
1598
- /* @__PURE__ */ jsx(Tabs.Panel, { value: "commands", pt: "sm", children: commands.length === 0 ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No pending decisions" }) : /* @__PURE__ */ jsx(Stack, { gap: 4, children: commands.slice(0, 5).map((task) => /* @__PURE__ */ jsx(
1599
- Box,
1600
- {
1601
- px: "sm",
1602
- py: 6,
1603
- onClick: onCommandQueueNavigate,
1604
- style: {
1605
- borderRadius: 4,
1606
- cursor: onCommandQueueNavigate ? "pointer" : "default"
1607
- },
1608
- children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
1609
- /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", style: { minWidth: 0 }, children: [
1610
- /* @__PURE__ */ jsx(
1611
- Box,
1612
- {
1613
- style: {
1614
- width: 8,
1615
- height: 8,
1616
- borderRadius: "50%",
1617
- backgroundColor: `var(--mantine-color-${task.priority >= 8 ? "red" : task.priority >= 4 ? "yellow" : "blue"}-6)`,
1618
- flexShrink: 0
1619
- }
1620
- }
1621
- ),
1622
- /* @__PURE__ */ jsx(Text, { size: "xs", lineClamp: 1, children: task.description || "No description" })
1623
- ] }),
1624
- /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", children: task.status })
1625
- ] })
1626
- },
1627
- task.id
1628
- )) }) }),
1629
- /* @__PURE__ */ jsx(Tabs.Panel, { value: "scheduled", pt: "sm", children: tasksLoading ? /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) }) : upcomingTasks.length === 0 ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No scheduled tasks" }) : /* @__PURE__ */ jsx(Stack, { gap: 4, children: upcomingTasks.map((task) => {
1630
- const runAt = new Date(task.nextRunAt);
1631
- const daysUntilNum = Math.floor((runAt.getTime() - today.getTime()) / (1e3 * 60 * 60 * 24));
1632
- return /* @__PURE__ */ jsx(
1633
- Box,
1634
- {
1635
- px: "sm",
1636
- py: 6,
1637
- onClick: onScheduledTasksNavigate,
1638
- style: {
1639
- borderRadius: 4,
1640
- cursor: onScheduledTasksNavigate ? "pointer" : "default"
1641
- },
1642
- children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
1643
- /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", style: { minWidth: 0 }, children: [
1644
- /* @__PURE__ */ jsx(
1645
- Box,
1646
- {
1647
- style: {
1648
- width: 8,
1649
- height: 8,
1650
- borderRadius: "50%",
1651
- backgroundColor: `var(--mantine-color-${daysUntilNum < 0 ? "red" : daysUntilNum <= 1 ? "yellow" : "blue"}-6)`,
1652
- flexShrink: 0
1653
- }
1654
- }
1655
- ),
1656
- /* @__PURE__ */ jsx(Text, { size: "xs", truncate: true, children: task.name || task.target.resourceId })
1657
- ] }),
1658
- /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: daysUntilNum <= 1 ? void 0 : "gray", children: formatDaysUntil(runAt) })
1659
- ] })
1660
- },
1661
- task.id
1662
- );
1663
- }) }) })
1664
- ] })
1665
- ] });
1666
- }
1667
- var entityTypeConfig = {
1668
- workflow: { icon: IconGitBranch, hasPath: true },
1669
- agent: { icon: IconBrain, hasPath: true }
1670
- };
1671
- function getEntityConfig(entityType) {
1672
- return entityTypeConfig[entityType] || { icon: IconActivity, hasPath: false };
1673
- }
1674
- function RecentExecutionsByResource({ timeRange, limit = 5, onResourceClick }) {
1675
- const { data, isLoading, isFetching, error } = useRecentExecutionsByResource({
1676
- timeRange,
1677
- limit
1678
- });
1679
- const showLoading = (isLoading || isFetching) && !data;
1680
- const { data: resourcesData } = useResources();
1681
- const resourceDefLookup = useMemo(() => {
1682
- if (!resourcesData) return /* @__PURE__ */ new Map();
1683
- const allResources = [...resourcesData.workflows || [], ...resourcesData.agents || []];
1684
- return new Map(allResources.map((r) => [r.resourceId, r]));
1685
- }, [resourcesData]);
1686
- const enrichedExecutions = useMemo(() => {
1687
- if (!data?.resources) return [];
1688
- return data.resources.map((exec) => {
1689
- const resourceDef = resourceDefLookup.get(exec.resourceId);
1690
- return {
1691
- ...exec,
1692
- resourceType: resourceDef?.type || "",
1693
- resourceName: resourceDef?.name || exec.resourceId
1694
- };
1695
- });
1696
- }, [data, resourceDefLookup]);
1697
- const resourceIds = useMemo(
1698
- () => enrichedExecutions.map((r) => ({
1699
- entityType: r.resourceType,
1700
- entityId: r.resourceId
1701
- })),
1702
- [enrichedExecutions]
1703
- );
1704
- const { startDate, endDate } = useMemo(() => getTimeRangeDates(timeRange), [timeRange]);
1705
- const granularity = timeRange === "1h" || timeRange === "24h" ? "hour" : "day";
1706
- const { data: healthData } = useResourcesHealth({
1707
- resources: resourceIds,
1708
- startDate,
1709
- endDate,
1710
- granularity
1711
- });
1712
- const healthLookup = useMemo(() => {
1713
- if (!healthData?.resources) return /* @__PURE__ */ new Map();
1714
- return new Map(healthData.resources.map((r) => [`${r.entityType}-${r.entityId}`, r]));
1715
- }, [healthData]);
1716
- const handleResourceClick = (resource) => {
1717
- const config = getEntityConfig(resource.resourceType);
1718
- if (config.hasPath) {
1719
- onResourceClick?.({ resourceType: resource.resourceType, resourceId: resource.resourceId });
1720
- }
1721
- };
1722
- if (showLoading) {
1723
- return /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) });
1724
- }
1725
- if (error) {
1726
- return /* @__PURE__ */ jsx(Center, { py: "md", children: /* @__PURE__ */ jsxs(Text, { size: "sm", c: "red.6", children: [
1727
- "Failed to load: ",
1728
- error.message
1729
- ] }) });
1730
- }
1731
- if (enrichedExecutions.length === 0) {
1732
- return /* @__PURE__ */ jsx(EmptyState, { icon: IconPlayerPlay, title: "No executions in this time range" });
1733
- }
1734
- return /* @__PURE__ */ jsx(Stack, { gap: "sm", children: enrichedExecutions.map((resource) => {
1735
- const config = getEntityConfig(resource.resourceType);
1736
- const Icon = config.icon;
1737
- const resourceKey = `${resource.resourceType}-${resource.resourceId}`;
1738
- const resourceHealth = healthLookup.get(resourceKey);
1739
- const resourceDef = resourceDefLookup.get(resource.resourceId);
1740
- return /* @__PURE__ */ jsx(
1741
- Card,
1742
- {
1743
- withBorder: true,
1744
- style: {
1745
- cursor: config.hasPath ? "pointer" : "default",
1746
- transition: "box-shadow var(--duration-fast) var(--easing)"
1747
- },
1748
- onClick: () => handleResourceClick(resource),
1749
- children: /* @__PURE__ */ jsxs(Grid, { gutter: "sm", align: "center", children: [
1750
- /* @__PURE__ */ jsx(Grid.Col, { span: 8, children: /* @__PURE__ */ jsxs(Group, { gap: "sm", wrap: "nowrap", children: [
1751
- /* @__PURE__ */ jsx(Icon, { size: 24, color: "var(--color-primary)" }),
1752
- /* @__PURE__ */ jsxs(Stack, { gap: 4, style: { flex: 1, minWidth: 0 }, children: [
1753
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, truncate: true, children: resource.resourceName }),
1754
- resourceDef?.description && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", truncate: true, children: resourceDef.description }),
1755
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1756
- resourceDef?.version && /* @__PURE__ */ jsxs(Badge, { variant: "outline", size: "xs", children: [
1757
- "v",
1758
- resourceDef.version
1759
- ] }),
1760
- resourceDef?.status && /* @__PURE__ */ jsx(Badge, { color: ResourceStatusColors[resourceDef.status], variant: "outline", size: "xs", children: resourceDef.status.toUpperCase() })
1761
- ] }),
1762
- /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
1763
- "Last run ",
1764
- formatRelativeTime(resource.lastExecution)
1765
- ] })
1766
- ] })
1767
- ] }) }),
1768
- /* @__PURE__ */ jsx(Grid.Col, { span: 4, children: /* @__PURE__ */ jsxs(Group, { justify: "flex-end", gap: "md", wrap: "nowrap", children: [
1769
- /* @__PURE__ */ jsx(
1770
- ExecutionStats,
1771
- {
1772
- totalExecutions: resource.totalExecutions,
1773
- successCount: resource.successCount,
1774
- failureCount: resource.failureCount,
1775
- warningCount: resource.warningCount,
1776
- successRate: resource.successRate
1777
- }
1778
- ),
1779
- /* @__PURE__ */ jsx(
1780
- ResourceHealthChart,
1781
- {
1782
- healthData: resourceHealth,
1783
- hasExecutions: resource.totalExecutions > 0,
1784
- width: 300,
1785
- height: 60
1786
- }
1787
- )
1788
- ] }) })
1789
- ] })
1790
- },
1791
- resource.resourceId
1792
- );
1793
- }) });
1794
- }
1795
- var severityColor2 = {
1796
- critical: "red",
1797
- warning: "yellow",
1798
- info: "blue"
1799
- };
1800
- function UnresolvedErrorsTeaser({ timeRange, onNavigateToAllErrors }) {
1801
- const { startDate, endDate } = useTimeRangeDates(timeRange);
1802
- const { data, isLoading } = useUnresolvedErrors({ startDate, endDate });
1803
- const errors = data?.errors ?? [];
1804
- const total = data?.total ?? 0;
1805
- if (isLoading) {
1806
- return /* @__PURE__ */ jsx(
1807
- Paper,
1808
- {
1809
- style: {
1810
- background: "var(--glass-background)",
1811
- backdropFilter: "var(--glass-blur)",
1812
- border: "1px solid var(--color-border)",
1813
- borderRadius: 8
1814
- },
1815
- children: /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) })
1816
- }
1817
- );
1818
- }
1819
- return /* @__PURE__ */ jsxs(
1820
- Paper,
1821
- {
1822
- style: {
1823
- background: "var(--glass-background)",
1824
- backdropFilter: "var(--glass-blur)",
1825
- border: "1px solid var(--color-border)",
1826
- borderRadius: 8
1827
- },
1828
- children: [
1829
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: errors.length > 0 ? "sm" : 0, children: [
1830
- /* @__PURE__ */ jsxs(Group, { gap: "sm", children: [
1831
- /* @__PURE__ */ jsx(ThemeIcon, { size: 28, radius: "md", variant: "light", color: total > 0 ? "red" : "green", children: total > 0 ? /* @__PURE__ */ jsx(IconAlertTriangle, { size: 16 }) : /* @__PURE__ */ jsx(IconCircleCheck, { size: 16 }) }),
1832
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, children: "Unresolved Errors" })
1833
- ] }),
1834
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1835
- total > 0 && /* @__PURE__ */ jsxs(Badge, { size: "xs", variant: "light", color: "red", children: [
1836
- total,
1837
- " unresolved"
1838
- ] }),
1839
- /* @__PURE__ */ jsx(ActionIcon, { variant: "subtle", size: "sm", onClick: onNavigateToAllErrors, children: /* @__PURE__ */ jsx(IconArrowUpRight, { size: 14 }) })
1840
- ] })
1841
- ] }),
1842
- errors.length === 0 && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No unresolved errors" }),
1843
- errors.length > 0 && /* @__PURE__ */ jsx(Stack, { gap: 4, children: errors.map((error) => /* @__PURE__ */ jsx(
1844
- Box,
1845
- {
1846
- px: "sm",
1847
- py: 6,
1848
- onClick: onNavigateToAllErrors,
1849
- style: {
1850
- borderLeft: `2px solid var(--mantine-color-${severityColor2[error.severity]}-6)`,
1851
- borderRadius: 4,
1852
- cursor: onNavigateToAllErrors ? "pointer" : "default",
1853
- textDecoration: "none",
1854
- color: "inherit"
1855
- },
1856
- children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
1857
- /* @__PURE__ */ jsxs(Stack, { gap: 0, style: { minWidth: 0 }, children: [
1858
- /* @__PURE__ */ jsx(Text, { size: "xs", lineClamp: 1, children: error.resourceName || error.resourceId }),
1859
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 1, children: error.errorType })
1860
- ] }),
1861
- /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", style: { flexShrink: 0 }, children: [
1862
- /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: severityColor2[error.severity], children: error.severity }),
1863
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatTimeAgo(error.timestamp) })
1864
- ] })
1865
- ] })
1866
- },
1867
- error.id
1868
- )) })
1869
- ]
1870
- }
1871
- );
1872
- }
1873
-
1874
- export { AgentExecutionTimeline, AgentExecutionVisualizer, AgentIterationEdge, AgentIterationNode, BaseEdge, BaseNode, Dashboard, DashboardOperationsOverview, EmptyVisualizer, ExecutionStats, ExecutionStatusBadge, GraphBackground, GraphContainer, GraphFitViewButton, GraphFitViewHandler, GraphLegend, OperationsOverview, RecentExecutionsByResource, ResourceOverview, RunResourceButton, TimelineAxis, TimelineBar, TimelineContainer, TimelineRow, UnifiedWorkflowEdge, UnifiedWorkflowGraph, UnifiedWorkflowNode, UnresolvedErrorsTeaser, VisualizerContainer, WorkflowExecutionTimeline, getGraphBackgroundStyles, useGraphBackgroundStyles, useGraphTheme };