@shipfox/client-workflows 0.2.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 +1 -0
- package/.storybook/preview.css +10 -0
- package/.storybook/preview.tsx +97 -0
- package/.swcrc +42 -0
- package/.turbo/turbo-build.log +2 -0
- package/.turbo/turbo-type$colon$emit.log +1 -0
- package/.turbo/turbo-type.log +1 -0
- package/CHANGELOG.md +162 -0
- package/LICENSE +21 -0
- package/dist/components/identifier/identifier.d.ts +6 -0
- package/dist/components/identifier/identifier.d.ts.map +1 -0
- package/dist/components/identifier/identifier.js +144 -0
- package/dist/components/identifier/identifier.js.map +1 -0
- package/dist/components/identifier/index.d.ts +2 -0
- package/dist/components/identifier/index.d.ts.map +1 -0
- package/dist/components/identifier/index.js +3 -0
- package/dist/components/identifier/index.js.map +1 -0
- package/dist/components/job-graph/graph-model.d.ts +27 -0
- package/dist/components/job-graph/graph-model.d.ts.map +1 -0
- package/dist/components/job-graph/graph-model.js +107 -0
- package/dist/components/job-graph/graph-model.js.map +1 -0
- package/dist/components/job-graph/index.d.ts +3 -0
- package/dist/components/job-graph/index.d.ts.map +1 -0
- package/dist/components/job-graph/index.js +3 -0
- package/dist/components/job-graph/index.js.map +1 -0
- package/dist/components/job-graph/job-duration-format.d.ts +4 -0
- package/dist/components/job-graph/job-duration-format.d.ts.map +1 -0
- package/dist/components/job-graph/job-duration-format.js +41 -0
- package/dist/components/job-graph/job-duration-format.js.map +1 -0
- package/dist/components/job-graph/job-duration-label.d.ts +5 -0
- package/dist/components/job-graph/job-duration-label.d.ts.map +1 -0
- package/dist/components/job-graph/job-duration-label.js +33 -0
- package/dist/components/job-graph/job-duration-label.js.map +1 -0
- package/dist/components/job-graph/job-graph-content.d.ts +9 -0
- package/dist/components/job-graph/job-graph-content.d.ts.map +1 -0
- package/dist/components/job-graph/job-graph-content.js +181 -0
- package/dist/components/job-graph/job-graph-content.js.map +1 -0
- package/dist/components/job-graph/job-graph-view.d.ts +11 -0
- package/dist/components/job-graph/job-graph-view.d.ts.map +1 -0
- package/dist/components/job-graph/job-graph-view.js +24 -0
- package/dist/components/job-graph/job-graph-view.js.map +1 -0
- package/dist/components/job-graph/job-graph.d.ts +3 -0
- package/dist/components/job-graph/job-graph.d.ts.map +1 -0
- package/dist/components/job-graph/job-graph.js +21 -0
- package/dist/components/job-graph/job-graph.js.map +1 -0
- package/dist/components/job-graph/job-node.d.ts +16 -0
- package/dist/components/job-graph/job-node.d.ts.map +1 -0
- package/dist/components/job-graph/job-node.js +196 -0
- package/dist/components/job-graph/job-node.js.map +1 -0
- package/dist/components/job-graph/types.d.ts +9 -0
- package/dist/components/job-graph/types.d.ts.map +1 -0
- package/dist/components/job-graph/types.js +3 -0
- package/dist/components/job-graph/types.js.map +1 -0
- package/dist/components/step-list/index.d.ts +3 -0
- package/dist/components/step-list/index.d.ts.map +1 -0
- package/dist/components/step-list/index.js +3 -0
- package/dist/components/step-list/index.js.map +1 -0
- package/dist/components/step-list/step-list-model.d.ts +36 -0
- package/dist/components/step-list/step-list-model.d.ts.map +1 -0
- package/dist/components/step-list/step-list-model.js +135 -0
- package/dist/components/step-list/step-list-model.js.map +1 -0
- package/dist/components/step-list/step-list.d.ts +32 -0
- package/dist/components/step-list/step-list.d.ts.map +1 -0
- package/dist/components/step-list/step-list.js +409 -0
- package/dist/components/step-list/step-list.js.map +1 -0
- package/dist/components/workflow-run-duration-label.d.ts +8 -0
- package/dist/components/workflow-run-duration-label.d.ts.map +1 -0
- package/dist/components/workflow-run-duration-label.js +84 -0
- package/dist/components/workflow-run-duration-label.js.map +1 -0
- package/dist/components/workflow-run-list/index.d.ts +2 -0
- package/dist/components/workflow-run-list/index.d.ts.map +1 -0
- package/dist/components/workflow-run-list/index.js +3 -0
- package/dist/components/workflow-run-list/index.js.map +1 -0
- package/dist/components/workflow-run-list/run-display.d.ts +5 -0
- package/dist/components/workflow-run-list/run-display.d.ts.map +1 -0
- package/dist/components/workflow-run-list/run-display.js +19 -0
- package/dist/components/workflow-run-list/run-display.js.map +1 -0
- package/dist/components/workflow-run-list/types.d.ts +21 -0
- package/dist/components/workflow-run-list/types.d.ts.map +1 -0
- package/dist/components/workflow-run-list/types.js +3 -0
- package/dist/components/workflow-run-list/types.js.map +1 -0
- package/dist/components/workflow-run-list/workflow-run-list-content.d.ts +14 -0
- package/dist/components/workflow-run-list/workflow-run-list-content.d.ts.map +1 -0
- package/dist/components/workflow-run-list/workflow-run-list-content.js +37 -0
- package/dist/components/workflow-run-list/workflow-run-list-content.js.map +1 -0
- package/dist/components/workflow-run-list/workflow-run-list-header.d.ts +10 -0
- package/dist/components/workflow-run-list/workflow-run-list-header.d.ts.map +1 -0
- package/dist/components/workflow-run-list/workflow-run-list-header.js +55 -0
- package/dist/components/workflow-run-list/workflow-run-list-header.js.map +1 -0
- package/dist/components/workflow-run-list/workflow-run-list-states.d.ts +15 -0
- package/dist/components/workflow-run-list/workflow-run-list-states.d.ts.map +1 -0
- package/dist/components/workflow-run-list/workflow-run-list-states.js +103 -0
- package/dist/components/workflow-run-list/workflow-run-list-states.js.map +1 -0
- package/dist/components/workflow-run-list/workflow-run-list-view.d.ts +3 -0
- package/dist/components/workflow-run-list/workflow-run-list-view.d.ts.map +1 -0
- package/dist/components/workflow-run-list/workflow-run-list-view.js +46 -0
- package/dist/components/workflow-run-list/workflow-run-list-view.js.map +1 -0
- package/dist/components/workflow-run-list/workflow-run-list.d.ts +3 -0
- package/dist/components/workflow-run-list/workflow-run-list.d.ts.map +1 -0
- package/dist/components/workflow-run-list/workflow-run-list.js +20 -0
- package/dist/components/workflow-run-list/workflow-run-list.js.map +1 -0
- package/dist/components/workflow-run-list/workflow-run-row.d.ts +14 -0
- package/dist/components/workflow-run-list/workflow-run-row.d.ts.map +1 -0
- package/dist/components/workflow-run-list/workflow-run-row.js +172 -0
- package/dist/components/workflow-run-list/workflow-run-row.js.map +1 -0
- package/dist/components/workflow-run-summary/index.d.ts +2 -0
- package/dist/components/workflow-run-summary/index.d.ts.map +1 -0
- package/dist/components/workflow-run-summary/index.js +3 -0
- package/dist/components/workflow-run-summary/index.js.map +1 -0
- package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.d.ts +9 -0
- package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.d.ts.map +1 -0
- package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js +138 -0
- package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js.map +1 -0
- package/dist/components/workflow-run-summary/workflow-run-summary.d.ts +20 -0
- package/dist/components/workflow-run-summary/workflow-run-summary.d.ts.map +1 -0
- package/dist/components/workflow-run-summary/workflow-run-summary.js +252 -0
- package/dist/components/workflow-run-summary/workflow-run-summary.js.map +1 -0
- package/dist/components/workflow-run-view/agent-config-failure-callout.d.ts +7 -0
- package/dist/components/workflow-run-view/agent-config-failure-callout.d.ts.map +1 -0
- package/dist/components/workflow-run-view/agent-config-failure-callout.js +84 -0
- package/dist/components/workflow-run-view/agent-config-failure-callout.js.map +1 -0
- package/dist/components/workflow-run-view/index.d.ts +3 -0
- package/dist/components/workflow-run-view/index.d.ts.map +1 -0
- package/dist/components/workflow-run-view/index.js +4 -0
- package/dist/components/workflow-run-view/index.js.map +1 -0
- package/dist/components/workflow-run-view/job-card.d.ts +17 -0
- package/dist/components/workflow-run-view/job-card.d.ts.map +1 -0
- package/dist/components/workflow-run-view/job-card.js +476 -0
- package/dist/components/workflow-run-view/job-card.js.map +1 -0
- package/dist/components/workflow-run-view/job-execution-switcher.d.ts +10 -0
- package/dist/components/workflow-run-view/job-execution-switcher.d.ts.map +1 -0
- package/dist/components/workflow-run-view/job-execution-switcher.js +171 -0
- package/dist/components/workflow-run-view/job-execution-switcher.js.map +1 -0
- package/dist/components/workflow-run-view/job-execution-time-text.d.ts +6 -0
- package/dist/components/workflow-run-view/job-execution-time-text.d.ts.map +1 -0
- package/dist/components/workflow-run-view/job-execution-time-text.js +24 -0
- package/dist/components/workflow-run-view/job-execution-time-text.js.map +1 -0
- package/dist/components/workflow-run-view/step-attempt-log-panel.d.ts +9 -0
- package/dist/components/workflow-run-view/step-attempt-log-panel.d.ts.map +1 -0
- package/dist/components/workflow-run-view/step-attempt-log-panel.js +152 -0
- package/dist/components/workflow-run-view/step-attempt-log-panel.js.map +1 -0
- package/dist/components/workflow-run-view/workflow-run-selection.d.ts +14 -0
- package/dist/components/workflow-run-view/workflow-run-selection.d.ts.map +1 -0
- package/dist/components/workflow-run-view/workflow-run-selection.js +56 -0
- package/dist/components/workflow-run-view/workflow-run-selection.js.map +1 -0
- package/dist/components/workflow-run-view/workflow-run-states.d.ts +12 -0
- package/dist/components/workflow-run-view/workflow-run-states.d.ts.map +1 -0
- package/dist/components/workflow-run-view/workflow-run-states.js +91 -0
- package/dist/components/workflow-run-view/workflow-run-states.js.map +1 -0
- package/dist/components/workflow-run-view/workflow-run-view.d.ts +15 -0
- package/dist/components/workflow-run-view/workflow-run-view.d.ts.map +1 -0
- package/dist/components/workflow-run-view/workflow-run-view.js +285 -0
- package/dist/components/workflow-run-view/workflow-run-view.js.map +1 -0
- package/dist/components/workflow-source-panel/index.d.ts +2 -0
- package/dist/components/workflow-source-panel/index.d.ts.map +1 -0
- package/dist/components/workflow-source-panel/index.js +3 -0
- package/dist/components/workflow-source-panel/index.js.map +1 -0
- package/dist/components/workflow-source-panel/workflow-source-panel.d.ts +13 -0
- package/dist/components/workflow-source-panel/workflow-source-panel.d.ts.map +1 -0
- package/dist/components/workflow-source-panel/workflow-source-panel.js +91 -0
- package/dist/components/workflow-source-panel/workflow-source-panel.js.map +1 -0
- package/dist/components/workflow-status/status-visuals.d.ts +12 -0
- package/dist/components/workflow-status/status-visuals.d.ts.map +1 -0
- package/dist/components/workflow-status/status-visuals.js +54 -0
- package/dist/components/workflow-status/status-visuals.js.map +1 -0
- package/dist/components/workflow-status/workflow-status-icon.d.ts +22 -0
- package/dist/components/workflow-status/workflow-status-icon.d.ts.map +1 -0
- package/dist/components/workflow-status/workflow-status-icon.js +100 -0
- package/dist/components/workflow-status/workflow-status-icon.js.map +1 -0
- package/dist/core/entities/job-execution.d.ts +69 -0
- package/dist/core/entities/job-execution.d.ts.map +1 -0
- package/dist/core/entities/job-execution.js +83 -0
- package/dist/core/entities/job-execution.js.map +1 -0
- package/dist/core/entities/job.d.ts +56 -0
- package/dist/core/entities/job.d.ts.map +1 -0
- package/dist/core/entities/job.js +71 -0
- package/dist/core/entities/job.js.map +1 -0
- package/dist/core/entities/step-attempt.d.ts +49 -0
- package/dist/core/entities/step-attempt.d.ts.map +1 -0
- package/dist/core/entities/step-attempt.js +48 -0
- package/dist/core/entities/step-attempt.js.map +1 -0
- package/dist/core/entities/step.d.ts +41 -0
- package/dist/core/entities/step.d.ts.map +1 -0
- package/dist/core/entities/step.js +51 -0
- package/dist/core/entities/step.js.map +1 -0
- package/dist/core/entities/workflow-run-attempt.d.ts +44 -0
- package/dist/core/entities/workflow-run-attempt.d.ts.map +1 -0
- package/dist/core/entities/workflow-run-attempt.js +51 -0
- package/dist/core/entities/workflow-run-attempt.js.map +1 -0
- package/dist/core/entities/workflow-run.d.ts +61 -0
- package/dist/core/entities/workflow-run.d.ts.map +1 -0
- package/dist/core/entities/workflow-run.js +104 -0
- package/dist/core/entities/workflow-run.js.map +1 -0
- package/dist/core/workflow-run-url-state.d.ts +13 -0
- package/dist/core/workflow-run-url-state.d.ts.map +1 -0
- package/dist/core/workflow-run-url-state.js +43 -0
- package/dist/core/workflow-run-url-state.js.map +1 -0
- package/dist/core/workflow-run.d.ts +13 -0
- package/dist/core/workflow-run.d.ts.map +1 -0
- package/dist/core/workflow-run.js +8 -0
- package/dist/core/workflow-run.js.map +1 -0
- package/dist/env.d.js +2 -0
- package/dist/env.d.js.map +1 -0
- package/dist/feature.d.ts +20 -0
- package/dist/feature.d.ts.map +1 -0
- package/dist/feature.js +27 -0
- package/dist/feature.js.map +1 -0
- package/dist/hooks/api/workflow-runs.d.ts +109 -0
- package/dist/hooks/api/workflow-runs.d.ts.map +1 -0
- package/dist/hooks/api/workflow-runs.js +394 -0
- package/dist/hooks/api/workflow-runs.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/pages/workflow-run-first-time-use.d.ts +6 -0
- package/dist/pages/workflow-run-first-time-use.d.ts.map +1 -0
- package/dist/pages/workflow-run-first-time-use.js +17 -0
- package/dist/pages/workflow-run-first-time-use.js.map +1 -0
- package/dist/pages/workflow-run-page.d.ts +8 -0
- package/dist/pages/workflow-run-page.d.ts.map +1 -0
- package/dist/pages/workflow-run-page.js +83 -0
- package/dist/pages/workflow-run-page.js.map +1 -0
- package/dist/routes/run-detail.d.ts +8 -0
- package/dist/routes/run-detail.d.ts.map +1 -0
- package/dist/routes/run-detail.js +21 -0
- package/dist/routes/run-detail.js.map +1 -0
- package/dist/routes/runs.d.ts +8 -0
- package/dist/routes/runs.d.ts.map +1 -0
- package/dist/routes/runs.js +20 -0
- package/dist/routes/runs.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -0
- package/package.json +114 -0
- package/src/components/identifier/identifier.tsx +178 -0
- package/src/components/identifier/index.ts +1 -0
- package/src/components/job-graph/graph-model.test.ts +189 -0
- package/src/components/job-graph/graph-model.ts +178 -0
- package/src/components/job-graph/index.ts +2 -0
- package/src/components/job-graph/job-duration-format.ts +54 -0
- package/src/components/job-graph/job-duration-label.tsx +29 -0
- package/src/components/job-graph/job-graph-content.tsx +225 -0
- package/src/components/job-graph/job-graph-view.test.tsx +298 -0
- package/src/components/job-graph/job-graph-view.tsx +45 -0
- package/src/components/job-graph/job-graph.stories.tsx +182 -0
- package/src/components/job-graph/job-graph.tsx +24 -0
- package/src/components/job-graph/job-node.stories.tsx +364 -0
- package/src/components/job-graph/job-node.test.tsx +347 -0
- package/src/components/job-graph/job-node.tsx +202 -0
- package/src/components/job-graph/types.ts +9 -0
- package/src/components/step-list/index.ts +6 -0
- package/src/components/step-list/step-list-model.test.ts +369 -0
- package/src/components/step-list/step-list-model.ts +205 -0
- package/src/components/step-list/step-list.stories.tsx +419 -0
- package/src/components/step-list/step-list.test.tsx +566 -0
- package/src/components/step-list/step-list.tsx +494 -0
- package/src/components/workflow-run-duration-label.tsx +118 -0
- package/src/components/workflow-run-list/index.ts +1 -0
- package/src/components/workflow-run-list/run-display.test.ts +53 -0
- package/src/components/workflow-run-list/run-display.ts +22 -0
- package/src/components/workflow-run-list/types.ts +22 -0
- package/src/components/workflow-run-list/workflow-run-list-content.tsx +58 -0
- package/src/components/workflow-run-list/workflow-run-list-header.tsx +53 -0
- package/src/components/workflow-run-list/workflow-run-list-states.tsx +86 -0
- package/src/components/workflow-run-list/workflow-run-list-view.test.tsx +178 -0
- package/src/components/workflow-run-list/workflow-run-list-view.tsx +57 -0
- package/src/components/workflow-run-list/workflow-run-list.stories.tsx +111 -0
- package/src/components/workflow-run-list/workflow-run-list.tsx +29 -0
- package/src/components/workflow-run-list/workflow-run-row.tsx +176 -0
- package/src/components/workflow-run-summary/index.ts +1 -0
- package/src/components/workflow-run-summary/workflow-run-attempt-switcher.test.tsx +230 -0
- package/src/components/workflow-run-summary/workflow-run-attempt-switcher.tsx +146 -0
- package/src/components/workflow-run-summary/workflow-run-summary.stories.tsx +414 -0
- package/src/components/workflow-run-summary/workflow-run-summary.test.tsx +354 -0
- package/src/components/workflow-run-summary/workflow-run-summary.tsx +295 -0
- package/src/components/workflow-run-view/agent-config-failure-callout.stories.tsx +140 -0
- package/src/components/workflow-run-view/agent-config-failure-callout.tsx +93 -0
- package/src/components/workflow-run-view/index.ts +2 -0
- package/src/components/workflow-run-view/job-card.stories.tsx +788 -0
- package/src/components/workflow-run-view/job-card.tsx +566 -0
- package/src/components/workflow-run-view/job-execution-switcher.tsx +170 -0
- package/src/components/workflow-run-view/job-execution-time-text.tsx +34 -0
- package/src/components/workflow-run-view/step-attempt-log-panel.test.tsx +290 -0
- package/src/components/workflow-run-view/step-attempt-log-panel.tsx +152 -0
- package/src/components/workflow-run-view/workflow-run-selection.test.ts +280 -0
- package/src/components/workflow-run-view/workflow-run-selection.ts +89 -0
- package/src/components/workflow-run-view/workflow-run-states.tsx +70 -0
- package/src/components/workflow-run-view/workflow-run-view.test.tsx +1214 -0
- package/src/components/workflow-run-view/workflow-run-view.tsx +341 -0
- package/src/components/workflow-source-panel/index.ts +1 -0
- package/src/components/workflow-source-panel/workflow-source-panel.stories.tsx +110 -0
- package/src/components/workflow-source-panel/workflow-source-panel.test.tsx +96 -0
- package/src/components/workflow-source-panel/workflow-source-panel.tsx +136 -0
- package/src/components/workflow-status/status-visuals.test.ts +38 -0
- package/src/components/workflow-status/status-visuals.ts +36 -0
- package/src/components/workflow-status/workflow-status-icon.stories.tsx +90 -0
- package/src/components/workflow-status/workflow-status-icon.tsx +135 -0
- package/src/core/entities/job-execution.ts +139 -0
- package/src/core/entities/job.ts +149 -0
- package/src/core/entities/step-attempt.ts +89 -0
- package/src/core/entities/step.ts +105 -0
- package/src/core/entities/workflow-run-attempt.ts +87 -0
- package/src/core/entities/workflow-run.ts +183 -0
- package/src/core/workflow-run-url-state.ts +61 -0
- package/src/core/workflow-run.test.ts +640 -0
- package/src/core/workflow-run.ts +66 -0
- package/src/env.d.ts +8 -0
- package/src/feature.ts +26 -0
- package/src/hooks/api/workflow-runs.test.tsx +410 -0
- package/src/hooks/api/workflow-runs.ts +485 -0
- package/src/index.ts +45 -0
- package/src/page-harness-budget.test.ts +33 -0
- package/src/pages/workflow-run-first-time-use.tsx +17 -0
- package/src/pages/workflow-run-page.test.tsx +517 -0
- package/src/pages/workflow-run-page.tsx +89 -0
- package/src/routes/run-detail.tsx +15 -0
- package/src/routes/runs.tsx +11 -0
- package/test/fixtures/logs.ts +13 -0
- package/test/fixtures/workflow-run.ts +311 -0
- package/test/pages.tsx +79 -0
- package/test/render.tsx +40 -0
- package/test/setup.ts +3 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +3 -0
- package/tsconfig.test.json +8 -0
- package/vercel.json +8 -0
- package/vitest.config.ts +70 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/workflow-run-view/workflow-run-states.tsx"],"sourcesContent":["import type {QueryLoadErrorQuery} from '@shipfox/client-ui';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport {Skeleton} from '@shipfox/react-ui/skeleton';\nimport {Text} from '@shipfox/react-ui/typography';\n\nexport function WorkflowRunSkeleton() {\n return (\n <section\n aria-label=\"Loading workflow run\"\n className=\"border-b border-border-neutral-base bg-background-subtle-base px-16 py-12\"\n >\n <div className=\"flex min-w-0 flex-wrap items-center gap-x-12 gap-y-8\">\n <div className=\"flex min-w-0 items-center gap-8\">\n <Skeleton className=\"size-8 rounded-full\" />\n <Skeleton className=\"h-24 w-180 rounded-6\" />\n </div>\n <Skeleton className=\"h-24 w-88 rounded-6\" />\n <span\n aria-hidden=\"true\"\n className=\"hidden h-20 w-px shrink-0 bg-border-neutral-base sm:block\"\n />\n <Skeleton className=\"h-20 w-64 rounded-4\" />\n <Skeleton className=\"h-20 w-112 rounded-4\" />\n <span className=\"min-w-0 flex-1\" />\n <Skeleton className=\"h-20 w-88 rounded-4\" />\n <Skeleton className=\"h-20 w-88 rounded-4\" />\n </div>\n </section>\n );\n}\n\nexport function WorkflowRunNotFound() {\n return (\n <EmptyState\n icon=\"pulseLine\"\n title=\"Run not found\"\n description=\"This run does not exist or is no longer available.\"\n />\n );\n}\n\n/**\n * Slim non-blocking banner shown when a background refetch fails after the run already\n * loaded (active-run polling can hit a transient API error), so the loaded run stays on\n * screen with an inline retry instead of being wiped by a full error placeholder.\n */\nexport function WorkflowRunStaleError({query}: {query: QueryLoadErrorQuery}) {\n return (\n <div className=\"border-b border-border-neutral-base p-8\">\n <Callout role=\"alert\" type=\"error\">\n <div className=\"flex items-center justify-between gap-8\">\n <Text size=\"xs\">Could not refresh this run.</Text>\n <Button\n type=\"button\"\n size=\"2xs\"\n variant=\"secondary\"\n isLoading={query.isFetching}\n onClick={() => {\n void query.refetch();\n }}\n >\n Retry\n </Button>\n </div>\n </Callout>\n </div>\n );\n}\n"],"names":["Button","Callout","EmptyState","Skeleton","Text","WorkflowRunSkeleton","section","aria-label","className","div","span","aria-hidden","WorkflowRunNotFound","icon","title","description","WorkflowRunStaleError","query","role","type","size","variant","isLoading","isFetching","onClick","refetch"],"mappings":";AACA,SAAQA,MAAM,QAAO,2BAA2B;AAChD,SAAQC,OAAO,QAAO,4BAA4B;AAClD,SAAQC,UAAU,QAAO,gCAAgC;AACzD,SAAQC,QAAQ,QAAO,6BAA6B;AACpD,SAAQC,IAAI,QAAO,+BAA+B;AAElD,OAAO,SAASC;IACd,qBACE,KAACC;QACCC,cAAW;QACXC,WAAU;kBAEV,cAAA,MAACC;YAAID,WAAU;;8BACb,MAACC;oBAAID,WAAU;;sCACb,KAACL;4BAASK,WAAU;;sCACpB,KAACL;4BAASK,WAAU;;;;8BAEtB,KAACL;oBAASK,WAAU;;8BACpB,KAACE;oBACCC,eAAY;oBACZH,WAAU;;8BAEZ,KAACL;oBAASK,WAAU;;8BACpB,KAACL;oBAASK,WAAU;;8BACpB,KAACE;oBAAKF,WAAU;;8BAChB,KAACL;oBAASK,WAAU;;8BACpB,KAACL;oBAASK,WAAU;;;;;AAI5B;AAEA,OAAO,SAASI;IACd,qBACE,KAACV;QACCW,MAAK;QACLC,OAAM;QACNC,aAAY;;AAGlB;AAEA;;;;CAIC,GACD,OAAO,SAASC,sBAAsB,EAACC,KAAK,EAA+B;IACzE,qBACE,KAACR;QAAID,WAAU;kBACb,cAAA,KAACP;YAAQiB,MAAK;YAAQC,MAAK;sBACzB,cAAA,MAACV;gBAAID,WAAU;;kCACb,KAACJ;wBAAKgB,MAAK;kCAAK;;kCAChB,KAACpB;wBACCmB,MAAK;wBACLC,MAAK;wBACLC,SAAQ;wBACRC,WAAWL,MAAMM,UAAU;wBAC3BC,SAAS;4BACP,KAAKP,MAAMQ,OAAO;wBACpB;kCACD;;;;;;AAOX"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type WorkflowRunSelectionInput } from '#core/workflow-run-url-state.js';
|
|
2
|
+
export interface WorkflowRunViewProps {
|
|
3
|
+
workspaceId: string;
|
|
4
|
+
projectId: string;
|
|
5
|
+
workflowRunId?: string | undefined;
|
|
6
|
+
selection?: WorkflowRunSelectionInput | undefined;
|
|
7
|
+
onSelectionChange?: ((selection: WorkflowRunSelectionInput) => void) | undefined;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Renders the run for `workflowRunId`, or a skeleton while `workflowRunId` is still unknown (the page is
|
|
11
|
+
* resolving which run to show) or the run is loading, so the page never branches on the
|
|
12
|
+
* loading state itself.
|
|
13
|
+
*/
|
|
14
|
+
export declare function WorkflowRunView({ workspaceId, projectId, workflowRunId, selection, onSelectionChange, }: WorkflowRunViewProps): import("react").JSX.Element;
|
|
15
|
+
//# sourceMappingURL=workflow-run-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-run-view.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-view/workflow-run-view.tsx"],"names":[],"mappings":"AAYA,OAAO,EACL,KAAK,yBAAyB,EAE/B,MAAM,iCAAiC,CAAC;AAsBzC,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,SAAS,CAAC,EAAE,yBAAyB,GAAG,SAAS,CAAC;IAClD,iBAAiB,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,yBAAyB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAClF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAC9B,WAAW,EACX,SAAS,EACT,aAAa,EACb,SAAS,EACT,iBAAiB,GAClB,EAAE,oBAAoB,+BAkBtB"}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { ApiError } from '@shipfox/client-api';
|
|
3
|
+
import { QueryLoadError } from '@shipfox/client-ui';
|
|
4
|
+
import { RelativeTimeProvider } from '@shipfox/react-ui/relative-time';
|
|
5
|
+
import { toast } from '@shipfox/react-ui/toast';
|
|
6
|
+
import { useNavigate } from '@tanstack/react-router';
|
|
7
|
+
import { useEffect, useId, useRef, useState } from 'react';
|
|
8
|
+
import { resolveJobExecution } from '#core/workflow-run.js';
|
|
9
|
+
import { withoutWorkflowRunSelectionSearch } from '#core/workflow-run-url-state.js';
|
|
10
|
+
import { useCancelWorkflowRunMutation, useRerunWorkflowRunMutation, useWorkflowRunAttemptQuery } from '#hooks/api/workflow-runs.js';
|
|
11
|
+
import { JobGraph } from '../job-graph/index.js';
|
|
12
|
+
import { WorkflowRunSummary } from '../workflow-run-summary/index.js';
|
|
13
|
+
import { WorkflowSourcePanel } from '../workflow-source-panel/index.js';
|
|
14
|
+
import { JobCard } from './job-card.js';
|
|
15
|
+
import { resolveWorkflowRunSelection } from './workflow-run-selection.js';
|
|
16
|
+
import { WorkflowRunNotFound, WorkflowRunSkeleton, WorkflowRunStaleError } from './workflow-run-states.js';
|
|
17
|
+
/**
|
|
18
|
+
* Renders the run for `workflowRunId`, or a skeleton while `workflowRunId` is still unknown (the page is
|
|
19
|
+
* resolving which run to show) or the run is loading, so the page never branches on the
|
|
20
|
+
* loading state itself.
|
|
21
|
+
*/ export function WorkflowRunView({ workspaceId, projectId, workflowRunId, selection, onSelectionChange }) {
|
|
22
|
+
const runQuery = useWorkflowRunAttemptQuery({
|
|
23
|
+
workflowRunId,
|
|
24
|
+
runAttempt: selection?.runAttempt
|
|
25
|
+
});
|
|
26
|
+
const rerunMutation = useRerunWorkflowRunMutation(projectId);
|
|
27
|
+
return /*#__PURE__*/ _jsx(RelativeTimeProvider, {
|
|
28
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
29
|
+
className: "flex min-h-0 min-w-0 flex-1 overflow-hidden",
|
|
30
|
+
children: /*#__PURE__*/ _jsx(RunViewContent, {
|
|
31
|
+
workspaceId: workspaceId,
|
|
32
|
+
projectId: projectId,
|
|
33
|
+
query: runQuery,
|
|
34
|
+
rerunMutation: rerunMutation,
|
|
35
|
+
selection: selection,
|
|
36
|
+
onSelectionChange: onSelectionChange
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function RunViewContent({ workspaceId, projectId, query, rerunMutation, selection, onSelectionChange }) {
|
|
42
|
+
const navigate = useNavigate();
|
|
43
|
+
const [selectedJobId, setSelectedJobId] = useState();
|
|
44
|
+
const [selectedJobExecutionId, setSelectedJobExecutionId] = useState();
|
|
45
|
+
const [sourcePanelOpen, setSourcePanelOpen] = useState(false);
|
|
46
|
+
const [sourceFocus, setSourceFocus] = useState(null);
|
|
47
|
+
const sourcePanelId = useId();
|
|
48
|
+
const sourceButtonRef = useRef(null);
|
|
49
|
+
// The button that last opened the panel (summary or a step detail), so Escape /
|
|
50
|
+
// Close returns focus to whoever opened it.
|
|
51
|
+
const lastSourceTriggerRef = useRef(null);
|
|
52
|
+
const selectionControlled = selection !== undefined;
|
|
53
|
+
const sourceAvailable = query.data?.sourceSnapshot !== null && query.data?.sourceSnapshot !== undefined;
|
|
54
|
+
const cancelMutation = useCancelWorkflowRunMutation(query.data);
|
|
55
|
+
useEffect(()=>{
|
|
56
|
+
if (!sourceAvailable) {
|
|
57
|
+
setSourcePanelOpen(false);
|
|
58
|
+
setSourceFocus(null);
|
|
59
|
+
}
|
|
60
|
+
}, [
|
|
61
|
+
sourceAvailable
|
|
62
|
+
]);
|
|
63
|
+
// If a refetch drops the focused step or its location, degrade to whole-workflow
|
|
64
|
+
// focus so the panel never points at an unmounted Source button.
|
|
65
|
+
useEffect(()=>{
|
|
66
|
+
if (!sourceFocus) return;
|
|
67
|
+
const stillLocated = query.data?.jobs.some((job)=>job.jobExecutions.some((execution)=>execution.steps.some((step)=>step.id === sourceFocus.stepId && step.sourceLocation)));
|
|
68
|
+
if (!stillLocated) {
|
|
69
|
+
setSourceFocus(null);
|
|
70
|
+
lastSourceTriggerRef.current = sourceButtonRef.current;
|
|
71
|
+
}
|
|
72
|
+
}, [
|
|
73
|
+
sourceFocus,
|
|
74
|
+
query.data
|
|
75
|
+
]);
|
|
76
|
+
if (query.isPending) return /*#__PURE__*/ _jsx(WorkflowRunSkeleton, {});
|
|
77
|
+
// Only show the full error placeholder when nothing ever loaded. A refetch that fails after
|
|
78
|
+
// a prior success keeps the loaded run on screen (see below) instead of wiping the pane,
|
|
79
|
+
// since active-run polling can hit a transient API error.
|
|
80
|
+
if (query.isError && query.data === undefined) {
|
|
81
|
+
if (query.error instanceof ApiError && query.error.status === 404) {
|
|
82
|
+
return /*#__PURE__*/ _jsx(WorkflowRunNotFound, {});
|
|
83
|
+
}
|
|
84
|
+
return /*#__PURE__*/ _jsx(QueryLoadError, {
|
|
85
|
+
query: query,
|
|
86
|
+
subject: "workflow run",
|
|
87
|
+
icon: "pulseLine"
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
if (query.data === undefined) return /*#__PURE__*/ _jsx(WorkflowRunSkeleton, {});
|
|
91
|
+
const runData = query.data;
|
|
92
|
+
const resolvedSelection = selectionControlled ? resolveWorkflowRunSelection({
|
|
93
|
+
run: runData,
|
|
94
|
+
selection
|
|
95
|
+
}) : undefined;
|
|
96
|
+
const selectedJob = selectionControlled ? resolvedSelection?.job : runData.jobs.find((job)=>job.id === selectedJobId) ?? runData.jobs.at(0);
|
|
97
|
+
const selectedJobExecution = selectionControlled ? resolvedSelection?.jobExecution : selectedJob ? resolveJobExecution(selectedJob, selectedJobExecutionId) : undefined;
|
|
98
|
+
const selectedAttemptId = selectionControlled ? resolvedSelection?.selectedAttemptId ?? null : undefined;
|
|
99
|
+
// Explicit per-step focus wins; fall back to the URL-selected step so deep links
|
|
100
|
+
// still pre-highlight when the summary opens the whole-workflow source.
|
|
101
|
+
const highlightedLineRange = sourceFocus?.location ?? resolvedSelection?.step?.sourceLocation ?? null;
|
|
102
|
+
const sourceSnapshot = runData.sourceSnapshot;
|
|
103
|
+
async function rerun(mode) {
|
|
104
|
+
try {
|
|
105
|
+
const run = await rerunMutation.mutateAsync({
|
|
106
|
+
workflowRunId: runData.id,
|
|
107
|
+
mode
|
|
108
|
+
});
|
|
109
|
+
toast.success('Re-run started');
|
|
110
|
+
await navigate({
|
|
111
|
+
to: '/workspaces/$wid/projects/$pid/runs/$workflowRunId',
|
|
112
|
+
params: {
|
|
113
|
+
wid: workspaceId,
|
|
114
|
+
pid: projectId,
|
|
115
|
+
workflowRunId: run.id
|
|
116
|
+
},
|
|
117
|
+
search: (previous)=>withoutWorkflowRunSelectionSearch(previous)
|
|
118
|
+
});
|
|
119
|
+
} catch (error) {
|
|
120
|
+
toast.error(error instanceof ApiError ? error.message : 'Could not start re-run');
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function selectJob(jobId) {
|
|
124
|
+
if (!selectionControlled) {
|
|
125
|
+
setSelectedJobId(jobId);
|
|
126
|
+
setSelectedJobExecutionId(undefined);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
onSelectionChange?.(jobId ? {
|
|
130
|
+
jobId,
|
|
131
|
+
runAttempt: selection?.runAttempt
|
|
132
|
+
} : {
|
|
133
|
+
runAttempt: selection?.runAttempt
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
function selectJobExecution(jobExecutionId) {
|
|
137
|
+
if (!selectionControlled) {
|
|
138
|
+
setSelectedJobExecutionId(jobExecutionId);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
if (!selectedJob) return;
|
|
142
|
+
onSelectionChange?.({
|
|
143
|
+
jobId: selectedJob.id,
|
|
144
|
+
jobExecutionId,
|
|
145
|
+
runAttempt: selection?.runAttempt
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
function selectAttempt(attemptId) {
|
|
149
|
+
if (!selectionControlled || !selectedJob || !selectedJobExecution) return;
|
|
150
|
+
if (!attemptId) {
|
|
151
|
+
onSelectionChange?.({
|
|
152
|
+
jobId: selectedJob.id,
|
|
153
|
+
jobExecutionId: selectedJobExecution.id,
|
|
154
|
+
runAttempt: selection?.runAttempt
|
|
155
|
+
});
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const match = findAttemptSelection(selectedJobExecution, attemptId);
|
|
159
|
+
if (!match) return;
|
|
160
|
+
onSelectionChange?.({
|
|
161
|
+
jobId: selectedJob.id,
|
|
162
|
+
jobExecutionId: selectedJobExecution.id,
|
|
163
|
+
stepId: match.stepId,
|
|
164
|
+
stepAttemptId: match.attemptId,
|
|
165
|
+
runAttempt: selection?.runAttempt
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
function openWholeWorkflowSource() {
|
|
169
|
+
setSourceFocus(null);
|
|
170
|
+
lastSourceTriggerRef.current = sourceButtonRef.current;
|
|
171
|
+
setSourcePanelOpen(true);
|
|
172
|
+
}
|
|
173
|
+
function toggleWholeWorkflowSource() {
|
|
174
|
+
if (sourcePanelOpen && sourceFocus === null) {
|
|
175
|
+
closeSourcePanel();
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
openWholeWorkflowSource();
|
|
179
|
+
}
|
|
180
|
+
function openStepSource(stepId, location, trigger) {
|
|
181
|
+
setSourceFocus({
|
|
182
|
+
stepId,
|
|
183
|
+
location
|
|
184
|
+
});
|
|
185
|
+
lastSourceTriggerRef.current = trigger;
|
|
186
|
+
setSourcePanelOpen(true);
|
|
187
|
+
}
|
|
188
|
+
function closeSourcePanel() {
|
|
189
|
+
const trigger = lastSourceTriggerRef.current;
|
|
190
|
+
const fallbackTrigger = sourceButtonRef.current;
|
|
191
|
+
setSourcePanelOpen(false);
|
|
192
|
+
// Defer so focus lands after the panel unmounts; clear the focus only after
|
|
193
|
+
// focusing so the opener button is still expanded (force-visible) on return.
|
|
194
|
+
window.setTimeout(()=>{
|
|
195
|
+
const focusTarget = trigger?.isConnected ? trigger : fallbackTrigger;
|
|
196
|
+
focusTarget?.focus();
|
|
197
|
+
setSourceFocus(null);
|
|
198
|
+
}, 0);
|
|
199
|
+
}
|
|
200
|
+
function cancelRun() {
|
|
201
|
+
cancelMutation.mutate(undefined, {
|
|
202
|
+
onError: (error)=>{
|
|
203
|
+
toast.error(cancelErrorMessage(error));
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
208
|
+
children: [
|
|
209
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
210
|
+
className: "flex min-w-0 flex-1 flex-col",
|
|
211
|
+
children: [
|
|
212
|
+
/*#__PURE__*/ _jsx(WorkflowRunSummary, {
|
|
213
|
+
workspaceId: workspaceId,
|
|
214
|
+
projectId: projectId,
|
|
215
|
+
run: runData,
|
|
216
|
+
sourceAvailable: sourceAvailable,
|
|
217
|
+
sourceOpen: sourcePanelOpen && sourceFocus === null,
|
|
218
|
+
sourcePanelId: sourcePanelId,
|
|
219
|
+
sourceButtonRef: sourceButtonRef,
|
|
220
|
+
onSourceToggle: toggleWholeWorkflowSource,
|
|
221
|
+
cancelling: cancelMutation.isPending,
|
|
222
|
+
onCancel: cancelRun,
|
|
223
|
+
rerunPending: rerunMutation.isPending,
|
|
224
|
+
onRerun: (mode)=>void rerun(mode),
|
|
225
|
+
latestAttempt: runData.latestAttempt
|
|
226
|
+
}),
|
|
227
|
+
query.isError ? /*#__PURE__*/ _jsx(WorkflowRunStaleError, {
|
|
228
|
+
query: query
|
|
229
|
+
}) : null,
|
|
230
|
+
/*#__PURE__*/ _jsx("div", {
|
|
231
|
+
className: "min-h-0 flex-1 overflow-auto bg-background-neutral-base p-16",
|
|
232
|
+
children: /*#__PURE__*/ _jsxs("div", {
|
|
233
|
+
className: "mx-auto flex w-full max-w-[1280px] flex-col gap-16",
|
|
234
|
+
children: [
|
|
235
|
+
/*#__PURE__*/ _jsx(JobGraph, {
|
|
236
|
+
run: runData,
|
|
237
|
+
selectedJobId: selectedJob?.id,
|
|
238
|
+
onSelectedJobChange: selectJob
|
|
239
|
+
}),
|
|
240
|
+
selectedJob ? /*#__PURE__*/ _jsx(JobCard, {
|
|
241
|
+
workspaceId: workspaceId,
|
|
242
|
+
job: selectedJob,
|
|
243
|
+
selectedJobExecution: selectedJobExecution,
|
|
244
|
+
selectedAttemptId: selectedJob.carriedOver ? undefined : selectedAttemptId,
|
|
245
|
+
onSelectedJobExecutionChange: selectJobExecution,
|
|
246
|
+
onSelectedAttemptChange: selectionControlled ? selectAttempt : undefined,
|
|
247
|
+
sourcePanelId: sourcePanelId,
|
|
248
|
+
sourceAvailable: sourceAvailable,
|
|
249
|
+
focusedSourceStepId: sourceFocus?.stepId ?? null,
|
|
250
|
+
onOpenStepSource: openStepSource
|
|
251
|
+
}) : null
|
|
252
|
+
]
|
|
253
|
+
})
|
|
254
|
+
})
|
|
255
|
+
]
|
|
256
|
+
}),
|
|
257
|
+
/*#__PURE__*/ _jsx(WorkflowSourcePanel, {
|
|
258
|
+
id: sourcePanelId,
|
|
259
|
+
source: sourceSnapshot,
|
|
260
|
+
open: sourcePanelOpen && sourceAvailable,
|
|
261
|
+
onClose: closeSourcePanel,
|
|
262
|
+
highlightedLineRange: highlightedLineRange,
|
|
263
|
+
scrollHighlightedIntoView: true
|
|
264
|
+
})
|
|
265
|
+
]
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
function cancelErrorMessage(error) {
|
|
269
|
+
if (error instanceof ApiError && error.code === 'run-already-finished') {
|
|
270
|
+
return 'This workflow run has already finished.';
|
|
271
|
+
}
|
|
272
|
+
return 'Could not cancel workflow run.';
|
|
273
|
+
}
|
|
274
|
+
function findAttemptSelection(jobExecution, attemptId) {
|
|
275
|
+
for (const step of jobExecution.steps){
|
|
276
|
+
const attempt = step.attempts.find((candidate)=>candidate.id === attemptId);
|
|
277
|
+
if (attempt) return {
|
|
278
|
+
stepId: step.id,
|
|
279
|
+
attemptId: attempt.id
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
return undefined;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
//# sourceMappingURL=workflow-run-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/workflow-run-view/workflow-run-view.tsx"],"sourcesContent":["import type {WorkflowRunRerunModeDto} from '@shipfox/api-workflows-dto';\nimport {ApiError} from '@shipfox/client-api';\nimport {QueryLoadError} from '@shipfox/client-ui';\nimport {RelativeTimeProvider} from '@shipfox/react-ui/relative-time';\nimport {toast} from '@shipfox/react-ui/toast';\nimport {useNavigate} from '@tanstack/react-router';\nimport {useEffect, useId, useRef, useState} from 'react';\nimport {\n type JobExecution,\n resolveJobExecution,\n type StepSourceLocation,\n} from '#core/workflow-run.js';\nimport {\n type WorkflowRunSelectionInput,\n withoutWorkflowRunSelectionSearch,\n} from '#core/workflow-run-url-state.js';\nimport {\n useCancelWorkflowRunMutation,\n useRerunWorkflowRunMutation,\n useWorkflowRunAttemptQuery,\n} from '#hooks/api/workflow-runs.js';\nimport {JobGraph} from '../job-graph/index.js';\nimport {WorkflowRunSummary} from '../workflow-run-summary/index.js';\nimport {WorkflowSourcePanel} from '../workflow-source-panel/index.js';\nimport {JobCard} from './job-card.js';\nimport {resolveWorkflowRunSelection} from './workflow-run-selection.js';\nimport {\n WorkflowRunNotFound,\n WorkflowRunSkeleton,\n WorkflowRunStaleError,\n} from './workflow-run-states.js';\n\ninterface WorkflowSourceFocus {\n stepId: string;\n location: StepSourceLocation;\n}\n\nexport interface WorkflowRunViewProps {\n workspaceId: string;\n projectId: string;\n workflowRunId?: string | undefined;\n selection?: WorkflowRunSelectionInput | undefined;\n onSelectionChange?: ((selection: WorkflowRunSelectionInput) => void) | undefined;\n}\n\n/**\n * Renders the run for `workflowRunId`, or a skeleton while `workflowRunId` is still unknown (the page is\n * resolving which run to show) or the run is loading, so the page never branches on the\n * loading state itself.\n */\nexport function WorkflowRunView({\n workspaceId,\n projectId,\n workflowRunId,\n selection,\n onSelectionChange,\n}: WorkflowRunViewProps) {\n const runQuery = useWorkflowRunAttemptQuery({workflowRunId, runAttempt: selection?.runAttempt});\n const rerunMutation = useRerunWorkflowRunMutation(projectId);\n\n return (\n <RelativeTimeProvider>\n <div className=\"flex min-h-0 min-w-0 flex-1 overflow-hidden\">\n <RunViewContent\n workspaceId={workspaceId}\n projectId={projectId}\n query={runQuery}\n rerunMutation={rerunMutation}\n selection={selection}\n onSelectionChange={onSelectionChange}\n />\n </div>\n </RelativeTimeProvider>\n );\n}\n\nfunction RunViewContent({\n workspaceId,\n projectId,\n query,\n rerunMutation,\n selection,\n onSelectionChange,\n}: {\n workspaceId: string;\n projectId: string;\n query: ReturnType<typeof useWorkflowRunAttemptQuery>;\n rerunMutation: ReturnType<typeof useRerunWorkflowRunMutation>;\n selection: WorkflowRunSelectionInput | undefined;\n onSelectionChange: ((selection: WorkflowRunSelectionInput) => void) | undefined;\n}) {\n const navigate = useNavigate();\n const [selectedJobId, setSelectedJobId] = useState<string | undefined>();\n const [selectedJobExecutionId, setSelectedJobExecutionId] = useState<string | undefined>();\n const [sourcePanelOpen, setSourcePanelOpen] = useState(false);\n const [sourceFocus, setSourceFocus] = useState<WorkflowSourceFocus | null>(null);\n const sourcePanelId = useId();\n const sourceButtonRef = useRef<HTMLButtonElement>(null);\n // The button that last opened the panel (summary or a step detail), so Escape /\n // Close returns focus to whoever opened it.\n const lastSourceTriggerRef = useRef<HTMLButtonElement | null>(null);\n const selectionControlled = selection !== undefined;\n const sourceAvailable =\n query.data?.sourceSnapshot !== null && query.data?.sourceSnapshot !== undefined;\n const cancelMutation = useCancelWorkflowRunMutation(query.data);\n\n useEffect(() => {\n if (!sourceAvailable) {\n setSourcePanelOpen(false);\n setSourceFocus(null);\n }\n }, [sourceAvailable]);\n\n // If a refetch drops the focused step or its location, degrade to whole-workflow\n // focus so the panel never points at an unmounted Source button.\n useEffect(() => {\n if (!sourceFocus) return;\n const stillLocated = query.data?.jobs.some((job) =>\n job.jobExecutions.some((execution) =>\n execution.steps.some((step) => step.id === sourceFocus.stepId && step.sourceLocation),\n ),\n );\n if (!stillLocated) {\n setSourceFocus(null);\n lastSourceTriggerRef.current = sourceButtonRef.current;\n }\n }, [sourceFocus, query.data]);\n\n if (query.isPending) return <WorkflowRunSkeleton />;\n\n // Only show the full error placeholder when nothing ever loaded. A refetch that fails after\n // a prior success keeps the loaded run on screen (see below) instead of wiping the pane,\n // since active-run polling can hit a transient API error.\n if (query.isError && query.data === undefined) {\n if (query.error instanceof ApiError && query.error.status === 404) {\n return <WorkflowRunNotFound />;\n }\n return <QueryLoadError query={query} subject=\"workflow run\" icon=\"pulseLine\" />;\n }\n\n if (query.data === undefined) return <WorkflowRunSkeleton />;\n\n const runData = query.data;\n const resolvedSelection = selectionControlled\n ? resolveWorkflowRunSelection({run: runData, selection})\n : undefined;\n const selectedJob = selectionControlled\n ? resolvedSelection?.job\n : (runData.jobs.find((job) => job.id === selectedJobId) ?? runData.jobs.at(0));\n const selectedJobExecution = selectionControlled\n ? resolvedSelection?.jobExecution\n : selectedJob\n ? resolveJobExecution(selectedJob, selectedJobExecutionId)\n : undefined;\n const selectedAttemptId = selectionControlled\n ? (resolvedSelection?.selectedAttemptId ?? null)\n : undefined;\n // Explicit per-step focus wins; fall back to the URL-selected step so deep links\n // still pre-highlight when the summary opens the whole-workflow source.\n const highlightedLineRange =\n sourceFocus?.location ?? resolvedSelection?.step?.sourceLocation ?? null;\n const sourceSnapshot = runData.sourceSnapshot;\n async function rerun(mode: WorkflowRunRerunModeDto) {\n try {\n const run = await rerunMutation.mutateAsync({workflowRunId: runData.id, mode});\n toast.success('Re-run started');\n await navigate({\n to: '/workspaces/$wid/projects/$pid/runs/$workflowRunId',\n params: {wid: workspaceId, pid: projectId, workflowRunId: run.id},\n search: ((previous: Record<string, unknown>) =>\n withoutWorkflowRunSelectionSearch(previous)) as never,\n });\n } catch (error) {\n toast.error(error instanceof ApiError ? error.message : 'Could not start re-run');\n }\n }\n\n function selectJob(jobId: string | undefined) {\n if (!selectionControlled) {\n setSelectedJobId(jobId);\n setSelectedJobExecutionId(undefined);\n return;\n }\n\n onSelectionChange?.(\n jobId ? {jobId, runAttempt: selection?.runAttempt} : {runAttempt: selection?.runAttempt},\n );\n }\n\n function selectJobExecution(jobExecutionId: string | undefined) {\n if (!selectionControlled) {\n setSelectedJobExecutionId(jobExecutionId);\n return;\n }\n if (!selectedJob) return;\n\n onSelectionChange?.({\n jobId: selectedJob.id,\n jobExecutionId,\n runAttempt: selection?.runAttempt,\n });\n }\n\n function selectAttempt(attemptId: string | undefined) {\n if (!selectionControlled || !selectedJob || !selectedJobExecution) return;\n\n if (!attemptId) {\n onSelectionChange?.({\n jobId: selectedJob.id,\n jobExecutionId: selectedJobExecution.id,\n runAttempt: selection?.runAttempt,\n });\n return;\n }\n\n const match = findAttemptSelection(selectedJobExecution, attemptId);\n if (!match) return;\n\n onSelectionChange?.({\n jobId: selectedJob.id,\n jobExecutionId: selectedJobExecution.id,\n stepId: match.stepId,\n stepAttemptId: match.attemptId,\n runAttempt: selection?.runAttempt,\n });\n }\n\n function openWholeWorkflowSource() {\n setSourceFocus(null);\n lastSourceTriggerRef.current = sourceButtonRef.current;\n setSourcePanelOpen(true);\n }\n\n function toggleWholeWorkflowSource() {\n if (sourcePanelOpen && sourceFocus === null) {\n closeSourcePanel();\n return;\n }\n openWholeWorkflowSource();\n }\n\n function openStepSource(\n stepId: string,\n location: StepSourceLocation,\n trigger: HTMLButtonElement | null,\n ) {\n setSourceFocus({stepId, location});\n lastSourceTriggerRef.current = trigger;\n setSourcePanelOpen(true);\n }\n\n function closeSourcePanel() {\n const trigger = lastSourceTriggerRef.current;\n const fallbackTrigger = sourceButtonRef.current;\n setSourcePanelOpen(false);\n // Defer so focus lands after the panel unmounts; clear the focus only after\n // focusing so the opener button is still expanded (force-visible) on return.\n window.setTimeout(() => {\n const focusTarget = trigger?.isConnected ? trigger : fallbackTrigger;\n focusTarget?.focus();\n setSourceFocus(null);\n }, 0);\n }\n\n function cancelRun() {\n cancelMutation.mutate(undefined, {\n onError: (error) => {\n toast.error(cancelErrorMessage(error));\n },\n });\n }\n\n return (\n <>\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <WorkflowRunSummary\n workspaceId={workspaceId}\n projectId={projectId}\n run={runData}\n sourceAvailable={sourceAvailable}\n sourceOpen={sourcePanelOpen && sourceFocus === null}\n sourcePanelId={sourcePanelId}\n sourceButtonRef={sourceButtonRef}\n onSourceToggle={toggleWholeWorkflowSource}\n cancelling={cancelMutation.isPending}\n onCancel={cancelRun}\n rerunPending={rerunMutation.isPending}\n onRerun={(mode) => void rerun(mode)}\n latestAttempt={runData.latestAttempt}\n />\n {query.isError ? <WorkflowRunStaleError query={query} /> : null}\n <div className=\"min-h-0 flex-1 overflow-auto bg-background-neutral-base p-16\">\n <div className=\"mx-auto flex w-full max-w-[1280px] flex-col gap-16\">\n <JobGraph\n run={runData}\n selectedJobId={selectedJob?.id}\n onSelectedJobChange={selectJob}\n />\n {selectedJob ? (\n <JobCard\n workspaceId={workspaceId}\n job={selectedJob}\n selectedJobExecution={selectedJobExecution}\n selectedAttemptId={selectedJob.carriedOver ? undefined : selectedAttemptId}\n onSelectedJobExecutionChange={selectJobExecution}\n onSelectedAttemptChange={selectionControlled ? selectAttempt : undefined}\n sourcePanelId={sourcePanelId}\n sourceAvailable={sourceAvailable}\n focusedSourceStepId={sourceFocus?.stepId ?? null}\n onOpenStepSource={openStepSource}\n />\n ) : null}\n </div>\n </div>\n </div>\n <WorkflowSourcePanel\n id={sourcePanelId}\n source={sourceSnapshot}\n open={sourcePanelOpen && sourceAvailable}\n onClose={closeSourcePanel}\n highlightedLineRange={highlightedLineRange}\n scrollHighlightedIntoView\n />\n </>\n );\n}\n\nfunction cancelErrorMessage(error: unknown): string {\n if (error instanceof ApiError && error.code === 'run-already-finished') {\n return 'This workflow run has already finished.';\n }\n return 'Could not cancel workflow run.';\n}\n\nfunction findAttemptSelection(jobExecution: JobExecution, attemptId: string) {\n for (const step of jobExecution.steps) {\n const attempt = step.attempts.find((candidate) => candidate.id === attemptId);\n if (attempt) return {stepId: step.id, attemptId: attempt.id};\n }\n return undefined;\n}\n"],"names":["ApiError","QueryLoadError","RelativeTimeProvider","toast","useNavigate","useEffect","useId","useRef","useState","resolveJobExecution","withoutWorkflowRunSelectionSearch","useCancelWorkflowRunMutation","useRerunWorkflowRunMutation","useWorkflowRunAttemptQuery","JobGraph","WorkflowRunSummary","WorkflowSourcePanel","JobCard","resolveWorkflowRunSelection","WorkflowRunNotFound","WorkflowRunSkeleton","WorkflowRunStaleError","WorkflowRunView","workspaceId","projectId","workflowRunId","selection","onSelectionChange","runQuery","runAttempt","rerunMutation","div","className","RunViewContent","query","navigate","selectedJobId","setSelectedJobId","selectedJobExecutionId","setSelectedJobExecutionId","sourcePanelOpen","setSourcePanelOpen","sourceFocus","setSourceFocus","sourcePanelId","sourceButtonRef","lastSourceTriggerRef","selectionControlled","undefined","sourceAvailable","data","sourceSnapshot","cancelMutation","stillLocated","jobs","some","job","jobExecutions","execution","steps","step","id","stepId","sourceLocation","current","isPending","isError","error","status","subject","icon","runData","resolvedSelection","run","selectedJob","find","at","selectedJobExecution","jobExecution","selectedAttemptId","highlightedLineRange","location","rerun","mode","mutateAsync","success","to","params","wid","pid","search","previous","message","selectJob","jobId","selectJobExecution","jobExecutionId","selectAttempt","attemptId","match","findAttemptSelection","stepAttemptId","openWholeWorkflowSource","toggleWholeWorkflowSource","closeSourcePanel","openStepSource","trigger","fallbackTrigger","window","setTimeout","focusTarget","isConnected","focus","cancelRun","mutate","onError","cancelErrorMessage","sourceOpen","onSourceToggle","cancelling","onCancel","rerunPending","onRerun","latestAttempt","onSelectedJobChange","carriedOver","onSelectedJobExecutionChange","onSelectedAttemptChange","focusedSourceStepId","onOpenStepSource","source","open","onClose","scrollHighlightedIntoView","code","attempt","attempts","candidate"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-source-panel/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/workflow-source-panel/index.ts"],"sourcesContent":["export * from './workflow-source-panel.js';\n"],"names":[],"mappings":"AAAA,cAAc,6BAA6B"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type CodeBlockHighlightedLineRange } from '@shipfox/react-ui/code-block';
|
|
2
|
+
import type { WorkflowSourceSnapshot } from '#core/workflow-run.js';
|
|
3
|
+
export interface WorkflowSourcePanelProps {
|
|
4
|
+
id: string;
|
|
5
|
+
source: WorkflowSourceSnapshot | null;
|
|
6
|
+
open: boolean;
|
|
7
|
+
onClose: () => void;
|
|
8
|
+
highlightedLineRange?: CodeBlockHighlightedLineRange | null | undefined;
|
|
9
|
+
scrollHighlightedIntoView?: boolean | undefined;
|
|
10
|
+
className?: string | undefined;
|
|
11
|
+
}
|
|
12
|
+
export declare function WorkflowSourcePanel({ id, source, open, onClose, highlightedLineRange, scrollHighlightedIntoView, className, }: WorkflowSourcePanelProps): import("react").JSX.Element | null;
|
|
13
|
+
//# sourceMappingURL=workflow-source-panel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-source-panel.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-source-panel/workflow-source-panel.tsx"],"names":[],"mappings":"AACA,OAAO,EAQL,KAAK,6BAA6B,EAEnC,MAAM,8BAA8B,CAAC;AAGtC,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,uBAAuB,CAAC;AAQlE,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAAC;IACtC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,oBAAoB,CAAC,EAAE,6BAA6B,GAAG,IAAI,GAAG,SAAS,CAAC;IACxE,yBAAyB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAChD,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED,wBAAgB,mBAAmB,CAAC,EAClC,EAAE,EACF,MAAM,EACN,IAAI,EACJ,OAAO,EACP,oBAAoB,EACpB,yBAAyB,EACzB,SAAS,GACV,EAAE,wBAAwB,sCAgC1B"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from '@shipfox/react-ui/button';
|
|
3
|
+
import { CodeBlock, CodeBlockBody, CodeBlockContent, CodeBlockCopyButton, CodeBlockFilename, CodeBlockFiles, CodeBlockHeader, CodeBlockItem } from '@shipfox/react-ui/code-block';
|
|
4
|
+
import { Sheet, SheetClose, SheetContent, SheetTitle } from '@shipfox/react-ui/sheet';
|
|
5
|
+
import { cn } from '@shipfox/react-ui/utils';
|
|
6
|
+
const WORKFLOW_SOURCE_FILENAME = 'workflow.yaml';
|
|
7
|
+
const WORKFLOW_SOURCE_CODE_THEMES = {
|
|
8
|
+
light: 'vitesse-dark',
|
|
9
|
+
dark: 'vitesse-dark'
|
|
10
|
+
};
|
|
11
|
+
export function WorkflowSourcePanel({ id, source, open, onClose, highlightedLineRange, scrollHighlightedIntoView, className }) {
|
|
12
|
+
const sheetOpen = open && source !== null;
|
|
13
|
+
if (!sheetOpen) return null;
|
|
14
|
+
return /*#__PURE__*/ _jsx(Sheet, {
|
|
15
|
+
open: true,
|
|
16
|
+
onOpenChange: (nextOpen)=>{
|
|
17
|
+
if (!nextOpen) onClose();
|
|
18
|
+
},
|
|
19
|
+
children: source ? /*#__PURE__*/ _jsxs(SheetContent, {
|
|
20
|
+
id: id,
|
|
21
|
+
side: "right",
|
|
22
|
+
"aria-describedby": undefined,
|
|
23
|
+
className: cn('w-screen max-w-none border-l-0 bg-background-contrast-base p-0 shadow-none sm:w-[min(85vw,1120px)] sm:max-w-none [&_.shadow-separator-inset]:shadow-none', className),
|
|
24
|
+
children: [
|
|
25
|
+
/*#__PURE__*/ _jsx(SheetTitle, {
|
|
26
|
+
className: "sr-only",
|
|
27
|
+
children: "Workflow source"
|
|
28
|
+
}),
|
|
29
|
+
/*#__PURE__*/ _jsx(WorkflowSourcePanelContent, {
|
|
30
|
+
source: source,
|
|
31
|
+
highlightedLineRange: highlightedLineRange,
|
|
32
|
+
scrollHighlightedIntoView: scrollHighlightedIntoView
|
|
33
|
+
})
|
|
34
|
+
]
|
|
35
|
+
}) : null
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function WorkflowSourcePanelContent({ source, highlightedLineRange, scrollHighlightedIntoView }) {
|
|
39
|
+
const data = [
|
|
40
|
+
{
|
|
41
|
+
language: 'yaml',
|
|
42
|
+
filename: WORKFLOW_SOURCE_FILENAME,
|
|
43
|
+
code: source.content
|
|
44
|
+
}
|
|
45
|
+
];
|
|
46
|
+
return /*#__PURE__*/ _jsxs(CodeBlock, {
|
|
47
|
+
data: data,
|
|
48
|
+
className: "flex size-full flex-col rounded-none bg-background-contrast-base shadow-none",
|
|
49
|
+
children: [
|
|
50
|
+
/*#__PURE__*/ _jsxs(CodeBlockHeader, {
|
|
51
|
+
className: "shrink-0 border-b border-border-contrast-base bg-background-contrast-base",
|
|
52
|
+
children: [
|
|
53
|
+
/*#__PURE__*/ _jsx(CodeBlockFiles, {
|
|
54
|
+
children: (item)=>/*#__PURE__*/ _jsx(CodeBlockFilename, {
|
|
55
|
+
value: item.filename,
|
|
56
|
+
children: item.filename
|
|
57
|
+
})
|
|
58
|
+
}),
|
|
59
|
+
/*#__PURE__*/ _jsx(CodeBlockCopyButton, {}),
|
|
60
|
+
/*#__PURE__*/ _jsx(SheetClose, {
|
|
61
|
+
asChild: true,
|
|
62
|
+
children: /*#__PURE__*/ _jsx(Button, {
|
|
63
|
+
type: "button",
|
|
64
|
+
variant: "transparentMuted",
|
|
65
|
+
size: "sm",
|
|
66
|
+
iconLeft: "close",
|
|
67
|
+
"aria-label": "Close source"
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
]
|
|
71
|
+
}),
|
|
72
|
+
/*#__PURE__*/ _jsx(CodeBlockBody, {
|
|
73
|
+
className: "flex min-h-0 flex-1 overflow-auto scrollbar",
|
|
74
|
+
children: (item)=>/*#__PURE__*/ _jsx(CodeBlockItem, {
|
|
75
|
+
value: item.filename,
|
|
76
|
+
className: cn('min-h-full px-0 pb-0', '[&>div]:rounded-none [&>div]:border-0 [&>div]:bg-background-contrast-base [&>div]:dark:bg-background-contrast-base', '[&_code]:!text-sm [&_code]:!text-foreground-neutral-on-inverted [&_.line]:!text-sm [&_.line]:before:!text-sm [&_.line]:before:!text-foreground-neutral-muted'),
|
|
77
|
+
children: /*#__PURE__*/ _jsx(CodeBlockContent, {
|
|
78
|
+
language: "yaml",
|
|
79
|
+
themes: WORKFLOW_SOURCE_CODE_THEMES,
|
|
80
|
+
syntaxHighlighting: true,
|
|
81
|
+
highlightedLineRange: highlightedLineRange,
|
|
82
|
+
scrollHighlightedIntoView: scrollHighlightedIntoView,
|
|
83
|
+
children: item.code
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
})
|
|
87
|
+
]
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
//# sourceMappingURL=workflow-source-panel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/workflow-source-panel/workflow-source-panel.tsx"],"sourcesContent":["import {Button} from '@shipfox/react-ui/button';\nimport {\n CodeBlock,\n CodeBlockBody,\n CodeBlockContent,\n CodeBlockCopyButton,\n CodeBlockFilename,\n CodeBlockFiles,\n CodeBlockHeader,\n type CodeBlockHighlightedLineRange,\n CodeBlockItem,\n} from '@shipfox/react-ui/code-block';\nimport {Sheet, SheetClose, SheetContent, SheetTitle} from '@shipfox/react-ui/sheet';\nimport {cn} from '@shipfox/react-ui/utils';\nimport type {WorkflowSourceSnapshot} from '#core/workflow-run.js';\n\nconst WORKFLOW_SOURCE_FILENAME = 'workflow.yaml';\nconst WORKFLOW_SOURCE_CODE_THEMES = {\n light: 'vitesse-dark',\n dark: 'vitesse-dark',\n};\n\nexport interface WorkflowSourcePanelProps {\n id: string;\n source: WorkflowSourceSnapshot | null;\n open: boolean;\n onClose: () => void;\n highlightedLineRange?: CodeBlockHighlightedLineRange | null | undefined;\n scrollHighlightedIntoView?: boolean | undefined;\n className?: string | undefined;\n}\n\nexport function WorkflowSourcePanel({\n id,\n source,\n open,\n onClose,\n highlightedLineRange,\n scrollHighlightedIntoView,\n className,\n}: WorkflowSourcePanelProps) {\n const sheetOpen = open && source !== null;\n\n if (!sheetOpen) return null;\n\n return (\n <Sheet\n open\n onOpenChange={(nextOpen) => {\n if (!nextOpen) onClose();\n }}\n >\n {source ? (\n <SheetContent\n id={id}\n side=\"right\"\n aria-describedby={undefined}\n className={cn(\n 'w-screen max-w-none border-l-0 bg-background-contrast-base p-0 shadow-none sm:w-[min(85vw,1120px)] sm:max-w-none [&_.shadow-separator-inset]:shadow-none',\n className,\n )}\n >\n <SheetTitle className=\"sr-only\">Workflow source</SheetTitle>\n <WorkflowSourcePanelContent\n source={source}\n highlightedLineRange={highlightedLineRange}\n scrollHighlightedIntoView={scrollHighlightedIntoView}\n />\n </SheetContent>\n ) : null}\n </Sheet>\n );\n}\n\nfunction WorkflowSourcePanelContent({\n source,\n highlightedLineRange,\n scrollHighlightedIntoView,\n}: {\n source: WorkflowSourceSnapshot;\n highlightedLineRange: CodeBlockHighlightedLineRange | null | undefined;\n scrollHighlightedIntoView: boolean | undefined;\n}) {\n const data = [\n {\n language: 'yaml',\n filename: WORKFLOW_SOURCE_FILENAME,\n code: source.content,\n },\n ];\n\n return (\n <CodeBlock\n data={data}\n className=\"flex size-full flex-col rounded-none bg-background-contrast-base shadow-none\"\n >\n <CodeBlockHeader className=\"shrink-0 border-b border-border-contrast-base bg-background-contrast-base\">\n <CodeBlockFiles>\n {(item) => <CodeBlockFilename value={item.filename}>{item.filename}</CodeBlockFilename>}\n </CodeBlockFiles>\n <CodeBlockCopyButton />\n <SheetClose asChild>\n <Button\n type=\"button\"\n variant=\"transparentMuted\"\n size=\"sm\"\n iconLeft=\"close\"\n aria-label=\"Close source\"\n />\n </SheetClose>\n </CodeBlockHeader>\n <CodeBlockBody className=\"flex min-h-0 flex-1 overflow-auto scrollbar\">\n {(item) => (\n <CodeBlockItem\n value={item.filename}\n className={cn(\n 'min-h-full px-0 pb-0',\n '[&>div]:rounded-none [&>div]:border-0 [&>div]:bg-background-contrast-base [&>div]:dark:bg-background-contrast-base',\n '[&_code]:!text-sm [&_code]:!text-foreground-neutral-on-inverted [&_.line]:!text-sm [&_.line]:before:!text-sm [&_.line]:before:!text-foreground-neutral-muted',\n )}\n >\n <CodeBlockContent\n language=\"yaml\"\n themes={WORKFLOW_SOURCE_CODE_THEMES}\n syntaxHighlighting\n highlightedLineRange={highlightedLineRange}\n scrollHighlightedIntoView={scrollHighlightedIntoView}\n >\n {item.code}\n </CodeBlockContent>\n </CodeBlockItem>\n )}\n </CodeBlockBody>\n </CodeBlock>\n );\n}\n"],"names":["Button","CodeBlock","CodeBlockBody","CodeBlockContent","CodeBlockCopyButton","CodeBlockFilename","CodeBlockFiles","CodeBlockHeader","CodeBlockItem","Sheet","SheetClose","SheetContent","SheetTitle","cn","WORKFLOW_SOURCE_FILENAME","WORKFLOW_SOURCE_CODE_THEMES","light","dark","WorkflowSourcePanel","id","source","open","onClose","highlightedLineRange","scrollHighlightedIntoView","className","sheetOpen","onOpenChange","nextOpen","side","aria-describedby","undefined","WorkflowSourcePanelContent","data","language","filename","code","content","item","value","asChild","type","variant","size","iconLeft","aria-label","themes","syntaxHighlighting"],"mappings":";AAAA,SAAQA,MAAM,QAAO,2BAA2B;AAChD,SACEC,SAAS,EACTC,aAAa,EACbC,gBAAgB,EAChBC,mBAAmB,EACnBC,iBAAiB,EACjBC,cAAc,EACdC,eAAe,EAEfC,aAAa,QACR,+BAA+B;AACtC,SAAQC,KAAK,EAAEC,UAAU,EAAEC,YAAY,EAAEC,UAAU,QAAO,0BAA0B;AACpF,SAAQC,EAAE,QAAO,0BAA0B;AAG3C,MAAMC,2BAA2B;AACjC,MAAMC,8BAA8B;IAClCC,OAAO;IACPC,MAAM;AACR;AAYA,OAAO,SAASC,oBAAoB,EAClCC,EAAE,EACFC,MAAM,EACNC,IAAI,EACJC,OAAO,EACPC,oBAAoB,EACpBC,yBAAyB,EACzBC,SAAS,EACgB;IACzB,MAAMC,YAAYL,QAAQD,WAAW;IAErC,IAAI,CAACM,WAAW,OAAO;IAEvB,qBACE,KAACjB;QACCY,IAAI;QACJM,cAAc,CAACC;YACb,IAAI,CAACA,UAAUN;QACjB;kBAECF,uBACC,MAACT;YACCQ,IAAIA;YACJU,MAAK;YACLC,oBAAkBC;YAClBN,WAAWZ,GACT,4JACAY;;8BAGF,KAACb;oBAAWa,WAAU;8BAAU;;8BAChC,KAACO;oBACCZ,QAAQA;oBACRG,sBAAsBA;oBACtBC,2BAA2BA;;;aAG7B;;AAGV;AAEA,SAASQ,2BAA2B,EAClCZ,MAAM,EACNG,oBAAoB,EACpBC,yBAAyB,EAK1B;IACC,MAAMS,OAAO;QACX;YACEC,UAAU;YACVC,UAAUrB;YACVsB,MAAMhB,OAAOiB,OAAO;QACtB;KACD;IAED,qBACE,MAACpC;QACCgC,MAAMA;QACNR,WAAU;;0BAEV,MAAClB;gBAAgBkB,WAAU;;kCACzB,KAACnB;kCACE,CAACgC,qBAAS,KAACjC;gCAAkBkC,OAAOD,KAAKH,QAAQ;0CAAGG,KAAKH,QAAQ;;;kCAEpE,KAAC/B;kCACD,KAACM;wBAAW8B,OAAO;kCACjB,cAAA,KAACxC;4BACCyC,MAAK;4BACLC,SAAQ;4BACRC,MAAK;4BACLC,UAAS;4BACTC,cAAW;;;;;0BAIjB,KAAC3C;gBAAcuB,WAAU;0BACtB,CAACa,qBACA,KAAC9B;wBACC+B,OAAOD,KAAKH,QAAQ;wBACpBV,WAAWZ,GACT,wBACA,sHACA;kCAGF,cAAA,KAACV;4BACC+B,UAAS;4BACTY,QAAQ/B;4BACRgC,kBAAkB;4BAClBxB,sBAAsBA;4BACtBC,2BAA2BA;sCAE1Bc,KAAKF,IAAI;;;;;;AAOxB"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { BadgeVariant } from '@shipfox/react-ui/badge';
|
|
2
|
+
import type { DotVariant } from '@shipfox/react-ui/dot';
|
|
3
|
+
import type { WorkflowStatus } from '#core/workflow-run.js';
|
|
4
|
+
export type { WorkflowStatus };
|
|
5
|
+
export interface WorkflowStatusVisual {
|
|
6
|
+
kind: WorkflowStatus;
|
|
7
|
+
label: string;
|
|
8
|
+
dot: DotVariant;
|
|
9
|
+
badge: BadgeVariant;
|
|
10
|
+
}
|
|
11
|
+
export declare function getWorkflowStatusVisual(status: WorkflowStatus): WorkflowStatusVisual;
|
|
12
|
+
//# sourceMappingURL=status-visuals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-visuals.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-status/status-visuals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,uBAAuB,CAAC;AAE1D,YAAY,EAAC,cAAc,EAAC,CAAC;AAE7B,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,UAAU,CAAC;IAChB,KAAK,EAAE,YAAY,CAAC;CACrB;AAMD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,cAAc,GAAG,oBAAoB,CAkBpF"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// The status -> visual mapping shared by the run-header pill (color + label) and
|
|
2
|
+
// WorkflowStatusIcon (which renders the glyph per kind). The exhaustive switch turns any new
|
|
3
|
+
// status the API grows into (DESIGN.md section 9) into a compile error; reserve the `warning`
|
|
4
|
+
// tone for the queued/awaiting-* states when they land.
|
|
5
|
+
export function getWorkflowStatusVisual(status) {
|
|
6
|
+
switch(status){
|
|
7
|
+
case 'pending':
|
|
8
|
+
return {
|
|
9
|
+
kind: 'pending',
|
|
10
|
+
label: 'Pending',
|
|
11
|
+
dot: 'neutral',
|
|
12
|
+
badge: 'neutral'
|
|
13
|
+
};
|
|
14
|
+
case 'running':
|
|
15
|
+
return {
|
|
16
|
+
kind: 'running',
|
|
17
|
+
label: 'Running',
|
|
18
|
+
dot: 'info',
|
|
19
|
+
badge: 'info'
|
|
20
|
+
};
|
|
21
|
+
case 'succeeded':
|
|
22
|
+
return {
|
|
23
|
+
kind: 'succeeded',
|
|
24
|
+
label: 'Succeeded',
|
|
25
|
+
dot: 'success',
|
|
26
|
+
badge: 'success'
|
|
27
|
+
};
|
|
28
|
+
case 'failed':
|
|
29
|
+
return {
|
|
30
|
+
kind: 'failed',
|
|
31
|
+
label: 'Failed',
|
|
32
|
+
dot: 'error',
|
|
33
|
+
badge: 'error'
|
|
34
|
+
};
|
|
35
|
+
case 'cancelled':
|
|
36
|
+
return {
|
|
37
|
+
kind: 'cancelled',
|
|
38
|
+
label: 'Cancelled',
|
|
39
|
+
dot: 'neutral',
|
|
40
|
+
badge: 'neutral'
|
|
41
|
+
};
|
|
42
|
+
case 'skipped':
|
|
43
|
+
return {
|
|
44
|
+
kind: 'skipped',
|
|
45
|
+
label: 'Skipped',
|
|
46
|
+
dot: 'neutral',
|
|
47
|
+
badge: 'neutral'
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
const exhaustive = status;
|
|
51
|
+
return exhaustive;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=status-visuals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/workflow-status/status-visuals.ts"],"sourcesContent":["import type {BadgeVariant} from '@shipfox/react-ui/badge';\nimport type {DotVariant} from '@shipfox/react-ui/dot';\nimport type {WorkflowStatus} from '#core/workflow-run.js';\n\nexport type {WorkflowStatus};\n\nexport interface WorkflowStatusVisual {\n kind: WorkflowStatus;\n label: string;\n dot: DotVariant;\n badge: BadgeVariant;\n}\n\n// The status -> visual mapping shared by the run-header pill (color + label) and\n// WorkflowStatusIcon (which renders the glyph per kind). The exhaustive switch turns any new\n// status the API grows into (DESIGN.md section 9) into a compile error; reserve the `warning`\n// tone for the queued/awaiting-* states when they land.\nexport function getWorkflowStatusVisual(status: WorkflowStatus): WorkflowStatusVisual {\n switch (status) {\n case 'pending':\n return {kind: 'pending', label: 'Pending', dot: 'neutral', badge: 'neutral'};\n case 'running':\n return {kind: 'running', label: 'Running', dot: 'info', badge: 'info'};\n case 'succeeded':\n return {kind: 'succeeded', label: 'Succeeded', dot: 'success', badge: 'success'};\n case 'failed':\n return {kind: 'failed', label: 'Failed', dot: 'error', badge: 'error'};\n case 'cancelled':\n return {kind: 'cancelled', label: 'Cancelled', dot: 'neutral', badge: 'neutral'};\n case 'skipped':\n return {kind: 'skipped', label: 'Skipped', dot: 'neutral', badge: 'neutral'};\n }\n\n const exhaustive: never = status;\n return exhaustive;\n}\n"],"names":["getWorkflowStatusVisual","status","kind","label","dot","badge","exhaustive"],"mappings":"AAaA,iFAAiF;AACjF,6FAA6F;AAC7F,8FAA8F;AAC9F,wDAAwD;AACxD,OAAO,SAASA,wBAAwBC,MAAsB;IAC5D,OAAQA;QACN,KAAK;YACH,OAAO;gBAACC,MAAM;gBAAWC,OAAO;gBAAWC,KAAK;gBAAWC,OAAO;YAAS;QAC7E,KAAK;YACH,OAAO;gBAACH,MAAM;gBAAWC,OAAO;gBAAWC,KAAK;gBAAQC,OAAO;YAAM;QACvE,KAAK;YACH,OAAO;gBAACH,MAAM;gBAAaC,OAAO;gBAAaC,KAAK;gBAAWC,OAAO;YAAS;QACjF,KAAK;YACH,OAAO;gBAACH,MAAM;gBAAUC,OAAO;gBAAUC,KAAK;gBAASC,OAAO;YAAO;QACvE,KAAK;YACH,OAAO;gBAACH,MAAM;gBAAaC,OAAO;gBAAaC,KAAK;gBAAWC,OAAO;YAAS;QACjF,KAAK;YACH,OAAO;gBAACH,MAAM;gBAAWC,OAAO;gBAAWC,KAAK;gBAAWC,OAAO;YAAS;IAC/E;IAEA,MAAMC,aAAoBL;IAC1B,OAAOK;AACT"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type WorkflowStatus } from './status-visuals.js';
|
|
2
|
+
export interface WorkflowStatusIconProps {
|
|
3
|
+
status: WorkflowStatus;
|
|
4
|
+
jobMode?: 'one_shot' | 'listening';
|
|
5
|
+
/** Optical diameter in px: 14 in the DAG node and run row. */
|
|
6
|
+
size?: number;
|
|
7
|
+
/** Pulsing halo for the running state. */
|
|
8
|
+
ripple?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Wrap the indicator in a hover tooltip naming the status. Defaults on. Pass false where
|
|
11
|
+
* the status text is already visible next to it (the DAG node) to avoid a redundant tooltip.
|
|
12
|
+
*/
|
|
13
|
+
tooltip?: boolean;
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The job/run/step state indicator: an icon-in-circle glyph whose shape (not just color)
|
|
18
|
+
* names the state. Carries the status as its accessible name (`role="img"`) and, by default,
|
|
19
|
+
* a hover tooltip, so the state is reachable by pointer and assistive tech everywhere.
|
|
20
|
+
*/
|
|
21
|
+
export declare function WorkflowStatusIcon({ status, jobMode, size, ripple, tooltip, className, }: WorkflowStatusIconProps): import("react").JSX.Element;
|
|
22
|
+
//# sourceMappingURL=workflow-status-icon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-status-icon.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-status/workflow-status-icon.tsx"],"names":[],"mappings":"AAKA,OAAO,EAA0B,KAAK,cAAc,EAAC,MAAM,qBAAqB,CAAC;AAyCjF,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC;IACnC,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,OAAoB,EACpB,IAAS,EACT,MAAa,EACb,OAAc,EACd,SAAS,GACV,EAAE,uBAAuB,+BA6DzB"}
|