fix(extensions): keep extensions entry points available before auth
This commit is contained in:
parent
7b16cfe73b
commit
1ee139b66a
3 changed files with 50 additions and 5 deletions
|
|
@ -387,6 +387,7 @@ const InstalledBanner = ({
|
|||
() => filterMainScreenCliProviders(cliStatus.providers),
|
||||
[cliStatus.providers]
|
||||
);
|
||||
const canOpenExtensions = cliStatus.installed;
|
||||
const runtimeLabel = formatRuntimeLabel(cliStatus);
|
||||
const runtimeAuthSummary = formatRuntimeAuthSummary(cliStatus, visibleProviders);
|
||||
|
||||
|
|
@ -471,8 +472,8 @@ const InstalledBanner = ({
|
|||
disabled={isBusy || cliStatusLoading || multimodelBusy}
|
||||
/>
|
||||
</div>
|
||||
{/* Extensions button — only when installed + authenticated */}
|
||||
{cliStatus.authLoggedIn && (
|
||||
{/* Extensions button — available whenever the runtime is installed */}
|
||||
{canOpenExtensions && (
|
||||
<button
|
||||
onClick={openExtensionsTab}
|
||||
className="flex shrink-0 items-center gap-1.5 rounded-md border px-3 py-1.5 text-xs font-medium transition-colors hover:bg-white/5"
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ export const CliStatusSection = (): React.JSX.Element | null => {
|
|||
!cliStatus && cliStatusLoading && multimodelEnabled
|
||||
? createLoadingMultimodelCliStatus()
|
||||
: cliStatus;
|
||||
const canOpenExtensions = effectiveCliStatus?.installed === true;
|
||||
const showInstalledControls =
|
||||
effectiveCliStatus !== null && (installerState === 'idle' || installerState === 'completed');
|
||||
|
||||
|
|
@ -396,7 +397,7 @@ export const CliStatusSection = (): React.JSX.Element | null => {
|
|||
</button>
|
||||
) : null}
|
||||
{/* Extensions button — right-aligned */}
|
||||
{effectiveCliStatus.authLoggedIn && (
|
||||
{canOpenExtensions && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={openExtensionsTab}
|
||||
|
|
|
|||
|
|
@ -283,6 +283,39 @@ describe('CLI status visibility during completed install state', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('keeps the dashboard Extensions button visible before authentication completes', async () => {
|
||||
vi.stubGlobal('IS_REACT_ACT_ENVIRONMENT', true);
|
||||
storeState.cliStatus = createInstalledCliStatus({
|
||||
authLoggedIn: false,
|
||||
});
|
||||
|
||||
const host = document.createElement('div');
|
||||
document.body.appendChild(host);
|
||||
const root = createRoot(host);
|
||||
|
||||
await act(async () => {
|
||||
root.render(React.createElement(CliStatusBanner));
|
||||
await Promise.resolve();
|
||||
});
|
||||
|
||||
const extensionsButton = Array.from(host.querySelectorAll('button')).find((button) =>
|
||||
button.textContent?.includes('Extensions')
|
||||
);
|
||||
expect(extensionsButton).not.toBeNull();
|
||||
|
||||
await act(async () => {
|
||||
extensionsButton?.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
||||
await Promise.resolve();
|
||||
});
|
||||
|
||||
expect(storeState.openExtensionsTab).toHaveBeenCalledTimes(1);
|
||||
|
||||
await act(async () => {
|
||||
root.unmount();
|
||||
await Promise.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
it('preserves dashboard runtime backend refresh errors for the manage dialog', async () => {
|
||||
vi.stubGlobal('IS_REACT_ACT_ENVIRONMENT', true);
|
||||
storeState.cliInstallerState = 'idle';
|
||||
|
|
@ -483,7 +516,7 @@ describe('CLI status visibility during completed install state', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('hides the settings Extensions button when the runtime is not authenticated yet', async () => {
|
||||
it('keeps the settings Extensions button visible when the runtime is installed but not authenticated yet', async () => {
|
||||
vi.stubGlobal('IS_REACT_ACT_ENVIRONMENT', true);
|
||||
storeState.cliStatus = createInstalledCliStatus({
|
||||
authLoggedIn: false,
|
||||
|
|
@ -498,7 +531,17 @@ describe('CLI status visibility during completed install state', () => {
|
|||
await Promise.resolve();
|
||||
});
|
||||
|
||||
expect(host.textContent).not.toContain('Extensions');
|
||||
const extensionsButton = Array.from(host.querySelectorAll('button')).find((button) =>
|
||||
button.textContent?.includes('Extensions')
|
||||
);
|
||||
expect(extensionsButton).not.toBeNull();
|
||||
|
||||
await act(async () => {
|
||||
extensionsButton?.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
||||
await Promise.resolve();
|
||||
});
|
||||
|
||||
expect(storeState.openExtensionsTab).toHaveBeenCalledTimes(1);
|
||||
|
||||
await act(async () => {
|
||||
root.unmount();
|
||||
|
|
|
|||
Loading…
Reference in a new issue