@shipfox/client-agent 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 +34 -0
- package/dist/components/add-custom-provider-card.d.ts.map +1 -1
- package/dist/components/add-custom-provider-card.js +11 -31
- package/dist/components/add-custom-provider-card.js.map +1 -1
- package/dist/components/available-provider-card.d.ts.map +1 -1
- package/dist/components/available-provider-card.js +11 -31
- package/dist/components/available-provider-card.js.map +1 -1
- package/dist/components/available-providers-grid.d.ts +0 -1
- package/dist/components/available-providers-grid.d.ts.map +1 -1
- package/dist/components/available-providers-grid.js +33 -27
- package/dist/components/available-providers-grid.js.map +1 -1
- package/dist/components/custom-model-provider-form.stories.js +1 -1
- package/dist/components/custom-model-provider-form.stories.js.map +1 -1
- package/dist/components/harnesses-section.d.ts.map +1 -1
- package/dist/components/harnesses-section.js +147 -134
- package/dist/components/harnesses-section.js.map +1 -1
- package/dist/components/harnesses-section.stories.js +1 -1
- package/dist/components/harnesses-section.stories.js.map +1 -1
- package/dist/components/model-provider-grid-skeleton.d.ts +4 -0
- package/dist/components/model-provider-grid-skeleton.d.ts.map +1 -0
- package/dist/components/model-provider-grid-skeleton.js +34 -0
- package/dist/components/model-provider-grid-skeleton.js.map +1 -0
- package/dist/components/model-provider-usage-modal.stories.js +1 -1
- package/dist/components/model-provider-usage-modal.stories.js.map +1 -1
- package/dist/components/model-providers-section.d.ts.map +1 -1
- package/dist/components/model-providers-section.js +253 -245
- package/dist/components/model-providers-section.js.map +1 -1
- package/dist/components/model-providers-section.stories.js +1 -1
- package/dist/components/model-providers-section.stories.js.map +1 -1
- package/dist/pages/model-provider-onboarding-page.d.ts.map +1 -1
- package/dist/pages/model-provider-onboarding-page.js +32 -64
- package/dist/pages/model-provider-onboarding-page.js.map +1 -1
- package/dist/pages/model-provider-onboarding-page.stories.js +1 -1
- package/dist/pages/model-provider-onboarding-page.stories.js.map +1 -1
- package/dist/routes/agents-settings.d.ts +3 -0
- package/dist/routes/agents-settings.js +3 -0
- package/dist/routes/agents-settings.js.map +1 -1
- package/dist/routes/model-provider.d.ts +3 -0
- package/dist/routes/model-provider.js +3 -0
- package/dist/routes/model-provider.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/components/add-custom-provider-card.tsx +9 -23
- package/src/components/available-provider-card.tsx +9 -23
- package/src/components/available-providers-grid.tsx +36 -29
- package/src/components/custom-model-provider-form.stories.tsx +1 -1
- package/src/components/harnesses-section.stories.tsx +1 -1
- package/src/components/harnesses-section.tsx +116 -106
- package/src/components/model-provider-grid-skeleton.tsx +21 -0
- package/src/components/model-provider-usage-modal.stories.tsx +1 -1
- package/src/components/model-providers-section.stories.tsx +1 -1
- package/src/components/model-providers-section.tsx +208 -191
- package/src/pages/model-provider-onboarding-page.stories.tsx +1 -1
- package/src/pages/model-provider-onboarding-page.tsx +26 -54
- package/src/routes/agents-settings.tsx +1 -0
- package/src/routes/model-provider.tsx +1 -0
- package/tsconfig.build.tsbuildinfo +1 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shipfox/client-agent",
|
|
3
3
|
"license": "MIT",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "22.0.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/ShipfoxHQ/shipfox.git",
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
"@tanstack/react-query": "^5.101.0",
|
|
31
31
|
"@shipfox/api-agent-dto": "12.2.0",
|
|
32
32
|
"@shipfox/client-api": "6.0.1",
|
|
33
|
-
"@shipfox/client-shell": "
|
|
34
|
-
"@shipfox/client-ui": "
|
|
35
|
-
"@shipfox/react-ui": "1.
|
|
33
|
+
"@shipfox/client-shell": "22.0.0",
|
|
34
|
+
"@shipfox/client-ui": "22.0.0",
|
|
35
|
+
"@shipfox/react-ui": "2.1.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@tanstack/react-query": "^5.101.0",
|
|
@@ -1,32 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {PanelCell, PanelCellAction} from '@shipfox/react-ui/panel';
|
|
2
2
|
import {Text} from '@shipfox/react-ui/typography';
|
|
3
|
-
import {cn} from '@shipfox/react-ui/utils';
|
|
4
|
-
|
|
5
|
-
const SURFACE_CLASS =
|
|
6
|
-
'overflow-hidden rounded-8 border border-border-neutral-base bg-background-neutral-base';
|
|
7
3
|
|
|
8
4
|
export function AddCustomProviderCard({onConfigure}: {onConfigure: () => void}) {
|
|
9
5
|
return (
|
|
10
|
-
<
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
className={cn(
|
|
14
|
-
'group block h-full w-full cursor-pointer p-panel-compact text-left outline-none transition-colors hover:bg-background-components-hover focus-visible:shadow-button-neutral-focus',
|
|
15
|
-
SURFACE_CLASS,
|
|
16
|
-
)}
|
|
6
|
+
<PanelCell>
|
|
7
|
+
<PanelCellAction
|
|
8
|
+
action="Configure"
|
|
17
9
|
aria-label="Configure custom provider"
|
|
18
10
|
onClick={onConfigure}
|
|
19
11
|
>
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
<Text size="sm">Configure</Text>
|
|
26
|
-
<Icon name="chevronRight" className="size-16" />
|
|
27
|
-
</div>
|
|
28
|
-
</div>
|
|
29
|
-
</button>
|
|
30
|
-
</li>
|
|
12
|
+
<Text as="span" size="md" bold className="min-w-0 truncate">
|
|
13
|
+
Custom
|
|
14
|
+
</Text>
|
|
15
|
+
</PanelCellAction>
|
|
16
|
+
</PanelCell>
|
|
31
17
|
);
|
|
32
18
|
}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {PanelCell, PanelCellAction} from '@shipfox/react-ui/panel';
|
|
2
2
|
import {Text} from '@shipfox/react-ui/typography';
|
|
3
|
-
import {cn} from '@shipfox/react-ui/utils';
|
|
4
3
|
import type {SupportedProvider} from '#core/models.js';
|
|
5
4
|
|
|
6
|
-
const SURFACE_CLASS =
|
|
7
|
-
'overflow-hidden rounded-8 border border-border-neutral-base bg-background-neutral-base';
|
|
8
|
-
|
|
9
5
|
export function AvailableProviderCard({
|
|
10
6
|
entry,
|
|
11
7
|
onConfigure,
|
|
@@ -14,26 +10,16 @@ export function AvailableProviderCard({
|
|
|
14
10
|
onConfigure: () => void;
|
|
15
11
|
}) {
|
|
16
12
|
return (
|
|
17
|
-
<
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
className={cn(
|
|
21
|
-
'group block w-full cursor-pointer p-panel-compact text-left outline-none transition-colors hover:bg-background-components-hover focus-visible:shadow-button-neutral-focus',
|
|
22
|
-
SURFACE_CLASS,
|
|
23
|
-
)}
|
|
13
|
+
<PanelCell>
|
|
14
|
+
<PanelCellAction
|
|
15
|
+
action="Configure"
|
|
24
16
|
aria-label={`Configure ${entry.label}`}
|
|
25
17
|
onClick={onConfigure}
|
|
26
18
|
>
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
<Text size="sm">Configure</Text>
|
|
33
|
-
<Icon name="chevronRight" className="size-16" />
|
|
34
|
-
</div>
|
|
35
|
-
</div>
|
|
36
|
-
</button>
|
|
37
|
-
</li>
|
|
19
|
+
<Text as="span" size="md" bold className="min-w-0 truncate">
|
|
20
|
+
{entry.label}
|
|
21
|
+
</Text>
|
|
22
|
+
</PanelCellAction>
|
|
23
|
+
</PanelCell>
|
|
38
24
|
);
|
|
39
25
|
}
|
|
@@ -2,14 +2,13 @@ import {Button} from '@shipfox/react-ui/button';
|
|
|
2
2
|
import {EmptyState} from '@shipfox/react-ui/empty-state';
|
|
3
3
|
import {Icon} from '@shipfox/react-ui/icon';
|
|
4
4
|
import {Input} from '@shipfox/react-ui/input';
|
|
5
|
+
import {Panel, PanelBody, PanelGrid, PanelHeader} from '@shipfox/react-ui/panel';
|
|
5
6
|
import type {ReactNode} from 'react';
|
|
6
7
|
import {useMemo, useRef, useState} from 'react';
|
|
7
8
|
import type {SupportedProvider} from '#core/models.js';
|
|
8
9
|
import {providerMatchesSearch} from '#core/provider-policy.js';
|
|
9
10
|
import {AvailableProviderCard} from './available-provider-card.js';
|
|
10
11
|
|
|
11
|
-
export const PROVIDER_GRID_CLASS = 'grid grid-cols-2 gap-cluster max-[760px]:grid-cols-1';
|
|
12
|
-
|
|
13
12
|
const SEARCH_VISIBILITY_THRESHOLD = 8;
|
|
14
13
|
const MAX_ECHOED_QUERY_LENGTH = 40;
|
|
15
14
|
|
|
@@ -45,38 +44,46 @@ export function AvailableProvidersGrid<TEntry extends SupportedProvider>({
|
|
|
45
44
|
}
|
|
46
45
|
|
|
47
46
|
return (
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
<ul className={PROVIDER_GRID_CLASS} aria-label={providerListLabel}>
|
|
63
|
-
{filteredEntries.map((entry) => (
|
|
64
|
-
<AvailableProviderCard
|
|
65
|
-
key={entry.id}
|
|
66
|
-
entry={entry}
|
|
67
|
-
onConfigure={() => onSelect(entry)}
|
|
47
|
+
<>
|
|
48
|
+
<Panel>
|
|
49
|
+
{showSearch ? (
|
|
50
|
+
<PanelHeader>
|
|
51
|
+
<Input
|
|
52
|
+
ref={inputRef}
|
|
53
|
+
type="search"
|
|
54
|
+
aria-label="Search providers"
|
|
55
|
+
placeholder="Search providers..."
|
|
56
|
+
value={search}
|
|
57
|
+
iconLeft={
|
|
58
|
+
<Icon name="searchLine" className="size-16 text-foreground-neutral-muted" />
|
|
59
|
+
}
|
|
60
|
+
onChange={(event) => setSearch(event.target.value)}
|
|
68
61
|
/>
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
62
|
+
</PanelHeader>
|
|
63
|
+
) : null}
|
|
64
|
+
|
|
65
|
+
<PanelBody>
|
|
66
|
+
{visibleCount > 0 ? (
|
|
67
|
+
<PanelGrid aria-label={providerListLabel}>
|
|
68
|
+
{filteredEntries.map((entry) => (
|
|
69
|
+
<AvailableProviderCard
|
|
70
|
+
key={entry.id}
|
|
71
|
+
entry={entry}
|
|
72
|
+
onConfigure={() => onSelect(entry)}
|
|
73
|
+
/>
|
|
74
|
+
))}
|
|
75
|
+
{trailingCardVisible ? trailingCard : null}
|
|
76
|
+
</PanelGrid>
|
|
77
|
+
) : (
|
|
78
|
+
<NoProviderSearchResults search={trimmedSearch} onClear={clearSearch} />
|
|
79
|
+
)}
|
|
80
|
+
</PanelBody>
|
|
81
|
+
</Panel>
|
|
75
82
|
|
|
76
83
|
<p role="status" aria-live="polite" className="sr-only">
|
|
77
84
|
{resultCountText}
|
|
78
85
|
</p>
|
|
79
|
-
|
|
86
|
+
</>
|
|
80
87
|
);
|
|
81
88
|
}
|
|
82
89
|
|
|
@@ -23,7 +23,7 @@ function CustomModelProviderFormStory({mode}: CustomModelProviderFormStoryProps)
|
|
|
23
23
|
|
|
24
24
|
return (
|
|
25
25
|
<QueryClientProvider client={queryClient}>
|
|
26
|
-
<div className="min-h-screen bg-background-
|
|
26
|
+
<div className="min-h-screen bg-background-subtle-base p-24">
|
|
27
27
|
<Modal open={open} onOpenChange={setOpen}>
|
|
28
28
|
<ModalContent
|
|
29
29
|
className="max-h-[min(760px,calc(100vh-32px))]"
|
|
@@ -33,7 +33,7 @@ function HarnessesStory({scenario}: HarnessesStoryProps) {
|
|
|
33
33
|
|
|
34
34
|
return (
|
|
35
35
|
<QueryClientProvider client={queryClient}>
|
|
36
|
-
<div className="mx-auto w-full max-w-[760px] bg-background-
|
|
36
|
+
<div className="mx-auto w-full max-w-[760px] bg-background-subtle-base p-24">
|
|
37
37
|
<WorkspaceHarnessesSection workspaceId={WORKSPACE_ID} />
|
|
38
38
|
</div>
|
|
39
39
|
<Toaster />
|
|
@@ -8,11 +8,11 @@ import {
|
|
|
8
8
|
DropdownMenuTrigger,
|
|
9
9
|
} from '@shipfox/react-ui/dropdown-menu';
|
|
10
10
|
import {Icon} from '@shipfox/react-ui/icon';
|
|
11
|
+
import {Panel, PanelBody, PanelRow} from '@shipfox/react-ui/panel';
|
|
11
12
|
import {Skeleton} from '@shipfox/react-ui/skeleton';
|
|
12
13
|
import {toast} from '@shipfox/react-ui/toast';
|
|
13
14
|
import {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';
|
|
14
15
|
import {Header, Text} from '@shipfox/react-ui/typography';
|
|
15
|
-
import {cn} from '@shipfox/react-ui/utils';
|
|
16
16
|
import {useRef, useState} from 'react';
|
|
17
17
|
import {DEFAULT_HARNESS, listHarnesses} from '#core/harness-policy.js';
|
|
18
18
|
import type {HarnessDescriptor, HarnessId} from '#core/models.js';
|
|
@@ -23,9 +23,6 @@ import {
|
|
|
23
23
|
import {modelProviderConfigErrorToFormError} from './form-errors.js';
|
|
24
24
|
import {isHarnessAvailable} from './harness-availability.js';
|
|
25
25
|
|
|
26
|
-
const SURFACE_CLASS =
|
|
27
|
-
'overflow-hidden rounded-8 border border-border-neutral-base bg-background-neutral-base';
|
|
28
|
-
|
|
29
26
|
export function WorkspaceHarnessesSection({workspaceId}: {workspaceId: string}) {
|
|
30
27
|
const configsQuery = useModelProviderConfigsQuery(workspaceId);
|
|
31
28
|
const setDefaultHarness = useSetDefaultHarnessMutation();
|
|
@@ -95,29 +92,34 @@ export function WorkspaceHarnessesSection({workspaceId}: {workspaceId: string})
|
|
|
95
92
|
{configsQuery.isPending ? <HarnessRowsSkeleton /> : null}
|
|
96
93
|
|
|
97
94
|
{configsQuery.isError && configsQuery.data === undefined ? (
|
|
98
|
-
<
|
|
99
|
-
<QueryLoadError query={configsQuery} subject="harnesses" />
|
|
100
|
-
</
|
|
95
|
+
<Panel>
|
|
96
|
+
<QueryLoadError query={configsQuery} subject="harnesses" variant="panel" />
|
|
97
|
+
</Panel>
|
|
101
98
|
) : null}
|
|
102
99
|
|
|
103
100
|
{configsQuery.data !== undefined ? (
|
|
104
|
-
<
|
|
105
|
-
|
|
106
|
-
<
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
101
|
+
<Panel>
|
|
102
|
+
<PanelBody asChild>
|
|
103
|
+
<ul>
|
|
104
|
+
{listHarnesses().map((harness) => (
|
|
105
|
+
<HarnessRow
|
|
106
|
+
key={harness.id}
|
|
107
|
+
harness={harness}
|
|
108
|
+
isDefault={harness.id === defaultHarnessId}
|
|
109
|
+
isAvailable={isHarnessAvailable(harness, configs)}
|
|
110
|
+
isSettingDefault={pendingDefaultHarness?.workspaceId === workspaceId}
|
|
111
|
+
defaultError={
|
|
112
|
+
defaultError?.workspaceId === workspaceId &&
|
|
113
|
+
defaultError.harnessId === harness.id
|
|
114
|
+
? defaultError.message
|
|
115
|
+
: undefined
|
|
116
|
+
}
|
|
117
|
+
onSetDefault={handleSetDefault}
|
|
118
|
+
/>
|
|
119
|
+
))}
|
|
120
|
+
</ul>
|
|
121
|
+
</PanelBody>
|
|
122
|
+
</Panel>
|
|
121
123
|
) : null}
|
|
122
124
|
</section>
|
|
123
125
|
);
|
|
@@ -141,78 +143,80 @@ function HarnessRow({
|
|
|
141
143
|
const unavailableCopy = harnessUnavailableCopy(isDefault);
|
|
142
144
|
|
|
143
145
|
return (
|
|
144
|
-
<
|
|
145
|
-
<
|
|
146
|
-
<div className="flex
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
<
|
|
151
|
-
<
|
|
152
|
-
<
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
<
|
|
171
|
-
<
|
|
172
|
-
<
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
146
|
+
<PanelRow asChild className="flex-col items-stretch gap-inline">
|
|
147
|
+
<li>
|
|
148
|
+
<div className="flex items-center justify-between gap-cluster">
|
|
149
|
+
<div className="flex min-w-0 items-center gap-inline">
|
|
150
|
+
{isDefault ? (
|
|
151
|
+
<>
|
|
152
|
+
<Tooltip>
|
|
153
|
+
<TooltipTrigger asChild>
|
|
154
|
+
<span className="inline-flex size-16 shrink-0 items-center justify-center">
|
|
155
|
+
<Icon
|
|
156
|
+
name="starLine"
|
|
157
|
+
className="size-16 text-foreground-neutral-muted"
|
|
158
|
+
aria-hidden
|
|
159
|
+
/>
|
|
160
|
+
</span>
|
|
161
|
+
</TooltipTrigger>
|
|
162
|
+
<TooltipContent>Default harness</TooltipContent>
|
|
163
|
+
</Tooltip>
|
|
164
|
+
<span className="sr-only">Default harness</span>
|
|
165
|
+
</>
|
|
166
|
+
) : null}
|
|
167
|
+
<Text size="md" bold className="truncate">
|
|
168
|
+
{harness.label}
|
|
169
|
+
</Text>
|
|
170
|
+
{!isAvailable ? (
|
|
171
|
+
<>
|
|
172
|
+
<Tooltip>
|
|
173
|
+
<TooltipTrigger asChild>
|
|
174
|
+
<span className="inline-flex size-16 shrink-0 items-center justify-center">
|
|
175
|
+
<Icon
|
|
176
|
+
name="errorWarningLine"
|
|
177
|
+
className="size-16 text-foreground-warning-base"
|
|
178
|
+
aria-hidden
|
|
179
|
+
/>
|
|
180
|
+
</span>
|
|
181
|
+
</TooltipTrigger>
|
|
182
|
+
<TooltipContent>{unavailableCopy}</TooltipContent>
|
|
183
|
+
</Tooltip>
|
|
184
|
+
<span className="sr-only">{unavailableCopy}</span>
|
|
185
|
+
</>
|
|
186
|
+
) : null}
|
|
187
|
+
</div>
|
|
188
|
+
{!isDefault ? (
|
|
189
|
+
<DropdownMenu>
|
|
190
|
+
<DropdownMenuTrigger asChild>
|
|
191
|
+
<IconButton
|
|
192
|
+
size="sm"
|
|
193
|
+
variant="transparent"
|
|
194
|
+
icon="more2Line"
|
|
195
|
+
disabled={isSettingDefault}
|
|
196
|
+
aria-label={`Open ${harness.label} harness actions`}
|
|
197
|
+
/>
|
|
198
|
+
</DropdownMenuTrigger>
|
|
199
|
+
<DropdownMenuContent align="end">
|
|
200
|
+
<DropdownMenuItem
|
|
201
|
+
icon="starLine"
|
|
202
|
+
disabled={isSettingDefault || !isAvailable}
|
|
203
|
+
onSelect={() => {
|
|
204
|
+
onSetDefault(harness);
|
|
205
|
+
}}
|
|
206
|
+
>
|
|
207
|
+
Set as default
|
|
208
|
+
</DropdownMenuItem>
|
|
209
|
+
</DropdownMenuContent>
|
|
210
|
+
</DropdownMenu>
|
|
183
211
|
) : null}
|
|
184
212
|
</div>
|
|
185
|
-
{
|
|
186
|
-
<
|
|
187
|
-
<
|
|
188
|
-
|
|
189
|
-
size="sm"
|
|
190
|
-
variant="transparent"
|
|
191
|
-
icon="more2Line"
|
|
192
|
-
disabled={isSettingDefault}
|
|
193
|
-
aria-label={`Open ${harness.label} harness actions`}
|
|
194
|
-
/>
|
|
195
|
-
</DropdownMenuTrigger>
|
|
196
|
-
<DropdownMenuContent align="end">
|
|
197
|
-
<DropdownMenuItem
|
|
198
|
-
icon="starLine"
|
|
199
|
-
disabled={isSettingDefault || !isAvailable}
|
|
200
|
-
onSelect={() => {
|
|
201
|
-
onSetDefault(harness);
|
|
202
|
-
}}
|
|
203
|
-
>
|
|
204
|
-
Set as default
|
|
205
|
-
</DropdownMenuItem>
|
|
206
|
-
</DropdownMenuContent>
|
|
207
|
-
</DropdownMenu>
|
|
213
|
+
{defaultError ? (
|
|
214
|
+
<Callout role="alert" type="error">
|
|
215
|
+
<Text size="sm">{defaultError}</Text>
|
|
216
|
+
</Callout>
|
|
208
217
|
) : null}
|
|
209
|
-
</
|
|
210
|
-
|
|
211
|
-
<Callout role="alert" type="error">
|
|
212
|
-
<Text size="sm">{defaultError}</Text>
|
|
213
|
-
</Callout>
|
|
214
|
-
) : null}
|
|
215
|
-
</li>
|
|
218
|
+
</li>
|
|
219
|
+
</PanelRow>
|
|
216
220
|
);
|
|
217
221
|
}
|
|
218
222
|
|
|
@@ -224,18 +228,24 @@ function harnessUnavailableCopy(isDefault: boolean): string {
|
|
|
224
228
|
|
|
225
229
|
function HarnessRowsSkeleton() {
|
|
226
230
|
return (
|
|
227
|
-
<
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
231
|
+
<Panel>
|
|
232
|
+
<PanelBody asChild>
|
|
233
|
+
<ul role="status" aria-label="Loading harnesses">
|
|
234
|
+
{[0, 1].map((row) => (
|
|
235
|
+
<PanelRow
|
|
236
|
+
asChild
|
|
237
|
+
className="justify-start gap-cluster hover:bg-background-neutral-base"
|
|
238
|
+
key={row}
|
|
239
|
+
>
|
|
240
|
+
<li>
|
|
241
|
+
<Skeleton className="size-16 shrink-0" />
|
|
242
|
+
<Skeleton className="h-16 w-120" />
|
|
243
|
+
<Skeleton className="ml-auto size-28 shrink-0" />
|
|
244
|
+
</li>
|
|
245
|
+
</PanelRow>
|
|
246
|
+
))}
|
|
247
|
+
</ul>
|
|
248
|
+
</PanelBody>
|
|
249
|
+
</Panel>
|
|
240
250
|
);
|
|
241
251
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {Panel, PanelBody, PanelCell, PanelGrid} from '@shipfox/react-ui/panel';
|
|
2
|
+
import {Skeleton} from '@shipfox/react-ui/skeleton';
|
|
3
|
+
|
|
4
|
+
export function ModelProviderGridSkeleton({label}: {label: string}) {
|
|
5
|
+
return (
|
|
6
|
+
<Panel>
|
|
7
|
+
<PanelBody>
|
|
8
|
+
<PanelGrid role="status" aria-busy="true" aria-label={label}>
|
|
9
|
+
{[0, 1, 2, 3].map((tile) => (
|
|
10
|
+
<PanelCell key={tile}>
|
|
11
|
+
<div className="flex items-center justify-between gap-cluster px-row py-row">
|
|
12
|
+
<Skeleton className="h-16 w-100" />
|
|
13
|
+
<Skeleton className="h-16 w-64 shrink-0" />
|
|
14
|
+
</div>
|
|
15
|
+
</PanelCell>
|
|
16
|
+
))}
|
|
17
|
+
</PanelGrid>
|
|
18
|
+
</PanelBody>
|
|
19
|
+
</Panel>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
@@ -20,7 +20,7 @@ function ModelProviderUsageModalStory({variant}: ModelProviderUsageModalStoryPro
|
|
|
20
20
|
: usageTargetFromCatalogEntry(entry);
|
|
21
21
|
|
|
22
22
|
return (
|
|
23
|
-
<div className="min-h-screen bg-background-
|
|
23
|
+
<div className="min-h-screen bg-background-subtle-base p-24">
|
|
24
24
|
<ModelProviderUsageModal
|
|
25
25
|
target={target}
|
|
26
26
|
initialModel={target.defaultModel}
|
|
@@ -118,7 +118,7 @@ function ModelProvidersStory({scenario}: ModelProvidersStoryProps) {
|
|
|
118
118
|
|
|
119
119
|
return (
|
|
120
120
|
<QueryClientProvider client={queryClient}>
|
|
121
|
-
<div className="mx-auto w-full max-w-[760px] bg-background-
|
|
121
|
+
<div className="mx-auto w-full max-w-[760px] bg-background-subtle-base p-24">
|
|
122
122
|
<WorkspaceModelProvidersSection workspaceId={WORKSPACE_ID} />
|
|
123
123
|
</div>
|
|
124
124
|
<Toaster />
|