Files
nxdns/admin/src/features/configuration/SettingsDefinitions.tsx
T
mokhtar 7e0df5fd94
Gates / frontend (push) Successful in 1m22s
Gates / test (push) Successful in 1m54s
Gates / test-aarch64 (push) Successful in 7m57s
Gates / package (push) Successful in 5m29s
Gates / container (push) Successful in 10s
CI / gates (push) Successful in 32m51s
milestone 32: task-shaped configuration, file mode as a rendering, config status api
2026-08-22 22:42:50 +02:00

68 lines
2.2 KiB
TypeScript

import * as stylex from "@stylexjs/stylex";
import type { Settings } from "@/lib/types";
import DefinitionList, { type Definition } from "@/ui/DefinitionList";
import { colors } from "@/ui/tokens.stylex";
import { SECTIONS, sectionValues, type AnyFieldDef } from "./settingsSections";
import { styles as config } from "./styles";
const styles = stylex.create({
absent: {
color: colors.textMuted,
},
});
/** The field key as a sentence. The exact key travels beside it, so this is free to read well. */
export function humanize(key: string): string {
const spaced = key.replace(/_/g, " ");
return spaced.charAt(0).toUpperCase() + spaced.slice(1);
}
/**
* Values are shown as the file spells them: `true`, not "Yes". The reader's
* next step is editing that file, and a value they cannot type back is a
* translation they have to undo.
*/
function renderValue(value: unknown) {
if (typeof value === "boolean") return String(value);
if (typeof value === "number") return String(value);
if (value === "") return <span {...stylex.props(styles.absent)}>empty</span>;
return String(value);
}
/**
* The settings under file authority: definition lists, one per section, each
* scalar carrying its exact ZON key. No inputs, no Save — the file is the
* form.
*/
export default function SettingsDefinitions({ settings }: { settings: Settings }) {
return (
<>
{SECTIONS.map(({ section, title, fields }) => {
const values = sectionValues(settings, section);
const items: Definition[] = (fields as readonly AnyFieldDef[]).map((def) => ({
label: humanize(def.key),
zonKey: `${section}.${def.key}`,
value: renderValue(values[def.key]),
}));
if (section === "web") {
// Derived from whether a password hash is stored, so it has no key of
// its own (D13). Naming one would send the reader to a line that is
// not in the file.
items.push({
label: "Authentication",
value: settings.web.auth_enabled ? "required" : "not configured",
});
}
return (
<section key={section} {...stylex.props(config.panel)}>
<h2 {...stylex.props(config.panelHeading)}>{title}</h2>
<div {...stylex.props(config.note)}>
<DefinitionList items={items} />
</div>
</section>
);
})}
</>
);
}