diff --git a/ui/litellm-dashboard/src/app/globals.css b/ui/litellm-dashboard/src/app/globals.css
index 0d453e284ef..02254cb9ed7 100644
--- a/ui/litellm-dashboard/src/app/globals.css
+++ b/ui/litellm-dashboard/src/app/globals.css
@@ -37,3 +37,8 @@ body {
.custom-border {
border: 1px solid var(--neutral-border);
}
+
+.model-select-multi .ant-select-selector {
+ max-height: 132px;
+ overflow-y: auto;
+}
diff --git a/ui/litellm-dashboard/src/components/ModelSelect/ModelSelect.test.tsx b/ui/litellm-dashboard/src/components/ModelSelect/ModelSelect.test.tsx
index e253bc4c0ef..5bab521d930 100644
--- a/ui/litellm-dashboard/src/components/ModelSelect/ModelSelect.test.tsx
+++ b/ui/litellm-dashboard/src/components/ModelSelect/ModelSelect.test.tsx
@@ -33,21 +33,20 @@ vi.mock("antd", async (importOriginal) => {
"data-testid": dataTestId,
allowClear,
maxTagCount,
- maxTagPlaceholder,
mode,
+ className,
...props
}: any) => {
- // Simulate maxTagCount responsive behavior - if value length > 5, call maxTagPlaceholder
- const shouldShowPlaceholder = maxTagCount === "responsive" && Array.isArray(value) && value.length > 5;
- const visibleValues = shouldShowPlaceholder ? value.slice(0, 5) : value;
- const omittedValues = shouldShowPlaceholder ? value.slice(5).map((v: string) => ({ value: v, label: v })) : [];
-
return (
-
+
- {shouldShowPlaceholder && maxTagPlaceholder && (
-
{maxTagPlaceholder(omittedValues)}
- )}
);
},
Skeleton: {
Input: ({ active, block }: any) =>
,
},
- Tooltip: ({ children }: { children: React.ReactNode }) => <>{children}>,
};
});
@@ -546,36 +541,13 @@ describe("ModelSelect", () => {
});
});
- it("should render maxTagPlaceholder when many items are selected", async () => {
- // Create many models to trigger maxTagCount responsive behavior
- const manyModels: ProxyModel[] = Array.from({ length: 20 }, (_, i) => ({
- id: `model-${i}`,
- object: "model",
- created: 1234567890,
- owned_by: "test",
- }));
-
- mockUseAllProxyModels.mockReturnValue({
- data: { data: manyModels },
- isLoading: false,
- } as any);
-
- const selectedValues = manyModels.slice(0, 10).map((m) => m.id);
-
+ it("wraps selected tags instead of collapsing them onto a single responsive row", async () => {
renderWithProviders(
-
,
+
,
);
- await waitFor(() => {
- expect(screen.getByTestId("model-select")).toBeInTheDocument();
- // Verify maxTagPlaceholder is rendered with omitted values
- expect(screen.getByTestId("max-tag-placeholder")).toBeInTheDocument();
- expect(screen.getByText(/\+5 more/)).toBeInTheDocument();
- });
+ const select = await screen.findByTestId("model-select");
+ expect(select).toHaveAttribute("data-classname", "model-select-multi");
+ expect(select.getAttribute("data-max-tag-count")).toBe("");
});
});
diff --git a/ui/litellm-dashboard/src/components/ModelSelect/ModelSelect.tsx b/ui/litellm-dashboard/src/components/ModelSelect/ModelSelect.tsx
index 898374d2a61..55e76bed977 100644
--- a/ui/litellm-dashboard/src/components/ModelSelect/ModelSelect.tsx
+++ b/ui/litellm-dashboard/src/components/ModelSelect/ModelSelect.tsx
@@ -2,7 +2,7 @@ import { ProxyModel, useAllProxyModels } from "@/app/(dashboard)/hooks/models/us
import { useOrganization } from "@/app/(dashboard)/hooks/organizations/useOrganizations";
import { useTeam } from "@/app/(dashboard)/hooks/teams/useTeams";
import { useCurrentUser } from "@/app/(dashboard)/hooks/users/useCurrentUser";
-import { Select, Skeleton, Tooltip, type SelectProps } from "antd";
+import { Select, Skeleton, type SelectProps } from "antd";
import { Organization, Team } from "../networking";
import { splitWildcardModels } from "./modelUtils";
@@ -208,15 +208,7 @@ export const ModelSelect = (props: ModelSelectProps) => {
mode="multiple"
placeholder="Select Models"
allowClear
- maxTagCount="responsive"
- maxTagPlaceholder={(omittedValues) => (
-
value).join(", ")}
- >
- +{omittedValues.length} more
-
- )}
+ className="model-select-multi"
/>
);
};