@shipfox/client-workflows 12.0.2 → 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/preview.tsx +3 -3
- package/.storybook/workspace-source.ts +31 -0
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +79 -0
- package/dist/components/job-graph/job-duration-format.d.ts +2 -2
- package/dist/components/job-graph/job-duration-format.d.ts.map +1 -1
- package/dist/components/job-graph/job-duration-format.js +4 -2
- package/dist/components/job-graph/job-duration-format.js.map +1 -1
- 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.d.ts +1 -1
- package/dist/components/job-graph/job-node.d.ts.map +1 -1
- package/dist/components/job-graph/job-node.js +10 -9
- 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/step-list/step-list.d.ts +2 -2
- package/dist/components/step-list/step-list.d.ts.map +1 -1
- package/dist/components/step-list/step-list.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-list/job-status-strip.d.ts +21 -0
- package/dist/components/workflow-run-list/job-status-strip.d.ts.map +1 -0
- package/dist/components/workflow-run-list/job-status-strip.js +185 -0
- package/dist/components/workflow-run-list/job-status-strip.js.map +1 -0
- package/dist/components/workflow-run-list/run-display.d.ts +27 -3
- package/dist/components/workflow-run-list/run-display.d.ts.map +1 -1
- package/dist/components/workflow-run-list/run-display.js +78 -7
- package/dist/components/workflow-run-list/run-display.js.map +1 -1
- package/dist/components/workflow-run-list/types.d.ts +23 -24
- package/dist/components/workflow-run-list/types.d.ts.map +1 -1
- package/dist/components/workflow-run-list/types.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-filter-menu.d.ts +22 -0
- package/dist/components/workflow-run-list/workflow-run-filter-menu.d.ts.map +1 -0
- package/dist/components/workflow-run-list/workflow-run-filter-menu.js +68 -0
- package/dist/components/workflow-run-list/workflow-run-filter-menu.js.map +1 -0
- package/dist/components/workflow-run-list/workflow-run-filters.d.ts +18 -0
- package/dist/components/workflow-run-list/workflow-run-filters.d.ts.map +1 -0
- package/dist/components/workflow-run-list/workflow-run-filters.js +236 -0
- package/dist/components/workflow-run-list/workflow-run-filters.js.map +1 -0
- package/dist/components/workflow-run-list/workflow-run-list-content.d.ts +8 -4
- package/dist/components/workflow-run-list/workflow-run-list-content.d.ts.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-content.js +40 -12
- package/dist/components/workflow-run-list/workflow-run-list-content.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-states.d.ts +29 -2
- package/dist/components/workflow-run-list/workflow-run-list-states.d.ts.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-states.js +103 -44
- package/dist/components/workflow-run-list/workflow-run-list-states.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-view.d.ts +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-view.d.ts.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-view.js +60 -43
- package/dist/components/workflow-run-list/workflow-run-list-view.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list.d.ts +1 -1
- package/dist/components/workflow-run-list/workflow-run-list.d.ts.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list.js +20 -8
- package/dist/components/workflow-run-list/workflow-run-list.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-row.d.ts +19 -9
- package/dist/components/workflow-run-list/workflow-run-row.d.ts.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-row.js +179 -112
- package/dist/components/workflow-run-list/workflow-run-row.js.map +1 -1
- package/dist/components/workflow-run-number-label.d.ts +15 -0
- package/dist/components/workflow-run-number-label.d.ts.map +1 -0
- package/dist/components/workflow-run-number-label.js +41 -0
- package/dist/components/workflow-run-number-label.js.map +1 -0
- package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.d.ts +3 -3
- package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.d.ts.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js +10 -9
- 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 +4 -9
- package/dist/components/workflow-run-summary/workflow-run-summary.d.ts.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-summary.js +107 -74
- 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/agent-config-failure-callout.d.ts +2 -2
- package/dist/components/workflow-run-view/agent-config-failure-callout.d.ts.map +1 -1
- package/dist/components/workflow-run-view/agent-config-failure-callout.js +4 -4
- package/dist/components/workflow-run-view/agent-config-failure-callout.js.map +1 -1
- package/dist/components/workflow-run-view/job-card.d.ts +2 -2
- package/dist/components/workflow-run-view/job-card.d.ts.map +1 -1
- package/dist/components/workflow-run-view/job-card.js +51 -32
- package/dist/components/workflow-run-view/job-card.js.map +1 -1
- package/dist/components/workflow-run-view/job-execution-switcher.d.ts +1 -1
- package/dist/components/workflow-run-view/job-execution-switcher.d.ts.map +1 -1
- package/dist/components/workflow-run-view/job-execution-switcher.js +20 -8
- package/dist/components/workflow-run-view/job-execution-switcher.js.map +1 -1
- 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 +10 -5
- package/dist/components/workflow-run-view/workflow-run-view.d.ts.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-view.js +136 -85
- 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/components/workflow-status/status-visuals.d.ts +4 -4
- package/dist/components/workflow-status/status-visuals.d.ts.map +1 -1
- package/dist/components/workflow-status/status-visuals.js +7 -0
- package/dist/components/workflow-status/status-visuals.js.map +1 -1
- package/dist/components/workflow-status/workflow-status-icon.d.ts +3 -4
- package/dist/components/workflow-status/workflow-status-icon.d.ts.map +1 -1
- package/dist/components/workflow-status/workflow-status-icon.js +6 -4
- package/dist/components/workflow-status/workflow-status-icon.js.map +1 -1
- package/dist/core/entities/job-execution.d.ts +10 -0
- package/dist/core/entities/job-execution.d.ts.map +1 -1
- package/dist/core/entities/job-execution.js +11 -0
- package/dist/core/entities/job-execution.js.map +1 -1
- package/dist/core/entities/job.d.ts +4 -2
- package/dist/core/entities/job.d.ts.map +1 -1
- package/dist/core/entities/job.js +8 -1
- package/dist/core/entities/job.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/entities/workflow-run.d.ts +52 -4
- package/dist/core/entities/workflow-run.d.ts.map +1 -1
- package/dist/core/entities/workflow-run.js +22 -3
- package/dist/core/entities/workflow-run.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/core/workflow-run.d.ts +6 -6
- 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 +7 -7
- package/dist/feature.js +5 -5
- package/dist/feature.js.map +1 -1
- package/dist/hooks/api/workflow-run-mapper.d.ts +4 -3
- package/dist/hooks/api/workflow-run-mapper.d.ts.map +1 -1
- package/dist/hooks/api/workflow-run-mapper.js +31 -3
- package/dist/hooks/api/workflow-run-mapper.js.map +1 -1
- package/dist/hooks/api/workflow-runs.d.ts +4 -4
- package/dist/hooks/api/workflow-runs.d.ts.map +1 -1
- package/dist/hooks/api/workflow-runs.js +12 -4
- package/dist/hooks/api/workflow-runs.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/pages/project-workflows-page.js +46 -1
- package/dist/pages/project-workflows-page.js.map +1 -1
- package/dist/pages/workflow-run-detail-page.d.ts +11 -0
- package/dist/pages/workflow-run-detail-page.d.ts.map +1 -0
- package/dist/pages/workflow-run-detail-page.js +52 -0
- package/dist/pages/workflow-run-detail-page.js.map +1 -0
- package/dist/pages/workflow-run-list-page.d.ts +10 -0
- package/dist/pages/workflow-run-list-page.d.ts.map +1 -0
- package/dist/pages/workflow-run-list-page.js +43 -0
- package/dist/pages/workflow-run-list-page.js.map +1 -0
- package/dist/routes/inputs.d.ts +94 -5
- package/dist/routes/inputs.d.ts.map +1 -1
- package/dist/routes/inputs.js +199 -13
- package/dist/routes/inputs.js.map +1 -1
- package/dist/routes/project-route.d.ts +6 -0
- package/dist/routes/project-route.d.ts.map +1 -0
- package/dist/routes/project-route.js +25 -0
- package/dist/routes/project-route.js.map +1 -0
- package/dist/routes/run-detail.d.ts.map +1 -1
- package/dist/routes/run-detail.js +12 -7
- package/dist/routes/run-detail.js.map +1 -1
- package/dist/routes/runs.d.ts.map +1 -1
- package/dist/routes/runs.js +11 -6
- package/dist/routes/runs.js.map +1 -1
- package/dist/routes/workflows.d.ts.map +1 -1
- package/dist/routes/workflows.js +6 -5
- package/dist/routes/workflows.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/src/components/job-graph/job-duration-format.ts +11 -2
- 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.test.tsx +19 -8
- package/src/components/job-graph/job-graph-view.tsx +6 -3
- package/src/components/job-graph/job-graph.stories.tsx +24 -20
- package/src/components/job-graph/job-node.stories.tsx +11 -6
- package/src/components/job-graph/job-node.test.tsx +82 -12
- package/src/components/job-graph/job-node.tsx +22 -15
- package/src/components/job-graph/types.ts +5 -1
- package/src/components/step-list/step-list.stories.tsx +2 -3
- package/src/components/step-list/step-list.tsx +3 -2
- package/src/components/workflow-run-duration-label.tsx +1 -1
- package/src/components/workflow-run-list/job-status-strip.tsx +189 -0
- package/src/components/workflow-run-list/run-display.test.ts +169 -30
- package/src/components/workflow-run-list/run-display.ts +116 -9
- package/src/components/workflow-run-list/types.ts +21 -17
- package/src/components/workflow-run-list/workflow-run-filter-menu.tsx +100 -0
- package/src/components/workflow-run-list/workflow-run-filters.tsx +243 -0
- package/src/components/workflow-run-list/workflow-run-list-content.tsx +44 -16
- package/src/components/workflow-run-list/workflow-run-list-states.tsx +128 -27
- package/src/components/workflow-run-list/workflow-run-list-view.test.tsx +441 -104
- package/src/components/workflow-run-list/workflow-run-list-view.tsx +73 -43
- package/src/components/workflow-run-list/workflow-run-list.stories.tsx +140 -20
- package/src/components/workflow-run-list/workflow-run-list.tsx +20 -10
- package/src/components/workflow-run-list/workflow-run-row.tsx +173 -106
- package/src/components/workflow-run-number-label.test.tsx +45 -0
- package/src/components/workflow-run-number-label.tsx +47 -0
- package/src/components/workflow-run-summary/workflow-run-attempt-switcher.test.tsx +7 -8
- package/src/components/workflow-run-summary/workflow-run-attempt-switcher.tsx +15 -14
- package/src/components/workflow-run-summary/workflow-run-summary.stories.tsx +29 -38
- package/src/components/workflow-run-summary/workflow-run-summary.test.tsx +30 -24
- package/src/components/workflow-run-summary/workflow-run-summary.tsx +102 -77
- 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/agent-config-failure-callout.stories.tsx +2 -3
- package/src/components/workflow-run-view/agent-config-failure-callout.tsx +4 -4
- package/src/components/workflow-run-view/job-card.stories.tsx +11 -10
- package/src/components/workflow-run-view/job-card.test.tsx +115 -0
- package/src/components/workflow-run-view/job-card.tsx +74 -35
- package/src/components/workflow-run-view/job-execution-switcher.tsx +31 -9
- 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 +152 -94
- package/src/components/workflow-run-view/workflow-run-view.tsx +219 -95
- 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/components/workflow-status/status-visuals.test.ts +9 -0
- package/src/components/workflow-status/status-visuals.ts +6 -4
- package/src/components/workflow-status/workflow-status-icon.stories.tsx +10 -2
- package/src/components/workflow-status/workflow-status-icon.test.tsx +18 -0
- package/src/components/workflow-status/workflow-status-icon.tsx +17 -24
- package/src/core/entities/job-execution.ts +22 -0
- package/src/core/entities/job-status.test.ts +104 -0
- package/src/core/entities/job.ts +18 -3
- package/src/core/entities/step.ts +4 -0
- package/src/core/entities/workflow-run.ts +76 -7
- package/src/core/workflow-run-tabs.ts +8 -0
- package/src/core/workflow-run.test.ts +24 -9
- package/src/core/workflow-run.ts +17 -2
- package/src/feature.ts +5 -5
- package/src/hooks/api/workflow-run-mapper.ts +30 -3
- package/src/hooks/api/workflow-runs.test.tsx +2 -0
- package/src/hooks/api/workflow-runs.ts +12 -7
- package/src/index.ts +7 -2
- package/src/page-harness-budget.test.ts +1 -1
- package/src/pages/project-workflows-page.test.tsx +59 -5
- package/src/pages/project-workflows-page.tsx +34 -1
- package/src/pages/workflow-run-detail-page.tsx +72 -0
- package/src/pages/workflow-run-list-page.tsx +65 -0
- package/src/pages/workflow-run-pages.test.tsx +823 -0
- package/src/routes/inputs.test.ts +240 -12
- package/src/routes/inputs.ts +215 -11
- package/src/routes/project-route.tsx +25 -0
- package/src/routes/run-detail.tsx +15 -8
- package/src/routes/runs.tsx +14 -7
- package/src/routes/workflows.tsx +5 -4
- package/src/storybook-config.test.ts +27 -0
- package/test/fixtures/workflow-run.ts +76 -7
- package/test/pages.tsx +18 -8
- package/test/render.tsx +8 -2
- package/tsconfig.build.tsbuildinfo +1 -1
- package/tsconfig.test.json +7 -1
- package/dist/components/workflow-run-list/workflow-run-list-header.d.ts +0 -10
- package/dist/components/workflow-run-list/workflow-run-list-header.d.ts.map +0 -1
- package/dist/components/workflow-run-list/workflow-run-list-header.js +0 -55
- package/dist/components/workflow-run-list/workflow-run-list-header.js.map +0 -1
- package/dist/pages/workflow-run-first-time-use.d.ts +0 -6
- package/dist/pages/workflow-run-first-time-use.d.ts.map +0 -1
- package/dist/pages/workflow-run-first-time-use.js +0 -17
- package/dist/pages/workflow-run-first-time-use.js.map +0 -1
- package/dist/pages/workflow-run-page.d.ts +0 -10
- package/dist/pages/workflow-run-page.d.ts.map +0 -1
- package/dist/pages/workflow-run-page.js +0 -90
- package/dist/pages/workflow-run-page.js.map +0 -1
- package/src/components/workflow-run-list/workflow-run-list-header.tsx +0 -53
- package/src/pages/workflow-run-first-time-use.tsx +0 -17
- package/src/pages/workflow-run-page.test.tsx +0 -519
- package/src/pages/workflow-run-page.tsx +0 -94
package/src/feature.ts
CHANGED
|
@@ -5,14 +5,14 @@ export const workflowsNavigation = [
|
|
|
5
5
|
id: 'nav.runs',
|
|
6
6
|
scope: 'project',
|
|
7
7
|
label: 'Runs',
|
|
8
|
-
to: '/
|
|
8
|
+
to: '/w/$workspaceSlug/p/$projectSlug/runs',
|
|
9
9
|
order: 100,
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
id: 'nav.workflows',
|
|
13
13
|
scope: 'project',
|
|
14
14
|
label: 'Workflows',
|
|
15
|
-
to: '/
|
|
15
|
+
to: '/w/$workspaceSlug/p/$projectSlug/workflows',
|
|
16
16
|
order: 200,
|
|
17
17
|
},
|
|
18
18
|
] as const satisfies readonly NavTabEntry[];
|
|
@@ -21,17 +21,17 @@ export const workflowsFeature = defineClientFeature({
|
|
|
21
21
|
id: 'shipfox.workflows',
|
|
22
22
|
routes: [
|
|
23
23
|
{
|
|
24
|
-
path: '/
|
|
24
|
+
path: '/w/$workspaceSlug/p/$projectSlug/workflows',
|
|
25
25
|
parent: 'projectLayout',
|
|
26
26
|
impl: '@shipfox/client-workflows/routes/workflows',
|
|
27
27
|
},
|
|
28
28
|
{
|
|
29
|
-
path: '/
|
|
29
|
+
path: '/w/$workspaceSlug/p/$projectSlug/runs',
|
|
30
30
|
parent: 'projectLayout',
|
|
31
31
|
impl: '@shipfox/client-workflows/routes/runs',
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
|
-
path: '/
|
|
34
|
+
path: '/w/$workspaceSlug/p/$projectSlug/runs/$workflowRunId',
|
|
35
35
|
parent: 'projectLayout',
|
|
36
36
|
impl: '@shipfox/client-workflows/routes/run-detail',
|
|
37
37
|
},
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
WorkflowRunDetailResponseDto,
|
|
8
8
|
WorkflowRunJobDetailDto,
|
|
9
9
|
WorkflowRunJobExecutionDetailDto,
|
|
10
|
+
WorkflowRunListItemDto,
|
|
10
11
|
WorkflowRunListResponseDto,
|
|
11
12
|
WorkflowRunResponseDto,
|
|
12
13
|
WorkflowRunStepDetailDto,
|
|
@@ -25,7 +26,7 @@ import {
|
|
|
25
26
|
type WorkflowRunDetail,
|
|
26
27
|
type WorkflowRunListItem,
|
|
27
28
|
type WorkflowRunListPage,
|
|
28
|
-
|
|
29
|
+
type WorkflowRunRecord,
|
|
29
30
|
workflowRunTriggerDisplayLabel,
|
|
30
31
|
workflowRunTriggerLabel,
|
|
31
32
|
} from '#core/workflow-run.js';
|
|
@@ -35,7 +36,9 @@ export function toWorkflowRun(dto: WorkflowRunResponseDto): WorkflowRun {
|
|
|
35
36
|
id: dto.id,
|
|
36
37
|
projectId: dto.project_id,
|
|
37
38
|
definitionId: dto.definition_id,
|
|
39
|
+
number: dto.number,
|
|
38
40
|
name: dto.name,
|
|
41
|
+
workflowName: dto.workflow_name,
|
|
39
42
|
currentAttempt: dto.current_attempt,
|
|
40
43
|
triggerProvider: dto.trigger_provider,
|
|
41
44
|
triggerSource: dto.trigger_source,
|
|
@@ -49,13 +52,13 @@ export function toWorkflowRun(dto: WorkflowRunResponseDto): WorkflowRun {
|
|
|
49
52
|
triggerEvent: dto.trigger_event,
|
|
50
53
|
}),
|
|
51
54
|
triggerPayload: dto.trigger_payload,
|
|
55
|
+
triggerReference: dto.trigger_reference,
|
|
52
56
|
inputs: dto.inputs ?? null,
|
|
53
57
|
sourceSnapshot: dto.source_snapshot
|
|
54
58
|
? {content: dto.source_snapshot.content, format: dto.source_snapshot.format}
|
|
55
59
|
: null,
|
|
56
60
|
createdAt: dto.created_at,
|
|
57
61
|
updatedAt: dto.updated_at,
|
|
58
|
-
shortId: workflowRunShortId(dto.id),
|
|
59
62
|
isTemporary: dto.id.startsWith('temp-'),
|
|
60
63
|
};
|
|
61
64
|
}
|
|
@@ -73,7 +76,7 @@ export function toWorkflowRunAttempt(dto: WorkflowRunAttemptDto): WorkflowRunAtt
|
|
|
73
76
|
});
|
|
74
77
|
}
|
|
75
78
|
|
|
76
|
-
export function
|
|
79
|
+
export function toWorkflowRunRecord(dto: WorkflowRunResponseDto): WorkflowRunRecord {
|
|
77
80
|
return {
|
|
78
81
|
...toWorkflowRun(dto),
|
|
79
82
|
status: dto.status,
|
|
@@ -89,6 +92,26 @@ export function toWorkflowRunListItem(dto: WorkflowRunResponseDto): WorkflowRunL
|
|
|
89
92
|
};
|
|
90
93
|
}
|
|
91
94
|
|
|
95
|
+
export function toWorkflowRunListItem(dto: WorkflowRunListItemDto): WorkflowRunListItem {
|
|
96
|
+
const statusCounts = dto.job_status_counts.map(({status, count}) => ({status, count}));
|
|
97
|
+
return {
|
|
98
|
+
...toWorkflowRunRecord(dto),
|
|
99
|
+
jobs: {
|
|
100
|
+
preview: dto.jobs.map((job) => ({
|
|
101
|
+
id: job.id,
|
|
102
|
+
key: job.key,
|
|
103
|
+
name: job.name,
|
|
104
|
+
status: job.status,
|
|
105
|
+
position: job.position,
|
|
106
|
+
})),
|
|
107
|
+
statusCounts,
|
|
108
|
+
// Derived rather than sent: the counts already cover every job, and a separate total
|
|
109
|
+
// would be a second source of truth that could disagree with them.
|
|
110
|
+
total: statusCounts.reduce((sum, entry) => sum + entry.count, 0),
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
92
115
|
export function toWorkflowRunListPage(dto: WorkflowRunListResponseDto): WorkflowRunListPage {
|
|
93
116
|
return {
|
|
94
117
|
runs: dto.runs.map(toWorkflowRunListItem),
|
|
@@ -220,6 +243,10 @@ function toWorkflowExecutionEvent(dto: WorkflowExecutionEventDto): WorkflowExecu
|
|
|
220
243
|
event: dto.event,
|
|
221
244
|
deliveryId: dto.delivery_id,
|
|
222
245
|
receivedAt: dto.received_at,
|
|
246
|
+
project: dto.project,
|
|
247
|
+
repository: dto.repository,
|
|
248
|
+
ref: dto.ref,
|
|
249
|
+
commit: dto.commit,
|
|
223
250
|
data: dto.data,
|
|
224
251
|
};
|
|
225
252
|
}
|
|
@@ -240,6 +240,8 @@ describe('workflow run API hooks', () => {
|
|
|
240
240
|
expect(cached?.pages[0]?.runs[0]).toMatchObject({
|
|
241
241
|
projectId: PROJECT_ID,
|
|
242
242
|
definitionId: DEFINITION_ID,
|
|
243
|
+
number: null,
|
|
244
|
+
workflowName: 'New run',
|
|
243
245
|
status: 'pending',
|
|
244
246
|
triggerSource: 'manual',
|
|
245
247
|
triggerProvider: null,
|
|
@@ -29,13 +29,14 @@ import {
|
|
|
29
29
|
type WorkflowRunDetail,
|
|
30
30
|
type WorkflowRunListItem,
|
|
31
31
|
type WorkflowRunListPage,
|
|
32
|
+
type WorkflowRunRecord,
|
|
32
33
|
type WorkflowRunStatus,
|
|
33
34
|
} from '#core/workflow-run.js';
|
|
34
35
|
import {
|
|
35
36
|
toWorkflowRunAttempt,
|
|
36
37
|
toWorkflowRunDetail,
|
|
37
|
-
toWorkflowRunListItem,
|
|
38
38
|
toWorkflowRunListPage,
|
|
39
|
+
toWorkflowRunRecord,
|
|
39
40
|
} from './workflow-run-mapper.js';
|
|
40
41
|
|
|
41
42
|
export interface WorkflowRunFilters {
|
|
@@ -250,8 +251,8 @@ async function cancelWorkflowRun({
|
|
|
250
251
|
workflowRunId,
|
|
251
252
|
}: {
|
|
252
253
|
workflowRunId: string;
|
|
253
|
-
}): Promise<
|
|
254
|
-
return
|
|
254
|
+
}): Promise<WorkflowRunRecord> {
|
|
255
|
+
return toWorkflowRunRecord(
|
|
255
256
|
await checkedApiRequest(workflowRunDtoSchema, `/workflows/runs/${workflowRunId}/cancel`, {
|
|
256
257
|
method: 'POST',
|
|
257
258
|
}),
|
|
@@ -264,8 +265,8 @@ export async function rerunWorkflowRun({
|
|
|
264
265
|
}: {
|
|
265
266
|
workflowRunId: string;
|
|
266
267
|
mode: WorkflowRunRerunModeDto;
|
|
267
|
-
}): Promise<
|
|
268
|
-
return
|
|
268
|
+
}): Promise<WorkflowRunRecord> {
|
|
269
|
+
return toWorkflowRunRecord(
|
|
269
270
|
await checkedApiRequest(workflowRunResponseSchema, `/workflows/runs/${workflowRunId}/rerun`, {
|
|
270
271
|
method: 'POST',
|
|
271
272
|
body: {mode} satisfies RerunWorkflowRunBodyDto,
|
|
@@ -338,7 +339,9 @@ function buildTempRun({
|
|
|
338
339
|
id,
|
|
339
340
|
projectId,
|
|
340
341
|
definitionId,
|
|
342
|
+
number: null,
|
|
341
343
|
name,
|
|
344
|
+
workflowName: name,
|
|
342
345
|
status: 'pending',
|
|
343
346
|
currentAttempt: 1,
|
|
344
347
|
latestAttempt: 1,
|
|
@@ -348,12 +351,14 @@ function buildTempRun({
|
|
|
348
351
|
triggerPayload: {source: 'manual', event: 'fire'},
|
|
349
352
|
triggerDisplayLabel: 'fire',
|
|
350
353
|
triggerLabel: 'manual · fire',
|
|
354
|
+
triggerReference: null,
|
|
351
355
|
inputs: null,
|
|
352
356
|
sourceSnapshot: null,
|
|
353
357
|
createdAt,
|
|
354
358
|
updatedAt: createdAt,
|
|
355
|
-
shortId: id.slice(0, 8),
|
|
356
359
|
isTemporary: true,
|
|
360
|
+
// The optimistic row genuinely has no jobs yet: the server has not planned the graph.
|
|
361
|
+
jobs: {preview: [], statusCounts: [], total: 0},
|
|
357
362
|
runAttempt: new WorkflowRunAttemptSummary({
|
|
358
363
|
workflowRunId: id,
|
|
359
364
|
attempt: 1,
|
|
@@ -568,7 +573,7 @@ export function workflowRunAttemptsQueryOptions({
|
|
|
568
573
|
export function useCancelWorkflowRunMutation(run: WorkflowRun | undefined) {
|
|
569
574
|
const queryClient = useQueryClient();
|
|
570
575
|
return useMutation({
|
|
571
|
-
mutationFn: async (): Promise<
|
|
576
|
+
mutationFn: async (): Promise<WorkflowRunRecord> => {
|
|
572
577
|
if (!run) throw new Error('Workflow run is not loaded');
|
|
573
578
|
return await cancelWorkflowRun({workflowRunId: run.id});
|
|
574
579
|
},
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export type {
|
|
2
2
|
AgentConfigIssue,
|
|
3
3
|
JobDisplayDuration,
|
|
4
|
+
JobDisplayStatus,
|
|
4
5
|
JobExecutionDisplayDuration,
|
|
6
|
+
JobExecutionDisplayStatus,
|
|
5
7
|
JobExecutionStatus,
|
|
6
8
|
JobExecutionTime,
|
|
7
9
|
JobStatus,
|
|
@@ -14,6 +16,7 @@ export type {
|
|
|
14
16
|
StepErrorReason,
|
|
15
17
|
StepGateResult,
|
|
16
18
|
StepSourceLocation,
|
|
19
|
+
WorkflowDisplayStatus,
|
|
17
20
|
WorkflowRun,
|
|
18
21
|
WorkflowRunAttempt,
|
|
19
22
|
WorkflowRunDetail,
|
|
@@ -23,13 +26,14 @@ export type {
|
|
|
23
26
|
WorkflowStatus,
|
|
24
27
|
} from '#core/workflow-run.js';
|
|
25
28
|
export {
|
|
29
|
+
deriveJobDisplayStatus,
|
|
30
|
+
deriveJobExecutionDisplayStatus,
|
|
26
31
|
isWorkflowRunTerminal,
|
|
27
32
|
isWorkflowStatus,
|
|
28
33
|
Job,
|
|
29
34
|
JobExecution,
|
|
30
35
|
TERMINAL_WORKFLOW_RUN_STATUSES,
|
|
31
36
|
WORKFLOW_RUN_STATUSES,
|
|
32
|
-
workflowRunShortId,
|
|
33
37
|
workflowRunTriggerLabel,
|
|
34
38
|
} from '#core/workflow-run.js';
|
|
35
39
|
export {
|
|
@@ -47,4 +51,5 @@ export {
|
|
|
47
51
|
workflowRunsQueryKeys,
|
|
48
52
|
} from './hooks/api/workflow-runs.js';
|
|
49
53
|
export {ProjectWorkflowsPage} from './pages/project-workflows-page.js';
|
|
50
|
-
export {
|
|
54
|
+
export {WorkflowRunDetailPage} from './pages/workflow-run-detail-page.js';
|
|
55
|
+
export {WorkflowRunsPage} from './pages/workflow-run-list-page.js';
|
|
@@ -8,7 +8,7 @@ const PAGE_HARNESS_ALLOWLIST = [
|
|
|
8
8
|
'src/components/workflow-run-summary/workflow-run-attempt-switcher.test.tsx',
|
|
9
9
|
'src/components/workflow-run-view/workflow-run-view.test.tsx',
|
|
10
10
|
'src/pages/project-workflows-page.test.tsx',
|
|
11
|
-
'src/pages/workflow-run-
|
|
11
|
+
'src/pages/workflow-run-pages.test.tsx',
|
|
12
12
|
];
|
|
13
13
|
|
|
14
14
|
const srcDir = dirname(fileURLToPath(import.meta.url));
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import {configureApiClient} from '@shipfox/client-api';
|
|
2
2
|
import {fireEvent, screen, waitFor} from '@testing-library/react';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
jsonResponse,
|
|
5
|
+
PROJECT_TEST_WID,
|
|
6
|
+
PROJECT_TEST_WSLUG,
|
|
7
|
+
renderProjectPage,
|
|
8
|
+
} from '#test/pages.js';
|
|
4
9
|
import {ProjectWorkflowsPage} from './project-workflows-page.js';
|
|
5
10
|
|
|
6
11
|
const PROJECT_ID = '44444444-4444-4444-8444-444444444444';
|
|
@@ -54,6 +59,13 @@ describe('ProjectWorkflowsPage', () => {
|
|
|
54
59
|
finished_at: null,
|
|
55
60
|
last_error_code: 'no-workflow-files',
|
|
56
61
|
last_error_message: 'No workflow files found',
|
|
62
|
+
warnings: [
|
|
63
|
+
{
|
|
64
|
+
code: 're-evaluating-command',
|
|
65
|
+
message: 'Workflow data is re-executed as shell code.',
|
|
66
|
+
path: 'jobs.build.steps.0.run',
|
|
67
|
+
},
|
|
68
|
+
],
|
|
57
69
|
},
|
|
58
70
|
}),
|
|
59
71
|
),
|
|
@@ -66,6 +78,47 @@ describe('ProjectWorkflowsPage', () => {
|
|
|
66
78
|
await screen.findByText('No workflow files found under .shipfox/workflows/.'),
|
|
67
79
|
).toBeInTheDocument();
|
|
68
80
|
expect(screen.getByText('Workflow sync failed')).toBeInTheDocument();
|
|
81
|
+
expect(screen.queryByText('Workflow definition warnings')).not.toBeInTheDocument();
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test('shows definition warnings without rendering a sync failure', async () => {
|
|
85
|
+
configureApiClient({
|
|
86
|
+
fetchImpl: createProjectDetailFetch({
|
|
87
|
+
definitions: jsonResponse(
|
|
88
|
+
definitionsDto({
|
|
89
|
+
sync: {
|
|
90
|
+
ref: 'main',
|
|
91
|
+
status: 'succeeded',
|
|
92
|
+
last_sync_at: '2026-05-07T01:00:00.000Z',
|
|
93
|
+
started_at: '2026-05-07T00:59:55.000Z',
|
|
94
|
+
finished_at: '2026-05-07T01:00:00.000Z',
|
|
95
|
+
last_error_code: null,
|
|
96
|
+
last_error_message: null,
|
|
97
|
+
warnings: [
|
|
98
|
+
{
|
|
99
|
+
code: 're-evaluating-command',
|
|
100
|
+
message: 'Workflow data is re-executed as shell code.',
|
|
101
|
+
path: 'jobs.build.steps.0.run',
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
code: 're-evaluating-command',
|
|
105
|
+
message: 'Workflow data is re-executed as shell code.',
|
|
106
|
+
path: 'jobs.build.steps.0.run',
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
}),
|
|
111
|
+
),
|
|
112
|
+
}),
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
renderWorkflowsPage();
|
|
116
|
+
|
|
117
|
+
expect(await screen.findByText('Workflow definition warnings')).toBeInTheDocument();
|
|
118
|
+
expect(screen.getAllByText('Workflow data is re-executed as shell code.')).toHaveLength(2);
|
|
119
|
+
expect(screen.getAllByRole('listitem')).toHaveLength(2);
|
|
120
|
+
expect(screen.getAllByText('jobs.build.steps.0.run')).toHaveLength(2);
|
|
121
|
+
expect(screen.queryByText('Workflow sync failed')).not.toBeInTheDocument();
|
|
69
122
|
});
|
|
70
123
|
|
|
71
124
|
test('opens and closes the definition drawer by clicking the row', async () => {
|
|
@@ -123,10 +176,9 @@ describe('ProjectWorkflowsPage', () => {
|
|
|
123
176
|
});
|
|
124
177
|
|
|
125
178
|
function renderWorkflowsPage() {
|
|
126
|
-
return renderProjectPage(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
);
|
|
179
|
+
return renderProjectPage(`/w/${PROJECT_TEST_WSLUG}/p/project/workflows`, () => (
|
|
180
|
+
<ProjectWorkflowsPage projectId={PROJECT_ID} />
|
|
181
|
+
));
|
|
130
182
|
}
|
|
131
183
|
|
|
132
184
|
function createProjectDetailFetch({
|
|
@@ -174,6 +226,7 @@ function projectDto() {
|
|
|
174
226
|
id: PROJECT_ID,
|
|
175
227
|
workspace_id: PROJECT_TEST_WID,
|
|
176
228
|
name: 'Platform',
|
|
229
|
+
slug: 'platform',
|
|
177
230
|
source: {
|
|
178
231
|
connection_id: CONNECTION_ID,
|
|
179
232
|
external_repository_id: 'platform',
|
|
@@ -238,6 +291,7 @@ function baseDefinitionsDto() {
|
|
|
238
291
|
finished_at: '2026-05-07T01:00:00.000Z',
|
|
239
292
|
last_error_code: null,
|
|
240
293
|
last_error_message: null,
|
|
294
|
+
warnings: [],
|
|
241
295
|
},
|
|
242
296
|
};
|
|
243
297
|
}
|
|
@@ -103,6 +103,7 @@ function ProjectWorkflowsPageInner({projectId}: {projectId: string}) {
|
|
|
103
103
|
/>
|
|
104
104
|
|
|
105
105
|
<WorkflowSyncAlert sync={sync} />
|
|
106
|
+
<WorkflowSyncWarnings sync={sync} />
|
|
106
107
|
|
|
107
108
|
<WorkflowDefinitionsList
|
|
108
109
|
definitions={definitions}
|
|
@@ -214,7 +215,7 @@ function WorkflowDefinitionsList({
|
|
|
214
215
|
// The workflow-name cell holds a `<button>` so the row is
|
|
215
216
|
// keyboard-reachable (Tab focuses, Enter/Space activates
|
|
216
217
|
// via native button semantics). The TableRow itself is no
|
|
217
|
-
// longer clickable
|
|
218
|
+
// longer clickable: a row-level onClick would be invisible
|
|
218
219
|
// to keyboard users and require custom keydown handling.
|
|
219
220
|
// The `group` class on the row still drives the Run button
|
|
220
221
|
// reveal on hover or focus-within.
|
|
@@ -374,6 +375,38 @@ function WorkflowSyncAlert({sync}: {sync: DefinitionSyncSummary | null | undefin
|
|
|
374
375
|
);
|
|
375
376
|
}
|
|
376
377
|
|
|
378
|
+
function WorkflowSyncWarnings({sync}: {sync: DefinitionSyncSummary | null | undefined}) {
|
|
379
|
+
if (sync?.status !== 'succeeded' || sync.warnings.length === 0) return null;
|
|
380
|
+
|
|
381
|
+
const seenKeys = new Map<string, number>();
|
|
382
|
+
const warningItems = sync.warnings.map((warning) => {
|
|
383
|
+
const baseKey = `${warning.code}-${warning.path ?? 'workflow'}-${warning.message}`;
|
|
384
|
+
const occurrence = seenKeys.get(baseKey) ?? 0;
|
|
385
|
+
seenKeys.set(baseKey, occurrence + 1);
|
|
386
|
+
return {key: `${baseKey}-${occurrence}`, warning};
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
return (
|
|
390
|
+
<Callout role="status" type="warning">
|
|
391
|
+
<div className="flex flex-col gap-6">
|
|
392
|
+
<Text size="sm" bold>
|
|
393
|
+
Workflow definition warnings
|
|
394
|
+
</Text>
|
|
395
|
+
<ul className="flex flex-col gap-4">
|
|
396
|
+
{warningItems.map(({key, warning}) => (
|
|
397
|
+
<li key={key}>
|
|
398
|
+
<Text size="sm">{warning.message}</Text>
|
|
399
|
+
{warning.path ? (
|
|
400
|
+
<Code className="text-foreground-neutral-muted">{warning.path}</Code>
|
|
401
|
+
) : null}
|
|
402
|
+
</li>
|
|
403
|
+
))}
|
|
404
|
+
</ul>
|
|
405
|
+
</div>
|
|
406
|
+
</Callout>
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
|
|
377
410
|
function DefinitionSheet({
|
|
378
411
|
definition,
|
|
379
412
|
onOpenChange,
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import {useNavigate} from '@tanstack/react-router';
|
|
2
|
+
import {useCallback} from 'react';
|
|
3
|
+
import {WorkflowRunView} from '#components/workflow-run-view/index.js';
|
|
4
|
+
import type {WorkflowRunSelectionInput} from '#core/workflow-run-url-state.js';
|
|
5
|
+
import {
|
|
6
|
+
validateWorkflowRunsSearch,
|
|
7
|
+
type WorkflowRunsSearch,
|
|
8
|
+
type WorkflowRunTab,
|
|
9
|
+
workflowRunSearchParams,
|
|
10
|
+
workflowRunTab,
|
|
11
|
+
} from '#routes/inputs.js';
|
|
12
|
+
|
|
13
|
+
interface WorkflowRunDetailPageProps {
|
|
14
|
+
projectId: string;
|
|
15
|
+
workspaceSlug: string;
|
|
16
|
+
projectSlug: string;
|
|
17
|
+
workflowRunId?: string | undefined;
|
|
18
|
+
search?: WorkflowRunsSearch;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function WorkflowRunDetailPage({
|
|
22
|
+
projectId,
|
|
23
|
+
workspaceSlug,
|
|
24
|
+
projectSlug,
|
|
25
|
+
workflowRunId,
|
|
26
|
+
search = {},
|
|
27
|
+
}: 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
|
+
return (
|
|
59
|
+
<div className="flex min-h-0 flex-1 overflow-hidden bg-background-neutral-background">
|
|
60
|
+
<WorkflowRunView
|
|
61
|
+
projectId={projectId}
|
|
62
|
+
workspaceSlug={workspaceSlug}
|
|
63
|
+
projectSlug={projectSlug}
|
|
64
|
+
workflowRunId={workflowRunId}
|
|
65
|
+
selection={selection}
|
|
66
|
+
onSelectionChange={onSelectionChange}
|
|
67
|
+
tab={workflowRunTab(search)}
|
|
68
|
+
onTabChange={onTabChange}
|
|
69
|
+
/>
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {useNavigate} from '@tanstack/react-router';
|
|
2
|
+
import {useCallback} from 'react';
|
|
3
|
+
import {WorkflowRunList} from '#components/workflow-run-list/workflow-run-list.js';
|
|
4
|
+
import {
|
|
5
|
+
applyWorkflowRunFilterPatch,
|
|
6
|
+
clearWorkflowRunFilters,
|
|
7
|
+
type WorkflowRunFilterPatch,
|
|
8
|
+
type WorkflowRunsSearch,
|
|
9
|
+
workflowRunSearchParams,
|
|
10
|
+
} from '#routes/inputs.js';
|
|
11
|
+
|
|
12
|
+
interface WorkflowRunsPageProps {
|
|
13
|
+
projectId: string;
|
|
14
|
+
workspaceSlug: string;
|
|
15
|
+
projectSlug: string;
|
|
16
|
+
search?: WorkflowRunsSearch;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const EMPTY_SEARCH: WorkflowRunsSearch = {};
|
|
20
|
+
|
|
21
|
+
export function WorkflowRunsPage({
|
|
22
|
+
projectId,
|
|
23
|
+
workspaceSlug,
|
|
24
|
+
projectSlug,
|
|
25
|
+
search = EMPTY_SEARCH,
|
|
26
|
+
}: WorkflowRunsPageProps) {
|
|
27
|
+
const navigate = useNavigate();
|
|
28
|
+
|
|
29
|
+
// Filter changes replace history instead of pushing it, so Back leaves the list rather than
|
|
30
|
+
// walking every keystroke of a search box.
|
|
31
|
+
const commitSearch = useCallback(
|
|
32
|
+
(next: WorkflowRunsSearch) => {
|
|
33
|
+
navigate({
|
|
34
|
+
search: workflowRunSearchParams(next, {}) as never,
|
|
35
|
+
replace: true,
|
|
36
|
+
});
|
|
37
|
+
},
|
|
38
|
+
[navigate],
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const onFiltersChange = useCallback(
|
|
42
|
+
(patch: WorkflowRunFilterPatch) => commitSearch(applyWorkflowRunFilterPatch(search, patch)),
|
|
43
|
+
[commitSearch, search],
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const onClearFilters = useCallback(
|
|
47
|
+
() => commitSearch(clearWorkflowRunFilters(search)),
|
|
48
|
+
[commitSearch, search],
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<div className="flex min-h-0 flex-1 overflow-hidden bg-background-neutral-base">
|
|
53
|
+
<div className="mx-auto flex min-h-0 w-full max-w-[1120px] flex-1 flex-col px-24 py-24">
|
|
54
|
+
<WorkflowRunList
|
|
55
|
+
projectId={projectId}
|
|
56
|
+
workspaceSlug={workspaceSlug}
|
|
57
|
+
projectSlug={projectSlug}
|
|
58
|
+
search={search}
|
|
59
|
+
onFiltersChange={onFiltersChange}
|
|
60
|
+
onClearFilters={onClearFilters}
|
|
61
|
+
/>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
}
|