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
39 lines
1.4 KiB
TypeScript
39 lines
1.4 KiB
TypeScript
import { useNavigate, useSearch } from "@tanstack/react-router";
|
|
import * as stylex from "@stylexjs/stylex";
|
|
import Tabs from "@/ui/Tabs";
|
|
import ProtectionGroups from "./ProtectionGroups";
|
|
import ProtectionSources from "./ProtectionSources";
|
|
import { styles } from "./styles";
|
|
import type { ProtectionTab } from "./search";
|
|
|
|
/**
|
|
* Protection: what policy governs each group, and which rules and lists
|
|
* produce it. Group-centred, because a rule or a source only means something
|
|
* once you know whose queries it applies to.
|
|
*/
|
|
export default function ProtectionPage() {
|
|
const search = useSearch({ from: "/shell/configuration/protection" });
|
|
const tab = search.tab ?? "groups";
|
|
const navigate = useNavigate({ from: "/configuration/protection" });
|
|
|
|
return (
|
|
<section>
|
|
<h1 {...stylex.props(styles.heading)}>Protection</h1>
|
|
<p {...stylex.props(styles.intro)}>What each group of clients is allowed to resolve, and why.</p>
|
|
<Tabs
|
|
label="Protection"
|
|
selectedKey={tab}
|
|
// The group rides along, so switching tabs and coming back returns to
|
|
// the group the reader was looking at rather than the first one.
|
|
onSelectionChange={(key) =>
|
|
void navigate({ search: { tab: key as ProtectionTab, group: search.group } })
|
|
}
|
|
tabs={[
|
|
{ id: "groups", label: "Groups", content: <ProtectionGroups /> },
|
|
{ id: "sources", label: "Sources", content: <ProtectionSources /> },
|
|
]}
|
|
/>
|
|
</section>
|
|
);
|
|
}
|