@shipfox/client-integrations 0.2.0 → 2.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 (78) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +50 -0
  3. package/dist/components/callback-status-shell.d.ts +9 -0
  4. package/dist/components/callback-status-shell.d.ts.map +1 -0
  5. package/dist/components/callback-status-shell.js +81 -0
  6. package/dist/components/callback-status-shell.js.map +1 -0
  7. package/dist/components/integration-gallery.stories.d.ts.map +1 -1
  8. package/dist/components/integration-gallery.stories.js +28 -0
  9. package/dist/components/integration-gallery.stories.js.map +1 -1
  10. package/dist/components/redirect-install-page.d.ts +2 -1
  11. package/dist/components/redirect-install-page.d.ts.map +1 -1
  12. package/dist/components/redirect-install-page.js +4 -2
  13. package/dist/components/redirect-install-page.js.map +1 -1
  14. package/dist/feature.d.ts +8 -0
  15. package/dist/feature.d.ts.map +1 -1
  16. package/dist/feature.js +10 -0
  17. package/dist/feature.js.map +1 -1
  18. package/dist/hooks/api/integrations.d.ts +41 -0
  19. package/dist/hooks/api/integrations.d.ts.map +1 -1
  20. package/dist/hooks/api/integrations.js +24 -0
  21. package/dist/hooks/api/integrations.js.map +1 -1
  22. package/dist/index.d.ts +3 -0
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +3 -0
  25. package/dist/index.js.map +1 -1
  26. package/dist/pages/linear-callback-page.d.ts.map +1 -1
  27. package/dist/pages/linear-callback-page.js +11 -78
  28. package/dist/pages/linear-callback-page.js.map +1 -1
  29. package/dist/pages/linear-install-page.d.ts.map +1 -1
  30. package/dist/pages/linear-install-page.js +1 -0
  31. package/dist/pages/linear-install-page.js.map +1 -1
  32. package/dist/pages/sentry-install-page.d.ts.map +1 -1
  33. package/dist/pages/sentry-install-page.js +1 -0
  34. package/dist/pages/sentry-install-page.js.map +1 -1
  35. package/dist/pages/slack-callback-page.d.ts +2 -0
  36. package/dist/pages/slack-callback-page.d.ts.map +1 -0
  37. package/dist/pages/slack-callback-page.js +114 -0
  38. package/dist/pages/slack-callback-page.js.map +1 -0
  39. package/dist/pages/slack-install-page.d.ts +2 -0
  40. package/dist/pages/slack-install-page.d.ts.map +1 -0
  41. package/dist/pages/slack-install-page.js +19 -0
  42. package/dist/pages/slack-install-page.js.map +1 -0
  43. package/dist/provider-catalog.d.ts +1 -1
  44. package/dist/provider-catalog.d.ts.map +1 -1
  45. package/dist/provider-catalog.js +5 -0
  46. package/dist/provider-catalog.js.map +1 -1
  47. package/dist/routes/slack-callback.d.ts +6 -0
  48. package/dist/routes/slack-callback.d.ts.map +1 -0
  49. package/dist/routes/slack-callback.js +7 -0
  50. package/dist/routes/slack-callback.js.map +1 -0
  51. package/dist/routes/slack.d.ts +6 -0
  52. package/dist/routes/slack.d.ts.map +1 -0
  53. package/dist/routes/slack.js +7 -0
  54. package/dist/routes/slack.js.map +1 -0
  55. package/dist/slack-callback.d.ts +17 -0
  56. package/dist/slack-callback.d.ts.map +1 -0
  57. package/dist/slack-callback.js +99 -0
  58. package/dist/slack-callback.js.map +1 -0
  59. package/dist/tsconfig.test.tsbuildinfo +1 -1
  60. package/package.json +26 -48
  61. package/src/components/callback-status-shell.tsx +73 -0
  62. package/src/components/integration-gallery.stories.tsx +18 -0
  63. package/src/components/redirect-install-page.tsx +3 -1
  64. package/src/feature.ts +10 -0
  65. package/src/hooks/api/integrations.test.ts +30 -0
  66. package/src/hooks/api/integrations.ts +35 -0
  67. package/src/index.ts +3 -0
  68. package/src/pages/linear-callback-page.tsx +11 -52
  69. package/src/pages/linear-install-page.tsx +1 -0
  70. package/src/pages/sentry-install-page.tsx +1 -0
  71. package/src/pages/slack-callback-page.tsx +120 -0
  72. package/src/pages/slack-install-page.tsx +22 -0
  73. package/src/provider-catalog.ts +7 -1
  74. package/src/routes/slack-callback.tsx +3 -0
  75. package/src/routes/slack.tsx +3 -0
  76. package/src/slack-callback.test.ts +32 -0
  77. package/src/slack-callback.ts +141 -0
  78. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1,2 +1,2 @@
1
1
  $ shipfox-swc
2
- Successfully compiled: 42 files with swc (57.5ms)
2
+ Successfully compiled: 48 files with swc (531.64ms)
package/CHANGELOG.md CHANGED
@@ -1,5 +1,55 @@
1
1
  # @shipfox/client-integrations
2
2
 
3
+ ## 2.0.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 1820feb: Adds Slack Settings installation and callback recovery while returning stable workspace access errors.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [0bb82a4]
12
+ - Updated dependencies [ba2e3dc]
13
+ - Updated dependencies [1820feb]
14
+ - Updated dependencies [7ac43a4]
15
+ - Updated dependencies [f262539]
16
+ - Updated dependencies [3bb4e26]
17
+ - Updated dependencies [4604a06]
18
+ - @shipfox/api-integration-core-dto@6.0.0
19
+ - @shipfox/client-auth@2.0.0
20
+ - @shipfox/react-ui@0.3.3
21
+ - @shipfox/client-shell@2.0.0
22
+ - @shipfox/api-integration-gitea-dto@6.0.0
23
+ - @shipfox/api-integration-github-dto@6.0.0
24
+ - @shipfox/api-integration-linear-dto@6.0.0
25
+ - @shipfox/api-integration-sentry-dto@6.0.0
26
+ - @shipfox/api-integration-slack-dto@6.0.0
27
+ - @shipfox/api-integration-webhook-dto@6.0.0
28
+ - @shipfox/client-ui@2.0.0
29
+
30
+ ## 1.0.0
31
+
32
+ ### Patch Changes
33
+
34
+ - bb037af: Resolves workspace packages from source during development while published consumers continue to use compiled output.
35
+ - Updated dependencies [47809a2]
36
+ - Updated dependencies [2875241]
37
+ - Updated dependencies [bb037af]
38
+ - Updated dependencies [5c63a2a]
39
+ - Updated dependencies [d8658ba]
40
+ - Updated dependencies [fb70438]
41
+ - @shipfox/client-shell@1.0.0
42
+ - @shipfox/api-integration-core-dto@5.0.0
43
+ - @shipfox/api-integration-gitea-dto@5.0.0
44
+ - @shipfox/api-integration-github-dto@5.0.0
45
+ - @shipfox/api-integration-linear-dto@5.0.0
46
+ - @shipfox/api-integration-sentry-dto@5.0.0
47
+ - @shipfox/api-integration-webhook-dto@5.0.0
48
+ - @shipfox/client-api@1.0.0
49
+ - @shipfox/client-auth@1.0.0
50
+ - @shipfox/client-ui@1.0.0
51
+ - @shipfox/react-ui@0.3.2
52
+
3
53
  ## 0.2.0
4
54
 
5
55
  ### Minor Changes
@@ -0,0 +1,9 @@
1
+ export declare function CallbackStatusShell({ title, message, startOver, switchAccount, workspaceId, installPath, }: {
2
+ title: string;
3
+ message: string;
4
+ startOver?: boolean;
5
+ switchAccount?: boolean;
6
+ workspaceId?: string | undefined;
7
+ installPath: '/workspaces/$wid/integrations/linear' | '/workspaces/$wid/integrations/slack';
8
+ }): import("react").JSX.Element;
9
+ //# sourceMappingURL=callback-status-shell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"callback-status-shell.d.ts","sourceRoot":"","sources":["../../src/components/callback-status-shell.tsx"],"names":[],"mappings":"AAMA,wBAAgB,mBAAmB,CAAC,EAClC,KAAK,EACL,OAAO,EACP,SAAS,EACT,aAAa,EACb,WAAW,EACX,WAAW,GACZ,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,WAAW,EAAE,sCAAsC,GAAG,qCAAqC,CAAC;CAC7F,+BAoDA"}
@@ -0,0 +1,81 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ButtonLink } from '@shipfox/react-ui/button';
3
+ import { Callout } from '@shipfox/react-ui/callout';
4
+ import { Text } from '@shipfox/react-ui/typography';
5
+ import { Link } from '@tanstack/react-router';
6
+ import { useEffect, useRef } from 'react';
7
+ export function CallbackStatusShell({ title, message, startOver, switchAccount, workspaceId, installPath }) {
8
+ const headingRef = useRef(null);
9
+ useEffect(()=>headingRef.current?.focus(), []);
10
+ const recoveryVariant = startOver || switchAccount ? 'muted' : 'base';
11
+ const settings = workspaceId ? /*#__PURE__*/ _jsx(ButtonLink, {
12
+ asChild: true,
13
+ variant: recoveryVariant,
14
+ className: "min-h-44 w-full sm:w-fit",
15
+ children: /*#__PURE__*/ _jsx(Link, {
16
+ to: "/workspaces/$wid/settings/integrations",
17
+ params: {
18
+ wid: workspaceId
19
+ },
20
+ children: "Back to integrations"
21
+ })
22
+ }) : /*#__PURE__*/ _jsx(ButtonLink, {
23
+ asChild: true,
24
+ variant: recoveryVariant,
25
+ className: "min-h-44 w-full sm:w-fit",
26
+ children: /*#__PURE__*/ _jsx(Link, {
27
+ to: "/",
28
+ children: "Back to Shipfox"
29
+ })
30
+ });
31
+ const logoutRedirect = workspaceId ? installPath.replace('$wid', workspaceId) : undefined;
32
+ return /*#__PURE__*/ _jsx("main", {
33
+ className: "flex min-h-screen bg-background-subtle-base px-16 py-32",
34
+ children: /*#__PURE__*/ _jsxs("div", {
35
+ className: "mx-auto flex w-full max-w-[480px] flex-col justify-center gap-20",
36
+ children: [
37
+ /*#__PURE__*/ _jsx("h2", {
38
+ ref: headingRef,
39
+ tabIndex: -1,
40
+ className: "text-24 font-semibold outline-none",
41
+ children: title
42
+ }),
43
+ /*#__PURE__*/ _jsx(Callout, {
44
+ role: "alert",
45
+ type: "error",
46
+ children: /*#__PURE__*/ _jsx(Text, {
47
+ size: "sm",
48
+ children: message
49
+ })
50
+ }),
51
+ /*#__PURE__*/ _jsxs("div", {
52
+ className: "flex flex-col gap-8 sm:flex-row sm:items-center",
53
+ children: [
54
+ switchAccount ? /*#__PURE__*/ _jsx(ButtonLink, {
55
+ asChild: true,
56
+ className: "min-h-44 w-full sm:w-fit",
57
+ children: /*#__PURE__*/ _jsx(Link, {
58
+ to: workspaceId ? `/auth/logout?redirect=${encodeURIComponent(logoutRedirect ?? '/')}` : '/auth/logout',
59
+ children: "Switch account"
60
+ })
61
+ }) : null,
62
+ startOver && workspaceId ? /*#__PURE__*/ _jsx(ButtonLink, {
63
+ asChild: true,
64
+ className: "min-h-44 w-full sm:w-fit",
65
+ children: /*#__PURE__*/ _jsx(Link, {
66
+ to: installPath,
67
+ params: {
68
+ wid: workspaceId
69
+ },
70
+ children: "Start over"
71
+ })
72
+ }) : null,
73
+ settings
74
+ ]
75
+ })
76
+ ]
77
+ })
78
+ });
79
+ }
80
+
81
+ //# sourceMappingURL=callback-status-shell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/callback-status-shell.tsx"],"sourcesContent":["import {ButtonLink} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {Text} from '@shipfox/react-ui/typography';\nimport {Link} from '@tanstack/react-router';\nimport {useEffect, useRef} from 'react';\n\nexport function CallbackStatusShell({\n title,\n message,\n startOver,\n switchAccount,\n workspaceId,\n installPath,\n}: {\n title: string;\n message: string;\n startOver?: boolean;\n switchAccount?: boolean;\n workspaceId?: string | undefined;\n installPath: '/workspaces/$wid/integrations/linear' | '/workspaces/$wid/integrations/slack';\n}) {\n const headingRef = useRef<HTMLHeadingElement>(null);\n useEffect(() => headingRef.current?.focus(), []);\n const recoveryVariant = startOver || switchAccount ? 'muted' : 'base';\n const settings = workspaceId ? (\n <ButtonLink asChild variant={recoveryVariant} className=\"min-h-44 w-full sm:w-fit\">\n <Link to=\"/workspaces/$wid/settings/integrations\" params={{wid: workspaceId}}>\n Back to integrations\n </Link>\n </ButtonLink>\n ) : (\n <ButtonLink asChild variant={recoveryVariant} className=\"min-h-44 w-full sm:w-fit\">\n <Link to=\"/\">Back to Shipfox</Link>\n </ButtonLink>\n );\n const logoutRedirect = workspaceId ? installPath.replace('$wid', workspaceId) : undefined;\n\n return (\n <main className=\"flex min-h-screen bg-background-subtle-base px-16 py-32\">\n <div className=\"mx-auto flex w-full max-w-[480px] flex-col justify-center gap-20\">\n <h2 ref={headingRef} tabIndex={-1} className=\"text-24 font-semibold outline-none\">\n {title}\n </h2>\n <Callout role=\"alert\" type=\"error\">\n <Text size=\"sm\">{message}</Text>\n </Callout>\n <div className=\"flex flex-col gap-8 sm:flex-row sm:items-center\">\n {switchAccount ? (\n <ButtonLink asChild className=\"min-h-44 w-full sm:w-fit\">\n <Link\n to={\n workspaceId\n ? `/auth/logout?redirect=${encodeURIComponent(logoutRedirect ?? '/')}`\n : '/auth/logout'\n }\n >\n Switch account\n </Link>\n </ButtonLink>\n ) : null}\n {startOver && workspaceId ? (\n <ButtonLink asChild className=\"min-h-44 w-full sm:w-fit\">\n <Link to={installPath} params={{wid: workspaceId}}>\n Start over\n </Link>\n </ButtonLink>\n ) : null}\n {settings}\n </div>\n </div>\n </main>\n );\n}\n"],"names":["ButtonLink","Callout","Text","Link","useEffect","useRef","CallbackStatusShell","title","message","startOver","switchAccount","workspaceId","installPath","headingRef","current","focus","recoveryVariant","settings","asChild","variant","className","to","params","wid","logoutRedirect","replace","undefined","main","div","h2","ref","tabIndex","role","type","size","encodeURIComponent"],"mappings":";AAAA,SAAQA,UAAU,QAAO,2BAA2B;AACpD,SAAQC,OAAO,QAAO,4BAA4B;AAClD,SAAQC,IAAI,QAAO,+BAA+B;AAClD,SAAQC,IAAI,QAAO,yBAAyB;AAC5C,SAAQC,SAAS,EAAEC,MAAM,QAAO,QAAQ;AAExC,OAAO,SAASC,oBAAoB,EAClCC,KAAK,EACLC,OAAO,EACPC,SAAS,EACTC,aAAa,EACbC,WAAW,EACXC,WAAW,EAQZ;IACC,MAAMC,aAAaR,OAA2B;IAC9CD,UAAU,IAAMS,WAAWC,OAAO,EAAEC,SAAS,EAAE;IAC/C,MAAMC,kBAAkBP,aAAaC,gBAAgB,UAAU;IAC/D,MAAMO,WAAWN,4BACf,KAACX;QAAWkB,OAAO;QAACC,SAASH;QAAiBI,WAAU;kBACtD,cAAA,KAACjB;YAAKkB,IAAG;YAAyCC,QAAQ;gBAACC,KAAKZ;YAAW;sBAAG;;uBAKhF,KAACX;QAAWkB,OAAO;QAACC,SAASH;QAAiBI,WAAU;kBACtD,cAAA,KAACjB;YAAKkB,IAAG;sBAAI;;;IAGjB,MAAMG,iBAAiBb,cAAcC,YAAYa,OAAO,CAAC,QAAQd,eAAee;IAEhF,qBACE,KAACC;QAAKP,WAAU;kBACd,cAAA,MAACQ;YAAIR,WAAU;;8BACb,KAACS;oBAAGC,KAAKjB;oBAAYkB,UAAU,CAAC;oBAAGX,WAAU;8BAC1Cb;;8BAEH,KAACN;oBAAQ+B,MAAK;oBAAQC,MAAK;8BACzB,cAAA,KAAC/B;wBAAKgC,MAAK;kCAAM1B;;;8BAEnB,MAACoB;oBAAIR,WAAU;;wBACZV,8BACC,KAACV;4BAAWkB,OAAO;4BAACE,WAAU;sCAC5B,cAAA,KAACjB;gCACCkB,IACEV,cACI,CAAC,sBAAsB,EAAEwB,mBAAmBX,kBAAkB,MAAM,GACpE;0CAEP;;6BAID;wBACHf,aAAaE,4BACZ,KAACX;4BAAWkB,OAAO;4BAACE,WAAU;sCAC5B,cAAA,KAACjB;gCAAKkB,IAAIT;gCAAaU,QAAQ;oCAACC,KAAKZ;gCAAW;0CAAG;;6BAInD;wBACHM;;;;;;AAKX"}
@@ -1 +1 @@
1
- {"version":3,"file":"integration-gallery.stories.d.ts","sourceRoot":"","sources":["../../src/components/integration-gallery.stories.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAO,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAwBrD,KAAK,QAAQ,GACT,OAAO,GACP,mBAAmB,GACnB,SAAS,GACT,mBAAmB,GACnB,iBAAiB,GACjB,cAAc,GACd,YAAY,CAAC;AAEjB,UAAU,4BAA4B;IACpC,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAUD,iBAAS,uBAAuB,CAAC,EAAC,QAAQ,EAAC,EAAE,4BAA4B,+BA0DxE;AAED,QAAA,MAAM,IAAI;;;;;;;;;CAKsC,CAAC;AAEjD,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,UAAU,EAAE,KAAU,CAAC;AAEpC,eAAO,MAAM,gBAAgB,EAAE,KAE9B,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAE9B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAE5B,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,KAElC,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAEvB,CAAC"}
1
+ {"version":3,"file":"integration-gallery.stories.d.ts","sourceRoot":"","sources":["../../src/components/integration-gallery.stories.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAO,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAyBrD,KAAK,QAAQ,GACT,OAAO,GACP,mBAAmB,GACnB,SAAS,GACT,mBAAmB,GACnB,iBAAiB,GACjB,cAAc,GACd,YAAY,CAAC;AAEjB,UAAU,4BAA4B;IACpC,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAWD,iBAAS,uBAAuB,CAAC,EAAC,QAAQ,EAAC,EAAE,4BAA4B,+BA0DxE;AAED,QAAA,MAAM,IAAI;;;;;;;;;CAKsC,CAAC;AAEjD,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,UAAU,EAAE,KAAU,CAAC;AAEpC,eAAO,MAAM,gBAAgB,EAAE,KAE9B,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAE9B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAE5B,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,KAElC,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAEvB,CAAC"}
@@ -13,6 +13,7 @@ const SETUP_PATHS = [
13
13
  '/workspaces/$wid/integrations/github',
14
14
  '/workspaces/$wid/integrations/sentry',
15
15
  '/workspaces/$wid/integrations/linear',
16
+ '/workspaces/$wid/integrations/slack',
16
17
  '/workspaces/$wid/integrations/gitea',
17
18
  '/workspaces/$wid/settings/events'
18
19
  ];
@@ -36,6 +37,13 @@ const PROVIDERS = [
36
37
  'agent_tools'
37
38
  ]
38
39
  },
40
+ {
41
+ provider: 'slack',
42
+ display_name: 'Slack',
43
+ capabilities: [
44
+ 'agent_tools'
45
+ ]
46
+ },
39
47
  {
40
48
  provider: 'gitea',
41
49
  display_name: 'Gitea',
@@ -256,6 +264,26 @@ function connectionsForScenario(scenario) {
256
264
  display_name: 'acme-corp',
257
265
  lifecycle_status: 'active'
258
266
  }),
267
+ connection({
268
+ id: '99999999-9999-4999-8999-999999999999',
269
+ provider: 'slack',
270
+ display_name: 'Slack Acme',
271
+ lifecycle_status: 'active',
272
+ capabilities: [
273
+ 'agent_tools'
274
+ ],
275
+ external_url: 'https://app.slack.com/client/T123'
276
+ }),
277
+ connection({
278
+ id: 'aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa',
279
+ provider: 'slack',
280
+ display_name: 'Slack disabled',
281
+ lifecycle_status: 'disabled',
282
+ capabilities: [
283
+ 'agent_tools'
284
+ ],
285
+ external_url: undefined
286
+ }),
259
287
  connection({
260
288
  id: '88888888-8888-4888-8888-888888888888',
261
289
  provider: 'linear',
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/integration-gallery.stories.tsx"],"sourcesContent":["import type {\n IntegrationConnectionDto,\n IntegrationProviderDto,\n} from '@shipfox/api-integration-core-dto';\nimport {configureApiClient} from '@shipfox/client-api';\nimport {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 {IntegrationGallery} from './integration-gallery.js';\n\nconst WORKSPACE_ID = '11111111-1111-4111-8111-111111111111';\nconst WORKSPACE_PATH = `/workspaces/${WORKSPACE_ID}/settings/integrations`;\nconst SETUP_PATHS = [\n '/workspaces/$wid/integrations/github',\n '/workspaces/$wid/integrations/sentry',\n '/workspaces/$wid/integrations/linear',\n '/workspaces/$wid/integrations/gitea',\n '/workspaces/$wid/settings/events',\n] as const;\n\ntype Scenario =\n | 'mixed'\n | 'empty-connections'\n | 'loading'\n | 'connections-error'\n | 'providers-error'\n | 'no-providers'\n | 'long-names';\n\ninterface IntegrationGalleryStoryProps {\n scenario: Scenario;\n}\n\nconst PROVIDERS: IntegrationProviderDto[] = [\n {provider: 'github', display_name: 'GitHub', capabilities: ['source_control']},\n {provider: 'sentry', display_name: 'Sentry', capabilities: []},\n {provider: 'linear', display_name: 'Linear', capabilities: ['agent_tools']},\n {provider: 'gitea', display_name: 'Gitea', capabilities: ['source_control']},\n {provider: 'webhook', display_name: 'Webhook', capabilities: []},\n];\n\nfunction IntegrationGalleryStory({scenario}: IntegrationGalleryStoryProps) {\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, {\n status: 'authenticated',\n workspaces: [{id: WORKSPACE_ID, name: 'Acme', membershipId: 'membership-1'}],\n });\n return nextStore;\n }, []);\n const router = useMemo(() => {\n const rootRoute = createRootRoute({component: Outlet});\n const workspaceRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: '/workspaces/$wid',\n component: Outlet,\n });\n const galleryRoute = createRoute({\n getParentRoute: () => workspaceRoute,\n path: 'settings/integrations',\n component: () => (\n <div className=\"mx-auto w-full max-w-[760px] bg-background-neutral-background p-24\">\n <IntegrationGallery workspaceId={WORKSPACE_ID} />\n </div>\n ),\n });\n const setupRoutes = SETUP_PATHS.map((path) =>\n createRoute({\n getParentRoute: () => workspaceRoute,\n path: path.replace('/workspaces/$wid/', ''),\n component: () => <div />,\n }),\n );\n\n return createRouter({\n history: createMemoryHistory({initialEntries: [WORKSPACE_PATH]}),\n routeTree: rootRoute.addChildren([\n workspaceRoute.addChildren([galleryRoute, ...setupRoutes]),\n ]),\n });\n }, []);\n\n return (\n <QueryClientProvider client={queryClient}>\n <JotaiProvider store={store}>\n <RouterProvider router={router} />\n <Toaster />\n </JotaiProvider>\n </QueryClientProvider>\n );\n}\n\nconst meta = {\n title: 'Integrations/Gallery',\n component: IntegrationGalleryStory,\n parameters: {layout: 'fullscreen'},\n args: {scenario: 'mixed'},\n} satisfies Meta<typeof IntegrationGalleryStory>;\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const Playground: Story = {};\n\nexport const EmptyConnections: Story = {\n args: {scenario: 'empty-connections'},\n};\n\nexport const Loading: Story = {\n args: {scenario: 'loading'},\n};\n\nexport const ConnectionsError: Story = {\n args: {scenario: 'connections-error'},\n};\n\nexport const ProvidersError: Story = {\n args: {scenario: 'providers-error'},\n};\n\nexport const NoProvidersAvailable: Story = {\n args: {scenario: 'no-providers'},\n};\n\nexport const LongNames: Story = {\n args: {scenario: 'long-names'},\n};\n\nfunction fetchForScenario(scenario: Scenario): typeof fetch {\n return (input, init) => {\n const url = requestUrl(input);\n const method = init?.method ?? 'GET';\n if (scenario === 'loading') return new Promise<Response>(() => undefined);\n if (url.pathname === '/integration-providers') {\n if (scenario === 'providers-error') return Promise.resolve(errorResponse());\n return Promise.resolve(\n jsonResponse({providers: scenario === 'no-providers' ? [] : PROVIDERS}),\n );\n }\n if (url.pathname.startsWith('/integration-connections/') && method === 'PATCH') {\n return Promise.resolve(\n jsonResponse({\n ...connection(),\n id: url.pathname.split('/').at(-1),\n lifecycle_status: 'disabled',\n }),\n );\n }\n if (url.pathname.startsWith('/integration-connections/') && method === 'DELETE') {\n return Promise.resolve(jsonResponse(undefined, {status: 204}));\n }\n if (url.pathname.startsWith('/integrations/webhook/connections/') && method === 'PATCH') {\n return Promise.resolve(\n jsonResponse({\n id: url.pathname.split('/').at(-1),\n workspace_id: WORKSPACE_ID,\n name: 'Stripe production',\n slug: 'stripe-prod',\n lifecycle_status: 'disabled',\n inbound_url: 'https://api.example.test/webhook/77777777-7777-4777-8777-777777777777',\n created_at: '2026-04-12T00:00:00.000Z',\n updated_at: '2026-04-12T00:00:00.000Z',\n }),\n );\n }\n if (url.pathname.startsWith('/integrations/webhook/connections/') && method === 'DELETE') {\n return Promise.resolve(jsonResponse(undefined, {status: 204}));\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 (url.pathname === '/integrations/webhook/connections') {\n return Promise.resolve(\n jsonResponse({\n connections: [\n {\n id: '77777777-7777-4777-8777-777777777777',\n workspace_id: WORKSPACE_ID,\n name: 'Stripe production',\n slug: 'stripe-prod',\n lifecycle_status: 'active',\n inbound_url: 'https://api.example.test/webhook/77777777-7777-4777-8777-777777777777',\n created_at: '2026-04-12T00:00:00.000Z',\n updated_at: '2026-04-12T00:00:00.000Z',\n },\n ],\n }),\n );\n }\n return Promise.resolve(jsonResponse({}, {status: 404}));\n };\n}\n\nfunction connectionsForScenario(scenario: Scenario): IntegrationConnectionDto[] {\n if (scenario === 'empty-connections' || scenario === 'no-providers') return [];\n if (scenario === 'long-names') {\n return [\n connection({\n display_name: 'acme-production-observability-and-source-control-organization',\n lifecycle_status: 'active',\n }),\n connection({\n id: '55555555-5555-4555-8555-555555555555',\n provider: 'sentry',\n display_name: 'sentry-team-with-a-very-long-connected-account-name',\n lifecycle_status: 'error',\n }),\n ];\n }\n return [\n connection({display_name: 'acme-corp', lifecycle_status: 'active'}),\n connection({\n id: '88888888-8888-4888-8888-888888888888',\n provider: 'linear',\n display_name: 'linear-acme',\n lifecycle_status: 'active',\n external_url: 'https://linear.app/acme/settings',\n }),\n connection({\n id: '55555555-5555-4555-8555-555555555555',\n provider: 'linear',\n display_name: 'linear-disabled',\n lifecycle_status: 'disabled',\n external_url: undefined,\n }),\n connection({\n id: '66666666-6666-4666-8666-666666666666',\n provider: 'linear',\n display_name: 'linear-error',\n lifecycle_status: 'error',\n external_url: undefined,\n }),\n connection({\n id: '77777777-7777-4777-8777-777777777777',\n provider: 'webhook',\n external_account_id: 'stripe-prod',\n slug: 'stripe-prod',\n display_name: 'Stripe production',\n capabilities: [],\n lifecycle_status: 'active',\n external_url: undefined,\n created_at: '2026-04-12T00:00:00.000Z',\n updated_at: '2026-04-12T00:00:00.000Z',\n }),\n ];\n}\n\nfunction connection(overrides: Partial<IntegrationConnectionDto> = {}): IntegrationConnectionDto {\n return {\n id: '44444444-4444-4444-8444-444444444444',\n workspace_id: WORKSPACE_ID,\n provider: 'github',\n external_account_id: 'installation-1',\n slug: 'github_acme_corp',\n display_name: 'acme-corp',\n lifecycle_status: 'active',\n capabilities: ['source_control'],\n external_url: 'https://github.com/organizations/acme-corp/settings/installations/1',\n created_at: '2026-03-12T00:00:00.000Z',\n updated_at: '2026-03-12T00:00:00.000Z',\n ...overrides,\n };\n}\n\nfunction requestUrl(input: RequestInfo | URL): URL {\n if (typeof input === 'string') return new URL(input);\n if (input instanceof URL) return input;\n return new URL(input.url);\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, statusText: 'Server error'});\n}\n"],"names":["configureApiClient","authStateAtom","Toaster","QueryClient","QueryClientProvider","createMemoryHistory","createRootRoute","createRoute","createRouter","Outlet","RouterProvider","createStore","Provider","JotaiProvider","useMemo","IntegrationGallery","WORKSPACE_ID","WORKSPACE_PATH","SETUP_PATHS","PROVIDERS","provider","display_name","capabilities","IntegrationGalleryStory","scenario","baseUrl","fetchImpl","fetchForScenario","queryClient","defaultOptions","queries","retry","store","nextStore","set","status","workspaces","id","name","membershipId","router","rootRoute","component","workspaceRoute","getParentRoute","path","galleryRoute","div","className","workspaceId","setupRoutes","map","replace","history","initialEntries","routeTree","addChildren","client","meta","title","parameters","layout","args","Playground","EmptyConnections","Loading","ConnectionsError","ProvidersError","NoProvidersAvailable","LongNames","input","init","url","requestUrl","method","Promise","undefined","pathname","resolve","errorResponse","jsonResponse","providers","startsWith","connection","split","at","lifecycle_status","workspace_id","slug","inbound_url","created_at","updated_at","connections","connectionsForScenario","external_url","external_account_id","overrides","URL","body","Response","JSON","stringify","headers","code","statusText"],"mappings":";AAIA,SAAQA,kBAAkB,QAAO,sBAAsB;AACvD,SAAQC,aAAa,QAAO,uBAAuB;AACnD,SAAQC,OAAO,QAAO,0BAA0B;AAEhD,SAAQC,WAAW,EAAEC,mBAAmB,QAAO,wBAAwB;AACvE,SACEC,mBAAmB,EACnBC,eAAe,EACfC,WAAW,EACXC,YAAY,EACZC,MAAM,EACNC,cAAc,QACT,yBAAyB;AAChC,SAAQC,WAAW,EAAEC,YAAYC,aAAa,QAAO,QAAQ;AAC7D,SAAQC,OAAO,QAAO,QAAQ;AAC9B,SAAQC,kBAAkB,QAAO,2BAA2B;AAE5D,MAAMC,eAAe;AACrB,MAAMC,iBAAiB,CAAC,YAAY,EAAED,aAAa,sBAAsB,CAAC;AAC1E,MAAME,cAAc;IAClB;IACA;IACA;IACA;IACA;CACD;AAeD,MAAMC,YAAsC;IAC1C;QAACC,UAAU;QAAUC,cAAc;QAAUC,cAAc;YAAC;SAAiB;IAAA;IAC7E;QAACF,UAAU;QAAUC,cAAc;QAAUC,cAAc,EAAE;IAAA;IAC7D;QAACF,UAAU;QAAUC,cAAc;QAAUC,cAAc;YAAC;SAAc;IAAA;IAC1E;QAACF,UAAU;QAASC,cAAc;QAASC,cAAc;YAAC;SAAiB;IAAA;IAC3E;QAACF,UAAU;QAAWC,cAAc;QAAWC,cAAc,EAAE;IAAA;CAChE;AAED,SAASC,wBAAwB,EAACC,QAAQ,EAA+B;IACvExB,mBAAmB;QACjByB,SAAS;QACTC,WAAWC,iBAAiBH;IAC9B;IAEA,MAAMI,cAAcd,QAClB,IAAM,IAAIX,YAAY;YAAC0B,gBAAgB;gBAACC,SAAS;oBAACC,OAAO;gBAAK;YAAC;QAAC,IAChE,EAAE;IAEJ,MAAMC,QAAQlB,QAAQ;QACpB,MAAMmB,YAAYtB;QAClBsB,UAAUC,GAAG,CAACjC,eAAe;YAC3BkC,QAAQ;YACRC,YAAY;gBAAC;oBAACC,IAAIrB;oBAAcsB,MAAM;oBAAQC,cAAc;gBAAc;aAAE;QAC9E;QACA,OAAON;IACT,GAAG,EAAE;IACL,MAAMO,SAAS1B,QAAQ;QACrB,MAAM2B,YAAYnC,gBAAgB;YAACoC,WAAWjC;QAAM;QACpD,MAAMkC,iBAAiBpC,YAAY;YACjCqC,gBAAgB,IAAMH;YACtBI,MAAM;YACNH,WAAWjC;QACb;QACA,MAAMqC,eAAevC,YAAY;YAC/BqC,gBAAgB,IAAMD;YACtBE,MAAM;YACNH,WAAW,kBACT,KAACK;oBAAIC,WAAU;8BACb,cAAA,KAACjC;wBAAmBkC,aAAajC;;;QAGvC;QACA,MAAMkC,cAAchC,YAAYiC,GAAG,CAAC,CAACN,OACnCtC,YAAY;gBACVqC,gBAAgB,IAAMD;gBACtBE,MAAMA,KAAKO,OAAO,CAAC,qBAAqB;gBACxCV,WAAW,kBAAM,KAACK;YACpB;QAGF,OAAOvC,aAAa;YAClB6C,SAAShD,oBAAoB;gBAACiD,gBAAgB;oBAACrC;iBAAe;YAAA;YAC9DsC,WAAWd,UAAUe,WAAW,CAAC;gBAC/Bb,eAAea,WAAW,CAAC;oBAACV;uBAAiBI;iBAAY;aAC1D;QACH;IACF,GAAG,EAAE;IAEL,qBACE,KAAC9C;QAAoBqD,QAAQ7B;kBAC3B,cAAA,MAACf;YAAcmB,OAAOA;;8BACpB,KAACtB;oBAAe8B,QAAQA;;8BACxB,KAACtC;;;;AAIT;AAEA,MAAMwD,OAAO;IACXC,OAAO;IACPjB,WAAWnB;IACXqC,YAAY;QAACC,QAAQ;IAAY;IACjCC,MAAM;QAACtC,UAAU;IAAO;AAC1B;AAEA,eAAekC,KAAK;AAGpB,OAAO,MAAMK,aAAoB,CAAC,EAAE;AAEpC,OAAO,MAAMC,mBAA0B;IACrCF,MAAM;QAACtC,UAAU;IAAmB;AACtC,EAAE;AAEF,OAAO,MAAMyC,UAAiB;IAC5BH,MAAM;QAACtC,UAAU;IAAS;AAC5B,EAAE;AAEF,OAAO,MAAM0C,mBAA0B;IACrCJ,MAAM;QAACtC,UAAU;IAAmB;AACtC,EAAE;AAEF,OAAO,MAAM2C,iBAAwB;IACnCL,MAAM;QAACtC,UAAU;IAAiB;AACpC,EAAE;AAEF,OAAO,MAAM4C,uBAA8B;IACzCN,MAAM;QAACtC,UAAU;IAAc;AACjC,EAAE;AAEF,OAAO,MAAM6C,YAAmB;IAC9BP,MAAM;QAACtC,UAAU;IAAY;AAC/B,EAAE;AAEF,SAASG,iBAAiBH,QAAkB;IAC1C,OAAO,CAAC8C,OAAOC;QACb,MAAMC,MAAMC,WAAWH;QACvB,MAAMI,SAASH,MAAMG,UAAU;QAC/B,IAAIlD,aAAa,WAAW,OAAO,IAAImD,QAAkB,IAAMC;QAC/D,IAAIJ,IAAIK,QAAQ,KAAK,0BAA0B;YAC7C,IAAIrD,aAAa,mBAAmB,OAAOmD,QAAQG,OAAO,CAACC;YAC3D,OAAOJ,QAAQG,OAAO,CACpBE,aAAa;gBAACC,WAAWzD,aAAa,iBAAiB,EAAE,GAAGL;YAAS;QAEzE;QACA,IAAIqD,IAAIK,QAAQ,CAACK,UAAU,CAAC,gCAAgCR,WAAW,SAAS;YAC9E,OAAOC,QAAQG,OAAO,CACpBE,aAAa;gBACX,GAAGG,YAAY;gBACf9C,IAAImC,IAAIK,QAAQ,CAACO,KAAK,CAAC,KAAKC,EAAE,CAAC,CAAC;gBAChCC,kBAAkB;YACpB;QAEJ;QACA,IAAId,IAAIK,QAAQ,CAACK,UAAU,CAAC,gCAAgCR,WAAW,UAAU;YAC/E,OAAOC,QAAQG,OAAO,CAACE,aAAaJ,WAAW;gBAACzC,QAAQ;YAAG;QAC7D;QACA,IAAIqC,IAAIK,QAAQ,CAACK,UAAU,CAAC,yCAAyCR,WAAW,SAAS;YACvF,OAAOC,QAAQG,OAAO,CACpBE,aAAa;gBACX3C,IAAImC,IAAIK,QAAQ,CAACO,KAAK,CAAC,KAAKC,EAAE,CAAC,CAAC;gBAChCE,cAAcvE;gBACdsB,MAAM;gBACNkD,MAAM;gBACNF,kBAAkB;gBAClBG,aAAa;gBACbC,YAAY;gBACZC,YAAY;YACd;QAEJ;QACA,IAAInB,IAAIK,QAAQ,CAACK,UAAU,CAAC,yCAAyCR,WAAW,UAAU;YACxF,OAAOC,QAAQG,OAAO,CAACE,aAAaJ,WAAW;gBAACzC,QAAQ;YAAG;QAC7D;QACA,IAAIqC,IAAIK,QAAQ,KAAK,4BAA4B;YAC/C,IAAIrD,aAAa,qBAAqB,OAAOmD,QAAQG,OAAO,CAACC;YAC7D,OAAOJ,QAAQG,OAAO,CAACE,aAAa;gBAACY,aAAaC,uBAAuBrE;YAAS;QACpF;QACA,IAAIgD,IAAIK,QAAQ,KAAK,qCAAqC;YACxD,OAAOF,QAAQG,OAAO,CACpBE,aAAa;gBACXY,aAAa;oBACX;wBACEvD,IAAI;wBACJkD,cAAcvE;wBACdsB,MAAM;wBACNkD,MAAM;wBACNF,kBAAkB;wBAClBG,aAAa;wBACbC,YAAY;wBACZC,YAAY;oBACd;iBACD;YACH;QAEJ;QACA,OAAOhB,QAAQG,OAAO,CAACE,aAAa,CAAC,GAAG;YAAC7C,QAAQ;QAAG;IACtD;AACF;AAEA,SAAS0D,uBAAuBrE,QAAkB;IAChD,IAAIA,aAAa,uBAAuBA,aAAa,gBAAgB,OAAO,EAAE;IAC9E,IAAIA,aAAa,cAAc;QAC7B,OAAO;YACL2D,WAAW;gBACT9D,cAAc;gBACdiE,kBAAkB;YACpB;YACAH,WAAW;gBACT9C,IAAI;gBACJjB,UAAU;gBACVC,cAAc;gBACdiE,kBAAkB;YACpB;SACD;IACH;IACA,OAAO;QACLH,WAAW;YAAC9D,cAAc;YAAaiE,kBAAkB;QAAQ;QACjEH,WAAW;YACT9C,IAAI;YACJjB,UAAU;YACVC,cAAc;YACdiE,kBAAkB;YAClBQ,cAAc;QAChB;QACAX,WAAW;YACT9C,IAAI;YACJjB,UAAU;YACVC,cAAc;YACdiE,kBAAkB;YAClBQ,cAAclB;QAChB;QACAO,WAAW;YACT9C,IAAI;YACJjB,UAAU;YACVC,cAAc;YACdiE,kBAAkB;YAClBQ,cAAclB;QAChB;QACAO,WAAW;YACT9C,IAAI;YACJjB,UAAU;YACV2E,qBAAqB;YACrBP,MAAM;YACNnE,cAAc;YACdC,cAAc,EAAE;YAChBgE,kBAAkB;YAClBQ,cAAclB;YACdc,YAAY;YACZC,YAAY;QACd;KACD;AACH;AAEA,SAASR,WAAWa,YAA+C,CAAC,CAAC;IACnE,OAAO;QACL3D,IAAI;QACJkD,cAAcvE;QACdI,UAAU;QACV2E,qBAAqB;QACrBP,MAAM;QACNnE,cAAc;QACdiE,kBAAkB;QAClBhE,cAAc;YAAC;SAAiB;QAChCwE,cAAc;QACdJ,YAAY;QACZC,YAAY;QACZ,GAAGK,SAAS;IACd;AACF;AAEA,SAASvB,WAAWH,KAAwB;IAC1C,IAAI,OAAOA,UAAU,UAAU,OAAO,IAAI2B,IAAI3B;IAC9C,IAAIA,iBAAiB2B,KAAK,OAAO3B;IACjC,OAAO,IAAI2B,IAAI3B,MAAME,GAAG;AAC1B;AAEA,SAASQ,aAAakB,IAAa,EAAE3B,OAAqB,CAAC,CAAC;IAC1D,OAAO,IAAI4B,SAASC,KAAKC,SAAS,CAACH,OAAO;QACxC/D,QAAQ;QACRmE,SAAS;YAAC,gBAAgB;QAAkB;QAC5C,GAAG/B,IAAI;IACT;AACF;AAEA,SAASQ;IACP,OAAOC,aAAa;QAACuB,MAAM;IAAc,GAAG;QAACpE,QAAQ;QAAKqE,YAAY;IAAc;AACtF"}
1
+ {"version":3,"sources":["../../src/components/integration-gallery.stories.tsx"],"sourcesContent":["import type {\n IntegrationConnectionDto,\n IntegrationProviderDto,\n} from '@shipfox/api-integration-core-dto';\nimport {configureApiClient} from '@shipfox/client-api';\nimport {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 {IntegrationGallery} from './integration-gallery.js';\n\nconst WORKSPACE_ID = '11111111-1111-4111-8111-111111111111';\nconst WORKSPACE_PATH = `/workspaces/${WORKSPACE_ID}/settings/integrations`;\nconst SETUP_PATHS = [\n '/workspaces/$wid/integrations/github',\n '/workspaces/$wid/integrations/sentry',\n '/workspaces/$wid/integrations/linear',\n '/workspaces/$wid/integrations/slack',\n '/workspaces/$wid/integrations/gitea',\n '/workspaces/$wid/settings/events',\n] as const;\n\ntype Scenario =\n | 'mixed'\n | 'empty-connections'\n | 'loading'\n | 'connections-error'\n | 'providers-error'\n | 'no-providers'\n | 'long-names';\n\ninterface IntegrationGalleryStoryProps {\n scenario: Scenario;\n}\n\nconst PROVIDERS: IntegrationProviderDto[] = [\n {provider: 'github', display_name: 'GitHub', capabilities: ['source_control']},\n {provider: 'sentry', display_name: 'Sentry', capabilities: []},\n {provider: 'linear', display_name: 'Linear', capabilities: ['agent_tools']},\n {provider: 'slack', display_name: 'Slack', capabilities: ['agent_tools']},\n {provider: 'gitea', display_name: 'Gitea', capabilities: ['source_control']},\n {provider: 'webhook', display_name: 'Webhook', capabilities: []},\n];\n\nfunction IntegrationGalleryStory({scenario}: IntegrationGalleryStoryProps) {\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, {\n status: 'authenticated',\n workspaces: [{id: WORKSPACE_ID, name: 'Acme', membershipId: 'membership-1'}],\n });\n return nextStore;\n }, []);\n const router = useMemo(() => {\n const rootRoute = createRootRoute({component: Outlet});\n const workspaceRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: '/workspaces/$wid',\n component: Outlet,\n });\n const galleryRoute = createRoute({\n getParentRoute: () => workspaceRoute,\n path: 'settings/integrations',\n component: () => (\n <div className=\"mx-auto w-full max-w-[760px] bg-background-neutral-background p-24\">\n <IntegrationGallery workspaceId={WORKSPACE_ID} />\n </div>\n ),\n });\n const setupRoutes = SETUP_PATHS.map((path) =>\n createRoute({\n getParentRoute: () => workspaceRoute,\n path: path.replace('/workspaces/$wid/', ''),\n component: () => <div />,\n }),\n );\n\n return createRouter({\n history: createMemoryHistory({initialEntries: [WORKSPACE_PATH]}),\n routeTree: rootRoute.addChildren([\n workspaceRoute.addChildren([galleryRoute, ...setupRoutes]),\n ]),\n });\n }, []);\n\n return (\n <QueryClientProvider client={queryClient}>\n <JotaiProvider store={store}>\n <RouterProvider router={router} />\n <Toaster />\n </JotaiProvider>\n </QueryClientProvider>\n );\n}\n\nconst meta = {\n title: 'Integrations/Gallery',\n component: IntegrationGalleryStory,\n parameters: {layout: 'fullscreen'},\n args: {scenario: 'mixed'},\n} satisfies Meta<typeof IntegrationGalleryStory>;\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const Playground: Story = {};\n\nexport const EmptyConnections: Story = {\n args: {scenario: 'empty-connections'},\n};\n\nexport const Loading: Story = {\n args: {scenario: 'loading'},\n};\n\nexport const ConnectionsError: Story = {\n args: {scenario: 'connections-error'},\n};\n\nexport const ProvidersError: Story = {\n args: {scenario: 'providers-error'},\n};\n\nexport const NoProvidersAvailable: Story = {\n args: {scenario: 'no-providers'},\n};\n\nexport const LongNames: Story = {\n args: {scenario: 'long-names'},\n};\n\nfunction fetchForScenario(scenario: Scenario): typeof fetch {\n return (input, init) => {\n const url = requestUrl(input);\n const method = init?.method ?? 'GET';\n if (scenario === 'loading') return new Promise<Response>(() => undefined);\n if (url.pathname === '/integration-providers') {\n if (scenario === 'providers-error') return Promise.resolve(errorResponse());\n return Promise.resolve(\n jsonResponse({providers: scenario === 'no-providers' ? [] : PROVIDERS}),\n );\n }\n if (url.pathname.startsWith('/integration-connections/') && method === 'PATCH') {\n return Promise.resolve(\n jsonResponse({\n ...connection(),\n id: url.pathname.split('/').at(-1),\n lifecycle_status: 'disabled',\n }),\n );\n }\n if (url.pathname.startsWith('/integration-connections/') && method === 'DELETE') {\n return Promise.resolve(jsonResponse(undefined, {status: 204}));\n }\n if (url.pathname.startsWith('/integrations/webhook/connections/') && method === 'PATCH') {\n return Promise.resolve(\n jsonResponse({\n id: url.pathname.split('/').at(-1),\n workspace_id: WORKSPACE_ID,\n name: 'Stripe production',\n slug: 'stripe-prod',\n lifecycle_status: 'disabled',\n inbound_url: 'https://api.example.test/webhook/77777777-7777-4777-8777-777777777777',\n created_at: '2026-04-12T00:00:00.000Z',\n updated_at: '2026-04-12T00:00:00.000Z',\n }),\n );\n }\n if (url.pathname.startsWith('/integrations/webhook/connections/') && method === 'DELETE') {\n return Promise.resolve(jsonResponse(undefined, {status: 204}));\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 (url.pathname === '/integrations/webhook/connections') {\n return Promise.resolve(\n jsonResponse({\n connections: [\n {\n id: '77777777-7777-4777-8777-777777777777',\n workspace_id: WORKSPACE_ID,\n name: 'Stripe production',\n slug: 'stripe-prod',\n lifecycle_status: 'active',\n inbound_url: 'https://api.example.test/webhook/77777777-7777-4777-8777-777777777777',\n created_at: '2026-04-12T00:00:00.000Z',\n updated_at: '2026-04-12T00:00:00.000Z',\n },\n ],\n }),\n );\n }\n return Promise.resolve(jsonResponse({}, {status: 404}));\n };\n}\n\nfunction connectionsForScenario(scenario: Scenario): IntegrationConnectionDto[] {\n if (scenario === 'empty-connections' || scenario === 'no-providers') return [];\n if (scenario === 'long-names') {\n return [\n connection({\n display_name: 'acme-production-observability-and-source-control-organization',\n lifecycle_status: 'active',\n }),\n connection({\n id: '55555555-5555-4555-8555-555555555555',\n provider: 'sentry',\n display_name: 'sentry-team-with-a-very-long-connected-account-name',\n lifecycle_status: 'error',\n }),\n ];\n }\n return [\n connection({display_name: 'acme-corp', lifecycle_status: 'active'}),\n connection({\n id: '99999999-9999-4999-8999-999999999999',\n provider: 'slack',\n display_name: 'Slack Acme',\n lifecycle_status: 'active',\n capabilities: ['agent_tools'],\n external_url: 'https://app.slack.com/client/T123',\n }),\n connection({\n id: 'aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa',\n provider: 'slack',\n display_name: 'Slack disabled',\n lifecycle_status: 'disabled',\n capabilities: ['agent_tools'],\n external_url: undefined,\n }),\n connection({\n id: '88888888-8888-4888-8888-888888888888',\n provider: 'linear',\n display_name: 'linear-acme',\n lifecycle_status: 'active',\n external_url: 'https://linear.app/acme/settings',\n }),\n connection({\n id: '55555555-5555-4555-8555-555555555555',\n provider: 'linear',\n display_name: 'linear-disabled',\n lifecycle_status: 'disabled',\n external_url: undefined,\n }),\n connection({\n id: '66666666-6666-4666-8666-666666666666',\n provider: 'linear',\n display_name: 'linear-error',\n lifecycle_status: 'error',\n external_url: undefined,\n }),\n connection({\n id: '77777777-7777-4777-8777-777777777777',\n provider: 'webhook',\n external_account_id: 'stripe-prod',\n slug: 'stripe-prod',\n display_name: 'Stripe production',\n capabilities: [],\n lifecycle_status: 'active',\n external_url: undefined,\n created_at: '2026-04-12T00:00:00.000Z',\n updated_at: '2026-04-12T00:00:00.000Z',\n }),\n ];\n}\n\nfunction connection(overrides: Partial<IntegrationConnectionDto> = {}): IntegrationConnectionDto {\n return {\n id: '44444444-4444-4444-8444-444444444444',\n workspace_id: WORKSPACE_ID,\n provider: 'github',\n external_account_id: 'installation-1',\n slug: 'github_acme_corp',\n display_name: 'acme-corp',\n lifecycle_status: 'active',\n capabilities: ['source_control'],\n external_url: 'https://github.com/organizations/acme-corp/settings/installations/1',\n created_at: '2026-03-12T00:00:00.000Z',\n updated_at: '2026-03-12T00:00:00.000Z',\n ...overrides,\n };\n}\n\nfunction requestUrl(input: RequestInfo | URL): URL {\n if (typeof input === 'string') return new URL(input);\n if (input instanceof URL) return input;\n return new URL(input.url);\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, statusText: 'Server error'});\n}\n"],"names":["configureApiClient","authStateAtom","Toaster","QueryClient","QueryClientProvider","createMemoryHistory","createRootRoute","createRoute","createRouter","Outlet","RouterProvider","createStore","Provider","JotaiProvider","useMemo","IntegrationGallery","WORKSPACE_ID","WORKSPACE_PATH","SETUP_PATHS","PROVIDERS","provider","display_name","capabilities","IntegrationGalleryStory","scenario","baseUrl","fetchImpl","fetchForScenario","queryClient","defaultOptions","queries","retry","store","nextStore","set","status","workspaces","id","name","membershipId","router","rootRoute","component","workspaceRoute","getParentRoute","path","galleryRoute","div","className","workspaceId","setupRoutes","map","replace","history","initialEntries","routeTree","addChildren","client","meta","title","parameters","layout","args","Playground","EmptyConnections","Loading","ConnectionsError","ProvidersError","NoProvidersAvailable","LongNames","input","init","url","requestUrl","method","Promise","undefined","pathname","resolve","errorResponse","jsonResponse","providers","startsWith","connection","split","at","lifecycle_status","workspace_id","slug","inbound_url","created_at","updated_at","connections","connectionsForScenario","external_url","external_account_id","overrides","URL","body","Response","JSON","stringify","headers","code","statusText"],"mappings":"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"}
@@ -5,6 +5,7 @@ interface RedirectInstallPageProps {
5
5
  install_url: string;
6
6
  }>;
7
7
  errorFallbackMessage: string;
8
+ loadingLabel?: string;
8
9
  /**
9
10
  * Runs before leaving the app (e.g. to persist the workspace id for a
10
11
  * state-less provider callback). Must not throw — a failed side effect
@@ -14,6 +15,6 @@ interface RedirectInstallPageProps {
14
15
  /** Injectable for tests: jsdom's window.location cannot be stubbed. */
15
16
  assignLocation?: (url: string) => void;
16
17
  }
17
- export declare function RedirectInstallPage({ installRequest, errorFallbackMessage, beforeRedirect, assignLocation, }: RedirectInstallPageProps): import("react").JSX.Element;
18
+ export declare function RedirectInstallPage({ installRequest, errorFallbackMessage, loadingLabel, beforeRedirect, assignLocation, }: RedirectInstallPageProps): import("react").JSX.Element;
18
19
  export {};
19
20
  //# sourceMappingURL=redirect-install-page.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"redirect-install-page.d.ts","sourceRoot":"","sources":["../../src/components/redirect-install-page.tsx"],"names":[],"mappings":"AASA,UAAU,wBAAwB;IAChC,cAAc,EAAE,CAAC,IAAI,EAAE;QAAC,YAAY,EAAE,MAAM,CAAA;KAAC,KAAK,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAC,CAAC,CAAC;IACjF,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,uEAAuE;IACvE,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,wBAAgB,mBAAmB,CAAC,EAClC,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,cAAqD,GACtD,EAAE,wBAAwB,+BAwC1B"}
1
+ {"version":3,"file":"redirect-install-page.d.ts","sourceRoot":"","sources":["../../src/components/redirect-install-page.tsx"],"names":[],"mappings":"AASA,UAAU,wBAAwB;IAChC,cAAc,EAAE,CAAC,IAAI,EAAE;QAAC,YAAY,EAAE,MAAM,CAAA;KAAC,KAAK,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAC,CAAC,CAAC;IACjF,oBAAoB,EAAE,MAAM,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,uEAAuE;IACvE,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,wBAAgB,mBAAmB,CAAC,EAClC,cAAc,EACd,oBAAoB,EACpB,YAAsC,EACtC,cAAc,EACd,cAAqD,GACtD,EAAE,wBAAwB,+BAwC1B"}
@@ -7,7 +7,7 @@ import { FullPageLoader } from '@shipfox/react-ui/loader';
7
7
  import { Text } from '@shipfox/react-ui/typography';
8
8
  import { Link } from '@tanstack/react-router';
9
9
  import { useEffect, useRef, useState } from 'react';
10
- export function RedirectInstallPage({ installRequest, errorFallbackMessage, beforeRedirect, assignLocation = (url)=>window.location.assign(url) }) {
10
+ export function RedirectInstallPage({ installRequest, errorFallbackMessage, loadingLabel = 'Starting installation', beforeRedirect, assignLocation = (url)=>window.location.assign(url) }) {
11
11
  const workspace = useActiveWorkspace();
12
12
  const startedRef = useRef(false);
13
13
  const [errorMessage, setErrorMessage] = useState();
@@ -62,7 +62,9 @@ export function RedirectInstallPage({ installRequest, errorFallbackMessage, befo
62
62
  ]
63
63
  });
64
64
  }
65
- return /*#__PURE__*/ _jsx(FullPageLoader, {});
65
+ return /*#__PURE__*/ _jsx(FullPageLoader, {
66
+ "aria-label": loadingLabel
67
+ });
66
68
  }
67
69
 
68
70
  //# sourceMappingURL=redirect-install-page.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/redirect-install-page.tsx"],"sourcesContent":["import {ApiError} from '@shipfox/client-api';\nimport {useActiveWorkspace} from '@shipfox/client-auth';\nimport {ButtonLink} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {FullPageLoader} from '@shipfox/react-ui/loader';\nimport {Text} from '@shipfox/react-ui/typography';\nimport {Link} from '@tanstack/react-router';\nimport {useEffect, useRef, useState} from 'react';\n\ninterface RedirectInstallPageProps {\n installRequest: (body: {workspace_id: string}) => Promise<{install_url: string}>;\n errorFallbackMessage: string;\n /**\n * Runs before leaving the app (e.g. to persist the workspace id for a\n * state-less provider callback). Must not throw — a failed side effect\n * should never block the redirect.\n */\n beforeRedirect?: (workspaceId: string) => void;\n /** Injectable for tests: jsdom's window.location cannot be stubbed. */\n assignLocation?: (url: string) => void;\n}\n\nexport function RedirectInstallPage({\n installRequest,\n errorFallbackMessage,\n beforeRedirect,\n assignLocation = (url) => window.location.assign(url),\n}: RedirectInstallPageProps) {\n const workspace = useActiveWorkspace();\n const startedRef = useRef(false);\n const [errorMessage, setErrorMessage] = useState<string | undefined>();\n\n useEffect(() => {\n if (startedRef.current) return;\n startedRef.current = true;\n // The side effect is best-effort persistence; a throw here must never\n // block the install redirect, so swallow it and continue.\n try {\n beforeRedirect?.(workspace.id);\n } catch {\n // ignore\n }\n installRequest({workspace_id: workspace.id})\n .then((response) => {\n assignLocation(response.install_url);\n })\n .catch((error: unknown) => {\n setErrorMessage(error instanceof ApiError ? error.message : errorFallbackMessage);\n });\n }, [workspace, installRequest, beforeRedirect, errorFallbackMessage, assignLocation]);\n\n if (errorMessage) {\n return (\n <div className=\"mx-auto flex w-full max-w-[480px] flex-col gap-16\">\n <Callout role=\"alert\" type=\"error\">\n <Text size=\"sm\">{errorMessage}</Text>\n </Callout>\n <ButtonLink asChild variant=\"muted\" className=\"w-fit\">\n <Link to=\"/workspaces/$wid/integrations\" params={{wid: workspace.id}}>\n Back to integrations\n </Link>\n </ButtonLink>\n </div>\n );\n }\n\n return <FullPageLoader />;\n}\n"],"names":["ApiError","useActiveWorkspace","ButtonLink","Callout","FullPageLoader","Text","Link","useEffect","useRef","useState","RedirectInstallPage","installRequest","errorFallbackMessage","beforeRedirect","assignLocation","url","window","location","assign","workspace","startedRef","errorMessage","setErrorMessage","current","id","workspace_id","then","response","install_url","catch","error","message","div","className","role","type","size","asChild","variant","to","params","wid"],"mappings":";AAAA,SAAQA,QAAQ,QAAO,sBAAsB;AAC7C,SAAQC,kBAAkB,QAAO,uBAAuB;AACxD,SAAQC,UAAU,QAAO,2BAA2B;AACpD,SAAQC,OAAO,QAAO,4BAA4B;AAClD,SAAQC,cAAc,QAAO,2BAA2B;AACxD,SAAQC,IAAI,QAAO,+BAA+B;AAClD,SAAQC,IAAI,QAAO,yBAAyB;AAC5C,SAAQC,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAO,QAAQ;AAelD,OAAO,SAASC,oBAAoB,EAClCC,cAAc,EACdC,oBAAoB,EACpBC,cAAc,EACdC,iBAAiB,CAACC,MAAQC,OAAOC,QAAQ,CAACC,MAAM,CAACH,IAAI,EAC5B;IACzB,MAAMI,YAAYlB;IAClB,MAAMmB,aAAaZ,OAAO;IAC1B,MAAM,CAACa,cAAcC,gBAAgB,GAAGb;IAExCF,UAAU;QACR,IAAIa,WAAWG,OAAO,EAAE;QACxBH,WAAWG,OAAO,GAAG;QACrB,sEAAsE;QACtE,0DAA0D;QAC1D,IAAI;YACFV,iBAAiBM,UAAUK,EAAE;QAC/B,EAAE,OAAM;QACN,SAAS;QACX;QACAb,eAAe;YAACc,cAAcN,UAAUK,EAAE;QAAA,GACvCE,IAAI,CAAC,CAACC;YACLb,eAAea,SAASC,WAAW;QACrC,GACCC,KAAK,CAAC,CAACC;YACNR,gBAAgBQ,iBAAiB9B,WAAW8B,MAAMC,OAAO,GAAGnB;QAC9D;IACJ,GAAG;QAACO;QAAWR;QAAgBE;QAAgBD;QAAsBE;KAAe;IAEpF,IAAIO,cAAc;QAChB,qBACE,MAACW;YAAIC,WAAU;;8BACb,KAAC9B;oBAAQ+B,MAAK;oBAAQC,MAAK;8BACzB,cAAA,KAAC9B;wBAAK+B,MAAK;kCAAMf;;;8BAEnB,KAACnB;oBAAWmC,OAAO;oBAACC,SAAQ;oBAAQL,WAAU;8BAC5C,cAAA,KAAC3B;wBAAKiC,IAAG;wBAAgCC,QAAQ;4BAACC,KAAKtB,UAAUK,EAAE;wBAAA;kCAAG;;;;;IAM9E;IAEA,qBAAO,KAACpB;AACV"}
1
+ {"version":3,"sources":["../../src/components/redirect-install-page.tsx"],"sourcesContent":["import {ApiError} from '@shipfox/client-api';\nimport {useActiveWorkspace} from '@shipfox/client-auth';\nimport {ButtonLink} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {FullPageLoader} from '@shipfox/react-ui/loader';\nimport {Text} from '@shipfox/react-ui/typography';\nimport {Link} from '@tanstack/react-router';\nimport {useEffect, useRef, useState} from 'react';\n\ninterface RedirectInstallPageProps {\n installRequest: (body: {workspace_id: string}) => Promise<{install_url: string}>;\n errorFallbackMessage: string;\n loadingLabel?: string;\n /**\n * Runs before leaving the app (e.g. to persist the workspace id for a\n * state-less provider callback). Must not throw — a failed side effect\n * should never block the redirect.\n */\n beforeRedirect?: (workspaceId: string) => void;\n /** Injectable for tests: jsdom's window.location cannot be stubbed. */\n assignLocation?: (url: string) => void;\n}\n\nexport function RedirectInstallPage({\n installRequest,\n errorFallbackMessage,\n loadingLabel = 'Starting installation',\n beforeRedirect,\n assignLocation = (url) => window.location.assign(url),\n}: RedirectInstallPageProps) {\n const workspace = useActiveWorkspace();\n const startedRef = useRef(false);\n const [errorMessage, setErrorMessage] = useState<string | undefined>();\n\n useEffect(() => {\n if (startedRef.current) return;\n startedRef.current = true;\n // The side effect is best-effort persistence; a throw here must never\n // block the install redirect, so swallow it and continue.\n try {\n beforeRedirect?.(workspace.id);\n } catch {\n // ignore\n }\n installRequest({workspace_id: workspace.id})\n .then((response) => {\n assignLocation(response.install_url);\n })\n .catch((error: unknown) => {\n setErrorMessage(error instanceof ApiError ? error.message : errorFallbackMessage);\n });\n }, [workspace, installRequest, beforeRedirect, errorFallbackMessage, assignLocation]);\n\n if (errorMessage) {\n return (\n <div className=\"mx-auto flex w-full max-w-[480px] flex-col gap-16\">\n <Callout role=\"alert\" type=\"error\">\n <Text size=\"sm\">{errorMessage}</Text>\n </Callout>\n <ButtonLink asChild variant=\"muted\" className=\"w-fit\">\n <Link to=\"/workspaces/$wid/integrations\" params={{wid: workspace.id}}>\n Back to integrations\n </Link>\n </ButtonLink>\n </div>\n );\n }\n\n return <FullPageLoader aria-label={loadingLabel} />;\n}\n"],"names":["ApiError","useActiveWorkspace","ButtonLink","Callout","FullPageLoader","Text","Link","useEffect","useRef","useState","RedirectInstallPage","installRequest","errorFallbackMessage","loadingLabel","beforeRedirect","assignLocation","url","window","location","assign","workspace","startedRef","errorMessage","setErrorMessage","current","id","workspace_id","then","response","install_url","catch","error","message","div","className","role","type","size","asChild","variant","to","params","wid","aria-label"],"mappings":";AAAA,SAAQA,QAAQ,QAAO,sBAAsB;AAC7C,SAAQC,kBAAkB,QAAO,uBAAuB;AACxD,SAAQC,UAAU,QAAO,2BAA2B;AACpD,SAAQC,OAAO,QAAO,4BAA4B;AAClD,SAAQC,cAAc,QAAO,2BAA2B;AACxD,SAAQC,IAAI,QAAO,+BAA+B;AAClD,SAAQC,IAAI,QAAO,yBAAyB;AAC5C,SAAQC,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAO,QAAQ;AAgBlD,OAAO,SAASC,oBAAoB,EAClCC,cAAc,EACdC,oBAAoB,EACpBC,eAAe,uBAAuB,EACtCC,cAAc,EACdC,iBAAiB,CAACC,MAAQC,OAAOC,QAAQ,CAACC,MAAM,CAACH,IAAI,EAC5B;IACzB,MAAMI,YAAYnB;IAClB,MAAMoB,aAAab,OAAO;IAC1B,MAAM,CAACc,cAAcC,gBAAgB,GAAGd;IAExCF,UAAU;QACR,IAAIc,WAAWG,OAAO,EAAE;QACxBH,WAAWG,OAAO,GAAG;QACrB,sEAAsE;QACtE,0DAA0D;QAC1D,IAAI;YACFV,iBAAiBM,UAAUK,EAAE;QAC/B,EAAE,OAAM;QACN,SAAS;QACX;QACAd,eAAe;YAACe,cAAcN,UAAUK,EAAE;QAAA,GACvCE,IAAI,CAAC,CAACC;YACLb,eAAea,SAASC,WAAW;QACrC,GACCC,KAAK,CAAC,CAACC;YACNR,gBAAgBQ,iBAAiB/B,WAAW+B,MAAMC,OAAO,GAAGpB;QAC9D;IACJ,GAAG;QAACQ;QAAWT;QAAgBG;QAAgBF;QAAsBG;KAAe;IAEpF,IAAIO,cAAc;QAChB,qBACE,MAACW;YAAIC,WAAU;;8BACb,KAAC/B;oBAAQgC,MAAK;oBAAQC,MAAK;8BACzB,cAAA,KAAC/B;wBAAKgC,MAAK;kCAAMf;;;8BAEnB,KAACpB;oBAAWoC,OAAO;oBAACC,SAAQ;oBAAQL,WAAU;8BAC5C,cAAA,KAAC5B;wBAAKkC,IAAG;wBAAgCC,QAAQ;4BAACC,KAAKtB,UAAUK,EAAE;wBAAA;kCAAG;;;;;IAM9E;IAEA,qBAAO,KAACrB;QAAeuC,cAAY9B;;AACrC"}
package/dist/feature.d.ts CHANGED
@@ -12,6 +12,10 @@ export declare const integrationsFeature: {
12
12
  readonly path: "/integrations/sentry/callback";
13
13
  readonly parent: "root";
14
14
  readonly impl: "@shipfox/client-integrations/routes/sentry-callback";
15
+ }, {
16
+ readonly path: "/integrations/slack/callback";
17
+ readonly parent: "root";
18
+ readonly impl: "@shipfox/client-integrations/routes/slack-callback";
15
19
  }, {
16
20
  readonly path: "/workspaces/$wid/integrations";
17
21
  readonly parent: "workspaceLayout";
@@ -32,6 +36,10 @@ export declare const integrationsFeature: {
32
36
  readonly path: "/workspaces/$wid/integrations/sentry";
33
37
  readonly parent: "workspaceLayout";
34
38
  readonly impl: "@shipfox/client-integrations/routes/sentry";
39
+ }, {
40
+ readonly path: "/workspaces/$wid/integrations/slack";
41
+ readonly parent: "workspaceLayout";
42
+ readonly impl: "@shipfox/client-integrations/routes/slack";
35
43
  }];
36
44
  };
37
45
  //# sourceMappingURL=feature.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"feature.d.ts","sourceRoot":"","sources":["../src/feature.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4C9B,CAAC"}
1
+ {"version":3,"file":"feature.d.ts","sourceRoot":"","sources":["../src/feature.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsD9B,CAAC"}
package/dist/feature.js CHANGED
@@ -17,6 +17,11 @@ export const integrationsFeature = defineClientFeature({
17
17
  parent: 'root',
18
18
  impl: '@shipfox/client-integrations/routes/sentry-callback'
19
19
  },
20
+ {
21
+ path: '/integrations/slack/callback',
22
+ parent: 'root',
23
+ impl: '@shipfox/client-integrations/routes/slack-callback'
24
+ },
20
25
  {
21
26
  path: '/workspaces/$wid/integrations',
22
27
  parent: 'workspaceLayout',
@@ -41,6 +46,11 @@ export const integrationsFeature = defineClientFeature({
41
46
  path: '/workspaces/$wid/integrations/sentry',
42
47
  parent: 'workspaceLayout',
43
48
  impl: '@shipfox/client-integrations/routes/sentry'
49
+ },
50
+ {
51
+ path: '/workspaces/$wid/integrations/slack',
52
+ parent: 'workspaceLayout',
53
+ impl: '@shipfox/client-integrations/routes/slack'
44
54
  }
45
55
  ]
46
56
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/feature.ts"],"sourcesContent":["import {defineClientFeature} from '@shipfox/client-shell';\n\nexport const integrationsFeature = defineClientFeature({\n id: 'shipfox.integrations',\n routes: [\n {\n path: '/integrations/github/callback',\n parent: 'root',\n impl: '@shipfox/client-integrations/routes/github-callback',\n },\n {\n path: '/integrations/linear/callback',\n parent: 'root',\n impl: '@shipfox/client-integrations/routes/linear-callback',\n },\n {\n path: '/integrations/sentry/callback',\n parent: 'root',\n impl: '@shipfox/client-integrations/routes/sentry-callback',\n },\n {\n path: '/workspaces/$wid/integrations',\n parent: 'workspaceLayout',\n impl: '@shipfox/client-integrations/routes/integrations',\n },\n {\n path: '/workspaces/$wid/integrations/gitea',\n parent: 'workspaceLayout',\n impl: '@shipfox/client-integrations/routes/gitea',\n },\n {\n path: '/workspaces/$wid/integrations/github',\n parent: 'workspaceLayout',\n impl: '@shipfox/client-integrations/routes/github',\n },\n {\n path: '/workspaces/$wid/integrations/linear',\n parent: 'workspaceLayout',\n impl: '@shipfox/client-integrations/routes/linear',\n },\n {\n path: '/workspaces/$wid/integrations/sentry',\n parent: 'workspaceLayout',\n impl: '@shipfox/client-integrations/routes/sentry',\n },\n ],\n});\n"],"names":["defineClientFeature","integrationsFeature","id","routes","path","parent","impl"],"mappings":"AAAA,SAAQA,mBAAmB,QAAO,wBAAwB;AAE1D,OAAO,MAAMC,sBAAsBD,oBAAoB;IACrDE,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;QACA;YACEF,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;AACH,GAAG"}
1
+ {"version":3,"sources":["../src/feature.ts"],"sourcesContent":["import {defineClientFeature} from '@shipfox/client-shell';\n\nexport const integrationsFeature = defineClientFeature({\n id: 'shipfox.integrations',\n routes: [\n {\n path: '/integrations/github/callback',\n parent: 'root',\n impl: '@shipfox/client-integrations/routes/github-callback',\n },\n {\n path: '/integrations/linear/callback',\n parent: 'root',\n impl: '@shipfox/client-integrations/routes/linear-callback',\n },\n {\n path: '/integrations/sentry/callback',\n parent: 'root',\n impl: '@shipfox/client-integrations/routes/sentry-callback',\n },\n {\n path: '/integrations/slack/callback',\n parent: 'root',\n impl: '@shipfox/client-integrations/routes/slack-callback',\n },\n {\n path: '/workspaces/$wid/integrations',\n parent: 'workspaceLayout',\n impl: '@shipfox/client-integrations/routes/integrations',\n },\n {\n path: '/workspaces/$wid/integrations/gitea',\n parent: 'workspaceLayout',\n impl: '@shipfox/client-integrations/routes/gitea',\n },\n {\n path: '/workspaces/$wid/integrations/github',\n parent: 'workspaceLayout',\n impl: '@shipfox/client-integrations/routes/github',\n },\n {\n path: '/workspaces/$wid/integrations/linear',\n parent: 'workspaceLayout',\n impl: '@shipfox/client-integrations/routes/linear',\n },\n {\n path: '/workspaces/$wid/integrations/sentry',\n parent: 'workspaceLayout',\n impl: '@shipfox/client-integrations/routes/sentry',\n },\n {\n path: '/workspaces/$wid/integrations/slack',\n parent: 'workspaceLayout',\n impl: '@shipfox/client-integrations/routes/slack',\n },\n ],\n});\n"],"names":["defineClientFeature","integrationsFeature","id","routes","path","parent","impl"],"mappings":"AAAA,SAAQA,mBAAmB,QAAO,wBAAwB;AAE1D,OAAO,MAAMC,sBAAsBD,oBAAoB;IACrDE,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;QACA;YACEF,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;QACA;YACEF,MAAM;YACNC,QAAQ;YACRC,MAAM;QACR;QACA;YACEF,MAAM;YACNC,QAAQ;YACRC,MAAM;QACR;KACD;AACH,GAAG"}
@@ -3,6 +3,7 @@ import type { CreateGiteaConnectionBodyDto } from '@shipfox/api-integration-gite
3
3
  import type { CreateGithubInstallBodyDto } from '@shipfox/api-integration-github-dto';
4
4
  import type { CreateLinearInstallBodyDto, LinearCallbackQueryDto } from '@shipfox/api-integration-linear-dto';
5
5
  import type { CreateSentryInstallBodyDto, SentryConnectBodyDto } from '@shipfox/api-integration-sentry-dto';
6
+ import type { CreateSlackInstallBodyDto, SlackCallbackQueryDto } from '@shipfox/api-integration-slack-dto';
6
7
  export declare const integrationsQueryKeys: {
7
8
  all: readonly ["integrations"];
8
9
  providers: (capability: IntegrationCapabilityDto | "all") => readonly ["integrations", "providers", "source_control" | "agent_tools" | "all"];
@@ -80,6 +81,9 @@ export declare function createSentryInstall(body: CreateSentryInstallBodyDto): P
80
81
  export declare function createLinearInstall(body: CreateLinearInstallBodyDto): Promise<{
81
82
  install_url: string;
82
83
  }>;
84
+ export declare function createSlackInstall(body: CreateSlackInstallBodyDto): Promise<{
85
+ install_url: string;
86
+ }>;
83
87
  export declare function completeLinearCallback({ query, token, }: {
84
88
  query: LinearCallbackQueryDto;
85
89
  token: string;
@@ -96,6 +100,22 @@ export declare function completeLinearCallback({ query, token, }: {
96
100
  updated_at: string;
97
101
  external_url?: string | undefined;
98
102
  }>;
103
+ export declare function completeSlackCallback({ query, token, }: {
104
+ query: SlackCallbackQueryDto;
105
+ token: string;
106
+ }): Promise<{
107
+ id: string;
108
+ workspace_id: string;
109
+ provider: string;
110
+ external_account_id: string;
111
+ slug: string;
112
+ display_name: string;
113
+ lifecycle_status: "error" | "active" | "disabled";
114
+ capabilities: ("source_control" | "agent_tools")[];
115
+ created_at: string;
116
+ updated_at: string;
117
+ external_url?: string | undefined;
118
+ }>;
99
119
  export declare function connectSentry({ body, token }: {
100
120
  body: SentryConnectBodyDto;
101
121
  token: string;
@@ -226,6 +246,11 @@ export declare function useCreateLinearInstallMutation(): import("@tanstack/reac
226
246
  }, Error, {
227
247
  workspace_id: string;
228
248
  }, unknown>;
249
+ export declare function useCreateSlackInstallMutation(): import("@tanstack/react-query").UseMutationResult<{
250
+ install_url: string;
251
+ }, Error, {
252
+ workspace_id: string;
253
+ }, unknown>;
229
254
  export declare function useCompleteLinearCallbackMutation(): import("@tanstack/react-query").UseMutationResult<{
230
255
  id: string;
231
256
  workspace_id: string;
@@ -242,6 +267,22 @@ export declare function useCompleteLinearCallbackMutation(): import("@tanstack/r
242
267
  query: LinearCallbackQueryDto;
243
268
  token: string;
244
269
  }, unknown>;
270
+ export declare function useCompleteSlackCallbackMutation(): import("@tanstack/react-query").UseMutationResult<{
271
+ id: string;
272
+ workspace_id: string;
273
+ provider: string;
274
+ external_account_id: string;
275
+ slug: string;
276
+ display_name: string;
277
+ lifecycle_status: "error" | "active" | "disabled";
278
+ capabilities: ("source_control" | "agent_tools")[];
279
+ created_at: string;
280
+ updated_at: string;
281
+ external_url?: string | undefined;
282
+ }, Error, {
283
+ query: SlackCallbackQueryDto;
284
+ token: string;
285
+ }, unknown>;
245
286
  export declare function useUpdateIntegrationConnectionMutation(): import("@tanstack/react-query").UseMutationResult<{
246
287
  id: string;
247
288
  workspace_id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"integrations.d.ts","sourceRoot":"","sources":["../../../src/hooks/api/integrations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"integrations.d.ts","sourceRoot":"","sources":["../../../src/hooks/api/integrations.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { apiRequest } from '@shipfox/client-api';
2
2
  import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
3
3
  import { serializeLinearCallbackQuery } from '#linear-callback.js';
4
+ import { serializeSlackCallbackQuery } from '#slack-callback.js';
4
5
  export const integrationsQueryKeys = {
5
6
  all: [
6
7
  'integrations'
@@ -88,6 +89,12 @@ export async function createLinearInstall(body) {
88
89
  body
89
90
  });
90
91
  }
92
+ export async function createSlackInstall(body) {
93
+ return await apiRequest('/integrations/slack/install', {
94
+ method: 'POST',
95
+ body
96
+ });
97
+ }
91
98
  export async function completeLinearCallback({ query, token }) {
92
99
  return await apiRequest(`/integrations/linear/callback/api?${serializeLinearCallbackQuery(query)}`, {
93
100
  headers: {
@@ -95,6 +102,13 @@ export async function completeLinearCallback({ query, token }) {
95
102
  }
96
103
  });
97
104
  }
105
+ export async function completeSlackCallback({ query, token }) {
106
+ return await apiRequest(`/integrations/slack/callback/api?${serializeSlackCallbackQuery(query)}`, {
107
+ headers: {
108
+ authorization: `Bearer ${token}`
109
+ }
110
+ });
111
+ }
98
112
  // Called from the callback route with an explicit bearer (same as the GitHub
99
113
  // callback): the route refreshes auth itself before forwarding the grant code.
100
114
  export async function connectSentry({ body, token }) {
@@ -196,11 +210,21 @@ export function useCreateLinearInstallMutation() {
196
210
  mutationFn: createLinearInstall
197
211
  });
198
212
  }
213
+ export function useCreateSlackInstallMutation() {
214
+ return useMutation({
215
+ mutationFn: createSlackInstall
216
+ });
217
+ }
199
218
  export function useCompleteLinearCallbackMutation() {
200
219
  return useMutation({
201
220
  mutationFn: completeLinearCallback
202
221
  });
203
222
  }
223
+ export function useCompleteSlackCallbackMutation() {
224
+ return useMutation({
225
+ mutationFn: completeSlackCallback
226
+ });
227
+ }
204
228
  export function useUpdateIntegrationConnectionMutation() {
205
229
  const queryClient = useQueryClient();
206
230
  return useMutation({