diff --git a/web/src/app/home/components/home-sidebar/HomeSidebar.tsx b/web/src/app/home/components/home-sidebar/HomeSidebar.tsx
index 2ecfd11ce..134a7deb9 100644
--- a/web/src/app/home/components/home-sidebar/HomeSidebar.tsx
+++ b/web/src/app/home/components/home-sidebar/HomeSidebar.tsx
@@ -70,7 +70,9 @@ import { Button } from '@/components/ui/button';
import WorkspaceSwitcher, {
OPEN_WORKSPACE_SETTINGS_EVENT,
} from '@/app/home/components/workspace-settings/WorkspaceSwitcher';
-const CloudPlansDialog = lazy(() => import('@/app/home/components/workspace-settings/CloudPlansDialog'));
+const CloudPlansDialog = lazy(
+ () => import('@/app/home/components/workspace-settings/CloudPlansDialog'),
+);
import NewVersionDialog from '@/app/home/components/new-version-dialog/NewVersionDialog';
import SettingsDialog, {
SettingsSection,
diff --git a/web/src/app/home/components/workspace-settings/WorkspaceSwitcher.tsx b/web/src/app/home/components/workspace-settings/WorkspaceSwitcher.tsx
index 6281d25e6..7660f8a35 100644
--- a/web/src/app/home/components/workspace-settings/WorkspaceSwitcher.tsx
+++ b/web/src/app/home/components/workspace-settings/WorkspaceSwitcher.tsx
@@ -44,7 +44,9 @@ export default function WorkspaceSwitcher({
aria-label={t('workspace.switchWorkspace')}
>
- {currentWorkspace.workspace.name}
+
+ {currentWorkspace.workspace.name}
+
diff --git a/web/src/i18n/locales/ja-JP.ts b/web/src/i18n/locales/ja-JP.ts
index 5b5fb193b..5a7342e8a 100644
--- a/web/src/i18n/locales/ja-JP.ts
+++ b/web/src/i18n/locales/ja-JP.ts
@@ -103,7 +103,8 @@ const jaJP = {
retentionHelp: '保存期間を過ぎた履歴は自動的に削除されます。',
credits: '毎月 {{count}} クレジット',
creditsLabel: 'モデルクレジット',
- creditsHelp: '年払いでも、契約の各月にクレジットが付与されます。クレジットが不足しても、独自に設定したモデルプロバイダーを引き続き利用できます。',
+ creditsHelp:
+ '年払いでも、契約の各月にクレジットが付与されます。クレジットが不足しても、独自に設定したモデルプロバイダーを引き続き利用できます。',
platforms: '主要プラットフォームに対応',
excludedPlatforms: '対象外:{{platforms}}',
allPlatforms: '現在利用可能なすべてのプラットフォーム',
diff --git a/web/src/i18n/locales/zh-Hans.ts b/web/src/i18n/locales/zh-Hans.ts
index 9e79a514c..146a27439 100644
--- a/web/src/i18n/locales/zh-Hans.ts
+++ b/web/src/i18n/locales/zh-Hans.ts
@@ -99,7 +99,8 @@ const zhHans = {
retentionHelp: '超过保留时长的消息记录会自动清理。',
credits: '每月赠送 {{count}} 积分',
creditsLabel: '模型积分',
- creditsHelp: '每个订阅月自动发放,年付计划同样按月发放。积分用尽后,仍可接入自行配置的模型供应商继续使用。',
+ creditsHelp:
+ '每个订阅月自动发放,年付计划同样按月发放。积分用尽后,仍可接入自行配置的模型供应商继续使用。',
platforms: '支持主流平台',
excludedPlatforms: '不支持:{{platforms}}',
allPlatforms: '支持当前所有可用平台',
diff --git a/web/tests/e2e/workspace-layout.spec.ts b/web/tests/e2e/workspace-layout.spec.ts
index dae717afd..e22f01700 100644
--- a/web/tests/e2e/workspace-layout.spec.ts
+++ b/web/tests/e2e/workspace-layout.spec.ts
@@ -55,6 +55,11 @@ for (const scenario of [
});
await expect(trigger).toHaveCount(scenario === 'singleton-local' ? 0 : 1);
if (scenario === 'singleton-local') return;
+ const upgrade = page.getByRole('button', {
+ name: 'Change or upgrade plan',
+ exact: true,
+ });
+ await expect(upgrade).toHaveCount(1);
const sidebar = page.locator('[data-slot="sidebar-inner"]');
const header = sidebar.locator('[data-slot="sidebar-header"]');
const home = sidebar.getByText('Home', { exact: true });
@@ -62,20 +67,30 @@ for (const scenario of [
name: 'Models',
exact: true,
});
- const [headerBox, triggerBox, homeBox, navBox] = await Promise.all([
- header.boundingBox(),
- trigger.boundingBox(),
- home.boundingBox(),
- navigation.boundingBox(),
- ]);
+ const [headerBox, triggerBox, homeBox, navBox, upgradeBox] =
+ await Promise.all([
+ header.boundingBox(),
+ trigger.boundingBox(),
+ home.boundingBox(),
+ navigation.boundingBox(),
+ upgrade.boundingBox(),
+ ]);
expect(triggerBox!.y).toBeGreaterThanOrEqual(
headerBox!.y + headerBox!.height,
);
expect(triggerBox!.y + triggerBox!.height).toBeLessThanOrEqual(homeBox!.y);
expect(Math.abs(triggerBox!.x - navBox!.x)).toBeLessThanOrEqual(1);
+ // The upgrade control shares the switcher row and owns its trailing edge,
+ // so the row stays flush with the navigation column while the switcher
+ // itself ends before the control.
+ expect(Math.abs(triggerBox!.y - upgradeBox!.y)).toBeLessThanOrEqual(1);
+ expect(upgradeBox!.x).toBeGreaterThanOrEqual(
+ triggerBox!.x + triggerBox!.width,
+ );
expect(
- Math.abs(triggerBox!.x + triggerBox!.width - navBox!.x - navBox!.width),
+ Math.abs(upgradeBox!.x + upgradeBox!.width - navBox!.x - navBox!.width),
).toBeLessThanOrEqual(1);
+ await expect(upgrade).toBeVisible();
await trigger.click();
const row = page
.getByRole('menuitem')