fix(extensions): keep provider placeholders during bootstrap
This commit is contained in:
parent
6f4fd254cf
commit
0648509a82
2 changed files with 48 additions and 2 deletions
|
|
@ -48,6 +48,8 @@ import { PluginsPanel } from './plugins/PluginsPanel';
|
||||||
import { SkillsPanel } from './skills/SkillsPanel';
|
import { SkillsPanel } from './skills/SkillsPanel';
|
||||||
import { ExtensionsSubTabTrigger } from './ExtensionsSubTabTrigger';
|
import { ExtensionsSubTabTrigger } from './ExtensionsSubTabTrigger';
|
||||||
|
|
||||||
|
import type { CliProviderStatus } from '@shared/types';
|
||||||
|
|
||||||
const ProviderCapabilityCardSkeleton = ({
|
const ProviderCapabilityCardSkeleton = ({
|
||||||
providerId,
|
providerId,
|
||||||
displayName,
|
displayName,
|
||||||
|
|
@ -82,6 +84,19 @@ const ProviderCapabilityCardSkeleton = ({
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function isProviderCapabilityCardLoading(
|
||||||
|
provider: CliProviderStatus,
|
||||||
|
providerLoading: boolean
|
||||||
|
): boolean {
|
||||||
|
return (
|
||||||
|
providerLoading ||
|
||||||
|
(!provider.authenticated &&
|
||||||
|
provider.statusMessage === 'Checking...' &&
|
||||||
|
provider.models.length === 0 &&
|
||||||
|
provider.backend == null)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export const ExtensionStoreView = (): React.JSX.Element => {
|
export const ExtensionStoreView = (): React.JSX.Element => {
|
||||||
const tabId = useTabIdOptional();
|
const tabId = useTabIdOptional();
|
||||||
const {
|
const {
|
||||||
|
|
@ -317,7 +332,7 @@ export const ExtensionStoreView = (): React.JSX.Element => {
|
||||||
<div className="mt-3 grid gap-2 md:grid-cols-2">
|
<div className="mt-3 grid gap-2 md:grid-cols-2">
|
||||||
{visibleProviders.map((provider) => {
|
{visibleProviders.map((provider) => {
|
||||||
const providerLoading = cliProviderStatusLoading[provider.providerId] === true;
|
const providerLoading = cliProviderStatusLoading[provider.providerId] === true;
|
||||||
if (providerLoading) {
|
if (isProviderCapabilityCardLoading(provider, providerLoading)) {
|
||||||
return (
|
return (
|
||||||
<ProviderCapabilityCardSkeleton
|
<ProviderCapabilityCardSkeleton
|
||||||
key={provider.providerId}
|
key={provider.providerId}
|
||||||
|
|
@ -365,7 +380,14 @@ export const ExtensionStoreView = (): React.JSX.Element => {
|
||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2 flex flex-wrap gap-1.5 text-[11px]">
|
<div className="mt-2 flex flex-wrap gap-1.5 text-[11px]">
|
||||||
<Badge variant="secondary">
|
<Badge
|
||||||
|
variant={pluginStatus === 'unsupported' ? 'outline' : 'secondary'}
|
||||||
|
className={
|
||||||
|
pluginStatus === 'unsupported'
|
||||||
|
? 'border-amber-500/30 bg-amber-500/10 text-amber-300'
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
>
|
||||||
Plugins: {formatCliExtensionCapabilityStatus(pluginStatus)}
|
Plugins: {formatCliExtensionCapabilityStatus(pluginStatus)}
|
||||||
</Badge>
|
</Badge>
|
||||||
<Badge variant="secondary">
|
<Badge variant="secondary">
|
||||||
|
|
|
||||||
|
|
@ -302,4 +302,28 @@ describe('ExtensionStoreView provider loading placeholders', () => {
|
||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('keeps provider placeholders visible when bootstrap data still says Checking...', async () => {
|
||||||
|
storeState.cliStatusLoading = false;
|
||||||
|
storeState.cliProviderStatusLoading = {};
|
||||||
|
|
||||||
|
const host = document.createElement('div');
|
||||||
|
document.body.appendChild(host);
|
||||||
|
const root = createRoot(host);
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
root.render(React.createElement(ExtensionStoreView));
|
||||||
|
await Promise.resolve();
|
||||||
|
await Promise.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(host.textContent).toContain('Checking provider status...');
|
||||||
|
expect(host.textContent).toContain('Loading...');
|
||||||
|
expect(host.textContent).not.toContain('Plugins: unsupported');
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
root.unmount();
|
||||||
|
await Promise.resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue