@shipfox/client-workflows 14.0.1 → 16.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/preview.css +4 -0
- package/.storybook/preview.tsx +7 -2
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +42 -0
- package/dist/components/job-detail/agent-config-failure-callout.d.ts.map +1 -0
- package/dist/components/{workflow-run-view → job-detail}/agent-config-failure-callout.js +2 -2
- package/dist/components/job-detail/agent-config-failure-callout.js.map +1 -0
- package/dist/components/job-detail/job-detail-header.d.ts +15 -0
- package/dist/components/job-detail/job-detail-header.d.ts.map +1 -0
- package/dist/components/job-detail/job-detail-header.js +124 -0
- package/dist/components/job-detail/job-detail-header.js.map +1 -0
- package/dist/components/job-detail/job-detail-view.d.ts +16 -0
- package/dist/components/job-detail/job-detail-view.d.ts.map +1 -0
- package/dist/components/job-detail/job-detail-view.js +420 -0
- package/dist/components/job-detail/job-detail-view.js.map +1 -0
- package/dist/components/job-detail/job-empty-states.d.ts +10 -0
- package/dist/components/job-detail/job-empty-states.d.ts.map +1 -0
- package/dist/components/job-detail/job-empty-states.js +195 -0
- package/dist/components/job-detail/job-empty-states.js.map +1 -0
- package/dist/components/job-detail/job-execution-switcher.d.ts.map +1 -0
- package/dist/components/job-detail/job-execution-switcher.js.map +1 -0
- package/dist/components/job-detail/job-execution-time-text.d.ts.map +1 -0
- package/dist/components/job-detail/job-execution-time-text.js.map +1 -0
- package/dist/components/job-detail/job-selection.d.ts +24 -0
- package/dist/components/job-detail/job-selection.d.ts.map +1 -0
- package/dist/components/job-detail/job-selection.js +66 -0
- package/dist/components/job-detail/job-selection.js.map +1 -0
- package/dist/components/job-detail/step-attempt-log-panel.d.ts +15 -0
- package/dist/components/job-detail/step-attempt-log-panel.d.ts.map +1 -0
- package/dist/components/{workflow-run-view → job-detail}/step-attempt-log-panel.js +61 -16
- package/dist/components/job-detail/step-attempt-log-panel.js.map +1 -0
- package/dist/components/job-graph/job-graph-content.js +1 -1
- package/dist/components/job-graph/job-graph-content.js.map +1 -1
- package/dist/components/step-list/step-list-model.js +2 -2
- package/dist/components/step-list/step-list-model.js.map +1 -1
- package/dist/components/step-list/step-list.d.ts +1 -0
- package/dist/components/step-list/step-list.d.ts.map +1 -1
- package/dist/components/step-list/step-list.js +29 -4
- package/dist/components/step-list/step-list.js.map +1 -1
- package/dist/components/workflow-run-duration-label.d.ts +9 -4
- package/dist/components/workflow-run-duration-label.d.ts.map +1 -1
- package/dist/components/workflow-run-duration-label.js +27 -7
- package/dist/components/workflow-run-duration-label.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-row.d.ts.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-row.js +6 -5
- package/dist/components/workflow-run-list/workflow-run-row.js.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-summary.d.ts.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-summary.js +69 -64
- package/dist/components/workflow-run-summary/workflow-run-summary.js.map +1 -1
- package/dist/components/workflow-run-tabs/index.d.ts +3 -3
- package/dist/components/workflow-run-tabs/index.d.ts.map +1 -1
- package/dist/components/workflow-run-tabs/index.js +3 -3
- package/dist/components/workflow-run-tabs/index.js.map +1 -1
- package/dist/components/workflow-run-tabs/run-annotation-count-chip.d.ts +16 -0
- package/dist/components/workflow-run-tabs/run-annotation-count-chip.d.ts.map +1 -0
- package/dist/components/workflow-run-tabs/run-annotation-count-chip.js +50 -0
- package/dist/components/workflow-run-tabs/run-annotation-count-chip.js.map +1 -0
- package/dist/components/workflow-run-tabs/run-annotation-item.d.ts +20 -0
- package/dist/components/workflow-run-tabs/run-annotation-item.d.ts.map +1 -0
- package/dist/components/workflow-run-tabs/run-annotation-item.js +102 -0
- package/dist/components/workflow-run-tabs/run-annotation-item.js.map +1 -0
- package/dist/components/workflow-run-tabs/run-annotation-list.d.ts +32 -0
- package/dist/components/workflow-run-tabs/run-annotation-list.d.ts.map +1 -0
- package/dist/components/workflow-run-tabs/run-annotation-list.js +202 -0
- package/dist/components/workflow-run-tabs/run-annotation-list.js.map +1 -0
- package/dist/components/workflow-run-tabs/run-annotation-summary-line.d.ts +1 -1
- package/dist/components/workflow-run-tabs/run-annotation-summary-line.d.ts.map +1 -1
- package/dist/components/workflow-run-tabs/run-annotation-summary-line.js +87 -22
- package/dist/components/workflow-run-tabs/run-annotation-summary-line.js.map +1 -1
- package/dist/components/workflow-run-tabs/run-annotations-empty.d.ts +3 -1
- package/dist/components/workflow-run-tabs/run-annotations-empty.d.ts.map +1 -1
- package/dist/components/workflow-run-tabs/run-annotations-empty.js +2 -2
- package/dist/components/workflow-run-tabs/run-annotations-empty.js.map +1 -1
- package/dist/components/workflow-run-tabs/severity-visuals.d.ts +20 -0
- package/dist/components/workflow-run-tabs/severity-visuals.d.ts.map +1 -0
- package/dist/components/workflow-run-tabs/severity-visuals.js +31 -0
- package/dist/components/workflow-run-tabs/severity-visuals.js.map +1 -0
- package/dist/components/workflow-run-view/index.d.ts +0 -1
- package/dist/components/workflow-run-view/index.d.ts.map +1 -1
- package/dist/components/workflow-run-view/index.js +0 -1
- package/dist/components/workflow-run-view/index.js.map +1 -1
- package/dist/components/workflow-run-view/run-workspace-nav.d.ts +20 -0
- package/dist/components/workflow-run-view/run-workspace-nav.d.ts.map +1 -0
- package/dist/components/workflow-run-view/run-workspace-nav.js +277 -0
- package/dist/components/workflow-run-view/run-workspace-nav.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 +1 -14
- package/dist/components/workflow-run-view/workflow-run-selection.js.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-view.d.ts +10 -10
- package/dist/components/workflow-run-view/workflow-run-view.d.ts.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-view.js +351 -239
- package/dist/components/workflow-run-view/workflow-run-view.js.map +1 -1
- package/dist/components/workflow-status/status-visuals.d.ts.map +1 -1
- package/dist/components/workflow-status/status-visuals.js +10 -2
- package/dist/components/workflow-status/status-visuals.js.map +1 -1
- package/dist/components/workflow-status/workflow-status-icon.d.ts +3 -1
- package/dist/components/workflow-status/workflow-status-icon.d.ts.map +1 -1
- package/dist/components/workflow-status/workflow-status-icon.js +13 -2
- package/dist/components/workflow-status/workflow-status-icon.js.map +1 -1
- package/dist/core/entities/job-execution.d.ts +9 -0
- package/dist/core/entities/job-execution.d.ts.map +1 -1
- package/dist/core/entities/job-execution.js +13 -3
- package/dist/core/entities/job-execution.js.map +1 -1
- package/dist/core/entities/job.d.ts.map +1 -1
- package/dist/core/entities/step-attempt.d.ts.map +1 -1
- package/dist/core/entities/step.d.ts +2 -0
- package/dist/core/entities/step.d.ts.map +1 -1
- package/dist/core/entities/step.js +13 -0
- package/dist/core/entities/step.js.map +1 -1
- package/dist/core/entities/workflow-run-attempt.d.ts.map +1 -1
- package/dist/core/entities/workflow-run.d.ts +56 -1
- package/dist/core/entities/workflow-run.d.ts.map +1 -1
- package/dist/core/entities/workflow-run.js +98 -0
- package/dist/core/entities/workflow-run.js.map +1 -1
- package/dist/core/run-annotation.d.ts +73 -0
- package/dist/core/run-annotation.d.ts.map +1 -0
- package/dist/core/run-annotation.js +125 -0
- package/dist/core/run-annotation.js.map +1 -0
- package/dist/core/workflow-run.d.ts +4 -4
- package/dist/core/workflow-run.d.ts.map +1 -1
- package/dist/core/workflow-run.js +3 -3
- package/dist/core/workflow-run.js.map +1 -1
- package/dist/feature.d.ts +20 -16
- package/dist/feature.d.ts.map +1 -1
- package/dist/feature.js +5 -0
- package/dist/feature.js.map +1 -1
- package/dist/hooks/api/run-annotation-mapper.d.ts +10 -0
- package/dist/hooks/api/run-annotation-mapper.d.ts.map +1 -0
- package/dist/hooks/api/run-annotation-mapper.js +22 -0
- package/dist/hooks/api/run-annotation-mapper.js.map +1 -0
- package/dist/hooks/api/run-annotations.d.ts +25 -0
- package/dist/hooks/api/run-annotations.d.ts.map +1 -0
- package/dist/hooks/api/run-annotations.js +78 -0
- package/dist/hooks/api/run-annotations.js.map +1 -0
- package/dist/hooks/api/workflow-runs.d.ts +5 -3
- package/dist/hooks/api/workflow-runs.d.ts.map +1 -1
- package/dist/hooks/api/workflow-runs.js +5 -4
- package/dist/hooks/api/workflow-runs.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/pages/workflow-job-detail-page.d.ts +11 -0
- package/dist/pages/workflow-job-detail-page.d.ts.map +1 -0
- package/dist/pages/workflow-job-detail-page.js +66 -0
- package/dist/pages/workflow-job-detail-page.js.map +1 -0
- package/dist/pages/workflow-run-detail-page.d.ts.map +1 -1
- package/dist/pages/workflow-run-detail-page.js +4 -37
- package/dist/pages/workflow-run-detail-page.js.map +1 -1
- package/dist/routes/inputs.d.ts +52 -34
- package/dist/routes/inputs.d.ts.map +1 -1
- package/dist/routes/inputs.js +74 -43
- package/dist/routes/inputs.js.map +1 -1
- package/dist/routes/job-detail.d.ts +10 -0
- package/dist/routes/job-detail.d.ts.map +1 -0
- package/dist/routes/job-detail.js +27 -0
- package/dist/routes/job-detail.js.map +1 -0
- package/dist/routes/project-route.d.ts +1 -1
- package/dist/routes/run-detail.d.ts.map +1 -1
- package/dist/routes/runs.d.ts.map +1 -1
- package/dist/routes/workflows.d.ts.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +10 -9
- package/src/components/{workflow-run-view → job-detail}/agent-config-failure-callout.stories.tsx +1 -1
- package/src/components/{workflow-run-view → job-detail}/agent-config-failure-callout.tsx +2 -2
- package/src/components/job-detail/job-detail-header.test.tsx +34 -0
- package/src/components/job-detail/job-detail-header.tsx +136 -0
- package/src/components/job-detail/job-detail-view.stories.tsx +531 -0
- package/src/components/job-detail/job-detail-view.tsx +467 -0
- package/src/components/job-detail/job-empty-states.test.ts +27 -0
- package/src/components/job-detail/job-empty-states.tsx +248 -0
- package/src/components/job-detail/job-selection.test.ts +188 -0
- package/src/components/job-detail/job-selection.ts +96 -0
- package/src/components/{workflow-run-view → job-detail}/step-attempt-log-panel.test.tsx +32 -9
- package/src/components/{workflow-run-view → job-detail}/step-attempt-log-panel.tsx +52 -18
- package/src/components/job-graph/job-graph-content.tsx +1 -1
- package/src/components/step-list/step-list-model.test.ts +1 -1
- package/src/components/step-list/step-list-model.ts +2 -2
- package/src/components/step-list/step-list.stories.tsx +1 -1
- package/src/components/step-list/step-list.test.tsx +33 -0
- package/src/components/step-list/step-list.tsx +40 -9
- package/src/components/workflow-run-duration-label.tsx +50 -12
- package/src/components/workflow-run-list/workflow-run-row.tsx +6 -4
- package/src/components/workflow-run-summary/workflow-run-summary.stories.tsx +38 -0
- package/src/components/workflow-run-summary/workflow-run-summary.test.tsx +79 -5
- package/src/components/workflow-run-summary/workflow-run-summary.tsx +56 -60
- package/src/components/workflow-run-tabs/index.ts +3 -3
- package/src/components/workflow-run-tabs/run-annotation-count-chip.tsx +63 -0
- package/src/components/workflow-run-tabs/run-annotation-item.tsx +123 -0
- package/src/components/workflow-run-tabs/run-annotation-list.tsx +258 -0
- package/src/components/workflow-run-tabs/run-annotation-summary-line.test.tsx +77 -3
- package/src/components/workflow-run-tabs/run-annotation-summary-line.tsx +92 -17
- package/src/components/workflow-run-tabs/run-annotations-empty.tsx +6 -2
- package/src/components/workflow-run-tabs/run-annotations.stories.tsx +293 -0
- package/src/components/workflow-run-tabs/severity-visuals.ts +37 -0
- package/src/components/workflow-run-view/index.ts +0 -1
- package/src/components/workflow-run-view/run-workspace-nav.test.tsx +286 -0
- package/src/components/workflow-run-view/run-workspace-nav.tsx +314 -0
- package/src/components/workflow-run-view/workflow-run-selection.ts +1 -23
- package/src/components/workflow-run-view/workflow-run-view.test.tsx +237 -1085
- package/src/components/workflow-run-view/workflow-run-view.tsx +450 -323
- package/src/components/workflow-status/status-visuals.ts +5 -2
- package/src/components/workflow-status/workflow-status-icon.stories.tsx +1 -0
- package/src/components/workflow-status/workflow-status-icon.tsx +26 -1
- package/src/core/entities/job-execution.ts +17 -2
- package/src/core/entities/step.ts +26 -0
- package/src/core/entities/workflow-run-display.test.ts +159 -0
- package/src/core/entities/workflow-run.ts +139 -1
- package/src/core/run-annotation.test.ts +315 -0
- package/src/core/run-annotation.ts +238 -0
- package/src/core/workflow-run.ts +16 -1
- package/src/feature.ts +5 -0
- package/src/hooks/api/run-annotation-mapper.ts +30 -0
- package/src/hooks/api/run-annotations.ts +137 -0
- package/src/hooks/api/workflow-runs.ts +6 -2
- package/src/index.ts +1 -0
- package/src/page-harness-budget.test.ts +1 -0
- package/src/pages/workflow-job-detail-page.test.tsx +605 -0
- package/src/pages/workflow-job-detail-page.tsx +84 -0
- package/src/pages/workflow-run-detail-page.tsx +3 -43
- package/src/pages/workflow-run-pages.test.tsx +77 -332
- package/src/routes/inputs.test.ts +56 -6
- package/src/routes/inputs.ts +71 -19
- package/src/routes/job-detail.tsx +29 -0
- package/test/pages.tsx +25 -3
- package/test/render.tsx +6 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/dist/components/workflow-run-tabs/run-jobs-list.d.ts +0 -18
- package/dist/components/workflow-run-tabs/run-jobs-list.d.ts.map +0 -1
- package/dist/components/workflow-run-tabs/run-jobs-list.js +0 -107
- package/dist/components/workflow-run-tabs/run-jobs-list.js.map +0 -1
- package/dist/components/workflow-run-tabs/run-tab-count.d.ts +0 -6
- package/dist/components/workflow-run-tabs/run-tab-count.d.ts.map +0 -1
- package/dist/components/workflow-run-tabs/run-tab-count.js +0 -27
- package/dist/components/workflow-run-tabs/run-tab-count.js.map +0 -1
- package/dist/components/workflow-run-tabs/run-tab-strip.d.ts +0 -8
- package/dist/components/workflow-run-tabs/run-tab-strip.d.ts.map +0 -1
- package/dist/components/workflow-run-tabs/run-tab-strip.js +0 -82
- package/dist/components/workflow-run-tabs/run-tab-strip.js.map +0 -1
- package/dist/components/workflow-run-view/agent-config-failure-callout.d.ts.map +0 -1
- package/dist/components/workflow-run-view/agent-config-failure-callout.js.map +0 -1
- package/dist/components/workflow-run-view/job-card.d.ts +0 -17
- package/dist/components/workflow-run-view/job-card.d.ts.map +0 -1
- package/dist/components/workflow-run-view/job-card.js +0 -496
- package/dist/components/workflow-run-view/job-card.js.map +0 -1
- package/dist/components/workflow-run-view/job-execution-switcher.d.ts.map +0 -1
- package/dist/components/workflow-run-view/job-execution-switcher.js.map +0 -1
- package/dist/components/workflow-run-view/job-execution-time-text.d.ts.map +0 -1
- package/dist/components/workflow-run-view/job-execution-time-text.js.map +0 -1
- package/dist/components/workflow-run-view/step-attempt-log-panel.d.ts +0 -9
- package/dist/components/workflow-run-view/step-attempt-log-panel.d.ts.map +0 -1
- package/dist/components/workflow-run-view/step-attempt-log-panel.js.map +0 -1
- package/dist/core/workflow-run-tabs.d.ts +0 -9
- package/dist/core/workflow-run-tabs.d.ts.map +0 -1
- package/dist/core/workflow-run-tabs.js +0 -3
- package/dist/core/workflow-run-tabs.js.map +0 -1
- package/src/components/workflow-run-tabs/run-jobs-list.tsx +0 -151
- package/src/components/workflow-run-tabs/run-tab-count.tsx +0 -28
- package/src/components/workflow-run-tabs/run-tab-strip.stories.tsx +0 -52
- package/src/components/workflow-run-tabs/run-tab-strip.test.tsx +0 -117
- package/src/components/workflow-run-tabs/run-tab-strip.tsx +0 -97
- package/src/components/workflow-run-view/job-card.stories.tsx +0 -789
- package/src/components/workflow-run-view/job-card.test.tsx +0 -115
- package/src/components/workflow-run-view/job-card.tsx +0 -614
- package/src/core/workflow-run-tabs.ts +0 -8
- /package/dist/components/{workflow-run-view → job-detail}/agent-config-failure-callout.d.ts +0 -0
- /package/dist/components/{workflow-run-view → job-detail}/job-execution-switcher.d.ts +0 -0
- /package/dist/components/{workflow-run-view → job-detail}/job-execution-switcher.js +0 -0
- /package/dist/components/{workflow-run-view → job-detail}/job-execution-time-text.d.ts +0 -0
- /package/dist/components/{workflow-run-view → job-detail}/job-execution-time-text.js +0 -0
- /package/src/components/{workflow-run-view → job-detail}/job-execution-switcher.tsx +0 -0
- /package/src/components/{workflow-run-view → job-detail}/job-execution-time-text.tsx +0 -0
|
@@ -1,14 +1,5 @@
|
|
|
1
|
-
import {useNavigate} from '@tanstack/react-router';
|
|
2
|
-
import {useCallback} from 'react';
|
|
3
1
|
import {WorkflowRunView} from '#components/workflow-run-view/index.js';
|
|
4
|
-
import type
|
|
5
|
-
import {
|
|
6
|
-
validateWorkflowRunsSearch,
|
|
7
|
-
type WorkflowRunsSearch,
|
|
8
|
-
type WorkflowRunTab,
|
|
9
|
-
workflowRunSearchParams,
|
|
10
|
-
workflowRunTab,
|
|
11
|
-
} from '#routes/inputs.js';
|
|
2
|
+
import {type WorkflowRunsSearch, workflowRunTab} from '#routes/inputs.js';
|
|
12
3
|
|
|
13
4
|
interface WorkflowRunDetailPageProps {
|
|
14
5
|
projectId: string;
|
|
@@ -25,36 +16,6 @@ export function WorkflowRunDetailPage({
|
|
|
25
16
|
workflowRunId,
|
|
26
17
|
search = {},
|
|
27
18
|
}: WorkflowRunDetailPageProps) {
|
|
28
|
-
const navigate = useNavigate();
|
|
29
|
-
const selection: WorkflowRunSelectionInput = search;
|
|
30
|
-
const onSelectionChange = useCallback(
|
|
31
|
-
(nextSelection: WorkflowRunSelectionInput) => {
|
|
32
|
-
navigate({
|
|
33
|
-
search: ((previous: Record<string, unknown>) => {
|
|
34
|
-
const current = validateWorkflowRunsSearch(previous);
|
|
35
|
-
return workflowRunSearchParams(current, nextSelection);
|
|
36
|
-
}) as never,
|
|
37
|
-
replace: true,
|
|
38
|
-
});
|
|
39
|
-
},
|
|
40
|
-
[navigate],
|
|
41
|
-
);
|
|
42
|
-
const onTabChange = useCallback(
|
|
43
|
-
(nextTab: WorkflowRunTab) => {
|
|
44
|
-
navigate({
|
|
45
|
-
search: ((previous: Record<string, unknown>) => {
|
|
46
|
-
const current = validateWorkflowRunsSearch(previous);
|
|
47
|
-
const nextSearch = workflowRunSearchParams({...current, tab: nextTab}, current);
|
|
48
|
-
return nextTab === 'summary' &&
|
|
49
|
-
(current.jobId || current.jobExecutionId || current.stepId || current.stepAttemptId)
|
|
50
|
-
? {...nextSearch, tab: nextTab}
|
|
51
|
-
: nextSearch;
|
|
52
|
-
}) as never,
|
|
53
|
-
});
|
|
54
|
-
},
|
|
55
|
-
[navigate],
|
|
56
|
-
);
|
|
57
|
-
|
|
58
19
|
return (
|
|
59
20
|
<div className="flex min-h-0 flex-1 overflow-hidden bg-background-neutral-background">
|
|
60
21
|
<WorkflowRunView
|
|
@@ -62,10 +23,9 @@ export function WorkflowRunDetailPage({
|
|
|
62
23
|
workspaceSlug={workspaceSlug}
|
|
63
24
|
projectSlug={projectSlug}
|
|
64
25
|
workflowRunId={workflowRunId}
|
|
65
|
-
|
|
66
|
-
|
|
26
|
+
runAttempt={search.runAttempt}
|
|
27
|
+
selection={search}
|
|
67
28
|
tab={workflowRunTab(search)}
|
|
68
|
-
onTabChange={onTabChange}
|
|
69
29
|
/>
|
|
70
30
|
</div>
|
|
71
31
|
);
|
|
@@ -5,16 +5,17 @@ import type {
|
|
|
5
5
|
import {configureApiClient} from '@shipfox/client-api';
|
|
6
6
|
import {act, screen, waitFor} from '@testing-library/react';
|
|
7
7
|
import userEvent from '@testing-library/user-event';
|
|
8
|
+
import type {WorkflowJobSearch, WorkflowRunsSearch} from '#routes/inputs.js';
|
|
8
9
|
import {inlineLogBody, outputLine} from '#test/fixtures/logs.js';
|
|
9
10
|
import {
|
|
10
11
|
workflowJobDto,
|
|
11
|
-
workflowJobExecutionDto,
|
|
12
12
|
workflowRunDetailDto,
|
|
13
13
|
workflowRunDto,
|
|
14
14
|
workflowStepAttemptDto,
|
|
15
15
|
workflowStepDto,
|
|
16
16
|
} from '#test/fixtures/workflow-run.js';
|
|
17
17
|
import {jsonResponse, PROJECT_TEST_WSLUG, renderProjectPage} from '#test/pages.js';
|
|
18
|
+
import {WorkflowJobDetailPage} from './workflow-job-detail-page.js';
|
|
18
19
|
import {WorkflowRunDetailPage} from './workflow-run-detail-page.js';
|
|
19
20
|
import {WorkflowRunsPage} from './workflow-run-list-page.js';
|
|
20
21
|
|
|
@@ -31,19 +32,15 @@ const DEPLOY_STEP_ID = '99999999-9999-4999-8999-999999999999';
|
|
|
31
32
|
const DEPLOY_RETRY_STEP_ID = '99999999-9999-4999-8999-000000000003';
|
|
32
33
|
const DEPLOY_ATTEMPT_ONE_ID = 'aaaaaaaa-aaaa-4aaa-8aaa-000000000001';
|
|
33
34
|
const DEPLOY_ATTEMPT_TWO_ID = 'aaaaaaaa-aaaa-4aaa-8aaa-000000000002';
|
|
34
|
-
const DEPLOY_EXECUTION_ONE_ID = 'bbbbbbbb-bbbb-4bbb-8bbb-000000000001';
|
|
35
|
-
const DEPLOY_EXECUTION_TWO_ID = 'bbbbbbbb-bbbb-4bbb-8bbb-000000000002';
|
|
36
35
|
const SMOKE_WEB_RE = /smoke-web/u;
|
|
37
36
|
const DEPLOY_WEB_RE = /deploy-web/u;
|
|
38
37
|
const OLDER_RUN_RE = /older-run/u;
|
|
39
38
|
const INTEGRATION_TESTS_RE = /integration-tests/u;
|
|
40
39
|
const BUILD_IMAGE_RE = /build-image/u;
|
|
41
40
|
const STATUS_FILTER_RE = /^Status\b.*filter$/u;
|
|
42
|
-
const EXECUTION_ONE_MENU_ITEM = /Execution #1: deploy review #1/u;
|
|
43
41
|
const JOBS_TAB_NAME = /^Jobs/u;
|
|
44
42
|
const BUILD_JOB_BUTTON_NAME = 'build, Succeeded';
|
|
45
43
|
const DEPLOY_JOB_BUTTON_NAME = 'deploy, Running';
|
|
46
|
-
const LIVE_DEPLOY_JOB_BUTTON_NAME = /^deploy, Running, running /u;
|
|
47
44
|
const RUN_DETAIL_PATH_RE = /^\/workflows\/runs\/([^/]+)$/u;
|
|
48
45
|
const RUN_OVERRIDES = {
|
|
49
46
|
id: RUN_ID,
|
|
@@ -172,163 +169,77 @@ describe('WorkflowRunPages', () => {
|
|
|
172
169
|
expect(screen.queryByLabelText('Loading workflow run')).not.toBeInTheDocument();
|
|
173
170
|
});
|
|
174
171
|
|
|
175
|
-
test('renders the
|
|
176
|
-
configureApiClient({fetchImpl: createRunDetailFetch()});
|
|
177
|
-
|
|
178
|
-
renderRunPath('?tab=jobs');
|
|
179
|
-
|
|
180
|
-
expect(await screen.findByRole('button', {name: DEPLOY_JOB_BUTTON_NAME})).toBeInTheDocument();
|
|
181
|
-
expect(screen.getByRole('link', {name: 'Runs'})).toHaveAttribute(
|
|
182
|
-
'href',
|
|
183
|
-
`/w/${PROJECT_TEST_WSLUG}/p/project/runs`,
|
|
184
|
-
);
|
|
185
|
-
expect(screen.queryByLabelText('Workflow runs')).not.toBeInTheDocument();
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
test('back to runs preserves list filters and drops run detail state', async () => {
|
|
189
|
-
configureApiClient({fetchImpl: createRunDetailFetch()});
|
|
190
|
-
|
|
191
|
-
renderRunPath(`?search=deploy-web&status=running&tab=jobs&job=${DEPLOY_JOB_ID}`);
|
|
192
|
-
|
|
193
|
-
expect(await screen.findByRole('link', {name: 'Runs'})).toHaveAttribute(
|
|
194
|
-
'href',
|
|
195
|
-
`/w/${PROJECT_TEST_WSLUG}/p/project/runs?search=deploy-web&status=running`,
|
|
196
|
-
);
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
test('defaults the detail route to the Summary tab', async () => {
|
|
172
|
+
test('renders the run workspace with the graph as the default all-jobs Summary', async () => {
|
|
200
173
|
configureApiClient({fetchImpl: createRunDetailFetch()});
|
|
201
174
|
|
|
202
175
|
const {router} = renderRunPath();
|
|
203
176
|
|
|
204
177
|
expect(await screen.findByRole('region', {name: 'deploy-web'})).toBeInTheDocument();
|
|
205
|
-
|
|
206
|
-
expect(
|
|
207
|
-
expect(
|
|
208
|
-
expect(screen.
|
|
178
|
+
expect(screen.getByRole('navigation', {name: 'Run workspace'})).toBeInTheDocument();
|
|
179
|
+
expect(screen.getByRole('link', {name: 'Summary'})).toHaveAttribute('aria-current', 'page');
|
|
180
|
+
expect(screen.getByRole('region', {name: 'All jobs summary'})).toBeInTheDocument();
|
|
181
|
+
expect(screen.getByRole('region', {name: 'Workflow jobs'})).toBeInTheDocument();
|
|
182
|
+
expect(screen.queryByLabelText('Workflow runs')).not.toBeInTheDocument();
|
|
183
|
+
expect(screen.queryByRole('tab', {name: JOBS_TAB_NAME})).not.toBeInTheDocument();
|
|
209
184
|
expect(currentSearch(router).tab).toBeUndefined();
|
|
210
185
|
});
|
|
211
186
|
|
|
212
|
-
test('
|
|
187
|
+
test('maps the removed Jobs tab URL to the graph Summary', async () => {
|
|
213
188
|
configureApiClient({fetchImpl: createRunDetailFetch()});
|
|
214
189
|
|
|
215
|
-
renderRunPath(
|
|
190
|
+
renderRunPath('?tab=jobs');
|
|
216
191
|
|
|
217
|
-
expect(await screen.findByRole('
|
|
218
|
-
expect(screen.getByRole('
|
|
192
|
+
expect(await screen.findByRole('region', {name: 'All jobs summary'})).toBeInTheDocument();
|
|
193
|
+
expect(screen.getByRole('link', {name: 'Summary'})).toHaveAttribute('aria-current', 'page');
|
|
219
194
|
});
|
|
220
195
|
|
|
221
|
-
test('
|
|
222
|
-
configureApiClient({
|
|
223
|
-
fetchImpl: createRunDetailFetch({details: {[RUN_ID]: retryRunDetailDto()}}),
|
|
224
|
-
});
|
|
196
|
+
test('redirects a legacy selected-step URL to its owning dedicated job page', async () => {
|
|
197
|
+
configureApiClient({fetchImpl: createRunDetailFetch()});
|
|
225
198
|
|
|
226
|
-
renderRunPath(`?
|
|
199
|
+
const {router} = renderRunPath(`?step=${DEPLOY_STEP_ID}&stepAttempt=${DEPLOY_ATTEMPT_TWO_ID}`);
|
|
227
200
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
jobs: [
|
|
237
|
-
workflowJobDto({
|
|
238
|
-
id: DEPLOY_JOB_ID,
|
|
239
|
-
run_attempt_id: RUN_ID,
|
|
240
|
-
name: 'deploy',
|
|
241
|
-
status: 'running',
|
|
242
|
-
job_executions: [
|
|
243
|
-
workflowJobExecutionDto({
|
|
244
|
-
job_id: DEPLOY_JOB_ID,
|
|
245
|
-
status: 'pending',
|
|
246
|
-
started_at: '2026-08-04T00:00:00.000Z',
|
|
247
|
-
steps: [workflowStepDto({status: 'running'})],
|
|
248
|
-
}),
|
|
249
|
-
],
|
|
250
|
-
}),
|
|
251
|
-
],
|
|
252
|
-
}),
|
|
253
|
-
},
|
|
254
|
-
}),
|
|
201
|
+
await waitFor(() =>
|
|
202
|
+
expect(router.state.location.pathname).toBe(
|
|
203
|
+
`/w/${PROJECT_TEST_WSLUG}/p/project/runs/${RUN_ID}/jobs/${DEPLOY_JOB_ID}`,
|
|
204
|
+
),
|
|
205
|
+
);
|
|
206
|
+
expect(currentSearch(router)).toMatchObject({
|
|
207
|
+
step: DEPLOY_STEP_ID,
|
|
208
|
+
stepAttempt: DEPLOY_ATTEMPT_TWO_ID,
|
|
255
209
|
});
|
|
256
|
-
|
|
257
|
-
renderRunPath(`?tab=jobs&job=${DEPLOY_JOB_ID}`);
|
|
258
|
-
|
|
259
|
-
expect(
|
|
260
|
-
await screen.findByRole('button', {name: LIVE_DEPLOY_JOB_BUTTON_NAME}),
|
|
261
|
-
).toBeInTheDocument();
|
|
210
|
+
expect(await screen.findByRole('heading', {name: 'deploy'})).toBeInTheDocument();
|
|
262
211
|
});
|
|
263
212
|
|
|
264
|
-
test('
|
|
213
|
+
test('navigates between run details and restores Summary with browser history', async () => {
|
|
265
214
|
const user = userEvent.setup();
|
|
266
215
|
configureApiClient({fetchImpl: createRunDetailFetch()});
|
|
267
216
|
|
|
268
217
|
const {router} = renderRunPath();
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
await user.click(await screen.findByRole('tab', {name: JOBS_TAB_NAME}));
|
|
218
|
+
await user.click(await screen.findByRole('link', {name: 'Source'}));
|
|
272
219
|
|
|
273
|
-
await waitFor(() => expect(currentSearch(router).tab).toBe('
|
|
274
|
-
expect(
|
|
275
|
-
expect(screen.getByRole('tab', {name: JOBS_TAB_NAME})).toHaveAttribute('aria-selected', 'true');
|
|
276
|
-
expect(screen.getByRole('list', {name: 'Run jobs'})).toBeInTheDocument();
|
|
277
|
-
|
|
278
|
-
await user.click(screen.getByRole('tab', {name: 'Summary'}));
|
|
220
|
+
await waitFor(() => expect(currentSearch(router).tab).toBe('source'));
|
|
221
|
+
expect(screen.getByRole('link', {name: 'Source'})).toHaveAttribute('aria-current', 'page');
|
|
279
222
|
|
|
223
|
+
await act(() => router.history.back());
|
|
280
224
|
await waitFor(() => expect(currentSearch(router).tab).toBeUndefined());
|
|
281
|
-
expect(
|
|
282
|
-
|
|
283
|
-
await act(() => {
|
|
284
|
-
router.history.back();
|
|
285
|
-
});
|
|
286
|
-
await waitFor(() => expect(currentSearch(router).tab).toBe('jobs'));
|
|
287
|
-
expect(screen.getByRole('list', {name: 'Run jobs'})).toBeInTheDocument();
|
|
225
|
+
expect(screen.getByRole('region', {name: 'All jobs summary'})).toBeInTheDocument();
|
|
288
226
|
});
|
|
289
227
|
|
|
290
|
-
test('
|
|
228
|
+
test('navigates from the Summary graph to the job detail route', async () => {
|
|
291
229
|
const user = userEvent.setup();
|
|
292
230
|
configureApiClient({fetchImpl: createRunDetailFetch()});
|
|
293
231
|
|
|
294
232
|
const {router} = renderRunPath();
|
|
295
|
-
const initialHistoryLength = router.history.length;
|
|
296
233
|
|
|
297
234
|
await user.click(await screen.findByRole('button', {name: 'deploy, Running'}));
|
|
298
235
|
|
|
299
|
-
await waitFor(() =>
|
|
300
|
-
expect(
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
expect(screen.getByRole('button', {name: 'deploy, Running'})).toHaveAttribute(
|
|
304
|
-
'aria-expanded',
|
|
305
|
-
'true',
|
|
306
|
-
);
|
|
307
|
-
expect(screen.getByRole('button', {name: 'deploy, Running'})).toHaveAttribute(
|
|
308
|
-
'aria-controls',
|
|
309
|
-
`job-card-${DEPLOY_JOB_ID}`,
|
|
310
|
-
);
|
|
311
|
-
expect(screen.getByRole('button', {name: BUILD_JOB_BUTTON_NAME})).not.toHaveAttribute(
|
|
312
|
-
'aria-controls',
|
|
236
|
+
await waitFor(() =>
|
|
237
|
+
expect(router.state.location.pathname).toBe(
|
|
238
|
+
`/w/${PROJECT_TEST_WSLUG}/p/project/runs/${RUN_ID}/jobs/${DEPLOY_JOB_ID}`,
|
|
239
|
+
),
|
|
313
240
|
);
|
|
314
241
|
});
|
|
315
242
|
|
|
316
|
-
test('preserves an explicit Summary tab with a selected job', async () => {
|
|
317
|
-
const user = userEvent.setup();
|
|
318
|
-
configureApiClient({fetchImpl: createRunDetailFetch()});
|
|
319
|
-
|
|
320
|
-
const {router} = renderRunPath(`?tab=jobs&job=${DEPLOY_JOB_ID}`);
|
|
321
|
-
|
|
322
|
-
await screen.findByRole('button', {name: DEPLOY_JOB_BUTTON_NAME});
|
|
323
|
-
await user.click(screen.getByRole('tab', {name: 'Summary'}));
|
|
324
|
-
|
|
325
|
-
await waitFor(() => {
|
|
326
|
-
expect(currentSearch(router)).toMatchObject({tab: 'summary', job: DEPLOY_JOB_ID});
|
|
327
|
-
});
|
|
328
|
-
expect(screen.getByRole('tab', {name: 'Summary'})).toHaveAttribute('aria-selected', 'true');
|
|
329
|
-
expect(screen.queryByRole('list', {name: 'Run jobs'})).not.toBeInTheDocument();
|
|
330
|
-
});
|
|
331
|
-
|
|
332
243
|
test('keeps Summary active while keyboard navigation moves graph focus', async () => {
|
|
333
244
|
const user = userEvent.setup();
|
|
334
245
|
configureApiClient({fetchImpl: createRunDetailFetch()});
|
|
@@ -342,125 +253,27 @@ describe('WorkflowRunPages', () => {
|
|
|
342
253
|
|
|
343
254
|
expect(deploy).toHaveFocus();
|
|
344
255
|
expect(deploy).toHaveAttribute('aria-pressed', 'true');
|
|
345
|
-
expect(screen.getByRole('
|
|
346
|
-
expect(screen.queryByRole('list', {name: 'Run jobs'})).not.toBeInTheDocument();
|
|
256
|
+
expect(screen.getByRole('link', {name: 'Summary'})).toHaveAttribute('aria-current', 'page');
|
|
347
257
|
expect(currentSearch(router).job).toBeUndefined();
|
|
348
258
|
});
|
|
349
259
|
|
|
350
|
-
test('
|
|
351
|
-
configureApiClient({fetchImpl: createRunDetailFetch()});
|
|
352
|
-
|
|
353
|
-
renderRunPath(
|
|
354
|
-
`?tab=jobs&job=${BUILD_JOB_ID}&step=${DEPLOY_STEP_ID}&stepAttempt=${DEPLOY_ATTEMPT_TWO_ID}`,
|
|
355
|
-
);
|
|
356
|
-
|
|
357
|
-
const deployJob = await screen.findByRole('button', {name: DEPLOY_JOB_BUTTON_NAME});
|
|
358
|
-
const deployAttempt = await screen.findByRole('button', {
|
|
359
|
-
name: 'deploy, Running, attempt 2',
|
|
360
|
-
});
|
|
361
|
-
|
|
362
|
-
expect(deployJob).toHaveAttribute('aria-expanded', 'true');
|
|
363
|
-
expect(deployAttempt).toHaveAttribute('aria-expanded', 'true');
|
|
364
|
-
expect(await screen.findByText('attempt two log')).toBeInTheDocument();
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
test('selecting a job writes job search state and clears stale step state', async () => {
|
|
260
|
+
test('selecting a job opens its dedicated page and clears stale step state', async () => {
|
|
368
261
|
const user = userEvent.setup();
|
|
369
262
|
configureApiClient({fetchImpl: createRunDetailFetch()});
|
|
370
|
-
const {router} = renderRunPath(
|
|
371
|
-
`?tab=jobs&step=${DEPLOY_STEP_ID}&stepAttempt=${DEPLOY_ATTEMPT_TWO_ID}&runAttempt=1`,
|
|
372
|
-
);
|
|
263
|
+
const {router} = renderRunPath(`?runAttempt=1`);
|
|
373
264
|
const initialHistoryLength = router.history.length;
|
|
374
265
|
|
|
375
266
|
await user.click(await screen.findByRole('button', {name: BUILD_JOB_BUTTON_NAME}));
|
|
376
267
|
|
|
377
|
-
await waitFor(() =>
|
|
378
|
-
expect(
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
expect(router.history.length).toBe(initialHistoryLength);
|
|
382
|
-
expect(currentSearch(router).step).toBeUndefined();
|
|
383
|
-
expect(currentSearch(router).stepAttempt).toBeUndefined();
|
|
384
|
-
expect(screen.getByRole('button', {name: 'checkout, Succeeded, attempt 1'})).toHaveAttribute(
|
|
385
|
-
'aria-expanded',
|
|
386
|
-
'false',
|
|
387
|
-
);
|
|
388
|
-
});
|
|
389
|
-
|
|
390
|
-
test('selecting an attempt writes job, step, and attempt search state', async () => {
|
|
391
|
-
const user = userEvent.setup();
|
|
392
|
-
configureApiClient({fetchImpl: createRunDetailFetch()});
|
|
393
|
-
const {router} = renderRunPath(`?tab=jobs&job=${DEPLOY_JOB_ID}`);
|
|
394
|
-
|
|
395
|
-
await user.click(await screen.findByRole('button', {name: 'deploy, Running, attempt 2'}));
|
|
396
|
-
|
|
397
|
-
await waitFor(() => {
|
|
398
|
-
expect(currentSearch(router)).toMatchObject({
|
|
399
|
-
job: DEPLOY_JOB_ID,
|
|
400
|
-
step: DEPLOY_STEP_ID,
|
|
401
|
-
stepAttempt: DEPLOY_ATTEMPT_TWO_ID,
|
|
402
|
-
});
|
|
403
|
-
});
|
|
404
|
-
});
|
|
405
|
-
|
|
406
|
-
test('selecting a listening execution writes job execution search state and scopes step selection', async () => {
|
|
407
|
-
const user = userEvent.setup();
|
|
408
|
-
configureApiClient({
|
|
409
|
-
fetchImpl: createRunDetailFetch({details: {[RUN_ID]: retryRunDetailDto()}}),
|
|
410
|
-
});
|
|
411
|
-
const {router} = renderRunPath(`?tab=jobs&job=${DEPLOY_JOB_ID}`);
|
|
412
|
-
|
|
413
|
-
await user.click(
|
|
414
|
-
await screen.findByRole('button', {
|
|
415
|
-
name: 'Switch job execution, currently execution 2: deploy review #2',
|
|
416
|
-
}),
|
|
417
|
-
);
|
|
418
|
-
await user.click(
|
|
419
|
-
screen.getByRole('menuitem', {
|
|
420
|
-
name: EXECUTION_ONE_MENU_ITEM,
|
|
421
|
-
}),
|
|
422
|
-
);
|
|
423
|
-
|
|
424
|
-
await waitFor(() => {
|
|
425
|
-
expect(currentSearch(router)).toMatchObject({
|
|
426
|
-
job: DEPLOY_JOB_ID,
|
|
427
|
-
jobExecution: DEPLOY_EXECUTION_ONE_ID,
|
|
428
|
-
});
|
|
429
|
-
});
|
|
430
|
-
expect(screen.getByRole('button', {name: 'deploy, Failed, attempt 1'})).toBeInTheDocument();
|
|
431
|
-
expect(screen.getAllByText('deploy review #1')).not.toHaveLength(0);
|
|
432
|
-
|
|
433
|
-
await user.click(screen.getByRole('button', {name: 'deploy, Failed, attempt 1'}));
|
|
434
|
-
|
|
435
|
-
await waitFor(() => {
|
|
436
|
-
expect(currentSearch(router)).toMatchObject({
|
|
437
|
-
job: DEPLOY_JOB_ID,
|
|
438
|
-
jobExecution: DEPLOY_EXECUTION_ONE_ID,
|
|
439
|
-
step: DEPLOY_STEP_ID,
|
|
440
|
-
stepAttempt: DEPLOY_ATTEMPT_ONE_ID,
|
|
441
|
-
});
|
|
442
|
-
});
|
|
443
|
-
expect(await screen.findByText('attempt one log')).toBeInTheDocument();
|
|
444
|
-
});
|
|
445
|
-
|
|
446
|
-
test('collapsing an attempt removes step and attempt while preserving job', async () => {
|
|
447
|
-
const user = userEvent.setup();
|
|
448
|
-
configureApiClient({fetchImpl: createRunDetailFetch()});
|
|
449
|
-
const {router} = renderRunPath(
|
|
450
|
-
`?tab=jobs&step=${DEPLOY_STEP_ID}&stepAttempt=${DEPLOY_ATTEMPT_TWO_ID}`,
|
|
268
|
+
await waitFor(() =>
|
|
269
|
+
expect(router.state.location.pathname).toBe(
|
|
270
|
+
`/w/${PROJECT_TEST_WSLUG}/p/project/runs/${RUN_ID}/jobs/${BUILD_JOB_ID}`,
|
|
271
|
+
),
|
|
451
272
|
);
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
name: 'deploy, Running, attempt 2',
|
|
455
|
-
});
|
|
456
|
-
await user.click(deployAttempt);
|
|
457
|
-
|
|
458
|
-
await waitFor(() => {
|
|
459
|
-
expect(currentSearch(router)).toMatchObject({job: DEPLOY_JOB_ID});
|
|
460
|
-
});
|
|
273
|
+
expect(router.history.length).toBe(initialHistoryLength + 1);
|
|
274
|
+
expect(currentSearch(router).runAttempt).toBe('1');
|
|
461
275
|
expect(currentSearch(router).step).toBeUndefined();
|
|
462
276
|
expect(currentSearch(router).stepAttempt).toBeUndefined();
|
|
463
|
-
expect(deployAttempt).toHaveAttribute('aria-expanded', 'false');
|
|
464
277
|
});
|
|
465
278
|
|
|
466
279
|
test('run list links navigate to detail and back restores list filters', async () => {
|
|
@@ -502,21 +315,30 @@ describe('WorkflowRunPages', () => {
|
|
|
502
315
|
function renderRunsPath(search = '') {
|
|
503
316
|
return renderProjectPage(
|
|
504
317
|
`/w/${PROJECT_TEST_WSLUG}/p/project/runs${search}`,
|
|
505
|
-
({workflowRunId, search}) =>
|
|
506
|
-
workflowRunId ? (
|
|
318
|
+
({workflowRunId, jobId, search}) =>
|
|
319
|
+
workflowRunId && jobId ? (
|
|
320
|
+
<WorkflowJobDetailPage
|
|
321
|
+
projectId={PROJECT_ID}
|
|
322
|
+
workspaceSlug={PROJECT_TEST_WSLUG}
|
|
323
|
+
projectSlug="project"
|
|
324
|
+
workflowRunId={workflowRunId}
|
|
325
|
+
jobId={jobId}
|
|
326
|
+
search={search as WorkflowJobSearch}
|
|
327
|
+
/>
|
|
328
|
+
) : workflowRunId ? (
|
|
507
329
|
<WorkflowRunDetailPage
|
|
508
330
|
projectId={PROJECT_ID}
|
|
509
331
|
workspaceSlug={PROJECT_TEST_WSLUG}
|
|
510
332
|
projectSlug="project"
|
|
511
333
|
workflowRunId={workflowRunId}
|
|
512
|
-
search={search}
|
|
334
|
+
search={search as WorkflowRunsSearch}
|
|
513
335
|
/>
|
|
514
336
|
) : (
|
|
515
337
|
<WorkflowRunsPage
|
|
516
338
|
projectId={PROJECT_ID}
|
|
517
339
|
workspaceSlug={PROJECT_TEST_WSLUG}
|
|
518
340
|
projectSlug="project"
|
|
519
|
-
search={search}
|
|
341
|
+
search={search as WorkflowRunsSearch}
|
|
520
342
|
/>
|
|
521
343
|
),
|
|
522
344
|
);
|
|
@@ -525,15 +347,25 @@ function renderRunsPath(search = '') {
|
|
|
525
347
|
function renderRunPath(search = '') {
|
|
526
348
|
return renderProjectPage(
|
|
527
349
|
`/w/${PROJECT_TEST_WSLUG}/p/project/runs/${RUN_ID}${search}`,
|
|
528
|
-
({workflowRunId, search}) =>
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
350
|
+
({workflowRunId, jobId, search}) =>
|
|
351
|
+
workflowRunId && jobId ? (
|
|
352
|
+
<WorkflowJobDetailPage
|
|
353
|
+
projectId={PROJECT_ID}
|
|
354
|
+
workspaceSlug={PROJECT_TEST_WSLUG}
|
|
355
|
+
projectSlug="project"
|
|
356
|
+
workflowRunId={workflowRunId}
|
|
357
|
+
jobId={jobId}
|
|
358
|
+
search={search as WorkflowJobSearch}
|
|
359
|
+
/>
|
|
360
|
+
) : (
|
|
361
|
+
<WorkflowRunDetailPage
|
|
362
|
+
projectId={PROJECT_ID}
|
|
363
|
+
workspaceSlug={PROJECT_TEST_WSLUG}
|
|
364
|
+
projectSlug="project"
|
|
365
|
+
workflowRunId={workflowRunId}
|
|
366
|
+
search={search as WorkflowRunsSearch}
|
|
367
|
+
/>
|
|
368
|
+
),
|
|
537
369
|
);
|
|
538
370
|
}
|
|
539
371
|
|
|
@@ -731,93 +563,6 @@ function defaultRunDetailDto(
|
|
|
731
563
|
});
|
|
732
564
|
}
|
|
733
565
|
|
|
734
|
-
function retryRunDetailDto(): WorkflowRunDetailResponseDto {
|
|
735
|
-
return defaultRunDetailDto({
|
|
736
|
-
jobs: [
|
|
737
|
-
workflowJobDto({
|
|
738
|
-
id: BUILD_JOB_ID,
|
|
739
|
-
run_attempt_id: RUN_ID,
|
|
740
|
-
name: 'build',
|
|
741
|
-
status: 'succeeded',
|
|
742
|
-
steps: [
|
|
743
|
-
workflowStepDto({
|
|
744
|
-
id: BUILD_STEP_ID,
|
|
745
|
-
name: 'checkout',
|
|
746
|
-
status: 'succeeded',
|
|
747
|
-
attempts: [
|
|
748
|
-
workflowStepAttemptDto({
|
|
749
|
-
id: BUILD_ATTEMPT_ID,
|
|
750
|
-
step_id: BUILD_STEP_ID,
|
|
751
|
-
status: 'succeeded',
|
|
752
|
-
}),
|
|
753
|
-
],
|
|
754
|
-
}),
|
|
755
|
-
],
|
|
756
|
-
}),
|
|
757
|
-
workflowJobDto({
|
|
758
|
-
id: DEPLOY_JOB_ID,
|
|
759
|
-
run_attempt_id: RUN_ID,
|
|
760
|
-
name: 'deploy',
|
|
761
|
-
mode: 'listening',
|
|
762
|
-
status: 'running',
|
|
763
|
-
listener_status: 'listening',
|
|
764
|
-
position: 1,
|
|
765
|
-
dependencies: ['build'],
|
|
766
|
-
job_executions: [
|
|
767
|
-
workflowJobExecutionDto({
|
|
768
|
-
id: DEPLOY_EXECUTION_ONE_ID,
|
|
769
|
-
job_id: DEPLOY_JOB_ID,
|
|
770
|
-
sequence: 1,
|
|
771
|
-
name: 'deploy review #1',
|
|
772
|
-
status: 'failed',
|
|
773
|
-
started_at: '2026-05-07T01:01:00.000Z',
|
|
774
|
-
finished_at: '2026-05-07T01:02:00.000Z',
|
|
775
|
-
steps: [
|
|
776
|
-
workflowStepDto({
|
|
777
|
-
id: DEPLOY_STEP_ID,
|
|
778
|
-
name: 'deploy',
|
|
779
|
-
status: 'failed',
|
|
780
|
-
attempts: [
|
|
781
|
-
workflowStepAttemptDto({
|
|
782
|
-
id: DEPLOY_ATTEMPT_ONE_ID,
|
|
783
|
-
step_id: DEPLOY_STEP_ID,
|
|
784
|
-
status: 'failed',
|
|
785
|
-
exit_code: 1,
|
|
786
|
-
}),
|
|
787
|
-
],
|
|
788
|
-
}),
|
|
789
|
-
],
|
|
790
|
-
}),
|
|
791
|
-
workflowJobExecutionDto({
|
|
792
|
-
id: DEPLOY_EXECUTION_TWO_ID,
|
|
793
|
-
job_id: DEPLOY_JOB_ID,
|
|
794
|
-
sequence: 2,
|
|
795
|
-
name: 'deploy review #2',
|
|
796
|
-
status: 'running',
|
|
797
|
-
started_at: '2026-05-07T01:03:00.000Z',
|
|
798
|
-
steps: [
|
|
799
|
-
workflowStepDto({
|
|
800
|
-
id: DEPLOY_RETRY_STEP_ID,
|
|
801
|
-
name: 'deploy retry',
|
|
802
|
-
status: 'running',
|
|
803
|
-
attempts: [
|
|
804
|
-
workflowStepAttemptDto({
|
|
805
|
-
id: DEPLOY_ATTEMPT_TWO_ID,
|
|
806
|
-
step_id: DEPLOY_RETRY_STEP_ID,
|
|
807
|
-
status: 'running',
|
|
808
|
-
exit_code: null,
|
|
809
|
-
finished_at: null,
|
|
810
|
-
}),
|
|
811
|
-
],
|
|
812
|
-
}),
|
|
813
|
-
],
|
|
814
|
-
}),
|
|
815
|
-
],
|
|
816
|
-
}),
|
|
817
|
-
],
|
|
818
|
-
});
|
|
819
|
-
}
|
|
820
|
-
|
|
821
566
|
function currentSearch({state}: ReturnType<typeof renderRunPath>['router']) {
|
|
822
567
|
return state.location.search as Record<string, unknown>;
|
|
823
568
|
}
|