milestone 20: declarative configuration for iac

This commit is contained in:
2026-08-11 23:31:40 +02:00
parent 2f29121e27
commit d76afc147a
74 changed files with 6722 additions and 1949 deletions
+31 -6
View File
@@ -17,16 +17,19 @@ import {
rowButtonClass,
tableWrapClass,
} from "@/ui/classes";
import { READ_ONLY_HINT, useReadOnlyConfig } from "@/features/settings/authority";
function ZoneForm({
initial,
busy,
readOnly,
error,
onSubmit,
onCancel,
}: {
initial?: ForwardZone;
busy: boolean;
readOnly: boolean;
error: unknown;
onSubmit: (input: ForwardZoneInput) => void;
onCancel: () => void;
@@ -70,7 +73,12 @@ function ZoneForm({
/>
</div>
<div className="flex gap-2">
<button type="submit" disabled={busy} className={largePrimaryButtonClass}>
<button
type="submit"
disabled={busy || readOnly}
title={readOnly ? READ_ONLY_HINT : undefined}
className={largePrimaryButtonClass}
>
{busy ? "Saving…" : "Save"}
</button>
<button type="button" onClick={onCancel} className={largeButtonClass}>
@@ -93,6 +101,7 @@ export default function ZonesTab() {
remove: forwardZoneDeleteMutation,
confirmDelete: (zone) => `Delete forward zone "${zone.zone}"?`,
});
const readOnly = useReadOnlyConfig();
return (
<div>
@@ -100,13 +109,25 @@ export default function ZonesTab() {
<p className="text-sm text-zinc-500">
Names under these zones go to their own resolver. Changes apply live.
</p>
<button type="button" onClick={() => openForm({ mode: "create" })} className={largePrimaryButtonClass}>
<button
type="button"
onClick={() => openForm({ mode: "create" })}
disabled={readOnly}
title={readOnly ? READ_ONLY_HINT : undefined}
className={largePrimaryButtonClass}
>
Add zone
</button>
</div>
<InlineError error={remove.error} />
{form?.mode === "create" && (
<ZoneForm busy={create.isPending} error={create.error} onSubmit={onSubmit} onCancel={closeForm} />
<ZoneForm
busy={create.isPending}
readOnly={readOnly}
error={create.error}
onSubmit={onSubmit}
onCancel={closeForm}
/>
)}
<div className={tableWrapClass}>
<table className="w-full text-left text-sm">
@@ -138,6 +159,7 @@ export default function ZonesTab() {
<ZoneForm
initial={zone}
busy={update.isPending}
readOnly={readOnly}
error={update.error}
onSubmit={onSubmit}
onCancel={closeForm}
@@ -151,15 +173,18 @@ export default function ZonesTab() {
<button
type="button"
onClick={() => openForm({ mode: "edit", entity: zone })}
className={rowButtonClass}
disabled={readOnly}
title={readOnly ? READ_ONLY_HINT : undefined}
className={`${rowButtonClass} disabled:opacity-50`}
>
Edit
</button>
<button
type="button"
onClick={() => onDelete(zone)}
disabled={remove.isPending}
className={`${rowButtonClass} text-red-600 dark:text-red-400`}
disabled={remove.isPending || readOnly}
title={readOnly ? READ_ONLY_HINT : undefined}
className={`${rowButtonClass} text-red-600 disabled:opacity-50 dark:text-red-400`}
>
Delete
</button>