@shipfox/client-integrations 1.0.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.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +27 -0
- package/dist/components/callback-status-shell.d.ts +9 -0
- package/dist/components/callback-status-shell.d.ts.map +1 -0
- package/dist/components/callback-status-shell.js +81 -0
- package/dist/components/callback-status-shell.js.map +1 -0
- package/dist/components/integration-gallery.stories.d.ts.map +1 -1
- package/dist/components/integration-gallery.stories.js +28 -0
- package/dist/components/integration-gallery.stories.js.map +1 -1
- package/dist/components/redirect-install-page.d.ts +2 -1
- package/dist/components/redirect-install-page.d.ts.map +1 -1
- package/dist/components/redirect-install-page.js +4 -2
- package/dist/components/redirect-install-page.js.map +1 -1
- package/dist/feature.d.ts +8 -0
- package/dist/feature.d.ts.map +1 -1
- package/dist/feature.js +10 -0
- package/dist/feature.js.map +1 -1
- package/dist/hooks/api/integrations.d.ts +41 -0
- package/dist/hooks/api/integrations.d.ts.map +1 -1
- package/dist/hooks/api/integrations.js +24 -0
- package/dist/hooks/api/integrations.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/pages/linear-callback-page.d.ts.map +1 -1
- package/dist/pages/linear-callback-page.js +11 -78
- package/dist/pages/linear-callback-page.js.map +1 -1
- package/dist/pages/linear-install-page.d.ts.map +1 -1
- package/dist/pages/linear-install-page.js +1 -0
- package/dist/pages/linear-install-page.js.map +1 -1
- package/dist/pages/sentry-install-page.d.ts.map +1 -1
- package/dist/pages/sentry-install-page.js +1 -0
- package/dist/pages/sentry-install-page.js.map +1 -1
- package/dist/pages/slack-callback-page.d.ts +2 -0
- package/dist/pages/slack-callback-page.d.ts.map +1 -0
- package/dist/pages/slack-callback-page.js +114 -0
- package/dist/pages/slack-callback-page.js.map +1 -0
- package/dist/pages/slack-install-page.d.ts +2 -0
- package/dist/pages/slack-install-page.d.ts.map +1 -0
- package/dist/pages/slack-install-page.js +19 -0
- package/dist/pages/slack-install-page.js.map +1 -0
- package/dist/provider-catalog.d.ts +1 -1
- package/dist/provider-catalog.d.ts.map +1 -1
- package/dist/provider-catalog.js +5 -0
- package/dist/provider-catalog.js.map +1 -1
- package/dist/routes/slack-callback.d.ts +6 -0
- package/dist/routes/slack-callback.d.ts.map +1 -0
- package/dist/routes/slack-callback.js +7 -0
- package/dist/routes/slack-callback.js.map +1 -0
- package/dist/routes/slack.d.ts +6 -0
- package/dist/routes/slack.d.ts.map +1 -0
- package/dist/routes/slack.js +7 -0
- package/dist/routes/slack.js.map +1 -0
- package/dist/slack-callback.d.ts +17 -0
- package/dist/slack-callback.d.ts.map +1 -0
- package/dist/slack-callback.js +99 -0
- package/dist/slack-callback.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +13 -12
- package/src/components/callback-status-shell.tsx +73 -0
- package/src/components/integration-gallery.stories.tsx +18 -0
- package/src/components/redirect-install-page.tsx +3 -1
- package/src/feature.ts +10 -0
- package/src/hooks/api/integrations.test.ts +30 -0
- package/src/hooks/api/integrations.ts +35 -0
- package/src/index.ts +3 -0
- package/src/pages/linear-callback-page.tsx +11 -52
- package/src/pages/linear-install-page.tsx +1 -0
- package/src/pages/sentry-install-page.tsx +1 -0
- package/src/pages/slack-callback-page.tsx +120 -0
- package/src/pages/slack-install-page.tsx +22 -0
- package/src/provider-catalog.ts +7 -1
- package/src/routes/slack-callback.tsx +3 -0
- package/src/routes/slack.tsx +3 -0
- package/src/slack-callback.test.ts +32 -0
- package/src/slack-callback.ts +141 -0
- package/tsconfig.build.tsbuildinfo +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
$ shipfox-swc
|
|
2
|
-
Successfully compiled:
|
|
2
|
+
Successfully compiled: 48 files with swc (531.64ms)
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
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
|
+
|
|
3
30
|
## 1.0.0
|
|
4
31
|
|
|
5
32
|
### Patch 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;
|
|
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":"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"}
|
|
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;
|
|
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
|
package/dist/feature.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature.d.ts","sourceRoot":"","sources":["../src/feature.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,mBAAmB
|
|
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
|
});
|
package/dist/feature.js.map
CHANGED
|
@@ -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":"AAAA,OAAO,KAAK,EACV,wBAAwB,EAKxB,kCAAkC,EACnC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EACV,4BAA4B,EAE7B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EACV,0BAA0B,EAE3B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EACV,0BAA0B,EAE1B,sBAAsB,EAEvB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EACV,0BAA0B,EAE1B,oBAAoB,EAErB,MAAM,qCAAqC,CAAC;
|
|
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({
|