@shipfox/client-workflows 4.0.0 → 6.0.1

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 (125) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +68 -0
  3. package/dist/components/workflow-run-list/types.d.ts +12 -0
  4. package/dist/components/workflow-run-list/types.d.ts.map +1 -1
  5. package/dist/components/workflow-run-list/types.js.map +1 -1
  6. package/dist/components/workflow-run-list/workflow-run-list-view.d.ts +1 -1
  7. package/dist/components/workflow-run-list/workflow-run-list-view.d.ts.map +1 -1
  8. package/dist/components/workflow-run-list/workflow-run-list-view.js +32 -11
  9. package/dist/components/workflow-run-list/workflow-run-list-view.js.map +1 -1
  10. package/dist/components/workflow-run-list/workflow-run-list.d.ts +1 -1
  11. package/dist/components/workflow-run-list/workflow-run-list.d.ts.map +1 -1
  12. package/dist/components/workflow-run-list/workflow-run-list.js +7 -2
  13. package/dist/components/workflow-run-list/workflow-run-list.js.map +1 -1
  14. package/dist/components/workflow-run-summary/workflow-run-summary.d.ts +2 -3
  15. package/dist/components/workflow-run-summary/workflow-run-summary.d.ts.map +1 -1
  16. package/dist/components/workflow-run-summary/workflow-run-summary.js.map +1 -1
  17. package/dist/components/workflow-run-view/job-card.d.ts.map +1 -1
  18. package/dist/components/workflow-run-view/job-card.js +9 -8
  19. package/dist/components/workflow-run-view/job-card.js.map +1 -1
  20. package/dist/components/workflow-run-view/workflow-run-view.js.map +1 -1
  21. package/dist/core/entities/job-execution.d.ts +11 -6
  22. package/dist/core/entities/job-execution.d.ts.map +1 -1
  23. package/dist/core/entities/job-execution.js +0 -19
  24. package/dist/core/entities/job-execution.js.map +1 -1
  25. package/dist/core/entities/job.d.ts +32 -10
  26. package/dist/core/entities/job.d.ts.map +1 -1
  27. package/dist/core/entities/job.js +0 -22
  28. package/dist/core/entities/job.js.map +1 -1
  29. package/dist/core/entities/step-attempt.d.ts +28 -3
  30. package/dist/core/entities/step-attempt.d.ts.map +1 -1
  31. package/dist/core/entities/step-attempt.js +0 -17
  32. package/dist/core/entities/step-attempt.js.map +1 -1
  33. package/dist/core/entities/step.d.ts +6 -6
  34. package/dist/core/entities/step.d.ts.map +1 -1
  35. package/dist/core/entities/step.js +19 -49
  36. package/dist/core/entities/step.js.map +1 -1
  37. package/dist/core/entities/workflow-run-attempt.d.ts +0 -2
  38. package/dist/core/entities/workflow-run-attempt.d.ts.map +1 -1
  39. package/dist/core/entities/workflow-run-attempt.js +0 -12
  40. package/dist/core/entities/workflow-run-attempt.js.map +1 -1
  41. package/dist/core/entities/workflow-run.d.ts +6 -7
  42. package/dist/core/entities/workflow-run.d.ts.map +1 -1
  43. package/dist/core/entities/workflow-run.js +1 -67
  44. package/dist/core/entities/workflow-run.js.map +1 -1
  45. package/dist/core/workflow-run.d.ts +9 -9
  46. package/dist/core/workflow-run.d.ts.map +1 -1
  47. package/dist/core/workflow-run.js +6 -6
  48. package/dist/core/workflow-run.js.map +1 -1
  49. package/dist/feature.d.ts +23 -0
  50. package/dist/feature.d.ts.map +1 -1
  51. package/dist/feature.js +22 -9
  52. package/dist/feature.js.map +1 -1
  53. package/dist/hooks/api/workflow-run-mapper.d.ts +12 -0
  54. package/dist/hooks/api/workflow-run-mapper.d.ts.map +1 -0
  55. package/dist/hooks/api/workflow-run-mapper.js +207 -0
  56. package/dist/hooks/api/workflow-run-mapper.js.map +1 -0
  57. package/dist/hooks/api/workflow-runs.d.ts +25 -55
  58. package/dist/hooks/api/workflow-runs.d.ts.map +1 -1
  59. package/dist/hooks/api/workflow-runs.js +95 -51
  60. package/dist/hooks/api/workflow-runs.js.map +1 -1
  61. package/dist/index.d.ts +3 -2
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +2 -1
  64. package/dist/index.js.map +1 -1
  65. package/dist/pages/project-workflows-page.d.ts +4 -0
  66. package/dist/pages/project-workflows-page.d.ts.map +1 -0
  67. package/dist/pages/project-workflows-page.js +479 -0
  68. package/dist/pages/project-workflows-page.js.map +1 -0
  69. package/dist/pages/workflow-run-page.d.ts +3 -1
  70. package/dist/pages/workflow-run-page.d.ts.map +1 -1
  71. package/dist/pages/workflow-run-page.js +21 -14
  72. package/dist/pages/workflow-run-page.js.map +1 -1
  73. package/dist/routes/inputs.d.ts +22 -0
  74. package/dist/routes/inputs.d.ts.map +1 -0
  75. package/dist/routes/inputs.js +76 -0
  76. package/dist/routes/inputs.js.map +1 -0
  77. package/dist/routes/run-detail.d.ts +2 -0
  78. package/dist/routes/run-detail.d.ts.map +1 -1
  79. package/dist/routes/run-detail.js +6 -6
  80. package/dist/routes/run-detail.js.map +1 -1
  81. package/dist/routes/runs.d.ts +2 -0
  82. package/dist/routes/runs.d.ts.map +1 -1
  83. package/dist/routes/runs.js +6 -6
  84. package/dist/routes/runs.js.map +1 -1
  85. package/dist/routes/workflows.d.ts +5 -0
  86. package/dist/routes/workflows.d.ts.map +1 -0
  87. package/dist/routes/workflows.js +14 -0
  88. package/dist/routes/workflows.js.map +1 -0
  89. package/dist/tsconfig.test.tsbuildinfo +1 -1
  90. package/package.json +13 -12
  91. package/src/components/workflow-run-list/types.ts +6 -0
  92. package/src/components/workflow-run-list/workflow-run-list-view.tsx +27 -11
  93. package/src/components/workflow-run-list/workflow-run-list.tsx +6 -0
  94. package/src/components/workflow-run-summary/workflow-run-attempt-switcher.test.tsx +5 -6
  95. package/src/components/workflow-run-summary/workflow-run-summary.tsx +3 -3
  96. package/src/components/workflow-run-view/job-card.tsx +20 -11
  97. package/src/components/workflow-run-view/workflow-run-view.test.tsx +3 -3
  98. package/src/components/workflow-run-view/workflow-run-view.tsx +2 -2
  99. package/src/core/entities/job-execution.ts +12 -28
  100. package/src/core/entities/job.ts +44 -45
  101. package/src/core/entities/step-attempt.ts +9 -20
  102. package/src/core/entities/step.ts +38 -66
  103. package/src/core/entities/workflow-run-attempt.ts +0 -14
  104. package/src/core/entities/workflow-run.ts +8 -86
  105. package/src/core/workflow-run.test.ts +13 -11
  106. package/src/core/workflow-run.ts +8 -13
  107. package/src/feature.ts +24 -10
  108. package/src/hooks/api/workflow-run-mapper.ts +246 -0
  109. package/src/hooks/api/workflow-runs.test.tsx +57 -59
  110. package/src/hooks/api/workflow-runs.ts +187 -88
  111. package/src/index.ts +5 -0
  112. package/src/page-harness-budget.test.ts +1 -0
  113. package/src/pages/project-workflows-page.test.tsx +247 -0
  114. package/src/pages/project-workflows-page.tsx +448 -0
  115. package/src/pages/workflow-run-page.test.tsx +4 -2
  116. package/src/pages/workflow-run-page.tsx +22 -17
  117. package/src/routes/inputs.test.ts +22 -0
  118. package/src/routes/inputs.ts +58 -0
  119. package/src/routes/run-detail.tsx +12 -8
  120. package/src/routes/runs.tsx +11 -4
  121. package/src/routes/workflows.tsx +10 -0
  122. package/test/fixtures/workflow-run.ts +9 -7
  123. package/test/pages.tsx +48 -6
  124. package/tsconfig.build.tsbuildinfo +1 -1
  125. package/vercel.json +5 -0
@@ -1,11 +1,18 @@
1
- import {defineRoute} from '@shipfox/client-shell/runtime';
2
- import {useParams} from '@tanstack/react-router';
1
+ import {defineRoute, useRouteParams, useRouteSearch} from '@shipfox/client-shell/runtime';
3
2
  import {WorkflowRunPage} from '#pages/workflow-run-page.js';
3
+ import {validateWorkflowRunsSearch, workflowRouteParams} from './inputs.js';
4
4
 
5
5
  export default defineRoute({
6
6
  staticData: {layout: 'full-bleed'},
7
+ validateSearch: validateWorkflowRunsSearch,
7
8
  component: () => {
8
- const {wid, pid} = useParams({strict: false}) as {wid: string; pid: string};
9
- return <WorkflowRunPage workspaceId={wid} projectId={pid} />;
9
+ const {wid, pid} = useRouteParams(workflowRouteParams);
10
+ return (
11
+ <WorkflowRunPage
12
+ workspaceId={wid}
13
+ projectId={pid}
14
+ search={useRouteSearch(validateWorkflowRunsSearch)}
15
+ />
16
+ );
10
17
  },
11
18
  });
@@ -0,0 +1,10 @@
1
+ import {defineRoute, useRouteParams} from '@shipfox/client-shell/runtime';
2
+ import {ProjectWorkflowsPage} from '#pages/project-workflows-page.js';
3
+ import {workflowRouteParams} from './inputs.js';
4
+
5
+ export default defineRoute({
6
+ component: () => {
7
+ const {pid} = useRouteParams(workflowRouteParams);
8
+ return <ProjectWorkflowsPage projectId={pid} />;
9
+ },
10
+ });
@@ -11,20 +11,22 @@ import type {
11
11
  WorkflowRunStatusDto,
12
12
  WorkflowRunStepDetailDto,
13
13
  } from '@shipfox/api-workflows-dto';
14
+ import type {
15
+ Job,
16
+ Step,
17
+ StepAttempt,
18
+ WorkflowRunDetail,
19
+ WorkflowRunListItem,
20
+ WorkflowRunListPage,
21
+ } from '#core/workflow-run.js';
14
22
  import {
15
- type Job,
16
- type Step,
17
- type StepAttempt,
18
23
  toJob,
19
24
  toStep,
20
25
  toStepAttempt,
21
26
  toWorkflowRunDetail,
22
27
  toWorkflowRunListItem,
23
28
  toWorkflowRunListPage,
24
- type WorkflowRunDetail,
25
- type WorkflowRunListItem,
26
- type WorkflowRunListPage,
27
- } from '#core/workflow-run.js';
29
+ } from '#hooks/api/workflow-run-mapper.js';
28
30
 
29
31
  const RUN_ID = '11111111-1111-4111-8111-111111111111';
30
32
  const RUN_ATTEMPT_ID = '11111111-1111-4111-8111-111111111112';
package/test/pages.tsx CHANGED
@@ -1,4 +1,6 @@
1
1
  import {configureApiClient} from '@shipfox/client-api';
2
+ import {type AuthState, authStateAtom} from '@shipfox/client-shell/runtime';
3
+ import {Toaster} from '@shipfox/react-ui/toast';
2
4
  import {QueryClient, QueryClientProvider} from '@tanstack/react-query';
3
5
  import {
4
6
  createMemoryHistory,
@@ -8,9 +10,12 @@ import {
8
10
  Outlet,
9
11
  RouterProvider,
10
12
  useParams,
13
+ useSearch,
11
14
  } from '@tanstack/react-router';
12
15
  import {type RenderResult, render} from '@testing-library/react';
16
+ import {createStore, Provider as JotaiProvider} from 'jotai';
13
17
  import type {ReactElement} from 'react';
18
+ import {validateWorkflowRunsSearch} from '#routes/inputs.js';
14
19
 
15
20
  // The workflow run page navigates with the router (run rows are links and the page redirects
16
21
  // to the first run), so the harness mounts the page under a memory router whose route tree
@@ -19,6 +24,15 @@ import type {ReactElement} from 'react';
19
24
  // the real route wiring so a redirect re-renders the page with the run it landed on.
20
25
  export const PROJECT_TEST_WID = '11111111-1111-4111-8111-111111111111';
21
26
 
27
+ // Pages that render components depending on `useActiveWorkspace()` (e.g. the project source
28
+ // strip) need an authenticated workspace matching `$wid` in the atom `client-shell/runtime`
29
+ // reads. A fixed membership id is fine here: nothing in these tests asserts on it.
30
+ const authState: AuthState = {
31
+ status: 'authenticated',
32
+ token: 'token',
33
+ workspaces: [{id: PROJECT_TEST_WID, name: 'Acme', membershipId: 'm-1'}],
34
+ };
35
+
22
36
  export function jsonResponse(body: unknown, init: ResponseInit = {}) {
23
37
  return new Response(JSON.stringify(body), {
24
38
  status: 200,
@@ -29,22 +43,37 @@ export function jsonResponse(body: unknown, init: ResponseInit = {}) {
29
43
 
30
44
  function createTestRouter(
31
45
  path: string,
32
- renderPage: (params: {workflowRunId?: string | undefined}) => ReactElement,
46
+ renderPage: (params: {
47
+ workflowRunId?: string | undefined;
48
+ search: ReturnType<typeof validateWorkflowRunsSearch>;
49
+ }) => ReactElement,
33
50
  ) {
34
51
  const rootRoute = createRootRoute({component: Outlet});
35
52
  const runsRoute = createRoute({
36
53
  getParentRoute: () => rootRoute,
37
54
  path: '/workspaces/$wid/projects/$pid/runs',
38
- component: () => renderPage({}),
55
+ component: function RunsRoute() {
56
+ return renderPage({
57
+ search: validateWorkflowRunsSearch(useSearch({strict: false}) as Record<string, unknown>),
58
+ });
59
+ },
39
60
  });
40
61
  const runDetailRoute = createRoute({
41
62
  getParentRoute: () => rootRoute,
42
63
  path: '/workspaces/$wid/projects/$pid/runs/$workflowRunId',
43
64
  component: function RunDetailRoute() {
44
65
  const {workflowRunId} = useParams({strict: false}) as {workflowRunId?: string};
45
- return renderPage({workflowRunId});
66
+ return renderPage({
67
+ workflowRunId,
68
+ search: validateWorkflowRunsSearch(useSearch({strict: false}) as Record<string, unknown>),
69
+ });
46
70
  },
47
71
  });
72
+ const workflowsRoute = createRoute({
73
+ getParentRoute: () => rootRoute,
74
+ path: '/workspaces/$wid/projects/$pid/workflows',
75
+ component: () => renderPage({search: {}}),
76
+ });
48
77
  const modelProviderSettingsRoute = createRoute({
49
78
  getParentRoute: () => rootRoute,
50
79
  path: '/workspaces/$wid/settings/agents',
@@ -53,25 +82,38 @@ function createTestRouter(
53
82
 
54
83
  return createRouter({
55
84
  history: createMemoryHistory({initialEntries: [path]}),
56
- routeTree: rootRoute.addChildren([runsRoute, runDetailRoute, modelProviderSettingsRoute]),
85
+ routeTree: rootRoute.addChildren([
86
+ runsRoute,
87
+ runDetailRoute,
88
+ workflowsRoute,
89
+ modelProviderSettingsRoute,
90
+ ]),
57
91
  });
58
92
  }
59
93
 
60
94
  export function renderProjectPage(
61
95
  path: string,
62
- renderPage: (params: {workflowRunId?: string | undefined}) => ReactElement,
96
+ renderPage: (params: {
97
+ workflowRunId?: string | undefined;
98
+ search: ReturnType<typeof validateWorkflowRunsSearch>;
99
+ }) => ReactElement,
63
100
  ): RenderResult & {
64
101
  queryClient: QueryClient;
65
102
  router: ReturnType<typeof createTestRouter>;
66
103
  } {
67
104
  const queryClient = new QueryClient({defaultOptions: {queries: {retry: false}}});
68
105
  const router = createTestRouter(path, renderPage);
106
+ const store = createStore();
107
+ store.set(authStateAtom, authState);
69
108
 
70
109
  configureApiClient({baseUrl: 'https://api.example.test'});
71
110
 
72
111
  const result = render(
73
112
  <QueryClientProvider client={queryClient}>
74
- <RouterProvider router={router} />
113
+ <JotaiProvider store={store}>
114
+ <RouterProvider router={router} />
115
+ <Toaster />
116
+ </JotaiProvider>
75
117
  </QueryClientProvider>,
76
118
  );
77
119