From 05c2438ac63648699c7469b1ae3c678e51295ea2 Mon Sep 17 00:00:00 2001 From: yassin Date: Fri, 31 Jul 2026 00:25:34 +0000 Subject: [PATCH] feat(ui): surface routing as a top-level sidebar item Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../src/components/leftnav.test.tsx | 13 +++++++------ ui/litellm-dashboard/src/components/leftnav.tsx | 14 +++++++------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/ui/litellm-dashboard/src/components/leftnav.test.tsx b/ui/litellm-dashboard/src/components/leftnav.test.tsx index dc893643559..3e4ecca5fb7 100644 --- a/ui/litellm-dashboard/src/components/leftnav.test.tsx +++ b/ui/litellm-dashboard/src/components/leftnav.test.tsx @@ -103,6 +103,7 @@ describe("Sidebar (leftnav)", () => { "Virtual Keys", "Playground", "Models + Endpoints", + "Routing", "Agentic", "MCP Servers", "Guardrails", @@ -139,11 +140,11 @@ describe("Sidebar (leftnav)", () => { expect(screen.getByText("Search Tools")).toBeInTheDocument(); }); }); - it("keeps Router Settings as a single Settings child", () => { - // Router Settings is admin-only, so getAvailablePages() filters it out entirely and the + it("keeps Routing as a single top-level AI Gateway item", () => { + // Routing is admin-only, so getAvailablePages() filters it out entirely and the // page_utils duplicate-key guard cannot see it. Walk menuGroups directly, otherwise a - // stray duplicate placement ships silently. - expect(placementsOf("router-settings")).toEqual(["SETTINGS > settings"]); + // stray duplicate placement (e.g. left behind under Settings) ships silently. + expect(placementsOf("router-settings")).toEqual(["AI GATEWAY"]); }); it("has no duplicate keys among all menu items and their children", () => { @@ -290,8 +291,8 @@ describe("getBreadcrumb", () => { expect(getBreadcrumb("search-tools")).toEqual({ section: "AI Gateway", title: "Search Tools" }); }); - it("resolves router-settings under the Settings section", () => { - expect(getBreadcrumb("router-settings")).toEqual({ section: "Settings", title: "Router Settings" }); + it("resolves router-settings as a top-level AI Gateway page", () => { + expect(getBreadcrumb("router-settings")).toEqual({ section: "AI Gateway", title: "Routing" }); }); it("falls back to a prettified title with no section for unknown pages", () => { diff --git a/ui/litellm-dashboard/src/components/leftnav.tsx b/ui/litellm-dashboard/src/components/leftnav.tsx index af76fccf9eb..fa24114a0bc 100644 --- a/ui/litellm-dashboard/src/components/leftnav.tsx +++ b/ui/litellm-dashboard/src/components/leftnav.tsx @@ -132,6 +132,13 @@ const menuGroups: MenuGroup[] = [ icon: , roles: rolesAllowedToViewWriteScopedPages, }, + { + key: "router-settings", + page: "router-settings", + label: "Routing", + icon: , + roles: all_admin_roles, + }, { key: "agentic", page: "agentic", @@ -296,13 +303,6 @@ const menuGroups: MenuGroup[] = [ icon: , roles: all_admin_roles, children: [ - { - key: "router-settings", - page: "router-settings", - label: "Router Settings", - icon: , - roles: all_admin_roles, - }, { key: "logging-and-alerts", page: "logging-and-alerts",