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
78 lines
2.4 KiB
TypeScript
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>
|
|
);
|
|
}
|