diff --git a/ui/litellm-dashboard/e2e_tests/fixtures/migratedPages.ts b/ui/litellm-dashboard/e2e_tests/fixtures/migratedPages.ts index 154badac021..af1991d2cf1 100644 --- a/ui/litellm-dashboard/e2e_tests/fixtures/migratedPages.ts +++ b/ui/litellm-dashboard/e2e_tests/fixtures/migratedPages.ts @@ -11,6 +11,7 @@ * Keep this in lockstep with MIGRATED_PAGES in src/utils/migratedPages.ts. */ export const MIGRATED_E2E_PAGES: Record = { + models: "models-and-endpoints", api_ref: "api-reference", "llm-playground": "playground", projects: "projects", diff --git a/ui/litellm-dashboard/e2e_tests/tests/migration/migratedPages.spec.ts b/ui/litellm-dashboard/e2e_tests/tests/migration/migratedPages.spec.ts index 98f4fee1450..c512ab2ddfb 100644 --- a/ui/litellm-dashboard/e2e_tests/tests/migration/migratedPages.spec.ts +++ b/ui/litellm-dashboard/e2e_tests/tests/migration/migratedPages.spec.ts @@ -17,7 +17,7 @@ const ROOT = process.env.SERVER_ROOT_PATH ?? ""; const esc = (s: string) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); const pathRe = (segment: string) => new RegExp(`${esc(ROOT)}/ui/${esc(segment)}/?($|\\?)`); -const legacyAnchor = (page: Page) => page.locator("a", { hasText: "Virtual Keys" }); +const legacyAnchor = (page: Page) => page.getByRole("link", { name: "Virtual Keys", exact: true }); /** The dashboard shell is present (sidebar rendered); page didn't 404 / crash. */ async function expectRendered(page: Page) { diff --git a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/ModelsAndEndpointsView.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/ModelsAndEndpointsView.test.tsx index 3c5101fc2dc..b4f95efade7 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/ModelsAndEndpointsView.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/ModelsAndEndpointsView.test.tsx @@ -120,14 +120,7 @@ describe("ModelsAndEndpointsView", () => { const queryClient = createQueryClient(); const { findByText } = render( - {}} - premiumUser={false} - teams={[]} - /> + , ); expect(await findByText("Model Management", {}, { timeout: 10000 })).toBeInTheDocument(); @@ -138,14 +131,7 @@ describe("ModelsAndEndpointsView", () => { const queryClient = createQueryClient(); const { findByText } = render( - {}} - premiumUser={false} - teams={[]} - /> + , ); expect(await findByText("Missing a provider?", {}, { timeout: 10000 })).toBeInTheDocument(); @@ -156,14 +142,7 @@ describe("ModelsAndEndpointsView", () => { const queryClient = createQueryClient(); const { findByText, queryByText, container } = render( - {}} - premiumUser={false} - teams={[]} - /> + , ); @@ -188,14 +167,7 @@ describe("ModelsAndEndpointsView", () => { const queryClient = createQueryClient(); const { findByText, queryByText } = render( - {}} - premiumUser={false} - teams={[]} - /> + , ); @@ -228,14 +200,7 @@ describe("ModelsAndEndpointsView", () => { const queryClient = createQueryClient(); const { getByRole } = render( - {}} - premiumUser={false} - teams={[]} - /> + , ); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/ModelsAndEndpointsView.tsx b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/ModelsAndEndpointsView.tsx index 88f4382d7dd..2f8f7350db9 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/ModelsAndEndpointsView.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/ModelsAndEndpointsView.tsx @@ -30,10 +30,6 @@ import TeamInfoView from "../../../components/team/TeamInfo"; import useAuthorized from "../hooks/useAuthorized"; interface ModelDashboardProps { - token: string | null; - modelData: any; - keys: any[] | null; - setModelData: any; premiumUser: boolean; teams: Team[] | null; } diff --git a/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/page.tsx b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/page.tsx new file mode 100644 index 00000000000..7594ee2f492 --- /dev/null +++ b/ui/litellm-dashboard/src/app/(dashboard)/models-and-endpoints/page.tsx @@ -0,0 +1,11 @@ +"use client"; + +import ModelsAndEndpointsView from "@/app/(dashboard)/models-and-endpoints/ModelsAndEndpointsView"; +import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized"; +import { useTeams } from "@/app/(dashboard)/hooks/teams/useTeams"; + +export default function ModelsAndEndpointsPage() { + const { premiumUser } = useAuthorized(); + const { data: teams } = useTeams(); + return ; +} diff --git a/ui/litellm-dashboard/src/app/(dashboard)/page.tsx b/ui/litellm-dashboard/src/app/(dashboard)/page.tsx index c99b6eb9b40..fe842be3ba6 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/page.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/page.tsx @@ -1,6 +1,5 @@ "use client"; -import ModelsAndEndpointsView from "@/app/(dashboard)/models-and-endpoints/ModelsAndEndpointsView"; import { teamListCall as v2TeamListCall } from "@/app/(dashboard)/hooks/teams/useTeams"; import { useUISettings } from "@/app/(dashboard)/hooks/uiSettings/useUISettings"; import LoadingScreen from "@/components/common_components/LoadingScreen"; @@ -34,7 +33,7 @@ function CreateKeyPageContent() { const router = useRouter(); const searchParams = useSearchParams()!; - const [modelData, setModelData] = useState({ data: [] }); + const [modelData] = useState({ data: [] }); const [createClicked, setCreateClicked] = useState(false); const { data: uiSettingsData, isLoading: uiSettingsLoading } = useUISettings(); @@ -308,15 +307,6 @@ function CreateKeyPageContent() { autoOpenCreate={autoOpenCreate} prefillData={prefillData} /> - ) : page == "models" ? ( - ) : page == "pass-through-settings" ? ( { expect(MIGRATED_PAGES["llm-playground"]).toBe("playground"); }); + it("maps the models sidebar id to the models-and-endpoints route and builds its redirect href", async () => { + vi.doMock("@/components/networking", () => ({ serverRootPath: "/" })); + const { MIGRATED_PAGES, migratedHref } = await import("./migratedPages"); + + expect(MIGRATED_PAGES.models).toBe("models-and-endpoints"); + expect(migratedHref(MIGRATED_PAGES.models)).toBe("/ui/models-and-endpoints"); + }); + it("maps the projects and access-groups sidebar ids to their routes", async () => { vi.doMock("@/components/networking", () => ({ serverRootPath: "/" })); const { MIGRATED_PAGES } = await import("./migratedPages"); diff --git a/ui/litellm-dashboard/src/utils/migratedPages.ts b/ui/litellm-dashboard/src/utils/migratedPages.ts index 9c08aa1960b..f4b324cfe91 100644 --- a/ui/litellm-dashboard/src/utils/migratedPages.ts +++ b/ui/litellm-dashboard/src/utils/migratedPages.ts @@ -9,6 +9,7 @@ import { serverRootPath } from "@/components/networking"; * legacy `?page=` URL; remove it to roll back. */ export const MIGRATED_PAGES: Record = { + models: "models-and-endpoints", api_ref: "api-reference", // Legacy alias: older bookmarks used the hyphenated ?page=api-reference form. "api-reference": "api-reference",