mirror of
https://github.com/BerriAI/litellm.git
synced 2025-04-27 11:43:54 +00:00
(UI - View SpendLogs Table) (#7842)
* litellm log messages / responses * add messages/response to schema.prisma * add support for logging messages / responses in DB * test_spend_logs_payload_with_prompts_enabled * _get_messages_for_spend_logs_payload * ui_view_spend_logs endpoint * add tanstack and moment * add uiSpendLogsCall * ui view logs table * ui view spendLogs table * ui_view_spend_logs * fix code quality * test_spend_logs_payload_with_prompts_enabled * _get_messages_for_spend_logs_payload * test_spend_logs_payload_with_prompts_enabled * test_spend_logs_payload_with_prompts_enabled * ui view spend logs * minor ui fix * ui - update leftnav * ui - clean up ui * fix leftnav * ui fix navbar * ui fix moving chat ui tab
This commit is contained in:
parent
fc7a931485
commit
16673ab488
15 changed files with 795 additions and 89 deletions
|
@ -2,6 +2,22 @@ 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
|
||||
} from '@ant-design/icons';
|
||||
|
||||
const { Sider } = Layout;
|
||||
|
||||
|
@ -18,6 +34,8 @@ interface MenuItem {
|
|||
page: string;
|
||||
label: string;
|
||||
roles?: string[];
|
||||
children?: MenuItem[]; // Add children property for submenus
|
||||
icon?: React.ReactNode;
|
||||
}
|
||||
|
||||
const old_admin_roles = ["Admin", "Admin Viewer"];
|
||||
|
@ -28,59 +46,103 @@ const rolesAllowedToSeeUsage = ["Admin", "Admin Viewer", "Internal User", "Inter
|
|||
|
||||
// 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" }, // all roles
|
||||
{ key: "3", page: "llm-playground", label: "Test Key" }, // all roles
|
||||
{ key: "2", page: "models", label: "Models", roles: all_admin_roles },
|
||||
{ key: "4", page: "usage", label: "Usage"}, // all roles
|
||||
{ key: "6", page: "teams", label: "Teams" },
|
||||
{ key: "17", page: "organizations", label: "Organizations", roles: all_admin_roles },
|
||||
{ key: "5", page: "users", label: "Internal Users", roles: all_admin_roles },
|
||||
{ key: "8", page: "settings", label: "Logging & Alerts", roles: all_admin_roles },
|
||||
{ key: "9", page: "caching", label: "Caching", roles: all_admin_roles },
|
||||
{ key: "10", page: "budgets", label: "Budgets", roles: all_admin_roles },
|
||||
{ key: "11", page: "general-settings", label: "Router Settings", roles: all_admin_roles },
|
||||
{ key: "12", page: "pass-through-settings", label: "Pass-Through", roles: all_admin_roles },
|
||||
{ key: "13", page: "admin-panel", label: "Admin Settings", roles: all_admin_roles },
|
||||
{ key: "14", page: "api_ref", label: "API Reference" }, // all roles
|
||||
{ key: "16", page: "model-hub", label: "Model Hub" }, // all roles
|
||||
{ key: "1", page: "api-keys", label: "Virtual Keys", icon: <KeyOutlined /> },
|
||||
{ key: "3", page: "llm-playground", label: "Test Key", icon: <PlayCircleOutlined /> },
|
||||
{ key: "2", page: "models", label: "Models", icon: <BlockOutlined />, roles: all_admin_roles },
|
||||
{ key: "4", page: "usage", label: "Usage", icon: <BarChartOutlined /> },
|
||||
{ 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: "extras",
|
||||
page: "extras",
|
||||
label: "Extras",
|
||||
icon: <DatabaseOutlined />,
|
||||
roles: all_admin_roles,
|
||||
children: [
|
||||
{ key: "15", page: "logs", label: "Logs", icon: <LineChartOutlined />, roles: all_admin_roles },
|
||||
{ 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: "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 },
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
// The Sidebar component can now be simplified to:
|
||||
const Sidebar: React.FC<SidebarProps> = ({
|
||||
setPage,
|
||||
userRole,
|
||||
defaultSelectedKey,
|
||||
}) => {
|
||||
// Find the menu item that matches the default page to get its key
|
||||
const selectedMenuItem = menuItems.find(item => item.page === defaultSelectedKey);
|
||||
const selectedMenuKey = selectedMenuItem?.key || "1";
|
||||
// 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 =>
|
||||
!item.roles || item.roles.includes(userRole)
|
||||
);
|
||||
|
||||
return (
|
||||
<Layout style={{ minHeight: "100vh", maxWidth: userRole === "Admin Viewer" ? "120px" : "145px" }}>
|
||||
<Sider width={userRole === "Admin Viewer" ? 120 : 145}>
|
||||
<Layout style={{ minHeight: "100vh" }}>
|
||||
<Sider theme="light" width={220}>
|
||||
<Menu
|
||||
mode="inline"
|
||||
selectedKeys={[selectedMenuKey]}
|
||||
style={{ height: "100%", borderRight: 0 }}
|
||||
>
|
||||
{filteredMenuItems.map(item => (
|
||||
<Menu.Item
|
||||
key={item.key}
|
||||
onClick={() => {
|
||||
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);
|
||||
}}
|
||||
>
|
||||
<Text>{item.label}</Text>
|
||||
</Menu.Item>
|
||||
))}
|
||||
</Menu>
|
||||
} : undefined
|
||||
}))}
|
||||
/>
|
||||
</Sider>
|
||||
</Layout>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue