@acmekit/dashboard 2.13.35 → 2.13.37

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-U37VC624.mjs → api-key-management-create-4AG76FJV.mjs} +3 -3
  2. package/dist/{api-key-management-detail-ZYKL4ATI.mjs → api-key-management-detail-T2TB4KST.mjs} +10 -10
  3. package/dist/{api-key-management-edit-TSZGMIBL.mjs → api-key-management-edit-R44OHS7B.mjs} +3 -3
  4. package/dist/{api-key-management-list-HCJFJWWB.mjs → api-key-management-list-QK4Q7Y5I.mjs} +3 -3
  5. package/dist/app.css +0 -31
  6. package/dist/app.js +1386 -3726
  7. package/dist/app.mjs +38 -240
  8. package/dist/{chunk-VEI6HW6L.mjs → chunk-2U3RK3JG.mjs} +5 -3
  9. package/dist/{chunk-FKTMBR44.mjs → chunk-DN3MIYQH.mjs} +1 -1
  10. package/dist/{chunk-7F3CWXUH.mjs → chunk-DQCEH3X2.mjs} +1 -1
  11. package/dist/{chunk-YKIWIMJX.mjs → chunk-DTY37DDZ.mjs} +0 -1
  12. package/dist/{chunk-PFZQYK7R.mjs → chunk-EFRMWHRX.mjs} +1 -1
  13. package/dist/{chunk-5IEHCYJO.mjs → chunk-GBFVWROS.mjs} +1 -1
  14. package/dist/chunk-LKWTBYYC.mjs +35 -0
  15. package/dist/chunk-RPAL6FHW.mjs +73 -0
  16. package/dist/{chunk-WLRJXEKL.mjs → chunk-ST2YB7JN.mjs} +1 -1
  17. package/dist/{chunk-XIP35KXF.mjs → chunk-ULSPL3DR.mjs} +1 -1
  18. package/dist/{chunk-SYACY6AL.mjs → chunk-XIM7X4FB.mjs} +1 -1
  19. package/dist/{chunk-HHPPTD3B.mjs → chunk-YRWSG3YM.mjs} +1 -1
  20. package/dist/en.json +3 -132
  21. package/dist/{invite-3JSNOA2B.mjs → invite-XGPZZBUP.mjs} +3 -3
  22. package/dist/{login-BEJ5EFGE.mjs → login-GNP3QIPI.mjs} +9 -9
  23. package/dist/{profile-detail-QVTJC4JC.mjs → profile-detail-YX27F7N6.mjs} +3 -3
  24. package/dist/{profile-edit-MIO62TWH.mjs → profile-edit-2VRDU75O.mjs} +3 -3
  25. package/dist/{reset-password-BN4KAJQL.mjs → reset-password-TWRNZO6Z.mjs} +2 -2
  26. package/dist/{settings-GH5IWXHE.mjs → settings-3XWLL5LG.mjs} +3 -3
  27. package/dist/{translation-list-JA22BUKN.mjs → translation-list-CCEQJNED.mjs} +10 -10
  28. package/dist/{translations-edit-STTMANVT.mjs → translations-edit-E57GVUFV.mjs} +11 -11
  29. package/dist/{user-detail-WCXBFRGS.mjs → user-detail-KUSRRVNX.mjs} +3 -3
  30. package/dist/{user-edit-XDVMJOS4.mjs → user-edit-HTN3ZGCL.mjs} +3 -3
  31. package/dist/{user-invite-73ZDSDFC.mjs → user-invite-E3FAAU3V.mjs} +3 -3
  32. package/dist/{user-list-MPJXE3CA.mjs → user-list-KNJ5S3IM.mjs} +5 -5
  33. package/dist/{user-metadata-ADNTL3LT.mjs → user-metadata-5GQK75DT.mjs} +10 -10
  34. package/dist/workflow-execution-detail-5O5VCXL3.mjs +870 -0
  35. package/dist/workflow-execution-list-DETG4MRT.mjs +347 -0
  36. package/package.json +9 -9
  37. package/src/components/layout/main-layout/main-layout.tsx +1 -28
  38. package/src/dashboard-app/routes/get-route.map.tsx +0 -71
  39. package/src/hooks/api/workflow-executions.tsx +1 -145
  40. package/src/i18n/translations/$schema.json +4 -534
  41. package/src/i18n/translations/en.json +3 -132
  42. package/src/routes/workflow-executions/constants.ts +0 -16
  43. package/src/routes/workflow-executions/utils.ts +14 -170
  44. package/src/routes/workflow-executions/workflow-execution-detail/breadcrumb.tsx +1 -7
  45. package/src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-history-section/workflow-execution-history-section.tsx +6 -157
  46. package/src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-payload-section/workflow-execution-payload-section.tsx +6 -122
  47. package/src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-timeline-section/workflow-execution-timeline-section.tsx +1 -7
  48. package/src/routes/workflow-executions/workflow-execution-detail/workflow-detail.tsx +1 -46
  49. package/src/routes/workflow-executions/workflow-execution-list/components/workflow-execution-list-table/use-workflow-execution-table-columns.tsx +0 -7
  50. package/src/routes/workflow-executions/workflow-execution-list/components/workflow-execution-list-table/use-workflow-execution-table-filters.tsx +1 -7
  51. package/src/routes/workflow-executions/workflow-execution-list/components/workflow-execution-list-table/use-workflow-execution-table-query.tsx +2 -4
  52. package/src/routes/workflow-executions/workflow-execution-list/components/workflow-execution-list-table/workflow-execution-list-table.tsx +1 -17
  53. package/src/routes/workflow-executions/workflow-execution-list/workflow-execution-list.tsx +1 -1
  54. package/dist/chunk-A7ULKHDE.mjs +0 -126
  55. package/dist/chunk-GBPAZAJK.mjs +0 -34
  56. package/dist/chunk-LP6CPB7N.mjs +0 -213
  57. package/dist/workflow-analytics-4WCI4ODQ.mjs +0 -152
  58. package/dist/workflow-definition-detail-GI6CFBMG.mjs +0 -94
  59. package/dist/workflow-definition-list-GF3XAEPS.mjs +0 -142
  60. package/dist/workflow-execution-complete-step-WSRLO572.mjs +0 -245
  61. package/dist/workflow-execution-detail-3RH6EQSS.mjs +0 -1411
  62. package/dist/workflow-execution-list-AQEGAME4.mjs +0 -596
  63. package/dist/workflow-execution-rerun-WCYLYL3Q.mjs +0 -138
  64. package/dist/workflow-execution-run-MWN5KWNY.mjs +0 -135
  65. package/dist/workflow-scheduled-list-ZPXR7CZM.mjs +0 -174
  66. package/src/hooks/api/workflow-definitions.tsx +0 -79
  67. package/src/hooks/api/workflow-metrics.tsx +0 -48
  68. package/src/hooks/use-workflow-sse.tsx +0 -78
  69. package/src/routes/workflow-analytics/workflow-analytics.tsx +0 -167
  70. package/src/routes/workflow-definitions/workflow-definition-detail/workflow-definition-detail.tsx +0 -98
  71. package/src/routes/workflow-definitions/workflow-definition-list/components/workflow-definition-list-table/use-workflow-definition-table-columns.tsx +0 -78
  72. package/src/routes/workflow-definitions/workflow-definition-list/components/workflow-definition-list-table/workflow-definition-list-table.tsx +0 -65
  73. package/src/routes/workflow-definitions/workflow-definition-list/workflow-definition-list.tsx +0 -15
  74. package/src/routes/workflow-executions/workflow-execution-complete-step/workflow-execution-complete-step.tsx +0 -270
  75. package/src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-action-bar/index.ts +0 -1
  76. package/src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-action-bar/workflow-execution-action-bar.tsx +0 -212
  77. package/src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-error-card/index.ts +0 -1
  78. package/src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-error-card/workflow-execution-error-card.tsx +0 -59
  79. package/src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-waiting-banner/index.ts +0 -1
  80. package/src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-waiting-banner/workflow-execution-waiting-banner.tsx +0 -63
  81. package/src/routes/workflow-executions/workflow-execution-list/components/workflow-execution-list-table/workflow-execution-auto-refresh.tsx +0 -73
  82. package/src/routes/workflow-executions/workflow-execution-list/components/workflow-execution-list-table/workflow-execution-row-actions.tsx +0 -116
  83. package/src/routes/workflow-executions/workflow-execution-list/components/workflow-execution-list-table/workflow-execution-saved-views.tsx +0 -84
  84. package/src/routes/workflow-executions/workflow-execution-rerun/workflow-execution-rerun.tsx +0 -159
  85. package/src/routes/workflow-executions/workflow-execution-run/workflow-execution-run.tsx +0 -139
  86. package/src/routes/workflow-scheduled/workflow-scheduled-list.tsx +0 -269
  87. /package/dist/{chunk-RISX76YT.mjs → chunk-22YYMH6M.mjs} +0 -0
@@ -1,138 +0,0 @@
1
- import {
2
- useRunWorkflow,
3
- useWorkflowExecution
4
- } from "./chunk-A7ULKHDE.mjs";
5
- import "./chunk-IUCDCPJU.mjs";
6
- import {
7
- KeyboundForm,
8
- RouteDrawer,
9
- useRouteModal
10
- } from "./chunk-VEI6HW6L.mjs";
11
- import {
12
- Form
13
- } from "./chunk-ND3ODI36.mjs";
14
- import "./chunk-FXYH54JP.mjs";
15
- import "./chunk-774WSTCC.mjs";
16
- import "./chunk-YKIWIMJX.mjs";
17
- import "./chunk-QZ7TP4HQ.mjs";
18
-
19
- // src/routes/workflow-executions/workflow-execution-rerun/workflow-execution-rerun.tsx
20
- import { zodResolver } from "@hookform/resolvers/zod";
21
- import { Button, Heading, Textarea, toast } from "@acmekit/ui";
22
- import { useForm } from "react-hook-form";
23
- import { useTranslation } from "react-i18next";
24
- import { useParams } from "react-router-dom";
25
- import * as zod from "zod";
26
- import { jsx, jsxs } from "react/jsx-runtime";
27
- var RerunSchema = zod.object({
28
- input: zod.string().refine(
29
- (val) => {
30
- try {
31
- JSON.parse(val);
32
- return true;
33
- } catch {
34
- return false;
35
- }
36
- },
37
- { message: "Must be valid JSON" }
38
- )
39
- });
40
- var WorkflowExecutionRerun = () => {
41
- const { t } = useTranslation();
42
- const { id } = useParams();
43
- const { handleSuccess } = useRouteModal();
44
- const {
45
- workflow_execution,
46
- isPending: isLoading,
47
- isError,
48
- error
49
- } = useWorkflowExecution(id);
50
- if (isError) {
51
- throw error;
52
- }
53
- if (isLoading || !workflow_execution) {
54
- return /* @__PURE__ */ jsx(RouteDrawer, { children: /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(Heading, { children: t("workflowExecutions.rerun.title") }) }) });
55
- }
56
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
57
- /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(Heading, { children: t("workflowExecutions.rerun.title") }) }),
58
- /* @__PURE__ */ jsx(
59
- RerunForm,
60
- {
61
- workflowId: workflow_execution.workflow_id,
62
- defaultInput: workflow_execution?.context?.data?.payload || {},
63
- onSuccess: handleSuccess
64
- }
65
- )
66
- ] });
67
- };
68
- var RerunForm = ({
69
- workflowId,
70
- defaultInput,
71
- onSuccess
72
- }) => {
73
- const { t } = useTranslation();
74
- const form = useForm({
75
- defaultValues: {
76
- input: JSON.stringify(defaultInput, null, 2)
77
- },
78
- resolver: zodResolver(RerunSchema)
79
- });
80
- const { mutateAsync, isPending } = useRunWorkflow(workflowId);
81
- const handleSubmit = form.handleSubmit(async (values) => {
82
- const parsed = JSON.parse(values.input);
83
- await mutateAsync(
84
- { input: parsed },
85
- {
86
- onSuccess: () => {
87
- toast.success(t("workflowExecutions.rerun.success"));
88
- onSuccess();
89
- },
90
- onError: (err) => {
91
- toast.error(err.message);
92
- }
93
- }
94
- );
95
- });
96
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
97
- KeyboundForm,
98
- {
99
- onSubmit: handleSubmit,
100
- className: "flex flex-1 flex-col overflow-hidden",
101
- children: [
102
- /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex max-w-full flex-1 flex-col gap-y-4 overflow-y-auto", children: [
103
- /* @__PURE__ */ jsx("div", { className: "bg-ui-bg-field border-ui-border-base rounded-lg border px-3 py-2", children: /* @__PURE__ */ jsx("span", { className: "txt-compact-small text-ui-fg-muted", children: workflowId }) }),
104
- /* @__PURE__ */ jsx(
105
- Form.Field,
106
- {
107
- control: form.control,
108
- name: "input",
109
- render: ({ field }) => {
110
- return /* @__PURE__ */ jsxs(Form.Item, { children: [
111
- /* @__PURE__ */ jsx(Form.Label, { children: t("workflowExecutions.rerun.inputLabel") }),
112
- /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(
113
- Textarea,
114
- {
115
- ...field,
116
- className: "font-mono text-xs",
117
- rows: 16
118
- }
119
- ) }),
120
- /* @__PURE__ */ jsx(Form.ErrorMessage, {})
121
- ] });
122
- }
123
- }
124
- )
125
- ] }),
126
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
127
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: t("actions.cancel") }) }),
128
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: t("workflowExecutions.rerun.submit") })
129
- ] }) })
130
- ]
131
- }
132
- ) });
133
- };
134
- var Component = WorkflowExecutionRerun;
135
- export {
136
- Component,
137
- WorkflowExecutionRerun
138
- };
@@ -1,135 +0,0 @@
1
- import {
2
- useRunWorkflow
3
- } from "./chunk-A7ULKHDE.mjs";
4
- import "./chunk-IUCDCPJU.mjs";
5
- import {
6
- KeyboundForm,
7
- RouteDrawer,
8
- useRouteModal
9
- } from "./chunk-VEI6HW6L.mjs";
10
- import {
11
- Form
12
- } from "./chunk-ND3ODI36.mjs";
13
- import "./chunk-FXYH54JP.mjs";
14
- import "./chunk-774WSTCC.mjs";
15
- import "./chunk-YKIWIMJX.mjs";
16
- import "./chunk-QZ7TP4HQ.mjs";
17
-
18
- // src/routes/workflow-executions/workflow-execution-run/workflow-execution-run.tsx
19
- import { zodResolver } from "@hookform/resolvers/zod";
20
- import { Button, Heading, Input, Textarea, toast } from "@acmekit/ui";
21
- import { useForm } from "react-hook-form";
22
- import { useTranslation } from "react-i18next";
23
- import * as zod from "zod";
24
- import { jsx, jsxs } from "react/jsx-runtime";
25
- var RunWorkflowSchema = zod.object({
26
- workflow_id: zod.string().min(1, "Workflow ID is required"),
27
- input: zod.string().refine(
28
- (val) => {
29
- if (!val.trim()) return true;
30
- try {
31
- JSON.parse(val);
32
- return true;
33
- } catch {
34
- return false;
35
- }
36
- },
37
- { message: "Must be valid JSON" }
38
- )
39
- });
40
- var WorkflowExecutionRun = () => {
41
- const { t } = useTranslation();
42
- const { handleSuccess } = useRouteModal();
43
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
44
- /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(Heading, { children: t("workflowExecutions.actions.runWorkflow") }) }),
45
- /* @__PURE__ */ jsx(RunWorkflowForm, { onSuccess: handleSuccess })
46
- ] });
47
- };
48
- var RunWorkflowForm = ({ onSuccess }) => {
49
- const { t } = useTranslation();
50
- const form = useForm({
51
- defaultValues: {
52
- workflow_id: "",
53
- input: "{}"
54
- },
55
- resolver: zodResolver(RunWorkflowSchema)
56
- });
57
- const workflowId = form.watch("workflow_id");
58
- const { mutateAsync, isPending } = useRunWorkflow(workflowId || "_placeholder");
59
- const handleSubmit = form.handleSubmit(async (values) => {
60
- const parsed = values.input.trim() ? JSON.parse(values.input) : {};
61
- await mutateAsync(
62
- { input: parsed },
63
- {
64
- onSuccess: () => {
65
- toast.success(t("workflowExecutions.rerun.success"));
66
- onSuccess();
67
- },
68
- onError: (err) => {
69
- toast.error(err.message);
70
- }
71
- }
72
- );
73
- });
74
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
75
- KeyboundForm,
76
- {
77
- onSubmit: handleSubmit,
78
- className: "flex flex-1 flex-col overflow-hidden",
79
- children: [
80
- /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex max-w-full flex-1 flex-col gap-y-4 overflow-y-auto", children: [
81
- /* @__PURE__ */ jsx(
82
- Form.Field,
83
- {
84
- control: form.control,
85
- name: "workflow_id",
86
- render: ({ field }) => {
87
- return /* @__PURE__ */ jsxs(Form.Item, { children: [
88
- /* @__PURE__ */ jsx(Form.Label, { children: t("workflowExecutions.workflowIdLabel") }),
89
- /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(
90
- Input,
91
- {
92
- ...field,
93
- placeholder: "my-workflow-id"
94
- }
95
- ) }),
96
- /* @__PURE__ */ jsx(Form.ErrorMessage, {})
97
- ] });
98
- }
99
- }
100
- ),
101
- /* @__PURE__ */ jsx(
102
- Form.Field,
103
- {
104
- control: form.control,
105
- name: "input",
106
- render: ({ field }) => {
107
- return /* @__PURE__ */ jsxs(Form.Item, { children: [
108
- /* @__PURE__ */ jsx(Form.Label, { children: t("workflowExecutions.rerun.inputLabel") }),
109
- /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(
110
- Textarea,
111
- {
112
- ...field,
113
- className: "font-mono text-xs",
114
- rows: 12
115
- }
116
- ) }),
117
- /* @__PURE__ */ jsx(Form.ErrorMessage, {})
118
- ] });
119
- }
120
- }
121
- )
122
- ] }),
123
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
124
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: t("actions.cancel") }) }),
125
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: t("workflowExecutions.rerun.submit") })
126
- ] }) })
127
- ]
128
- }
129
- ) });
130
- };
131
- var Component = WorkflowExecutionRun;
132
- export {
133
- Component,
134
- WorkflowExecutionRun
135
- };
@@ -1,174 +0,0 @@
1
- import {
2
- useWorkflowDefinitions
3
- } from "./chunk-GBPAZAJK.mjs";
4
- import {
5
- SingleColumnPage
6
- } from "./chunk-RISX76YT.mjs";
7
- import {
8
- useRunWorkflow
9
- } from "./chunk-A7ULKHDE.mjs";
10
- import "./chunk-FXYH54JP.mjs";
11
- import "./chunk-774WSTCC.mjs";
12
- import "./chunk-YKIWIMJX.mjs";
13
- import "./chunk-QZ7TP4HQ.mjs";
14
-
15
- // src/routes/workflow-scheduled/workflow-scheduled-list.tsx
16
- import { Badge, Button, Container, Heading, Text, toast } from "@acmekit/ui";
17
- import { keepPreviousData } from "@tanstack/react-query";
18
- import { formatDistanceToNow } from "date-fns";
19
- import { useTranslation } from "react-i18next";
20
- import { jsx, jsxs } from "react/jsx-runtime";
21
- function describeCron(cron) {
22
- const parts = cron.trim().split(/\s+/);
23
- if (parts.length < 5) return cron;
24
- const [minute, hour, dom, month, dow] = parts;
25
- if (minute === "*" && hour === "*" && dom === "*" && month === "*" && dow === "*") {
26
- return "Every minute";
27
- }
28
- if (minute !== "*" && hour === "*" && dom === "*" && month === "*" && dow === "*") {
29
- return `Every hour at minute ${minute}`;
30
- }
31
- if (minute !== "*" && hour !== "*" && dom === "*" && month === "*" && dow === "*") {
32
- const h = parseInt(hour, 10);
33
- const m = parseInt(minute, 10);
34
- const ampm = h >= 12 ? "PM" : "AM";
35
- const h12 = h % 12 || 12;
36
- return `Daily at ${h12}:${String(m).padStart(2, "0")} ${ampm}`;
37
- }
38
- if (minute !== "*" && hour !== "*" && dom === "*" && month === "*" && dow !== "*") {
39
- const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
40
- const dayNames = dow.split(",").map((d) => days[parseInt(d, 10)] ?? d).join(", ");
41
- const h = parseInt(hour, 10);
42
- const m = parseInt(minute, 10);
43
- const ampm = h >= 12 ? "PM" : "AM";
44
- const h12 = h % 12 || 12;
45
- return `${dayNames} at ${h12}:${String(m).padStart(2, "0")} ${ampm}`;
46
- }
47
- if (minute !== "*" && hour !== "*" && dom !== "*" && month === "*" && dow === "*") {
48
- return `Monthly on day ${dom} at ${hour}:${String(parseInt(minute, 10)).padStart(2, "0")}`;
49
- }
50
- return cron;
51
- }
52
- function getNextRunLabel(cron) {
53
- try {
54
- const parts = cron.trim().split(/\s+/);
55
- if (parts.length < 5) return "Unknown";
56
- const [minuteStr, hourStr] = parts;
57
- const now = /* @__PURE__ */ new Date();
58
- const next = new Date(now);
59
- if (minuteStr === "*") {
60
- next.setSeconds(0, 0);
61
- next.setMinutes(now.getMinutes() + 1);
62
- } else if (hourStr === "*") {
63
- const m = parseInt(minuteStr, 10);
64
- next.setMinutes(m, 0, 0);
65
- if (next <= now) next.setHours(now.getHours() + 1);
66
- } else {
67
- const h = parseInt(hourStr, 10);
68
- const m = parseInt(minuteStr, 10);
69
- next.setHours(h, m, 0, 0);
70
- if (next <= now) next.setDate(now.getDate() + 1);
71
- }
72
- return formatDistanceToNow(next, { addSuffix: true });
73
- } catch {
74
- return "Unknown";
75
- }
76
- }
77
- var ScheduledRow = ({ def }) => {
78
- const { t } = useTranslation();
79
- const schedule = def.options?.schedule;
80
- const cronStr = typeof schedule === "string" ? schedule : typeof schedule === "object" ? schedule?.cron ?? String(schedule?.interval ?? "") : "";
81
- const humanSchedule = cronStr ? describeCron(cronStr) : "\u2014";
82
- const nextRun = cronStr ? getNextRunLabel(cronStr) : "\u2014";
83
- const { mutateAsync: runWorkflow, isPending } = useRunWorkflow(def.id);
84
- const handleRunNow = async () => {
85
- await runWorkflow(
86
- { input: {} },
87
- {
88
- onSuccess: () => {
89
- toast.success(t("workflowExecutions.actions.retrySuccess"));
90
- }
91
- }
92
- );
93
- };
94
- return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_1fr_1fr_auto] items-center gap-x-4 px-6 py-3", children: [
95
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-0.5", children: [
96
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: def.id }),
97
- /* @__PURE__ */ jsxs(Text, { size: "xsmall", className: "text-ui-fg-muted", children: [
98
- def.handler_count,
99
- " ",
100
- t("workflowExecutions.definitions.handlers")
101
- ] })
102
- ] }),
103
- /* @__PURE__ */ jsxs("div", { children: [
104
- /* @__PURE__ */ jsx(Badge, { size: "2xsmall", className: "font-mono", children: cronStr || "\u2014" }),
105
- /* @__PURE__ */ jsx(Text, { size: "xsmall", className: "text-ui-fg-subtle mt-0.5", children: humanSchedule })
106
- ] }),
107
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: nextRun }),
108
- /* @__PURE__ */ jsx(
109
- Button,
110
- {
111
- size: "small",
112
- variant: "secondary",
113
- isLoading: isPending,
114
- onClick: handleRunNow,
115
- children: t("workflowExecutions.scheduled.runNow")
116
- }
117
- )
118
- ] });
119
- };
120
- var WorkflowScheduledList = () => {
121
- const { t } = useTranslation();
122
- const { workflow_definitions, isPending } = useWorkflowDefinitions(
123
- void 0,
124
- { placeholderData: keepPreviousData }
125
- );
126
- const scheduled = (workflow_definitions ?? []).filter((def) => {
127
- const opts = def.options;
128
- return opts && (opts.schedule || opts.cron);
129
- });
130
- return /* @__PURE__ */ jsx(SingleColumnPage, { widgets: { before: [], after: [] }, children: /* @__PURE__ */ jsxs(Container, { className: "divide-y p-0", children: [
131
- /* @__PURE__ */ jsx("div", { className: "flex items-center justify-between px-6 py-4", children: /* @__PURE__ */ jsxs("div", { children: [
132
- /* @__PURE__ */ jsx(Heading, { children: t("workflowExecutions.scheduled.domain") }),
133
- /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", size: "small", children: t("workflowExecutions.scheduled.subtitle") })
134
- ] }) }),
135
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_1fr_1fr_auto] gap-x-4 border-b border-ui-border-base px-6 py-2", children: [
136
- /* @__PURE__ */ jsx(
137
- Text,
138
- {
139
- size: "xsmall",
140
- weight: "plus",
141
- className: "text-ui-fg-subtle uppercase",
142
- children: "Workflow"
143
- }
144
- ),
145
- /* @__PURE__ */ jsx(
146
- Text,
147
- {
148
- size: "xsmall",
149
- weight: "plus",
150
- className: "text-ui-fg-subtle uppercase",
151
- children: t("workflowExecutions.scheduled.schedule")
152
- }
153
- ),
154
- /* @__PURE__ */ jsx(
155
- Text,
156
- {
157
- size: "xsmall",
158
- weight: "plus",
159
- className: "text-ui-fg-subtle uppercase",
160
- children: t("workflowExecutions.scheduled.nextRun")
161
- }
162
- ),
163
- /* @__PURE__ */ jsx("div", {})
164
- ] }),
165
- isPending && /* @__PURE__ */ jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Loading..." }) }),
166
- !isPending && scheduled.length === 0 && /* @__PURE__ */ jsx("div", { className: "px-6 py-8 text-center", children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: t("workflowExecutions.scheduled.noRecordsMessage") }) }),
167
- scheduled.map((def) => /* @__PURE__ */ jsx(ScheduledRow, { def }, def.id))
168
- ] }) });
169
- };
170
- var Component = WorkflowScheduledList;
171
- export {
172
- Component,
173
- WorkflowScheduledList
174
- };
@@ -1,79 +0,0 @@
1
- import { QueryKey, UseQueryOptions, useQuery } from "@tanstack/react-query"
2
- import { sdk } from "../../lib/client"
3
- import { queryKeysFactory } from "../../lib/query-key-factory"
4
- import { FetchError } from "@acmekit/js-sdk"
5
-
6
- export type WorkflowDefinitionResponse = {
7
- workflow_definitions: Array<{
8
- id: string
9
- handler_count: number
10
- steps: Array<{
11
- action: string
12
- depth: number
13
- noCompensation: boolean
14
- }>
15
- options: Record<string, unknown>
16
- }>
17
- count: number
18
- }
19
-
20
- export type WorkflowDefinitionDetailResponse = {
21
- workflow_definition: {
22
- id: string
23
- handler_count: number
24
- steps: Array<{
25
- action: string
26
- depth: number
27
- noCompensation: boolean
28
- }>
29
- flow: Record<string, unknown> | null
30
- options: Record<string, unknown>
31
- }
32
- }
33
-
34
- const WORKFLOW_DEFINITIONS_QUERY_KEY = "workflow_definitions" as const
35
- export const workflowDefinitionsQueryKeys = queryKeysFactory(
36
- WORKFLOW_DEFINITIONS_QUERY_KEY
37
- )
38
-
39
- export const useWorkflowDefinitions = (
40
- query?: Record<string, unknown>,
41
- options?: Omit<
42
- UseQueryOptions<
43
- WorkflowDefinitionResponse,
44
- FetchError,
45
- WorkflowDefinitionResponse,
46
- QueryKey
47
- >,
48
- "queryKey" | "queryFn"
49
- >
50
- ) => {
51
- const { data, ...rest } = useQuery({
52
- queryFn: () => sdk.admin.workflowDefinition.list(query),
53
- queryKey: workflowDefinitionsQueryKeys.list(query),
54
- ...options,
55
- })
56
-
57
- return { ...data, ...rest }
58
- }
59
-
60
- export const useWorkflowDefinition = (
61
- id: string,
62
- options?: Omit<
63
- UseQueryOptions<
64
- WorkflowDefinitionDetailResponse,
65
- FetchError,
66
- WorkflowDefinitionDetailResponse,
67
- QueryKey
68
- >,
69
- "queryKey" | "queryFn"
70
- >
71
- ) => {
72
- const { data, ...rest } = useQuery({
73
- queryFn: () => sdk.admin.workflowDefinition.retrieve(id),
74
- queryKey: workflowDefinitionsQueryKeys.detail(id),
75
- ...options,
76
- })
77
-
78
- return { ...data, ...rest }
79
- }
@@ -1,48 +0,0 @@
1
- import { QueryKey, UseQueryOptions, useQuery } from "@tanstack/react-query"
2
- import { sdk } from "../../lib/client"
3
- import { queryKeysFactory } from "../../lib/query-key-factory"
4
- import { FetchError } from "@acmekit/js-sdk"
5
-
6
- export type WorkflowMetricsResponse = {
7
- total_24h: number
8
- success_rate_24h: number
9
- avg_duration_ms_24h: number
10
- running_now: number
11
- per_workflow: Array<{
12
- workflow_id: string
13
- runs: number
14
- success_rate: number
15
- avg_duration_ms: number
16
- }>
17
- }
18
-
19
- const WORKFLOW_METRICS_QUERY_KEY = "workflow_metrics" as const
20
- export const workflowMetricsQueryKeys = queryKeysFactory(
21
- WORKFLOW_METRICS_QUERY_KEY
22
- )
23
-
24
- export const useWorkflowMetrics = (
25
- options?: Omit<
26
- UseQueryOptions<
27
- WorkflowMetricsResponse,
28
- FetchError,
29
- WorkflowMetricsResponse,
30
- QueryKey
31
- >,
32
- "queryKey" | "queryFn"
33
- >
34
- ) => {
35
- const { data, ...rest } = useQuery({
36
- queryFn: async () => {
37
- const result = await sdk.client.fetch<WorkflowMetricsResponse>(
38
- "/admin/workflows-executions/metrics"
39
- )
40
- return result as unknown as WorkflowMetricsResponse
41
- },
42
- queryKey: workflowMetricsQueryKeys.all,
43
- refetchInterval: 30000,
44
- ...options,
45
- })
46
-
47
- return { ...data, ...rest }
48
- }
@@ -1,78 +0,0 @@
1
- import { useEffect, useRef, useState } from "react"
2
- import { backendUrl } from "../lib/client"
3
-
4
- export interface WorkflowSSEEvent {
5
- event_type: string
6
- workflow_id: string
7
- transaction_id: string
8
- step?: Record<string, unknown>
9
- response?: Record<string, unknown>
10
- result?: Record<string, unknown>
11
- errors?: Array<Record<string, unknown>>
12
- }
13
-
14
- interface UseWorkflowSSEOptions {
15
- enabled?: boolean
16
- onEvent?: (event: WorkflowSSEEvent) => void
17
- }
18
-
19
- export const useWorkflowSSE = (
20
- workflowId: string | undefined,
21
- options?: UseWorkflowSSEOptions
22
- ) => {
23
- const { enabled = true, onEvent } = options || {}
24
- const [isConnected, setIsConnected] = useState(false)
25
- const eventSourceRef = useRef<EventSource | null>(null)
26
- const onEventRef = useRef(onEvent)
27
- onEventRef.current = onEvent
28
-
29
- useEffect(() => {
30
- if (!enabled || !workflowId) {
31
- if (eventSourceRef.current) {
32
- eventSourceRef.current.close()
33
- eventSourceRef.current = null
34
- setIsConnected(false)
35
- }
36
- return
37
- }
38
-
39
- const base = backendUrl === "/" ? "" : backendUrl
40
- const url = `${base}/admin/workflows-executions/${workflowId}/subscribe`
41
-
42
- const es = new EventSource(url, { withCredentials: true })
43
- eventSourceRef.current = es
44
-
45
- es.onopen = () => {
46
- setIsConnected(true)
47
- }
48
-
49
- es.onmessage = (e) => {
50
- try {
51
- const data = JSON.parse(e.data) as WorkflowSSEEvent
52
- onEventRef.current?.(data)
53
- } catch {
54
- // ignore parse errors
55
- }
56
- }
57
-
58
- es.onerror = () => {
59
- setIsConnected(false)
60
- }
61
-
62
- return () => {
63
- es.close()
64
- eventSourceRef.current = null
65
- setIsConnected(false)
66
- }
67
- }, [enabled, workflowId])
68
-
69
- const disconnect = () => {
70
- if (eventSourceRef.current) {
71
- eventSourceRef.current.close()
72
- eventSourceRef.current = null
73
- setIsConnected(false)
74
- }
75
- }
76
-
77
- return { isConnected, disconnect }
78
- }