diff --git a/ui/litellm-dashboard/.eslintrc.json b/ui/litellm-dashboard/.eslintrc.json index 6a3ecedccd1..0daae7d30b0 100644 --- a/ui/litellm-dashboard/.eslintrc.json +++ b/ui/litellm-dashboard/.eslintrc.json @@ -28,7 +28,8 @@ "src/components/GuardrailsMonitor/GuardrailDetail.tsx", "src/components/GuardrailsMonitor/LogViewer.tsx", "src/components/GuardrailsMonitor/GuardrailsOverview.tsx", - "src/components/common_components/IconActionButton/TableIconActionButtons/TableIconActionButton.tsx" + "src/components/common_components/IconActionButton/TableIconActionButtons/TableIconActionButton.tsx", + "src/components/GuardrailSettingsView.tsx" ], "rules": { "litellm-ui/no-banned-ui-imports": "off", diff --git a/ui/litellm-dashboard/src/components/GuardrailSettingsView.tsx b/ui/litellm-dashboard/src/components/GuardrailSettingsView.tsx index e322ce29785..dd23a403fc5 100644 --- a/ui/litellm-dashboard/src/components/GuardrailSettingsView.tsx +++ b/ui/litellm-dashboard/src/components/GuardrailSettingsView.tsx @@ -1,6 +1,7 @@ import React from "react"; -import { Tag } from "antd"; -import { GlobalOutlined } from "@ant-design/icons"; +import { Badge } from "@/components/ui/badge"; +import { Globe } from "lucide-react"; +import { cn } from "@/lib/utils"; interface GuardrailSettingsViewProps { globalGuardrailNames: Set; @@ -28,43 +29,56 @@ export function GuardrailSettingsView({ ); const isEmpty = - !killSwitchOn && globalsRunning.length === 0 && nonGlobalOptIns.length === 0; + !killSwitchOn && + globalsRunning.length === 0 && + nonGlobalOptIns.length === 0; const content = isEmpty ? ( - No guardrails configured + No guardrails configured ) : (
- - + + Global {killSwitchOn ? ( - Bypassed for this team + + Bypassed for this team + ) : globalsRunning.length > 0 ? (
{globalsRunning.map((name) => ( - + {name} - + ))}
) : ( - None configured + + None configured + )}
- Team-specific + + Team-specific + {nonGlobalOptIns.length > 0 ? (
{nonGlobalOptIns.map((name) => ( - + {name} - + ))}
) : ( - None configured + + None configured + )}
@@ -72,11 +86,18 @@ export function GuardrailSettingsView({ if (variant === "card") { return ( -
+
- Guardrails Settings - + + Guardrails Settings + + Global and team-specific guardrails applied to this team
@@ -87,8 +108,10 @@ export function GuardrailSettingsView({ } return ( -
- Guardrails Settings +
+ + Guardrails Settings + {content}
); diff --git a/ui/litellm-dashboard/src/components/general_settings.tsx b/ui/litellm-dashboard/src/components/general_settings.tsx index 22c8d38a379..7c7c4f91498 100644 --- a/ui/litellm-dashboard/src/components/general_settings.tsx +++ b/ui/litellm-dashboard/src/components/general_settings.tsx @@ -1,203 +1,220 @@ import React, { useState, useEffect } from "react"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { Card } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { Switch } from "@/components/ui/switch"; import { - Card, Table, - TableHead, - TableRow, - Badge, - TableHeaderCell, - TableCell, TableBody, - Text, - Button, - Icon, - Switch, -} from "@tremor/react"; -import { TabPanel, TabPanels, TabGroup, TabList, Tab } from "@tremor/react"; + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { CheckCircle, Trash2 } from "lucide-react"; import { getGeneralSettingsCall, updateConfigFieldSetting, deleteConfigFieldSetting, } from "./networking"; -import { InputNumber } from "antd"; -import { TrashIcon, CheckCircleIcon } from "@heroicons/react/outline"; - import RouterSettings from "./router_settings"; import Fallbacks from "./Settings/RouterSettings/Fallbacks/Fallbacks"; + interface GeneralSettingsPageProps { accessToken: string | null; userRole: string | null; userID: string | null; + // eslint-disable-next-line @typescript-eslint/no-explicit-any modelData: any; } interface generalSettingsItem { field_name: string; field_type: string; + // eslint-disable-next-line @typescript-eslint/no-explicit-any field_value: any; field_description: string; stored_in_db: boolean | null; } -const GeneralSettings: React.FC = ({ accessToken, userRole, userID, modelData }) => { - const [generalSettings, setGeneralSettings] = useState([]); +const GeneralSettings: React.FC = ({ + accessToken, + userRole, + userID, + modelData, +}) => { + const [generalSettings, setGeneralSettings] = useState< + generalSettingsItem[] + >([]); useEffect(() => { - if (!accessToken) { - return; - } + if (!accessToken) return; getGeneralSettingsCall(accessToken).then((data) => { - let general_settings = data; - setGeneralSettings(general_settings); + setGeneralSettings(data); }); }, [accessToken]); + // eslint-disable-next-line @typescript-eslint/no-explicit-any const handleInputChange = (fieldName: string, newValue: any) => { - // Update the value in the state const updatedSettings = generalSettings.map((setting) => - setting.field_name === fieldName ? { ...setting, field_value: newValue } : setting, + setting.field_name === fieldName + ? { ...setting, field_value: newValue } + : setting, ); setGeneralSettings(updatedSettings); }; const handleUpdateField = (fieldName: string, idx: number) => { - if (!accessToken) { - return; - } - - let fieldValue = generalSettings[idx].field_value; - - if (fieldValue == null || fieldValue == undefined) { - return; - } + if (!accessToken) return; + const fieldValue = generalSettings[idx].field_value; + if (fieldValue == null || fieldValue == undefined) return; try { updateConfigFieldSetting(accessToken, fieldName, fieldValue); - // update value in state - const updatedSettings = generalSettings.map((setting) => - setting.field_name === fieldName ? { ...setting, stored_in_db: true } : setting, + setting.field_name === fieldName + ? { ...setting, stored_in_db: true } + : setting, ); setGeneralSettings(updatedSettings); - } catch (error) { - // do something + } catch { + // ignore } }; - const handleResetField = (fieldName: string, idx: number) => { - if (!accessToken) { - return; - } - + const handleResetField = (fieldName: string) => { + if (!accessToken) return; try { deleteConfigFieldSetting(accessToken, fieldName); - // update value in state - const updatedSettings = generalSettings.map((setting) => - setting.field_name === fieldName ? { ...setting, stored_in_db: null, field_value: null } : setting, + setting.field_name === fieldName + ? { ...setting, stored_in_db: null, field_value: null } + : setting, ); setGeneralSettings(updatedSettings); - } catch (error) { - // do something + } catch { + // ignore } }; - if (!accessToken) { - return null; - } + if (!accessToken) return null; return (
- - - Loadbalancing - Fallbacks - General - - - + + + Loadbalancing + Fallbacks + General + +
+ - - + + - - - + + + - + - Setting - Value - Status - Action + Setting + Value + Status + Action - + {generalSettings .filter((value) => value.field_type !== "TypedDictionary") .map((value, index) => ( - {value.field_name} -

+

{value.field_name}

+

{value.field_description}

- {value.field_type == "Integer" ? ( - handleInputChange(value.field_name, newValue)} + value={value.field_value ?? ""} + onChange={(e) => + handleInputChange( + value.field_name, + e.target.value === "" + ? null + : Number(e.target.value), + ) + } /> - ) : value.field_type == "Boolean" ? ( + ) : value.field_type === "Boolean" ? ( handleInputChange(value.field_name, checked)} + checked={ + value.field_value === true || + value.field_value === "true" + } + onCheckedChange={(checked) => + handleInputChange(value.field_name, checked) + } /> ) : null} - {value.stored_in_db == true ? ( - + {value.stored_in_db === true ? ( + + In DB - ) : value.stored_in_db == false ? ( - In Config + ) : value.stored_in_db === false ? ( + In Config ) : ( - Not Set + Not Set )} - - handleResetField(value.field_name, index)}> - Reset - +
+ + +
))}
- - - +
+
+
); };