@acmekit/dashboard 2.13.36 → 2.13.38

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 (49) 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 +6 -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/dist/chunk-A7ULKHDE.mjs +0 -126
  38. package/dist/chunk-GBPAZAJK.mjs +0 -34
  39. package/dist/chunk-LP6CPB7N.mjs +0 -213
  40. package/dist/workflow-analytics-4WCI4ODQ.mjs +0 -152
  41. package/dist/workflow-definition-detail-GI6CFBMG.mjs +0 -94
  42. package/dist/workflow-definition-list-GF3XAEPS.mjs +0 -142
  43. package/dist/workflow-execution-complete-step-WSRLO572.mjs +0 -245
  44. package/dist/workflow-execution-detail-3RH6EQSS.mjs +0 -1411
  45. package/dist/workflow-execution-list-AQEGAME4.mjs +0 -596
  46. package/dist/workflow-execution-rerun-WCYLYL3Q.mjs +0 -138
  47. package/dist/workflow-execution-run-MWN5KWNY.mjs +0 -135
  48. package/dist/workflow-scheduled-list-ZPXR7CZM.mjs +0 -174
  49. /package/dist/{chunk-RISX76YT.mjs → chunk-22YYMH6M.mjs} +0 -0
@@ -1,1411 +0,0 @@
1
- import {
2
- STEP_ERROR_STATES,
3
- STEP_INACTIVE_STATES,
4
- STEP_IN_PROGRESS_STATES,
5
- STEP_OK_STATES,
6
- STEP_SKIPPED_STATES,
7
- TRANSACTION_ACTIVE_STATES,
8
- TRANSACTION_ERROR_STATES,
9
- TRANSACTION_IN_PROGRESS_STATES,
10
- computeIdempotencyKey,
11
- formatStepDuration,
12
- getFailedSteps,
13
- getTransactionState,
14
- getTransactionStateColor,
15
- getWaitingSteps,
16
- isTerminalState,
17
- mergeStepEvent
18
- } from "./chunk-LP6CPB7N.mjs";
19
- import {
20
- useDate
21
- } from "./chunk-DFFLVEZ5.mjs";
22
- import "./chunk-535OVBXR.mjs";
23
- import {
24
- JsonViewSection,
25
- SingleColumnPage
26
- } from "./chunk-RISX76YT.mjs";
27
- import {
28
- useExtension
29
- } from "./chunk-C5P5PL3E.mjs";
30
- import {
31
- ActionMenu
32
- } from "./chunk-S3REQHPQ.mjs";
33
- import "./chunk-WLRJXEKL.mjs";
34
- import "./chunk-5IEHCYJO.mjs";
35
- import "./chunk-XIP35KXF.mjs";
36
- import "./chunk-PFZQYK7R.mjs";
37
- import {
38
- useCancelWorkflowExecution,
39
- useRetryStep,
40
- useRunWorkflow,
41
- useWorkflowExecution,
42
- workflowExecutionsQueryKeys
43
- } from "./chunk-A7ULKHDE.mjs";
44
- import "./chunk-FKTMBR44.mjs";
45
- import "./chunk-SYACY6AL.mjs";
46
- import {
47
- SingleColumnPageSkeleton
48
- } from "./chunk-ITNQKZQQ.mjs";
49
- import "./chunk-OAHCJFG3.mjs";
50
- import {
51
- useDocumentDirection
52
- } from "./chunk-S4DMV3ZT.mjs";
53
- import "./chunk-HHPPTD3B.mjs";
54
- import {
55
- queryClient
56
- } from "./chunk-FXYH54JP.mjs";
57
- import "./chunk-774WSTCC.mjs";
58
- import {
59
- backendUrl,
60
- sdk
61
- } from "./chunk-YKIWIMJX.mjs";
62
- import "./chunk-QZ7TP4HQ.mjs";
63
-
64
- // src/routes/workflow-executions/workflow-execution-detail/breadcrumb.tsx
65
- import { jsx, jsxs } from "react/jsx-runtime";
66
- var WorkflowExecutionDetailBreadcrumb = (props) => {
67
- const { id } = props.params || {};
68
- const { workflow_execution } = useWorkflowExecution(id, {
69
- initialData: props.data,
70
- enabled: Boolean(id)
71
- });
72
- if (!workflow_execution) {
73
- return null;
74
- }
75
- const cleanId = workflow_execution.id.replace("wf_exec_", "");
76
- return /* @__PURE__ */ jsxs("span", { children: [
77
- workflow_execution.workflow_id,
78
- /* @__PURE__ */ jsx("span", { className: "text-ui-fg-muted", children: " / " }),
79
- cleanId
80
- ] });
81
- };
82
-
83
- // src/routes/workflow-executions/workflow-execution-detail/loader.ts
84
- var executionDetailQuery = (id) => ({
85
- queryKey: workflowExecutionsQueryKeys.detail(id),
86
- queryFn: async () => sdk.admin.workflowExecution.retrieve(id)
87
- });
88
- var workflowExecutionLoader = async ({
89
- params
90
- }) => {
91
- const id = params.id;
92
- const query = executionDetailQuery(id);
93
- return queryClient.ensureQueryData(query);
94
- };
95
-
96
- // src/routes/workflow-executions/workflow-execution-detail/workflow-detail.tsx
97
- import { useParams } from "react-router-dom";
98
- import { useQueryClient } from "@tanstack/react-query";
99
-
100
- // src/hooks/use-workflow-sse.tsx
101
- import { useEffect, useRef, useState } from "react";
102
- var useWorkflowSSE = (workflowId, options) => {
103
- const { enabled = true, onEvent } = options || {};
104
- const [isConnected, setIsConnected] = useState(false);
105
- const eventSourceRef = useRef(null);
106
- const onEventRef = useRef(onEvent);
107
- onEventRef.current = onEvent;
108
- useEffect(() => {
109
- if (!enabled || !workflowId) {
110
- if (eventSourceRef.current) {
111
- eventSourceRef.current.close();
112
- eventSourceRef.current = null;
113
- setIsConnected(false);
114
- }
115
- return;
116
- }
117
- const base = backendUrl === "/" ? "" : backendUrl;
118
- const url = `${base}/admin/workflows-executions/${workflowId}/subscribe`;
119
- const es = new EventSource(url, { withCredentials: true });
120
- eventSourceRef.current = es;
121
- es.onopen = () => {
122
- setIsConnected(true);
123
- };
124
- es.onmessage = (e) => {
125
- try {
126
- const data = JSON.parse(e.data);
127
- onEventRef.current?.(data);
128
- } catch {
129
- }
130
- };
131
- es.onerror = () => {
132
- setIsConnected(false);
133
- };
134
- return () => {
135
- es.close();
136
- eventSourceRef.current = null;
137
- setIsConnected(false);
138
- };
139
- }, [enabled, workflowId]);
140
- const disconnect = () => {
141
- if (eventSourceRef.current) {
142
- eventSourceRef.current.close();
143
- eventSourceRef.current = null;
144
- setIsConnected(false);
145
- }
146
- };
147
- return { isConnected, disconnect };
148
- };
149
-
150
- // src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-action-bar/workflow-execution-action-bar.tsx
151
- import { ArrowPathMini, EllipsisHorizontal, XMark } from "@acmekit/icons";
152
- import {
153
- Badge,
154
- Button,
155
- Container,
156
- Copy,
157
- StatusBadge,
158
- toast,
159
- usePrompt
160
- } from "@acmekit/ui";
161
- import { useTranslation } from "react-i18next";
162
- import { Link } from "react-router-dom";
163
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
164
- var WorkflowExecutionActionBar = ({
165
- execution
166
- }) => {
167
- const { t } = useTranslation();
168
- const prompt = usePrompt();
169
- const state = execution.state;
170
- const stateColor = getTransactionStateColor(state);
171
- const translatedState = getTransactionState(t, state);
172
- const workflowId = execution.workflow_id;
173
- const transactionId = execution.transaction_id;
174
- const isFailed = TRANSACTION_ERROR_STATES.includes(state);
175
- const isRunning = TRANSACTION_IN_PROGRESS_STATES.includes(state);
176
- const waitingSteps = getWaitingSteps(execution);
177
- const hasWaitingSteps = waitingSteps.length > 0;
178
- const { mutateAsync: runAsync, isPending: isRunning_ } = useRunWorkflow(workflowId);
179
- const { mutateAsync: cancelAsync, isPending: isCancelling } = useCancelWorkflowExecution(workflowId, transactionId);
180
- const handleRetry = async () => {
181
- const payload = execution?.context?.data?.payload;
182
- const input = payload && typeof payload === "object" ? payload : {};
183
- await runAsync(
184
- { input },
185
- {
186
- onSuccess: () => {
187
- toast.success(t("workflowExecutions.actions.retrySuccess"));
188
- },
189
- onError: (err) => {
190
- toast.error(err.message);
191
- }
192
- }
193
- );
194
- };
195
- const handleCancel = async () => {
196
- const res = await prompt({
197
- title: t("workflowExecutions.actions.cancelConfirmTitle"),
198
- description: t("workflowExecutions.actions.cancelConfirmDescription", {
199
- workflow_id: workflowId
200
- }),
201
- confirmText: t("workflowExecutions.actions.cancel"),
202
- cancelText: t("actions.cancel")
203
- });
204
- if (!res) return;
205
- await cancelAsync(void 0, {
206
- onSuccess: () => {
207
- toast.success(t("workflowExecutions.actions.cancelSuccess"));
208
- },
209
- onError: (err) => {
210
- toast.error(err.message);
211
- }
212
- });
213
- };
214
- const handleExportJson = () => {
215
- const data = JSON.stringify(execution, null, 2);
216
- const blob = new Blob([data], { type: "application/json" });
217
- const url = URL.createObjectURL(blob);
218
- const a = document.createElement("a");
219
- a.href = url;
220
- a.download = `workflow-${workflowId}-${execution.id}.json`;
221
- a.click();
222
- URL.revokeObjectURL(url);
223
- };
224
- const handleExportCsv = () => {
225
- const steps = execution?.execution?.steps || {};
226
- const rows = [["Step", "State", "Duration"]];
227
- for (const [stepId, step] of Object.entries(steps)) {
228
- if (stepId === "_root") continue;
229
- const invokeState = step?.invoke?.state || "unknown";
230
- rows.push([stepId, invokeState, ""]);
231
- }
232
- const csv = rows.map((r) => r.join(",")).join("\n");
233
- const blob = new Blob([csv], { type: "text/csv" });
234
- const url = URL.createObjectURL(blob);
235
- const a = document.createElement("a");
236
- a.href = url;
237
- a.download = `workflow-${workflowId}-${execution.id}.csv`;
238
- a.click();
239
- URL.revokeObjectURL(url);
240
- };
241
- const cleanId = execution.id.replace("wf_exec_", "");
242
- return /* @__PURE__ */ jsx2(Container, { className: "sticky top-14 z-10 p-0", children: /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between px-6 py-3", children: [
243
- /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-x-3", children: [
244
- /* @__PURE__ */ jsx2(Copy, { content: workflowId, asChild: true, children: /* @__PURE__ */ jsx2(Badge, { size: "2xsmall", className: "cursor-pointer", children: workflowId }) }),
245
- /* @__PURE__ */ jsx2(StatusBadge, { color: stateColor, children: translatedState }),
246
- /* @__PURE__ */ jsx2(Copy, { content: execution.id, asChild: true, children: /* @__PURE__ */ jsx2(
247
- Badge,
248
- {
249
- size: "2xsmall",
250
- color: "grey",
251
- className: "cursor-pointer text-ui-fg-muted",
252
- children: cleanId
253
- }
254
- ) })
255
- ] }),
256
- /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-x-2", children: [
257
- isFailed && /* @__PURE__ */ jsxs2(
258
- Button,
259
- {
260
- variant: "secondary",
261
- size: "small",
262
- onClick: handleRetry,
263
- isLoading: isRunning_,
264
- children: [
265
- /* @__PURE__ */ jsx2(ArrowPathMini, { className: "mr-1" }),
266
- t("workflowExecutions.actions.retry")
267
- ]
268
- }
269
- ),
270
- isRunning && /* @__PURE__ */ jsxs2(
271
- Button,
272
- {
273
- variant: "danger",
274
- size: "small",
275
- onClick: handleCancel,
276
- isLoading: isCancelling,
277
- children: [
278
- /* @__PURE__ */ jsx2(XMark, { className: "mr-1" }),
279
- t("workflowExecutions.actions.cancel")
280
- ]
281
- }
282
- ),
283
- hasWaitingSteps && /* @__PURE__ */ jsx2(Button, { variant: "secondary", size: "small", asChild: true, children: /* @__PURE__ */ jsx2(Link, { to: "complete-step", children: t("workflowExecutions.actions.completeStep") }) }),
284
- /* @__PURE__ */ jsx2(
285
- ActionMenu,
286
- {
287
- groups: [
288
- {
289
- actions: [
290
- ...isFailed ? [
291
- {
292
- label: t(
293
- "workflowExecutions.actions.retryWithNewInput"
294
- ),
295
- icon: /* @__PURE__ */ jsx2(ArrowPathMini, {}),
296
- to: "rerun"
297
- }
298
- ] : [],
299
- {
300
- label: t("workflowExecutions.actions.exportJson"),
301
- icon: /* @__PURE__ */ jsx2(EllipsisHorizontal, {}),
302
- onClick: handleExportJson
303
- },
304
- {
305
- label: t("workflowExecutions.actions.exportCsv"),
306
- icon: /* @__PURE__ */ jsx2(EllipsisHorizontal, {}),
307
- onClick: handleExportCsv
308
- }
309
- ]
310
- }
311
- ]
312
- }
313
- )
314
- ] })
315
- ] }) });
316
- };
317
-
318
- // src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-error-card/workflow-execution-error-card.tsx
319
- import { XCircle } from "@acmekit/icons";
320
- import { Container as Container2, Heading, Text } from "@acmekit/ui";
321
- import { useTranslation as useTranslation2 } from "react-i18next";
322
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
323
- var WorkflowExecutionErrorCard = ({
324
- execution
325
- }) => {
326
- const { t } = useTranslation2();
327
- if (execution.state !== "failed" /* FAILED */) {
328
- return null;
329
- }
330
- const failedSteps = getFailedSteps(execution);
331
- if (failedSteps.length === 0) return null;
332
- const firstFailure = failedSteps[0];
333
- const errorMessage = firstFailure.error?.error?.message || firstFailure.error?.error || "Unknown error";
334
- const handlerType = firstFailure.error?.handlerType || "invoke";
335
- return /* @__PURE__ */ jsx3(Container2, { className: "border border-ui-tag-red-border bg-ui-tag-red-bg p-0", children: /* @__PURE__ */ jsxs3("div", { className: "flex items-start gap-x-3 px-6 py-4", children: [
336
- /* @__PURE__ */ jsx3("div", { className: "mt-0.5", children: /* @__PURE__ */ jsx3(XCircle, { className: "text-ui-tag-red-icon" }) }),
337
- /* @__PURE__ */ jsxs3("div", { className: "flex flex-1 flex-col gap-y-1", children: [
338
- /* @__PURE__ */ jsx3(Heading, { level: "h3", children: t("workflowExecutions.error.failureAtStep", {
339
- step: firstFailure.stepId
340
- }) }),
341
- /* @__PURE__ */ jsx3(Text, { size: "small", className: "text-ui-fg-subtle", children: String(errorMessage) }),
342
- /* @__PURE__ */ jsxs3(Text, { size: "xsmall", className: "text-ui-fg-muted", children: [
343
- handlerType === "compensate" ? "Compensation" : "Invoke",
344
- " failure"
345
- ] })
346
- ] }),
347
- /* @__PURE__ */ jsx3(
348
- "a",
349
- {
350
- href: `#${firstFailure.stepId}`,
351
- className: "text-ui-fg-interactive txt-compact-small-plus shrink-0 hover:underline",
352
- children: t("workflowExecutions.error.jumpToStep")
353
- }
354
- )
355
- ] }) });
356
- };
357
-
358
- // src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-waiting-banner/workflow-execution-waiting-banner.tsx
359
- import { ClockSolidMini } from "@acmekit/icons";
360
- import { Container as Container3, Copy as Copy2, Heading as Heading2, Text as Text2 } from "@acmekit/ui";
361
- import { useTranslation as useTranslation3 } from "react-i18next";
362
- import { Link as Link2 } from "react-router-dom";
363
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
364
- var WorkflowExecutionWaitingBanner = ({
365
- execution
366
- }) => {
367
- const { t } = useTranslation3();
368
- const waitingSteps = getWaitingSteps(execution);
369
- if (waitingSteps.length === 0) return null;
370
- const firstStep = waitingSteps[0];
371
- const idempotencyKey = computeIdempotencyKey(
372
- execution.workflow_id,
373
- execution.transaction_id,
374
- firstStep.stepId,
375
- "invoke"
376
- );
377
- return /* @__PURE__ */ jsx4(Container3, { className: "border border-ui-tag-purple-border bg-ui-tag-purple-bg p-0", children: /* @__PURE__ */ jsxs4("div", { className: "flex items-start gap-x-3 px-6 py-4", children: [
378
- /* @__PURE__ */ jsx4("div", { className: "mt-0.5", children: /* @__PURE__ */ jsx4(ClockSolidMini, { className: "text-ui-tag-purple-icon" }) }),
379
- /* @__PURE__ */ jsxs4("div", { className: "flex flex-1 flex-col gap-y-1", children: [
380
- /* @__PURE__ */ jsx4(Heading2, { level: "h3", children: t("workflowExecutions.asyncStep.waitingBanner") }),
381
- /* @__PURE__ */ jsx4(Text2, { size: "small", className: "text-ui-fg-subtle", children: t("workflowExecutions.asyncStep.waitingDescription", {
382
- step: firstStep.stepId
383
- }) }),
384
- /* @__PURE__ */ jsxs4("div", { className: "mt-1 flex items-center gap-x-2", children: [
385
- /* @__PURE__ */ jsxs4(Text2, { size: "xsmall", className: "text-ui-fg-muted", children: [
386
- t("workflowExecutions.asyncStep.idempotencyKey"),
387
- ":"
388
- ] }),
389
- /* @__PURE__ */ jsx4(Copy2, { content: idempotencyKey, asChild: true, children: /* @__PURE__ */ jsx4("code", { className: "bg-ui-bg-base txt-compact-xsmall cursor-pointer rounded px-1.5 py-0.5", children: idempotencyKey }) })
390
- ] })
391
- ] }),
392
- /* @__PURE__ */ jsx4(
393
- Link2,
394
- {
395
- to: "complete-step",
396
- className: "text-ui-fg-interactive txt-compact-small-plus shrink-0 hover:underline",
397
- children: t("workflowExecutions.actions.completeStep")
398
- }
399
- )
400
- ] }) });
401
- };
402
-
403
- // src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-general-section/workflow-execution-general-section.tsx
404
- import { Badge as Badge2, Container as Container4, Copy as Copy3, Heading as Heading3, StatusBadge as StatusBadge2, Text as Text3, clx } from "@acmekit/ui";
405
- import { useTranslation as useTranslation4 } from "react-i18next";
406
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
407
- var WorkflowExecutionGeneralSection = ({
408
- execution
409
- }) => {
410
- const { t } = useTranslation4();
411
- const { getFullDate } = useDate();
412
- const cleanId = execution.id.replace("wf_exec_", "");
413
- const translatedState = getTransactionState(
414
- t,
415
- execution.state
416
- );
417
- const stateColor = getTransactionStateColor(
418
- execution.state
419
- );
420
- const createdAt = execution.created_at;
421
- const updatedAt = execution.updated_at;
422
- const allSteps = Object.values(execution.execution?.steps || {}).filter(
423
- (step) => step.id !== ROOT_PREFIX
424
- );
425
- const totalSteps = allSteps.length;
426
- const completedSteps = allSteps.filter(
427
- (step) => step.invoke.state === "done" /* DONE */
428
- ).length;
429
- const failedSteps = allSteps.filter(
430
- (step) => STEP_ERROR_STATES.includes(step.invoke.state)
431
- ).length;
432
- const skippedSteps = allSteps.filter(
433
- (step) => STEP_SKIPPED_STATES.includes(step.invoke.state)
434
- ).length;
435
- const compensatedSteps = allSteps.filter(
436
- (step) => step.compensate.state === "reverted" /* REVERTED */
437
- ).length;
438
- return /* @__PURE__ */ jsxs5(Container4, { className: "divide-y p-0", children: [
439
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between px-6 py-4", children: [
440
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-x-0.5", children: [
441
- /* @__PURE__ */ jsx5(Heading3, { children: cleanId }),
442
- /* @__PURE__ */ jsx5(Copy3, { content: cleanId, className: "text-ui-fg-muted" })
443
- ] }),
444
- /* @__PURE__ */ jsx5(StatusBadge2, { color: stateColor, children: translatedState })
445
- ] }),
446
- /* @__PURE__ */ jsxs5("div", { className: "text-ui-fg-subtle grid grid-cols-2 px-6 py-4", children: [
447
- /* @__PURE__ */ jsx5(Text3, { size: "small", leading: "compact", weight: "plus", children: t("workflowExecutions.workflowIdLabel") }),
448
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-x-1", children: [
449
- /* @__PURE__ */ jsx5(Badge2, { size: "2xsmall", className: "w-fit", children: execution.workflow_id }),
450
- /* @__PURE__ */ jsx5(Copy3, { content: execution.workflow_id, className: "text-ui-fg-muted" })
451
- ] })
452
- ] }),
453
- /* @__PURE__ */ jsxs5("div", { className: "text-ui-fg-subtle grid grid-cols-2 px-6 py-4", children: [
454
- /* @__PURE__ */ jsx5(Text3, { size: "small", leading: "compact", weight: "plus", children: t("workflowExecutions.transactionIdLabel") }),
455
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-x-1", children: [
456
- /* @__PURE__ */ jsx5(Badge2, { size: "2xsmall", className: "w-fit", children: execution.transaction_id }),
457
- /* @__PURE__ */ jsx5(
458
- Copy3,
459
- {
460
- content: execution.transaction_id,
461
- className: "text-ui-fg-muted"
462
- }
463
- )
464
- ] })
465
- ] }),
466
- /* @__PURE__ */ jsxs5("div", { className: "text-ui-fg-subtle grid grid-cols-2 px-6 py-4", children: [
467
- /* @__PURE__ */ jsx5(Text3, { size: "small", leading: "compact", weight: "plus", children: t("workflowExecutions.progressLabel") }),
468
- /* @__PURE__ */ jsx5(Progress, { steps: execution.execution?.steps })
469
- ] }),
470
- /* @__PURE__ */ jsxs5("div", { className: "text-ui-fg-subtle grid grid-cols-2 px-6 py-4", children: [
471
- /* @__PURE__ */ jsx5(Text3, { size: "small", leading: "compact", weight: "plus", children: t("fields.summary") }),
472
- /* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-y-1", children: [
473
- /* @__PURE__ */ jsx5(Text3, { size: "small", leading: "compact", className: "text-ui-fg-subtle", children: t("workflowExecutions.metrics.stepsSummary", {
474
- completed: completedSteps,
475
- total: totalSteps
476
- }) }),
477
- failedSteps > 0 && /* @__PURE__ */ jsx5(Text3, { size: "small", leading: "compact", className: "text-ui-fg-subtle", children: t("workflowExecutions.metrics.failedSteps", {
478
- count: failedSteps
479
- }) }),
480
- skippedSteps > 0 && /* @__PURE__ */ jsx5(Text3, { size: "small", leading: "compact", className: "text-ui-fg-subtle", children: t("workflowExecutions.metrics.skippedSteps", {
481
- count: skippedSteps
482
- }) }),
483
- /* @__PURE__ */ jsx5(Text3, { size: "small", leading: "compact", className: "text-ui-fg-subtle", children: compensatedSteps > 0 ? t("workflowExecutions.metrics.compensatedYes") : t("workflowExecutions.metrics.compensatedNo") })
484
- ] })
485
- ] }),
486
- /* @__PURE__ */ jsxs5("div", { className: "text-ui-fg-subtle grid grid-cols-2 px-6 py-4", children: [
487
- /* @__PURE__ */ jsx5(Text3, { size: "small", leading: "compact", weight: "plus", children: t("fields.createdAt") }),
488
- /* @__PURE__ */ jsx5(Text3, { size: "small", leading: "compact", children: createdAt ? getFullDate({ date: createdAt, includeTime: true }) : "-" })
489
- ] }),
490
- /* @__PURE__ */ jsxs5("div", { className: "text-ui-fg-subtle grid grid-cols-2 px-6 py-4", children: [
491
- /* @__PURE__ */ jsx5(Text3, { size: "small", leading: "compact", weight: "plus", children: t("fields.updatedAt") }),
492
- /* @__PURE__ */ jsx5(Text3, { size: "small", leading: "compact", children: updatedAt ? getFullDate({ date: updatedAt, includeTime: true }) : "-" })
493
- ] })
494
- ] });
495
- };
496
- var ROOT_PREFIX = "_root";
497
- var Progress = ({
498
- steps
499
- }) => {
500
- const { t } = useTranslation4();
501
- if (!steps) {
502
- return /* @__PURE__ */ jsx5(Text3, { size: "small", leading: "compact", className: "text-ui-fg-subtle", children: t("workflowExecutions.stepsCompletedLabel", {
503
- completed: 0,
504
- count: 0
505
- }) });
506
- }
507
- const actionableSteps = Object.values(steps).filter(
508
- (step) => step.id !== ROOT_PREFIX
509
- );
510
- const completedSteps = actionableSteps.filter(
511
- (step) => step.invoke.state === "done" /* DONE */
512
- );
513
- return /* @__PURE__ */ jsxs5("div", { className: "flex w-fit items-center gap-x-2", children: [
514
- /* @__PURE__ */ jsx5("div", { className: "flex items-center gap-x-[3px]", children: actionableSteps.map((step) => /* @__PURE__ */ jsx5(
515
- "div",
516
- {
517
- className: clx(
518
- "bg-ui-bg-switch-off shadow-details-switch-background h-3 w-1.5 rounded-full",
519
- {
520
- "bg-ui-fg-muted": step.invoke.state === "done" /* DONE */
521
- }
522
- )
523
- },
524
- step.id
525
- )) }),
526
- /* @__PURE__ */ jsx5(Text3, { size: "small", leading: "compact", className: "text-ui-fg-subtle", children: t("workflowExecutions.stepsCompletedLabel", {
527
- completed: completedSteps.length,
528
- count: actionableSteps.length
529
- }) })
530
- ] });
531
- };
532
-
533
- // src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-history-section/workflow-execution-history-section.tsx
534
- import { Spinner, TriangleDownMini } from "@acmekit/icons";
535
- import {
536
- Button as Button2,
537
- clx as clx2,
538
- CodeBlock,
539
- Container as Container5,
540
- Copy as Copy4,
541
- Heading as Heading4,
542
- IconButton,
543
- Text as Text4,
544
- toast as toast2
545
- } from "@acmekit/ui";
546
- import { format } from "date-fns";
547
- import { Collapsible as RadixCollapsible } from "radix-ui";
548
- import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
549
- import { useTranslation as useTranslation5 } from "react-i18next";
550
- import { useLocation } from "react-router-dom";
551
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
552
- var WorkflowExecutionHistorySection = ({
553
- execution
554
- }) => {
555
- const { t } = useTranslation5();
556
- const map = Object.values(execution.execution?.steps || {});
557
- const steps = map.filter((step) => step.id !== "_root");
558
- const hasCompensation = [
559
- "compensating" /* COMPENSATING */,
560
- "reverted" /* REVERTED */,
561
- "waiting_to_compensate" /* WAITING_TO_COMPENSATE */
562
- ].includes(execution.state);
563
- const [showCompensation, setShowCompensation] = useState2(false);
564
- const unreachableStepId = steps.find(
565
- (step) => step.invoke.status === "permanent_failure" /* PERMANENT_FAILURE */
566
- )?.id;
567
- const unreachableSteps = unreachableStepId ? steps.filter(
568
- (step) => step.id !== unreachableStepId && step.id.includes(unreachableStepId)
569
- ).map((step) => step.id) : [];
570
- return /* @__PURE__ */ jsxs6(Container5, { className: "divide-y p-0", children: [
571
- /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between px-6 py-4", children: [
572
- /* @__PURE__ */ jsx6(Heading4, { level: "h2", children: t("workflowExecutions.history.sectionTitle") }),
573
- hasCompensation && /* @__PURE__ */ jsx6(
574
- Button2,
575
- {
576
- size: "small",
577
- variant: "secondary",
578
- onClick: () => setShowCompensation((v) => !v),
579
- children: showCompensation ? t("workflowExecutions.history.showInvoke") : t("workflowExecutions.history.showCompensation")
580
- }
581
- )
582
- ] }),
583
- /* @__PURE__ */ jsx6("div", { className: "flex flex-col gap-y-0.5 px-6 py-4", children: steps.map((step, index) => {
584
- const stepId = step.id.split(".").pop();
585
- if (!stepId) {
586
- return null;
587
- }
588
- const context = execution.context?.data.invoke[stepId];
589
- const error = execution.context?.errors.find(
590
- (e) => e.action === stepId
591
- );
592
- return /* @__PURE__ */ jsx6(
593
- Event,
594
- {
595
- step,
596
- stepInvokeContext: context,
597
- stepError: error,
598
- isLast: index === steps.length - 1,
599
- isUnreachable: unreachableSteps.includes(step.id),
600
- execution,
601
- showCompensation
602
- },
603
- step.id
604
- );
605
- }) })
606
- ] });
607
- };
608
- var Event = ({
609
- step,
610
- stepInvokeContext,
611
- stepError,
612
- isLast,
613
- isUnreachable,
614
- execution,
615
- showCompensation
616
- }) => {
617
- const [open, setOpen] = useState2(false);
618
- const ref = useRef2(null);
619
- const { hash } = useLocation();
620
- const { t } = useTranslation5();
621
- const stepId = step.id.split(".").pop();
622
- useEffect2(() => {
623
- if (hash === `#${stepId}`) {
624
- setOpen(true);
625
- }
626
- }, [hash, stepId]);
627
- const identifier = step.id.split(".").pop();
628
- const isPermanentFailure = step.invoke.status === "permanent_failure" /* PERMANENT_FAILURE */;
629
- const isWaiting = step.invoke.status === "waiting_response" /* WAITING */;
630
- const idempotencyKey = computeIdempotencyKey(
631
- execution.workflow_id,
632
- execution.transaction_id,
633
- stepId,
634
- "invoke"
635
- );
636
- const duration = formatStepDuration(
637
- step.startedAt ?? void 0,
638
- step.endedAt ?? void 0
639
- );
640
- const { mutateAsync: retryStep, isPending: isRetrying } = useRetryStep(
641
- execution.workflow_id,
642
- execution.transaction_id
643
- );
644
- const handleRetryStep = async () => {
645
- await retryStep(
646
- { step_id: stepId },
647
- {
648
- onSuccess: () => {
649
- toast2.success(t("workflowExecutions.actions.retryStepSuccess"));
650
- }
651
- }
652
- );
653
- };
654
- return /* @__PURE__ */ jsxs6(
655
- "div",
656
- {
657
- className: "grid grid-cols-[20px_1fr] items-start gap-x-2 px-2",
658
- id: stepId,
659
- children: [
660
- /* @__PURE__ */ jsxs6("div", { className: "grid h-full grid-rows-[20px_1fr] items-center justify-center gap-y-0.5", children: [
661
- /* @__PURE__ */ jsx6("div", { className: "flex size-5 items-center justify-center", children: /* @__PURE__ */ jsx6("div", { className: "bg-ui-bg-base shadow-borders-base flex size-2.5 items-center justify-center rounded-full", children: /* @__PURE__ */ jsx6(
662
- "div",
663
- {
664
- className: clx2("size-1.5 rounded-full", {
665
- "bg-ui-tag-neutral-bg": STEP_SKIPPED_STATES.includes(
666
- step.invoke.state
667
- ),
668
- "bg-ui-tag-green-icon": STEP_OK_STATES.includes(
669
- step.invoke.state
670
- ),
671
- "bg-ui-tag-purple-icon": isWaiting,
672
- "bg-ui-tag-orange-icon": !isWaiting && STEP_IN_PROGRESS_STATES.includes(step.invoke.state),
673
- "bg-ui-tag-red-icon": STEP_ERROR_STATES.includes(
674
- step.invoke.state
675
- ),
676
- "bg-ui-tag-neutral-icon": STEP_INACTIVE_STATES.includes(
677
- step.invoke.state
678
- )
679
- })
680
- }
681
- ) }) }),
682
- /* @__PURE__ */ jsx6("div", { className: "flex h-full flex-col items-center", children: /* @__PURE__ */ jsx6(
683
- "div",
684
- {
685
- "aria-hidden": true,
686
- role: "presentation",
687
- className: clx2({
688
- "bg-ui-border-base h-full min-h-[14px] w-px": !isLast
689
- })
690
- }
691
- ) })
692
- ] }),
693
- /* @__PURE__ */ jsxs6(
694
- RadixCollapsible.Root,
695
- {
696
- open,
697
- onOpenChange: (isOpen) => {
698
- setOpen(isOpen);
699
- if (isOpen) {
700
- window.history.replaceState(null, "", `#${stepId}`);
701
- }
702
- },
703
- children: [
704
- /* @__PURE__ */ jsx6(RadixCollapsible.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs6("div", { className: "group flex cursor-pointer items-start justify-between outline-none", children: [
705
- /* @__PURE__ */ jsx6(Text4, { size: "small", leading: "compact", weight: "plus", children: identifier }),
706
- /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-x-2", children: [
707
- duration && /* @__PURE__ */ jsx6(Text4, { size: "small", leading: "compact", className: "text-ui-fg-muted", children: duration }),
708
- /* @__PURE__ */ jsx6(
709
- StepState,
710
- {
711
- state: step.invoke.state,
712
- status: step.invoke.status,
713
- startedAt: step.startedAt,
714
- isUnreachable
715
- }
716
- ),
717
- /* @__PURE__ */ jsx6(IconButton, { size: "2xsmall", variant: "transparent", children: /* @__PURE__ */ jsx6(TriangleDownMini, { className: "text-ui-fg-muted transition-transform group-data-[state=open]:rotate-180" }) })
718
- ] })
719
- ] }) }),
720
- /* @__PURE__ */ jsx6(RadixCollapsible.Content, { ref, children: /* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-y-2 pb-4 pt-2", children: [
721
- /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between", children: [
722
- /* @__PURE__ */ jsx6(Text4, { size: "xsmall", className: "text-ui-fg-muted", children: t("workflowExecutions.history.idempotencyKeyLabel") }),
723
- /* @__PURE__ */ jsx6(Copy4, { content: idempotencyKey, asChild: true, children: /* @__PURE__ */ jsx6(
724
- Text4,
725
- {
726
- size: "xsmall",
727
- className: "text-ui-fg-subtle cursor-pointer font-mono",
728
- children: idempotencyKey
729
- }
730
- ) })
731
- ] }),
732
- isPermanentFailure && /* @__PURE__ */ jsx6("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx6(
733
- Button2,
734
- {
735
- size: "small",
736
- variant: "secondary",
737
- isLoading: isRetrying,
738
- onClick: handleRetryStep,
739
- children: t("workflowExecutions.history.retryFromStep")
740
- }
741
- ) }),
742
- /* @__PURE__ */ jsxs6("div", { className: "text-ui-fg-subtle flex flex-col gap-y-2", children: [
743
- /* @__PURE__ */ jsx6(Text4, { size: "small", leading: "compact", children: t("workflowExecutions.history.definitionLabel") }),
744
- /* @__PURE__ */ jsx6(
745
- CodeBlock,
746
- {
747
- snippets: [
748
- {
749
- code: JSON.stringify(step.definition, null, 2),
750
- label: t("workflowExecutions.history.definitionLabel"),
751
- language: "json",
752
- hideLineNumbers: true
753
- }
754
- ],
755
- children: /* @__PURE__ */ jsx6(CodeBlock.Body, {})
756
- }
757
- )
758
- ] }),
759
- stepInvokeContext && /* @__PURE__ */ jsxs6("div", { className: "text-ui-fg-subtle flex flex-col gap-y-2", children: [
760
- /* @__PURE__ */ jsx6(Text4, { size: "small", leading: "compact", children: t("workflowExecutions.history.outputLabel") }),
761
- /* @__PURE__ */ jsx6(
762
- CodeBlock,
763
- {
764
- snippets: [
765
- {
766
- code: JSON.stringify(
767
- // TODO: Apply resolve value: packages/core/workflows-sdk/src/utils/composer/helpers/resolve-value.ts
768
- stepInvokeContext?.output?.output ?? {},
769
- null,
770
- 2
771
- ),
772
- label: t("workflowExecutions.history.outputLabel"),
773
- language: "json",
774
- hideLineNumbers: true
775
- }
776
- ],
777
- children: /* @__PURE__ */ jsx6(CodeBlock.Body, {})
778
- }
779
- )
780
- ] }),
781
- showCompensation && step.compensate.state !== "not_started" /* NOT_STARTED */ && /* @__PURE__ */ jsxs6("div", { className: "border-ui-tag-orange-border bg-ui-tag-orange-bg rounded-md border p-3", children: [
782
- /* @__PURE__ */ jsxs6(Text4, { size: "xsmall", weight: "plus", className: "text-ui-tag-orange-text mb-2", children: [
783
- "\u21A9 ",
784
- t("workflowExecutions.history.revertedLabel"),
785
- " \u2014 ",
786
- step.compensate.state
787
- ] }),
788
- !!stepInvokeContext?.output?.compensateInput && /* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-y-1", children: [
789
- /* @__PURE__ */ jsx6(Text4, { size: "xsmall", className: "text-ui-fg-subtle", children: t("workflowExecutions.history.compensateInputLabel") }),
790
- /* @__PURE__ */ jsx6(
791
- CodeBlock,
792
- {
793
- snippets: [
794
- {
795
- code: JSON.stringify(
796
- stepInvokeContext?.output?.compensateInput ?? {},
797
- null,
798
- 2
799
- ),
800
- label: t("workflowExecutions.history.compensateInputLabel"),
801
- language: "json",
802
- hideLineNumbers: true
803
- }
804
- ],
805
- children: /* @__PURE__ */ jsx6(CodeBlock.Body, {})
806
- }
807
- )
808
- ] })
809
- ] }),
810
- !showCompensation && !!stepInvokeContext?.output?.compensateInput && step.compensate.state === "reverted" /* REVERTED */ && /* @__PURE__ */ jsxs6("div", { className: "text-ui-fg-subtle flex flex-col gap-y-2", children: [
811
- /* @__PURE__ */ jsx6(Text4, { size: "small", leading: "compact", children: t("workflowExecutions.history.compensateInputLabel") }),
812
- /* @__PURE__ */ jsx6(
813
- CodeBlock,
814
- {
815
- snippets: [
816
- {
817
- // TODO: Apply resolve value: packages/core/workflows-sdk/src/utils/composer/helpers/resolve-value.ts
818
- code: JSON.stringify(
819
- stepInvokeContext?.output?.compensateInput ?? {},
820
- null,
821
- 2
822
- ),
823
- label: t(
824
- "workflowExecutions.history.compensateInputLabel"
825
- ),
826
- language: "json",
827
- hideLineNumbers: true
828
- }
829
- ],
830
- children: /* @__PURE__ */ jsx6(CodeBlock.Body, {})
831
- }
832
- )
833
- ] }),
834
- stepError && /* @__PURE__ */ jsxs6("div", { className: "text-ui-fg-subtle flex flex-col gap-y-2", children: [
835
- /* @__PURE__ */ jsx6(Text4, { size: "small", leading: "compact", children: t("workflowExecutions.history.errorLabel") }),
836
- /* @__PURE__ */ jsx6(
837
- CodeBlock,
838
- {
839
- snippets: [
840
- {
841
- code: JSON.stringify(
842
- {
843
- error: stepError.error,
844
- handlerType: stepError.handlerType
845
- },
846
- null,
847
- 2
848
- ),
849
- label: t("workflowExecutions.history.errorLabel"),
850
- language: "json",
851
- hideLineNumbers: true
852
- }
853
- ],
854
- children: /* @__PURE__ */ jsx6(CodeBlock.Body, {})
855
- }
856
- )
857
- ] })
858
- ] }) })
859
- ]
860
- }
861
- )
862
- ]
863
- }
864
- );
865
- };
866
- var StepState = ({
867
- state,
868
- status,
869
- startedAt,
870
- isUnreachable
871
- }) => {
872
- const { t } = useTranslation5();
873
- const isFailed = state === "failed" /* FAILED */;
874
- const isRunning = state === "invoking" /* INVOKING */;
875
- const isWaitingResponse = status === "waiting_response" /* WAITING */;
876
- const isSkipped = state === "skipped" /* SKIPPED */;
877
- const isSkippedFailure = state === "skipped_failure" /* SKIPPED_FAILURE */;
878
- if (isUnreachable) {
879
- return null;
880
- }
881
- if (isWaitingResponse) {
882
- return /* @__PURE__ */ jsx6("div", { className: "flex items-center gap-x-1", children: /* @__PURE__ */ jsx6(Text4, { size: "small", leading: "compact", className: "text-ui-tag-purple-text", children: t("workflowExecutions.history.awaitingState") }) });
883
- }
884
- if (isRunning) {
885
- return /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-x-1", children: [
886
- /* @__PURE__ */ jsx6(Text4, { size: "small", leading: "compact", className: "text-ui-fg-subtle", children: t("workflowExecutions.history.runningState") }),
887
- /* @__PURE__ */ jsx6(Spinner, { className: "text-ui-fg-interactive animate-spin" })
888
- ] });
889
- }
890
- let stateText;
891
- if (isSkipped) {
892
- stateText = t("workflowExecutions.history.skippedState");
893
- } else if (isSkippedFailure) {
894
- stateText = t("workflowExecutions.history.skippedFailureState");
895
- } else if (isFailed) {
896
- stateText = t("workflowExecutions.history.failedState");
897
- }
898
- if (stateText !== null) {
899
- return /* @__PURE__ */ jsx6(Text4, { size: "small", leading: "compact", className: "text-ui-fg-subtle", children: stateText });
900
- }
901
- if (startedAt) {
902
- return /* @__PURE__ */ jsx6(Text4, { size: "small", leading: "compact", className: "text-ui-fg-muted", children: format(startedAt, "dd MMM yyyy HH:mm:ss") });
903
- }
904
- };
905
-
906
- // src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-payload-section/workflow-execution-payload-section.tsx
907
- import { Button as Button3, Container as Container6, Heading as Heading5, Tabs, toast as toast3 } from "@acmekit/ui";
908
- import { useState as useState3 } from "react";
909
- import { useTranslation as useTranslation6 } from "react-i18next";
910
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
911
- function downloadJson(data, filename) {
912
- const blob = new Blob([JSON.stringify(data, null, 2)], {
913
- type: "application/json"
914
- });
915
- const url = URL.createObjectURL(blob);
916
- const a = document.createElement("a");
917
- a.href = url;
918
- a.download = filename;
919
- a.click();
920
- URL.revokeObjectURL(url);
921
- }
922
- var WorkflowExecutionPayloadSection = ({
923
- execution
924
- }) => {
925
- const { t } = useTranslation6();
926
- let payload = execution.context?.data?.payload;
927
- if (payload && typeof payload !== "object") {
928
- payload = { input: payload };
929
- }
930
- const checkpoint = execution.context || {};
931
- const errors = execution.context?.errors || [];
932
- const stepOutputs = {};
933
- const steps = execution?.execution?.steps || {};
934
- for (const [stepId, step] of Object.entries(steps)) {
935
- if (stepId === "_root") continue;
936
- const output = step?.invoke?.output;
937
- if (output !== void 0) {
938
- stepOutputs[stepId] = output;
939
- }
940
- }
941
- const hasPayload = !!payload;
942
- const hasStepOutputs = Object.keys(stepOutputs).length > 0;
943
- const hasErrors = errors.length > 0;
944
- const defaultTab = hasPayload ? "input" : "checkpoint";
945
- const [activeTab, setActiveTab] = useState3(defaultTab);
946
- if (!hasPayload && !hasStepOutputs && !hasErrors) {
947
- return null;
948
- }
949
- const activeData = activeTab === "input" ? payload : activeTab === "checkpoint" ? checkpoint : activeTab === "outputs" ? stepOutputs : errors;
950
- const handleCopyAll = () => {
951
- navigator.clipboard.writeText(JSON.stringify(activeData, null, 2));
952
- toast3.success("Copied to clipboard");
953
- };
954
- const handleDownload = () => {
955
- downloadJson(
956
- activeData,
957
- `${execution.workflow_id}-${activeTab}.json`
958
- );
959
- };
960
- return /* @__PURE__ */ jsxs7(Container6, { className: "divide-y p-0", children: [
961
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between px-6 py-4", children: [
962
- /* @__PURE__ */ jsx7(Heading5, { level: "h2", children: t("workflowExecutions.payload.inputPayload") }),
963
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-x-2", children: [
964
- /* @__PURE__ */ jsx7(Button3, { size: "small", variant: "transparent", onClick: handleCopyAll, children: t("workflowExecutions.payload.copyAll") }),
965
- /* @__PURE__ */ jsx7(Button3, { size: "small", variant: "transparent", onClick: handleDownload, children: t("workflowExecutions.payload.downloadJson") })
966
- ] })
967
- ] }),
968
- /* @__PURE__ */ jsxs7(
969
- Tabs,
970
- {
971
- value: activeTab,
972
- onValueChange: setActiveTab,
973
- children: [
974
- /* @__PURE__ */ jsx7("div", { className: "border-ui-border-base border-b px-6", children: /* @__PURE__ */ jsxs7(Tabs.List, { children: [
975
- hasPayload && /* @__PURE__ */ jsx7(Tabs.Trigger, { value: "input", children: t("workflowExecutions.payload.inputPayload") }),
976
- /* @__PURE__ */ jsx7(Tabs.Trigger, { value: "checkpoint", children: t("workflowExecutions.payload.fullCheckpoint") }),
977
- hasStepOutputs && /* @__PURE__ */ jsx7(Tabs.Trigger, { value: "outputs", children: t("workflowExecutions.payload.stepOutputs") }),
978
- hasErrors && /* @__PURE__ */ jsx7(Tabs.Trigger, { value: "errors", children: t("workflowExecutions.payload.errors") })
979
- ] }) }),
980
- hasPayload && /* @__PURE__ */ jsx7(Tabs.Content, { value: "input", className: "p-0", children: /* @__PURE__ */ jsx7(JsonViewSection, { data: payload }) }),
981
- /* @__PURE__ */ jsx7(Tabs.Content, { value: "checkpoint", className: "p-0", children: /* @__PURE__ */ jsx7(JsonViewSection, { data: checkpoint }) }),
982
- hasStepOutputs && /* @__PURE__ */ jsx7(Tabs.Content, { value: "outputs", className: "p-0", children: /* @__PURE__ */ jsx7(JsonViewSection, { data: stepOutputs }) }),
983
- hasErrors && /* @__PURE__ */ jsx7(Tabs.Content, { value: "errors", className: "p-0", children: /* @__PURE__ */ jsx7(JsonViewSection, { data: errors }) })
984
- ]
985
- }
986
- )
987
- ] });
988
- };
989
-
990
- // src/routes/workflow-executions/workflow-execution-detail/components/workflow-execution-timeline-section/workflow-execution-timeline-section.tsx
991
- import { ArrowPathMini as ArrowPathMini2, MinusMini, PlusMini } from "@acmekit/icons";
992
- import { Container as Container7, DropdownMenu, Heading as Heading6, Text as Text5, clx as clx3 } from "@acmekit/ui";
993
- import {
994
- motion,
995
- useAnimationControls,
996
- useDragControls,
997
- useMotionValue
998
- } from "motion/react";
999
- import { useEffect as useEffect3, useRef as useRef3, useState as useState4 } from "react";
1000
- import { useTranslation as useTranslation7 } from "react-i18next";
1001
- import { Link as Link3 } from "react-router-dom";
1002
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
1003
- var WorkflowExecutionTimelineSection = ({
1004
- execution
1005
- }) => {
1006
- const { t } = useTranslation7();
1007
- return /* @__PURE__ */ jsxs8(Container7, { className: "overflow-hidden px-0 pb-8 pt-0", children: [
1008
- /* @__PURE__ */ jsx8("div", { className: "flex items-center justify-between px-6 py-4", children: /* @__PURE__ */ jsx8(Heading6, { level: "h2", children: t("general.timeline") }) }),
1009
- /* @__PURE__ */ jsx8("div", { className: "w-full overflow-hidden border-y", children: /* @__PURE__ */ jsx8(Canvas, { execution }) })
1010
- ] });
1011
- };
1012
- var createNodeClusters = (steps) => {
1013
- const actionableSteps = Object.values(steps).filter(
1014
- (step) => step.id !== "_root"
1015
- );
1016
- const clusters = {};
1017
- actionableSteps.forEach((step) => {
1018
- if (!clusters[step.depth]) {
1019
- clusters[step.depth] = [];
1020
- }
1021
- clusters[step.depth].push(step);
1022
- });
1023
- return clusters;
1024
- };
1025
- var getNextCluster = (clusters, depth) => {
1026
- const nextDepth = depth + 1;
1027
- return clusters[nextDepth];
1028
- };
1029
- var defaultState = {
1030
- x: -860,
1031
- y: -1020,
1032
- scale: 1
1033
- };
1034
- var MAX_ZOOM = 1.5;
1035
- var MIN_ZOOM = 0.5;
1036
- var ZOOM_STEP = 0.25;
1037
- var Canvas = ({
1038
- execution
1039
- }) => {
1040
- const [zoom, setZoom] = useState4(1);
1041
- const [isDragging, setIsDragging] = useState4(false);
1042
- const direction = useDocumentDirection();
1043
- const scale = useMotionValue(defaultState.scale);
1044
- const x = useMotionValue(defaultState.x);
1045
- const y = useMotionValue(defaultState.y);
1046
- const controls = useAnimationControls();
1047
- const dragControls = useDragControls();
1048
- const dragConstraints = useRef3(null);
1049
- const canZoomIn = zoom < MAX_ZOOM;
1050
- const canZoomOut = zoom > MIN_ZOOM;
1051
- useEffect3(() => {
1052
- const unsubscribe = scale.on("change", (latest) => {
1053
- setZoom(latest);
1054
- });
1055
- return () => {
1056
- unsubscribe();
1057
- };
1058
- }, [scale]);
1059
- const clusters = createNodeClusters(execution.execution?.steps || {});
1060
- function scaleXandY(prevScale, newScale, x2, y2) {
1061
- const scaleRatio = newScale / prevScale;
1062
- return {
1063
- x: x2 * scaleRatio,
1064
- y: y2 * scaleRatio
1065
- };
1066
- }
1067
- const changeZoom = (newScale) => {
1068
- const { x: newX, y: newY } = scaleXandY(zoom, newScale, x.get(), y.get());
1069
- setZoom(newScale);
1070
- controls.set({ scale: newScale, x: newX, y: newY });
1071
- };
1072
- const zoomIn = () => {
1073
- const curr = scale.get();
1074
- if (curr < 1.5) {
1075
- const newScale = curr + ZOOM_STEP;
1076
- changeZoom(newScale);
1077
- }
1078
- };
1079
- const zoomOut = () => {
1080
- const curr = scale.get();
1081
- if (curr > 0.5) {
1082
- const newScale = curr - ZOOM_STEP;
1083
- changeZoom(newScale);
1084
- }
1085
- };
1086
- const resetCanvas = () => {
1087
- controls.start(defaultState);
1088
- };
1089
- return /* @__PURE__ */ jsx8("div", { className: "h-[400px] w-full", children: /* @__PURE__ */ jsxs8("div", { ref: dragConstraints, className: "relative size-full", children: [
1090
- /* @__PURE__ */ jsx8("div", { className: "relative size-full overflow-hidden object-contain", children: /* @__PURE__ */ jsx8("div", { children: /* @__PURE__ */ jsx8(
1091
- motion.div,
1092
- {
1093
- onMouseDown: () => setIsDragging(true),
1094
- onMouseUp: () => setIsDragging(false),
1095
- drag: true,
1096
- dragConstraints,
1097
- dragElastic: 0,
1098
- dragMomentum: false,
1099
- dragControls,
1100
- initial: false,
1101
- animate: controls,
1102
- transition: { duration: 0.25 },
1103
- style: {
1104
- x,
1105
- y,
1106
- scale
1107
- },
1108
- className: clx3(
1109
- "bg-ui-bg-subtle relative size-[500rem] origin-top-left items-start justify-start overflow-hidden",
1110
- "bg-[radial-gradient(var(--border-base)_1.5px,transparent_0)] bg-[length:20px_20px] bg-repeat",
1111
- {
1112
- "cursor-grab": !isDragging,
1113
- "cursor-grabbing": isDragging
1114
- }
1115
- ),
1116
- children: /* @__PURE__ */ jsx8("main", { className: "size-full", children: /* @__PURE__ */ jsx8("div", { className: "absolute left-[1100px] top-[1100px] flex select-none items-start", children: Object.entries(clusters).map(([depth, cluster]) => {
1117
- const next = getNextCluster(clusters, Number(depth));
1118
- return /* @__PURE__ */ jsxs8("div", { className: "flex items-start", children: [
1119
- /* @__PURE__ */ jsx8("div", { className: "flex flex-col justify-center gap-y-2", children: cluster.map((step) => /* @__PURE__ */ jsx8(Node, { step }, step.id)) }),
1120
- /* @__PURE__ */ jsx8(Line, { next })
1121
- ] }, depth);
1122
- }) }) })
1123
- }
1124
- ) }) }),
1125
- /* @__PURE__ */ jsxs8("div", { className: "bg-ui-bg-base shadow-borders-base text-ui-fg-subtle absolute bottom-4 left-6 flex h-7 items-center overflow-hidden rounded-md", children: [
1126
- /* @__PURE__ */ jsxs8("div", { className: "flex items-center", children: [
1127
- /* @__PURE__ */ jsx8(
1128
- "button",
1129
- {
1130
- onClick: zoomIn,
1131
- type: "button",
1132
- disabled: !canZoomIn,
1133
- "aria-label": "Zoom in",
1134
- className: "disabled:text-ui-fg-disabled transition-fg hover:bg-ui-bg-base-hover active:bg-ui-bg-base-pressed focus-visible:bg-ui-bg-base-pressed border-r p-1 outline-none",
1135
- children: /* @__PURE__ */ jsx8(PlusMini, {})
1136
- }
1137
- ),
1138
- /* @__PURE__ */ jsx8("div", { children: /* @__PURE__ */ jsxs8(DropdownMenu, { dir: direction, children: [
1139
- /* @__PURE__ */ jsx8(DropdownMenu.Trigger, { className: "disabled:text-ui-fg-disabled transition-fg hover:bg-ui-bg-base-hover active:bg-ui-bg-base-pressed focus-visible:bg-ui-bg-base-pressed flex w-[50px] items-center justify-center border-r p-1 outline-none", children: /* @__PURE__ */ jsxs8(
1140
- Text5,
1141
- {
1142
- as: "span",
1143
- size: "xsmall",
1144
- leading: "compact",
1145
- className: "select-none tabular-nums",
1146
- children: [
1147
- Math.round(zoom * 100),
1148
- "%"
1149
- ]
1150
- }
1151
- ) }),
1152
- /* @__PURE__ */ jsx8(DropdownMenu.Content, { children: [50, 75, 100, 125, 150].map((value) => /* @__PURE__ */ jsxs8(
1153
- DropdownMenu.Item,
1154
- {
1155
- onClick: () => changeZoom(value / 100),
1156
- children: [
1157
- value,
1158
- "%"
1159
- ]
1160
- },
1161
- value
1162
- )) })
1163
- ] }) }),
1164
- /* @__PURE__ */ jsx8(
1165
- "button",
1166
- {
1167
- onClick: zoomOut,
1168
- type: "button",
1169
- disabled: !canZoomOut,
1170
- "aria-label": "Zoom out",
1171
- className: "disabled:text-ui-fg-disabled transition-fg hover:bg-ui-bg-base-hover active:bg-ui-bg-base-pressed focus-visible:bg-ui-bg-base-pressed border-r p-1 outline-none",
1172
- children: /* @__PURE__ */ jsx8(MinusMini, {})
1173
- }
1174
- )
1175
- ] }),
1176
- /* @__PURE__ */ jsx8(
1177
- "button",
1178
- {
1179
- onClick: resetCanvas,
1180
- type: "button",
1181
- "aria-label": "Reset canvas",
1182
- className: "disabled:text-ui-fg-disabled transition-fg hover:bg-ui-bg-base-hover active:bg-ui-bg-base-pressed focus-visible:bg-ui-bg-base-pressed p-1 outline-none",
1183
- children: /* @__PURE__ */ jsx8(ArrowPathMini2, {})
1184
- }
1185
- )
1186
- ] })
1187
- ] }) });
1188
- };
1189
- var HorizontalArrow = () => {
1190
- return /* @__PURE__ */ jsx8(
1191
- "svg",
1192
- {
1193
- width: "42",
1194
- height: "12",
1195
- viewBox: "0 0 42 12",
1196
- fill: "none",
1197
- xmlns: "http://www.w3.org/2000/svg",
1198
- children: /* @__PURE__ */ jsx8(
1199
- "path",
1200
- {
1201
- d: "M41.5303 6.53033C41.8232 6.23744 41.8232 5.76256 41.5303 5.46967L36.7574 0.696699C36.4645 0.403806 35.9896 0.403806 35.6967 0.696699C35.4038 0.989593 35.4038 1.46447 35.6967 1.75736L39.9393 6L35.6967 10.2426C35.4038 10.5355 35.4038 11.0104 35.6967 11.3033C35.9896 11.5962 36.4645 11.5962 36.7574 11.3033L41.5303 6.53033ZM0.999996 5.25C0.585785 5.25 0.249996 5.58579 0.249996 6C0.249996 6.41421 0.585785 6.75 0.999996 6.75V5.25ZM41 5.25L0.999996 5.25V6.75L41 6.75V5.25Z",
1202
- fill: "var(--border-strong)"
1203
- }
1204
- )
1205
- }
1206
- );
1207
- };
1208
- var MiddleArrow = () => {
1209
- return /* @__PURE__ */ jsx8(
1210
- "svg",
1211
- {
1212
- width: "22",
1213
- height: "38",
1214
- viewBox: "0 0 22 38",
1215
- fill: "none",
1216
- xmlns: "http://www.w3.org/2000/svg",
1217
- className: "-mt-[6px]",
1218
- children: /* @__PURE__ */ jsx8(
1219
- "path",
1220
- {
1221
- d: "M0.999878 32H0.249878V32.75H0.999878V32ZM21.5284 32.5303C21.8213 32.2374 21.8213 31.7626 21.5284 31.4697L16.7554 26.6967C16.4625 26.4038 15.9876 26.4038 15.6947 26.6967C15.4019 26.9896 15.4019 27.4645 15.6947 27.7574L19.9374 32L15.6947 36.2426C15.4019 36.5355 15.4019 37.0104 15.6947 37.3033C15.9876 37.5962 16.4625 37.5962 16.7554 37.3033L21.5284 32.5303ZM0.249878 0L0.249878 32H1.74988L1.74988 0H0.249878ZM0.999878 32.75L20.998 32.75V31.25L0.999878 31.25V32.75Z",
1222
- fill: "var(--border-strong)"
1223
- }
1224
- )
1225
- }
1226
- );
1227
- };
1228
- var EndArrow = () => {
1229
- return /* @__PURE__ */ jsx8(
1230
- "svg",
1231
- {
1232
- width: "22",
1233
- height: "38",
1234
- viewBox: "0 0 22 38",
1235
- fill: "none",
1236
- xmlns: "http://www.w3.org/2000/svg",
1237
- className: "-mt-[6px]",
1238
- children: /* @__PURE__ */ jsx8(
1239
- "path",
1240
- {
1241
- d: "M21.5284 32.5303C21.8213 32.2374 21.8213 31.7626 21.5284 31.4697L16.7554 26.6967C16.4625 26.4038 15.9876 26.4038 15.6947 26.6967C15.4019 26.9896 15.4019 27.4645 15.6947 27.7574L19.9374 32L15.6947 36.2426C15.4019 36.5355 15.4019 37.0104 15.6947 37.3033C15.9876 37.5962 16.4625 37.5962 16.7554 37.3033L21.5284 32.5303ZM0.249878 0L0.249878 28H1.74988L1.74988 0H0.249878ZM4.99988 32.75L20.998 32.75V31.25L4.99988 31.25V32.75ZM0.249878 28C0.249878 30.6234 2.37653 32.75 4.99988 32.75V31.25C3.20495 31.25 1.74988 29.7949 1.74988 28H0.249878Z",
1242
- fill: "var(--border-strong)"
1243
- }
1244
- )
1245
- }
1246
- );
1247
- };
1248
- var Arrow = ({ depth }) => {
1249
- if (depth === 1) {
1250
- return /* @__PURE__ */ jsx8(HorizontalArrow, {});
1251
- }
1252
- if (depth === 2) {
1253
- return /* @__PURE__ */ jsxs8("div", { className: "flex flex-col items-end", children: [
1254
- /* @__PURE__ */ jsx8(HorizontalArrow, {}),
1255
- /* @__PURE__ */ jsx8(EndArrow, {})
1256
- ] });
1257
- }
1258
- const inbetween = Array.from({ length: depth - 2 }).map((_, index) => /* @__PURE__ */ jsx8(MiddleArrow, {}, index));
1259
- return /* @__PURE__ */ jsxs8("div", { className: "flex flex-col items-end", children: [
1260
- /* @__PURE__ */ jsx8(HorizontalArrow, {}),
1261
- inbetween,
1262
- /* @__PURE__ */ jsx8(EndArrow, {})
1263
- ] });
1264
- };
1265
- var Line = ({ next }) => {
1266
- if (!next) {
1267
- return null;
1268
- }
1269
- return /* @__PURE__ */ jsx8("div", { className: "-ml-[5px] -mr-[7px] w-[60px] pr-[7px]", children: /* @__PURE__ */ jsxs8("div", { className: "flex min-h-[24px] w-full items-start", children: [
1270
- /* @__PURE__ */ jsx8("div", { className: "flex h-6 w-2.5 items-center justify-center", children: /* @__PURE__ */ jsx8("div", { className: "bg-ui-button-neutral shadow-borders-base size-2.5 shrink-0 rounded-full" }) }),
1271
- /* @__PURE__ */ jsx8("div", { className: "pt-1.5", children: /* @__PURE__ */ jsx8(Arrow, { depth: next.length }) })
1272
- ] }) });
1273
- };
1274
- var Node = ({ step }) => {
1275
- if (step.id === "_root") {
1276
- return null;
1277
- }
1278
- const stepId = step.id.split(".").pop();
1279
- const handleScrollTo = () => {
1280
- if (!stepId) {
1281
- return;
1282
- }
1283
- const historyItem = document.getElementById(stepId);
1284
- if (!historyItem) {
1285
- return;
1286
- }
1287
- setTimeout(() => {
1288
- historyItem.scrollIntoView({
1289
- behavior: "smooth",
1290
- block: "end"
1291
- });
1292
- }, 100);
1293
- };
1294
- const isInvoking = step.invoke.state === "invoking" /* INVOKING */;
1295
- return /* @__PURE__ */ jsx8(
1296
- Link3,
1297
- {
1298
- to: `#${stepId}`,
1299
- onClick: handleScrollTo,
1300
- className: "focus-visible:shadow-borders-focus transition-fg rounded-md outline-none",
1301
- children: /* @__PURE__ */ jsxs8(
1302
- "div",
1303
- {
1304
- className: clx3(
1305
- "bg-ui-bg-base shadow-borders-base flex min-w-[120px] items-center gap-x-0.5 rounded-md p-0.5",
1306
- { "animate-pulse": isInvoking }
1307
- ),
1308
- "data-step-id": step.id,
1309
- children: [
1310
- /* @__PURE__ */ jsx8("div", { className: "flex size-5 items-center justify-center", children: /* @__PURE__ */ jsx8(
1311
- "div",
1312
- {
1313
- className: clx3(
1314
- "size-2 rounded-sm shadow-[inset_0_0_0_1px_rgba(0,0,0,0.12)]",
1315
- {
1316
- "bg-ui-tag-neutral-bg": STEP_SKIPPED_STATES.includes(
1317
- step.invoke.state
1318
- ),
1319
- "bg-ui-tag-green-icon": STEP_OK_STATES.includes(
1320
- step.invoke.state
1321
- ),
1322
- "bg-ui-tag-orange-icon": STEP_IN_PROGRESS_STATES.includes(
1323
- step.invoke.state
1324
- ),
1325
- "bg-ui-tag-red-icon": STEP_ERROR_STATES.includes(
1326
- step.invoke.state
1327
- ),
1328
- "bg-ui-tag-neutral-icon": STEP_INACTIVE_STATES.includes(
1329
- step.invoke.state
1330
- )
1331
- }
1332
- )
1333
- }
1334
- ) }),
1335
- /* @__PURE__ */ jsx8(
1336
- Text5,
1337
- {
1338
- size: "xsmall",
1339
- leading: "compact",
1340
- weight: "plus",
1341
- className: "select-none",
1342
- children: stepId
1343
- }
1344
- )
1345
- ]
1346
- }
1347
- )
1348
- }
1349
- );
1350
- };
1351
-
1352
- // src/routes/workflow-executions/workflow-execution-detail/workflow-detail.tsx
1353
- import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1354
- var ExecutionDetail = () => {
1355
- const { id } = useParams();
1356
- const queryClient2 = useQueryClient();
1357
- const { workflow_execution, isLoading, isError, error } = useWorkflowExecution(id);
1358
- const { getWidgets } = useExtension();
1359
- const isActive = workflow_execution ? TRANSACTION_ACTIVE_STATES.includes(
1360
- workflow_execution.state
1361
- ) : false;
1362
- useWorkflowSSE(workflow_execution?.workflow_id || "", {
1363
- enabled: isActive && !!workflow_execution?.workflow_id,
1364
- onEvent: (event) => {
1365
- queryClient2.setQueryData(
1366
- workflowExecutionsQueryKeys.detail(id),
1367
- (current) => {
1368
- if (!current) return current;
1369
- return mergeStepEvent(current, event);
1370
- }
1371
- );
1372
- if (event.event_type === "onFinish" || event.response?.state && isTerminalState(event.response.state)) {
1373
- queryClient2.invalidateQueries({
1374
- queryKey: workflowExecutionsQueryKeys.detail(id)
1375
- });
1376
- }
1377
- }
1378
- });
1379
- if (isLoading || !workflow_execution) {
1380
- return /* @__PURE__ */ jsx9(SingleColumnPageSkeleton, { sections: 4, showJSON: true });
1381
- }
1382
- if (isError) {
1383
- throw error;
1384
- }
1385
- return /* @__PURE__ */ jsxs9(
1386
- SingleColumnPage,
1387
- {
1388
- widgets: {
1389
- after: getWidgets("workflow.details.after"),
1390
- before: getWidgets("workflow.details.before")
1391
- },
1392
- data: workflow_execution,
1393
- showJSON: true,
1394
- hasOutlet: true,
1395
- children: [
1396
- /* @__PURE__ */ jsx9(WorkflowExecutionActionBar, { execution: workflow_execution }),
1397
- /* @__PURE__ */ jsx9(WorkflowExecutionErrorCard, { execution: workflow_execution }),
1398
- /* @__PURE__ */ jsx9(WorkflowExecutionWaitingBanner, { execution: workflow_execution }),
1399
- /* @__PURE__ */ jsx9(WorkflowExecutionGeneralSection, { execution: workflow_execution }),
1400
- /* @__PURE__ */ jsx9(WorkflowExecutionTimelineSection, { execution: workflow_execution }),
1401
- /* @__PURE__ */ jsx9(WorkflowExecutionPayloadSection, { execution: workflow_execution }),
1402
- /* @__PURE__ */ jsx9(WorkflowExecutionHistorySection, { execution: workflow_execution })
1403
- ]
1404
- }
1405
- );
1406
- };
1407
- export {
1408
- WorkflowExecutionDetailBreadcrumb as Breadcrumb,
1409
- ExecutionDetail as Component,
1410
- workflowExecutionLoader as loader
1411
- };