Improve HashicorpVault form: group fields into sections, add readable labels

This commit is contained in:
Ryan Crabbe 2026-02-28 16:56:42 -08:00
parent 25cf31dac4
commit 936b405ff7

View file

@ -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<string, string> = {
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 (
<Form.Item
key={fieldName}
name={fieldName}
label={FIELD_LABELS[fieldName] ?? fieldName}
>
{SENSITIVE_FIELDS.has(fieldName) ? (
<Input.Password placeholder={fieldSchema?.description} />
) : (
<Input placeholder={fieldSchema?.description} />
)}
</Form.Item>
);
};
return (
<Card title="Hashicorp Vault">
{isLoading ? (
@ -72,25 +132,22 @@ export default function HashicorpVault() {
)}
<Form layout="vertical" initialValues={values} onFinish={handleSave}>
{Object.entries(properties).map(([fieldName, fieldSchema]: [string, any]) => (
<Form.Item
key={fieldName}
name={fieldName}
label={
<Typography.Text strong>
{fieldName}
</Typography.Text>
}
help={fieldSchema?.description}
>
{SENSITIVE_FIELDS.has(fieldName) ? (
<Input.Password placeholder={fieldName} />
) : (
<Input placeholder={fieldName} />
{FIELD_GROUPS.map((group, index) => (
<div key={group.title}>
{index > 0 && <Divider />}
<Typography.Title level={5} style={{ marginBottom: 4 }}>
{group.title}
</Typography.Title>
{group.subtitle && (
<Typography.Paragraph type="secondary" style={{ marginBottom: 16 }}>
{group.subtitle}
</Typography.Paragraph>
)}
</Form.Item>
{group.fields.map(renderField)}
</div>
))}
<Divider />
<Form.Item>
<Button type="primary" htmlType="submit" loading={isUpdating}>
Save