@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-list/workflow-run-row.tsx"],"sourcesContent":["import {TriggerSourceIcon} from '@shipfox/client-triggers';\nimport {RelativeTime} from '@shipfox/react-ui/relative-time';\nimport {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';\nimport {Code, Text} from '@shipfox/react-ui/typography';\nimport {cn} from '@shipfox/react-ui/utils';\nimport {Link} from '@tanstack/react-router';\nimport {\n useWorkflowRunDurationAccessibleLabel,\n WorkflowRunDurationLabel,\n} from '#components/workflow-run-duration-label.js';\nimport {getWorkflowStatusVisual} from '#components/workflow-status/status-visuals.js';\nimport {WorkflowStatusIcon} from '#components/workflow-status/workflow-status-icon.js';\nimport type {WorkflowRunListItem} from '#core/workflow-run.js';\nimport {withoutWorkflowRunSelectionSearch} from '#core/workflow-run-url-state.js';\n\nexport function WorkflowRunRowList({\n runs,\n workspaceId,\n projectId,\n selectedWorkflowRunId,\n}: {\n runs: WorkflowRunListItem[];\n workspaceId: string;\n projectId: string;\n selectedWorkflowRunId?: string | undefined;\n}) {\n return (\n <nav aria-label=\"Run history\">\n <ul className=\"flex flex-col gap-4 p-8\">\n {runs.map((run) => (\n <li key={run.id}>\n <WorkflowRunRow\n run={run}\n workspaceId={workspaceId}\n projectId={projectId}\n selected={run.id === selectedWorkflowRunId}\n />\n </li>\n ))}\n </ul>\n </nav>\n );\n}\n\nexport function WorkflowRunRow({\n run,\n workspaceId,\n projectId,\n selected,\n}: {\n run: WorkflowRunListItem;\n workspaceId: string;\n projectId: string;\n selected: boolean;\n}) {\n const durationLabel = useWorkflowRunDurationAccessibleLabel(run.runAttempt.displayDuration);\n const statusLabel = getWorkflowStatusVisual(run.status).label;\n const body = (\n <>\n {selected ? (\n <span\n aria-hidden=\"true\"\n className=\"absolute inset-y-8 left-0 w-3 rounded-full bg-border-highlights-interactive\"\n />\n ) : null}\n\n <div className=\"flex min-w-0 items-center gap-8\">\n <WorkflowStatusIcon status={run.status} size={14} />\n <Code variant=\"label\" bold className=\"truncate text-foreground-neutral-base\">\n {run.name}\n </Code>\n </div>\n\n <div className=\"flex min-w-0 items-center gap-8\">\n {run.triggerDisplayLabel ? (\n <TriggerLabel run={run} />\n ) : (\n <span className=\"flex min-w-0 flex-1 items-center gap-8 truncate text-foreground-neutral-muted\">\n <span aria-hidden=\"true\" className=\"size-14 shrink-0\" />\n <span className=\"sr-only\">Run updated </span>\n </span>\n )}\n <span className=\"ml-auto flex shrink-0 items-center gap-6\">\n <WorkflowRunDurationLabel\n duration={run.runAttempt.displayDuration}\n className=\"text-foreground-neutral-disabled\"\n />\n {durationLabel ? <RunMetadataSeparator /> : null}\n <Code variant=\"label\" className=\"shrink-0 text-foreground-neutral-disabled\">\n <RelativeTime value={run.updatedAt} />\n </Code>\n </span>\n </div>\n </>\n );\n\n // Optimistic manual runs (temp-<uuid>) have no detail page until the canonical row\n // replaces them on the next poll, so they render non-interactively instead of as a link\n // that would navigate to a workflow run id the detail route rejects.\n if (run.isTemporary) {\n return (\n <div className=\"relative flex w-full flex-col gap-4 rounded-8 border border-transparent px-10 py-8 text-left\">\n {body}\n </div>\n );\n }\n\n const runLink = (\n <Link\n to=\"/workspaces/$wid/projects/$pid/runs/$workflowRunId\"\n params={{wid: workspaceId, pid: projectId, workflowRunId: run.id}}\n search={\n ((previous: Record<string, unknown>) =>\n withoutWorkflowRunSelectionSearch(previous)) as never\n }\n aria-current={selected ? 'page' : undefined}\n aria-label={[run.name, statusLabel, durationLabel, run.triggerLabel]\n .filter((part): part is string => Boolean(part))\n .join(', ')}\n className={cn(\n 'group relative flex w-full flex-col gap-4 rounded-8 border border-transparent px-10 py-8 text-left transition-colors hover:bg-background-components-hover focus-visible:shadow-border-interactive-with-active focus-visible:outline-none',\n selected && 'bg-background-components-hover',\n )}\n >\n {body}\n </Link>\n );\n\n return runLink;\n}\n\nfunction TriggerLabel({run}: {run: WorkflowRunListItem}) {\n return (\n <span className=\"flex min-w-0 flex-1 items-center\">\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"flex w-fit max-w-full min-w-0 items-center gap-8 rounded-6 outline-none\">\n <TriggerSourceIcon\n provider={run.triggerProvider}\n source={run.triggerSource}\n aria-hidden\n className=\"size-14 shrink-0 text-foreground-neutral-muted\"\n />\n <Text as=\"span\" size=\"xs\" className=\"min-w-0 truncate text-foreground-neutral-subtle\">\n {run.triggerDisplayLabel}\n </Text>\n </span>\n </TooltipTrigger>\n <TriggerTooltip label={run.triggerLabel} />\n </Tooltip>\n </span>\n );\n}\n\nfunction TriggerTooltip({label}: {label: string}) {\n return (\n <TooltipContent>\n <Text as=\"span\" size=\"xs\" className=\"block max-w-[360px] break-words\">\n {label}\n </Text>\n </TooltipContent>\n );\n}\n\nfunction RunMetadataSeparator() {\n return (\n <Code\n as=\"span\"\n variant=\"label\"\n aria-hidden=\"true\"\n className=\"shrink-0 text-foreground-neutral-disabled\"\n >\n ·\n </Code>\n );\n}\n"],"names":["TriggerSourceIcon","RelativeTime","Tooltip","TooltipContent","TooltipTrigger","Code","Text","cn","Link","useWorkflowRunDurationAccessibleLabel","WorkflowRunDurationLabel","getWorkflowStatusVisual","WorkflowStatusIcon","withoutWorkflowRunSelectionSearch","WorkflowRunRowList","runs","workspaceId","projectId","selectedWorkflowRunId","nav","aria-label","ul","className","map","run","li","WorkflowRunRow","selected","id","durationLabel","runAttempt","displayDuration","statusLabel","status","label","body","span","aria-hidden","div","size","variant","bold","name","triggerDisplayLabel","TriggerLabel","duration","RunMetadataSeparator","value","updatedAt","isTemporary","runLink","to","params","wid","pid","workflowRunId","search","previous","aria-current","undefined","triggerLabel","filter","part","Boolean","join","asChild","provider","triggerProvider","source","triggerSource","as","TriggerTooltip"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-summary/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAC,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/workflow-run-summary/index.ts"],"sourcesContent":["export {WorkflowRunSummary} from './workflow-run-summary.js';\n"],"names":["WorkflowRunSummary"],"mappings":"AAAA,SAAQA,kBAAkB,QAAO,4BAA4B"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { WorkflowRunDetail } from '#core/workflow-run.js';
|
|
2
|
+
export interface WorkflowRunAttemptSwitcherProps {
|
|
3
|
+
workspaceId: string;
|
|
4
|
+
projectId: string;
|
|
5
|
+
run: WorkflowRunDetail;
|
|
6
|
+
latestAttempt: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function WorkflowRunAttemptSwitcher({ workspaceId, projectId, run, latestAttempt, }: WorkflowRunAttemptSwitcherProps): import("react").JSX.Element | null;
|
|
9
|
+
//# sourceMappingURL=workflow-run-attempt-switcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-run-attempt-switcher.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-summary/workflow-run-attempt-switcher.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAqB,iBAAiB,EAAC,MAAM,uBAAuB,CAAC;AAKjF,MAAM,WAAW,+BAA+B;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,iBAAiB,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,0BAA0B,CAAC,EACzC,WAAW,EACX,SAAS,EACT,GAAG,EACH,aAAa,GACd,EAAE,+BAA+B,sCAsDjC"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from '@shipfox/react-ui/button';
|
|
3
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@shipfox/react-ui/dropdown-menu';
|
|
4
|
+
import { RelativeTime } from '@shipfox/react-ui/relative-time';
|
|
5
|
+
import { Code, Text } from '@shipfox/react-ui/typography';
|
|
6
|
+
import { cn } from '@shipfox/react-ui/utils';
|
|
7
|
+
import { Link } from '@tanstack/react-router';
|
|
8
|
+
import { useState } from 'react';
|
|
9
|
+
import { withoutWorkflowRunSelectionSearch } from '#core/workflow-run-url-state.js';
|
|
10
|
+
import { useWorkflowRunAttemptsQuery } from '#hooks/api/workflow-runs.js';
|
|
11
|
+
import { WorkflowStatusIcon } from '../workflow-status/workflow-status-icon.js';
|
|
12
|
+
export function WorkflowRunAttemptSwitcher({ workspaceId, projectId, run, latestAttempt }) {
|
|
13
|
+
const [open, setOpen] = useState(false);
|
|
14
|
+
const attemptsQuery = useWorkflowRunAttemptsQuery({
|
|
15
|
+
workflowRunId: run.id,
|
|
16
|
+
enabled: open
|
|
17
|
+
});
|
|
18
|
+
if (latestAttempt <= 1) return null;
|
|
19
|
+
const attempts = attemptsQuery.data ?? [];
|
|
20
|
+
const latestLoadedAttempt = Math.max(0, ...attempts.map((attempt)=>attempt.attempt));
|
|
21
|
+
const maxAttempt = Math.max(latestAttempt, run.runAttempt.attempt, latestLoadedAttempt);
|
|
22
|
+
const isLoadingMissingAttempt = attempts.length > 0 && attemptsQuery.isFetching && latestLoadedAttempt < maxAttempt;
|
|
23
|
+
return /*#__PURE__*/ _jsxs(DropdownMenu, {
|
|
24
|
+
open: open,
|
|
25
|
+
onOpenChange: setOpen,
|
|
26
|
+
children: [
|
|
27
|
+
/*#__PURE__*/ _jsx(DropdownMenuTrigger, {
|
|
28
|
+
asChild: true,
|
|
29
|
+
children: /*#__PURE__*/ _jsx(Button, {
|
|
30
|
+
type: "button",
|
|
31
|
+
variant: "transparentMuted",
|
|
32
|
+
size: "2xs",
|
|
33
|
+
iconRight: "arrowDownSLine",
|
|
34
|
+
"aria-label": `Switch attempt, currently ${run.runAttempt.attempt} of ${maxAttempt}`,
|
|
35
|
+
className: "h-20 px-4 text-foreground-neutral-muted hover:text-foreground-neutral-base",
|
|
36
|
+
children: /*#__PURE__*/ _jsxs(Text, {
|
|
37
|
+
as: "span",
|
|
38
|
+
size: "xs",
|
|
39
|
+
className: "text-inherit",
|
|
40
|
+
children: [
|
|
41
|
+
"Attempt ",
|
|
42
|
+
run.runAttempt.attempt,
|
|
43
|
+
" of ",
|
|
44
|
+
maxAttempt
|
|
45
|
+
]
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
}),
|
|
49
|
+
/*#__PURE__*/ _jsxs(DropdownMenuContent, {
|
|
50
|
+
align: "start",
|
|
51
|
+
size: "lg",
|
|
52
|
+
children: [
|
|
53
|
+
attemptsQuery.isPending && attempts.length === 0 ? /*#__PURE__*/ _jsx(LoadingRow, {}) : null,
|
|
54
|
+
isLoadingMissingAttempt ? /*#__PURE__*/ _jsx(LoadingRow, {}) : null,
|
|
55
|
+
attemptsQuery.isError && attempts.length === 0 ? /*#__PURE__*/ _jsx(ErrorRow, {
|
|
56
|
+
onRetry: ()=>void attemptsQuery.refetch()
|
|
57
|
+
}) : null,
|
|
58
|
+
attempts.length > 0 ? [
|
|
59
|
+
...attempts
|
|
60
|
+
].sort((left, right)=>right.attempt - left.attempt).map((attempt)=>/*#__PURE__*/ _jsx(AttemptItem, {
|
|
61
|
+
attempt: attempt,
|
|
62
|
+
current: attempt.id === run.runAttempt.id,
|
|
63
|
+
workflowRunId: run.id,
|
|
64
|
+
workspaceId: workspaceId,
|
|
65
|
+
projectId: projectId
|
|
66
|
+
}, attempt.id)) : null
|
|
67
|
+
]
|
|
68
|
+
})
|
|
69
|
+
]
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function LoadingRow() {
|
|
73
|
+
return /*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
74
|
+
disabled: true,
|
|
75
|
+
children: /*#__PURE__*/ _jsx(Text, {
|
|
76
|
+
as: "span",
|
|
77
|
+
size: "sm",
|
|
78
|
+
className: "text-foreground-neutral-muted",
|
|
79
|
+
children: "Loading attempts..."
|
|
80
|
+
})
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function ErrorRow({ onRetry }) {
|
|
84
|
+
return /*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
85
|
+
closeOnSelect: false,
|
|
86
|
+
onSelect: onRetry,
|
|
87
|
+
children: /*#__PURE__*/ _jsx(Text, {
|
|
88
|
+
as: "span",
|
|
89
|
+
size: "sm",
|
|
90
|
+
className: "text-foreground-highlight-error",
|
|
91
|
+
children: "Could not load attempts. Retry"
|
|
92
|
+
})
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
function AttemptItem({ attempt, current, workflowRunId, workspaceId, projectId }) {
|
|
96
|
+
return /*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
97
|
+
asChild: true,
|
|
98
|
+
className: cn(current && 'text-foreground-neutral-base'),
|
|
99
|
+
children: /*#__PURE__*/ _jsxs(Link, {
|
|
100
|
+
to: "/workspaces/$wid/projects/$pid/runs/$workflowRunId",
|
|
101
|
+
params: {
|
|
102
|
+
wid: workspaceId,
|
|
103
|
+
pid: projectId,
|
|
104
|
+
workflowRunId
|
|
105
|
+
},
|
|
106
|
+
search: (previous)=>{
|
|
107
|
+
if (current) return previous;
|
|
108
|
+
return {
|
|
109
|
+
...withoutWorkflowRunSelectionSearch(previous),
|
|
110
|
+
runAttempt: attempt.attempt
|
|
111
|
+
};
|
|
112
|
+
},
|
|
113
|
+
"aria-current": current ? 'page' : undefined,
|
|
114
|
+
children: [
|
|
115
|
+
/*#__PURE__*/ _jsx(WorkflowStatusIcon, {
|
|
116
|
+
status: attempt.status,
|
|
117
|
+
size: 14,
|
|
118
|
+
tooltip: false
|
|
119
|
+
}),
|
|
120
|
+
/*#__PURE__*/ _jsxs(Code, {
|
|
121
|
+
as: "span",
|
|
122
|
+
variant: "label",
|
|
123
|
+
className: "min-w-0 flex-1 truncate text-inherit",
|
|
124
|
+
children: [
|
|
125
|
+
"Attempt ",
|
|
126
|
+
attempt.attempt
|
|
127
|
+
]
|
|
128
|
+
}),
|
|
129
|
+
/*#__PURE__*/ _jsx(RelativeTime, {
|
|
130
|
+
value: attempt.createdAt,
|
|
131
|
+
className: "shrink-0 whitespace-nowrap font-code text-xs leading-20 text-foreground-neutral-muted"
|
|
132
|
+
})
|
|
133
|
+
]
|
|
134
|
+
})
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
//# sourceMappingURL=workflow-run-attempt-switcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/workflow-run-summary/workflow-run-attempt-switcher.tsx"],"sourcesContent":["import {Button} from '@shipfox/react-ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@shipfox/react-ui/dropdown-menu';\nimport {RelativeTime} from '@shipfox/react-ui/relative-time';\nimport {Code, Text} from '@shipfox/react-ui/typography';\nimport {cn} from '@shipfox/react-ui/utils';\nimport {Link} from '@tanstack/react-router';\nimport {useState} from 'react';\nimport type {WorkflowRunAttempt, WorkflowRunDetail} from '#core/workflow-run.js';\nimport {withoutWorkflowRunSelectionSearch} from '#core/workflow-run-url-state.js';\nimport {useWorkflowRunAttemptsQuery} from '#hooks/api/workflow-runs.js';\nimport {WorkflowStatusIcon} from '../workflow-status/workflow-status-icon.js';\n\nexport interface WorkflowRunAttemptSwitcherProps {\n workspaceId: string;\n projectId: string;\n run: WorkflowRunDetail;\n latestAttempt: number;\n}\n\nexport function WorkflowRunAttemptSwitcher({\n workspaceId,\n projectId,\n run,\n latestAttempt,\n}: WorkflowRunAttemptSwitcherProps) {\n const [open, setOpen] = useState(false);\n const attemptsQuery = useWorkflowRunAttemptsQuery({\n workflowRunId: run.id,\n enabled: open,\n });\n\n if (latestAttempt <= 1) return null;\n\n const attempts = attemptsQuery.data ?? [];\n const latestLoadedAttempt = Math.max(0, ...attempts.map((attempt) => attempt.attempt));\n const maxAttempt = Math.max(latestAttempt, run.runAttempt.attempt, latestLoadedAttempt);\n const isLoadingMissingAttempt =\n attempts.length > 0 && attemptsQuery.isFetching && latestLoadedAttempt < maxAttempt;\n\n return (\n <DropdownMenu open={open} onOpenChange={setOpen}>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n variant=\"transparentMuted\"\n size=\"2xs\"\n iconRight=\"arrowDownSLine\"\n aria-label={`Switch attempt, currently ${run.runAttempt.attempt} of ${maxAttempt}`}\n className=\"h-20 px-4 text-foreground-neutral-muted hover:text-foreground-neutral-base\"\n >\n <Text as=\"span\" size=\"xs\" className=\"text-inherit\">\n Attempt {run.runAttempt.attempt} of {maxAttempt}\n </Text>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" size=\"lg\">\n {attemptsQuery.isPending && attempts.length === 0 ? <LoadingRow /> : null}\n {isLoadingMissingAttempt ? <LoadingRow /> : null}\n {attemptsQuery.isError && attempts.length === 0 ? (\n <ErrorRow onRetry={() => void attemptsQuery.refetch()} />\n ) : null}\n {attempts.length > 0\n ? [...attempts]\n .sort((left, right) => right.attempt - left.attempt)\n .map((attempt) => (\n <AttemptItem\n key={attempt.id}\n attempt={attempt}\n current={attempt.id === run.runAttempt.id}\n workflowRunId={run.id}\n workspaceId={workspaceId}\n projectId={projectId}\n />\n ))\n : null}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n\nfunction LoadingRow() {\n return (\n <DropdownMenuItem disabled>\n <Text as=\"span\" size=\"sm\" className=\"text-foreground-neutral-muted\">\n Loading attempts...\n </Text>\n </DropdownMenuItem>\n );\n}\n\nfunction ErrorRow({onRetry}: {onRetry: () => void}) {\n return (\n <DropdownMenuItem closeOnSelect={false} onSelect={onRetry}>\n <Text as=\"span\" size=\"sm\" className=\"text-foreground-highlight-error\">\n Could not load attempts. Retry\n </Text>\n </DropdownMenuItem>\n );\n}\n\nfunction AttemptItem({\n attempt,\n current,\n workflowRunId,\n workspaceId,\n projectId,\n}: {\n attempt: WorkflowRunAttempt;\n current: boolean;\n workflowRunId: string;\n workspaceId: string;\n projectId: string;\n}) {\n return (\n <DropdownMenuItem asChild className={cn(current && 'text-foreground-neutral-base')}>\n <Link\n to=\"/workspaces/$wid/projects/$pid/runs/$workflowRunId\"\n params={{wid: workspaceId, pid: projectId, workflowRunId}}\n search={\n ((previous: Record<string, unknown>) => {\n if (current) return previous;\n return {\n ...withoutWorkflowRunSelectionSearch(previous),\n runAttempt: attempt.attempt,\n };\n }) as never\n }\n aria-current={current ? 'page' : undefined}\n >\n <WorkflowStatusIcon status={attempt.status} size={14} tooltip={false} />\n <Code as=\"span\" variant=\"label\" className=\"min-w-0 flex-1 truncate text-inherit\">\n Attempt {attempt.attempt}\n </Code>\n <RelativeTime\n value={attempt.createdAt}\n className=\"shrink-0 whitespace-nowrap font-code text-xs leading-20 text-foreground-neutral-muted\"\n />\n </Link>\n </DropdownMenuItem>\n );\n}\n"],"names":["Button","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","RelativeTime","Code","Text","cn","Link","useState","withoutWorkflowRunSelectionSearch","useWorkflowRunAttemptsQuery","WorkflowStatusIcon","WorkflowRunAttemptSwitcher","workspaceId","projectId","run","latestAttempt","open","setOpen","attemptsQuery","workflowRunId","id","enabled","attempts","data","latestLoadedAttempt","Math","max","map","attempt","maxAttempt","runAttempt","isLoadingMissingAttempt","length","isFetching","onOpenChange","asChild","type","variant","size","iconRight","aria-label","className","as","align","isPending","LoadingRow","isError","ErrorRow","onRetry","refetch","sort","left","right","AttemptItem","current","disabled","closeOnSelect","onSelect","to","params","wid","pid","search","previous","aria-current","undefined","status","tooltip","value","createdAt"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { WorkflowRunRerunModeDto } from '@shipfox/api-workflows-dto';
|
|
2
|
+
import type { Ref } from 'react';
|
|
3
|
+
import { type WorkflowRunDetail } from '#core/workflow-run.js';
|
|
4
|
+
export interface WorkflowRunSummaryProps {
|
|
5
|
+
workspaceId?: string | undefined;
|
|
6
|
+
projectId?: string | undefined;
|
|
7
|
+
run: WorkflowRunDetail;
|
|
8
|
+
sourceAvailable?: boolean | undefined;
|
|
9
|
+
sourceOpen?: boolean | undefined;
|
|
10
|
+
sourcePanelId?: string | undefined;
|
|
11
|
+
sourceButtonRef?: Ref<HTMLButtonElement> | undefined;
|
|
12
|
+
onSourceToggle?: (() => void) | undefined;
|
|
13
|
+
cancelling?: boolean | undefined;
|
|
14
|
+
onCancel?: (() => void) | undefined;
|
|
15
|
+
rerunPending?: boolean | undefined;
|
|
16
|
+
onRerun?: ((mode: WorkflowRunRerunModeDto) => void) | undefined;
|
|
17
|
+
latestAttempt?: number | undefined;
|
|
18
|
+
}
|
|
19
|
+
export declare function WorkflowRunSummary({ workspaceId, projectId, run, sourceAvailable, sourceOpen, sourcePanelId, sourceButtonRef, onSourceToggle, cancelling, onCancel, rerunPending, onRerun, latestAttempt, }: WorkflowRunSummaryProps): import("react").JSX.Element;
|
|
20
|
+
//# sourceMappingURL=workflow-run-summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-run-summary.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-summary/workflow-run-summary.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,4BAA4B,CAAC;AAexE,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,OAAO,CAAC;AAE/B,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,uBAAuB,CAAC;AAW/B,MAAM,WAAW,uBAAuB;IACtC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,GAAG,EAAE,iBAAiB,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,eAAe,CAAC,EAAE,GAAG,CAAC,iBAAiB,CAAC,GAAG,SAAS,CAAC;IACrD,cAAc,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IAC1C,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IACpC,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACnC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,uBAAuB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAChE,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAED,wBAAgB,kBAAkB,CAAC,EACjC,WAAW,EACX,SAAS,EACT,GAAG,EACH,eAAuB,EACvB,UAAkB,EAClB,aAAa,EACb,eAAe,EACf,cAAc,EACd,UAAkB,EAClB,QAAQ,EACR,YAAoB,EACpB,OAAO,EACP,aAAa,GACd,EAAE,uBAAuB,+BAqIzB"}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { TriggerSourceIcon } from '@shipfox/client-triggers';
|
|
3
|
+
import { Badge } from '@shipfox/react-ui/badge';
|
|
4
|
+
import { Button } from '@shipfox/react-ui/button';
|
|
5
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@shipfox/react-ui/dropdown-menu';
|
|
6
|
+
import { useIsTextTruncated } from '@shipfox/react-ui/hooks';
|
|
7
|
+
import { RelativeTime } from '@shipfox/react-ui/relative-time';
|
|
8
|
+
import { TimeTickerProvider } from '@shipfox/react-ui/time-ticker';
|
|
9
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from '@shipfox/react-ui/tooltip';
|
|
10
|
+
import { Header, Text } from '@shipfox/react-ui/typography';
|
|
11
|
+
import { useId } from 'react';
|
|
12
|
+
import { isWorkflowRunTerminal, WORKFLOW_RUN_STATUSES } from '#core/workflow-run.js';
|
|
13
|
+
import { WorkflowRunDurationLabel } from '../workflow-run-duration-label.js';
|
|
14
|
+
import { getWorkflowStatusVisual } from '../workflow-status/status-visuals.js';
|
|
15
|
+
import { WorkflowRunAttemptSwitcher } from './workflow-run-attempt-switcher.js';
|
|
16
|
+
const STATUS_BADGE_LABEL_WIDTH_CH = Math.max(...WORKFLOW_RUN_STATUSES.map((status)=>getWorkflowStatusVisual(status).label.length));
|
|
17
|
+
export function WorkflowRunSummary({ workspaceId, projectId, run, sourceAvailable = false, sourceOpen = false, sourcePanelId, sourceButtonRef, onSourceToggle, cancelling = false, onCancel, rerunPending = false, onRerun, latestAttempt }) {
|
|
18
|
+
const headingId = useId();
|
|
19
|
+
const status = getWorkflowStatusVisual(run.runAttempt.status);
|
|
20
|
+
const action = workflowRunActionForRun(run);
|
|
21
|
+
const attemptSwitcher = latestAttempt && latestAttempt > 1 && workspaceId && projectId ? {
|
|
22
|
+
workspaceId,
|
|
23
|
+
projectId,
|
|
24
|
+
latestAttempt
|
|
25
|
+
} : null;
|
|
26
|
+
const displayDuration = run.runAttempt.displayDuration;
|
|
27
|
+
const { ref: headingTextRef, isTruncated: isHeadingTruncated } = useIsTextTruncated(run.name);
|
|
28
|
+
return /*#__PURE__*/ _jsx(TimeTickerProvider, {
|
|
29
|
+
intervalMs: 1000,
|
|
30
|
+
reducedMotionIntervalMs: 10_000,
|
|
31
|
+
children: /*#__PURE__*/ _jsx("section", {
|
|
32
|
+
"aria-labelledby": headingId,
|
|
33
|
+
className: "border-b border-border-neutral-base bg-background-subtle-base px-16 py-8",
|
|
34
|
+
children: /*#__PURE__*/ _jsxs("div", {
|
|
35
|
+
className: "grid min-w-0 grid-cols-[minmax(0,1fr)_auto] items-center gap-x-12 gap-y-4 overflow-hidden",
|
|
36
|
+
children: [
|
|
37
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
38
|
+
className: "col-start-1 row-start-1 flex min-w-0 items-center gap-8",
|
|
39
|
+
children: [
|
|
40
|
+
/*#__PURE__*/ _jsx(Badge, {
|
|
41
|
+
variant: status.badge,
|
|
42
|
+
size: "xs",
|
|
43
|
+
children: /*#__PURE__*/ _jsx("span", {
|
|
44
|
+
className: "text-center",
|
|
45
|
+
style: {
|
|
46
|
+
width: `${STATUS_BADGE_LABEL_WIDTH_CH}ch`
|
|
47
|
+
},
|
|
48
|
+
children: status.label
|
|
49
|
+
})
|
|
50
|
+
}),
|
|
51
|
+
/*#__PURE__*/ _jsxs(Tooltip, {
|
|
52
|
+
children: [
|
|
53
|
+
/*#__PURE__*/ _jsx(TooltipTrigger, {
|
|
54
|
+
asChild: true,
|
|
55
|
+
children: /*#__PURE__*/ _jsx(Header, {
|
|
56
|
+
id: headingId,
|
|
57
|
+
variant: "h3",
|
|
58
|
+
className: "min-w-0 truncate",
|
|
59
|
+
children: /*#__PURE__*/ _jsx("span", {
|
|
60
|
+
ref: headingTextRef,
|
|
61
|
+
title: isHeadingTruncated ? run.name : undefined,
|
|
62
|
+
className: "block min-w-0 truncate",
|
|
63
|
+
children: run.name
|
|
64
|
+
})
|
|
65
|
+
})
|
|
66
|
+
}),
|
|
67
|
+
isHeadingTruncated ? /*#__PURE__*/ _jsx(TooltipContent, {
|
|
68
|
+
children: /*#__PURE__*/ _jsx(Text, {
|
|
69
|
+
as: "span",
|
|
70
|
+
size: "xs",
|
|
71
|
+
className: "max-w-[360px] break-words",
|
|
72
|
+
children: run.name
|
|
73
|
+
})
|
|
74
|
+
}) : null
|
|
75
|
+
]
|
|
76
|
+
})
|
|
77
|
+
]
|
|
78
|
+
}),
|
|
79
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
80
|
+
className: "col-start-2 row-start-1 flex min-w-max items-center gap-6 justify-self-end",
|
|
81
|
+
children: [
|
|
82
|
+
/*#__PURE__*/ _jsx(WorkflowRunActionSlot, {
|
|
83
|
+
action: action,
|
|
84
|
+
cancelling: cancelling,
|
|
85
|
+
onCancel: onCancel,
|
|
86
|
+
rerunPending: rerunPending,
|
|
87
|
+
onRerun: onRerun
|
|
88
|
+
}),
|
|
89
|
+
sourceAvailable ? /*#__PURE__*/ _jsx(Button, {
|
|
90
|
+
ref: sourceButtonRef,
|
|
91
|
+
type: "button",
|
|
92
|
+
variant: "secondary",
|
|
93
|
+
size: "xs",
|
|
94
|
+
"aria-controls": sourcePanelId,
|
|
95
|
+
"aria-expanded": sourceOpen,
|
|
96
|
+
onClick: onSourceToggle,
|
|
97
|
+
children: "View source"
|
|
98
|
+
}) : null
|
|
99
|
+
]
|
|
100
|
+
}),
|
|
101
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
102
|
+
className: "col-span-2 row-start-2 flex min-w-0 items-center gap-12 overflow-hidden text-foreground-neutral-muted",
|
|
103
|
+
children: [
|
|
104
|
+
attemptSwitcher ? /*#__PURE__*/ _jsx(WorkflowRunAttemptSwitcher, {
|
|
105
|
+
workspaceId: attemptSwitcher.workspaceId,
|
|
106
|
+
projectId: attemptSwitcher.projectId,
|
|
107
|
+
run: run,
|
|
108
|
+
latestAttempt: attemptSwitcher.latestAttempt
|
|
109
|
+
}) : null,
|
|
110
|
+
run.triggerDisplayLabel ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
111
|
+
children: [
|
|
112
|
+
attemptSwitcher ? /*#__PURE__*/ _jsx(MetadataSeparator, {}) : null,
|
|
113
|
+
/*#__PURE__*/ _jsx("span", {
|
|
114
|
+
className: "min-w-0",
|
|
115
|
+
children: /*#__PURE__*/ _jsxs(Tooltip, {
|
|
116
|
+
children: [
|
|
117
|
+
/*#__PURE__*/ _jsx(TooltipTrigger, {
|
|
118
|
+
asChild: true,
|
|
119
|
+
children: /*#__PURE__*/ _jsxs("button", {
|
|
120
|
+
type: "button",
|
|
121
|
+
"aria-label": run.triggerLabel,
|
|
122
|
+
className: "inline-flex max-w-full min-w-0 items-center gap-4 rounded-6 border-0 bg-transparent p-0 text-left text-foreground-neutral-muted outline-none focus-visible:shadow-button-neutral-focus",
|
|
123
|
+
children: [
|
|
124
|
+
/*#__PURE__*/ _jsx(TriggerSourceIcon, {
|
|
125
|
+
provider: run.triggerProvider,
|
|
126
|
+
source: run.triggerSource,
|
|
127
|
+
"aria-hidden": "true",
|
|
128
|
+
className: "size-12 shrink-0"
|
|
129
|
+
}),
|
|
130
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
131
|
+
as: "span",
|
|
132
|
+
size: "xs",
|
|
133
|
+
className: "min-w-0 truncate",
|
|
134
|
+
children: run.triggerDisplayLabel
|
|
135
|
+
})
|
|
136
|
+
]
|
|
137
|
+
})
|
|
138
|
+
}),
|
|
139
|
+
/*#__PURE__*/ _jsx(TooltipContent, {
|
|
140
|
+
children: /*#__PURE__*/ _jsx(Text, {
|
|
141
|
+
as: "span",
|
|
142
|
+
size: "xs",
|
|
143
|
+
className: "block max-w-[360px] break-words",
|
|
144
|
+
children: run.triggerLabel
|
|
145
|
+
})
|
|
146
|
+
})
|
|
147
|
+
]
|
|
148
|
+
})
|
|
149
|
+
})
|
|
150
|
+
]
|
|
151
|
+
}) : null,
|
|
152
|
+
attemptSwitcher || run.triggerDisplayLabel ? /*#__PURE__*/ _jsx(MetadataSeparator, {}) : null,
|
|
153
|
+
/*#__PURE__*/ _jsx(RelativeTime, {
|
|
154
|
+
value: run.runAttempt.createdAt,
|
|
155
|
+
className: "shrink-0 whitespace-nowrap text-xs leading-20 text-foreground-neutral-muted"
|
|
156
|
+
}),
|
|
157
|
+
displayDuration ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
158
|
+
children: [
|
|
159
|
+
/*#__PURE__*/ _jsx(MetadataSeparator, {}),
|
|
160
|
+
/*#__PURE__*/ _jsx(WorkflowRunDurationLabel, {
|
|
161
|
+
duration: displayDuration,
|
|
162
|
+
className: "text-foreground-neutral-muted"
|
|
163
|
+
})
|
|
164
|
+
]
|
|
165
|
+
}) : null
|
|
166
|
+
]
|
|
167
|
+
})
|
|
168
|
+
]
|
|
169
|
+
})
|
|
170
|
+
})
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
function WorkflowRunActionSlot({ action, cancelling, onCancel, rerunPending, onRerun }) {
|
|
174
|
+
if (action === 'none') return null;
|
|
175
|
+
if (action === 'cancel') {
|
|
176
|
+
if (!onCancel) return null;
|
|
177
|
+
return /*#__PURE__*/ _jsx(Button, {
|
|
178
|
+
type: "button",
|
|
179
|
+
variant: "danger",
|
|
180
|
+
size: "xs",
|
|
181
|
+
isLoading: cancelling,
|
|
182
|
+
disabled: cancelling,
|
|
183
|
+
onClick: onCancel,
|
|
184
|
+
children: "Cancel workflow"
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
if (action === 'rerun-all') {
|
|
188
|
+
if (!onRerun) return null;
|
|
189
|
+
return /*#__PURE__*/ _jsx(Button, {
|
|
190
|
+
type: "button",
|
|
191
|
+
variant: "secondary",
|
|
192
|
+
size: "xs",
|
|
193
|
+
isLoading: rerunPending,
|
|
194
|
+
disabled: rerunPending,
|
|
195
|
+
onClick: ()=>onRerun('all'),
|
|
196
|
+
children: "Re-run workflow"
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
if (!onRerun) return null;
|
|
200
|
+
return /*#__PURE__*/ _jsxs(DropdownMenu, {
|
|
201
|
+
children: [
|
|
202
|
+
/*#__PURE__*/ _jsx(DropdownMenuTrigger, {
|
|
203
|
+
asChild: true,
|
|
204
|
+
children: /*#__PURE__*/ _jsx(Button, {
|
|
205
|
+
type: "button",
|
|
206
|
+
variant: "secondary",
|
|
207
|
+
size: "xs",
|
|
208
|
+
iconRight: "arrowDownSLine",
|
|
209
|
+
isLoading: rerunPending,
|
|
210
|
+
disabled: rerunPending,
|
|
211
|
+
children: "Re-run jobs"
|
|
212
|
+
})
|
|
213
|
+
}),
|
|
214
|
+
/*#__PURE__*/ _jsxs(DropdownMenuContent, {
|
|
215
|
+
align: "end",
|
|
216
|
+
children: [
|
|
217
|
+
/*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
218
|
+
disabled: rerunPending,
|
|
219
|
+
onSelect: ()=>onRerun('all'),
|
|
220
|
+
children: "Re-run all jobs"
|
|
221
|
+
}),
|
|
222
|
+
/*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
223
|
+
disabled: rerunPending,
|
|
224
|
+
onSelect: ()=>onRerun('failed'),
|
|
225
|
+
children: "Re-run failed jobs"
|
|
226
|
+
})
|
|
227
|
+
]
|
|
228
|
+
})
|
|
229
|
+
]
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
function workflowRunActionForRun(run) {
|
|
233
|
+
if (run.runAttempt.attempt !== run.currentAttempt) return 'none';
|
|
234
|
+
if (!isWorkflowRunTerminal(run.runAttempt.status)) return 'cancel';
|
|
235
|
+
if (run.runAttempt.status === 'succeeded' || !hasFailedOrCancelledJobs(run)) return 'rerun-all';
|
|
236
|
+
return 'rerun-menu';
|
|
237
|
+
}
|
|
238
|
+
function hasFailedOrCancelledJobs(run) {
|
|
239
|
+
if (!workflowRunHasJobs(run)) return false;
|
|
240
|
+
return run.jobs.some((job)=>job.status === 'failed' || job.status === 'cancelled');
|
|
241
|
+
}
|
|
242
|
+
function workflowRunHasJobs(run) {
|
|
243
|
+
return 'jobs' in run && Array.isArray(run.jobs);
|
|
244
|
+
}
|
|
245
|
+
function MetadataSeparator() {
|
|
246
|
+
return /*#__PURE__*/ _jsx("span", {
|
|
247
|
+
"aria-hidden": "true",
|
|
248
|
+
className: "h-12 w-px shrink-0 bg-border-neutral-base"
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
//# sourceMappingURL=workflow-run-summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/workflow-run-summary/workflow-run-summary.tsx"],"sourcesContent":["import type {WorkflowRunRerunModeDto} from '@shipfox/api-workflows-dto';\nimport {TriggerSourceIcon} from '@shipfox/client-triggers';\nimport {Badge} from '@shipfox/react-ui/badge';\nimport {Button} from '@shipfox/react-ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@shipfox/react-ui/dropdown-menu';\nimport {useIsTextTruncated} from '@shipfox/react-ui/hooks';\nimport {RelativeTime} from '@shipfox/react-ui/relative-time';\nimport {TimeTickerProvider} from '@shipfox/react-ui/time-ticker';\nimport {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';\nimport {Header, Text} from '@shipfox/react-ui/typography';\nimport type {Ref} from 'react';\nimport {useId} from 'react';\nimport {\n isWorkflowRunTerminal,\n type Job,\n WORKFLOW_RUN_STATUSES,\n type WorkflowRunDetail,\n} from '#core/workflow-run.js';\nimport {WorkflowRunDurationLabel} from '../workflow-run-duration-label.js';\nimport {getWorkflowStatusVisual} from '../workflow-status/status-visuals.js';\nimport {WorkflowRunAttemptSwitcher} from './workflow-run-attempt-switcher.js';\n\nconst STATUS_BADGE_LABEL_WIDTH_CH = Math.max(\n ...WORKFLOW_RUN_STATUSES.map((status) => getWorkflowStatusVisual(status).label.length),\n);\n\ntype WorkflowRunAction = 'cancel' | 'rerun-all' | 'rerun-menu' | 'none';\n\nexport interface WorkflowRunSummaryProps {\n workspaceId?: string | undefined;\n projectId?: string | undefined;\n run: WorkflowRunDetail;\n sourceAvailable?: boolean | undefined;\n sourceOpen?: boolean | undefined;\n sourcePanelId?: string | undefined;\n sourceButtonRef?: Ref<HTMLButtonElement> | undefined;\n onSourceToggle?: (() => void) | undefined;\n cancelling?: boolean | undefined;\n onCancel?: (() => void) | undefined;\n rerunPending?: boolean | undefined;\n onRerun?: ((mode: WorkflowRunRerunModeDto) => void) | undefined;\n latestAttempt?: number | undefined;\n}\n\nexport function WorkflowRunSummary({\n workspaceId,\n projectId,\n run,\n sourceAvailable = false,\n sourceOpen = false,\n sourcePanelId,\n sourceButtonRef,\n onSourceToggle,\n cancelling = false,\n onCancel,\n rerunPending = false,\n onRerun,\n latestAttempt,\n}: WorkflowRunSummaryProps) {\n const headingId = useId();\n const status = getWorkflowStatusVisual(run.runAttempt.status);\n const action = workflowRunActionForRun(run);\n const attemptSwitcher =\n latestAttempt && latestAttempt > 1 && workspaceId && projectId\n ? {workspaceId, projectId, latestAttempt}\n : null;\n const displayDuration = run.runAttempt.displayDuration;\n const {ref: headingTextRef, isTruncated: isHeadingTruncated} =\n useIsTextTruncated<HTMLSpanElement>(run.name);\n\n return (\n <TimeTickerProvider intervalMs={1000} reducedMotionIntervalMs={10_000}>\n <section\n aria-labelledby={headingId}\n className=\"border-b border-border-neutral-base bg-background-subtle-base px-16 py-8\"\n >\n <div className=\"grid min-w-0 grid-cols-[minmax(0,1fr)_auto] items-center gap-x-12 gap-y-4 overflow-hidden\">\n <div className=\"col-start-1 row-start-1 flex min-w-0 items-center gap-8\">\n <Badge variant={status.badge} size=\"xs\">\n <span className=\"text-center\" style={{width: `${STATUS_BADGE_LABEL_WIDTH_CH}ch`}}>\n {status.label}\n </span>\n </Badge>\n\n <Tooltip>\n <TooltipTrigger asChild>\n <Header id={headingId} variant=\"h3\" className=\"min-w-0 truncate\">\n <span\n ref={headingTextRef}\n title={isHeadingTruncated ? run.name : undefined}\n className=\"block min-w-0 truncate\"\n >\n {run.name}\n </span>\n </Header>\n </TooltipTrigger>\n {isHeadingTruncated ? (\n <TooltipContent>\n <Text as=\"span\" size=\"xs\" className=\"max-w-[360px] break-words\">\n {run.name}\n </Text>\n </TooltipContent>\n ) : null}\n </Tooltip>\n </div>\n\n <div className=\"col-start-2 row-start-1 flex min-w-max items-center gap-6 justify-self-end\">\n <WorkflowRunActionSlot\n action={action}\n cancelling={cancelling}\n onCancel={onCancel}\n rerunPending={rerunPending}\n onRerun={onRerun}\n />\n {sourceAvailable ? (\n <Button\n ref={sourceButtonRef}\n type=\"button\"\n variant=\"secondary\"\n size=\"xs\"\n aria-controls={sourcePanelId}\n aria-expanded={sourceOpen}\n onClick={onSourceToggle}\n >\n View source\n </Button>\n ) : null}\n </div>\n\n <div className=\"col-span-2 row-start-2 flex min-w-0 items-center gap-12 overflow-hidden text-foreground-neutral-muted\">\n {attemptSwitcher ? (\n <WorkflowRunAttemptSwitcher\n workspaceId={attemptSwitcher.workspaceId}\n projectId={attemptSwitcher.projectId}\n run={run}\n latestAttempt={attemptSwitcher.latestAttempt}\n />\n ) : null}\n\n {run.triggerDisplayLabel ? (\n <>\n {attemptSwitcher ? <MetadataSeparator /> : null}\n <span className=\"min-w-0\">\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n aria-label={run.triggerLabel}\n className=\"inline-flex max-w-full min-w-0 items-center gap-4 rounded-6 border-0 bg-transparent p-0 text-left text-foreground-neutral-muted outline-none focus-visible:shadow-button-neutral-focus\"\n >\n <TriggerSourceIcon\n provider={run.triggerProvider}\n source={run.triggerSource}\n aria-hidden=\"true\"\n className=\"size-12 shrink-0\"\n />\n <Text as=\"span\" size=\"xs\" className=\"min-w-0 truncate\">\n {run.triggerDisplayLabel}\n </Text>\n </button>\n </TooltipTrigger>\n <TooltipContent>\n <Text as=\"span\" size=\"xs\" className=\"block max-w-[360px] break-words\">\n {run.triggerLabel}\n </Text>\n </TooltipContent>\n </Tooltip>\n </span>\n </>\n ) : null}\n\n {attemptSwitcher || run.triggerDisplayLabel ? <MetadataSeparator /> : null}\n <RelativeTime\n value={run.runAttempt.createdAt}\n className=\"shrink-0 whitespace-nowrap text-xs leading-20 text-foreground-neutral-muted\"\n />\n\n {displayDuration ? (\n <>\n <MetadataSeparator />\n <WorkflowRunDurationLabel\n duration={displayDuration}\n className=\"text-foreground-neutral-muted\"\n />\n </>\n ) : null}\n </div>\n </div>\n </section>\n </TimeTickerProvider>\n );\n}\n\nfunction WorkflowRunActionSlot({\n action,\n cancelling,\n onCancel,\n rerunPending,\n onRerun,\n}: {\n action: WorkflowRunAction;\n cancelling: boolean;\n onCancel?: (() => void) | undefined;\n rerunPending: boolean;\n onRerun?: ((mode: WorkflowRunRerunModeDto) => void) | undefined;\n}) {\n if (action === 'none') return null;\n\n if (action === 'cancel') {\n if (!onCancel) return null;\n\n return (\n <Button\n type=\"button\"\n variant=\"danger\"\n size=\"xs\"\n isLoading={cancelling}\n disabled={cancelling}\n onClick={onCancel}\n >\n Cancel workflow\n </Button>\n );\n }\n\n if (action === 'rerun-all') {\n if (!onRerun) return null;\n\n return (\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"xs\"\n isLoading={rerunPending}\n disabled={rerunPending}\n onClick={() => onRerun('all')}\n >\n Re-run workflow\n </Button>\n );\n }\n\n if (!onRerun) return null;\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"xs\"\n iconRight=\"arrowDownSLine\"\n isLoading={rerunPending}\n disabled={rerunPending}\n >\n Re-run jobs\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem disabled={rerunPending} onSelect={() => onRerun('all')}>\n Re-run all jobs\n </DropdownMenuItem>\n <DropdownMenuItem disabled={rerunPending} onSelect={() => onRerun('failed')}>\n Re-run failed jobs\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n\nfunction workflowRunActionForRun(run: WorkflowRunDetail): WorkflowRunAction {\n if (run.runAttempt.attempt !== run.currentAttempt) return 'none';\n if (!isWorkflowRunTerminal(run.runAttempt.status)) return 'cancel';\n if (run.runAttempt.status === 'succeeded' || !hasFailedOrCancelledJobs(run)) return 'rerun-all';\n return 'rerun-menu';\n}\n\nfunction hasFailedOrCancelledJobs(run: WorkflowRunDetail): boolean {\n if (!workflowRunHasJobs(run)) return false;\n\n return run.jobs.some((job) => job.status === 'failed' || job.status === 'cancelled');\n}\n\nfunction workflowRunHasJobs(run: WorkflowRunDetail): run is WorkflowRunDetail & {jobs: Job[]} {\n return 'jobs' in run && Array.isArray(run.jobs);\n}\n\nfunction MetadataSeparator() {\n return <span aria-hidden=\"true\" className=\"h-12 w-px shrink-0 bg-border-neutral-base\" />;\n}\n"],"names":["TriggerSourceIcon","Badge","Button","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","useIsTextTruncated","RelativeTime","TimeTickerProvider","Tooltip","TooltipContent","TooltipTrigger","Header","Text","useId","isWorkflowRunTerminal","WORKFLOW_RUN_STATUSES","WorkflowRunDurationLabel","getWorkflowStatusVisual","WorkflowRunAttemptSwitcher","STATUS_BADGE_LABEL_WIDTH_CH","Math","max","map","status","label","length","WorkflowRunSummary","workspaceId","projectId","run","sourceAvailable","sourceOpen","sourcePanelId","sourceButtonRef","onSourceToggle","cancelling","onCancel","rerunPending","onRerun","latestAttempt","headingId","runAttempt","action","workflowRunActionForRun","attemptSwitcher","displayDuration","ref","headingTextRef","isTruncated","isHeadingTruncated","name","intervalMs","reducedMotionIntervalMs","section","aria-labelledby","className","div","variant","badge","size","span","style","width","asChild","id","title","undefined","as","WorkflowRunActionSlot","type","aria-controls","aria-expanded","onClick","triggerDisplayLabel","MetadataSeparator","button","aria-label","triggerLabel","provider","triggerProvider","source","triggerSource","aria-hidden","value","createdAt","duration","isLoading","disabled","iconRight","align","onSelect","attempt","currentAttempt","hasFailedOrCancelledJobs","workflowRunHasJobs","jobs","some","job","Array","isArray"],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AgentStepConfig, StepError } from '#core/workflow-run.js';
|
|
2
|
+
export declare function AgentConfigFailureCallout({ workspaceId, config, error, }: {
|
|
3
|
+
workspaceId: string;
|
|
4
|
+
config: AgentStepConfig | null;
|
|
5
|
+
error: StepError | null;
|
|
6
|
+
}): import("react").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=agent-config-failure-callout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-config-failure-callout.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-view/agent-config-failure-callout.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAC,eAAe,EAAE,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAEtE,wBAAgB,yBAAyB,CAAC,EACxC,WAAW,EACX,MAAM,EACN,KAAK,GACN,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;CACzB,+BAoBA"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Alert, AlertActions, AlertContent, AlertDescription, AlertTitle } from '@shipfox/react-ui/alert';
|
|
3
|
+
import { Button } from '@shipfox/react-ui/button';
|
|
4
|
+
import { Link } from '@tanstack/react-router';
|
|
5
|
+
export function AgentConfigFailureCallout({ workspaceId, config, error }) {
|
|
6
|
+
const copy = agentConfigFailureCopy(config, error);
|
|
7
|
+
return /*#__PURE__*/ _jsx(Alert, {
|
|
8
|
+
variant: "warning",
|
|
9
|
+
animated: false,
|
|
10
|
+
className: "px-10 py-8",
|
|
11
|
+
children: /*#__PURE__*/ _jsxs(AlertContent, {
|
|
12
|
+
children: [
|
|
13
|
+
/*#__PURE__*/ _jsx(AlertTitle, {
|
|
14
|
+
children: copy.title
|
|
15
|
+
}),
|
|
16
|
+
/*#__PURE__*/ _jsx(AlertDescription, {
|
|
17
|
+
children: copy.description
|
|
18
|
+
}),
|
|
19
|
+
copy.showProviderCta ? /*#__PURE__*/ _jsx(AlertActions, {
|
|
20
|
+
children: /*#__PURE__*/ _jsx(Button, {
|
|
21
|
+
asChild: true,
|
|
22
|
+
size: "2xs",
|
|
23
|
+
variant: "secondary",
|
|
24
|
+
iconRight: "chevronRight",
|
|
25
|
+
children: /*#__PURE__*/ _jsx(Link, {
|
|
26
|
+
to: "/workspaces/$wid/settings/agents",
|
|
27
|
+
params: {
|
|
28
|
+
wid: workspaceId
|
|
29
|
+
},
|
|
30
|
+
children: "Configure Agents"
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
}) : null
|
|
34
|
+
]
|
|
35
|
+
})
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function agentConfigFailureCopy(config, error) {
|
|
39
|
+
const provider = configValue(config?.provider, 'the selected provider');
|
|
40
|
+
const model = configValue(config?.model, 'the selected model');
|
|
41
|
+
switch(error?.agentConfigIssue){
|
|
42
|
+
case 'provider_not_configured':
|
|
43
|
+
return {
|
|
44
|
+
title: `Configure credentials for ${provider}`,
|
|
45
|
+
description: `This step uses ${provider}, but no workspace credentials are configured for that model provider. Configure ${provider} in Agents, then re-run the workflow.`,
|
|
46
|
+
showProviderCta: true
|
|
47
|
+
};
|
|
48
|
+
case 'credentials_invalid':
|
|
49
|
+
return {
|
|
50
|
+
title: `Update credentials for ${provider}`,
|
|
51
|
+
description: `This step uses ${provider}, but the saved credentials could not be used. Reconfigure ${provider} in Agents, then re-run the workflow.`,
|
|
52
|
+
showProviderCta: true
|
|
53
|
+
};
|
|
54
|
+
case 'provider_unsupported':
|
|
55
|
+
return {
|
|
56
|
+
title: `Choose a supported model provider`,
|
|
57
|
+
description: `This step references ${provider}, which is not available to the agent runner. Update the workflow to use a supported provider, then re-run it.`,
|
|
58
|
+
showProviderCta: false
|
|
59
|
+
};
|
|
60
|
+
case 'model_unavailable':
|
|
61
|
+
return {
|
|
62
|
+
title: `Choose an available model`,
|
|
63
|
+
description: `This step uses ${model} with ${provider}, but that model is not available for the provider. Update the model or provider in the workflow, then re-run it.`,
|
|
64
|
+
showProviderCta: false
|
|
65
|
+
};
|
|
66
|
+
case 'step_config_invalid':
|
|
67
|
+
return {
|
|
68
|
+
title: "Fix this step's agent settings",
|
|
69
|
+
description: 'Make sure the step has a prompt, provider, model, and thinking value, then re-run the workflow.',
|
|
70
|
+
showProviderCta: false
|
|
71
|
+
};
|
|
72
|
+
case undefined:
|
|
73
|
+
return {
|
|
74
|
+
title: "We couldn't load the agent configuration for this step",
|
|
75
|
+
description: 'Make sure the step has a prompt, provider, model, and thinking value. Then configure credentials for the model provider in Agents and re-run the workflow.',
|
|
76
|
+
showProviderCta: true
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function configValue(value, fallback) {
|
|
81
|
+
return value ?? fallback;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
//# sourceMappingURL=agent-config-failure-callout.js.map
|