@shipfox/client-integrations 21.0.0 → 22.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 +19 -0
- package/dist/components/callback-status-shell.d.ts.map +1 -1
- package/dist/components/callback-status-shell.js +4 -3
- package/dist/components/callback-status-shell.js.map +1 -1
- package/dist/components/connection-picker.js +2 -2
- package/dist/components/connection-picker.js.map +1 -1
- package/dist/components/installed-integrations-section.d.ts.map +1 -1
- package/dist/components/installed-integrations-section.js +155 -141
- package/dist/components/installed-integrations-section.js.map +1 -1
- package/dist/components/integration-gallery.stories.d.ts.map +1 -1
- package/dist/components/integration-gallery.stories.js +7 -2
- package/dist/components/integration-gallery.stories.js.map +1 -1
- package/dist/components/provider-grid.d.ts +0 -2
- package/dist/components/provider-grid.d.ts.map +1 -1
- package/dist/components/provider-grid.js +88 -104
- package/dist/components/provider-grid.js.map +1 -1
- package/dist/components/redirect-install-page.d.ts.map +1 -1
- package/dist/components/redirect-install-page.js +3 -2
- package/dist/components/redirect-install-page.js.map +1 -1
- package/dist/components/repository-picker.d.ts +1 -4
- package/dist/components/repository-picker.d.ts.map +1 -1
- package/dist/components/repository-picker.js +24 -37
- package/dist/components/repository-picker.js.map +1 -1
- package/dist/pages/gitea-install-page.js +1 -1
- package/dist/pages/gitea-install-page.js.map +1 -1
- package/dist/pages/jira-callback-page.js +4 -4
- package/dist/pages/jira-callback-page.js.map +1 -1
- package/dist/pages/sentry-callback-page.js +4 -4
- package/dist/pages/sentry-callback-page.js.map +1 -1
- package/dist/pages/source-control-onboarding-page.js +1 -1
- package/dist/pages/source-control-onboarding-page.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/src/components/callback-status-shell.tsx +4 -3
- package/src/components/connection-picker.tsx +2 -2
- package/src/components/installed-integrations-section.tsx +110 -98
- package/src/components/integration-gallery.stories.tsx +7 -2
- package/src/components/integration-gallery.test.tsx +3 -2
- package/src/components/provider-grid.tsx +69 -79
- package/src/components/redirect-install-page.test.tsx +4 -0
- package/src/components/redirect-install-page.tsx +3 -2
- package/src/components/repository-picker.test.tsx +27 -13
- package/src/components/repository-picker.tsx +22 -47
- package/src/pages/gitea-install-page.tsx +1 -1
- package/src/pages/jira-callback-page.tsx +4 -4
- package/src/pages/sentry-callback-page.tsx +3 -3
- package/src/pages/slack-callback-page.test.tsx +7 -0
- package/src/pages/source-control-onboarding-page.tsx +1 -1
- package/tsconfig.build.tsbuildinfo +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
$ shipfox-swc
|
|
2
|
-
Successfully compiled: 59 files with swc (
|
|
2
|
+
Successfully compiled: 59 files with swc (414.74ms)
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @shipfox/client-integrations
|
|
2
2
|
|
|
3
|
+
## 22.0.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 50b3867: Consolidate authentication, onboarding, integration-install, and callback surfaces onto the shared focused frame.
|
|
8
|
+
- 7693eb3: Render empty and load-error states inside bordered panel bodies and keep loading placeholders aligned with their data regions.
|
|
9
|
+
- 00c1cb8: Panels across these surfaces share one hover, focus, and elevation treatment. Grids of openable things, including the integration gallery, the available providers grid, and the harness picker, render as cells inside a single panel divided by hairlines instead of separate bordered tiles.
|
|
10
|
+
- 56f4526: Project settings and project creation now use shared panels, with source integrations presented as button-style radio choices.
|
|
11
|
+
- Updated dependencies [50b3867]
|
|
12
|
+
- Updated dependencies [00c1cb8]
|
|
13
|
+
- Updated dependencies [7693eb3]
|
|
14
|
+
- Updated dependencies [00c1cb8]
|
|
15
|
+
- Updated dependencies [56f4526]
|
|
16
|
+
- @shipfox/client-auth@22.0.0
|
|
17
|
+
- @shipfox/client-shell@22.0.0
|
|
18
|
+
- @shipfox/react-ui@2.1.0
|
|
19
|
+
- @shipfox/client-ui@22.0.0
|
|
20
|
+
- @shipfox/integration-icons@0.3.5
|
|
21
|
+
|
|
3
22
|
## 21.0.0
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"callback-status-shell.d.ts","sourceRoot":"","sources":["../../src/components/callback-status-shell.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"callback-status-shell.d.ts","sourceRoot":"","sources":["../../src/components/callback-status-shell.tsx"],"names":[],"mappings":"AAOA,wBAAgB,mBAAmB,CAAC,EAClC,KAAK,EACL,OAAO,EACP,MAAgB,EAChB,SAAS,EACT,aAAa,EACb,aAAa,EACb,WAAW,GACZ,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,WAAW,EACP,uCAAuC,GACvC,sCAAsC,GACtC,qCAAqC,CAAC;CAC3C,+BAmDA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { FocusedFrame } from '@shipfox/client-shell/runtime';
|
|
2
3
|
import { ButtonLink } from '@shipfox/react-ui/button';
|
|
3
4
|
import { Callout } from '@shipfox/react-ui/callout';
|
|
4
5
|
import { Text } from '@shipfox/react-ui/typography';
|
|
@@ -30,9 +31,9 @@ export function CallbackStatusShell({ title, message, status = 'error', startOve
|
|
|
30
31
|
});
|
|
31
32
|
const logoutRedirect = workspaceSlug ? installPath.replace('$workspaceSlug', workspaceSlug) : undefined;
|
|
32
33
|
return /*#__PURE__*/ _jsx("main", {
|
|
33
|
-
className: "flex min-h-screen px-
|
|
34
|
-
children: /*#__PURE__*/ _jsxs(
|
|
35
|
-
className: "
|
|
34
|
+
className: "flex min-h-screen px-frame py-frame",
|
|
35
|
+
children: /*#__PURE__*/ _jsxs(FocusedFrame, {
|
|
36
|
+
className: "flex flex-col justify-center gap-section",
|
|
36
37
|
children: [
|
|
37
38
|
/*#__PURE__*/ _jsx("h2", {
|
|
38
39
|
ref: headingRef,
|
|
@@ -1 +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 status = 'error',\n startOver,\n switchAccount,\n workspaceSlug,\n installPath,\n}: {\n title: string;\n message: string;\n status?: 'error' | 'success';\n startOver?: boolean;\n switchAccount?: boolean;\n workspaceSlug?: string | undefined;\n installPath:\n | '/w/$workspaceSlug/integrations/linear'\n | '/w/$workspaceSlug/integrations/slack'\n | '/w/$workspaceSlug/integrations/jira';\n}) {\n const headingRef = useRef<HTMLHeadingElement>(null);\n useEffect(() => headingRef.current?.focus(), []);\n const recoveryVariant = startOver || switchAccount ? 'muted' : 'base';\n const settings = workspaceSlug ? (\n <ButtonLink asChild variant={recoveryVariant} className=\"min-h-44 w-full sm:w-fit\">\n <Link to=\"/w/$workspaceSlug/settings/integrations\" params={{workspaceSlug}}>\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 = workspaceSlug\n ? installPath.replace('$workspaceSlug', workspaceSlug)\n : undefined;\n\n return (\n <main className=\"flex min-h-screen px-
|
|
1
|
+
{"version":3,"sources":["../../src/components/callback-status-shell.tsx"],"sourcesContent":["import {FocusedFrame} from '@shipfox/client-shell/runtime';\nimport {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 status = 'error',\n startOver,\n switchAccount,\n workspaceSlug,\n installPath,\n}: {\n title: string;\n message: string;\n status?: 'error' | 'success';\n startOver?: boolean;\n switchAccount?: boolean;\n workspaceSlug?: string | undefined;\n installPath:\n | '/w/$workspaceSlug/integrations/linear'\n | '/w/$workspaceSlug/integrations/slack'\n | '/w/$workspaceSlug/integrations/jira';\n}) {\n const headingRef = useRef<HTMLHeadingElement>(null);\n useEffect(() => headingRef.current?.focus(), []);\n const recoveryVariant = startOver || switchAccount ? 'muted' : 'base';\n const settings = workspaceSlug ? (\n <ButtonLink asChild variant={recoveryVariant} className=\"min-h-44 w-full sm:w-fit\">\n <Link to=\"/w/$workspaceSlug/settings/integrations\" params={{workspaceSlug}}>\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 = workspaceSlug\n ? installPath.replace('$workspaceSlug', workspaceSlug)\n : undefined;\n\n return (\n <main className=\"flex min-h-screen px-frame py-frame\">\n <FocusedFrame className=\"flex flex-col justify-center gap-section\">\n <h2 ref={headingRef} tabIndex={-1} className=\"text-24 font-semibold outline-none\">\n {title}\n </h2>\n <Callout role={status === 'error' ? 'alert' : 'status'} type={status}>\n <Text size=\"sm\">{message}</Text>\n </Callout>\n <div className=\"flex flex-col gap-inline sm:flex-row sm:items-center\">\n {switchAccount ? (\n <ButtonLink asChild className=\"min-h-44 w-full sm:w-fit\">\n <Link\n to=\"/auth/logout\"\n search={logoutRedirect ? {redirect: logoutRedirect} : undefined}\n >\n Switch account\n </Link>\n </ButtonLink>\n ) : null}\n {startOver && workspaceSlug ? (\n <ButtonLink asChild className=\"min-h-44 w-full sm:w-fit\">\n <Link to={installPath} params={{workspaceSlug}}>\n Start over\n </Link>\n </ButtonLink>\n ) : null}\n {settings}\n </div>\n </FocusedFrame>\n </main>\n );\n}\n"],"names":["FocusedFrame","ButtonLink","Callout","Text","Link","useEffect","useRef","CallbackStatusShell","title","message","status","startOver","switchAccount","workspaceSlug","installPath","headingRef","current","focus","recoveryVariant","settings","asChild","variant","className","to","params","logoutRedirect","replace","undefined","main","h2","ref","tabIndex","role","type","size","div","search","redirect"],"mappings":";AAAA,SAAQA,YAAY,QAAO,gCAAgC;AAC3D,SAAQC,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,OAAO,EAChBC,SAAS,EACTC,aAAa,EACbC,aAAa,EACbC,WAAW,EAYZ;IACC,MAAMC,aAAaT,OAA2B;IAC9CD,UAAU,IAAMU,WAAWC,OAAO,EAAEC,SAAS,EAAE;IAC/C,MAAMC,kBAAkBP,aAAaC,gBAAgB,UAAU;IAC/D,MAAMO,WAAWN,8BACf,KAACZ;QAAWmB,OAAO;QAACC,SAASH;QAAiBI,WAAU;kBACtD,cAAA,KAAClB;YAAKmB,IAAG;YAA0CC,QAAQ;gBAACX;YAAa;sBAAG;;uBAK9E,KAACZ;QAAWmB,OAAO;QAACC,SAASH;QAAiBI,WAAU;kBACtD,cAAA,KAAClB;YAAKmB,IAAG;sBAAI;;;IAGjB,MAAME,iBAAiBZ,gBACnBC,YAAYY,OAAO,CAAC,kBAAkBb,iBACtCc;IAEJ,qBACE,KAACC;QAAKN,WAAU;kBACd,cAAA,MAACtB;YAAasB,WAAU;;8BACtB,KAACO;oBAAGC,KAAKf;oBAAYgB,UAAU,CAAC;oBAAGT,WAAU;8BAC1Cd;;8BAEH,KAACN;oBAAQ8B,MAAMtB,WAAW,UAAU,UAAU;oBAAUuB,MAAMvB;8BAC5D,cAAA,KAACP;wBAAK+B,MAAK;kCAAMzB;;;8BAEnB,MAAC0B;oBAAIb,WAAU;;wBACZV,8BACC,KAACX;4BAAWmB,OAAO;4BAACE,WAAU;sCAC5B,cAAA,KAAClB;gCACCmB,IAAG;gCACHa,QAAQX,iBAAiB;oCAACY,UAAUZ;gCAAc,IAAIE;0CACvD;;6BAID;wBACHhB,aAAaE,8BACZ,KAACZ;4BAAWmB,OAAO;4BAACE,WAAU;sCAC5B,cAAA,KAAClB;gCAAKmB,IAAIT;gCAAaU,QAAQ;oCAACX;gCAAa;0CAAG;;6BAIhD;wBACHM;;;;;;AAKX"}
|
|
@@ -9,7 +9,7 @@ import { useId } from 'react';
|
|
|
9
9
|
export function ConnectionPicker({ connections, selectedConnectionId, onSelect }) {
|
|
10
10
|
const labelId = useId();
|
|
11
11
|
return /*#__PURE__*/ _jsxs("div", {
|
|
12
|
-
className: "flex flex-col
|
|
12
|
+
className: "flex min-w-0 flex-col",
|
|
13
13
|
children: [
|
|
14
14
|
/*#__PURE__*/ _jsx(Label, {
|
|
15
15
|
id: labelId,
|
|
@@ -17,10 +17,10 @@ export function ConnectionPicker({ connections, selectedConnectionId, onSelect }
|
|
|
17
17
|
children: "Source integration"
|
|
18
18
|
}),
|
|
19
19
|
/*#__PURE__*/ _jsx(RadioGroup, {
|
|
20
|
+
variant: "cell",
|
|
20
21
|
"aria-labelledby": labelId,
|
|
21
22
|
value: selectedConnectionId ?? '',
|
|
22
23
|
onValueChange: onSelect,
|
|
23
|
-
className: "grid grid-cols-2 gap-inline max-[760px]:grid-cols-1",
|
|
24
24
|
children: connections.map((connection)=>/*#__PURE__*/ _jsx(RadioGroupItem, {
|
|
25
25
|
value: connection.id,
|
|
26
26
|
children: /*#__PURE__*/ _jsx(ConnectionOption, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/connection-picker.tsx"],"sourcesContent":["import {IntegrationIcon} from '@shipfox/integration-icons';\nimport {useIsTextTruncated} from '@shipfox/react-ui/hooks';\nimport {Label} from '@shipfox/react-ui/label';\nimport {RadioGroup, RadioGroupItem} from '@shipfox/react-ui/radio-group';\nimport {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';\nimport {Text} from '@shipfox/react-ui/typography';\nimport {useId} from 'react';\nimport type {IntegrationConnection} from '#core/models.js';\n\nexport function ConnectionPicker({\n connections,\n selectedConnectionId,\n onSelect,\n}: {\n connections: IntegrationConnection[];\n selectedConnectionId: string | undefined;\n onSelect: (connectionId: string) => void;\n}) {\n const labelId = useId();\n\n return (\n <div className=\"flex flex-col
|
|
1
|
+
{"version":3,"sources":["../../src/components/connection-picker.tsx"],"sourcesContent":["import {IntegrationIcon} from '@shipfox/integration-icons';\nimport {useIsTextTruncated} from '@shipfox/react-ui/hooks';\nimport {Label} from '@shipfox/react-ui/label';\nimport {RadioGroup, RadioGroupItem} from '@shipfox/react-ui/radio-group';\nimport {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';\nimport {Text} from '@shipfox/react-ui/typography';\nimport {useId} from 'react';\nimport type {IntegrationConnection} from '#core/models.js';\n\nexport function ConnectionPicker({\n connections,\n selectedConnectionId,\n onSelect,\n}: {\n connections: IntegrationConnection[];\n selectedConnectionId: string | undefined;\n onSelect: (connectionId: string) => void;\n}) {\n const labelId = useId();\n\n return (\n <div className=\"flex min-w-0 flex-col\">\n <Label id={labelId} className=\"sr-only\">\n Source integration\n </Label>\n <RadioGroup\n variant=\"cell\"\n aria-labelledby={labelId}\n value={selectedConnectionId ?? ''}\n onValueChange={onSelect}\n >\n {connections.map((connection) => (\n <RadioGroupItem key={connection.id} value={connection.id}>\n <ConnectionOption connection={connection} />\n </RadioGroupItem>\n ))}\n </RadioGroup>\n </div>\n );\n}\n\nfunction ConnectionOption({connection}: {connection: IntegrationConnection}) {\n const {ref: nameRef, isTruncated} = useIsTextTruncated<HTMLSpanElement>(connection.displayName);\n\n return (\n <span className=\"flex min-w-0 items-center gap-inline\">\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"shrink-0\">\n <IntegrationIcon\n source={connection.provider}\n aria-hidden\n className=\"size-20 text-foreground-neutral-base\"\n />\n </span>\n </TooltipTrigger>\n <TooltipContent>{integrationName(connection.provider)}</TooltipContent>\n </Tooltip>\n\n <Tooltip>\n <TooltipTrigger asChild>\n <span ref={nameRef} className=\"min-w-0 truncate\">\n <Text as=\"span\" size=\"sm\" bold>\n {connection.displayName}\n </Text>\n </span>\n </TooltipTrigger>\n {isTruncated ? <TooltipContent>{connection.displayName}</TooltipContent> : null}\n </Tooltip>\n </span>\n );\n}\n\nfunction integrationName(provider: string): string {\n switch (provider) {\n case 'github':\n return 'GitHub';\n case 'gitea':\n return 'Gitea';\n case 'sentry':\n return 'Sentry';\n case 'webhook':\n return 'Webhook';\n case 'debug':\n return 'Debug';\n default:\n return provider;\n }\n}\n"],"names":["IntegrationIcon","useIsTextTruncated","Label","RadioGroup","RadioGroupItem","Tooltip","TooltipContent","TooltipTrigger","Text","useId","ConnectionPicker","connections","selectedConnectionId","onSelect","labelId","div","className","id","variant","aria-labelledby","value","onValueChange","map","connection","ConnectionOption","ref","nameRef","isTruncated","displayName","span","asChild","source","provider","aria-hidden","integrationName","as","size","bold"],"mappings":";AAAA,SAAQA,eAAe,QAAO,6BAA6B;AAC3D,SAAQC,kBAAkB,QAAO,0BAA0B;AAC3D,SAAQC,KAAK,QAAO,0BAA0B;AAC9C,SAAQC,UAAU,EAAEC,cAAc,QAAO,gCAAgC;AACzE,SAAQC,OAAO,EAAEC,cAAc,EAAEC,cAAc,QAAO,4BAA4B;AAClF,SAAQC,IAAI,QAAO,+BAA+B;AAClD,SAAQC,KAAK,QAAO,QAAQ;AAG5B,OAAO,SAASC,iBAAiB,EAC/BC,WAAW,EACXC,oBAAoB,EACpBC,QAAQ,EAKT;IACC,MAAMC,UAAUL;IAEhB,qBACE,MAACM;QAAIC,WAAU;;0BACb,KAACd;gBAAMe,IAAIH;gBAASE,WAAU;0BAAU;;0BAGxC,KAACb;gBACCe,SAAQ;gBACRC,mBAAiBL;gBACjBM,OAAOR,wBAAwB;gBAC/BS,eAAeR;0BAEdF,YAAYW,GAAG,CAAC,CAACC,2BAChB,KAACnB;wBAAmCgB,OAAOG,WAAWN,EAAE;kCACtD,cAAA,KAACO;4BAAiBD,YAAYA;;uBADXA,WAAWN,EAAE;;;;AAO5C;AAEA,SAASO,iBAAiB,EAACD,UAAU,EAAsC;IACzE,MAAM,EAACE,KAAKC,OAAO,EAAEC,WAAW,EAAC,GAAG1B,mBAAoCsB,WAAWK,WAAW;IAE9F,qBACE,MAACC;QAAKb,WAAU;;0BACd,MAACX;;kCACC,KAACE;wBAAeuB,OAAO;kCACrB,cAAA,KAACD;4BAAKb,WAAU;sCACd,cAAA,KAAChB;gCACC+B,QAAQR,WAAWS,QAAQ;gCAC3BC,aAAW;gCACXjB,WAAU;;;;kCAIhB,KAACV;kCAAgB4B,gBAAgBX,WAAWS,QAAQ;;;;0BAGtD,MAAC3B;;kCACC,KAACE;wBAAeuB,OAAO;kCACrB,cAAA,KAACD;4BAAKJ,KAAKC;4BAASV,WAAU;sCAC5B,cAAA,KAACR;gCAAK2B,IAAG;gCAAOC,MAAK;gCAAKC,IAAI;0CAC3Bd,WAAWK,WAAW;;;;oBAI5BD,4BAAc,KAACrB;kCAAgBiB,WAAWK,WAAW;yBAAqB;;;;;AAInF;AAEA,SAASM,gBAAgBF,QAAgB;IACvC,OAAQA;QACN,KAAK;YACH,OAAO;QACT,KAAK;YACH,OAAO;QACT,KAAK;YACH,OAAO;QACT,KAAK;YACH,OAAO;QACT,KAAK;YACH,OAAO;QACT;YACE,OAAOA;IACX;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installed-integrations-section.d.ts","sourceRoot":"","sources":["../../src/components/installed-integrations-section.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"installed-integrations-section.d.ts","sourceRoot":"","sources":["../../src/components/installed-integrations-section.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAAC,KAAK,qBAAqB,EAAqB,MAAM,iBAAiB,CAAC;AAG/E,UAAU,iCAAiC;IACzC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,WAAW,EAAE,qBAAqB,EAAE,CAAC;IACrC,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC;IACjC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,WAAW,EAAE,CAAC,UAAU,EAAE,qBAAqB,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1E,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,mBAAmB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CAC/D;AAED,wBAAgB,4BAA4B,CAAC,EAC3C,aAAa,EACb,WAAW,EACX,SAAS,EACT,UAAU,EACV,KAAK,EACL,OAAO,EACP,UAAU,EACV,KAAK,EACL,WAAW,EACX,QAAQ,EACR,mBAAmB,GACpB,EAAE,iCAAiC,+BAuDnC"}
|
|
@@ -4,6 +4,7 @@ import { IntegrationIcon } from '@shipfox/integration-icons';
|
|
|
4
4
|
import { IconButton } from '@shipfox/react-ui/button';
|
|
5
5
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from '@shipfox/react-ui/dropdown-menu';
|
|
6
6
|
import { EmptyState } from '@shipfox/react-ui/empty-state';
|
|
7
|
+
import { Panel, PanelBody, PanelRow } from '@shipfox/react-ui/panel';
|
|
7
8
|
import { Skeleton } from '@shipfox/react-ui/skeleton';
|
|
8
9
|
import { Header, Text } from '@shipfox/react-ui/typography';
|
|
9
10
|
import { cn, formatDate } from '@shipfox/react-ui/utils';
|
|
@@ -11,7 +12,6 @@ import { Link } from '@tanstack/react-router';
|
|
|
11
12
|
import { ConnectionStatusBadge } from '#connection-status-badge.js';
|
|
12
13
|
import { isUsableConnection } from '#core/models.js';
|
|
13
14
|
import { usageEventsForConnection } from './integration-usage-events.js';
|
|
14
|
-
const INSTALLED_SURFACE_CLASS = 'overflow-hidden rounded-8 border border-border-neutral-base bg-background-neutral-base';
|
|
15
15
|
export function InstalledIntegrationsSection({ workspaceSlug, connections, isPending, isFetching, error, onRetry, isMutating, onUse, onSetActive, onDelete, providerDisplayName }) {
|
|
16
16
|
return /*#__PURE__*/ _jsxs("section", {
|
|
17
17
|
className: "flex flex-col gap-group",
|
|
@@ -34,8 +34,7 @@ export function InstalledIntegrationsSection({ workspaceSlug, connections, isPen
|
|
|
34
34
|
isPending ? /*#__PURE__*/ _jsx(InstalledSkeleton, {
|
|
35
35
|
label: "Loading integrations"
|
|
36
36
|
}) : null,
|
|
37
|
-
error ? /*#__PURE__*/ _jsx(
|
|
38
|
-
className: cn(INSTALLED_SURFACE_CLASS, 'px-row'),
|
|
37
|
+
error ? /*#__PURE__*/ _jsx(Panel, {
|
|
39
38
|
children: /*#__PURE__*/ _jsx(QueryLoadError, {
|
|
40
39
|
query: {
|
|
41
40
|
isError: true,
|
|
@@ -44,28 +43,33 @@ export function InstalledIntegrationsSection({ workspaceSlug, connections, isPen
|
|
|
44
43
|
error,
|
|
45
44
|
refetch: onRetry
|
|
46
45
|
},
|
|
47
|
-
subject: "integrations"
|
|
46
|
+
subject: "integrations",
|
|
47
|
+
variant: "panel"
|
|
48
48
|
})
|
|
49
49
|
}) : null,
|
|
50
|
-
!isPending && !error && connections.length === 0 ? /*#__PURE__*/ _jsx(
|
|
51
|
-
className: cn(INSTALLED_SURFACE_CLASS, 'px-row'),
|
|
50
|
+
!isPending && !error && connections.length === 0 ? /*#__PURE__*/ _jsx(Panel, {
|
|
52
51
|
children: /*#__PURE__*/ _jsx(EmptyState, {
|
|
53
52
|
icon: "componentLine",
|
|
54
53
|
title: "No integrations installed yet",
|
|
55
|
-
description: "Install a provider below to get started."
|
|
54
|
+
description: "Install a provider below to get started.",
|
|
55
|
+
variant: "panel"
|
|
56
56
|
})
|
|
57
57
|
}) : null,
|
|
58
|
-
connections.length > 0 ? /*#__PURE__*/ _jsx(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
58
|
+
connections.length > 0 ? /*#__PURE__*/ _jsx(Panel, {
|
|
59
|
+
children: /*#__PURE__*/ _jsx(PanelBody, {
|
|
60
|
+
asChild: true,
|
|
61
|
+
children: /*#__PURE__*/ _jsx("ul", {
|
|
62
|
+
children: connections.map((connection)=>/*#__PURE__*/ _jsx(InstalledRow, {
|
|
63
|
+
connection: connection,
|
|
64
|
+
workspaceSlug: workspaceSlug,
|
|
65
|
+
isMutating: isMutating,
|
|
66
|
+
onUse: onUse,
|
|
67
|
+
onSetActive: (nextActive)=>onSetActive(connection, nextActive),
|
|
68
|
+
onDelete: onDelete,
|
|
69
|
+
providerDisplayName: providerDisplayName
|
|
70
|
+
}, connection.id))
|
|
71
|
+
})
|
|
72
|
+
})
|
|
69
73
|
}) : null
|
|
70
74
|
]
|
|
71
75
|
});
|
|
@@ -75,136 +79,146 @@ function InstalledRow({ connection, workspaceSlug, isMutating, onUse, onSetActiv
|
|
|
75
79
|
const active = isUsableConnection(connection);
|
|
76
80
|
const recentEventsEvent = usageEventsForConnection(connection)[0]?.value ?? 'received';
|
|
77
81
|
const providerName = providerDisplayName(connection.provider);
|
|
78
|
-
return /*#__PURE__*/
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
children: [
|
|
108
|
-
"Added ",
|
|
109
|
-
formatDate(connection.createdAt)
|
|
110
|
-
]
|
|
111
|
-
})
|
|
112
|
-
]
|
|
113
|
-
}),
|
|
114
|
-
/*#__PURE__*/ _jsxs(DropdownMenu, {
|
|
115
|
-
children: [
|
|
116
|
-
/*#__PURE__*/ _jsx(DropdownMenuTrigger, {
|
|
117
|
-
asChild: true,
|
|
118
|
-
children: /*#__PURE__*/ _jsx(IconButton, {
|
|
82
|
+
return /*#__PURE__*/ _jsx(PanelRow, {
|
|
83
|
+
asChild: true,
|
|
84
|
+
className: "justify-start gap-cluster",
|
|
85
|
+
children: /*#__PURE__*/ _jsxs("li", {
|
|
86
|
+
children: [
|
|
87
|
+
/*#__PURE__*/ _jsx(IntegrationIcon, {
|
|
88
|
+
source: connection.provider,
|
|
89
|
+
"aria-hidden": true,
|
|
90
|
+
className: cn('size-24 shrink-0', muted ? 'text-foreground-neutral-disabled' : 'text-foreground-neutral-base')
|
|
91
|
+
}),
|
|
92
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
93
|
+
className: "flex min-w-0 flex-1 flex-col gap-tight",
|
|
94
|
+
children: [
|
|
95
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
96
|
+
className: "flex min-w-0 items-center gap-inline",
|
|
97
|
+
children: [
|
|
98
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
99
|
+
size: "md",
|
|
100
|
+
bold: true,
|
|
101
|
+
className: cn('truncate', muted ? 'text-foreground-neutral-disabled' : undefined),
|
|
102
|
+
children: connection.displayName
|
|
103
|
+
}),
|
|
104
|
+
/*#__PURE__*/ _jsx(ConnectionStatusBadge, {
|
|
105
|
+
status: connection.lifecycleStatus,
|
|
106
|
+
className: "shrink-0"
|
|
107
|
+
})
|
|
108
|
+
]
|
|
109
|
+
}),
|
|
110
|
+
/*#__PURE__*/ _jsxs(Text, {
|
|
119
111
|
size: "sm",
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
112
|
+
className: "truncate text-foreground-neutral-muted",
|
|
113
|
+
children: [
|
|
114
|
+
"Added ",
|
|
115
|
+
formatDate(connection.createdAt)
|
|
116
|
+
]
|
|
123
117
|
})
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
})
|
|
136
|
-
}) : null,
|
|
137
|
-
/*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
138
|
-
onSelect: ()=>onUse(connection.id),
|
|
139
|
-
children: "Use this integration"
|
|
140
|
-
}),
|
|
141
|
-
workspaceSlug ? /*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
142
|
-
asChild: true,
|
|
143
|
-
children: /*#__PURE__*/ _jsx(Link, {
|
|
144
|
-
to: "/w/$workspaceSlug/settings/events",
|
|
145
|
-
params: {
|
|
146
|
-
workspaceSlug
|
|
147
|
-
},
|
|
148
|
-
search: {
|
|
149
|
-
source: [
|
|
150
|
-
connection.slug
|
|
151
|
-
],
|
|
152
|
-
event: [
|
|
153
|
-
recentEventsEvent
|
|
154
|
-
]
|
|
155
|
-
},
|
|
156
|
-
children: "View recent events"
|
|
157
|
-
})
|
|
158
|
-
}) : null,
|
|
159
|
-
/*#__PURE__*/ _jsx(DropdownMenuSeparator, {}),
|
|
160
|
-
/*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
161
|
-
disabled: isMutating,
|
|
162
|
-
onSelect: ()=>onSetActive(!active),
|
|
163
|
-
children: active ? 'Disable integration' : 'Enable integration'
|
|
164
|
-
}),
|
|
165
|
-
/*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
166
|
-
disabled: isMutating,
|
|
167
|
-
onSelect: ()=>onDelete(connection.id),
|
|
168
|
-
children: "Delete integration"
|
|
118
|
+
]
|
|
119
|
+
}),
|
|
120
|
+
/*#__PURE__*/ _jsxs(DropdownMenu, {
|
|
121
|
+
children: [
|
|
122
|
+
/*#__PURE__*/ _jsx(DropdownMenuTrigger, {
|
|
123
|
+
asChild: true,
|
|
124
|
+
children: /*#__PURE__*/ _jsx(IconButton, {
|
|
125
|
+
size: "sm",
|
|
126
|
+
variant: "transparent",
|
|
127
|
+
icon: "more2Line",
|
|
128
|
+
"aria-label": `Open ${connection.displayName} integration actions`
|
|
169
129
|
})
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
130
|
+
}),
|
|
131
|
+
/*#__PURE__*/ _jsxs(DropdownMenuContent, {
|
|
132
|
+
align: "end",
|
|
133
|
+
children: [
|
|
134
|
+
connection.externalUrl ? /*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
135
|
+
asChild: true,
|
|
136
|
+
children: /*#__PURE__*/ _jsx("a", {
|
|
137
|
+
href: connection.externalUrl,
|
|
138
|
+
target: "_blank",
|
|
139
|
+
rel: "noreferrer noopener",
|
|
140
|
+
children: providerName ? `Open in ${providerName}` : 'Open provider settings'
|
|
141
|
+
})
|
|
142
|
+
}) : null,
|
|
143
|
+
/*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
144
|
+
onSelect: ()=>onUse(connection.id),
|
|
145
|
+
children: "Use this integration"
|
|
146
|
+
}),
|
|
147
|
+
workspaceSlug ? /*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
148
|
+
asChild: true,
|
|
149
|
+
children: /*#__PURE__*/ _jsx(Link, {
|
|
150
|
+
to: "/w/$workspaceSlug/settings/events",
|
|
151
|
+
params: {
|
|
152
|
+
workspaceSlug
|
|
153
|
+
},
|
|
154
|
+
search: {
|
|
155
|
+
source: [
|
|
156
|
+
connection.slug
|
|
157
|
+
],
|
|
158
|
+
event: [
|
|
159
|
+
recentEventsEvent
|
|
160
|
+
]
|
|
161
|
+
},
|
|
162
|
+
children: "View recent events"
|
|
163
|
+
})
|
|
164
|
+
}) : null,
|
|
165
|
+
/*#__PURE__*/ _jsx(DropdownMenuSeparator, {}),
|
|
166
|
+
/*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
167
|
+
disabled: isMutating,
|
|
168
|
+
onSelect: ()=>onSetActive(!active),
|
|
169
|
+
children: active ? 'Disable integration' : 'Enable integration'
|
|
170
|
+
}),
|
|
171
|
+
/*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
172
|
+
disabled: isMutating,
|
|
173
|
+
onSelect: ()=>onDelete(connection.id),
|
|
174
|
+
children: "Delete integration"
|
|
175
|
+
})
|
|
176
|
+
]
|
|
177
|
+
})
|
|
178
|
+
]
|
|
179
|
+
})
|
|
180
|
+
]
|
|
181
|
+
})
|
|
175
182
|
});
|
|
176
183
|
}
|
|
177
184
|
function InstalledSkeleton({ label }) {
|
|
178
|
-
return /*#__PURE__*/ _jsx(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
1,
|
|
185
|
-
2
|
|
186
|
-
].map((row)=>/*#__PURE__*/ _jsxs("li", {
|
|
187
|
-
className: "flex items-center gap-cluster px-row py-row",
|
|
185
|
+
return /*#__PURE__*/ _jsx(Panel, {
|
|
186
|
+
children: /*#__PURE__*/ _jsx(PanelBody, {
|
|
187
|
+
asChild: true,
|
|
188
|
+
children: /*#__PURE__*/ _jsx("ul", {
|
|
189
|
+
role: "status",
|
|
190
|
+
"aria-label": label,
|
|
188
191
|
children: [
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
192
|
+
0,
|
|
193
|
+
1,
|
|
194
|
+
2
|
|
195
|
+
].map((row)=>/*#__PURE__*/ _jsx(PanelRow, {
|
|
196
|
+
asChild: true,
|
|
197
|
+
className: "justify-start gap-cluster hover:bg-background-neutral-base",
|
|
198
|
+
children: /*#__PURE__*/ _jsxs("li", {
|
|
199
|
+
children: [
|
|
200
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
201
|
+
className: "size-24 shrink-0"
|
|
202
|
+
}),
|
|
203
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
204
|
+
className: "flex min-w-0 flex-1 flex-col gap-tight",
|
|
205
|
+
children: [
|
|
206
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
207
|
+
className: "h-16 w-120"
|
|
208
|
+
}),
|
|
209
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
210
|
+
className: "h-12 w-80"
|
|
211
|
+
})
|
|
212
|
+
]
|
|
213
|
+
}),
|
|
214
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
215
|
+
className: "h-20 w-72 shrink-0"
|
|
216
|
+
})
|
|
217
|
+
]
|
|
218
|
+
})
|
|
219
|
+
}, row))
|
|
220
|
+
})
|
|
221
|
+
})
|
|
208
222
|
});
|
|
209
223
|
}
|
|
210
224
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/installed-integrations-section.tsx"],"sourcesContent":["import {QueryLoadError} from '@shipfox/client-ui';\nimport {IntegrationIcon} from '@shipfox/integration-icons';\nimport {IconButton} from '@shipfox/react-ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@shipfox/react-ui/dropdown-menu';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport {Skeleton} from '@shipfox/react-ui/skeleton';\nimport {Header, Text} from '@shipfox/react-ui/typography';\nimport {cn, formatDate} from '@shipfox/react-ui/utils';\nimport {Link} from '@tanstack/react-router';\nimport {ConnectionStatusBadge} from '#connection-status-badge.js';\nimport {type IntegrationConnection, isUsableConnection} from '#core/models.js';\nimport {usageEventsForConnection} from './integration-usage-events.js';\n\ninterface InstalledIntegrationsSectionProps {\n workspaceSlug?: string | undefined;\n connections: IntegrationConnection[];\n isPending: boolean;\n isFetching: boolean;\n error?: Error | null | undefined;\n onRetry: () => void;\n isMutating: boolean;\n onUse: (connectionId: string) => void;\n onSetActive: (connection: IntegrationConnection, active: boolean) => void;\n onDelete: (connectionId: string) => void;\n providerDisplayName: (provider: string) => string | undefined;\n}\n\nconst INSTALLED_SURFACE_CLASS =\n 'overflow-hidden rounded-8 border border-border-neutral-base bg-background-neutral-base';\n\nexport function InstalledIntegrationsSection({\n workspaceSlug,\n connections,\n isPending,\n isFetching,\n error,\n onRetry,\n isMutating,\n onUse,\n onSetActive,\n onDelete,\n providerDisplayName,\n}: InstalledIntegrationsSectionProps) {\n return (\n <section className=\"flex flex-col gap-group\" aria-label=\"Installed integrations\">\n <div className=\"flex flex-col gap-tight\">\n <Header variant=\"h3\">Installed integrations</Header>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Provider accounts installed in this workspace.\n </Text>\n </div>\n\n {isPending ? <InstalledSkeleton label=\"Loading integrations\" /> : null}\n\n {error ? (\n <div className={cn(INSTALLED_SURFACE_CLASS, 'px-row')}>\n <QueryLoadError\n query={{isError: true, isFetching, data: undefined, error, refetch: onRetry}}\n subject=\"integrations\"\n />\n </div>\n ) : null}\n\n {!isPending && !error && connections.length === 0 ? (\n <div className={cn(INSTALLED_SURFACE_CLASS, 'px-row')}>\n <EmptyState\n icon=\"componentLine\"\n title=\"No integrations installed yet\"\n description=\"Install a provider below to get started.\"\n />\n </div>\n ) : null}\n\n {connections.length > 0 ? (\n <ul className={cn('divide-y divide-border-neutral-base', INSTALLED_SURFACE_CLASS)}>\n {connections.map((connection) => (\n <InstalledRow\n key={connection.id}\n connection={connection}\n workspaceSlug={workspaceSlug}\n isMutating={isMutating}\n onUse={onUse}\n onSetActive={(nextActive) => onSetActive(connection, nextActive)}\n onDelete={onDelete}\n providerDisplayName={providerDisplayName}\n />\n ))}\n </ul>\n ) : null}\n </section>\n );\n}\n\nfunction InstalledRow({\n connection,\n workspaceSlug,\n isMutating,\n onUse,\n onSetActive,\n onDelete,\n providerDisplayName,\n}: {\n connection: IntegrationConnection;\n workspaceSlug?: string | undefined;\n isMutating: boolean;\n onUse: (connectionId: string) => void;\n onSetActive: (active: boolean) => void;\n onDelete: (connectionId: string) => void;\n providerDisplayName: (provider: string) => string | undefined;\n}) {\n const muted = connection.lifecycleStatus === 'disabled';\n const active = isUsableConnection(connection);\n const recentEventsEvent = usageEventsForConnection(connection)[0]?.value ?? 'received';\n const providerName = providerDisplayName(connection.provider);\n\n return (\n <li className=\"flex items-center gap-cluster px-row py-row transition-colors hover:bg-background-components-hover\">\n <IntegrationIcon\n source={connection.provider}\n aria-hidden\n className={cn(\n 'size-24 shrink-0',\n muted ? 'text-foreground-neutral-disabled' : 'text-foreground-neutral-base',\n )}\n />\n <div className=\"flex min-w-0 flex-1 flex-col gap-tight\">\n <div className=\"flex min-w-0 items-center gap-inline\">\n <Text\n size=\"md\"\n bold\n className={cn('truncate', muted ? 'text-foreground-neutral-disabled' : undefined)}\n >\n {connection.displayName}\n </Text>\n <ConnectionStatusBadge status={connection.lifecycleStatus} className=\"shrink-0\" />\n </div>\n <Text size=\"sm\" className=\"truncate text-foreground-neutral-muted\">\n Added {formatDate(connection.createdAt)}\n </Text>\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <IconButton\n size=\"sm\"\n variant=\"transparent\"\n icon=\"more2Line\"\n aria-label={`Open ${connection.displayName} integration actions`}\n />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {connection.externalUrl ? (\n <DropdownMenuItem asChild>\n <a href={connection.externalUrl} target=\"_blank\" rel=\"noreferrer noopener\">\n {providerName ? `Open in ${providerName}` : 'Open provider settings'}\n </a>\n </DropdownMenuItem>\n ) : null}\n <DropdownMenuItem onSelect={() => onUse(connection.id)}>\n Use this integration\n </DropdownMenuItem>\n {workspaceSlug ? (\n <DropdownMenuItem asChild>\n <Link\n to=\"/w/$workspaceSlug/settings/events\"\n params={{workspaceSlug}}\n search={{source: [connection.slug], event: [recentEventsEvent]}}\n >\n View recent events\n </Link>\n </DropdownMenuItem>\n ) : null}\n <DropdownMenuSeparator />\n <DropdownMenuItem disabled={isMutating} onSelect={() => onSetActive(!active)}>\n {active ? 'Disable integration' : 'Enable integration'}\n </DropdownMenuItem>\n <DropdownMenuItem disabled={isMutating} onSelect={() => onDelete(connection.id)}>\n Delete integration\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </li>\n );\n}\n\nfunction InstalledSkeleton({label}: {label: string}) {\n return (\n <ul\n role=\"status\"\n aria-label={label}\n className={cn('divide-y divide-border-neutral-base', INSTALLED_SURFACE_CLASS)}\n >\n {[0, 1, 2].map((row) => (\n <li key={row} className=\"flex items-center gap-cluster px-row py-row\">\n <Skeleton className=\"size-24 shrink-0\" />\n <div className=\"flex min-w-0 flex-1 flex-col gap-tight\">\n <Skeleton className=\"h-16 w-120\" />\n <Skeleton className=\"h-12 w-80\" />\n </div>\n <Skeleton className=\"h-20 w-72 shrink-0\" />\n </li>\n ))}\n </ul>\n );\n}\n"],"names":["QueryLoadError","IntegrationIcon","IconButton","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuSeparator","DropdownMenuTrigger","EmptyState","Skeleton","Header","Text","cn","formatDate","Link","ConnectionStatusBadge","isUsableConnection","usageEventsForConnection","INSTALLED_SURFACE_CLASS","InstalledIntegrationsSection","workspaceSlug","connections","isPending","isFetching","error","onRetry","isMutating","onUse","onSetActive","onDelete","providerDisplayName","section","className","aria-label","div","variant","size","InstalledSkeleton","label","query","isError","data","undefined","refetch","subject","length","icon","title","description","ul","map","connection","InstalledRow","nextActive","id","muted","lifecycleStatus","active","recentEventsEvent","value","providerName","provider","li","source","aria-hidden","bold","displayName","status","createdAt","asChild","align","externalUrl","a","href","target","rel","onSelect","to","params","search","slug","event","disabled","role","row"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/components/installed-integrations-section.tsx"],"sourcesContent":["import {QueryLoadError} from '@shipfox/client-ui';\nimport {IntegrationIcon} from '@shipfox/integration-icons';\nimport {IconButton} from '@shipfox/react-ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@shipfox/react-ui/dropdown-menu';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport {Panel, PanelBody, PanelRow} from '@shipfox/react-ui/panel';\nimport {Skeleton} from '@shipfox/react-ui/skeleton';\nimport {Header, Text} from '@shipfox/react-ui/typography';\nimport {cn, formatDate} from '@shipfox/react-ui/utils';\nimport {Link} from '@tanstack/react-router';\nimport {ConnectionStatusBadge} from '#connection-status-badge.js';\nimport {type IntegrationConnection, isUsableConnection} from '#core/models.js';\nimport {usageEventsForConnection} from './integration-usage-events.js';\n\ninterface InstalledIntegrationsSectionProps {\n workspaceSlug?: string | undefined;\n connections: IntegrationConnection[];\n isPending: boolean;\n isFetching: boolean;\n error?: Error | null | undefined;\n onRetry: () => void;\n isMutating: boolean;\n onUse: (connectionId: string) => void;\n onSetActive: (connection: IntegrationConnection, active: boolean) => void;\n onDelete: (connectionId: string) => void;\n providerDisplayName: (provider: string) => string | undefined;\n}\n\nexport function InstalledIntegrationsSection({\n workspaceSlug,\n connections,\n isPending,\n isFetching,\n error,\n onRetry,\n isMutating,\n onUse,\n onSetActive,\n onDelete,\n providerDisplayName,\n}: InstalledIntegrationsSectionProps) {\n return (\n <section className=\"flex flex-col gap-group\" aria-label=\"Installed integrations\">\n <div className=\"flex flex-col gap-tight\">\n <Header variant=\"h3\">Installed integrations</Header>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Provider accounts installed in this workspace.\n </Text>\n </div>\n\n {isPending ? <InstalledSkeleton label=\"Loading integrations\" /> : null}\n\n {error ? (\n <Panel>\n <QueryLoadError\n query={{isError: true, isFetching, data: undefined, error, refetch: onRetry}}\n subject=\"integrations\"\n variant=\"panel\"\n />\n </Panel>\n ) : null}\n\n {!isPending && !error && connections.length === 0 ? (\n <Panel>\n <EmptyState\n icon=\"componentLine\"\n title=\"No integrations installed yet\"\n description=\"Install a provider below to get started.\"\n variant=\"panel\"\n />\n </Panel>\n ) : null}\n\n {connections.length > 0 ? (\n <Panel>\n <PanelBody asChild>\n <ul>\n {connections.map((connection) => (\n <InstalledRow\n key={connection.id}\n connection={connection}\n workspaceSlug={workspaceSlug}\n isMutating={isMutating}\n onUse={onUse}\n onSetActive={(nextActive) => onSetActive(connection, nextActive)}\n onDelete={onDelete}\n providerDisplayName={providerDisplayName}\n />\n ))}\n </ul>\n </PanelBody>\n </Panel>\n ) : null}\n </section>\n );\n}\n\nfunction InstalledRow({\n connection,\n workspaceSlug,\n isMutating,\n onUse,\n onSetActive,\n onDelete,\n providerDisplayName,\n}: {\n connection: IntegrationConnection;\n workspaceSlug?: string | undefined;\n isMutating: boolean;\n onUse: (connectionId: string) => void;\n onSetActive: (active: boolean) => void;\n onDelete: (connectionId: string) => void;\n providerDisplayName: (provider: string) => string | undefined;\n}) {\n const muted = connection.lifecycleStatus === 'disabled';\n const active = isUsableConnection(connection);\n const recentEventsEvent = usageEventsForConnection(connection)[0]?.value ?? 'received';\n const providerName = providerDisplayName(connection.provider);\n\n return (\n <PanelRow asChild className=\"justify-start gap-cluster\">\n <li>\n <IntegrationIcon\n source={connection.provider}\n aria-hidden\n className={cn(\n 'size-24 shrink-0',\n muted ? 'text-foreground-neutral-disabled' : 'text-foreground-neutral-base',\n )}\n />\n <div className=\"flex min-w-0 flex-1 flex-col gap-tight\">\n <div className=\"flex min-w-0 items-center gap-inline\">\n <Text\n size=\"md\"\n bold\n className={cn('truncate', muted ? 'text-foreground-neutral-disabled' : undefined)}\n >\n {connection.displayName}\n </Text>\n <ConnectionStatusBadge status={connection.lifecycleStatus} className=\"shrink-0\" />\n </div>\n <Text size=\"sm\" className=\"truncate text-foreground-neutral-muted\">\n Added {formatDate(connection.createdAt)}\n </Text>\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <IconButton\n size=\"sm\"\n variant=\"transparent\"\n icon=\"more2Line\"\n aria-label={`Open ${connection.displayName} integration actions`}\n />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {connection.externalUrl ? (\n <DropdownMenuItem asChild>\n <a href={connection.externalUrl} target=\"_blank\" rel=\"noreferrer noopener\">\n {providerName ? `Open in ${providerName}` : 'Open provider settings'}\n </a>\n </DropdownMenuItem>\n ) : null}\n <DropdownMenuItem onSelect={() => onUse(connection.id)}>\n Use this integration\n </DropdownMenuItem>\n {workspaceSlug ? (\n <DropdownMenuItem asChild>\n <Link\n to=\"/w/$workspaceSlug/settings/events\"\n params={{workspaceSlug}}\n search={{source: [connection.slug], event: [recentEventsEvent]}}\n >\n View recent events\n </Link>\n </DropdownMenuItem>\n ) : null}\n <DropdownMenuSeparator />\n <DropdownMenuItem disabled={isMutating} onSelect={() => onSetActive(!active)}>\n {active ? 'Disable integration' : 'Enable integration'}\n </DropdownMenuItem>\n <DropdownMenuItem disabled={isMutating} onSelect={() => onDelete(connection.id)}>\n Delete integration\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </li>\n </PanelRow>\n );\n}\n\nfunction InstalledSkeleton({label}: {label: string}) {\n return (\n <Panel>\n <PanelBody asChild>\n <ul role=\"status\" aria-label={label}>\n {[0, 1, 2].map((row) => (\n <PanelRow\n asChild\n className=\"justify-start gap-cluster hover:bg-background-neutral-base\"\n key={row}\n >\n <li>\n <Skeleton className=\"size-24 shrink-0\" />\n <div className=\"flex min-w-0 flex-1 flex-col gap-tight\">\n <Skeleton className=\"h-16 w-120\" />\n <Skeleton className=\"h-12 w-80\" />\n </div>\n <Skeleton className=\"h-20 w-72 shrink-0\" />\n </li>\n </PanelRow>\n ))}\n </ul>\n </PanelBody>\n </Panel>\n );\n}\n"],"names":["QueryLoadError","IntegrationIcon","IconButton","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuSeparator","DropdownMenuTrigger","EmptyState","Panel","PanelBody","PanelRow","Skeleton","Header","Text","cn","formatDate","Link","ConnectionStatusBadge","isUsableConnection","usageEventsForConnection","InstalledIntegrationsSection","workspaceSlug","connections","isPending","isFetching","error","onRetry","isMutating","onUse","onSetActive","onDelete","providerDisplayName","section","className","aria-label","div","variant","size","InstalledSkeleton","label","query","isError","data","undefined","refetch","subject","length","icon","title","description","asChild","ul","map","connection","InstalledRow","nextActive","id","muted","lifecycleStatus","active","recentEventsEvent","value","providerName","provider","li","source","aria-hidden","bold","displayName","status","createdAt","align","externalUrl","a","href","target","rel","onSelect","to","params","search","slug","event","disabled","role","row"],"mappings":"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"}
|
|
@@ -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;AA0BrD,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;;;;QAGK,MAAM;;;;;CAE2B,CAAC;eAElC,IAAI;AACnB,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;AAEF,eAAO,MAAM,kCAAkC,EAAE,
|
|
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;AA0BrD,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;;;;QAGK,MAAM;;;;;CAE2B,CAAC;eAElC,IAAI;AACnB,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;AAEF,eAAO,MAAM,kCAAkC,EAAE,KAsBhD,CAAC"}
|
|
@@ -6,7 +6,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
|
6
6
|
import { createMemoryHistory, createRootRoute, createRoute, createRouter, Outlet, RouterProvider } from '@tanstack/react-router';
|
|
7
7
|
import { createStore, Provider as JotaiProvider } from 'jotai';
|
|
8
8
|
import { useMemo } from 'react';
|
|
9
|
-
import { expect, screen, userEvent, within } from 'storybook/test';
|
|
9
|
+
import { expect, screen, userEvent, waitFor, within } from 'storybook/test';
|
|
10
10
|
import { IntegrationGallery } from './integration-gallery.js';
|
|
11
11
|
const WORKSPACE_ID = '11111111-1111-4111-8111-111111111111';
|
|
12
12
|
const WORKSPACE_PATH = '/w/acme/settings/integrations';
|
|
@@ -198,7 +198,12 @@ export const UsageModalCloseRestoresInteraction = {
|
|
|
198
198
|
expect(screen.queryByRole('dialog', {
|
|
199
199
|
name: 'Use acme-corp'
|
|
200
200
|
})).not.toBeInTheDocument();
|
|
201
|
-
|
|
201
|
+
// The dialog unmounts before its dismissable layer releases the body, so
|
|
202
|
+
// wait for the release rather than asserting it on the same tick: clicking
|
|
203
|
+
// while `pointer-events: none` is still set is swallowed silently.
|
|
204
|
+
await waitFor(()=>{
|
|
205
|
+
expect(document.body.style.pointerEvents).not.toBe('none');
|
|
206
|
+
});
|
|
202
207
|
await user.click(actionsButton);
|
|
203
208
|
await screen.findByRole('menuitem', {
|
|
204
209
|
name: 'Use this integration'
|