diff --git a/ui/litellm-dashboard/src/components/view_logs/table.test.tsx b/ui/litellm-dashboard/src/components/view_logs/table.test.tsx
deleted file mode 100644
index 9a8469cfeba..00000000000
--- a/ui/litellm-dashboard/src/components/view_logs/table.test.tsx
+++ /dev/null
@@ -1,258 +0,0 @@
-import type { ColumnDef } from "@tanstack/react-table";
-import { render, screen, within } from "@testing-library/react";
-import userEvent from "@testing-library/user-event";
-import { describe, expect, it, vi } from "vitest";
-import { DataTable } from "./table";
-
-type Row = { request_id: string; a: string; b: string };
-
-const data: Row[] = [{ request_id: "r1", a: "alpha", b: "beta" }];
-
-const sizedColumns: ColumnDef
[] = [
- { header: "A", accessorKey: "a", size: 120 },
- { header: "B", accessorKey: "b", size: 80 },
-];
-
-const unsizedColumns: ColumnDef[] = [
- { header: "A", accessorKey: "a" },
- { header: "B", accessorKey: "b" },
-];
-
-const expanderColumn: ColumnDef = {
- id: "expander",
- header: () => null,
- cell: ({ row }) =>
- row.getCanExpand() ? (
-
- {row.getIsExpanded() ? "collapse" : "expand"}
-
- ) : null,
-};
-
-describe("DataTable column sizing", () => {
- it("min-widths the table to the column total and sizes every cell when columns declare sizes", () => {
- render( );
-
- const table = screen.getByRole("table");
- expect(table.style.minWidth).toBe("200px");
- expect(table.style.width).toBe("");
-
- const headers = screen.getAllByRole("columnheader");
- expect(headers.map((h) => h.style.width)).toEqual(["120px", "80px"]);
-
- const cells = screen.getAllByRole("cell");
- expect(cells.map((c) => c.style.width)).toEqual(["120px", "80px"]);
- });
-
- it("leaves cells unsized and keeps the fluid table when no column declares a size", () => {
- render( );
-
- const table = screen.getByRole("table");
- expect(table.style.width).toBe("");
- expect(table.style.minWidth).toBe("400px");
-
- for (const cell of [...screen.getAllByRole("columnheader"), ...screen.getAllByRole("cell")]) {
- expect(cell.style.width).toBe("");
- }
- });
-});
-
-describe("DataTable states", () => {
- it("shows the loading message instead of rows while loading", () => {
- render( );
-
- expect(screen.getByText("Fetching things")).toBeInTheDocument();
- expect(screen.queryByText("alpha")).not.toBeInTheDocument();
- });
-
- it("shows the no-data message when there are no rows", () => {
- render( );
-
- expect(screen.getByText("Nothing here")).toBeInTheDocument();
- });
-
- it("falls back to generic loading and empty defaults", () => {
- const { rerender } = render( );
- expect(screen.getByText("Loading...")).toBeInTheDocument();
-
- rerender( );
- expect(screen.getByText("No results")).toBeInTheDocument();
- });
-
- it("suppresses the primitive's row hover on loading, empty, and expansion placeholder rows", async () => {
- const user = userEvent.setup();
- const { rerender } = render( );
- expect(screen.getByText("Loading...").closest("tr")).toHaveClass("hover:bg-transparent");
-
- rerender( );
- expect(screen.getByText("No results").closest("tr")).toHaveClass("hover:bg-transparent");
-
- rerender(
- true}
- renderSubComponent={({ row }) => details for {row.original.request_id}
}
- />,
- );
- await user.click(screen.getByRole("button", { name: "expand r1" }));
- expect(screen.getByText("details for r1").closest("tr")).toHaveClass("hover:bg-transparent");
- expect(screen.getByText("alpha").closest("tr")).not.toHaveClass("hover:bg-transparent");
- });
-
- it("renders row data through plain TanStack column defs, including custom cell renderers", () => {
- const columns: ColumnDef[] = [
- { header: "A", accessorKey: "a" },
- { header: "B", cell: ({ row }) => custom:{row.original.b} },
- ];
- render( );
-
- expect(screen.getByText("alpha")).toBeInTheDocument();
- expect(screen.getByText("custom:beta")).toBeInTheDocument();
- });
-
- it("clips the table to the rounded wrapper so the header band cannot bleed past the corners", () => {
- const { container } = render( );
-
- const wrapper = container.firstElementChild;
- expect(wrapper).toHaveClass("rounded-lg", "overflow-hidden");
- });
-
- it("right-aligns headers and cells with tabular figures for numeric meta columns", () => {
- const columns: ColumnDef[] = [
- { header: "A", accessorKey: "a" },
- { header: "B", accessorKey: "b", meta: { numeric: true } },
- ];
- render( );
-
- const headers = screen.getAllByRole("columnheader");
- expect(headers[1].querySelector("div")).toHaveClass("justify-end");
- expect(headers[0].querySelector("div")).not.toHaveClass("justify-end");
-
- const cells = screen.getAllByRole("cell");
- expect(cells[1]).toHaveClass("text-right", "tabular-nums");
- expect(cells[0]).not.toHaveClass("text-right");
- });
-});
-
-describe("DataTable row interaction", () => {
- it("fires onRowClick with the row's original data", async () => {
- const user = userEvent.setup();
- const onRowClick = vi.fn();
- render( );
-
- await user.click(screen.getByText("alpha"));
-
- expect(onRowClick).toHaveBeenCalledExactlyOnceWith(data[0]);
- });
-});
-
-describe("DataTable expansion", () => {
- const rows: Row[] = [
- { request_id: "r1", a: "alpha", b: "beta" },
- { request_id: "r2", a: "gamma", b: "delta" },
- ];
-
- it("toggles the sub-component in a full-width cell (colspan path)", async () => {
- const user = userEvent.setup();
- render(
- true}
- renderSubComponent={({ row }) => details for {row.original.request_id}
}
- />,
- );
-
- expect(screen.queryByText("details for r1")).not.toBeInTheDocument();
-
- await user.click(screen.getByRole("button", { name: "expand r1" }));
- const details = screen.getByText("details for r1");
- expect(details).toBeInTheDocument();
- expect(screen.queryByText("details for r2")).not.toBeInTheDocument();
-
- const detailCell = details.closest("td");
- expect(detailCell).toHaveAttribute("colspan", "3");
-
- await user.click(screen.getByRole("button", { name: "collapse r1" }));
- expect(screen.queryByText("details for r1")).not.toBeInTheDocument();
- });
-
- it("keeps expansion attached to the same row through data reorders when getRowId is injected", async () => {
- const user = userEvent.setup();
- const { rerender } = render(
- row.request_id}
- getRowCanExpand={() => true}
- renderSubComponent={({ row }) => details for {row.original.request_id}
}
- />,
- );
-
- await user.click(screen.getByRole("button", { name: "expand r1" }));
- expect(screen.getByText("details for r1")).toBeInTheDocument();
-
- rerender(
- row.request_id}
- getRowCanExpand={() => true}
- renderSubComponent={({ row }) => details for {row.original.request_id}
}
- />,
- );
-
- expect(screen.getByText("details for r1")).toBeInTheDocument();
- expect(screen.queryByText("details for r2")).not.toBeInTheDocument();
- });
-
- it("does not expand rows when getRowCanExpand is missing even if a renderer is provided", () => {
- render(
- details for {row.original.request_id}
}
- />,
- );
-
- expect(screen.queryByRole("button", { name: "expand r1" })).not.toBeInTheDocument();
- });
-});
-
-describe("DataTable sorting", () => {
- const rows: Row[] = [
- { request_id: "r1", a: "bravo", b: "2" },
- { request_id: "r2", a: "alpha", b: "1" },
- { request_id: "r3", a: "charlie", b: "3" },
- ];
-
- const firstColumnValues = () =>
- screen
- .getAllByRole("row")
- .slice(1)
- .map((row) => within(row).getAllByRole("cell")[0].textContent);
-
- it("leaves row order untouched when sorting is disabled", async () => {
- const user = userEvent.setup();
- render( );
-
- await user.click(screen.getByText("A"));
-
- expect(firstColumnValues()).toEqual(["bravo", "alpha", "charlie"]);
- });
-
- it("sorts ascending then descending on header clicks when enabled", async () => {
- const user = userEvent.setup();
- render( );
-
- await user.click(screen.getByText("A"));
- expect(firstColumnValues()).toEqual(["alpha", "bravo", "charlie"]);
-
- await user.click(screen.getByText("A"));
- expect(firstColumnValues()).toEqual(["charlie", "bravo", "alpha"]);
- });
-});
diff --git a/ui/litellm-dashboard/src/components/view_logs/table.tsx b/ui/litellm-dashboard/src/components/view_logs/table.tsx
deleted file mode 100644
index d522478e370..00000000000
--- a/ui/litellm-dashboard/src/components/view_logs/table.tsx
+++ /dev/null
@@ -1,159 +0,0 @@
-import { Fragment, useState } from "react";
-import {
- ColumnDef,
- RowData,
- flexRender,
- getCoreRowModel,
- getExpandedRowModel,
- Row,
- useReactTable,
- getSortedRowModel,
- SortingState,
-} from "@tanstack/react-table";
-
-import { Table, TableHeader, TableHead, TableBody, TableRow, TableCell } from "@/components/ui/table";
-
-declare module "@tanstack/react-table" {
- // eslint-disable-next-line @typescript-eslint/no-unused-vars -- declaration merging requires the type parameters to match the upstream ColumnMeta signature exactly (TS2428)
- interface ColumnMeta {
- numeric?: boolean;
- }
-}
-
-interface DataTableProps {
- data: TData[];
- columns: ColumnDef[];
- getRowId?: (row: TData, index: number) => string;
- onRowClick?: (row: TData) => void;
- /** Renders inside a single colspan cell */
- renderSubComponent?: (props: { row: Row }) => React.ReactElement;
- getRowCanExpand?: (row: Row) => boolean;
- isLoading?: boolean;
- loadingMessage?: string;
- noDataMessage?: string;
- /** Enable client-side column sorting (defaults to false to avoid conflicts with server-side sorting) */
- enableSorting?: boolean;
-}
-
-export function DataTable({
- data = [],
- columns,
- getRowId,
- onRowClick,
- renderSubComponent,
- getRowCanExpand,
- isLoading = false,
- loadingMessage = "Loading...",
- noDataMessage = "No results",
- enableSorting = false,
-}: DataTableProps) {
- const supportsExpansion = !!renderSubComponent && !!getRowCanExpand;
- const hasExplicitColumnSizes = columns.some((column) => column.size !== undefined);
- const [sorting, setSorting] = useState([]);
-
- const table = useReactTable({
- data,
- columns,
- ...(enableSorting && {
- state: {
- sorting,
- },
- onSortingChange: setSorting,
- enableSortingRemoval: false,
- }),
- ...(supportsExpansion && { getRowCanExpand }),
- ...(getRowId && { getRowId }),
- getCoreRowModel: getCoreRowModel(),
- ...(enableSorting && { getSortedRowModel: getSortedRowModel() }),
- ...(supportsExpansion && { getExpandedRowModel: getExpandedRowModel() }),
- });
-
- const tableClassName = hasExplicitColumnSizes ? "table-fixed" : "table-fixed w-full box-border";
- const tableStyle = hasExplicitColumnSizes ? { minWidth: table.getCenterTotalSize() } : { minWidth: "400px" };
-
- return (
-
-
-
- {table.getHeaderGroups().map((headerGroup) => (
-
- {headerGroup.headers.map((header) => {
- const canSort = enableSorting && header.column.getCanSort();
- const isSorted = header.column.getIsSorted();
- const numeric = header.column.columnDef.meta?.numeric;
-
- return (
-
- {header.isPlaceholder ? null : (
-
- {flexRender(header.column.columnDef.header, header.getContext())}
- {canSort && (
-
- {isSorted === "asc" ? "↑" : isSorted === "desc" ? "↓" : "⇅"}
-
- )}
-
- )}
-
- );
- })}
-
- ))}
-
-
- {isLoading ? (
-
-
-
-
-
- ) : table.getRowModel().rows.length > 0 ? (
- table.getRowModel().rows.map((row) => (
-
- onRowClick?.(row.original)}
- >
- {row.getVisibleCells().map((cell) => (
-
- {flexRender(cell.column.columnDef.cell, cell.getContext())}
-
- ))}
-
-
- {supportsExpansion && row.getIsExpanded() && renderSubComponent && (
-
-
- {renderSubComponent({ row })}
-
-
- )}
-
- ))
- ) : (
-
-
- {noDataMessage}
-
-
- )}
-
-
-
- );
-}