diff --git a/sundynix-desktop/frontend/src/shell/TopBar.tsx b/sundynix-desktop/frontend/src/shell/TopBar.tsx
index 486c619..9019443 100644
--- a/sundynix-desktop/frontend/src/shell/TopBar.tsx
+++ b/sundynix-desktop/frontend/src/shell/TopBar.tsx
@@ -1,5 +1,5 @@
import type { CSSProperties } from "react";
-import { User, ChevronDown, Search as SearchIcon, LogOut, Sun, Moon, Coins, Building2, Users as UsersIcon, Plus } from "lucide-react";
+import { User, ChevronDown, Search as SearchIcon, LogOut, Sun, Moon, Coins, Building2, Users as UsersIcon, Plus, Globe } from "lucide-react";
import type { AuthUser, TenantCtx, MyTenant, SpaceCtx, MySpace } from "../lib/api";
import { useHealth } from "../lib/health";
import { isMacDesktop } from "../lib/desktop";
@@ -67,9 +67,11 @@ function TenantSwitcher({ tenants, activeId, onSwitch }: { tenants: MyTenant[];
// 工作区切换器:切换活跃 Space(共享工作区 — 个人/项目/全员)。含"新建项目空间"。
// 个人空间恒有,故 ≥1 即显示(让用户随时能建/进项目协作空间)。
-function SpaceSwitcher({ spaces, activeId, onSwitch, onCreate }: { spaces: MySpace[]; activeId?: string; onSwitch?: (id: string) => void; onCreate?: (name: string) => void }) {
+function SpaceSwitcher({ spaces, activeId, onSwitch, onCreate, onEnableTenantSpace, tenantRole }: { spaces: MySpace[]; activeId?: string; onSwitch?: (id: string) => void; onCreate?: (name: string) => void; onEnableTenantSpace?: () => void; tenantRole?: string }) {
if (spaces.length === 0) return null;
const label = (s: MySpace) => (s.kind === "personal" ? "个人空间" : s.name) + (s.kind !== "personal" ? ` · ${s.members}人` : "");
+ const canManage = tenantRole === "owner" || tenantRole === "admin";
+ const hasTenantSpace = spaces.some((s) => s.kind === "tenant");
return (
@@ -98,12 +100,23 @@ function SpaceSwitcher({ spaces, activeId, onSwitch, onCreate }: { spaces: MySpa
>
+ {canManage && !hasTenantSpace && (
+
+ )}
);
}
// 顶栏:品牌 · 垂直切换 · 健康灯 · 租户/工作区切换 · 积分余额 · 登录用户 + 登出(深色 + 毛玻璃)。
-export function TopBar({ user, tenant, tenants = [], onSwitchTenant, space, spaces = [], onSwitchSpace, onCreateSpace, onLogout, onCommand, onOpenUsage }: { user: AuthUser; tenant?: TenantCtx | null; tenants?: MyTenant[]; onSwitchTenant?: (id: string) => void; space?: SpaceCtx | null; spaces?: MySpace[]; onSwitchSpace?: (id: string) => void; onCreateSpace?: (name: string) => void; onLogout: () => void; onCommand?: () => void; onOpenUsage?: () => void }) {
+export function TopBar({ user, tenant, tenants = [], onSwitchTenant, space, spaces = [], onSwitchSpace, onCreateSpace, onEnableTenantSpace, tenantRole, onLogout, onCommand, onOpenUsage }: { user: AuthUser; tenant?: TenantCtx | null; tenants?: MyTenant[]; onSwitchTenant?: (id: string) => void; space?: SpaceCtx | null; spaces?: MySpace[]; onSwitchSpace?: (id: string) => void; onCreateSpace?: (name: string) => void; onEnableTenantSpace?: () => void; tenantRole?: string; onLogout: () => void; onCommand?: () => void; onOpenUsage?: () => void }) {
const h = useHealth();
const { theme, toggle } = useTheme();
return (
@@ -147,7 +160,7 @@ export function TopBar({ user, tenant, tenants = [], onSwitchTenant, space, spac
-
+
{tenant?.tenant && }