@shipfox/client-integrations 0.2.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/.storybook/main.ts +1 -0
- package/.storybook/preview.css +4 -0
- package/.storybook/preview.tsx +56 -0
- package/.turbo/turbo-build.log +2 -0
- package/.turbo/turbo-type$colon$emit.log +1 -0
- package/.turbo/turbo-type.log +1 -0
- package/CHANGELOG.md +207 -0
- package/LICENSE +21 -0
- package/dist/components/connection-picker.d.ts +7 -0
- package/dist/components/connection-picker.d.ts.map +1 -0
- package/dist/components/connection-picker.js +98 -0
- package/dist/components/connection-picker.js.map +1 -0
- package/dist/components/installed-integrations-section.d.ts +14 -0
- package/dist/components/installed-integrations-section.d.ts.map +1 -0
- package/dist/components/installed-integrations-section.js +203 -0
- package/dist/components/installed-integrations-section.js.map +1 -0
- package/dist/components/integration-delete-confirm-modal.d.ts +10 -0
- package/dist/components/integration-delete-confirm-modal.d.ts.map +1 -0
- package/dist/components/integration-delete-confirm-modal.js +61 -0
- package/dist/components/integration-delete-confirm-modal.js.map +1 -0
- package/dist/components/integration-gallery-for-workspace.d.ts +9 -0
- package/dist/components/integration-gallery-for-workspace.d.ts.map +1 -0
- package/dist/components/integration-gallery-for-workspace.js +169 -0
- package/dist/components/integration-gallery-for-workspace.js.map +1 -0
- package/dist/components/integration-gallery.d.ts +8 -0
- package/dist/components/integration-gallery.d.ts.map +1 -0
- package/dist/components/integration-gallery.js +26 -0
- package/dist/components/integration-gallery.js.map +1 -0
- package/dist/components/integration-gallery.stories.d.ts +26 -0
- package/dist/components/integration-gallery.stories.d.ts.map +1 -0
- package/dist/components/integration-gallery.stories.js +335 -0
- package/dist/components/integration-gallery.stories.js.map +1 -0
- package/dist/components/integration-usage-events.d.ts +4 -0
- package/dist/components/integration-usage-events.d.ts.map +1 -0
- package/dist/components/integration-usage-events.js +127 -0
- package/dist/components/integration-usage-events.js.map +1 -0
- package/dist/components/integration-usage-modal.d.ts +16 -0
- package/dist/components/integration-usage-modal.d.ts.map +1 -0
- package/dist/components/integration-usage-modal.js +184 -0
- package/dist/components/integration-usage-modal.js.map +1 -0
- package/dist/components/provider-grid.d.ts +14 -0
- package/dist/components/provider-grid.d.ts.map +1 -0
- package/dist/components/provider-grid.js +152 -0
- package/dist/components/provider-grid.js.map +1 -0
- package/dist/components/redirect-install-page.d.ts +19 -0
- package/dist/components/redirect-install-page.d.ts.map +1 -0
- package/dist/components/redirect-install-page.js +68 -0
- package/dist/components/redirect-install-page.js.map +1 -0
- package/dist/components/repository-picker.d.ts +15 -0
- package/dist/components/repository-picker.d.ts.map +1 -0
- package/dist/components/repository-picker.js +78 -0
- package/dist/components/repository-picker.js.map +1 -0
- package/dist/components/webhook/copyable-value.d.ts +10 -0
- package/dist/components/webhook/copyable-value.d.ts.map +1 -0
- package/dist/components/webhook/copyable-value.js +65 -0
- package/dist/components/webhook/copyable-value.js.map +1 -0
- package/dist/components/webhook/webhook-create-modal.d.ts +10 -0
- package/dist/components/webhook/webhook-create-modal.d.ts.map +1 -0
- package/dist/components/webhook/webhook-create-modal.js +233 -0
- package/dist/components/webhook/webhook-create-modal.js.map +1 -0
- package/dist/components/webhook/webhook-form-errors.d.ts +11 -0
- package/dist/components/webhook/webhook-form-errors.d.ts.map +1 -0
- package/dist/components/webhook/webhook-form-errors.js +27 -0
- package/dist/components/webhook/webhook-form-errors.js.map +1 -0
- package/dist/components/webhook/webhook-modals.stories.d.ts +25 -0
- package/dist/components/webhook/webhook-modals.stories.d.ts.map +1 -0
- package/dist/components/webhook/webhook-modals.stories.js +222 -0
- package/dist/components/webhook/webhook-modals.stories.js.map +1 -0
- package/dist/components/webhook/webhook-public-endpoint-alert.d.ts +2 -0
- package/dist/components/webhook/webhook-public-endpoint-alert.d.ts.map +1 -0
- package/dist/components/webhook/webhook-public-endpoint-alert.js +20 -0
- package/dist/components/webhook/webhook-public-endpoint-alert.js.map +1 -0
- package/dist/components/webhook/webhook-usage-details.d.ts +7 -0
- package/dist/components/webhook/webhook-usage-details.d.ts.map +1 -0
- package/dist/components/webhook/webhook-usage-details.js +49 -0
- package/dist/components/webhook/webhook-usage-details.js.map +1 -0
- package/dist/connection-status-badge.d.ts +12 -0
- package/dist/connection-status-badge.d.ts.map +1 -0
- package/dist/connection-status-badge.js +34 -0
- package/dist/connection-status-badge.js.map +1 -0
- package/dist/feature.d.ts +37 -0
- package/dist/feature.d.ts.map +1 -0
- package/dist/feature.js +48 -0
- package/dist/feature.js.map +1 -0
- package/dist/hooks/api/integrations.d.ts +265 -0
- package/dist/hooks/api/integrations.d.ts.map +1 -0
- package/dist/hooks/api/integrations.js +229 -0
- package/dist/hooks/api/integrations.js.map +1 -0
- package/dist/hooks/api/webhook-connections.d.ts +91 -0
- package/dist/hooks/api/webhook-connections.d.ts.map +1 -0
- package/dist/hooks/api/webhook-connections.js +97 -0
- package/dist/hooks/api/webhook-connections.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/integration-icon.d.ts +17 -0
- package/dist/integration-icon.d.ts.map +1 -0
- package/dist/integration-icon.js +22 -0
- package/dist/integration-icon.js.map +1 -0
- package/dist/linear-callback.d.ts +17 -0
- package/dist/linear-callback.d.ts.map +1 -0
- package/dist/linear-callback.js +113 -0
- package/dist/linear-callback.js.map +1 -0
- package/dist/pages/gitea-form-errors.d.ts +11 -0
- package/dist/pages/gitea-form-errors.d.ts.map +1 -0
- package/dist/pages/gitea-form-errors.js +35 -0
- package/dist/pages/gitea-form-errors.js.map +1 -0
- package/dist/pages/gitea-install-page.d.ts +2 -0
- package/dist/pages/gitea-install-page.d.ts.map +1 -0
- package/dist/pages/gitea-install-page.js +139 -0
- package/dist/pages/gitea-install-page.js.map +1 -0
- package/dist/pages/github-install-page.d.ts +2 -0
- package/dist/pages/github-install-page.d.ts.map +1 -0
- package/dist/pages/github-install-page.js +11 -0
- package/dist/pages/github-install-page.js.map +1 -0
- package/dist/pages/linear-callback-page.d.ts +2 -0
- package/dist/pages/linear-callback-page.d.ts.map +1 -0
- package/dist/pages/linear-callback-page.js +192 -0
- package/dist/pages/linear-callback-page.js.map +1 -0
- package/dist/pages/linear-install-page.d.ts +2 -0
- package/dist/pages/linear-install-page.d.ts.map +1 -0
- package/dist/pages/linear-install-page.js +24 -0
- package/dist/pages/linear-install-page.js.map +1 -0
- package/dist/pages/sentry-callback-page.d.ts +2 -0
- package/dist/pages/sentry-callback-page.d.ts.map +1 -0
- package/dist/pages/sentry-callback-page.js +256 -0
- package/dist/pages/sentry-callback-page.js.map +1 -0
- package/dist/pages/sentry-install-page.d.ts +2 -0
- package/dist/pages/sentry-install-page.d.ts.map +1 -0
- package/dist/pages/sentry-install-page.js +17 -0
- package/dist/pages/sentry-install-page.js.map +1 -0
- package/dist/pages/source-control-onboarding-page.d.ts +2 -0
- package/dist/pages/source-control-onboarding-page.d.ts.map +1 -0
- package/dist/pages/source-control-onboarding-page.js +37 -0
- package/dist/pages/source-control-onboarding-page.js.map +1 -0
- package/dist/provider-catalog.d.ts +15 -0
- package/dist/provider-catalog.d.ts.map +1 -0
- package/dist/provider-catalog.js +28 -0
- package/dist/provider-catalog.js.map +1 -0
- package/dist/routes/gitea.d.ts +6 -0
- package/dist/routes/gitea.d.ts.map +1 -0
- package/dist/routes/gitea.js +7 -0
- package/dist/routes/gitea.js.map +1 -0
- package/dist/routes/github-callback.d.ts +6 -0
- package/dist/routes/github-callback.d.ts.map +1 -0
- package/dist/routes/github-callback.js +129 -0
- package/dist/routes/github-callback.js.map +1 -0
- package/dist/routes/github.d.ts +6 -0
- package/dist/routes/github.d.ts.map +1 -0
- package/dist/routes/github.js +7 -0
- package/dist/routes/github.js.map +1 -0
- package/dist/routes/integrations.d.ts +6 -0
- package/dist/routes/integrations.d.ts.map +1 -0
- package/dist/routes/integrations.js +7 -0
- package/dist/routes/integrations.js.map +1 -0
- package/dist/routes/linear-callback.d.ts +6 -0
- package/dist/routes/linear-callback.d.ts.map +1 -0
- package/dist/routes/linear-callback.js +7 -0
- package/dist/routes/linear-callback.js.map +1 -0
- package/dist/routes/linear.d.ts +6 -0
- package/dist/routes/linear.d.ts.map +1 -0
- package/dist/routes/linear.js +7 -0
- package/dist/routes/linear.js.map +1 -0
- package/dist/routes/sentry-callback.d.ts +6 -0
- package/dist/routes/sentry-callback.d.ts.map +1 -0
- package/dist/routes/sentry-callback.js +7 -0
- package/dist/routes/sentry-callback.js.map +1 -0
- package/dist/routes/sentry.d.ts +6 -0
- package/dist/routes/sentry.d.ts.map +1 -0
- package/dist/routes/sentry.js +7 -0
- package/dist/routes/sentry.js.map +1 -0
- package/dist/sentry-callback.d.ts +35 -0
- package/dist/sentry-callback.d.ts.map +1 -0
- package/dist/sentry-callback.js +132 -0
- package/dist/sentry-callback.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -0
- package/package.json +120 -0
- package/src/components/connection-picker.tsx +89 -0
- package/src/components/installed-integrations-section.tsx +198 -0
- package/src/components/integration-delete-confirm-modal.tsx +62 -0
- package/src/components/integration-gallery-for-workspace.tsx +193 -0
- package/src/components/integration-gallery.stories.tsx +302 -0
- package/src/components/integration-gallery.test.tsx +692 -0
- package/src/components/integration-gallery.tsx +49 -0
- package/src/components/integration-usage-events.test.ts +80 -0
- package/src/components/integration-usage-events.ts +116 -0
- package/src/components/integration-usage-modal.tsx +178 -0
- package/src/components/provider-grid.tsx +163 -0
- package/src/components/redirect-install-page.test.tsx +98 -0
- package/src/components/redirect-install-page.tsx +68 -0
- package/src/components/repository-picker.tsx +102 -0
- package/src/components/webhook/copyable-value.test.tsx +41 -0
- package/src/components/webhook/copyable-value.tsx +72 -0
- package/src/components/webhook/webhook-create-modal.tsx +247 -0
- package/src/components/webhook/webhook-form-errors.test.ts +45 -0
- package/src/components/webhook/webhook-form-errors.ts +32 -0
- package/src/components/webhook/webhook-modals.stories.tsx +225 -0
- package/src/components/webhook/webhook-public-endpoint-alert.tsx +15 -0
- package/src/components/webhook/webhook-usage-details.tsx +44 -0
- package/src/connection-status-badge.tsx +38 -0
- package/src/feature.ts +47 -0
- package/src/hooks/api/integrations.test.ts +105 -0
- package/src/hooks/api/integrations.ts +287 -0
- package/src/hooks/api/webhook-connections.ts +115 -0
- package/src/index.ts +16 -0
- package/src/integration-icon.react.test.tsx +40 -0
- package/src/integration-icon.test.ts +19 -0
- package/src/integration-icon.tsx +26 -0
- package/src/linear-callback.test.ts +227 -0
- package/src/linear-callback.ts +136 -0
- package/src/pages/gitea-form-errors.test.ts +55 -0
- package/src/pages/gitea-form-errors.ts +36 -0
- package/src/pages/gitea-install-page.tsx +108 -0
- package/src/pages/github-install-page.tsx +11 -0
- package/src/pages/linear-callback-page.test.tsx +157 -0
- package/src/pages/linear-callback-page.tsx +175 -0
- package/src/pages/linear-install-page.tsx +26 -0
- package/src/pages/sentry-callback-page.test.tsx +205 -0
- package/src/pages/sentry-callback-page.tsx +238 -0
- package/src/pages/sentry-install-page.tsx +17 -0
- package/src/pages/source-control-onboarding-page.test.tsx +46 -0
- package/src/pages/source-control-onboarding-page.tsx +26 -0
- package/src/provider-catalog.test.ts +42 -0
- package/src/provider-catalog.ts +49 -0
- package/src/routes/gitea.tsx +4 -0
- package/src/routes/github-callback.tsx +114 -0
- package/src/routes/github.tsx +4 -0
- package/src/routes/integrations.tsx +4 -0
- package/src/routes/linear-callback.tsx +4 -0
- package/src/routes/linear.tsx +4 -0
- package/src/routes/sentry-callback.tsx +4 -0
- package/src/routes/sentry.tsx +4 -0
- package/src/sentry-callback.test.ts +239 -0
- package/src/sentry-callback.ts +142 -0
- package/test/render.tsx +111 -0
- package/test/setup.ts +3 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +3 -0
- package/tsconfig.test.json +8 -0
- package/vercel.json +8 -0
- package/vitest.config.ts +75 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {default} from '../../.storybook/main.ts';
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import './preview.css';
|
|
2
|
+
import {ThemeProvider} from '@shipfox/react-ui/theme';
|
|
3
|
+
import type {Decorator, Preview} from '@storybook/react';
|
|
4
|
+
|
|
5
|
+
if (typeof document !== 'undefined' && document.fonts) {
|
|
6
|
+
void Promise.all([
|
|
7
|
+
document.fonts.load("16px 'Inter'"),
|
|
8
|
+
document.fonts.load("italic 16px 'Inter'"),
|
|
9
|
+
document.fonts.load("16px 'Commit Mono'"),
|
|
10
|
+
document.fonts.load("bold 16px 'Commit Mono'"),
|
|
11
|
+
]);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const withTheme: Decorator = (Story, context) => {
|
|
15
|
+
const theme = context.globals.theme;
|
|
16
|
+
return (
|
|
17
|
+
<ThemeProvider key={theme} defaultTheme={theme} storageKey={`shipfox-theme-${theme}`}>
|
|
18
|
+
<Story />
|
|
19
|
+
</ThemeProvider>
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const preview: Preview = {
|
|
24
|
+
decorators: [withTheme],
|
|
25
|
+
parameters: {
|
|
26
|
+
argos: {
|
|
27
|
+
// Dual-theme coverage lives in @shipfox/react-ui (the theming source of truth);
|
|
28
|
+
// feature packages capture only the primary dark theme to limit Argos spend.
|
|
29
|
+
modes: {
|
|
30
|
+
dark: {theme: 'dark'},
|
|
31
|
+
},
|
|
32
|
+
fitToContent: false,
|
|
33
|
+
},
|
|
34
|
+
options: {
|
|
35
|
+
storySort: {method: 'alphabetical'},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
globalTypes: {
|
|
39
|
+
theme: {
|
|
40
|
+
name: 'Theme',
|
|
41
|
+
description: 'Global theme for components',
|
|
42
|
+
defaultValue: 'dark',
|
|
43
|
+
toolbar: {
|
|
44
|
+
icon: 'sun',
|
|
45
|
+
items: [
|
|
46
|
+
{value: 'light', icon: 'sun', title: 'Light'},
|
|
47
|
+
{value: 'dark', icon: 'moon', title: 'Dark'},
|
|
48
|
+
{value: 'system', icon: 'info', title: 'System'},
|
|
49
|
+
],
|
|
50
|
+
showName: true,
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export default preview;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
$ shipfox-tsc-emit
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
$ shipfox-tsc-check
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# @shipfox/client-integrations
|
|
2
|
+
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 3d064b8: Publishes the client runtime closure with shell, feature, route, Vite, and testing contracts.
|
|
8
|
+
- 6bc2e45: Adds the composable upstream client shell, feature catalog, and route manifests for every client feature.
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- Updated dependencies [3d064b8]
|
|
13
|
+
- Updated dependencies [6bc2e45]
|
|
14
|
+
- @shipfox/client-api@0.2.0
|
|
15
|
+
- @shipfox/client-auth@0.2.0
|
|
16
|
+
- @shipfox/client-shell@0.2.0
|
|
17
|
+
- @shipfox/client-ui@0.2.0
|
|
18
|
+
|
|
19
|
+
## 0.1.2
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Updated dependencies [6b23868]
|
|
24
|
+
- Updated dependencies [c18d624]
|
|
25
|
+
- Updated dependencies [60e7bf5]
|
|
26
|
+
- @shipfox/api-integration-core-dto@3.0.0
|
|
27
|
+
- @shipfox/api-integration-github-dto@3.0.0
|
|
28
|
+
- @shipfox/api-integration-sentry-dto@3.0.0
|
|
29
|
+
- @shipfox/api-integration-webhook-dto@3.0.0
|
|
30
|
+
- @shipfox/react-ui@0.3.1
|
|
31
|
+
- @shipfox/api-integration-gitea-dto@3.0.0
|
|
32
|
+
- @shipfox/api-integration-linear-dto@3.0.0
|
|
33
|
+
- @shipfox/client-auth@0.0.5
|
|
34
|
+
- @shipfox/client-ui@0.1.2
|
|
35
|
+
|
|
36
|
+
## 0.1.1
|
|
37
|
+
|
|
38
|
+
### Patch Changes
|
|
39
|
+
|
|
40
|
+
- Updated dependencies [1b0d344]
|
|
41
|
+
- @shipfox/api-integration-core-dto@2.0.0
|
|
42
|
+
- @shipfox/api-integration-gitea-dto@2.0.0
|
|
43
|
+
- @shipfox/api-integration-github-dto@2.0.0
|
|
44
|
+
- @shipfox/api-integration-linear-dto@2.0.0
|
|
45
|
+
- @shipfox/api-integration-sentry-dto@2.0.0
|
|
46
|
+
- @shipfox/api-integration-webhook-dto@2.0.0
|
|
47
|
+
- @shipfox/client-ui@0.1.1
|
|
48
|
+
- @shipfox/client-auth@0.0.4
|
|
49
|
+
- @shipfox/client-api@0.0.1
|
|
50
|
+
- @shipfox/react-ui@0.3.0
|
|
51
|
+
|
|
52
|
+
## 0.1.0
|
|
53
|
+
|
|
54
|
+
### Minor Changes
|
|
55
|
+
|
|
56
|
+
- 43d7996: Adds the Linear OAuth connect experience to workspace integration settings.
|
|
57
|
+
- e4c6abf: Add reusable, source-keyed icon building blocks so any surface can render an integration or trigger icon without re-implementing the catalog lookup and fallback.
|
|
58
|
+
|
|
59
|
+
`@shipfox/client-integrations` exposes `getIntegrationIcon(source)` and `<IntegrationIcon source />`, resolving an integration source (a connection `provider`, a run `trigger_source`, or a trigger event `source`) against the central `PROVIDER_CATALOG` with a neutral `componentLine` fallback. The catalog stays the single place each integration declares its icon; the integration gallery now renders `<IntegrationIcon>` instead of an inline lookup (no behavior change).
|
|
60
|
+
|
|
61
|
+
New `@shipfox/client-triggers` package adds `getTriggerSourceIcon(source)` and `<TriggerSourceIcon source />`, built on the integration resolver. It recognizes the system trigger sources `manual` (a person fired the run) and `cron` (a schedule), and delegates every other source to the integration catalog. This is the building block for showing an icon on run rows and trigger events; adopting it on those surfaces lands separately.
|
|
62
|
+
|
|
63
|
+
- b8e49ff: Add the client-side Sentry install/connect flow and a workspace settings
|
|
64
|
+
integrations hub.
|
|
65
|
+
- `@shipfox/client-integrations`: shared `IntegrationGallerySection` (capability
|
|
66
|
+
filter, lifecycle pills, "Added" date, external link, connected-first
|
|
67
|
+
ordering, degraded status mode), shared `RedirectInstallPage` powering the
|
|
68
|
+
GitHub and new Sentry install pages, `SentryCallbackPage` with an explicit
|
|
69
|
+
workspace confirm (sessionStorage only pre-selects), two-tier retry, and the
|
|
70
|
+
Sentry hooks (`useCreateSentryInstallMutation`, `connectSentry`,
|
|
71
|
+
`useIntegrationConnectionsQuery`).
|
|
72
|
+
- `@shipfox/client-workspace-settings`: new `/workspaces/$wid/settings/integrations`
|
|
73
|
+
page and an Integrations entry in the settings nav.
|
|
74
|
+
- `@shipfox/client-router`: routes for the Sentry install page, the root-level
|
|
75
|
+
Sentry callback, and the settings integrations page.
|
|
76
|
+
- `@shipfox/react-ui`: `sentry` icon (monochrome, theme-aware).
|
|
77
|
+
- `@shipfox/api-integration-core-dto`: optional `external_url` on the connection
|
|
78
|
+
DTO and an optional `connectionExternalUrl` method on `IntegrationProvider`.
|
|
79
|
+
- `@shipfox/api-integration-core`: `GET /integration-connections` now returns
|
|
80
|
+
connections of every lifecycle status (the active-only filter prevented
|
|
81
|
+
clients from surfacing disabled/error state) and resolves `external_url`
|
|
82
|
+
per connection best-effort.
|
|
83
|
+
- `@shipfox/api-integration-sentry` / `@shipfox/api-integration-github`:
|
|
84
|
+
implement `connectionExternalUrl` (Sentry org URL via a new
|
|
85
|
+
by-connection-id installation lookup; GitHub installation settings URL).
|
|
86
|
+
|
|
87
|
+
### Patch Changes
|
|
88
|
+
|
|
89
|
+
- d245be8: [api/integrations] Make the signed Sentry installation webhook authoritative.
|
|
90
|
+
- `@shipfox/api-integration-sentry-dto`: reshape `sentryInstallationWebhookSchema`
|
|
91
|
+
to read `data.installation.{uuid, organization.slug, status, code}` plus an
|
|
92
|
+
optional top-level `actor`. Only consumed fields are validated and the raw
|
|
93
|
+
`code` is never logged.
|
|
94
|
+
- `@shipfox/api-integration-sentry`: the signed `installation.created` webhook now
|
|
95
|
+
exchanges the single-use code and persists a verified-but-unclaimed installation
|
|
96
|
+
(`connection_id IS NULL`, `code_hash = sha256(code)`). The browser flow narrows
|
|
97
|
+
to a claim that binds a verified install to a workspace under unified claim auth
|
|
98
|
+
(exchange-success, same-code hash match, or a retryable
|
|
99
|
+
`verification-in-progress` while a concurrent webhook is mid-exchange), with a
|
|
100
|
+
proof-mismatch 403 closing the bare-uuid IDOR. The exchange/verify run outside
|
|
101
|
+
the DB transaction; a short transaction wraps persist + delivery record. Adds
|
|
102
|
+
`connection_id` nullable + `code_hash` to the installations table and a daily TTL
|
|
103
|
+
cron that tombstones never-claimed installs.
|
|
104
|
+
- `@shipfox/api-integration-core`: inject the Sentry client into the webhook
|
|
105
|
+
context, resolve a null `connection_id` to "no connection" for pre-claim issue
|
|
106
|
+
deliveries, and register the unclaimed-installation cleanup cron when Sentry is
|
|
107
|
+
enabled.
|
|
108
|
+
- `@shipfox/client-integrations`: treat the retryable `verification-in-progress`
|
|
109
|
+
response as a backoff-eligible failure on the connect callback.
|
|
110
|
+
|
|
111
|
+
- 0f06c02: Redesign the integration gallery into separate Installed and Available sections, rendering one card per connection so multiple connections from the same provider are no longer collapsed and silently hidden.
|
|
112
|
+
- 42443b4: Redesign the projects hub cards around source health and align them with the
|
|
113
|
+
integration gallery cards. Each card now shows the integration provider logo
|
|
114
|
+
before the name, drops the raw external repository id, and surfaces a status
|
|
115
|
+
pill only when the project's source is not active (Disabled or Error), in the
|
|
116
|
+
same inline location as the gallery. The cards adopt the gallery layout
|
|
117
|
+
(two-column grid, 16px padding, 24px icon) and carry no call to action.
|
|
118
|
+
|
|
119
|
+
Extract the connection lifecycle pill into a shared `ConnectionStatusBadge` in
|
|
120
|
+
`@shipfox/client-integrations` so the gallery and the projects hub render the
|
|
121
|
+
same taxonomy from one source of truth.
|
|
122
|
+
|
|
123
|
+
- 63bcac8: Moves workspace setup gating into route hooks so VCS onboarding and first project creation resolve before protected workspace content renders.
|
|
124
|
+
- a7da648: Fixes invisible keyboard focus rings on the user menu, integration tiles, and project cards by using the existing neutral button focus token.
|
|
125
|
+
- Updated dependencies [43d7996]
|
|
126
|
+
- Updated dependencies [0948b67]
|
|
127
|
+
- Updated dependencies [14e0bea]
|
|
128
|
+
- Updated dependencies [861091c]
|
|
129
|
+
- Updated dependencies [9018f0b]
|
|
130
|
+
- Updated dependencies [7fdfd72]
|
|
131
|
+
- Updated dependencies [115655e]
|
|
132
|
+
- Updated dependencies [2a3193f]
|
|
133
|
+
- Updated dependencies [ce062a9]
|
|
134
|
+
- Updated dependencies [f104ff2]
|
|
135
|
+
- Updated dependencies [7341569]
|
|
136
|
+
- Updated dependencies [f3614ae]
|
|
137
|
+
- Updated dependencies [d245be8]
|
|
138
|
+
- Updated dependencies [f8f339a]
|
|
139
|
+
- Updated dependencies [e4c6abf]
|
|
140
|
+
- Updated dependencies [58f51bd]
|
|
141
|
+
- Updated dependencies [570ac69]
|
|
142
|
+
- Updated dependencies [857fd73]
|
|
143
|
+
- Updated dependencies [5d0676a]
|
|
144
|
+
- Updated dependencies [a35c2dc]
|
|
145
|
+
- Updated dependencies [58f7aef]
|
|
146
|
+
- Updated dependencies [5264a22]
|
|
147
|
+
- Updated dependencies [9674879]
|
|
148
|
+
- Updated dependencies [225c9a5]
|
|
149
|
+
- Updated dependencies [24f131b]
|
|
150
|
+
- Updated dependencies [7790355]
|
|
151
|
+
- Updated dependencies [bb2a7bc]
|
|
152
|
+
- Updated dependencies [63bcac8]
|
|
153
|
+
- Updated dependencies [5eb06d0]
|
|
154
|
+
- Updated dependencies [4e13e5f]
|
|
155
|
+
- Updated dependencies [e92150d]
|
|
156
|
+
- Updated dependencies [8037501]
|
|
157
|
+
- Updated dependencies [0fb6018]
|
|
158
|
+
- Updated dependencies [c27a1ed]
|
|
159
|
+
- Updated dependencies [b8e49ff]
|
|
160
|
+
- Updated dependencies [5b8ed32]
|
|
161
|
+
- Updated dependencies [d6d4862]
|
|
162
|
+
- Updated dependencies [8037501]
|
|
163
|
+
- Updated dependencies [6c0da64]
|
|
164
|
+
- Updated dependencies [07f8ff8]
|
|
165
|
+
- Updated dependencies [e457582]
|
|
166
|
+
- Updated dependencies [8b5c905]
|
|
167
|
+
- Updated dependencies [01be723]
|
|
168
|
+
- Updated dependencies [f849131]
|
|
169
|
+
- Updated dependencies [94bdcc5]
|
|
170
|
+
- Updated dependencies [a34c8ea]
|
|
171
|
+
- Updated dependencies [27770eb]
|
|
172
|
+
- Updated dependencies [2933c33]
|
|
173
|
+
- Updated dependencies [8ac4bf4]
|
|
174
|
+
- Updated dependencies [3a0be6b]
|
|
175
|
+
- Updated dependencies [d42baf4]
|
|
176
|
+
- Updated dependencies [8037501]
|
|
177
|
+
- Updated dependencies [54bb8a3]
|
|
178
|
+
- Updated dependencies [f711e18]
|
|
179
|
+
- @shipfox/react-ui@0.3.0
|
|
180
|
+
- @shipfox/api-integration-linear-dto@0.0.1
|
|
181
|
+
- @shipfox/api-integration-webhook-dto@0.0.1
|
|
182
|
+
- @shipfox/api-integration-core-dto@0.1.0
|
|
183
|
+
- @shipfox/api-integration-sentry-dto@0.1.0
|
|
184
|
+
- @shipfox/api-integration-gitea-dto@0.0.1
|
|
185
|
+
- @shipfox/client-api@0.0.1
|
|
186
|
+
- @shipfox/client-ui@0.1.0
|
|
187
|
+
- @shipfox/client-auth@0.0.3
|
|
188
|
+
- @shipfox/api-integration-github-dto@0.0.1
|
|
189
|
+
|
|
190
|
+
## 0.0.2
|
|
191
|
+
|
|
192
|
+
### Patch Changes
|
|
193
|
+
|
|
194
|
+
- Updated dependencies [5c1e777]
|
|
195
|
+
- @shipfox/react-ui@0.2.0
|
|
196
|
+
- @shipfox/client-auth@0.0.2
|
|
197
|
+
|
|
198
|
+
## 0.0.1
|
|
199
|
+
|
|
200
|
+
### Patch Changes
|
|
201
|
+
|
|
202
|
+
- Updated dependencies [2311e15]
|
|
203
|
+
- @shipfox/react-ui@0.1.1
|
|
204
|
+
- @shipfox/client-auth@0.0.1
|
|
205
|
+
- @shipfox/api-integration-core-dto@0.0.0
|
|
206
|
+
- @shipfox/api-integration-github-dto@0.0.0
|
|
207
|
+
- @shipfox/client-api@0.0.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shipfox
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { IntegrationConnectionDto } from '@shipfox/api-integration-core-dto';
|
|
2
|
+
export declare function ConnectionPicker({ connections, selectedConnectionId, onSelect, }: {
|
|
3
|
+
connections: IntegrationConnectionDto[];
|
|
4
|
+
selectedConnectionId: string | undefined;
|
|
5
|
+
onSelect: (connectionId: string) => void;
|
|
6
|
+
}): import("react").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=connection-picker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-picker.d.ts","sourceRoot":"","sources":["../../src/components/connection-picker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,mCAAmC,CAAC;AAShF,wBAAgB,gBAAgB,CAAC,EAC/B,WAAW,EACX,oBAAoB,EACpB,QAAQ,GACT,EAAE;IACD,WAAW,EAAE,wBAAwB,EAAE,CAAC;IACxC,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1C,+BAsBA"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useIsTextTruncated } from '@shipfox/react-ui/hooks';
|
|
3
|
+
import { Label } from '@shipfox/react-ui/label';
|
|
4
|
+
import { RadioGroup, RadioGroupItem } from '@shipfox/react-ui/radio-group';
|
|
5
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from '@shipfox/react-ui/tooltip';
|
|
6
|
+
import { Text } from '@shipfox/react-ui/typography';
|
|
7
|
+
import { useId } from 'react';
|
|
8
|
+
import { IntegrationIcon } from '#integration-icon.js';
|
|
9
|
+
export function ConnectionPicker({ connections, selectedConnectionId, onSelect }) {
|
|
10
|
+
const labelId = useId();
|
|
11
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
12
|
+
className: "flex flex-col gap-10",
|
|
13
|
+
children: [
|
|
14
|
+
/*#__PURE__*/ _jsx(Label, {
|
|
15
|
+
id: labelId,
|
|
16
|
+
className: "sr-only",
|
|
17
|
+
children: "Source integration"
|
|
18
|
+
}),
|
|
19
|
+
/*#__PURE__*/ _jsx(RadioGroup, {
|
|
20
|
+
"aria-labelledby": labelId,
|
|
21
|
+
value: selectedConnectionId ?? '',
|
|
22
|
+
onValueChange: onSelect,
|
|
23
|
+
className: "grid grid-cols-2 gap-8 min-[1200px]:grid-cols-3 max-[760px]:grid-cols-1",
|
|
24
|
+
children: connections.map((connection)=>/*#__PURE__*/ _jsx(RadioGroupItem, {
|
|
25
|
+
value: connection.id,
|
|
26
|
+
className: "p-12",
|
|
27
|
+
children: /*#__PURE__*/ _jsx(ConnectionOption, {
|
|
28
|
+
connection: connection
|
|
29
|
+
})
|
|
30
|
+
}, connection.id))
|
|
31
|
+
})
|
|
32
|
+
]
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function ConnectionOption({ connection }) {
|
|
36
|
+
const { ref: nameRef, isTruncated } = useIsTextTruncated(connection.display_name);
|
|
37
|
+
return /*#__PURE__*/ _jsxs("span", {
|
|
38
|
+
className: "flex min-w-0 items-center gap-10",
|
|
39
|
+
children: [
|
|
40
|
+
/*#__PURE__*/ _jsxs(Tooltip, {
|
|
41
|
+
children: [
|
|
42
|
+
/*#__PURE__*/ _jsx(TooltipTrigger, {
|
|
43
|
+
asChild: true,
|
|
44
|
+
children: /*#__PURE__*/ _jsx("span", {
|
|
45
|
+
className: "shrink-0",
|
|
46
|
+
children: /*#__PURE__*/ _jsx(IntegrationIcon, {
|
|
47
|
+
source: connection.provider,
|
|
48
|
+
"aria-hidden": true,
|
|
49
|
+
className: "size-20 text-foreground-neutral-base"
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
}),
|
|
53
|
+
/*#__PURE__*/ _jsx(TooltipContent, {
|
|
54
|
+
children: integrationName(connection.provider)
|
|
55
|
+
})
|
|
56
|
+
]
|
|
57
|
+
}),
|
|
58
|
+
/*#__PURE__*/ _jsxs(Tooltip, {
|
|
59
|
+
children: [
|
|
60
|
+
/*#__PURE__*/ _jsx(TooltipTrigger, {
|
|
61
|
+
asChild: true,
|
|
62
|
+
children: /*#__PURE__*/ _jsx("span", {
|
|
63
|
+
ref: nameRef,
|
|
64
|
+
className: "min-w-0 truncate",
|
|
65
|
+
children: /*#__PURE__*/ _jsx(Text, {
|
|
66
|
+
as: "span",
|
|
67
|
+
size: "sm",
|
|
68
|
+
bold: true,
|
|
69
|
+
children: connection.display_name
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
}),
|
|
73
|
+
isTruncated ? /*#__PURE__*/ _jsx(TooltipContent, {
|
|
74
|
+
children: connection.display_name
|
|
75
|
+
}) : null
|
|
76
|
+
]
|
|
77
|
+
})
|
|
78
|
+
]
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function integrationName(provider) {
|
|
82
|
+
switch(provider){
|
|
83
|
+
case 'github':
|
|
84
|
+
return 'GitHub';
|
|
85
|
+
case 'gitea':
|
|
86
|
+
return 'Gitea';
|
|
87
|
+
case 'sentry':
|
|
88
|
+
return 'Sentry';
|
|
89
|
+
case 'webhook':
|
|
90
|
+
return 'Webhook';
|
|
91
|
+
case 'debug':
|
|
92
|
+
return 'Debug';
|
|
93
|
+
default:
|
|
94
|
+
return provider;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
//# sourceMappingURL=connection-picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/connection-picker.tsx"],"sourcesContent":["import type {IntegrationConnectionDto} from '@shipfox/api-integration-core-dto';\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 {IntegrationIcon} from '#integration-icon.js';\n\nexport function ConnectionPicker({\n connections,\n selectedConnectionId,\n onSelect,\n}: {\n connections: IntegrationConnectionDto[];\n selectedConnectionId: string | undefined;\n onSelect: (connectionId: string) => void;\n}) {\n const labelId = useId();\n\n return (\n <div className=\"flex flex-col gap-10\">\n <Label id={labelId} className=\"sr-only\">\n Source integration\n </Label>\n <RadioGroup\n aria-labelledby={labelId}\n value={selectedConnectionId ?? ''}\n onValueChange={onSelect}\n className=\"grid grid-cols-2 gap-8 min-[1200px]:grid-cols-3 max-[760px]:grid-cols-1\"\n >\n {connections.map((connection) => (\n <RadioGroupItem key={connection.id} value={connection.id} className=\"p-12\">\n <ConnectionOption connection={connection} />\n </RadioGroupItem>\n ))}\n </RadioGroup>\n </div>\n );\n}\n\nfunction ConnectionOption({connection}: {connection: IntegrationConnectionDto}) {\n const {ref: nameRef, isTruncated} = useIsTextTruncated<HTMLSpanElement>(connection.display_name);\n\n return (\n <span className=\"flex min-w-0 items-center gap-10\">\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.display_name}\n </Text>\n </span>\n </TooltipTrigger>\n {isTruncated ? <TooltipContent>{connection.display_name}</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":["useIsTextTruncated","Label","RadioGroup","RadioGroupItem","Tooltip","TooltipContent","TooltipTrigger","Text","useId","IntegrationIcon","ConnectionPicker","connections","selectedConnectionId","onSelect","labelId","div","className","id","aria-labelledby","value","onValueChange","map","connection","ConnectionOption","ref","nameRef","isTruncated","display_name","span","asChild","source","provider","aria-hidden","integrationName","as","size","bold"],"mappings":";AACA,SAAQA,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;AAC5B,SAAQC,eAAe,QAAO,uBAAuB;AAErD,OAAO,SAASC,iBAAiB,EAC/BC,WAAW,EACXC,oBAAoB,EACpBC,QAAQ,EAKT;IACC,MAAMC,UAAUN;IAEhB,qBACE,MAACO;QAAIC,WAAU;;0BACb,KAACf;gBAAMgB,IAAIH;gBAASE,WAAU;0BAAU;;0BAGxC,KAACd;gBACCgB,mBAAiBJ;gBACjBK,OAAOP,wBAAwB;gBAC/BQ,eAAeP;gBACfG,WAAU;0BAETL,YAAYU,GAAG,CAAC,CAACC,2BAChB,KAACnB;wBAAmCgB,OAAOG,WAAWL,EAAE;wBAAED,WAAU;kCAClE,cAAA,KAACO;4BAAiBD,YAAYA;;uBADXA,WAAWL,EAAE;;;;AAO5C;AAEA,SAASM,iBAAiB,EAACD,UAAU,EAAyC;IAC5E,MAAM,EAACE,KAAKC,OAAO,EAAEC,WAAW,EAAC,GAAG1B,mBAAoCsB,WAAWK,YAAY;IAE/F,qBACE,MAACC;QAAKZ,WAAU;;0BACd,MAACZ;;kCACC,KAACE;wBAAeuB,OAAO;kCACrB,cAAA,KAACD;4BAAKZ,WAAU;sCACd,cAAA,KAACP;gCACCqB,QAAQR,WAAWS,QAAQ;gCAC3BC,aAAW;gCACXhB,WAAU;;;;kCAIhB,KAACX;kCAAgB4B,gBAAgBX,WAAWS,QAAQ;;;;0BAGtD,MAAC3B;;kCACC,KAACE;wBAAeuB,OAAO;kCACrB,cAAA,KAACD;4BAAKJ,KAAKC;4BAAST,WAAU;sCAC5B,cAAA,KAACT;gCAAK2B,IAAG;gCAAOC,MAAK;gCAAKC,IAAI;0CAC3Bd,WAAWK,YAAY;;;;oBAI7BD,4BAAc,KAACrB;kCAAgBiB,WAAWK,YAAY;yBAAqB;;;;;AAIpF;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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { IntegrationConnectionDto, ListIntegrationConnectionsResponseDto } from '@shipfox/api-integration-core-dto';
|
|
2
|
+
import type { UseQueryResult } from '@tanstack/react-query';
|
|
3
|
+
interface InstalledIntegrationsSectionProps {
|
|
4
|
+
connectionsQuery: UseQueryResult<ListIntegrationConnectionsResponseDto, Error>;
|
|
5
|
+
connections: IntegrationConnectionDto[];
|
|
6
|
+
isMutating: boolean;
|
|
7
|
+
onUse: (connectionId: string) => void;
|
|
8
|
+
onSetActive: (connection: IntegrationConnectionDto, active: boolean) => void;
|
|
9
|
+
onDelete: (connectionId: string) => void;
|
|
10
|
+
providerDisplayName: (provider: string) => string | undefined;
|
|
11
|
+
}
|
|
12
|
+
export declare function InstalledIntegrationsSection({ connectionsQuery, connections, isMutating, onUse, onSetActive, onDelete, providerDisplayName, }: InstalledIntegrationsSectionProps): import("react").JSX.Element;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=installed-integrations-section.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installed-integrations-section.d.ts","sourceRoot":"","sources":["../../src/components/installed-integrations-section.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,qCAAqC,EACtC,MAAM,mCAAmC,CAAC;AAc3C,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,uBAAuB,CAAC;AAM1D,UAAU,iCAAiC;IACzC,gBAAgB,EAAE,cAAc,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAC;IAC/E,WAAW,EAAE,wBAAwB,EAAE,CAAC;IACxC,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,WAAW,EAAE,CAAC,UAAU,EAAE,wBAAwB,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7E,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,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,KAAK,EACL,WAAW,EACX,QAAQ,EACR,mBAAmB,GACpB,EAAE,iCAAiC,+BA6CnC"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { QueryLoadError } from '@shipfox/client-ui';
|
|
3
|
+
import { IconButton } from '@shipfox/react-ui/button';
|
|
4
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from '@shipfox/react-ui/dropdown-menu';
|
|
5
|
+
import { EmptyState } from '@shipfox/react-ui/empty-state';
|
|
6
|
+
import { Skeleton } from '@shipfox/react-ui/skeleton';
|
|
7
|
+
import { Header, Text } from '@shipfox/react-ui/typography';
|
|
8
|
+
import { cn, formatDate } from '@shipfox/react-ui/utils';
|
|
9
|
+
import { Link } from '@tanstack/react-router';
|
|
10
|
+
import { ConnectionStatusBadge } from '#connection-status-badge.js';
|
|
11
|
+
import { IntegrationIcon } from '#integration-icon.js';
|
|
12
|
+
import { usageEventsForConnection } from './integration-usage-events.js';
|
|
13
|
+
const INSTALLED_SURFACE_CLASS = 'overflow-hidden rounded-8 border border-border-neutral-base bg-background-neutral-base';
|
|
14
|
+
export function InstalledIntegrationsSection({ connectionsQuery, connections, isMutating, onUse, onSetActive, onDelete, providerDisplayName }) {
|
|
15
|
+
return /*#__PURE__*/ _jsxs("section", {
|
|
16
|
+
className: "flex flex-col gap-16",
|
|
17
|
+
"aria-label": "Installed integrations",
|
|
18
|
+
children: [
|
|
19
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
20
|
+
className: "flex flex-col gap-4",
|
|
21
|
+
children: [
|
|
22
|
+
/*#__PURE__*/ _jsx(Header, {
|
|
23
|
+
variant: "h3",
|
|
24
|
+
children: "Installed integrations"
|
|
25
|
+
}),
|
|
26
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
27
|
+
size: "sm",
|
|
28
|
+
className: "text-foreground-neutral-muted",
|
|
29
|
+
children: "Provider accounts installed in this workspace."
|
|
30
|
+
})
|
|
31
|
+
]
|
|
32
|
+
}),
|
|
33
|
+
connectionsQuery.isPending ? /*#__PURE__*/ _jsx(InstalledSkeleton, {
|
|
34
|
+
label: "Loading integrations"
|
|
35
|
+
}) : null,
|
|
36
|
+
connectionsQuery.isError && connectionsQuery.data === undefined ? /*#__PURE__*/ _jsx("div", {
|
|
37
|
+
className: cn(INSTALLED_SURFACE_CLASS, 'px-16'),
|
|
38
|
+
children: /*#__PURE__*/ _jsx(QueryLoadError, {
|
|
39
|
+
query: connectionsQuery,
|
|
40
|
+
subject: "integrations"
|
|
41
|
+
})
|
|
42
|
+
}) : null,
|
|
43
|
+
connectionsQuery.data !== undefined && connections.length === 0 ? /*#__PURE__*/ _jsx("div", {
|
|
44
|
+
className: cn(INSTALLED_SURFACE_CLASS, 'px-16'),
|
|
45
|
+
children: /*#__PURE__*/ _jsx(EmptyState, {
|
|
46
|
+
icon: "componentLine",
|
|
47
|
+
title: "No integrations installed yet",
|
|
48
|
+
description: "Install a provider below to get started."
|
|
49
|
+
})
|
|
50
|
+
}) : null,
|
|
51
|
+
connections.length > 0 ? /*#__PURE__*/ _jsx("ul", {
|
|
52
|
+
className: cn('divide-y divide-border-neutral-base', INSTALLED_SURFACE_CLASS),
|
|
53
|
+
children: connections.map((connection)=>/*#__PURE__*/ _jsx(InstalledRow, {
|
|
54
|
+
connection: connection,
|
|
55
|
+
isMutating: isMutating,
|
|
56
|
+
onUse: onUse,
|
|
57
|
+
onSetActive: (nextActive)=>onSetActive(connection, nextActive),
|
|
58
|
+
onDelete: onDelete,
|
|
59
|
+
providerDisplayName: providerDisplayName
|
|
60
|
+
}, connection.id))
|
|
61
|
+
}) : null
|
|
62
|
+
]
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function InstalledRow({ connection, isMutating, onUse, onSetActive, onDelete, providerDisplayName }) {
|
|
66
|
+
const muted = connection.lifecycle_status === 'disabled';
|
|
67
|
+
const active = connection.lifecycle_status === 'active';
|
|
68
|
+
const recentEventsEvent = usageEventsForConnection(connection)[0]?.value ?? 'received';
|
|
69
|
+
const providerName = providerDisplayName(connection.provider);
|
|
70
|
+
return /*#__PURE__*/ _jsxs("li", {
|
|
71
|
+
className: "flex items-center gap-12 px-16 py-12 transition-colors hover:bg-background-components-hover",
|
|
72
|
+
children: [
|
|
73
|
+
/*#__PURE__*/ _jsx(IntegrationIcon, {
|
|
74
|
+
source: connection.provider,
|
|
75
|
+
"aria-hidden": true,
|
|
76
|
+
className: cn('size-24 shrink-0', muted ? 'text-foreground-neutral-disabled' : 'text-foreground-neutral-base')
|
|
77
|
+
}),
|
|
78
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
79
|
+
className: "flex min-w-0 flex-1 flex-col gap-2",
|
|
80
|
+
children: [
|
|
81
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
82
|
+
className: "flex min-w-0 items-center gap-8",
|
|
83
|
+
children: [
|
|
84
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
85
|
+
size: "md",
|
|
86
|
+
bold: true,
|
|
87
|
+
className: cn('truncate', muted ? 'text-foreground-neutral-disabled' : undefined),
|
|
88
|
+
children: connection.display_name
|
|
89
|
+
}),
|
|
90
|
+
/*#__PURE__*/ _jsx(ConnectionStatusBadge, {
|
|
91
|
+
status: connection.lifecycle_status,
|
|
92
|
+
className: "shrink-0"
|
|
93
|
+
})
|
|
94
|
+
]
|
|
95
|
+
}),
|
|
96
|
+
/*#__PURE__*/ _jsxs(Text, {
|
|
97
|
+
size: "sm",
|
|
98
|
+
className: "truncate text-foreground-neutral-muted",
|
|
99
|
+
children: [
|
|
100
|
+
"Added ",
|
|
101
|
+
formatDate(connection.created_at)
|
|
102
|
+
]
|
|
103
|
+
})
|
|
104
|
+
]
|
|
105
|
+
}),
|
|
106
|
+
/*#__PURE__*/ _jsxs(DropdownMenu, {
|
|
107
|
+
children: [
|
|
108
|
+
/*#__PURE__*/ _jsx(DropdownMenuTrigger, {
|
|
109
|
+
asChild: true,
|
|
110
|
+
children: /*#__PURE__*/ _jsx(IconButton, {
|
|
111
|
+
size: "sm",
|
|
112
|
+
variant: "transparent",
|
|
113
|
+
icon: "more2Line",
|
|
114
|
+
"aria-label": `Open ${connection.display_name} integration actions`
|
|
115
|
+
})
|
|
116
|
+
}),
|
|
117
|
+
/*#__PURE__*/ _jsxs(DropdownMenuContent, {
|
|
118
|
+
align: "end",
|
|
119
|
+
children: [
|
|
120
|
+
connection.external_url ? /*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
121
|
+
asChild: true,
|
|
122
|
+
children: /*#__PURE__*/ _jsx("a", {
|
|
123
|
+
href: connection.external_url,
|
|
124
|
+
target: "_blank",
|
|
125
|
+
rel: "noreferrer noopener",
|
|
126
|
+
children: providerName ? `Open in ${providerName}` : 'Open provider settings'
|
|
127
|
+
})
|
|
128
|
+
}) : null,
|
|
129
|
+
/*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
130
|
+
onSelect: ()=>onUse(connection.id),
|
|
131
|
+
children: "Use this integration"
|
|
132
|
+
}),
|
|
133
|
+
/*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
134
|
+
asChild: true,
|
|
135
|
+
children: /*#__PURE__*/ _jsx(Link, {
|
|
136
|
+
to: "/workspaces/$wid/settings/events",
|
|
137
|
+
params: {
|
|
138
|
+
wid: connection.workspace_id
|
|
139
|
+
},
|
|
140
|
+
search: {
|
|
141
|
+
source: [
|
|
142
|
+
connection.slug
|
|
143
|
+
],
|
|
144
|
+
event: [
|
|
145
|
+
recentEventsEvent
|
|
146
|
+
]
|
|
147
|
+
},
|
|
148
|
+
children: "View recent events"
|
|
149
|
+
})
|
|
150
|
+
}),
|
|
151
|
+
/*#__PURE__*/ _jsx(DropdownMenuSeparator, {}),
|
|
152
|
+
/*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
153
|
+
disabled: isMutating,
|
|
154
|
+
onSelect: ()=>onSetActive(!active),
|
|
155
|
+
children: active ? 'Disable integration' : 'Enable integration'
|
|
156
|
+
}),
|
|
157
|
+
/*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
158
|
+
disabled: isMutating,
|
|
159
|
+
onSelect: ()=>onDelete(connection.id),
|
|
160
|
+
children: "Delete integration"
|
|
161
|
+
})
|
|
162
|
+
]
|
|
163
|
+
})
|
|
164
|
+
]
|
|
165
|
+
})
|
|
166
|
+
]
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
function InstalledSkeleton({ label }) {
|
|
170
|
+
return /*#__PURE__*/ _jsx("ul", {
|
|
171
|
+
role: "status",
|
|
172
|
+
"aria-label": label,
|
|
173
|
+
className: cn('divide-y divide-border-neutral-base', INSTALLED_SURFACE_CLASS),
|
|
174
|
+
children: [
|
|
175
|
+
0,
|
|
176
|
+
1,
|
|
177
|
+
2
|
|
178
|
+
].map((row)=>/*#__PURE__*/ _jsxs("li", {
|
|
179
|
+
className: "flex items-center gap-12 px-16 py-12",
|
|
180
|
+
children: [
|
|
181
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
182
|
+
className: "size-24 shrink-0"
|
|
183
|
+
}),
|
|
184
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
185
|
+
className: "flex min-w-0 flex-1 flex-col gap-2",
|
|
186
|
+
children: [
|
|
187
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
188
|
+
className: "h-16 w-120"
|
|
189
|
+
}),
|
|
190
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
191
|
+
className: "h-12 w-80"
|
|
192
|
+
})
|
|
193
|
+
]
|
|
194
|
+
}),
|
|
195
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
196
|
+
className: "h-20 w-72 shrink-0"
|
|
197
|
+
})
|
|
198
|
+
]
|
|
199
|
+
}, row))
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
//# sourceMappingURL=installed-integrations-section.js.map
|