feat(web): rename credits label to model credits, shorten workspace switcher, add upgrade button

- creditsLabel: 每月赠送积分 → 模型积分 (zh), Monthly credits → Model credits (en), 毎月のクレジット → モデルクレジット (ja)
- creditsHelp: append note that own model providers remain usable after credits run out, all locales
- WorkspaceSwitcher trigger: cap workspace name to 6rem, remove justify-start
- HomeSidebar: add ArrowUp upgrade icon button next to workspace switcher (cloud_projection only), opens CloudPlansDialog lazy-loaded

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
This commit is contained in:
Chin Rock
2026-10-21 07:45:56 +00:00
co-authored by Claude Opus 5.5 multica-agent
parent 09b373c333
commit fa2913a986
5 changed files with 41 additions and 11 deletions
@@ -1,4 +1,4 @@
import { useEffect, useRef, useState } from 'react';
import { useEffect, useRef, useState, lazy, Suspense } from 'react';
import { SidebarChildVO } from '@/app/home/components/home-sidebar/HomeSidebarChild';
import { useNavigate, useLocation, useSearchParams } from 'react-router-dom';
import { sidebarConfigList } from '@/app/home/components/home-sidebar/sidbarConfigList';
@@ -70,6 +70,7 @@ 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'));
import NewVersionDialog from '@/app/home/components/new-version-dialog/NewVersionDialog';
import SettingsDialog, {
SettingsSection,
@@ -1893,6 +1894,7 @@ export default function HomeSidebar({
const [hasNewVersion, setHasNewVersion] = useState(false);
const [versionDialogOpen, setVersionDialogOpen] = useState(false);
const [feedbackOpen, setFeedbackOpen] = useState(false);
const [cloudPlansOpen, setCloudPlansOpen] = useState(false);
const [userEmail, setUserEmail] = useState<string>('');
const [starCount, setStarCount] = useState<number | null>(null);
const [userMenuOpen, setUserMenuOpen] = useState(false);
@@ -2163,8 +2165,26 @@ export default function HomeSidebar({
</SidebarHeader>
{showWorkspaceSwitcher && (
<div className="px-2 group-data-[collapsible=icon]:px-0">
<WorkspaceSwitcher className="w-full group-data-[collapsible=icon]:min-w-0 group-data-[collapsible=icon]:px-2" />
<div className="flex items-center gap-1 px-2 group-data-[collapsible=icon]:px-0">
<WorkspaceSwitcher className="min-w-0 flex-1 group-data-[collapsible=icon]:min-w-0 group-data-[collapsible=icon]:px-2" />
{currentWorkspace?.workspace.source === 'cloud_projection' && (
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className="size-9 shrink-0 text-muted-foreground hover:text-foreground group-data-[collapsible=icon]:hidden"
aria-label={t('workspace.upgradePlan')}
onClick={() => setCloudPlansOpen(true)}
>
<ArrowUp className="size-4" />
</Button>
</TooltipTrigger>
<TooltipContent side="right">
{t('workspace.upgradePlan')}
</TooltipContent>
</Tooltip>
)}
</div>
)}
@@ -2473,6 +2493,16 @@ export default function HomeSidebar({
</DialogContent>
</Dialog>
{currentWorkspace && (
<Suspense fallback={null}>
<CloudPlansDialog
open={cloudPlansOpen}
onOpenChange={setCloudPlansOpen}
workspace={currentWorkspace}
spaceURL={systemInfo.cloud_service_url}
/>
</Suspense>
)}
<SettingsDialog
open={settingsOpen}
onOpenChange={handleSettingsOpenChange}
@@ -40,11 +40,11 @@ export default function WorkspaceSwitcher({
<Button
variant="outline"
size="sm"
className={cn('h-9 min-w-0 justify-start px-2.5 text-sm', className)}
className={cn('h-9 min-w-0 gap-1.5 px-2.5 text-sm', className)}
aria-label={t('workspace.switchWorkspace')}
>
<Building2 className="size-4 shrink-0" />
<span className="truncate">{currentWorkspace.workspace.name}</span>
<span className="max-w-[6rem] truncate">{currentWorkspace.workspace.name}</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start" className="w-64 p-1.5">
+2 -2
View File
@@ -103,9 +103,9 @@ const enUS = {
retentionHelp:
'Message history is automatically removed after this period.',
credits: '{{count}} credits every month',
creditsLabel: 'Monthly credits',
creditsLabel: 'Model credits',
creditsHelp:
'Credits are granted each subscription month, including on yearly plans.',
'Credits are granted each subscription month, including on yearly plans. When credits run out, you can still use your own configured model providers.',
platforms: 'Mainstream platforms supported',
excludedPlatforms: 'Excluded: {{platforms}}',
allPlatforms: 'All currently available platforms',
+2 -2
View File
@@ -102,8 +102,8 @@ const jaJP = {
retentionLabel: 'メッセージ履歴の保存期間',
retentionHelp: '保存期間を過ぎた履歴は自動的に削除されます。',
credits: '毎月 {{count}} クレジット',
creditsLabel: '毎月のクレジット',
creditsHelp: '年払いでも、契約の各月にクレジットが付与されます。',
creditsLabel: 'モデルクレジット',
creditsHelp: '年払いでも、契約の各月にクレジットが付与されます。クレジットが不足しても、独自に設定したモデルプロバイダーを引き続き利用できます。',
platforms: '主要プラットフォームに対応',
excludedPlatforms: '対象外:{{platforms}}',
allPlatforms: '現在利用可能なすべてのプラットフォーム',
+2 -2
View File
@@ -98,8 +98,8 @@ const zhHans = {
retentionLabel: '消息记录保留时长',
retentionHelp: '超过保留时长的消息记录会自动清理。',
credits: '每月赠送 {{count}} 积分',
creditsLabel: '每月赠送积分',
creditsHelp: '每个订阅月自动发放,年付计划同样按月发放。',
creditsLabel: '模型积分',
creditsHelp: '每个订阅月自动发放,年付计划同样按月发放。积分用尽后,仍可接入自行配置的模型供应商继续使用。',
platforms: '支持主流平台',
excludedPlatforms: '不支持:{{platforms}}',
allPlatforms: '支持当前所有可用平台',