88 lines
2.5 KiB
TypeScript
88 lines
2.5 KiB
TypeScript
import Icon from "./Icon";
|
|
|
|
type ActivePage = "home" | "scripts" | "data-resources" | "schedules" | "system";
|
|
|
|
type SidebarProps = {
|
|
activePage: ActivePage;
|
|
collapsed: boolean;
|
|
onNavigate: (page: ActivePage) => void;
|
|
onToggleCollapse: () => void;
|
|
onEndEditing?: () => void;
|
|
onSelectScript?: (scriptId: null) => void;
|
|
editSessionRef?: React.RefObject<unknown | null>;
|
|
isSystemAdmin?: boolean;
|
|
};
|
|
|
|
type NavigationItem = {
|
|
label: string;
|
|
icon: "home" | "script" | "database" | "schedule" | "settings";
|
|
page: ActivePage;
|
|
};
|
|
|
|
export function Sidebar({
|
|
activePage,
|
|
collapsed,
|
|
onNavigate,
|
|
onToggleCollapse,
|
|
onEndEditing,
|
|
onSelectScript,
|
|
editSessionRef,
|
|
isSystemAdmin = false,
|
|
}: SidebarProps) {
|
|
const handleNavigationClick = (page: ActivePage) => {
|
|
if (page !== "scripts") {
|
|
if (editSessionRef?.current) {
|
|
onEndEditing?.();
|
|
} else {
|
|
onSelectScript?.(null);
|
|
}
|
|
}
|
|
onNavigate(page);
|
|
};
|
|
|
|
// 根据管理员权限构建菜单项
|
|
const navigation: NavigationItem[] = [
|
|
{ label: "工作台", icon: "home", page: "home" },
|
|
{ label: "构建脚本", icon: "script", page: "scripts" },
|
|
{ label: "数据资源", icon: "database", page: "data-resources" },
|
|
{ label: "调度配置", icon: "schedule", page: "schedules" },
|
|
];
|
|
|
|
// 系统管理员才显示"系统管理"菜单
|
|
if (isSystemAdmin) {
|
|
navigation.push({ label: "系统管理", icon: "settings", page: "system" });
|
|
}
|
|
|
|
return (
|
|
<aside className={`sidebar${collapsed ? " is-collapsed" : ""}`}>
|
|
<div className="brand">
|
|
<span className="brand__mark"><Icon name="brand" size={31} /></span>
|
|
{!collapsed && <span className="brand__name">模型实验开发平台</span>}
|
|
</div>
|
|
|
|
{!collapsed && (
|
|
<nav className="navigation" aria-label="主导航">
|
|
{navigation.map((item) => (
|
|
<button
|
|
className={`nav-item${
|
|
item.page === activePage ? " nav-item--active" : ""
|
|
}`}
|
|
key={item.label}
|
|
type="button"
|
|
onClick={() => handleNavigationClick(item.page)}
|
|
>
|
|
<Icon name={item.icon} size={19} />
|
|
<span>{item.label}</span>
|
|
</button>
|
|
))}
|
|
</nav>
|
|
)}
|
|
|
|
<button className="sidebar-footer" type="button" onClick={onToggleCollapse}>
|
|
<Icon name="menu" size={19} />
|
|
<span>{collapsed ? "展开菜单" : "收起菜单"}</span>
|
|
</button>
|
|
</aside>
|
|
);
|
|
}
|