+
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/users/_components/DefaultUserSettings.tsx b/ui/litellm-dashboard/src/app/(dashboard)/users/_components/DefaultUserSettings.tsx
index 7fee2e14b27..edd79fd5d5d 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/users/_components/DefaultUserSettings.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/users/_components/DefaultUserSettings.tsx
@@ -1,7 +1,5 @@
import React, { useState, useEffect } from "react";
-import { Card, Title, Text, Divider, TextInput } from "@tremor/react";
-import { Button, Typography, Spin, Switch, Select, InputNumber } from "antd";
-import { PlusOutlined, DeleteOutlined } from "@ant-design/icons";
+import { Plus, Trash2 } from "lucide-react";
import { getInternalUserSettings, updateInternalUserSettings, modelAvailableCall } from "@/components/networking";
import BudgetDurationDropdown, {
getBudgetDurationLabel,
@@ -9,6 +7,25 @@ import BudgetDurationDropdown, {
import { getModelDisplayName } from "@/components/key_team_helpers/fetch_available_models_team_key";
import { formatNumberWithCommas } from "@/utils/dataUtils";
import NotificationManager from "@/components/molecules/notifications_manager";
+import { Badge } from "@/components/ui/badge";
+import { Button } from "@/components/ui/button";
+import { Card, CardContent } from "@/components/ui/card";
+import {
+ Combobox,
+ ComboboxChip,
+ ComboboxChips,
+ ComboboxChipsInput,
+ ComboboxContent,
+ ComboboxEmpty,
+ ComboboxItem,
+ ComboboxList,
+ ComboboxValue,
+} from "@/components/ui/combobox";
+import { Input } from "@/components/ui/input";
+import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
+import { Separator } from "@/components/ui/separator";
+import { Switch } from "@/components/ui/switch";
+import { UiLoadingSpinner } from "@/components/ui/ui-loading-spinner";
interface DefaultUserSettingsProps {
accessToken: string | null;
@@ -23,6 +40,13 @@ interface TeamEntry {
user_role: "user" | "admin";
}
+const TEAM_MEMBER_ROLES: TeamEntry["user_role"][] = ["user", "admin"];
+
+const TEAM_MEMBER_ROLE_LABELS: Record
= {
+ user: "User",
+ admin: "Admin",
+};
+
const DefaultUserSettings: React.FC = ({
accessToken,
possibleUIRoles,
@@ -35,8 +59,6 @@ const DefaultUserSettings: React.FC = ({
const [editedValues, setEditedValues] = useState({});
const [saving, setSaving] = useState(false);
const [availableModels, setAvailableModels] = useState([]);
- const { Paragraph } = Typography;
- const { Option } = Select;
useEffect(() => {
const fetchSSOSettings = async () => {
@@ -129,16 +151,48 @@ const DefaultUserSettings: React.FC = ({
});
};
+ const renderMultiSelect = (key: string, options: string[], placeholder: string, getLabel: (o: string) => string) => {
+ const selected: string[] = editedValues[key] || [];
+
+ return (
+ handleTextInputChange(key, value)}
+ >
+
+
+ {(values: string[]) =>
+ values.map((option) => (
+
+ {getLabel(option)}
+
+ ))
+ }
+
+
+
+
+ No options found
+
+ {(option: string) => (
+
+ {getLabel(option)}
+
+ )}
+
+
+
+ );
+ };
+
// Teams editor component
const renderTeamsEditor = (teams: any[]) => {
const normalizedTeams = normalizeTeams(teams);
const updateTeam = (index: number, field: keyof TeamEntry, value: any) => {
- const updatedTeams = [...normalizedTeams];
- updatedTeams[index] = {
- ...updatedTeams[index],
- [field]: value,
- };
+ const updatedTeams = normalizedTeams.map((team, i) => (i === index ? { ...team, [field]: value } : team));
handleTextInputChange("teams", updatedTeams);
};
@@ -158,53 +212,69 @@ const DefaultUserSettings: React.FC = ({
return (
{normalizedTeams.map((team, index) => (
-
-
-
Team {index + 1}
-
} onClick={() => removeTeam(index)}>
+
+
+
Team {index + 1}
+
-
+
- Team ID
- Team ID
+ updateTeam(index, "team_id", e.target.value)}
+ onChange={(event) => updateTeam(index, "team_id", event.target.value)}
placeholder="Enter team ID"
/>
-
Max Budget in Team
-
updateTeam(index, "max_budget_in_team", value)}
+ Max Budget in Team
+
+ updateTeam(
+ index,
+ "max_budget_in_team",
+ event.target.value === "" ? undefined : Number(event.target.value),
+ )
+ }
placeholder="Optional"
min={0}
step={0.01}
- precision={2}
/>
-
User Role
+
User Role
))}
-
} onClick={addTeam} className="w-full">
+
@@ -217,23 +287,24 @@ const DefaultUserSettings: React.FC
= ({
if (key === "teams") {
return {renderTeamsEditor(editedValues[key] || [])}
;
} else if (key === "user_role" && possibleUIRoles) {
+ const internalUserRoles = Object.entries(possibleUIRoles).filter(([role]) => role.includes("internal_user"));
+ const selectedRole = editedValues[key] || null;
+
return (
-