diff --git a/ui/litellm-dashboard/src/components/model_add/EditCredentialModal.tsx b/ui/litellm-dashboard/src/components/model_add/EditCredentialModal.tsx index b206ed6c91d..8480ee89b22 100644 --- a/ui/litellm-dashboard/src/components/model_add/EditCredentialModal.tsx +++ b/ui/litellm-dashboard/src/components/model_add/EditCredentialModal.tsx @@ -1,15 +1,28 @@ -import { TextInput } from "@tremor/react"; -import { Select as AntdSelect, Button, Form, Modal, Tooltip, Typography } from "antd"; +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; +import { Input } from "@/components/ui/input"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip"; +import { Select as AntdSelect, Form } from "antd"; import type { UploadProps } from "antd/es/upload"; import { useEffect, useState } from "react"; import ProviderSpecificFields from "../add_model/provider_specific_fields"; import { CredentialItem } from "../networking"; import { Providers, providerLogoMap } from "../provider_info_helpers"; -const { Link } = Typography; interface EditCredentialsModalProps { open: boolean; onCancel: () => void; + // eslint-disable-next-line @typescript-eslint/no-explicit-any onUpdateCredential: (values: any) => void; uploadProps: UploadProps; existingCredential: CredentialItem | null; @@ -23,127 +36,148 @@ export default function EditCredentialsModal({ existingCredential, }: EditCredentialsModalProps) { const [form] = Form.useForm(); - const [selectedProvider, setSelectedProvider] = useState(Providers.Anthropic); + const [selectedProvider, setSelectedProvider] = useState( + Providers.Anthropic, + ); + // eslint-disable-next-line @typescript-eslint/no-explicit-any const handleSubmit = (values: any) => { - const filteredValues = Object.entries(values).reduce((acc, [key, value]) => { - if (value !== "" && value !== undefined && value !== null) { - acc[key] = value; - } - return acc; - }, {} as any); + const filteredValues = Object.entries(values).reduce( + (acc, [key, value]) => { + if (value !== "" && value !== undefined && value !== null) { + acc[key] = value; + } + return acc; + }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + {} as any, + ); onUpdateCredential(filteredValues); form.resetFields(); }; useEffect(() => { if (existingCredential) { - // Spread all credential_values dynamically, converting undefined/null to null for form compatibility - const credentialValues = Object.entries(existingCredential.credential_values || {}).reduce( + const credentialValues = Object.entries( + existingCredential.credential_values || {}, + ).reduce( (acc, [key, value]) => { acc[key] = value ?? null; return acc; }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any {} as Record, ); form.setFieldsValue({ credential_name: existingCredential.credential_name, - custom_llm_provider: existingCredential.credential_info.custom_llm_provider, + custom_llm_provider: + existingCredential.credential_info.custom_llm_provider, ...credentialValues, }); - setSelectedProvider(existingCredential.credential_info.custom_llm_provider as Providers); + setSelectedProvider( + existingCredential.credential_info.custom_llm_provider as Providers, + ); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [existingCredential]); + const handleCancel = () => { + onCancel(); + form.resetFields(); + }; + return ( - { - onCancel(); - form.resetFields(); - }} - footer={null} - width={600} - destroyOnHidden={true} - > -
- {/* Credential Name */} - - - - - {/* Provider Selection */} - - { - setSelectedProvider(value as Providers); - form.setFieldValue("custom_llm_provider", value); - }} + (!o ? handleCancel() : undefined)}> + + + Edit Credential + + + - {Object.entries(Providers).map(([providerEnum, providerDisplayName]) => ( - -
- {`${providerEnum} { - const target = e.target as HTMLImageElement; - const parent = target.parentElement; - if (parent) { - const fallbackDiv = document.createElement("div"); - fallbackDiv.className = - "w-5 h-5 rounded-full bg-gray-200 flex items-center justify-center text-xs"; - fallbackDiv.textContent = providerDisplayName.charAt(0); - parent.replaceChild(fallbackDiv, target); - } - }} - /> - {providerDisplayName} -
-
- ))} -
-
+ + - - - {/* Modal Footer */} -
- - Need Help? - - -
- - + {Object.entries(Providers).map( + ([providerEnum, providerDisplayName]) => ( + +
+ {/* eslint-disable-next-line @next/next/no-img-element */} + {`${providerEnum} { + const target = e.target as HTMLImageElement; + const parent = target.parentElement; + if (parent) { + const fallbackDiv = document.createElement("div"); + fallbackDiv.className = + "w-5 h-5 rounded-full bg-muted flex items-center justify-center text-xs"; + fallbackDiv.textContent = + providerDisplayName.charAt(0); + parent.replaceChild(fallbackDiv, target); + } + }} + /> + {providerDisplayName} +
+
+ ), + )} + + + + + +
+ + + + + Need Help? + + + Get help on our github + + + +
+ + +
-
- - + + + ); }