@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.
Files changed (327) hide show
  1. package/.storybook/main.ts +1 -0
  2. package/.storybook/preview.css +10 -0
  3. package/.storybook/preview.tsx +97 -0
  4. package/.swcrc +42 -0
  5. package/.turbo/turbo-build.log +2 -0
  6. package/.turbo/turbo-type$colon$emit.log +1 -0
  7. package/.turbo/turbo-type.log +1 -0
  8. package/CHANGELOG.md +162 -0
  9. package/LICENSE +21 -0
  10. package/dist/components/identifier/identifier.d.ts +6 -0
  11. package/dist/components/identifier/identifier.d.ts.map +1 -0
  12. package/dist/components/identifier/identifier.js +144 -0
  13. package/dist/components/identifier/identifier.js.map +1 -0
  14. package/dist/components/identifier/index.d.ts +2 -0
  15. package/dist/components/identifier/index.d.ts.map +1 -0
  16. package/dist/components/identifier/index.js +3 -0
  17. package/dist/components/identifier/index.js.map +1 -0
  18. package/dist/components/job-graph/graph-model.d.ts +27 -0
  19. package/dist/components/job-graph/graph-model.d.ts.map +1 -0
  20. package/dist/components/job-graph/graph-model.js +107 -0
  21. package/dist/components/job-graph/graph-model.js.map +1 -0
  22. package/dist/components/job-graph/index.d.ts +3 -0
  23. package/dist/components/job-graph/index.d.ts.map +1 -0
  24. package/dist/components/job-graph/index.js +3 -0
  25. package/dist/components/job-graph/index.js.map +1 -0
  26. package/dist/components/job-graph/job-duration-format.d.ts +4 -0
  27. package/dist/components/job-graph/job-duration-format.d.ts.map +1 -0
  28. package/dist/components/job-graph/job-duration-format.js +41 -0
  29. package/dist/components/job-graph/job-duration-format.js.map +1 -0
  30. package/dist/components/job-graph/job-duration-label.d.ts +5 -0
  31. package/dist/components/job-graph/job-duration-label.d.ts.map +1 -0
  32. package/dist/components/job-graph/job-duration-label.js +33 -0
  33. package/dist/components/job-graph/job-duration-label.js.map +1 -0
  34. package/dist/components/job-graph/job-graph-content.d.ts +9 -0
  35. package/dist/components/job-graph/job-graph-content.d.ts.map +1 -0
  36. package/dist/components/job-graph/job-graph-content.js +181 -0
  37. package/dist/components/job-graph/job-graph-content.js.map +1 -0
  38. package/dist/components/job-graph/job-graph-view.d.ts +11 -0
  39. package/dist/components/job-graph/job-graph-view.d.ts.map +1 -0
  40. package/dist/components/job-graph/job-graph-view.js +24 -0
  41. package/dist/components/job-graph/job-graph-view.js.map +1 -0
  42. package/dist/components/job-graph/job-graph.d.ts +3 -0
  43. package/dist/components/job-graph/job-graph.d.ts.map +1 -0
  44. package/dist/components/job-graph/job-graph.js +21 -0
  45. package/dist/components/job-graph/job-graph.js.map +1 -0
  46. package/dist/components/job-graph/job-node.d.ts +16 -0
  47. package/dist/components/job-graph/job-node.d.ts.map +1 -0
  48. package/dist/components/job-graph/job-node.js +196 -0
  49. package/dist/components/job-graph/job-node.js.map +1 -0
  50. package/dist/components/job-graph/types.d.ts +9 -0
  51. package/dist/components/job-graph/types.d.ts.map +1 -0
  52. package/dist/components/job-graph/types.js +3 -0
  53. package/dist/components/job-graph/types.js.map +1 -0
  54. package/dist/components/step-list/index.d.ts +3 -0
  55. package/dist/components/step-list/index.d.ts.map +1 -0
  56. package/dist/components/step-list/index.js +3 -0
  57. package/dist/components/step-list/index.js.map +1 -0
  58. package/dist/components/step-list/step-list-model.d.ts +36 -0
  59. package/dist/components/step-list/step-list-model.d.ts.map +1 -0
  60. package/dist/components/step-list/step-list-model.js +135 -0
  61. package/dist/components/step-list/step-list-model.js.map +1 -0
  62. package/dist/components/step-list/step-list.d.ts +32 -0
  63. package/dist/components/step-list/step-list.d.ts.map +1 -0
  64. package/dist/components/step-list/step-list.js +409 -0
  65. package/dist/components/step-list/step-list.js.map +1 -0
  66. package/dist/components/workflow-run-duration-label.d.ts +8 -0
  67. package/dist/components/workflow-run-duration-label.d.ts.map +1 -0
  68. package/dist/components/workflow-run-duration-label.js +84 -0
  69. package/dist/components/workflow-run-duration-label.js.map +1 -0
  70. package/dist/components/workflow-run-list/index.d.ts +2 -0
  71. package/dist/components/workflow-run-list/index.d.ts.map +1 -0
  72. package/dist/components/workflow-run-list/index.js +3 -0
  73. package/dist/components/workflow-run-list/index.js.map +1 -0
  74. package/dist/components/workflow-run-list/run-display.d.ts +5 -0
  75. package/dist/components/workflow-run-list/run-display.d.ts.map +1 -0
  76. package/dist/components/workflow-run-list/run-display.js +19 -0
  77. package/dist/components/workflow-run-list/run-display.js.map +1 -0
  78. package/dist/components/workflow-run-list/types.d.ts +21 -0
  79. package/dist/components/workflow-run-list/types.d.ts.map +1 -0
  80. package/dist/components/workflow-run-list/types.js +3 -0
  81. package/dist/components/workflow-run-list/types.js.map +1 -0
  82. package/dist/components/workflow-run-list/workflow-run-list-content.d.ts +14 -0
  83. package/dist/components/workflow-run-list/workflow-run-list-content.d.ts.map +1 -0
  84. package/dist/components/workflow-run-list/workflow-run-list-content.js +37 -0
  85. package/dist/components/workflow-run-list/workflow-run-list-content.js.map +1 -0
  86. package/dist/components/workflow-run-list/workflow-run-list-header.d.ts +10 -0
  87. package/dist/components/workflow-run-list/workflow-run-list-header.d.ts.map +1 -0
  88. package/dist/components/workflow-run-list/workflow-run-list-header.js +55 -0
  89. package/dist/components/workflow-run-list/workflow-run-list-header.js.map +1 -0
  90. package/dist/components/workflow-run-list/workflow-run-list-states.d.ts +15 -0
  91. package/dist/components/workflow-run-list/workflow-run-list-states.d.ts.map +1 -0
  92. package/dist/components/workflow-run-list/workflow-run-list-states.js +103 -0
  93. package/dist/components/workflow-run-list/workflow-run-list-states.js.map +1 -0
  94. package/dist/components/workflow-run-list/workflow-run-list-view.d.ts +3 -0
  95. package/dist/components/workflow-run-list/workflow-run-list-view.d.ts.map +1 -0
  96. package/dist/components/workflow-run-list/workflow-run-list-view.js +46 -0
  97. package/dist/components/workflow-run-list/workflow-run-list-view.js.map +1 -0
  98. package/dist/components/workflow-run-list/workflow-run-list.d.ts +3 -0
  99. package/dist/components/workflow-run-list/workflow-run-list.d.ts.map +1 -0
  100. package/dist/components/workflow-run-list/workflow-run-list.js +20 -0
  101. package/dist/components/workflow-run-list/workflow-run-list.js.map +1 -0
  102. package/dist/components/workflow-run-list/workflow-run-row.d.ts +14 -0
  103. package/dist/components/workflow-run-list/workflow-run-row.d.ts.map +1 -0
  104. package/dist/components/workflow-run-list/workflow-run-row.js +172 -0
  105. package/dist/components/workflow-run-list/workflow-run-row.js.map +1 -0
  106. package/dist/components/workflow-run-summary/index.d.ts +2 -0
  107. package/dist/components/workflow-run-summary/index.d.ts.map +1 -0
  108. package/dist/components/workflow-run-summary/index.js +3 -0
  109. package/dist/components/workflow-run-summary/index.js.map +1 -0
  110. package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.d.ts +9 -0
  111. package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.d.ts.map +1 -0
  112. package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js +138 -0
  113. package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js.map +1 -0
  114. package/dist/components/workflow-run-summary/workflow-run-summary.d.ts +20 -0
  115. package/dist/components/workflow-run-summary/workflow-run-summary.d.ts.map +1 -0
  116. package/dist/components/workflow-run-summary/workflow-run-summary.js +252 -0
  117. package/dist/components/workflow-run-summary/workflow-run-summary.js.map +1 -0
  118. package/dist/components/workflow-run-view/agent-config-failure-callout.d.ts +7 -0
  119. package/dist/components/workflow-run-view/agent-config-failure-callout.d.ts.map +1 -0
  120. package/dist/components/workflow-run-view/agent-config-failure-callout.js +84 -0
  121. package/dist/components/workflow-run-view/agent-config-failure-callout.js.map +1 -0
  122. package/dist/components/workflow-run-view/index.d.ts +3 -0
  123. package/dist/components/workflow-run-view/index.d.ts.map +1 -0
  124. package/dist/components/workflow-run-view/index.js +4 -0
  125. package/dist/components/workflow-run-view/index.js.map +1 -0
  126. package/dist/components/workflow-run-view/job-card.d.ts +17 -0
  127. package/dist/components/workflow-run-view/job-card.d.ts.map +1 -0
  128. package/dist/components/workflow-run-view/job-card.js +476 -0
  129. package/dist/components/workflow-run-view/job-card.js.map +1 -0
  130. package/dist/components/workflow-run-view/job-execution-switcher.d.ts +10 -0
  131. package/dist/components/workflow-run-view/job-execution-switcher.d.ts.map +1 -0
  132. package/dist/components/workflow-run-view/job-execution-switcher.js +171 -0
  133. package/dist/components/workflow-run-view/job-execution-switcher.js.map +1 -0
  134. package/dist/components/workflow-run-view/job-execution-time-text.d.ts +6 -0
  135. package/dist/components/workflow-run-view/job-execution-time-text.d.ts.map +1 -0
  136. package/dist/components/workflow-run-view/job-execution-time-text.js +24 -0
  137. package/dist/components/workflow-run-view/job-execution-time-text.js.map +1 -0
  138. package/dist/components/workflow-run-view/step-attempt-log-panel.d.ts +9 -0
  139. package/dist/components/workflow-run-view/step-attempt-log-panel.d.ts.map +1 -0
  140. package/dist/components/workflow-run-view/step-attempt-log-panel.js +152 -0
  141. package/dist/components/workflow-run-view/step-attempt-log-panel.js.map +1 -0
  142. package/dist/components/workflow-run-view/workflow-run-selection.d.ts +14 -0
  143. package/dist/components/workflow-run-view/workflow-run-selection.d.ts.map +1 -0
  144. package/dist/components/workflow-run-view/workflow-run-selection.js +56 -0
  145. package/dist/components/workflow-run-view/workflow-run-selection.js.map +1 -0
  146. package/dist/components/workflow-run-view/workflow-run-states.d.ts +12 -0
  147. package/dist/components/workflow-run-view/workflow-run-states.d.ts.map +1 -0
  148. package/dist/components/workflow-run-view/workflow-run-states.js +91 -0
  149. package/dist/components/workflow-run-view/workflow-run-states.js.map +1 -0
  150. package/dist/components/workflow-run-view/workflow-run-view.d.ts +15 -0
  151. package/dist/components/workflow-run-view/workflow-run-view.d.ts.map +1 -0
  152. package/dist/components/workflow-run-view/workflow-run-view.js +285 -0
  153. package/dist/components/workflow-run-view/workflow-run-view.js.map +1 -0
  154. package/dist/components/workflow-source-panel/index.d.ts +2 -0
  155. package/dist/components/workflow-source-panel/index.d.ts.map +1 -0
  156. package/dist/components/workflow-source-panel/index.js +3 -0
  157. package/dist/components/workflow-source-panel/index.js.map +1 -0
  158. package/dist/components/workflow-source-panel/workflow-source-panel.d.ts +13 -0
  159. package/dist/components/workflow-source-panel/workflow-source-panel.d.ts.map +1 -0
  160. package/dist/components/workflow-source-panel/workflow-source-panel.js +91 -0
  161. package/dist/components/workflow-source-panel/workflow-source-panel.js.map +1 -0
  162. package/dist/components/workflow-status/status-visuals.d.ts +12 -0
  163. package/dist/components/workflow-status/status-visuals.d.ts.map +1 -0
  164. package/dist/components/workflow-status/status-visuals.js +54 -0
  165. package/dist/components/workflow-status/status-visuals.js.map +1 -0
  166. package/dist/components/workflow-status/workflow-status-icon.d.ts +22 -0
  167. package/dist/components/workflow-status/workflow-status-icon.d.ts.map +1 -0
  168. package/dist/components/workflow-status/workflow-status-icon.js +100 -0
  169. package/dist/components/workflow-status/workflow-status-icon.js.map +1 -0
  170. package/dist/core/entities/job-execution.d.ts +69 -0
  171. package/dist/core/entities/job-execution.d.ts.map +1 -0
  172. package/dist/core/entities/job-execution.js +83 -0
  173. package/dist/core/entities/job-execution.js.map +1 -0
  174. package/dist/core/entities/job.d.ts +56 -0
  175. package/dist/core/entities/job.d.ts.map +1 -0
  176. package/dist/core/entities/job.js +71 -0
  177. package/dist/core/entities/job.js.map +1 -0
  178. package/dist/core/entities/step-attempt.d.ts +49 -0
  179. package/dist/core/entities/step-attempt.d.ts.map +1 -0
  180. package/dist/core/entities/step-attempt.js +48 -0
  181. package/dist/core/entities/step-attempt.js.map +1 -0
  182. package/dist/core/entities/step.d.ts +41 -0
  183. package/dist/core/entities/step.d.ts.map +1 -0
  184. package/dist/core/entities/step.js +51 -0
  185. package/dist/core/entities/step.js.map +1 -0
  186. package/dist/core/entities/workflow-run-attempt.d.ts +44 -0
  187. package/dist/core/entities/workflow-run-attempt.d.ts.map +1 -0
  188. package/dist/core/entities/workflow-run-attempt.js +51 -0
  189. package/dist/core/entities/workflow-run-attempt.js.map +1 -0
  190. package/dist/core/entities/workflow-run.d.ts +61 -0
  191. package/dist/core/entities/workflow-run.d.ts.map +1 -0
  192. package/dist/core/entities/workflow-run.js +104 -0
  193. package/dist/core/entities/workflow-run.js.map +1 -0
  194. package/dist/core/workflow-run-url-state.d.ts +13 -0
  195. package/dist/core/workflow-run-url-state.d.ts.map +1 -0
  196. package/dist/core/workflow-run-url-state.js +43 -0
  197. package/dist/core/workflow-run-url-state.js.map +1 -0
  198. package/dist/core/workflow-run.d.ts +13 -0
  199. package/dist/core/workflow-run.d.ts.map +1 -0
  200. package/dist/core/workflow-run.js +8 -0
  201. package/dist/core/workflow-run.js.map +1 -0
  202. package/dist/env.d.js +2 -0
  203. package/dist/env.d.js.map +1 -0
  204. package/dist/feature.d.ts +20 -0
  205. package/dist/feature.d.ts.map +1 -0
  206. package/dist/feature.js +27 -0
  207. package/dist/feature.js.map +1 -0
  208. package/dist/hooks/api/workflow-runs.d.ts +109 -0
  209. package/dist/hooks/api/workflow-runs.d.ts.map +1 -0
  210. package/dist/hooks/api/workflow-runs.js +394 -0
  211. package/dist/hooks/api/workflow-runs.js.map +1 -0
  212. package/dist/index.d.ts +5 -0
  213. package/dist/index.d.ts.map +1 -0
  214. package/dist/index.js +5 -0
  215. package/dist/index.js.map +1 -0
  216. package/dist/pages/workflow-run-first-time-use.d.ts +6 -0
  217. package/dist/pages/workflow-run-first-time-use.d.ts.map +1 -0
  218. package/dist/pages/workflow-run-first-time-use.js +17 -0
  219. package/dist/pages/workflow-run-first-time-use.js.map +1 -0
  220. package/dist/pages/workflow-run-page.d.ts +8 -0
  221. package/dist/pages/workflow-run-page.d.ts.map +1 -0
  222. package/dist/pages/workflow-run-page.js +83 -0
  223. package/dist/pages/workflow-run-page.js.map +1 -0
  224. package/dist/routes/run-detail.d.ts +8 -0
  225. package/dist/routes/run-detail.d.ts.map +1 -0
  226. package/dist/routes/run-detail.js +21 -0
  227. package/dist/routes/run-detail.js.map +1 -0
  228. package/dist/routes/runs.d.ts +8 -0
  229. package/dist/routes/runs.d.ts.map +1 -0
  230. package/dist/routes/runs.js +20 -0
  231. package/dist/routes/runs.js.map +1 -0
  232. package/dist/tsconfig.test.tsbuildinfo +1 -0
  233. package/package.json +114 -0
  234. package/src/components/identifier/identifier.tsx +178 -0
  235. package/src/components/identifier/index.ts +1 -0
  236. package/src/components/job-graph/graph-model.test.ts +189 -0
  237. package/src/components/job-graph/graph-model.ts +178 -0
  238. package/src/components/job-graph/index.ts +2 -0
  239. package/src/components/job-graph/job-duration-format.ts +54 -0
  240. package/src/components/job-graph/job-duration-label.tsx +29 -0
  241. package/src/components/job-graph/job-graph-content.tsx +225 -0
  242. package/src/components/job-graph/job-graph-view.test.tsx +298 -0
  243. package/src/components/job-graph/job-graph-view.tsx +45 -0
  244. package/src/components/job-graph/job-graph.stories.tsx +182 -0
  245. package/src/components/job-graph/job-graph.tsx +24 -0
  246. package/src/components/job-graph/job-node.stories.tsx +364 -0
  247. package/src/components/job-graph/job-node.test.tsx +347 -0
  248. package/src/components/job-graph/job-node.tsx +202 -0
  249. package/src/components/job-graph/types.ts +9 -0
  250. package/src/components/step-list/index.ts +6 -0
  251. package/src/components/step-list/step-list-model.test.ts +369 -0
  252. package/src/components/step-list/step-list-model.ts +205 -0
  253. package/src/components/step-list/step-list.stories.tsx +419 -0
  254. package/src/components/step-list/step-list.test.tsx +566 -0
  255. package/src/components/step-list/step-list.tsx +494 -0
  256. package/src/components/workflow-run-duration-label.tsx +118 -0
  257. package/src/components/workflow-run-list/index.ts +1 -0
  258. package/src/components/workflow-run-list/run-display.test.ts +53 -0
  259. package/src/components/workflow-run-list/run-display.ts +22 -0
  260. package/src/components/workflow-run-list/types.ts +22 -0
  261. package/src/components/workflow-run-list/workflow-run-list-content.tsx +58 -0
  262. package/src/components/workflow-run-list/workflow-run-list-header.tsx +53 -0
  263. package/src/components/workflow-run-list/workflow-run-list-states.tsx +86 -0
  264. package/src/components/workflow-run-list/workflow-run-list-view.test.tsx +178 -0
  265. package/src/components/workflow-run-list/workflow-run-list-view.tsx +57 -0
  266. package/src/components/workflow-run-list/workflow-run-list.stories.tsx +111 -0
  267. package/src/components/workflow-run-list/workflow-run-list.tsx +29 -0
  268. package/src/components/workflow-run-list/workflow-run-row.tsx +176 -0
  269. package/src/components/workflow-run-summary/index.ts +1 -0
  270. package/src/components/workflow-run-summary/workflow-run-attempt-switcher.test.tsx +230 -0
  271. package/src/components/workflow-run-summary/workflow-run-attempt-switcher.tsx +146 -0
  272. package/src/components/workflow-run-summary/workflow-run-summary.stories.tsx +414 -0
  273. package/src/components/workflow-run-summary/workflow-run-summary.test.tsx +354 -0
  274. package/src/components/workflow-run-summary/workflow-run-summary.tsx +295 -0
  275. package/src/components/workflow-run-view/agent-config-failure-callout.stories.tsx +140 -0
  276. package/src/components/workflow-run-view/agent-config-failure-callout.tsx +93 -0
  277. package/src/components/workflow-run-view/index.ts +2 -0
  278. package/src/components/workflow-run-view/job-card.stories.tsx +788 -0
  279. package/src/components/workflow-run-view/job-card.tsx +566 -0
  280. package/src/components/workflow-run-view/job-execution-switcher.tsx +170 -0
  281. package/src/components/workflow-run-view/job-execution-time-text.tsx +34 -0
  282. package/src/components/workflow-run-view/step-attempt-log-panel.test.tsx +290 -0
  283. package/src/components/workflow-run-view/step-attempt-log-panel.tsx +152 -0
  284. package/src/components/workflow-run-view/workflow-run-selection.test.ts +280 -0
  285. package/src/components/workflow-run-view/workflow-run-selection.ts +89 -0
  286. package/src/components/workflow-run-view/workflow-run-states.tsx +70 -0
  287. package/src/components/workflow-run-view/workflow-run-view.test.tsx +1214 -0
  288. package/src/components/workflow-run-view/workflow-run-view.tsx +341 -0
  289. package/src/components/workflow-source-panel/index.ts +1 -0
  290. package/src/components/workflow-source-panel/workflow-source-panel.stories.tsx +110 -0
  291. package/src/components/workflow-source-panel/workflow-source-panel.test.tsx +96 -0
  292. package/src/components/workflow-source-panel/workflow-source-panel.tsx +136 -0
  293. package/src/components/workflow-status/status-visuals.test.ts +38 -0
  294. package/src/components/workflow-status/status-visuals.ts +36 -0
  295. package/src/components/workflow-status/workflow-status-icon.stories.tsx +90 -0
  296. package/src/components/workflow-status/workflow-status-icon.tsx +135 -0
  297. package/src/core/entities/job-execution.ts +139 -0
  298. package/src/core/entities/job.ts +149 -0
  299. package/src/core/entities/step-attempt.ts +89 -0
  300. package/src/core/entities/step.ts +105 -0
  301. package/src/core/entities/workflow-run-attempt.ts +87 -0
  302. package/src/core/entities/workflow-run.ts +183 -0
  303. package/src/core/workflow-run-url-state.ts +61 -0
  304. package/src/core/workflow-run.test.ts +640 -0
  305. package/src/core/workflow-run.ts +66 -0
  306. package/src/env.d.ts +8 -0
  307. package/src/feature.ts +26 -0
  308. package/src/hooks/api/workflow-runs.test.tsx +410 -0
  309. package/src/hooks/api/workflow-runs.ts +485 -0
  310. package/src/index.ts +45 -0
  311. package/src/page-harness-budget.test.ts +33 -0
  312. package/src/pages/workflow-run-first-time-use.tsx +17 -0
  313. package/src/pages/workflow-run-page.test.tsx +517 -0
  314. package/src/pages/workflow-run-page.tsx +89 -0
  315. package/src/routes/run-detail.tsx +15 -0
  316. package/src/routes/runs.tsx +11 -0
  317. package/test/fixtures/logs.ts +13 -0
  318. package/test/fixtures/workflow-run.ts +311 -0
  319. package/test/pages.tsx +79 -0
  320. package/test/render.tsx +40 -0
  321. package/test/setup.ts +3 -0
  322. package/tsconfig.build.json +9 -0
  323. package/tsconfig.build.tsbuildinfo +1 -0
  324. package/tsconfig.json +3 -0
  325. package/tsconfig.test.json +8 -0
  326. package/vercel.json +8 -0
  327. package/vitest.config.ts +70 -0
@@ -0,0 +1,414 @@
1
+ import {argosScreenshot} from '@argos-ci/storybook/vitest';
2
+ import type {RerunMode} from '@shipfox/api-workflows-dto';
3
+ import {configureApiClient} from '@shipfox/client-api';
4
+ import type {Decorator, Meta, StoryObj} from '@storybook/react';
5
+ import {QueryClient, QueryClientProvider} from '@tanstack/react-query';
6
+ import {
7
+ createMemoryHistory,
8
+ createRootRoute,
9
+ createRoute,
10
+ createRouter,
11
+ Outlet,
12
+ RouterProvider,
13
+ } from '@tanstack/react-router';
14
+ import type {ReactNode} from 'react';
15
+ import {useEffect, useState} from 'react';
16
+ import {screen, userEvent, within} from 'storybook/test';
17
+ import {WorkflowRunAttempt, type WorkflowRunStatus} from '#core/workflow-run.js';
18
+ import {
19
+ runAttemptsResponseDto,
20
+ workflowJobDto,
21
+ workflowRunAttemptDto,
22
+ workflowRunDetail,
23
+ } from '#test/fixtures/workflow-run.js';
24
+ import {WorkflowRunSummary} from './workflow-run-summary.js';
25
+
26
+ const ROOT_RUN_ID = '11111111-1111-4111-8111-111111111111';
27
+ const CURRENT_RUN_ID = '22222222-2222-4222-8222-222222222222';
28
+ const NEXT_RUN_ID = '33333333-3333-4333-8333-333333333333';
29
+ const WORKSPACE_ID = '44444444-4444-4444-8444-444444444444';
30
+ const PROJECT_ID = '55555555-5555-4555-8555-555555555555';
31
+ const SWITCH_ATTEMPT_PATTERN = /Switch attempt/;
32
+ const ATTEMPT_3_PATTERN = /Attempt 3/;
33
+ const STORYBOOK_NOW = '2026-06-26T12:00:00.000Z';
34
+ const RUN_STARTED_AT = '2026-06-26T11:57:46.000Z';
35
+ const RUN_ATTEMPTS_RESPONSE = runAttemptsResponseDto({
36
+ attempts: [
37
+ workflowRunAttemptDto({
38
+ id: ROOT_RUN_ID,
39
+ attempt: 1,
40
+ status: 'succeeded',
41
+ created_at: '2026-06-21T12:00:00.000Z',
42
+ }),
43
+ workflowRunAttemptDto({
44
+ id: CURRENT_RUN_ID,
45
+ attempt: 2,
46
+ status: 'failed',
47
+ created_at: '2026-06-21T12:08:00.000Z',
48
+ rerun_mode: 'all',
49
+ }),
50
+ workflowRunAttemptDto({
51
+ id: NEXT_RUN_ID,
52
+ attempt: 3,
53
+ status: 'running',
54
+ created_at: '2026-06-21T12:14:00.000Z',
55
+ rerun_mode: 'failed',
56
+ }),
57
+ ],
58
+ });
59
+
60
+ const withFrame: Decorator = (Story) => (
61
+ <div className="min-h-screen bg-background-neutral-base">
62
+ <div className="mx-auto flex min-h-screen w-full max-w-[1120px] flex-col overflow-hidden border-x border-border-neutral-base bg-background-subtle-base">
63
+ <Story />
64
+ <div className="min-h-0 flex-1 bg-background-neutral-base p-16" />
65
+ </div>
66
+ </div>
67
+ );
68
+
69
+ const withAttemptApi: Decorator = (Story) => {
70
+ const queryClient = new QueryClient({defaultOptions: {queries: {retry: false}}});
71
+ const rootRoute = createRootRoute({component: Outlet});
72
+ const runRoute = createRoute({
73
+ getParentRoute: () => rootRoute,
74
+ path: '/workspaces/$wid/projects/$pid/runs/$workflowRunId',
75
+ component: () => <Story />,
76
+ });
77
+ const router = createRouter({
78
+ history: createMemoryHistory({
79
+ initialEntries: [`/workspaces/${WORKSPACE_ID}/projects/${PROJECT_ID}/runs/${CURRENT_RUN_ID}`],
80
+ }),
81
+ routeTree: rootRoute.addChildren([runRoute]),
82
+ });
83
+
84
+ return (
85
+ <AttemptApiProvider>
86
+ <QueryClientProvider client={queryClient}>
87
+ <RouterProvider router={router} />
88
+ </QueryClientProvider>
89
+ </AttemptApiProvider>
90
+ );
91
+ };
92
+
93
+ function AttemptApiProvider({children}: {children: ReactNode}) {
94
+ const [configured, setConfigured] = useState(false);
95
+
96
+ useEffect(() => {
97
+ configureApiClient({
98
+ baseUrl: 'https://api.example.test',
99
+ fetchImpl: async () =>
100
+ new Response(JSON.stringify(RUN_ATTEMPTS_RESPONSE), {
101
+ headers: {'content-type': 'application/json'},
102
+ }),
103
+ });
104
+ setConfigured(true);
105
+
106
+ return () => {
107
+ configureApiClient({baseUrl: '', fetchImpl: undefined});
108
+ };
109
+ }, []);
110
+
111
+ if (!configured) return null;
112
+ return children;
113
+ }
114
+
115
+ const meta = {
116
+ title: 'Workflows/RunSummary',
117
+ component: WorkflowRunSummary,
118
+ parameters: {
119
+ layout: 'fullscreen',
120
+ argos: {
121
+ modes: {
122
+ light: {theme: 'light'},
123
+ dark: {theme: 'dark'},
124
+ },
125
+ },
126
+ },
127
+ decorators: [withFrame],
128
+ args: {run: workflowRunDetail({status: 'succeeded'})},
129
+ } satisfies Meta<typeof WorkflowRunSummary>;
130
+
131
+ export default meta;
132
+ type Story = StoryObj<typeof meta>;
133
+ type WorkflowRunSummaryStoryContext = Parameters<NonNullable<Story['play']>>[0];
134
+
135
+ async function captureOpenAttemptsMenu(ctx: WorkflowRunSummaryStoryContext) {
136
+ const canvas = within(ctx.canvasElement);
137
+
138
+ await userEvent.click(await canvas.findByRole('button', {name: SWITCH_ATTEMPT_PATTERN}));
139
+ await screen.findByRole('menu');
140
+ await screen.findByRole('menuitem', {name: ATTEMPT_3_PATTERN});
141
+ await argosScreenshot(ctx, 'Workflow Run Summary Attempts Open');
142
+ }
143
+
144
+ const noop = () => undefined;
145
+ const noopRerun = (_mode: RerunMode) => undefined;
146
+
147
+ const ATTEMPT_SUMMARY_ARGS = {
148
+ run: workflowRunDetail({
149
+ id: CURRENT_RUN_ID,
150
+ current_attempt: 2,
151
+ run_attempt: workflowRunAttemptDto({
152
+ id: CURRENT_RUN_ID,
153
+ workflow_run_id: CURRENT_RUN_ID,
154
+ attempt: 2,
155
+ }),
156
+ status: 'failed',
157
+ }),
158
+ workspaceId: WORKSPACE_ID,
159
+ projectId: PROJECT_ID,
160
+ latestAttempt: 3,
161
+ };
162
+
163
+ export const Playground: Story = {};
164
+
165
+ export const WithSourceButton: Story = {
166
+ args: {
167
+ run: workflowRunDetail({
168
+ status: 'succeeded',
169
+ source_snapshot: {format: 'yaml', content: 'jobs:\n build:\n steps: []'},
170
+ }),
171
+ sourceAvailable: true,
172
+ sourceOpen: false,
173
+ sourcePanelId: 'workflow-source-panel',
174
+ },
175
+ };
176
+
177
+ export const SourceOpen: Story = {
178
+ args: {
179
+ run: workflowRunDetail({
180
+ status: 'succeeded',
181
+ source_snapshot: {format: 'yaml', content: 'jobs:\n build:\n steps: []'},
182
+ }),
183
+ sourceAvailable: true,
184
+ sourceOpen: true,
185
+ sourcePanelId: 'workflow-source-panel',
186
+ },
187
+ };
188
+
189
+ export const WithAttempts: Story = {
190
+ decorators: [withAttemptApi],
191
+ args: ATTEMPT_SUMMARY_ARGS,
192
+ };
193
+
194
+ export const WithAttemptsOpen: Story = {
195
+ decorators: [withAttemptApi],
196
+ play: captureOpenAttemptsMenu,
197
+ args: ATTEMPT_SUMMARY_ARGS,
198
+ };
199
+
200
+ export const Durations: Story = {
201
+ render: () => (
202
+ <div className="flex flex-col">
203
+ <WorkflowRunSummary
204
+ run={workflowRunDetail({
205
+ status: 'succeeded',
206
+ name: 'release-finished',
207
+ run_attempt: workflowRunAttemptDto({
208
+ status: 'succeeded',
209
+ created_at: RUN_STARTED_AT,
210
+ started_at: RUN_STARTED_AT,
211
+ finished_at: STORYBOOK_NOW,
212
+ }),
213
+ })}
214
+ />
215
+ <WorkflowRunSummary
216
+ run={workflowRunDetail({
217
+ status: 'running',
218
+ name: 'release-running',
219
+ run_attempt: workflowRunAttemptDto({
220
+ status: 'running',
221
+ created_at: RUN_STARTED_AT,
222
+ started_at: RUN_STARTED_AT,
223
+ finished_at: null,
224
+ }),
225
+ })}
226
+ />
227
+ </div>
228
+ ),
229
+ };
230
+
231
+ export const Cancellable: Story = {
232
+ args: {
233
+ run: workflowRunDetail({status: 'running'}),
234
+ onCancel: noop,
235
+ },
236
+ };
237
+
238
+ export const Cancelling: Story = {
239
+ args: {
240
+ run: workflowRunDetail({status: 'running'}),
241
+ onCancel: noop,
242
+ cancelling: true,
243
+ },
244
+ };
245
+
246
+ const ALL_STATUSES: WorkflowRunStatus[] = [
247
+ 'pending',
248
+ 'running',
249
+ 'succeeded',
250
+ 'failed',
251
+ 'cancelled',
252
+ ];
253
+
254
+ export const Statuses: Story = {
255
+ render: () => (
256
+ <div className="flex flex-col">
257
+ {ALL_STATUSES.map((status, index) => (
258
+ <WorkflowRunSummary
259
+ key={status}
260
+ run={workflowRunDetail({
261
+ id: `11111111-1111-4111-8111-${String(index + 2).padStart(12, '0')}`,
262
+ status,
263
+ name: `${status}-pipeline`,
264
+ })}
265
+ />
266
+ ))}
267
+ </div>
268
+ ),
269
+ };
270
+
271
+ const ACTION_VARIANTS = [
272
+ {
273
+ label: 'Running',
274
+ run: workflowRunDetail({status: 'running', name: 'running-pipeline'}),
275
+ props: {onCancel: noop},
276
+ },
277
+ {
278
+ label: 'Cancelling',
279
+ run: workflowRunDetail({status: 'running', name: 'cancelling-pipeline'}),
280
+ props: {cancelling: true, onCancel: noop},
281
+ },
282
+ {
283
+ label: 'Succeeded',
284
+ run: workflowRunDetail({status: 'succeeded', name: 'succeeded-pipeline'}),
285
+ props: {onRerun: noopRerun},
286
+ },
287
+ {
288
+ label: 'Re-running',
289
+ run: workflowRunDetail({status: 'succeeded', name: 'rerun-pending-pipeline'}),
290
+ props: {rerunPending: true, onRerun: noopRerun},
291
+ },
292
+ {
293
+ label: 'Failed',
294
+ run: workflowRunDetail({
295
+ status: 'failed',
296
+ name: 'failed-pipeline',
297
+ jobs: [workflowJobDto({status: 'failed'})],
298
+ }),
299
+ props: {onRerun: noopRerun},
300
+ },
301
+ {
302
+ label: 'Cancelled',
303
+ run: workflowRunDetail({
304
+ status: 'cancelled',
305
+ name: 'cancelled-pipeline',
306
+ jobs: [workflowJobDto({status: 'cancelled'})],
307
+ }),
308
+ props: {onRerun: noopRerun},
309
+ },
310
+ {
311
+ label: 'Failed without failed jobs',
312
+ run: workflowRunDetail({
313
+ status: 'failed',
314
+ name: 'failed-without-failed-jobs-pipeline',
315
+ jobs: [workflowJobDto({status: 'succeeded'})],
316
+ }),
317
+ props: {onRerun: noopRerun},
318
+ },
319
+ ] satisfies Array<{
320
+ label: string;
321
+ run: ReturnType<typeof workflowRunDetail>;
322
+ props: Pick<
323
+ Parameters<typeof WorkflowRunSummary>[0],
324
+ 'cancelling' | 'onCancel' | 'rerunPending' | 'onRerun'
325
+ >;
326
+ }>;
327
+
328
+ export const ActionVariantsWithSource: Story = {
329
+ render: () => (
330
+ <div className="flex flex-col">
331
+ {ACTION_VARIANTS.map(({label, run, props}, index) => (
332
+ <WorkflowRunSummary
333
+ key={label}
334
+ run={{
335
+ ...run,
336
+ id: `22222222-2222-4222-8222-${String(index + 2).padStart(12, '0')}`,
337
+ }}
338
+ sourceAvailable
339
+ sourceOpen={label === 'Running'}
340
+ sourcePanelId={`workflow-source-panel-${index}`}
341
+ {...props}
342
+ />
343
+ ))}
344
+ </div>
345
+ ),
346
+ };
347
+
348
+ export const ActionVariantsWithAttempts: Story = {
349
+ decorators: [withAttemptApi],
350
+ render: () => (
351
+ <div className="flex flex-col">
352
+ {ACTION_VARIANTS.map(({label, run, props}, index) => (
353
+ <WorkflowRunSummary
354
+ key={label}
355
+ workspaceId={WORKSPACE_ID}
356
+ projectId={PROJECT_ID}
357
+ run={{
358
+ ...run,
359
+ id: `22222222-2222-4222-8222-${String(index + 2).padStart(12, '0')}`,
360
+ currentAttempt: 2,
361
+ runAttempt: new WorkflowRunAttempt({
362
+ id: `22222222-2222-4222-8222-${String(index + 2).padStart(12, '0')}`,
363
+ workflowRunId: `22222222-2222-4222-8222-${String(index + 2).padStart(12, '0')}`,
364
+ attempt: 2,
365
+ status: run.runAttempt.status,
366
+ createdAt: run.createdAt,
367
+ startedAt: null,
368
+ finishedAt: null,
369
+ rerunMode: null,
370
+ }),
371
+ }}
372
+ latestAttempt={3}
373
+ {...props}
374
+ />
375
+ ))}
376
+ </div>
377
+ ),
378
+ };
379
+
380
+ export const MissingTriggerMetadata: Story = {
381
+ args: {
382
+ run: workflowRunDetail({
383
+ status: 'succeeded',
384
+ trigger_source: '',
385
+ trigger_event: '',
386
+ }),
387
+ },
388
+ };
389
+
390
+ export const EmptyTriggerPayload: Story = {
391
+ args: {
392
+ run: workflowRunDetail({status: 'succeeded', trigger_payload: {}}),
393
+ },
394
+ };
395
+
396
+ export const LongRunName: Story = {
397
+ args: {
398
+ run: workflowRunDetail({
399
+ status: 'succeeded',
400
+ name: 'release-production-multi-region-with-canary-and-smoke-tests-and-progressive-delivery-observability-and-post-deploy-validation-for-enterprise-workspaces',
401
+ }),
402
+ },
403
+ };
404
+
405
+ export const LongTriggerMetadata: Story = {
406
+ args: {
407
+ run: workflowRunDetail({
408
+ status: 'succeeded',
409
+ trigger_provider: 'github',
410
+ trigger_source: 'github-enterprise-cloud-production-organization',
411
+ trigger_event: 'workflow_dispatch_with_release_candidate_payload',
412
+ }),
413
+ },
414
+ };