mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-06 02:48:13 +00:00
* refactor(ui): extract shared tab-routing helpers
Every per-tab-routed page copy-pastes the same URL<->slug logic and the
same active-tab/redirect engine. Extract two reusable pieces:
- createTabRoutes(baseSegment, slugs) in utils/tabRoutes.ts returns
{ baseSegment, slugs, tabHref, slugFromPathname }, the trailing-slash
href builder (via migratedHref) and the pathname->slug reader.
- useTabRouting({ routes, baseTabKey, visibleKeys, ready }) derives the
active tab from the pathname, redirects an unknown/forbidden slug to
base once ready, and returns an onTabChange navigator.
visibleKeys + ready exist so a role-gated page can pass its filtered tab
set and defer the redirect until permissions resolve, rather than
bouncing a user off a still-loading valid tab. Both are pure/unit-tested.
No page consumes them yet.
* refactor(ui): migrate Models + Endpoints onto the shared tab-routing helpers
Replace the page's hand-rolled tabRoutes.ts (base segment + slug tuple +
href builder + slugFromPathname) with createTabRoutes, keeping the
existing named exports as thin re-exports so callers and tests are
unchanged. The layout drops its local activeSlug/isKnownSlug/activeKey
derivation, its redirect useEffect and its router.push onChange in favor
of useTabRouting, passing the role-filtered visibleKeys and a ready flag
(!teamsLoading && !uiSettingsLoading) so the permission-gated redirect
behavior is preserved exactly. The antd tab bar, role-gated tab set, the
refresh button and the ?model=/?team= drill-in overlay are untouched; the
file's pre-existing antd import is now recorded in the suppressions
baseline since editing it makes it a linted-as-changed file.
The existing models-and-endpoints layout.test.tsx and tabRoutes.test.ts
pass unchanged, which is the regression guarantee.
26 lines
812 B
TypeScript
26 lines
812 B
TypeScript
import { migratedHref } from "@/utils/migratedPages";
|
|
|
|
export interface TabRoutes<Slug extends string> {
|
|
baseSegment: string;
|
|
slugs: readonly Slug[];
|
|
tabHref: (slug: string) => string;
|
|
slugFromPathname: (pathname: string) => string;
|
|
}
|
|
|
|
export function createTabRoutes<Slug extends string>(baseSegment: string, slugs: readonly Slug[]): TabRoutes<Slug> {
|
|
const tabHref = (slug: string): string => {
|
|
const base = migratedHref(baseSegment);
|
|
return slug ? `${base}/${slug}/` : `${base}/`;
|
|
};
|
|
|
|
const slugFromPathname = (pathname: string): string => {
|
|
const parts = pathname.split("/").filter(Boolean);
|
|
const idx = parts.indexOf(baseSegment);
|
|
if (idx === -1) {
|
|
return "";
|
|
}
|
|
return parts[idx + 1] ?? "";
|
|
};
|
|
|
|
return { baseSegment, slugs, tabHref, slugFromPathname };
|
|
}
|