Add ignore-self toggle to Jail Detail page

Implements the missing UI control for POST /api/jails/{name}/ignoreself:
- Add jailIgnoreSelf endpoint constant to endpoints.ts
- Add toggleIgnoreSelf(name, on) API function to jails.ts
- Expose toggleIgnoreSelf action from useJailDetail hook
- Replace read-only 'ignore self' badge with a Fluent Switch in
  IgnoreListSection to allow enabling/disabling the flag per jail
- Add 5 vitest tests for checked/unchecked state and toggle behaviour
This commit is contained in:
2026-03-14 20:24:49 +01:00
parent d3b2022ffb
commit 6bb38dbd8c
6 changed files with 370 additions and 8 deletions

View File

@@ -17,6 +17,7 @@ import {
MessageBar,
MessageBarBody,
Spinner,
Switch,
Text,
Tooltip,
makeStyles,
@@ -443,6 +444,7 @@ interface IgnoreListSectionProps {
ignoreSelf: boolean;
onAdd: (ip: string) => Promise<void>;
onRemove: (ip: string) => Promise<void>;
onToggleIgnoreSelf: (on: boolean) => Promise<void>;
}
function IgnoreListSection({
@@ -451,6 +453,7 @@ function IgnoreListSection({
ignoreSelf,
onAdd,
onRemove,
onToggleIgnoreSelf,
}: IgnoreListSectionProps): React.JSX.Element {
const styles = useStyles();
const [inputVal, setInputVal] = useState("");
@@ -494,17 +497,27 @@ function IgnoreListSection({
<Text as="h2" size={500} weight="semibold">
Ignore List (IP Whitelist)
</Text>
{ignoreSelf && (
<Tooltip content="This jail ignores the server's own IP addresses" relationship="label">
<Badge appearance="tint" color="informative">
ignore self
</Badge>
</Tooltip>
)}
</div>
<Badge appearance="tint">{String(ignoreList.length)}</Badge>
</div>
{/* Ignore-self toggle */}
<Switch
label="Ignore self — exclude this server's own IP addresses from banning"
checked={ignoreSelf}
onChange={(_e, data): void => {
onToggleIgnoreSelf(data.checked).catch((err: unknown) => {
const msg =
err instanceof ApiError
? `${String(err.status)}: ${err.body}`
: err instanceof Error
? err.message
: String(err);
setOpError(msg);
});
}}
/>
{opError && (
<MessageBar intent="error">
<MessageBarBody>{opError}</MessageBarBody>
@@ -579,7 +592,7 @@ function IgnoreListSection({
export function JailDetailPage(): React.JSX.Element {
const styles = useStyles();
const { name = "" } = useParams<{ name: string }>();
const { jail, ignoreList, ignoreSelf, loading, error, refresh, addIp, removeIp } =
const { jail, ignoreList, ignoreSelf, loading, error, refresh, addIp, removeIp, toggleIgnoreSelf } =
useJailDetail(name);
if (loading && !jail) {
@@ -634,6 +647,7 @@ export function JailDetailPage(): React.JSX.Element {
ignoreSelf={ignoreSelf}
onAdd={addIp}
onRemove={removeIp}
onToggleIgnoreSelf={toggleIgnoreSelf}
/>
</div>
);