@alepha/ui 0.16.1 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/dist/admin/{AdminApiKeys-GMORg-1l.js → AdminApiKeys-CF_qOO3u.js} +20 -19
  2. package/dist/admin/AdminApiKeys-CF_qOO3u.js.map +1 -0
  3. package/dist/admin/{AdminAudits-pkWrjq1Z.js → AdminAudits-BQno3hZG.js} +7 -7
  4. package/dist/admin/AdminAudits-BQno3hZG.js.map +1 -0
  5. package/dist/admin/{AdminFiles-WeQbsCsl.js → AdminFiles-kvuUaASF.js} +3 -4
  6. package/dist/admin/{AdminFiles-WeQbsCsl.js.map → AdminFiles-kvuUaASF.js.map} +1 -1
  7. package/dist/admin/AdminJobDashboard-CrPxp0W1.js +485 -0
  8. package/dist/admin/AdminJobDashboard-CrPxp0W1.js.map +1 -0
  9. package/dist/admin/AdminJobExecutions-D-b4Zt7W.js +678 -0
  10. package/dist/admin/AdminJobExecutions-D-b4Zt7W.js.map +1 -0
  11. package/dist/admin/AdminJobRegistry-CNX5cpDx.js +301 -0
  12. package/dist/admin/AdminJobRegistry-CNX5cpDx.js.map +1 -0
  13. package/dist/admin/{AdminLayout-BqZiXx4H.js → AdminLayout-e-ZP5nWw.js} +6 -9
  14. package/dist/admin/AdminLayout-e-ZP5nWw.js.map +1 -0
  15. package/dist/admin/{AdminNotifications-Ds5Un0NJ.js → AdminNotifications-DeHJFf6W.js} +3 -4
  16. package/dist/admin/{AdminNotifications-Ds5Un0NJ.js.map → AdminNotifications-DeHJFf6W.js.map} +1 -1
  17. package/dist/admin/AdminParameters-iQE8o7a7.js +774 -0
  18. package/dist/admin/AdminParameters-iQE8o7a7.js.map +1 -0
  19. package/dist/admin/{AdminSessions-DzIOxM3b.js → AdminSessions-oKJCbd7w.js} +5 -6
  20. package/dist/admin/AdminSessions-oKJCbd7w.js.map +1 -0
  21. package/dist/admin/{AdminUserAudits-CiUPN2BC.js → AdminUserAudits-BNCEle_E.js} +6 -7
  22. package/dist/admin/AdminUserAudits-BNCEle_E.js.map +1 -0
  23. package/dist/admin/{AdminUserCreate-BwQKr4xE.js → AdminUserCreate-CgqeFwCt.js} +6 -6
  24. package/dist/admin/AdminUserCreate-CgqeFwCt.js.map +1 -0
  25. package/dist/admin/{AdminUserDetails-uqtC5aJ1.js → AdminUserDetails-DDe1A1GP.js} +30 -28
  26. package/dist/admin/AdminUserDetails-DDe1A1GP.js.map +1 -0
  27. package/dist/admin/{AdminUserLayout-CiPay35T.js → AdminUserLayout-HAlobhWf.js} +20 -19
  28. package/dist/admin/AdminUserLayout-HAlobhWf.js.map +1 -0
  29. package/dist/admin/{AdminUserSessions-DAE8Nf1F.js → AdminUserSessions-Bq1LnVLf.js} +5 -6
  30. package/dist/admin/AdminUserSessions-Bq1LnVLf.js.map +1 -0
  31. package/dist/admin/{AdminUserSettings-EbahaV2a.js → AdminUserSettings-BRsBZoxV.js} +10 -9
  32. package/dist/admin/AdminUserSettings-BRsBZoxV.js.map +1 -0
  33. package/dist/admin/{AdminUsers-Dcjh0KNW.js → AdminUsers-D71kIOSn.js} +6 -7
  34. package/dist/admin/AdminUsers-D71kIOSn.js.map +1 -0
  35. package/dist/admin/index.d.ts +21 -85
  36. package/dist/admin/index.d.ts.map +1 -1
  37. package/dist/admin/index.js +66 -88
  38. package/dist/admin/index.js.map +1 -1
  39. package/dist/auth/{AuthLayout-Dj5K4SIN.js → AuthLayout-CdJcrPs4.js} +2 -3
  40. package/dist/auth/{AuthLayout-Dj5K4SIN.js.map → AuthLayout-CdJcrPs4.js.map} +1 -1
  41. package/dist/{demo/IconGoogle-CbBF8Hqq.js → auth/IconGoogle-Bm18QD2q.js} +2 -4
  42. package/dist/auth/{IconGoogle-DpSlPZ1u.js.map → IconGoogle-Bm18QD2q.js.map} +1 -1
  43. package/dist/auth/{Login-BBqTosqZ.js → Login-BS_FYTy0.js} +19 -13
  44. package/dist/auth/Login-BS_FYTy0.js.map +1 -0
  45. package/dist/auth/{Profile-Bxj8Nwom.js → Profile-CjDsW378.js} +17 -12
  46. package/dist/auth/Profile-CjDsW378.js.map +1 -0
  47. package/dist/auth/{Register-Ce675Crg.js → Register-C5eqzAaD.js} +27 -17
  48. package/dist/auth/Register-C5eqzAaD.js.map +1 -0
  49. package/dist/auth/{ResetPassword-DWdt7c40.js → ResetPassword-XifinVao.js} +17 -10
  50. package/dist/auth/ResetPassword-XifinVao.js.map +1 -0
  51. package/dist/auth/{VerifyEmail-CI4JwByV.js → VerifyEmail-DTgbeJOO.js} +9 -6
  52. package/dist/auth/VerifyEmail-DTgbeJOO.js.map +1 -0
  53. package/dist/auth/index.d.ts +18 -14
  54. package/dist/auth/index.d.ts.map +1 -1
  55. package/dist/auth/index.js +19 -18
  56. package/dist/auth/index.js.map +1 -1
  57. package/dist/auth/rolldown-runtime-CjeV3_4I.js +18 -0
  58. package/dist/core/index.d.ts +182 -92
  59. package/dist/core/index.d.ts.map +1 -1
  60. package/dist/core/index.js +789 -476
  61. package/dist/core/index.js.map +1 -1
  62. package/dist/demo/DemoDataTable-lnBKWBf8.js +362 -0
  63. package/dist/demo/DemoDataTable-lnBKWBf8.js.map +1 -0
  64. package/dist/demo/{DemoHome-Cce2bWmg.js → DemoHome-CUMZsYaH.js} +6 -6
  65. package/dist/demo/DemoHome-CUMZsYaH.js.map +1 -0
  66. package/dist/demo/{DemoJsonViewer-Dgdk3Txb.js → DemoJsonViewer-_uokbGaW.js} +18 -19
  67. package/dist/demo/DemoJsonViewer-_uokbGaW.js.map +1 -0
  68. package/dist/demo/{DemoLayout-B20TEuhV.js → DemoLayout-DHVoacE6.js} +4 -5
  69. package/dist/demo/DemoLayout-DHVoacE6.js.map +1 -0
  70. package/dist/demo/{DemoLogin-CvCG2WVh.js → DemoLogin-DjJ9314c.js} +27 -24
  71. package/dist/demo/DemoLogin-DjJ9314c.js.map +1 -0
  72. package/dist/demo/{DemoRegister-CmeHbOAs.js → DemoRegister-DzkJ5M83.js} +39 -32
  73. package/dist/demo/DemoRegister-DzkJ5M83.js.map +1 -0
  74. package/dist/demo/{DemoResetPassword-CKO5iA_6.js → DemoResetPassword-DWh4_BpQ.js} +30 -26
  75. package/dist/demo/DemoResetPassword-DWh4_BpQ.js.map +1 -0
  76. package/dist/demo/{DemoSidebar-MVmQKfMt.js → DemoSidebar-C1csnGhX.js} +4 -5
  77. package/dist/demo/DemoSidebar-C1csnGhX.js.map +1 -0
  78. package/dist/demo/{DemoTypeForm-w-qtfRlC.js → DemoTypeForm-CWz6fJrJ.js} +4 -5
  79. package/dist/demo/DemoTypeForm-CWz6fJrJ.js.map +1 -0
  80. package/dist/demo/{DemoVerifyEmail-C8FFJT5A.js → DemoVerifyEmail-DbU_tCj8.js} +16 -16
  81. package/dist/demo/DemoVerifyEmail-DbU_tCj8.js.map +1 -0
  82. package/dist/{auth/IconGoogle-DpSlPZ1u.js → demo/IconGoogle-Ch1m3Uzl.js} +2 -4
  83. package/dist/demo/{IconGoogle-CbBF8Hqq.js.map → IconGoogle-Ch1m3Uzl.js.map} +1 -1
  84. package/dist/demo/{Showcase-CQrMWars.js → Showcase-BzoXNlCn.js} +11 -13
  85. package/dist/demo/Showcase-BzoXNlCn.js.map +1 -0
  86. package/dist/demo/index.d.ts +3 -70
  87. package/dist/demo/index.d.ts.map +1 -1
  88. package/dist/demo/index.js +11 -15
  89. package/dist/demo/index.js.map +1 -1
  90. package/dist/json/index.js +2 -2
  91. package/dist/json/index.js.map +1 -1
  92. package/package.json +11 -5
  93. package/src/admin/AdminRouter.ts +51 -29
  94. package/src/admin/components/AdminLayout.tsx +6 -9
  95. package/src/admin/components/audits/AdminAudits.tsx +5 -5
  96. package/src/admin/components/jobs/AdminJobDashboard.tsx +455 -0
  97. package/src/admin/components/jobs/AdminJobExecutions.tsx +693 -0
  98. package/src/admin/components/jobs/AdminJobRegistry.tsx +325 -0
  99. package/src/admin/components/keys/AdminApiKeys.tsx +28 -31
  100. package/src/admin/components/parameters/AdminParameters.tsx +156 -78
  101. package/src/admin/components/parameters/ParameterDetails.tsx +173 -108
  102. package/src/admin/components/parameters/ParameterEmptyState.tsx +27 -0
  103. package/src/admin/components/parameters/ParameterHistory.tsx +22 -35
  104. package/src/admin/components/parameters/ParameterTree.tsx +283 -109
  105. package/src/admin/components/parameters/types.ts +3 -3
  106. package/src/admin/components/sessions/AdminSessions.tsx +3 -3
  107. package/src/admin/components/shared/AdminResourceHeader.tsx +20 -16
  108. package/src/admin/components/users/AdminUserAudits.tsx +5 -5
  109. package/src/admin/components/users/AdminUserCreate.tsx +3 -3
  110. package/src/admin/components/users/AdminUserDetails.tsx +51 -53
  111. package/src/admin/components/users/AdminUserLayout.tsx +7 -7
  112. package/src/admin/components/users/AdminUserSessions.tsx +3 -3
  113. package/src/admin/components/users/AdminUserSettings.tsx +9 -9
  114. package/src/admin/components/users/AdminUsers.tsx +5 -5
  115. package/src/admin/components/verifications/AdminVerifications.tsx +3 -3
  116. package/src/admin/index.ts +0 -24
  117. package/src/admin/primitives/$uiAdmin.ts +2 -2
  118. package/src/auth/AuthRouter.ts +1 -0
  119. package/src/auth/components/Login.tsx +13 -13
  120. package/src/auth/components/Profile.tsx +17 -26
  121. package/src/auth/components/Register.tsx +21 -31
  122. package/src/auth/components/ResetPassword.tsx +13 -22
  123. package/src/auth/components/VerifyEmail.tsx +5 -5
  124. package/src/auth/components/buttons/UserButton.tsx +14 -4
  125. package/src/core/components/buttons/ActionButton.tsx +13 -17
  126. package/src/core/components/buttons/DarkModeButton.tsx +8 -4
  127. package/src/core/components/buttons/ToggleSidebarButton.tsx +3 -5
  128. package/src/core/components/data/ErrorViewer.tsx +15 -15
  129. package/src/core/components/dialogs/AlertDialog.tsx +3 -3
  130. package/src/core/components/dialogs/ConfirmDialog.tsx +3 -3
  131. package/src/core/components/dialogs/PromptDialog.tsx +3 -3
  132. package/src/core/components/form/Control.tsx +19 -32
  133. package/src/core/components/form/ControlArray.tsx +206 -96
  134. package/src/core/components/form/ControlObject.tsx +3 -3
  135. package/src/core/components/form/ControlQueryBuilder.tsx +20 -22
  136. package/src/core/components/form/ControlSelect.tsx +4 -0
  137. package/src/core/components/form/TypeForm.browser.spec.tsx +727 -0
  138. package/src/core/components/form/TypeForm.tsx +7 -0
  139. package/src/core/components/layout/AlephaMantineProvider.tsx +1 -0
  140. package/src/core/components/layout/Breadcrumb.tsx +91 -0
  141. package/src/core/components/layout/{AdminShell.tsx → DashboardShell.tsx} +77 -32
  142. package/src/core/components/layout/Omnibar.tsx +2 -1
  143. package/src/core/components/layout/Sidebar.tsx +63 -19
  144. package/src/core/components/table/ColumnPicker.tsx +47 -31
  145. package/src/core/components/table/DataTable.tsx +277 -201
  146. package/src/core/components/table/DataTableFilters.tsx +8 -0
  147. package/src/core/components/table/DataTableToolbar.tsx +98 -5
  148. package/src/core/components/table/FilterPicker.tsx +28 -26
  149. package/src/core/components/table/types.ts +52 -37
  150. package/src/core/components/table/useTableSelection.ts +83 -0
  151. package/src/core/constants/ui.ts +1 -1
  152. package/src/core/helpers/renderIcon.tsx +5 -2
  153. package/src/core/index.ts +9 -5
  154. package/src/core/styles.css +8 -7
  155. package/src/core/utils/parseInput.ts +1 -0
  156. package/src/core/utils/string.ts +28 -4
  157. package/src/demo/components/DemoHome.tsx +5 -5
  158. package/src/demo/components/DemoLayout.tsx +6 -2
  159. package/src/demo/components/core/DemoDataTable.tsx +209 -5
  160. package/src/demo/components/json/DemoJsonViewer.tsx +1 -1
  161. package/src/demo/components/shared/MacWindow.tsx +7 -7
  162. package/src/demo/components/shared/Showcase.tsx +3 -3
  163. package/src/demo/index.ts +0 -11
  164. package/src/json/components/JsonViewer.tsx +3 -3
  165. package/dist/admin/AdminApiKeys-DsmGnHNh.js +0 -3
  166. package/dist/admin/AdminApiKeys-GMORg-1l.js.map +0 -1
  167. package/dist/admin/AdminAudits-8SM96viT.js +0 -3
  168. package/dist/admin/AdminAudits-pkWrjq1Z.js.map +0 -1
  169. package/dist/admin/AdminFiles-B56ocq4H.js +0 -3
  170. package/dist/admin/AdminJobs-B-q9iGO3.js +0 -697
  171. package/dist/admin/AdminJobs-B-q9iGO3.js.map +0 -1
  172. package/dist/admin/AdminJobs-CED1syCn.js +0 -3
  173. package/dist/admin/AdminLayout-BqZiXx4H.js.map +0 -1
  174. package/dist/admin/AdminNotifications-B0B1rdc4.js +0 -3
  175. package/dist/admin/AdminParameters-BU3lATdJ.js +0 -3
  176. package/dist/admin/AdminParameters-CfDUpc78.js +0 -575
  177. package/dist/admin/AdminParameters-CfDUpc78.js.map +0 -1
  178. package/dist/admin/AdminSessions-BDGK2MS6.js +0 -3
  179. package/dist/admin/AdminSessions-DzIOxM3b.js.map +0 -1
  180. package/dist/admin/AdminUserAudits-CiUPN2BC.js.map +0 -1
  181. package/dist/admin/AdminUserAudits-Cj79gENT.js +0 -3
  182. package/dist/admin/AdminUserCreate-BwQKr4xE.js.map +0 -1
  183. package/dist/admin/AdminUserCreate-Cq-mUmBs.js +0 -3
  184. package/dist/admin/AdminUserDetails-DRjVAPFd.js +0 -3
  185. package/dist/admin/AdminUserDetails-uqtC5aJ1.js.map +0 -1
  186. package/dist/admin/AdminUserLayout-CGzmHHby.js +0 -3
  187. package/dist/admin/AdminUserLayout-CiPay35T.js.map +0 -1
  188. package/dist/admin/AdminUserSessions-DAE8Nf1F.js.map +0 -1
  189. package/dist/admin/AdminUserSessions-DcdzuNZ9.js +0 -3
  190. package/dist/admin/AdminUserSettings-D7V6-ceX.js +0 -3
  191. package/dist/admin/AdminUserSettings-EbahaV2a.js.map +0 -1
  192. package/dist/admin/AdminUsers-D9nyzGqQ.js +0 -3
  193. package/dist/admin/AdminUsers-Dcjh0KNW.js.map +0 -1
  194. package/dist/auth/Login-BBqTosqZ.js.map +0 -1
  195. package/dist/auth/Login-CoU63mMR.js +0 -4
  196. package/dist/auth/Profile-Bxj8Nwom.js.map +0 -1
  197. package/dist/auth/Register-BV_oa_AK.js +0 -4
  198. package/dist/auth/Register-Ce675Crg.js.map +0 -1
  199. package/dist/auth/ResetPassword-D5wC8GAA.js +0 -3
  200. package/dist/auth/ResetPassword-DWdt7c40.js.map +0 -1
  201. package/dist/auth/VerifyEmail-CI4JwByV.js.map +0 -1
  202. package/dist/auth/VerifyEmail-DAfqVm5s.js +0 -3
  203. package/dist/demo/DemoDataTable-CguplbR7.js +0 -150
  204. package/dist/demo/DemoDataTable-CguplbR7.js.map +0 -1
  205. package/dist/demo/DemoHome-Cce2bWmg.js.map +0 -1
  206. package/dist/demo/DemoHome-DC9qkMNe.js +0 -3
  207. package/dist/demo/DemoJsonViewer-DIssGVlJ.js +0 -4
  208. package/dist/demo/DemoJsonViewer-Dgdk3Txb.js.map +0 -1
  209. package/dist/demo/DemoLayout-B20TEuhV.js.map +0 -1
  210. package/dist/demo/DemoLayout-DSRyf4qJ.js +0 -3
  211. package/dist/demo/DemoLogin-CvCG2WVh.js.map +0 -1
  212. package/dist/demo/DemoRegister-CmeHbOAs.js.map +0 -1
  213. package/dist/demo/DemoResetPassword-CKO5iA_6.js.map +0 -1
  214. package/dist/demo/DemoSidebar-MVmQKfMt.js.map +0 -1
  215. package/dist/demo/DemoTypeForm-w-qtfRlC.js.map +0 -1
  216. package/dist/demo/DemoVerifyEmail-C8FFJT5A.js.map +0 -1
  217. package/dist/demo/Showcase-CQrMWars.js.map +0 -1
  218. package/src/admin/components/jobs/AdminJobs.tsx +0 -772
@@ -1,697 +0,0 @@
1
- import { ActionButton, DataTable, Flex, Text, useDialog, useToast } from "@alepha/ui";
2
- import { t } from "alepha";
3
- import { IconAlertTriangle, IconCircleCheck, IconCircleX, IconClock, IconPlayerPlay, IconRefresh, IconTerminal2 } from "@tabler/icons-react";
4
- import { ActionIcon, Badge, Box, Card, Group, Paper, Progress, RingProgress, ScrollArea, SimpleGrid, Skeleton, Stack, Tabs, ThemeIcon, Tooltip, useMantineTheme } from "@mantine/core";
5
- import { useClient } from "alepha/react";
6
- import { useI18n } from "alepha/react/i18n";
7
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
- import { jobExecutions } from "alepha/api/jobs";
9
- import { useCallback, useEffect, useState } from "react";
10
-
11
- //#region ../../src/admin/components/jobs/AdminJobs.tsx
12
- const formatDuration = (start, end) => {
13
- const startTime = new Date(start).getTime();
14
- const duration = (end ? new Date(end).getTime() : Date.now()) - startTime;
15
- if (duration < 1e3) return `${duration}ms`;
16
- if (duration < 6e4) return `${(duration / 1e3).toFixed(1)}s`;
17
- if (duration < 36e5) return `${Math.floor(duration / 6e4)}m ${Math.floor(duration % 6e4 / 1e3)}s`;
18
- return `${Math.floor(duration / 36e5)}h ${Math.floor(duration % 36e5 / 6e4)}m`;
19
- };
20
- const getStatusColor = (status) => {
21
- switch (status) {
22
- case "COMPLETED": return "teal";
23
- case "FAILED": return "red";
24
- case "STARTED": return "blue";
25
- default: return "gray";
26
- }
27
- };
28
- const getStatusIcon = (status, size = 14) => {
29
- switch (status) {
30
- case "COMPLETED": return /* @__PURE__ */ jsx(IconCircleCheck, { size });
31
- case "FAILED": return /* @__PURE__ */ jsx(IconCircleX, { size });
32
- case "STARTED": return /* @__PURE__ */ jsx(IconPlayerPlay, { size });
33
- default: return /* @__PURE__ */ jsx(IconClock, { size });
34
- }
35
- };
36
- const getLogLevelColor = (level) => {
37
- switch (level) {
38
- case "ERROR": return "red";
39
- case "WARN": return "yellow";
40
- case "INFO": return "blue";
41
- case "DEBUG": return "gray";
42
- case "TRACE": return "dimmed";
43
- default: return "dimmed";
44
- }
45
- };
46
- const JobCard = (props) => {
47
- const { job, stats, isTriggering, onTrigger, onSelect, isSelected } = props;
48
- const theme = useMantineTheme();
49
- stats && stats.total > 0 && stats.completed / stats.total * 100;
50
- return /* @__PURE__ */ jsxs(Card, {
51
- p: "md",
52
- radius: "md",
53
- withBorder: true,
54
- onClick: () => onSelect(job),
55
- style: {
56
- cursor: "pointer",
57
- borderColor: isSelected ? theme.colors.blue[6] : void 0,
58
- backgroundColor: isSelected ? "var(--mantine-color-blue-light)" : void 0,
59
- transition: "all 150ms ease"
60
- },
61
- children: [/* @__PURE__ */ jsxs(Group, {
62
- justify: "space-between",
63
- mb: "xs",
64
- children: [/* @__PURE__ */ jsxs(Group, {
65
- gap: "xs",
66
- children: [/* @__PURE__ */ jsx(ThemeIcon, {
67
- size: "sm",
68
- radius: "sm",
69
- variant: "light",
70
- color: stats?.lastStatus ? getStatusColor(stats.lastStatus) : "gray",
71
- children: /* @__PURE__ */ jsx(IconTerminal2, { size: 14 })
72
- }), /* @__PURE__ */ jsx(Text, {
73
- size: "sm",
74
- fw: 600,
75
- ff: "monospace",
76
- children: job
77
- })]
78
- }), /* @__PURE__ */ jsx(Tooltip, {
79
- label: "Trigger job manually",
80
- position: "left",
81
- children: /* @__PURE__ */ jsx(ActionIcon, {
82
- size: "sm",
83
- variant: "light",
84
- color: "blue",
85
- loading: isTriggering,
86
- onClick: (e) => {
87
- e.stopPropagation();
88
- onTrigger(job);
89
- },
90
- children: /* @__PURE__ */ jsx(IconPlayerPlay, { size: 12 })
91
- })
92
- })]
93
- }), stats ? /* @__PURE__ */ jsxs(Fragment, { children: [
94
- /* @__PURE__ */ jsxs(Group, {
95
- gap: "lg",
96
- mb: "xs",
97
- children: [
98
- /* @__PURE__ */ jsxs(Box, { children: [/* @__PURE__ */ jsx(Text, {
99
- size: "xs",
100
- c: "dimmed",
101
- tt: "uppercase",
102
- fw: 500,
103
- children: "Total"
104
- }), /* @__PURE__ */ jsx(Text, {
105
- size: "lg",
106
- fw: 700,
107
- ff: "monospace",
108
- children: stats.total
109
- })] }),
110
- /* @__PURE__ */ jsxs(Box, { children: [/* @__PURE__ */ jsx(Text, {
111
- size: "xs",
112
- c: "dimmed",
113
- tt: "uppercase",
114
- fw: 500,
115
- children: "Success"
116
- }), /* @__PURE__ */ jsx(Text, {
117
- size: "lg",
118
- fw: 700,
119
- ff: "monospace",
120
- c: "teal",
121
- children: stats.completed
122
- })] }),
123
- /* @__PURE__ */ jsxs(Box, { children: [/* @__PURE__ */ jsx(Text, {
124
- size: "xs",
125
- c: "dimmed",
126
- tt: "uppercase",
127
- fw: 500,
128
- children: "Failed"
129
- }), /* @__PURE__ */ jsx(Text, {
130
- size: "lg",
131
- fw: 700,
132
- ff: "monospace",
133
- c: "red",
134
- children: stats.failed
135
- })] })
136
- ]
137
- }),
138
- /* @__PURE__ */ jsxs(Progress.Root, {
139
- size: "sm",
140
- radius: "xs",
141
- children: [
142
- /* @__PURE__ */ jsx(Tooltip, {
143
- label: `${stats.completed} completed`,
144
- children: /* @__PURE__ */ jsx(Progress.Section, {
145
- value: stats.completed / Math.max(stats.total, 1) * 100,
146
- color: "teal"
147
- })
148
- }),
149
- /* @__PURE__ */ jsx(Tooltip, {
150
- label: `${stats.failed} failed`,
151
- children: /* @__PURE__ */ jsx(Progress.Section, {
152
- value: stats.failed / Math.max(stats.total, 1) * 100,
153
- color: "red"
154
- })
155
- }),
156
- /* @__PURE__ */ jsx(Tooltip, {
157
- label: `${stats.running} running`,
158
- children: /* @__PURE__ */ jsx(Progress.Section, {
159
- value: stats.running / Math.max(stats.total, 1) * 100,
160
- color: "blue"
161
- })
162
- })
163
- ]
164
- }),
165
- stats.lastRun && /* @__PURE__ */ jsxs(Text, {
166
- size: "xs",
167
- c: "dimmed",
168
- mt: "xs",
169
- children: [
170
- "Last run: ",
171
- formatDuration(stats.lastRun, /* @__PURE__ */ new Date()),
172
- " ago"
173
- ]
174
- })
175
- ] }) : /* @__PURE__ */ jsxs(Stack, {
176
- gap: "xs",
177
- children: [/* @__PURE__ */ jsx(Skeleton, {
178
- height: 8,
179
- radius: "xl"
180
- }), /* @__PURE__ */ jsx(Skeleton, {
181
- height: 8,
182
- width: "70%",
183
- radius: "xl"
184
- })]
185
- })]
186
- });
187
- };
188
- const ExecutionLogViewer = (props) => {
189
- const { logs, error } = props;
190
- if (!logs?.length && !error) return /* @__PURE__ */ jsx(Box, {
191
- p: "md",
192
- children: /* @__PURE__ */ jsx(Text, {
193
- size: "sm",
194
- c: "dimmed",
195
- ta: "center",
196
- children: "No logs available"
197
- })
198
- });
199
- return /* @__PURE__ */ jsx(ScrollArea, {
200
- h: 300,
201
- type: "auto",
202
- children: /* @__PURE__ */ jsxs(Box, {
203
- p: "md",
204
- style: {
205
- fontFamily: "var(--mantine-font-family-monospace)",
206
- fontSize: "12px",
207
- lineHeight: 1.6
208
- },
209
- children: [error && /* @__PURE__ */ jsx(Paper, {
210
- p: "sm",
211
- mb: "md",
212
- bg: "var(--mantine-color-red-light)",
213
- radius: "sm",
214
- children: /* @__PURE__ */ jsxs(Group, {
215
- gap: "xs",
216
- align: "flex-start",
217
- children: [/* @__PURE__ */ jsx(IconAlertTriangle, {
218
- size: 14,
219
- color: "var(--mantine-color-red-filled)"
220
- }), /* @__PURE__ */ jsx(Text, {
221
- size: "xs",
222
- c: "red",
223
- style: {
224
- whiteSpace: "pre-wrap",
225
- wordBreak: "break-word"
226
- },
227
- children: error
228
- })]
229
- })
230
- }), logs?.map((log, index) => /* @__PURE__ */ jsxs(Group, {
231
- gap: "sm",
232
- align: "flex-start",
233
- mb: 4,
234
- wrap: "nowrap",
235
- children: [
236
- /* @__PURE__ */ jsx(Text, {
237
- size: "xs",
238
- c: "dimmed",
239
- style: {
240
- minWidth: 80,
241
- flexShrink: 0
242
- },
243
- children: new Date(log.timestamp).toLocaleTimeString()
244
- }),
245
- /* @__PURE__ */ jsx(Badge, {
246
- size: "xs",
247
- variant: "light",
248
- color: getLogLevelColor(log.level),
249
- style: { minWidth: 50 },
250
- children: log.level
251
- }),
252
- /* @__PURE__ */ jsx(Text, {
253
- size: "xs",
254
- c: "dimmed",
255
- style: {
256
- minWidth: 100,
257
- flexShrink: 0
258
- },
259
- children: log.module
260
- }),
261
- /* @__PURE__ */ jsx(Text, {
262
- size: "xs",
263
- style: { wordBreak: "break-word" },
264
- children: log.message
265
- })
266
- ]
267
- }, index))]
268
- })
269
- });
270
- };
271
- const AdminJobs = () => {
272
- const client = useClient();
273
- const { l } = useI18n();
274
- const toast = useToast();
275
- const dialog = useDialog();
276
- const [jobs, setJobs] = useState([]);
277
- const [jobStats, setJobStats] = useState(/* @__PURE__ */ new Map());
278
- const [selectedJob, setSelectedJob] = useState(null);
279
- const [triggeringJobs, setTriggeringJobs] = useState(/* @__PURE__ */ new Set());
280
- const [refreshKey, setRefreshKey] = useState(0);
281
- const [loading, setLoading] = useState(true);
282
- const [activeTab, setActiveTab] = useState("overview");
283
- useEffect(() => {
284
- const loadJobs = async () => {
285
- try {
286
- const jobList = await client.getJobs();
287
- setJobs(jobList);
288
- const statsMap = /* @__PURE__ */ new Map();
289
- for (const job of jobList) {
290
- const items = (await client.getJobExecutions({ query: {
291
- job,
292
- size: 100
293
- } })).content || [];
294
- const completed = items.filter((e) => e.status === "COMPLETED").length;
295
- const failed = items.filter((e) => e.status === "FAILED").length;
296
- const running = items.filter((e) => e.status === "STARTED").length;
297
- const completedItems = items.filter((e) => e.status === "COMPLETED" && e.finishedAt);
298
- const avgDuration = completedItems.length > 0 ? completedItems.reduce((acc, e) => {
299
- return acc + (new Date(e.finishedAt).getTime() - new Date(e.createdAt).getTime());
300
- }, 0) / completedItems.length : 0;
301
- const lastItem = items[0];
302
- statsMap.set(job, {
303
- name: job,
304
- total: items.length,
305
- completed,
306
- failed,
307
- running,
308
- avgDuration,
309
- lastRun: lastItem?.createdAt ? new Date(lastItem.createdAt) : void 0,
310
- lastStatus: lastItem?.status
311
- });
312
- }
313
- setJobStats(statsMap);
314
- } catch (error) {
315
- toast.danger("Failed to load jobs");
316
- } finally {
317
- setLoading(false);
318
- }
319
- };
320
- loadJobs();
321
- }, [refreshKey]);
322
- const handleTriggerJob = useCallback(async (job) => {
323
- if (!await dialog.confirm({
324
- title: "Trigger Job",
325
- message: `Are you sure you want to trigger "${job}" manually?`,
326
- confirmLabel: "Trigger",
327
- confirmColor: "blue"
328
- })) return;
329
- setTriggeringJobs((prev) => new Set(prev).add(job));
330
- try {
331
- await client.triggerJob({ body: { name: job } });
332
- toast.success(`Job "${job}" triggered successfully`);
333
- setRefreshKey((k) => k + 1);
334
- } catch (error) {
335
- toast.danger(`Failed to trigger job "${job}"`);
336
- } finally {
337
- setTriggeringJobs((prev) => {
338
- const next = new Set(prev);
339
- next.delete(job);
340
- return next;
341
- });
342
- }
343
- }, [
344
- client,
345
- dialog,
346
- toast
347
- ]);
348
- const filters = t.object({
349
- job: t.optional(t.string({ $control: { query: t.pick(jobExecutions.schema, ["job"]) } })),
350
- status: t.optional(t.enum([
351
- "STARTED",
352
- "FAILED",
353
- "COMPLETED"
354
- ]))
355
- });
356
- const globalStats = {
357
- total: Array.from(jobStats.values()).reduce((acc, s) => acc + s.total, 0),
358
- completed: Array.from(jobStats.values()).reduce((acc, s) => acc + s.completed, 0),
359
- failed: Array.from(jobStats.values()).reduce((acc, s) => acc + s.failed, 0),
360
- running: Array.from(jobStats.values()).reduce((acc, s) => acc + s.running, 0)
361
- };
362
- const successRate = globalStats.total > 0 ? Math.round(globalStats.completed / globalStats.total * 100) : 0;
363
- return /* @__PURE__ */ jsxs(Flex, {
364
- flex: 1,
365
- direction: "column",
366
- gap: "md",
367
- children: [/* @__PURE__ */ jsxs(SimpleGrid, {
368
- cols: {
369
- base: 2,
370
- sm: 4
371
- },
372
- spacing: "md",
373
- children: [
374
- /* @__PURE__ */ jsx(Paper, {
375
- p: "md",
376
- radius: "md",
377
- withBorder: true,
378
- children: /* @__PURE__ */ jsxs(Group, {
379
- justify: "space-between",
380
- children: [/* @__PURE__ */ jsxs(Box, { children: [/* @__PURE__ */ jsx(Text, {
381
- size: "xs",
382
- c: "dimmed",
383
- tt: "uppercase",
384
- fw: 600,
385
- children: "Total Jobs"
386
- }), /* @__PURE__ */ jsx(Text, {
387
- size: "xl",
388
- fw: 700,
389
- ff: "monospace",
390
- children: jobs.length
391
- })] }), /* @__PURE__ */ jsx(ThemeIcon, {
392
- size: "lg",
393
- radius: "md",
394
- variant: "light",
395
- color: "blue",
396
- children: /* @__PURE__ */ jsx(IconTerminal2, { size: 20 })
397
- })]
398
- })
399
- }),
400
- /* @__PURE__ */ jsx(Paper, {
401
- p: "md",
402
- radius: "md",
403
- withBorder: true,
404
- children: /* @__PURE__ */ jsxs(Group, {
405
- justify: "space-between",
406
- children: [/* @__PURE__ */ jsxs(Box, { children: [/* @__PURE__ */ jsx(Text, {
407
- size: "xs",
408
- c: "dimmed",
409
- tt: "uppercase",
410
- fw: 600,
411
- children: "Executions"
412
- }), /* @__PURE__ */ jsx(Text, {
413
- size: "xl",
414
- fw: 700,
415
- ff: "monospace",
416
- children: globalStats.total
417
- })] }), /* @__PURE__ */ jsx(ThemeIcon, {
418
- size: "lg",
419
- radius: "md",
420
- variant: "light",
421
- color: "gray",
422
- children: /* @__PURE__ */ jsx(IconClock, { size: 20 })
423
- })]
424
- })
425
- }),
426
- /* @__PURE__ */ jsx(Paper, {
427
- p: "md",
428
- radius: "md",
429
- withBorder: true,
430
- children: /* @__PURE__ */ jsxs(Group, {
431
- justify: "space-between",
432
- children: [/* @__PURE__ */ jsxs(Box, { children: [/* @__PURE__ */ jsx(Text, {
433
- size: "xs",
434
- c: "dimmed",
435
- tt: "uppercase",
436
- fw: 600,
437
- children: "Success Rate"
438
- }), /* @__PURE__ */ jsxs(Text, {
439
- size: "xl",
440
- fw: 700,
441
- ff: "monospace",
442
- c: successRate >= 90 ? "teal" : successRate >= 70 ? "yellow" : "red",
443
- children: [successRate, "%"]
444
- })] }), /* @__PURE__ */ jsx(RingProgress, {
445
- size: 48,
446
- thickness: 4,
447
- roundCaps: true,
448
- sections: [{
449
- value: successRate,
450
- color: successRate >= 90 ? "teal" : successRate >= 70 ? "yellow" : "red"
451
- }]
452
- })]
453
- })
454
- }),
455
- /* @__PURE__ */ jsx(Paper, {
456
- p: "md",
457
- radius: "md",
458
- withBorder: true,
459
- children: /* @__PURE__ */ jsxs(Group, {
460
- justify: "space-between",
461
- children: [/* @__PURE__ */ jsxs(Box, { children: [/* @__PURE__ */ jsx(Text, {
462
- size: "xs",
463
- c: "dimmed",
464
- tt: "uppercase",
465
- fw: 600,
466
- children: "Running Now"
467
- }), /* @__PURE__ */ jsx(Text, {
468
- size: "xl",
469
- fw: 700,
470
- ff: "monospace",
471
- c: "blue",
472
- children: globalStats.running
473
- })] }), /* @__PURE__ */ jsx(ThemeIcon, {
474
- size: "lg",
475
- radius: "md",
476
- variant: "light",
477
- color: globalStats.running > 0 ? "blue" : "gray",
478
- children: /* @__PURE__ */ jsx(IconPlayerPlay, { size: 20 })
479
- })]
480
- })
481
- })
482
- ]
483
- }), /* @__PURE__ */ jsxs(Tabs, {
484
- value: activeTab,
485
- onChange: setActiveTab,
486
- children: [
487
- /* @__PURE__ */ jsxs(Tabs.List, { children: [/* @__PURE__ */ jsx(Tabs.Tab, {
488
- value: "overview",
489
- leftSection: /* @__PURE__ */ jsx(IconTerminal2, { size: 14 }),
490
- children: "Jobs Overview"
491
- }), /* @__PURE__ */ jsx(Tabs.Tab, {
492
- value: "executions",
493
- leftSection: /* @__PURE__ */ jsx(IconClock, { size: 14 }),
494
- children: "Execution History"
495
- })] }),
496
- /* @__PURE__ */ jsxs(Tabs.Panel, {
497
- value: "overview",
498
- pt: "md",
499
- children: [/* @__PURE__ */ jsxs(Group, {
500
- justify: "space-between",
501
- mb: "md",
502
- children: [/* @__PURE__ */ jsxs(Text, {
503
- size: "sm",
504
- c: "dimmed",
505
- children: [
506
- jobs.length,
507
- " registered job",
508
- jobs.length !== 1 ? "s" : ""
509
- ]
510
- }), /* @__PURE__ */ jsx(ActionButton, {
511
- size: "xs",
512
- variant: "light",
513
- leftSection: /* @__PURE__ */ jsx(IconRefresh, { size: 14 }),
514
- onClick: () => setRefreshKey((k) => k + 1),
515
- children: "Refresh"
516
- })]
517
- }), loading ? /* @__PURE__ */ jsx(SimpleGrid, {
518
- cols: {
519
- base: 1,
520
- sm: 2,
521
- lg: 3
522
- },
523
- spacing: "md",
524
- children: [
525
- 1,
526
- 2,
527
- 3
528
- ].map((i) => /* @__PURE__ */ jsx(Skeleton, {
529
- height: 150,
530
- radius: "md"
531
- }, i))
532
- }) : jobs.length === 0 ? /* @__PURE__ */ jsxs(Paper, {
533
- p: "xl",
534
- radius: "md",
535
- withBorder: true,
536
- ta: "center",
537
- children: [
538
- /* @__PURE__ */ jsx(IconTerminal2, {
539
- size: 48,
540
- color: "var(--mantine-color-dimmed)"
541
- }),
542
- /* @__PURE__ */ jsx(Text, {
543
- size: "lg",
544
- fw: 500,
545
- mt: "md",
546
- children: "No jobs registered"
547
- }),
548
- /* @__PURE__ */ jsx(Text, {
549
- size: "sm",
550
- c: "dimmed",
551
- mt: "xs",
552
- children: "Jobs will appear here once they are defined using $job primitive"
553
- })
554
- ]
555
- }) : /* @__PURE__ */ jsx(SimpleGrid, {
556
- cols: {
557
- base: 1,
558
- sm: 2,
559
- lg: 3
560
- },
561
- spacing: "md",
562
- children: jobs.map((job) => /* @__PURE__ */ jsx(JobCard, {
563
- job,
564
- stats: jobStats.get(job),
565
- isTriggering: triggeringJobs.has(job),
566
- onTrigger: handleTriggerJob,
567
- onSelect: setSelectedJob,
568
- isSelected: selectedJob === job
569
- }, job))
570
- })]
571
- }),
572
- /* @__PURE__ */ jsx(Tabs.Panel, {
573
- value: "executions",
574
- pt: "md",
575
- children: /* @__PURE__ */ jsx(DataTable, {
576
- submitOnInit: true,
577
- defaultSize: 15,
578
- typeFormProps: {
579
- skipSubmitButton: true,
580
- columns: 3
581
- },
582
- tableProps: {
583
- horizontalSpacing: "sm",
584
- verticalSpacing: "sm",
585
- highlightOnHover: true
586
- },
587
- onFilterChange: (key, _value, form) => {
588
- if (key === "job" || key === "status") return form.submit();
589
- },
590
- filters,
591
- items: async (filters) => {
592
- return await client.getJobExecutions({ query: {
593
- ...filters,
594
- job: selectedJob || filters.job
595
- } });
596
- },
597
- columns: {
598
- job: {
599
- label: "Job",
600
- value: (item) => /* @__PURE__ */ jsx(Text, {
601
- size: "sm",
602
- fw: 500,
603
- ff: "monospace",
604
- children: item.job
605
- })
606
- },
607
- status: {
608
- label: "Status",
609
- fit: true,
610
- value: (item) => /* @__PURE__ */ jsx(Badge, {
611
- size: "sm",
612
- variant: "light",
613
- color: getStatusColor(item.status),
614
- leftSection: getStatusIcon(item.status, 12),
615
- children: item.status
616
- })
617
- },
618
- duration: {
619
- label: "Duration",
620
- fit: true,
621
- value: (item) => /* @__PURE__ */ jsx(Text, {
622
- size: "xs",
623
- c: "dimmed",
624
- ff: "monospace",
625
- children: formatDuration(item.createdAt, item.finishedAt)
626
- })
627
- },
628
- logs: {
629
- label: "Logs",
630
- fit: true,
631
- value: (item) => {
632
- const logCount = item.logs?.length || 0;
633
- const errorCount = item.logs?.filter((log) => log.level === "ERROR").length || 0;
634
- return /* @__PURE__ */ jsxs(Group, {
635
- gap: 4,
636
- children: [/* @__PURE__ */ jsxs(Badge, {
637
- size: "xs",
638
- variant: "light",
639
- color: "gray",
640
- children: [logCount, " logs"]
641
- }), errorCount > 0 && /* @__PURE__ */ jsxs(Badge, {
642
- size: "xs",
643
- variant: "light",
644
- color: "red",
645
- children: [errorCount, " errors"]
646
- })]
647
- });
648
- }
649
- },
650
- error: {
651
- label: "Error",
652
- value: (item) => item.error ? /* @__PURE__ */ jsx(Tooltip, {
653
- label: item.error,
654
- multiline: true,
655
- w: 300,
656
- children: /* @__PURE__ */ jsx(Text, {
657
- size: "xs",
658
- c: "red",
659
- lineClamp: 1,
660
- children: item.error
661
- })
662
- }) : /* @__PURE__ */ jsx(Text, {
663
- size: "xs",
664
- c: "dimmed",
665
- children: "—"
666
- })
667
- },
668
- createdAt: {
669
- label: "Started",
670
- fit: true,
671
- value: (item) => /* @__PURE__ */ jsx(Text, {
672
- size: "xs",
673
- c: "dimmed",
674
- children: l(item.createdAt, { date: "fromNow" })
675
- })
676
- }
677
- },
678
- panel: (item) => /* @__PURE__ */ jsx(Box, {
679
- bg: "var(--mantine-color-dark-7)",
680
- p: 0,
681
- children: /* @__PURE__ */ jsx(ExecutionLogViewer, {
682
- logs: item.logs,
683
- error: item.error
684
- })
685
- }),
686
- canPanel: (item) => Boolean(item.logs?.length || item.error)
687
- }, refreshKey)
688
- })
689
- ]
690
- })]
691
- });
692
- };
693
- var AdminJobs_default = AdminJobs;
694
-
695
- //#endregion
696
- export { AdminJobs_default as t };
697
- //# sourceMappingURL=AdminJobs-B-q9iGO3.js.map