@acmekit/dashboard 2.13.34 → 2.13.35

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 (87) hide show
  1. package/dist/{api-key-management-create-4AG76FJV.mjs → api-key-management-create-U37VC624.mjs} +3 -3
  2. package/dist/{api-key-management-detail-T2TB4KST.mjs → api-key-management-detail-ZYKL4ATI.mjs} +10 -10
  3. package/dist/{api-key-management-edit-R44OHS7B.mjs → api-key-management-edit-TSZGMIBL.mjs} +3 -3
  4. package/dist/{api-key-management-list-QK4Q7Y5I.mjs → api-key-management-list-HCJFJWWB.mjs} +3 -3
  5. package/dist/app.css +31 -0
  6. package/dist/app.js +3726 -1386
  7. package/dist/app.mjs +240 -38
  8. package/dist/{chunk-GBFVWROS.mjs → chunk-5IEHCYJO.mjs} +1 -1
  9. package/dist/{chunk-DQCEH3X2.mjs → chunk-7F3CWXUH.mjs} +1 -1
  10. package/dist/chunk-A7ULKHDE.mjs +126 -0
  11. package/dist/{chunk-DN3MIYQH.mjs → chunk-FKTMBR44.mjs} +1 -1
  12. package/dist/chunk-GBPAZAJK.mjs +34 -0
  13. package/dist/{chunk-YRWSG3YM.mjs → chunk-HHPPTD3B.mjs} +1 -1
  14. package/dist/chunk-LP6CPB7N.mjs +213 -0
  15. package/dist/{chunk-EFRMWHRX.mjs → chunk-PFZQYK7R.mjs} +1 -1
  16. package/dist/{chunk-XIM7X4FB.mjs → chunk-SYACY6AL.mjs} +1 -1
  17. package/dist/{chunk-2U3RK3JG.mjs → chunk-VEI6HW6L.mjs} +3 -5
  18. package/dist/{chunk-ST2YB7JN.mjs → chunk-WLRJXEKL.mjs} +1 -1
  19. package/dist/{chunk-ULSPL3DR.mjs → chunk-XIP35KXF.mjs} +1 -1
  20. package/dist/{chunk-DTY37DDZ.mjs → chunk-YKIWIMJX.mjs} +1 -0
  21. package/dist/en.json +132 -3
  22. package/dist/{invite-XGPZZBUP.mjs → invite-3JSNOA2B.mjs} +3 -3
  23. package/dist/{login-GNP3QIPI.mjs → login-BEJ5EFGE.mjs} +9 -9
  24. package/dist/{profile-detail-YX27F7N6.mjs → profile-detail-QVTJC4JC.mjs} +3 -3
  25. package/dist/{profile-edit-2VRDU75O.mjs → profile-edit-MIO62TWH.mjs} +3 -3
  26. package/dist/{reset-password-TWRNZO6Z.mjs → reset-password-BN4KAJQL.mjs} +2 -2
  27. package/dist/{settings-3XWLL5LG.mjs → settings-GH5IWXHE.mjs} +3 -3
  28. package/dist/{translation-list-CCEQJNED.mjs → translation-list-JA22BUKN.mjs} +10 -10
  29. package/dist/{translations-edit-E57GVUFV.mjs → translations-edit-STTMANVT.mjs} +11 -11
  30. package/dist/{user-detail-KUSRRVNX.mjs → user-detail-WCXBFRGS.mjs} +3 -3
  31. package/dist/{user-edit-HTN3ZGCL.mjs → user-edit-XDVMJOS4.mjs} +3 -3
  32. package/dist/{user-invite-E3FAAU3V.mjs → user-invite-73ZDSDFC.mjs} +3 -3
  33. package/dist/{user-list-KNJ5S3IM.mjs → user-list-MPJXE3CA.mjs} +5 -5
  34. package/dist/{user-metadata-5GQK75DT.mjs → user-metadata-ADNTL3LT.mjs} +10 -10
  35. package/dist/workflow-analytics-4WCI4ODQ.mjs +152 -0
  36. package/dist/workflow-definition-detail-GI6CFBMG.mjs +94 -0
  37. package/dist/workflow-definition-list-GF3XAEPS.mjs +142 -0
  38. package/dist/workflow-execution-complete-step-WSRLO572.mjs +245 -0
  39. package/dist/workflow-execution-detail-3RH6EQSS.mjs +1411 -0
  40. package/dist/workflow-execution-list-AQEGAME4.mjs +596 -0
  41. package/dist/workflow-execution-rerun-WCYLYL3Q.mjs +138 -0
  42. package/dist/workflow-execution-run-MWN5KWNY.mjs +135 -0
  43. package/dist/workflow-scheduled-list-ZPXR7CZM.mjs +174 -0
  44. package/package.json +9 -9
  45. package/src/components/layout/main-layout/main-layout.tsx +28 -1
  46. package/src/dashboard-app/routes/get-route.map.tsx +71 -0
  47. package/src/hooks/api/workflow-definitions.tsx +79 -0
  48. package/src/hooks/api/workflow-executions.tsx +145 -1
  49. package/src/hooks/api/workflow-metrics.tsx +48 -0
  50. package/src/hooks/use-workflow-sse.tsx +78 -0
  51. package/src/i18n/translations/$schema.json +534 -4
  52. package/src/i18n/translations/en.json +132 -3
  53. package/src/routes/workflow-analytics/workflow-analytics.tsx +167 -0
  54. package/src/routes/workflow-definitions/workflow-definition-detail/workflow-definition-detail.tsx +98 -0
  55. package/src/routes/workflow-definitions/workflow-definition-list/components/workflow-definition-list-table/use-workflow-definition-table-columns.tsx +78 -0
  56. package/src/routes/workflow-definitions/workflow-definition-list/components/workflow-definition-list-table/workflow-definition-list-table.tsx +65 -0
  57. package/src/routes/workflow-definitions/workflow-definition-list/workflow-definition-list.tsx +15 -0
  58. package/src/routes/workflow-executions/constants.ts +16 -0
  59. package/src/routes/workflow-executions/utils.ts +170 -14
  60. package/src/routes/workflow-executions/workflow-execution-complete-step/workflow-execution-complete-step.tsx +270 -0
  61. package/src/routes/workflow-executions/workflow-execution-detail/breadcrumb.tsx +7 -1
  62. package/src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-action-bar/index.ts +1 -0
  63. package/src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-action-bar/workflow-execution-action-bar.tsx +212 -0
  64. package/src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-error-card/index.ts +1 -0
  65. package/src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-error-card/workflow-execution-error-card.tsx +59 -0
  66. package/src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-history-section/workflow-execution-history-section.tsx +157 -6
  67. package/src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-payload-section/workflow-execution-payload-section.tsx +122 -6
  68. package/src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-timeline-section/workflow-execution-timeline-section.tsx +7 -1
  69. package/src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-waiting-banner/index.ts +1 -0
  70. package/src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-waiting-banner/workflow-execution-waiting-banner.tsx +63 -0
  71. package/src/routes/workflow-executions/workflow-execution-detail/workflow-detail.tsx +46 -1
  72. package/src/routes/workflow-executions/workflow-execution-list/components/workflow-execution-list-table/use-workflow-execution-table-columns.tsx +7 -0
  73. package/src/routes/workflow-executions/workflow-execution-list/components/workflow-execution-list-table/use-workflow-execution-table-filters.tsx +7 -1
  74. package/src/routes/workflow-executions/workflow-execution-list/components/workflow-execution-list-table/use-workflow-execution-table-query.tsx +4 -2
  75. package/src/routes/workflow-executions/workflow-execution-list/components/workflow-execution-list-table/workflow-execution-auto-refresh.tsx +73 -0
  76. package/src/routes/workflow-executions/workflow-execution-list/components/workflow-execution-list-table/workflow-execution-list-table.tsx +17 -1
  77. package/src/routes/workflow-executions/workflow-execution-list/components/workflow-execution-list-table/workflow-execution-row-actions.tsx +116 -0
  78. package/src/routes/workflow-executions/workflow-execution-list/components/workflow-execution-list-table/workflow-execution-saved-views.tsx +84 -0
  79. package/src/routes/workflow-executions/workflow-execution-list/workflow-execution-list.tsx +1 -1
  80. package/src/routes/workflow-executions/workflow-execution-rerun/workflow-execution-rerun.tsx +159 -0
  81. package/src/routes/workflow-executions/workflow-execution-run/workflow-execution-run.tsx +139 -0
  82. package/src/routes/workflow-scheduled/workflow-scheduled-list.tsx +269 -0
  83. package/dist/chunk-LKWTBYYC.mjs +0 -35
  84. package/dist/chunk-RPAL6FHW.mjs +0 -73
  85. package/dist/workflow-execution-detail-5O5VCXL3.mjs +0 -870
  86. package/dist/workflow-execution-list-DETG4MRT.mjs +0 -347
  87. /package/dist/{chunk-22YYMH6M.mjs → chunk-RISX76YT.mjs} +0 -0
@@ -0,0 +1,269 @@
1
+ import { Badge, Button, Container, Heading, Text, toast } from "@acmekit/ui"
2
+ import { keepPreviousData } from "@tanstack/react-query"
3
+ import { formatDistanceToNow } from "date-fns"
4
+ import { useTranslation } from "react-i18next"
5
+ import { SingleColumnPage } from "../../components/layout/pages"
6
+ import {
7
+ useWorkflowDefinitions,
8
+ } from "../../hooks/api/workflow-definitions"
9
+ import { useRunWorkflow } from "../../hooks/api/workflow-executions"
10
+
11
+ /**
12
+ * Very small cron → human-readable description utility.
13
+ * Handles the most common patterns without an external library.
14
+ */
15
+ function describeCron(cron: string): string {
16
+ const parts = cron.trim().split(/\s+/)
17
+ if (parts.length < 5) return cron
18
+
19
+ const [minute, hour, dom, month, dow] = parts
20
+
21
+ if (
22
+ minute === "*" &&
23
+ hour === "*" &&
24
+ dom === "*" &&
25
+ month === "*" &&
26
+ dow === "*"
27
+ ) {
28
+ return "Every minute"
29
+ }
30
+
31
+ if (
32
+ minute !== "*" &&
33
+ hour === "*" &&
34
+ dom === "*" &&
35
+ month === "*" &&
36
+ dow === "*"
37
+ ) {
38
+ return `Every hour at minute ${minute}`
39
+ }
40
+
41
+ if (
42
+ minute !== "*" &&
43
+ hour !== "*" &&
44
+ dom === "*" &&
45
+ month === "*" &&
46
+ dow === "*"
47
+ ) {
48
+ const h = parseInt(hour, 10)
49
+ const m = parseInt(minute, 10)
50
+ const ampm = h >= 12 ? "PM" : "AM"
51
+ const h12 = h % 12 || 12
52
+ return `Daily at ${h12}:${String(m).padStart(2, "0")} ${ampm}`
53
+ }
54
+
55
+ if (
56
+ minute !== "*" &&
57
+ hour !== "*" &&
58
+ dom === "*" &&
59
+ month === "*" &&
60
+ dow !== "*"
61
+ ) {
62
+ const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
63
+ const dayNames = dow
64
+ .split(",")
65
+ .map((d) => days[parseInt(d, 10)] ?? d)
66
+ .join(", ")
67
+ const h = parseInt(hour, 10)
68
+ const m = parseInt(minute, 10)
69
+ const ampm = h >= 12 ? "PM" : "AM"
70
+ const h12 = h % 12 || 12
71
+ return `${dayNames} at ${h12}:${String(m).padStart(2, "0")} ${ampm}`
72
+ }
73
+
74
+ if (
75
+ minute !== "*" &&
76
+ hour !== "*" &&
77
+ dom !== "*" &&
78
+ month === "*" &&
79
+ dow === "*"
80
+ ) {
81
+ return `Monthly on day ${dom} at ${hour}:${String(parseInt(minute, 10)).padStart(2, "0")}`
82
+ }
83
+
84
+ return cron
85
+ }
86
+
87
+ /**
88
+ * Rough next-run estimate using date-fns (not exact; just indicative).
89
+ */
90
+ function getNextRunLabel(cron: string): string {
91
+ try {
92
+ const parts = cron.trim().split(/\s+/)
93
+ if (parts.length < 5) return "Unknown"
94
+
95
+ const [minuteStr, hourStr] = parts
96
+ const now = new Date()
97
+ const next = new Date(now)
98
+
99
+ if (minuteStr === "*") {
100
+ // every minute
101
+ next.setSeconds(0, 0)
102
+ next.setMinutes(now.getMinutes() + 1)
103
+ } else if (hourStr === "*") {
104
+ // every hour at :MM
105
+ const m = parseInt(minuteStr, 10)
106
+ next.setMinutes(m, 0, 0)
107
+ if (next <= now) next.setHours(now.getHours() + 1)
108
+ } else {
109
+ // daily at HH:MM (simplified)
110
+ const h = parseInt(hourStr, 10)
111
+ const m = parseInt(minuteStr, 10)
112
+ next.setHours(h, m, 0, 0)
113
+ if (next <= now) next.setDate(now.getDate() + 1)
114
+ }
115
+
116
+ return formatDistanceToNow(next, { addSuffix: true })
117
+ } catch {
118
+ return "Unknown"
119
+ }
120
+ }
121
+
122
+ type WorkflowDef = {
123
+ id: string
124
+ handler_count: number
125
+ steps: Array<{ action: string; depth: number; noCompensation: boolean }>
126
+ options: Record<string, unknown>
127
+ }
128
+
129
+ const ScheduledRow = ({ def }: { def: WorkflowDef }) => {
130
+ const { t } = useTranslation()
131
+
132
+ const schedule = def.options?.schedule as
133
+ | { cron?: string; interval?: string }
134
+ | string
135
+ | undefined
136
+
137
+ const cronStr =
138
+ typeof schedule === "string"
139
+ ? schedule
140
+ : typeof schedule === "object"
141
+ ? schedule?.cron ?? String(schedule?.interval ?? "")
142
+ : ""
143
+
144
+ const humanSchedule = cronStr ? describeCron(cronStr) : "—"
145
+ const nextRun = cronStr ? getNextRunLabel(cronStr) : "—"
146
+
147
+ const { mutateAsync: runWorkflow, isPending } = useRunWorkflow(def.id)
148
+
149
+ const handleRunNow = async () => {
150
+ await runWorkflow(
151
+ { input: {} },
152
+ {
153
+ onSuccess: () => {
154
+ toast.success(t("workflowExecutions.actions.retrySuccess"))
155
+ },
156
+ }
157
+ )
158
+ }
159
+
160
+ return (
161
+ <div className="grid grid-cols-[1fr_1fr_1fr_auto] items-center gap-x-4 px-6 py-3">
162
+ <div className="flex flex-col gap-y-0.5">
163
+ <Text size="small" weight="plus" leading="compact">
164
+ {def.id}
165
+ </Text>
166
+ <Text size="xsmall" className="text-ui-fg-muted">
167
+ {def.handler_count}{" "}
168
+ {t("workflowExecutions.definitions.handlers")}
169
+ </Text>
170
+ </div>
171
+ <div>
172
+ <Badge size="2xsmall" className="font-mono">
173
+ {cronStr || "—"}
174
+ </Badge>
175
+ <Text size="xsmall" className="text-ui-fg-subtle mt-0.5">
176
+ {humanSchedule}
177
+ </Text>
178
+ </div>
179
+ <Text size="small" className="text-ui-fg-subtle">
180
+ {nextRun}
181
+ </Text>
182
+ <Button
183
+ size="small"
184
+ variant="secondary"
185
+ isLoading={isPending}
186
+ onClick={handleRunNow}
187
+ >
188
+ {t("workflowExecutions.scheduled.runNow")}
189
+ </Button>
190
+ </div>
191
+ )
192
+ }
193
+
194
+ export const WorkflowScheduledList = () => {
195
+ const { t } = useTranslation()
196
+
197
+ const { workflow_definitions, isPending } = useWorkflowDefinitions(
198
+ undefined,
199
+ { placeholderData: keepPreviousData }
200
+ )
201
+
202
+ const scheduled = (workflow_definitions ?? []).filter((def) => {
203
+ const opts = def.options
204
+ return opts && (opts.schedule || opts.cron)
205
+ })
206
+
207
+ return (
208
+ <SingleColumnPage widgets={{ before: [], after: [] }}>
209
+ <Container className="divide-y p-0">
210
+ <div className="flex items-center justify-between px-6 py-4">
211
+ <div>
212
+ <Heading>{t("workflowExecutions.scheduled.domain")}</Heading>
213
+ <Text className="text-ui-fg-subtle" size="small">
214
+ {t("workflowExecutions.scheduled.subtitle")}
215
+ </Text>
216
+ </div>
217
+ </div>
218
+
219
+ {/* Table header */}
220
+ <div className="grid grid-cols-[1fr_1fr_1fr_auto] gap-x-4 border-b border-ui-border-base px-6 py-2">
221
+ <Text
222
+ size="xsmall"
223
+ weight="plus"
224
+ className="text-ui-fg-subtle uppercase"
225
+ >
226
+ Workflow
227
+ </Text>
228
+ <Text
229
+ size="xsmall"
230
+ weight="plus"
231
+ className="text-ui-fg-subtle uppercase"
232
+ >
233
+ {t("workflowExecutions.scheduled.schedule")}
234
+ </Text>
235
+ <Text
236
+ size="xsmall"
237
+ weight="plus"
238
+ className="text-ui-fg-subtle uppercase"
239
+ >
240
+ {t("workflowExecutions.scheduled.nextRun")}
241
+ </Text>
242
+ <div />
243
+ </div>
244
+
245
+ {isPending && (
246
+ <div className="px-6 py-4">
247
+ <Text size="small" className="text-ui-fg-muted">
248
+ Loading...
249
+ </Text>
250
+ </div>
251
+ )}
252
+
253
+ {!isPending && scheduled.length === 0 && (
254
+ <div className="px-6 py-8 text-center">
255
+ <Text size="small" className="text-ui-fg-muted">
256
+ {t("workflowExecutions.scheduled.noRecordsMessage")}
257
+ </Text>
258
+ </div>
259
+ )}
260
+
261
+ {scheduled.map((def) => (
262
+ <ScheduledRow key={def.id} def={def} />
263
+ ))}
264
+ </Container>
265
+ </SingleColumnPage>
266
+ )
267
+ }
268
+
269
+ export const Component = WorkflowScheduledList
@@ -1,35 +0,0 @@
1
- import {
2
- queryKeysFactory
3
- } from "./chunk-774WSTCC.mjs";
4
- import {
5
- sdk
6
- } from "./chunk-DTY37DDZ.mjs";
7
-
8
- // src/hooks/api/workflow-executions.tsx
9
- import { useQuery } from "@tanstack/react-query";
10
- var WORKFLOW_EXECUTIONS_QUERY_KEY = "workflow_executions";
11
- var workflowExecutionsQueryKeys = queryKeysFactory(
12
- WORKFLOW_EXECUTIONS_QUERY_KEY
13
- );
14
- var useWorkflowExecutions = (query, options) => {
15
- const { data, ...rest } = useQuery({
16
- queryFn: () => sdk.admin.workflowExecution.list(query),
17
- queryKey: workflowExecutionsQueryKeys.list(query),
18
- ...options
19
- });
20
- return { ...data, ...rest };
21
- };
22
- var useWorkflowExecution = (id, options) => {
23
- const { data, ...rest } = useQuery({
24
- queryFn: () => sdk.admin.workflowExecution.retrieve(id),
25
- queryKey: workflowExecutionsQueryKeys.detail(id),
26
- ...options
27
- });
28
- return { ...data, ...rest };
29
- };
30
-
31
- export {
32
- workflowExecutionsQueryKeys,
33
- useWorkflowExecutions,
34
- useWorkflowExecution
35
- };
@@ -1,73 +0,0 @@
1
- // src/routes/workflow-executions/constants.ts
2
- var STEP_IN_PROGRESS_STATES = [
3
- "compensating" /* COMPENSATING */,
4
- "invoking" /* INVOKING */
5
- ];
6
- var STEP_SKIPPED_STATES = [
7
- "skipped" /* SKIPPED */,
8
- "skipped_failure" /* SKIPPED_FAILURE */
9
- ];
10
- var STEP_OK_STATES = [
11
- "done" /* DONE */
12
- ];
13
- var STEP_ERROR_STATES = [
14
- "failed" /* FAILED */,
15
- "reverted" /* REVERTED */,
16
- "timeout" /* TIMEOUT */,
17
- "dormant" /* DORMANT */
18
- ];
19
- var STEP_INACTIVE_STATES = [
20
- "not_started" /* NOT_STARTED */
21
- ];
22
- var TRANSACTION_OK_STATES = [
23
- "done" /* DONE */
24
- ];
25
- var TRANSACTION_ERROR_STATES = [
26
- "failed" /* FAILED */,
27
- "reverted" /* REVERTED */
28
- ];
29
- var TRANSACTION_IN_PROGRESS_STATES = [
30
- "invoking" /* INVOKING */,
31
- "waiting_to_compensate" /* WAITING_TO_COMPENSATE */,
32
- "compensating" /* COMPENSATING */
33
- ];
34
-
35
- // src/routes/workflow-executions/utils.ts
36
- var getTransactionStateColor = (state) => {
37
- let statusColor = "green";
38
- if (TRANSACTION_ERROR_STATES.includes(state)) {
39
- statusColor = "red";
40
- }
41
- if (TRANSACTION_IN_PROGRESS_STATES.includes(state)) {
42
- statusColor = "orange";
43
- }
44
- return statusColor;
45
- };
46
- var getTransactionState = (t, state) => {
47
- switch (state) {
48
- case "done" /* DONE */:
49
- return t("workflowExecutions.state.done");
50
- case "failed" /* FAILED */:
51
- return t("workflowExecutions.state.failed");
52
- case "reverted" /* REVERTED */:
53
- return t("workflowExecutions.state.reverted");
54
- case "invoking" /* INVOKING */:
55
- return t("workflowExecutions.state.invoking");
56
- case "waiting_to_compensate" /* WAITING_TO_COMPENSATE */:
57
- return t("workflowExecutions.transaction.state.waitingToCompensate");
58
- case "compensating" /* COMPENSATING */:
59
- return t("workflowExecutions.state.compensating");
60
- case "not_started" /* NOT_STARTED */:
61
- return t("workflowExecutions.state.notStarted");
62
- }
63
- };
64
-
65
- export {
66
- STEP_IN_PROGRESS_STATES,
67
- STEP_SKIPPED_STATES,
68
- STEP_OK_STATES,
69
- STEP_ERROR_STATES,
70
- STEP_INACTIVE_STATES,
71
- getTransactionStateColor,
72
- getTransactionState
73
- };