Loading section...
;
@@ -89,13 +93,16 @@ function ConfigSectionForm({
const meta = sectionData._meta;
const displayValues = editValues ?? Object.fromEntries(fields);
const isEditing = editValues !== null;
+ const sectionSchema = schema?.[section] ?? {};
const handleEdit = () => {
setEditValues(Object.fromEntries(fields));
+ setShowPassword({});
};
const handleCancel = () => {
setEditValues(null);
+ setShowPassword({});
};
const handleSave = async () => {
@@ -107,6 +114,7 @@ function ConfigSectionForm({
});
addNotification({ type: "success", message: `${section} config updated` });
setEditValues(null);
+ setShowPassword({});
} catch (err) {
logger.error("ConfigEditor", "Failed to update config section %s: %s", section, err);
if (err instanceof Error && "response" in err) {
@@ -127,6 +135,10 @@ function ConfigSectionForm({
setEditValues({ ...editValues, [key]: value });
};
+ const toggleShowPassword = (key: string) => {
+ setShowPassword((prev) => ({ ...prev, [key]: !prev[key] }));
+ };
+
return (
@@ -140,23 +152,33 @@ function ConfigSectionForm({
)}
- {fields.map(([key, value]) => (
-
-
- {isEditing && !SENSITIVE_KEYS.has(key) ? (
- handleChange(key, e.target.value)}
- type={typeof value === "number" ? "number" : "text"}
- />
- ) : (
-
- {SENSITIVE_KEYS.has(key) ? "••••••••" : String(value ?? "--")}
-
- )}
-
- ))}
+ {fields.map(([key]) => {
+ const fieldSchema: FieldSchema | undefined = sectionSchema[key];
+ const widget = fieldSchema?.widget ?? (SENSITIVE_KEYS.has(key) ? "password" : "text");
+ const label = fieldSchema?.label ?? formatLabel(key);
+ const rawValue = displayValues[key];
+
+ return (
+
+
+ {isEditing ? (
+ toggleShowPassword(key)}
+ onChange={(v) => handleChange(key, v)}
+ />
+ ) : (
+
+ {widget === "password" ? "••••••••" : formatDisplayValue(rawValue)}
+
+ )}
+
+ );
+ })}
{isEditing && (
@@ -172,8 +194,117 @@ function ConfigSectionForm({
);
}
+function FieldWidget({
+ fieldKey,
+ widget,
+ fieldSchema,
+ value,
+ showPassword,
+ onTogglePassword,
+ onChange,
+}: {
+ fieldKey: string;
+ widget: string;
+ fieldSchema: FieldSchema | undefined;
+ value: unknown;
+ showPassword: boolean;
+ onTogglePassword: () => void;
+ onChange: (v: unknown) => void;
+}) {
+ switch (widget) {
+ case "textarea":
+ return (
+