@elevasis/ui 1.26.1 → 1.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/charts/index.js +2 -2
- package/dist/{chunk-AWT255UH.js → chunk-2IJCM3VQ.js} +37 -37
- package/dist/chunk-5COLSYBE.js +199 -0
- package/dist/{chunk-RMPXGBNI.js → chunk-5JSR6TL5.js} +2 -2
- package/dist/chunk-BAGYETKM.js +635 -0
- package/dist/{chunk-L3GVDMCA.js → chunk-C27LLJM6.js} +3 -195
- package/dist/{chunk-O4UB5DQQ.js → chunk-F2J7675J.js} +1 -1
- package/dist/chunk-ITCEULI5.js +238 -0
- package/dist/{chunk-4WKWLFBZ.js → chunk-P5EWG45B.js} +1 -1
- package/dist/{chunk-BS4J2LAW.js → chunk-QTD5HPKD.js} +1 -1
- package/dist/{chunk-ZVJKIJFG.js → chunk-RCQPWA5X.js} +13 -42
- package/dist/chunk-TLAIQC7B.js +6382 -0
- package/dist/{chunk-FEZZ3IDU.js → chunk-TXPUIHX2.js} +10 -10
- package/dist/{chunk-L4XXM55J.js → chunk-W4VYXIN7.js} +142 -3
- package/dist/chunk-WJ7W7JU4.js +2115 -0
- package/dist/{chunk-YNGQ7U5H.js → chunk-WLNEJ6JJ.js} +2 -2
- package/dist/{chunk-4INR75ZS.js → chunk-Y2SYGFRF.js} +589 -65
- package/dist/components/index.d.ts +333 -73
- package/dist/components/index.js +838 -686
- package/dist/features/auth/index.d.ts +125 -0
- package/dist/features/auth/index.js +2 -2
- package/dist/features/dashboard/index.d.ts +28 -2
- package/dist/features/dashboard/index.js +21 -635
- package/dist/features/monitoring/index.d.ts +28 -1
- package/dist/features/monitoring/index.js +19 -529
- package/dist/features/operations/index.d.ts +51 -8
- package/dist/features/operations/index.js +25 -3760
- package/dist/features/settings/index.d.ts +153 -1
- package/dist/features/settings/index.js +19 -1438
- package/dist/hooks/index.d.ts +262 -25
- package/dist/hooks/index.js +12 -8
- package/dist/hooks/published.d.ts +137 -25
- package/dist/hooks/published.js +11 -7
- package/dist/index.d.ts +310 -28
- package/dist/index.js +12 -11
- package/dist/initialization/index.d.ts +125 -0
- package/dist/layout/index.d.ts +2 -0
- package/dist/layout/index.js +6 -5
- package/dist/organization/index.js +1 -2
- package/dist/profile/index.d.ts +125 -0
- package/dist/provider/index.d.ts +48 -3
- package/dist/provider/index.js +10 -4
- package/dist/provider/published.d.ts +48 -3
- package/dist/provider/published.js +8 -2
- package/dist/supabase/index.d.ts +242 -0
- package/dist/theme/index.js +2 -2
- package/dist/types/index.d.ts +126 -1
- package/package.json +3 -3
- package/dist/chunk-LR4WVA7W.js +0 -682
- package/dist/chunk-R7WLWGPO.js +0 -126
- package/dist/chunk-TCKIAHDC.js +0 -2626
- package/dist/chunk-V7XHGJQZ.js +0 -145
- package/dist/{chunk-WWEMNIHW.js → chunk-YYBM5LNJ.js} +1 -1
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { FilterBar } from './chunk-PDHTXPSF.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { CustomModal } from './chunk-GBMNCNHX.js';
|
|
3
|
+
import { CyberAreaChart, CostTrendChart, ActivityTrendChart } from './chunk-JHVKGZ2P.js';
|
|
4
|
+
import { CenteredErrorState, CardHeader, StatsCardSkeleton, TrendIndicator, DetailCardSkeleton, EmptyState, PageTitleCaption, JsonViewer } from './chunk-MCA6LOGM.js';
|
|
5
|
+
import { AppShellLoader } from './chunk-YYBM5LNJ.js';
|
|
6
|
+
import { useExecutionLogsFilters, useTimeRangeDates, useActivityFilters } from './chunk-WLNEJ6JJ.js';
|
|
7
|
+
import { useResolveError, useResolveAllErrors, usePaginationState, useErrorDetails, useMarkAsRead, useExecutionLogs, useExecutionHealth, useErrorAnalysis, useErrorDetail, useResolveErrorsByExecution, useResources, useCostTrends, useCostSummary, useCostByModel, useCostBreakdown, useActivityTrend, useActivities, useNotifications, useMarkAllAsRead, useTestNotification } from './chunk-RCQPWA5X.js';
|
|
8
|
+
import { formatBucketTime, getTimeRangeDates } from './chunk-LXHZYSMQ.js';
|
|
6
9
|
import { formatDuration } from './chunk-XA34RETF.js';
|
|
7
10
|
import { PAGE_SIZE_DEFAULT } from './chunk-IOKL7BKE.js';
|
|
8
11
|
import { useRouterContext } from './chunk-Q7DJKLEN.js';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
+
import { useState, useMemo, useCallback } from 'react';
|
|
13
|
+
import { Table, Text, Badge, Tooltip, Card, Group, Select, SegmentedControl, Button, TextInput, Stack, Paper, Center, Loader, ActionIcon, NumberFormatter, Box, Alert, Switch, Pagination, UnstyledButton, Title, Divider, Code, CopyButton, Accordion } from '@mantine/core';
|
|
14
|
+
import { IconActivity, IconFilterOff, IconCircleCheck, IconThumbDown, IconThumbUp, IconClock, IconCircleX, IconSearch, IconArrowUpRight, IconAlertTriangle, IconAlertCircle, IconExternalLink, IconChartPie, IconHeartbeat, IconDownload, IconCpu, IconTrendingUp, IconChartBar, IconCash, IconInfoCircle, IconExclamationCircle, IconBug, IconChecks, IconCircle, IconCircleFilled, IconCheck, IconCopy, IconCircleDashed, IconPlus, IconArrowUp, IconArrowDown, IconFileOff, IconRobot, IconKey, IconUser } from '@tabler/icons-react';
|
|
15
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
12
16
|
import { formatDistanceToNow } from 'date-fns';
|
|
13
|
-
import { useState } from 'react';
|
|
14
17
|
|
|
15
18
|
function formatStartTime(timestamp) {
|
|
16
19
|
return new Date(timestamp).toLocaleString("en-US", {
|
|
@@ -113,6 +116,51 @@ SDK: ${execution.sdkVersion ?? "-"}`,
|
|
|
113
116
|
}) })
|
|
114
117
|
] });
|
|
115
118
|
}
|
|
119
|
+
var resourceOptions = [{ value: "", label: "All Resources" }];
|
|
120
|
+
var statusOptions = [
|
|
121
|
+
{ value: "all", label: "All" },
|
|
122
|
+
{ value: "running", label: "Running" },
|
|
123
|
+
{ value: "completed", label: "Completed" },
|
|
124
|
+
{ value: "warning", label: "Warning" },
|
|
125
|
+
{ value: "failed", label: "Failed" }
|
|
126
|
+
];
|
|
127
|
+
var environmentOptions = [
|
|
128
|
+
{ value: "all", label: "All" },
|
|
129
|
+
{ value: "dev", label: "Dev" },
|
|
130
|
+
{ value: "prod", label: "Prod" }
|
|
131
|
+
];
|
|
132
|
+
function ExecutionLogsFilters({ filters, onFilterChange, onReset }) {
|
|
133
|
+
const hasActiveFilters = filters.resourceId !== void 0 || filters.status !== "all" || filters.resourceStatus !== "all";
|
|
134
|
+
return /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(Group, { gap: "md", wrap: "wrap", children: [
|
|
135
|
+
/* @__PURE__ */ jsx(
|
|
136
|
+
Select,
|
|
137
|
+
{
|
|
138
|
+
placeholder: "Resource",
|
|
139
|
+
data: resourceOptions,
|
|
140
|
+
value: filters.resourceId ?? "",
|
|
141
|
+
onChange: (value) => onFilterChange("resourceId", value === "" || value === null ? void 0 : value),
|
|
142
|
+
style: { minWidth: 180 }
|
|
143
|
+
}
|
|
144
|
+
),
|
|
145
|
+
/* @__PURE__ */ jsx(
|
|
146
|
+
SegmentedControl,
|
|
147
|
+
{
|
|
148
|
+
data: statusOptions,
|
|
149
|
+
value: filters.status,
|
|
150
|
+
onChange: (value) => onFilterChange("status", value)
|
|
151
|
+
}
|
|
152
|
+
),
|
|
153
|
+
/* @__PURE__ */ jsx(
|
|
154
|
+
SegmentedControl,
|
|
155
|
+
{
|
|
156
|
+
data: environmentOptions,
|
|
157
|
+
value: filters.resourceStatus,
|
|
158
|
+
onChange: (value) => onFilterChange("resourceStatus", value)
|
|
159
|
+
}
|
|
160
|
+
),
|
|
161
|
+
hasActiveFilters && /* @__PURE__ */ jsx(Button, { variant: "subtle", color: "gray", leftSection: /* @__PURE__ */ jsx(IconFilterOff, { size: 16 }), onClick: onReset, children: "Reset" })
|
|
162
|
+
] }) });
|
|
163
|
+
}
|
|
116
164
|
var statusConfig = {
|
|
117
165
|
success: { color: "green", icon: IconCircleCheck },
|
|
118
166
|
failure: { color: "red", icon: IconCircleX },
|
|
@@ -201,7 +249,7 @@ var activityTypeOptions = [
|
|
|
201
249
|
{ value: "deployment_change", label: "Deployment Changes" },
|
|
202
250
|
{ value: "membership_change", label: "Membership Changes" }
|
|
203
251
|
];
|
|
204
|
-
var
|
|
252
|
+
var statusOptions2 = [
|
|
205
253
|
{ value: "all", label: "All Statuses" },
|
|
206
254
|
{ value: "success", label: "Success" },
|
|
207
255
|
{ value: "failure", label: "Failure" },
|
|
@@ -230,7 +278,7 @@ function ActivityFilters({ filters, onFilterChange, onReset }) {
|
|
|
230
278
|
Select,
|
|
231
279
|
{
|
|
232
280
|
placeholder: "Status",
|
|
233
|
-
data:
|
|
281
|
+
data: statusOptions2,
|
|
234
282
|
value: filters.status || "all",
|
|
235
283
|
onChange: (value) => onFilterChange("status", value),
|
|
236
284
|
style: { flex: 1, minWidth: 150 }
|
|
@@ -542,51 +590,6 @@ function ExecutionHealthCard({ data, isLoading, error }) {
|
|
|
542
590
|
] })
|
|
543
591
|
] });
|
|
544
592
|
}
|
|
545
|
-
var resourceOptions = [{ value: "", label: "All Resources" }];
|
|
546
|
-
var statusOptions2 = [
|
|
547
|
-
{ value: "all", label: "All" },
|
|
548
|
-
{ value: "running", label: "Running" },
|
|
549
|
-
{ value: "completed", label: "Completed" },
|
|
550
|
-
{ value: "warning", label: "Warning" },
|
|
551
|
-
{ value: "failed", label: "Failed" }
|
|
552
|
-
];
|
|
553
|
-
var environmentOptions = [
|
|
554
|
-
{ value: "all", label: "All" },
|
|
555
|
-
{ value: "dev", label: "Dev" },
|
|
556
|
-
{ value: "prod", label: "Prod" }
|
|
557
|
-
];
|
|
558
|
-
function ExecutionLogsFilters({ filters, onFilterChange, onReset }) {
|
|
559
|
-
const hasActiveFilters = filters.resourceId !== void 0 || filters.status !== "all" || filters.resourceStatus !== "all";
|
|
560
|
-
return /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(Group, { gap: "md", wrap: "wrap", children: [
|
|
561
|
-
/* @__PURE__ */ jsx(
|
|
562
|
-
Select,
|
|
563
|
-
{
|
|
564
|
-
placeholder: "Resource",
|
|
565
|
-
data: resourceOptions,
|
|
566
|
-
value: filters.resourceId ?? "",
|
|
567
|
-
onChange: (value) => onFilterChange("resourceId", value === "" || value === null ? void 0 : value),
|
|
568
|
-
style: { minWidth: 180 }
|
|
569
|
-
}
|
|
570
|
-
),
|
|
571
|
-
/* @__PURE__ */ jsx(
|
|
572
|
-
SegmentedControl,
|
|
573
|
-
{
|
|
574
|
-
data: statusOptions2,
|
|
575
|
-
value: filters.status,
|
|
576
|
-
onChange: (value) => onFilterChange("status", value)
|
|
577
|
-
}
|
|
578
|
-
),
|
|
579
|
-
/* @__PURE__ */ jsx(
|
|
580
|
-
SegmentedControl,
|
|
581
|
-
{
|
|
582
|
-
data: environmentOptions,
|
|
583
|
-
value: filters.resourceStatus,
|
|
584
|
-
onChange: (value) => onFilterChange("resourceStatus", value)
|
|
585
|
-
}
|
|
586
|
-
),
|
|
587
|
-
hasActiveFilters && /* @__PURE__ */ jsx(Button, { variant: "subtle", color: "gray", leftSection: /* @__PURE__ */ jsx(IconFilterOff, { size: 16 }), onClick: onReset, children: "Reset" })
|
|
588
|
-
] }) });
|
|
589
|
-
}
|
|
590
593
|
function CostByModelTable({ data, isLoading, error }) {
|
|
591
594
|
const [sortField, setSortField] = useState("cost");
|
|
592
595
|
const [sortDirection, setSortDirection] = useState("desc");
|
|
@@ -1220,15 +1223,6 @@ function ErrorBreakdownTable({ startDate, endDate, onErrorClick }) {
|
|
|
1220
1223
|
totalPages(total) > 1 && /* @__PURE__ */ jsx(Group, { justify: "flex-start", children: /* @__PURE__ */ jsx(Pagination, { total: totalPages(total), value: page, onChange: setPage, size: "sm", boundaries: 1 }) })
|
|
1221
1224
|
] }) });
|
|
1222
1225
|
}
|
|
1223
|
-
function NotificationList({ notifications, isLoading, onClose, onNavigate }) {
|
|
1224
|
-
if (isLoading) {
|
|
1225
|
-
return /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) });
|
|
1226
|
-
}
|
|
1227
|
-
if (notifications.length === 0) {
|
|
1228
|
-
return /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No notifications" }) });
|
|
1229
|
-
}
|
|
1230
|
-
return /* @__PURE__ */ jsx(Stack, { gap: 0, children: notifications.map((notification) => /* @__PURE__ */ jsx(NotificationItem, { notification, onClose, onNavigate }, notification.id)) });
|
|
1231
|
-
}
|
|
1232
1226
|
var categoryColors = {
|
|
1233
1227
|
info: "blue",
|
|
1234
1228
|
queue: "cyan",
|
|
@@ -1276,5 +1270,535 @@ function NotificationItem({ notification, onClose, onNavigate }) {
|
|
|
1276
1270
|
}
|
|
1277
1271
|
);
|
|
1278
1272
|
}
|
|
1273
|
+
function NotificationList({ notifications, isLoading, onClose, onNavigate }) {
|
|
1274
|
+
if (isLoading) {
|
|
1275
|
+
return /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) });
|
|
1276
|
+
}
|
|
1277
|
+
if (notifications.length === 0) {
|
|
1278
|
+
return /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No notifications" }) });
|
|
1279
|
+
}
|
|
1280
|
+
return /* @__PURE__ */ jsx(Stack, { gap: 0, children: notifications.map((notification) => /* @__PURE__ */ jsx(NotificationItem, { notification, onClose, onNavigate }, notification.id)) });
|
|
1281
|
+
}
|
|
1282
|
+
function ExecutionLogsPage({
|
|
1283
|
+
timeRange,
|
|
1284
|
+
pageSize = 20,
|
|
1285
|
+
onNavigateToExecution,
|
|
1286
|
+
renderTrendChart
|
|
1287
|
+
}) {
|
|
1288
|
+
const { filters, updateFilter, resetFilters } = useExecutionLogsFilters(timeRange);
|
|
1289
|
+
const startDate = useMemo(() => {
|
|
1290
|
+
const { startDate: sd } = getTimeRangeDates(timeRange);
|
|
1291
|
+
return new Date(sd).getTime();
|
|
1292
|
+
}, [timeRange]);
|
|
1293
|
+
const { page, setPage, offset, totalPages } = usePaginationState(pageSize, [
|
|
1294
|
+
filters.resourceId,
|
|
1295
|
+
filters.status,
|
|
1296
|
+
filters.resourceStatus,
|
|
1297
|
+
timeRange
|
|
1298
|
+
]);
|
|
1299
|
+
const { data, isLoading } = useExecutionLogs({
|
|
1300
|
+
resourceId: filters.resourceId,
|
|
1301
|
+
status: filters.status !== "all" ? filters.status : void 0,
|
|
1302
|
+
resourceStatus: filters.resourceStatus !== "all" ? filters.resourceStatus : void 0,
|
|
1303
|
+
startDate,
|
|
1304
|
+
limit: pageSize,
|
|
1305
|
+
offset
|
|
1306
|
+
});
|
|
1307
|
+
const total = data?.total ?? 0;
|
|
1308
|
+
return /* @__PURE__ */ jsxs(Stack, { children: [
|
|
1309
|
+
/* @__PURE__ */ jsx(PageTitleCaption, { title: "Execution Logs", caption: "View and filter execution history across all resources" }),
|
|
1310
|
+
renderTrendChart({ timeRange }),
|
|
1311
|
+
/* @__PURE__ */ jsx(Paper, { children: /* @__PURE__ */ jsxs(Stack, { children: [
|
|
1312
|
+
/* @__PURE__ */ jsx(ExecutionLogsFilters, { filters, onFilterChange: updateFilter, onReset: resetFilters }),
|
|
1313
|
+
/* @__PURE__ */ jsx(
|
|
1314
|
+
ExecutionLogsTable,
|
|
1315
|
+
{
|
|
1316
|
+
executions: data?.executions || [],
|
|
1317
|
+
isLoading,
|
|
1318
|
+
onRowClick: onNavigateToExecution
|
|
1319
|
+
}
|
|
1320
|
+
),
|
|
1321
|
+
totalPages(total) > 1 && /* @__PURE__ */ jsx(Group, { justify: "flex-start", children: /* @__PURE__ */ jsx(Pagination, { value: page, onChange: setPage, total: totalPages(total), size: "sm", boundaries: 1 }) })
|
|
1322
|
+
] }) })
|
|
1323
|
+
] });
|
|
1324
|
+
}
|
|
1325
|
+
function ExecutionHealth({ timeRange, onErrorClick }) {
|
|
1326
|
+
const { data, isLoading, error } = useExecutionHealth({ timeRange });
|
|
1327
|
+
const { data: errorData, isLoading: errorLoading, error: errorError } = useErrorAnalysis(timeRange);
|
|
1328
|
+
const { startDate, endDate } = useTimeRangeDates(timeRange);
|
|
1329
|
+
if (isLoading) return /* @__PURE__ */ jsx(AppShellLoader, {});
|
|
1330
|
+
return /* @__PURE__ */ jsxs(Stack, { children: [
|
|
1331
|
+
/* @__PURE__ */ jsx(
|
|
1332
|
+
PageTitleCaption,
|
|
1333
|
+
{
|
|
1334
|
+
title: "Execution Health",
|
|
1335
|
+
caption: "Detailed execution metrics, success rates, and performance trends"
|
|
1336
|
+
}
|
|
1337
|
+
),
|
|
1338
|
+
/* @__PURE__ */ jsx(ExecutionHealthCard, { data: data?.executionHealth, isLoading, error }),
|
|
1339
|
+
/* @__PURE__ */ jsx(
|
|
1340
|
+
ErrorBreakdownTable,
|
|
1341
|
+
{
|
|
1342
|
+
startDate,
|
|
1343
|
+
endDate,
|
|
1344
|
+
onErrorClick: (executionId) => onErrorClick(executionId)
|
|
1345
|
+
}
|
|
1346
|
+
),
|
|
1347
|
+
/* @__PURE__ */ jsx(ErrorAnalysisCard, { data: errorData, isLoading: errorLoading, error: errorError })
|
|
1348
|
+
] });
|
|
1349
|
+
}
|
|
1350
|
+
function ErrorDetailsModal({ executionId, opened, onClose, organizationName }) {
|
|
1351
|
+
const { data: errors, isLoading, isError } = useErrorDetail(executionId);
|
|
1352
|
+
const resolveErrors = useResolveErrorsByExecution();
|
|
1353
|
+
const { data: resources } = useResources();
|
|
1354
|
+
const resourceNameMap = useMemo(() => {
|
|
1355
|
+
const map = /* @__PURE__ */ new Map();
|
|
1356
|
+
if (resources) {
|
|
1357
|
+
for (const r of [...resources.workflows, ...resources.agents]) {
|
|
1358
|
+
map.set(r.resourceId, r.name);
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
return map;
|
|
1362
|
+
}, [resources]);
|
|
1363
|
+
const primaryError = errors?.[0];
|
|
1364
|
+
const resolvedResourceName = primaryError ? resourceNameMap.get(primaryError.resourceId) ?? primaryError.resourceId : void 0;
|
|
1365
|
+
const allResolved = errors?.every((e) => e.resolved) ?? false;
|
|
1366
|
+
const hasRetries = errors && errors.length > 1;
|
|
1367
|
+
const handleCopyDetails = () => {
|
|
1368
|
+
if (!primaryError) return;
|
|
1369
|
+
const detailsText = `
|
|
1370
|
+
Error ID: ${primaryError.id}
|
|
1371
|
+
Timestamp: ${primaryError.timestamp}
|
|
1372
|
+
Type: ${primaryError.errorType}
|
|
1373
|
+
Severity: ${primaryError.severity}
|
|
1374
|
+
Execution ID: ${primaryError.executionId}
|
|
1375
|
+
Resource: ${primaryError.resourceName}
|
|
1376
|
+
|
|
1377
|
+
Message:
|
|
1378
|
+
${primaryError.message}
|
|
1379
|
+
|
|
1380
|
+
Stack Trace:
|
|
1381
|
+
${primaryError.stackTrace || "No stack trace available"}
|
|
1382
|
+
|
|
1383
|
+
Context:
|
|
1384
|
+
${primaryError.errorContext ? JSON.stringify(primaryError.errorContext, null, 2) : "No context available"}
|
|
1385
|
+
`.trim();
|
|
1386
|
+
navigator.clipboard.writeText(detailsText);
|
|
1387
|
+
};
|
|
1388
|
+
return /* @__PURE__ */ jsx(CustomModal, { opened, onClose, size: "xl", children: /* @__PURE__ */ jsxs(Stack, { children: [
|
|
1389
|
+
isLoading && /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) }),
|
|
1390
|
+
isError && /* @__PURE__ */ jsx(Alert, { color: "red", icon: /* @__PURE__ */ jsx(IconAlertCircle, {}), title: "Error Loading Details", children: "Failed to load error details. Please try again." }),
|
|
1391
|
+
!isLoading && !isError && !primaryError && /* @__PURE__ */ jsx(Alert, { color: "gray", icon: /* @__PURE__ */ jsx(IconBug, {}), children: "No error details found for this execution." }),
|
|
1392
|
+
!isLoading && !isError && primaryError && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1393
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
|
|
1394
|
+
/* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
|
|
1395
|
+
/* @__PURE__ */ jsx(IconAlertCircle, { size: 24, color: "var(--color-error)" }),
|
|
1396
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1397
|
+
/* @__PURE__ */ jsx(Title, { order: 3, children: primaryError.errorType }),
|
|
1398
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: new Date(primaryError.timestamp).toLocaleString("en-US", {
|
|
1399
|
+
month: "long",
|
|
1400
|
+
day: "numeric",
|
|
1401
|
+
year: "numeric",
|
|
1402
|
+
hour: "2-digit",
|
|
1403
|
+
minute: "2-digit",
|
|
1404
|
+
second: "2-digit"
|
|
1405
|
+
}) })
|
|
1406
|
+
] })
|
|
1407
|
+
] }),
|
|
1408
|
+
/* @__PURE__ */ jsx(
|
|
1409
|
+
Badge,
|
|
1410
|
+
{
|
|
1411
|
+
color: primaryError.severity === "critical" ? "red" : primaryError.severity === "warning" ? "orange" : "blue",
|
|
1412
|
+
variant: "light",
|
|
1413
|
+
children: primaryError.severity
|
|
1414
|
+
}
|
|
1415
|
+
)
|
|
1416
|
+
] }),
|
|
1417
|
+
/* @__PURE__ */ jsx(Divider, {}),
|
|
1418
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1419
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, mb: "xs", style: { fontFamily: "var(--mantine-font-family-headings)" }, children: "Error Message" }),
|
|
1420
|
+
/* @__PURE__ */ jsx(Alert, { color: "red", icon: /* @__PURE__ */ jsx(IconBug, { size: 16 }), children: primaryError.message })
|
|
1421
|
+
] }),
|
|
1422
|
+
hasRetries && /* @__PURE__ */ jsxs(Alert, { color: "yellow", icon: /* @__PURE__ */ jsx(IconAlertCircle, { size: 16 }), children: [
|
|
1423
|
+
"This execution has ",
|
|
1424
|
+
errors.length,
|
|
1425
|
+
" errors (including retries). Showing most recent error."
|
|
1426
|
+
] }),
|
|
1427
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1428
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, mb: "xs", style: { fontFamily: "var(--mantine-font-family-headings)" }, children: "Execution Context" }),
|
|
1429
|
+
/* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
|
|
1430
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
|
|
1431
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Execution ID" }),
|
|
1432
|
+
/* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
|
|
1433
|
+
/* @__PURE__ */ jsx(Code, { children: primaryError.executionId }),
|
|
1434
|
+
/* @__PURE__ */ jsx(CopyButton, { value: `"${organizationName}/${primaryError.resourceId}" ${primaryError.executionId}`, children: ({ copied, copy }) => /* @__PURE__ */ jsx(Tooltip, { label: copied ? "Copied" : "Copy Execution Ref", children: /* @__PURE__ */ jsx(ActionIcon, { variant: "subtle", size: "sm", color: copied ? "teal" : "gray", onClick: copy, children: copied ? /* @__PURE__ */ jsx(IconCheck, { size: 14 }) : /* @__PURE__ */ jsx(IconCopy, { size: 14 }) }) }) }),
|
|
1435
|
+
/* @__PURE__ */ jsx(
|
|
1436
|
+
ActionIcon,
|
|
1437
|
+
{
|
|
1438
|
+
variant: "subtle",
|
|
1439
|
+
size: "sm",
|
|
1440
|
+
component: "a",
|
|
1441
|
+
href: `/operations/resources/workflow/${primaryError.resourceId}`,
|
|
1442
|
+
target: "_blank",
|
|
1443
|
+
title: "View Execution Log",
|
|
1444
|
+
children: /* @__PURE__ */ jsx(IconExternalLink, { size: 14 })
|
|
1445
|
+
}
|
|
1446
|
+
)
|
|
1447
|
+
] })
|
|
1448
|
+
] }),
|
|
1449
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
|
|
1450
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Resource Name" }),
|
|
1451
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", children: resolvedResourceName })
|
|
1452
|
+
] }),
|
|
1453
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
|
|
1454
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Resource ID" }),
|
|
1455
|
+
/* @__PURE__ */ jsx(Code, { children: primaryError.resourceId })
|
|
1456
|
+
] }),
|
|
1457
|
+
primaryError.retryAttempt && /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
|
|
1458
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Retry Attempt" }),
|
|
1459
|
+
/* @__PURE__ */ jsx(Badge, { size: "sm", children: primaryError.retryAttempt })
|
|
1460
|
+
] }),
|
|
1461
|
+
primaryError.stepName && /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
|
|
1462
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Step Name" }),
|
|
1463
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", children: primaryError.stepName })
|
|
1464
|
+
] })
|
|
1465
|
+
] })
|
|
1466
|
+
] }),
|
|
1467
|
+
primaryError.stackTrace && /* @__PURE__ */ jsxs("div", { children: [
|
|
1468
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: "xs", children: [
|
|
1469
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, style: { fontFamily: "var(--mantine-font-family-headings)" }, children: "Stack Trace" }),
|
|
1470
|
+
/* @__PURE__ */ jsx(CopyButton, { value: primaryError.stackTrace, children: ({ copied, copy }) => /* @__PURE__ */ jsx(Tooltip, { label: copied ? "Copied" : "Copy stack trace", children: /* @__PURE__ */ jsx(ActionIcon, { variant: "subtle", size: "sm", onClick: copy, children: copied ? /* @__PURE__ */ jsx(IconCheck, { size: 14 }) : /* @__PURE__ */ jsx(IconCopy, { size: 14 }) }) }) })
|
|
1471
|
+
] }),
|
|
1472
|
+
/* @__PURE__ */ jsx(
|
|
1473
|
+
Code,
|
|
1474
|
+
{
|
|
1475
|
+
block: true,
|
|
1476
|
+
style: {
|
|
1477
|
+
maxHeight: 300,
|
|
1478
|
+
overflow: "auto",
|
|
1479
|
+
fontSize: "12px",
|
|
1480
|
+
lineHeight: "1.5"
|
|
1481
|
+
},
|
|
1482
|
+
children: primaryError.stackTrace
|
|
1483
|
+
}
|
|
1484
|
+
)
|
|
1485
|
+
] }),
|
|
1486
|
+
primaryError.errorContext && /* @__PURE__ */ jsxs("div", { children: [
|
|
1487
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, mb: "xs", style: { fontFamily: "var(--mantine-font-family-headings)" }, children: "Error Context" }),
|
|
1488
|
+
/* @__PURE__ */ jsx(JsonViewer, { data: primaryError.errorContext, maxHeight: 200, fontSize: "12px" })
|
|
1489
|
+
] }),
|
|
1490
|
+
primaryError.executionContext && /* @__PURE__ */ jsxs("div", { children: [
|
|
1491
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, mb: "xs", style: { fontFamily: "var(--mantine-font-family-headings)" }, children: "Execution Context" }),
|
|
1492
|
+
/* @__PURE__ */ jsx(JsonViewer, { data: primaryError.executionContext, maxHeight: 200, fontSize: "12px" })
|
|
1493
|
+
] }),
|
|
1494
|
+
hasRetries && /* @__PURE__ */ jsxs("div", { children: [
|
|
1495
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, mb: "xs", style: { fontFamily: "var(--mantine-font-family-headings)" }, children: "All Errors (including retries)" }),
|
|
1496
|
+
/* @__PURE__ */ jsx(Accordion, { children: errors.map((error, index) => /* @__PURE__ */ jsxs(Accordion.Item, { value: error.id, children: [
|
|
1497
|
+
/* @__PURE__ */ jsx(Accordion.Control, { children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
|
|
1498
|
+
/* @__PURE__ */ jsxs(Text, { size: "sm", children: [
|
|
1499
|
+
"Attempt ",
|
|
1500
|
+
error.retryAttempt || index + 1,
|
|
1501
|
+
" - ",
|
|
1502
|
+
error.errorType
|
|
1503
|
+
] }),
|
|
1504
|
+
/* @__PURE__ */ jsx(
|
|
1505
|
+
Badge,
|
|
1506
|
+
{
|
|
1507
|
+
size: "sm",
|
|
1508
|
+
color: error.severity === "critical" ? "red" : error.severity === "warning" ? "orange" : "blue",
|
|
1509
|
+
children: error.severity
|
|
1510
|
+
}
|
|
1511
|
+
)
|
|
1512
|
+
] }) }),
|
|
1513
|
+
/* @__PURE__ */ jsx(Accordion.Panel, { children: /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
|
|
1514
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", children: error.message }),
|
|
1515
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: new Date(error.timestamp).toLocaleString() }),
|
|
1516
|
+
error.stackTrace && /* @__PURE__ */ jsx(Code, { block: true, style: { fontSize: "11px", maxHeight: 150, overflow: "auto" }, children: error.stackTrace })
|
|
1517
|
+
] }) })
|
|
1518
|
+
] }, error.id)) })
|
|
1519
|
+
] }),
|
|
1520
|
+
/* @__PURE__ */ jsx(Divider, {}),
|
|
1521
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
|
|
1522
|
+
/* @__PURE__ */ jsxs(Group, { children: [
|
|
1523
|
+
/* @__PURE__ */ jsx(Button, { variant: "light", leftSection: /* @__PURE__ */ jsx(IconCopy, { size: 16 }), onClick: handleCopyDetails, children: "Copy Error Details" }),
|
|
1524
|
+
allResolved ? /* @__PURE__ */ jsx(
|
|
1525
|
+
Badge,
|
|
1526
|
+
{
|
|
1527
|
+
size: "lg",
|
|
1528
|
+
color: "green",
|
|
1529
|
+
variant: "light",
|
|
1530
|
+
leftSection: /* @__PURE__ */ jsx(IconCircleCheck, { size: 14 }),
|
|
1531
|
+
style: { cursor: "default" },
|
|
1532
|
+
children: "Resolved"
|
|
1533
|
+
}
|
|
1534
|
+
) : /* @__PURE__ */ jsx(
|
|
1535
|
+
Button,
|
|
1536
|
+
{
|
|
1537
|
+
variant: "light",
|
|
1538
|
+
color: "teal",
|
|
1539
|
+
leftSection: /* @__PURE__ */ jsx(IconCircleDashed, { size: 16 }),
|
|
1540
|
+
loading: resolveErrors.isPending,
|
|
1541
|
+
onClick: () => executionId && resolveErrors.mutate(executionId),
|
|
1542
|
+
children: "Resolve"
|
|
1543
|
+
}
|
|
1544
|
+
)
|
|
1545
|
+
] }),
|
|
1546
|
+
/* @__PURE__ */ jsxs(Group, { children: [
|
|
1547
|
+
/* @__PURE__ */ jsx(Button, { variant: "default", onClick: onClose, children: "Close" }),
|
|
1548
|
+
/* @__PURE__ */ jsx(
|
|
1549
|
+
Button,
|
|
1550
|
+
{
|
|
1551
|
+
component: "a",
|
|
1552
|
+
href: `/operations/resources/workflow/${primaryError.resourceId}`,
|
|
1553
|
+
target: "_blank",
|
|
1554
|
+
leftSection: /* @__PURE__ */ jsx(IconExternalLink, { size: 16 }),
|
|
1555
|
+
children: "View Execution Log"
|
|
1556
|
+
}
|
|
1557
|
+
)
|
|
1558
|
+
] })
|
|
1559
|
+
] })
|
|
1560
|
+
] })
|
|
1561
|
+
] }) });
|
|
1562
|
+
}
|
|
1563
|
+
function CostAnalytics({ timeRange }) {
|
|
1564
|
+
const { data: trendsData, isLoading: trendsLoading, error: trendsError } = useCostTrends(timeRange);
|
|
1565
|
+
const { data: summaryData } = useCostSummary(timeRange);
|
|
1566
|
+
const { data: modelData, isLoading: modelLoading, error: modelError } = useCostByModel(timeRange);
|
|
1567
|
+
const { data: breakdownData, isLoading: breakdownLoading, error: breakdownError } = useCostBreakdown(timeRange);
|
|
1568
|
+
if (trendsLoading) return /* @__PURE__ */ jsx(AppShellLoader, {});
|
|
1569
|
+
return /* @__PURE__ */ jsxs(Stack, { children: [
|
|
1570
|
+
/* @__PURE__ */ jsx(
|
|
1571
|
+
PageTitleCaption,
|
|
1572
|
+
{
|
|
1573
|
+
title: "Cost Analytics",
|
|
1574
|
+
caption: "Comprehensive cost tracking, budgets, ROI analysis, and labor savings"
|
|
1575
|
+
}
|
|
1576
|
+
),
|
|
1577
|
+
/* @__PURE__ */ jsx(CostTrendChart, { data: trendsData, summaryData, isLoading: trendsLoading, error: trendsError }),
|
|
1578
|
+
/* @__PURE__ */ jsx(
|
|
1579
|
+
CostBreakdownCard,
|
|
1580
|
+
{
|
|
1581
|
+
breakdownData,
|
|
1582
|
+
summaryData,
|
|
1583
|
+
isLoading: breakdownLoading,
|
|
1584
|
+
error: breakdownError
|
|
1585
|
+
}
|
|
1586
|
+
),
|
|
1587
|
+
/* @__PURE__ */ jsx(CostByModelTable, { data: modelData, isLoading: modelLoading, error: modelError })
|
|
1588
|
+
] });
|
|
1589
|
+
}
|
|
1590
|
+
function getNavigationPath2(activity) {
|
|
1591
|
+
switch (activity.activityType) {
|
|
1592
|
+
case "workflow_execution":
|
|
1593
|
+
return `/operations/resources/workflow/${activity.entityId}`;
|
|
1594
|
+
case "agent_run":
|
|
1595
|
+
return `/operations/resources/agent/${activity.entityId}`;
|
|
1596
|
+
case "hitl_action":
|
|
1597
|
+
return "/command-queue";
|
|
1598
|
+
case "credential_change":
|
|
1599
|
+
return "/settings/credentials";
|
|
1600
|
+
case "api_key_change":
|
|
1601
|
+
return "/settings/api-keys";
|
|
1602
|
+
case "deployment_change":
|
|
1603
|
+
return "/settings/deployments";
|
|
1604
|
+
case "membership_change":
|
|
1605
|
+
return "/settings/organization";
|
|
1606
|
+
default:
|
|
1607
|
+
return null;
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
function ActivityLog({ timeRange, pageSize = PAGE_SIZE_DEFAULT, onNavigate }) {
|
|
1611
|
+
const { filters, updateFilter, resetFilters } = useActivityFilters(timeRange);
|
|
1612
|
+
const startDate = useMemo(() => {
|
|
1613
|
+
const { startDate: startDate2 } = getTimeRangeDates(timeRange);
|
|
1614
|
+
return startDate2;
|
|
1615
|
+
}, [timeRange]);
|
|
1616
|
+
const activityType = filters.activityType !== "all" ? filters.activityType : void 0;
|
|
1617
|
+
const { page, setPage, offset, totalPages } = usePaginationState(pageSize, [
|
|
1618
|
+
filters.activityType,
|
|
1619
|
+
filters.status,
|
|
1620
|
+
filters.search,
|
|
1621
|
+
timeRange
|
|
1622
|
+
]);
|
|
1623
|
+
const { data: chartData, isLoading: isChartLoading } = useActivityTrend({
|
|
1624
|
+
activityType,
|
|
1625
|
+
startDate
|
|
1626
|
+
});
|
|
1627
|
+
const tableParams = useMemo(() => {
|
|
1628
|
+
const params = {
|
|
1629
|
+
limit: pageSize,
|
|
1630
|
+
offset,
|
|
1631
|
+
startDate
|
|
1632
|
+
};
|
|
1633
|
+
if (filters.activityType && filters.activityType !== "all") {
|
|
1634
|
+
params.activityType = filters.activityType;
|
|
1635
|
+
}
|
|
1636
|
+
if (filters.status && filters.status !== "all") {
|
|
1637
|
+
params.status = filters.status;
|
|
1638
|
+
}
|
|
1639
|
+
if (filters.search?.trim()) {
|
|
1640
|
+
params.search = filters.search.trim();
|
|
1641
|
+
}
|
|
1642
|
+
return params;
|
|
1643
|
+
}, [offset, startDate, filters.activityType, filters.status, filters.search, pageSize]);
|
|
1644
|
+
const { data: tableData, isLoading: isTableLoading } = useActivities(tableParams);
|
|
1645
|
+
const total = tableData?.total ?? 0;
|
|
1646
|
+
const handleRowClick = useCallback(
|
|
1647
|
+
(activity) => {
|
|
1648
|
+
const path = getNavigationPath2(activity);
|
|
1649
|
+
if (path) {
|
|
1650
|
+
onNavigate(path);
|
|
1651
|
+
}
|
|
1652
|
+
},
|
|
1653
|
+
[onNavigate]
|
|
1654
|
+
);
|
|
1655
|
+
if (isChartLoading && isTableLoading) return /* @__PURE__ */ jsx(AppShellLoader, {});
|
|
1656
|
+
return /* @__PURE__ */ jsxs(Stack, { children: [
|
|
1657
|
+
/* @__PURE__ */ jsx(
|
|
1658
|
+
PageTitleCaption,
|
|
1659
|
+
{
|
|
1660
|
+
title: "Activity Log",
|
|
1661
|
+
caption: "Real-time activity feed with automatic updates every 30 seconds"
|
|
1662
|
+
}
|
|
1663
|
+
),
|
|
1664
|
+
/* @__PURE__ */ jsx(
|
|
1665
|
+
ActivityTrendChart,
|
|
1666
|
+
{
|
|
1667
|
+
timestamps: chartData?.timestamps ?? [],
|
|
1668
|
+
total: chartData?.total ?? 0,
|
|
1669
|
+
isLoading: isChartLoading,
|
|
1670
|
+
timeRange
|
|
1671
|
+
}
|
|
1672
|
+
),
|
|
1673
|
+
/* @__PURE__ */ jsx(Paper, { children: /* @__PURE__ */ jsxs(Stack, { children: [
|
|
1674
|
+
/* @__PURE__ */ jsx(ActivityFilters, { filters, onFilterChange: updateFilter, onReset: resetFilters }),
|
|
1675
|
+
/* @__PURE__ */ jsx(
|
|
1676
|
+
ActivityTable,
|
|
1677
|
+
{
|
|
1678
|
+
activities: tableData?.activities ?? [],
|
|
1679
|
+
isLoading: isTableLoading,
|
|
1680
|
+
onRowClick: handleRowClick
|
|
1681
|
+
}
|
|
1682
|
+
),
|
|
1683
|
+
totalPages(total) > 1 && /* @__PURE__ */ jsx(Group, { justify: "flex-start", children: /* @__PURE__ */ jsx(Pagination, { value: page, onChange: setPage, total: totalPages(total), size: "sm", boundaries: 1 }) })
|
|
1684
|
+
] }) })
|
|
1685
|
+
] });
|
|
1686
|
+
}
|
|
1687
|
+
function ActivityFeed({
|
|
1688
|
+
limit = 50,
|
|
1689
|
+
activityType,
|
|
1690
|
+
entityType,
|
|
1691
|
+
entityId,
|
|
1692
|
+
filters,
|
|
1693
|
+
clientFilters,
|
|
1694
|
+
overrideData,
|
|
1695
|
+
overrideLoading
|
|
1696
|
+
}) {
|
|
1697
|
+
const [currentLimit, setCurrentLimit] = useState(limit);
|
|
1698
|
+
const shouldFetch = !overrideData;
|
|
1699
|
+
const fetchResult = useActivities({
|
|
1700
|
+
limit: currentLimit,
|
|
1701
|
+
activityType: filters?.activityType || activityType,
|
|
1702
|
+
entityType,
|
|
1703
|
+
entityId,
|
|
1704
|
+
startDate: filters?.startDate
|
|
1705
|
+
});
|
|
1706
|
+
const data = overrideData ?? fetchResult.data;
|
|
1707
|
+
const error = shouldFetch ? fetchResult.error : null;
|
|
1708
|
+
const isLoading = overrideLoading ?? (shouldFetch ? fetchResult.isLoading : false);
|
|
1709
|
+
const handleLoadMore = () => {
|
|
1710
|
+
setCurrentLimit((prev) => prev + 50);
|
|
1711
|
+
};
|
|
1712
|
+
const filteredActivities = useMemo(() => {
|
|
1713
|
+
if (!data?.activities) return [];
|
|
1714
|
+
let filtered = data.activities;
|
|
1715
|
+
if (clientFilters?.status) {
|
|
1716
|
+
filtered = filtered.filter((activity) => activity.status === clientFilters.status);
|
|
1717
|
+
}
|
|
1718
|
+
if (clientFilters?.search) {
|
|
1719
|
+
const searchLower = clientFilters.search.toLowerCase();
|
|
1720
|
+
filtered = filtered.filter(
|
|
1721
|
+
(activity) => activity.title.toLowerCase().includes(searchLower) || activity.description?.toLowerCase().includes(searchLower) || activity.entityName?.toLowerCase().includes(searchLower)
|
|
1722
|
+
);
|
|
1723
|
+
}
|
|
1724
|
+
return filtered;
|
|
1725
|
+
}, [data?.activities, clientFilters]);
|
|
1726
|
+
if (isLoading) {
|
|
1727
|
+
return /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, { size: "md" }) });
|
|
1728
|
+
}
|
|
1729
|
+
if (error) {
|
|
1730
|
+
return /* @__PURE__ */ jsx(Alert, { icon: /* @__PURE__ */ jsx(IconInfoCircle, { size: 16 }), title: "Error loading activities", color: "red", children: /* @__PURE__ */ jsx(Text, { size: "sm", children: error instanceof Error ? error.message : "Failed to load activities" }) });
|
|
1731
|
+
}
|
|
1732
|
+
if (!filteredActivities.length) {
|
|
1733
|
+
return /* @__PURE__ */ jsx(EmptyState, { icon: IconActivity, title: "No activities found" });
|
|
1734
|
+
}
|
|
1735
|
+
const hasMore = data ? data.total > currentLimit : false;
|
|
1736
|
+
const showingCount = filteredActivities.length;
|
|
1737
|
+
const totalCount = data?.total || 0;
|
|
1738
|
+
return /* @__PURE__ */ jsxs(Stack, { children: [
|
|
1739
|
+
/* @__PURE__ */ jsx(Group, { justify: "space-between", children: /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
1740
|
+
"Showing ",
|
|
1741
|
+
showingCount,
|
|
1742
|
+
" of ",
|
|
1743
|
+
totalCount,
|
|
1744
|
+
" activities"
|
|
1745
|
+
] }) }),
|
|
1746
|
+
/* @__PURE__ */ jsx(Stack, { children: filteredActivities.map((activity) => /* @__PURE__ */ jsx(ActivityCard, { activity }, activity.id)) }),
|
|
1747
|
+
hasMore && /* @__PURE__ */ jsx(Center, { children: /* @__PURE__ */ jsx(Button, { variant: "light", onClick: handleLoadMore, loading: isLoading, children: "Load More" }) })
|
|
1748
|
+
] });
|
|
1749
|
+
}
|
|
1750
|
+
function NotificationCenter({ pageSize = 20 }) {
|
|
1751
|
+
const { page, setPage, offset, totalPages } = usePaginationState(pageSize);
|
|
1752
|
+
const { data, isLoading } = useNotifications({ limit: pageSize, offset });
|
|
1753
|
+
const notifications = data?.notifications ?? [];
|
|
1754
|
+
const markAllAsRead = useMarkAllAsRead();
|
|
1755
|
+
const testNotification = useTestNotification();
|
|
1756
|
+
const hasUnread = notifications.some((n) => !n.read);
|
|
1757
|
+
const handleMarkAllAsRead = async () => {
|
|
1758
|
+
await markAllAsRead.mutateAsync();
|
|
1759
|
+
};
|
|
1760
|
+
const handleCreateTest = async () => {
|
|
1761
|
+
await testNotification.mutateAsync();
|
|
1762
|
+
};
|
|
1763
|
+
const isDevelopment = process.env.NODE_ENV === "development";
|
|
1764
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1765
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
|
|
1766
|
+
/* @__PURE__ */ jsx(Title, { order: 1, children: "Notifications" }),
|
|
1767
|
+
/* @__PURE__ */ jsxs(Group, { gap: "sm", children: [
|
|
1768
|
+
isDevelopment && /* @__PURE__ */ jsx(
|
|
1769
|
+
Button,
|
|
1770
|
+
{
|
|
1771
|
+
variant: "light",
|
|
1772
|
+
size: "sm",
|
|
1773
|
+
leftSection: /* @__PURE__ */ jsx(IconPlus, { size: 16 }),
|
|
1774
|
+
onClick: handleCreateTest,
|
|
1775
|
+
loading: testNotification.isPending,
|
|
1776
|
+
children: "Create Test Notification"
|
|
1777
|
+
}
|
|
1778
|
+
),
|
|
1779
|
+
hasUnread && /* @__PURE__ */ jsx(Button, { variant: "light", size: "sm", onClick: handleMarkAllAsRead, loading: markAllAsRead.isPending, children: "Mark all as read" })
|
|
1780
|
+
] })
|
|
1781
|
+
] }),
|
|
1782
|
+
/* @__PURE__ */ jsx(Paper, { children: /* @__PURE__ */ jsx(NotificationList, { notifications, isLoading }) }),
|
|
1783
|
+
totalPages(data?.total ?? 0) > 1 && /* @__PURE__ */ jsx(Group, { justify: "flex-start", children: /* @__PURE__ */ jsx(Pagination, { value: page, onChange: setPage, total: totalPages(data?.total ?? 0), size: "sm", boundaries: 1 }) })
|
|
1784
|
+
] });
|
|
1785
|
+
}
|
|
1786
|
+
var monitoringManifest = {
|
|
1787
|
+
key: "monitoring",
|
|
1788
|
+
label: "Monitoring",
|
|
1789
|
+
navEntry: {
|
|
1790
|
+
label: "Monitoring",
|
|
1791
|
+
icon: IconActivity,
|
|
1792
|
+
featureKey: "monitoring",
|
|
1793
|
+
dataOnboardingTourId: "sidebar-monitoring",
|
|
1794
|
+
links: [
|
|
1795
|
+
{ label: "Activity Log", link: "/monitoring/activity-log" },
|
|
1796
|
+
{ label: "Execution Logs", link: "/monitoring/execution-logs" },
|
|
1797
|
+
{ label: "Execution Health", link: "/monitoring/execution-health" },
|
|
1798
|
+
{ label: "Cost Analytics", link: "/monitoring/cost-analytics" },
|
|
1799
|
+
{ label: "Notifications", link: "/monitoring/notifications" }
|
|
1800
|
+
]
|
|
1801
|
+
}
|
|
1802
|
+
};
|
|
1279
1803
|
|
|
1280
|
-
export { ActivityCard, ActivityFilters, ActivityTable, BusinessImpactCard, CostBreakdownCard, CostByModelTable, CostMetricsCard, ErrorAnalysisCard, ErrorBreakdownTable, ExecutionBreakdownTable, ExecutionHealthCard, ExecutionLogsFilters, ExecutionLogsTable, NotificationItem, NotificationList };
|
|
1804
|
+
export { ActivityCard, ActivityFeed, ActivityFilters, ActivityLog, ActivityTable, BusinessImpactCard, CostAnalytics, CostBreakdownCard, CostByModelTable, CostMetricsCard, ErrorAnalysisCard, ErrorBreakdownTable, ErrorDetailsModal, ExecutionBreakdownTable, ExecutionHealth, ExecutionHealthCard, ExecutionLogsFilters, ExecutionLogsPage, ExecutionLogsTable, NotificationCenter, NotificationItem, NotificationList, monitoringManifest };
|