@elevasis/ui 2.25.6 → 2.26.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/dist/api/index.js +2 -2
  2. package/dist/app/index.css +15 -5
  3. package/dist/app/index.d.ts +61 -14
  4. package/dist/app/index.js +6 -6
  5. package/dist/charts/index.js +6 -5
  6. package/dist/chunk-3MEXPLWT.js +265 -0
  7. package/dist/{chunk-BDKM56TP.js → chunk-4KTLOK7K.js} +1 -1
  8. package/dist/{chunk-KMAXFJPH.js → chunk-CW3UNAF2.js} +5 -409
  9. package/dist/{chunk-HKBEURCV.js → chunk-G26INIF3.js} +1 -1
  10. package/dist/{chunk-7F3IQMLI.js → chunk-G66QFZXD.js} +11 -214
  11. package/dist/{chunk-QIW6OCEI.js → chunk-HLFFKKT3.js} +27 -373
  12. package/dist/chunk-JDNEWB5F.js +10 -0
  13. package/dist/{chunk-L7D6KNHV.js → chunk-JKBGDFX2.js} +890 -749
  14. package/dist/{chunk-YRKQNPK2.js → chunk-JPGX3533.js} +4 -3
  15. package/dist/chunk-KEFWANZY.js +155 -0
  16. package/dist/chunk-LH4GPYDX.js +448 -0
  17. package/dist/{chunk-JXSBOG2R.js → chunk-LWKZ3BCC.js} +5 -4
  18. package/dist/chunk-MYEOTM7D.js +92 -0
  19. package/dist/chunk-OGXKOMUT.js +412 -0
  20. package/dist/chunk-OHXU5WWK.js +3731 -0
  21. package/dist/chunk-ONFKASZI.js +2004 -0
  22. package/dist/{chunk-U36X6NZM.js → chunk-RIFTUOPE.js} +2 -14
  23. package/dist/{chunk-T6INEVX6.js → chunk-SGS4CQ2B.js} +1 -1
  24. package/dist/{chunk-C7IBFI5B.js → chunk-UPMX5GJI.js} +5 -5
  25. package/dist/{chunk-ARJPZ66V.js → chunk-UY5I2KOZ.js} +208 -3124
  26. package/dist/chunk-W2ZTLH7Y.js +662 -0
  27. package/dist/{chunk-KNISO652.js → chunk-WUVR4QY6.js} +9 -9
  28. package/dist/{chunk-Q5BEODAT.js → chunk-X2SUMO3P.js} +2 -1
  29. package/dist/{chunk-SNHGSCKH.js → chunk-XBMCDGHA.js} +1 -1
  30. package/dist/{chunk-N55DVMAG.js → chunk-XQQEKWTL.js} +2 -6
  31. package/dist/{chunk-SBQ4MYQV.js → chunk-XZSEPJZQ.js} +5 -6
  32. package/dist/{chunk-CPAJXBTL.js → chunk-YHBPR67D.js} +490 -676
  33. package/dist/{chunk-QARSVM7Q.js → chunk-YO2YORW4.js} +4 -4
  34. package/dist/{chunk-TAIX4NO3.js → chunk-ZFLM2YVW.js} +2 -2
  35. package/dist/components/index.css +15 -5
  36. package/dist/components/index.d.ts +202 -383
  37. package/dist/components/index.js +43 -429
  38. package/dist/components/navigation/index.css +25 -15
  39. package/dist/execution/index.d.ts +0 -73
  40. package/dist/features/auth/index.css +25 -15
  41. package/dist/features/crm/index.css +25 -15
  42. package/dist/features/crm/index.d.ts +49 -49
  43. package/dist/features/crm/index.js +14 -15
  44. package/dist/features/dashboard/index.css +25 -15
  45. package/dist/features/dashboard/index.js +18 -16
  46. package/dist/features/delivery/index.css +15 -5
  47. package/dist/features/delivery/index.js +14 -15
  48. package/dist/features/knowledge/index.css +611 -0
  49. package/dist/features/knowledge/index.js +375 -72
  50. package/dist/features/lead-gen/index.css +25 -15
  51. package/dist/features/lead-gen/index.d.ts +60 -21
  52. package/dist/features/lead-gen/index.js +16 -16
  53. package/dist/features/monitoring/index.css +15 -5
  54. package/dist/features/monitoring/index.js +17 -17
  55. package/dist/features/monitoring/requests/index.css +25 -15
  56. package/dist/features/monitoring/requests/index.js +13 -14
  57. package/dist/features/operations/index.css +25 -15
  58. package/dist/features/operations/index.d.ts +16 -98
  59. package/dist/features/operations/index.js +26 -22
  60. package/dist/features/settings/index.css +25 -15
  61. package/dist/features/settings/index.d.ts +1 -0
  62. package/dist/features/settings/index.js +15 -16
  63. package/dist/hooks/delivery/index.css +25 -15
  64. package/dist/hooks/delivery/index.js +2 -2
  65. package/dist/hooks/index.css +15 -5
  66. package/dist/hooks/index.d.ts +172 -380
  67. package/dist/hooks/index.js +13 -14
  68. package/dist/hooks/published.css +15 -5
  69. package/dist/hooks/published.d.ts +172 -380
  70. package/dist/hooks/published.js +13 -14
  71. package/dist/index.css +15 -5
  72. package/dist/index.d.ts +988 -403
  73. package/dist/index.js +15 -15
  74. package/dist/initialization/index.d.ts +1 -0
  75. package/dist/knowledge/index.d.ts +981 -41
  76. package/dist/knowledge/index.js +5449 -294
  77. package/dist/layout/index.d.ts +2 -0
  78. package/dist/layout/index.js +3 -2
  79. package/dist/organization/index.css +25 -15
  80. package/dist/organization/index.d.ts +1 -0
  81. package/dist/provider/index.css +25 -15
  82. package/dist/provider/index.d.ts +818 -26
  83. package/dist/provider/index.js +11 -11
  84. package/dist/provider/published.css +25 -15
  85. package/dist/provider/published.d.ts +817 -25
  86. package/dist/provider/published.js +8 -9
  87. package/dist/test-utils/index.js +2 -2
  88. package/dist/test-utils/setup.js +1 -1
  89. package/dist/theme/index.js +3 -2
  90. package/dist/theme/presets/index.d.ts +97 -0
  91. package/dist/theme/presets/index.js +3 -0
  92. package/dist/types/index.d.ts +71 -126
  93. package/dist/utils/index.js +1 -1
  94. package/dist/vite/index.d.ts +7 -0
  95. package/dist/vite/index.js +10 -0
  96. package/dist/vite-plugin-knowledge/index.d.ts +1 -33
  97. package/dist/vite-plugin-knowledge/index.js +1 -66
  98. package/package.json +16 -3
  99. package/src/knowledge/README.md +8 -8
  100. package/src/theme/presets/README.md +19 -0
  101. package/dist/chunk-5RLYII6P.js +0 -314
  102. package/dist/chunk-6U7AIIHF.js +0 -880
  103. package/dist/chunk-HAEJ4M54.js +0 -94
  104. package/dist/chunk-LPM7O6XM.js +0 -293
  105. /package/dist/{chunk-SGXXJE52.js → chunk-QD4X4H5A.js} +0 -0
@@ -0,0 +1,92 @@
1
+ import { existsSync } from 'fs';
2
+ import { resolve } from 'path';
3
+ import { spawnSync } from 'child_process';
4
+ import { runKnowledgeCodegen } from '@elevasis/sdk/node';
5
+
6
+ // src/vite-plugin-knowledge/index.ts
7
+ function detectLayout(viteRoot) {
8
+ let dir = viteRoot;
9
+ for (; ; ) {
10
+ if (existsSync(resolve(dir, ".elevasis"))) {
11
+ const projectRoot = dir;
12
+ return {
13
+ mode: "external",
14
+ projectRoot,
15
+ omSourcePath: resolve(projectRoot, "core/config/organization-model.ts"),
16
+ mdxNodesDir: resolve(projectRoot, "core/config/knowledge/nodes"),
17
+ generatedDir: resolve(projectRoot, "core/config/knowledge/_generated"),
18
+ watchPaths: [
19
+ resolve(projectRoot, "core/config/knowledge/nodes"),
20
+ resolve(projectRoot, "core/config/organization-model.ts")
21
+ ]
22
+ };
23
+ }
24
+ if (existsSync(resolve(dir, "pnpm-workspace.yaml"))) {
25
+ const projectRoot = dir;
26
+ return {
27
+ mode: "monorepo",
28
+ projectRoot,
29
+ omSourcePath: resolve(projectRoot, "packages/elevasis-core/src/organization-model.ts"),
30
+ // monorepo mode does not consume mdxNodesDir; field kept for type uniformity
31
+ mdxNodesDir: resolve(projectRoot, "packages/elevasis-core/knowledge-nodes-unused"),
32
+ generatedDir: resolve(projectRoot, "packages/ui/src/knowledge/_generated"),
33
+ watchPaths: [resolve(projectRoot, "packages/elevasis-core/src/organization-model.ts")]
34
+ };
35
+ }
36
+ const parent = resolve(dir, "..");
37
+ if (parent === dir) {
38
+ throw new Error("knowledgePlugin: no '.elevasis' or 'pnpm-workspace.yaml' found above the Vite root");
39
+ }
40
+ dir = parent;
41
+ }
42
+ }
43
+ function knowledgePlugin() {
44
+ let layout;
45
+ async function runCodegen() {
46
+ if (layout.mode === "monorepo") {
47
+ const result = spawnSync(
48
+ "pnpm",
49
+ ["-C", "packages/ui", "exec", "tsx", "scripts/run-knowledge-bodies-codegen.ts"],
50
+ {
51
+ cwd: layout.projectRoot,
52
+ encoding: "utf8",
53
+ shell: process.platform === "win32"
54
+ }
55
+ );
56
+ if (result.status !== 0) {
57
+ throw new Error(result.error?.message || result.stderr || result.stdout || "knowledge codegen failed");
58
+ }
59
+ return;
60
+ }
61
+ await runKnowledgeCodegen(layout);
62
+ }
63
+ return {
64
+ name: "elevasis:knowledge",
65
+ configResolved(config) {
66
+ layout = detectLayout(config.root);
67
+ },
68
+ async buildStart() {
69
+ await runCodegen();
70
+ if (this.meta.watchMode) {
71
+ for (const p of layout.watchPaths) this.addWatchFile(p);
72
+ }
73
+ },
74
+ async handleHotUpdate({ file, server }) {
75
+ const watched = layout.watchPaths.some((p) => file === p || file.startsWith(p + "/") || file.startsWith(p + "\\"));
76
+ if (!watched) return;
77
+ try {
78
+ await runCodegen();
79
+ } catch (err) {
80
+ server.config.logger.error(`[knowledge-plugin] codegen failed: ${String(err)}`);
81
+ return;
82
+ }
83
+ const bodies = server.moduleGraph.getModuleById(resolve(layout.generatedDir, "knowledge-bodies.tsx"));
84
+ if (bodies) {
85
+ server.moduleGraph.invalidateModule(bodies);
86
+ server.hot.send({ type: "full-reload" });
87
+ }
88
+ }
89
+ };
90
+ }
91
+
92
+ export { knowledgePlugin };
@@ -0,0 +1,412 @@
1
+ import { CyberAreaChart, useCyberColors, CyberLegendItem } from './chunk-CW3UNAF2.js';
2
+ import { useErrorTrends } from './chunk-VKMNWHTL.js';
3
+ import { CardHeader, CenteredErrorState, TrendIndicator, EmptyState, StatCard } from './chunk-RIFTUOPE.js';
4
+ import { getTimeRangeLabel, getTimeRangeDates, formatBucketTime } from './chunk-QD4X4H5A.js';
5
+ import { useRef, useState, useLayoutEffect, useEffect, useMemo, useCallback } from 'react';
6
+ import { jsx, jsxs } from 'react/jsx-runtime';
7
+ import { Center, Loader, Paper, Button, Group, Text, NumberFormatter, Badge, Space, Tooltip, SimpleGrid, Alert, SegmentedControl, Box } from '@mantine/core';
8
+ import { IconActivity, IconDownload, IconChartLine, IconInfoCircle, IconApps, IconPlayerPlay, IconChartBar, IconAlertTriangle, IconRocket, IconAlertCircle } from '@tabler/icons-react';
9
+
10
+ function ChartFrame({ h, debounceMs = 150, children }) {
11
+ const ref = useRef(null);
12
+ const [width, setWidth] = useState(0);
13
+ useLayoutEffect(() => {
14
+ const el = ref.current;
15
+ if (!el) return;
16
+ const w = el.getBoundingClientRect().width;
17
+ if (w > 0) setWidth(w);
18
+ }, []);
19
+ useEffect(() => {
20
+ const el = ref.current;
21
+ if (!el) return;
22
+ let timeout;
23
+ const ro = new ResizeObserver((entries) => {
24
+ if (timeout !== void 0) window.clearTimeout(timeout);
25
+ const nextWidth = entries[0]?.contentRect.width ?? 0;
26
+ timeout = window.setTimeout(() => {
27
+ if (nextWidth > 0) setWidth(nextWidth);
28
+ }, debounceMs);
29
+ });
30
+ ro.observe(el);
31
+ return () => {
32
+ ro.disconnect();
33
+ if (timeout !== void 0) window.clearTimeout(timeout);
34
+ };
35
+ }, [debounceMs]);
36
+ return /* @__PURE__ */ jsx("div", { ref, style: { width: "100%", height: h, position: "relative" }, children: width > 0 && /* @__PURE__ */ jsx("div", { style: { width, height: h }, children }) });
37
+ }
38
+ var GRANULARITY_MAP = {
39
+ "1h": "hour",
40
+ "24h": "hour",
41
+ "7d": "day",
42
+ "30d": "day"
43
+ };
44
+ var BUCKET_CONFIG = {
45
+ "1h": { size: 5 * 60 * 1e3, count: 12 },
46
+ "24h": { size: 60 * 60 * 1e3, count: 24 },
47
+ "7d": { size: 24 * 60 * 60 * 1e3, count: 7 },
48
+ "30d": { size: 24 * 60 * 60 * 1e3, count: 30 }
49
+ };
50
+ function groupTimestampsByTime(timestamps, timeRange) {
51
+ const { size: bucketSize, count: bucketCount } = BUCKET_CONFIG[timeRange];
52
+ const granularity = GRANULARITY_MAP[timeRange];
53
+ const now = /* @__PURE__ */ new Date();
54
+ const flooredNow = new Date(now.getTime() - now.getTime() % bucketSize);
55
+ const buckets = /* @__PURE__ */ new Map();
56
+ for (let i = bucketCount - 1; i >= 0; i--) {
57
+ const bucketTime = new Date(flooredNow.getTime() - i * bucketSize);
58
+ const label = formatBucketTime(bucketTime.toISOString(), granularity);
59
+ buckets.set(label, 0);
60
+ }
61
+ timestamps.forEach((occurredAt) => {
62
+ const timeDiff = flooredNow.getTime() - occurredAt.getTime();
63
+ const bucketIndex = Math.floor(timeDiff / bucketSize);
64
+ if (bucketIndex >= 0 && bucketIndex < bucketCount) {
65
+ const bucketTime = new Date(flooredNow.getTime() - bucketIndex * bucketSize);
66
+ const label = formatBucketTime(bucketTime.toISOString(), granularity);
67
+ buckets.set(label, (buckets.get(label) || 0) + 1);
68
+ }
69
+ });
70
+ return Array.from(buckets.entries()).map(([time, count]) => ({
71
+ time,
72
+ "Activity Count": count
73
+ }));
74
+ }
75
+ function ActivityTrendChart({ timestamps, total, isLoading, timeRange }) {
76
+ const chartData = useMemo(() => {
77
+ return groupTimestampsByTime(timestamps, timeRange);
78
+ }, [timestamps, timeRange]);
79
+ if (isLoading) {
80
+ return /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) });
81
+ }
82
+ return /* @__PURE__ */ jsxs(Paper, { withBorder: true, children: [
83
+ /* @__PURE__ */ jsx(
84
+ CardHeader,
85
+ {
86
+ icon: /* @__PURE__ */ jsx(IconActivity, { size: 18 }),
87
+ title: "Activity Trend",
88
+ subtitle: `${total} activities in ${getTimeRangeLabel(timeRange)}`
89
+ }
90
+ ),
91
+ /* @__PURE__ */ jsx(
92
+ CyberAreaChart,
93
+ {
94
+ data: chartData,
95
+ series: [{ dataKey: "Activity Count", color: "blue" }],
96
+ height: 200,
97
+ yAxisLabel: "Count",
98
+ yDomain: [0, "auto"]
99
+ }
100
+ )
101
+ ] });
102
+ }
103
+ function formatDollar(value) {
104
+ return `$${value.toFixed(2)}`;
105
+ }
106
+ function CostTrendChart({ data, summaryData, isLoading, error }) {
107
+ const todayCost = summaryData?.current.totalCostUsd ?? 0;
108
+ const previousCost = summaryData?.previous.totalCostUsd ?? 0;
109
+ const mtdCost = summaryData?.mtd.totalCostUsd ?? 0;
110
+ const projectedMonthlyCost = summaryData?.projection.monthlyCostUsd ?? 0;
111
+ const confidence = summaryData?.projection.confidence ?? "low";
112
+ const budget = 1500;
113
+ const budgetStatus = projectedMonthlyCost <= budget ? "green" : projectedMonthlyCost <= budget * 1.1 ? "yellow" : "red";
114
+ const budgetLabel = projectedMonthlyCost <= budget ? "On Budget" : projectedMonthlyCost <= budget * 1.1 ? "Warning" : "Over Budget";
115
+ const chartData = data?.trendData.map((point) => {
116
+ const date = new Date(point.time);
117
+ const timeLabel = data.granularity === "hour" ? date.toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit" }) : date.toLocaleDateString("en-US", { month: "short", day: "numeric" });
118
+ return {
119
+ time: timeLabel,
120
+ "Total Cost": point.totalCostUsd
121
+ };
122
+ }) ?? [];
123
+ const handleExport = () => {
124
+ if (!data) return;
125
+ const csvContent = [
126
+ ["Time", "Total Cost ($)", "Executions", "Avg Cost/Execution ($)"],
127
+ ...data.trendData.map((d) => [
128
+ d.time,
129
+ d.totalCostUsd.toFixed(4),
130
+ d.executionCount,
131
+ d.avgCostPerExecution.toFixed(4)
132
+ ])
133
+ ].map((row) => row.join(",")).join("\n");
134
+ const blob = new Blob([csvContent], { type: "text/csv" });
135
+ const url = URL.createObjectURL(blob);
136
+ const link = document.createElement("a");
137
+ link.href = url;
138
+ link.download = `cost-trends-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.csv`;
139
+ link.click();
140
+ URL.revokeObjectURL(url);
141
+ };
142
+ if (error) {
143
+ return /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsx(CenteredErrorState, { error, title: "Failed to load cost trends" }) });
144
+ }
145
+ if (isLoading) {
146
+ return /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) }) });
147
+ }
148
+ const granularityLabel = data?.granularity === "hour" ? "Hourly" : "Daily";
149
+ return /* @__PURE__ */ jsxs(Paper, { withBorder: true, children: [
150
+ /* @__PURE__ */ jsx(
151
+ CardHeader,
152
+ {
153
+ icon: /* @__PURE__ */ jsx(IconChartLine, { size: 18 }),
154
+ title: `Cost Trend (${granularityLabel})`,
155
+ rightSection: /* @__PURE__ */ jsx(Button, { variant: "subtle", size: "xs", leftSection: /* @__PURE__ */ jsx(IconDownload, { size: 14 }), onClick: handleExport, children: "Export CSV" })
156
+ }
157
+ ),
158
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "center", mb: "md", children: [
159
+ /* @__PURE__ */ jsxs(Group, { gap: "lg", children: [
160
+ /* @__PURE__ */ jsxs(Group, { gap: 6, align: "baseline", children: [
161
+ /* @__PURE__ */ jsx(Text, { size: "xl", fw: 700, style: { fontFamily: "var(--mantine-font-family-headings)" }, children: /* @__PURE__ */ jsx(NumberFormatter, { prefix: "$", value: todayCost, decimalScale: 2 }) }),
162
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "period" }),
163
+ /* @__PURE__ */ jsx(TrendIndicator, { current: todayCost, previous: previousCost, inverse: true })
164
+ ] }),
165
+ /* @__PURE__ */ jsxs(Group, { gap: 6, align: "baseline", children: [
166
+ /* @__PURE__ */ jsx(Text, { size: "xl", fw: 700, style: { fontFamily: "var(--mantine-font-family-headings)" }, children: /* @__PURE__ */ jsx(NumberFormatter, { prefix: "$", value: mtdCost, thousandSeparator: true, decimalScale: 2 }) }),
167
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "MTD" })
168
+ ] })
169
+ ] }),
170
+ /* @__PURE__ */ jsx(Badge, { size: "md", variant: "dot", color: budgetStatus, children: budgetLabel })
171
+ ] }),
172
+ chartData.length > 0 ? /* @__PURE__ */ jsx(
173
+ CyberAreaChart,
174
+ {
175
+ data: chartData,
176
+ series: [{ dataKey: "Total Cost", color: "blue", name: "Total Cost" }],
177
+ height: 200,
178
+ yDomain: [0, (max) => Math.max(max * 1.1, 0.01)],
179
+ yTickFormatter: formatDollar,
180
+ tooltipFormatter: formatDollar,
181
+ baselineColor: "blue"
182
+ }
183
+ ) : /* @__PURE__ */ jsx(EmptyState, { icon: IconChartLine, title: "No cost data available for this time period" }),
184
+ /* @__PURE__ */ jsx(Space, { h: "lg" }),
185
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
186
+ /* @__PURE__ */ jsxs(Group, { gap: 4, children: [
187
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
188
+ "Projected monthly:",
189
+ " ",
190
+ /* @__PURE__ */ jsx(NumberFormatter, { prefix: "$", value: projectedMonthlyCost, thousandSeparator: true, decimalScale: 2 })
191
+ ] }),
192
+ /* @__PURE__ */ jsx(Tooltip, { label: `Projection confidence: ${confidence}`, children: /* @__PURE__ */ jsx(IconInfoCircle, { size: 12, color: "var(--color-text-subtle)" }) })
193
+ ] }),
194
+ /* @__PURE__ */ jsxs(
195
+ Text,
196
+ {
197
+ size: "xs",
198
+ fw: 600,
199
+ c: projectedMonthlyCost > budget ? "red" : "dimmed",
200
+ style: { fontFamily: "var(--mantine-font-family-headings)" },
201
+ children: [
202
+ "Budget: ",
203
+ /* @__PURE__ */ jsx(NumberFormatter, { prefix: "$", value: budget, thousandSeparator: true, decimalScale: 2 })
204
+ ]
205
+ }
206
+ )
207
+ ] })
208
+ ] });
209
+ }
210
+ var EM_DASH = "\u2014";
211
+ function getSuccessRateColor(rate) {
212
+ if (rate >= 95) return "var(--mantine-color-teal-6)";
213
+ if (rate >= 80) return "var(--mantine-color-yellow-6)";
214
+ return "var(--mantine-color-red-6)";
215
+ }
216
+ function getErrorCountColor(count) {
217
+ if (count === 0) return "var(--mantine-color-teal-6)";
218
+ if (count <= 5) return "var(--mantine-color-yellow-6)";
219
+ return "var(--mantine-color-red-6)";
220
+ }
221
+ function HeroStatsRow({
222
+ resourcesData,
223
+ resourcesLoading,
224
+ dashboardData,
225
+ dashboardLoading,
226
+ unresolvedErrorCount,
227
+ errorsLoading
228
+ }) {
229
+ const health = dashboardData?.executionHealth;
230
+ const resourceCount = resourcesData?.total ?? null;
231
+ const totalExecutions = health?.totalExecutions ?? null;
232
+ const successRate = totalExecutions ? health?.successRate ?? null : null;
233
+ return /* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 2, sm: 5 }, children: [
234
+ /* @__PURE__ */ jsx(
235
+ StatCard,
236
+ {
237
+ variant: "hero",
238
+ icon: IconApps,
239
+ value: resourceCount ?? EM_DASH,
240
+ label: "Resources",
241
+ isLoading: resourcesLoading
242
+ }
243
+ ),
244
+ /* @__PURE__ */ jsx(
245
+ StatCard,
246
+ {
247
+ variant: "hero",
248
+ icon: IconPlayerPlay,
249
+ value: totalExecutions ?? EM_DASH,
250
+ label: "Executions",
251
+ isLoading: dashboardLoading
252
+ }
253
+ ),
254
+ /* @__PURE__ */ jsx(
255
+ StatCard,
256
+ {
257
+ variant: "hero",
258
+ icon: IconChartBar,
259
+ value: successRate != null ? `${Math.round(successRate)}%` : EM_DASH,
260
+ label: "Success Rate",
261
+ valueColor: successRate != null ? getSuccessRateColor(successRate) : void 0,
262
+ isLoading: dashboardLoading
263
+ }
264
+ ),
265
+ /* @__PURE__ */ jsx(
266
+ StatCard,
267
+ {
268
+ variant: "hero",
269
+ icon: IconAlertTriangle,
270
+ value: errorsLoading ? EM_DASH : unresolvedErrorCount ?? EM_DASH,
271
+ label: "Errors",
272
+ valueColor: unresolvedErrorCount != null ? getErrorCountColor(unresolvedErrorCount) : void 0
273
+ }
274
+ ),
275
+ /* @__PURE__ */ jsx(
276
+ StatCard,
277
+ {
278
+ variant: "hero",
279
+ icon: IconRocket,
280
+ value: dashboardData?.activeDeploymentVersion ?? EM_DASH,
281
+ label: "Deployment",
282
+ isLoading: dashboardLoading
283
+ }
284
+ )
285
+ ] });
286
+ }
287
+ function getGranularityFromTimeRange(timeRange) {
288
+ return ["1h", "24h"].includes(timeRange) ? "hour" : "day";
289
+ }
290
+ function formatPeakPeriod(peakPeriod, granularity) {
291
+ if (!peakPeriod) return "N/A";
292
+ const date = new Date(peakPeriod);
293
+ if (granularity === "hour") {
294
+ return date.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit", hour12: true });
295
+ } else {
296
+ return date.toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric" });
297
+ }
298
+ }
299
+ function CombinedTrendChart({
300
+ healthData,
301
+ errorData: _errorData,
302
+ isLoading,
303
+ error,
304
+ timeRange,
305
+ navigationAction
306
+ }) {
307
+ const [activeTab, setActiveTab] = useState("success");
308
+ const colors = useCyberColors();
309
+ const { startDate: start, endDate: end } = useMemo(() => getTimeRangeDates(timeRange), [timeRange]);
310
+ const granularity = getGranularityFromTimeRange(timeRange);
311
+ const { data: errorTrends } = useErrorTrends({
312
+ startDate: start,
313
+ endDate: end,
314
+ granularity
315
+ });
316
+ const xTickFormatter = useCallback((value) => formatBucketTime(value, granularity), [granularity]);
317
+ if (error) {
318
+ return /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsx(CenteredErrorState, { error, title: "Failed to load trend data" }) });
319
+ }
320
+ if (isLoading) {
321
+ return /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) }) });
322
+ }
323
+ const errorTrendsMap = new Map(errorTrends?.map((trend) => [trend.time, trend.errorCount]) || []);
324
+ const successErrorData = healthData?.trendData.length ? healthData.trendData.map((d) => {
325
+ const errorCount = errorTrendsMap.get(d.time) || 0;
326
+ return {
327
+ time: d.time,
328
+ "Success Count": d.successCount,
329
+ "Error Count": errorCount
330
+ };
331
+ }) : [];
332
+ const throughputData = healthData?.trendData.length ? healthData.trendData.map((d) => ({
333
+ time: d.time,
334
+ Executions: d.executionCount
335
+ })) : [];
336
+ const totalExecutions = healthData?.totalExecutions ?? 0;
337
+ const peakPeriod = healthData?.peakPeriod ?? "";
338
+ const dataGranularity = healthData?.granularity ?? granularity;
339
+ if (!successErrorData.length) {
340
+ return /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsx(Center, { h: 300, children: /* @__PURE__ */ jsx(Alert, { icon: /* @__PURE__ */ jsx(IconAlertCircle, {}), color: "gray", variant: "light", children: "No trend data available for the selected time range" }) }) });
341
+ }
342
+ return /* @__PURE__ */ jsxs(Paper, { withBorder: true, children: [
343
+ /* @__PURE__ */ jsx(
344
+ CardHeader,
345
+ {
346
+ icon: /* @__PURE__ */ jsx(IconChartLine, { size: 18 }),
347
+ title: "Execution Trends",
348
+ subtitle: `${getTimeRangeLabel(timeRange)} - ${dataGranularity === "hour" ? "Hourly" : "Daily"} data`,
349
+ rightSection: /* @__PURE__ */ jsxs(Group, { gap: "sm", children: [
350
+ /* @__PURE__ */ jsx(
351
+ SegmentedControl,
352
+ {
353
+ value: activeTab ?? "success",
354
+ onChange: setActiveTab,
355
+ size: "xs",
356
+ data: [
357
+ { label: "Success & Errors", value: "success" },
358
+ { label: "Throughput", value: "throughput" }
359
+ ]
360
+ }
361
+ ),
362
+ navigationAction
363
+ ] })
364
+ }
365
+ ),
366
+ activeTab === "success" && /* @__PURE__ */ jsxs(Box, { style: { height: 280 }, children: [
367
+ /* @__PURE__ */ jsxs(Group, { gap: "lg", justify: "center", mb: "xs", h: 24, align: "center", children: [
368
+ /* @__PURE__ */ jsx(CyberLegendItem, { color: colors.green, label: "Success Count" }),
369
+ /* @__PURE__ */ jsx(CyberLegendItem, { color: colors.red, label: "Error Count" })
370
+ ] }),
371
+ /* @__PURE__ */ jsx(
372
+ CyberAreaChart,
373
+ {
374
+ data: successErrorData,
375
+ series: [
376
+ { dataKey: "Error Count", color: "red" },
377
+ { dataKey: "Success Count", color: "green", animationDuration: 1400 }
378
+ ],
379
+ height: 250,
380
+ yAxisLabel: "Count",
381
+ baselineColor: "green",
382
+ xTickFormatter
383
+ }
384
+ )
385
+ ] }),
386
+ activeTab === "throughput" && /* @__PURE__ */ jsxs(Box, { style: { height: 280 }, children: [
387
+ /* @__PURE__ */ jsxs(Group, { gap: "lg", justify: "center", mb: "xs", h: 24, align: "center", children: [
388
+ /* @__PURE__ */ jsxs(Group, { gap: 6, children: [
389
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, style: { color: colors.blue, fontVariantNumeric: "tabular-nums" }, children: totalExecutions.toLocaleString() }),
390
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "executions" })
391
+ ] }),
392
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "|" }),
393
+ /* @__PURE__ */ jsxs(Group, { gap: 6, children: [
394
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "peak" }),
395
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, style: { color: colors.blue, fontVariantNumeric: "tabular-nums" }, children: formatPeakPeriod(peakPeriod, dataGranularity) })
396
+ ] }),
397
+ /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "dot", color: "green", children: "Normal" })
398
+ ] }),
399
+ /* @__PURE__ */ jsx(
400
+ CyberAreaChart,
401
+ {
402
+ data: throughputData,
403
+ series: [{ dataKey: "Executions", color: "blue" }],
404
+ height: 250,
405
+ xTickFormatter
406
+ }
407
+ )
408
+ ] })
409
+ ] });
410
+ }
411
+
412
+ export { ActivityTrendChart, ChartFrame, CombinedTrendChart, CostTrendChart, HeroStatsRow };