From 087d82ffca88b2cd0f9f39a5b68120feaf3305dc Mon Sep 17 00:00:00 2001
From: ryan-crabbe-berri
Date: Tue, 18 Aug 2026 16:19:23 -0700
Subject: [PATCH] refactor(ui): move the model info view and pass-through
endpoint forms off tremor (#37308)
* refactor(ui): move the model info view and pass-through endpoint forms off tremor
The pass-through settings form's Save button relied on tremor's implicit
submit, so it now carries an explicit type="submit" because the Base UI
button defaults to type="button". The include-subpath switch inside the
antd Form.Item is wired through onCheckedChange plus form.setFieldsValue,
since the Base UI switch does not read the onChange antd injects. Both
tab strips keep every panel mounted so the edit forms survive a tab
switch, pinned by a new mount-contract test on the model info view. Also
prunes the six tremor no-restricted-imports suppressions these files no
longer need.
* test(ui): pin the model info overview panel to its own dom node across tab switches
* fix(ui): keep the line tab strip on the model info and pass-through views
Both tab strips were bare tremor TabLists, which defaulted to the line
variant, so the straight rename turned them into filled segmented pills.
They now use the same full-width line strip the agent, guardrail and
prompt info views ship.
---
ui/litellm-dashboard/CLAUDE.md | 2 +
ui/litellm-dashboard/eslint-suppressions.json | 17 +-
.../src/components/add_pass_through.tsx | 44 ++--
.../PassThroughGuardrailsSection.tsx | 12 +-
.../PassThroughSecuritySection.tsx | 14 +-
.../check_openapi_schema.tsx | 10 +-
.../src/components/model_info_view.test.tsx | 22 ++
.../src/components/model_info_view.tsx | 217 +++++++++---------
.../src/components/pass_through_info.tsx | 131 +++++------
ui/litellm-dashboard/tests/setupTests.ts | 9 +
10 files changed, 253 insertions(+), 225 deletions(-)
diff --git a/ui/litellm-dashboard/CLAUDE.md b/ui/litellm-dashboard/CLAUDE.md
index 9640784c21d..197e6d17fc6 100644
--- a/ui/litellm-dashboard/CLAUDE.md
+++ b/ui/litellm-dashboard/CLAUDE.md
@@ -19,3 +19,5 @@ Do not trust `eslint --fix` for these two plugins. Fixing the suite in bulk prod
A test may reach for a component library's own CSS class only when that library exposes no role, label, title or ARIA state to query instead, and then the line carries a suppression naming the rule and the reason. Check first: antd icons render as `role="img"` with an `aria-label`, and antd `Form.Item` associates its label with the control, so both are reachable accessibly. When a label does not resolve, suspect the control rather than the test, since a custom wrapper that destructures props without spreading them drops the `id` antd injects and leaves the rendered label pointing at nothing
Rules beyond the enabled set were measured against the whole suite and left off rather than recorded in a budget file, because a ceiling that permits a violation anywhere is worse than an honest gap. `no-node-access` and `no-container` are the ones worth revisiting first, since they catch the DOM archaeology the rules above only discourage. `prefer-implicit-assert` and `prefer-explicit-assert` contradict each other, so neither is enabled
+
+Never run the full unit suite (`npx vitest run` with no path). It is 380 files and thousands of tests, it saturates the machine for many minutes, and CI runs it anyway. Run only the test files your change touches, plus any file whose failure your change could plausibly explain, by passing explicit paths
diff --git a/ui/litellm-dashboard/eslint-suppressions.json b/ui/litellm-dashboard/eslint-suppressions.json
index 4e9dcb810d0..be7da7c2b42 100644
--- a/ui/litellm-dashboard/eslint-suppressions.json
+++ b/ui/litellm-dashboard/eslint-suppressions.json
@@ -1981,7 +1981,7 @@
"count": 1
},
"no-restricted-imports": {
- "count": 3
+ "count": 1
}
},
"src/components/agent_management/AgentSelector.test.tsx": {
@@ -2128,17 +2128,9 @@
},
"src/components/common_components/PassThroughGuardrailsSection.tsx": {
"no-restricted-imports": {
- "count": 2
- },
- "react-hooks/set-state-in-effect": {
"count": 1
}
},
- "src/components/common_components/PassThroughSecuritySection.tsx": {
- "no-restricted-imports": {
- "count": 2
- }
- },
"src/components/common_components/RateLimitTypeFormItem.test.tsx": {
"no-restricted-imports": {
"count": 1
@@ -2167,7 +2159,7 @@
"count": 1
},
"no-restricted-imports": {
- "count": 3
+ "count": 2
}
},
"src/components/common_components/fetch_teams.tsx": {
@@ -2395,7 +2387,7 @@
"count": 14
},
"no-restricted-imports": {
- "count": 2
+ "count": 1
},
"prefer-const": {
"count": 5
@@ -2493,9 +2485,6 @@
"src/components/pass_through_info.tsx": {
"local/filename-pascal-case": {
"count": 1
- },
- "no-restricted-imports": {
- "count": 2
}
},
"src/components/per_user_usage.tsx": {
diff --git a/ui/litellm-dashboard/src/components/add_pass_through.tsx b/ui/litellm-dashboard/src/components/add_pass_through.tsx
index 6d6fe4b0dc7..9f95e7f27ac 100644
--- a/ui/litellm-dashboard/src/components/add_pass_through.tsx
+++ b/ui/litellm-dashboard/src/components/add_pass_through.tsx
@@ -1,7 +1,6 @@
"use client";
import React, { useState } from "react";
-import { Card, Title, Subtitle } from "@tremor/react";
import { Modal, Alert } from "antd";
import { CircleHelp, Plug } from "lucide-react";
import { useWatch } from "react-hook-form";
@@ -18,6 +17,8 @@ import PassThroughSecuritySection from "./common_components/PassThroughSecurityS
import PassThroughGuardrailsSection from "./common_components/PassThroughGuardrailsSection";
import { FormField } from "@/components/shared/form/FormField";
import { Button } from "@/components/ui/button";
+import { Card } from "@/components/ui/card";
+import { UiLoadingSpinner } from "@/components/ui/ui-loading-spinner";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
@@ -164,11 +165,11 @@ const AddPassThroughEndpoint: React.FC = ({
/>
= ({
-
- Headers
-
+
+
Headers
+
Add headers that will be sent with every request to the target API
-
+
= ({
-
- Default Query Parameters
-
+
+
Default Query Parameters
+
Add query parameters that will be automatically sent with every request to the target API
-
+
= ({
-
- Performance
-
+
+
Performance
+
Configure upstream request timeout for this endpoint
-
+
= ({
-
- Billing
- Optional cost tracking for this endpoint
+
+
Billing
+
Optional cost tracking for this endpoint
= ({
-
diff --git a/ui/litellm-dashboard/src/components/common_components/PassThroughGuardrailsSection.tsx b/ui/litellm-dashboard/src/components/common_components/PassThroughGuardrailsSection.tsx
index 21d013624fc..2c6856cb8b8 100644
--- a/ui/litellm-dashboard/src/components/common_components/PassThroughGuardrailsSection.tsx
+++ b/ui/litellm-dashboard/src/components/common_components/PassThroughGuardrailsSection.tsx
@@ -1,5 +1,4 @@
import React from "react";
-import { Card, Title, Subtitle } from "@tremor/react";
import { Alert } from "antd";
import { CircleHelp } from "lucide-react";
@@ -7,6 +6,7 @@ import GuardrailSelector from "../guardrails/GuardrailSelector";
import { TagsInput } from "@/app/(dashboard)/guardrails/_components/content_filter/TagsInput";
import { Field, FieldLabel } from "@/components/shared/form/field";
import { Button } from "@/components/ui/button";
+import { Card } from "@/components/ui/card";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
type GuardrailFields = { request_fields?: string[]; response_fields?: string[] };
@@ -60,12 +60,12 @@ const PassThroughGuardrailsSection: React.FC
return (
-
- Guardrails
-
+
+
Guardrails
+
Configure guardrails to enforce policies on requests and responses. Guardrails are opt-in for passthrough
endpoints.
-