refactor(ui): give each Logs tab its own route - #34430
Conversation
Greptile SummaryRefactors Logs into route-backed tabs
Confidence Score: 4/5This PR is not safe to merge until Logs routes work when the server root path collides with the Logs route segment The attempted routing fix still parses the first ui/litellm-dashboard/src/app/(dashboard)/logs/tabRoutes.ts and ui/litellm-dashboard/src/utils/tabRoutes.ts
|
| Filename | Overview |
|---|---|
| ui/litellm-dashboard/src/app/(dashboard)/logs/tabRoutes.ts | Delegates Logs routing to a shared parser that retains the previously reported SERVER_ROOT_PATH collision |
| ui/litellm-dashboard/src/app/(dashboard)/logs/layout.tsx | Adds the credential-gated shared layout and pathname-driven tab navigation |
| ui/litellm-dashboard/src/app/(dashboard)/components/TabRouteBar.tsx | Adds reusable anchor-based tabs with client-side navigation and modifier-click support |
| ui/litellm-dashboard/src/utils/migratedPages.ts | Resolves nested migrated routes to their sidebar key using the first relative path segment |
Reviews (2): Last reviewed commit: "refactor(ui): adopt shared tab-routing h..." | Re-trigger Greptile
Split the Logs page's four tabs (Request Logs, Audit Logs, Deleted Keys, Deleted Teams) into their own prerendered paths under /logs, mirroring the earlier per-tab routing migrations. A shared layout gates on credentials (the existing loading-spinner contract), renders the tab bar and derives the active tab from the pathname; each tab is its own page.tsx, so deep links and hard-loads to /logs/audit, /logs/deleted-keys and /logs/deleted-teams resolve to real static HTML with no nginx change. The former SpendLogsTable god-component (a Tremor TabGroup wrapping the four panels) is gone; its tab bar is rebuilt on the shadcn Tabs primitive. Because each tab now mounts only when its route is active, the Request Logs and Audit Logs panels receive isActive directly instead of a shared activeTab flag, which also drops the quirk where selecting Deleted Keys/Teams marked the audit-logs panel active.
legacyKeyForPathname matched the full relative path against a single route segment, so a nested tab route like /logs/audit resolved to no key and the shell fell back to the default page, leaving the Logs nav item unhighlighted. Match on the first path segment instead, which fixes every migrated page with nested tab routes.
…n Logs Replace the page's hand-written tabRoutes.ts and layout routing engine with createTabRoutes + useTabRouting + the shared <TabRouteBar>, keeping the credentials loading-spinner guard inline. The per-page tabRoutes.test.ts is dropped in favor of the central factory test.
4676196 to
9200361
Compare
|
Rebased onto staging now that the shared tab-routing helpers (#34435) are merged. This branch now uses |
|
@greptileai re review |
QA (Devin) — before/after after the shared tab-routing helper refactorRe-QA'd the Logs per-tab routing locally ( AFTER results (this PR): each tab has its own URL — clicking a tab and deep-linking / hard-refreshing both land on the exact nested tab (e.g.
Two things to flag (shared across all 4 routing PRs):
Full report + recording: https://app.devin.ai/sessions/f98c3131bcf746c88756b609bae3e724 |
|
Good catch on the server-root collision. The parser lives in the shared |
TLDR
Problem this solves:
How it solves it:
Relevant issues
Linear ticket
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
@greptileaito re-request a review after pushing changes)Delays in PR merge?
If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).
Screenshots / Proof of Fix
UI-only change; steps to verify against a live proxy.
out/logs/index.html,out/logs/audit/index.html,out/logs/deleted-keys/index.html,out/logs/deleted-teams/index.htmlScreenshots of each tab and of a hard-refresh deep link to be attached.
Type
🧹 Refactoring
Changes
Logs moves from a single Tremor TabGroup wrapper to path-based routing, the same pattern used for Models + Endpoints (#34327), Caching (#34415), Cost Optimization (#34424) and Router Settings (#34428).
tabRoutes.tsis the source of truth: the tab slugs pluslogsTabHrefandslugFromPathname, which map a slug to a trailing-slash URL and read the active slug back off the pathname.layout.tsxkeeps the page's existing loading contract (a spinner until access token, session token, role and user id are all present), renders the tab bar, derives the active tab fromusePathname()so no tab state is stored, and pushes to a tab's path on click; an unknown slug redirects to the base route. Each tab is its ownpage.tsx(Request Logs at the index, thenaudit,deleted-keys,deleted-teams). Build-time-known tab paths prerender to static HTML, so deep links and hard-loads work with no nginx change; there is no runtime-unknown id here, so nothing needs query params.The former
SpendLogsTablegod-component is deleted and its tab bar rebuilt on the shadcnTabsprimitive. Previously it tracked anactiveTabstring and passed anisActiveflag into the Request Logs and Audit Logs panels so background tabs would not query. With routing, only the active tab's panel is mounted, so each panel receivesisActivedirectly; this also drops a pre-existing quirk where selecting Deleted Keys or Deleted Teams setisActivetrue on the audit-logs panel. The four panel components are unchanged and stay where they are.A second commit fixes a shared shell helper that every nested tab route depends on:
legacyKeyForPathnamematched the full relative path against a single route segment, so a path like/logs/auditresolved to no key and the shell fell back to the default page, leaving the sidebar item unhighlighted. It now matches on the first path segment, which fixes highlighting for every migrated page with nested routes. This is the same one-line shell fix that is also in #34415, #34424 and #34428; the edits are byte-identical, so they merge cleanly whichever lands first.Tests:
tabRoutes.test.tslocks the slug/href mapping,layout.test.tsxcovers rendering the four tabs, the active base tab, routing on click, the unknown-slug redirect and the credentials-not-ready spinner (the guard regression migrated from the deleted god-component's test), andmigratedPages.test.tsgains a regression for nested-route sidebar resolution.Final Attestation