@shipfox/client-projects 3.0.1 → 5.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 (46) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +39 -0
  3. package/dist/components/model-provider-reminder-banner.d.ts.map +1 -1
  4. package/dist/components/model-provider-reminder-banner.js +11 -15
  5. package/dist/components/model-provider-reminder-banner.js.map +1 -1
  6. package/dist/feature.d.ts +0 -10
  7. package/dist/feature.d.ts.map +1 -1
  8. package/dist/feature.js +0 -12
  9. package/dist/feature.js.map +1 -1
  10. package/dist/hooks/api/projects.d.ts +5 -1
  11. package/dist/hooks/api/projects.d.ts.map +1 -1
  12. package/dist/hooks/api/projects.js +12 -1
  13. package/dist/hooks/api/projects.js.map +1 -1
  14. package/dist/index.d.ts +1 -3
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +1 -2
  17. package/dist/index.js.map +1 -1
  18. package/dist/pages/create-project-page.stories.d.ts.map +1 -1
  19. package/dist/pages/create-project-page.stories.js +1 -4
  20. package/dist/pages/create-project-page.stories.js.map +1 -1
  21. package/dist/tsconfig.test.tsbuildinfo +1 -1
  22. package/package.json +9 -43
  23. package/src/components/model-provider-reminder-banner.tsx +11 -18
  24. package/src/feature.ts +0 -12
  25. package/src/hooks/api/projects.ts +23 -1
  26. package/src/index.ts +1 -6
  27. package/src/pages/create-project-page.stories.tsx +1 -4
  28. package/test/pages.tsx +2 -17
  29. package/tsconfig.build.tsbuildinfo +1 -1
  30. package/dist/components/workspace-setup-guard.d.ts +0 -9
  31. package/dist/components/workspace-setup-guard.d.ts.map +0 -1
  32. package/dist/components/workspace-setup-guard.js +0 -160
  33. package/dist/components/workspace-setup-guard.js.map +0 -1
  34. package/dist/pages/project-workflows-page.d.ts +0 -4
  35. package/dist/pages/project-workflows-page.d.ts.map +0 -1
  36. package/dist/pages/project-workflows-page.js +0 -481
  37. package/dist/pages/project-workflows-page.js.map +0 -1
  38. package/dist/routes/workflows.d.ts +0 -5
  39. package/dist/routes/workflows.d.ts.map +0 -1
  40. package/dist/routes/workflows.js +0 -16
  41. package/dist/routes/workflows.js.map +0 -1
  42. package/src/components/workspace-setup-guard.test.tsx +0 -534
  43. package/src/components/workspace-setup-guard.tsx +0 -185
  44. package/src/pages/project-workflows-page.test.tsx +0 -258
  45. package/src/pages/project-workflows-page.tsx +0 -445
  46. package/src/routes/workflows.tsx +0 -10
@@ -1,2 +1,2 @@
1
1
  $ shipfox-swc
2
- Successfully compiled: 20 files with swc (446.36ms)
2
+ Successfully compiled: 17 files with swc (292.16ms)
package/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # @shipfox/client-projects
2
2
 
3
+ ## 5.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 8d8cdef: Extracts workspace onboarding into a dedicated coordinator and shares its feature query policies.
8
+
9
+ ### Patch Changes
10
+
11
+ - ffd727b: Converges auth session and invitation state onto shared camelCase domain types validated at the API boundary, replacing the raw snake_case DTOs previously returned by login, signup, password reset, email verification, workspace creation, and invitation preview. `AuthState.user`, `useRefreshAuth()`, and `usePreviewInvitation()` now resolve to `UserIdentity`/`AuthenticatedSession`/`InvitationPreview` shapes (for example `accessToken` instead of `token`, `workspaceName` instead of `workspace_name`). Also moves the shared `AuthShell` component and session mapping helpers into `@shipfox/client-shell`, breaking the former `client-auth` ↔ `client-invitations` circular dependency.
12
+ - f1d6465: Moves workspace-settings and project-workflow route ownership from centralized packages into each feature's own route module, so a feature package declares and ships its own settings pages.
13
+ - Updated dependencies [8d8cdef]
14
+ - Updated dependencies [ffd727b]
15
+ - Updated dependencies [f1d6465]
16
+ - Updated dependencies [7f227c6]
17
+ - @shipfox/client-agent@5.0.0
18
+ - @shipfox/client-integrations@5.0.0
19
+ - @shipfox/client-shell@5.0.0
20
+ - @shipfox/client-auth@5.0.0
21
+ - @shipfox/api-integration-core-dto@8.0.0
22
+ - @shipfox/api-projects-dto@8.0.0
23
+
24
+ ## 4.0.0
25
+
26
+ ### Patch Changes
27
+
28
+ - 2e5b718: Adds safe browser persistence and bounded callback deduplication across client flows.
29
+ - Updated dependencies [2e5b718]
30
+ - Updated dependencies [6b4a575]
31
+ - Updated dependencies [20e4feb]
32
+ - Updated dependencies [11b10f7]
33
+ - Updated dependencies [781a45b]
34
+ - @shipfox/client-ui@4.0.0
35
+ - @shipfox/client-agent@4.0.0
36
+ - @shipfox/client-integrations@4.0.0
37
+ - @shipfox/client-shell@4.0.0
38
+ - @shipfox/client-api@4.0.0
39
+ - @shipfox/client-auth@4.0.0
40
+ - @shipfox/client-workflows@4.0.0
41
+
3
42
  ## 3.0.1
4
43
 
5
44
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"model-provider-reminder-banner.d.ts","sourceRoot":"","sources":["../../src/components/model-provider-reminder-banner.tsx"],"names":[],"mappings":"AAeA,wBAAgB,2BAA2B,CAAC,EAAC,WAAW,EAAC,EAAE;IAAC,WAAW,EAAE,MAAM,CAAA;CAAC,sCAsC/E"}
1
+ {"version":3,"file":"model-provider-reminder-banner.d.ts","sourceRoot":"","sources":["../../src/components/model-provider-reminder-banner.tsx"],"names":[],"mappings":"AAcA,wBAAgB,2BAA2B,CAAC,EAAC,WAAW,EAAC,EAAE;IAAC,WAAW,EAAE,MAAM,CAAA;CAAC,sCAsC/E"}
@@ -1,10 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useModelProviderConfigsQuery } from '@shipfox/client-agent';
3
+ import { createTypedBrowserStorage, sessionStorageOrUndefined } from '@shipfox/client-ui';
3
4
  import { Alert, AlertActions, AlertClose, AlertContent, AlertDescription, AlertTitle } from '@shipfox/react-ui/alert';
4
5
  import { Button } from '@shipfox/react-ui/button';
5
6
  import { Link } from '@tanstack/react-router';
6
7
  import { useState } from 'react';
7
- const REMINDER_SESSION_KEY_PREFIX = 'shipfox.modelProviderReminder.dismissed.';
8
8
  export function ModelProviderReminderBanner({ workspaceId }) {
9
9
  const configsQuery = useModelProviderConfigsQuery(workspaceId);
10
10
  const [dismissed, setDismissed] = useState(()=>isReminderDismissed(workspaceId));
@@ -51,23 +51,19 @@ export function ModelProviderReminderBanner({ workspaceId }) {
51
51
  });
52
52
  }
53
53
  function isReminderDismissed(workspaceId) {
54
- if (typeof window === 'undefined') return false;
55
- try {
56
- return window.sessionStorage.getItem(sessionKey(workspaceId)) === 'true';
57
- } catch {
58
- return false;
59
- }
54
+ return reminderStorage(workspaceId).read() === true;
60
55
  }
61
56
  function dismissReminder(workspaceId) {
62
- if (typeof window === 'undefined') return;
63
- try {
64
- window.sessionStorage.setItem(sessionKey(workspaceId), 'true');
65
- } catch {
66
- // Session persistence is best-effort; showing the banner again is benign.
67
- }
57
+ reminderStorage(workspaceId).write(true);
68
58
  }
69
- function sessionKey(workspaceId) {
70
- return `${REMINDER_SESSION_KEY_PREFIX}${workspaceId}`;
59
+ function reminderStorage(workspaceId) {
60
+ return createTypedBrowserStorage(sessionStorageOrUndefined, {
61
+ key: `shipfox.modelProviderReminder.dismissed.${workspaceId}`,
62
+ lifetime: 'session',
63
+ principalScope: 'workspace',
64
+ serialize: (dismissed)=>JSON.stringify(dismissed),
65
+ parse: (raw)=>raw === 'true'
66
+ });
71
67
  }
72
68
 
73
69
  //# sourceMappingURL=model-provider-reminder-banner.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/model-provider-reminder-banner.tsx"],"sourcesContent":["import {useModelProviderConfigsQuery} from '@shipfox/client-agent';\nimport {\n Alert,\n AlertActions,\n AlertClose,\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 {useState} from 'react';\n\nconst REMINDER_SESSION_KEY_PREFIX = 'shipfox.modelProviderReminder.dismissed.';\n\nexport function ModelProviderReminderBanner({workspaceId}: {workspaceId: string}) {\n const configsQuery = useModelProviderConfigsQuery(workspaceId);\n const [dismissed, setDismissed] = useState(() => isReminderDismissed(workspaceId));\n const configs = configsQuery.data?.configs;\n const unconfigured =\n Array.isArray(configs) &&\n configs.length === 0 &&\n configsQuery.data?.default_provider_id === null;\n\n if (!unconfigured || dismissed) return null;\n\n return (\n <Alert\n variant=\"info\"\n animated={false}\n onOpenChange={(open) => {\n if (!open) {\n dismissReminder(workspaceId);\n setDismissed(true);\n }\n }}\n >\n <AlertContent className=\"pr-28\">\n <AlertTitle>Finish setting up a model provider</AlertTitle>\n <AlertDescription>\n Add workspace credentials, or keep using the instance default.\n </AlertDescription>\n <AlertActions>\n <Button asChild size=\"sm\" variant=\"secondary\">\n <Link to=\"/workspaces/$wid/settings/agents\" params={{wid: workspaceId}}>\n Agents\n </Link>\n </Button>\n </AlertActions>\n </AlertContent>\n <AlertClose />\n </Alert>\n );\n}\n\nfunction isReminderDismissed(workspaceId: string): boolean {\n if (typeof window === 'undefined') return false;\n\n try {\n return window.sessionStorage.getItem(sessionKey(workspaceId)) === 'true';\n } catch {\n return false;\n }\n}\n\nfunction dismissReminder(workspaceId: string): void {\n if (typeof window === 'undefined') return;\n\n try {\n window.sessionStorage.setItem(sessionKey(workspaceId), 'true');\n } catch {\n // Session persistence is best-effort; showing the banner again is benign.\n }\n}\n\nfunction sessionKey(workspaceId: string): string {\n return `${REMINDER_SESSION_KEY_PREFIX}${workspaceId}`;\n}\n"],"names":["useModelProviderConfigsQuery","Alert","AlertActions","AlertClose","AlertContent","AlertDescription","AlertTitle","Button","Link","useState","REMINDER_SESSION_KEY_PREFIX","ModelProviderReminderBanner","workspaceId","configsQuery","dismissed","setDismissed","isReminderDismissed","configs","data","unconfigured","Array","isArray","length","default_provider_id","variant","animated","onOpenChange","open","dismissReminder","className","asChild","size","to","params","wid","window","sessionStorage","getItem","sessionKey","setItem"],"mappings":";AAAA,SAAQA,4BAA4B,QAAO,wBAAwB;AACnE,SACEC,KAAK,EACLC,YAAY,EACZC,UAAU,EACVC,YAAY,EACZC,gBAAgB,EAChBC,UAAU,QACL,0BAA0B;AACjC,SAAQC,MAAM,QAAO,2BAA2B;AAChD,SAAQC,IAAI,QAAO,yBAAyB;AAC5C,SAAQC,QAAQ,QAAO,QAAQ;AAE/B,MAAMC,8BAA8B;AAEpC,OAAO,SAASC,4BAA4B,EAACC,WAAW,EAAwB;IAC9E,MAAMC,eAAeb,6BAA6BY;IAClD,MAAM,CAACE,WAAWC,aAAa,GAAGN,SAAS,IAAMO,oBAAoBJ;IACrE,MAAMK,UAAUJ,aAAaK,IAAI,EAAED;IACnC,MAAME,eACJC,MAAMC,OAAO,CAACJ,YACdA,QAAQK,MAAM,KAAK,KACnBT,aAAaK,IAAI,EAAEK,wBAAwB;IAE7C,IAAI,CAACJ,gBAAgBL,WAAW,OAAO;IAEvC,qBACE,MAACb;QACCuB,SAAQ;QACRC,UAAU;QACVC,cAAc,CAACC;YACb,IAAI,CAACA,MAAM;gBACTC,gBAAgBhB;gBAChBG,aAAa;YACf;QACF;;0BAEA,MAACX;gBAAayB,WAAU;;kCACtB,KAACvB;kCAAW;;kCACZ,KAACD;kCAAiB;;kCAGlB,KAACH;kCACC,cAAA,KAACK;4BAAOuB,OAAO;4BAACC,MAAK;4BAAKP,SAAQ;sCAChC,cAAA,KAAChB;gCAAKwB,IAAG;gCAAmCC,QAAQ;oCAACC,KAAKtB;gCAAW;0CAAG;;;;;;0BAM9E,KAACT;;;AAGP;AAEA,SAASa,oBAAoBJ,WAAmB;IAC9C,IAAI,OAAOuB,WAAW,aAAa,OAAO;IAE1C,IAAI;QACF,OAAOA,OAAOC,cAAc,CAACC,OAAO,CAACC,WAAW1B,kBAAkB;IACpE,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA,SAASgB,gBAAgBhB,WAAmB;IAC1C,IAAI,OAAOuB,WAAW,aAAa;IAEnC,IAAI;QACFA,OAAOC,cAAc,CAACG,OAAO,CAACD,WAAW1B,cAAc;IACzD,EAAE,OAAM;IACN,0EAA0E;IAC5E;AACF;AAEA,SAAS0B,WAAW1B,WAAmB;IACrC,OAAO,GAAGF,8BAA8BE,aAAa;AACvD"}
1
+ {"version":3,"sources":["../../src/components/model-provider-reminder-banner.tsx"],"sourcesContent":["import {useModelProviderConfigsQuery} from '@shipfox/client-agent';\nimport {createTypedBrowserStorage, sessionStorageOrUndefined} from '@shipfox/client-ui';\nimport {\n Alert,\n AlertActions,\n AlertClose,\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 {useState} from 'react';\n\nexport function ModelProviderReminderBanner({workspaceId}: {workspaceId: string}) {\n const configsQuery = useModelProviderConfigsQuery(workspaceId);\n const [dismissed, setDismissed] = useState(() => isReminderDismissed(workspaceId));\n const configs = configsQuery.data?.configs;\n const unconfigured =\n Array.isArray(configs) &&\n configs.length === 0 &&\n configsQuery.data?.default_provider_id === null;\n\n if (!unconfigured || dismissed) return null;\n\n return (\n <Alert\n variant=\"info\"\n animated={false}\n onOpenChange={(open) => {\n if (!open) {\n dismissReminder(workspaceId);\n setDismissed(true);\n }\n }}\n >\n <AlertContent className=\"pr-28\">\n <AlertTitle>Finish setting up a model provider</AlertTitle>\n <AlertDescription>\n Add workspace credentials, or keep using the instance default.\n </AlertDescription>\n <AlertActions>\n <Button asChild size=\"sm\" variant=\"secondary\">\n <Link to=\"/workspaces/$wid/settings/agents\" params={{wid: workspaceId}}>\n Agents\n </Link>\n </Button>\n </AlertActions>\n </AlertContent>\n <AlertClose />\n </Alert>\n );\n}\n\nfunction isReminderDismissed(workspaceId: string): boolean {\n return reminderStorage(workspaceId).read() === true;\n}\n\nfunction dismissReminder(workspaceId: string): void {\n reminderStorage(workspaceId).write(true);\n}\n\nfunction reminderStorage(workspaceId: string) {\n return createTypedBrowserStorage(sessionStorageOrUndefined, {\n key: `shipfox.modelProviderReminder.dismissed.${workspaceId}`,\n lifetime: 'session' as const,\n principalScope: 'workspace' as const,\n serialize: (dismissed: boolean) => JSON.stringify(dismissed),\n parse: (raw: string) => raw === 'true',\n });\n}\n"],"names":["useModelProviderConfigsQuery","createTypedBrowserStorage","sessionStorageOrUndefined","Alert","AlertActions","AlertClose","AlertContent","AlertDescription","AlertTitle","Button","Link","useState","ModelProviderReminderBanner","workspaceId","configsQuery","dismissed","setDismissed","isReminderDismissed","configs","data","unconfigured","Array","isArray","length","default_provider_id","variant","animated","onOpenChange","open","dismissReminder","className","asChild","size","to","params","wid","reminderStorage","read","write","key","lifetime","principalScope","serialize","JSON","stringify","parse","raw"],"mappings":";AAAA,SAAQA,4BAA4B,QAAO,wBAAwB;AACnE,SAAQC,yBAAyB,EAAEC,yBAAyB,QAAO,qBAAqB;AACxF,SACEC,KAAK,EACLC,YAAY,EACZC,UAAU,EACVC,YAAY,EACZC,gBAAgB,EAChBC,UAAU,QACL,0BAA0B;AACjC,SAAQC,MAAM,QAAO,2BAA2B;AAChD,SAAQC,IAAI,QAAO,yBAAyB;AAC5C,SAAQC,QAAQ,QAAO,QAAQ;AAE/B,OAAO,SAASC,4BAA4B,EAACC,WAAW,EAAwB;IAC9E,MAAMC,eAAed,6BAA6Ba;IAClD,MAAM,CAACE,WAAWC,aAAa,GAAGL,SAAS,IAAMM,oBAAoBJ;IACrE,MAAMK,UAAUJ,aAAaK,IAAI,EAAED;IACnC,MAAME,eACJC,MAAMC,OAAO,CAACJ,YACdA,QAAQK,MAAM,KAAK,KACnBT,aAAaK,IAAI,EAAEK,wBAAwB;IAE7C,IAAI,CAACJ,gBAAgBL,WAAW,OAAO;IAEvC,qBACE,MAACZ;QACCsB,SAAQ;QACRC,UAAU;QACVC,cAAc,CAACC;YACb,IAAI,CAACA,MAAM;gBACTC,gBAAgBhB;gBAChBG,aAAa;YACf;QACF;;0BAEA,MAACV;gBAAawB,WAAU;;kCACtB,KAACtB;kCAAW;;kCACZ,KAACD;kCAAiB;;kCAGlB,KAACH;kCACC,cAAA,KAACK;4BAAOsB,OAAO;4BAACC,MAAK;4BAAKP,SAAQ;sCAChC,cAAA,KAACf;gCAAKuB,IAAG;gCAAmCC,QAAQ;oCAACC,KAAKtB;gCAAW;0CAAG;;;;;;0BAM9E,KAACR;;;AAGP;AAEA,SAASY,oBAAoBJ,WAAmB;IAC9C,OAAOuB,gBAAgBvB,aAAawB,IAAI,OAAO;AACjD;AAEA,SAASR,gBAAgBhB,WAAmB;IAC1CuB,gBAAgBvB,aAAayB,KAAK,CAAC;AACrC;AAEA,SAASF,gBAAgBvB,WAAmB;IAC1C,OAAOZ,0BAA0BC,2BAA2B;QAC1DqC,KAAK,CAAC,wCAAwC,EAAE1B,aAAa;QAC7D2B,UAAU;QACVC,gBAAgB;QAChBC,WAAW,CAAC3B,YAAuB4B,KAAKC,SAAS,CAAC7B;QAClD8B,OAAO,CAACC,MAAgBA,QAAQ;IAClC;AACF"}
package/dist/feature.d.ts CHANGED
@@ -12,10 +12,6 @@ export declare const projectsFeature: {
12
12
  readonly path: "/workspaces/$wid/projects/$pid";
13
13
  readonly parent: "projectLayout";
14
14
  readonly impl: "@shipfox/client-projects/routes/project-index";
15
- }, {
16
- readonly path: "/workspaces/$wid/projects/$pid/workflows";
17
- readonly parent: "projectLayout";
18
- readonly impl: "@shipfox/client-projects/routes/workflows";
19
15
  }];
20
16
  readonly navigation: readonly [{
21
17
  readonly id: "nav.projects";
@@ -24,12 +20,6 @@ export declare const projectsFeature: {
24
20
  readonly to: "/workspaces/$wid";
25
21
  readonly exact: true;
26
22
  readonly order: 100;
27
- }, {
28
- readonly id: "nav.workflows";
29
- readonly scope: "project";
30
- readonly label: "Workflows";
31
- readonly to: "/workspaces/$wid/projects/$pid/workflows";
32
- readonly order: 200;
33
23
  }];
34
24
  };
35
25
  //# sourceMappingURL=feature.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"feature.d.ts","sourceRoot":"","sources":["../src/feature.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyC1B,CAAC"}
1
+ {"version":3,"file":"feature.d.ts","sourceRoot":"","sources":["../src/feature.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;CA6B1B,CAAC"}
package/dist/feature.js CHANGED
@@ -16,11 +16,6 @@ export const projectsFeature = defineClientFeature({
16
16
  path: '/workspaces/$wid/projects/$pid',
17
17
  parent: 'projectLayout',
18
18
  impl: '@shipfox/client-projects/routes/project-index'
19
- },
20
- {
21
- path: '/workspaces/$wid/projects/$pid/workflows',
22
- parent: 'projectLayout',
23
- impl: '@shipfox/client-projects/routes/workflows'
24
19
  }
25
20
  ],
26
21
  navigation: [
@@ -31,13 +26,6 @@ export const projectsFeature = defineClientFeature({
31
26
  to: '/workspaces/$wid',
32
27
  exact: true,
33
28
  order: 100
34
- },
35
- {
36
- id: 'nav.workflows',
37
- scope: 'project',
38
- label: 'Workflows',
39
- to: '/workspaces/$wid/projects/$pid/workflows',
40
- order: 200
41
29
  }
42
30
  ]
43
31
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/feature.ts"],"sourcesContent":["import {defineClientFeature} from '@shipfox/client-shell';\n\nexport const projectsFeature = defineClientFeature({\n id: 'shipfox.projects',\n routes: [\n {\n path: '/workspaces/$wid',\n parent: 'workspaceLayout',\n impl: '@shipfox/client-projects/routes/home',\n },\n {\n path: '/workspaces/$wid/projects/new',\n parent: 'workspaceLayout',\n impl: '@shipfox/client-projects/routes/create-project',\n },\n {\n path: '/workspaces/$wid/projects/$pid',\n parent: 'projectLayout',\n impl: '@shipfox/client-projects/routes/project-index',\n },\n {\n path: '/workspaces/$wid/projects/$pid/workflows',\n parent: 'projectLayout',\n impl: '@shipfox/client-projects/routes/workflows',\n },\n ],\n navigation: [\n {\n id: 'nav.projects',\n scope: 'workspace',\n label: 'Projects',\n to: '/workspaces/$wid',\n exact: true,\n order: 100,\n },\n {\n id: 'nav.workflows',\n scope: 'project',\n label: 'Workflows',\n to: '/workspaces/$wid/projects/$pid/workflows',\n order: 200,\n },\n ],\n});\n"],"names":["defineClientFeature","projectsFeature","id","routes","path","parent","impl","navigation","scope","label","to","exact","order"],"mappings":"AAAA,SAAQA,mBAAmB,QAAO,wBAAwB;AAE1D,OAAO,MAAMC,kBAAkBD,oBAAoB;IACjDE,IAAI;IACJC,QAAQ;QACN;YACEC,MAAM;YACNC,QAAQ;YACRC,MAAM;QACR;QACA;YACEF,MAAM;YACNC,QAAQ;YACRC,MAAM;QACR;QACA;YACEF,MAAM;YACNC,QAAQ;YACRC,MAAM;QACR;QACA;YACEF,MAAM;YACNC,QAAQ;YACRC,MAAM;QACR;KACD;IACDC,YAAY;QACV;YACEL,IAAI;YACJM,OAAO;YACPC,OAAO;YACPC,IAAI;YACJC,OAAO;YACPC,OAAO;QACT;QACA;YACEV,IAAI;YACJM,OAAO;YACPC,OAAO;YACPC,IAAI;YACJE,OAAO;QACT;KACD;AACH,GAAG"}
1
+ {"version":3,"sources":["../src/feature.ts"],"sourcesContent":["import {defineClientFeature} from '@shipfox/client-shell';\n\nexport const projectsFeature = defineClientFeature({\n id: 'shipfox.projects',\n routes: [\n {\n path: '/workspaces/$wid',\n parent: 'workspaceLayout',\n impl: '@shipfox/client-projects/routes/home',\n },\n {\n path: '/workspaces/$wid/projects/new',\n parent: 'workspaceLayout',\n impl: '@shipfox/client-projects/routes/create-project',\n },\n {\n path: '/workspaces/$wid/projects/$pid',\n parent: 'projectLayout',\n impl: '@shipfox/client-projects/routes/project-index',\n },\n ],\n navigation: [\n {\n id: 'nav.projects',\n scope: 'workspace',\n label: 'Projects',\n to: '/workspaces/$wid',\n exact: true,\n order: 100,\n },\n ],\n});\n"],"names":["defineClientFeature","projectsFeature","id","routes","path","parent","impl","navigation","scope","label","to","exact","order"],"mappings":"AAAA,SAAQA,mBAAmB,QAAO,wBAAwB;AAE1D,OAAO,MAAMC,kBAAkBD,oBAAoB;IACjDE,IAAI;IACJC,QAAQ;QACN;YACEC,MAAM;YACNC,QAAQ;YACRC,MAAM;QACR;QACA;YACEF,MAAM;YACNC,QAAQ;YACRC,MAAM;QACR;QACA;YACEF,MAAM;YACNC,QAAQ;YACRC,MAAM;QACR;KACD;IACDC,YAAY;QACV;YACEL,IAAI;YACJM,OAAO;YACPC,OAAO;YACPC,IAAI;YACJC,OAAO;YACPC,OAAO;QACT;KACD;AACH,GAAG"}
@@ -1,10 +1,12 @@
1
- import type { CreateProjectBodyDto } from '@shipfox/api-projects-dto';
1
+ import type { CreateProjectBodyDto, ListProjectsResponseDto } from '@shipfox/api-projects-dto';
2
+ import { type FetchQueryOptions } from '@tanstack/react-query';
2
3
  export declare const projectsQueryKeys: {
3
4
  all: readonly ["projects"];
4
5
  list: (workspaceId: string, search?: string) => readonly ["projects", "list", string, string];
5
6
  exists: (workspaceId: string) => readonly ["projects", "exists", string];
6
7
  detail: (projectId: string) => readonly ["projects", "detail", string];
7
8
  };
9
+ type ProjectExistenceQueryOptions = FetchQueryOptions<ListProjectsResponseDto, Error, ListProjectsResponseDto, ReturnType<typeof projectsQueryKeys.exists>>;
8
10
  export declare function listProjects({ workspaceId, limit, cursor, search, signal, }: {
9
11
  workspaceId: string;
10
12
  limit?: number;
@@ -47,6 +49,7 @@ export declare function createProject(body: CreateProjectBodyDto): Promise<{
47
49
  created_at: string;
48
50
  updated_at: string;
49
51
  }>;
52
+ export declare function projectExistenceQueryOptions(workspaceId: string): ProjectExistenceQueryOptions;
50
53
  export declare function useProjectsInfiniteQuery(workspaceId: string | undefined, search?: string, limit?: number): import("@tanstack/react-query").UseInfiniteQueryResult<import("@tanstack/react-query").InfiniteData<{
51
54
  projects: {
52
55
  id: string;
@@ -90,4 +93,5 @@ export declare function useCreateProjectMutation(): import("@tanstack/react-quer
90
93
  external_repository_id: string;
91
94
  };
92
95
  }, unknown>;
96
+ export {};
93
97
  //# sourceMappingURL=projects.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../../src/hooks/api/projects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EAGrB,MAAM,2BAA2B,CAAC;AAInC,eAAO,MAAM,iBAAiB;;wBAER,MAAM,WAAW,MAAM;0BAErB,MAAM;wBACR,MAAM;CAC3B,CAAC;AAEF,wBAAsB,YAAY,CAAC,EACjC,WAAW,EACX,KAAU,EACV,MAAM,EACN,MAAM,EACN,MAAM,GACP,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;;;;;;;;;;;;;GAMA;AAED,wBAAsB,UAAU,CAAC,SAAS,EAAE,MAAM;;;;;;;;;;GAEjD;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,oBAAoB;;;;;;;;;;GAE7D;AAED,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,MAAM,CAAC,EAAE,MAAM,EACf,KAAK,SAAK;;;;;;;;;;;;;oBAaX;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS;;;;;;;;;;WAQ5D;AAED,wBAAgB,wBAAwB;;;;;;;;;;;;;;;;;YAEvC"}
1
+ {"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../../src/hooks/api/projects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,uBAAuB,EAExB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,KAAK,iBAAiB,EAMvB,MAAM,uBAAuB,CAAC;AAE/B,eAAO,MAAM,iBAAiB;;wBAER,MAAM,WAAW,MAAM;0BAErB,MAAM;wBACR,MAAM;CAC3B,CAAC;AAEF,KAAK,4BAA4B,GAAG,iBAAiB,CACnD,uBAAuB,EACvB,KAAK,EACL,uBAAuB,EACvB,UAAU,CAAC,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAC5C,CAAC;AAEF,wBAAsB,YAAY,CAAC,EACjC,WAAW,EACX,KAAU,EACV,MAAM,EACN,MAAM,EACN,MAAM,GACP,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;;;;;;;;;;;;;GAMA;AAED,wBAAsB,UAAU,CAAC,SAAS,EAAE,MAAM;;;;;;;;;;GAEjD;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,oBAAoB;;;;;;;;;;GAE7D;AAED,wBAAgB,4BAA4B,CAAC,WAAW,EAAE,MAAM,GAAG,4BAA4B,CAM9F;AAED,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,MAAM,CAAC,EAAE,MAAM,EACf,KAAK,SAAK;;;;;;;;;;;;;oBAaX;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS;;;;;;;;;;WAQ5D;AAED,wBAAgB,wBAAwB;;;;;;;;;;;;;;;;;YAEvC"}
@@ -1,5 +1,5 @@
1
1
  import { apiRequest } from '@shipfox/client-api';
2
- import { keepPreviousData, useInfiniteQuery, useMutation, useQuery } from '@tanstack/react-query';
2
+ import { keepPreviousData, queryOptions, useInfiniteQuery, useMutation, useQuery } from '@tanstack/react-query';
3
3
  export const projectsQueryKeys = {
4
4
  all: [
5
5
  'projects'
@@ -41,6 +41,17 @@ export async function createProject(body) {
41
41
  body
42
42
  });
43
43
  }
44
+ export function projectExistenceQueryOptions(workspaceId) {
45
+ return queryOptions({
46
+ queryKey: projectsQueryKeys.exists(workspaceId),
47
+ queryFn: ({ signal })=>listProjects({
48
+ workspaceId,
49
+ limit: 1,
50
+ signal
51
+ }),
52
+ staleTime: 30_000
53
+ });
54
+ }
44
55
  export function useProjectsInfiniteQuery(workspaceId, search, limit = 50) {
45
56
  return useInfiniteQuery({
46
57
  queryKey: workspaceId ? projectsQueryKeys.list(workspaceId, search) : [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/hooks/api/projects.ts"],"sourcesContent":["import type {\n CreateProjectBodyDto,\n ListProjectsResponseDto,\n ProjectResponseDto,\n} from '@shipfox/api-projects-dto';\nimport {apiRequest} from '@shipfox/client-api';\nimport {keepPreviousData, useInfiniteQuery, useMutation, useQuery} from '@tanstack/react-query';\n\nexport const projectsQueryKeys = {\n all: ['projects'] as const,\n list: (workspaceId: string, search?: string) =>\n [...projectsQueryKeys.all, 'list', workspaceId, search ?? ''] as const,\n exists: (workspaceId: string) => [...projectsQueryKeys.all, 'exists', workspaceId] as const,\n detail: (projectId: string) => [...projectsQueryKeys.all, 'detail', projectId] as const,\n};\n\nexport async function listProjects({\n workspaceId,\n limit = 50,\n cursor,\n search,\n signal,\n}: {\n workspaceId: string;\n limit?: number;\n cursor?: string | undefined;\n search?: string | undefined;\n signal?: AbortSignal;\n}) {\n const params = new URLSearchParams({workspace_id: workspaceId, limit: String(limit)});\n if (cursor) params.set('cursor', cursor);\n if (search) params.set('search', search);\n\n return await apiRequest<ListProjectsResponseDto>(`/projects?${params.toString()}`, {signal});\n}\n\nexport async function getProject(projectId: string) {\n return await apiRequest<ProjectResponseDto>(`/projects/${projectId}`);\n}\n\nexport async function createProject(body: CreateProjectBodyDto) {\n return await apiRequest<ProjectResponseDto>('/projects', {method: 'POST', body});\n}\n\nexport function useProjectsInfiniteQuery(\n workspaceId: string | undefined,\n search?: string,\n limit = 50,\n) {\n return useInfiniteQuery({\n queryKey: workspaceId\n ? projectsQueryKeys.list(workspaceId, search)\n : [...projectsQueryKeys.all, 'list'],\n enabled: Boolean(workspaceId),\n initialPageParam: undefined as string | undefined,\n queryFn: ({pageParam, signal}) =>\n listProjects({workspaceId: workspaceId ?? '', limit, cursor: pageParam, search, signal}),\n getNextPageParam: (lastPage) => lastPage.next_cursor ?? undefined,\n placeholderData: keepPreviousData,\n });\n}\n\nexport function useProjectQuery(projectId: string | undefined) {\n return useQuery({\n queryKey: projectId\n ? projectsQueryKeys.detail(projectId)\n : [...projectsQueryKeys.all, 'detail'],\n enabled: Boolean(projectId),\n queryFn: () => getProject(projectId ?? ''),\n });\n}\n\nexport function useCreateProjectMutation() {\n return useMutation({mutationFn: createProject});\n}\n"],"names":["apiRequest","keepPreviousData","useInfiniteQuery","useMutation","useQuery","projectsQueryKeys","all","list","workspaceId","search","exists","detail","projectId","listProjects","limit","cursor","signal","params","URLSearchParams","workspace_id","String","set","toString","getProject","createProject","body","method","useProjectsInfiniteQuery","queryKey","enabled","Boolean","initialPageParam","undefined","queryFn","pageParam","getNextPageParam","lastPage","next_cursor","placeholderData","useProjectQuery","useCreateProjectMutation","mutationFn"],"mappings":"AAKA,SAAQA,UAAU,QAAO,sBAAsB;AAC/C,SAAQC,gBAAgB,EAAEC,gBAAgB,EAAEC,WAAW,EAAEC,QAAQ,QAAO,wBAAwB;AAEhG,OAAO,MAAMC,oBAAoB;IAC/BC,KAAK;QAAC;KAAW;IACjBC,MAAM,CAACC,aAAqBC,SAC1B;eAAIJ,kBAAkBC,GAAG;YAAE;YAAQE;YAAaC,UAAU;SAAG;IAC/DC,QAAQ,CAACF,cAAwB;eAAIH,kBAAkBC,GAAG;YAAE;YAAUE;SAAY;IAClFG,QAAQ,CAACC,YAAsB;eAAIP,kBAAkBC,GAAG;YAAE;YAAUM;SAAU;AAChF,EAAE;AAEF,OAAO,eAAeC,aAAa,EACjCL,WAAW,EACXM,QAAQ,EAAE,EACVC,MAAM,EACNN,MAAM,EACNO,MAAM,EAOP;IACC,MAAMC,SAAS,IAAIC,gBAAgB;QAACC,cAAcX;QAAaM,OAAOM,OAAON;IAAM;IACnF,IAAIC,QAAQE,OAAOI,GAAG,CAAC,UAAUN;IACjC,IAAIN,QAAQQ,OAAOI,GAAG,CAAC,UAAUZ;IAEjC,OAAO,MAAMT,WAAoC,CAAC,UAAU,EAAEiB,OAAOK,QAAQ,IAAI,EAAE;QAACN;IAAM;AAC5F;AAEA,OAAO,eAAeO,WAAWX,SAAiB;IAChD,OAAO,MAAMZ,WAA+B,CAAC,UAAU,EAAEY,WAAW;AACtE;AAEA,OAAO,eAAeY,cAAcC,IAA0B;IAC5D,OAAO,MAAMzB,WAA+B,aAAa;QAAC0B,QAAQ;QAAQD;IAAI;AAChF;AAEA,OAAO,SAASE,yBACdnB,WAA+B,EAC/BC,MAAe,EACfK,QAAQ,EAAE;IAEV,OAAOZ,iBAAiB;QACtB0B,UAAUpB,cACNH,kBAAkBE,IAAI,CAACC,aAAaC,UACpC;eAAIJ,kBAAkBC,GAAG;YAAE;SAAO;QACtCuB,SAASC,QAAQtB;QACjBuB,kBAAkBC;QAClBC,SAAS,CAAC,EAACC,SAAS,EAAElB,MAAM,EAAC,GAC3BH,aAAa;gBAACL,aAAaA,eAAe;gBAAIM;gBAAOC,QAAQmB;gBAAWzB;gBAAQO;YAAM;QACxFmB,kBAAkB,CAACC,WAAaA,SAASC,WAAW,IAAIL;QACxDM,iBAAiBrC;IACnB;AACF;AAEA,OAAO,SAASsC,gBAAgB3B,SAA6B;IAC3D,OAAOR,SAAS;QACdwB,UAAUhB,YACNP,kBAAkBM,MAAM,CAACC,aACzB;eAAIP,kBAAkBC,GAAG;YAAE;SAAS;QACxCuB,SAASC,QAAQlB;QACjBqB,SAAS,IAAMV,WAAWX,aAAa;IACzC;AACF;AAEA,OAAO,SAAS4B;IACd,OAAOrC,YAAY;QAACsC,YAAYjB;IAAa;AAC/C"}
1
+ {"version":3,"sources":["../../../src/hooks/api/projects.ts"],"sourcesContent":["import type {\n CreateProjectBodyDto,\n ListProjectsResponseDto,\n ProjectResponseDto,\n} from '@shipfox/api-projects-dto';\nimport {apiRequest} from '@shipfox/client-api';\nimport {\n type FetchQueryOptions,\n keepPreviousData,\n queryOptions,\n useInfiniteQuery,\n useMutation,\n useQuery,\n} from '@tanstack/react-query';\n\nexport const projectsQueryKeys = {\n all: ['projects'] as const,\n list: (workspaceId: string, search?: string) =>\n [...projectsQueryKeys.all, 'list', workspaceId, search ?? ''] as const,\n exists: (workspaceId: string) => [...projectsQueryKeys.all, 'exists', workspaceId] as const,\n detail: (projectId: string) => [...projectsQueryKeys.all, 'detail', projectId] as const,\n};\n\ntype ProjectExistenceQueryOptions = FetchQueryOptions<\n ListProjectsResponseDto,\n Error,\n ListProjectsResponseDto,\n ReturnType<typeof projectsQueryKeys.exists>\n>;\n\nexport async function listProjects({\n workspaceId,\n limit = 50,\n cursor,\n search,\n signal,\n}: {\n workspaceId: string;\n limit?: number;\n cursor?: string | undefined;\n search?: string | undefined;\n signal?: AbortSignal;\n}) {\n const params = new URLSearchParams({workspace_id: workspaceId, limit: String(limit)});\n if (cursor) params.set('cursor', cursor);\n if (search) params.set('search', search);\n\n return await apiRequest<ListProjectsResponseDto>(`/projects?${params.toString()}`, {signal});\n}\n\nexport async function getProject(projectId: string) {\n return await apiRequest<ProjectResponseDto>(`/projects/${projectId}`);\n}\n\nexport async function createProject(body: CreateProjectBodyDto) {\n return await apiRequest<ProjectResponseDto>('/projects', {method: 'POST', body});\n}\n\nexport function projectExistenceQueryOptions(workspaceId: string): ProjectExistenceQueryOptions {\n return queryOptions({\n queryKey: projectsQueryKeys.exists(workspaceId),\n queryFn: ({signal}) => listProjects({workspaceId, limit: 1, signal}),\n staleTime: 30_000,\n });\n}\n\nexport function useProjectsInfiniteQuery(\n workspaceId: string | undefined,\n search?: string,\n limit = 50,\n) {\n return useInfiniteQuery({\n queryKey: workspaceId\n ? projectsQueryKeys.list(workspaceId, search)\n : [...projectsQueryKeys.all, 'list'],\n enabled: Boolean(workspaceId),\n initialPageParam: undefined as string | undefined,\n queryFn: ({pageParam, signal}) =>\n listProjects({workspaceId: workspaceId ?? '', limit, cursor: pageParam, search, signal}),\n getNextPageParam: (lastPage) => lastPage.next_cursor ?? undefined,\n placeholderData: keepPreviousData,\n });\n}\n\nexport function useProjectQuery(projectId: string | undefined) {\n return useQuery({\n queryKey: projectId\n ? projectsQueryKeys.detail(projectId)\n : [...projectsQueryKeys.all, 'detail'],\n enabled: Boolean(projectId),\n queryFn: () => getProject(projectId ?? ''),\n });\n}\n\nexport function useCreateProjectMutation() {\n return useMutation({mutationFn: createProject});\n}\n"],"names":["apiRequest","keepPreviousData","queryOptions","useInfiniteQuery","useMutation","useQuery","projectsQueryKeys","all","list","workspaceId","search","exists","detail","projectId","listProjects","limit","cursor","signal","params","URLSearchParams","workspace_id","String","set","toString","getProject","createProject","body","method","projectExistenceQueryOptions","queryKey","queryFn","staleTime","useProjectsInfiniteQuery","enabled","Boolean","initialPageParam","undefined","pageParam","getNextPageParam","lastPage","next_cursor","placeholderData","useProjectQuery","useCreateProjectMutation","mutationFn"],"mappings":"AAKA,SAAQA,UAAU,QAAO,sBAAsB;AAC/C,SAEEC,gBAAgB,EAChBC,YAAY,EACZC,gBAAgB,EAChBC,WAAW,EACXC,QAAQ,QACH,wBAAwB;AAE/B,OAAO,MAAMC,oBAAoB;IAC/BC,KAAK;QAAC;KAAW;IACjBC,MAAM,CAACC,aAAqBC,SAC1B;eAAIJ,kBAAkBC,GAAG;YAAE;YAAQE;YAAaC,UAAU;SAAG;IAC/DC,QAAQ,CAACF,cAAwB;eAAIH,kBAAkBC,GAAG;YAAE;YAAUE;SAAY;IAClFG,QAAQ,CAACC,YAAsB;eAAIP,kBAAkBC,GAAG;YAAE;YAAUM;SAAU;AAChF,EAAE;AASF,OAAO,eAAeC,aAAa,EACjCL,WAAW,EACXM,QAAQ,EAAE,EACVC,MAAM,EACNN,MAAM,EACNO,MAAM,EAOP;IACC,MAAMC,SAAS,IAAIC,gBAAgB;QAACC,cAAcX;QAAaM,OAAOM,OAAON;IAAM;IACnF,IAAIC,QAAQE,OAAOI,GAAG,CAAC,UAAUN;IACjC,IAAIN,QAAQQ,OAAOI,GAAG,CAAC,UAAUZ;IAEjC,OAAO,MAAMV,WAAoC,CAAC,UAAU,EAAEkB,OAAOK,QAAQ,IAAI,EAAE;QAACN;IAAM;AAC5F;AAEA,OAAO,eAAeO,WAAWX,SAAiB;IAChD,OAAO,MAAMb,WAA+B,CAAC,UAAU,EAAEa,WAAW;AACtE;AAEA,OAAO,eAAeY,cAAcC,IAA0B;IAC5D,OAAO,MAAM1B,WAA+B,aAAa;QAAC2B,QAAQ;QAAQD;IAAI;AAChF;AAEA,OAAO,SAASE,6BAA6BnB,WAAmB;IAC9D,OAAOP,aAAa;QAClB2B,UAAUvB,kBAAkBK,MAAM,CAACF;QACnCqB,SAAS,CAAC,EAACb,MAAM,EAAC,GAAKH,aAAa;gBAACL;gBAAaM,OAAO;gBAAGE;YAAM;QAClEc,WAAW;IACb;AACF;AAEA,OAAO,SAASC,yBACdvB,WAA+B,EAC/BC,MAAe,EACfK,QAAQ,EAAE;IAEV,OAAOZ,iBAAiB;QACtB0B,UAAUpB,cACNH,kBAAkBE,IAAI,CAACC,aAAaC,UACpC;eAAIJ,kBAAkBC,GAAG;YAAE;SAAO;QACtC0B,SAASC,QAAQzB;QACjB0B,kBAAkBC;QAClBN,SAAS,CAAC,EAACO,SAAS,EAAEpB,MAAM,EAAC,GAC3BH,aAAa;gBAACL,aAAaA,eAAe;gBAAIM;gBAAOC,QAAQqB;gBAAW3B;gBAAQO;YAAM;QACxFqB,kBAAkB,CAACC,WAAaA,SAASC,WAAW,IAAIJ;QACxDK,iBAAiBxC;IACnB;AACF;AAEA,OAAO,SAASyC,gBAAgB7B,SAA6B;IAC3D,OAAOR,SAAS;QACdwB,UAAUhB,YACNP,kBAAkBM,MAAM,CAACC,aACzB;eAAIP,kBAAkBC,GAAG;YAAE;SAAS;QACxC0B,SAASC,QAAQrB;QACjBiB,SAAS,IAAMN,WAAWX,aAAa;IACzC;AACF;AAEA,OAAO,SAAS8B;IACd,OAAOvC,YAAY;QAACwC,YAAYnB;IAAa;AAC/C"}
package/dist/index.d.ts CHANGED
@@ -1,13 +1,11 @@
1
- export type { WorkspaceSetupState } from '@shipfox/client-shell/runtime';
2
1
  export { ProjectBreadcrumb, ProjectLayoutGuard } from './chrome.js';
3
2
  export { ProjectCrumb, type ProjectCrumbProps } from './components/project-crumb.js';
4
3
  export { ProjectSwitcher, type ProjectSwitcherProps } from './components/project-switcher.js';
5
- export { loadWorkspaceSetupRoute, type WorkspaceSetupRouteOptions, } from './components/workspace-setup-guard.js';
4
+ export { SourceStrip } from './components/source-strip.js';
6
5
  export * from './hooks/api/definitions.js';
7
6
  export * from './hooks/api/projects.js';
8
7
  export * from './pages/create-project-page.js';
9
8
  export * from './pages/home-router.js';
10
- export * from './pages/project-workflows-page.js';
11
9
  export * from './pages/projects-hub-page.js';
12
10
  export * from './project-error.js';
13
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAC,mBAAmB,EAAC,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAC,iBAAiB,EAAE,kBAAkB,EAAC,MAAM,aAAa,CAAC;AAClE,OAAO,EAAC,YAAY,EAAE,KAAK,iBAAiB,EAAC,MAAM,+BAA+B,CAAC;AACnF,OAAO,EAAC,eAAe,EAAE,KAAK,oBAAoB,EAAC,MAAM,kCAAkC,CAAC;AAC5F,OAAO,EACL,uBAAuB,EACvB,KAAK,0BAA0B,GAChC,MAAM,uCAAuC,CAAC;AAC/C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,wBAAwB,CAAC;AACvC,cAAc,mCAAmC,CAAC;AAClD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAE,kBAAkB,EAAC,MAAM,aAAa,CAAC;AAClE,OAAO,EAAC,YAAY,EAAE,KAAK,iBAAiB,EAAC,MAAM,+BAA+B,CAAC;AACnF,OAAO,EAAC,eAAe,EAAE,KAAK,oBAAoB,EAAC,MAAM,kCAAkC,CAAC;AAC5F,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AACzD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -1,12 +1,11 @@
1
1
  export { ProjectBreadcrumb, ProjectLayoutGuard } from './chrome.js';
2
2
  export { ProjectCrumb } from './components/project-crumb.js';
3
3
  export { ProjectSwitcher } from './components/project-switcher.js';
4
- export { loadWorkspaceSetupRoute } from './components/workspace-setup-guard.js';
4
+ export { SourceStrip } from './components/source-strip.js';
5
5
  export * from './hooks/api/definitions.js';
6
6
  export * from './hooks/api/projects.js';
7
7
  export * from './pages/create-project-page.js';
8
8
  export * from './pages/home-router.js';
9
- export * from './pages/project-workflows-page.js';
10
9
  export * from './pages/projects-hub-page.js';
11
10
  export * from './project-error.js';
12
11
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export type {WorkspaceSetupState} from '@shipfox/client-shell/runtime';\nexport {ProjectBreadcrumb, ProjectLayoutGuard} from './chrome.js';\nexport {ProjectCrumb, type ProjectCrumbProps} from './components/project-crumb.js';\nexport {ProjectSwitcher, type ProjectSwitcherProps} from './components/project-switcher.js';\nexport {\n loadWorkspaceSetupRoute,\n type WorkspaceSetupRouteOptions,\n} from './components/workspace-setup-guard.js';\nexport * from './hooks/api/definitions.js';\nexport * from './hooks/api/projects.js';\nexport * from './pages/create-project-page.js';\nexport * from './pages/home-router.js';\nexport * from './pages/project-workflows-page.js';\nexport * from './pages/projects-hub-page.js';\nexport * from './project-error.js';\n"],"names":["ProjectBreadcrumb","ProjectLayoutGuard","ProjectCrumb","ProjectSwitcher","loadWorkspaceSetupRoute"],"mappings":"AACA,SAAQA,iBAAiB,EAAEC,kBAAkB,QAAO,cAAc;AAClE,SAAQC,YAAY,QAA+B,gCAAgC;AACnF,SAAQC,eAAe,QAAkC,mCAAmC;AAC5F,SACEC,uBAAuB,QAElB,wCAAwC;AAC/C,cAAc,6BAA6B;AAC3C,cAAc,0BAA0B;AACxC,cAAc,iCAAiC;AAC/C,cAAc,yBAAyB;AACvC,cAAc,oCAAoC;AAClD,cAAc,+BAA+B;AAC7C,cAAc,qBAAqB"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export {ProjectBreadcrumb, ProjectLayoutGuard} from './chrome.js';\nexport {ProjectCrumb, type ProjectCrumbProps} from './components/project-crumb.js';\nexport {ProjectSwitcher, type ProjectSwitcherProps} from './components/project-switcher.js';\nexport {SourceStrip} from './components/source-strip.js';\nexport * from './hooks/api/definitions.js';\nexport * from './hooks/api/projects.js';\nexport * from './pages/create-project-page.js';\nexport * from './pages/home-router.js';\nexport * from './pages/projects-hub-page.js';\nexport * from './project-error.js';\n"],"names":["ProjectBreadcrumb","ProjectLayoutGuard","ProjectCrumb","ProjectSwitcher","SourceStrip"],"mappings":"AAAA,SAAQA,iBAAiB,EAAEC,kBAAkB,QAAO,cAAc;AAClE,SAAQC,YAAY,QAA+B,gCAAgC;AACnF,SAAQC,eAAe,QAAkC,mCAAmC;AAC5F,SAAQC,WAAW,QAAO,+BAA+B;AACzD,cAAc,6BAA6B;AAC3C,cAAc,0BAA0B;AACxC,cAAc,iCAAiC;AAC/C,cAAc,yBAAyB;AACvC,cAAc,+BAA+B;AAC7C,cAAc,qBAAqB"}
@@ -1 +1 @@
1
- {"version":3,"file":"create-project-page.stories.d.ts","sourceRoot":"","sources":["../../src/pages/create-project-page.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAO,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAmBrD,KAAK,QAAQ,GACT,YAAY,GACZ,YAAY,GACZ,oBAAoB,GACpB,oBAAoB,GACpB,mBAAmB,CAAC;AAExB,UAAU,2BAA2B;IACnC,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAiBD,iBAAS,sBAAsB,CAAC,EAAC,QAAQ,EAAC,EAAE,2BAA2B,+BA6BtE;AAED,QAAA,MAAM,IAAI;;;;;;;;;CAKqC,CAAC;AAEhD,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,UAAU,EAAE,KAAU,CAAC;AAEpC,eAAO,MAAM,SAAS,EAAE,KAEvB,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAE/B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAE/B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAE9B,CAAC"}
1
+ {"version":3,"file":"create-project-page.stories.d.ts","sourceRoot":"","sources":["../../src/pages/create-project-page.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAO,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAmBrD,KAAK,QAAQ,GACT,YAAY,GACZ,YAAY,GACZ,oBAAoB,GACpB,oBAAoB,GACpB,mBAAmB,CAAC;AAExB,UAAU,2BAA2B;IACnC,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAcD,iBAAS,sBAAsB,CAAC,EAAC,QAAQ,EAAC,EAAE,2BAA2B,+BA6BtE;AAED,QAAA,MAAM,IAAI;;;;;;;;;CAKqC,CAAC;AAEhD,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,UAAU,EAAE,KAAU,CAAC;AAEpC,eAAO,MAAM,SAAS,EAAE,KAEvB,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAE/B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAE/B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAE9B,CAAC"}
@@ -18,10 +18,7 @@ const authState = {
18
18
  id: '22222222-2222-4222-8222-222222222222',
19
19
  email: 'platform@example.com',
20
20
  name: 'Platform Engineer',
21
- email_verified_at: '2026-01-01T00:00:00.000Z',
22
- status: 'active',
23
- created_at: '2026-01-01T00:00:00.000Z',
24
- updated_at: '2026-01-01T00:00:00.000Z'
21
+ emailVerifiedAt: '2026-01-01T00:00:00.000Z'
25
22
  },
26
23
  workspaces: [
27
24
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/pages/create-project-page.stories.tsx"],"sourcesContent":["import type {IntegrationConnectionDto, RepositoryDto} from '@shipfox/api-integration-core-dto';\nimport {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 {CreateProjectPage} from './create-project-page.js';\n\nconst WORKSPACE_ID = '11111111-1111-4111-8111-111111111111';\nconst WORKSPACE_PATH = `/workspaces/${WORKSPACE_ID}/projects/new`;\nconst GITHUB_CONNECTION_ID = '33333333-3333-4333-8333-333333333333';\nconst GITEA_CONNECTION_ID = '44444444-4444-4444-8444-444444444444';\n\ntype Scenario =\n | 'playground'\n | 'long-names'\n | 'repository-loading'\n | 'empty-repositories'\n | 'connections-error';\n\ninterface CreateProjectPageStoryProps {\n scenario: Scenario;\n}\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 email_verified_at: '2026-01-01T00:00:00.000Z',\n status: 'active',\n created_at: '2026-01-01T00:00:00.000Z',\n updated_at: '2026-01-01T00:00:00.000Z',\n },\n workspaces: [{id: WORKSPACE_ID, name: 'Acme', membershipId: 'membership-1'}],\n};\n\nfunction CreateProjectPageStory({scenario}: CreateProjectPageStoryProps) {\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-neutral-background 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/CreateProjectPage',\n component: CreateProjectPageStory,\n parameters: {layout: 'fullscreen'},\n args: {scenario: 'playground'},\n} satisfies Meta<typeof CreateProjectPageStory>;\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const Playground: Story = {};\n\nexport const LongNames: Story = {\n args: {scenario: 'long-names'},\n};\n\nexport const RepositoryLoading: Story = {\n args: {scenario: 'repository-loading'},\n};\n\nexport const EmptyRepositories: Story = {\n args: {scenario: 'empty-repositories'},\n};\n\nexport const ConnectionsError: Story = {\n args: {scenario: 'connections-error'},\n};\n\nfunction createStoryRouter() {\n const rootRoute = createRootRoute({component: Outlet});\n const workspaceRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: '/workspaces/$wid',\n component: Outlet,\n });\n const createProjectRoute = createRoute({\n getParentRoute: () => workspaceRoute,\n path: 'projects/new',\n component: CreateProjectPage,\n });\n const integrationsRoute = createRoute({\n getParentRoute: () => workspaceRoute,\n path: 'integrations',\n component: () => <div />,\n });\n const modelProvidersRoute = createRoute({\n getParentRoute: () => workspaceRoute,\n path: 'settings/agents',\n component: () => <div />,\n });\n const projectRoute = createRoute({\n getParentRoute: () => workspaceRoute,\n path: 'projects/$pid',\n component: () => <div />,\n });\n\n return createRouter({\n history: createMemoryHistory({initialEntries: [WORKSPACE_PATH]}),\n routeTree: rootRoute.addChildren([\n workspaceRoute.addChildren([\n createProjectRoute,\n integrationsRoute,\n modelProvidersRoute,\n projectRoute,\n ]),\n ]),\n });\n}\n\nfunction fetchForScenario(scenario: Scenario): typeof fetch {\n return (input, init) => {\n const url = requestUrl(input);\n const method = input instanceof Request ? input.method : (init?.method ?? 'GET');\n if (url.pathname === `/workspaces/${WORKSPACE_ID}/agent/model-providers`) {\n return Promise.resolve(\n jsonResponse({configs: [modelProviderConfig()], default_provider_id: 'openai'}),\n );\n }\n if (url.pathname === '/integration-connections') {\n if (scenario === 'connections-error') return Promise.resolve(errorResponse());\n return Promise.resolve(jsonResponse({connections: connectionsForScenario(scenario)}));\n }\n if (\n url.pathname.startsWith('/integration-connections/') &&\n url.pathname.endsWith('/repositories')\n ) {\n if (scenario === 'repository-loading') return new Promise<Response>(() => undefined);\n return Promise.resolve(\n jsonResponse({repositories: repositoriesForScenario(scenario), next_cursor: null}),\n );\n }\n if (url.pathname === '/projects' && method === 'POST') {\n return Promise.resolve(\n jsonResponse({\n id: '99999999-9999-4999-8999-999999999999',\n workspace_id: WORKSPACE_ID,\n name: 'Platform',\n source: {\n connection_id: GITHUB_CONNECTION_ID,\n external_repository_id: 'platform',\n },\n created_at: '2026-01-01T00:00:00.000Z',\n updated_at: '2026-01-01T00:00:00.000Z',\n }),\n );\n }\n return Promise.resolve(jsonResponse({}, {status: 404}));\n };\n}\n\nfunction connectionsForScenario(scenario: Scenario): IntegrationConnectionDto[] {\n if (scenario === 'long-names') {\n return [\n connection({\n id: GITHUB_CONNECTION_ID,\n provider: 'github',\n display_name: 'acme-platform-engineering-production',\n external_account_id: 'acme-platform-engineering-production',\n }),\n connection({\n id: GITEA_CONNECTION_ID,\n provider: 'gitea',\n display_name: 'git.internal.acme.example/platform-tools',\n external_account_id: 'git.internal.acme.example/platform-tools',\n }),\n ];\n }\n\n return [\n connection({\n id: GITHUB_CONNECTION_ID,\n provider: 'github',\n display_name: 'acme',\n external_account_id: 'acme',\n }),\n connection({\n id: GITEA_CONNECTION_ID,\n provider: 'gitea',\n display_name: 'git.acme.internal',\n external_account_id: 'git.acme.internal',\n }),\n ];\n}\n\nfunction repositoriesForScenario(scenario: Scenario): RepositoryDto[] {\n if (scenario === 'empty-repositories') return [];\n if (scenario === 'long-names') {\n return [\n repository({\n external_repository_id: 'acme-platform-infrastructure-control-plane',\n name: 'acme-platform-infrastructure-control-plane',\n full_name: 'acme-engineering/acme-platform-infrastructure-control-plane',\n default_branch: 'production',\n }),\n repository({\n external_repository_id: 'workflow-automation-and-runner-orchestration',\n name: 'workflow-automation-and-runner-orchestration',\n full_name: 'acme-engineering/workflow-automation-and-runner-orchestration',\n default_branch: 'main',\n }),\n repository({\n external_repository_id: 'customer-deployment-pipelines',\n name: 'customer-deployment-pipelines',\n full_name: 'acme-solutions/customer-deployment-pipelines',\n default_branch: 'release',\n }),\n ];\n }\n\n return [\n repository({\n external_repository_id: 'platform',\n name: 'platform',\n full_name: 'acme/platform',\n default_branch: 'main',\n }),\n repository({\n external_repository_id: 'api',\n name: 'api',\n full_name: 'acme/api',\n default_branch: 'main',\n }),\n repository({\n external_repository_id: 'client',\n name: 'client',\n full_name: 'acme/client',\n default_branch: 'main',\n }),\n repository({\n external_repository_id: 'runners',\n name: 'runners',\n full_name: 'acme/runners',\n default_branch: 'main',\n }),\n repository({\n external_repository_id: 'workflows',\n name: 'workflows',\n full_name: 'acme/workflows',\n default_branch: 'develop',\n }),\n ];\n}\n\nfunction connection(\n overrides: Partial<IntegrationConnectionDto> & Pick<IntegrationConnectionDto, 'id'>,\n): IntegrationConnectionDto {\n return {\n workspace_id: WORKSPACE_ID,\n provider: 'github',\n external_account_id: 'acme',\n slug: 'github_acme',\n display_name: '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 ...overrides,\n };\n}\n\nfunction repository(overrides: Partial<RepositoryDto>): RepositoryDto {\n return {\n connection_id: GITHUB_CONNECTION_ID,\n external_repository_id: 'platform',\n owner: 'acme',\n name: 'platform',\n full_name: 'acme/platform',\n default_branch: 'main',\n visibility: 'private',\n clone_url: 'https://github.example.test/acme/platform.git',\n html_url: 'https://github.example.test/acme/platform',\n ...overrides,\n };\n}\n\nfunction modelProviderConfig() {\n return {\n workspace_id: WORKSPACE_ID,\n provider_id: 'openai',\n default_model: 'gpt-5.5-pro',\n credential_fields: ['api_key'],\n lifecycle_status: 'active',\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\nfunction errorResponse() {\n return jsonResponse({code: 'server-error'}, {status: 500});\n}\n"],"names":["configureApiClient","authStateAtom","Toaster","QueryClient","QueryClientProvider","createMemoryHistory","createRootRoute","createRoute","createRouter","Outlet","RouterProvider","createStore","Provider","JotaiProvider","useMemo","CreateProjectPage","WORKSPACE_ID","WORKSPACE_PATH","GITHUB_CONNECTION_ID","GITEA_CONNECTION_ID","authState","status","token","user","id","email","name","email_verified_at","created_at","updated_at","workspaces","membershipId","CreateProjectPageStory","scenario","baseUrl","fetchImpl","fetchForScenario","queryClient","defaultOptions","queries","retry","store","nextStore","set","router","createStoryRouter","client","div","className","meta","title","component","parameters","layout","args","Playground","LongNames","RepositoryLoading","EmptyRepositories","ConnectionsError","rootRoute","workspaceRoute","getParentRoute","path","createProjectRoute","integrationsRoute","modelProvidersRoute","projectRoute","history","initialEntries","routeTree","addChildren","input","init","url","requestUrl","method","Request","pathname","Promise","resolve","jsonResponse","configs","modelProviderConfig","default_provider_id","errorResponse","connections","connectionsForScenario","startsWith","endsWith","undefined","repositories","repositoriesForScenario","next_cursor","workspace_id","source","connection_id","external_repository_id","connection","provider","display_name","external_account_id","repository","full_name","default_branch","overrides","slug","lifecycle_status","capabilities","owner","visibility","clone_url","html_url","provider_id","default_model","credential_fields","URL","body","Response","JSON","stringify","headers","code"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/pages/create-project-page.stories.tsx"],"sourcesContent":["import type {IntegrationConnectionDto, RepositoryDto} from '@shipfox/api-integration-core-dto';\nimport {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 {CreateProjectPage} from './create-project-page.js';\n\nconst WORKSPACE_ID = '11111111-1111-4111-8111-111111111111';\nconst WORKSPACE_PATH = `/workspaces/${WORKSPACE_ID}/projects/new`;\nconst GITHUB_CONNECTION_ID = '33333333-3333-4333-8333-333333333333';\nconst GITEA_CONNECTION_ID = '44444444-4444-4444-8444-444444444444';\n\ntype Scenario =\n | 'playground'\n | 'long-names'\n | 'repository-loading'\n | 'empty-repositories'\n | 'connections-error';\n\ninterface CreateProjectPageStoryProps {\n scenario: Scenario;\n}\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', membershipId: 'membership-1'}],\n};\n\nfunction CreateProjectPageStory({scenario}: CreateProjectPageStoryProps) {\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-neutral-background 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/CreateProjectPage',\n component: CreateProjectPageStory,\n parameters: {layout: 'fullscreen'},\n args: {scenario: 'playground'},\n} satisfies Meta<typeof CreateProjectPageStory>;\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const Playground: Story = {};\n\nexport const LongNames: Story = {\n args: {scenario: 'long-names'},\n};\n\nexport const RepositoryLoading: Story = {\n args: {scenario: 'repository-loading'},\n};\n\nexport const EmptyRepositories: Story = {\n args: {scenario: 'empty-repositories'},\n};\n\nexport const ConnectionsError: Story = {\n args: {scenario: 'connections-error'},\n};\n\nfunction createStoryRouter() {\n const rootRoute = createRootRoute({component: Outlet});\n const workspaceRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: '/workspaces/$wid',\n component: Outlet,\n });\n const createProjectRoute = createRoute({\n getParentRoute: () => workspaceRoute,\n path: 'projects/new',\n component: CreateProjectPage,\n });\n const integrationsRoute = createRoute({\n getParentRoute: () => workspaceRoute,\n path: 'integrations',\n component: () => <div />,\n });\n const modelProvidersRoute = createRoute({\n getParentRoute: () => workspaceRoute,\n path: 'settings/agents',\n component: () => <div />,\n });\n const projectRoute = createRoute({\n getParentRoute: () => workspaceRoute,\n path: 'projects/$pid',\n component: () => <div />,\n });\n\n return createRouter({\n history: createMemoryHistory({initialEntries: [WORKSPACE_PATH]}),\n routeTree: rootRoute.addChildren([\n workspaceRoute.addChildren([\n createProjectRoute,\n integrationsRoute,\n modelProvidersRoute,\n projectRoute,\n ]),\n ]),\n });\n}\n\nfunction fetchForScenario(scenario: Scenario): typeof fetch {\n return (input, init) => {\n const url = requestUrl(input);\n const method = input instanceof Request ? input.method : (init?.method ?? 'GET');\n if (url.pathname === `/workspaces/${WORKSPACE_ID}/agent/model-providers`) {\n return Promise.resolve(\n jsonResponse({configs: [modelProviderConfig()], default_provider_id: 'openai'}),\n );\n }\n if (url.pathname === '/integration-connections') {\n if (scenario === 'connections-error') return Promise.resolve(errorResponse());\n return Promise.resolve(jsonResponse({connections: connectionsForScenario(scenario)}));\n }\n if (\n url.pathname.startsWith('/integration-connections/') &&\n url.pathname.endsWith('/repositories')\n ) {\n if (scenario === 'repository-loading') return new Promise<Response>(() => undefined);\n return Promise.resolve(\n jsonResponse({repositories: repositoriesForScenario(scenario), next_cursor: null}),\n );\n }\n if (url.pathname === '/projects' && method === 'POST') {\n return Promise.resolve(\n jsonResponse({\n id: '99999999-9999-4999-8999-999999999999',\n workspace_id: WORKSPACE_ID,\n name: 'Platform',\n source: {\n connection_id: GITHUB_CONNECTION_ID,\n external_repository_id: 'platform',\n },\n created_at: '2026-01-01T00:00:00.000Z',\n updated_at: '2026-01-01T00:00:00.000Z',\n }),\n );\n }\n return Promise.resolve(jsonResponse({}, {status: 404}));\n };\n}\n\nfunction connectionsForScenario(scenario: Scenario): IntegrationConnectionDto[] {\n if (scenario === 'long-names') {\n return [\n connection({\n id: GITHUB_CONNECTION_ID,\n provider: 'github',\n display_name: 'acme-platform-engineering-production',\n external_account_id: 'acme-platform-engineering-production',\n }),\n connection({\n id: GITEA_CONNECTION_ID,\n provider: 'gitea',\n display_name: 'git.internal.acme.example/platform-tools',\n external_account_id: 'git.internal.acme.example/platform-tools',\n }),\n ];\n }\n\n return [\n connection({\n id: GITHUB_CONNECTION_ID,\n provider: 'github',\n display_name: 'acme',\n external_account_id: 'acme',\n }),\n connection({\n id: GITEA_CONNECTION_ID,\n provider: 'gitea',\n display_name: 'git.acme.internal',\n external_account_id: 'git.acme.internal',\n }),\n ];\n}\n\nfunction repositoriesForScenario(scenario: Scenario): RepositoryDto[] {\n if (scenario === 'empty-repositories') return [];\n if (scenario === 'long-names') {\n return [\n repository({\n external_repository_id: 'acme-platform-infrastructure-control-plane',\n name: 'acme-platform-infrastructure-control-plane',\n full_name: 'acme-engineering/acme-platform-infrastructure-control-plane',\n default_branch: 'production',\n }),\n repository({\n external_repository_id: 'workflow-automation-and-runner-orchestration',\n name: 'workflow-automation-and-runner-orchestration',\n full_name: 'acme-engineering/workflow-automation-and-runner-orchestration',\n default_branch: 'main',\n }),\n repository({\n external_repository_id: 'customer-deployment-pipelines',\n name: 'customer-deployment-pipelines',\n full_name: 'acme-solutions/customer-deployment-pipelines',\n default_branch: 'release',\n }),\n ];\n }\n\n return [\n repository({\n external_repository_id: 'platform',\n name: 'platform',\n full_name: 'acme/platform',\n default_branch: 'main',\n }),\n repository({\n external_repository_id: 'api',\n name: 'api',\n full_name: 'acme/api',\n default_branch: 'main',\n }),\n repository({\n external_repository_id: 'client',\n name: 'client',\n full_name: 'acme/client',\n default_branch: 'main',\n }),\n repository({\n external_repository_id: 'runners',\n name: 'runners',\n full_name: 'acme/runners',\n default_branch: 'main',\n }),\n repository({\n external_repository_id: 'workflows',\n name: 'workflows',\n full_name: 'acme/workflows',\n default_branch: 'develop',\n }),\n ];\n}\n\nfunction connection(\n overrides: Partial<IntegrationConnectionDto> & Pick<IntegrationConnectionDto, 'id'>,\n): IntegrationConnectionDto {\n return {\n workspace_id: WORKSPACE_ID,\n provider: 'github',\n external_account_id: 'acme',\n slug: 'github_acme',\n display_name: '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 ...overrides,\n };\n}\n\nfunction repository(overrides: Partial<RepositoryDto>): RepositoryDto {\n return {\n connection_id: GITHUB_CONNECTION_ID,\n external_repository_id: 'platform',\n owner: 'acme',\n name: 'platform',\n full_name: 'acme/platform',\n default_branch: 'main',\n visibility: 'private',\n clone_url: 'https://github.example.test/acme/platform.git',\n html_url: 'https://github.example.test/acme/platform',\n ...overrides,\n };\n}\n\nfunction modelProviderConfig() {\n return {\n workspace_id: WORKSPACE_ID,\n provider_id: 'openai',\n default_model: 'gpt-5.5-pro',\n credential_fields: ['api_key'],\n lifecycle_status: 'active',\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\nfunction errorResponse() {\n return jsonResponse({code: 'server-error'}, {status: 500});\n}\n"],"names":["configureApiClient","authStateAtom","Toaster","QueryClient","QueryClientProvider","createMemoryHistory","createRootRoute","createRoute","createRouter","Outlet","RouterProvider","createStore","Provider","JotaiProvider","useMemo","CreateProjectPage","WORKSPACE_ID","WORKSPACE_PATH","GITHUB_CONNECTION_ID","GITEA_CONNECTION_ID","authState","status","token","user","id","email","name","emailVerifiedAt","workspaces","membershipId","CreateProjectPageStory","scenario","baseUrl","fetchImpl","fetchForScenario","queryClient","defaultOptions","queries","retry","store","nextStore","set","router","createStoryRouter","client","div","className","meta","title","component","parameters","layout","args","Playground","LongNames","RepositoryLoading","EmptyRepositories","ConnectionsError","rootRoute","workspaceRoute","getParentRoute","path","createProjectRoute","integrationsRoute","modelProvidersRoute","projectRoute","history","initialEntries","routeTree","addChildren","input","init","url","requestUrl","method","Request","pathname","Promise","resolve","jsonResponse","configs","modelProviderConfig","default_provider_id","errorResponse","connections","connectionsForScenario","startsWith","endsWith","undefined","repositories","repositoriesForScenario","next_cursor","workspace_id","source","connection_id","external_repository_id","created_at","updated_at","connection","provider","display_name","external_account_id","repository","full_name","default_branch","overrides","slug","lifecycle_status","capabilities","owner","visibility","clone_url","html_url","provider_id","default_model","credential_fields","URL","body","Response","JSON","stringify","headers","code"],"mappings":"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"}