@shipfox/client-projects 21.0.0 → 22.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.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +31 -0
- package/dist/components/source-strip.d.ts.map +1 -1
- package/dist/components/source-strip.js +49 -45
- package/dist/components/source-strip.js.map +1 -1
- package/dist/pages/create-project-page.d.ts.map +1 -1
- package/dist/pages/create-project-page.js +161 -175
- package/dist/pages/create-project-page.js.map +1 -1
- package/dist/pages/project-settings-page.d.ts.map +1 -1
- package/dist/pages/project-settings-page.js +82 -84
- package/dist/pages/project-settings-page.js.map +1 -1
- package/dist/pages/projects-hub-page.d.ts.map +1 -1
- package/dist/pages/projects-hub-page.js +160 -159
- package/dist/pages/projects-hub-page.js.map +1 -1
- package/dist/pages/projects-hub-page.stories.d.ts +22 -0
- package/dist/pages/projects-hub-page.stories.d.ts.map +1 -0
- package/dist/pages/projects-hub-page.stories.js +214 -0
- package/dist/pages/projects-hub-page.stories.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/src/components/source-strip.tsx +29 -26
- package/src/pages/create-project-page.test.tsx +85 -1
- package/src/pages/create-project-page.tsx +165 -153
- package/src/pages/home-router.test.tsx +2 -1
- package/src/pages/project-settings-page.test.tsx +10 -1
- package/src/pages/project-settings-page.tsx +88 -76
- package/src/pages/projects-hub-page.stories.tsx +203 -0
- package/src/pages/projects-hub-page.test.tsx +90 -10
- package/src/pages/projects-hub-page.tsx +136 -125
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { configureApiClient } from '@shipfox/client-api';
|
|
3
|
+
import { authStateAtom } from '@shipfox/client-auth';
|
|
4
|
+
import { Toaster } from '@shipfox/react-ui/toast';
|
|
5
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
6
|
+
import { createMemoryHistory, createRootRoute, createRoute, createRouter, Outlet, RouterProvider } from '@tanstack/react-router';
|
|
7
|
+
import { createStore, Provider as JotaiProvider } from 'jotai';
|
|
8
|
+
import { useMemo } from 'react';
|
|
9
|
+
import { ProjectsHubPage } from './projects-hub-page.js';
|
|
10
|
+
const WORKSPACE_ID = '11111111-1111-4111-8111-111111111111';
|
|
11
|
+
const CONNECTION_ID = '33333333-3333-4333-8333-333333333333';
|
|
12
|
+
const authState = {
|
|
13
|
+
status: 'authenticated',
|
|
14
|
+
token: 'token',
|
|
15
|
+
user: {
|
|
16
|
+
id: '22222222-2222-4222-8222-222222222222',
|
|
17
|
+
email: 'platform@example.com',
|
|
18
|
+
name: 'Platform Engineer',
|
|
19
|
+
emailVerifiedAt: '2026-01-01T00:00:00.000Z'
|
|
20
|
+
},
|
|
21
|
+
workspaces: [
|
|
22
|
+
{
|
|
23
|
+
id: WORKSPACE_ID,
|
|
24
|
+
name: 'Acme',
|
|
25
|
+
slug: 'acme',
|
|
26
|
+
membershipId: 'membership-1'
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
};
|
|
30
|
+
function ProjectsHubPageStory({ scenario }) {
|
|
31
|
+
configureApiClient({
|
|
32
|
+
baseUrl: 'https://api.example.test',
|
|
33
|
+
fetchImpl: fetchForScenario(scenario)
|
|
34
|
+
});
|
|
35
|
+
const queryClient = useMemo(()=>new QueryClient({
|
|
36
|
+
defaultOptions: {
|
|
37
|
+
queries: {
|
|
38
|
+
retry: false
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}), []);
|
|
42
|
+
const store = useMemo(()=>{
|
|
43
|
+
const nextStore = createStore();
|
|
44
|
+
nextStore.set(authStateAtom, authState);
|
|
45
|
+
return nextStore;
|
|
46
|
+
}, []);
|
|
47
|
+
const router = useMemo(()=>createStoryRouter(), []);
|
|
48
|
+
return /*#__PURE__*/ _jsx(QueryClientProvider, {
|
|
49
|
+
client: queryClient,
|
|
50
|
+
children: /*#__PURE__*/ _jsxs(JotaiProvider, {
|
|
51
|
+
store: store,
|
|
52
|
+
children: [
|
|
53
|
+
/*#__PURE__*/ _jsx("div", {
|
|
54
|
+
className: "min-h-screen bg-background-subtle-base px-24 py-32",
|
|
55
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
56
|
+
className: "mx-auto w-full max-w-[1120px]",
|
|
57
|
+
children: /*#__PURE__*/ _jsx(RouterProvider, {
|
|
58
|
+
router: router
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
}),
|
|
62
|
+
/*#__PURE__*/ _jsx(Toaster, {})
|
|
63
|
+
]
|
|
64
|
+
})
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
const meta = {
|
|
68
|
+
title: 'Projects/ProjectsHubPage',
|
|
69
|
+
component: ProjectsHubPageStory,
|
|
70
|
+
parameters: {
|
|
71
|
+
layout: 'fullscreen'
|
|
72
|
+
},
|
|
73
|
+
args: {
|
|
74
|
+
scenario: 'list'
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
export default meta;
|
|
78
|
+
export const Playground = {};
|
|
79
|
+
export const Empty = {
|
|
80
|
+
args: {
|
|
81
|
+
scenario: 'empty'
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
export const Loading = {
|
|
85
|
+
args: {
|
|
86
|
+
scenario: 'loading'
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
export const ErrorState = {
|
|
90
|
+
args: {
|
|
91
|
+
scenario: 'error'
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
function createStoryRouter() {
|
|
95
|
+
const rootRoute = createRootRoute({
|
|
96
|
+
component: Outlet
|
|
97
|
+
});
|
|
98
|
+
const workspaceRoute = createRoute({
|
|
99
|
+
getParentRoute: ()=>rootRoute,
|
|
100
|
+
path: '/w/$workspaceSlug',
|
|
101
|
+
component: ProjectsHubPage
|
|
102
|
+
});
|
|
103
|
+
return createRouter({
|
|
104
|
+
history: createMemoryHistory({
|
|
105
|
+
initialEntries: [
|
|
106
|
+
'/w/acme'
|
|
107
|
+
]
|
|
108
|
+
}),
|
|
109
|
+
routeTree: rootRoute.addChildren([
|
|
110
|
+
workspaceRoute
|
|
111
|
+
])
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
function fetchForScenario(scenario) {
|
|
115
|
+
return (input)=>{
|
|
116
|
+
const url = requestUrl(input);
|
|
117
|
+
if (url.pathname.endsWith('/agent/model-providers')) {
|
|
118
|
+
return Promise.resolve(jsonResponse({
|
|
119
|
+
configs: [
|
|
120
|
+
{
|
|
121
|
+
kind: 'builtin',
|
|
122
|
+
provider_id: 'anthropic',
|
|
123
|
+
default_model: null,
|
|
124
|
+
created_at: '2026-01-01T00:00:00.000Z',
|
|
125
|
+
updated_at: '2026-01-01T00:00:00.000Z'
|
|
126
|
+
}
|
|
127
|
+
],
|
|
128
|
+
default_provider_id: 'anthropic',
|
|
129
|
+
default_harness_id: null
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
if (url.pathname === '/integration-connections') {
|
|
133
|
+
return Promise.resolve(jsonResponse({
|
|
134
|
+
connections: [
|
|
135
|
+
{
|
|
136
|
+
id: CONNECTION_ID,
|
|
137
|
+
workspace_id: WORKSPACE_ID,
|
|
138
|
+
provider: 'github',
|
|
139
|
+
external_account_id: 'octo',
|
|
140
|
+
slug: 'github_octo',
|
|
141
|
+
display_name: 'Acme GitHub',
|
|
142
|
+
lifecycle_status: 'active',
|
|
143
|
+
capabilities: [
|
|
144
|
+
'source_control'
|
|
145
|
+
],
|
|
146
|
+
created_at: '2026-01-01T00:00:00.000Z',
|
|
147
|
+
updated_at: '2026-01-01T00:00:00.000Z'
|
|
148
|
+
}
|
|
149
|
+
]
|
|
150
|
+
}));
|
|
151
|
+
}
|
|
152
|
+
if (url.pathname === '/projects') {
|
|
153
|
+
if (scenario === 'loading') {
|
|
154
|
+
return new Promise(()=>{
|
|
155
|
+
// Keep the request pending to show the initial skeleton.
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
if (scenario === 'error') {
|
|
159
|
+
return Promise.resolve(jsonResponse({
|
|
160
|
+
code: 'server-error'
|
|
161
|
+
}, {
|
|
162
|
+
status: 500
|
|
163
|
+
}));
|
|
164
|
+
}
|
|
165
|
+
if (scenario === 'empty') {
|
|
166
|
+
return Promise.resolve(jsonResponse({
|
|
167
|
+
projects: [],
|
|
168
|
+
next_cursor: null
|
|
169
|
+
}));
|
|
170
|
+
}
|
|
171
|
+
return Promise.resolve(jsonResponse({
|
|
172
|
+
projects: [
|
|
173
|
+
projectForStory('Platform', '11111111-1111-4111-8111-111111111112'),
|
|
174
|
+
projectForStory('Agent', '11111111-1111-4111-8111-111111111113'),
|
|
175
|
+
projectForStory('Workflows', '11111111-1111-4111-8111-111111111114')
|
|
176
|
+
],
|
|
177
|
+
next_cursor: null
|
|
178
|
+
}));
|
|
179
|
+
}
|
|
180
|
+
return Promise.resolve(jsonResponse({}, {
|
|
181
|
+
status: 404
|
|
182
|
+
}));
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function projectForStory(name, id) {
|
|
186
|
+
return {
|
|
187
|
+
id,
|
|
188
|
+
workspace_id: WORKSPACE_ID,
|
|
189
|
+
name,
|
|
190
|
+
slug: name.toLowerCase(),
|
|
191
|
+
source: {
|
|
192
|
+
connection_id: CONNECTION_ID,
|
|
193
|
+
external_repository_id: `github:octo/${name.toLowerCase()}`
|
|
194
|
+
},
|
|
195
|
+
created_at: '2026-01-01T00:00:00.000Z',
|
|
196
|
+
updated_at: '2026-01-01T00:00:00.000Z'
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
function requestUrl(input) {
|
|
200
|
+
if (input instanceof Request) return new URL(input.url);
|
|
201
|
+
if (input instanceof URL) return input;
|
|
202
|
+
return new URL(input, 'https://api.example.test');
|
|
203
|
+
}
|
|
204
|
+
function jsonResponse(body, init = {}) {
|
|
205
|
+
return new Response(JSON.stringify(body), {
|
|
206
|
+
status: 200,
|
|
207
|
+
headers: {
|
|
208
|
+
'content-type': 'application/json'
|
|
209
|
+
},
|
|
210
|
+
...init
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
//# sourceMappingURL=projects-hub-page.stories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/pages/projects-hub-page.stories.tsx"],"sourcesContent":["import {configureApiClient} from '@shipfox/client-api';\nimport {type AuthState, authStateAtom} from '@shipfox/client-auth';\nimport {Toaster} from '@shipfox/react-ui/toast';\nimport type {Meta, StoryObj} from '@storybook/react';\nimport {QueryClient, QueryClientProvider} from '@tanstack/react-query';\nimport {\n createMemoryHistory,\n createRootRoute,\n createRoute,\n createRouter,\n Outlet,\n RouterProvider,\n} from '@tanstack/react-router';\nimport {createStore, Provider as JotaiProvider} from 'jotai';\nimport {useMemo} from 'react';\nimport {ProjectsHubPage} from './projects-hub-page.js';\n\nconst WORKSPACE_ID = '11111111-1111-4111-8111-111111111111';\nconst CONNECTION_ID = '33333333-3333-4333-8333-333333333333';\n\ntype Scenario = 'list' | 'empty' | 'loading' | 'error';\n\nconst authState: AuthState = {\n status: 'authenticated',\n token: 'token',\n user: {\n id: '22222222-2222-4222-8222-222222222222',\n email: 'platform@example.com',\n name: 'Platform Engineer',\n emailVerifiedAt: '2026-01-01T00:00:00.000Z',\n },\n workspaces: [{id: WORKSPACE_ID, name: 'Acme', slug: 'acme', membershipId: 'membership-1'}],\n};\n\nfunction ProjectsHubPageStory({scenario}: {scenario: Scenario}) {\n configureApiClient({\n baseUrl: 'https://api.example.test',\n fetchImpl: fetchForScenario(scenario),\n });\n\n const queryClient = useMemo(\n () => new QueryClient({defaultOptions: {queries: {retry: false}}}),\n [],\n );\n const store = useMemo(() => {\n const nextStore = createStore();\n nextStore.set(authStateAtom, authState);\n return nextStore;\n }, []);\n const router = useMemo(() => createStoryRouter(), []);\n\n return (\n <QueryClientProvider client={queryClient}>\n <JotaiProvider store={store}>\n <div className=\"min-h-screen bg-background-subtle-base px-24 py-32\">\n <div className=\"mx-auto w-full max-w-[1120px]\">\n <RouterProvider router={router} />\n </div>\n </div>\n <Toaster />\n </JotaiProvider>\n </QueryClientProvider>\n );\n}\n\nconst meta = {\n title: 'Projects/ProjectsHubPage',\n component: ProjectsHubPageStory,\n parameters: {layout: 'fullscreen'},\n args: {scenario: 'list'},\n} satisfies Meta<typeof ProjectsHubPageStory>;\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const Playground: Story = {};\n\nexport const Empty: Story = {\n args: {scenario: 'empty'},\n};\n\nexport const Loading: Story = {\n args: {scenario: 'loading'},\n};\n\nexport const ErrorState: Story = {\n args: {scenario: 'error'},\n};\n\nfunction createStoryRouter() {\n const rootRoute = createRootRoute({component: Outlet});\n const workspaceRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: '/w/$workspaceSlug',\n component: ProjectsHubPage,\n });\n\n return createRouter({\n history: createMemoryHistory({initialEntries: ['/w/acme']}),\n routeTree: rootRoute.addChildren([workspaceRoute]),\n });\n}\n\nfunction fetchForScenario(scenario: Scenario): typeof fetch {\n return (input) => {\n const url = requestUrl(input);\n\n if (url.pathname.endsWith('/agent/model-providers')) {\n return Promise.resolve(\n jsonResponse({\n configs: [\n {\n kind: 'builtin',\n provider_id: 'anthropic',\n default_model: null,\n created_at: '2026-01-01T00:00:00.000Z',\n updated_at: '2026-01-01T00:00:00.000Z',\n },\n ],\n default_provider_id: 'anthropic',\n default_harness_id: null,\n }),\n );\n }\n\n if (url.pathname === '/integration-connections') {\n return Promise.resolve(\n jsonResponse({\n connections: [\n {\n id: CONNECTION_ID,\n workspace_id: WORKSPACE_ID,\n provider: 'github',\n external_account_id: 'octo',\n slug: 'github_octo',\n display_name: 'Acme GitHub',\n lifecycle_status: 'active',\n capabilities: ['source_control'],\n created_at: '2026-01-01T00:00:00.000Z',\n updated_at: '2026-01-01T00:00:00.000Z',\n },\n ],\n }),\n );\n }\n\n if (url.pathname === '/projects') {\n if (scenario === 'loading') {\n return new Promise<Response>(() => {\n // Keep the request pending to show the initial skeleton.\n });\n }\n if (scenario === 'error') {\n return Promise.resolve(jsonResponse({code: 'server-error'}, {status: 500}));\n }\n if (scenario === 'empty') {\n return Promise.resolve(jsonResponse({projects: [], next_cursor: null}));\n }\n\n return Promise.resolve(\n jsonResponse({\n projects: [\n projectForStory('Platform', '11111111-1111-4111-8111-111111111112'),\n projectForStory('Agent', '11111111-1111-4111-8111-111111111113'),\n projectForStory('Workflows', '11111111-1111-4111-8111-111111111114'),\n ],\n next_cursor: null,\n }),\n );\n }\n\n return Promise.resolve(jsonResponse({}, {status: 404}));\n };\n}\n\nfunction projectForStory(name: string, id: string) {\n return {\n id,\n workspace_id: WORKSPACE_ID,\n name,\n slug: name.toLowerCase(),\n source: {\n connection_id: CONNECTION_ID,\n external_repository_id: `github:octo/${name.toLowerCase()}`,\n },\n created_at: '2026-01-01T00:00:00.000Z',\n updated_at: '2026-01-01T00:00:00.000Z',\n };\n}\n\nfunction requestUrl(input: RequestInfo | URL): URL {\n if (input instanceof Request) return new URL(input.url);\n if (input instanceof URL) return input;\n return new URL(input, 'https://api.example.test');\n}\n\nfunction jsonResponse(body: unknown, init: ResponseInit = {}) {\n return new Response(JSON.stringify(body), {\n status: 200,\n headers: {'content-type': 'application/json'},\n ...init,\n });\n}\n"],"names":["configureApiClient","authStateAtom","Toaster","QueryClient","QueryClientProvider","createMemoryHistory","createRootRoute","createRoute","createRouter","Outlet","RouterProvider","createStore","Provider","JotaiProvider","useMemo","ProjectsHubPage","WORKSPACE_ID","CONNECTION_ID","authState","status","token","user","id","email","name","emailVerifiedAt","workspaces","slug","membershipId","ProjectsHubPageStory","scenario","baseUrl","fetchImpl","fetchForScenario","queryClient","defaultOptions","queries","retry","store","nextStore","set","router","createStoryRouter","client","div","className","meta","title","component","parameters","layout","args","Playground","Empty","Loading","ErrorState","rootRoute","workspaceRoute","getParentRoute","path","history","initialEntries","routeTree","addChildren","input","url","requestUrl","pathname","endsWith","Promise","resolve","jsonResponse","configs","kind","provider_id","default_model","created_at","updated_at","default_provider_id","default_harness_id","connections","workspace_id","provider","external_account_id","display_name","lifecycle_status","capabilities","code","projects","next_cursor","projectForStory","toLowerCase","source","connection_id","external_repository_id","Request","URL","body","init","Response","JSON","stringify","headers"],"mappings":"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"}
|