From 8df6cfe9d86e147d0ac22ce014797c39dddfe7b6 Mon Sep 17 00:00:00 2001 From: yuneng-jiang Date: Fri, 6 Feb 2026 12:27:03 -0800 Subject: [PATCH] fix model page col resize --- .../model_dashboard/all_models_table.tsx | 11 +- .../src/components/model_dashboard/table.tsx | 11 +- .../molecules/models/columns.test.tsx | 808 ++++++++++++++++++ .../components/molecules/models/columns.tsx | 134 ++- 4 files changed, 922 insertions(+), 42 deletions(-) create mode 100644 ui/litellm-dashboard/src/components/molecules/models/columns.test.tsx diff --git a/ui/litellm-dashboard/src/components/model_dashboard/all_models_table.tsx b/ui/litellm-dashboard/src/components/model_dashboard/all_models_table.tsx index 1ae3335a82..964bb5658f 100644 --- a/ui/litellm-dashboard/src/components/model_dashboard/all_models_table.tsx +++ b/ui/litellm-dashboard/src/components/model_dashboard/all_models_table.tsx @@ -95,7 +95,14 @@ export function AllModelsDataTable({
- +
{tableInstance.getHeaderGroups().map((headerGroup) => ( @@ -171,7 +178,7 @@ export function AllModelsDataTable({ {row.getVisibleCells().map((cell) => ( ({
-
+
{tableInstance.getHeaderGroups().map((headerGroup) => ( @@ -161,7 +168,7 @@ export function ModelDataTable({ {row.getVisibleCells().map((cell) => ( { + const React = await import("react"); + const actual = await importOriginal(); + return { + ...actual, + Icon: React.forwardRef(({ icon: IconComponent, onClick, className, ...props }, ref) => { + const ariaLabel = className?.includes("cursor-not-allowed") + ? "Config model cannot be deleted on the dashboard. Please delete it from the config file." + : "Delete model"; + return React.createElement( + "button", + { ...props, onClick, className, ref, "aria-label": ariaLabel }, + IconComponent && React.createElement(IconComponent, { className: "w-4 h-4" }), + ); + }), + }; +}); + +const createMockModel = (overrides: Partial = {}): ModelData => ({ + model_info: { + id: "test-model-id", + created_at: "2024-01-01T00:00:00Z", + updated_at: "2024-01-02T00:00:00Z", + created_by: "test-user", + team_id: "test-team-id", + db_model: true, + access_groups: ["group1"], + }, + model_name: "test-model", + provider: "openai", + litellm_model_name: "gpt-4", + input_cost: 0.01, + output_cost: 0.03, + max_tokens: 4096, + max_input_tokens: 8192, + litellm_params: { + model: "gpt-4", + litellm_credential_name: "test-credential", + }, + cleanedLitellmParams: {}, + ...overrides, +}); + +const TestTable = ({ + data, + columns: cols, +}: { + data: ModelData[]; + columns: ReturnType; +}) => { + const table = useReactTable({ + data, + columns: cols, + getCoreRowModel: getCoreRowModel(), + }); + + return ( +
+ + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => ( + + {header.isPlaceholder + ? null + : flexRender(header.column.columnDef.header, header.getContext())} + + ))} + + ))} + + + {table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + ))} + + ))} + +
+ ); +}; + +describe("columns", () => { + beforeEach(() => { + vi.mocked(providerInfoHelpers.getProviderLogoAndName).mockImplementation((provider: string) => { + const providerMap: Record = { + openai: { displayName: "OpenAI", logo: "/openai-logo.png" }, + anthropic: { displayName: "Anthropic", logo: "/anthropic-logo.png" }, + }; + return providerMap[provider] || { displayName: provider || "Unknown provider", logo: "" }; + }); + }); + + const defaultProps = { + userRole: "Admin", + userID: "test-user", + premiumUser: false, + setSelectedModelId: vi.fn(), + setSelectedTeamId: vi.fn(), + getDisplayModelName: vi.fn((model: ModelData) => model.model_name || "-"), + handleEditClick: vi.fn(), + handleRefreshClick: vi.fn(), + expandedRows: new Set(), + setExpandedRows: vi.fn(), + }; + + it("should render columns with table structure", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel(); + render(); + + expect(screen.getByText("Model ID")).toBeInTheDocument(); + expect(screen.getByText("Model Information")).toBeInTheDocument(); + expect(screen.getByText("Credentials")).toBeInTheDocument(); + expect(screen.getByText("Created By")).toBeInTheDocument(); + expect(screen.getByText("Updated At")).toBeInTheDocument(); + expect(screen.getByText("Costs")).toBeInTheDocument(); + expect(screen.getByText("Team ID")).toBeInTheDocument(); + expect(screen.getByText("Model Access Group")).toBeInTheDocument(); + expect(screen.getByText("Status")).toBeInTheDocument(); + expect(screen.getByText("Actions")).toBeInTheDocument(); + }); + + it("should display model information with provider logo", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + model_name: "GPT-4", + provider: "openai", + litellm_model_name: "gpt-4", + }); + render(); + + expect(screen.getByText("GPT-4")).toBeInTheDocument(); + expect(screen.getByText("gpt-4")).toBeInTheDocument(); + }); + + it("should display credential name when available", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + litellm_params: { + model: "gpt-4", + litellm_credential_name: "my-credential", + }, + }); + render(); + + expect(screen.getByText("my-credential")).toBeInTheDocument(); + }); + + it("should display 'No credentials' when credential name is missing", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + litellm_params: { + model: "gpt-4", + }, + }); + render(); + + expect(screen.getByText("No credentials")).toBeInTheDocument(); + }); + + it("should display created by information for DB models", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + model_info: { + ...createMockModel().model_info, + db_model: true, + created_by: "admin-user", + created_at: "2024-01-15T10:30:00Z", + }, + }); + render(); + + expect(screen.getByText("admin-user")).toBeInTheDocument(); + }); + + it("should display 'Defined in config' for config models", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + model_info: { + ...createMockModel().model_info, + db_model: false, + }, + }); + render(); + + expect(screen.getByText("Defined in config")).toBeInTheDocument(); + }); + + it("should display costs when available", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + input_cost: 0.01, + output_cost: 0.03, + }); + render(); + + expect(screen.getByText("In: $0.01")).toBeInTheDocument(); + expect(screen.getByText("Out: $0.03")).toBeInTheDocument(); + }); + + it("should display '-' when costs are missing", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + input_cost: undefined as any, + output_cost: undefined as any, + }); + render(); + + const costCells = screen.getAllByText("-"); + expect(costCells.length).toBeGreaterThan(0); + }); + + it("should display '-' when team ID is missing", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + model_info: { + ...createMockModel().model_info, + team_id: "", + }, + }); + render(); + + const teamIdCells = screen.getAllByText("-"); + expect(teamIdCells.length).toBeGreaterThan(0); + }); + + it("should display access groups", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + model_info: { + ...createMockModel().model_info, + access_groups: ["group1", "group2"], + }, + }); + render(); + + expect(screen.getByText("group1")).toBeInTheDocument(); + expect(screen.getByText("+1")).toBeInTheDocument(); + }); + + it("should expand access groups when expand button is clicked", async () => { + const user = userEvent.setup(); + const setExpandedRows = vi.fn(); + const expandedRows = new Set(); + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + expandedRows, + setExpandedRows, + ); + + const model = createMockModel({ + model_info: { + ...createMockModel().model_info, + id: "model-with-groups", + access_groups: ["group1", "group2", "group3"], + }, + }); + render(); + + const expandButton = screen.getByText("+2"); + expect(expandButton).toBeInTheDocument(); + + await user.click(expandButton); + expect(setExpandedRows).toHaveBeenCalled(); + }); + + it("should display '-' when access groups are empty", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + model_info: { + ...createMockModel().model_info, + access_groups: null, + }, + }); + render(); + + const emptyCells = screen.getAllByText("-"); + expect(emptyCells.length).toBeGreaterThan(0); + }); + + it("should display 'DB Model' status for DB models", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + model_info: { + ...createMockModel().model_info, + db_model: true, + }, + }); + render(); + + expect(screen.getByText("DB Model")).toBeInTheDocument(); + }); + + it("should display 'Config Model' status for config models", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + model_info: { + ...createMockModel().model_info, + db_model: false, + }, + }); + render(); + + expect(screen.getByText("Config Model")).toBeInTheDocument(); + }); + + it("should allow Admin to delete DB models", async () => { + const user = userEvent.setup(); + const setSelectedModelId = vi.fn(); + const cols = columns( + "Admin", + "admin-user", + defaultProps.premiumUser, + setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + model_info: { + ...createMockModel().model_info, + db_model: true, + id: "deletable-model", + }, + }); + render(); + + const deleteButton = screen.getByRole("button", { name: "Delete model" }); + expect(deleteButton).toBeInTheDocument(); + + await user.click(deleteButton); + expect(setSelectedModelId).toHaveBeenCalledWith("deletable-model"); + }); + + it("should allow model creator to delete their own DB models", async () => { + const user = userEvent.setup(); + const setSelectedModelId = vi.fn(); + const cols = columns( + "User", + "model-creator", + defaultProps.premiumUser, + setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + model_info: { + ...createMockModel().model_info, + db_model: true, + created_by: "model-creator", + id: "user-model", + }, + }); + render(); + + const deleteButton = screen.getByRole("button", { name: "Delete model" }); + expect(deleteButton).toBeInTheDocument(); + + await user.click(deleteButton); + expect(setSelectedModelId).toHaveBeenCalledWith("user-model"); + }); + + + it("should disable delete for config models", () => { + const cols = columns( + "Admin", + "admin-user", + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + model_info: { + ...createMockModel().model_info, + db_model: false, + }, + }); + render(); + + const deleteButton = screen.getByRole("button", { name: /config model cannot be deleted/i }); + expect(deleteButton).toBeInTheDocument(); + expect(deleteButton).toHaveClass("cursor-not-allowed"); + }); + + it("should display collapsed access groups with expand button", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + new Set(), + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + model_info: { + ...createMockModel().model_info, + access_groups: ["group1", "group2", "group3"], + }, + }); + render(); + + expect(screen.getByText("group1")).toBeInTheDocument(); + expect(screen.getByText("+2")).toBeInTheDocument(); + expect(screen.queryByText("group2")).not.toBeInTheDocument(); + expect(screen.queryByText("group3")).not.toBeInTheDocument(); + }); + + it("should display expanded access groups when expanded", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + new Set(["test-model-id"]), + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + model_info: { + ...createMockModel().model_info, + id: "test-model-id", + access_groups: ["group1", "group2", "group3"], + }, + }); + render(); + + expect(screen.getByText("group1")).toBeInTheDocument(); + expect(screen.getByText("group2")).toBeInTheDocument(); + expect(screen.getByText("group3")).toBeInTheDocument(); + expect(screen.getByText("−")).toBeInTheDocument(); + }); + + it("should display single access group without expand button", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + model_info: { + ...createMockModel().model_info, + access_groups: ["group1"], + }, + }); + render(); + + expect(screen.getByText("group1")).toBeInTheDocument(); + expect(screen.queryByText(/\+/)).not.toBeInTheDocument(); + }); + + + it("should handle missing display name gracefully", () => { + const getDisplayModelName = vi.fn(() => ""); + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel(); + render(); + + expect(screen.getByText("-")).toBeInTheDocument(); + }); + + it("should handle missing created_at date", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + model_info: { + ...createMockModel().model_info, + created_at: "", + }, + }); + render(); + + expect(screen.getByText("Unknown date")).toBeInTheDocument(); + }); + + it("should handle missing updated_at date", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + model_info: { + ...createMockModel().model_info, + updated_at: "", + }, + }); + render(); + + const updatedAtCells = screen.getAllByText("-"); + expect(updatedAtCells.length).toBeGreaterThan(0); + }); + + it("should handle missing created_by for DB models", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + model_info: { + ...createMockModel().model_info, + db_model: true, + created_by: "", + }, + }); + render(); + + expect(screen.getByText("Unknown")).toBeInTheDocument(); + }); + + it("should display only input cost when output cost is missing", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + input_cost: 0.01, + output_cost: undefined as any, + }); + render(); + + expect(screen.getByText("In: $0.01")).toBeInTheDocument(); + expect(screen.queryByText(/Out:/)).not.toBeInTheDocument(); + }); + + it("should display only output cost when input cost is missing", () => { + const cols = columns( + defaultProps.userRole, + defaultProps.userID, + defaultProps.premiumUser, + defaultProps.setSelectedModelId, + defaultProps.setSelectedTeamId, + defaultProps.getDisplayModelName, + defaultProps.handleEditClick, + defaultProps.handleRefreshClick, + defaultProps.expandedRows, + defaultProps.setExpandedRows, + ); + + const model = createMockModel({ + input_cost: undefined as any, + output_cost: 0.03, + }); + render(); + + expect(screen.getByText("Out: $0.03")).toBeInTheDocument(); + expect(screen.queryByText(/In:/)).not.toBeInTheDocument(); + }); +}); diff --git a/ui/litellm-dashboard/src/components/molecules/models/columns.tsx b/ui/litellm-dashboard/src/components/molecules/models/columns.tsx index 1fc08e502a..958b6ac86a 100644 --- a/ui/litellm-dashboard/src/components/molecules/models/columns.tsx +++ b/ui/litellm-dashboard/src/components/molecules/models/columns.tsx @@ -1,10 +1,12 @@ import { KeyIcon, TrashIcon } from "@heroicons/react/outline"; import { ColumnDef } from "@tanstack/react-table"; import { Badge, Button, Icon } from "@tremor/react"; -import { Tooltip } from "antd"; +import { Popover, Tooltip, Typography, Space, Flex } from "antd"; import { ModelData } from "../../model_dashboard/types"; import { ProviderLogo } from "./ProviderLogo"; +const { Text } = Typography; + export const columns = ( userRole: string, userID: string, @@ -21,16 +23,20 @@ export const columns = ( header: () => Model ID, accessorKey: "model_info.id", enableSorting: false, + size: 130, + minSize: 80, cell: ({ row }) => { const model = row.original; return ( -
setSelectedModelId(model.model_info.id)} > {model.model_info.id} -
+
); }, @@ -38,28 +44,67 @@ export const columns = ( { header: () => Model Information, accessorKey: "model_name", - size: 250, // Fixed column width + size: 250, + minSize: 120, cell: ({ row }) => { const model = row.original; const displayName = getDisplayModelName(row.original) || "-"; - const tooltipContent = ( -
-
- Provider: {model.provider || "-"} -
-
- Public Model Name: {displayName} -
-
- LiteLLM Model Name: {model.litellm_model_name || "-"} -
-
+ const popoverContent = ( + + + + + {model.provider || "Unknown provider"} + + + + + + + Public Model Name + + + {displayName} + + + + + + LiteLLM Model Name + + + {model.litellm_model_name || "-"} + + + + ); return ( - -
- {/* Provider Icon */} + +
{model.provider ? ( @@ -68,17 +113,16 @@ export const columns = ( )}
- {/* Model Names Container */}
- {/* Public Model Name */} -
{displayName}
- {/* LiteLLM Model Name */} -
+ + {displayName} + + {model.litellm_model_name || "-"} -
+
- +
); }, }, @@ -86,14 +130,15 @@ export const columns = ( header: () => Credentials, accessorKey: "litellm_credential_name", enableSorting: false, - size: 180, // Fixed column width + size: 180, + minSize: 100, cell: ({ row }) => { const model = row.original; const credentialName = model.litellm_params?.litellm_credential_name; return credentialName ? ( -
+
{credentialName} @@ -101,7 +146,7 @@ export const columns = (
) : ( -
+
No credentials
@@ -112,7 +157,8 @@ export const columns = ( header: () => Created By, accessorKey: "model_info.created_by", sortingFn: "datetime", - size: 160, // Fixed column width + size: 160, + minSize: 100, cell: ({ row }) => { const model = row.original; const isConfigModel = !model.model_info?.db_model; @@ -120,7 +166,7 @@ export const columns = ( const createdAt = model.model_info.created_at ? new Date(model.model_info.created_at).toLocaleDateString() : null; return ( -
+
{/* Created By - Primary */}
Updated At, accessorKey: "model_info.updated_at", sortingFn: "datetime", + size: 120, + minSize: 80, cell: ({ row }) => { const model = row.original; return ( @@ -155,7 +203,8 @@ export const columns = ( { header: () => Costs, accessorKey: "input_cost", - size: 120, // Fixed column width + size: 120, + minSize: 80, cell: ({ row }) => { const model = row.original; const inputCost = model.input_cost; @@ -164,7 +213,7 @@ export const columns = ( // If both costs are missing or undefined, show "-" if (!inputCost && !outputCost) { return ( -
+
-
); @@ -172,7 +221,7 @@ export const columns = ( return ( -
+
{/* Input Cost - Primary */} {inputCost &&
In: ${inputCost}
} {/* Output Cost - Secondary */} @@ -186,15 +235,17 @@ export const columns = ( header: () => Team ID, accessorKey: "model_info.team_id", enableSorting: false, + size: 130, + minSize: 80, cell: ({ row }) => { const model = row.original; return model.model_info.team_id ? ( -
+