@shipfox/client-workflows 12.0.2 → 13.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. package/.storybook/preview.tsx +3 -3
  2. package/.turbo/turbo-build.log +1 -1
  3. package/CHANGELOG.md +56 -0
  4. package/dist/components/job-graph/job-duration-format.d.ts +2 -2
  5. package/dist/components/job-graph/job-duration-format.d.ts.map +1 -1
  6. package/dist/components/job-graph/job-duration-format.js +4 -2
  7. package/dist/components/job-graph/job-duration-format.js.map +1 -1
  8. package/dist/components/job-graph/job-node.d.ts +1 -1
  9. package/dist/components/job-graph/job-node.d.ts.map +1 -1
  10. package/dist/components/job-graph/job-node.js +5 -4
  11. package/dist/components/job-graph/job-node.js.map +1 -1
  12. package/dist/components/step-list/step-list.d.ts +2 -2
  13. package/dist/components/step-list/step-list.d.ts.map +1 -1
  14. package/dist/components/step-list/step-list.js.map +1 -1
  15. package/dist/components/workflow-run-list/job-status-strip.d.ts +21 -0
  16. package/dist/components/workflow-run-list/job-status-strip.d.ts.map +1 -0
  17. package/dist/components/workflow-run-list/job-status-strip.js +185 -0
  18. package/dist/components/workflow-run-list/job-status-strip.js.map +1 -0
  19. package/dist/components/workflow-run-list/run-display.d.ts +27 -3
  20. package/dist/components/workflow-run-list/run-display.d.ts.map +1 -1
  21. package/dist/components/workflow-run-list/run-display.js +78 -7
  22. package/dist/components/workflow-run-list/run-display.js.map +1 -1
  23. package/dist/components/workflow-run-list/types.d.ts +23 -24
  24. package/dist/components/workflow-run-list/types.d.ts.map +1 -1
  25. package/dist/components/workflow-run-list/types.js.map +1 -1
  26. package/dist/components/workflow-run-list/workflow-run-filter-menu.d.ts +22 -0
  27. package/dist/components/workflow-run-list/workflow-run-filter-menu.d.ts.map +1 -0
  28. package/dist/components/workflow-run-list/workflow-run-filter-menu.js +68 -0
  29. package/dist/components/workflow-run-list/workflow-run-filter-menu.js.map +1 -0
  30. package/dist/components/workflow-run-list/workflow-run-filters.d.ts +18 -0
  31. package/dist/components/workflow-run-list/workflow-run-filters.d.ts.map +1 -0
  32. package/dist/components/workflow-run-list/workflow-run-filters.js +236 -0
  33. package/dist/components/workflow-run-list/workflow-run-filters.js.map +1 -0
  34. package/dist/components/workflow-run-list/workflow-run-list-content.d.ts +8 -4
  35. package/dist/components/workflow-run-list/workflow-run-list-content.d.ts.map +1 -1
  36. package/dist/components/workflow-run-list/workflow-run-list-content.js +40 -12
  37. package/dist/components/workflow-run-list/workflow-run-list-content.js.map +1 -1
  38. package/dist/components/workflow-run-list/workflow-run-list-states.d.ts +29 -2
  39. package/dist/components/workflow-run-list/workflow-run-list-states.d.ts.map +1 -1
  40. package/dist/components/workflow-run-list/workflow-run-list-states.js +103 -44
  41. package/dist/components/workflow-run-list/workflow-run-list-states.js.map +1 -1
  42. package/dist/components/workflow-run-list/workflow-run-list-view.d.ts +1 -1
  43. package/dist/components/workflow-run-list/workflow-run-list-view.d.ts.map +1 -1
  44. package/dist/components/workflow-run-list/workflow-run-list-view.js +60 -43
  45. package/dist/components/workflow-run-list/workflow-run-list-view.js.map +1 -1
  46. package/dist/components/workflow-run-list/workflow-run-list.d.ts +1 -1
  47. package/dist/components/workflow-run-list/workflow-run-list.d.ts.map +1 -1
  48. package/dist/components/workflow-run-list/workflow-run-list.js +20 -8
  49. package/dist/components/workflow-run-list/workflow-run-list.js.map +1 -1
  50. package/dist/components/workflow-run-list/workflow-run-row.d.ts +19 -9
  51. package/dist/components/workflow-run-list/workflow-run-row.d.ts.map +1 -1
  52. package/dist/components/workflow-run-list/workflow-run-row.js +179 -112
  53. package/dist/components/workflow-run-list/workflow-run-row.js.map +1 -1
  54. package/dist/components/workflow-run-number-label.d.ts +15 -0
  55. package/dist/components/workflow-run-number-label.d.ts.map +1 -0
  56. package/dist/components/workflow-run-number-label.js +41 -0
  57. package/dist/components/workflow-run-number-label.js.map +1 -0
  58. package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.d.ts +3 -3
  59. package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.d.ts.map +1 -1
  60. package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js +8 -7
  61. package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js.map +1 -1
  62. package/dist/components/workflow-run-summary/workflow-run-summary.d.ts +3 -3
  63. package/dist/components/workflow-run-summary/workflow-run-summary.d.ts.map +1 -1
  64. package/dist/components/workflow-run-summary/workflow-run-summary.js +16 -7
  65. package/dist/components/workflow-run-summary/workflow-run-summary.js.map +1 -1
  66. package/dist/components/workflow-run-view/agent-config-failure-callout.d.ts +2 -2
  67. package/dist/components/workflow-run-view/agent-config-failure-callout.d.ts.map +1 -1
  68. package/dist/components/workflow-run-view/agent-config-failure-callout.js +4 -4
  69. package/dist/components/workflow-run-view/agent-config-failure-callout.js.map +1 -1
  70. package/dist/components/workflow-run-view/job-card.d.ts +2 -2
  71. package/dist/components/workflow-run-view/job-card.d.ts.map +1 -1
  72. package/dist/components/workflow-run-view/job-card.js +51 -32
  73. package/dist/components/workflow-run-view/job-card.js.map +1 -1
  74. package/dist/components/workflow-run-view/job-execution-switcher.d.ts +1 -1
  75. package/dist/components/workflow-run-view/job-execution-switcher.d.ts.map +1 -1
  76. package/dist/components/workflow-run-view/job-execution-switcher.js +20 -8
  77. package/dist/components/workflow-run-view/job-execution-switcher.js.map +1 -1
  78. package/dist/components/workflow-run-view/workflow-run-view.d.ts +3 -2
  79. package/dist/components/workflow-run-view/workflow-run-view.d.ts.map +1 -1
  80. package/dist/components/workflow-run-view/workflow-run-view.js +15 -11
  81. package/dist/components/workflow-run-view/workflow-run-view.js.map +1 -1
  82. package/dist/components/workflow-status/status-visuals.d.ts +4 -4
  83. package/dist/components/workflow-status/status-visuals.d.ts.map +1 -1
  84. package/dist/components/workflow-status/status-visuals.js +7 -0
  85. package/dist/components/workflow-status/status-visuals.js.map +1 -1
  86. package/dist/components/workflow-status/workflow-status-icon.d.ts +3 -4
  87. package/dist/components/workflow-status/workflow-status-icon.d.ts.map +1 -1
  88. package/dist/components/workflow-status/workflow-status-icon.js +6 -4
  89. package/dist/components/workflow-status/workflow-status-icon.js.map +1 -1
  90. package/dist/core/entities/job-execution.d.ts +10 -0
  91. package/dist/core/entities/job-execution.d.ts.map +1 -1
  92. package/dist/core/entities/job-execution.js +11 -0
  93. package/dist/core/entities/job-execution.js.map +1 -1
  94. package/dist/core/entities/job.d.ts +4 -2
  95. package/dist/core/entities/job.d.ts.map +1 -1
  96. package/dist/core/entities/job.js +8 -1
  97. package/dist/core/entities/job.js.map +1 -1
  98. package/dist/core/entities/workflow-run.d.ts +52 -4
  99. package/dist/core/entities/workflow-run.d.ts.map +1 -1
  100. package/dist/core/entities/workflow-run.js +22 -3
  101. package/dist/core/entities/workflow-run.js.map +1 -1
  102. package/dist/core/workflow-run.d.ts +6 -6
  103. package/dist/core/workflow-run.d.ts.map +1 -1
  104. package/dist/core/workflow-run.js +3 -3
  105. package/dist/core/workflow-run.js.map +1 -1
  106. package/dist/feature.d.ts +7 -7
  107. package/dist/feature.js +5 -5
  108. package/dist/feature.js.map +1 -1
  109. package/dist/hooks/api/workflow-run-mapper.d.ts +4 -3
  110. package/dist/hooks/api/workflow-run-mapper.d.ts.map +1 -1
  111. package/dist/hooks/api/workflow-run-mapper.js +31 -3
  112. package/dist/hooks/api/workflow-run-mapper.js.map +1 -1
  113. package/dist/hooks/api/workflow-runs.d.ts +4 -4
  114. package/dist/hooks/api/workflow-runs.d.ts.map +1 -1
  115. package/dist/hooks/api/workflow-runs.js +12 -4
  116. package/dist/hooks/api/workflow-runs.js.map +1 -1
  117. package/dist/index.d.ts +4 -3
  118. package/dist/index.d.ts.map +1 -1
  119. package/dist/index.js +3 -2
  120. package/dist/index.js.map +1 -1
  121. package/dist/pages/project-workflows-page.js +46 -1
  122. package/dist/pages/project-workflows-page.js.map +1 -1
  123. package/dist/pages/workflow-run-detail-page.d.ts +11 -0
  124. package/dist/pages/workflow-run-detail-page.d.ts.map +1 -0
  125. package/dist/pages/workflow-run-detail-page.js +30 -0
  126. package/dist/pages/workflow-run-detail-page.js.map +1 -0
  127. package/dist/pages/workflow-run-list-page.d.ts +10 -0
  128. package/dist/pages/workflow-run-list-page.d.ts.map +1 -0
  129. package/dist/pages/workflow-run-list-page.js +43 -0
  130. package/dist/pages/workflow-run-list-page.js.map +1 -0
  131. package/dist/routes/inputs.d.ts +61 -5
  132. package/dist/routes/inputs.d.ts.map +1 -1
  133. package/dist/routes/inputs.js +150 -13
  134. package/dist/routes/inputs.js.map +1 -1
  135. package/dist/routes/project-route.d.ts +6 -0
  136. package/dist/routes/project-route.d.ts.map +1 -0
  137. package/dist/routes/project-route.js +25 -0
  138. package/dist/routes/project-route.js.map +1 -0
  139. package/dist/routes/run-detail.d.ts.map +1 -1
  140. package/dist/routes/run-detail.js +12 -7
  141. package/dist/routes/run-detail.js.map +1 -1
  142. package/dist/routes/runs.d.ts.map +1 -1
  143. package/dist/routes/runs.js +11 -6
  144. package/dist/routes/runs.js.map +1 -1
  145. package/dist/routes/workflows.d.ts.map +1 -1
  146. package/dist/routes/workflows.js +6 -5
  147. package/dist/routes/workflows.js.map +1 -1
  148. package/dist/tsconfig.test.tsbuildinfo +1 -1
  149. package/package.json +9 -9
  150. package/src/components/job-graph/job-duration-format.ts +11 -2
  151. package/src/components/job-graph/job-graph-view.test.tsx +19 -8
  152. package/src/components/job-graph/job-graph.stories.tsx +23 -19
  153. package/src/components/job-graph/job-node.stories.tsx +10 -5
  154. package/src/components/job-graph/job-node.test.tsx +55 -10
  155. package/src/components/job-graph/job-node.tsx +16 -9
  156. package/src/components/step-list/step-list.stories.tsx +2 -3
  157. package/src/components/step-list/step-list.tsx +3 -2
  158. package/src/components/workflow-run-list/job-status-strip.tsx +189 -0
  159. package/src/components/workflow-run-list/run-display.test.ts +169 -30
  160. package/src/components/workflow-run-list/run-display.ts +116 -9
  161. package/src/components/workflow-run-list/types.ts +21 -17
  162. package/src/components/workflow-run-list/workflow-run-filter-menu.tsx +100 -0
  163. package/src/components/workflow-run-list/workflow-run-filters.tsx +243 -0
  164. package/src/components/workflow-run-list/workflow-run-list-content.tsx +44 -16
  165. package/src/components/workflow-run-list/workflow-run-list-states.tsx +128 -27
  166. package/src/components/workflow-run-list/workflow-run-list-view.test.tsx +441 -104
  167. package/src/components/workflow-run-list/workflow-run-list-view.tsx +73 -43
  168. package/src/components/workflow-run-list/workflow-run-list.stories.tsx +140 -20
  169. package/src/components/workflow-run-list/workflow-run-list.tsx +20 -10
  170. package/src/components/workflow-run-list/workflow-run-row.tsx +173 -106
  171. package/src/components/workflow-run-number-label.test.tsx +45 -0
  172. package/src/components/workflow-run-number-label.tsx +47 -0
  173. package/src/components/workflow-run-summary/workflow-run-attempt-switcher.test.tsx +7 -8
  174. package/src/components/workflow-run-summary/workflow-run-attempt-switcher.tsx +13 -12
  175. package/src/components/workflow-run-summary/workflow-run-summary.stories.tsx +6 -8
  176. package/src/components/workflow-run-summary/workflow-run-summary.test.tsx +27 -2
  177. package/src/components/workflow-run-summary/workflow-run-summary.tsx +19 -9
  178. package/src/components/workflow-run-view/agent-config-failure-callout.stories.tsx +2 -3
  179. package/src/components/workflow-run-view/agent-config-failure-callout.tsx +4 -4
  180. package/src/components/workflow-run-view/job-card.stories.tsx +11 -10
  181. package/src/components/workflow-run-view/job-card.test.tsx +115 -0
  182. package/src/components/workflow-run-view/job-card.tsx +74 -35
  183. package/src/components/workflow-run-view/job-execution-switcher.tsx +31 -9
  184. package/src/components/workflow-run-view/workflow-run-view.test.tsx +88 -30
  185. package/src/components/workflow-run-view/workflow-run-view.tsx +24 -14
  186. package/src/components/workflow-status/status-visuals.test.ts +9 -0
  187. package/src/components/workflow-status/status-visuals.ts +6 -4
  188. package/src/components/workflow-status/workflow-status-icon.stories.tsx +10 -2
  189. package/src/components/workflow-status/workflow-status-icon.test.tsx +18 -0
  190. package/src/components/workflow-status/workflow-status-icon.tsx +17 -24
  191. package/src/core/entities/job-execution.ts +22 -0
  192. package/src/core/entities/job-status.test.ts +104 -0
  193. package/src/core/entities/job.ts +18 -3
  194. package/src/core/entities/workflow-run.ts +76 -7
  195. package/src/core/workflow-run.test.ts +24 -9
  196. package/src/core/workflow-run.ts +17 -2
  197. package/src/feature.ts +5 -5
  198. package/src/hooks/api/workflow-run-mapper.ts +30 -3
  199. package/src/hooks/api/workflow-runs.test.tsx +2 -0
  200. package/src/hooks/api/workflow-runs.ts +12 -7
  201. package/src/index.ts +7 -2
  202. package/src/page-harness-budget.test.ts +1 -1
  203. package/src/pages/project-workflows-page.test.tsx +59 -5
  204. package/src/pages/project-workflows-page.tsx +34 -1
  205. package/src/pages/workflow-run-detail-page.tsx +45 -0
  206. package/src/pages/workflow-run-list-page.tsx +65 -0
  207. package/src/pages/{workflow-run-page.test.tsx → workflow-run-pages.test.tsx} +211 -47
  208. package/src/routes/inputs.test.ts +193 -12
  209. package/src/routes/inputs.ts +170 -11
  210. package/src/routes/project-route.tsx +25 -0
  211. package/src/routes/run-detail.tsx +15 -8
  212. package/src/routes/runs.tsx +14 -7
  213. package/src/routes/workflows.tsx +5 -4
  214. package/test/fixtures/workflow-run.ts +76 -7
  215. package/test/pages.tsx +18 -8
  216. package/test/render.tsx +8 -2
  217. package/tsconfig.build.tsbuildinfo +1 -1
  218. package/dist/components/workflow-run-list/workflow-run-list-header.d.ts +0 -10
  219. package/dist/components/workflow-run-list/workflow-run-list-header.d.ts.map +0 -1
  220. package/dist/components/workflow-run-list/workflow-run-list-header.js +0 -55
  221. package/dist/components/workflow-run-list/workflow-run-list-header.js.map +0 -1
  222. package/dist/pages/workflow-run-first-time-use.d.ts +0 -6
  223. package/dist/pages/workflow-run-first-time-use.d.ts.map +0 -1
  224. package/dist/pages/workflow-run-first-time-use.js +0 -17
  225. package/dist/pages/workflow-run-first-time-use.js.map +0 -1
  226. package/dist/pages/workflow-run-page.d.ts +0 -10
  227. package/dist/pages/workflow-run-page.d.ts.map +0 -1
  228. package/dist/pages/workflow-run-page.js +0 -90
  229. package/dist/pages/workflow-run-page.js.map +0 -1
  230. package/src/components/workflow-run-list/workflow-run-list-header.tsx +0 -53
  231. package/src/pages/workflow-run-first-time-use.tsx +0 -17
  232. package/src/pages/workflow-run-page.tsx +0 -94
@@ -1,8 +1,8 @@
1
1
  import type { Ref } from 'react';
2
2
  import { type WorkflowRunDetail, type WorkflowRunRerunMode } from '#core/workflow-run.js';
3
3
  export interface WorkflowRunSummaryProps {
4
- workspaceId?: string | undefined;
5
- projectId?: string | undefined;
4
+ workspaceSlug?: string | undefined;
5
+ projectSlug?: string | undefined;
6
6
  run: WorkflowRunDetail;
7
7
  sourceAvailable?: boolean | undefined;
8
8
  sourceOpen?: boolean | undefined;
@@ -15,5 +15,5 @@ export interface WorkflowRunSummaryProps {
15
15
  onRerun?: ((mode: WorkflowRunRerunMode) => void) | undefined;
16
16
  latestAttempt?: number | undefined;
17
17
  }
18
- export declare function WorkflowRunSummary({ workspaceId, projectId, run, sourceAvailable, sourceOpen, sourcePanelId, sourceButtonRef, onSourceToggle, cancelling, onCancel, rerunPending, onRerun, latestAttempt, }: WorkflowRunSummaryProps): import("react").JSX.Element;
18
+ export declare function WorkflowRunSummary({ workspaceSlug, projectSlug, run, sourceAvailable, sourceOpen, sourcePanelId, sourceButtonRef, onSourceToggle, cancelling, onCancel, rerunPending, onRerun, latestAttempt, }: WorkflowRunSummaryProps): import("react").JSX.Element;
19
19
  //# sourceMappingURL=workflow-run-summary.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-run-summary.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-summary/workflow-run-summary.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,OAAO,CAAC;AAE/B,OAAO,EAIL,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EAC1B,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,oBAAoB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC7D,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"}
1
+ {"version":3,"file":"workflow-run-summary.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-summary/workflow-run-summary.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,OAAO,CAAC;AAG/B,OAAO,EAIL,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EAC1B,MAAM,uBAAuB,CAAC;AAW/B,MAAM,WAAW,uBAAuB;IACtC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,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,oBAAoB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC7D,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAED,wBAAgB,kBAAkB,CAAC,EACjC,aAAa,EACb,WAAW,EACX,GAAG,EACH,eAAuB,EACvB,UAAkB,EAClB,aAAa,EACb,eAAe,EACf,cAAc,EACd,UAAkB,EAClB,QAAQ,EACR,YAAoB,EACpB,OAAO,EACP,aAAa,GACd,EAAE,uBAAuB,+BA8IzB"}
@@ -9,18 +9,19 @@ import { TimeTickerProvider } from '@shipfox/react-ui/time-ticker';
9
9
  import { Tooltip, TooltipContent, TooltipTrigger } from '@shipfox/react-ui/tooltip';
10
10
  import { Header, Text } from '@shipfox/react-ui/typography';
11
11
  import { useId } from 'react';
12
+ import { WorkflowRunNumberLabel } from '#components/workflow-run-number-label.js';
12
13
  import { isWorkflowRunTerminal, WORKFLOW_RUN_STATUSES } from '#core/workflow-run.js';
13
14
  import { WorkflowRunDurationLabel } from '../workflow-run-duration-label.js';
14
15
  import { getWorkflowStatusVisual } from '../workflow-status/status-visuals.js';
15
16
  import { WorkflowRunAttemptSwitcher } from './workflow-run-attempt-switcher.js';
16
17
  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
+ export function WorkflowRunSummary({ workspaceSlug, projectSlug, run, sourceAvailable = false, sourceOpen = false, sourcePanelId, sourceButtonRef, onSourceToggle, cancelling = false, onCancel, rerunPending = false, onRerun, latestAttempt }) {
18
19
  const headingId = useId();
19
20
  const status = getWorkflowStatusVisual(run.runAttempt.status);
20
21
  const action = workflowRunActionForRun(run);
21
- const attemptSwitcher = latestAttempt && latestAttempt > 1 && workspaceId && projectId ? {
22
- workspaceId,
23
- projectId,
22
+ const attemptSwitcher = latestAttempt && latestAttempt > 1 && workspaceSlug && projectSlug ? {
23
+ workspaceSlug,
24
+ projectSlug,
24
25
  latestAttempt
25
26
  } : null;
26
27
  const displayDuration = run.runAttempt.displayDuration;
@@ -101,9 +102,17 @@ export function WorkflowRunSummary({ workspaceId, projectId, run, sourceAvailabl
101
102
  /*#__PURE__*/ _jsxs("div", {
102
103
  className: "col-span-2 row-start-2 flex min-w-0 items-center gap-12 overflow-hidden text-foreground-neutral-muted",
103
104
  children: [
105
+ run.number !== null ? /*#__PURE__*/ _jsxs(_Fragment, {
106
+ children: [
107
+ /*#__PURE__*/ _jsx(WorkflowRunNumberLabel, {
108
+ run: run
109
+ }),
110
+ attemptSwitcher || run.triggerDisplayLabel ? /*#__PURE__*/ _jsx(MetadataSeparator, {}) : null
111
+ ]
112
+ }) : null,
104
113
  attemptSwitcher ? /*#__PURE__*/ _jsx(WorkflowRunAttemptSwitcher, {
105
- workspaceId: attemptSwitcher.workspaceId,
106
- projectId: attemptSwitcher.projectId,
114
+ workspaceSlug: attemptSwitcher.workspaceSlug,
115
+ projectSlug: attemptSwitcher.projectSlug,
107
116
  run: run,
108
117
  latestAttempt: attemptSwitcher.latestAttempt
109
118
  }) : null,
@@ -149,7 +158,7 @@ export function WorkflowRunSummary({ workspaceId, projectId, run, sourceAvailabl
149
158
  })
150
159
  ]
151
160
  }) : null,
152
- attemptSwitcher || run.triggerDisplayLabel ? /*#__PURE__*/ _jsx(MetadataSeparator, {}) : null,
161
+ run.number !== null || attemptSwitcher || run.triggerDisplayLabel ? /*#__PURE__*/ _jsx(MetadataSeparator, {}) : null,
153
162
  /*#__PURE__*/ _jsx(RelativeTime, {
154
163
  value: run.runAttempt.createdAt,
155
164
  className: "shrink-0 whitespace-nowrap text-xs leading-20 text-foreground-neutral-muted"
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/workflow-run-summary/workflow-run-summary.tsx"],"sourcesContent":["import {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 type WorkflowRunRerunMode,\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: WorkflowRunRerunMode) => 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: WorkflowRunRerunMode) => 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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"}
1
+ {"version":3,"sources":["../../../src/components/workflow-run-summary/workflow-run-summary.tsx"],"sourcesContent":["import {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 {WorkflowRunNumberLabel} from '#components/workflow-run-number-label.js';\nimport {\n isWorkflowRunTerminal,\n type Job,\n WORKFLOW_RUN_STATUSES,\n type WorkflowRunDetail,\n type WorkflowRunRerunMode,\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 workspaceSlug?: string | undefined;\n projectSlug?: 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: WorkflowRunRerunMode) => void) | undefined;\n latestAttempt?: number | undefined;\n}\n\nexport function WorkflowRunSummary({\n workspaceSlug,\n projectSlug,\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 && workspaceSlug && projectSlug\n ? {workspaceSlug, projectSlug, 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 {run.number !== null ? (\n <>\n <WorkflowRunNumberLabel run={run} />\n {attemptSwitcher || run.triggerDisplayLabel ? <MetadataSeparator /> : null}\n </>\n ) : null}\n\n {attemptSwitcher ? (\n <WorkflowRunAttemptSwitcher\n workspaceSlug={attemptSwitcher.workspaceSlug}\n projectSlug={attemptSwitcher.projectSlug}\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 {run.number !== null || attemptSwitcher || run.triggerDisplayLabel ? (\n <MetadataSeparator />\n ) : 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: WorkflowRunRerunMode) => 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","WorkflowRunNumberLabel","isWorkflowRunTerminal","WORKFLOW_RUN_STATUSES","WorkflowRunDurationLabel","getWorkflowStatusVisual","WorkflowRunAttemptSwitcher","STATUS_BADGE_LABEL_WIDTH_CH","Math","max","map","status","label","length","WorkflowRunSummary","workspaceSlug","projectSlug","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","number","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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"}
@@ -1,6 +1,6 @@
1
1
  import type { AgentStepConfig, StepError } from '#core/workflow-run.js';
2
- export declare function AgentConfigFailureCallout({ workspaceId, config, error, }: {
3
- workspaceId: string;
2
+ export declare function AgentConfigFailureCallout({ workspaceSlug, config, error, }: {
3
+ workspaceSlug?: string | undefined;
4
4
  config: AgentStepConfig | null;
5
5
  error: StepError | null;
6
6
  }): import("react").JSX.Element;
@@ -1 +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"}
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,aAAa,EACb,MAAM,EACN,KAAK,GACN,EAAE;IACD,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;CACzB,+BAoBA"}
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Alert, AlertActions, AlertContent, AlertDescription, AlertTitle } from '@shipfox/react-ui/alert';
3
3
  import { Button } from '@shipfox/react-ui/button';
4
4
  import { Link } from '@tanstack/react-router';
5
- export function AgentConfigFailureCallout({ workspaceId, config, error }) {
5
+ export function AgentConfigFailureCallout({ workspaceSlug, config, error }) {
6
6
  const copy = agentConfigFailureCopy(config, error);
7
7
  return /*#__PURE__*/ _jsx(Alert, {
8
8
  variant: "warning",
@@ -16,16 +16,16 @@ export function AgentConfigFailureCallout({ workspaceId, config, error }) {
16
16
  /*#__PURE__*/ _jsx(AlertDescription, {
17
17
  children: copy.description
18
18
  }),
19
- copy.showProviderCta ? /*#__PURE__*/ _jsx(AlertActions, {
19
+ copy.showProviderCta && workspaceSlug ? /*#__PURE__*/ _jsx(AlertActions, {
20
20
  children: /*#__PURE__*/ _jsx(Button, {
21
21
  asChild: true,
22
22
  size: "2xs",
23
23
  variant: "secondary",
24
24
  iconRight: "chevronRight",
25
25
  children: /*#__PURE__*/ _jsx(Link, {
26
- to: "/workspaces/$wid/settings/agents",
26
+ to: "/w/$workspaceSlug/settings/agents",
27
27
  params: {
28
- wid: workspaceId
28
+ workspaceSlug
29
29
  },
30
30
  children: "Configure Agents"
31
31
  })
@@ -1 +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"}
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 workspaceSlug,\n config,\n error,\n}: {\n workspaceSlug?: string | undefined;\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 && workspaceSlug ? (\n <AlertActions>\n <Button asChild size=\"2xs\" variant=\"secondary\" iconRight=\"chevronRight\">\n <Link to=\"/w/$workspaceSlug/settings/agents\" params={{workspaceSlug}}>\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","workspaceSlug","config","error","copy","agentConfigFailureCopy","variant","animated","className","title","description","showProviderCta","asChild","size","iconRight","to","params","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,aAAa,EACbC,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,IAAIV,8BACvB,KAACP;8BACC,cAAA,KAACI;wBAAOc,OAAO;wBAACC,MAAK;wBAAMP,SAAQ;wBAAYQ,WAAU;kCACvD,cAAA,KAACf;4BAAKgB,IAAG;4BAAoCC,QAAQ;gCAACf;4BAAa;sCAAG;;;qBAKxE;;;;AAIZ;AAEA,SAASI,uBACPH,MAA8B,EAC9BC,KAAuB;IAEvB,MAAMc,WAAWC,YAAYhB,QAAQe,UAAU;IAC/C,MAAME,QAAQD,YAAYhB,QAAQiB,OAAO;IAEzC,OAAQhB,OAAOiB;QACb,KAAK;YACH,OAAO;gBACLX,OAAO,CAAC,0BAA0B,EAAEQ,UAAU;gBAC9CP,aAAa,CAAC,eAAe,EAAEO,SAAS,iFAAiF,EAAEA,SAAS,qCAAqC,CAAC;gBAC1KN,iBAAiB;YACnB;QACF,KAAK;YACH,OAAO;gBACLF,OAAO,CAAC,uBAAuB,EAAEQ,UAAU;gBAC3CP,aAAa,CAAC,eAAe,EAAEO,SAAS,2DAA2D,EAAEA,SAAS,qCAAqC,CAAC;gBACpJN,iBAAiB;YACnB;QACF,KAAK;YACH,OAAO;gBACLF,OAAO,CAAC,iCAAiC,CAAC;gBAC1CC,aAAa,CAAC,qBAAqB,EAAEO,SAAS,8GAA8G,CAAC;gBAC7JN,iBAAiB;YACnB;QACF,KAAK;YACH,OAAO;gBACLF,OAAO,CAAC,yBAAyB,CAAC;gBAClCC,aAAa,CAAC,eAAe,EAAES,MAAM,MAAM,EAAEF,SAAS,iHAAiH,CAAC;gBACxKN,iBAAiB;YACnB;QACF,KAAK;YACH,OAAO;gBACLF,OAAO;gBACPC,aACE;gBACFC,iBAAiB;YACnB;QACF,KAAKU;YACH,OAAO;gBACLZ,OAAO;gBACPC,aACE;gBACFC,iBAAiB;YACnB;IACJ;AACF;AAEA,SAASO,YAAYI,KAAgC,EAAEC,QAAgB;IACrE,OAAOD,SAASC;AAClB"}
@@ -1,8 +1,8 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import { type Job, type JobExecution, type StepSourceLocation } from '#core/workflow-run.js';
3
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;
4
+ export declare function JobCard({ workspaceSlug, job, selectedJobExecution, selectedAttemptId, onSelectedJobExecutionChange, onSelectedAttemptChange, renderExpandedStep, sourcePanelId, sourceAvailable, focusedSourceStepId, onOpenStepSource, }: {
5
+ workspaceSlug?: string | undefined;
6
6
  job: Job;
7
7
  selectedJobExecution: JobExecution | undefined;
8
8
  selectedAttemptId: string | null | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"job-card.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-view/job-card.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAGrC,OAAO,EAEL,KAAK,GAAG,EACR,KAAK,YAAY,EAKjB,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"}
1
+ {"version":3,"file":"job-card.d.ts","sourceRoot":"","sources":["../../../src/components/workflow-run-view/job-card.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAGrC,OAAO,EAKL,KAAK,GAAG,EAER,KAAK,YAAY,EAKjB,KAAK,kBAAkB,EAIxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAC,KAAK,mBAAmB,EAAoC,MAAM,uBAAuB,CAAC;AAiBlG,wBAAgB,OAAO,CAAC,EACtB,aAAa,EACb,GAAG,EACH,oBAAoB,EACpB,iBAAiB,EACjB,4BAA4B,EAC5B,uBAAuB,EACvB,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,gBAAgB,GACjB,EAAE;IACD,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,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,+BAyIA"}
@@ -10,25 +10,30 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@shipfox/react-ui/toolt
10
10
  import { Text } from '@shipfox/react-ui/typography';
11
11
  import { Fragment, useId, useRef, useState } from 'react';
12
12
  import { getWorkflowStatusVisual } from '#components/workflow-status/status-visuals.js';
13
- import { AGENT_CONFIG_ISSUES, STEP_ERROR_REASONS, WORKFLOW_JOB_STATUSES, workflowRunTriggerDisplayLabel, workflowRunTriggerLabel } from '#core/workflow-run.js';
13
+ import { AGENT_CONFIG_ISSUES, defaultJobExecution, deriveJobDisplayStatus, deriveJobExecutionDisplayStatus, STEP_ERROR_REASONS, WORKFLOW_JOB_STATUSES, workflowRunTriggerDisplayLabel, workflowRunTriggerLabel } from '#core/workflow-run.js';
14
14
  import { StepList } from '../step-list/index.js';
15
15
  import { AgentConfigFailureCallout } from './agent-config-failure-callout.js';
16
16
  import { JobExecutionSwitcher } from './job-execution-switcher.js';
17
17
  import { formatJobExecutionTime, JobExecutionTimeText } from './job-execution-time-text.js';
18
18
  import { StepAttemptLogPanel } from './step-attempt-log-panel.js';
19
- const STATUS_BADGE_LABEL_WIDTH_CH = Math.max(...WORKFLOW_JOB_STATUSES.map((status)=>getWorkflowStatusVisual(status).label.length));
20
- export function JobCard({ workspaceId, job, selectedJobExecution, selectedAttemptId, onSelectedJobExecutionChange, onSelectedAttemptChange, renderExpandedStep, sourcePanelId, sourceAvailable, focusedSourceStepId, onOpenStepSource }) {
19
+ const STATUS_BADGE_LABEL_WIDTH_CH = Math.max(...[
20
+ ...WORKFLOW_JOB_STATUSES,
21
+ 'listening'
22
+ ].map((status)=>getWorkflowStatusVisual(status).label.length));
23
+ export function JobCard({ workspaceSlug, job, selectedJobExecution, selectedAttemptId, onSelectedJobExecutionChange, onSelectedAttemptChange, renderExpandedStep, sourcePanelId, sourceAvailable, focusedSourceStepId, onOpenStepSource }) {
21
24
  const titleId = useId();
22
25
  const sourceButtonRef = useRef(null);
23
26
  const [localSelectedAttempt, setLocalSelectedAttempt] = useState({
24
27
  jobExecutionId: undefined,
25
28
  attemptId: null
26
29
  });
27
- const selectedExecutionStatus = selectedJobExecution?.status ?? job.status;
30
+ const title = selectedJobExecution?.displayName ?? job.displayName;
31
+ const isNonDefaultExecutionSelected = selectedJobExecution !== undefined && selectedJobExecution.id !== defaultJobExecution(job)?.id;
32
+ const selectedExecutionStatus = isNonDefaultExecutionSelected ? deriveJobExecutionDisplayStatus(selectedJobExecution) : deriveJobDisplayStatus(job);
28
33
  const effectiveSelectedAttemptId = selectedAttemptId === undefined && localSelectedAttempt.jobExecutionId === selectedJobExecution?.id ? localSelectedAttempt.attemptId : selectedAttemptId;
29
34
  const selectedSourceAction = selectedStepSourceAction(selectedJobExecution, effectiveSelectedAttemptId);
30
35
  const defaultRenderExpandedStep = ({ step, stepId, attempt, attemptError, attemptStatus, carriedOver })=>carriedOver ? /*#__PURE__*/ _jsx(CarriedOverStepPanel, {}) : /*#__PURE__*/ _jsx(StepAttemptDetailPanel, {
31
- workspaceId: workspaceId,
36
+ workspaceSlug: workspaceSlug,
32
37
  step: step,
33
38
  stepId: stepId,
34
39
  attempt: attempt,
@@ -62,7 +67,7 @@ export function JobCard({ workspaceId, job, selectedJobExecution, selectedAttemp
62
67
  size: "sm",
63
68
  bold: true,
64
69
  className: "sr-only",
65
- children: job.displayName
70
+ children: title
66
71
  }),
67
72
  /*#__PURE__*/ _jsxs("div", {
68
73
  className: "flex min-w-0 items-center gap-8",
@@ -85,13 +90,16 @@ export function JobCard({ workspaceId, job, selectedJobExecution, selectedAttemp
85
90
  /*#__PURE__*/ _jsx(JobStatusBadge, {
86
91
  status: selectedExecutionStatus
87
92
  }),
88
- /*#__PURE__*/ _jsx(Text, {
89
- as: "h2",
90
- id: titleId,
91
- size: "sm",
92
- bold: true,
93
- className: "min-w-0 truncate text-foreground-neutral-base",
94
- children: job.displayName
93
+ /*#__PURE__*/ _jsx("div", {
94
+ className: "flex min-w-0 items-center gap-8",
95
+ children: /*#__PURE__*/ _jsx(Text, {
96
+ as: "h2",
97
+ id: titleId,
98
+ size: "sm",
99
+ bold: true,
100
+ className: "min-w-0 truncate text-foreground-neutral-base",
101
+ children: title
102
+ })
95
103
  })
96
104
  ]
97
105
  }),
@@ -200,7 +208,8 @@ function JobExecutionMetadata({ execution }) {
200
208
  }) : /*#__PURE__*/ _jsx(JobExecutionMetadataItem, {
201
209
  icon: item.icon,
202
210
  kind: item.kind,
203
- time: item.time
211
+ time: item.time,
212
+ displayStatus: deriveJobExecutionDisplayStatus(execution)
204
213
  })
205
214
  ]
206
215
  }, item.key))
@@ -258,9 +267,9 @@ function JobExecutionTriggerMetadata({ execution }) {
258
267
  ]
259
268
  });
260
269
  }
261
- function JobExecutionMetadataItem({ icon, kind, time }) {
270
+ function JobExecutionMetadataItem({ icon, kind, time, displayStatus }) {
262
271
  useTimeTick();
263
- const tooltip = `${jobExecutionTimeVerb(kind, time)} for ${formatJobExecutionTime(time)}`;
272
+ const tooltip = `${jobExecutionTimeVerb(kind, time, displayStatus)} for ${formatJobExecutionTime(time)}`;
264
273
  return /*#__PURE__*/ _jsxs(Tooltip, {
265
274
  children: [
266
275
  /*#__PURE__*/ _jsx(TooltipTrigger, {
@@ -294,9 +303,11 @@ function JobExecutionMetadataItem({ icon, kind, time }) {
294
303
  ]
295
304
  });
296
305
  }
297
- function jobExecutionTimeVerb(kind, time) {
298
- if (kind === 'queue') return time.state === 'live' ? 'Queuing' : 'Queued';
299
- return time.state === 'live' ? 'Running' : 'Ran';
306
+ function jobExecutionTimeVerb(kind, time, displayStatus) {
307
+ if (kind === 'queue') return time.state === 'live' ? 'Queueing' : 'Queued';
308
+ if (time.state !== 'live') return 'Ran';
309
+ if (displayStatus === 'running') return 'Running';
310
+ return displayStatus === 'pending' ? 'Runner assigned' : 'Execution elapsed';
300
311
  }
301
312
  function MetadataSeparator() {
302
313
  return /*#__PURE__*/ _jsx("span", {
@@ -317,13 +328,13 @@ function selectedStepSourceAction(jobExecution, selectedAttemptId) {
317
328
  }
318
329
  return null;
319
330
  }
320
- function StepAttemptDetailPanel({ workspaceId, step, stepId, attempt, attemptError, attemptStatus }) {
331
+ function StepAttemptDetailPanel({ workspaceSlug, step, stepId, attempt, attemptError, attemptStatus }) {
321
332
  const selectedAttemptError = toSelectedAttemptError(step, attemptError) ?? step.error;
322
333
  return /*#__PURE__*/ _jsxs("div", {
323
334
  className: "flex min-w-0 flex-col gap-10",
324
335
  children: [
325
336
  isAgentConfigFailure(step, selectedAttemptError) ? /*#__PURE__*/ _jsx(AgentConfigFailureCallout, {
326
- workspaceId: workspaceId,
337
+ workspaceSlug: workspaceSlug,
327
338
  config: step.agentConfig,
328
339
  error: selectedAttemptError
329
340
  }) : null,
@@ -350,7 +361,7 @@ function toSelectedAttemptError(step, error) {
350
361
  signal: typeof error.signal === 'string' ? error.signal : undefined,
351
362
  reason: resolvedReason,
352
363
  agentConfigIssue,
353
- category: step.type === 'setup' ? 'setup' : 'user'
364
+ category: step.type === 'setup' || step.type === 'checkout' ? 'setup' : 'user'
354
365
  };
355
366
  }
356
367
  function isAgentConfigFailure(step, error) {
@@ -364,32 +375,40 @@ function emptyStateForJob(job, jobExecution) {
364
375
  status: 'succeeded'
365
376
  };
366
377
  }
367
- if (jobExecution.status === 'pending') {
378
+ const displayStatus = job.mode === 'listening' ? deriveJobExecutionDisplayStatus(jobExecution) : deriveJobDisplayStatus(job);
379
+ if (jobExecution.status === 'running' && displayStatus === 'pending') {
380
+ return {
381
+ title: 'Runner preparing job',
382
+ description: 'A runner is assigned. Steps will appear here when work begins.',
383
+ status: displayStatus
384
+ };
385
+ }
386
+ if (displayStatus === 'pending') {
368
387
  return {
369
388
  title: 'Waiting for this job to start',
370
389
  description: 'Steps will appear here once the job starts.',
371
- status: jobExecution.status
390
+ status: displayStatus
372
391
  };
373
392
  }
374
- if (jobExecution.status === 'running') {
393
+ if (displayStatus === 'running') {
375
394
  return {
376
395
  title: 'Waiting for the first step',
377
- description: 'This job is running, but no steps have started yet.',
378
- status: jobExecution.status
396
+ description: 'The first running step will appear here shortly.',
397
+ status: displayStatus
379
398
  };
380
399
  }
381
- if (jobExecution.status === 'cancelled') {
400
+ if (displayStatus === 'cancelled') {
382
401
  return {
383
402
  title: 'Cancelled before start',
384
403
  description: 'This job was cancelled before any step started.',
385
- status: jobExecution.status
404
+ status: displayStatus
386
405
  };
387
406
  }
388
- if (jobExecution.status === 'succeeded' || jobExecution.status === 'failed') {
407
+ if (displayStatus === 'succeeded' || displayStatus === 'failed') {
389
408
  return {
390
409
  title: 'No steps recorded',
391
410
  description: `Execution #${jobExecution.sequence} finished without recorded steps.`,
392
- status: jobExecution.status
411
+ status: displayStatus
393
412
  };
394
413
  }
395
414
  return undefined;
@@ -406,7 +425,7 @@ function emptyStateForMissingExecution(job) {
406
425
  return {
407
426
  title: 'Waiting for trigger events',
408
427
  description: 'Matching trigger events will create job executions here.',
409
- status: 'running'
428
+ status: deriveJobDisplayStatus(job)
410
429
  };
411
430
  }
412
431
  if (job.mode === 'listening' && job.listenerStatus === 'resolved') {