milestone 32: task-shaped configuration, file mode as a rendering, config status api
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
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
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user