diff --git a/ui/litellm-dashboard/src/components/view_users/columns.tsx b/ui/litellm-dashboard/src/components/view_users/columns.tsx
index 20df4fc246e..48895c69def 100644
--- a/ui/litellm-dashboard/src/components/view_users/columns.tsx
+++ b/ui/litellm-dashboard/src/components/view_users/columns.tsx
@@ -46,6 +46,12 @@ export const columns = (
enableSorting: true,
cell: ({ row }) => {possibleUIRoles?.[row.original.user_role]?.ui_label || "-"},
},
+ {
+ header: "User Alias",
+ accessorKey: "user_alias",
+ enableSorting: false,
+ cell: ({ row }) => {row.original.user_alias || "-"},
+ },
{
header: "Spend (USD)",
accessorKey: "spend",
diff --git a/ui/litellm-dashboard/src/components/view_users/table.test.tsx b/ui/litellm-dashboard/src/components/view_users/table.test.tsx
index 8ef887932cc..c688d5749d0 100644
--- a/ui/litellm-dashboard/src/components/view_users/table.test.tsx
+++ b/ui/litellm-dashboard/src/components/view_users/table.test.tsx
@@ -1,63 +1,52 @@
import { act, fireEvent, render, screen } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
-
import { UserDataTable } from "./table";
+const defaultFilters = {
+ email: "",
+ user_id: "",
+ user_role: "",
+ sso_user_id: "",
+ team: "",
+ model: "",
+ min_spend: null,
+ max_spend: null,
+ sort_by: "",
+ sort_order: "asc" as const,
+};
+
+const getDefaultProps = () => ({
+ data: [] as any[],
+ columns: [] as any[],
+ accessToken: null,
+ userRole: "Admin",
+ possibleUIRoles: null as Record> | null,
+ filters: defaultFilters,
+ updateFilters: vi.fn(),
+ initialFilters: defaultFilters,
+ teams: [] as any[],
+ handleEdit: vi.fn(),
+ handleDelete: vi.fn(),
+ handleResetPassword: vi.fn(),
+ userListResponse: { users: [], total: 0, page: 1, page_size: 25, total_pages: 1 },
+ currentPage: 1,
+ handlePageChange: vi.fn(),
+});
+
describe("UserDataTable", () => {
it("should render the UserDataTable component", () => {
- const filters = {
- email: "",
- user_id: "",
- user_role: "",
- sso_user_id: "",
- team: "",
- model: "",
- min_spend: null,
- max_spend: null,
- sort_by: "",
- sort_order: "asc" as const,
- };
-
- const updateFilters = vi.fn();
-
- render(
- ,
- );
+ render();
expect(screen.getByText("Filters")).toBeInTheDocument();
});
it("should call onSortChange when clicking a sortable header", () => {
const filters = {
- email: "",
- user_id: "",
- user_role: "",
- sso_user_id: "",
- team: "",
- model: "",
- min_spend: null,
- max_spend: null,
+ ...defaultFilters,
sort_by: "created_at",
sort_order: "desc" as const,
};
- const updateFilters = vi.fn();
const onSortChange = vi.fn();
const possibleUIRoles = {
@@ -67,21 +56,10 @@ describe("UserDataTable", () => {
render(
,
@@ -96,41 +74,7 @@ describe("UserDataTable", () => {
});
it("should show skeleton loaders when isLoading is true", () => {
- const filters = {
- email: "",
- user_id: "",
- user_role: "",
- sso_user_id: "",
- team: "",
- model: "",
- min_spend: null,
- max_spend: null,
- sort_by: "",
- sort_order: "asc" as const,
- };
-
- const updateFilters = vi.fn();
-
- render(
- ,
- );
+ render();
expect(screen.queryByText(/Showing/i)).not.toBeInTheDocument();
expect(screen.queryByRole("button", { name: /Previous/i })).not.toBeInTheDocument();
@@ -138,44 +82,35 @@ describe("UserDataTable", () => {
});
it("should show actual content when isLoading is false", () => {
- const filters = {
- email: "",
- user_id: "",
- user_role: "",
- sso_user_id: "",
- team: "",
- model: "",
- min_spend: null,
- max_spend: null,
- sort_by: "",
- sort_order: "asc" as const,
- };
-
- const updateFilters = vi.fn();
-
- render(
- ,
- );
+ render();
expect(screen.getByText(/Showing/i)).toBeInTheDocument();
expect(screen.getByRole("button", { name: /Previous/i })).toBeInTheDocument();
expect(screen.getByRole("button", { name: /Next/i })).toBeInTheDocument();
});
+
+ it("should render all column headers", () => {
+ const possibleUIRoles = {
+ admin: { ui_label: "Admin" },
+ user: { ui_label: "User" },
+ };
+
+ render();
+
+ [
+ "User ID",
+ "Email",
+ "Global Proxy Role",
+ "User Alias",
+ "Spend (USD)",
+ "Budget (USD)",
+ "SSO ID",
+ "API Keys",
+ "Created At",
+ "Updated At",
+ "Actions",
+ ].forEach((header) => {
+ expect(screen.getByRole("columnheader", { name: header })).toBeInTheDocument();
+ });
+ });
});
diff --git a/ui/litellm-dashboard/src/components/view_users/types.ts b/ui/litellm-dashboard/src/components/view_users/types.ts
index d976d46ebc1..d674db5c7db 100644
--- a/ui/litellm-dashboard/src/components/view_users/types.ts
+++ b/ui/litellm-dashboard/src/components/view_users/types.ts
@@ -1,6 +1,7 @@
export interface UserInfo {
user_id: string;
user_email: string;
+ user_alias: string | null;
user_role: string;
spend: number;
max_budget: number | null;