@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/agent-config-failure-callout.tsx"],"sourcesContent":["import {\n Alert,\n AlertActions,\n AlertContent,\n AlertDescription,\n AlertTitle,\n} from '@shipfox/react-ui/alert';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Link} from '@tanstack/react-router';\nimport type {AgentStepConfig, StepError} from '#core/workflow-run.js';\n\nexport function AgentConfigFailureCallout({\n workspaceId,\n config,\n error,\n}: {\n workspaceId: string;\n config: AgentStepConfig | null;\n error: StepError | null;\n}) {\n const copy = agentConfigFailureCopy(config, error);\n\n return (\n <Alert variant=\"warning\" animated={false} className=\"px-10 py-8\">\n <AlertContent>\n <AlertTitle>{copy.title}</AlertTitle>\n <AlertDescription>{copy.description}</AlertDescription>\n {copy.showProviderCta ? (\n <AlertActions>\n <Button asChild size=\"2xs\" variant=\"secondary\" iconRight=\"chevronRight\">\n <Link to=\"/workspaces/$wid/settings/agents\" params={{wid: workspaceId}}>\n Configure Agents\n </Link>\n </Button>\n </AlertActions>\n ) : null}\n </AlertContent>\n </Alert>\n );\n}\n\nfunction agentConfigFailureCopy(\n config: AgentStepConfig | null,\n error: StepError | null,\n): {title: string; description: string; showProviderCta: boolean} {\n const provider = configValue(config?.provider, 'the selected provider');\n const model = configValue(config?.model, 'the selected model');\n\n switch (error?.agentConfigIssue) {\n case 'provider_not_configured':\n return {\n title: `Configure credentials for ${provider}`,\n description: `This step uses ${provider}, but no workspace credentials are configured for that model provider. Configure ${provider} in Agents, then re-run the workflow.`,\n showProviderCta: true,\n };\n case 'credentials_invalid':\n return {\n title: `Update credentials for ${provider}`,\n description: `This step uses ${provider}, but the saved credentials could not be used. Reconfigure ${provider} in Agents, then re-run the workflow.`,\n showProviderCta: true,\n };\n case 'provider_unsupported':\n return {\n title: `Choose a supported model provider`,\n 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.`,\n showProviderCta: false,\n };\n case 'model_unavailable':\n return {\n title: `Choose an available model`,\n 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.`,\n showProviderCta: false,\n };\n case 'step_config_invalid':\n return {\n title: \"Fix this step's agent settings\",\n description:\n 'Make sure the step has a prompt, provider, model, and thinking value, then re-run the workflow.',\n showProviderCta: false,\n };\n case undefined:\n return {\n title: \"We couldn't load the agent configuration for this step\",\n description:\n '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.',\n showProviderCta: true,\n };\n }\n}\n\nfunction configValue(value: string | null | undefined, fallback: string): string {\n return value ?? fallback;\n}\n"],"names":["Alert","AlertActions","AlertContent","AlertDescription","AlertTitle","Button","Link","AgentConfigFailureCallout","workspaceId","config","error","copy","agentConfigFailureCopy","variant","animated","className","title","description","showProviderCta","asChild","size","iconRight","to","params","wid","provider","configValue","model","agentConfigIssue","undefined","value","fallback"],"mappings":";AAAA,SACEA,KAAK,EACLC,YAAY,EACZC,YAAY,EACZC,gBAAgB,EAChBC,UAAU,QACL,0BAA0B;AACjC,SAAQC,MAAM,QAAO,2BAA2B;AAChD,SAAQC,IAAI,QAAO,yBAAyB;AAG5C,OAAO,SAASC,0BAA0B,EACxCC,WAAW,EACXC,MAAM,EACNC,KAAK,EAKN;IACC,MAAMC,OAAOC,uBAAuBH,QAAQC;IAE5C,qBACE,KAACV;QAAMa,SAAQ;QAAUC,UAAU;QAAOC,WAAU;kBAClD,cAAA,MAACb;;8BACC,KAACE;8BAAYO,KAAKK,KAAK;;8BACvB,KAACb;8BAAkBQ,KAAKM,WAAW;;gBAClCN,KAAKO,eAAe,iBACnB,KAACjB;8BACC,cAAA,KAACI;wBAAOc,OAAO;wBAACC,MAAK;wBAAMP,SAAQ;wBAAYQ,WAAU;kCACvD,cAAA,KAACf;4BAAKgB,IAAG;4BAAmCC,QAAQ;gCAACC,KAAKhB;4BAAW;sCAAG;;;qBAK1E;;;;AAIZ;AAEA,SAASI,uBACPH,MAA8B,EAC9BC,KAAuB;IAEvB,MAAMe,WAAWC,YAAYjB,QAAQgB,UAAU;IAC/C,MAAME,QAAQD,YAAYjB,QAAQkB,OAAO;IAEzC,OAAQjB,OAAOkB;QACb,KAAK;YACH,OAAO;gBACLZ,OAAO,CAAC,0BAA0B,EAAES,UAAU;gBAC9CR,aAAa,CAAC,eAAe,EAAEQ,SAAS,iFAAiF,EAAEA,SAAS,qCAAqC,CAAC;gBAC1KP,iBAAiB;YACnB;QACF,KAAK;YACH,OAAO;gBACLF,OAAO,CAAC,uBAAuB,EAAES,UAAU;gBAC3CR,aAAa,CAAC,eAAe,EAAEQ,SAAS,2DAA2D,EAAEA,SAAS,qCAAqC,CAAC;gBACpJP,iBAAiB;YACnB;QACF,KAAK;YACH,OAAO;gBACLF,OAAO,CAAC,iCAAiC,CAAC;gBAC1CC,aAAa,CAAC,qBAAqB,EAAEQ,SAAS,8GAA8G,CAAC;gBAC7JP,iBAAiB;YACnB;QACF,KAAK;YACH,OAAO;gBACLF,OAAO,CAAC,yBAAyB,CAAC;gBAClCC,aAAa,CAAC,eAAe,EAAEU,MAAM,MAAM,EAAEF,SAAS,iHAAiH,CAAC;gBACxKP,iBAAiB;YACnB;QACF,KAAK;YACH,OAAO;gBACLF,OAAO;gBACPC,aACE;gBACFC,iBAAiB;YACnB;QACF,KAAKW;YACH,OAAO;gBACLb,OAAO;gBACPC,aACE;gBACFC,iBAAiB;YACnB;IACJ;AACF;AAEA,SAASQ,YAAYI,KAAgC,EAAEC,QAAgB;IACrE,OAAOD,SAASC;AAClB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-view/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,eAAe,CAAC;AACtC,OAAO,EAAC,eAAe,EAAC,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/workflow-run-view/index.ts"],"sourcesContent":["export {JobCard} from './job-card.js';\nexport {WorkflowRunView} from './workflow-run-view.js';\n"],"names":["JobCard","WorkflowRunView"],"mappings":"AAAA,SAAQA,OAAO,QAAO,gBAAgB;AACtC,SAAQC,eAAe,QAAO,yBAAyB"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { type Job, type JobExecution, type StepSourceLocation } from '#core/workflow-run.js';
|
|
3
|
+
import { type StepExpandedContext } from '../step-list/index.js';
|
|
4
|
+
export declare function JobCard({ workspaceId, job, selectedJobExecution, selectedAttemptId, onSelectedJobExecutionChange, onSelectedAttemptChange, renderExpandedStep, sourcePanelId, sourceAvailable, focusedSourceStepId, onOpenStepSource, }: {
|
|
5
|
+
workspaceId: string;
|
|
6
|
+
job: Job;
|
|
7
|
+
selectedJobExecution: JobExecution | undefined;
|
|
8
|
+
selectedAttemptId: string | null | undefined;
|
|
9
|
+
onSelectedJobExecutionChange: ((jobExecutionId: string | undefined) => void) | undefined;
|
|
10
|
+
onSelectedAttemptChange: ((attemptId: string | undefined) => void) | undefined;
|
|
11
|
+
renderExpandedStep?: ((context: StepExpandedContext) => ReactNode) | undefined;
|
|
12
|
+
sourcePanelId?: string | undefined;
|
|
13
|
+
sourceAvailable?: boolean | undefined;
|
|
14
|
+
focusedSourceStepId?: string | null | undefined;
|
|
15
|
+
onOpenStepSource?: ((stepId: string, location: StepSourceLocation, trigger: HTMLButtonElement | null) => void) | undefined;
|
|
16
|
+
}): import("react").JSX.Element;
|
|
17
|
+
//# sourceMappingURL=job-card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-card.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-view/job-card.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAGrC,OAAO,EACL,KAAK,GAAG,EACR,KAAK,YAAY,EAIjB,KAAK,kBAAkB,EAIxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAC,KAAK,mBAAmB,EAAoC,MAAM,uBAAuB,CAAC;AAelG,wBAAgB,OAAO,CAAC,EACtB,WAAW,EACX,GAAG,EACH,oBAAoB,EACpB,iBAAiB,EACjB,4BAA4B,EAC5B,uBAAuB,EACvB,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,gBAAgB,GACjB,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,GAAG,CAAC;IACT,oBAAoB,EAAE,YAAY,GAAG,SAAS,CAAC;IAC/C,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC7C,4BAA4B,EAAE,CAAC,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACzF,uBAAuB,EAAE,CAAC,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC/E,kBAAkB,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,mBAAmB,KAAK,SAAS,CAAC,GAAG,SAAS,CAAC;IAC/E,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,eAAe,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChD,gBAAgB,CAAC,EACb,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,kBAAkB,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI,KAAK,IAAI,CAAC,GAC3F,SAAS,CAAC;CACf,+BAkIA"}
|
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { agentConfigIssueSchema, stepErrorReasonSchema } from '@shipfox/api-workflows-dto';
|
|
3
|
+
import { TriggerSourceIcon } from '@shipfox/client-triggers';
|
|
4
|
+
import { Badge } from '@shipfox/react-ui/badge';
|
|
5
|
+
import { Button } from '@shipfox/react-ui/button';
|
|
6
|
+
import { EmptyState } from '@shipfox/react-ui/empty-state';
|
|
7
|
+
import { Icon } from '@shipfox/react-ui/icon';
|
|
8
|
+
import { RelativeTime } from '@shipfox/react-ui/relative-time';
|
|
9
|
+
import { useTimeTick } from '@shipfox/react-ui/time-ticker';
|
|
10
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from '@shipfox/react-ui/tooltip';
|
|
11
|
+
import { Text } from '@shipfox/react-ui/typography';
|
|
12
|
+
import { Fragment, useId, useRef, useState } from 'react';
|
|
13
|
+
import { getWorkflowStatusVisual } from '#components/workflow-status/status-visuals.js';
|
|
14
|
+
import { WORKFLOW_JOB_STATUSES, workflowRunTriggerDisplayLabel, workflowRunTriggerLabel } from '#core/workflow-run.js';
|
|
15
|
+
import { StepList } from '../step-list/index.js';
|
|
16
|
+
import { AgentConfigFailureCallout } from './agent-config-failure-callout.js';
|
|
17
|
+
import { JobExecutionSwitcher } from './job-execution-switcher.js';
|
|
18
|
+
import { formatJobExecutionTime, JobExecutionTimeText } from './job-execution-time-text.js';
|
|
19
|
+
import { StepAttemptLogPanel } from './step-attempt-log-panel.js';
|
|
20
|
+
const STATUS_BADGE_LABEL_WIDTH_CH = Math.max(...WORKFLOW_JOB_STATUSES.map((status)=>getWorkflowStatusVisual(status).label.length));
|
|
21
|
+
export function JobCard({ workspaceId, job, selectedJobExecution, selectedAttemptId, onSelectedJobExecutionChange, onSelectedAttemptChange, renderExpandedStep, sourcePanelId, sourceAvailable, focusedSourceStepId, onOpenStepSource }) {
|
|
22
|
+
const titleId = useId();
|
|
23
|
+
const sourceButtonRef = useRef(null);
|
|
24
|
+
const [localSelectedAttempt, setLocalSelectedAttempt] = useState({
|
|
25
|
+
jobExecutionId: undefined,
|
|
26
|
+
attemptId: null
|
|
27
|
+
});
|
|
28
|
+
const selectedExecutionStatus = selectedJobExecution?.status ?? job.status;
|
|
29
|
+
const effectiveSelectedAttemptId = selectedAttemptId === undefined && localSelectedAttempt.jobExecutionId === selectedJobExecution?.id ? localSelectedAttempt.attemptId : selectedAttemptId;
|
|
30
|
+
const selectedSourceAction = selectedStepSourceAction(selectedJobExecution, effectiveSelectedAttemptId);
|
|
31
|
+
const defaultRenderExpandedStep = ({ step, stepId, attempt, attemptError, attemptStatus, carriedOver })=>carriedOver ? /*#__PURE__*/ _jsx(CarriedOverStepPanel, {}) : /*#__PURE__*/ _jsx(StepAttemptDetailPanel, {
|
|
32
|
+
workspaceId: workspaceId,
|
|
33
|
+
step: step,
|
|
34
|
+
stepId: stepId,
|
|
35
|
+
attempt: attempt,
|
|
36
|
+
attemptError: attemptError,
|
|
37
|
+
attemptStatus: attemptStatus
|
|
38
|
+
});
|
|
39
|
+
function selectAttempt(attemptId) {
|
|
40
|
+
if (selectedAttemptId === undefined) {
|
|
41
|
+
setLocalSelectedAttempt({
|
|
42
|
+
jobExecutionId: selectedJobExecution?.id,
|
|
43
|
+
attemptId: attemptId ?? null
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
onSelectedAttemptChange?.(attemptId);
|
|
47
|
+
}
|
|
48
|
+
return /*#__PURE__*/ _jsxs("section", {
|
|
49
|
+
"aria-labelledby": titleId,
|
|
50
|
+
className: "flex min-h-0 flex-col rounded-8 border border-border-neutral-base bg-background-components-base",
|
|
51
|
+
children: [
|
|
52
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
53
|
+
className: "grid min-h-52 min-w-0 grid-cols-1 gap-y-4 px-16 py-12",
|
|
54
|
+
children: [
|
|
55
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
56
|
+
className: "flex min-w-0 flex-wrap items-center justify-between gap-10",
|
|
57
|
+
children: [
|
|
58
|
+
job.mode === 'listening' && job.jobExecutions.length > 0 && onSelectedJobExecutionChange ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
59
|
+
children: [
|
|
60
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
61
|
+
as: "h2",
|
|
62
|
+
id: titleId,
|
|
63
|
+
size: "sm",
|
|
64
|
+
bold: true,
|
|
65
|
+
className: "sr-only",
|
|
66
|
+
children: job.displayName
|
|
67
|
+
}),
|
|
68
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
69
|
+
className: "flex min-w-0 items-center gap-8",
|
|
70
|
+
children: [
|
|
71
|
+
/*#__PURE__*/ _jsx(JobStatusBadge, {
|
|
72
|
+
status: selectedExecutionStatus
|
|
73
|
+
}),
|
|
74
|
+
/*#__PURE__*/ _jsx(JobExecutionSwitcher, {
|
|
75
|
+
job: job,
|
|
76
|
+
selectedJobExecution: selectedJobExecution?.id ?? null,
|
|
77
|
+
onSelectedJobExecutionChange: onSelectedJobExecutionChange,
|
|
78
|
+
variant: "title"
|
|
79
|
+
})
|
|
80
|
+
]
|
|
81
|
+
})
|
|
82
|
+
]
|
|
83
|
+
}) : /*#__PURE__*/ _jsxs("div", {
|
|
84
|
+
className: "flex min-w-0 items-center gap-8",
|
|
85
|
+
children: [
|
|
86
|
+
/*#__PURE__*/ _jsx(JobStatusBadge, {
|
|
87
|
+
status: selectedExecutionStatus
|
|
88
|
+
}),
|
|
89
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
90
|
+
as: "h2",
|
|
91
|
+
id: titleId,
|
|
92
|
+
size: "sm",
|
|
93
|
+
bold: true,
|
|
94
|
+
className: "min-w-0 truncate text-foreground-neutral-base",
|
|
95
|
+
children: job.displayName
|
|
96
|
+
})
|
|
97
|
+
]
|
|
98
|
+
}),
|
|
99
|
+
sourceAvailable && selectedSourceAction && sourcePanelId && onOpenStepSource ? /*#__PURE__*/ _jsx("div", {
|
|
100
|
+
className: "flex min-w-max items-center gap-6",
|
|
101
|
+
children: /*#__PURE__*/ _jsx(Button, {
|
|
102
|
+
ref: sourceButtonRef,
|
|
103
|
+
type: "button",
|
|
104
|
+
variant: "secondary",
|
|
105
|
+
size: "xs",
|
|
106
|
+
"aria-controls": sourcePanelId,
|
|
107
|
+
"aria-expanded": focusedSourceStepId === selectedSourceAction.stepId,
|
|
108
|
+
onClick: ()=>onOpenStepSource(selectedSourceAction.stepId, selectedSourceAction.location, sourceButtonRef.current),
|
|
109
|
+
children: "View source"
|
|
110
|
+
})
|
|
111
|
+
}) : null
|
|
112
|
+
]
|
|
113
|
+
}),
|
|
114
|
+
/*#__PURE__*/ _jsx(JobExecutionMetadata, {
|
|
115
|
+
execution: selectedJobExecution
|
|
116
|
+
})
|
|
117
|
+
]
|
|
118
|
+
}),
|
|
119
|
+
/*#__PURE__*/ _jsx("div", {
|
|
120
|
+
className: "min-h-0 border-t border-border-neutral-strong",
|
|
121
|
+
children: selectedJobExecution ? /*#__PURE__*/ _jsx(StepList, {
|
|
122
|
+
job: job,
|
|
123
|
+
jobExecution: selectedJobExecution,
|
|
124
|
+
selectedAttemptId: selectedAttemptId,
|
|
125
|
+
onSelectedAttemptChange: selectAttempt,
|
|
126
|
+
autoSelectActiveAttempt: true,
|
|
127
|
+
emptyState: emptyStateForJob(job, selectedJobExecution),
|
|
128
|
+
showHeader: false,
|
|
129
|
+
className: "rounded-none border-0 bg-transparent",
|
|
130
|
+
renderExpandedStep: renderExpandedStep ?? defaultRenderExpandedStep
|
|
131
|
+
}) : /*#__PURE__*/ _jsx(JobExecutionEmptyState, {
|
|
132
|
+
job: job
|
|
133
|
+
})
|
|
134
|
+
})
|
|
135
|
+
]
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
function JobStatusBadge({ status }) {
|
|
139
|
+
const visual = getWorkflowStatusVisual(status);
|
|
140
|
+
return /*#__PURE__*/ _jsx(Badge, {
|
|
141
|
+
variant: visual.badge,
|
|
142
|
+
size: "xs",
|
|
143
|
+
children: /*#__PURE__*/ _jsx("span", {
|
|
144
|
+
className: "text-center",
|
|
145
|
+
style: {
|
|
146
|
+
width: `${STATUS_BADGE_LABEL_WIDTH_CH}ch`
|
|
147
|
+
},
|
|
148
|
+
children: visual.label
|
|
149
|
+
})
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
function JobExecutionEmptyState({ job }) {
|
|
153
|
+
const emptyState = emptyStateForMissingExecution(job);
|
|
154
|
+
return /*#__PURE__*/ _jsx(EmptyState, {
|
|
155
|
+
className: "min-h-120 px-16 py-20",
|
|
156
|
+
icon: "componentLine",
|
|
157
|
+
title: emptyState.title,
|
|
158
|
+
description: emptyState.description,
|
|
159
|
+
variant: "compact"
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
function JobExecutionMetadata({ execution }) {
|
|
163
|
+
if (!execution) return null;
|
|
164
|
+
const queueTime = execution.queueTime;
|
|
165
|
+
const runTime = execution.runTime;
|
|
166
|
+
const executionStartedAt = execution.startedAt ?? execution.queuedAt ?? execution.createdAt;
|
|
167
|
+
const items = [
|
|
168
|
+
execution.triggerEvents.length > 0 ? {
|
|
169
|
+
key: 'trigger',
|
|
170
|
+
kind: 'trigger'
|
|
171
|
+
} : null,
|
|
172
|
+
{
|
|
173
|
+
key: 'started',
|
|
174
|
+
kind: 'started',
|
|
175
|
+
value: executionStartedAt
|
|
176
|
+
},
|
|
177
|
+
queueTime ? {
|
|
178
|
+
key: 'queue',
|
|
179
|
+
icon: 'hourglassLine',
|
|
180
|
+
kind: 'queue',
|
|
181
|
+
time: queueTime
|
|
182
|
+
} : null,
|
|
183
|
+
runTime ? {
|
|
184
|
+
key: 'run',
|
|
185
|
+
icon: 'timerLine',
|
|
186
|
+
kind: 'run',
|
|
187
|
+
time: runTime
|
|
188
|
+
} : null
|
|
189
|
+
].filter((item)=>item !== null);
|
|
190
|
+
if (items.length === 0) return null;
|
|
191
|
+
return /*#__PURE__*/ _jsx("div", {
|
|
192
|
+
className: "flex min-w-0 items-center gap-12 overflow-hidden text-foreground-neutral-muted",
|
|
193
|
+
children: items.map((item, index)=>/*#__PURE__*/ _jsxs(Fragment, {
|
|
194
|
+
children: [
|
|
195
|
+
index > 0 ? /*#__PURE__*/ _jsx(MetadataSeparator, {}) : null,
|
|
196
|
+
item.kind === 'started' ? /*#__PURE__*/ _jsx(RelativeTime, {
|
|
197
|
+
value: item.value,
|
|
198
|
+
className: "shrink-0 whitespace-nowrap text-xs leading-20 text-foreground-neutral-muted"
|
|
199
|
+
}) : item.kind === 'trigger' ? /*#__PURE__*/ _jsx(JobExecutionTriggerMetadata, {
|
|
200
|
+
execution: execution
|
|
201
|
+
}) : /*#__PURE__*/ _jsx(JobExecutionMetadataItem, {
|
|
202
|
+
icon: item.icon,
|
|
203
|
+
kind: item.kind,
|
|
204
|
+
time: item.time
|
|
205
|
+
})
|
|
206
|
+
]
|
|
207
|
+
}, item.key))
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
function JobExecutionTriggerMetadata({ execution }) {
|
|
211
|
+
const triggerEvent = execution.triggerEvents[0];
|
|
212
|
+
if (!triggerEvent) return null;
|
|
213
|
+
const triggerLabel = workflowRunTriggerLabel({
|
|
214
|
+
triggerSource: triggerEvent.source,
|
|
215
|
+
triggerEvent: triggerEvent.event
|
|
216
|
+
});
|
|
217
|
+
const triggerDisplayLabel = workflowRunTriggerDisplayLabel({
|
|
218
|
+
triggerSource: triggerEvent.source,
|
|
219
|
+
triggerEvent: triggerEvent.event
|
|
220
|
+
});
|
|
221
|
+
const triggerCount = execution.triggerEvents.length;
|
|
222
|
+
const countLabel = triggerCount > 1 ? ` (${triggerCount})` : '';
|
|
223
|
+
const tooltip = triggerCount > 1 ? `${triggerLabel} (${triggerCount} events)` : triggerLabel;
|
|
224
|
+
return /*#__PURE__*/ _jsxs(Tooltip, {
|
|
225
|
+
children: [
|
|
226
|
+
/*#__PURE__*/ _jsx(TooltipTrigger, {
|
|
227
|
+
asChild: true,
|
|
228
|
+
children: /*#__PURE__*/ _jsxs("button", {
|
|
229
|
+
type: "button",
|
|
230
|
+
"aria-label": tooltip,
|
|
231
|
+
className: "inline-flex min-w-0 max-w-full cursor-default items-center gap-4 rounded-4 border-0 bg-transparent p-0 text-left text-foreground-neutral-muted outline-none focus-visible:shadow-border-interactive-with-active",
|
|
232
|
+
children: [
|
|
233
|
+
/*#__PURE__*/ _jsx(TriggerSourceIcon, {
|
|
234
|
+
provider: triggerEvent.source,
|
|
235
|
+
source: triggerEvent.source,
|
|
236
|
+
"aria-hidden": "true",
|
|
237
|
+
className: "size-12 shrink-0"
|
|
238
|
+
}),
|
|
239
|
+
/*#__PURE__*/ _jsxs(Text, {
|
|
240
|
+
as: "span",
|
|
241
|
+
size: "xs",
|
|
242
|
+
className: "min-w-0 truncate",
|
|
243
|
+
children: [
|
|
244
|
+
triggerDisplayLabel,
|
|
245
|
+
countLabel
|
|
246
|
+
]
|
|
247
|
+
})
|
|
248
|
+
]
|
|
249
|
+
})
|
|
250
|
+
}),
|
|
251
|
+
/*#__PURE__*/ _jsx(TooltipContent, {
|
|
252
|
+
children: /*#__PURE__*/ _jsx(Text, {
|
|
253
|
+
as: "span",
|
|
254
|
+
size: "xs",
|
|
255
|
+
className: "block max-w-[360px] break-words",
|
|
256
|
+
children: tooltip
|
|
257
|
+
})
|
|
258
|
+
})
|
|
259
|
+
]
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
function JobExecutionMetadataItem({ icon, kind, time }) {
|
|
263
|
+
useTimeTick();
|
|
264
|
+
const tooltip = `${jobExecutionTimeVerb(kind, time)} for ${formatJobExecutionTime(time)}`;
|
|
265
|
+
return /*#__PURE__*/ _jsxs(Tooltip, {
|
|
266
|
+
children: [
|
|
267
|
+
/*#__PURE__*/ _jsx(TooltipTrigger, {
|
|
268
|
+
asChild: true,
|
|
269
|
+
children: /*#__PURE__*/ _jsxs("button", {
|
|
270
|
+
type: "button",
|
|
271
|
+
"aria-label": tooltip,
|
|
272
|
+
className: "inline-flex min-w-0 cursor-default items-center gap-4 rounded-4 border-0 bg-transparent p-0 text-foreground-neutral-muted outline-none focus-visible:shadow-border-interactive-with-active",
|
|
273
|
+
children: [
|
|
274
|
+
/*#__PURE__*/ _jsx(Icon, {
|
|
275
|
+
name: icon,
|
|
276
|
+
className: "size-12 shrink-0",
|
|
277
|
+
"aria-hidden": "true"
|
|
278
|
+
}),
|
|
279
|
+
/*#__PURE__*/ _jsx("span", {
|
|
280
|
+
className: "shrink-0 text-xs leading-20 text-foreground-neutral-muted tabular-nums",
|
|
281
|
+
children: /*#__PURE__*/ _jsx(JobExecutionTimeText, {
|
|
282
|
+
time: time
|
|
283
|
+
})
|
|
284
|
+
})
|
|
285
|
+
]
|
|
286
|
+
})
|
|
287
|
+
}),
|
|
288
|
+
/*#__PURE__*/ _jsx(TooltipContent, {
|
|
289
|
+
children: /*#__PURE__*/ _jsx(Text, {
|
|
290
|
+
as: "span",
|
|
291
|
+
size: "xs",
|
|
292
|
+
children: tooltip
|
|
293
|
+
})
|
|
294
|
+
})
|
|
295
|
+
]
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
function jobExecutionTimeVerb(kind, time) {
|
|
299
|
+
if (kind === 'queue') return time.state === 'live' ? 'Queuing' : 'Queued';
|
|
300
|
+
return time.state === 'live' ? 'Running' : 'Ran';
|
|
301
|
+
}
|
|
302
|
+
function MetadataSeparator() {
|
|
303
|
+
return /*#__PURE__*/ _jsx("span", {
|
|
304
|
+
"aria-hidden": "true",
|
|
305
|
+
className: "h-12 w-px shrink-0 bg-border-neutral-strong"
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
function selectedStepSourceAction(jobExecution, selectedAttemptId) {
|
|
309
|
+
if (!jobExecution || !selectedAttemptId) return null;
|
|
310
|
+
for (const step of jobExecution.steps){
|
|
311
|
+
const selected = selectedAttemptId === `carried-over:${step.id}` || step.attempts.some((attempt)=>attempt.id === selectedAttemptId);
|
|
312
|
+
if (selected && step.sourceLocation) {
|
|
313
|
+
return {
|
|
314
|
+
stepId: step.id,
|
|
315
|
+
location: step.sourceLocation
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
321
|
+
function StepAttemptDetailPanel({ workspaceId, step, stepId, attempt, attemptError, attemptStatus }) {
|
|
322
|
+
const selectedAttemptError = toSelectedAttemptError(step, attemptError) ?? step.error;
|
|
323
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
324
|
+
className: "flex min-w-0 flex-col gap-10",
|
|
325
|
+
children: [
|
|
326
|
+
isAgentConfigFailure(step, selectedAttemptError) ? /*#__PURE__*/ _jsx(AgentConfigFailureCallout, {
|
|
327
|
+
workspaceId: workspaceId,
|
|
328
|
+
config: null,
|
|
329
|
+
error: selectedAttemptError
|
|
330
|
+
}) : null,
|
|
331
|
+
/*#__PURE__*/ _jsx(StepAttemptLogPanel, {
|
|
332
|
+
stepId: stepId,
|
|
333
|
+
attempt: attempt,
|
|
334
|
+
attemptStatus: attemptStatus
|
|
335
|
+
})
|
|
336
|
+
]
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
function toSelectedAttemptError(step, error) {
|
|
340
|
+
if (error === null) return null;
|
|
341
|
+
const reason = stepErrorReasonSchema.safeParse(error.reason);
|
|
342
|
+
const agentConfigIssue = agentConfigIssueSchema.safeParse(error.agentConfigIssue ?? error.agent_config_issue);
|
|
343
|
+
const exitCode = error.exitCode ?? error.exit_code;
|
|
344
|
+
const parsedReason = reason.success ? reason.data : agentConfigIssue.success ? 'agent_config_invalid' : undefined;
|
|
345
|
+
if (parsedReason === undefined) return null;
|
|
346
|
+
return {
|
|
347
|
+
message: typeof error.message === 'string' ? error.message : '',
|
|
348
|
+
exitCode: exitCode === null || typeof exitCode === 'number' ? exitCode : null,
|
|
349
|
+
signal: typeof error.signal === 'string' ? error.signal : undefined,
|
|
350
|
+
reason: parsedReason,
|
|
351
|
+
agentConfigIssue: agentConfigIssue.success ? agentConfigIssue.data : undefined,
|
|
352
|
+
category: step.type === 'setup' ? 'setup' : 'user'
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
function isAgentConfigFailure(step, error) {
|
|
356
|
+
return step.type === 'agent' && error?.reason === 'agent_config_invalid';
|
|
357
|
+
}
|
|
358
|
+
function emptyStateForJob(job, jobExecution) {
|
|
359
|
+
if (job.carriedOver) {
|
|
360
|
+
return {
|
|
361
|
+
title: 'Carried over from a previous attempt',
|
|
362
|
+
description: 'This job did not execute in this run.',
|
|
363
|
+
status: 'succeeded'
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
if (jobExecution.status === 'pending') {
|
|
367
|
+
return {
|
|
368
|
+
title: 'Waiting for this job to start',
|
|
369
|
+
description: 'Steps will appear here once the job starts.',
|
|
370
|
+
status: jobExecution.status
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
if (jobExecution.status === 'running') {
|
|
374
|
+
return {
|
|
375
|
+
title: 'Waiting for the first step',
|
|
376
|
+
description: 'This job is running, but no steps have started yet.',
|
|
377
|
+
status: jobExecution.status
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
if (jobExecution.status === 'cancelled') {
|
|
381
|
+
return {
|
|
382
|
+
title: 'Cancelled before start',
|
|
383
|
+
description: 'This job was cancelled before any step started.',
|
|
384
|
+
status: jobExecution.status
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
if (jobExecution.status === 'succeeded' || jobExecution.status === 'failed') {
|
|
388
|
+
return {
|
|
389
|
+
title: 'No steps recorded',
|
|
390
|
+
description: `Execution #${jobExecution.sequence} finished without recorded steps.`,
|
|
391
|
+
status: jobExecution.status
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
return undefined;
|
|
395
|
+
}
|
|
396
|
+
function emptyStateForMissingExecution(job) {
|
|
397
|
+
if (job.carriedOver) {
|
|
398
|
+
return {
|
|
399
|
+
title: 'Carried over from a previous attempt',
|
|
400
|
+
description: 'This job did not execute in this run.',
|
|
401
|
+
status: 'succeeded'
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
if (job.mode === 'listening' && job.listenerStatus === 'listening') {
|
|
405
|
+
return {
|
|
406
|
+
title: 'Waiting for trigger events',
|
|
407
|
+
description: 'Matching trigger events will create job executions here.',
|
|
408
|
+
status: 'running'
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
if (job.mode === 'listening' && job.listenerStatus === 'resolved') {
|
|
412
|
+
return {
|
|
413
|
+
title: 'Listener resolved without executions',
|
|
414
|
+
description: 'No matching trigger event created a job execution before the listener stopped.',
|
|
415
|
+
status: job.status
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
if (job.status === 'pending') {
|
|
419
|
+
return {
|
|
420
|
+
title: 'Waiting for this job to start',
|
|
421
|
+
description: 'No execution has been created for this job yet.',
|
|
422
|
+
status: 'pending'
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
if (job.status === 'skipped') {
|
|
426
|
+
return {
|
|
427
|
+
title: 'This job was skipped',
|
|
428
|
+
description: skippedJobDescription(job.statusReason),
|
|
429
|
+
status: 'skipped'
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
if (job.status === 'cancelled') {
|
|
433
|
+
return {
|
|
434
|
+
title: 'Cancelled before start',
|
|
435
|
+
description: 'This job was cancelled before an execution was created.',
|
|
436
|
+
status: 'cancelled'
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
return {
|
|
440
|
+
title: 'Execution details unavailable',
|
|
441
|
+
description: 'This job finished, but no job execution record is available.',
|
|
442
|
+
status: job.status
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
function CarriedOverStepPanel() {
|
|
446
|
+
return /*#__PURE__*/ _jsx(EmptyState, {
|
|
447
|
+
className: "min-h-120 rounded-8 border border-border-neutral-base bg-background-components-base px-16 py-20",
|
|
448
|
+
icon: "componentLine",
|
|
449
|
+
title: "Carried over from a previous attempt",
|
|
450
|
+
description: "Not executed in this run.",
|
|
451
|
+
variant: "compact"
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
function skippedJobDescription(reason) {
|
|
455
|
+
switch(reason){
|
|
456
|
+
case 'dependency_not_completed':
|
|
457
|
+
return 'A required job did not complete, so this job was skipped.';
|
|
458
|
+
case 'default_gate_rejected':
|
|
459
|
+
return 'A required job did not succeed, so this job was skipped.';
|
|
460
|
+
case 'condition_false':
|
|
461
|
+
case 'condition_rejected':
|
|
462
|
+
return 'The job condition did not match, so this job was skipped.';
|
|
463
|
+
case 'condition_errored':
|
|
464
|
+
return 'The job condition could not be evaluated, so this job was skipped.';
|
|
465
|
+
case 'user_cancelled':
|
|
466
|
+
case 'run_cancelled':
|
|
467
|
+
case 'timed_out':
|
|
468
|
+
case 'runner_lost':
|
|
469
|
+
case 'step_failed':
|
|
470
|
+
case 'unknown':
|
|
471
|
+
case null:
|
|
472
|
+
return 'This job did not start.';
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
//# sourceMappingURL=job-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/workflow-run-view/job-card.tsx"],"sourcesContent":["import {agentConfigIssueSchema, stepErrorReasonSchema} 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 {EmptyState} from '@shipfox/react-ui/empty-state';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {RelativeTime} from '@shipfox/react-ui/relative-time';\nimport {useTimeTick} from '@shipfox/react-ui/time-ticker';\nimport {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';\nimport {Text} from '@shipfox/react-ui/typography';\nimport type {ReactNode} from 'react';\nimport {Fragment, useId, useRef, useState} from 'react';\nimport {getWorkflowStatusVisual} from '#components/workflow-status/status-visuals.js';\nimport {\n type Job,\n type JobExecution,\n type JobExecutionTime,\n type Step,\n type StepError,\n type StepSourceLocation,\n WORKFLOW_JOB_STATUSES,\n workflowRunTriggerDisplayLabel,\n workflowRunTriggerLabel,\n} from '#core/workflow-run.js';\nimport {type StepExpandedContext, StepList, type StepListEmptyState} from '../step-list/index.js';\nimport {AgentConfigFailureCallout} from './agent-config-failure-callout.js';\nimport {JobExecutionSwitcher} from './job-execution-switcher.js';\nimport {formatJobExecutionTime, JobExecutionTimeText} from './job-execution-time-text.js';\nimport {StepAttemptLogPanel} from './step-attempt-log-panel.js';\n\nconst STATUS_BADGE_LABEL_WIDTH_CH = Math.max(\n ...WORKFLOW_JOB_STATUSES.map((status) => getWorkflowStatusVisual(status).label.length),\n);\n\ninterface LocalSelectedAttempt {\n jobExecutionId: string | undefined;\n attemptId: string | null;\n}\n\nexport function JobCard({\n workspaceId,\n job,\n selectedJobExecution,\n selectedAttemptId,\n onSelectedJobExecutionChange,\n onSelectedAttemptChange,\n renderExpandedStep,\n sourcePanelId,\n sourceAvailable,\n focusedSourceStepId,\n onOpenStepSource,\n}: {\n workspaceId: string;\n job: Job;\n selectedJobExecution: JobExecution | undefined;\n selectedAttemptId: string | null | undefined;\n onSelectedJobExecutionChange: ((jobExecutionId: string | undefined) => void) | undefined;\n onSelectedAttemptChange: ((attemptId: string | undefined) => void) | undefined;\n renderExpandedStep?: ((context: StepExpandedContext) => ReactNode) | undefined;\n sourcePanelId?: string | undefined;\n sourceAvailable?: boolean | undefined;\n focusedSourceStepId?: string | null | undefined;\n onOpenStepSource?:\n | ((stepId: string, location: StepSourceLocation, trigger: HTMLButtonElement | null) => void)\n | undefined;\n}) {\n const titleId = useId();\n const sourceButtonRef = useRef<HTMLButtonElement>(null);\n const [localSelectedAttempt, setLocalSelectedAttempt] = useState<LocalSelectedAttempt>({\n jobExecutionId: undefined,\n attemptId: null,\n });\n const selectedExecutionStatus = selectedJobExecution?.status ?? job.status;\n const effectiveSelectedAttemptId =\n selectedAttemptId === undefined &&\n localSelectedAttempt.jobExecutionId === selectedJobExecution?.id\n ? localSelectedAttempt.attemptId\n : selectedAttemptId;\n const selectedSourceAction = selectedStepSourceAction(\n selectedJobExecution,\n effectiveSelectedAttemptId,\n );\n const defaultRenderExpandedStep = ({\n step,\n stepId,\n attempt,\n attemptError,\n attemptStatus,\n carriedOver,\n }: StepExpandedContext) =>\n carriedOver ? (\n <CarriedOverStepPanel />\n ) : (\n <StepAttemptDetailPanel\n workspaceId={workspaceId}\n step={step}\n stepId={stepId}\n attempt={attempt}\n attemptError={attemptError}\n attemptStatus={attemptStatus}\n />\n );\n\n function selectAttempt(attemptId: string | undefined) {\n if (selectedAttemptId === undefined) {\n setLocalSelectedAttempt({\n jobExecutionId: selectedJobExecution?.id,\n attemptId: attemptId ?? null,\n });\n }\n\n onSelectedAttemptChange?.(attemptId);\n }\n\n return (\n <section\n aria-labelledby={titleId}\n className=\"flex min-h-0 flex-col rounded-8 border border-border-neutral-base bg-background-components-base\"\n >\n <div className=\"grid min-h-52 min-w-0 grid-cols-1 gap-y-4 px-16 py-12\">\n <div className=\"flex min-w-0 flex-wrap items-center justify-between gap-10\">\n {job.mode === 'listening' &&\n job.jobExecutions.length > 0 &&\n onSelectedJobExecutionChange ? (\n <>\n <Text as=\"h2\" id={titleId} size=\"sm\" bold className=\"sr-only\">\n {job.displayName}\n </Text>\n <div className=\"flex min-w-0 items-center gap-8\">\n <JobStatusBadge status={selectedExecutionStatus} />\n <JobExecutionSwitcher\n job={job}\n selectedJobExecution={selectedJobExecution?.id ?? null}\n onSelectedJobExecutionChange={onSelectedJobExecutionChange}\n variant=\"title\"\n />\n </div>\n </>\n ) : (\n <div className=\"flex min-w-0 items-center gap-8\">\n <JobStatusBadge status={selectedExecutionStatus} />\n <Text\n as=\"h2\"\n id={titleId}\n size=\"sm\"\n bold\n className=\"min-w-0 truncate text-foreground-neutral-base\"\n >\n {job.displayName}\n </Text>\n </div>\n )}\n {sourceAvailable && selectedSourceAction && sourcePanelId && onOpenStepSource ? (\n <div className=\"flex min-w-max items-center gap-6\">\n <Button\n ref={sourceButtonRef}\n type=\"button\"\n variant=\"secondary\"\n size=\"xs\"\n aria-controls={sourcePanelId}\n aria-expanded={focusedSourceStepId === selectedSourceAction.stepId}\n onClick={() =>\n onOpenStepSource(\n selectedSourceAction.stepId,\n selectedSourceAction.location,\n sourceButtonRef.current,\n )\n }\n >\n View source\n </Button>\n </div>\n ) : null}\n </div>\n <JobExecutionMetadata execution={selectedJobExecution} />\n </div>\n <div className=\"min-h-0 border-t border-border-neutral-strong\">\n {selectedJobExecution ? (\n <StepList\n job={job}\n jobExecution={selectedJobExecution}\n selectedAttemptId={selectedAttemptId}\n onSelectedAttemptChange={selectAttempt}\n autoSelectActiveAttempt\n emptyState={emptyStateForJob(job, selectedJobExecution)}\n showHeader={false}\n className=\"rounded-none border-0 bg-transparent\"\n renderExpandedStep={renderExpandedStep ?? defaultRenderExpandedStep}\n />\n ) : (\n <JobExecutionEmptyState job={job} />\n )}\n </div>\n </section>\n );\n}\n\nfunction JobStatusBadge({status}: {status: Job['status'] | JobExecution['status']}) {\n const visual = getWorkflowStatusVisual(status);\n\n return (\n <Badge variant={visual.badge} size=\"xs\">\n <span className=\"text-center\" style={{width: `${STATUS_BADGE_LABEL_WIDTH_CH}ch`}}>\n {visual.label}\n </span>\n </Badge>\n );\n}\n\nfunction JobExecutionEmptyState({job}: {job: Job}) {\n const emptyState = emptyStateForMissingExecution(job);\n\n return (\n <EmptyState\n className=\"min-h-120 px-16 py-20\"\n icon=\"componentLine\"\n title={emptyState.title}\n description={emptyState.description}\n variant=\"compact\"\n />\n );\n}\n\nfunction JobExecutionMetadata({execution}: {execution: JobExecution | undefined}) {\n if (!execution) return null;\n\n const queueTime = execution.queueTime;\n const runTime = execution.runTime;\n const executionStartedAt = execution.startedAt ?? execution.queuedAt ?? execution.createdAt;\n const items = [\n execution.triggerEvents.length > 0 ? {key: 'trigger', kind: 'trigger' as const} : null,\n {key: 'started', kind: 'started' as const, value: executionStartedAt},\n queueTime\n ? {key: 'queue', icon: 'hourglassLine' as const, kind: 'queue' as const, time: queueTime}\n : null,\n runTime ? {key: 'run', icon: 'timerLine' as const, kind: 'run' as const, time: runTime} : null,\n ].filter((item) => item !== null);\n\n if (items.length === 0) return null;\n\n return (\n <div className=\"flex min-w-0 items-center gap-12 overflow-hidden text-foreground-neutral-muted\">\n {items.map((item, index) => (\n <Fragment key={item.key}>\n {index > 0 ? <MetadataSeparator /> : null}\n {item.kind === 'started' ? (\n <RelativeTime\n value={item.value}\n className=\"shrink-0 whitespace-nowrap text-xs leading-20 text-foreground-neutral-muted\"\n />\n ) : item.kind === 'trigger' ? (\n <JobExecutionTriggerMetadata execution={execution} />\n ) : (\n <JobExecutionMetadataItem icon={item.icon} kind={item.kind} time={item.time} />\n )}\n </Fragment>\n ))}\n </div>\n );\n}\n\nfunction JobExecutionTriggerMetadata({execution}: {execution: JobExecution}) {\n const triggerEvent = execution.triggerEvents[0];\n if (!triggerEvent) return null;\n\n const triggerLabel = workflowRunTriggerLabel({\n triggerSource: triggerEvent.source,\n triggerEvent: triggerEvent.event,\n });\n const triggerDisplayLabel = workflowRunTriggerDisplayLabel({\n triggerSource: triggerEvent.source,\n triggerEvent: triggerEvent.event,\n });\n const triggerCount = execution.triggerEvents.length;\n const countLabel = triggerCount > 1 ? ` (${triggerCount})` : '';\n const tooltip = triggerCount > 1 ? `${triggerLabel} (${triggerCount} events)` : triggerLabel;\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n aria-label={tooltip}\n className=\"inline-flex min-w-0 max-w-full cursor-default items-center gap-4 rounded-4 border-0 bg-transparent p-0 text-left text-foreground-neutral-muted outline-none focus-visible:shadow-border-interactive-with-active\"\n >\n <TriggerSourceIcon\n provider={triggerEvent.source}\n source={triggerEvent.source}\n aria-hidden=\"true\"\n className=\"size-12 shrink-0\"\n />\n <Text as=\"span\" size=\"xs\" className=\"min-w-0 truncate\">\n {triggerDisplayLabel}\n {countLabel}\n </Text>\n </button>\n </TooltipTrigger>\n <TooltipContent>\n <Text as=\"span\" size=\"xs\" className=\"block max-w-[360px] break-words\">\n {tooltip}\n </Text>\n </TooltipContent>\n </Tooltip>\n );\n}\n\nfunction JobExecutionMetadataItem({\n icon,\n kind,\n time,\n}: {\n icon: 'hourglassLine' | 'timerLine';\n kind: 'queue' | 'run';\n time: JobExecutionTime;\n}) {\n useTimeTick();\n\n const tooltip = `${jobExecutionTimeVerb(kind, time)} for ${formatJobExecutionTime(time)}`;\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n aria-label={tooltip}\n className=\"inline-flex min-w-0 cursor-default items-center gap-4 rounded-4 border-0 bg-transparent p-0 text-foreground-neutral-muted outline-none focus-visible:shadow-border-interactive-with-active\"\n >\n <Icon name={icon} className=\"size-12 shrink-0\" aria-hidden=\"true\" />\n <span className=\"shrink-0 text-xs leading-20 text-foreground-neutral-muted tabular-nums\">\n <JobExecutionTimeText time={time} />\n </span>\n </button>\n </TooltipTrigger>\n <TooltipContent>\n <Text as=\"span\" size=\"xs\">\n {tooltip}\n </Text>\n </TooltipContent>\n </Tooltip>\n );\n}\n\nfunction jobExecutionTimeVerb(kind: 'queue' | 'run', time: JobExecutionTime): string {\n if (kind === 'queue') return time.state === 'live' ? 'Queuing' : 'Queued';\n return time.state === 'live' ? 'Running' : 'Ran';\n}\n\nfunction MetadataSeparator() {\n return <span aria-hidden=\"true\" className=\"h-12 w-px shrink-0 bg-border-neutral-strong\" />;\n}\n\nfunction selectedStepSourceAction(\n jobExecution: JobExecution | undefined,\n selectedAttemptId: string | null | undefined,\n): {stepId: string; location: StepSourceLocation} | null {\n if (!jobExecution || !selectedAttemptId) return null;\n\n for (const step of jobExecution.steps) {\n const selected =\n selectedAttemptId === `carried-over:${step.id}` ||\n step.attempts.some((attempt) => attempt.id === selectedAttemptId);\n if (selected && step.sourceLocation) {\n return {stepId: step.id, location: step.sourceLocation};\n }\n }\n\n return null;\n}\n\nfunction StepAttemptDetailPanel({\n workspaceId,\n step,\n stepId,\n attempt,\n attemptError,\n attemptStatus,\n}: {\n workspaceId: string;\n step: Step;\n stepId: string;\n attempt: number;\n attemptError: Record<string, unknown> | null;\n attemptStatus: string;\n}) {\n const selectedAttemptError = toSelectedAttemptError(step, attemptError) ?? step.error;\n\n return (\n <div className=\"flex min-w-0 flex-col gap-10\">\n {isAgentConfigFailure(step, selectedAttemptError) ? (\n <AgentConfigFailureCallout\n workspaceId={workspaceId}\n config={null}\n error={selectedAttemptError}\n />\n ) : null}\n <StepAttemptLogPanel stepId={stepId} attempt={attempt} attemptStatus={attemptStatus} />\n </div>\n );\n}\n\nfunction toSelectedAttemptError(\n step: Step,\n error: Record<string, unknown> | null,\n): StepError | null {\n if (error === null) return null;\n\n const reason = stepErrorReasonSchema.safeParse(error.reason);\n const agentConfigIssue = agentConfigIssueSchema.safeParse(\n error.agentConfigIssue ?? error.agent_config_issue,\n );\n const exitCode = error.exitCode ?? error.exit_code;\n const parsedReason = reason.success\n ? reason.data\n : agentConfigIssue.success\n ? 'agent_config_invalid'\n : undefined;\n\n if (parsedReason === undefined) return null;\n\n return {\n message: typeof error.message === 'string' ? error.message : '',\n exitCode: exitCode === null || typeof exitCode === 'number' ? exitCode : null,\n signal: typeof error.signal === 'string' ? error.signal : undefined,\n reason: parsedReason,\n agentConfigIssue: agentConfigIssue.success ? agentConfigIssue.data : undefined,\n category: step.type === 'setup' ? 'setup' : 'user',\n };\n}\n\nfunction isAgentConfigFailure(step: Step, error: StepError | null): boolean {\n return step.type === 'agent' && error?.reason === 'agent_config_invalid';\n}\n\nfunction emptyStateForJob(job: Job, jobExecution: JobExecution): StepListEmptyState | undefined {\n if (job.carriedOver) {\n return {\n title: 'Carried over from a previous attempt',\n description: 'This job did not execute in this run.',\n status: 'succeeded',\n };\n }\n\n if (jobExecution.status === 'pending') {\n return {\n title: 'Waiting for this job to start',\n description: 'Steps will appear here once the job starts.',\n status: jobExecution.status,\n };\n }\n\n if (jobExecution.status === 'running') {\n return {\n title: 'Waiting for the first step',\n description: 'This job is running, but no steps have started yet.',\n status: jobExecution.status,\n };\n }\n\n if (jobExecution.status === 'cancelled') {\n return {\n title: 'Cancelled before start',\n description: 'This job was cancelled before any step started.',\n status: jobExecution.status,\n };\n }\n\n if (jobExecution.status === 'succeeded' || jobExecution.status === 'failed') {\n return {\n title: 'No steps recorded',\n description: `Execution #${jobExecution.sequence} finished without recorded steps.`,\n status: jobExecution.status,\n };\n }\n\n return undefined;\n}\n\nfunction emptyStateForMissingExecution(job: Job): StepListEmptyState {\n if (job.carriedOver) {\n return {\n title: 'Carried over from a previous attempt',\n description: 'This job did not execute in this run.',\n status: 'succeeded',\n };\n }\n\n if (job.mode === 'listening' && job.listenerStatus === 'listening') {\n return {\n title: 'Waiting for trigger events',\n description: 'Matching trigger events will create job executions here.',\n status: 'running',\n };\n }\n\n if (job.mode === 'listening' && job.listenerStatus === 'resolved') {\n return {\n title: 'Listener resolved without executions',\n description: 'No matching trigger event created a job execution before the listener stopped.',\n status: job.status,\n };\n }\n\n if (job.status === 'pending') {\n return {\n title: 'Waiting for this job to start',\n description: 'No execution has been created for this job yet.',\n status: 'pending',\n };\n }\n\n if (job.status === 'skipped') {\n return {\n title: 'This job was skipped',\n description: skippedJobDescription(job.statusReason),\n status: 'skipped',\n };\n }\n\n if (job.status === 'cancelled') {\n return {\n title: 'Cancelled before start',\n description: 'This job was cancelled before an execution was created.',\n status: 'cancelled',\n };\n }\n\n return {\n title: 'Execution details unavailable',\n description: 'This job finished, but no job execution record is available.',\n status: job.status,\n };\n}\n\nfunction CarriedOverStepPanel() {\n return (\n <EmptyState\n className=\"min-h-120 rounded-8 border border-border-neutral-base bg-background-components-base px-16 py-20\"\n icon=\"componentLine\"\n title=\"Carried over from a previous attempt\"\n description=\"Not executed in this run.\"\n variant=\"compact\"\n />\n );\n}\n\nfunction skippedJobDescription(reason: Job['statusReason']): string {\n switch (reason) {\n case 'dependency_not_completed':\n return 'A required job did not complete, so this job was skipped.';\n case 'default_gate_rejected':\n return 'A required job did not succeed, so this job was skipped.';\n case 'condition_false':\n case 'condition_rejected':\n return 'The job condition did not match, so this job was skipped.';\n case 'condition_errored':\n return 'The job condition could not be evaluated, so this job was skipped.';\n case 'user_cancelled':\n case 'run_cancelled':\n case 'timed_out':\n case 'runner_lost':\n case 'step_failed':\n case 'unknown':\n case null:\n return 'This job did not start.';\n }\n}\n"],"names":["agentConfigIssueSchema","stepErrorReasonSchema","TriggerSourceIcon","Badge","Button","EmptyState","Icon","RelativeTime","useTimeTick","Tooltip","TooltipContent","TooltipTrigger","Text","Fragment","useId","useRef","useState","getWorkflowStatusVisual","WORKFLOW_JOB_STATUSES","workflowRunTriggerDisplayLabel","workflowRunTriggerLabel","StepList","AgentConfigFailureCallout","JobExecutionSwitcher","formatJobExecutionTime","JobExecutionTimeText","StepAttemptLogPanel","STATUS_BADGE_LABEL_WIDTH_CH","Math","max","map","status","label","length","JobCard","workspaceId","job","selectedJobExecution","selectedAttemptId","onSelectedJobExecutionChange","onSelectedAttemptChange","renderExpandedStep","sourcePanelId","sourceAvailable","focusedSourceStepId","onOpenStepSource","titleId","sourceButtonRef","localSelectedAttempt","setLocalSelectedAttempt","jobExecutionId","undefined","attemptId","selectedExecutionStatus","effectiveSelectedAttemptId","id","selectedSourceAction","selectedStepSourceAction","defaultRenderExpandedStep","step","stepId","attempt","attemptError","attemptStatus","carriedOver","CarriedOverStepPanel","StepAttemptDetailPanel","selectAttempt","section","aria-labelledby","className","div","mode","jobExecutions","as","size","bold","displayName","JobStatusBadge","variant","ref","type","aria-controls","aria-expanded","onClick","location","current","JobExecutionMetadata","execution","jobExecution","autoSelectActiveAttempt","emptyState","emptyStateForJob","showHeader","JobExecutionEmptyState","visual","badge","span","style","width","emptyStateForMissingExecution","icon","title","description","queueTime","runTime","executionStartedAt","startedAt","queuedAt","createdAt","items","triggerEvents","key","kind","value","time","filter","item","index","MetadataSeparator","JobExecutionTriggerMetadata","JobExecutionMetadataItem","triggerEvent","triggerLabel","triggerSource","source","event","triggerDisplayLabel","triggerCount","countLabel","tooltip","asChild","button","aria-label","provider","aria-hidden","jobExecutionTimeVerb","name","state","steps","selected","attempts","some","sourceLocation","selectedAttemptError","toSelectedAttemptError","error","isAgentConfigFailure","config","reason","safeParse","agentConfigIssue","agent_config_issue","exitCode","exit_code","parsedReason","success","data","message","signal","category","sequence","listenerStatus","skippedJobDescription","statusReason"],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Job } from '#core/workflow-run.js';
|
|
2
|
+
export interface JobExecutionSwitcherProps {
|
|
3
|
+
job: Job;
|
|
4
|
+
selectedJobExecution: string | null;
|
|
5
|
+
onSelectedJobExecutionChange: (jobExecutionId: string) => void;
|
|
6
|
+
variant?: 'compact' | 'title' | undefined;
|
|
7
|
+
className?: string | undefined;
|
|
8
|
+
}
|
|
9
|
+
export declare function JobExecutionSwitcher({ job, selectedJobExecution, onSelectedJobExecutionChange, variant, className, }: JobExecutionSwitcherProps): import("react").JSX.Element | null;
|
|
10
|
+
//# sourceMappingURL=job-execution-switcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-execution-switcher.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-view/job-execution-switcher.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAC,GAAG,EAAe,MAAM,uBAAuB,CAAC;AAG7D,MAAM,WAAW,yBAAyB;IACxC,GAAG,EAAE,GAAG,CAAC;IACT,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,4BAA4B,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/D,OAAO,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IAC1C,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED,wBAAgB,oBAAoB,CAAC,EACnC,GAAG,EACH,oBAAoB,EACpB,4BAA4B,EAC5B,OAAmB,EACnB,SAAS,GACV,EAAE,yBAAyB,sCA0F3B"}
|