@elevasis/ui 2.69.0 → 2.70.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 (64) hide show
  1. package/dist/app/index.js +7 -7
  2. package/dist/auth/index.css +149 -149
  3. package/dist/auth/index.js +3 -3
  4. package/dist/charts/index.css +208 -208
  5. package/dist/charts/index.js +3 -3
  6. package/dist/{chunk-ZD6LM53O.js → chunk-5C62IRKS.js} +2 -2
  7. package/dist/{chunk-WXHAHKKI.js → chunk-6TT3FQEZ.js} +16204 -16039
  8. package/dist/{chunk-MFLM7BVC.js → chunk-AGX2CY2O.js} +1 -1
  9. package/dist/{chunk-IRV6KJPV.js → chunk-CCZJ4OWY.js} +1 -1
  10. package/dist/{chunk-XAZR3T6Y.js → chunk-DUEGHF7A.js} +3 -3
  11. package/dist/{chunk-NU3NBXHP.js → chunk-GJQF3S2Q.js} +1 -1
  12. package/dist/{chunk-YNRYIXUT.js → chunk-GZADST64.js} +6 -6
  13. package/dist/{chunk-YCRINA2D.js → chunk-JA2XDMAE.js} +1 -1
  14. package/dist/{chunk-6PZFOHJK.js → chunk-LWYLZUUV.js} +2 -2
  15. package/dist/{chunk-7WJEPTE7.js → chunk-LY3IKYTZ.js} +1 -1
  16. package/dist/{chunk-RW64UJWT.js → chunk-MFCV4JMQ.js} +2 -2
  17. package/dist/{chunk-IT7GTJCB.js → chunk-QDMIFD6F.js} +1 -1
  18. package/dist/{chunk-FLECOYUS.js → chunk-R6NMRXNO.js} +1 -1
  19. package/dist/{chunk-XQ3ILKYN.js → chunk-SMH6SQQE.js} +1 -1
  20. package/dist/{chunk-MRVGQLWN.js → chunk-TJMZUL6E.js} +1 -1
  21. package/dist/{chunk-YGCMMOY4.js → chunk-XKUEO4HG.js} +695 -73
  22. package/dist/{chunk-4JHLS234.js → chunk-ZFISGKYW.js} +1 -1
  23. package/dist/components/index.css +208 -208
  24. package/dist/components/index.js +24 -25
  25. package/dist/components/navigation/index.css +149 -149
  26. package/dist/components/navigation/index.js +4 -4
  27. package/dist/features/auth/index.css +149 -149
  28. package/dist/features/auth/index.js +5 -5
  29. package/dist/features/clients/index.css +208 -208
  30. package/dist/features/clients/index.js +4 -4
  31. package/dist/features/content/index.d.ts +238 -48
  32. package/dist/features/content/index.js +542 -410
  33. package/dist/features/crm/index.js +5 -5
  34. package/dist/features/dashboard/index.js +6 -7
  35. package/dist/features/delivery/index.css +149 -149
  36. package/dist/features/delivery/index.js +4 -4
  37. package/dist/features/knowledge/index.css +149 -149
  38. package/dist/features/knowledge/index.js +3 -3
  39. package/dist/features/lead-gen/index.js +5 -5
  40. package/dist/features/monitoring/index.css +149 -149
  41. package/dist/features/monitoring/index.js +6 -6
  42. package/dist/features/monitoring/requests/index.js +4 -4
  43. package/dist/features/operations/index.js +9 -10
  44. package/dist/features/settings/index.js +6 -6
  45. package/dist/hooks/access/index.css +149 -149
  46. package/dist/hooks/access/index.js +3 -3
  47. package/dist/hooks/index.css +149 -149
  48. package/dist/hooks/index.d.ts +2 -60
  49. package/dist/hooks/index.js +3 -3
  50. package/dist/hooks/published.css +149 -149
  51. package/dist/hooks/published.d.ts +2 -60
  52. package/dist/hooks/published.js +3 -3
  53. package/dist/knowledge/index.css +149 -149
  54. package/dist/knowledge/index.js +7 -7
  55. package/dist/layout/index.css +149 -149
  56. package/dist/layout/index.js +6 -6
  57. package/dist/provider/index.js +3 -3
  58. package/dist/provider/published.css +149 -149
  59. package/dist/provider/published.js +3 -3
  60. package/dist/theme/index.js +3 -3
  61. package/dist/theme/presets/index.js +1 -1
  62. package/package.json +3 -3
  63. package/dist/chunk-ZPTEGGKU.js +0 -631
  64. /package/dist/{chunk-XQBURFKM.js → chunk-RBGVNPA6.js} +0 -0
@@ -1,631 +0,0 @@
1
- import { ResourceHealthChart } from './chunk-LGKLC5MG.js';
2
- import { AppShellCenteredContainer, AppShellLoader } from './chunk-XQ3ILKYN.js';
3
- import { ExecutionStats } from './chunk-YGCMMOY4.js';
4
- import { EmptyState, useDashboardMetrics, useResources, useTimeRangeDates, useUnresolvedErrors, useRecentExecutionsByResource, PageTitleCaption, HeroStatsRow, useCommandQueue, useScheduledTasks, TabCountBadge, useResourcesHealth, useCyberColors, GlowDot } from './chunk-WXHAHKKI.js';
5
- import { CardHeader } from './chunk-62GVNH5U.js';
6
- import { useInitialization } from './chunk-P45GQ3ZW.js';
7
- import { formatTimeAgo, formatRelativeTime } from './chunk-NM4A63KJ.js';
8
- import { getTimeRangeDates } from './chunk-Y6I3IC45.js';
9
- import { ResourceStatusColors } from './chunk-6SSQGWK7.js';
10
- import { useMemo, useState } from 'react';
11
- import { Paper, Group, Badge, ActionIcon, Center, Loader, SimpleGrid, Stack, Title, Text, Tabs, Box, Card, Grid, ThemeIcon } from '@mantine/core';
12
- import { IconArrowUpRight, IconLayoutDashboard, IconActivity, IconAlertTriangle, IconHandStop, IconCalendarEvent, IconPlayerPlay, IconCircleCheck, IconBrain, IconGitBranch } from '@tabler/icons-react';
13
- import '@mantine/charts/styles.css';
14
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
15
-
16
- var DEFAULT_LIMIT = 6;
17
- var typeIcons = {
18
- workflow: IconGitBranch,
19
- agent: IconBrain
20
- };
21
- function ResourceCard({ resource, onClick }) {
22
- const [hovered, setHovered] = useState(false);
23
- const Icon = typeIcons[resource.type] ?? IconActivity;
24
- const cyberColors = useCyberColors();
25
- return /* @__PURE__ */ jsxs(
26
- Card,
27
- {
28
- withBorder: true,
29
- style: {
30
- cursor: "pointer",
31
- transition: "all 150ms ease",
32
- borderColor: hovered ? "var(--border-primary-strong)" : "var(--color-border)",
33
- boxShadow: hovered ? "var(--card-shadow), 0 0 12px color-mix(in srgb, var(--color-primary) 25%, transparent)" : "var(--card-shadow)",
34
- transform: hovered ? "translateY(-1px)" : "none"
35
- },
36
- onMouseEnter: () => setHovered(true),
37
- onMouseLeave: () => setHovered(false),
38
- onClick,
39
- children: [
40
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: "sm", wrap: "nowrap", align: "flex-start", children: [
41
- /* @__PURE__ */ jsxs(Group, { gap: "sm", wrap: "nowrap", style: { minWidth: 0 }, children: [
42
- /* @__PURE__ */ jsx(ThemeIcon, { size: 32, radius: "md", variant: "light", children: /* @__PURE__ */ jsx(Icon, { size: 18 }) }),
43
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, truncate: true, children: resource.name })
44
- ] }),
45
- resource.active && resource.execution ? (() => {
46
- const rate = resource.execution.successRate;
47
- const color = rate >= 95 ? cyberColors.green : rate >= 80 ? cyberColors.yellow : cyberColors.red;
48
- return /* @__PURE__ */ jsxs(Group, { gap: 8, wrap: "nowrap", style: { flexShrink: 0 }, children: [
49
- /* @__PURE__ */ jsxs(Text, { size: "xs", fw: 500, style: { color, letterSpacing: "0.03em" }, children: [
50
- rate.toFixed(0),
51
- "%"
52
- ] }),
53
- /* @__PURE__ */ jsx(GlowDot, { size: "md", color })
54
- ] });
55
- })() : null
56
- ] }),
57
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
58
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
59
- /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", children: resource.type }),
60
- /* @__PURE__ */ jsx(
61
- Badge,
62
- {
63
- size: "xs",
64
- variant: "light",
65
- color: ResourceStatusColors[resource.status],
66
- children: resource.status
67
- }
68
- )
69
- ] }),
70
- resource.active && resource.execution ? /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", style: { flexShrink: 0 }, children: [
71
- /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
72
- resource.execution.totalExecutions,
73
- " runs"
74
- ] }),
75
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "\xB7" }),
76
- /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
77
- "Last run ",
78
- formatTimeAgo(resource.execution.lastExecution)
79
- ] })
80
- ] }) : /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No recent activity" })
81
- ] })
82
- ]
83
- }
84
- );
85
- }
86
- function ResourceOverview({
87
- recentExecutions,
88
- allResources,
89
- isLoading,
90
- limit = DEFAULT_LIMIT,
91
- onResourceClick
92
- }) {
93
- const { displayResources, totalCount } = useMemo(() => {
94
- const items = [];
95
- const seenIds = /* @__PURE__ */ new Set();
96
- const resourceLookup = /* @__PURE__ */ new Map();
97
- if (allResources) {
98
- for (const r of [...allResources.workflows, ...allResources.agents]) {
99
- resourceLookup.set(r.resourceId, r);
100
- }
101
- }
102
- if (recentExecutions) {
103
- for (const exec of recentExecutions) {
104
- const def = resourceLookup.get(exec.resourceId);
105
- items.push({
106
- resourceId: exec.resourceId,
107
- name: def?.name ?? exec.resourceName ?? exec.resourceId,
108
- type: def?.type ?? exec.resourceType ?? "",
109
- status: def?.status ?? "dev",
110
- active: true,
111
- execution: exec
112
- });
113
- seenIds.add(exec.resourceId);
114
- }
115
- }
116
- if (allResources) {
117
- for (const r of [...allResources.workflows, ...allResources.agents]) {
118
- if (!seenIds.has(r.resourceId)) {
119
- items.push({
120
- resourceId: r.resourceId,
121
- name: r.name,
122
- type: r.type,
123
- status: r.status,
124
- active: false
125
- });
126
- seenIds.add(r.resourceId);
127
- }
128
- }
129
- }
130
- return { displayResources: items.slice(0, limit), totalCount: items.length };
131
- }, [recentExecutions, allResources, limit]);
132
- const handleClick = (resource) => {
133
- onResourceClick?.(resource);
134
- };
135
- return /* @__PURE__ */ jsxs(Paper, { withBorder: true, children: [
136
- /* @__PURE__ */ jsx(
137
- CardHeader,
138
- {
139
- icon: /* @__PURE__ */ jsx(IconLayoutDashboard, { size: 18 }),
140
- title: "Resources",
141
- subtitle: totalCount > limit ? `Showing ${limit} of ${totalCount}` : void 0,
142
- rightSection: /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
143
- totalCount > 0 && /* @__PURE__ */ jsxs(Badge, { variant: "light", size: "sm", children: [
144
- totalCount,
145
- " total"
146
- ] }),
147
- /* @__PURE__ */ jsx(ActionIcon, { variant: "subtle", size: "sm", onClick: () => onResourceClick?.(displayResources[0]), children: /* @__PURE__ */ jsx(IconArrowUpRight, { size: 16 }) })
148
- ] })
149
- }
150
- ),
151
- 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)) })
152
- ] });
153
- }
154
- var severityColor = {
155
- critical: "red",
156
- warning: "yellow",
157
- info: "blue"
158
- };
159
- function OperationsOverview({
160
- timeRange,
161
- onResourceClick,
162
- onErrorsNavigate,
163
- onCommandQueueNavigate,
164
- onScheduledTasksNavigate,
165
- renderTrendChart,
166
- renderOperationalOverview
167
- }) {
168
- const { organizationReady, error: initError } = useInitialization();
169
- const { data: dashboardDataRaw, isLoading, error } = useDashboardMetrics(timeRange);
170
- const dashboardData = dashboardDataRaw;
171
- const { data: resourcesData, isLoading: resourcesLoading } = useResources();
172
- const { startDate, endDate } = useTimeRangeDates(timeRange);
173
- const { data: errorData, isLoading: errorsLoading } = useUnresolvedErrors({ startDate, endDate });
174
- const { data: recentExecData, isLoading: recentExecLoading } = useRecentExecutionsByResource({
175
- timeRange,
176
- limit: 6
177
- });
178
- if (initError?.layer === "organization") {
179
- return /* @__PURE__ */ jsx(AppShellCenteredContainer, { children: /* @__PURE__ */ jsxs(Stack, { align: "center", justify: "center", children: [
180
- /* @__PURE__ */ jsx(Title, { order: 3, c: "dimmed", children: "No organization detected" }),
181
- /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: initError?.message })
182
- ] }) });
183
- }
184
- if (!organizationReady || isLoading || resourcesLoading) return /* @__PURE__ */ jsx(AppShellLoader, {});
185
- return /* @__PURE__ */ jsxs(Fragment, { children: [
186
- /* @__PURE__ */ jsx(PageTitleCaption, { title: "Overview", caption: "AI Operations Health & Performance" }),
187
- /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
188
- /* @__PURE__ */ jsx(
189
- HeroStatsRow,
190
- {
191
- resourcesData,
192
- resourcesLoading,
193
- dashboardData,
194
- dashboardLoading: isLoading,
195
- unresolvedErrorCount: errorData?.total ?? null,
196
- errorsLoading
197
- }
198
- ),
199
- renderTrendChart?.(dashboardData?.executionHealth, isLoading, error ?? void 0)
200
- ] }),
201
- /* @__PURE__ */ jsx(
202
- ResourceOverview,
203
- {
204
- recentExecutions: recentExecData?.resources,
205
- allResources: resourcesData,
206
- isLoading: resourcesLoading || recentExecLoading,
207
- limit: 6,
208
- onResourceClick: onResourceClick ? (resource) => onResourceClick({
209
- resourceId: resource.resourceId,
210
- resourceType: resource.type
211
- }) : void 0
212
- }
213
- ),
214
- renderOperationalOverview ? renderOperationalOverview({
215
- timeRange,
216
- onErrorsNavigate,
217
- onCommandQueueNavigate,
218
- onScheduledTasksNavigate
219
- }) : /* @__PURE__ */ jsx(
220
- DashboardOperationsOverview,
221
- {
222
- timeRange,
223
- onErrorsNavigate,
224
- onCommandQueueNavigate,
225
- onScheduledTasksNavigate
226
- }
227
- )
228
- ] });
229
- }
230
- var Dashboard = OperationsOverview;
231
- function DashboardOperationsOverview({
232
- timeRange,
233
- onErrorsNavigate,
234
- onCommandQueueNavigate,
235
- onScheduledTasksNavigate
236
- }) {
237
- const { startDate, endDate } = useTimeRangeDates(timeRange);
238
- const { data: errorData, isLoading: errorsLoading } = useUnresolvedErrors({ startDate, endDate });
239
- const errors = errorData?.errors ?? [];
240
- const errorCount = errorData?.total ?? 0;
241
- const { data: allCommands } = useCommandQueue({ status: "pending", limit: 100 });
242
- const commands = allCommands?.tasks ?? [];
243
- const commandCount = commands.length;
244
- const { data: allTasks, isLoading: tasksLoading } = useScheduledTasks();
245
- const tasks = allTasks ?? [];
246
- const now = /* @__PURE__ */ new Date();
247
- const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
248
- const { totalScheduled, upcomingTasks } = useMemo(() => {
249
- const totalScheduled2 = tasks.filter((t) => t.status === "active").length;
250
- 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);
251
- return { totalScheduled: totalScheduled2, upcomingTasks: upcomingTasks2 };
252
- }, [tasks]);
253
- const defaultTab = useMemo(() => {
254
- if (errorCount > 0) return "errors";
255
- if (commandCount > 0) return "commands";
256
- if (totalScheduled > 0) return "scheduled";
257
- return "errors";
258
- }, [errorCount, commandCount, totalScheduled]);
259
- const [activeTab, setActiveTab] = useState(null);
260
- const effectiveTab = activeTab ?? defaultTab;
261
- const formatDaysUntil = (runAt) => {
262
- const diffMs = runAt.getTime() - now.getTime();
263
- const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
264
- const diffHours = Math.floor(diffMs / (1e3 * 60 * 60));
265
- if (diffHours < 0) return "Overdue";
266
- if (diffHours < 1) return "Soon";
267
- if (diffDays === 0) return "Today";
268
- if (diffDays === 1) return "Tomorrow";
269
- if (diffDays <= 7) return `In ${diffDays}d`;
270
- return `In ${Math.floor(diffDays / 7)}w`;
271
- };
272
- return /* @__PURE__ */ jsxs(Paper, { withBorder: true, children: [
273
- /* @__PURE__ */ jsx(CardHeader, { icon: /* @__PURE__ */ jsx(IconActivity, { size: 18 }), title: "Operational Overview" }),
274
- /* @__PURE__ */ jsxs(Tabs, { value: effectiveTab, onChange: setActiveTab, variant: "default", children: [
275
- /* @__PURE__ */ jsxs(Tabs.List, { children: [
276
- /* @__PURE__ */ jsx(
277
- Tabs.Tab,
278
- {
279
- value: "errors",
280
- leftSection: /* @__PURE__ */ jsx(IconAlertTriangle, { size: 16 }),
281
- rightSection: /* @__PURE__ */ jsx(TabCountBadge, { count: errorCount, isLoading: errorsLoading }),
282
- children: "Unresolved Errors"
283
- }
284
- ),
285
- /* @__PURE__ */ jsx(
286
- Tabs.Tab,
287
- {
288
- value: "commands",
289
- leftSection: /* @__PURE__ */ jsx(IconHandStop, { size: 16 }),
290
- rightSection: /* @__PURE__ */ jsx(TabCountBadge, { count: commandCount }),
291
- children: "Command Queue"
292
- }
293
- ),
294
- /* @__PURE__ */ jsx(
295
- Tabs.Tab,
296
- {
297
- value: "scheduled",
298
- leftSection: /* @__PURE__ */ jsx(IconCalendarEvent, { size: 16 }),
299
- rightSection: /* @__PURE__ */ jsx(TabCountBadge, { count: totalScheduled, isLoading: tasksLoading }),
300
- children: "Scheduled Tasks"
301
- }
302
- )
303
- ] }),
304
- /* @__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: [
305
- errors.map((error) => /* @__PURE__ */ jsx(
306
- Box,
307
- {
308
- px: "sm",
309
- py: 6,
310
- onClick: onErrorsNavigate,
311
- style: {
312
- borderRadius: 4,
313
- cursor: onErrorsNavigate ? "pointer" : "default"
314
- },
315
- children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
316
- /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", style: { minWidth: 200, width: 200, flexShrink: 0 }, children: [
317
- /* @__PURE__ */ jsx(
318
- Box,
319
- {
320
- style: {
321
- width: 8,
322
- height: 8,
323
- borderRadius: "50%",
324
- backgroundColor: `var(--mantine-color-${severityColor[error.severity]}-6)`,
325
- flexShrink: 0
326
- }
327
- }
328
- ),
329
- /* @__PURE__ */ jsxs(Stack, { gap: 0, style: { minWidth: 0 }, children: [
330
- /* @__PURE__ */ jsx(Text, { size: "xs", lineClamp: 1, children: error.resourceName || error.resourceId }),
331
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 1, children: error.errorType })
332
- ] })
333
- ] }),
334
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 1, style: { flex: "1 1 auto", minWidth: 0 }, children: error.message }),
335
- /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", style: { flexShrink: 0 }, children: [
336
- /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: severityColor[error.severity], children: error.severity }),
337
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatTimeAgo(error.timestamp) })
338
- ] })
339
- ] })
340
- },
341
- error.id
342
- )),
343
- errorCount > 5 && /* @__PURE__ */ jsx(
344
- Group,
345
- {
346
- gap: 4,
347
- justify: "center",
348
- pt: 4,
349
- onClick: onErrorsNavigate,
350
- style: { cursor: onErrorsNavigate ? "pointer" : "default" },
351
- children: /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "See all errors" })
352
- }
353
- )
354
- ] }) }),
355
- /* @__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(
356
- Box,
357
- {
358
- px: "sm",
359
- py: 6,
360
- onClick: onCommandQueueNavigate,
361
- style: {
362
- borderRadius: 4,
363
- cursor: onCommandQueueNavigate ? "pointer" : "default"
364
- },
365
- children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
366
- /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", style: { minWidth: 0 }, children: [
367
- /* @__PURE__ */ jsx(
368
- Box,
369
- {
370
- style: {
371
- width: 8,
372
- height: 8,
373
- borderRadius: "50%",
374
- backgroundColor: `var(--mantine-color-${task.priority >= 8 ? "red" : task.priority >= 4 ? "yellow" : "blue"}-6)`,
375
- flexShrink: 0
376
- }
377
- }
378
- ),
379
- /* @__PURE__ */ jsx(Text, { size: "xs", lineClamp: 1, children: task.description || "No description" })
380
- ] }),
381
- /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", children: task.status })
382
- ] })
383
- },
384
- task.id
385
- )) }) }),
386
- /* @__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) => {
387
- const runAt = new Date(task.nextRunAt);
388
- const daysUntilNum = Math.floor((runAt.getTime() - today.getTime()) / (1e3 * 60 * 60 * 24));
389
- return /* @__PURE__ */ jsx(
390
- Box,
391
- {
392
- px: "sm",
393
- py: 6,
394
- onClick: onScheduledTasksNavigate,
395
- style: {
396
- borderRadius: 4,
397
- cursor: onScheduledTasksNavigate ? "pointer" : "default"
398
- },
399
- children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
400
- /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", style: { minWidth: 0 }, children: [
401
- /* @__PURE__ */ jsx(
402
- Box,
403
- {
404
- style: {
405
- width: 8,
406
- height: 8,
407
- borderRadius: "50%",
408
- backgroundColor: `var(--mantine-color-${daysUntilNum < 0 ? "red" : daysUntilNum <= 1 ? "yellow" : "blue"}-6)`,
409
- flexShrink: 0
410
- }
411
- }
412
- ),
413
- /* @__PURE__ */ jsx(Text, { size: "xs", truncate: true, children: task.name || task.target.resourceId })
414
- ] }),
415
- /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: daysUntilNum <= 1 ? void 0 : "gray", children: formatDaysUntil(runAt) })
416
- ] })
417
- },
418
- task.id
419
- );
420
- }) }) })
421
- ] })
422
- ] });
423
- }
424
- var entityTypeConfig = {
425
- workflow: { icon: IconGitBranch, hasPath: true },
426
- agent: { icon: IconBrain, hasPath: true }
427
- };
428
- function getEntityConfig(entityType) {
429
- return entityTypeConfig[entityType] || { icon: IconActivity, hasPath: false };
430
- }
431
- function RecentExecutionsByResource({ timeRange, limit = 5, onResourceClick }) {
432
- const { data, isLoading, isFetching, error } = useRecentExecutionsByResource({
433
- timeRange,
434
- limit
435
- });
436
- const showLoading = (isLoading || isFetching) && !data;
437
- const { data: resourcesData } = useResources();
438
- const resourceDefLookup = useMemo(() => {
439
- if (!resourcesData) return /* @__PURE__ */ new Map();
440
- const allResources = [...resourcesData.workflows || [], ...resourcesData.agents || []];
441
- return new Map(allResources.map((r) => [r.resourceId, r]));
442
- }, [resourcesData]);
443
- const enrichedExecutions = useMemo(() => {
444
- if (!data?.resources) return [];
445
- return data.resources.map((exec) => {
446
- const resourceDef = resourceDefLookup.get(exec.resourceId);
447
- return {
448
- ...exec,
449
- resourceType: resourceDef?.type || "",
450
- resourceName: resourceDef?.name || exec.resourceId
451
- };
452
- });
453
- }, [data, resourceDefLookup]);
454
- const resourceIds = useMemo(
455
- () => enrichedExecutions.map((r) => ({
456
- entityType: r.resourceType,
457
- entityId: r.resourceId
458
- })),
459
- [enrichedExecutions]
460
- );
461
- const { startDate, endDate } = useMemo(() => getTimeRangeDates(timeRange), [timeRange]);
462
- const granularity = timeRange === "1h" || timeRange === "24h" ? "hour" : "day";
463
- const { data: healthData } = useResourcesHealth({
464
- resources: resourceIds,
465
- startDate,
466
- endDate,
467
- granularity
468
- });
469
- const healthLookup = useMemo(() => {
470
- if (!healthData?.resources) return /* @__PURE__ */ new Map();
471
- return new Map(healthData.resources.map((r) => [`${r.entityType}-${r.entityId}`, r]));
472
- }, [healthData]);
473
- const handleResourceClick = (resource) => {
474
- const config = getEntityConfig(resource.resourceType);
475
- if (config.hasPath) {
476
- onResourceClick?.({ resourceType: resource.resourceType, resourceId: resource.resourceId });
477
- }
478
- };
479
- if (showLoading) {
480
- return /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) });
481
- }
482
- if (error) {
483
- return /* @__PURE__ */ jsx(Center, { py: "md", children: /* @__PURE__ */ jsxs(Text, { size: "sm", c: "red.6", children: [
484
- "Failed to load: ",
485
- error.message
486
- ] }) });
487
- }
488
- if (enrichedExecutions.length === 0) {
489
- return /* @__PURE__ */ jsx(EmptyState, { icon: IconPlayerPlay, title: "No executions in this time range" });
490
- }
491
- return /* @__PURE__ */ jsx(Stack, { gap: "sm", children: enrichedExecutions.map((resource) => {
492
- const config = getEntityConfig(resource.resourceType);
493
- const Icon = config.icon;
494
- const resourceKey = `${resource.resourceType}-${resource.resourceId}`;
495
- const resourceHealth = healthLookup.get(resourceKey);
496
- const resourceDef = resourceDefLookup.get(resource.resourceId);
497
- return /* @__PURE__ */ jsx(
498
- Card,
499
- {
500
- withBorder: true,
501
- style: {
502
- cursor: config.hasPath ? "pointer" : "default",
503
- transition: "box-shadow var(--duration-fast) var(--easing)"
504
- },
505
- onClick: () => handleResourceClick(resource),
506
- children: /* @__PURE__ */ jsxs(Grid, { gutter: "sm", align: "center", children: [
507
- /* @__PURE__ */ jsx(Grid.Col, { span: 8, children: /* @__PURE__ */ jsxs(Group, { gap: "sm", wrap: "nowrap", children: [
508
- /* @__PURE__ */ jsx(Icon, { size: 24, color: "var(--color-primary)" }),
509
- /* @__PURE__ */ jsxs(Stack, { gap: 4, style: { flex: 1, minWidth: 0 }, children: [
510
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, truncate: true, children: resource.resourceName }),
511
- resourceDef?.description && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", truncate: true, children: resourceDef.description }),
512
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
513
- resourceDef?.version && /* @__PURE__ */ jsxs(Badge, { variant: "outline", size: "xs", children: [
514
- "v",
515
- resourceDef.version
516
- ] }),
517
- resourceDef?.status && /* @__PURE__ */ jsx(Badge, { color: ResourceStatusColors[resourceDef.status], variant: "outline", size: "xs", children: resourceDef.status.toUpperCase() })
518
- ] }),
519
- /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
520
- "Last run ",
521
- formatRelativeTime(resource.lastExecution)
522
- ] })
523
- ] })
524
- ] }) }),
525
- /* @__PURE__ */ jsx(Grid.Col, { span: 4, children: /* @__PURE__ */ jsxs(Group, { justify: "flex-end", gap: "md", wrap: "nowrap", children: [
526
- /* @__PURE__ */ jsx(
527
- ExecutionStats,
528
- {
529
- totalExecutions: resource.totalExecutions,
530
- successCount: resource.successCount,
531
- failureCount: resource.failureCount,
532
- warningCount: resource.warningCount,
533
- successRate: resource.successRate
534
- }
535
- ),
536
- /* @__PURE__ */ jsx(
537
- ResourceHealthChart,
538
- {
539
- healthData: resourceHealth,
540
- hasExecutions: resource.totalExecutions > 0,
541
- width: 300,
542
- height: 60
543
- }
544
- )
545
- ] }) })
546
- ] })
547
- },
548
- resource.resourceId
549
- );
550
- }) });
551
- }
552
- var severityColor2 = {
553
- critical: "red",
554
- warning: "yellow",
555
- info: "blue"
556
- };
557
- function UnresolvedErrorsTeaser({ timeRange, onNavigateToAllErrors }) {
558
- const { startDate, endDate } = useTimeRangeDates(timeRange);
559
- const { data, isLoading } = useUnresolvedErrors({ startDate, endDate });
560
- const errors = data?.errors ?? [];
561
- const total = data?.total ?? 0;
562
- if (isLoading) {
563
- return /* @__PURE__ */ jsx(
564
- Paper,
565
- {
566
- style: {
567
- background: "var(--glass-background)",
568
- backdropFilter: "var(--glass-blur)",
569
- border: "1px solid var(--color-border)",
570
- borderRadius: 8
571
- },
572
- children: /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) })
573
- }
574
- );
575
- }
576
- return /* @__PURE__ */ jsxs(
577
- Paper,
578
- {
579
- style: {
580
- background: "var(--glass-background)",
581
- backdropFilter: "var(--glass-blur)",
582
- border: "1px solid var(--color-border)",
583
- borderRadius: 8
584
- },
585
- children: [
586
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: errors.length > 0 ? "sm" : 0, children: [
587
- /* @__PURE__ */ jsxs(Group, { gap: "sm", children: [
588
- /* @__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 }) }),
589
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, children: "Unresolved Errors" })
590
- ] }),
591
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
592
- total > 0 && /* @__PURE__ */ jsxs(Badge, { size: "xs", variant: "light", color: "red", children: [
593
- total,
594
- " unresolved"
595
- ] }),
596
- /* @__PURE__ */ jsx(ActionIcon, { variant: "subtle", size: "sm", onClick: onNavigateToAllErrors, children: /* @__PURE__ */ jsx(IconArrowUpRight, { size: 14 }) })
597
- ] })
598
- ] }),
599
- errors.length === 0 && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No unresolved errors" }),
600
- errors.length > 0 && /* @__PURE__ */ jsx(Stack, { gap: 4, children: errors.map((error) => /* @__PURE__ */ jsx(
601
- Box,
602
- {
603
- px: "sm",
604
- py: 6,
605
- onClick: onNavigateToAllErrors,
606
- style: {
607
- borderLeft: `2px solid var(--mantine-color-${severityColor2[error.severity]}-6)`,
608
- borderRadius: 4,
609
- cursor: onNavigateToAllErrors ? "pointer" : "default",
610
- textDecoration: "none",
611
- color: "inherit"
612
- },
613
- children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
614
- /* @__PURE__ */ jsxs(Stack, { gap: 0, style: { minWidth: 0 }, children: [
615
- /* @__PURE__ */ jsx(Text, { size: "xs", lineClamp: 1, children: error.resourceName || error.resourceId }),
616
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 1, children: error.errorType })
617
- ] }),
618
- /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", style: { flexShrink: 0 }, children: [
619
- /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: severityColor2[error.severity], children: error.severity }),
620
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatTimeAgo(error.timestamp) })
621
- ] })
622
- ] })
623
- },
624
- error.id
625
- )) })
626
- ]
627
- }
628
- );
629
- }
630
-
631
- export { Dashboard, DashboardOperationsOverview, OperationsOverview, RecentExecutionsByResource, ResourceOverview, UnresolvedErrorsTeaser };
File without changes