@burdenoff/fluidgrids-fe-sdk 2026.510.105
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.
- package/README.md +149 -0
- package/dist/ExecutionDetailPage-3EVS3WEC.js +6 -0
- package/dist/ExecutionDetailPage-3EVS3WEC.js.map +1 -0
- package/dist/ExecutionsListPage-NH2JLL2D.js +8 -0
- package/dist/ExecutionsListPage-NH2JLL2D.js.map +1 -0
- package/dist/TemplateConfigurationModal-UJAGRE7X.js +258 -0
- package/dist/TemplateConfigurationModal-UJAGRE7X.js.map +1 -0
- package/dist/TemplateDetailPanel-UXH6KPCH.js +172 -0
- package/dist/TemplateDetailPanel-UXH6KPCH.js.map +1 -0
- package/dist/WorkflowBuilder-BMKFLHVE.js +15 -0
- package/dist/WorkflowBuilder-BMKFLHVE.js.map +1 -0
- package/dist/WorkflowsList-CLI32VRE.js +8 -0
- package/dist/WorkflowsList-CLI32VRE.js.map +1 -0
- package/dist/chunk-4FFPGQD3.js +584 -0
- package/dist/chunk-4FFPGQD3.js.map +1 -0
- package/dist/chunk-5BDQNSP3.js +107 -0
- package/dist/chunk-5BDQNSP3.js.map +1 -0
- package/dist/chunk-6PHBYAEG.js +11494 -0
- package/dist/chunk-6PHBYAEG.js.map +1 -0
- package/dist/chunk-BQXHJIER.js +45 -0
- package/dist/chunk-BQXHJIER.js.map +1 -0
- package/dist/chunk-BXDSTMUA.js +8848 -0
- package/dist/chunk-BXDSTMUA.js.map +1 -0
- package/dist/chunk-CGKBAJMM.js +292 -0
- package/dist/chunk-CGKBAJMM.js.map +1 -0
- package/dist/chunk-FGYVIXQ7.js +979 -0
- package/dist/chunk-FGYVIXQ7.js.map +1 -0
- package/dist/chunk-G7B4SYFM.js +22 -0
- package/dist/chunk-G7B4SYFM.js.map +1 -0
- package/dist/chunk-GSJOLO3A.js +251 -0
- package/dist/chunk-GSJOLO3A.js.map +1 -0
- package/dist/chunk-GSS5PHRL.js +386 -0
- package/dist/chunk-GSS5PHRL.js.map +1 -0
- package/dist/chunk-GY66IQWN.js +524 -0
- package/dist/chunk-GY66IQWN.js.map +1 -0
- package/dist/chunk-LUGJJ7LL.js +297 -0
- package/dist/chunk-LUGJJ7LL.js.map +1 -0
- package/dist/chunk-NDJSUC4W.js +155 -0
- package/dist/chunk-NDJSUC4W.js.map +1 -0
- package/dist/chunk-UOCR65PI.js +262 -0
- package/dist/chunk-UOCR65PI.js.map +1 -0
- package/dist/chunk-WD52O45G.js +2015 -0
- package/dist/chunk-WD52O45G.js.map +1 -0
- package/dist/chunk-WWU2O2SR.js +52 -0
- package/dist/chunk-WWU2O2SR.js.map +1 -0
- package/dist/chunk-XQP33UJR.js +57 -0
- package/dist/chunk-XQP33UJR.js.map +1 -0
- package/dist/chunk-Z54K22LP.js +82 -0
- package/dist/chunk-Z54K22LP.js.map +1 -0
- package/dist/client-AMUUS7VE.js +3 -0
- package/dist/client-AMUUS7VE.js.map +1 -0
- package/dist/config-E4E7M6IN.js +3 -0
- package/dist/config-E4E7M6IN.js.map +1 -0
- package/dist/global-client-OW43ZRDR.js +3 -0
- package/dist/global-client-OW43ZRDR.js.map +1 -0
- package/dist/global-operations-WPTEYCJM.js +3 -0
- package/dist/global-operations-WPTEYCJM.js.map +1 -0
- package/dist/index.d.ts +56706 -0
- package/dist/index.js +6564 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.css +139 -0
- package/dist/template-input-applicator-657KE4DM.js +3 -0
- package/dist/template-input-applicator-657KE4DM.js.map +1 -0
- package/dist/useImportWorkflowTemplate-2HS5D2OP.js +11 -0
- package/dist/useImportWorkflowTemplate-2HS5D2OP.js.map +1 -0
- package/dist/useTemplateDetail-NK63V3PC.js +6 -0
- package/dist/useTemplateDetail-NK63V3PC.js.map +1 -0
- package/package.json +148 -0
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
import { useExecution, useExecutionLogs, useExecutionActions, useAutoRefresh, ExecutionStatusBadge, NodeTimeline } from './chunk-WD52O45G.js';
|
|
2
|
+
import { useState, useCallback } from 'react';
|
|
3
|
+
import { useParams, useNavigate, Link } from 'react-router-dom';
|
|
4
|
+
import { Icon } from '@iconify/react';
|
|
5
|
+
import { Button } from '@burdenoff/fe-libs/button';
|
|
6
|
+
import { AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction } from '@burdenoff/fe-libs/ui';
|
|
7
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
|
+
|
|
9
|
+
function ExecutionDetailPage() {
|
|
10
|
+
const { runId } = useParams();
|
|
11
|
+
const navigate = useNavigate();
|
|
12
|
+
const [activeTab, setActiveTab] = useState("timeline");
|
|
13
|
+
const [autoRefreshEnabled, setAutoRefreshEnabled] = useState(true);
|
|
14
|
+
const [showTerminateDialog, setShowTerminateDialog] = useState(false);
|
|
15
|
+
const { execution, loading, error, refetch } = useExecution(runId);
|
|
16
|
+
const {
|
|
17
|
+
logs,
|
|
18
|
+
loading: logsLoading,
|
|
19
|
+
refetch: refetchLogs
|
|
20
|
+
} = useExecutionLogs(runId, 100);
|
|
21
|
+
const {
|
|
22
|
+
pauseExecution,
|
|
23
|
+
resumeExecution,
|
|
24
|
+
cancelExecution,
|
|
25
|
+
retryNode,
|
|
26
|
+
terminateExecution,
|
|
27
|
+
loading: actionLoading
|
|
28
|
+
} = useExecutionActions();
|
|
29
|
+
const isActive = execution?.status === "RUNNING" || execution?.status === "PENDING" || execution?.status === "WAITING";
|
|
30
|
+
useAutoRefresh(
|
|
31
|
+
useCallback(() => {
|
|
32
|
+
refetch();
|
|
33
|
+
if (activeTab === "logs") {
|
|
34
|
+
refetchLogs();
|
|
35
|
+
}
|
|
36
|
+
}, [refetch, refetchLogs, activeTab]),
|
|
37
|
+
autoRefreshEnabled && isActive,
|
|
38
|
+
2e3
|
|
39
|
+
);
|
|
40
|
+
const handlePause = async () => {
|
|
41
|
+
if (!runId) return;
|
|
42
|
+
await pauseExecution(runId);
|
|
43
|
+
refetch();
|
|
44
|
+
};
|
|
45
|
+
const handleResume = async () => {
|
|
46
|
+
if (!runId) return;
|
|
47
|
+
await resumeExecution(runId);
|
|
48
|
+
refetch();
|
|
49
|
+
};
|
|
50
|
+
const handleCancel = async () => {
|
|
51
|
+
if (!runId) return;
|
|
52
|
+
await cancelExecution(runId);
|
|
53
|
+
refetch();
|
|
54
|
+
};
|
|
55
|
+
const handleTerminate = async () => {
|
|
56
|
+
if (!runId) return;
|
|
57
|
+
await terminateExecution(runId, "User terminated");
|
|
58
|
+
setShowTerminateDialog(false);
|
|
59
|
+
refetch();
|
|
60
|
+
};
|
|
61
|
+
const handleRetryNode = async (nodeId) => {
|
|
62
|
+
if (!runId) return;
|
|
63
|
+
await retryNode(runId, nodeId);
|
|
64
|
+
refetch();
|
|
65
|
+
};
|
|
66
|
+
const handleViewChildRun = useCallback(
|
|
67
|
+
(childRunId) => {
|
|
68
|
+
navigate(`../runs/${childRunId}`);
|
|
69
|
+
},
|
|
70
|
+
[navigate]
|
|
71
|
+
);
|
|
72
|
+
const formatDuration = (ms) => {
|
|
73
|
+
if (!ms) return "-";
|
|
74
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
75
|
+
if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
|
|
76
|
+
if (ms < 36e5)
|
|
77
|
+
return `${Math.round(ms / 6e4)}m ${Math.round(ms % 6e4 / 1e3)}s`;
|
|
78
|
+
return `${Math.round(ms / 36e5)}h ${Math.round(ms % 36e5 / 6e4)}m`;
|
|
79
|
+
};
|
|
80
|
+
const formatDateTime = (dateStr) => {
|
|
81
|
+
if (!dateStr) return "-";
|
|
82
|
+
const date = new Date(dateStr);
|
|
83
|
+
return date.toLocaleString("en-US", {
|
|
84
|
+
month: "short",
|
|
85
|
+
day: "numeric",
|
|
86
|
+
year: "numeric",
|
|
87
|
+
hour: "2-digit",
|
|
88
|
+
minute: "2-digit",
|
|
89
|
+
second: "2-digit"
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
if (loading && !execution) {
|
|
93
|
+
return /* @__PURE__ */ jsx("div", { className: "p-4 sm:p-6 bg-background-primary min-h-screen", children: /* @__PURE__ */ jsxs("div", { className: "animate-pulse", children: [
|
|
94
|
+
/* @__PURE__ */ jsx("div", { className: "h-8 w-48 bg-background-tertiary rounded mb-4" }),
|
|
95
|
+
/* @__PURE__ */ jsx("div", { className: "h-4 w-32 bg-background-tertiary rounded mb-8" }),
|
|
96
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 sm:grid-cols-4 gap-4 mb-6", children: [...Array(4)].map((_, i) => /* @__PURE__ */ jsx("div", { className: "h-24 bg-background-tertiary rounded-lg" }, i)) }),
|
|
97
|
+
/* @__PURE__ */ jsx("div", { className: "h-96 bg-background-tertiary rounded-lg" })
|
|
98
|
+
] }) });
|
|
99
|
+
}
|
|
100
|
+
if (error) {
|
|
101
|
+
return /* @__PURE__ */ jsxs("div", { className: "p-4 sm:p-6 bg-background-primary min-h-screen", children: [
|
|
102
|
+
/* @__PURE__ */ jsx(
|
|
103
|
+
Link,
|
|
104
|
+
{
|
|
105
|
+
to: "../runs",
|
|
106
|
+
className: "text-action-primary-text hover:underline text-sm mb-4 inline-block",
|
|
107
|
+
children: "\u2190 Back to Executions"
|
|
108
|
+
}
|
|
109
|
+
),
|
|
110
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-[var(--color-status-error-bg-subtle)] border border-[var(--color-status-error-border)] rounded-lg p-6 text-center", children: [
|
|
111
|
+
/* @__PURE__ */ jsx(
|
|
112
|
+
Icon,
|
|
113
|
+
{
|
|
114
|
+
icon: "mdi:alert-circle",
|
|
115
|
+
className: "mx-auto text-[var(--color-status-error-text)] mb-4",
|
|
116
|
+
width: 48
|
|
117
|
+
}
|
|
118
|
+
),
|
|
119
|
+
/* @__PURE__ */ jsx("h2", { className: "text-lg font-medium text-[var(--color-status-error-text)] mb-2", children: "Failed to load execution" }),
|
|
120
|
+
/* @__PURE__ */ jsx("p", { className: "text-[var(--color-status-error-text)] mb-4", children: error.message }),
|
|
121
|
+
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: refetch, children: "Try Again" })
|
|
122
|
+
] })
|
|
123
|
+
] });
|
|
124
|
+
}
|
|
125
|
+
if (!execution) {
|
|
126
|
+
return /* @__PURE__ */ jsxs("div", { className: "p-4 sm:p-6 bg-background-primary min-h-screen", children: [
|
|
127
|
+
/* @__PURE__ */ jsx(
|
|
128
|
+
Link,
|
|
129
|
+
{
|
|
130
|
+
to: "../runs",
|
|
131
|
+
className: "text-action-primary-text hover:underline text-sm mb-4 inline-block",
|
|
132
|
+
children: "\u2190 Back to Executions"
|
|
133
|
+
}
|
|
134
|
+
),
|
|
135
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-background-secondary border border-border-secondary rounded-lg p-6 text-center", children: [
|
|
136
|
+
/* @__PURE__ */ jsx(
|
|
137
|
+
Icon,
|
|
138
|
+
{
|
|
139
|
+
icon: "mdi:file-find-outline",
|
|
140
|
+
className: "mx-auto text-text-secondary mb-4",
|
|
141
|
+
width: 48
|
|
142
|
+
}
|
|
143
|
+
),
|
|
144
|
+
/* @__PURE__ */ jsx("h2", { className: "text-lg font-medium text-text-primary mb-2", children: "Execution not found" }),
|
|
145
|
+
/* @__PURE__ */ jsxs("p", { className: "text-text-secondary", children: [
|
|
146
|
+
'The execution with ID "',
|
|
147
|
+
runId,
|
|
148
|
+
'" could not be found.'
|
|
149
|
+
] })
|
|
150
|
+
] })
|
|
151
|
+
] });
|
|
152
|
+
}
|
|
153
|
+
const tabs = [
|
|
154
|
+
{ id: "timeline", label: "Timeline", icon: "mdi:timeline" },
|
|
155
|
+
{ id: "logs", label: "Logs", icon: "mdi:text-box-outline" },
|
|
156
|
+
{ id: "input", label: "Input Data", icon: "mdi:code-json" },
|
|
157
|
+
{ id: "context", label: "Context", icon: "mdi:information-outline" }
|
|
158
|
+
];
|
|
159
|
+
return /* @__PURE__ */ jsxs("div", { className: "p-4 sm:p-6 bg-background-primary min-h-screen", children: [
|
|
160
|
+
/* @__PURE__ */ jsx(
|
|
161
|
+
Link,
|
|
162
|
+
{
|
|
163
|
+
to: "../runs",
|
|
164
|
+
className: "text-action-primary-text hover:underline text-sm mb-4 inline-block",
|
|
165
|
+
children: "\u2190 Back to Executions"
|
|
166
|
+
}
|
|
167
|
+
),
|
|
168
|
+
execution.parentRunId && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-3 text-sm", children: [
|
|
169
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mdi:sitemap", className: "text-indigo-500", width: 16 }),
|
|
170
|
+
/* @__PURE__ */ jsx("span", { className: "text-text-secondary", children: "Sub-workflow of" }),
|
|
171
|
+
/* @__PURE__ */ jsxs(
|
|
172
|
+
Link,
|
|
173
|
+
{
|
|
174
|
+
to: `../runs/${execution.parentRunId}`,
|
|
175
|
+
className: "text-indigo-600 hover:underline font-medium",
|
|
176
|
+
children: [
|
|
177
|
+
"Parent Run ",
|
|
178
|
+
execution.parentRunId.slice(0, 12),
|
|
179
|
+
"..."
|
|
180
|
+
]
|
|
181
|
+
}
|
|
182
|
+
)
|
|
183
|
+
] }),
|
|
184
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col lg:flex-row lg:items-start lg:justify-between gap-4 mb-6", children: [
|
|
185
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
186
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 mb-2", children: [
|
|
187
|
+
/* @__PURE__ */ jsx("h1", { className: "text-2xl sm:text-3xl font-bold text-text-primary", children: execution.workflow?.name || execution.workflowKey }),
|
|
188
|
+
/* @__PURE__ */ jsx(ExecutionStatusBadge, { status: execution.status, size: "lg" }),
|
|
189
|
+
execution.parentRunId && /* @__PURE__ */ jsx("span", { className: "px-2 py-0.5 text-xs bg-indigo-100 text-indigo-700 rounded", children: "Sub-Workflow" })
|
|
190
|
+
] }),
|
|
191
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-4 text-sm text-text-secondary", children: [
|
|
192
|
+
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
|
|
193
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mdi:identifier", width: 16 }),
|
|
194
|
+
/* @__PURE__ */ jsxs("code", { className: "font-mono", children: [
|
|
195
|
+
execution.id.slice(0, 12),
|
|
196
|
+
"..."
|
|
197
|
+
] })
|
|
198
|
+
] }),
|
|
199
|
+
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
|
|
200
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mdi:tag-outline", width: 16 }),
|
|
201
|
+
"v",
|
|
202
|
+
execution.version
|
|
203
|
+
] }),
|
|
204
|
+
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
|
|
205
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mdi:clock-outline", width: 16 }),
|
|
206
|
+
formatDateTime(execution.startedAt || execution.createdAt)
|
|
207
|
+
] })
|
|
208
|
+
] })
|
|
209
|
+
] }),
|
|
210
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
211
|
+
isActive && /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm text-text-secondary mr-4", children: [
|
|
212
|
+
/* @__PURE__ */ jsx(
|
|
213
|
+
"input",
|
|
214
|
+
{
|
|
215
|
+
type: "checkbox",
|
|
216
|
+
checked: autoRefreshEnabled,
|
|
217
|
+
onChange: (e) => setAutoRefreshEnabled(e.target.checked),
|
|
218
|
+
className: "w-4 h-4 rounded"
|
|
219
|
+
}
|
|
220
|
+
),
|
|
221
|
+
"Auto-refresh"
|
|
222
|
+
] }),
|
|
223
|
+
execution.status === "RUNNING" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
224
|
+
/* @__PURE__ */ jsxs(
|
|
225
|
+
Button,
|
|
226
|
+
{
|
|
227
|
+
variant: "outline",
|
|
228
|
+
size: "sm",
|
|
229
|
+
onClick: handlePause,
|
|
230
|
+
disabled: actionLoading,
|
|
231
|
+
children: [
|
|
232
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mdi:pause", className: "mr-1", width: 16 }),
|
|
233
|
+
"Pause"
|
|
234
|
+
]
|
|
235
|
+
}
|
|
236
|
+
),
|
|
237
|
+
/* @__PURE__ */ jsxs(
|
|
238
|
+
Button,
|
|
239
|
+
{
|
|
240
|
+
variant: "outline",
|
|
241
|
+
size: "sm",
|
|
242
|
+
onClick: handleCancel,
|
|
243
|
+
disabled: actionLoading,
|
|
244
|
+
className: "border-[var(--color-status-warning-border)] text-[var(--color-status-warning-text)] hover:bg-[var(--color-status-warning-bg-subtle)]",
|
|
245
|
+
children: [
|
|
246
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mdi:stop", className: "mr-1", width: 16 }),
|
|
247
|
+
"Cancel"
|
|
248
|
+
]
|
|
249
|
+
}
|
|
250
|
+
)
|
|
251
|
+
] }),
|
|
252
|
+
execution.status === "WAITING" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
253
|
+
/* @__PURE__ */ jsxs(
|
|
254
|
+
Button,
|
|
255
|
+
{
|
|
256
|
+
variant: "outline",
|
|
257
|
+
size: "sm",
|
|
258
|
+
onClick: handleResume,
|
|
259
|
+
disabled: actionLoading,
|
|
260
|
+
children: [
|
|
261
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mdi:play", className: "mr-1", width: 16 }),
|
|
262
|
+
"Resume"
|
|
263
|
+
]
|
|
264
|
+
}
|
|
265
|
+
),
|
|
266
|
+
/* @__PURE__ */ jsxs(
|
|
267
|
+
Button,
|
|
268
|
+
{
|
|
269
|
+
variant: "outline",
|
|
270
|
+
size: "sm",
|
|
271
|
+
onClick: handleCancel,
|
|
272
|
+
disabled: actionLoading,
|
|
273
|
+
className: "border-[var(--color-status-warning-border)] text-[var(--color-status-warning-text)] hover:bg-[var(--color-status-warning-bg-subtle)]",
|
|
274
|
+
children: [
|
|
275
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mdi:stop", className: "mr-1", width: 16 }),
|
|
276
|
+
"Cancel"
|
|
277
|
+
]
|
|
278
|
+
}
|
|
279
|
+
)
|
|
280
|
+
] }),
|
|
281
|
+
execution.status === "PENDING" && /* @__PURE__ */ jsxs(
|
|
282
|
+
Button,
|
|
283
|
+
{
|
|
284
|
+
variant: "outline",
|
|
285
|
+
size: "sm",
|
|
286
|
+
onClick: handleCancel,
|
|
287
|
+
disabled: actionLoading,
|
|
288
|
+
children: [
|
|
289
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mdi:stop", className: "mr-1", width: 16 }),
|
|
290
|
+
"Cancel"
|
|
291
|
+
]
|
|
292
|
+
}
|
|
293
|
+
),
|
|
294
|
+
(execution.status === "RUNNING" || execution.status === "WAITING") && /* @__PURE__ */ jsxs(
|
|
295
|
+
Button,
|
|
296
|
+
{
|
|
297
|
+
variant: "outline",
|
|
298
|
+
size: "sm",
|
|
299
|
+
onClick: () => setShowTerminateDialog(true),
|
|
300
|
+
disabled: actionLoading,
|
|
301
|
+
className: "border-[var(--color-status-error-border)] text-[var(--color-status-error-text)] hover:bg-[var(--color-status-error-bg-subtle)]",
|
|
302
|
+
children: [
|
|
303
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mdi:close-octagon", className: "mr-1", width: 16 }),
|
|
304
|
+
"Terminate"
|
|
305
|
+
]
|
|
306
|
+
}
|
|
307
|
+
),
|
|
308
|
+
/* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", onClick: refetch, children: [
|
|
309
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mdi:refresh", className: "mr-1", width: 16 }),
|
|
310
|
+
"Refresh"
|
|
311
|
+
] })
|
|
312
|
+
] })
|
|
313
|
+
] }),
|
|
314
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 sm:grid-cols-4 gap-4 mb-6", children: [
|
|
315
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-background-secondary rounded-lg border border-border-secondary p-4", children: [
|
|
316
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm text-text-secondary", children: "Duration" }),
|
|
317
|
+
/* @__PURE__ */ jsx("div", { className: "text-xl font-bold text-text-primary mt-1", children: formatDuration(execution.duration) })
|
|
318
|
+
] }),
|
|
319
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-background-secondary rounded-lg border border-border-secondary p-4", children: [
|
|
320
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm text-text-secondary", children: "Progress" }),
|
|
321
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
|
|
322
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 h-2 bg-background-tertiary rounded-full overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
323
|
+
"div",
|
|
324
|
+
{
|
|
325
|
+
className: `h-full ${execution.status === "FAILED" ? "bg-[var(--color-status-error-bg)]" : execution.status === "COMPLETED" ? "bg-[var(--color-status-success-bg)]" : "bg-[var(--color-status-info-bg)]"}`,
|
|
326
|
+
style: { width: `${execution.progress}%` }
|
|
327
|
+
}
|
|
328
|
+
) }),
|
|
329
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xl font-bold text-text-primary", children: [
|
|
330
|
+
Math.round(execution.progress),
|
|
331
|
+
"%"
|
|
332
|
+
] })
|
|
333
|
+
] })
|
|
334
|
+
] }),
|
|
335
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-background-secondary rounded-lg border border-border-secondary p-4", children: [
|
|
336
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm text-text-secondary", children: "Nodes" }),
|
|
337
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
|
|
338
|
+
/* @__PURE__ */ jsx("span", { className: "text-xl font-bold text-[var(--color-status-success-text)]", children: execution.completedNodes ?? 0 }),
|
|
339
|
+
/* @__PURE__ */ jsx("span", { className: "text-text-secondary", children: "/" }),
|
|
340
|
+
/* @__PURE__ */ jsx("span", { className: "text-xl font-bold text-text-primary", children: execution.totalNodes ?? 0 }),
|
|
341
|
+
(execution.failedNodes ?? 0) > 0 && /* @__PURE__ */ jsxs("span", { className: "text-sm text-[var(--color-status-error-text)] ml-2", children: [
|
|
342
|
+
"(",
|
|
343
|
+
execution.failedNodes,
|
|
344
|
+
" failed)"
|
|
345
|
+
] })
|
|
346
|
+
] })
|
|
347
|
+
] }),
|
|
348
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-background-secondary rounded-lg border border-border-secondary p-4", children: [
|
|
349
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm text-text-secondary", children: "Trigger" }),
|
|
350
|
+
/* @__PURE__ */ jsx("div", { className: "text-lg font-medium text-text-primary mt-1 truncate", children: execution.triggerNodeId })
|
|
351
|
+
] })
|
|
352
|
+
] }),
|
|
353
|
+
execution.errorMessage && /* @__PURE__ */ jsxs("div", { className: "mb-6 p-4 bg-[var(--color-status-error-bg-subtle)] border border-[var(--color-status-error-border)] rounded-lg", children: [
|
|
354
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-[var(--color-status-error-text)] mb-2", children: [
|
|
355
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mdi:alert-circle", width: 20 }),
|
|
356
|
+
/* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
|
|
357
|
+
"Error",
|
|
358
|
+
execution.errorType ? ` (${execution.errorType})` : ""
|
|
359
|
+
] })
|
|
360
|
+
] }),
|
|
361
|
+
/* @__PURE__ */ jsx("p", { className: "text-[var(--color-status-error-text)]", children: execution.errorMessage })
|
|
362
|
+
] }),
|
|
363
|
+
/* @__PURE__ */ jsx("div", { className: "border-b border-border-secondary mb-6", children: /* @__PURE__ */ jsx("nav", { className: "flex gap-4 -mb-px", children: tabs.map((tab) => /* @__PURE__ */ jsxs(
|
|
364
|
+
"button",
|
|
365
|
+
{
|
|
366
|
+
onClick: () => setActiveTab(tab.id),
|
|
367
|
+
className: `
|
|
368
|
+
flex items-center gap-2 px-4 py-3 border-b-2 text-sm font-medium transition-colors
|
|
369
|
+
${activeTab === tab.id ? "border-action-primary-bg text-action-primary-text" : "border-transparent text-text-secondary hover:text-text-primary hover:border-border-primary"}
|
|
370
|
+
`,
|
|
371
|
+
children: [
|
|
372
|
+
/* @__PURE__ */ jsx(Icon, { icon: tab.icon, width: 18 }),
|
|
373
|
+
tab.label
|
|
374
|
+
]
|
|
375
|
+
},
|
|
376
|
+
tab.id
|
|
377
|
+
)) }) }),
|
|
378
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-background-secondary rounded-lg border border-border-secondary", children: [
|
|
379
|
+
activeTab === "timeline" && /* @__PURE__ */ jsx("div", { className: "p-4 sm:p-6", children: /* @__PURE__ */ jsx(
|
|
380
|
+
NodeTimeline,
|
|
381
|
+
{
|
|
382
|
+
nodeStates: execution.nodeStates ?? [],
|
|
383
|
+
onRetryNode: handleRetryNode,
|
|
384
|
+
onViewChildRun: handleViewChildRun
|
|
385
|
+
}
|
|
386
|
+
) }),
|
|
387
|
+
activeTab === "logs" && /* @__PURE__ */ jsx("div", { className: "p-4 sm:p-6", children: logsLoading && logs.length === 0 ? /* @__PURE__ */ jsx("div", { className: "space-y-2", children: [...Array(5)].map((_, i) => /* @__PURE__ */ jsx(
|
|
388
|
+
"div",
|
|
389
|
+
{
|
|
390
|
+
className: "h-8 bg-background-tertiary rounded animate-pulse"
|
|
391
|
+
},
|
|
392
|
+
i
|
|
393
|
+
)) }) : logs.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "text-center py-8 text-text-secondary", children: [
|
|
394
|
+
/* @__PURE__ */ jsx(
|
|
395
|
+
Icon,
|
|
396
|
+
{
|
|
397
|
+
icon: "mdi:text-box-outline",
|
|
398
|
+
className: "mx-auto mb-2",
|
|
399
|
+
width: 32
|
|
400
|
+
}
|
|
401
|
+
),
|
|
402
|
+
/* @__PURE__ */ jsx("p", { children: "No logs available" })
|
|
403
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "space-y-1 font-mono text-sm max-h-[600px] overflow-auto", children: logs.map((log) => /* @__PURE__ */ jsxs(
|
|
404
|
+
"div",
|
|
405
|
+
{
|
|
406
|
+
className: `
|
|
407
|
+
flex items-start gap-3 px-3 py-1.5 rounded
|
|
408
|
+
${log.level === "ERROR" ? "bg-[var(--color-status-error-bg-subtle)] text-[var(--color-status-error-text)]" : log.level === "WARN" ? "bg-[var(--color-status-warning-bg-subtle)] text-[var(--color-status-warning-text)]" : "text-text-primary hover:bg-background-tertiary"}
|
|
409
|
+
`,
|
|
410
|
+
children: [
|
|
411
|
+
/* @__PURE__ */ jsx("span", { className: "text-text-secondary text-xs whitespace-nowrap", children: new Date(log.timestamp).toLocaleTimeString() }),
|
|
412
|
+
/* @__PURE__ */ jsx(
|
|
413
|
+
"span",
|
|
414
|
+
{
|
|
415
|
+
className: `
|
|
416
|
+
text-xs px-1.5 py-0.5 rounded uppercase font-medium
|
|
417
|
+
${log.level === "ERROR" ? "bg-[var(--color-status-error-bg)] text-[var(--color-status-error-text)]" : log.level === "WARN" ? "bg-[var(--color-status-warning-bg)] text-[var(--color-status-warning-text)]" : log.level === "INFO" ? "bg-[var(--color-status-info-bg)] text-[var(--color-status-info-text)]" : "bg-muted text-tertiary"}
|
|
418
|
+
`,
|
|
419
|
+
children: log.level
|
|
420
|
+
}
|
|
421
|
+
),
|
|
422
|
+
log.nodeId && /* @__PURE__ */ jsxs("span", { className: "text-xs text-text-secondary", children: [
|
|
423
|
+
"[",
|
|
424
|
+
log.nodeId,
|
|
425
|
+
"]"
|
|
426
|
+
] }),
|
|
427
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1", children: log.message })
|
|
428
|
+
]
|
|
429
|
+
},
|
|
430
|
+
log.id
|
|
431
|
+
)) }) }),
|
|
432
|
+
activeTab === "input" && /* @__PURE__ */ jsxs("div", { className: "p-4 sm:p-6", children: [
|
|
433
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-medium text-text-primary mb-4", children: "Trigger Data" }),
|
|
434
|
+
/* @__PURE__ */ jsx("div", { className: "bg-background-primary rounded p-4 max-h-[400px] overflow-auto", children: /* @__PURE__ */ jsx("pre", { className: "text-sm text-text-primary font-mono whitespace-pre-wrap break-words", children: JSON.stringify(execution.triggerData ?? null, null, 2) }) })
|
|
435
|
+
] }),
|
|
436
|
+
activeTab === "context" && /* @__PURE__ */ jsx("div", { className: "p-4 sm:p-6", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-6", children: [
|
|
437
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
438
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-medium text-text-primary mb-4", children: "Execution Context" }),
|
|
439
|
+
/* @__PURE__ */ jsx("div", { className: "bg-background-primary rounded p-4 max-h-[300px] overflow-auto", children: /* @__PURE__ */ jsx("pre", { className: "text-sm text-text-primary font-mono whitespace-pre-wrap break-words", children: JSON.stringify(execution.context ?? null, null, 2) }) })
|
|
440
|
+
] }),
|
|
441
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
442
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-medium text-text-primary mb-4", children: "Execution Details" }),
|
|
443
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
444
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between py-2 border-b border-border-secondary", children: [
|
|
445
|
+
/* @__PURE__ */ jsx("span", { className: "text-text-secondary", children: "Run ID" }),
|
|
446
|
+
/* @__PURE__ */ jsx("code", { className: "font-mono text-text-primary", children: execution.id })
|
|
447
|
+
] }),
|
|
448
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between py-2 border-b border-border-secondary", children: [
|
|
449
|
+
/* @__PURE__ */ jsx("span", { className: "text-text-secondary", children: "Workflow ID" }),
|
|
450
|
+
/* @__PURE__ */ jsx("code", { className: "font-mono text-text-primary", children: execution.workflowId })
|
|
451
|
+
] }),
|
|
452
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between py-2 border-b border-border-secondary", children: [
|
|
453
|
+
/* @__PURE__ */ jsx("span", { className: "text-text-secondary", children: "Workflow Key" }),
|
|
454
|
+
/* @__PURE__ */ jsx("span", { className: "text-text-primary", children: execution.workflowKey })
|
|
455
|
+
] }),
|
|
456
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between py-2 border-b border-border-secondary", children: [
|
|
457
|
+
/* @__PURE__ */ jsx("span", { className: "text-text-secondary", children: "Version" }),
|
|
458
|
+
/* @__PURE__ */ jsx("span", { className: "text-text-primary", children: execution.version })
|
|
459
|
+
] }),
|
|
460
|
+
execution.triggeredById && /* @__PURE__ */ jsxs("div", { className: "flex justify-between py-2 border-b border-border-secondary", children: [
|
|
461
|
+
/* @__PURE__ */ jsx("span", { className: "text-text-secondary", children: "Triggered By" }),
|
|
462
|
+
/* @__PURE__ */ jsx("span", { className: "text-text-primary", children: execution.triggeredById })
|
|
463
|
+
] }),
|
|
464
|
+
execution.parentRunId && /* @__PURE__ */ jsxs("div", { className: "flex justify-between py-2 border-b border-border-secondary", children: [
|
|
465
|
+
/* @__PURE__ */ jsx("span", { className: "text-text-secondary", children: "Parent Run" }),
|
|
466
|
+
/* @__PURE__ */ jsxs(
|
|
467
|
+
Link,
|
|
468
|
+
{
|
|
469
|
+
to: `/runs/${execution.parentRunId}`,
|
|
470
|
+
className: "text-action-primary-text hover:underline font-mono",
|
|
471
|
+
children: [
|
|
472
|
+
execution.parentRunId.slice(0, 12),
|
|
473
|
+
"..."
|
|
474
|
+
]
|
|
475
|
+
}
|
|
476
|
+
)
|
|
477
|
+
] }),
|
|
478
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between py-2 border-b border-border-secondary", children: [
|
|
479
|
+
/* @__PURE__ */ jsx("span", { className: "text-text-secondary", children: "Created" }),
|
|
480
|
+
/* @__PURE__ */ jsx("span", { className: "text-text-primary", children: formatDateTime(execution.createdAt) })
|
|
481
|
+
] }),
|
|
482
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between py-2 border-b border-border-secondary", children: [
|
|
483
|
+
/* @__PURE__ */ jsx("span", { className: "text-text-secondary", children: "Started" }),
|
|
484
|
+
/* @__PURE__ */ jsx("span", { className: "text-text-primary", children: formatDateTime(execution.startedAt) })
|
|
485
|
+
] }),
|
|
486
|
+
execution.completedAt && /* @__PURE__ */ jsxs("div", { className: "flex justify-between py-2 border-b border-border-secondary", children: [
|
|
487
|
+
/* @__PURE__ */ jsx("span", { className: "text-text-secondary", children: "Completed" }),
|
|
488
|
+
/* @__PURE__ */ jsx("span", { className: "text-text-primary", children: formatDateTime(execution.completedAt) })
|
|
489
|
+
] })
|
|
490
|
+
] })
|
|
491
|
+
] })
|
|
492
|
+
] }) })
|
|
493
|
+
] }),
|
|
494
|
+
/* @__PURE__ */ jsx(
|
|
495
|
+
AlertDialog,
|
|
496
|
+
{
|
|
497
|
+
open: showTerminateDialog,
|
|
498
|
+
onOpenChange: setShowTerminateDialog,
|
|
499
|
+
children: /* @__PURE__ */ jsxs(AlertDialogContent, { children: [
|
|
500
|
+
/* @__PURE__ */ jsxs(AlertDialogHeader, { children: [
|
|
501
|
+
/* @__PURE__ */ jsx(AlertDialogTitle, { children: "Terminate Execution" }),
|
|
502
|
+
/* @__PURE__ */ jsx(AlertDialogDescription, { children: "Are you sure you want to force terminate this execution? This will immediately stop the running workflow and cannot be resumed." })
|
|
503
|
+
] }),
|
|
504
|
+
/* @__PURE__ */ jsxs(AlertDialogFooter, { children: [
|
|
505
|
+
/* @__PURE__ */ jsx(AlertDialogCancel, { disabled: actionLoading, children: "Cancel" }),
|
|
506
|
+
/* @__PURE__ */ jsx(
|
|
507
|
+
AlertDialogAction,
|
|
508
|
+
{
|
|
509
|
+
onClick: handleTerminate,
|
|
510
|
+
disabled: actionLoading,
|
|
511
|
+
className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
512
|
+
children: actionLoading ? "Terminating..." : "Terminate"
|
|
513
|
+
}
|
|
514
|
+
)
|
|
515
|
+
] })
|
|
516
|
+
] })
|
|
517
|
+
}
|
|
518
|
+
)
|
|
519
|
+
] });
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
export { ExecutionDetailPage };
|
|
523
|
+
//# sourceMappingURL=chunk-GY66IQWN.js.map
|
|
524
|
+
//# sourceMappingURL=chunk-GY66IQWN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/modules/executions/pages/ExecutionDetailPage.tsx"],"names":[],"mappings":"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","file":"chunk-GY66IQWN.js","sourcesContent":["import { useState, useCallback } from \"react\";\nimport { useParams, Link, useNavigate } from \"react-router-dom\";\nimport { Icon } from \"@iconify/react\";\nimport { Button } from \"@burdenoff/fe-libs/button\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from \"@burdenoff/fe-libs/ui\";\nimport { ExecutionStatusBadge, NodeTimeline } from \"../components\";\nimport {\n useExecution,\n useExecutionLogs,\n useExecutionActions,\n useAutoRefresh,\n} from \"../hooks/useExecutions\";\n\ntype DetailTab = \"timeline\" | \"logs\" | \"input\" | \"context\";\n\nexport function ExecutionDetailPage() {\n const { runId } = useParams<{ runId: string }>();\n const navigate = useNavigate();\n\n const [activeTab, setActiveTab] = useState<DetailTab>(\"timeline\");\n const [autoRefreshEnabled, setAutoRefreshEnabled] = useState(true);\n const [showTerminateDialog, setShowTerminateDialog] = useState(false);\n\n // Data fetching\n const { execution, loading, error, refetch } = useExecution(runId);\n const {\n logs,\n loading: logsLoading,\n refetch: refetchLogs,\n } = useExecutionLogs(runId, 100);\n const {\n pauseExecution,\n resumeExecution,\n cancelExecution,\n retryNode,\n terminateExecution,\n loading: actionLoading,\n } = useExecutionActions();\n\n // Auto-refresh for running executions\n const isActive =\n execution?.status === \"RUNNING\" ||\n execution?.status === \"PENDING\" ||\n execution?.status === \"WAITING\";\n\n useAutoRefresh(\n useCallback(() => {\n refetch();\n if (activeTab === \"logs\") {\n refetchLogs();\n }\n }, [refetch, refetchLogs, activeTab]),\n autoRefreshEnabled && isActive,\n 2000,\n );\n\n // Handlers\n const handlePause = async () => {\n if (!runId) return;\n await pauseExecution(runId);\n refetch();\n };\n\n const handleResume = async () => {\n if (!runId) return;\n await resumeExecution(runId);\n refetch();\n };\n\n const handleCancel = async () => {\n if (!runId) return;\n await cancelExecution(runId);\n refetch();\n };\n\n const handleTerminate = async () => {\n if (!runId) return;\n await terminateExecution(runId, \"User terminated\");\n setShowTerminateDialog(false);\n refetch();\n };\n\n const handleRetryNode = async (nodeId: string) => {\n if (!runId) return;\n await retryNode(runId, nodeId);\n refetch();\n };\n\n const handleViewChildRun = useCallback(\n (childRunId: string) => {\n navigate(`../runs/${childRunId}`);\n },\n [navigate],\n );\n\n // Formatting helpers\n const formatDuration = (ms?: number): string => {\n if (!ms) return \"-\";\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;\n if (ms < 3600000)\n return `${Math.round(ms / 60000)}m ${Math.round((ms % 60000) / 1000)}s`;\n return `${Math.round(ms / 3600000)}h ${Math.round((ms % 3600000) / 60000)}m`;\n };\n\n const formatDateTime = (dateStr?: string): string => {\n if (!dateStr) return \"-\";\n const date = new Date(dateStr);\n return date.toLocaleString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n });\n };\n\n // Loading state\n if (loading && !execution) {\n return (\n <div className=\"p-4 sm:p-6 bg-background-primary min-h-screen\">\n <div className=\"animate-pulse\">\n <div className=\"h-8 w-48 bg-background-tertiary rounded mb-4\" />\n <div className=\"h-4 w-32 bg-background-tertiary rounded mb-8\" />\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-4 mb-6\">\n {[...Array(4)].map((_, i) => (\n <div key={i} className=\"h-24 bg-background-tertiary rounded-lg\" />\n ))}\n </div>\n <div className=\"h-96 bg-background-tertiary rounded-lg\" />\n </div>\n </div>\n );\n }\n\n // Error state\n if (error) {\n return (\n <div className=\"p-4 sm:p-6 bg-background-primary min-h-screen\">\n <Link\n to=\"../runs\"\n className=\"text-action-primary-text hover:underline text-sm mb-4 inline-block\"\n >\n ← Back to Executions\n </Link>\n <div className=\"bg-[var(--color-status-error-bg-subtle)] border border-[var(--color-status-error-border)] rounded-lg p-6 text-center\">\n <Icon\n icon=\"mdi:alert-circle\"\n className=\"mx-auto text-[var(--color-status-error-text)] mb-4\"\n width={48}\n />\n <h2 className=\"text-lg font-medium text-[var(--color-status-error-text)] mb-2\">\n Failed to load execution\n </h2>\n <p className=\"text-[var(--color-status-error-text)] mb-4\">\n {error.message}\n </p>\n <Button variant=\"outline\" onClick={refetch}>\n Try Again\n </Button>\n </div>\n </div>\n );\n }\n\n // Not found state\n if (!execution) {\n return (\n <div className=\"p-4 sm:p-6 bg-background-primary min-h-screen\">\n <Link\n to=\"../runs\"\n className=\"text-action-primary-text hover:underline text-sm mb-4 inline-block\"\n >\n ← Back to Executions\n </Link>\n <div className=\"bg-background-secondary border border-border-secondary rounded-lg p-6 text-center\">\n <Icon\n icon=\"mdi:file-find-outline\"\n className=\"mx-auto text-text-secondary mb-4\"\n width={48}\n />\n <h2 className=\"text-lg font-medium text-text-primary mb-2\">\n Execution not found\n </h2>\n <p className=\"text-text-secondary\">\n The execution with ID "{runId}" could not be found.\n </p>\n </div>\n </div>\n );\n }\n\n const tabs: Array<{ id: DetailTab; label: string; icon: string }> = [\n { id: \"timeline\", label: \"Timeline\", icon: \"mdi:timeline\" },\n { id: \"logs\", label: \"Logs\", icon: \"mdi:text-box-outline\" },\n { id: \"input\", label: \"Input Data\", icon: \"mdi:code-json\" },\n { id: \"context\", label: \"Context\", icon: \"mdi:information-outline\" },\n ];\n\n return (\n <div className=\"p-4 sm:p-6 bg-background-primary min-h-screen\">\n {/* Back link */}\n <Link\n to=\"../runs\"\n className=\"text-action-primary-text hover:underline text-sm mb-4 inline-block\"\n >\n ← Back to Executions\n </Link>\n\n {/* Sub-workflow parent breadcrumb */}\n {execution.parentRunId && (\n <div className=\"flex items-center gap-2 mb-3 text-sm\">\n <Icon icon=\"mdi:sitemap\" className=\"text-indigo-500\" width={16} />\n <span className=\"text-text-secondary\">Sub-workflow of</span>\n <Link\n to={`../runs/${execution.parentRunId}`}\n className=\"text-indigo-600 hover:underline font-medium\"\n >\n Parent Run {execution.parentRunId.slice(0, 12)}...\n </Link>\n </div>\n )}\n\n {/* Header */}\n <div className=\"flex flex-col lg:flex-row lg:items-start lg:justify-between gap-4 mb-6\">\n <div>\n <div className=\"flex items-center gap-3 mb-2\">\n <h1 className=\"text-2xl sm:text-3xl font-bold text-text-primary\">\n {execution.workflow?.name || execution.workflowKey}\n </h1>\n <ExecutionStatusBadge status={execution.status} size=\"lg\" />\n {execution.parentRunId && (\n <span className=\"px-2 py-0.5 text-xs bg-indigo-100 text-indigo-700 rounded\">\n Sub-Workflow\n </span>\n )}\n </div>\n <div className=\"flex flex-wrap items-center gap-4 text-sm text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <Icon icon=\"mdi:identifier\" width={16} />\n <code className=\"font-mono\">{execution.id.slice(0, 12)}...</code>\n </span>\n <span className=\"flex items-center gap-1\">\n <Icon icon=\"mdi:tag-outline\" width={16} />v{execution.version}\n </span>\n <span className=\"flex items-center gap-1\">\n <Icon icon=\"mdi:clock-outline\" width={16} />\n {formatDateTime(execution.startedAt || execution.createdAt)}\n </span>\n </div>\n </div>\n\n {/* Actions */}\n <div className=\"flex flex-wrap items-center gap-2\">\n {/* Auto-refresh toggle */}\n {isActive && (\n <label className=\"flex items-center gap-2 text-sm text-text-secondary mr-4\">\n <input\n type=\"checkbox\"\n checked={autoRefreshEnabled}\n onChange={(e) => setAutoRefreshEnabled(e.target.checked)}\n className=\"w-4 h-4 rounded\"\n />\n Auto-refresh\n </label>\n )}\n\n {/* Control buttons based on status */}\n {execution.status === \"RUNNING\" && (\n <>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handlePause}\n disabled={actionLoading}\n >\n <Icon icon=\"mdi:pause\" className=\"mr-1\" width={16} />\n Pause\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleCancel}\n disabled={actionLoading}\n className=\"border-[var(--color-status-warning-border)] text-[var(--color-status-warning-text)] hover:bg-[var(--color-status-warning-bg-subtle)]\"\n >\n <Icon icon=\"mdi:stop\" className=\"mr-1\" width={16} />\n Cancel\n </Button>\n </>\n )}\n\n {execution.status === \"WAITING\" && (\n <>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleResume}\n disabled={actionLoading}\n >\n <Icon icon=\"mdi:play\" className=\"mr-1\" width={16} />\n Resume\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleCancel}\n disabled={actionLoading}\n className=\"border-[var(--color-status-warning-border)] text-[var(--color-status-warning-text)] hover:bg-[var(--color-status-warning-bg-subtle)]\"\n >\n <Icon icon=\"mdi:stop\" className=\"mr-1\" width={16} />\n Cancel\n </Button>\n </>\n )}\n\n {execution.status === \"PENDING\" && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleCancel}\n disabled={actionLoading}\n >\n <Icon icon=\"mdi:stop\" className=\"mr-1\" width={16} />\n Cancel\n </Button>\n )}\n\n {(execution.status === \"RUNNING\" ||\n execution.status === \"WAITING\") && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setShowTerminateDialog(true)}\n disabled={actionLoading}\n className=\"border-[var(--color-status-error-border)] text-[var(--color-status-error-text)] hover:bg-[var(--color-status-error-bg-subtle)]\"\n >\n <Icon icon=\"mdi:close-octagon\" className=\"mr-1\" width={16} />\n Terminate\n </Button>\n )}\n\n <Button variant=\"outline\" size=\"sm\" onClick={refetch}>\n <Icon icon=\"mdi:refresh\" className=\"mr-1\" width={16} />\n Refresh\n </Button>\n </div>\n </div>\n\n {/* Stats Grid */}\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-4 mb-6\">\n <div className=\"bg-background-secondary rounded-lg border border-border-secondary p-4\">\n <div className=\"text-sm text-text-secondary\">Duration</div>\n <div className=\"text-xl font-bold text-text-primary mt-1\">\n {formatDuration(execution.duration)}\n </div>\n </div>\n <div className=\"bg-background-secondary rounded-lg border border-border-secondary p-4\">\n <div className=\"text-sm text-text-secondary\">Progress</div>\n <div className=\"flex items-center gap-2 mt-1\">\n <div className=\"flex-1 h-2 bg-background-tertiary rounded-full overflow-hidden\">\n <div\n className={`h-full ${\n execution.status === \"FAILED\"\n ? \"bg-[var(--color-status-error-bg)]\"\n : execution.status === \"COMPLETED\"\n ? \"bg-[var(--color-status-success-bg)]\"\n : \"bg-[var(--color-status-info-bg)]\"\n }`}\n style={{ width: `${execution.progress}%` }}\n />\n </div>\n <span className=\"text-xl font-bold text-text-primary\">\n {Math.round(execution.progress)}%\n </span>\n </div>\n </div>\n <div className=\"bg-background-secondary rounded-lg border border-border-secondary p-4\">\n <div className=\"text-sm text-text-secondary\">Nodes</div>\n <div className=\"flex items-center gap-2 mt-1\">\n <span className=\"text-xl font-bold text-[var(--color-status-success-text)]\">\n {execution.completedNodes ?? 0}\n </span>\n <span className=\"text-text-secondary\">/</span>\n <span className=\"text-xl font-bold text-text-primary\">\n {execution.totalNodes ?? 0}\n </span>\n {(execution.failedNodes ?? 0) > 0 && (\n <span className=\"text-sm text-[var(--color-status-error-text)] ml-2\">\n ({execution.failedNodes} failed)\n </span>\n )}\n </div>\n </div>\n <div className=\"bg-background-secondary rounded-lg border border-border-secondary p-4\">\n <div className=\"text-sm text-text-secondary\">Trigger</div>\n <div className=\"text-lg font-medium text-text-primary mt-1 truncate\">\n {execution.triggerNodeId}\n </div>\n </div>\n </div>\n\n {/* Error Banner */}\n {execution.errorMessage && (\n <div className=\"mb-6 p-4 bg-[var(--color-status-error-bg-subtle)] border border-[var(--color-status-error-border)] rounded-lg\">\n <div className=\"flex items-center gap-2 text-[var(--color-status-error-text)] mb-2\">\n <Icon icon=\"mdi:alert-circle\" width={20} />\n <span className=\"font-medium\">\n Error{execution.errorType ? ` (${execution.errorType})` : \"\"}\n </span>\n </div>\n <p className=\"text-[var(--color-status-error-text)]\">\n {execution.errorMessage}\n </p>\n </div>\n )}\n\n {/* Tabs */}\n <div className=\"border-b border-border-secondary mb-6\">\n <nav className=\"flex gap-4 -mb-px\">\n {tabs.map((tab) => (\n <button\n key={tab.id}\n onClick={() => setActiveTab(tab.id)}\n className={`\n flex items-center gap-2 px-4 py-3 border-b-2 text-sm font-medium transition-colors\n ${\n activeTab === tab.id\n ? \"border-action-primary-bg text-action-primary-text\"\n : \"border-transparent text-text-secondary hover:text-text-primary hover:border-border-primary\"\n }\n `}\n >\n <Icon icon={tab.icon} width={18} />\n {tab.label}\n </button>\n ))}\n </nav>\n </div>\n\n {/* Tab Content */}\n <div className=\"bg-background-secondary rounded-lg border border-border-secondary\">\n {activeTab === \"timeline\" && (\n <div className=\"p-4 sm:p-6\">\n <NodeTimeline\n nodeStates={execution.nodeStates ?? []}\n onRetryNode={handleRetryNode}\n onViewChildRun={handleViewChildRun}\n />\n </div>\n )}\n\n {activeTab === \"logs\" && (\n <div className=\"p-4 sm:p-6\">\n {logsLoading && logs.length === 0 ? (\n <div className=\"space-y-2\">\n {[...Array(5)].map((_, i) => (\n <div\n key={i}\n className=\"h-8 bg-background-tertiary rounded animate-pulse\"\n />\n ))}\n </div>\n ) : logs.length === 0 ? (\n <div className=\"text-center py-8 text-text-secondary\">\n <Icon\n icon=\"mdi:text-box-outline\"\n className=\"mx-auto mb-2\"\n width={32}\n />\n <p>No logs available</p>\n </div>\n ) : (\n <div className=\"space-y-1 font-mono text-sm max-h-[600px] overflow-auto\">\n {logs.map((log) => (\n <div\n key={log.id}\n className={`\n flex items-start gap-3 px-3 py-1.5 rounded\n ${\n log.level === \"ERROR\"\n ? \"bg-[var(--color-status-error-bg-subtle)] text-[var(--color-status-error-text)]\"\n : log.level === \"WARN\"\n ? \"bg-[var(--color-status-warning-bg-subtle)] text-[var(--color-status-warning-text)]\"\n : \"text-text-primary hover:bg-background-tertiary\"\n }\n `}\n >\n <span className=\"text-text-secondary text-xs whitespace-nowrap\">\n {new Date(log.timestamp).toLocaleTimeString()}\n </span>\n <span\n className={`\n text-xs px-1.5 py-0.5 rounded uppercase font-medium\n ${\n log.level === \"ERROR\"\n ? \"bg-[var(--color-status-error-bg)] text-[var(--color-status-error-text)]\"\n : log.level === \"WARN\"\n ? \"bg-[var(--color-status-warning-bg)] text-[var(--color-status-warning-text)]\"\n : log.level === \"INFO\"\n ? \"bg-[var(--color-status-info-bg)] text-[var(--color-status-info-text)]\"\n : \"bg-muted text-tertiary\"\n }\n `}\n >\n {log.level}\n </span>\n {log.nodeId && (\n <span className=\"text-xs text-text-secondary\">\n [{log.nodeId}]\n </span>\n )}\n <span className=\"flex-1\">{log.message}</span>\n </div>\n ))}\n </div>\n )}\n </div>\n )}\n\n {activeTab === \"input\" && (\n <div className=\"p-4 sm:p-6\">\n <h3 className=\"text-lg font-medium text-text-primary mb-4\">\n Trigger Data\n </h3>\n <div className=\"bg-background-primary rounded p-4 max-h-[400px] overflow-auto\">\n <pre className=\"text-sm text-text-primary font-mono whitespace-pre-wrap break-words\">\n {JSON.stringify(execution.triggerData ?? null, null, 2)}\n </pre>\n </div>\n </div>\n )}\n\n {activeTab === \"context\" && (\n <div className=\"p-4 sm:p-6\">\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\n <div>\n <h3 className=\"text-lg font-medium text-text-primary mb-4\">\n Execution Context\n </h3>\n <div className=\"bg-background-primary rounded p-4 max-h-[300px] overflow-auto\">\n <pre className=\"text-sm text-text-primary font-mono whitespace-pre-wrap break-words\">\n {JSON.stringify(execution.context ?? null, null, 2)}\n </pre>\n </div>\n </div>\n <div>\n <h3 className=\"text-lg font-medium text-text-primary mb-4\">\n Execution Details\n </h3>\n <div className=\"space-y-3\">\n <div className=\"flex justify-between py-2 border-b border-border-secondary\">\n <span className=\"text-text-secondary\">Run ID</span>\n <code className=\"font-mono text-text-primary\">\n {execution.id}\n </code>\n </div>\n <div className=\"flex justify-between py-2 border-b border-border-secondary\">\n <span className=\"text-text-secondary\">Workflow ID</span>\n <code className=\"font-mono text-text-primary\">\n {execution.workflowId}\n </code>\n </div>\n <div className=\"flex justify-between py-2 border-b border-border-secondary\">\n <span className=\"text-text-secondary\">Workflow Key</span>\n <span className=\"text-text-primary\">\n {execution.workflowKey}\n </span>\n </div>\n <div className=\"flex justify-between py-2 border-b border-border-secondary\">\n <span className=\"text-text-secondary\">Version</span>\n <span className=\"text-text-primary\">\n {execution.version}\n </span>\n </div>\n {execution.triggeredById && (\n <div className=\"flex justify-between py-2 border-b border-border-secondary\">\n <span className=\"text-text-secondary\">Triggered By</span>\n <span className=\"text-text-primary\">\n {execution.triggeredById}\n </span>\n </div>\n )}\n {execution.parentRunId && (\n <div className=\"flex justify-between py-2 border-b border-border-secondary\">\n <span className=\"text-text-secondary\">Parent Run</span>\n <Link\n to={`/runs/${execution.parentRunId}`}\n className=\"text-action-primary-text hover:underline font-mono\"\n >\n {execution.parentRunId.slice(0, 12)}...\n </Link>\n </div>\n )}\n <div className=\"flex justify-between py-2 border-b border-border-secondary\">\n <span className=\"text-text-secondary\">Created</span>\n <span className=\"text-text-primary\">\n {formatDateTime(execution.createdAt)}\n </span>\n </div>\n <div className=\"flex justify-between py-2 border-b border-border-secondary\">\n <span className=\"text-text-secondary\">Started</span>\n <span className=\"text-text-primary\">\n {formatDateTime(execution.startedAt)}\n </span>\n </div>\n {execution.completedAt && (\n <div className=\"flex justify-between py-2 border-b border-border-secondary\">\n <span className=\"text-text-secondary\">Completed</span>\n <span className=\"text-text-primary\">\n {formatDateTime(execution.completedAt)}\n </span>\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n )}\n </div>\n\n <AlertDialog\n open={showTerminateDialog}\n onOpenChange={setShowTerminateDialog}\n >\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Terminate Execution</AlertDialogTitle>\n <AlertDialogDescription>\n Are you sure you want to force terminate this execution? This will\n immediately stop the running workflow and cannot be resumed.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={actionLoading}>\n Cancel\n </AlertDialogCancel>\n <AlertDialogAction\n onClick={handleTerminate}\n disabled={actionLoading}\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n >\n {actionLoading ? \"Terminating...\" : \"Terminate\"}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n );\n}\n"]}
|