diff --git a/ui/litellm-dashboard/src/components/Settings/AdminSettings/HashicorpVault/HashicorpVault.tsx b/ui/litellm-dashboard/src/components/Settings/AdminSettings/HashicorpVault/HashicorpVault.tsx new file mode 100644 index 00000000000..08892928a29 --- /dev/null +++ b/ui/litellm-dashboard/src/components/Settings/AdminSettings/HashicorpVault/HashicorpVault.tsx @@ -0,0 +1,104 @@ +"use client"; + +import { useHashicorpVaultConfig } from "@/app/(dashboard)/hooks/configOverrides/useHashicorpVaultConfig"; +import { useUpdateHashicorpVaultConfig } from "@/app/(dashboard)/hooks/configOverrides/useUpdateHashicorpVaultConfig"; +import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized"; +import NotificationManager from "@/components/molecules/notifications_manager"; +import { Alert, Button, Card, Form, Input, Skeleton, Space, Typography } from "antd"; + +const SENSITIVE_FIELDS = new Set([ + "vault_token", + "approle_role_id", + "approle_secret_id", + "client_key", +]); + +export default function HashicorpVault() { + const { accessToken } = useAuthorized(); + const { data, isLoading, isError, error } = useHashicorpVaultConfig(); + const { + mutate: updateConfig, + isPending: isUpdating, + error: updateError, + } = useUpdateHashicorpVaultConfig(accessToken); + + const schema = data?.field_schema; + const properties = schema?.properties ?? {}; + const values = data?.values ?? {}; + + const handleSave = (formValues: Record) => { + // Only send fields that have a value + const config: Record = {}; + for (const [key, value] of Object.entries(formValues)) { + if (value !== undefined && value !== null && value !== "") { + config[key] = value; + } + } + + updateConfig(config, { + onSuccess: () => { + NotificationManager.success("Hashicorp Vault configuration updated successfully"); + }, + onError: (err) => { + NotificationManager.fromBackend(err); + }, + }); + }; + + return ( + + {isLoading ? ( + + ) : isError ? ( + + ) : ( + + {schema?.description && ( + + {schema.description} + + )} + + {updateError && ( + + )} + +
+ {Object.entries(properties).map(([fieldName, fieldSchema]: [string, any]) => ( + + {fieldName} + + } + help={fieldSchema?.description} + > + {SENSITIVE_FIELDS.has(fieldName) ? ( + + ) : ( + + )} + + ))} + + + + +
+
+ )} +
+ ); +}