@elevasis/ui 2.0.0 → 2.0.2

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 (54) hide show
  1. package/dist/auth/index.js +1 -2
  2. package/dist/charts/index.js +7 -9
  3. package/dist/{chunk-FW4S3Z5I.js → chunk-2DSYC52I.js} +3 -3
  4. package/dist/{chunk-ZWY3A6ZU.js → chunk-CTU2JO57.js} +31 -31
  5. package/dist/{chunk-QJ2S46NI.js → chunk-DT3QYZVU.js} +2 -2
  6. package/dist/{chunk-QTD5HPKD.js → chunk-EIHG5JZN.js} +1 -1
  7. package/dist/{chunk-JHVKGZ2P.js → chunk-KFICYU6S.js} +3 -4
  8. package/dist/{chunk-R2BQITMQ.js → chunk-MELNDAZY.js} +20 -110
  9. package/dist/{chunk-RWQIFKMJ.js → chunk-MTJ43R2E.js} +10 -2
  10. package/dist/{chunk-45MS3IAW.js → chunk-MZPVNRPL.js} +136 -28
  11. package/dist/{chunk-NNKKBSJN.js → chunk-NYBEU5TE.js} +1 -1
  12. package/dist/{chunk-2IJCM3VQ.js → chunk-OCP2MBTY.js} +134 -118
  13. package/dist/{chunk-KP6LNTMH.js → chunk-OKKGD3S6.js} +3 -3
  14. package/dist/{chunk-BYZ7VTSH.js → chunk-PRLXFMNP.js} +2 -2
  15. package/dist/{chunk-T2X3WHQS.js → chunk-QRHLV74B.js} +23 -18
  16. package/dist/{chunk-5COLSYBE.js → chunk-RX4UWZZR.js} +1 -1
  17. package/dist/{chunk-C27LLJM6.js → chunk-SMJLS23U.js} +2 -2
  18. package/dist/{chunk-F2J7675J.js → chunk-TQ3HK7ZR.js} +633 -7
  19. package/dist/{chunk-EINVPEHK.js → chunk-TZOGB3X4.js} +2 -2
  20. package/dist/{chunk-TXPUIHX2.js → chunk-X7CHQ3RE.js} +1 -1
  21. package/dist/{chunk-MCA6LOGM.js → chunk-Y3D3WFJG.js} +54 -5
  22. package/dist/{chunk-YYBM5LNJ.js → chunk-YEX4MQSY.js} +1 -1
  23. package/dist/components/index.d.ts +24 -16
  24. package/dist/components/index.js +102 -271
  25. package/dist/features/auth/index.js +3 -4
  26. package/dist/features/dashboard/index.d.ts +15 -4
  27. package/dist/features/dashboard/index.js +15 -18
  28. package/dist/features/monitoring/index.css +127 -127
  29. package/dist/features/monitoring/index.d.ts +1 -0
  30. package/dist/features/monitoring/index.js +17 -19
  31. package/dist/features/operations/index.d.ts +173 -56
  32. package/dist/features/operations/index.js +19 -20
  33. package/dist/features/settings/index.d.ts +1 -0
  34. package/dist/features/settings/index.js +15 -17
  35. package/dist/hooks/index.css +127 -127
  36. package/dist/hooks/index.js +12 -9
  37. package/dist/hooks/published.css +127 -127
  38. package/dist/hooks/published.js +11 -8
  39. package/dist/index.css +118 -118
  40. package/dist/index.d.ts +14 -2
  41. package/dist/index.js +13 -12
  42. package/dist/layout/index.d.ts +20 -44
  43. package/dist/layout/index.js +6 -6
  44. package/dist/provider/index.css +127 -59
  45. package/dist/provider/index.d.ts +14 -2
  46. package/dist/provider/index.js +10 -6
  47. package/dist/provider/published.css +126 -0
  48. package/dist/provider/published.d.ts +14 -2
  49. package/dist/provider/published.js +8 -3
  50. package/dist/theme/index.js +2 -2
  51. package/package.json +3 -3
  52. package/dist/chunk-ALA56RGZ.js +0 -13
  53. package/dist/chunk-JQ4AKYUD.js +0 -635
  54. package/dist/chunk-SZHARWKU.js +0 -15
@@ -1,14 +1,23 @@
1
- import { useCyberColors } from './chunk-JHVKGZ2P.js';
2
- import { GlowDot } from './chunk-MCA6LOGM.js';
1
+ import { ResourceHealthChart } from './chunk-LGKLC5MG.js';
2
+ import { useCyberColors, HeroStatsRow } from './chunk-KFICYU6S.js';
3
+ import { AppShellCenteredContainer, AppShellLoader } from './chunk-YEX4MQSY.js';
4
+ import { useTimeRangeDates } from './chunk-PRLXFMNP.js';
5
+ import { useDashboardMetrics, useResources, useUnresolvedErrors, useRecentExecutionsByResource, useCommandQueue, useScheduledTasks, useResourcesHealth } from './chunk-TZOGB3X4.js';
6
+ import { getTimeRangeDates } from './chunk-LXHZYSMQ.js';
3
7
  import { Graph_module_css_default, useDirectedChainHighlighting, useNodeSelection, useFitViewTrigger } from './chunk-F6RBK7NJ.js';
4
8
  import { STATUS_COLORS, getStatusIcon, formatDuration, getStatusColors, AGENT_CONSTANTS, shouldAnimateEdge, TIMELINE_CONSTANTS, calculateBarPosition, CONTAINER_CONSTANTS, useExecutionPath, useUnifiedWorkflowLayout, WORKFLOW_CONSTANTS, useReactFlowAgent } from './chunk-XA34RETF.js';
5
- import { glassBase } from './chunk-TXPUIHX2.js';
9
+ import { glassBase } from './chunk-X7CHQ3RE.js';
10
+ import { GlowDot, CardHeader, EmptyState, PageTitleCaption, TabCountBadge } from './chunk-Y3D3WFJG.js';
11
+ import { ResourceStatusColors } from './chunk-ELJIFLCB.js';
12
+ import { formatTimeAgo, formatRelativeTime } from './chunk-IOKL7BKE.js';
13
+ import { useInitialization } from './chunk-TUXTSEAF.js';
6
14
  import { memo, useMemo, useEffect, useState, useCallback, Fragment } from 'react';
7
- import { Paper, Stack, Text, Group, Badge, Box, useComputedColorScheme, Card, ActionIcon, Loader, SegmentedControl } from '@mantine/core';
8
- import { jsxs, jsx } from 'react/jsx-runtime';
15
+ import { Paper, Stack, Text, Group, Badge, Box, useComputedColorScheme, Card, ActionIcon, Loader, SegmentedControl, Center, SimpleGrid, Title, Tabs, Grid, ThemeIcon } from '@mantine/core';
16
+ import { jsxs, jsx, Fragment as Fragment$1 } from 'react/jsx-runtime';
9
17
  import { Position, Handle, getSmoothStepPath, BaseEdge as BaseEdge$1, EdgeLabelRenderer, Panel, useReactFlow, Controls, ReactFlowProvider, ReactFlow } from '@xyflow/react';
10
- import { IconPlayerPlay, IconPlayerStop, IconArrowsSplit, IconSquare, IconFocus2 } from '@tabler/icons-react';
18
+ import { IconPlayerPlay, IconPlayerStop, IconArrowsSplit, IconSquare, IconDashboard, IconFocus2, IconArrowUpRight, IconLayoutDashboard, IconActivity, IconAlertTriangle, IconHandStop, IconCalendarEvent, IconCircleCheck, IconBrain, IconGitBranch } from '@tabler/icons-react';
11
19
  import '@xyflow/react/dist/style.css';
20
+ import '@mantine/charts/styles.css';
12
21
 
13
22
  var DOMAIN_COLORS = {
14
23
  primary: "var(--color-primary)",
@@ -1194,5 +1203,622 @@ function AgentExecutionTimeline({ iterationData, selectedIterationId }) {
1194
1203
  )
1195
1204
  ] });
1196
1205
  }
1206
+ var DEFAULT_LIMIT = 6;
1207
+ var typeIcons = {
1208
+ workflow: IconGitBranch,
1209
+ agent: IconBrain
1210
+ };
1211
+ function ResourceCard({ resource, onClick }) {
1212
+ const [hovered, setHovered] = useState(false);
1213
+ const Icon = typeIcons[resource.type] ?? IconActivity;
1214
+ const cyberColors = useCyberColors();
1215
+ return /* @__PURE__ */ jsxs(
1216
+ Card,
1217
+ {
1218
+ withBorder: true,
1219
+ style: {
1220
+ cursor: "pointer",
1221
+ transition: "all 150ms ease",
1222
+ borderColor: hovered ? "color-mix(in srgb, var(--color-primary) 40%, var(--color-border))" : "var(--color-border)",
1223
+ boxShadow: hovered ? "var(--card-shadow), 0 0 12px color-mix(in srgb, var(--color-primary) 25%, transparent)" : "var(--card-shadow)",
1224
+ transform: hovered ? "translateY(-1px)" : "none"
1225
+ },
1226
+ onMouseEnter: () => setHovered(true),
1227
+ onMouseLeave: () => setHovered(false),
1228
+ onClick,
1229
+ children: [
1230
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: "sm", wrap: "nowrap", align: "flex-start", children: [
1231
+ /* @__PURE__ */ jsxs(Group, { gap: "sm", wrap: "nowrap", style: { minWidth: 0 }, children: [
1232
+ /* @__PURE__ */ jsx(ThemeIcon, { size: 32, radius: "md", variant: "light", children: /* @__PURE__ */ jsx(Icon, { size: 18 }) }),
1233
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, truncate: true, children: resource.name })
1234
+ ] }),
1235
+ resource.active && resource.execution ? (() => {
1236
+ const rate = resource.execution.successRate;
1237
+ const color = rate >= 95 ? cyberColors.green : rate >= 80 ? cyberColors.yellow : cyberColors.red;
1238
+ return /* @__PURE__ */ jsxs(Group, { gap: 8, wrap: "nowrap", style: { flexShrink: 0 }, children: [
1239
+ /* @__PURE__ */ jsxs(Text, { size: "xs", fw: 500, style: { color, letterSpacing: "0.03em" }, children: [
1240
+ rate.toFixed(0),
1241
+ "%"
1242
+ ] }),
1243
+ /* @__PURE__ */ jsx(GlowDot, { size: "md", color })
1244
+ ] });
1245
+ })() : null
1246
+ ] }),
1247
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
1248
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1249
+ /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", children: resource.type }),
1250
+ /* @__PURE__ */ jsx(
1251
+ Badge,
1252
+ {
1253
+ size: "xs",
1254
+ variant: "light",
1255
+ color: ResourceStatusColors[resource.status],
1256
+ children: resource.status
1257
+ }
1258
+ )
1259
+ ] }),
1260
+ resource.active && resource.execution ? /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", style: { flexShrink: 0 }, children: [
1261
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
1262
+ resource.execution.totalExecutions,
1263
+ " runs"
1264
+ ] }),
1265
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "\xB7" }),
1266
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
1267
+ "Last run ",
1268
+ formatTimeAgo(resource.execution.lastExecution)
1269
+ ] })
1270
+ ] }) : /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No recent activity" })
1271
+ ] })
1272
+ ]
1273
+ }
1274
+ );
1275
+ }
1276
+ function ResourceOverview({
1277
+ recentExecutions,
1278
+ allResources,
1279
+ isLoading,
1280
+ limit = DEFAULT_LIMIT,
1281
+ onResourceClick
1282
+ }) {
1283
+ const { displayResources, totalCount } = useMemo(() => {
1284
+ const items = [];
1285
+ const seenIds = /* @__PURE__ */ new Set();
1286
+ const resourceLookup = /* @__PURE__ */ new Map();
1287
+ if (allResources) {
1288
+ for (const r of [...allResources.workflows, ...allResources.agents]) {
1289
+ resourceLookup.set(r.resourceId, r);
1290
+ }
1291
+ }
1292
+ if (recentExecutions) {
1293
+ for (const exec of recentExecutions) {
1294
+ const def = resourceLookup.get(exec.resourceId);
1295
+ items.push({
1296
+ resourceId: exec.resourceId,
1297
+ name: def?.name ?? exec.resourceName ?? exec.resourceId,
1298
+ type: def?.type ?? exec.resourceType ?? "",
1299
+ status: def?.status ?? "dev",
1300
+ active: true,
1301
+ execution: exec
1302
+ });
1303
+ seenIds.add(exec.resourceId);
1304
+ }
1305
+ }
1306
+ if (allResources) {
1307
+ for (const r of [...allResources.workflows, ...allResources.agents]) {
1308
+ if (!seenIds.has(r.resourceId)) {
1309
+ items.push({
1310
+ resourceId: r.resourceId,
1311
+ name: r.name,
1312
+ type: r.type,
1313
+ status: r.status,
1314
+ active: false
1315
+ });
1316
+ seenIds.add(r.resourceId);
1317
+ }
1318
+ }
1319
+ }
1320
+ return { displayResources: items.slice(0, limit), totalCount: items.length };
1321
+ }, [recentExecutions, allResources, limit]);
1322
+ const handleClick = (resource) => {
1323
+ onResourceClick?.(resource);
1324
+ };
1325
+ return /* @__PURE__ */ jsxs(Paper, { withBorder: true, children: [
1326
+ /* @__PURE__ */ jsx(
1327
+ CardHeader,
1328
+ {
1329
+ icon: /* @__PURE__ */ jsx(IconLayoutDashboard, { size: 18 }),
1330
+ title: "Resources",
1331
+ subtitle: totalCount > limit ? `Showing ${limit} of ${totalCount}` : void 0,
1332
+ rightSection: /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1333
+ totalCount > 0 && /* @__PURE__ */ jsxs(Badge, { variant: "light", size: "sm", children: [
1334
+ totalCount,
1335
+ " total"
1336
+ ] }),
1337
+ /* @__PURE__ */ jsx(ActionIcon, { variant: "subtle", size: "sm", onClick: () => onResourceClick?.(displayResources[0]), children: /* @__PURE__ */ jsx(IconArrowUpRight, { size: 16 }) })
1338
+ ] })
1339
+ }
1340
+ ),
1341
+ 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)) })
1342
+ ] });
1343
+ }
1344
+ var severityColor = {
1345
+ critical: "red",
1346
+ warning: "yellow",
1347
+ info: "blue"
1348
+ };
1349
+ function OperationsOverview({
1350
+ timeRange,
1351
+ onResourceClick,
1352
+ onErrorsNavigate,
1353
+ onCommandQueueNavigate,
1354
+ onScheduledTasksNavigate,
1355
+ renderTrendChart
1356
+ }) {
1357
+ const { organizationReady, error: initError } = useInitialization();
1358
+ const { data: dashboardDataRaw, isLoading, error } = useDashboardMetrics(timeRange);
1359
+ const dashboardData = dashboardDataRaw;
1360
+ const { data: resourcesData, isLoading: resourcesLoading } = useResources();
1361
+ const { startDate, endDate } = useTimeRangeDates(timeRange);
1362
+ const { data: errorData, isLoading: errorsLoading } = useUnresolvedErrors({ startDate, endDate });
1363
+ const { data: recentExecData, isLoading: recentExecLoading } = useRecentExecutionsByResource({
1364
+ timeRange,
1365
+ limit: 6
1366
+ });
1367
+ if (initError?.layer === "organization") {
1368
+ return /* @__PURE__ */ jsx(AppShellCenteredContainer, { children: /* @__PURE__ */ jsxs(Stack, { align: "center", justify: "center", children: [
1369
+ /* @__PURE__ */ jsx(Title, { order: 3, c: "dimmed", children: "No organization detected" }),
1370
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: initError?.message })
1371
+ ] }) });
1372
+ }
1373
+ if (!organizationReady || isLoading || resourcesLoading) return /* @__PURE__ */ jsx(AppShellLoader, {});
1374
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
1375
+ /* @__PURE__ */ jsx(PageTitleCaption, { title: "Overview", caption: "AI Operations Health & Performance" }),
1376
+ /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
1377
+ /* @__PURE__ */ jsx(
1378
+ HeroStatsRow,
1379
+ {
1380
+ resourcesData,
1381
+ resourcesLoading,
1382
+ dashboardData,
1383
+ dashboardLoading: isLoading,
1384
+ unresolvedErrorCount: errorData?.total ?? null,
1385
+ errorsLoading
1386
+ }
1387
+ ),
1388
+ renderTrendChart?.(dashboardData?.executionHealth, isLoading, error ?? void 0)
1389
+ ] }),
1390
+ /* @__PURE__ */ jsx(
1391
+ ResourceOverview,
1392
+ {
1393
+ recentExecutions: recentExecData?.resources,
1394
+ allResources: resourcesData,
1395
+ isLoading: resourcesLoading || recentExecLoading,
1396
+ limit: 6,
1397
+ onResourceClick: onResourceClick ? (resource) => onResourceClick({
1398
+ resourceId: resource.resourceId,
1399
+ resourceType: resource.type
1400
+ }) : void 0
1401
+ }
1402
+ ),
1403
+ /* @__PURE__ */ jsx(
1404
+ OperationalOverview,
1405
+ {
1406
+ timeRange,
1407
+ onErrorsNavigate,
1408
+ onCommandQueueNavigate,
1409
+ onScheduledTasksNavigate
1410
+ }
1411
+ )
1412
+ ] });
1413
+ }
1414
+ var Dashboard = OperationsOverview;
1415
+ function OperationalOverview({
1416
+ timeRange,
1417
+ onErrorsNavigate,
1418
+ onCommandQueueNavigate,
1419
+ onScheduledTasksNavigate
1420
+ }) {
1421
+ const { startDate, endDate } = useTimeRangeDates(timeRange);
1422
+ const { data: errorData, isLoading: errorsLoading } = useUnresolvedErrors({ startDate, endDate });
1423
+ const errors = errorData?.errors ?? [];
1424
+ const errorCount = errorData?.total ?? 0;
1425
+ const { data: allCommands } = useCommandQueue({ status: "pending", limit: 100 });
1426
+ const commands = allCommands ?? [];
1427
+ const commandCount = commands.length;
1428
+ const { data: allTasks, isLoading: tasksLoading } = useScheduledTasks();
1429
+ const tasks = allTasks ?? [];
1430
+ const now = /* @__PURE__ */ new Date();
1431
+ const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
1432
+ const { totalScheduled, upcomingTasks } = useMemo(() => {
1433
+ const totalScheduled2 = tasks.filter((t) => t.status === "active").length;
1434
+ 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);
1435
+ return { totalScheduled: totalScheduled2, upcomingTasks: upcomingTasks2 };
1436
+ }, [tasks]);
1437
+ const defaultTab = useMemo(() => {
1438
+ if (errorCount > 0) return "errors";
1439
+ if (commandCount > 0) return "commands";
1440
+ if (totalScheduled > 0) return "scheduled";
1441
+ return "errors";
1442
+ }, [errorCount, commandCount, totalScheduled]);
1443
+ const [activeTab, setActiveTab] = useState(null);
1444
+ const effectiveTab = activeTab ?? defaultTab;
1445
+ const formatDaysUntil = (runAt) => {
1446
+ const diffMs = runAt.getTime() - now.getTime();
1447
+ const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
1448
+ const diffHours = Math.floor(diffMs / (1e3 * 60 * 60));
1449
+ if (diffHours < 0) return "Overdue";
1450
+ if (diffHours < 1) return "Soon";
1451
+ if (diffDays === 0) return "Today";
1452
+ if (diffDays === 1) return "Tomorrow";
1453
+ if (diffDays <= 7) return `In ${diffDays}d`;
1454
+ return `In ${Math.floor(diffDays / 7)}w`;
1455
+ };
1456
+ return /* @__PURE__ */ jsxs(Paper, { withBorder: true, children: [
1457
+ /* @__PURE__ */ jsx(CardHeader, { icon: /* @__PURE__ */ jsx(IconActivity, { size: 18 }), title: "Operational Overview" }),
1458
+ /* @__PURE__ */ jsxs(Tabs, { value: effectiveTab, onChange: setActiveTab, variant: "default", children: [
1459
+ /* @__PURE__ */ jsxs(Tabs.List, { children: [
1460
+ /* @__PURE__ */ jsx(
1461
+ Tabs.Tab,
1462
+ {
1463
+ value: "errors",
1464
+ leftSection: /* @__PURE__ */ jsx(IconAlertTriangle, { size: 16 }),
1465
+ rightSection: /* @__PURE__ */ jsx(TabCountBadge, { count: errorCount, isLoading: errorsLoading }),
1466
+ children: "Unresolved Errors"
1467
+ }
1468
+ ),
1469
+ /* @__PURE__ */ jsx(
1470
+ Tabs.Tab,
1471
+ {
1472
+ value: "commands",
1473
+ leftSection: /* @__PURE__ */ jsx(IconHandStop, { size: 16 }),
1474
+ rightSection: /* @__PURE__ */ jsx(TabCountBadge, { count: commandCount }),
1475
+ children: "Command Queue"
1476
+ }
1477
+ ),
1478
+ /* @__PURE__ */ jsx(
1479
+ Tabs.Tab,
1480
+ {
1481
+ value: "scheduled",
1482
+ leftSection: /* @__PURE__ */ jsx(IconCalendarEvent, { size: 16 }),
1483
+ rightSection: /* @__PURE__ */ jsx(TabCountBadge, { count: totalScheduled, isLoading: tasksLoading }),
1484
+ children: "Scheduled Tasks"
1485
+ }
1486
+ )
1487
+ ] }),
1488
+ /* @__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: [
1489
+ errors.map((error) => /* @__PURE__ */ jsx(
1490
+ Box,
1491
+ {
1492
+ px: "sm",
1493
+ py: 6,
1494
+ onClick: onErrorsNavigate,
1495
+ style: {
1496
+ borderRadius: 4,
1497
+ cursor: onErrorsNavigate ? "pointer" : "default"
1498
+ },
1499
+ children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
1500
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", style: { minWidth: 200, width: 200, flexShrink: 0 }, children: [
1501
+ /* @__PURE__ */ jsx(
1502
+ Box,
1503
+ {
1504
+ style: {
1505
+ width: 8,
1506
+ height: 8,
1507
+ borderRadius: "50%",
1508
+ backgroundColor: `var(--mantine-color-${severityColor[error.severity]}-6)`,
1509
+ flexShrink: 0
1510
+ }
1511
+ }
1512
+ ),
1513
+ /* @__PURE__ */ jsxs(Stack, { gap: 0, style: { minWidth: 0 }, children: [
1514
+ /* @__PURE__ */ jsx(Text, { size: "xs", lineClamp: 1, children: error.resourceName || error.resourceId }),
1515
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 1, children: error.errorType })
1516
+ ] })
1517
+ ] }),
1518
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 1, style: { flex: "1 1 auto", minWidth: 0 }, children: error.message }),
1519
+ /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", style: { flexShrink: 0 }, children: [
1520
+ /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: severityColor[error.severity], children: error.severity }),
1521
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatTimeAgo(error.timestamp) })
1522
+ ] })
1523
+ ] })
1524
+ },
1525
+ error.id
1526
+ )),
1527
+ errorCount > 5 && /* @__PURE__ */ jsx(
1528
+ Group,
1529
+ {
1530
+ gap: 4,
1531
+ justify: "center",
1532
+ pt: 4,
1533
+ onClick: onErrorsNavigate,
1534
+ style: { cursor: onErrorsNavigate ? "pointer" : "default" },
1535
+ children: /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "See all errors" })
1536
+ }
1537
+ )
1538
+ ] }) }),
1539
+ /* @__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(
1540
+ Box,
1541
+ {
1542
+ px: "sm",
1543
+ py: 6,
1544
+ onClick: onCommandQueueNavigate,
1545
+ style: {
1546
+ borderRadius: 4,
1547
+ cursor: onCommandQueueNavigate ? "pointer" : "default"
1548
+ },
1549
+ children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
1550
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", style: { minWidth: 0 }, children: [
1551
+ /* @__PURE__ */ jsx(
1552
+ Box,
1553
+ {
1554
+ style: {
1555
+ width: 8,
1556
+ height: 8,
1557
+ borderRadius: "50%",
1558
+ backgroundColor: `var(--mantine-color-${task.priority >= 8 ? "red" : task.priority >= 4 ? "yellow" : "blue"}-6)`,
1559
+ flexShrink: 0
1560
+ }
1561
+ }
1562
+ ),
1563
+ /* @__PURE__ */ jsx(Text, { size: "xs", lineClamp: 1, children: task.description || "No description" })
1564
+ ] }),
1565
+ /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", children: task.status })
1566
+ ] })
1567
+ },
1568
+ task.id
1569
+ )) }) }),
1570
+ /* @__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) => {
1571
+ const runAt = new Date(task.nextRunAt);
1572
+ const daysUntilNum = Math.floor((runAt.getTime() - today.getTime()) / (1e3 * 60 * 60 * 24));
1573
+ return /* @__PURE__ */ jsx(
1574
+ Box,
1575
+ {
1576
+ px: "sm",
1577
+ py: 6,
1578
+ onClick: onScheduledTasksNavigate,
1579
+ style: {
1580
+ borderRadius: 4,
1581
+ cursor: onScheduledTasksNavigate ? "pointer" : "default"
1582
+ },
1583
+ children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
1584
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", style: { minWidth: 0 }, children: [
1585
+ /* @__PURE__ */ jsx(
1586
+ Box,
1587
+ {
1588
+ style: {
1589
+ width: 8,
1590
+ height: 8,
1591
+ borderRadius: "50%",
1592
+ backgroundColor: `var(--mantine-color-${daysUntilNum < 0 ? "red" : daysUntilNum <= 1 ? "yellow" : "blue"}-6)`,
1593
+ flexShrink: 0
1594
+ }
1595
+ }
1596
+ ),
1597
+ /* @__PURE__ */ jsx(Text, { size: "xs", truncate: true, children: task.name || task.target.resourceId })
1598
+ ] }),
1599
+ /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: daysUntilNum <= 1 ? void 0 : "gray", children: formatDaysUntil(runAt) })
1600
+ ] })
1601
+ },
1602
+ task.id
1603
+ );
1604
+ }) }) })
1605
+ ] })
1606
+ ] });
1607
+ }
1608
+ var entityTypeConfig = {
1609
+ workflow: { icon: IconGitBranch, hasPath: true },
1610
+ agent: { icon: IconBrain, hasPath: true }
1611
+ };
1612
+ function getEntityConfig(entityType) {
1613
+ return entityTypeConfig[entityType] || { icon: IconActivity, hasPath: false };
1614
+ }
1615
+ function RecentExecutionsByResource({ timeRange, limit = 5, onResourceClick }) {
1616
+ const { data, isLoading, isFetching, error } = useRecentExecutionsByResource({
1617
+ timeRange,
1618
+ limit
1619
+ });
1620
+ const showLoading = (isLoading || isFetching) && !data;
1621
+ const { data: resourcesData } = useResources();
1622
+ const resourceDefLookup = useMemo(() => {
1623
+ if (!resourcesData) return /* @__PURE__ */ new Map();
1624
+ const allResources = [...resourcesData.workflows || [], ...resourcesData.agents || []];
1625
+ return new Map(allResources.map((r) => [r.resourceId, r]));
1626
+ }, [resourcesData]);
1627
+ const enrichedExecutions = useMemo(() => {
1628
+ if (!data?.resources) return [];
1629
+ return data.resources.map((exec) => {
1630
+ const resourceDef = resourceDefLookup.get(exec.resourceId);
1631
+ return {
1632
+ ...exec,
1633
+ resourceType: resourceDef?.type || "",
1634
+ resourceName: resourceDef?.name || exec.resourceId
1635
+ };
1636
+ });
1637
+ }, [data, resourceDefLookup]);
1638
+ const resourceIds = useMemo(
1639
+ () => enrichedExecutions.map((r) => ({
1640
+ entityType: r.resourceType,
1641
+ entityId: r.resourceId
1642
+ })),
1643
+ [enrichedExecutions]
1644
+ );
1645
+ const { startDate, endDate } = useMemo(() => getTimeRangeDates(timeRange), [timeRange]);
1646
+ const granularity = timeRange === "1h" || timeRange === "24h" ? "hour" : "day";
1647
+ const { data: healthData } = useResourcesHealth({
1648
+ resources: resourceIds,
1649
+ startDate,
1650
+ endDate,
1651
+ granularity
1652
+ });
1653
+ const healthLookup = useMemo(() => {
1654
+ if (!healthData?.resources) return /* @__PURE__ */ new Map();
1655
+ return new Map(healthData.resources.map((r) => [`${r.entityType}-${r.entityId}`, r]));
1656
+ }, [healthData]);
1657
+ const handleResourceClick = (resource) => {
1658
+ const config = getEntityConfig(resource.resourceType);
1659
+ if (config.hasPath) {
1660
+ onResourceClick?.({ resourceType: resource.resourceType, resourceId: resource.resourceId });
1661
+ }
1662
+ };
1663
+ if (showLoading) {
1664
+ return /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) });
1665
+ }
1666
+ if (error) {
1667
+ return /* @__PURE__ */ jsx(Center, { py: "md", children: /* @__PURE__ */ jsxs(Text, { size: "sm", c: "red.6", children: [
1668
+ "Failed to load: ",
1669
+ error.message
1670
+ ] }) });
1671
+ }
1672
+ if (enrichedExecutions.length === 0) {
1673
+ return /* @__PURE__ */ jsx(EmptyState, { icon: IconPlayerPlay, title: "No executions in this time range" });
1674
+ }
1675
+ return /* @__PURE__ */ jsx(Stack, { gap: "sm", children: enrichedExecutions.map((resource) => {
1676
+ const config = getEntityConfig(resource.resourceType);
1677
+ const Icon = config.icon;
1678
+ const resourceKey = `${resource.resourceType}-${resource.resourceId}`;
1679
+ const resourceHealth = healthLookup.get(resourceKey);
1680
+ const resourceDef = resourceDefLookup.get(resource.resourceId);
1681
+ return /* @__PURE__ */ jsx(
1682
+ Card,
1683
+ {
1684
+ withBorder: true,
1685
+ style: {
1686
+ cursor: config.hasPath ? "pointer" : "default",
1687
+ transition: "box-shadow var(--duration-fast) var(--easing)"
1688
+ },
1689
+ onClick: () => handleResourceClick(resource),
1690
+ children: /* @__PURE__ */ jsxs(Grid, { gutter: "sm", align: "center", children: [
1691
+ /* @__PURE__ */ jsx(Grid.Col, { span: 8, children: /* @__PURE__ */ jsxs(Group, { gap: "sm", wrap: "nowrap", children: [
1692
+ /* @__PURE__ */ jsx(Icon, { size: 24, color: "var(--color-primary)" }),
1693
+ /* @__PURE__ */ jsxs(Stack, { gap: 4, style: { flex: 1, minWidth: 0 }, children: [
1694
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, truncate: true, children: resource.resourceName }),
1695
+ resourceDef?.description && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", truncate: true, children: resourceDef.description }),
1696
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1697
+ resourceDef?.version && /* @__PURE__ */ jsxs(Badge, { variant: "outline", size: "xs", children: [
1698
+ "v",
1699
+ resourceDef.version
1700
+ ] }),
1701
+ resourceDef?.status && /* @__PURE__ */ jsx(Badge, { color: ResourceStatusColors[resourceDef.status], variant: "outline", size: "xs", children: resourceDef.status.toUpperCase() })
1702
+ ] }),
1703
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
1704
+ "Last run ",
1705
+ formatRelativeTime(resource.lastExecution)
1706
+ ] })
1707
+ ] })
1708
+ ] }) }),
1709
+ /* @__PURE__ */ jsx(Grid.Col, { span: 4, children: /* @__PURE__ */ jsxs(Group, { justify: "flex-end", gap: "md", wrap: "nowrap", children: [
1710
+ /* @__PURE__ */ jsx(
1711
+ ExecutionStats,
1712
+ {
1713
+ totalExecutions: resource.totalExecutions,
1714
+ successCount: resource.successCount,
1715
+ failureCount: resource.failureCount,
1716
+ warningCount: resource.warningCount,
1717
+ successRate: resource.successRate
1718
+ }
1719
+ ),
1720
+ /* @__PURE__ */ jsx(
1721
+ ResourceHealthChart,
1722
+ {
1723
+ healthData: resourceHealth,
1724
+ hasExecutions: resource.totalExecutions > 0,
1725
+ width: 300,
1726
+ height: 60
1727
+ }
1728
+ )
1729
+ ] }) })
1730
+ ] })
1731
+ },
1732
+ resource.resourceId
1733
+ );
1734
+ }) });
1735
+ }
1736
+ var severityColor2 = {
1737
+ critical: "red",
1738
+ warning: "yellow",
1739
+ info: "blue"
1740
+ };
1741
+ function UnresolvedErrorsTeaser({ timeRange, onNavigateToAllErrors }) {
1742
+ const { startDate, endDate } = useTimeRangeDates(timeRange);
1743
+ const { data, isLoading } = useUnresolvedErrors({ startDate, endDate });
1744
+ const errors = data?.errors ?? [];
1745
+ const total = data?.total ?? 0;
1746
+ if (isLoading) {
1747
+ return /* @__PURE__ */ jsx(
1748
+ Paper,
1749
+ {
1750
+ style: {
1751
+ background: "var(--glass-background)",
1752
+ backdropFilter: "var(--glass-blur)",
1753
+ border: "1px solid var(--color-border)",
1754
+ borderRadius: 8
1755
+ },
1756
+ children: /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) })
1757
+ }
1758
+ );
1759
+ }
1760
+ return /* @__PURE__ */ jsxs(
1761
+ Paper,
1762
+ {
1763
+ style: {
1764
+ background: "var(--glass-background)",
1765
+ backdropFilter: "var(--glass-blur)",
1766
+ border: "1px solid var(--color-border)",
1767
+ borderRadius: 8
1768
+ },
1769
+ children: [
1770
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: errors.length > 0 ? "sm" : 0, children: [
1771
+ /* @__PURE__ */ jsxs(Group, { gap: "sm", children: [
1772
+ /* @__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 }) }),
1773
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, children: "Unresolved Errors" })
1774
+ ] }),
1775
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1776
+ total > 0 && /* @__PURE__ */ jsxs(Badge, { size: "xs", variant: "light", color: "red", children: [
1777
+ total,
1778
+ " unresolved"
1779
+ ] }),
1780
+ /* @__PURE__ */ jsx(ActionIcon, { variant: "subtle", size: "sm", onClick: onNavigateToAllErrors, children: /* @__PURE__ */ jsx(IconArrowUpRight, { size: 14 }) })
1781
+ ] })
1782
+ ] }),
1783
+ errors.length === 0 && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No unresolved errors" }),
1784
+ errors.length > 0 && /* @__PURE__ */ jsx(Stack, { gap: 4, children: errors.map((error) => /* @__PURE__ */ jsx(
1785
+ Box,
1786
+ {
1787
+ px: "sm",
1788
+ py: 6,
1789
+ onClick: onNavigateToAllErrors,
1790
+ style: {
1791
+ borderLeft: `2px solid var(--mantine-color-${severityColor2[error.severity]}-6)`,
1792
+ borderRadius: 4,
1793
+ cursor: onNavigateToAllErrors ? "pointer" : "default",
1794
+ textDecoration: "none",
1795
+ color: "inherit"
1796
+ },
1797
+ children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
1798
+ /* @__PURE__ */ jsxs(Stack, { gap: 0, style: { minWidth: 0 }, children: [
1799
+ /* @__PURE__ */ jsx(Text, { size: "xs", lineClamp: 1, children: error.resourceName || error.resourceId }),
1800
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 1, children: error.errorType })
1801
+ ] }),
1802
+ /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", style: { flexShrink: 0 }, children: [
1803
+ /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: severityColor2[error.severity], children: error.severity }),
1804
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatTimeAgo(error.timestamp) })
1805
+ ] })
1806
+ ] })
1807
+ },
1808
+ error.id
1809
+ )) })
1810
+ ]
1811
+ }
1812
+ );
1813
+ }
1814
+ var dashboardManifest = {
1815
+ key: "dashboard",
1816
+ label: "Dashboard",
1817
+ navEntry: {
1818
+ label: "Dashboard",
1819
+ icon: IconDashboard,
1820
+ link: "/"
1821
+ }
1822
+ };
1197
1823
 
1198
- export { AgentExecutionTimeline, AgentExecutionVisualizer, AgentIterationEdge, AgentIterationNode, BaseEdge, BaseNode, EmptyVisualizer, ExecutionStats, ExecutionStatusBadge, GraphBackground, GraphContainer, GraphFitViewButton, GraphFitViewHandler, GraphLegend, TimelineAxis, TimelineBar, TimelineContainer, TimelineRow, UnifiedWorkflowEdge, UnifiedWorkflowGraph, UnifiedWorkflowNode, VisualizerContainer, WorkflowExecutionTimeline, getGraphBackgroundStyles, useGraphBackgroundStyles, useGraphTheme };
1824
+ export { AgentExecutionTimeline, AgentExecutionVisualizer, AgentIterationEdge, AgentIterationNode, BaseEdge, BaseNode, Dashboard, EmptyVisualizer, ExecutionStats, ExecutionStatusBadge, GraphBackground, GraphContainer, GraphFitViewButton, GraphFitViewHandler, GraphLegend, OperationsOverview, RecentExecutionsByResource, ResourceOverview, TimelineAxis, TimelineBar, TimelineContainer, TimelineRow, UnifiedWorkflowEdge, UnifiedWorkflowGraph, UnifiedWorkflowNode, UnresolvedErrorsTeaser, VisualizerContainer, WorkflowExecutionTimeline, dashboardManifest, getGraphBackgroundStyles, useGraphBackgroundStyles, useGraphTheme };
@@ -1,9 +1,9 @@
1
1
  import { getTimeRangeDates, observabilityKeys } from './chunk-LXHZYSMQ.js';
2
2
  import { GRAPH_CONSTANTS } from './chunk-F6RBK7NJ.js';
3
- import { useNotificationAdapter } from './chunk-45MS3IAW.js';
3
+ import { useNotificationAdapter } from './chunk-MZPVNRPL.js';
4
4
  import { HTTP_HEADERS } from './chunk-NVOCKXUQ.js';
5
5
  import { STALE_TIME_MONITORING, REFETCH_INTERVAL_DASHBOARD, REFETCH_INTERVAL_RUNNING, WS_MAX_RETRIES_BEFORE_ERROR, WS_RECONNECT_BASE_DELAY, WS_RECONNECT_MAX_DELAY, getErrorInfo, formatErrorMessage, getErrorTitle, STALE_TIME_DEFAULT, STALE_TIME_ADMIN, APIClientError } from './chunk-IOKL7BKE.js';
6
- import { useStableAccessToken } from './chunk-ALA56RGZ.js';
6
+ import { useStableAccessToken } from './chunk-MTJ43R2E.js';
7
7
  import { useOrganization } from './chunk-DD3CCMCZ.js';
8
8
  import { useElevasisServices } from './chunk-QEPXAWE2.js';
9
9
  import { useAuthContext } from './chunk-BRJ3QZ4E.js';
@@ -173,7 +173,7 @@ var tacticalPreset = {
173
173
  glassBackground: "rgba(14, 15, 17, 0.6)",
174
174
  glassBlur: "blur(24px) saturate(170%)",
175
175
  shadow: "0px 1px 2px rgba(0, 0, 0, 0.5), 0px 12px 32px -8px rgba(0, 0, 0, 0.6)",
176
- cardShadow: "inset 0 1px 0 rgba(255, 255, 255, 0.04), inset 0 0 0 1px rgba(255, 255, 255, 0.03), 0 2px 8px rgba(0, 0, 0, 0.3), 0 12px 32px -8px rgba(0, 0, 0, 0.4), 0 32px 64px -16px rgba(0, 0, 0, 0.3)",
176
+ cardShadow: "inset 0 1px 0 rgba(255, 255, 255, 0.04), inset 0 0 8px -6px rgba(255, 255, 255, 0.1), 0 2px 8px rgba(0, 0, 0, 0.3), 0 12px 32px -8px rgba(0, 0, 0, 0.4), 0 32px 64px -16px rgba(0, 0, 0, 0.3)",
177
177
  durationFast: "100ms",
178
178
  durationNormal: "180ms",
179
179
  easing: "cubic-bezier(0.22, 0, 0.1, 1)",