74 lines
2.1 KiB
TypeScript
74 lines
2.1 KiB
TypeScript
import Icon from "./Icon";
|
|
|
|
const navigation = [
|
|
{ label: "工作台", icon: "home" as const, page: "home" as const },
|
|
{ label: "构建脚本", icon: "script" as const, page: "scripts" as const },
|
|
{ label: "调度配置", icon: "schedule" as const, page: "schedules" as const },
|
|
{ label: "系统管理", icon: "settings" as const, page: "system" as const },
|
|
];
|
|
|
|
type ActivePage = "home" | "scripts" | "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>;
|
|
};
|
|
|
|
export function Sidebar({
|
|
activePage,
|
|
collapsed,
|
|
onNavigate,
|
|
onToggleCollapse,
|
|
onEndEditing,
|
|
onSelectScript,
|
|
editSessionRef,
|
|
}: SidebarProps) {
|
|
const handleNavigationClick = (page: ActivePage) => {
|
|
if (page !== "scripts") {
|
|
if (editSessionRef?.current) {
|
|
onEndEditing?.();
|
|
} else {
|
|
onSelectScript?.(null);
|
|
}
|
|
}
|
|
onNavigate(page);
|
|
};
|
|
|
|
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>
|
|
);
|
|
}
|