From 936b405ff7d6ded22291789f2c3a98627675f702 Mon Sep 17 00:00:00 2001 From: Ryan Crabbe Date: Sat, 28 Feb 2026 16:56:42 -0800 Subject: [PATCH] Improve HashicorpVault form: group fields into sections, add readable labels --- .../HashicorpVault/HashicorpVault.tsx | 91 +++++++++++++++---- 1 file changed, 74 insertions(+), 17 deletions(-) diff --git a/ui/litellm-dashboard/src/components/Settings/AdminSettings/HashicorpVault/HashicorpVault.tsx b/ui/litellm-dashboard/src/components/Settings/AdminSettings/HashicorpVault/HashicorpVault.tsx index 08892928a29..c96e16b2d5a 100644 --- a/ui/litellm-dashboard/src/components/Settings/AdminSettings/HashicorpVault/HashicorpVault.tsx +++ b/ui/litellm-dashboard/src/components/Settings/AdminSettings/HashicorpVault/HashicorpVault.tsx @@ -4,7 +4,7 @@ import { useHashicorpVaultConfig } from "@/app/(dashboard)/hooks/configOverrides 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"; +import { Alert, Button, Card, Divider, Form, Input, Skeleton, Space, Typography } from "antd"; const SENSITIVE_FIELDS = new Set([ "vault_token", @@ -13,6 +13,47 @@ const SENSITIVE_FIELDS = new Set([ "client_key", ]); +const FIELD_LABELS: Record = { + vault_addr: "Vault Address", + vault_namespace: "Namespace", + vault_mount_name: "KV Mount Name", + vault_path_prefix: "Path Prefix", + vault_token: "Token", + approle_role_id: "Role ID", + approle_secret_id: "Secret ID", + approle_mount_path: "Mount Path", + client_cert: "Client Certificate", + client_key: "Client Key", +}; + +interface FieldGroup { + title: string; + subtitle?: string; + fields: string[]; +} + +const FIELD_GROUPS: FieldGroup[] = [ + { + title: "Connection", + fields: ["vault_addr", "vault_namespace", "vault_mount_name", "vault_path_prefix"], + }, + { + title: "Token Authentication", + subtitle: "Use a Vault token to authenticate. Only one auth method is required.", + fields: ["vault_token"], + }, + { + title: "AppRole Authentication", + subtitle: "Use AppRole credentials to authenticate. Only one auth method is required.", + fields: ["approle_role_id", "approle_secret_id", "approle_mount_path"], + }, + { + title: "TLS", + subtitle: "Optional client certificate for mTLS.", + fields: ["client_cert", "client_key"], + }, +]; + export default function HashicorpVault() { const { accessToken } = useAuthorized(); const { data, isLoading, isError, error } = useHashicorpVaultConfig(); @@ -45,6 +86,25 @@ export default function HashicorpVault() { }); }; + const renderField = (fieldName: string) => { + const fieldSchema = properties[fieldName]; + if (!fieldSchema) return null; + + return ( + + {SENSITIVE_FIELDS.has(fieldName) ? ( + + ) : ( + + )} + + ); + }; + return ( {isLoading ? ( @@ -72,25 +132,22 @@ export default function HashicorpVault() { )}
- {Object.entries(properties).map(([fieldName, fieldSchema]: [string, any]) => ( - - {fieldName} - - } - help={fieldSchema?.description} - > - {SENSITIVE_FIELDS.has(fieldName) ? ( - - ) : ( - + {FIELD_GROUPS.map((group, index) => ( +
+ {index > 0 && } + + {group.title} + + {group.subtitle && ( + + {group.subtitle} + )} - + {group.fields.map(renderField)} +
))} +