@shipfox/client-integrations 17.0.0 → 22.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +39 -0
- package/dist/components/callback-status-shell.d.ts.map +1 -1
- package/dist/components/callback-status-shell.js +4 -3
- package/dist/components/callback-status-shell.js.map +1 -1
- package/dist/components/connection-picker.js +2 -2
- package/dist/components/connection-picker.js.map +1 -1
- package/dist/components/installed-integrations-section.d.ts.map +1 -1
- package/dist/components/installed-integrations-section.js +155 -141
- package/dist/components/installed-integrations-section.js.map +1 -1
- package/dist/components/integration-gallery.stories.d.ts.map +1 -1
- package/dist/components/integration-gallery.stories.js +8 -3
- package/dist/components/integration-gallery.stories.js.map +1 -1
- package/dist/components/provider-grid.d.ts +0 -2
- package/dist/components/provider-grid.d.ts.map +1 -1
- package/dist/components/provider-grid.js +88 -104
- package/dist/components/provider-grid.js.map +1 -1
- package/dist/components/redirect-install-page.d.ts.map +1 -1
- package/dist/components/redirect-install-page.js +3 -2
- package/dist/components/redirect-install-page.js.map +1 -1
- package/dist/components/repository-picker.d.ts +1 -4
- package/dist/components/repository-picker.d.ts.map +1 -1
- package/dist/components/repository-picker.js +24 -37
- package/dist/components/repository-picker.js.map +1 -1
- package/dist/components/webhook/webhook-modals.stories.js +1 -1
- package/dist/components/webhook/webhook-modals.stories.js.map +1 -1
- package/dist/pages/gitea-install-page.js +1 -1
- package/dist/pages/gitea-install-page.js.map +1 -1
- package/dist/pages/jira-callback-page.js +6 -6
- package/dist/pages/jira-callback-page.js.map +1 -1
- package/dist/pages/sentry-callback-page.js +6 -6
- package/dist/pages/sentry-callback-page.js.map +1 -1
- package/dist/pages/source-control-onboarding-page.js +1 -1
- package/dist/pages/source-control-onboarding-page.js.map +1 -1
- package/dist/routes/gitea.d.ts +3 -0
- package/dist/routes/gitea.js +3 -0
- package/dist/routes/gitea.js.map +1 -1
- package/dist/routes/github-callback.d.ts +3 -0
- package/dist/routes/github-callback.d.ts.map +1 -1
- package/dist/routes/github-callback.js +3 -0
- package/dist/routes/github-callback.js.map +1 -1
- package/dist/routes/github.d.ts +3 -0
- package/dist/routes/github.js +3 -0
- package/dist/routes/github.js.map +1 -1
- package/dist/routes/integrations-settings.d.ts +3 -0
- package/dist/routes/integrations-settings.js +3 -0
- package/dist/routes/integrations-settings.js.map +1 -1
- package/dist/routes/integrations.d.ts +3 -0
- package/dist/routes/integrations.js +3 -0
- package/dist/routes/integrations.js.map +1 -1
- package/dist/routes/jira-callback.d.ts +3 -0
- package/dist/routes/jira-callback.js +3 -0
- package/dist/routes/jira-callback.js.map +1 -1
- package/dist/routes/jira.d.ts +3 -0
- package/dist/routes/jira.js +3 -0
- package/dist/routes/jira.js.map +1 -1
- package/dist/routes/linear-callback.d.ts +3 -0
- package/dist/routes/linear-callback.js +3 -0
- package/dist/routes/linear-callback.js.map +1 -1
- package/dist/routes/linear.d.ts +3 -0
- package/dist/routes/linear.js +3 -0
- package/dist/routes/linear.js.map +1 -1
- package/dist/routes/sentry-callback.d.ts +3 -0
- package/dist/routes/sentry-callback.js +3 -0
- package/dist/routes/sentry-callback.js.map +1 -1
- package/dist/routes/sentry.d.ts +3 -0
- package/dist/routes/sentry.js +3 -0
- package/dist/routes/sentry.js.map +1 -1
- package/dist/routes/slack-callback.d.ts +3 -0
- package/dist/routes/slack-callback.js +3 -0
- package/dist/routes/slack-callback.js.map +1 -1
- package/dist/routes/slack.d.ts +3 -0
- package/dist/routes/slack.js +3 -0
- package/dist/routes/slack.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +8 -8
- package/src/components/callback-status-shell.tsx +4 -3
- package/src/components/connection-picker.tsx +2 -2
- package/src/components/installed-integrations-section.tsx +110 -98
- package/src/components/integration-gallery.stories.tsx +8 -3
- package/src/components/integration-gallery.test.tsx +3 -1
- package/src/components/provider-grid.tsx +69 -79
- package/src/components/redirect-install-page.test.tsx +4 -0
- package/src/components/redirect-install-page.tsx +3 -2
- package/src/components/repository-picker.test.tsx +27 -13
- package/src/components/repository-picker.tsx +22 -47
- package/src/components/webhook/webhook-modals.stories.tsx +1 -1
- package/src/pages/gitea-install-page.tsx +1 -1
- package/src/pages/jira-callback-page.tsx +7 -7
- package/src/pages/sentry-callback-page.tsx +6 -8
- package/src/pages/slack-callback-page.test.tsx +7 -0
- package/src/pages/source-control-onboarding-page.tsx +1 -1
- package/src/routes/gitea.tsx +4 -1
- package/src/routes/github-callback.tsx +1 -0
- package/src/routes/github.tsx +4 -1
- package/src/routes/integrations-settings.tsx +4 -1
- package/src/routes/integrations.tsx +4 -1
- package/src/routes/jira-callback.tsx +1 -0
- package/src/routes/jira.tsx +4 -1
- package/src/routes/linear-callback.tsx +1 -0
- package/src/routes/linear.tsx +4 -1
- package/src/routes/sentry-callback.tsx +1 -0
- package/src/routes/sentry.tsx +4 -1
- package/src/routes/slack-callback.tsx +1 -0
- package/src/routes/slack.tsx +4 -1
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -17,6 +17,19 @@ afterEach(() => {
|
|
|
17
17
|
});
|
|
18
18
|
|
|
19
19
|
describe('RepositoryPicker', () => {
|
|
20
|
+
test('renders the default empty message without an internal search control', () => {
|
|
21
|
+
renderPicker();
|
|
22
|
+
|
|
23
|
+
expect(screen.getByText('No repositories found.')).toBeInTheDocument();
|
|
24
|
+
expect(screen.queryByRole('searchbox')).not.toBeInTheDocument();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('renders a custom empty message', () => {
|
|
28
|
+
renderPicker({emptyMessage: 'No repositories visible to this connection.'});
|
|
29
|
+
|
|
30
|
+
expect(screen.getByText('No repositories visible to this connection.')).toBeInTheDocument();
|
|
31
|
+
});
|
|
32
|
+
|
|
20
33
|
test('renders repository names without owner or default branch metadata', () => {
|
|
21
34
|
renderPicker({
|
|
22
35
|
repositories: [
|
|
@@ -65,27 +78,28 @@ describe('RepositoryPicker', () => {
|
|
|
65
78
|
const {container} = renderPicker({
|
|
66
79
|
repositories: [],
|
|
67
80
|
isLoading: true,
|
|
68
|
-
searchValue: '',
|
|
69
|
-
onSearchChange: () => undefined,
|
|
70
81
|
});
|
|
71
82
|
|
|
72
83
|
expect(screen.getByRole('status')).toHaveTextContent('Loading repositories.');
|
|
73
|
-
expect(screen.
|
|
84
|
+
expect(screen.queryByRole('searchbox')).not.toBeInTheDocument();
|
|
74
85
|
|
|
75
86
|
const loadingGrid = container.querySelector('[aria-hidden="true"]');
|
|
76
87
|
if (!loadingGrid) throw new Error('Repository loading grid was not rendered');
|
|
77
88
|
|
|
78
|
-
|
|
89
|
+
// The placeholders sit in the same hairline cell grid as the loaded cards,
|
|
90
|
+
// so the list does not change shape when the fetch resolves.
|
|
91
|
+
expect(loadingGrid).toHaveClass('grid', 'grid-cols-2', 'max-[760px]:grid-cols-1');
|
|
92
|
+
expect(loadingGrid).toHaveClass('min-[760px]:[&>*:nth-child(2n_of_:not(input))]:border-l');
|
|
93
|
+
expect(loadingGrid).not.toHaveClass('gap-inline');
|
|
79
94
|
expect(loadingGrid.querySelectorAll('[data-slot="skeleton"]')).toHaveLength(4);
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
);
|
|
95
|
+
// The placeholder box belongs to `RadioGroupItemSkeleton`, so this only
|
|
96
|
+
// checks that each slot carries the indicator and one bar. react-ui owns
|
|
97
|
+
// keeping that surface identical to a real item.
|
|
98
|
+
const placeholders = loadingGrid.querySelectorAll(':scope > div');
|
|
99
|
+
expect(placeholders).toHaveLength(4);
|
|
100
|
+
for (const placeholder of placeholders) {
|
|
101
|
+
expect(placeholder.querySelector('[data-slot="radio-indicator"]')).not.toBeNull();
|
|
102
|
+
expect(placeholder.querySelector('[data-slot="skeleton"]')).not.toBeNull();
|
|
89
103
|
}
|
|
90
104
|
});
|
|
91
105
|
});
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import {Button} from '@shipfox/react-ui/button';
|
|
2
2
|
import {useIsTextTruncated} from '@shipfox/react-ui/hooks';
|
|
3
|
-
import {Input} from '@shipfox/react-ui/input';
|
|
4
3
|
import {Label} from '@shipfox/react-ui/label';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import {PanelGrid} from '@shipfox/react-ui/panel';
|
|
5
|
+
import {RadioGroup, RadioGroupItem, RadioGroupItemSkeleton} from '@shipfox/react-ui/radio-group';
|
|
7
6
|
import {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';
|
|
8
7
|
import {Text} from '@shipfox/react-ui/typography';
|
|
9
8
|
import {useId} from 'react';
|
|
10
9
|
import type {Repository} from '#core/models.js';
|
|
11
10
|
|
|
12
|
-
const REPOSITORY_GRID_CLASS_NAME = 'grid grid-cols-2 gap-inline max-[760px]:grid-cols-1';
|
|
13
11
|
const REPOSITORY_SKELETON_WIDTHS = ['w-64', 'w-96', 'w-80', 'w-112'] as const;
|
|
14
12
|
|
|
15
13
|
export function RepositoryPicker({
|
|
@@ -21,9 +19,6 @@ export function RepositoryPicker({
|
|
|
21
19
|
hasNextPage,
|
|
22
20
|
onLoadMore,
|
|
23
21
|
emptyMessage = 'No repositories found.',
|
|
24
|
-
searchValue,
|
|
25
|
-
onSearchChange,
|
|
26
|
-
searchDisabled,
|
|
27
22
|
}: {
|
|
28
23
|
repositories: Repository[];
|
|
29
24
|
selectedRepositoryId: string | undefined;
|
|
@@ -33,44 +28,29 @@ export function RepositoryPicker({
|
|
|
33
28
|
hasNextPage?: boolean;
|
|
34
29
|
onLoadMore?: () => void;
|
|
35
30
|
emptyMessage?: string;
|
|
36
|
-
searchValue?: string;
|
|
37
|
-
onSearchChange?: (value: string) => void;
|
|
38
|
-
searchDisabled?: boolean;
|
|
39
31
|
}) {
|
|
40
32
|
const labelId = useId();
|
|
41
|
-
const showSearch = onSearchChange !== undefined;
|
|
42
33
|
|
|
43
34
|
return (
|
|
44
|
-
<div className="flex flex-col
|
|
35
|
+
<div className="flex min-w-0 flex-col">
|
|
45
36
|
<Label id={labelId} className="sr-only">
|
|
46
37
|
Repository
|
|
47
38
|
</Label>
|
|
48
39
|
|
|
49
|
-
{showSearch ? (
|
|
50
|
-
<Input
|
|
51
|
-
type="search"
|
|
52
|
-
placeholder="Search repositories…"
|
|
53
|
-
aria-label="Search repositories"
|
|
54
|
-
value={searchValue ?? ''}
|
|
55
|
-
onChange={(event) => onSearchChange?.(event.target.value)}
|
|
56
|
-
disabled={searchDisabled}
|
|
57
|
-
/>
|
|
58
|
-
) : null}
|
|
59
|
-
|
|
60
40
|
{isLoading ? <RepositoryLoadingState /> : null}
|
|
61
41
|
|
|
62
42
|
{!isLoading && repositories.length === 0 ? (
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
</
|
|
43
|
+
<Text size="sm" className="px-row py-row">
|
|
44
|
+
{emptyMessage}
|
|
45
|
+
</Text>
|
|
66
46
|
) : null}
|
|
67
47
|
|
|
68
48
|
{repositories.length > 0 ? (
|
|
69
49
|
<RadioGroup
|
|
50
|
+
variant="cell"
|
|
70
51
|
aria-labelledby={labelId}
|
|
71
52
|
value={selectedRepositoryId ?? ''}
|
|
72
53
|
onValueChange={onSelect}
|
|
73
|
-
className={REPOSITORY_GRID_CLASS_NAME}
|
|
74
54
|
>
|
|
75
55
|
{repositories.map((repository) => (
|
|
76
56
|
<RepositoryCard key={repository.externalRepositoryId} repository={repository} />
|
|
@@ -79,15 +59,17 @@ export function RepositoryPicker({
|
|
|
79
59
|
) : null}
|
|
80
60
|
|
|
81
61
|
{hasNextPage && onLoadMore ? (
|
|
82
|
-
<
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
62
|
+
<div className="flex justify-center border-t border-border-neutral-base p-panel-compact">
|
|
63
|
+
<Button
|
|
64
|
+
type="button"
|
|
65
|
+
variant="secondary"
|
|
66
|
+
size="sm"
|
|
67
|
+
isLoading={isFetchingNextPage ?? false}
|
|
68
|
+
onClick={onLoadMore}
|
|
69
|
+
>
|
|
70
|
+
Load more
|
|
71
|
+
</Button>
|
|
72
|
+
</div>
|
|
91
73
|
) : null}
|
|
92
74
|
</div>
|
|
93
75
|
);
|
|
@@ -99,7 +81,7 @@ function RepositoryCard({repository}: {repository: Repository}) {
|
|
|
99
81
|
return (
|
|
100
82
|
<Tooltip>
|
|
101
83
|
<TooltipTrigger asChild>
|
|
102
|
-
<RadioGroupItem value={repository.externalRepositoryId}
|
|
84
|
+
<RadioGroupItem value={repository.externalRepositoryId}>
|
|
103
85
|
<span ref={nameRef} className="block min-w-0 truncate">
|
|
104
86
|
<Text as="span" size="sm" bold>
|
|
105
87
|
{repository.name}
|
|
@@ -118,18 +100,11 @@ function RepositoryLoadingState() {
|
|
|
118
100
|
<div role="status" className="sr-only">
|
|
119
101
|
Loading repositories.
|
|
120
102
|
</div>
|
|
121
|
-
<div aria-hidden="true"
|
|
122
|
-
{/* The skeleton mirrors RadioGroupItem's own 14px padding contract so the
|
|
123
|
-
placeholder and the loaded card stay the same height. */}
|
|
103
|
+
<PanelGrid as="div" aria-hidden="true">
|
|
124
104
|
{REPOSITORY_SKELETON_WIDTHS.map((width) => (
|
|
125
|
-
<
|
|
126
|
-
key={width}
|
|
127
|
-
className="h-50 min-w-0 rounded-8 border border-border-neutral-base bg-background-neutral-base p-[14px]"
|
|
128
|
-
>
|
|
129
|
-
<Skeleton className={`h-20 ${width}`} />
|
|
130
|
-
</div>
|
|
105
|
+
<RadioGroupItemSkeleton key={width} variant="cell" labelClassName={width} />
|
|
131
106
|
))}
|
|
132
|
-
</
|
|
107
|
+
</PanelGrid>
|
|
133
108
|
</>
|
|
134
109
|
);
|
|
135
110
|
}
|
|
@@ -126,7 +126,7 @@ export const CopyableValueState: Story = {
|
|
|
126
126
|
|
|
127
127
|
function StorySurface({scenario}: {scenario: Scenario}) {
|
|
128
128
|
return (
|
|
129
|
-
<div className="min-h-screen bg-background-
|
|
129
|
+
<div className="min-h-screen bg-background-subtle-base p-24">
|
|
130
130
|
{scenario === 'create-form' ? (
|
|
131
131
|
<WebhookCreateModal
|
|
132
132
|
workspaceId={WORKSPACE_ID}
|
|
@@ -40,7 +40,7 @@ export function GiteaInstallPage() {
|
|
|
40
40
|
});
|
|
41
41
|
|
|
42
42
|
return (
|
|
43
|
-
<div className="
|
|
43
|
+
<div className="flex w-full flex-col gap-section">
|
|
44
44
|
<header className="flex flex-col gap-inline">
|
|
45
45
|
<Header variant="h1">Install Gitea</Header>
|
|
46
46
|
<Text size="md" className="text-foreground-neutral-muted">
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {useAuthState, useRefreshAuth} from '@shipfox/client-auth';
|
|
2
|
-
import {useRouteSearch} from '@shipfox/client-shell/runtime';
|
|
2
|
+
import {FocusedFrame, useRouteSearch} from '@shipfox/client-shell/runtime';
|
|
3
3
|
import {sessionStorageOrUndefined} from '@shipfox/client-ui';
|
|
4
4
|
import {Button, ButtonLink} from '@shipfox/react-ui/button';
|
|
5
5
|
import {Callout} from '@shipfox/react-ui/callout';
|
|
6
|
-
import {Card} from '@shipfox/react-ui/card';
|
|
7
6
|
import {FullPageLoader} from '@shipfox/react-ui/loader';
|
|
7
|
+
import {Panel} from '@shipfox/react-ui/panel';
|
|
8
8
|
import {toast} from '@shipfox/react-ui/toast';
|
|
9
9
|
import {Header, Text} from '@shipfox/react-ui/typography';
|
|
10
10
|
import {useQueryClient} from '@tanstack/react-query';
|
|
@@ -300,8 +300,8 @@ function JiraSiteSelectionPage({
|
|
|
300
300
|
onSelect: (site: JiraSite) => void;
|
|
301
301
|
}) {
|
|
302
302
|
return (
|
|
303
|
-
<main className="flex min-h-screen
|
|
304
|
-
<
|
|
303
|
+
<main className="flex min-h-screen px-frame py-frame">
|
|
304
|
+
<FocusedFrame className="flex flex-col justify-center gap-section">
|
|
305
305
|
<header className="flex flex-col gap-inline">
|
|
306
306
|
<Header variant="h2">Choose a Jira site</Header>
|
|
307
307
|
<Text size="sm" className="text-foreground-neutral-muted">
|
|
@@ -317,7 +317,7 @@ function JiraSiteSelectionPage({
|
|
|
317
317
|
|
|
318
318
|
<section className="flex flex-col gap-inline" aria-label="Choose a Jira site">
|
|
319
319
|
{sites.map((site) => (
|
|
320
|
-
<
|
|
320
|
+
<Panel key={site.cloudId} className="p-panel-compact">
|
|
321
321
|
<div className="flex items-center justify-between gap-cluster">
|
|
322
322
|
<div className="min-w-0">
|
|
323
323
|
<Text size="md" bold className="truncate">
|
|
@@ -336,7 +336,7 @@ function JiraSiteSelectionPage({
|
|
|
336
336
|
Connect
|
|
337
337
|
</Button>
|
|
338
338
|
</div>
|
|
339
|
-
</
|
|
339
|
+
</Panel>
|
|
340
340
|
))}
|
|
341
341
|
</section>
|
|
342
342
|
|
|
@@ -360,7 +360,7 @@ function JiraSiteSelectionPage({
|
|
|
360
360
|
</ButtonLink>
|
|
361
361
|
)}
|
|
362
362
|
</div>
|
|
363
|
-
</
|
|
363
|
+
</FocusedFrame>
|
|
364
364
|
</main>
|
|
365
365
|
);
|
|
366
366
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {useAuthState, useRefreshAuth} from '@shipfox/client-auth';
|
|
2
|
-
import {useRouteSearch} from '@shipfox/client-shell/runtime';
|
|
2
|
+
import {FocusedFrame, useRouteSearch} from '@shipfox/client-shell/runtime';
|
|
3
3
|
import {createSingleFlight, sessionStorageOrUndefined} from '@shipfox/client-ui';
|
|
4
4
|
import {Button, ButtonLink} from '@shipfox/react-ui/button';
|
|
5
5
|
import {Callout} from '@shipfox/react-ui/callout';
|
|
6
|
-
import {Card} from '@shipfox/react-ui/card';
|
|
7
6
|
import {FullPageLoader} from '@shipfox/react-ui/loader';
|
|
7
|
+
import {Panel} from '@shipfox/react-ui/panel';
|
|
8
8
|
import {toast} from '@shipfox/react-ui/toast';
|
|
9
9
|
import {Header, Text} from '@shipfox/react-ui/typography';
|
|
10
10
|
import {useQueryClient} from '@tanstack/react-query';
|
|
@@ -212,7 +212,7 @@ export function SentryCallbackPage() {
|
|
|
212
212
|
|
|
213
213
|
<section className="flex flex-col gap-inline" aria-label="Choose a workspace">
|
|
214
214
|
{orderedWorkspaces.map((workspace) => (
|
|
215
|
-
<
|
|
215
|
+
<Panel key={workspace.id} className="p-panel-compact">
|
|
216
216
|
<div className="flex items-center justify-between gap-cluster">
|
|
217
217
|
<Text size="md" bold className="truncate">
|
|
218
218
|
{workspace.name}
|
|
@@ -226,7 +226,7 @@ export function SentryCallbackPage() {
|
|
|
226
226
|
Install
|
|
227
227
|
</Button>
|
|
228
228
|
</div>
|
|
229
|
-
</
|
|
229
|
+
</Panel>
|
|
230
230
|
))}
|
|
231
231
|
</section>
|
|
232
232
|
|
|
@@ -246,10 +246,8 @@ export function SentryCallbackPage() {
|
|
|
246
246
|
|
|
247
247
|
function CallbackColumn({children}: {children: React.ReactNode}) {
|
|
248
248
|
return (
|
|
249
|
-
<main className="flex min-h-screen
|
|
250
|
-
<
|
|
251
|
-
{children}
|
|
252
|
-
</div>
|
|
249
|
+
<main className="flex min-h-screen px-frame py-frame">
|
|
250
|
+
<FocusedFrame className="flex flex-col justify-center gap-section">{children}</FocusedFrame>
|
|
253
251
|
</main>
|
|
254
252
|
);
|
|
255
253
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// @vitest-environment jsdom
|
|
2
2
|
import '@testing-library/jest-dom/vitest';
|
|
3
|
+
import {configureApiClient} from '@shipfox/client-api';
|
|
3
4
|
import {screen, waitFor} from '@testing-library/react';
|
|
4
5
|
import {StrictMode} from 'react';
|
|
5
6
|
import {SLACK_INSTALL_WORKSPACE_KEY} from '#slack-callback.js';
|
|
@@ -27,6 +28,12 @@ vi.mock('#hooks/api/integrations.js', async (importOriginal) => {
|
|
|
27
28
|
beforeEach(() => {
|
|
28
29
|
window.sessionStorage.clear();
|
|
29
30
|
completeCallbackMock.mockReset();
|
|
31
|
+
configureApiClient({
|
|
32
|
+
baseUrl: 'https://api.example.test',
|
|
33
|
+
fetchImpl: vi.fn((_input: RequestInfo | URL) =>
|
|
34
|
+
Promise.reject(new Error('Workspace list unavailable')),
|
|
35
|
+
),
|
|
36
|
+
});
|
|
30
37
|
});
|
|
31
38
|
|
|
32
39
|
describe('SlackCallbackPage', () => {
|
|
@@ -8,7 +8,7 @@ export function SourceControlOnboardingPage() {
|
|
|
8
8
|
const providersQuery = useIntegrationProvidersQuery({capability: 'source_control'});
|
|
9
9
|
|
|
10
10
|
return (
|
|
11
|
-
<div className="
|
|
11
|
+
<div className="flex w-full flex-col gap-section">
|
|
12
12
|
<header className="flex flex-col gap-inline">
|
|
13
13
|
<Header variant="h1">Install source control</Header>
|
|
14
14
|
<Text size="md" className="text-foreground-neutral-muted">
|
package/src/routes/gitea.tsx
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import {defineRoute} from '@shipfox/client-shell/runtime';
|
|
2
2
|
import {GiteaInstallPage} from '#pages/gitea-install-page.js';
|
|
3
3
|
|
|
4
|
-
export default defineRoute({
|
|
4
|
+
export default defineRoute({
|
|
5
|
+
staticData: {frame: 'focused'},
|
|
6
|
+
component: GiteaInstallPage,
|
|
7
|
+
});
|
|
@@ -29,6 +29,7 @@ const callbackRequests = createSingleFlight<string, void>({maxTerminalResults: 3
|
|
|
29
29
|
const toastedCallbacks = new Set<string>();
|
|
30
30
|
|
|
31
31
|
export default defineRoute({
|
|
32
|
+
staticData: {frame: 'focused'},
|
|
32
33
|
validateSearch: validateGithubCallbackSearch,
|
|
33
34
|
component: GithubCallbackRoute,
|
|
34
35
|
});
|
package/src/routes/github.tsx
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import {defineRoute} from '@shipfox/client-shell/runtime';
|
|
2
2
|
import {GithubInstallPage} from '#pages/github-install-page.js';
|
|
3
3
|
|
|
4
|
-
export default defineRoute({
|
|
4
|
+
export default defineRoute({
|
|
5
|
+
staticData: {frame: 'focused'},
|
|
6
|
+
component: GithubInstallPage,
|
|
7
|
+
});
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import {defineRoute} from '@shipfox/client-shell/runtime';
|
|
2
2
|
import {IntegrationGallery} from '#index.js';
|
|
3
3
|
|
|
4
|
-
export default defineRoute({
|
|
4
|
+
export default defineRoute({
|
|
5
|
+
staticData: {frame: 'content'},
|
|
6
|
+
component: IntegrationGallery,
|
|
7
|
+
});
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import {defineRoute} from '@shipfox/client-shell/runtime';
|
|
2
2
|
import {SourceControlOnboardingPage} from '#pages/source-control-onboarding-page.js';
|
|
3
3
|
|
|
4
|
-
export default defineRoute({
|
|
4
|
+
export default defineRoute({
|
|
5
|
+
staticData: {frame: 'focused'},
|
|
6
|
+
component: SourceControlOnboardingPage,
|
|
7
|
+
});
|
|
@@ -3,6 +3,7 @@ import {JiraCallbackPage} from '#pages/jira-callback-page.js';
|
|
|
3
3
|
import {parseJiraCallbackQuery} from '../jira-callback.js';
|
|
4
4
|
|
|
5
5
|
export default defineRoute({
|
|
6
|
+
staticData: {frame: 'focused'},
|
|
6
7
|
validateSearch: parseJiraCallbackQuery,
|
|
7
8
|
component: JiraCallbackPage,
|
|
8
9
|
});
|
package/src/routes/jira.tsx
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import {defineRoute} from '@shipfox/client-shell/runtime';
|
|
2
2
|
import {JiraInstallPage} from '#pages/jira-install-page.js';
|
|
3
3
|
|
|
4
|
-
export default defineRoute({
|
|
4
|
+
export default defineRoute({
|
|
5
|
+
staticData: {frame: 'focused'},
|
|
6
|
+
component: JiraInstallPage,
|
|
7
|
+
});
|
|
@@ -3,6 +3,7 @@ import {LinearCallbackPage} from '#pages/linear-callback-page.js';
|
|
|
3
3
|
import {parseLinearCallbackQuery} from '../linear-callback.js';
|
|
4
4
|
|
|
5
5
|
export default defineRoute({
|
|
6
|
+
staticData: {frame: 'focused'},
|
|
6
7
|
validateSearch: parseLinearCallbackQuery,
|
|
7
8
|
component: LinearCallbackPage,
|
|
8
9
|
});
|
package/src/routes/linear.tsx
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import {defineRoute} from '@shipfox/client-shell/runtime';
|
|
2
2
|
import {LinearInstallPage} from '#pages/linear-install-page.js';
|
|
3
3
|
|
|
4
|
-
export default defineRoute({
|
|
4
|
+
export default defineRoute({
|
|
5
|
+
staticData: {frame: 'focused'},
|
|
6
|
+
component: LinearInstallPage,
|
|
7
|
+
});
|
|
@@ -3,6 +3,7 @@ import {SentryCallbackPage} from '#pages/sentry-callback-page.js';
|
|
|
3
3
|
import {parseSentryCallbackParams} from '../sentry-callback.js';
|
|
4
4
|
|
|
5
5
|
export default defineRoute({
|
|
6
|
+
staticData: {frame: 'focused'},
|
|
6
7
|
validateSearch: parseSentryCallbackParams,
|
|
7
8
|
component: SentryCallbackPage,
|
|
8
9
|
});
|
package/src/routes/sentry.tsx
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import {defineRoute} from '@shipfox/client-shell/runtime';
|
|
2
2
|
import {SentryInstallPage} from '#pages/sentry-install-page.js';
|
|
3
3
|
|
|
4
|
-
export default defineRoute({
|
|
4
|
+
export default defineRoute({
|
|
5
|
+
staticData: {frame: 'focused'},
|
|
6
|
+
component: SentryInstallPage,
|
|
7
|
+
});
|
|
@@ -3,6 +3,7 @@ import {SlackCallbackPage} from '#pages/slack-callback-page.js';
|
|
|
3
3
|
import {parseSlackCallbackQuery} from '../slack-callback.js';
|
|
4
4
|
|
|
5
5
|
export default defineRoute({
|
|
6
|
+
staticData: {frame: 'focused'},
|
|
6
7
|
validateSearch: parseSlackCallbackQuery,
|
|
7
8
|
component: SlackCallbackPage,
|
|
8
9
|
});
|
package/src/routes/slack.tsx
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import {defineRoute} from '@shipfox/client-shell/runtime';
|
|
2
2
|
import {SlackInstallPage} from '#pages/slack-install-page.js';
|
|
3
|
-
export default defineRoute({
|
|
3
|
+
export default defineRoute({
|
|
4
|
+
staticData: {frame: 'focused'},
|
|
5
|
+
component: SlackInstallPage,
|
|
6
|
+
});
|