Spaces:
Paused
Paused
| import { Layout, Menu } from "antd"; | |
| import Link from "next/link"; | |
| import { List } from "postcss/lib/list"; | |
| import { Text } from "@tremor/react"; | |
| import { | |
| KeyOutlined, | |
| PlayCircleOutlined, | |
| BlockOutlined, | |
| BarChartOutlined, | |
| TeamOutlined, | |
| BankOutlined, | |
| UserOutlined, | |
| SettingOutlined, | |
| ApiOutlined, | |
| AppstoreOutlined, | |
| DatabaseOutlined, | |
| FileTextOutlined, | |
| LineOutlined, | |
| LineChartOutlined, | |
| SafetyOutlined, | |
| ExperimentOutlined, | |
| ThunderboltOutlined, | |
| LockOutlined, | |
| ToolOutlined, | |
| TagsOutlined, | |
| } from '@ant-design/icons'; | |
| import { old_admin_roles, v2_admin_role_names, all_admin_roles, rolesAllowedToSeeUsage, rolesWithWriteAccess, internalUserRoles } from '../utils/roles'; | |
| const { Sider } = Layout; | |
| // Define the props type | |
| interface SidebarProps { | |
| setPage: (page: string) => void; | |
| userRole: string; | |
| defaultSelectedKey: string; | |
| } | |
| // Create a more comprehensive menu item configuration | |
| interface MenuItem { | |
| key: string; | |
| page: string; | |
| label: string; | |
| roles?: string[]; | |
| children?: MenuItem[]; // Add children property for submenus | |
| icon?: React.ReactNode; | |
| } | |
| const Sidebar: React.FC<SidebarProps> = ({ | |
| setPage, | |
| userRole, | |
| defaultSelectedKey, | |
| }) => { | |
| // Note: If a menu item does not have a role, it is visible to all roles. | |
| const menuItems: MenuItem[] = [ | |
| { key: "1", page: "api-keys", label: "Virtual Keys", icon: <KeyOutlined /> }, | |
| { key: "3", page: "llm-playground", label: "Test Key", icon: <PlayCircleOutlined />, roles: rolesWithWriteAccess }, | |
| { key: "2", page: "models", label: "Models", icon: <BlockOutlined />, roles: rolesWithWriteAccess }, | |
| { key: "12", page: "new_usage", label: "Usage", icon: <BarChartOutlined />, roles: [...all_admin_roles, ...internalUserRoles] }, | |
| { key: "6", page: "teams", label: "Teams", icon: <TeamOutlined /> }, | |
| { key: "17", page: "organizations", label: "Organizations", icon: <BankOutlined />, roles: all_admin_roles }, | |
| { key: "5", page: "users", label: "Internal Users", icon: <UserOutlined />, roles: all_admin_roles }, | |
| { key: "14", page: "api_ref", label: "API Reference", icon: <ApiOutlined /> }, | |
| { key: "16", page: "model-hub", label: "Model Hub", icon: <AppstoreOutlined /> }, | |
| { key: "15", page: "logs", label: "Logs", icon: <LineChartOutlined />}, | |
| { | |
| key: "experimental", | |
| page: "experimental", | |
| label: "Experimental", | |
| icon: <ExperimentOutlined />, | |
| children: [ | |
| { key: "9", page: "caching", label: "Caching", icon: <DatabaseOutlined />, roles: all_admin_roles }, | |
| { key: "10", page: "budgets", label: "Budgets", icon: <BankOutlined />, roles: all_admin_roles }, | |
| { key: "11", page: "guardrails", label: "Guardrails", icon: <SafetyOutlined />, roles: all_admin_roles }, | |
| { key: "20", page: "transform-request", label: "API Playground", icon: <ApiOutlined />, roles: [...all_admin_roles, ...internalUserRoles] }, | |
| { key: "18", page: "mcp-tools", label: "MCP Tools", icon: <ToolOutlined />, roles: all_admin_roles }, | |
| { key: "19", page: "tag-management", label: "Tag Management", icon: <TagsOutlined />, roles: all_admin_roles }, | |
| { key: "21", page: "vector-stores", label: "Vector Stores", icon: <DatabaseOutlined />, roles: all_admin_roles }, | |
| { key: "4", page: "usage", label: "Old Usage", icon: <BarChartOutlined /> }, | |
| ] | |
| }, | |
| { | |
| key: "settings", | |
| page: "settings", | |
| label: "Settings", | |
| icon: <SettingOutlined />, | |
| roles: all_admin_roles, | |
| children: [ | |
| { key: "11", page: "general-settings", label: "Router Settings", icon: <SettingOutlined />, roles: all_admin_roles }, | |
| { key: "12", page: "pass-through-settings", label: "Pass-Through", icon: <ApiOutlined />, roles: all_admin_roles }, | |
| { key: "8", page: "settings", label: "Logging & Alerts", icon: <SettingOutlined />, roles: all_admin_roles }, | |
| { key: "13", page: "admin-panel", label: "Admin Settings", icon: <SettingOutlined />, roles: all_admin_roles }, | |
| ] | |
| } | |
| ]; | |
| // Find the menu item that matches the default page, including in submenus | |
| const findMenuItemKey = (page: string): string => { | |
| // Check top-level items | |
| const topLevelItem = menuItems.find(item => item.page === page); | |
| if (topLevelItem) return topLevelItem.key; | |
| // Check submenu items | |
| for (const item of menuItems) { | |
| if (item.children) { | |
| const childItem = item.children.find(child => child.page === page); | |
| if (childItem) return childItem.key; | |
| } | |
| } | |
| return "1"; // Default to first item if not found | |
| }; | |
| const selectedMenuKey = findMenuItemKey(defaultSelectedKey); | |
| const filteredMenuItems = menuItems.filter(item => { | |
| // Check if parent item has roles and user has access | |
| const hasParentAccess = !item.roles || item.roles.includes(userRole); | |
| if (!hasParentAccess) return false; | |
| // Filter children if they exist | |
| if (item.children) { | |
| item.children = item.children.filter(child => | |
| !child.roles || child.roles.includes(userRole) | |
| ); | |
| } | |
| return true; | |
| }); | |
| return ( | |
| <Layout style={{ minHeight: "100vh" }}> | |
| <Sider theme="light" width={220}> | |
| <Menu | |
| mode="inline" | |
| selectedKeys={[selectedMenuKey]} | |
| style={{ | |
| borderRight: 0, | |
| backgroundColor: 'transparent', | |
| fontSize: '14px', | |
| }} | |
| items={filteredMenuItems.map(item => ({ | |
| key: item.key, | |
| icon: item.icon, | |
| label: item.label, | |
| children: item.children?.map(child => ({ | |
| key: child.key, | |
| icon: child.icon, | |
| label: child.label, | |
| onClick: () => { | |
| const newSearchParams = new URLSearchParams(window.location.search); | |
| newSearchParams.set('page', child.page); | |
| window.history.pushState(null, '', `?${newSearchParams.toString()}`); | |
| setPage(child.page); | |
| } | |
| })), | |
| onClick: !item.children ? () => { | |
| const newSearchParams = new URLSearchParams(window.location.search); | |
| newSearchParams.set('page', item.page); | |
| window.history.pushState(null, '', `?${newSearchParams.toString()}`); | |
| setPage(item.page); | |
| } : undefined | |
| }))} | |
| /> | |
| </Sider> | |
| </Layout> | |
| ); | |
| }; | |
| export default Sidebar; | |