Files
model-platform/frontend/app/components/common/Topbar.tsx
T
2026-08-13 20:13:37 +08:00

122 lines
3.7 KiB
TypeScript

import Icon from "./Icon";
import type { AuthUser, AuthWorkspace } from "../../context/AuthContext";
type TopbarProps = {
activePage: string;
apiOnline: boolean;
user: AuthUser | null;
currentWorkspace: AuthWorkspace;
workspaces: AuthWorkspace[];
workspaceMenuOpen: boolean;
onSetWorkspaceMenuOpen: (open: boolean) => void;
onSetCurrentWorkspace: (workspaceId: string) => void;
onLogout: () => void;
};
export function Topbar({
activePage,
apiOnline,
user,
currentWorkspace,
workspaces,
workspaceMenuOpen,
onSetWorkspaceMenuOpen,
onSetCurrentWorkspace,
onLogout,
}: TopbarProps) {
const pageTitles: Record<string, string> = {
home: "工作台",
scripts: "构建脚本",
schedules: "调度配置",
"data-resources": "数据资源",
system: "系统管理",
};
return (
<header className="topbar">
<div className="page-title">
<button className="icon-button icon-button--back" type="button">
<Icon name="chevron" size={19} />
</button>
<div>
<span className="page-title__eyebrow">开发工作区</span>
<h1>{pageTitles[activePage] || "工作台"}</h1>
</div>
</div>
<div className="topbar__actions">
<div className="api-state">
<span className={`api-state__dot${apiOnline ? " is-online" : ""}`} />
{apiOnline ? "服务已连接" : "服务未连接"}
</div>
<div className="topbar-menu-wrap">
<button
className="workspace-switcher"
type="button"
onClick={() => onSetWorkspaceMenuOpen(!workspaceMenuOpen)}
>
<span className="workspace-switcher__icon">
<Icon name="workspace" size={18} />
</span>
<span>
<small>当前 Workspace</small>
<strong>{currentWorkspace.workspace_name}</strong>
</span>
<Icon name="chevron" size={15} />
</button>
{workspaceMenuOpen && (
<div className="topbar-dropdown">
{workspaces.map((workspace) => (
<button
className={
workspace.workspace_id === currentWorkspace.workspace_id
? "is-selected"
: ""
}
type="button"
key={workspace.workspace_id}
onClick={() => {
onSetCurrentWorkspace(workspace.workspace_id);
onSetWorkspaceMenuOpen(false);
}}
>
<Icon name="workspace" size={15} />
<span>
<strong>{workspace.workspace_name}</strong>
<small>
{workspace.workspace_id === currentWorkspace.workspace_id
? "当前使用"
: "点击切换"}
</small>
</span>
</button>
))}
</div>
)}
</div>
<div className="topbar-menu-wrap">
<button className="user-menu" type="button">
<span className="avatar">
{user?.display_name?.slice(0, 1) ?? "?"}
</span>
<span className="user-menu__copy">
<strong>{user?.display_name ?? "未知用户"}</strong>
<small>
{user?.role_code === "admin" ? "管理员" : "开发人员"}
</small>
</span>
</button>
<button
className="text-button"
type="button"
onClick={() => {
void onLogout();
}}
>
登出
</button>
</div>
</div>
</header>
);
}