From 7d931edc237d32390353581284d3a4f83103ac64 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Tue, 24 Feb 2026 19:39:28 -0800 Subject: [PATCH] feat(ui): add user filtering to usage page Adds "User Usage" as a new view option in the usage page dropdown, allowing admins to view and filter usage data by individual users via the existing /user/daily/activity backend endpoint. Co-Authored-By: Claude Opus 4.6 --- .../src/components/EntityUsageExport/types.ts | 2 +- .../UsagePage/components/EntityUsage/EntityUsage.tsx | 10 ++++++++++ .../UsagePage/components/UsagePageView.tsx | 12 ++++++++++++ .../components/UsageViewSelect/UsageViewSelect.tsx | 10 +++++++++- 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/ui/litellm-dashboard/src/components/EntityUsageExport/types.ts b/ui/litellm-dashboard/src/components/EntityUsageExport/types.ts index ccf0b1b45cf..0f92b61a46e 100644 --- a/ui/litellm-dashboard/src/components/EntityUsageExport/types.ts +++ b/ui/litellm-dashboard/src/components/EntityUsageExport/types.ts @@ -3,7 +3,7 @@ import type { Team } from "@/components/key_team_helpers/key_list"; export type ExportFormat = "csv" | "json"; export type ExportScope = "daily" | "daily_with_keys" | "daily_with_models"; -export type EntityType = "tag" | "team" | "organization" | "customer" | "agent"; +export type EntityType = "tag" | "team" | "organization" | "customer" | "agent" | "user"; export interface EntitySpendData { results: any[]; diff --git a/ui/litellm-dashboard/src/components/UsagePage/components/EntityUsage/EntityUsage.tsx b/ui/litellm-dashboard/src/components/UsagePage/components/EntityUsage/EntityUsage.tsx index 32882341921..793226f18db 100644 --- a/ui/litellm-dashboard/src/components/UsagePage/components/EntityUsage/EntityUsage.tsx +++ b/ui/litellm-dashboard/src/components/UsagePage/components/EntityUsage/EntityUsage.tsx @@ -32,6 +32,7 @@ import { organizationDailyActivityCall, tagDailyActivityCall, teamDailyActivityCall, + userDailyActivityCall, } from "../../../networking"; import { getProviderLogoAndName } from "../../../provider_info_helpers"; import { BreakdownMetrics, DailyData, EntityMetricWithMetadata, KeyMetricWithMetadata, TagUsage } from "../../types"; @@ -156,6 +157,15 @@ const EntityUsage: React.FC = ({ accessToken, entityType, enti selectedTags.length > 0 ? selectedTags : null, ); setSpendData(data); + } else if (entityType === "user") { + const data = await userDailyActivityCall( + accessToken, + startTime, + endTime, + 1, + selectedTags.length > 0 ? selectedTags[0] : null, + ); + setSpendData(data); } else { throw new Error("Invalid entity type"); } diff --git a/ui/litellm-dashboard/src/components/UsagePage/components/UsagePageView.tsx b/ui/litellm-dashboard/src/components/UsagePage/components/UsagePageView.tsx index 3e5f0a2014d..52143d23b9a 100644 --- a/ui/litellm-dashboard/src/components/UsagePage/components/UsagePageView.tsx +++ b/ui/litellm-dashboard/src/components/UsagePage/components/UsagePageView.tsx @@ -898,6 +898,18 @@ const UsagePage: React.FC = ({ teams, organizations }) => { dateValue={dateValue} /> )} + {/* User Usage Panel */} + {usageView === "user" && ( + 0 ? userOptions : null} + premiumUser={premiumUser} + dateValue={dateValue} + /> + )} {/* User Agent Activity Panel */} {usageView === "user-agent-activity" && ( diff --git a/ui/litellm-dashboard/src/components/UsagePage/components/UsageViewSelect/UsageViewSelect.tsx b/ui/litellm-dashboard/src/components/UsagePage/components/UsageViewSelect/UsageViewSelect.tsx index 3d456de5a65..53236756d5c 100644 --- a/ui/litellm-dashboard/src/components/UsagePage/components/UsageViewSelect/UsageViewSelect.tsx +++ b/ui/litellm-dashboard/src/components/UsagePage/components/UsageViewSelect/UsageViewSelect.tsx @@ -7,10 +7,11 @@ import { ShoppingCartOutlined, TagsOutlined, TeamOutlined, + UserOutlined, } from "@ant-design/icons"; import { Badge, Select } from "antd"; import React from "react"; -export type UsageOption = "global" | "organization" | "team" | "customer" | "tag" | "agent" | "user-agent-activity"; +export type UsageOption = "global" | "organization" | "team" | "customer" | "tag" | "agent" | "user" | "user-agent-activity"; export interface UsageViewSelectProps { value: UsageOption; onChange: (value: UsageOption) => void; @@ -79,6 +80,13 @@ const OPTIONS: OptionConfig[] = [ icon: , adminOnly: true, }, + { + value: "user", + label: "User Usage", + description: "View usage by individual users", + icon: , + adminOnly: true, + }, { value: "user-agent-activity", label: "User Agent Activity",