@elevasis/ui 1.19.0 → 1.20.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 (94) hide show
  1. package/dist/api/index.js +2 -2
  2. package/dist/auth/index.js +3 -3
  3. package/dist/charts/index.css +14 -0
  4. package/dist/charts/index.js +8 -6
  5. package/dist/{chunk-7ATCF6UL.js → chunk-3DIU726S.js} +11 -4
  6. package/dist/chunk-4SY4EQSK.js +68 -0
  7. package/dist/{chunk-2Z7LYTIX.js → chunk-AQ5MQDSS.js} +30 -17
  8. package/dist/chunk-AWMZCYKH.js +639 -0
  9. package/dist/{chunk-BVNAC4SQ.js → chunk-C7AD6N23.js} +38 -48
  10. package/dist/{chunk-ZFCG5SHW.js → chunk-COTI2QPO.js} +1 -1
  11. package/dist/{chunk-WAPZN2U3.js → chunk-EMN755L5.js} +7 -41
  12. package/dist/{chunk-LBY7FVFD.js → chunk-ERVB3QJQ.js} +31 -715
  13. package/dist/chunk-GBMNCNHX.js +105 -0
  14. package/dist/{chunk-MBZDE6UT.js → chunk-IOKL7BKE.js} +9 -1
  15. package/dist/{chunk-35UWYH2A.js → chunk-JFRG2JJE.js} +8 -2
  16. package/dist/chunk-JIABC3AE.js +2622 -0
  17. package/dist/chunk-JZEXFQ6N.js +671 -0
  18. package/dist/chunk-LGKLC5MG.js +44 -0
  19. package/dist/chunk-MG3NF7QL.js +63 -0
  20. package/dist/{chunk-KBLGVZBD.js → chunk-NNKKBSJN.js} +2 -22
  21. package/dist/{chunk-JNBHUCKW.js → chunk-NVOCKXUQ.js} +1 -1
  22. package/dist/chunk-OFAXUZPZ.js +2411 -0
  23. package/dist/chunk-PDHTXPSF.js +12 -0
  24. package/dist/chunk-QJ2S46NI.js +23 -0
  25. package/dist/{chunk-NUULWBAD.js → chunk-R3R367QY.js} +1 -1
  26. package/dist/{chunk-UANJP5P7.js → chunk-R7WLWGPO.js} +5 -5
  27. package/dist/{chunk-CC3SDRIF.js → chunk-RWQIFKMJ.js} +1 -1
  28. package/dist/chunk-UMFPUM7Q.js +1281 -0
  29. package/dist/{chunk-KNJKCD73.js → chunk-VLTVZXP6.js} +4 -4
  30. package/dist/chunk-WWEMNIHW.js +37 -0
  31. package/dist/{chunk-UTWJZEOJ.js → chunk-XOTN3X3Z.js} +3 -3
  32. package/dist/components/index.css +14 -0
  33. package/dist/components/index.d.ts +41 -7
  34. package/dist/components/index.js +564 -5023
  35. package/dist/components/navigation/index.js +2 -63
  36. package/dist/features/auth/index.css +579 -0
  37. package/dist/features/auth/index.d.ts +2557 -0
  38. package/dist/features/auth/index.js +125 -0
  39. package/dist/features/dashboard/index.css +579 -0
  40. package/dist/features/dashboard/index.d.ts +244 -0
  41. package/dist/features/dashboard/index.js +650 -0
  42. package/dist/features/monitoring/index.css +579 -0
  43. package/dist/features/monitoring/index.d.ts +121 -0
  44. package/dist/features/monitoring/index.js +538 -0
  45. package/dist/features/operations/index.css +14 -0
  46. package/dist/features/operations/index.d.ts +1675 -2
  47. package/dist/features/operations/index.js +2148 -28
  48. package/dist/features/settings/index.css +579 -0
  49. package/dist/features/settings/index.d.ts +2589 -0
  50. package/dist/features/settings/index.js +1437 -0
  51. package/dist/hooks/index.css +14 -0
  52. package/dist/hooks/index.d.ts +29 -11
  53. package/dist/hooks/index.js +13 -13
  54. package/dist/hooks/published.css +14 -0
  55. package/dist/hooks/published.d.ts +29 -11
  56. package/dist/hooks/published.js +12 -12
  57. package/dist/index.css +14 -0
  58. package/dist/index.d.ts +41 -12
  59. package/dist/index.js +15 -15
  60. package/dist/initialization/index.js +2 -2
  61. package/dist/layout/index.d.ts +7 -1
  62. package/dist/layout/index.js +7 -5
  63. package/dist/organization/index.js +2 -2
  64. package/dist/provider/index.css +14 -0
  65. package/dist/provider/index.d.ts +1 -1
  66. package/dist/provider/index.js +10 -10
  67. package/dist/provider/published.d.ts +1 -1
  68. package/dist/provider/published.js +6 -6
  69. package/dist/theme/index.d.ts +1 -1
  70. package/dist/theme/index.js +3 -3
  71. package/dist/theme/presets/__tests__/getPreset.test.d.ts +2 -0
  72. package/dist/theme/presets/__tests__/getPreset.test.d.ts.map +1 -0
  73. package/dist/theme/presets/__tests__/getPreset.test.js +92 -0
  74. package/dist/theme/presets/cyber-volt.d.ts +12 -0
  75. package/dist/theme/presets/cyber-volt.d.ts.map +1 -0
  76. package/dist/theme/presets/cyber-volt.js +70 -0
  77. package/dist/theme/presets/regal.d.ts +8 -0
  78. package/dist/theme/presets/regal.d.ts.map +1 -0
  79. package/dist/theme/presets/regal.js +69 -0
  80. package/dist/theme/presets/rose-gold.d.ts +12 -0
  81. package/dist/theme/presets/rose-gold.d.ts.map +1 -0
  82. package/dist/theme/presets/rose-gold.js +76 -0
  83. package/dist/types/index.d.ts +1 -1
  84. package/dist/utils/index.d.ts +12 -1
  85. package/dist/utils/index.js +1 -1
  86. package/dist/zustand/index.d.ts +80 -0
  87. package/dist/zustand/index.js +105 -0
  88. package/package.json +55 -4
  89. package/dist/chunk-2YW3LDFT.js +0 -1542
  90. package/dist/theme/presets/cyber-void.d.ts +0 -12
  91. package/dist/theme/presets/cyber-void.d.ts.map +0 -1
  92. package/dist/theme/presets/cyber-void.js +0 -75
  93. package/dist/{chunk-DVKEEY5J.js → chunk-TUXTSEAF.js} +1 -1
  94. package/dist/{chunk-U2522LSW.js → chunk-V7XHGJQZ.js} +1 -1
@@ -0,0 +1,639 @@
1
+ import { ResourceStatusColors } from './chunk-ELJIFLCB.js';
2
+ import { getErrorInfo, getErrorTitle, getResourceIcon } from './chunk-IOKL7BKE.js';
3
+ import { useAuthContext } from './chunk-BRJ3QZ4E.js';
4
+ import { useRouterContext } from './chunk-Q7DJKLEN.js';
5
+ import { Center, Stack, Title, Text, Button, Box, Loader, Badge, Group, Collapse, ScrollArea, Card, Skeleton, Select, Alert, Code, ThemeIcon, Paper, Space } from '@mantine/core';
6
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
+ import { IconMinus, IconTrendingUp, IconTrendingDown, IconChevronUp, IconChevronDown, IconAlertCircle, IconClock, IconInfoCircle, IconChevronRight } from '@tabler/icons-react';
8
+ import { useState } from 'react';
9
+ import Markdown from 'react-markdown';
10
+ import { Prism } from 'react-syntax-highlighter';
11
+ import { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism';
12
+
13
+ function EmptyState({ icon: Icon, title, description, action, py = "xl" }) {
14
+ return /* @__PURE__ */ jsx(Center, { py, children: /* @__PURE__ */ jsxs(Stack, { align: "center", gap: "xs", children: [
15
+ /* @__PURE__ */ jsx(Icon, { size: 48, style: { opacity: 0.5 } }),
16
+ /* @__PURE__ */ jsx(Title, { order: 4, children: title }),
17
+ description && /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", ta: "center", children: description }),
18
+ action && /* @__PURE__ */ jsx(Button, { variant: "light", onClick: action.onClick, leftSection: action.icon, mt: "sm", children: action.label })
19
+ ] }) });
20
+ }
21
+ function TabCountBadge({ count, isLoading }) {
22
+ return /* @__PURE__ */ jsx(Box, { miw: 20, h: 20, style: { display: "flex", alignItems: "center", justifyContent: "center" }, children: isLoading ? /* @__PURE__ */ jsx(Loader, { size: 12 }) : /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", circle: count < 10, children: count }) });
23
+ }
24
+ function TrendIndicator({ current, previous, inverse }) {
25
+ const change = previous === 0 ? 0 : (current - previous) / previous * 100;
26
+ const isPositive = inverse ? change < 0 : change > 0;
27
+ const isFlat = Math.abs(change) < 0.1;
28
+ const color = isFlat ? "gray" : isPositive ? "green" : "red";
29
+ const Icon = isFlat ? IconMinus : change > 0 ? IconTrendingUp : IconTrendingDown;
30
+ return /* @__PURE__ */ jsxs(Group, { gap: 4, children: [
31
+ /* @__PURE__ */ jsx(Icon, { size: 12 }),
32
+ /* @__PURE__ */ jsx(Badge, { size: "sm", color, variant: "light", children: isFlat ? "No change" : `${isPositive ? "+" : ""}${Math.abs(change).toFixed(1)}%` })
33
+ ] });
34
+ }
35
+ function CollapsibleSection({
36
+ title,
37
+ count,
38
+ countLabel,
39
+ children,
40
+ emptyMessage,
41
+ defaultExpanded = true,
42
+ maxHeight = 300
43
+ }) {
44
+ const [expanded, setExpanded] = useState(defaultExpanded);
45
+ const isEmpty = count === 0;
46
+ return /* @__PURE__ */ jsxs(
47
+ "div",
48
+ {
49
+ style: {
50
+ borderRadius: "8px",
51
+ padding: "8px",
52
+ border: "1px solid var(--color-border)",
53
+ boxShadow: "var(--standard-box-shadow)"
54
+ },
55
+ children: [
56
+ /* @__PURE__ */ jsxs(
57
+ Group,
58
+ {
59
+ gap: "xs",
60
+ mb: expanded ? "xs" : 0,
61
+ justify: "space-between",
62
+ align: "center",
63
+ style: { cursor: "pointer" },
64
+ onClick: () => setExpanded(!expanded),
65
+ children: [
66
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", align: "center", style: { flex: 1 }, children: [
67
+ typeof title === "string" ? /* @__PURE__ */ jsx(
68
+ Text,
69
+ {
70
+ fw: 600,
71
+ size: "sm",
72
+ c: "var(--color-text)",
73
+ style: { fontFamily: "var(--elevasis-font-family-subtitle)" },
74
+ children: title
75
+ }
76
+ ) : title,
77
+ count !== void 0 && countLabel && /* @__PURE__ */ jsxs(Badge, { size: "sm", variant: "light", color: "gray", children: [
78
+ count,
79
+ " ",
80
+ count === 1 ? countLabel.replace(/s$/, "") : countLabel
81
+ ] })
82
+ ] }),
83
+ expanded ? /* @__PURE__ */ jsx(IconChevronUp, { size: 16 }) : /* @__PURE__ */ jsx(IconChevronDown, { size: 16 })
84
+ ]
85
+ }
86
+ ),
87
+ /* @__PURE__ */ jsx(Collapse, { in: expanded, children: isEmpty && emptyMessage ? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: emptyMessage }) : /* @__PURE__ */ jsx(ScrollArea, { h: maxHeight, type: "scroll", offsetScrollbars: true, children }) })
88
+ ]
89
+ }
90
+ );
91
+ }
92
+ var PageTitleCaption = ({ title, caption, rightSection }) => {
93
+ const renderCaption = () => {
94
+ if (!caption) return null;
95
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Text, { c: "dimmed", style: { fontFamily: "var(--elevasis-font-family-subtitle)" }, children: caption }) });
96
+ };
97
+ const titleContent = /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column" }, children: [
98
+ /* @__PURE__ */ jsx(Title, { order: 1, children: title }),
99
+ /* @__PURE__ */ jsx(Space, { h: "4" }),
100
+ renderCaption()
101
+ ] });
102
+ if (!rightSection) {
103
+ return titleContent;
104
+ }
105
+ return /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "end", children: [
106
+ titleContent,
107
+ rightSection
108
+ ] });
109
+ };
110
+ function StatsCardSkeleton({ chartHeight = 120, withChart = true, statCount = 3 }) {
111
+ return /* @__PURE__ */ jsxs(Card, { withBorder: true, children: [
112
+ /* @__PURE__ */ jsx(Skeleton, { height: 24, width: 150, mb: "md" }),
113
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: "xl", children: [
114
+ /* @__PURE__ */ jsx(Skeleton, { height: 60, width: 100 }),
115
+ statCount >= 2 && /* @__PURE__ */ jsx(Skeleton, { height: 60, width: 100 }),
116
+ /* @__PURE__ */ jsx(Skeleton, { height: 40, circle: true })
117
+ ] }),
118
+ withChart && /* @__PURE__ */ jsx(Skeleton, { height: chartHeight })
119
+ ] });
120
+ }
121
+ function ListSkeleton({ rows = 3, rowHeight = 50 }) {
122
+ return /* @__PURE__ */ jsx(Stack, { gap: "xs", children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx(Skeleton, { height: rowHeight }, i)) });
123
+ }
124
+ function DetailCardSkeleton({ rows = 3 }) {
125
+ return /* @__PURE__ */ jsxs(Card, { withBorder: true, children: [
126
+ /* @__PURE__ */ jsx(Skeleton, { height: 24, width: 150, mb: "md" }),
127
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: "lg", children: [
128
+ /* @__PURE__ */ jsx(Skeleton, { height: 80, width: 100 }),
129
+ /* @__PURE__ */ jsx(Skeleton, { height: 80, width: 100 }),
130
+ /* @__PURE__ */ jsx(Skeleton, { height: 40, circle: true })
131
+ ] }),
132
+ /* @__PURE__ */ jsx(Stack, { gap: "xs", children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx(Skeleton, { height: 60 }, i)) })
133
+ ] });
134
+ }
135
+ function CustomSelector({
136
+ value,
137
+ onChange,
138
+ data,
139
+ leftSection,
140
+ placeholder,
141
+ w,
142
+ withCheckIcon = false,
143
+ disabled
144
+ }) {
145
+ return /* @__PURE__ */ jsx(
146
+ Select,
147
+ {
148
+ value,
149
+ onChange,
150
+ data,
151
+ leftSection,
152
+ placeholder,
153
+ w,
154
+ size: "xs",
155
+ variant: "unstyled",
156
+ withCheckIcon,
157
+ disabled,
158
+ styles: {
159
+ wrapper: {
160
+ border: "1px solid var(--color-border)",
161
+ borderRadius: "var(--mantine-radius-default)",
162
+ backgroundColor: "var(--color-surface)",
163
+ transition: "border-color 150ms ease, background-color 150ms ease",
164
+ "&:hover": {
165
+ borderColor: "var(--color-border-hover, var(--mantine-color-dark-3))"
166
+ }
167
+ },
168
+ input: {
169
+ fontSize: "var(--mantine-font-size-xs)",
170
+ fontWeight: 500,
171
+ height: "30px",
172
+ minHeight: "30px",
173
+ paddingLeft: leftSection ? "30px" : void 0,
174
+ borderRadius: "var(--mantine-radius-default)",
175
+ cursor: "pointer"
176
+ },
177
+ section: {
178
+ color: "var(--color-text-subtle)"
179
+ },
180
+ dropdown: {
181
+ border: "1px solid var(--color-border)",
182
+ backgroundColor: "var(--color-surface)",
183
+ boxShadow: "var(--card-shadow)"
184
+ },
185
+ option: {
186
+ fontSize: "var(--mantine-font-size-xs)"
187
+ }
188
+ }
189
+ }
190
+ );
191
+ }
192
+ function APIErrorAlert({
193
+ error,
194
+ title,
195
+ showRequestId = true,
196
+ icon = /* @__PURE__ */ jsx(IconAlertCircle, {}),
197
+ color = "red"
198
+ }) {
199
+ const { message, code, requestId, retryAfter } = getErrorInfo(error);
200
+ const alertTitle = title || getErrorTitle(code);
201
+ return /* @__PURE__ */ jsxs(Alert, { icon, title: alertTitle, color, variant: "light", children: [
202
+ /* @__PURE__ */ jsx(Text, { size: "sm", children: message }),
203
+ retryAfter && /* @__PURE__ */ jsxs(Text, { size: "sm", mt: "xs", children: [
204
+ "Please wait ",
205
+ retryAfter,
206
+ " seconds before retrying."
207
+ ] }),
208
+ showRequestId && requestId && /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", mt: "xs", children: [
209
+ "Request ID: ",
210
+ /* @__PURE__ */ jsx(Code, { children: requestId })
211
+ ] })
212
+ ] });
213
+ }
214
+
215
+ // src/components/display/StatCard.module.css.js
216
+ var StatCard_module_css_default = { "heroCard": "heroCard", "iconRing": "iconRing", "iconRingSm": "iconRingSm", "heroValue": "heroValue", "heroValueSm": "heroValueSm", "heroLabel": "heroLabel", "heroLabelSm": "heroLabelSm" };
217
+ function StatCard(props) {
218
+ if (props.variant === "hero") {
219
+ return /* @__PURE__ */ jsx(HeroStatCard, { ...props });
220
+ }
221
+ const { label, value, icon: IconComponent, color } = props;
222
+ return /* @__PURE__ */ jsx(Card, { withBorder: true, children: /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
223
+ /* @__PURE__ */ jsx(ThemeIcon, { size: "lg", variant: "light", color, children: /* @__PURE__ */ jsx(IconComponent, { size: 18 }) }),
224
+ /* @__PURE__ */ jsxs("div", { children: [
225
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: label }),
226
+ /* @__PURE__ */ jsx(Text, { size: "lg", fw: 600, style: { fontFamily: "var(--elevasis-font-family-subtitle)" }, children: value })
227
+ ] })
228
+ ] }) });
229
+ }
230
+ function HeroStatCard({
231
+ icon: IconComponent,
232
+ value,
233
+ label,
234
+ valueColor,
235
+ isLoading,
236
+ size = "sm",
237
+ children
238
+ }) {
239
+ const sm = size === "sm";
240
+ const iconSize = sm ? 36 : 46;
241
+ if (isLoading) {
242
+ return /* @__PURE__ */ jsx(Paper, { p: sm ? "md" : "lg", className: StatCard_module_css_default.heroCard, children: /* @__PURE__ */ jsxs(Group, { gap: sm ? "sm" : "md", wrap: "nowrap", children: [
243
+ /* @__PURE__ */ jsx(Skeleton, { circle: true, height: iconSize }),
244
+ /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
245
+ /* @__PURE__ */ jsx(Skeleton, { height: sm ? 24 : 32, width: 60 }),
246
+ /* @__PURE__ */ jsx(Skeleton, { height: 12, width: 80 })
247
+ ] })
248
+ ] }) });
249
+ }
250
+ return /* @__PURE__ */ jsx(Paper, { p: sm ? "md" : "lg", className: StatCard_module_css_default.heroCard, children: /* @__PURE__ */ jsxs(Group, { gap: sm ? "sm" : "md", wrap: "nowrap", children: [
251
+ /* @__PURE__ */ jsx("div", { className: sm ? StatCard_module_css_default.iconRingSm : StatCard_module_css_default.iconRing, children: /* @__PURE__ */ jsx(IconComponent, { size: sm ? 18 : 22 }) }),
252
+ /* @__PURE__ */ jsxs(Stack, { gap: 2, style: { flex: children ? 1 : void 0 }, children: [
253
+ /* @__PURE__ */ jsx(
254
+ "span",
255
+ {
256
+ className: sm ? StatCard_module_css_default.heroValueSm : StatCard_module_css_default.heroValue,
257
+ style: valueColor ? { color: valueColor } : void 0,
258
+ children: value
259
+ }
260
+ ),
261
+ children ? /* @__PURE__ */ jsxs(Group, { gap: "sm", wrap: "nowrap", style: { flex: 1 }, children: [
262
+ /* @__PURE__ */ jsx("span", { className: sm ? StatCard_module_css_default.heroLabelSm : StatCard_module_css_default.heroLabel, children: label }),
263
+ /* @__PURE__ */ jsx("div", { style: { flex: 1 }, children })
264
+ ] }) : /* @__PURE__ */ jsx("span", { className: sm ? StatCard_module_css_default.heroLabelSm : StatCard_module_css_default.heroLabel, children: label })
265
+ ] })
266
+ ] }) });
267
+ }
268
+ function StatCardSkeleton() {
269
+ return /* @__PURE__ */ jsx(Card, { withBorder: true, children: /* @__PURE__ */ jsx(Skeleton, { height: 60 }) });
270
+ }
271
+ var customCodeTheme = Object.fromEntries(
272
+ Object.entries(oneDark).map(([key, value]) => [
273
+ key,
274
+ typeof value === "object" && value !== null ? { ...value, background: "none", backgroundColor: "none" } : value
275
+ ])
276
+ );
277
+ var defaultComponents = {
278
+ h1: ({ children }) => /* @__PURE__ */ jsx(Title, { order: 3, c: "var(--color-primary)", mb: "xs", mt: "md", children }),
279
+ h2: ({ children }) => /* @__PURE__ */ jsx(Title, { order: 4, c: "var(--color-primary)", mb: "xs", mt: "sm", children }),
280
+ ul: ({ children }) => /* @__PURE__ */ jsx("ul", { style: { margin: "0.5rem 0", paddingLeft: "1.5rem" }, children }),
281
+ ol: ({ children }) => /* @__PURE__ */ jsx("ol", { style: { margin: "0.5rem 0", paddingLeft: "1.5rem" }, children }),
282
+ li: ({ children }) => /* @__PURE__ */ jsx("li", { style: { marginBottom: "0.25rem", fontSize: "var(--mantine-font-size-sm)" }, children }),
283
+ code: ({ className, children, ...props }) => {
284
+ const match = /language-(\w+)/.exec(className || "");
285
+ const codeString = String(children).replace(/\n$/, "");
286
+ if (match) {
287
+ return /* @__PURE__ */ jsx(
288
+ Prism,
289
+ {
290
+ style: customCodeTheme,
291
+ language: match[1],
292
+ PreTag: "div",
293
+ customStyle: {
294
+ margin: "0.5rem 0",
295
+ borderRadius: "var(--mantine-radius-default)",
296
+ fontSize: "0.8rem"
297
+ },
298
+ children: codeString
299
+ }
300
+ );
301
+ }
302
+ return /* @__PURE__ */ jsx(Code, { ...props, children });
303
+ },
304
+ pre: ({ children }) => /* @__PURE__ */ jsx(Fragment, { children }),
305
+ blockquote: ({ children }) => /* @__PURE__ */ jsx(Box, { pl: "sm", my: "xs", style: { borderLeft: "2px solid var(--color-border)" }, children }),
306
+ p: ({ children }) => /* @__PURE__ */ jsx(Text, { size: "sm", m: 0, children }),
307
+ strong: ({ children }) => /* @__PURE__ */ jsx(Text, { component: "span", fw: 700, children }),
308
+ em: ({ children }) => /* @__PURE__ */ jsx(Text, { component: "span", fs: "italic", children })
309
+ };
310
+ function StyledMarkdown({ children, components, className, style }) {
311
+ const mergedComponents = components ? { ...defaultComponents, ...components } : defaultComponents;
312
+ return /* @__PURE__ */ jsx("div", { className, style, children: /* @__PURE__ */ jsx(Markdown, { components: mergedComponents, children }) });
313
+ }
314
+ var jsonTheme = Object.fromEntries(
315
+ Object.entries(oneDark).map(([key, value]) => [
316
+ key,
317
+ typeof value === "object" && value !== null ? { ...value, background: "none", backgroundColor: "none" } : value
318
+ ])
319
+ );
320
+ function JsonViewer({ data, maxHeight, fontSize = "0.8rem" }) {
321
+ const jsonString = typeof data === "string" ? data : JSON.stringify(data, null, 2);
322
+ return /* @__PURE__ */ jsx(
323
+ Prism,
324
+ {
325
+ language: "json",
326
+ style: jsonTheme,
327
+ customStyle: {
328
+ margin: 0,
329
+ fontSize,
330
+ maxHeight,
331
+ overflow: maxHeight ? "auto" : void 0,
332
+ overflowX: "auto"
333
+ },
334
+ children: jsonString
335
+ }
336
+ );
337
+ }
338
+ var subtleMarkdownComponents = {
339
+ p: ({ children }) => /* @__PURE__ */ jsx(Text, { size: "sm", m: 0, c: "var(--color-text-subtle)", style: { whiteSpace: "pre-wrap" }, children })
340
+ };
341
+ var subtleMarkdownWrapperStyle = {
342
+ display: "flex",
343
+ flexDirection: "column",
344
+ gap: 8
345
+ };
346
+ function ContextViewer({ data }) {
347
+ return /* @__PURE__ */ jsx(ContextNode, { data, depth: 0 });
348
+ }
349
+ function ContextNode({ data, depth }) {
350
+ if (data === null || data === void 0) {
351
+ return /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", fs: "italic", children: "No context provided" });
352
+ }
353
+ if (typeof data === "string") {
354
+ return /* @__PURE__ */ jsx(StyledMarkdown, { components: subtleMarkdownComponents, style: subtleMarkdownWrapperStyle, children: data });
355
+ }
356
+ if (typeof data === "number" || typeof data === "boolean") {
357
+ return /* @__PURE__ */ jsx(Text, { size: "sm", children: String(data) });
358
+ }
359
+ if (Array.isArray(data)) {
360
+ return /* @__PURE__ */ jsx(ArrayView, { items: data, depth });
361
+ }
362
+ if (typeof data === "object") {
363
+ return /* @__PURE__ */ jsx(ObjectView, { data, depth });
364
+ }
365
+ return /* @__PURE__ */ jsx(Text, { size: "sm", children: String(data) });
366
+ }
367
+ function formatLabel(key) {
368
+ return key.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
369
+ }
370
+ function hasMarkdown(value) {
371
+ return /(\*\*.+\*\*|^#{1,6}\s|^\s*[-*]\s|\[.+\]\(.+\)|^\|.+\|$|^>\s|```)/.test(value);
372
+ }
373
+ function NestedSection({ title, children }) {
374
+ const [expanded, setExpanded] = useState(true);
375
+ return /* @__PURE__ */ jsxs(Stack, { gap: 6, children: [
376
+ /* @__PURE__ */ jsxs(Group, { gap: 4, style: { cursor: "pointer", userSelect: "none" }, onClick: () => setExpanded((v) => !v), children: [
377
+ /* @__PURE__ */ jsx(
378
+ IconChevronRight,
379
+ {
380
+ size: 14,
381
+ color: "var(--color-primary)",
382
+ style: {
383
+ transition: "transform 150ms ease",
384
+ transform: expanded ? "rotate(90deg)" : "rotate(0deg)",
385
+ flexShrink: 0
386
+ }
387
+ }
388
+ ),
389
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, style: { fontFamily: "var(--mantine-font-family-headings)" }, children: title })
390
+ ] }),
391
+ expanded && /* @__PURE__ */ jsx(Box, { pl: "sm", style: { borderLeft: "2px solid var(--color-border)" }, children })
392
+ ] });
393
+ }
394
+ function PrimitiveValue({ value }) {
395
+ if (value === null || value === void 0) {
396
+ return /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", fs: "italic", children: "\u2014" });
397
+ }
398
+ if (typeof value === "boolean") {
399
+ return /* @__PURE__ */ jsx(Text, { size: "sm", m: 0, children: value ? "Yes" : "No" });
400
+ }
401
+ if (typeof value === "number") {
402
+ return /* @__PURE__ */ jsx(Text, { size: "sm", m: 0, children: value.toLocaleString() });
403
+ }
404
+ const str = String(value);
405
+ if (hasMarkdown(str)) {
406
+ return /* @__PURE__ */ jsx(StyledMarkdown, { components: subtleMarkdownComponents, children: str });
407
+ }
408
+ return /* @__PURE__ */ jsx(Text, { size: "sm", m: 0, c: "var(--color-text-subtle)", style: { whiteSpace: "pre-wrap" }, children: str });
409
+ }
410
+ function ArrayView({ items, depth }) {
411
+ if (items.length === 0) {
412
+ return /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", fs: "italic", children: "Empty list" });
413
+ }
414
+ const allPrimitive = items.every((item) => typeof item !== "object" || item === null);
415
+ if (allPrimitive) {
416
+ return /* @__PURE__ */ jsx(Stack, { gap: 2, children: items.map((item, i) => /* @__PURE__ */ jsxs(Group, { gap: "xs", align: "flex-start", children: [
417
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", style: { userSelect: "none" }, children: "\u2022" }),
418
+ /* @__PURE__ */ jsx(PrimitiveValue, { value: item })
419
+ ] }, i)) });
420
+ }
421
+ return /* @__PURE__ */ jsx(Stack, { gap: "sm", children: items.map((item, i) => /* @__PURE__ */ jsx(Paper, { p: "sm", style: { border: "1px solid var(--color-border)" }, children: /* @__PURE__ */ jsx(ContextNode, { data: item, depth: depth + 1 }) }, i)) });
422
+ }
423
+ function ObjectView({ data, depth }) {
424
+ const entries = Object.entries(data);
425
+ if (entries.length === 0) {
426
+ return /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", fs: "italic", children: "Empty" });
427
+ }
428
+ const simpleEntries = [];
429
+ const complexEntries = [];
430
+ for (const [key, value] of entries) {
431
+ if (value === null || value === void 0 || typeof value === "boolean" || typeof value === "number") {
432
+ simpleEntries.push([key, value]);
433
+ } else if (typeof value === "string") {
434
+ if (hasMarkdown(value) || value.length > 120) {
435
+ complexEntries.push([key, value]);
436
+ } else {
437
+ simpleEntries.push([key, value]);
438
+ }
439
+ } else {
440
+ complexEntries.push([key, value]);
441
+ }
442
+ }
443
+ return /* @__PURE__ */ jsxs(Stack, { gap: 10, children: [
444
+ simpleEntries.length > 0 && /* @__PURE__ */ jsx(Stack, { gap: 6, children: simpleEntries.map(([key, value]) => /* @__PURE__ */ jsxs(Group, { gap: "sm", align: "flex-start", wrap: "nowrap", children: [
445
+ /* @__PURE__ */ jsx(
446
+ Text,
447
+ {
448
+ size: "sm",
449
+ style: { minWidth: 140, flexShrink: 0, fontFamily: "var(--mantine-font-family-headings)" },
450
+ children: formatLabel(key)
451
+ }
452
+ ),
453
+ /* @__PURE__ */ jsx(PrimitiveValue, { value })
454
+ ] }, key)) }),
455
+ complexEntries.map(([key, value]) => /* @__PURE__ */ jsx(NestedSection, { title: formatLabel(key), children: /* @__PURE__ */ jsx(ContextNode, { data: value, depth: depth + 1 }) }, key))
456
+ ] });
457
+ }
458
+ var TIME_RANGE_OPTIONS = [
459
+ { value: "1h", label: "Last 1 hour" },
460
+ { value: "24h", label: "Last 24 hours" },
461
+ { value: "7d", label: "Last 7 days" },
462
+ { value: "30d", label: "Last 30 days" }
463
+ ];
464
+ function TimeRangeSelector({ value, onChange, width = 180 }) {
465
+ return /* @__PURE__ */ jsx(
466
+ CustomSelector,
467
+ {
468
+ value,
469
+ onChange: (newValue) => newValue && onChange(newValue),
470
+ data: TIME_RANGE_OPTIONS,
471
+ leftSection: /* @__PURE__ */ jsx(IconClock, { size: 16, color: "var(--color-text-subtle)" }),
472
+ w: width,
473
+ withCheckIcon: true
474
+ }
475
+ );
476
+ }
477
+ function PageNotFound() {
478
+ const { currentPath, navigate } = useRouterContext();
479
+ const { user, isLoading } = useAuthContext();
480
+ const isAuthPage = currentPath === "/login" || currentPath === "/auth-redirect";
481
+ const shouldShowSidebar = user && !isLoading && !isAuthPage;
482
+ const height = shouldShowSidebar ? "100%" : "100vh";
483
+ return /* @__PURE__ */ jsx(Center, { h: height, bg: "var(--color-background)", children: /* @__PURE__ */ jsxs(Stack, { align: "center", justify: "center", children: [
484
+ /* @__PURE__ */ jsx(IconInfoCircle, { size: 60, color: "var(--color-text-subtle)" }),
485
+ /* @__PURE__ */ jsx(Title, { order: 1, children: "Page Not Found" }),
486
+ /* @__PURE__ */ jsx(Text, { c: "dimmed", size: "lg", children: "The page you are looking for does not exist." }),
487
+ /* @__PURE__ */ jsx(Group, { justify: "center", children: /* @__PURE__ */ jsx(Button, { size: "md", onClick: () => navigate("/"), children: "Go Home" }) })
488
+ ] }) });
489
+ }
490
+ function ResourceCard({
491
+ resource,
492
+ onClick,
493
+ layout = "stack",
494
+ rightSection,
495
+ lastRunLabel,
496
+ style,
497
+ ...rest
498
+ }) {
499
+ const Icon = getResourceIcon(resource.type);
500
+ if (!Icon) {
501
+ return /* @__PURE__ */ jsx(Paper, { shadow: "sm", withBorder: true, children: /* @__PURE__ */ jsxs(Text, { children: [
502
+ "Invalid resource type: ",
503
+ resource.type
504
+ ] }) });
505
+ }
506
+ const cardStyle = {
507
+ cursor: "pointer",
508
+ ...layout === "grid" || layout === "card" ? { transition: "box-shadow var(--duration-fast) var(--easing)" } : {},
509
+ ...style
510
+ };
511
+ const iconSize = layout === "grid" ? 28 : 20;
512
+ const details = /* @__PURE__ */ jsxs(Group, { gap: "sm", wrap: "nowrap", children: [
513
+ /* @__PURE__ */ jsx(Icon, { size: iconSize, color: "var(--color-primary)" }),
514
+ /* @__PURE__ */ jsxs(Stack, { gap: 4, style: { flex: 1, minWidth: 0 }, children: [
515
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", align: "center", children: [
516
+ /* @__PURE__ */ jsx(
517
+ Text,
518
+ {
519
+ fw: 600,
520
+ size: "sm",
521
+ style: { fontFamily: "var(--elevasis-font-family-subtitle)" },
522
+ ...layout === "stack" ? { lineClamp: 1 } : { truncate: true },
523
+ children: resource.name
524
+ }
525
+ ),
526
+ /* @__PURE__ */ jsx(Badge, { variant: "light", size: layout === "grid" ? "xs" : "sm", children: resource.type })
527
+ ] }),
528
+ resource.description && /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", ...layout === "stack" ? { lineClamp: 1 } : { truncate: true }, children: resource.description }),
529
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
530
+ resource.version && /* @__PURE__ */ jsxs(Badge, { variant: "outline", size: "xs", children: [
531
+ "v",
532
+ resource.version
533
+ ] }),
534
+ /* @__PURE__ */ jsx(Badge, { color: ResourceStatusColors[resource.status], variant: "outline", size: layout === "grid" ? "xs" : "sm", children: resource.status.toUpperCase() })
535
+ ] }),
536
+ lastRunLabel && /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: lastRunLabel }),
537
+ /* @__PURE__ */ jsx(Text, { size: layout === "grid" ? "sm" : "xs", c: "dimmed", ff: "monospace", children: resource.resourceId })
538
+ ] })
539
+ ] });
540
+ if (layout === "row") {
541
+ return /* @__PURE__ */ jsx(
542
+ Paper,
543
+ {
544
+ withBorder: true,
545
+ style: { cursor: "pointer", ...style },
546
+ onClick: () => onClick(resource),
547
+ "data-resource-id": rest["data-resource-id"],
548
+ children: /* @__PURE__ */ jsxs(
549
+ "div",
550
+ {
551
+ style: {
552
+ display: "grid",
553
+ gridTemplateColumns: "18px 200px 120px 1fr 180px 140px 14px",
554
+ alignItems: "center",
555
+ gap: "var(--mantine-spacing-sm)"
556
+ },
557
+ children: [
558
+ /* @__PURE__ */ jsx(Icon, { size: 18, color: "var(--color-primary)" }),
559
+ /* @__PURE__ */ jsx(Text, { fw: 600, size: "md", truncate: true, style: { fontFamily: "var(--elevasis-font-family-subtitle)" }, children: resource.name }),
560
+ /* @__PURE__ */ jsxs(Group, { gap: 6, wrap: "nowrap", children: [
561
+ resource.version && /* @__PURE__ */ jsxs(Badge, { variant: "light", size: "sm", children: [
562
+ "v",
563
+ resource.version
564
+ ] }),
565
+ /* @__PURE__ */ jsx(Badge, { color: ResourceStatusColors[resource.status], variant: "light", size: "sm", children: resource.status.toUpperCase() })
566
+ ] }),
567
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", truncate: true, style: { minWidth: 0 }, children: resource.description || "" }),
568
+ /* @__PURE__ */ jsx("div", { style: { whiteSpace: "nowrap" }, children: rightSection }),
569
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", style: { whiteSpace: "nowrap", textAlign: "right" }, children: lastRunLabel || "" }),
570
+ /* @__PURE__ */ jsx(IconChevronRight, { size: 14, style: { opacity: 0.3 } })
571
+ ]
572
+ }
573
+ )
574
+ }
575
+ );
576
+ }
577
+ return /* @__PURE__ */ jsx(
578
+ Paper,
579
+ {
580
+ shadow: "sm",
581
+ withBorder: true,
582
+ style: cardStyle,
583
+ onClick: () => onClick(resource),
584
+ "data-resource-id": rest["data-resource-id"],
585
+ children: /* @__PURE__ */ jsx(Stack, { children: details })
586
+ }
587
+ );
588
+ }
589
+
590
+ // src/components/display/ResourceCardAdapters.ts
591
+ function catalogItemToResourceDefinition(item) {
592
+ return {
593
+ resourceId: item.resourceId,
594
+ name: item.resourceName,
595
+ description: item.description || "",
596
+ version: item.version,
597
+ type: item.resourceType,
598
+ status: item.status
599
+ };
600
+ }
601
+ function CardHeader({ icon, title, subtitle, rightSection }) {
602
+ const wrappedIcon = icon ? /* @__PURE__ */ jsx(ThemeIcon, { size: "md", variant: "light", children: icon }) : null;
603
+ return /* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: "md", children: [
604
+ subtitle ? /* @__PURE__ */ jsxs("div", { children: [
605
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
606
+ wrappedIcon,
607
+ /* @__PURE__ */ jsx(Title, { order: 3, children: title })
608
+ ] }),
609
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", mt: 2, children: subtitle })
610
+ ] }) : /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
611
+ wrappedIcon,
612
+ /* @__PURE__ */ jsx(Title, { order: 3, children: title })
613
+ ] }),
614
+ rightSection
615
+ ] });
616
+ }
617
+ var SIZE_MAP = {
618
+ sm: { dot: 7, inner: 6, outer: 12 },
619
+ md: { dot: 10, inner: 8, outer: 16 },
620
+ lg: { dot: 12, inner: 10, outer: 20 }
621
+ };
622
+ function GlowDot({ color, size = "md" }) {
623
+ const { dot, inner, outer } = SIZE_MAP[size];
624
+ return /* @__PURE__ */ jsx(
625
+ "div",
626
+ {
627
+ style: {
628
+ width: dot,
629
+ height: dot,
630
+ borderRadius: "50%",
631
+ backgroundColor: color,
632
+ boxShadow: `0 0 ${inner}px ${color}, 0 0 ${outer}px ${color}40`,
633
+ flexShrink: 0
634
+ }
635
+ }
636
+ );
637
+ }
638
+
639
+ export { APIErrorAlert, CardHeader, CollapsibleSection, ContextViewer, CustomSelector, DetailCardSkeleton, EmptyState, GlowDot, JsonViewer, ListSkeleton, PageNotFound, PageTitleCaption, ResourceCard, StatCard, StatCardSkeleton, StatsCardSkeleton, StyledMarkdown, TabCountBadge, TimeRangeSelector, TrendIndicator, catalogItemToResourceDefinition };