@shipfox/client-workflows 13.0.0 → 14.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.storybook/main.ts +16 -1
- package/.storybook/workspace-source.ts +31 -0
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +23 -0
- package/dist/components/job-graph/job-duration-label.js +1 -1
- package/dist/components/job-graph/job-duration-label.js.map +1 -1
- package/dist/components/job-graph/job-graph-content.d.ts +2 -1
- package/dist/components/job-graph/job-graph-content.d.ts.map +1 -1
- package/dist/components/job-graph/job-graph-content.js +3 -3
- package/dist/components/job-graph/job-graph-content.js.map +1 -1
- package/dist/components/job-graph/job-graph-view.d.ts +2 -1
- package/dist/components/job-graph/job-graph-view.d.ts.map +1 -1
- package/dist/components/job-graph/job-graph-view.js +2 -2
- package/dist/components/job-graph/job-graph-view.js.map +1 -1
- package/dist/components/job-graph/job-node.js +5 -5
- package/dist/components/job-graph/job-node.js.map +1 -1
- package/dist/components/job-graph/types.d.ts +2 -1
- package/dist/components/job-graph/types.d.ts.map +1 -1
- package/dist/components/job-graph/types.js.map +1 -1
- package/dist/components/workflow-run-duration-label.js +1 -1
- package/dist/components/workflow-run-duration-label.js.map +1 -1
- package/dist/components/workflow-run-number-label.js +1 -1
- package/dist/components/workflow-run-number-label.js.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js +2 -2
- package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-summary.d.ts +2 -7
- package/dist/components/workflow-run-summary/workflow-run-summary.d.ts.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-summary.js +92 -68
- package/dist/components/workflow-run-summary/workflow-run-summary.js.map +1 -1
- package/dist/components/workflow-run-tabs/index.d.ts +6 -0
- package/dist/components/workflow-run-tabs/index.d.ts.map +1 -0
- package/dist/components/workflow-run-tabs/index.js +7 -0
- package/dist/components/workflow-run-tabs/index.js.map +1 -0
- package/dist/components/workflow-run-tabs/run-annotation-summary-line.d.ts +11 -0
- package/dist/components/workflow-run-tabs/run-annotation-summary-line.d.ts.map +1 -0
- package/dist/components/workflow-run-tabs/run-annotation-summary-line.js +71 -0
- package/dist/components/workflow-run-tabs/run-annotation-summary-line.js.map +1 -0
- package/dist/components/workflow-run-tabs/run-annotations-empty.d.ts +2 -0
- package/dist/components/workflow-run-tabs/run-annotations-empty.d.ts.map +1 -0
- package/dist/components/workflow-run-tabs/run-annotations-empty.js +11 -0
- package/dist/components/workflow-run-tabs/run-annotations-empty.js.map +1 -0
- package/dist/components/workflow-run-tabs/run-jobs-list.d.ts +18 -0
- package/dist/components/workflow-run-tabs/run-jobs-list.d.ts.map +1 -0
- package/dist/components/workflow-run-tabs/run-jobs-list.js +107 -0
- package/dist/components/workflow-run-tabs/run-jobs-list.js.map +1 -0
- package/dist/components/workflow-run-tabs/run-tab-count.d.ts +6 -0
- package/dist/components/workflow-run-tabs/run-tab-count.d.ts.map +1 -0
- package/dist/components/workflow-run-tabs/run-tab-count.js +27 -0
- package/dist/components/workflow-run-tabs/run-tab-count.js.map +1 -0
- package/dist/components/workflow-run-tabs/run-tab-strip.d.ts +8 -0
- package/dist/components/workflow-run-tabs/run-tab-strip.d.ts.map +1 -0
- package/dist/components/workflow-run-tabs/run-tab-strip.js +82 -0
- package/dist/components/workflow-run-tabs/run-tab-strip.js.map +1 -0
- package/dist/components/workflow-run-view/workflow-run-selection.d.ts.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-selection.js +40 -1
- package/dist/components/workflow-run-view/workflow-run-selection.js.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-states.d.ts +1 -0
- package/dist/components/workflow-run-view/workflow-run-states.d.ts.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-states.js +10 -1
- package/dist/components/workflow-run-view/workflow-run-states.js.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-view.d.ts +8 -4
- package/dist/components/workflow-run-view/workflow-run-view.d.ts.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-view.js +125 -78
- package/dist/components/workflow-run-view/workflow-run-view.js.map +1 -1
- package/dist/components/workflow-source-panel/index.d.ts +1 -0
- package/dist/components/workflow-source-panel/index.d.ts.map +1 -1
- package/dist/components/workflow-source-panel/index.js +1 -0
- package/dist/components/workflow-source-panel/index.js.map +1 -1
- package/dist/components/workflow-source-panel/workflow-source-content.d.ts +12 -0
- package/dist/components/workflow-source-panel/workflow-source-content.d.ts.map +1 -0
- package/dist/components/workflow-source-panel/workflow-source-content.js +53 -0
- package/dist/components/workflow-source-panel/workflow-source-content.js.map +1 -0
- package/dist/components/workflow-source-panel/workflow-source-panel.d.ts +1 -1
- package/dist/components/workflow-source-panel/workflow-source-panel.d.ts.map +1 -1
- package/dist/components/workflow-source-panel/workflow-source-panel.js +7 -54
- package/dist/components/workflow-source-panel/workflow-source-panel.js.map +1 -1
- package/dist/core/entities/step.d.ts +1 -1
- package/dist/core/entities/step.d.ts.map +1 -1
- package/dist/core/entities/step.js +2 -0
- package/dist/core/entities/step.js.map +1 -1
- package/dist/core/workflow-run-tabs.d.ts +9 -0
- package/dist/core/workflow-run-tabs.d.ts.map +1 -0
- package/dist/core/workflow-run-tabs.js +3 -0
- package/dist/core/workflow-run-tabs.js.map +1 -0
- package/dist/pages/workflow-run-detail-page.d.ts.map +1 -1
- package/dist/pages/workflow-run-detail-page.js +28 -6
- package/dist/pages/workflow-run-detail-page.js.map +1 -1
- package/dist/routes/inputs.d.ts +33 -0
- package/dist/routes/inputs.d.ts.map +1 -1
- package/dist/routes/inputs.js +49 -0
- package/dist/routes/inputs.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/src/components/job-graph/job-duration-label.tsx +5 -1
- package/src/components/job-graph/job-graph-content.tsx +7 -4
- package/src/components/job-graph/job-graph-view.tsx +6 -3
- package/src/components/job-graph/job-graph.stories.tsx +1 -1
- package/src/components/job-graph/job-node.stories.tsx +1 -1
- package/src/components/job-graph/job-node.test.tsx +27 -2
- package/src/components/job-graph/job-node.tsx +6 -6
- package/src/components/job-graph/types.ts +5 -1
- package/src/components/workflow-run-duration-label.tsx +1 -1
- package/src/components/workflow-run-number-label.tsx +1 -1
- package/src/components/workflow-run-summary/workflow-run-attempt-switcher.tsx +2 -2
- package/src/components/workflow-run-summary/workflow-run-summary.stories.tsx +23 -30
- package/src/components/workflow-run-summary/workflow-run-summary.test.tsx +3 -22
- package/src/components/workflow-run-summary/workflow-run-summary.tsx +84 -69
- package/src/components/workflow-run-tabs/index.ts +5 -0
- package/src/components/workflow-run-tabs/run-annotation-summary-line.test.tsx +69 -0
- package/src/components/workflow-run-tabs/run-annotation-summary-line.tsx +97 -0
- package/src/components/workflow-run-tabs/run-annotations-empty.tsx +11 -0
- package/src/components/workflow-run-tabs/run-jobs-list.tsx +151 -0
- package/src/components/workflow-run-tabs/run-tab-count.tsx +28 -0
- package/src/components/workflow-run-tabs/run-tab-strip.stories.tsx +52 -0
- package/src/components/workflow-run-tabs/run-tab-strip.test.tsx +117 -0
- package/src/components/workflow-run-tabs/run-tab-strip.tsx +97 -0
- package/src/components/workflow-run-view/workflow-run-selection.test.ts +48 -0
- package/src/components/workflow-run-view/workflow-run-selection.ts +48 -1
- package/src/components/workflow-run-view/workflow-run-states.tsx +12 -1
- package/src/components/workflow-run-view/workflow-run-view.test.tsx +64 -64
- package/src/components/workflow-run-view/workflow-run-view.tsx +199 -85
- package/src/components/workflow-source-panel/index.ts +1 -0
- package/src/components/workflow-source-panel/workflow-source-content.tsx +84 -0
- package/src/components/workflow-source-panel/workflow-source-panel.tsx +14 -81
- package/src/core/entities/step.ts +4 -0
- package/src/core/workflow-run-tabs.ts +8 -0
- package/src/pages/workflow-run-detail-page.tsx +31 -4
- package/src/pages/workflow-run-pages.test.tsx +185 -45
- package/src/routes/inputs.test.ts +47 -0
- package/src/routes/inputs.ts +45 -0
- package/src/storybook-config.test.ts +27 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/tsconfig.test.json +7 -1
|
@@ -8,17 +8,20 @@ import { RelativeTime } from '@shipfox/react-ui/relative-time';
|
|
|
8
8
|
import { TimeTickerProvider } from '@shipfox/react-ui/time-ticker';
|
|
9
9
|
import { Tooltip, TooltipContent, TooltipTrigger } from '@shipfox/react-ui/tooltip';
|
|
10
10
|
import { Header, Text } from '@shipfox/react-ui/typography';
|
|
11
|
+
import { Link } from '@tanstack/react-router';
|
|
11
12
|
import { useId } from 'react';
|
|
12
13
|
import { WorkflowRunNumberLabel } from '#components/workflow-run-number-label.js';
|
|
13
14
|
import { isWorkflowRunTerminal, WORKFLOW_RUN_STATUSES } from '#core/workflow-run.js';
|
|
15
|
+
import { validateWorkflowRunsSearch, workflowRunListSearchParams } from '#routes/inputs.js';
|
|
14
16
|
import { WorkflowRunDurationLabel } from '../workflow-run-duration-label.js';
|
|
15
17
|
import { getWorkflowStatusVisual } from '../workflow-status/status-visuals.js';
|
|
16
18
|
import { WorkflowRunAttemptSwitcher } from './workflow-run-attempt-switcher.js';
|
|
17
19
|
const STATUS_BADGE_LABEL_WIDTH_CH = Math.max(...WORKFLOW_RUN_STATUSES.map((status)=>getWorkflowStatusVisual(status).label.length));
|
|
18
|
-
export function WorkflowRunSummary({ workspaceSlug, projectSlug, run,
|
|
20
|
+
export function WorkflowRunSummary({ workspaceSlug, projectSlug, run, cancelling = false, onCancel, rerunPending = false, onRerun, latestAttempt }) {
|
|
19
21
|
const headingId = useId();
|
|
20
22
|
const status = getWorkflowStatusVisual(run.runAttempt.status);
|
|
21
23
|
const action = workflowRunActionForRun(run);
|
|
24
|
+
const hasAction = canRenderWorkflowRunAction(action, onCancel, onRerun);
|
|
22
25
|
const attemptSwitcher = latestAttempt && latestAttempt > 1 && workspaceSlug && projectSlug ? {
|
|
23
26
|
workspaceSlug,
|
|
24
27
|
projectSlug,
|
|
@@ -31,76 +34,92 @@ export function WorkflowRunSummary({ workspaceSlug, projectSlug, run, sourceAvai
|
|
|
31
34
|
reducedMotionIntervalMs: 10_000,
|
|
32
35
|
children: /*#__PURE__*/ _jsx("section", {
|
|
33
36
|
"aria-labelledby": headingId,
|
|
34
|
-
className: "
|
|
37
|
+
className: "bg-background-neutral-background px-16 py-12",
|
|
35
38
|
children: /*#__PURE__*/ _jsxs("div", {
|
|
36
|
-
className: "grid min-w-0 grid-cols-[minmax(0,1fr)_auto] items-center gap-x-12 gap-y-
|
|
39
|
+
className: "grid min-w-0 grid-cols-[minmax(0,1fr)_auto] items-center gap-x-12 gap-y-8 overflow-hidden max-[480px]:grid-cols-1",
|
|
37
40
|
children: [
|
|
38
|
-
/*#__PURE__*/
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
className: "
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
41
|
+
/*#__PURE__*/ _jsx("nav", {
|
|
42
|
+
"aria-label": "Breadcrumb",
|
|
43
|
+
className: "col-start-1 row-start-1 min-w-0 max-[480px]:col-start-auto max-[480px]:row-start-auto",
|
|
44
|
+
children: /*#__PURE__*/ _jsxs("ol", {
|
|
45
|
+
className: "flex min-w-0 items-center gap-8",
|
|
46
|
+
children: [
|
|
47
|
+
workspaceSlug && projectSlug ? /*#__PURE__*/ _jsx("li", {
|
|
48
|
+
className: "shrink-0",
|
|
49
|
+
children: /*#__PURE__*/ _jsx(Link, {
|
|
50
|
+
to: "/w/$workspaceSlug/p/$projectSlug/runs",
|
|
51
|
+
params: {
|
|
52
|
+
workspaceSlug,
|
|
53
|
+
projectSlug
|
|
54
|
+
},
|
|
55
|
+
search: (previous)=>workflowRunListSearchParams(validateWorkflowRunsSearch(previous)),
|
|
56
|
+
className: "rounded-4 text-xs font-medium text-foreground-neutral-subtle underline decoration-border-neutral-strong underline-offset-4 outline-none hover:text-foreground-neutral-base focus-visible:shadow-border-interactive-with-active",
|
|
57
|
+
children: "Runs"
|
|
58
|
+
})
|
|
59
|
+
}) : null,
|
|
60
|
+
workspaceSlug && projectSlug ? /*#__PURE__*/ _jsx("li", {
|
|
61
|
+
"aria-hidden": "true",
|
|
62
|
+
className: "shrink-0 text-xs text-foreground-neutral-subtle",
|
|
63
|
+
children: "/"
|
|
64
|
+
}) : null,
|
|
65
|
+
/*#__PURE__*/ _jsxs("li", {
|
|
66
|
+
"aria-current": "page",
|
|
67
|
+
className: "flex min-w-0 items-center gap-8",
|
|
68
|
+
children: [
|
|
69
|
+
/*#__PURE__*/ _jsx(Badge, {
|
|
70
|
+
variant: status.badge,
|
|
71
|
+
size: "xs",
|
|
60
72
|
children: /*#__PURE__*/ _jsx("span", {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
73
|
+
className: "text-center",
|
|
74
|
+
style: {
|
|
75
|
+
width: `${STATUS_BADGE_LABEL_WIDTH_CH}ch`
|
|
76
|
+
},
|
|
77
|
+
children: status.label
|
|
65
78
|
})
|
|
79
|
+
}),
|
|
80
|
+
/*#__PURE__*/ _jsxs(Tooltip, {
|
|
81
|
+
children: [
|
|
82
|
+
/*#__PURE__*/ _jsx(TooltipTrigger, {
|
|
83
|
+
asChild: true,
|
|
84
|
+
children: /*#__PURE__*/ _jsx(Header, {
|
|
85
|
+
id: headingId,
|
|
86
|
+
variant: "h3",
|
|
87
|
+
className: "min-w-0 truncate",
|
|
88
|
+
children: /*#__PURE__*/ _jsx("span", {
|
|
89
|
+
ref: headingTextRef,
|
|
90
|
+
title: isHeadingTruncated ? run.name : undefined,
|
|
91
|
+
className: "block min-w-0 truncate",
|
|
92
|
+
children: run.name
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
}),
|
|
96
|
+
isHeadingTruncated ? /*#__PURE__*/ _jsx(TooltipContent, {
|
|
97
|
+
children: /*#__PURE__*/ _jsx(Text, {
|
|
98
|
+
as: "span",
|
|
99
|
+
size: "xs",
|
|
100
|
+
className: "max-w-[360px] break-words",
|
|
101
|
+
children: run.name
|
|
102
|
+
})
|
|
103
|
+
}) : null
|
|
104
|
+
]
|
|
66
105
|
})
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
size: "xs",
|
|
72
|
-
className: "max-w-[360px] break-words",
|
|
73
|
-
children: run.name
|
|
74
|
-
})
|
|
75
|
-
}) : null
|
|
76
|
-
]
|
|
77
|
-
})
|
|
78
|
-
]
|
|
79
|
-
}),
|
|
80
|
-
/*#__PURE__*/ _jsxs("div", {
|
|
81
|
-
className: "col-start-2 row-start-1 flex min-w-max items-center gap-6 justify-self-end",
|
|
82
|
-
children: [
|
|
83
|
-
/*#__PURE__*/ _jsx(WorkflowRunActionSlot, {
|
|
84
|
-
action: action,
|
|
85
|
-
cancelling: cancelling,
|
|
86
|
-
onCancel: onCancel,
|
|
87
|
-
rerunPending: rerunPending,
|
|
88
|
-
onRerun: onRerun
|
|
89
|
-
}),
|
|
90
|
-
sourceAvailable ? /*#__PURE__*/ _jsx(Button, {
|
|
91
|
-
ref: sourceButtonRef,
|
|
92
|
-
type: "button",
|
|
93
|
-
variant: "secondary",
|
|
94
|
-
size: "xs",
|
|
95
|
-
"aria-controls": sourcePanelId,
|
|
96
|
-
"aria-expanded": sourceOpen,
|
|
97
|
-
onClick: onSourceToggle,
|
|
98
|
-
children: "View source"
|
|
99
|
-
}) : null
|
|
100
|
-
]
|
|
106
|
+
]
|
|
107
|
+
})
|
|
108
|
+
]
|
|
109
|
+
})
|
|
101
110
|
}),
|
|
111
|
+
hasAction ? /*#__PURE__*/ _jsx("div", {
|
|
112
|
+
className: "col-start-2 row-start-1 flex min-w-max items-center gap-6 justify-self-end max-[480px]:col-start-auto max-[480px]:row-start-auto max-[480px]:justify-self-start",
|
|
113
|
+
children: /*#__PURE__*/ _jsx(WorkflowRunActionSlot, {
|
|
114
|
+
action: action,
|
|
115
|
+
cancelling: cancelling,
|
|
116
|
+
onCancel: onCancel,
|
|
117
|
+
rerunPending: rerunPending,
|
|
118
|
+
onRerun: onRerun
|
|
119
|
+
})
|
|
120
|
+
}) : null,
|
|
102
121
|
/*#__PURE__*/ _jsxs("div", {
|
|
103
|
-
className: "col-span-2 row-start-2 flex min-w-0 items-center gap-12 overflow-hidden text-foreground-neutral-
|
|
122
|
+
className: "col-span-2 row-start-2 flex min-w-0 items-center gap-12 overflow-hidden text-foreground-neutral-subtle max-[480px]:col-span-1 max-[480px]:row-start-auto",
|
|
104
123
|
children: [
|
|
105
124
|
run.number !== null ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
106
125
|
children: [
|
|
@@ -128,7 +147,7 @@ export function WorkflowRunSummary({ workspaceSlug, projectSlug, run, sourceAvai
|
|
|
128
147
|
children: /*#__PURE__*/ _jsxs("button", {
|
|
129
148
|
type: "button",
|
|
130
149
|
"aria-label": run.triggerLabel,
|
|
131
|
-
className: "inline-flex max-w-full min-w-0 items-center gap-4 rounded-6 border-0 bg-transparent p-0 text-left text-foreground-neutral-
|
|
150
|
+
className: "inline-flex max-w-full min-w-0 cursor-help items-center gap-4 rounded-6 border-0 bg-transparent p-0 text-left text-foreground-neutral-subtle outline-none focus-visible:shadow-button-neutral-focus",
|
|
132
151
|
children: [
|
|
133
152
|
/*#__PURE__*/ _jsx(TriggerSourceIcon, {
|
|
134
153
|
provider: run.triggerProvider,
|
|
@@ -161,14 +180,14 @@ export function WorkflowRunSummary({ workspaceSlug, projectSlug, run, sourceAvai
|
|
|
161
180
|
run.number !== null || attemptSwitcher || run.triggerDisplayLabel ? /*#__PURE__*/ _jsx(MetadataSeparator, {}) : null,
|
|
162
181
|
/*#__PURE__*/ _jsx(RelativeTime, {
|
|
163
182
|
value: run.runAttempt.createdAt,
|
|
164
|
-
className: "shrink-0 whitespace-nowrap text-xs leading-20 text-foreground-neutral-
|
|
183
|
+
className: "shrink-0 whitespace-nowrap text-xs leading-20 text-foreground-neutral-subtle"
|
|
165
184
|
}),
|
|
166
185
|
displayDuration ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
167
186
|
children: [
|
|
168
187
|
/*#__PURE__*/ _jsx(MetadataSeparator, {}),
|
|
169
188
|
/*#__PURE__*/ _jsx(WorkflowRunDurationLabel, {
|
|
170
189
|
duration: displayDuration,
|
|
171
|
-
className: "text-foreground-neutral-
|
|
190
|
+
className: "text-foreground-neutral-subtle"
|
|
172
191
|
})
|
|
173
192
|
]
|
|
174
193
|
}) : null
|
|
@@ -244,6 +263,11 @@ function workflowRunActionForRun(run) {
|
|
|
244
263
|
if (run.runAttempt.status === 'succeeded' || !hasFailedOrCancelledJobs(run)) return 'rerun-all';
|
|
245
264
|
return 'rerun-menu';
|
|
246
265
|
}
|
|
266
|
+
function canRenderWorkflowRunAction(action, onCancel, onRerun) {
|
|
267
|
+
if (action === 'cancel') return onCancel !== undefined;
|
|
268
|
+
if (action === 'rerun-all' || action === 'rerun-menu') return onRerun !== undefined;
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
247
271
|
function hasFailedOrCancelledJobs(run) {
|
|
248
272
|
if (!workflowRunHasJobs(run)) return false;
|
|
249
273
|
return run.jobs.some((job)=>job.status === 'failed' || job.status === 'cancelled');
|
|
@@ -251,7 +275,7 @@ function hasFailedOrCancelledJobs(run) {
|
|
|
251
275
|
function workflowRunHasJobs(run) {
|
|
252
276
|
return 'jobs' in run && Array.isArray(run.jobs);
|
|
253
277
|
}
|
|
254
|
-
function MetadataSeparator() {
|
|
278
|
+
export function MetadataSeparator() {
|
|
255
279
|
return /*#__PURE__*/ _jsx("span", {
|
|
256
280
|
"aria-hidden": "true",
|
|
257
281
|
className: "h-12 w-px shrink-0 bg-border-neutral-base"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/workflow-run-summary/workflow-run-summary.tsx"],"sourcesContent":["import {TriggerSourceIcon} from '@shipfox/client-triggers';\nimport {Badge} from '@shipfox/react-ui/badge';\nimport {Button} from '@shipfox/react-ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@shipfox/react-ui/dropdown-menu';\nimport {useIsTextTruncated} from '@shipfox/react-ui/hooks';\nimport {RelativeTime} from '@shipfox/react-ui/relative-time';\nimport {TimeTickerProvider} from '@shipfox/react-ui/time-ticker';\nimport {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';\nimport {Header, Text} from '@shipfox/react-ui/typography';\nimport type {Ref} from 'react';\nimport {useId} from 'react';\nimport {WorkflowRunNumberLabel} from '#components/workflow-run-number-label.js';\nimport {\n isWorkflowRunTerminal,\n type Job,\n WORKFLOW_RUN_STATUSES,\n type WorkflowRunDetail,\n type WorkflowRunRerunMode,\n} from '#core/workflow-run.js';\nimport {WorkflowRunDurationLabel} from '../workflow-run-duration-label.js';\nimport {getWorkflowStatusVisual} from '../workflow-status/status-visuals.js';\nimport {WorkflowRunAttemptSwitcher} from './workflow-run-attempt-switcher.js';\n\nconst STATUS_BADGE_LABEL_WIDTH_CH = Math.max(\n ...WORKFLOW_RUN_STATUSES.map((status) => getWorkflowStatusVisual(status).label.length),\n);\n\ntype WorkflowRunAction = 'cancel' | 'rerun-all' | 'rerun-menu' | 'none';\n\nexport interface WorkflowRunSummaryProps {\n workspaceSlug?: string | undefined;\n projectSlug?: string | undefined;\n run: WorkflowRunDetail;\n sourceAvailable?: boolean | undefined;\n sourceOpen?: boolean | undefined;\n sourcePanelId?: string | undefined;\n sourceButtonRef?: Ref<HTMLButtonElement> | undefined;\n onSourceToggle?: (() => void) | undefined;\n cancelling?: boolean | undefined;\n onCancel?: (() => void) | undefined;\n rerunPending?: boolean | undefined;\n onRerun?: ((mode: WorkflowRunRerunMode) => void) | undefined;\n latestAttempt?: number | undefined;\n}\n\nexport function WorkflowRunSummary({\n workspaceSlug,\n projectSlug,\n run,\n sourceAvailable = false,\n sourceOpen = false,\n sourcePanelId,\n sourceButtonRef,\n onSourceToggle,\n cancelling = false,\n onCancel,\n rerunPending = false,\n onRerun,\n latestAttempt,\n}: WorkflowRunSummaryProps) {\n const headingId = useId();\n const status = getWorkflowStatusVisual(run.runAttempt.status);\n const action = workflowRunActionForRun(run);\n const attemptSwitcher =\n latestAttempt && latestAttempt > 1 && workspaceSlug && projectSlug\n ? {workspaceSlug, projectSlug, latestAttempt}\n : null;\n const displayDuration = run.runAttempt.displayDuration;\n const {ref: headingTextRef, isTruncated: isHeadingTruncated} =\n useIsTextTruncated<HTMLSpanElement>(run.name);\n\n return (\n <TimeTickerProvider intervalMs={1000} reducedMotionIntervalMs={10_000}>\n <section\n aria-labelledby={headingId}\n className=\"border-b border-border-neutral-base bg-background-subtle-base px-16 py-8\"\n >\n <div className=\"grid min-w-0 grid-cols-[minmax(0,1fr)_auto] items-center gap-x-12 gap-y-4 overflow-hidden\">\n <div className=\"col-start-1 row-start-1 flex min-w-0 items-center gap-8\">\n <Badge variant={status.badge} size=\"xs\">\n <span className=\"text-center\" style={{width: `${STATUS_BADGE_LABEL_WIDTH_CH}ch`}}>\n {status.label}\n </span>\n </Badge>\n\n <Tooltip>\n <TooltipTrigger asChild>\n <Header id={headingId} variant=\"h3\" className=\"min-w-0 truncate\">\n <span\n ref={headingTextRef}\n title={isHeadingTruncated ? run.name : undefined}\n className=\"block min-w-0 truncate\"\n >\n {run.name}\n </span>\n </Header>\n </TooltipTrigger>\n {isHeadingTruncated ? (\n <TooltipContent>\n <Text as=\"span\" size=\"xs\" className=\"max-w-[360px] break-words\">\n {run.name}\n </Text>\n </TooltipContent>\n ) : null}\n </Tooltip>\n </div>\n\n <div className=\"col-start-2 row-start-1 flex min-w-max items-center gap-6 justify-self-end\">\n <WorkflowRunActionSlot\n action={action}\n cancelling={cancelling}\n onCancel={onCancel}\n rerunPending={rerunPending}\n onRerun={onRerun}\n />\n {sourceAvailable ? (\n <Button\n ref={sourceButtonRef}\n type=\"button\"\n variant=\"secondary\"\n size=\"xs\"\n aria-controls={sourcePanelId}\n aria-expanded={sourceOpen}\n onClick={onSourceToggle}\n >\n View source\n </Button>\n ) : null}\n </div>\n\n <div className=\"col-span-2 row-start-2 flex min-w-0 items-center gap-12 overflow-hidden text-foreground-neutral-muted\">\n {run.number !== null ? (\n <>\n <WorkflowRunNumberLabel run={run} />\n {attemptSwitcher || run.triggerDisplayLabel ? <MetadataSeparator /> : null}\n </>\n ) : null}\n\n {attemptSwitcher ? (\n <WorkflowRunAttemptSwitcher\n workspaceSlug={attemptSwitcher.workspaceSlug}\n projectSlug={attemptSwitcher.projectSlug}\n run={run}\n latestAttempt={attemptSwitcher.latestAttempt}\n />\n ) : null}\n\n {run.triggerDisplayLabel ? (\n <>\n {attemptSwitcher ? <MetadataSeparator /> : null}\n <span className=\"min-w-0\">\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n aria-label={run.triggerLabel}\n className=\"inline-flex max-w-full min-w-0 items-center gap-4 rounded-6 border-0 bg-transparent p-0 text-left text-foreground-neutral-muted outline-none focus-visible:shadow-button-neutral-focus\"\n >\n <TriggerSourceIcon\n provider={run.triggerProvider}\n source={run.triggerSource}\n aria-hidden=\"true\"\n className=\"size-12 shrink-0\"\n />\n <Text as=\"span\" size=\"xs\" className=\"min-w-0 truncate\">\n {run.triggerDisplayLabel}\n </Text>\n </button>\n </TooltipTrigger>\n <TooltipContent>\n <Text as=\"span\" size=\"xs\" className=\"block max-w-[360px] break-words\">\n {run.triggerLabel}\n </Text>\n </TooltipContent>\n </Tooltip>\n </span>\n </>\n ) : null}\n\n {run.number !== null || attemptSwitcher || run.triggerDisplayLabel ? (\n <MetadataSeparator />\n ) : null}\n <RelativeTime\n value={run.runAttempt.createdAt}\n className=\"shrink-0 whitespace-nowrap text-xs leading-20 text-foreground-neutral-muted\"\n />\n\n {displayDuration ? (\n <>\n <MetadataSeparator />\n <WorkflowRunDurationLabel\n duration={displayDuration}\n className=\"text-foreground-neutral-muted\"\n />\n </>\n ) : null}\n </div>\n </div>\n </section>\n </TimeTickerProvider>\n );\n}\n\nfunction WorkflowRunActionSlot({\n action,\n cancelling,\n onCancel,\n rerunPending,\n onRerun,\n}: {\n action: WorkflowRunAction;\n cancelling: boolean;\n onCancel?: (() => void) | undefined;\n rerunPending: boolean;\n onRerun?: ((mode: WorkflowRunRerunMode) => void) | undefined;\n}) {\n if (action === 'none') return null;\n\n if (action === 'cancel') {\n if (!onCancel) return null;\n\n return (\n <Button\n type=\"button\"\n variant=\"danger\"\n size=\"xs\"\n isLoading={cancelling}\n disabled={cancelling}\n onClick={onCancel}\n >\n Cancel workflow\n </Button>\n );\n }\n\n if (action === 'rerun-all') {\n if (!onRerun) return null;\n\n return (\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"xs\"\n isLoading={rerunPending}\n disabled={rerunPending}\n onClick={() => onRerun('all')}\n >\n Re-run workflow\n </Button>\n );\n }\n\n if (!onRerun) return null;\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"xs\"\n iconRight=\"arrowDownSLine\"\n isLoading={rerunPending}\n disabled={rerunPending}\n >\n Re-run jobs\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem disabled={rerunPending} onSelect={() => onRerun('all')}>\n Re-run all jobs\n </DropdownMenuItem>\n <DropdownMenuItem disabled={rerunPending} onSelect={() => onRerun('failed')}>\n Re-run failed jobs\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n\nfunction workflowRunActionForRun(run: WorkflowRunDetail): WorkflowRunAction {\n if (run.runAttempt.attempt !== run.currentAttempt) return 'none';\n if (!isWorkflowRunTerminal(run.runAttempt.status)) return 'cancel';\n if (run.runAttempt.status === 'succeeded' || !hasFailedOrCancelledJobs(run)) return 'rerun-all';\n return 'rerun-menu';\n}\n\nfunction hasFailedOrCancelledJobs(run: WorkflowRunDetail): boolean {\n if (!workflowRunHasJobs(run)) return false;\n\n return run.jobs.some((job) => job.status === 'failed' || job.status === 'cancelled');\n}\n\nfunction workflowRunHasJobs(run: WorkflowRunDetail): run is WorkflowRunDetail & {jobs: Job[]} {\n return 'jobs' in run && Array.isArray(run.jobs);\n}\n\nfunction MetadataSeparator() {\n return <span aria-hidden=\"true\" className=\"h-12 w-px shrink-0 bg-border-neutral-base\" />;\n}\n"],"names":["TriggerSourceIcon","Badge","Button","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","useIsTextTruncated","RelativeTime","TimeTickerProvider","Tooltip","TooltipContent","TooltipTrigger","Header","Text","useId","WorkflowRunNumberLabel","isWorkflowRunTerminal","WORKFLOW_RUN_STATUSES","WorkflowRunDurationLabel","getWorkflowStatusVisual","WorkflowRunAttemptSwitcher","STATUS_BADGE_LABEL_WIDTH_CH","Math","max","map","status","label","length","WorkflowRunSummary","workspaceSlug","projectSlug","run","sourceAvailable","sourceOpen","sourcePanelId","sourceButtonRef","onSourceToggle","cancelling","onCancel","rerunPending","onRerun","latestAttempt","headingId","runAttempt","action","workflowRunActionForRun","attemptSwitcher","displayDuration","ref","headingTextRef","isTruncated","isHeadingTruncated","name","intervalMs","reducedMotionIntervalMs","section","aria-labelledby","className","div","variant","badge","size","span","style","width","asChild","id","title","undefined","as","WorkflowRunActionSlot","type","aria-controls","aria-expanded","onClick","number","triggerDisplayLabel","MetadataSeparator","button","aria-label","triggerLabel","provider","triggerProvider","source","triggerSource","aria-hidden","value","createdAt","duration","isLoading","disabled","iconRight","align","onSelect","attempt","currentAttempt","hasFailedOrCancelledJobs","workflowRunHasJobs","jobs","some","job","Array","isArray"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/workflow-run-summary/workflow-run-summary.tsx"],"sourcesContent":["import {TriggerSourceIcon} from '@shipfox/client-triggers';\nimport {Badge} from '@shipfox/react-ui/badge';\nimport {Button} from '@shipfox/react-ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@shipfox/react-ui/dropdown-menu';\nimport {useIsTextTruncated} from '@shipfox/react-ui/hooks';\nimport {RelativeTime} from '@shipfox/react-ui/relative-time';\nimport {TimeTickerProvider} from '@shipfox/react-ui/time-ticker';\nimport {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';\nimport {Header, Text} from '@shipfox/react-ui/typography';\nimport {Link} from '@tanstack/react-router';\nimport {useId} from 'react';\nimport {WorkflowRunNumberLabel} from '#components/workflow-run-number-label.js';\nimport {\n isWorkflowRunTerminal,\n type Job,\n WORKFLOW_RUN_STATUSES,\n type WorkflowRunDetail,\n type WorkflowRunRerunMode,\n} from '#core/workflow-run.js';\nimport {validateWorkflowRunsSearch, workflowRunListSearchParams} from '#routes/inputs.js';\nimport {WorkflowRunDurationLabel} from '../workflow-run-duration-label.js';\nimport {getWorkflowStatusVisual} from '../workflow-status/status-visuals.js';\nimport {WorkflowRunAttemptSwitcher} from './workflow-run-attempt-switcher.js';\n\nconst STATUS_BADGE_LABEL_WIDTH_CH = Math.max(\n ...WORKFLOW_RUN_STATUSES.map((status) => getWorkflowStatusVisual(status).label.length),\n);\n\ntype WorkflowRunAction = 'cancel' | 'rerun-all' | 'rerun-menu' | 'none';\n\nexport interface WorkflowRunSummaryProps {\n workspaceSlug?: string | undefined;\n projectSlug?: string | undefined;\n run: WorkflowRunDetail;\n cancelling?: boolean | undefined;\n onCancel?: (() => void) | undefined;\n rerunPending?: boolean | undefined;\n onRerun?: ((mode: WorkflowRunRerunMode) => void) | undefined;\n latestAttempt?: number | undefined;\n}\n\nexport function WorkflowRunSummary({\n workspaceSlug,\n projectSlug,\n run,\n cancelling = false,\n onCancel,\n rerunPending = false,\n onRerun,\n latestAttempt,\n}: WorkflowRunSummaryProps) {\n const headingId = useId();\n const status = getWorkflowStatusVisual(run.runAttempt.status);\n const action = workflowRunActionForRun(run);\n const hasAction = canRenderWorkflowRunAction(action, onCancel, onRerun);\n const attemptSwitcher =\n latestAttempt && latestAttempt > 1 && workspaceSlug && projectSlug\n ? {workspaceSlug, projectSlug, latestAttempt}\n : null;\n const displayDuration = run.runAttempt.displayDuration;\n const {ref: headingTextRef, isTruncated: isHeadingTruncated} =\n useIsTextTruncated<HTMLSpanElement>(run.name);\n\n return (\n <TimeTickerProvider intervalMs={1000} reducedMotionIntervalMs={10_000}>\n <section aria-labelledby={headingId} className=\"bg-background-neutral-background px-16 py-12\">\n <div className=\"grid min-w-0 grid-cols-[minmax(0,1fr)_auto] items-center gap-x-12 gap-y-8 overflow-hidden max-[480px]:grid-cols-1\">\n <nav\n aria-label=\"Breadcrumb\"\n className=\"col-start-1 row-start-1 min-w-0 max-[480px]:col-start-auto max-[480px]:row-start-auto\"\n >\n <ol className=\"flex min-w-0 items-center gap-8\">\n {workspaceSlug && projectSlug ? (\n <li className=\"shrink-0\">\n <Link\n to=\"/w/$workspaceSlug/p/$projectSlug/runs\"\n params={{workspaceSlug, projectSlug}}\n search={\n ((previous: Record<string, unknown>) =>\n workflowRunListSearchParams(validateWorkflowRunsSearch(previous))) as never\n }\n className=\"rounded-4 text-xs font-medium text-foreground-neutral-subtle underline decoration-border-neutral-strong underline-offset-4 outline-none hover:text-foreground-neutral-base focus-visible:shadow-border-interactive-with-active\"\n >\n Runs\n </Link>\n </li>\n ) : null}\n {workspaceSlug && projectSlug ? (\n <li aria-hidden=\"true\" className=\"shrink-0 text-xs text-foreground-neutral-subtle\">\n /\n </li>\n ) : null}\n <li aria-current=\"page\" className=\"flex min-w-0 items-center gap-8\">\n <Badge variant={status.badge} size=\"xs\">\n <span className=\"text-center\" style={{width: `${STATUS_BADGE_LABEL_WIDTH_CH}ch`}}>\n {status.label}\n </span>\n </Badge>\n\n <Tooltip>\n <TooltipTrigger asChild>\n <Header id={headingId} variant=\"h3\" className=\"min-w-0 truncate\">\n <span\n ref={headingTextRef}\n title={isHeadingTruncated ? run.name : undefined}\n className=\"block min-w-0 truncate\"\n >\n {run.name}\n </span>\n </Header>\n </TooltipTrigger>\n {isHeadingTruncated ? (\n <TooltipContent>\n <Text as=\"span\" size=\"xs\" className=\"max-w-[360px] break-words\">\n {run.name}\n </Text>\n </TooltipContent>\n ) : null}\n </Tooltip>\n </li>\n </ol>\n </nav>\n\n {hasAction ? (\n <div className=\"col-start-2 row-start-1 flex min-w-max items-center gap-6 justify-self-end max-[480px]:col-start-auto max-[480px]:row-start-auto max-[480px]:justify-self-start\">\n <WorkflowRunActionSlot\n action={action}\n cancelling={cancelling}\n onCancel={onCancel}\n rerunPending={rerunPending}\n onRerun={onRerun}\n />\n </div>\n ) : null}\n\n <div className=\"col-span-2 row-start-2 flex min-w-0 items-center gap-12 overflow-hidden text-foreground-neutral-subtle max-[480px]:col-span-1 max-[480px]:row-start-auto\">\n {run.number !== null ? (\n <>\n <WorkflowRunNumberLabel run={run} />\n {attemptSwitcher || run.triggerDisplayLabel ? <MetadataSeparator /> : null}\n </>\n ) : null}\n\n {attemptSwitcher ? (\n <WorkflowRunAttemptSwitcher\n workspaceSlug={attemptSwitcher.workspaceSlug}\n projectSlug={attemptSwitcher.projectSlug}\n run={run}\n latestAttempt={attemptSwitcher.latestAttempt}\n />\n ) : null}\n\n {run.triggerDisplayLabel ? (\n <>\n {attemptSwitcher ? <MetadataSeparator /> : null}\n <span className=\"min-w-0\">\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n aria-label={run.triggerLabel}\n className=\"inline-flex max-w-full min-w-0 cursor-help items-center gap-4 rounded-6 border-0 bg-transparent p-0 text-left text-foreground-neutral-subtle outline-none focus-visible:shadow-button-neutral-focus\"\n >\n <TriggerSourceIcon\n provider={run.triggerProvider}\n source={run.triggerSource}\n aria-hidden=\"true\"\n className=\"size-12 shrink-0\"\n />\n <Text as=\"span\" size=\"xs\" className=\"min-w-0 truncate\">\n {run.triggerDisplayLabel}\n </Text>\n </button>\n </TooltipTrigger>\n <TooltipContent>\n <Text as=\"span\" size=\"xs\" className=\"block max-w-[360px] break-words\">\n {run.triggerLabel}\n </Text>\n </TooltipContent>\n </Tooltip>\n </span>\n </>\n ) : null}\n\n {run.number !== null || attemptSwitcher || run.triggerDisplayLabel ? (\n <MetadataSeparator />\n ) : null}\n <RelativeTime\n value={run.runAttempt.createdAt}\n className=\"shrink-0 whitespace-nowrap text-xs leading-20 text-foreground-neutral-subtle\"\n />\n\n {displayDuration ? (\n <>\n <MetadataSeparator />\n <WorkflowRunDurationLabel\n duration={displayDuration}\n className=\"text-foreground-neutral-subtle\"\n />\n </>\n ) : null}\n </div>\n </div>\n </section>\n </TimeTickerProvider>\n );\n}\n\nfunction WorkflowRunActionSlot({\n action,\n cancelling,\n onCancel,\n rerunPending,\n onRerun,\n}: {\n action: WorkflowRunAction;\n cancelling: boolean;\n onCancel?: (() => void) | undefined;\n rerunPending: boolean;\n onRerun?: ((mode: WorkflowRunRerunMode) => void) | undefined;\n}) {\n if (action === 'none') return null;\n\n if (action === 'cancel') {\n if (!onCancel) return null;\n\n return (\n <Button\n type=\"button\"\n variant=\"danger\"\n size=\"xs\"\n isLoading={cancelling}\n disabled={cancelling}\n onClick={onCancel}\n >\n Cancel workflow\n </Button>\n );\n }\n\n if (action === 'rerun-all') {\n if (!onRerun) return null;\n\n return (\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"xs\"\n isLoading={rerunPending}\n disabled={rerunPending}\n onClick={() => onRerun('all')}\n >\n Re-run workflow\n </Button>\n );\n }\n\n if (!onRerun) return null;\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"xs\"\n iconRight=\"arrowDownSLine\"\n isLoading={rerunPending}\n disabled={rerunPending}\n >\n Re-run jobs\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem disabled={rerunPending} onSelect={() => onRerun('all')}>\n Re-run all jobs\n </DropdownMenuItem>\n <DropdownMenuItem disabled={rerunPending} onSelect={() => onRerun('failed')}>\n Re-run failed jobs\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n\nfunction workflowRunActionForRun(run: WorkflowRunDetail): WorkflowRunAction {\n if (run.runAttempt.attempt !== run.currentAttempt) return 'none';\n if (!isWorkflowRunTerminal(run.runAttempt.status)) return 'cancel';\n if (run.runAttempt.status === 'succeeded' || !hasFailedOrCancelledJobs(run)) return 'rerun-all';\n return 'rerun-menu';\n}\n\nfunction canRenderWorkflowRunAction(\n action: WorkflowRunAction,\n onCancel: (() => void) | undefined,\n onRerun: ((mode: WorkflowRunRerunMode) => void) | undefined,\n): boolean {\n if (action === 'cancel') return onCancel !== undefined;\n if (action === 'rerun-all' || action === 'rerun-menu') return onRerun !== undefined;\n return false;\n}\n\nfunction hasFailedOrCancelledJobs(run: WorkflowRunDetail): boolean {\n if (!workflowRunHasJobs(run)) return false;\n\n return run.jobs.some((job) => job.status === 'failed' || job.status === 'cancelled');\n}\n\nfunction workflowRunHasJobs(run: WorkflowRunDetail): run is WorkflowRunDetail & {jobs: Job[]} {\n return 'jobs' in run && Array.isArray(run.jobs);\n}\n\nexport function MetadataSeparator() {\n return <span aria-hidden=\"true\" className=\"h-12 w-px shrink-0 bg-border-neutral-base\" />;\n}\n"],"names":["TriggerSourceIcon","Badge","Button","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","useIsTextTruncated","RelativeTime","TimeTickerProvider","Tooltip","TooltipContent","TooltipTrigger","Header","Text","Link","useId","WorkflowRunNumberLabel","isWorkflowRunTerminal","WORKFLOW_RUN_STATUSES","validateWorkflowRunsSearch","workflowRunListSearchParams","WorkflowRunDurationLabel","getWorkflowStatusVisual","WorkflowRunAttemptSwitcher","STATUS_BADGE_LABEL_WIDTH_CH","Math","max","map","status","label","length","WorkflowRunSummary","workspaceSlug","projectSlug","run","cancelling","onCancel","rerunPending","onRerun","latestAttempt","headingId","runAttempt","action","workflowRunActionForRun","hasAction","canRenderWorkflowRunAction","attemptSwitcher","displayDuration","ref","headingTextRef","isTruncated","isHeadingTruncated","name","intervalMs","reducedMotionIntervalMs","section","aria-labelledby","className","div","nav","aria-label","ol","li","to","params","search","previous","aria-hidden","aria-current","variant","badge","size","span","style","width","asChild","id","title","undefined","as","WorkflowRunActionSlot","number","triggerDisplayLabel","MetadataSeparator","button","type","triggerLabel","provider","triggerProvider","source","triggerSource","value","createdAt","duration","isLoading","disabled","onClick","iconRight","align","onSelect","attempt","currentAttempt","hasFailedOrCancelledJobs","workflowRunHasJobs","jobs","some","job","Array","isArray"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { RunAnnotationSummaryLine } from './run-annotation-summary-line.js';
|
|
2
|
+
export { RunAnnotationsEmpty } from './run-annotations-empty.js';
|
|
3
|
+
export { RunJobsList } from './run-jobs-list.js';
|
|
4
|
+
export { RunTabCount } from './run-tab-count.js';
|
|
5
|
+
export { RunTabStrip } from './run-tab-strip.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-tabs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,wBAAwB,EAAC,MAAM,kCAAkC,CAAC;AAC1E,OAAO,EAAC,mBAAmB,EAAC,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { RunAnnotationSummaryLine } from './run-annotation-summary-line.js';
|
|
2
|
+
export { RunAnnotationsEmpty } from './run-annotations-empty.js';
|
|
3
|
+
export { RunJobsList } from './run-jobs-list.js';
|
|
4
|
+
export { RunTabCount } from './run-tab-count.js';
|
|
5
|
+
export { RunTabStrip } from './run-tab-strip.js';
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/workflow-run-tabs/index.ts"],"sourcesContent":["export {RunAnnotationSummaryLine} from './run-annotation-summary-line.js';\nexport {RunAnnotationsEmpty} from './run-annotations-empty.js';\nexport {RunJobsList} from './run-jobs-list.js';\nexport {RunTabCount} from './run-tab-count.js';\nexport {RunTabStrip} from './run-tab-strip.js';\n"],"names":["RunAnnotationSummaryLine","RunAnnotationsEmpty","RunJobsList","RunTabCount","RunTabStrip"],"mappings":"AAAA,SAAQA,wBAAwB,QAAO,mCAAmC;AAC1E,SAAQC,mBAAmB,QAAO,6BAA6B;AAC/D,SAAQC,WAAW,QAAO,qBAAqB;AAC/C,SAAQC,WAAW,QAAO,qBAAqB;AAC/C,SAAQC,WAAW,QAAO,qBAAqB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { RunAnnotationSummary } from '#core/workflow-run-tabs.js';
|
|
2
|
+
import { type WorkflowRunsSearch } from '#routes/inputs.js';
|
|
3
|
+
export interface RunAnnotationSummaryLineProps {
|
|
4
|
+
summary?: RunAnnotationSummary | undefined;
|
|
5
|
+
workspaceSlug?: string | undefined;
|
|
6
|
+
projectSlug?: string | undefined;
|
|
7
|
+
workflowRunId?: string | undefined;
|
|
8
|
+
search?: WorkflowRunsSearch | undefined;
|
|
9
|
+
}
|
|
10
|
+
export declare function RunAnnotationSummaryLine({ summary, workspaceSlug, projectSlug, workflowRunId, search, }: RunAnnotationSummaryLineProps): import("react").JSX.Element | null;
|
|
11
|
+
//# sourceMappingURL=run-annotation-summary-line.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-annotation-summary-line.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-tabs/run-annotation-summary-line.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAGL,KAAK,kBAAkB,EAExB,MAAM,mBAAmB,CAAC;AAG3B,MAAM,WAAW,6BAA6B;IAC5C,OAAO,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;IAC3C,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,MAAM,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;CACzC;AAED,wBAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,aAAa,EACb,WAAW,EACX,aAAa,EACb,MAAW,GACZ,EAAE,6BAA6B,sCA2B/B"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Text } from '@shipfox/react-ui/typography';
|
|
3
|
+
import { Link } from '@tanstack/react-router';
|
|
4
|
+
import { WORKFLOW_RUN_ANNOTATION_SEVERITIES, workflowRunSearchParams } from '#routes/inputs.js';
|
|
5
|
+
import { MetadataSeparator } from '../workflow-run-summary/workflow-run-summary.js';
|
|
6
|
+
export function RunAnnotationSummaryLine({ summary, workspaceSlug, projectSlug, workflowRunId, search = {} }) {
|
|
7
|
+
if (!summary) return null;
|
|
8
|
+
const visibleSeverities = WORKFLOW_RUN_ANNOTATION_SEVERITIES.filter((severity)=>summary[severity] > 0);
|
|
9
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
10
|
+
className: "flex flex-wrap items-center gap-x-8 gap-y-4 text-foreground-neutral-subtle",
|
|
11
|
+
children: [
|
|
12
|
+
/*#__PURE__*/ _jsxs(Text, {
|
|
13
|
+
as: "span",
|
|
14
|
+
size: "xs",
|
|
15
|
+
className: "shrink-0 text-foreground-neutral-subtle",
|
|
16
|
+
children: [
|
|
17
|
+
summary.total,
|
|
18
|
+
" ",
|
|
19
|
+
pluralize('annotation', summary.total)
|
|
20
|
+
]
|
|
21
|
+
}),
|
|
22
|
+
visibleSeverities.map((severity)=>/*#__PURE__*/ _jsxs("span", {
|
|
23
|
+
className: "inline-flex shrink-0 items-center gap-8",
|
|
24
|
+
children: [
|
|
25
|
+
/*#__PURE__*/ _jsx(MetadataSeparator, {}),
|
|
26
|
+
/*#__PURE__*/ _jsx(SeverityLink, {
|
|
27
|
+
count: summary[severity],
|
|
28
|
+
severity: severity,
|
|
29
|
+
workspaceSlug: workspaceSlug,
|
|
30
|
+
projectSlug: projectSlug,
|
|
31
|
+
workflowRunId: workflowRunId,
|
|
32
|
+
search: search
|
|
33
|
+
})
|
|
34
|
+
]
|
|
35
|
+
}, severity))
|
|
36
|
+
]
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function SeverityLink({ count, severity, workspaceSlug, projectSlug, workflowRunId, search }) {
|
|
40
|
+
const label = `${count} ${pluralize(severity, count)}`;
|
|
41
|
+
if (!workspaceSlug || !projectSlug || !workflowRunId) {
|
|
42
|
+
return /*#__PURE__*/ _jsx("span", {
|
|
43
|
+
className: "text-foreground-highlight-interactive",
|
|
44
|
+
children: label
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
const searchWithoutAnnotation = {
|
|
48
|
+
...search
|
|
49
|
+
};
|
|
50
|
+
delete searchWithoutAnnotation.annotation;
|
|
51
|
+
return /*#__PURE__*/ _jsx(Link, {
|
|
52
|
+
to: "/w/$workspaceSlug/p/$projectSlug/runs/$workflowRunId",
|
|
53
|
+
params: {
|
|
54
|
+
workspaceSlug,
|
|
55
|
+
projectSlug,
|
|
56
|
+
workflowRunId
|
|
57
|
+
},
|
|
58
|
+
search: workflowRunSearchParams({
|
|
59
|
+
...searchWithoutAnnotation,
|
|
60
|
+
tab: 'annotations',
|
|
61
|
+
severity
|
|
62
|
+
}, search),
|
|
63
|
+
className: "text-foreground-highlight-interactive outline-none hover:underline focus-visible:shadow-border-interactive-with-active",
|
|
64
|
+
children: label
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
function pluralize(word, count) {
|
|
68
|
+
return count === 1 ? word : `${word}s`;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=run-annotation-summary-line.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/workflow-run-tabs/run-annotation-summary-line.tsx"],"sourcesContent":["import {Text} from '@shipfox/react-ui/typography';\nimport {Link} from '@tanstack/react-router';\nimport type {RunAnnotationSummary} from '#core/workflow-run-tabs.js';\nimport {\n WORKFLOW_RUN_ANNOTATION_SEVERITIES,\n type WorkflowRunAnnotationSeverity,\n type WorkflowRunsSearch,\n workflowRunSearchParams,\n} from '#routes/inputs.js';\nimport {MetadataSeparator} from '../workflow-run-summary/workflow-run-summary.js';\n\nexport interface RunAnnotationSummaryLineProps {\n summary?: RunAnnotationSummary | undefined;\n workspaceSlug?: string | undefined;\n projectSlug?: string | undefined;\n workflowRunId?: string | undefined;\n search?: WorkflowRunsSearch | undefined;\n}\n\nexport function RunAnnotationSummaryLine({\n summary,\n workspaceSlug,\n projectSlug,\n workflowRunId,\n search = {},\n}: RunAnnotationSummaryLineProps) {\n if (!summary) return null;\n\n const visibleSeverities = WORKFLOW_RUN_ANNOTATION_SEVERITIES.filter(\n (severity) => summary[severity] > 0,\n );\n\n return (\n <div className=\"flex flex-wrap items-center gap-x-8 gap-y-4 text-foreground-neutral-subtle\">\n <Text as=\"span\" size=\"xs\" className=\"shrink-0 text-foreground-neutral-subtle\">\n {summary.total} {pluralize('annotation', summary.total)}\n </Text>\n {visibleSeverities.map((severity) => (\n <span key={severity} className=\"inline-flex shrink-0 items-center gap-8\">\n <MetadataSeparator />\n <SeverityLink\n count={summary[severity]}\n severity={severity}\n workspaceSlug={workspaceSlug}\n projectSlug={projectSlug}\n workflowRunId={workflowRunId}\n search={search}\n />\n </span>\n ))}\n </div>\n );\n}\n\nfunction SeverityLink({\n count,\n severity,\n workspaceSlug,\n projectSlug,\n workflowRunId,\n search,\n}: {\n count: number;\n severity: WorkflowRunAnnotationSeverity;\n workspaceSlug?: string | undefined;\n projectSlug?: string | undefined;\n workflowRunId?: string | undefined;\n search: WorkflowRunsSearch;\n}) {\n const label = `${count} ${pluralize(severity, count)}`;\n if (!workspaceSlug || !projectSlug || !workflowRunId) {\n return <span className=\"text-foreground-highlight-interactive\">{label}</span>;\n }\n\n const searchWithoutAnnotation = {...search};\n delete searchWithoutAnnotation.annotation;\n\n return (\n <Link\n to=\"/w/$workspaceSlug/p/$projectSlug/runs/$workflowRunId\"\n params={{workspaceSlug, projectSlug, workflowRunId}}\n search={\n workflowRunSearchParams(\n {...searchWithoutAnnotation, tab: 'annotations', severity},\n search,\n ) as never\n }\n className=\"text-foreground-highlight-interactive outline-none hover:underline focus-visible:shadow-border-interactive-with-active\"\n >\n {label}\n </Link>\n );\n}\n\nfunction pluralize(word: string, count: number): string {\n return count === 1 ? word : `${word}s`;\n}\n"],"names":["Text","Link","WORKFLOW_RUN_ANNOTATION_SEVERITIES","workflowRunSearchParams","MetadataSeparator","RunAnnotationSummaryLine","summary","workspaceSlug","projectSlug","workflowRunId","search","visibleSeverities","filter","severity","div","className","as","size","total","pluralize","map","span","SeverityLink","count","label","searchWithoutAnnotation","annotation","to","params","tab","word"],"mappings":";AAAA,SAAQA,IAAI,QAAO,+BAA+B;AAClD,SAAQC,IAAI,QAAO,yBAAyB;AAE5C,SACEC,kCAAkC,EAGlCC,uBAAuB,QAClB,oBAAoB;AAC3B,SAAQC,iBAAiB,QAAO,kDAAkD;AAUlF,OAAO,SAASC,yBAAyB,EACvCC,OAAO,EACPC,aAAa,EACbC,WAAW,EACXC,aAAa,EACbC,SAAS,CAAC,CAAC,EACmB;IAC9B,IAAI,CAACJ,SAAS,OAAO;IAErB,MAAMK,oBAAoBT,mCAAmCU,MAAM,CACjE,CAACC,WAAaP,OAAO,CAACO,SAAS,GAAG;IAGpC,qBACE,MAACC;QAAIC,WAAU;;0BACb,MAACf;gBAAKgB,IAAG;gBAAOC,MAAK;gBAAKF,WAAU;;oBACjCT,QAAQY,KAAK;oBAAC;oBAAEC,UAAU,cAAcb,QAAQY,KAAK;;;YAEvDP,kBAAkBS,GAAG,CAAC,CAACP,yBACtB,MAACQ;oBAAoBN,WAAU;;sCAC7B,KAACX;sCACD,KAACkB;4BACCC,OAAOjB,OAAO,CAACO,SAAS;4BACxBA,UAAUA;4BACVN,eAAeA;4BACfC,aAAaA;4BACbC,eAAeA;4BACfC,QAAQA;;;mBARDG;;;AAcnB;AAEA,SAASS,aAAa,EACpBC,KAAK,EACLV,QAAQ,EACRN,aAAa,EACbC,WAAW,EACXC,aAAa,EACbC,MAAM,EAQP;IACC,MAAMc,QAAQ,GAAGD,MAAM,CAAC,EAAEJ,UAAUN,UAAUU,QAAQ;IACtD,IAAI,CAAChB,iBAAiB,CAACC,eAAe,CAACC,eAAe;QACpD,qBAAO,KAACY;YAAKN,WAAU;sBAAyCS;;IAClE;IAEA,MAAMC,0BAA0B;QAAC,GAAGf,MAAM;IAAA;IAC1C,OAAOe,wBAAwBC,UAAU;IAEzC,qBACE,KAACzB;QACC0B,IAAG;QACHC,QAAQ;YAACrB;YAAeC;YAAaC;QAAa;QAClDC,QACEP,wBACE;YAAC,GAAGsB,uBAAuB;YAAEI,KAAK;YAAehB;QAAQ,GACzDH;QAGJK,WAAU;kBAETS;;AAGP;AAEA,SAASL,UAAUW,IAAY,EAAEP,KAAa;IAC5C,OAAOA,UAAU,IAAIO,OAAO,GAAGA,KAAK,CAAC,CAAC;AACxC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-annotations-empty.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-tabs/run-annotations-empty.tsx"],"names":[],"mappings":"AAEA,wBAAgB,mBAAmB,gCAQlC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { EmptyState } from '@shipfox/react-ui/empty-state';
|
|
3
|
+
export function RunAnnotationsEmpty() {
|
|
4
|
+
return /*#__PURE__*/ _jsx(EmptyState, {
|
|
5
|
+
icon: "fileDamageLine",
|
|
6
|
+
title: "No annotations",
|
|
7
|
+
description: "This run has no annotations to show."
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=run-annotations-empty.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/workflow-run-tabs/run-annotations-empty.tsx"],"sourcesContent":["import {EmptyState} from '@shipfox/react-ui/empty-state';\n\nexport function RunAnnotationsEmpty() {\n return (\n <EmptyState\n icon=\"fileDamageLine\"\n title=\"No annotations\"\n description=\"This run has no annotations to show.\"\n />\n );\n}\n"],"names":["EmptyState","RunAnnotationsEmpty","icon","title","description"],"mappings":";AAAA,SAAQA,UAAU,QAAO,gCAAgC;AAEzD,OAAO,SAASC;IACd,qBACE,KAACD;QACCE,MAAK;QACLC,OAAM;QACNC,aAAY;;AAGlB"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defaultJobExecution, type Job } from '#core/workflow-run.js';
|
|
2
|
+
import { JobCard } from '../workflow-run-view/job-card.js';
|
|
3
|
+
export interface RunJobsListProps {
|
|
4
|
+
jobs: Job[];
|
|
5
|
+
selectedJobId?: string | undefined;
|
|
6
|
+
onSelectedJobChange: (jobId: string | undefined) => void;
|
|
7
|
+
workspaceSlug?: string | undefined;
|
|
8
|
+
selectedJobExecution: ReturnType<typeof defaultJobExecution>;
|
|
9
|
+
selectedAttemptId: string | null | undefined;
|
|
10
|
+
onSelectedJobExecutionChange: ((jobExecutionId: string | undefined) => void) | undefined;
|
|
11
|
+
onSelectedAttemptChange: ((attemptId: string | undefined) => void) | undefined;
|
|
12
|
+
sourcePanelId?: string | undefined;
|
|
13
|
+
sourceAvailable?: boolean | undefined;
|
|
14
|
+
focusedSourceStepId?: string | null | undefined;
|
|
15
|
+
onOpenStepSource?: Parameters<typeof JobCard>[0]['onOpenStepSource'];
|
|
16
|
+
}
|
|
17
|
+
export declare function RunJobsList({ jobs, selectedJobId, onSelectedJobChange, workspaceSlug, selectedJobExecution, selectedAttemptId, onSelectedJobExecutionChange, onSelectedAttemptChange, sourcePanelId, sourceAvailable, focusedSourceStepId, onOpenStepSource, }: RunJobsListProps): import("react").JSX.Element;
|
|
18
|
+
//# sourceMappingURL=run-jobs-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-jobs-list.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-tabs/run-jobs-list.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,mBAAmB,EAGnB,KAAK,GAAG,EACT,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAC,OAAO,EAAC,MAAM,kCAAkC,CAAC;AAGzD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,mBAAmB,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IACzD,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,oBAAoB,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;IAC7D,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC7C,4BAA4B,EAAE,CAAC,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACzF,uBAAuB,EAAE,CAAC,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC/E,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,eAAe,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChD,gBAAgB,CAAC,EAAE,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;CACtE;AAED,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,aAAa,EACb,mBAAmB,EACnB,aAAa,EACb,oBAAoB,EACpB,iBAAiB,EACjB,4BAA4B,EAC5B,uBAAuB,EACvB,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,gBAAgB,GACjB,EAAE,gBAAgB,+BAsFlB"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { EmptyState } from '@shipfox/react-ui/empty-state';
|
|
3
|
+
import { useTimeTick } from '@shipfox/react-ui/time-ticker';
|
|
4
|
+
import { cn } from '@shipfox/react-ui/utils';
|
|
5
|
+
import { defaultJobExecution, deriveJobDisplayStatus, deriveJobExecutionDisplayStatus } from '#core/workflow-run.js';
|
|
6
|
+
import { formatJobDurationAccessibleLabel } from '../job-graph/job-duration-format.js';
|
|
7
|
+
import { JobDurationLabel } from '../job-graph/job-duration-label.js';
|
|
8
|
+
import { JobCard } from '../workflow-run-view/job-card.js';
|
|
9
|
+
import { WorkflowStatusIcon } from '../workflow-status/workflow-status-icon.js';
|
|
10
|
+
export function RunJobsList({ jobs, selectedJobId, onSelectedJobChange, workspaceSlug, selectedJobExecution, selectedAttemptId, onSelectedJobExecutionChange, onSelectedAttemptChange, sourcePanelId, sourceAvailable, focusedSourceStepId, onOpenStepSource }) {
|
|
11
|
+
useTimeTick();
|
|
12
|
+
if (jobs.length === 0) {
|
|
13
|
+
return /*#__PURE__*/ _jsx("section", {
|
|
14
|
+
"aria-label": "Workflow jobs",
|
|
15
|
+
className: "rounded-8 border border-border-neutral-base bg-background-components-base",
|
|
16
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
17
|
+
className: "min-h-160",
|
|
18
|
+
children: /*#__PURE__*/ _jsx(RunJobsEmptyState, {})
|
|
19
|
+
})
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
const orderedJobs = [
|
|
23
|
+
...jobs
|
|
24
|
+
].sort(compareJobs);
|
|
25
|
+
return /*#__PURE__*/ _jsx("section", {
|
|
26
|
+
"aria-label": "Workflow jobs",
|
|
27
|
+
className: "flex min-w-0 flex-col gap-8",
|
|
28
|
+
children: /*#__PURE__*/ _jsx("ul", {
|
|
29
|
+
"aria-label": "Run jobs",
|
|
30
|
+
className: "m-0 flex min-w-0 list-none flex-col gap-8 p-0",
|
|
31
|
+
children: orderedJobs.map((job)=>{
|
|
32
|
+
const selected = job.id === selectedJobId;
|
|
33
|
+
const status = deriveJobDisplayStatus(job);
|
|
34
|
+
const execution = defaultJobExecution(job);
|
|
35
|
+
const durationLabel = formatJobDurationAccessibleLabel(job.displayDuration, execution ? deriveJobExecutionDisplayStatus(execution) : undefined);
|
|
36
|
+
const rowLabel = [
|
|
37
|
+
job.displayName,
|
|
38
|
+
statusLabel(status),
|
|
39
|
+
durationLabel,
|
|
40
|
+
job.carriedOver ? 'reused' : undefined
|
|
41
|
+
].filter((part)=>Boolean(part)).join(', ');
|
|
42
|
+
return /*#__PURE__*/ _jsxs("li", {
|
|
43
|
+
className: "min-w-0",
|
|
44
|
+
children: [
|
|
45
|
+
/*#__PURE__*/ _jsxs("button", {
|
|
46
|
+
type: "button",
|
|
47
|
+
"aria-expanded": selected,
|
|
48
|
+
"aria-controls": selected ? `job-card-${job.id}` : undefined,
|
|
49
|
+
"aria-label": rowLabel,
|
|
50
|
+
onClick: ()=>onSelectedJobChange(selected ? undefined : job.id),
|
|
51
|
+
className: cn('relative flex min-h-44 w-full min-w-0 items-center gap-8 rounded-8 bg-background-neutral-base px-12 text-left shadow-button-neutral outline-none transition-colors hover:bg-background-components-hover focus-visible:shadow-button-neutral-focus', selected && 'bg-background-components-hover hover:bg-background-components-pressed'),
|
|
52
|
+
children: [
|
|
53
|
+
selected ? /*#__PURE__*/ _jsx("span", {
|
|
54
|
+
"aria-hidden": "true",
|
|
55
|
+
className: "absolute inset-y-6 left-0 w-px rounded-full bg-border-highlights-interactive"
|
|
56
|
+
}) : null,
|
|
57
|
+
/*#__PURE__*/ _jsx(WorkflowStatusIcon, {
|
|
58
|
+
status: status,
|
|
59
|
+
size: 14,
|
|
60
|
+
tooltip: false
|
|
61
|
+
}),
|
|
62
|
+
/*#__PURE__*/ _jsx("span", {
|
|
63
|
+
className: "min-w-0 flex-1 truncate text-sm font-medium text-foreground-neutral-base",
|
|
64
|
+
children: job.displayName
|
|
65
|
+
}),
|
|
66
|
+
/*#__PURE__*/ _jsx(JobDurationLabel, {
|
|
67
|
+
duration: job.displayDuration
|
|
68
|
+
})
|
|
69
|
+
]
|
|
70
|
+
}),
|
|
71
|
+
selected ? /*#__PURE__*/ _jsx("div", {
|
|
72
|
+
id: `job-card-${job.id}`,
|
|
73
|
+
className: "mt-8",
|
|
74
|
+
children: /*#__PURE__*/ _jsx(JobCard, {
|
|
75
|
+
workspaceSlug: workspaceSlug,
|
|
76
|
+
job: job,
|
|
77
|
+
selectedJobExecution: selectedJobExecution,
|
|
78
|
+
selectedAttemptId: job.carriedOver ? undefined : selectedAttemptId,
|
|
79
|
+
onSelectedJobExecutionChange: onSelectedJobExecutionChange,
|
|
80
|
+
onSelectedAttemptChange: onSelectedAttemptChange,
|
|
81
|
+
sourcePanelId: sourcePanelId,
|
|
82
|
+
sourceAvailable: sourceAvailable,
|
|
83
|
+
focusedSourceStepId: focusedSourceStepId,
|
|
84
|
+
onOpenStepSource: onOpenStepSource
|
|
85
|
+
})
|
|
86
|
+
}) : null
|
|
87
|
+
]
|
|
88
|
+
}, job.id);
|
|
89
|
+
})
|
|
90
|
+
})
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
function RunJobsEmptyState() {
|
|
94
|
+
return /*#__PURE__*/ _jsx(EmptyState, {
|
|
95
|
+
icon: "componentLine",
|
|
96
|
+
title: "No jobs yet",
|
|
97
|
+
description: "This run has not materialized jobs."
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
function compareJobs(left, right) {
|
|
101
|
+
return left.position - right.position || left.displayName.localeCompare(right.displayName) || left.id.localeCompare(right.id);
|
|
102
|
+
}
|
|
103
|
+
function statusLabel(status) {
|
|
104
|
+
return status === 'listening' ? 'Listening' : status.charAt(0).toUpperCase() + status.slice(1);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
//# sourceMappingURL=run-jobs-list.js.map
|