@shipfox/client-integrations 12.0.2 → 14.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 +52 -0
- package/dist/application/complete-integration-callback.d.ts +11 -0
- package/dist/application/complete-integration-callback.d.ts.map +1 -1
- package/dist/application/complete-integration-callback.js +38 -8
- package/dist/application/complete-integration-callback.js.map +1 -1
- package/dist/components/callback-status-shell.d.ts +4 -3
- package/dist/components/callback-status-shell.d.ts.map +1 -1
- package/dist/components/callback-status-shell.js +11 -11
- package/dist/components/callback-status-shell.js.map +1 -1
- package/dist/components/installed-integrations-section.d.ts +2 -1
- package/dist/components/installed-integrations-section.d.ts.map +1 -1
- package/dist/components/installed-integrations-section.js +7 -6
- package/dist/components/installed-integrations-section.js.map +1 -1
- package/dist/components/integration-gallery-for-workspace.d.ts.map +1 -1
- package/dist/components/integration-gallery-for-workspace.js +11 -2
- package/dist/components/integration-gallery-for-workspace.js.map +1 -1
- package/dist/components/integration-gallery.stories.js +10 -9
- package/dist/components/integration-gallery.stories.js.map +1 -1
- package/dist/components/provider-grid.d.ts +2 -2
- package/dist/components/provider-grid.d.ts.map +1 -1
- package/dist/components/provider-grid.js +4 -4
- package/dist/components/provider-grid.js.map +1 -1
- package/dist/components/redirect-install-page.d.ts +1 -1
- package/dist/components/redirect-install-page.js +2 -2
- package/dist/components/redirect-install-page.js.map +1 -1
- package/dist/components/webhook/webhook-modals.stories.js +2 -2
- package/dist/components/webhook/webhook-modals.stories.js.map +1 -1
- package/dist/core/models.d.ts +6 -0
- package/dist/core/models.d.ts.map +1 -1
- package/dist/core/models.js +12 -0
- package/dist/core/models.js.map +1 -1
- package/dist/feature.d.ts +15 -7
- package/dist/feature.d.ts.map +1 -1
- package/dist/feature.js +17 -7
- package/dist/feature.js.map +1 -1
- package/dist/hooks/api/integration-mapper.d.ts +3 -1
- package/dist/hooks/api/integration-mapper.d.ts.map +1 -1
- package/dist/hooks/api/integration-mapper.js +8 -0
- package/dist/hooks/api/integration-mapper.js.map +1 -1
- package/dist/hooks/api/integrations.d.ts +25 -1
- package/dist/hooks/api/integrations.d.ts.map +1 -1
- package/dist/hooks/api/integrations.js +45 -2
- package/dist/hooks/api/integrations.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/jira-callback-state.d.ts +9 -0
- package/dist/jira-callback-state.d.ts.map +1 -0
- package/dist/jira-callback-state.js +16 -0
- package/dist/jira-callback-state.js.map +1 -0
- package/dist/jira-callback.d.ts +11 -0
- package/dist/jira-callback.d.ts.map +1 -0
- package/dist/jira-callback.js +59 -0
- package/dist/jira-callback.js.map +1 -0
- package/dist/jira-form-errors.d.ts +8 -0
- package/dist/jira-form-errors.d.ts.map +1 -0
- package/dist/jira-form-errors.js +55 -0
- package/dist/jira-form-errors.js.map +1 -0
- package/dist/pages/gitea-install-page.js +4 -4
- package/dist/pages/gitea-install-page.js.map +1 -1
- package/dist/pages/jira-callback-page.d.ts +2 -0
- package/dist/pages/jira-callback-page.d.ts.map +1 -0
- package/dist/pages/jira-callback-page.js +341 -0
- package/dist/pages/jira-callback-page.js.map +1 -0
- package/dist/pages/jira-install-page.d.ts +2 -0
- package/dist/pages/jira-install-page.d.ts.map +1 -0
- package/dist/pages/jira-install-page.js +26 -0
- package/dist/pages/jira-install-page.js.map +1 -0
- package/dist/pages/linear-callback-page.d.ts.map +1 -1
- package/dist/pages/linear-callback-page.js +58 -12
- package/dist/pages/linear-callback-page.js.map +1 -1
- package/dist/pages/sentry-callback-page.d.ts.map +1 -1
- package/dist/pages/sentry-callback-page.js +22 -9
- package/dist/pages/sentry-callback-page.js.map +1 -1
- package/dist/pages/slack-callback-page.d.ts.map +1 -1
- package/dist/pages/slack-callback-page.js +50 -18
- package/dist/pages/slack-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/provider-catalog.d.ts +1 -1
- package/dist/provider-catalog.d.ts.map +1 -1
- package/dist/provider-catalog.js +10 -5
- package/dist/provider-catalog.js.map +1 -1
- package/dist/routes/jira-callback.d.ts +8 -0
- package/dist/routes/jira-callback.d.ts.map +1 -0
- package/dist/routes/jira-callback.js +9 -0
- package/dist/routes/jira-callback.js.map +1 -0
- package/dist/routes/jira.d.ts +6 -0
- package/dist/routes/jira.d.ts.map +1 -0
- package/dist/routes/jira.js +7 -0
- package/dist/routes/jira.js.map +1 -0
- package/dist/sentry-callback.js +2 -2
- package/dist/sentry-callback.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/dist/workspace-navigation.d.ts +13 -0
- package/dist/workspace-navigation.d.ts.map +1 -0
- package/dist/workspace-navigation.js +17 -0
- package/dist/workspace-navigation.js.map +1 -0
- package/package.json +14 -13
- package/src/application/complete-integration-callback.test.ts +44 -1
- package/src/application/complete-integration-callback.ts +61 -8
- package/src/components/callback-status-shell.tsx +17 -10
- package/src/components/installed-integrations-section.tsx +16 -9
- package/src/components/integration-gallery-for-workspace.tsx +20 -10
- package/src/components/integration-gallery.stories.tsx +10 -10
- package/src/components/integration-gallery.test.tsx +30 -15
- package/src/components/integration-usage-events.test.ts +13 -0
- package/src/components/provider-grid.tsx +6 -6
- package/src/components/redirect-install-page.test.tsx +3 -3
- package/src/components/redirect-install-page.tsx +2 -2
- package/src/components/webhook/webhook-modals.stories.tsx +2 -2
- package/src/core/models.ts +18 -0
- package/src/feature.ts +17 -7
- package/src/hooks/api/integration-mapper.ts +6 -0
- package/src/hooks/api/integrations.test.ts +92 -0
- package/src/hooks/api/integrations.ts +72 -1
- package/src/index.ts +4 -0
- package/src/jira-callback-state.ts +19 -0
- package/src/jira-callback.test.ts +76 -0
- package/src/jira-callback.ts +67 -0
- package/src/jira-form-errors.test.ts +57 -0
- package/src/jira-form-errors.ts +94 -0
- package/src/pages/gitea-install-page.tsx +2 -2
- package/src/pages/jira-callback-page.test.tsx +250 -0
- package/src/pages/jira-callback-page.tsx +366 -0
- package/src/pages/jira-install-page.tsx +28 -0
- package/src/pages/linear-callback-page.test.tsx +25 -12
- package/src/pages/linear-callback-page.tsx +73 -12
- package/src/pages/sentry-callback-page.test.tsx +8 -5
- package/src/pages/sentry-callback-page.tsx +32 -8
- package/src/pages/slack-callback-page.test.tsx +78 -0
- package/src/pages/slack-callback-page.tsx +56 -18
- package/src/pages/source-control-onboarding-page.test.tsx +4 -4
- package/src/pages/source-control-onboarding-page.tsx +1 -1
- package/src/provider-catalog.test.ts +10 -4
- package/src/provider-catalog.ts +16 -10
- package/src/routes/jira-callback.tsx +8 -0
- package/src/routes/jira.tsx +4 -0
- package/src/sentry-callback.ts +2 -2
- package/src/workspace-navigation.test.ts +43 -0
- package/src/workspace-navigation.ts +38 -0
- package/test/render.tsx +2 -1
- 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: 59 files with swc (445.33ms)
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,57 @@
|
|
|
1
1
|
# @shipfox/client-integrations
|
|
2
2
|
|
|
3
|
+
## 14.0.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 1267eb3: Adds Jira connection flows and provider icons to workspace integrations settings.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [baa7594]
|
|
12
|
+
- Updated dependencies [f8a98cb]
|
|
13
|
+
- Updated dependencies [1267eb3]
|
|
14
|
+
- Updated dependencies [b2d4550]
|
|
15
|
+
- @shipfox/react-ui@0.5.0
|
|
16
|
+
- @shipfox/client-ui@14.0.0
|
|
17
|
+
- @shipfox/integration-icons@0.3.0
|
|
18
|
+
- @shipfox/client-auth@14.0.0
|
|
19
|
+
- @shipfox/client-shell@14.0.0
|
|
20
|
+
|
|
21
|
+
## 13.0.0
|
|
22
|
+
|
|
23
|
+
### Major Changes
|
|
24
|
+
|
|
25
|
+
- e405e92: Move client routes to slug-based `/w/$workspaceSlug` and `/p/$projectSlug` URLs, enforce the new composition contract, and support bounded project-slug resolution.
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- f78740d: Remove Unicode dash punctuation from package prose and source comments.
|
|
30
|
+
- Updated dependencies [e405e92]
|
|
31
|
+
- Updated dependencies [f78740d]
|
|
32
|
+
- Updated dependencies [9969937]
|
|
33
|
+
- Updated dependencies [3c73365]
|
|
34
|
+
- Updated dependencies [f13e8bb]
|
|
35
|
+
- Updated dependencies [869a792]
|
|
36
|
+
- Updated dependencies [54c820e]
|
|
37
|
+
- Updated dependencies [6adc228]
|
|
38
|
+
- Updated dependencies [032d316]
|
|
39
|
+
- Updated dependencies [54c820e]
|
|
40
|
+
- Updated dependencies [cb0abfa]
|
|
41
|
+
- Updated dependencies [e1efaee]
|
|
42
|
+
- @shipfox/client-auth@13.0.0
|
|
43
|
+
- @shipfox/client-shell@13.0.0
|
|
44
|
+
- @shipfox/api-integration-sentry-dto@12.0.0
|
|
45
|
+
- @shipfox/client-ui@13.0.0
|
|
46
|
+
- @shipfox/react-ui@0.4.0
|
|
47
|
+
- @shipfox/api-integration-core-dto@12.0.0
|
|
48
|
+
- @shipfox/api-integration-github-dto@12.0.0
|
|
49
|
+
- @shipfox/integration-icons@0.2.3
|
|
50
|
+
- @shipfox/api-integration-gitea-dto@12.0.0
|
|
51
|
+
- @shipfox/api-integration-linear-dto@12.0.0
|
|
52
|
+
- @shipfox/api-integration-slack-dto@12.0.0
|
|
53
|
+
- @shipfox/api-integration-webhook-dto@12.0.0
|
|
54
|
+
|
|
3
55
|
## 12.0.2
|
|
4
56
|
|
|
5
57
|
### Patch Changes
|
|
@@ -8,6 +8,17 @@ export interface CompleteIntegrationCallbackOptions<TInput> {
|
|
|
8
8
|
complete: (input: TInput, accessToken: string) => Promise<IntegrationConnection>;
|
|
9
9
|
queryClient: QueryClient;
|
|
10
10
|
}
|
|
11
|
+
export interface CompleteIntegrationCallbackResultOptions<TInput, TResult> {
|
|
12
|
+
input: TInput;
|
|
13
|
+
refreshAuth: () => Promise<{
|
|
14
|
+
accessToken: string;
|
|
15
|
+
}>;
|
|
16
|
+
complete: (input: TInput, accessToken: string) => Promise<TResult>;
|
|
17
|
+
getConnection: (result: TResult) => IntegrationConnection | undefined;
|
|
18
|
+
queryClient: QueryClient;
|
|
19
|
+
}
|
|
11
20
|
export declare function completeIntegrationCallback<TInput>({ input, refreshAuth, complete, queryClient, }: CompleteIntegrationCallbackOptions<TInput>): Promise<IntegrationConnection>;
|
|
21
|
+
export declare function completeIntegrationCallbackResult<TInput, TResult>({ input, refreshAuth, complete, getConnection, queryClient, }: CompleteIntegrationCallbackResultOptions<TInput, TResult>): Promise<TResult>;
|
|
12
22
|
export declare function useCompleteIntegrationCallback(): <TInput>(options: Omit<CompleteIntegrationCallbackOptions<TInput>, "queryClient">) => Promise<IntegrationConnection>;
|
|
23
|
+
export declare function useCompleteIntegrationCallbackResult(): <TInput, TResult>(options: Omit<CompleteIntegrationCallbackResultOptions<TInput, TResult>, "queryClient">) => Promise<TResult>;
|
|
13
24
|
//# sourceMappingURL=complete-integration-callback.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"complete-integration-callback.d.ts","sourceRoot":"","sources":["../../src/application/complete-integration-callback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,WAAW,EAAiB,MAAM,uBAAuB,CAAC;AAEvE,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,iBAAiB,CAAC;AAG3D,MAAM,WAAW,kCAAkC,CAAC,MAAM;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAC,CAAC,CAAC;IAClD,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACjF,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,wBAAsB,2BAA2B,CAAC,MAAM,EAAE,EACxD,KAAK,EACL,WAAW,EACX,QAAQ,EACR,WAAW,GACZ,EAAE,kCAAkC,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,qBAAqB,CAAC,
|
|
1
|
+
{"version":3,"file":"complete-integration-callback.d.ts","sourceRoot":"","sources":["../../src/application/complete-integration-callback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,WAAW,EAAiB,MAAM,uBAAuB,CAAC;AAEvE,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,iBAAiB,CAAC;AAG3D,MAAM,WAAW,kCAAkC,CAAC,MAAM;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAC,CAAC,CAAC;IAClD,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACjF,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,MAAM,WAAW,wCAAwC,CAAC,MAAM,EAAE,OAAO;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAC,CAAC,CAAC;IAClD,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACnE,aAAa,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,qBAAqB,GAAG,SAAS,CAAC;IACtE,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,wBAAsB,2BAA2B,CAAC,MAAM,EAAE,EACxD,KAAK,EACL,WAAW,EACX,QAAQ,EACR,WAAW,GACZ,EAAE,kCAAkC,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAQ7E;AAED,wBAAsB,iCAAiC,CAAC,MAAM,EAAE,OAAO,EAAE,EACvE,KAAK,EACL,WAAW,EACX,QAAQ,EACR,aAAa,EACb,WAAW,GACZ,EAAE,wCAAwC,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ9E;AAwBD,wBAAgB,8BAA8B,KAGnC,MAAM,WACF,IAAI,CAAC,kCAAkC,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,KACvE,OAAO,CAAC,qBAAqB,CAAC,CAGpC;AAED,wBAAgB,oCAAoC,KAGzC,MAAM,EAAE,OAAO,WACX,IAAI,CAAC,wCAAwC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,CAAC,KACtF,OAAO,CAAC,OAAO,CAAC,CAGtB"}
|
|
@@ -2,16 +2,37 @@ import { useQueryClient } from '@tanstack/react-query';
|
|
|
2
2
|
import { useCallback } from 'react';
|
|
3
3
|
import { integrationsQueryKeys } from '#hooks/api/integrations.js';
|
|
4
4
|
export async function completeIntegrationCallback({ input, refreshAuth, complete, queryClient }) {
|
|
5
|
+
return await completeIntegrationCallbackResultInternal({
|
|
6
|
+
input,
|
|
7
|
+
refreshAuth,
|
|
8
|
+
complete,
|
|
9
|
+
getConnection: (result)=>result,
|
|
10
|
+
queryClient
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
export async function completeIntegrationCallbackResult({ input, refreshAuth, complete, getConnection, queryClient }) {
|
|
14
|
+
return await completeIntegrationCallbackResultInternal({
|
|
15
|
+
input,
|
|
16
|
+
refreshAuth,
|
|
17
|
+
complete,
|
|
18
|
+
getConnection,
|
|
19
|
+
queryClient
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
async function completeIntegrationCallbackResultInternal({ input, refreshAuth, complete, getConnection, queryClient }) {
|
|
5
23
|
const session = await refreshAuth();
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
24
|
+
const result = await complete(input, session.accessToken);
|
|
25
|
+
const connection = getConnection(result);
|
|
26
|
+
if (connection) {
|
|
27
|
+
try {
|
|
28
|
+
await queryClient.invalidateQueries({
|
|
29
|
+
queryKey: integrationsQueryKeys.connectionsByWorkspace(connection.workspaceId)
|
|
30
|
+
});
|
|
31
|
+
} catch {
|
|
32
|
+
// Cache refresh is best effort: the callback is already committed server-side.
|
|
33
|
+
}
|
|
13
34
|
}
|
|
14
|
-
return
|
|
35
|
+
return result;
|
|
15
36
|
}
|
|
16
37
|
export function useCompleteIntegrationCallback() {
|
|
17
38
|
const queryClient = useQueryClient();
|
|
@@ -22,5 +43,14 @@ export function useCompleteIntegrationCallback() {
|
|
|
22
43
|
queryClient
|
|
23
44
|
]);
|
|
24
45
|
}
|
|
46
|
+
export function useCompleteIntegrationCallbackResult() {
|
|
47
|
+
const queryClient = useQueryClient();
|
|
48
|
+
return useCallback(async (options)=>completeIntegrationCallbackResult({
|
|
49
|
+
...options,
|
|
50
|
+
queryClient
|
|
51
|
+
}), [
|
|
52
|
+
queryClient
|
|
53
|
+
]);
|
|
54
|
+
}
|
|
25
55
|
|
|
26
56
|
//# sourceMappingURL=complete-integration-callback.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/application/complete-integration-callback.ts"],"sourcesContent":["import {type QueryClient, useQueryClient} from '@tanstack/react-query';\nimport {useCallback} from 'react';\nimport type {IntegrationConnection} from '#core/models.js';\nimport {integrationsQueryKeys} from '#hooks/api/integrations.js';\n\nexport interface CompleteIntegrationCallbackOptions<TInput> {\n input: TInput;\n refreshAuth: () => Promise<{accessToken: string}>;\n complete: (input: TInput, accessToken: string) => Promise<IntegrationConnection>;\n queryClient: QueryClient;\n}\n\nexport async function completeIntegrationCallback<TInput>({\n input,\n refreshAuth,\n complete,\n queryClient,\n}: CompleteIntegrationCallbackOptions<TInput>): Promise<IntegrationConnection> {\n const session = await refreshAuth();\n const
|
|
1
|
+
{"version":3,"sources":["../../src/application/complete-integration-callback.ts"],"sourcesContent":["import {type QueryClient, useQueryClient} from '@tanstack/react-query';\nimport {useCallback} from 'react';\nimport type {IntegrationConnection} from '#core/models.js';\nimport {integrationsQueryKeys} from '#hooks/api/integrations.js';\n\nexport interface CompleteIntegrationCallbackOptions<TInput> {\n input: TInput;\n refreshAuth: () => Promise<{accessToken: string}>;\n complete: (input: TInput, accessToken: string) => Promise<IntegrationConnection>;\n queryClient: QueryClient;\n}\n\nexport interface CompleteIntegrationCallbackResultOptions<TInput, TResult> {\n input: TInput;\n refreshAuth: () => Promise<{accessToken: string}>;\n complete: (input: TInput, accessToken: string) => Promise<TResult>;\n getConnection: (result: TResult) => IntegrationConnection | undefined;\n queryClient: QueryClient;\n}\n\nexport async function completeIntegrationCallback<TInput>({\n input,\n refreshAuth,\n complete,\n queryClient,\n}: CompleteIntegrationCallbackOptions<TInput>): Promise<IntegrationConnection> {\n return await completeIntegrationCallbackResultInternal({\n input,\n refreshAuth,\n complete,\n getConnection: (result) => result,\n queryClient,\n });\n}\n\nexport async function completeIntegrationCallbackResult<TInput, TResult>({\n input,\n refreshAuth,\n complete,\n getConnection,\n queryClient,\n}: CompleteIntegrationCallbackResultOptions<TInput, TResult>): Promise<TResult> {\n return await completeIntegrationCallbackResultInternal({\n input,\n refreshAuth,\n complete,\n getConnection,\n queryClient,\n });\n}\n\nasync function completeIntegrationCallbackResultInternal<TInput, TResult>({\n input,\n refreshAuth,\n complete,\n getConnection,\n queryClient,\n}: CompleteIntegrationCallbackResultOptions<TInput, TResult>): Promise<TResult> {\n const session = await refreshAuth();\n const result = await complete(input, session.accessToken);\n const connection = getConnection(result);\n if (connection) {\n try {\n await queryClient.invalidateQueries({\n queryKey: integrationsQueryKeys.connectionsByWorkspace(connection.workspaceId),\n });\n } catch {\n // Cache refresh is best effort: the callback is already committed server-side.\n }\n }\n return result;\n}\n\nexport function useCompleteIntegrationCallback() {\n const queryClient = useQueryClient();\n return useCallback(\n async <TInput>(\n options: Omit<CompleteIntegrationCallbackOptions<TInput>, 'queryClient'>,\n ): Promise<IntegrationConnection> => completeIntegrationCallback({...options, queryClient}),\n [queryClient],\n );\n}\n\nexport function useCompleteIntegrationCallbackResult() {\n const queryClient = useQueryClient();\n return useCallback(\n async <TInput, TResult>(\n options: Omit<CompleteIntegrationCallbackResultOptions<TInput, TResult>, 'queryClient'>,\n ): Promise<TResult> => completeIntegrationCallbackResult({...options, queryClient}),\n [queryClient],\n );\n}\n"],"names":["useQueryClient","useCallback","integrationsQueryKeys","completeIntegrationCallback","input","refreshAuth","complete","queryClient","completeIntegrationCallbackResultInternal","getConnection","result","completeIntegrationCallbackResult","session","accessToken","connection","invalidateQueries","queryKey","connectionsByWorkspace","workspaceId","useCompleteIntegrationCallback","options","useCompleteIntegrationCallbackResult"],"mappings":"AAAA,SAA0BA,cAAc,QAAO,wBAAwB;AACvE,SAAQC,WAAW,QAAO,QAAQ;AAElC,SAAQC,qBAAqB,QAAO,6BAA6B;AAiBjE,OAAO,eAAeC,4BAAoC,EACxDC,KAAK,EACLC,WAAW,EACXC,QAAQ,EACRC,WAAW,EACgC;IAC3C,OAAO,MAAMC,0CAA0C;QACrDJ;QACAC;QACAC;QACAG,eAAe,CAACC,SAAWA;QAC3BH;IACF;AACF;AAEA,OAAO,eAAeI,kCAAmD,EACvEP,KAAK,EACLC,WAAW,EACXC,QAAQ,EACRG,aAAa,EACbF,WAAW,EAC+C;IAC1D,OAAO,MAAMC,0CAA0C;QACrDJ;QACAC;QACAC;QACAG;QACAF;IACF;AACF;AAEA,eAAeC,0CAA2D,EACxEJ,KAAK,EACLC,WAAW,EACXC,QAAQ,EACRG,aAAa,EACbF,WAAW,EAC+C;IAC1D,MAAMK,UAAU,MAAMP;IACtB,MAAMK,SAAS,MAAMJ,SAASF,OAAOQ,QAAQC,WAAW;IACxD,MAAMC,aAAaL,cAAcC;IACjC,IAAII,YAAY;QACd,IAAI;YACF,MAAMP,YAAYQ,iBAAiB,CAAC;gBAClCC,UAAUd,sBAAsBe,sBAAsB,CAACH,WAAWI,WAAW;YAC/E;QACF,EAAE,OAAM;QACN,+EAA+E;QACjF;IACF;IACA,OAAOR;AACT;AAEA,OAAO,SAASS;IACd,MAAMZ,cAAcP;IACpB,OAAOC,YACL,OACEmB,UACmCjB,4BAA4B;YAAC,GAAGiB,OAAO;YAAEb;QAAW,IACzF;QAACA;KAAY;AAEjB;AAEA,OAAO,SAASc;IACd,MAAMd,cAAcP;IACpB,OAAOC,YACL,OACEmB,UACqBT,kCAAkC;YAAC,GAAGS,OAAO;YAAEb;QAAW,IACjF;QAACA;KAAY;AAEjB"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export declare function CallbackStatusShell({ title, message, startOver, switchAccount,
|
|
1
|
+
export declare function CallbackStatusShell({ title, message, status, startOver, switchAccount, workspaceSlug, installPath, }: {
|
|
2
2
|
title: string;
|
|
3
3
|
message: string;
|
|
4
|
+
status?: 'error' | 'success';
|
|
4
5
|
startOver?: boolean;
|
|
5
6
|
switchAccount?: boolean;
|
|
6
|
-
|
|
7
|
-
installPath: '/
|
|
7
|
+
workspaceSlug?: string | undefined;
|
|
8
|
+
installPath: '/w/$workspaceSlug/integrations/linear' | '/w/$workspaceSlug/integrations/slack' | '/w/$workspaceSlug/integrations/jira';
|
|
8
9
|
}): import("react").JSX.Element;
|
|
9
10
|
//# sourceMappingURL=callback-status-shell.d.ts.map
|
|
@@ -1 +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,
|
|
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,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"}
|
|
@@ -4,18 +4,18 @@ import { Callout } from '@shipfox/react-ui/callout';
|
|
|
4
4
|
import { Text } from '@shipfox/react-ui/typography';
|
|
5
5
|
import { Link } from '@tanstack/react-router';
|
|
6
6
|
import { useEffect, useRef } from 'react';
|
|
7
|
-
export function CallbackStatusShell({ title, message, startOver, switchAccount,
|
|
7
|
+
export function CallbackStatusShell({ title, message, status = 'error', startOver, switchAccount, workspaceSlug, installPath }) {
|
|
8
8
|
const headingRef = useRef(null);
|
|
9
9
|
useEffect(()=>headingRef.current?.focus(), []);
|
|
10
10
|
const recoveryVariant = startOver || switchAccount ? 'muted' : 'base';
|
|
11
|
-
const settings =
|
|
11
|
+
const settings = workspaceSlug ? /*#__PURE__*/ _jsx(ButtonLink, {
|
|
12
12
|
asChild: true,
|
|
13
13
|
variant: recoveryVariant,
|
|
14
14
|
className: "min-h-44 w-full sm:w-fit",
|
|
15
15
|
children: /*#__PURE__*/ _jsx(Link, {
|
|
16
|
-
to: "/
|
|
16
|
+
to: "/w/$workspaceSlug/settings/integrations",
|
|
17
17
|
params: {
|
|
18
|
-
|
|
18
|
+
workspaceSlug
|
|
19
19
|
},
|
|
20
20
|
children: "Back to integrations"
|
|
21
21
|
})
|
|
@@ -28,7 +28,7 @@ export function CallbackStatusShell({ title, message, startOver, switchAccount,
|
|
|
28
28
|
children: "Back to Shipfox"
|
|
29
29
|
})
|
|
30
30
|
});
|
|
31
|
-
const logoutRedirect =
|
|
31
|
+
const logoutRedirect = workspaceSlug ? installPath.replace('$workspaceSlug', workspaceSlug) : undefined;
|
|
32
32
|
return /*#__PURE__*/ _jsx("main", {
|
|
33
33
|
className: "flex min-h-screen bg-background-subtle-base px-16 py-32",
|
|
34
34
|
children: /*#__PURE__*/ _jsxs("div", {
|
|
@@ -41,8 +41,8 @@ export function CallbackStatusShell({ title, message, startOver, switchAccount,
|
|
|
41
41
|
children: title
|
|
42
42
|
}),
|
|
43
43
|
/*#__PURE__*/ _jsx(Callout, {
|
|
44
|
-
role:
|
|
45
|
-
type:
|
|
44
|
+
role: status === 'error' ? 'alert' : 'status',
|
|
45
|
+
type: status,
|
|
46
46
|
children: /*#__PURE__*/ _jsx(Text, {
|
|
47
47
|
size: "sm",
|
|
48
48
|
children: message
|
|
@@ -56,19 +56,19 @@ export function CallbackStatusShell({ title, message, startOver, switchAccount,
|
|
|
56
56
|
className: "min-h-44 w-full sm:w-fit",
|
|
57
57
|
children: /*#__PURE__*/ _jsx(Link, {
|
|
58
58
|
to: "/auth/logout",
|
|
59
|
-
search:
|
|
60
|
-
redirect: logoutRedirect
|
|
59
|
+
search: logoutRedirect ? {
|
|
60
|
+
redirect: logoutRedirect
|
|
61
61
|
} : undefined,
|
|
62
62
|
children: "Switch account"
|
|
63
63
|
})
|
|
64
64
|
}) : null,
|
|
65
|
-
startOver &&
|
|
65
|
+
startOver && workspaceSlug ? /*#__PURE__*/ _jsx(ButtonLink, {
|
|
66
66
|
asChild: true,
|
|
67
67
|
className: "min-h-44 w-full sm:w-fit",
|
|
68
68
|
children: /*#__PURE__*/ _jsx(Link, {
|
|
69
69
|
to: installPath,
|
|
70
70
|
params: {
|
|
71
|
-
|
|
71
|
+
workspaceSlug
|
|
72
72
|
},
|
|
73
73
|
children: "Start over"
|
|
74
74
|
})
|
|
@@ -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 startOver,\n switchAccount,\n
|
|
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 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={status === 'error' ? 'alert' : 'status'} type={status}>\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=\"/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 </div>\n </main>\n );\n}\n"],"names":["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","div","h2","ref","tabIndex","role","type","size","search","redirect"],"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,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,MAACO;YAAIP,WAAU;;8BACb,KAACQ;oBAAGC,KAAKhB;oBAAYiB,UAAU,CAAC;oBAAGV,WAAU;8BAC1Cd;;8BAEH,KAACN;oBAAQ+B,MAAMvB,WAAW,UAAU,UAAU;oBAAUwB,MAAMxB;8BAC5D,cAAA,KAACP;wBAAKgC,MAAK;kCAAM1B;;;8BAEnB,MAACoB;oBAAIP,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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type IntegrationConnection } from '#core/models.js';
|
|
2
2
|
interface InstalledIntegrationsSectionProps {
|
|
3
|
+
workspaceSlug?: string | undefined;
|
|
3
4
|
connections: IntegrationConnection[];
|
|
4
5
|
isPending: boolean;
|
|
5
6
|
isFetching: boolean;
|
|
@@ -11,6 +12,6 @@ interface InstalledIntegrationsSectionProps {
|
|
|
11
12
|
onDelete: (connectionId: string) => void;
|
|
12
13
|
providerDisplayName: (provider: string) => string | undefined;
|
|
13
14
|
}
|
|
14
|
-
export declare function InstalledIntegrationsSection({ connections, isPending, isFetching, error, onRetry, isMutating, onUse, onSetActive, onDelete, providerDisplayName, }: InstalledIntegrationsSectionProps): import("react").JSX.Element;
|
|
15
|
+
export declare function InstalledIntegrationsSection({ workspaceSlug, connections, isPending, isFetching, error, onRetry, isMutating, onUse, onSetActive, onDelete, providerDisplayName, }: InstalledIntegrationsSectionProps): import("react").JSX.Element;
|
|
15
16
|
export {};
|
|
16
17
|
//# sourceMappingURL=installed-integrations-section.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installed-integrations-section.d.ts","sourceRoot":"","sources":["../../src/components/installed-integrations-section.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAAC,KAAK,qBAAqB,EAAqB,MAAM,iBAAiB,CAAC;AAG/E,UAAU,iCAAiC;IACzC,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;AAKD,wBAAgB,4BAA4B,CAAC,EAC3C,WAAW,EACX,SAAS,EACT,UAAU,EACV,KAAK,EACL,OAAO,EACP,UAAU,EACV,KAAK,EACL,WAAW,EACX,QAAQ,EACR,mBAAmB,GACpB,EAAE,iCAAiC,+
|
|
1
|
+
{"version":3,"file":"installed-integrations-section.d.ts","sourceRoot":"","sources":["../../src/components/installed-integrations-section.tsx"],"names":[],"mappings":"AAgBA,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;AAKD,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,+BAiDnC"}
|
|
@@ -12,7 +12,7 @@ import { ConnectionStatusBadge } from '#connection-status-badge.js';
|
|
|
12
12
|
import { isUsableConnection } from '#core/models.js';
|
|
13
13
|
import { usageEventsForConnection } from './integration-usage-events.js';
|
|
14
14
|
const INSTALLED_SURFACE_CLASS = 'overflow-hidden rounded-8 border border-border-neutral-base bg-background-neutral-base';
|
|
15
|
-
export function InstalledIntegrationsSection({ connections, isPending, isFetching, error, onRetry, isMutating, onUse, onSetActive, onDelete, providerDisplayName }) {
|
|
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-16",
|
|
18
18
|
"aria-label": "Installed integrations",
|
|
@@ -59,6 +59,7 @@ export function InstalledIntegrationsSection({ connections, isPending, isFetchin
|
|
|
59
59
|
className: cn('divide-y divide-border-neutral-base', INSTALLED_SURFACE_CLASS),
|
|
60
60
|
children: connections.map((connection)=>/*#__PURE__*/ _jsx(InstalledRow, {
|
|
61
61
|
connection: connection,
|
|
62
|
+
workspaceSlug: workspaceSlug,
|
|
62
63
|
isMutating: isMutating,
|
|
63
64
|
onUse: onUse,
|
|
64
65
|
onSetActive: (nextActive)=>onSetActive(connection, nextActive),
|
|
@@ -69,7 +70,7 @@ export function InstalledIntegrationsSection({ connections, isPending, isFetchin
|
|
|
69
70
|
]
|
|
70
71
|
});
|
|
71
72
|
}
|
|
72
|
-
function InstalledRow({ connection, isMutating, onUse, onSetActive, onDelete, providerDisplayName }) {
|
|
73
|
+
function InstalledRow({ connection, workspaceSlug, isMutating, onUse, onSetActive, onDelete, providerDisplayName }) {
|
|
73
74
|
const muted = connection.lifecycleStatus === 'disabled';
|
|
74
75
|
const active = isUsableConnection(connection);
|
|
75
76
|
const recentEventsEvent = usageEventsForConnection(connection)[0]?.value ?? 'received';
|
|
@@ -137,12 +138,12 @@ function InstalledRow({ connection, isMutating, onUse, onSetActive, onDelete, pr
|
|
|
137
138
|
onSelect: ()=>onUse(connection.id),
|
|
138
139
|
children: "Use this integration"
|
|
139
140
|
}),
|
|
140
|
-
/*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
141
|
+
workspaceSlug ? /*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
141
142
|
asChild: true,
|
|
142
143
|
children: /*#__PURE__*/ _jsx(Link, {
|
|
143
|
-
to: "/
|
|
144
|
+
to: "/w/$workspaceSlug/settings/events",
|
|
144
145
|
params: {
|
|
145
|
-
|
|
146
|
+
workspaceSlug
|
|
146
147
|
},
|
|
147
148
|
search: {
|
|
148
149
|
source: [
|
|
@@ -154,7 +155,7 @@ function InstalledRow({ connection, isMutating, onUse, onSetActive, onDelete, pr
|
|
|
154
155
|
},
|
|
155
156
|
children: "View recent events"
|
|
156
157
|
})
|
|
157
|
-
}),
|
|
158
|
+
}) : null,
|
|
158
159
|
/*#__PURE__*/ _jsx(DropdownMenuSeparator, {}),
|
|
159
160
|
/*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
160
161
|
disabled: isMutating,
|
|
@@ -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 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 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-16\" aria-label=\"Installed integrations\">\n <div className=\"flex flex-col gap-4\">\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-16')}>\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-16')}>\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 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 isMutating,\n onUse,\n onSetActive,\n onDelete,\n providerDisplayName,\n}: {\n connection: IntegrationConnection;\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-12 px-16 py-12 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-2\">\n <div className=\"flex min-w-0 items-center gap-8\">\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 <DropdownMenuItem asChild>\n <Link\n to=\"/workspaces/$wid/settings/events\"\n params={{wid: connection.workspaceId}}\n search={{source: [connection.slug], event: [recentEventsEvent]}}\n >\n View recent events\n </Link>\n </DropdownMenuItem>\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-12 px-16 py-12\">\n <Skeleton className=\"size-24 shrink-0\" />\n <div className=\"flex min-w-0 flex-1 flex-col gap-2\">\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","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","wid","workspaceId","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 {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-16\" aria-label=\"Installed integrations\">\n <div className=\"flex flex-col gap-4\">\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-16')}>\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-16')}>\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-12 px-16 py-12 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-2\">\n <div className=\"flex min-w-0 items-center gap-8\">\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-12 px-16 py-12\">\n <Skeleton className=\"size-24 shrink-0\" />\n <div className=\"flex min-w-0 flex-1 flex-col gap-2\">\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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration-gallery-for-workspace.d.ts","sourceRoot":"","sources":["../../src/components/integration-gallery-for-workspace.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"integration-gallery-for-workspace.d.ts","sourceRoot":"","sources":["../../src/components/integration-gallery-for-workspace.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,qBAAqB,EAGtB,MAAM,iBAAiB,CAAC;AAmBzB,UAAU,mCAAmC;IAC3C,UAAU,EAAE,qBAAqB,GAAG,SAAS,CAAC;IAC9C,qBAAqB,EAAE,MAAM,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,8BAA8B,CAAC,EAC7C,UAAU,EACV,qBAAqB,EACrB,WAAW,GACZ,EAAE,mCAAmC,+BA4KrC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useAuthState } from '@shipfox/client-auth';
|
|
2
3
|
import { toast } from '@shipfox/react-ui/toast';
|
|
3
4
|
import { Header, Text } from '@shipfox/react-ui/typography';
|
|
4
5
|
import { useState } from 'react';
|
|
@@ -12,6 +13,8 @@ import { ProviderGrid } from './provider-grid.js';
|
|
|
12
13
|
import { WebhookCreateModal } from './webhook/webhook-create-modal.js';
|
|
13
14
|
import { WebhookUsageDetails } from './webhook/webhook-usage-details.js';
|
|
14
15
|
export function IntegrationGalleryForWorkspace({ capability, emptyProvidersMessage, workspaceId }) {
|
|
16
|
+
const { workspaces } = useAuthState();
|
|
17
|
+
const workspaceSlug = workspaces.find((workspace)=>workspace.id === workspaceId)?.slug;
|
|
15
18
|
const [createProvider, setCreateProvider] = useState();
|
|
16
19
|
const [usageConnectionId, setUsageConnectionId] = useState();
|
|
17
20
|
const [createdUsageConnection, setCreatedUsageConnection] = useState();
|
|
@@ -91,6 +94,7 @@ export function IntegrationGalleryForWorkspace({ capability, emptyProvidersMessa
|
|
|
91
94
|
className: "flex flex-col gap-24",
|
|
92
95
|
children: [
|
|
93
96
|
/*#__PURE__*/ _jsx(InstalledIntegrationsSection, {
|
|
97
|
+
workspaceSlug: workspaceSlug,
|
|
94
98
|
connections: sortedConnections,
|
|
95
99
|
isPending: connectionsQuery.isPending,
|
|
96
100
|
isFetching: connectionsQuery.isFetching,
|
|
@@ -122,15 +126,20 @@ export function IntegrationGalleryForWorkspace({ capability, emptyProvidersMessa
|
|
|
122
126
|
})
|
|
123
127
|
]
|
|
124
128
|
}),
|
|
125
|
-
/*#__PURE__*/ _jsx(ProviderGrid, {
|
|
129
|
+
workspaceSlug ? /*#__PURE__*/ _jsx(ProviderGrid, {
|
|
130
|
+
workspaceSlug: workspaceSlug,
|
|
126
131
|
providers: providers,
|
|
127
132
|
isPending: providersQuery.isPending,
|
|
128
133
|
isFetching: providersQuery.isFetching,
|
|
129
134
|
error: providersQuery.isError ? providersQuery.error : undefined,
|
|
130
135
|
onRetry: ()=>void providersQuery.refetch(),
|
|
131
|
-
workspaceId: workspaceId,
|
|
132
136
|
emptyMessage: emptyProvidersMessage,
|
|
133
137
|
onOpenProvider: setCreateProvider
|
|
138
|
+
}) : /*#__PURE__*/ _jsx(Text, {
|
|
139
|
+
size: "sm",
|
|
140
|
+
className: "text-foreground-neutral-muted",
|
|
141
|
+
"aria-live": "polite",
|
|
142
|
+
children: "Loading workspace details…"
|
|
134
143
|
})
|
|
135
144
|
]
|
|
136
145
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/integration-gallery-for-workspace.tsx"],"sourcesContent":["import {toast} from '@shipfox/react-ui/toast';\nimport {Header, Text} from '@shipfox/react-ui/typography';\nimport {useState} from 'react';\nimport type {\n IntegrationCapability,\n IntegrationConnection,\n IntegrationProvider,\n} from '#core/models.js';\nimport {\n useDeleteIntegrationConnectionMutation,\n useIntegrationConnectionsQuery,\n useIntegrationProvidersQuery,\n useUpdateIntegrationConnectionMutation,\n} from '#hooks/api/integrations.js';\nimport {\n useDeleteWebhookConnectionMutation,\n useUpdateWebhookConnectionMutation,\n} from '#hooks/api/webhook-connections.js';\nimport {InstalledIntegrationsSection} from './installed-integrations-section.js';\nimport {IntegrationDeleteConfirmModal} from './integration-delete-confirm-modal.js';\nimport {usageEventsForConnection} from './integration-usage-events.js';\nimport {IntegrationUsageModal} from './integration-usage-modal.js';\nimport {ProviderGrid} from './provider-grid.js';\nimport {WebhookCreateModal} from './webhook/webhook-create-modal.js';\nimport {WebhookUsageDetails} from './webhook/webhook-usage-details.js';\n\ninterface IntegrationGalleryForWorkspaceProps {\n capability: IntegrationCapability | undefined;\n emptyProvidersMessage: string;\n workspaceId: string;\n}\n\nexport function IntegrationGalleryForWorkspace({\n capability,\n emptyProvidersMessage,\n workspaceId,\n}: IntegrationGalleryForWorkspaceProps) {\n const [createProvider, setCreateProvider] = useState<string | undefined>();\n const [usageConnectionId, setUsageConnectionId] = useState<string | undefined>();\n const [createdUsageConnection, setCreatedUsageConnection] = useState<\n IntegrationConnection | undefined\n >();\n const [deleteConnectionId, setDeleteConnectionId] = useState<string | undefined>();\n const providersQuery = useIntegrationProvidersQuery(capability ? {capability} : undefined);\n const connectionsQuery = useIntegrationConnectionsQuery(workspaceId);\n const updateConnection = useUpdateIntegrationConnectionMutation();\n const deleteConnection = useDeleteIntegrationConnectionMutation();\n const updateWebhookConnection = useUpdateWebhookConnectionMutation();\n const deleteWebhookConnection = useDeleteWebhookConnectionMutation();\n\n const providers = providersQuery.data ?? [];\n const providersMap = new Map<string, IntegrationProvider>(\n providers.map((provider) => [provider.provider, provider]),\n );\n\n const allConnections = connectionsQuery.data ?? [];\n // Filter in memory so the all-status cache key stays shared; passing capability\n // into the hook would collide with the active-only `source_control` key used\n // elsewhere.\n const connections = capability\n ? allConnections.filter((connection) => connection.capabilities.includes(capability))\n : allConnections;\n\n const providerDisplayName = (provider: string) => providersMap.get(provider)?.displayName;\n const providerLabel = (provider: string) => providerDisplayName(provider) ?? provider;\n\n const sortedConnections = [...connections].sort((a, b) => {\n const byProvider = providerLabel(a.provider).localeCompare(providerLabel(b.provider));\n if (byProvider !== 0) return byProvider;\n return a.createdAt.localeCompare(b.createdAt);\n });\n const usageConnection =\n sortedConnections.find((connection) => connection.id === usageConnectionId) ??\n (createdUsageConnection?.id === usageConnectionId ? createdUsageConnection : null) ??\n null;\n const deleteConnectionTarget = sortedConnections.find(\n (connection) => connection.id === deleteConnectionId,\n );\n\n async function setConnectionActive(connection: IntegrationConnection, active: boolean) {\n try {\n const body = {lifecycle_status: active ? 'active' : 'disabled'} as const;\n if (connection.provider === 'webhook') {\n await updateWebhookConnection.mutateAsync({\n workspaceId,\n connectionId: connection.id,\n body,\n });\n } else {\n await updateConnection.mutateAsync({\n connectionId: connection.id,\n body,\n });\n }\n toast.success(active ? 'Integration enabled.' : 'Integration disabled.');\n } catch (error) {\n toast.error(error instanceof Error ? error.message : 'Could not update integration.');\n }\n }\n\n async function confirmDeleteConnection() {\n if (!deleteConnectionTarget) return;\n try {\n if (deleteConnectionTarget.provider === 'webhook') {\n await deleteWebhookConnection.mutateAsync({\n workspaceId,\n connectionId: deleteConnectionTarget.id,\n });\n } else {\n await deleteConnection.mutateAsync({\n workspaceId,\n connectionId: deleteConnectionTarget.id,\n });\n }\n toast.success('Integration deleted.');\n setDeleteConnectionId(undefined);\n } catch (error) {\n toast.error(error instanceof Error ? error.message : 'Could not delete integration.');\n }\n }\n\n return (\n <div className=\"flex flex-col gap-24\">\n <InstalledIntegrationsSection\n connections={sortedConnections}\n isPending={connectionsQuery.isPending}\n isFetching={connectionsQuery.isFetching}\n error={connectionsQuery.isError ? connectionsQuery.error : undefined}\n onRetry={() => void connectionsQuery.refetch()}\n isMutating={\n updateConnection.isPending ||\n deleteConnection.isPending ||\n updateWebhookConnection.isPending ||\n deleteWebhookConnection.isPending\n }\n onUse={setUsageConnectionId}\n onSetActive={(connection, active) => {\n void setConnectionActive(connection, active);\n }}\n onDelete={setDeleteConnectionId}\n providerDisplayName={providerDisplayName}\n />\n\n <section className=\"flex flex-col gap-16\" aria-label=\"Available integrations\">\n <div className=\"flex flex-col gap-4\">\n <Header variant=\"h3\">Available integrations</Header>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Providers available to install in this workspace.\n </Text>\n </div>\n\n <ProviderGrid\n providers={providers}\n isPending={providersQuery.isPending}\n isFetching={providersQuery.isFetching}\n error={providersQuery.isError ? providersQuery.error : undefined}\n onRetry={() => void providersQuery.refetch()}\n workspaceId={workspaceId}\n emptyMessage={emptyProvidersMessage}\n onOpenProvider={setCreateProvider}\n />\n </section>\n <WebhookCreateModal\n workspaceId={workspaceId}\n open={createProvider === 'webhook'}\n onOpenChange={(open) => setCreateProvider(open ? 'webhook' : undefined)}\n onCreated={(connection) => {\n setCreatedUsageConnection(connection);\n setUsageConnectionId(connection.id);\n }}\n />\n <IntegrationUsageModal\n connection={usageConnection}\n events={usageConnection ? usageEventsForConnection(usageConnection) : []}\n open={usageConnection !== null}\n onOpenChange={(open) => {\n if (!open) {\n setUsageConnectionId(undefined);\n setCreatedUsageConnection(undefined);\n }\n }}\n >\n {usageConnection?.provider === 'webhook' ? (\n <WebhookUsageDetails workspaceId={workspaceId} connectionId={usageConnection.id} />\n ) : null}\n </IntegrationUsageModal>\n <IntegrationDeleteConfirmModal\n connectionName={deleteConnectionTarget?.displayName}\n open={deleteConnectionId !== undefined}\n isPending={deleteConnection.isPending || deleteWebhookConnection.isPending}\n onOpenChange={(open) => {\n if (!open) setDeleteConnectionId(undefined);\n }}\n onConfirm={() => {\n void confirmDeleteConnection();\n }}\n />\n </div>\n );\n}\n"],"names":["toast","Header","Text","useState","useDeleteIntegrationConnectionMutation","useIntegrationConnectionsQuery","useIntegrationProvidersQuery","useUpdateIntegrationConnectionMutation","useDeleteWebhookConnectionMutation","useUpdateWebhookConnectionMutation","InstalledIntegrationsSection","IntegrationDeleteConfirmModal","usageEventsForConnection","IntegrationUsageModal","ProviderGrid","WebhookCreateModal","WebhookUsageDetails","IntegrationGalleryForWorkspace","capability","emptyProvidersMessage","workspaceId","createProvider","setCreateProvider","usageConnectionId","setUsageConnectionId","createdUsageConnection","setCreatedUsageConnection","deleteConnectionId","setDeleteConnectionId","providersQuery","undefined","connectionsQuery","updateConnection","deleteConnection","updateWebhookConnection","deleteWebhookConnection","providers","data","providersMap","Map","map","provider","allConnections","connections","filter","connection","capabilities","includes","providerDisplayName","get","displayName","providerLabel","sortedConnections","sort","a","b","byProvider","localeCompare","createdAt","usageConnection","find","id","deleteConnectionTarget","setConnectionActive","active","body","lifecycle_status","mutateAsync","connectionId","success","error","Error","message","confirmDeleteConnection","div","className","isPending","isFetching","isError","onRetry","refetch","isMutating","onUse","onSetActive","onDelete","section","aria-label","variant","size","emptyMessage","onOpenProvider","open","onOpenChange","onCreated","events","connectionName","onConfirm"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/components/integration-gallery-for-workspace.tsx"],"sourcesContent":["import {useAuthState} from '@shipfox/client-auth';\nimport {toast} from '@shipfox/react-ui/toast';\nimport {Header, Text} from '@shipfox/react-ui/typography';\nimport {useState} from 'react';\nimport type {\n IntegrationCapability,\n IntegrationConnection,\n IntegrationProvider,\n} from '#core/models.js';\nimport {\n useDeleteIntegrationConnectionMutation,\n useIntegrationConnectionsQuery,\n useIntegrationProvidersQuery,\n useUpdateIntegrationConnectionMutation,\n} from '#hooks/api/integrations.js';\nimport {\n useDeleteWebhookConnectionMutation,\n useUpdateWebhookConnectionMutation,\n} from '#hooks/api/webhook-connections.js';\nimport {InstalledIntegrationsSection} from './installed-integrations-section.js';\nimport {IntegrationDeleteConfirmModal} from './integration-delete-confirm-modal.js';\nimport {usageEventsForConnection} from './integration-usage-events.js';\nimport {IntegrationUsageModal} from './integration-usage-modal.js';\nimport {ProviderGrid} from './provider-grid.js';\nimport {WebhookCreateModal} from './webhook/webhook-create-modal.js';\nimport {WebhookUsageDetails} from './webhook/webhook-usage-details.js';\n\ninterface IntegrationGalleryForWorkspaceProps {\n capability: IntegrationCapability | undefined;\n emptyProvidersMessage: string;\n workspaceId: string;\n}\n\nexport function IntegrationGalleryForWorkspace({\n capability,\n emptyProvidersMessage,\n workspaceId,\n}: IntegrationGalleryForWorkspaceProps) {\n const {workspaces} = useAuthState();\n const workspaceSlug = workspaces.find((workspace) => workspace.id === workspaceId)?.slug;\n const [createProvider, setCreateProvider] = useState<string | undefined>();\n const [usageConnectionId, setUsageConnectionId] = useState<string | undefined>();\n const [createdUsageConnection, setCreatedUsageConnection] = useState<\n IntegrationConnection | undefined\n >();\n const [deleteConnectionId, setDeleteConnectionId] = useState<string | undefined>();\n const providersQuery = useIntegrationProvidersQuery(capability ? {capability} : undefined);\n const connectionsQuery = useIntegrationConnectionsQuery(workspaceId);\n const updateConnection = useUpdateIntegrationConnectionMutation();\n const deleteConnection = useDeleteIntegrationConnectionMutation();\n const updateWebhookConnection = useUpdateWebhookConnectionMutation();\n const deleteWebhookConnection = useDeleteWebhookConnectionMutation();\n\n const providers = providersQuery.data ?? [];\n const providersMap = new Map<string, IntegrationProvider>(\n providers.map((provider) => [provider.provider, provider]),\n );\n\n const allConnections = connectionsQuery.data ?? [];\n // Filter in memory so the all-status cache key stays shared; passing capability\n // into the hook would collide with the active-only `source_control` key used\n // elsewhere.\n const connections = capability\n ? allConnections.filter((connection) => connection.capabilities.includes(capability))\n : allConnections;\n\n const providerDisplayName = (provider: string) => providersMap.get(provider)?.displayName;\n const providerLabel = (provider: string) => providerDisplayName(provider) ?? provider;\n\n const sortedConnections = [...connections].sort((a, b) => {\n const byProvider = providerLabel(a.provider).localeCompare(providerLabel(b.provider));\n if (byProvider !== 0) return byProvider;\n return a.createdAt.localeCompare(b.createdAt);\n });\n const usageConnection =\n sortedConnections.find((connection) => connection.id === usageConnectionId) ??\n (createdUsageConnection?.id === usageConnectionId ? createdUsageConnection : null) ??\n null;\n const deleteConnectionTarget = sortedConnections.find(\n (connection) => connection.id === deleteConnectionId,\n );\n\n async function setConnectionActive(connection: IntegrationConnection, active: boolean) {\n try {\n const body = {lifecycle_status: active ? 'active' : 'disabled'} as const;\n if (connection.provider === 'webhook') {\n await updateWebhookConnection.mutateAsync({\n workspaceId,\n connectionId: connection.id,\n body,\n });\n } else {\n await updateConnection.mutateAsync({\n connectionId: connection.id,\n body,\n });\n }\n toast.success(active ? 'Integration enabled.' : 'Integration disabled.');\n } catch (error) {\n toast.error(error instanceof Error ? error.message : 'Could not update integration.');\n }\n }\n\n async function confirmDeleteConnection() {\n if (!deleteConnectionTarget) return;\n try {\n if (deleteConnectionTarget.provider === 'webhook') {\n await deleteWebhookConnection.mutateAsync({\n workspaceId,\n connectionId: deleteConnectionTarget.id,\n });\n } else {\n await deleteConnection.mutateAsync({\n workspaceId,\n connectionId: deleteConnectionTarget.id,\n });\n }\n toast.success('Integration deleted.');\n setDeleteConnectionId(undefined);\n } catch (error) {\n toast.error(error instanceof Error ? error.message : 'Could not delete integration.');\n }\n }\n\n return (\n <div className=\"flex flex-col gap-24\">\n <InstalledIntegrationsSection\n workspaceSlug={workspaceSlug}\n connections={sortedConnections}\n isPending={connectionsQuery.isPending}\n isFetching={connectionsQuery.isFetching}\n error={connectionsQuery.isError ? connectionsQuery.error : undefined}\n onRetry={() => void connectionsQuery.refetch()}\n isMutating={\n updateConnection.isPending ||\n deleteConnection.isPending ||\n updateWebhookConnection.isPending ||\n deleteWebhookConnection.isPending\n }\n onUse={setUsageConnectionId}\n onSetActive={(connection, active) => {\n void setConnectionActive(connection, active);\n }}\n onDelete={setDeleteConnectionId}\n providerDisplayName={providerDisplayName}\n />\n\n <section className=\"flex flex-col gap-16\" aria-label=\"Available integrations\">\n <div className=\"flex flex-col gap-4\">\n <Header variant=\"h3\">Available integrations</Header>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Providers available to install in this workspace.\n </Text>\n </div>\n\n {workspaceSlug ? (\n <ProviderGrid\n workspaceSlug={workspaceSlug}\n providers={providers}\n isPending={providersQuery.isPending}\n isFetching={providersQuery.isFetching}\n error={providersQuery.isError ? providersQuery.error : undefined}\n onRetry={() => void providersQuery.refetch()}\n emptyMessage={emptyProvidersMessage}\n onOpenProvider={setCreateProvider}\n />\n ) : (\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\" aria-live=\"polite\">\n Loading workspace details…\n </Text>\n )}\n </section>\n <WebhookCreateModal\n workspaceId={workspaceId}\n open={createProvider === 'webhook'}\n onOpenChange={(open) => setCreateProvider(open ? 'webhook' : undefined)}\n onCreated={(connection) => {\n setCreatedUsageConnection(connection);\n setUsageConnectionId(connection.id);\n }}\n />\n <IntegrationUsageModal\n connection={usageConnection}\n events={usageConnection ? usageEventsForConnection(usageConnection) : []}\n open={usageConnection !== null}\n onOpenChange={(open) => {\n if (!open) {\n setUsageConnectionId(undefined);\n setCreatedUsageConnection(undefined);\n }\n }}\n >\n {usageConnection?.provider === 'webhook' ? (\n <WebhookUsageDetails workspaceId={workspaceId} connectionId={usageConnection.id} />\n ) : null}\n </IntegrationUsageModal>\n <IntegrationDeleteConfirmModal\n connectionName={deleteConnectionTarget?.displayName}\n open={deleteConnectionId !== undefined}\n isPending={deleteConnection.isPending || deleteWebhookConnection.isPending}\n onOpenChange={(open) => {\n if (!open) setDeleteConnectionId(undefined);\n }}\n onConfirm={() => {\n void confirmDeleteConnection();\n }}\n />\n </div>\n );\n}\n"],"names":["useAuthState","toast","Header","Text","useState","useDeleteIntegrationConnectionMutation","useIntegrationConnectionsQuery","useIntegrationProvidersQuery","useUpdateIntegrationConnectionMutation","useDeleteWebhookConnectionMutation","useUpdateWebhookConnectionMutation","InstalledIntegrationsSection","IntegrationDeleteConfirmModal","usageEventsForConnection","IntegrationUsageModal","ProviderGrid","WebhookCreateModal","WebhookUsageDetails","IntegrationGalleryForWorkspace","capability","emptyProvidersMessage","workspaceId","workspaces","workspaceSlug","find","workspace","id","slug","createProvider","setCreateProvider","usageConnectionId","setUsageConnectionId","createdUsageConnection","setCreatedUsageConnection","deleteConnectionId","setDeleteConnectionId","providersQuery","undefined","connectionsQuery","updateConnection","deleteConnection","updateWebhookConnection","deleteWebhookConnection","providers","data","providersMap","Map","map","provider","allConnections","connections","filter","connection","capabilities","includes","providerDisplayName","get","displayName","providerLabel","sortedConnections","sort","a","b","byProvider","localeCompare","createdAt","usageConnection","deleteConnectionTarget","setConnectionActive","active","body","lifecycle_status","mutateAsync","connectionId","success","error","Error","message","confirmDeleteConnection","div","className","isPending","isFetching","isError","onRetry","refetch","isMutating","onUse","onSetActive","onDelete","section","aria-label","variant","size","emptyMessage","onOpenProvider","aria-live","open","onOpenChange","onCreated","events","connectionName","onConfirm"],"mappings":"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"}
|
|
@@ -8,14 +8,14 @@ import { createStore, Provider as JotaiProvider } from 'jotai';
|
|
|
8
8
|
import { useMemo } from 'react';
|
|
9
9
|
import { IntegrationGallery } from './integration-gallery.js';
|
|
10
10
|
const WORKSPACE_ID = '11111111-1111-4111-8111-111111111111';
|
|
11
|
-
const WORKSPACE_PATH =
|
|
11
|
+
const WORKSPACE_PATH = '/w/acme/settings/integrations';
|
|
12
12
|
const SETUP_PATHS = [
|
|
13
|
-
'/
|
|
14
|
-
'/
|
|
15
|
-
'/
|
|
16
|
-
'/
|
|
17
|
-
'/
|
|
18
|
-
'/
|
|
13
|
+
'/w/$workspaceSlug/integrations/github',
|
|
14
|
+
'/w/$workspaceSlug/integrations/sentry',
|
|
15
|
+
'/w/$workspaceSlug/integrations/linear',
|
|
16
|
+
'/w/$workspaceSlug/integrations/slack',
|
|
17
|
+
'/w/$workspaceSlug/integrations/gitea',
|
|
18
|
+
'/w/$workspaceSlug/settings/events'
|
|
19
19
|
];
|
|
20
20
|
const PROVIDERS = [
|
|
21
21
|
{
|
|
@@ -77,6 +77,7 @@ function IntegrationGalleryStory({ scenario }) {
|
|
|
77
77
|
{
|
|
78
78
|
id: WORKSPACE_ID,
|
|
79
79
|
name: 'Acme',
|
|
80
|
+
slug: 'acme',
|
|
80
81
|
membershipId: 'membership-1'
|
|
81
82
|
}
|
|
82
83
|
]
|
|
@@ -89,7 +90,7 @@ function IntegrationGalleryStory({ scenario }) {
|
|
|
89
90
|
});
|
|
90
91
|
const workspaceRoute = createRoute({
|
|
91
92
|
getParentRoute: ()=>rootRoute,
|
|
92
|
-
path: '/
|
|
93
|
+
path: '/w/$workspaceSlug',
|
|
93
94
|
component: Outlet
|
|
94
95
|
});
|
|
95
96
|
const galleryRoute = createRoute({
|
|
@@ -104,7 +105,7 @@ function IntegrationGalleryStory({ scenario }) {
|
|
|
104
105
|
});
|
|
105
106
|
const setupRoutes = SETUP_PATHS.map((path)=>createRoute({
|
|
106
107
|
getParentRoute: ()=>workspaceRoute,
|
|
107
|
-
path: path.replace('/
|
|
108
|
+
path: path.replace('/w/$workspaceSlug/', ''),
|
|
108
109
|
component: ()=>/*#__PURE__*/ _jsx("div", {})
|
|
109
110
|
}));
|
|
110
111
|
return createRouter({
|