Files
nxdns/admin/src/features/configuration/ResolutionPage.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

78 lines
2.4 KiB
TypeScript

import { useQuery } from "@tanstack/react-query";
import { useNavigate, useSearch } from "@tanstack/react-router";
import * as stylex from "@stylexjs/stylex";
import { forwardZonesQuery, localRecordsQuery } from "@/lib/queries";
import Tabs from "@/ui/Tabs";
import AuthorityGate from "./AuthorityGate";
import FileModeNote from "./FileModeNote";
import { RecordsReadOnly, ZonesReadOnly } from "./LocalReadOnly";
import QueryPanel from "./QueryPanel";
import RecordsTab from "./RecordsTab";
import UpstreamsTab from "./UpstreamsTab";
import ZonesTab from "./ZonesTab";
import { styles } from "./styles";
import type { ResolutionTab } from "./search";
function RecordsPanel() {
const records = useQuery(localRecordsQuery());
return (
<AuthorityGate>
{(status) =>
status.authority === "managed_file" ? (
<>
<FileModeNote path={status.path} />
<QueryPanel query={records}>{(rows) => <RecordsReadOnly records={rows} />}</QueryPanel>
</>
) : (
<RecordsTab />
)
}
</AuthorityGate>
);
}
function ZonesPanel() {
const zones = useQuery(forwardZonesQuery());
return (
<AuthorityGate>
{(status) =>
status.authority === "managed_file" ? (
<>
<FileModeNote path={status.path} />
<QueryPanel query={zones}>{(rows) => <ZonesReadOnly zones={rows} />}</QueryPanel>
</>
) : (
<ZonesTab />
)
}
</AuthorityGate>
);
}
/**
* Resolution: where a permitted name gets its answer. Three tabs in the order
* a query meets them — the pool that answers most of them, the records nxdns
* answers itself, and the zones it hands to another resolver.
*/
export default function ResolutionPage() {
const tab = useSearch({ from: "/shell/configuration/resolution" }).tab ?? "upstreams";
const navigate = useNavigate({ from: "/configuration/resolution" });
return (
<section>
<h1 {...stylex.props(styles.heading)}>Resolution</h1>
<p {...stylex.props(styles.intro)}>Where nxdns answers or forwards the names it permits.</p>
<Tabs
label="Resolution"
selectedKey={tab}
onSelectionChange={(key) => void navigate({ search: { tab: key as ResolutionTab } })}
tabs={[
{ id: "upstreams", label: "Upstreams", content: <UpstreamsTab /> },
{ id: "records", label: "Records", content: <RecordsPanel /> },
{ id: "zones", label: "Forward zones", content: <ZonesPanel /> },
]}
/>
</section>
);
}