147 lines
4.7 KiB
TypeScript
147 lines
4.7 KiB
TypeScript
import { useState } from "react";
|
|
import { useNavigate } from "react-router-dom";
|
|
import {
|
|
Badge,
|
|
Button,
|
|
MessageBar,
|
|
MessageBarBody,
|
|
Text,
|
|
} from "@fluentui/react-components";
|
|
import {
|
|
ArrowClockwiseRegular,
|
|
ArrowSyncRegular,
|
|
PauseRegular,
|
|
PlayRegular,
|
|
StopRegular,
|
|
} from "@fluentui/react-icons";
|
|
import { useCommonSectionStyles } from "../../components/commonStyles";
|
|
import { useJailDetailPageStyles } from "./jailDetailPageStyles";
|
|
import type { Jail } from "../../types/jail";
|
|
|
|
interface JailInfoProps {
|
|
jail: Jail;
|
|
onRefresh: () => void;
|
|
onStart: () => Promise<void>;
|
|
onStop: () => Promise<void>;
|
|
onSetIdle: (on: boolean) => Promise<void>;
|
|
onReload: () => Promise<void>;
|
|
}
|
|
|
|
export function JailInfoSection({ jail, onRefresh, onStart, onStop, onSetIdle, onReload }: JailInfoProps): React.JSX.Element {
|
|
const styles = useJailDetailPageStyles();
|
|
const sectionStyles = useCommonSectionStyles();
|
|
const navigate = useNavigate();
|
|
const [ctrlError, setCtrlError] = useState<string | null>(null);
|
|
|
|
const handle =
|
|
(fn: () => Promise<unknown>, postNavigate = false) =>
|
|
(): void => {
|
|
setCtrlError(null);
|
|
fn()
|
|
.then(() => {
|
|
if (postNavigate) {
|
|
navigate("/jails");
|
|
} else {
|
|
onRefresh();
|
|
}
|
|
})
|
|
.catch((err: unknown) => {
|
|
const msg = err instanceof Error ? err.message : String(err);
|
|
setCtrlError(msg);
|
|
});
|
|
};
|
|
|
|
return (
|
|
<div className={sectionStyles.section}>
|
|
<div className={sectionStyles.sectionHeader}>
|
|
<div className={styles.headerRow}>
|
|
<Text size={600} weight="semibold" style={{ fontFamily: "Consolas, 'Courier New', monospace" }}>
|
|
{jail.name}
|
|
</Text>
|
|
{jail.running ? (
|
|
jail.idle ? (
|
|
<Badge appearance="filled" color="warning">idle</Badge>
|
|
) : (
|
|
<Badge appearance="filled" color="success">running</Badge>
|
|
)
|
|
) : (
|
|
<Badge appearance="filled" color="danger">stopped</Badge>
|
|
)}
|
|
</div>
|
|
<Button
|
|
size="small"
|
|
appearance="subtle"
|
|
icon={<ArrowClockwiseRegular />}
|
|
onClick={onRefresh}
|
|
aria-label="Refresh"
|
|
/>
|
|
</div>
|
|
|
|
{ctrlError && (
|
|
<MessageBar intent="error">
|
|
<MessageBarBody>{ctrlError}</MessageBarBody>
|
|
</MessageBar>
|
|
)}
|
|
|
|
<div className={styles.controlRow}>
|
|
{jail.running ? (
|
|
<Button appearance="secondary" icon={<StopRegular />} onClick={handle(onStop)}>
|
|
Stop
|
|
</Button>
|
|
) : (
|
|
<Button appearance="primary" icon={<PlayRegular />} onClick={handle(onStart)}>
|
|
Start
|
|
</Button>
|
|
)}
|
|
<Button
|
|
appearance="outline"
|
|
icon={<PauseRegular />}
|
|
onClick={handle(() => onSetIdle(!jail.idle))}
|
|
disabled={!jail.running}
|
|
>
|
|
{jail.idle ? "Resume" : "Set Idle"}
|
|
</Button>
|
|
<Button appearance="outline" icon={<ArrowSyncRegular />} onClick={handle(onReload)}>
|
|
Reload
|
|
</Button>
|
|
</div>
|
|
|
|
{jail.status && (
|
|
<div className={styles.grid} style={{ marginTop: "var(--spacingVerticalS)" }}>
|
|
<Text className={styles.label}>Currently banned:</Text>
|
|
<Text>{String(jail.status.currently_banned)}</Text>
|
|
<Text className={styles.label}>Total banned:</Text>
|
|
<Text>{String(jail.status.total_banned)}</Text>
|
|
<Text className={styles.label}>Currently failed:</Text>
|
|
<Text>{String(jail.status.currently_failed)}</Text>
|
|
<Text className={styles.label}>Total failed:</Text>
|
|
<Text>{String(jail.status.total_failed)}</Text>
|
|
</div>
|
|
)}
|
|
|
|
<div className={styles.grid} style={{ marginTop: "var(--spacingVerticalS)" }}>
|
|
<Text className={styles.label}>Backend:</Text>
|
|
<Text className={styles.mono}>{jail.backend}</Text>
|
|
<Text className={styles.label}>Find time:</Text>
|
|
<Text>{String(jail.find_time)}</Text>
|
|
<Text className={styles.label}>Ban time:</Text>
|
|
<Text>{String(jail.ban_time)}</Text>
|
|
<Text className={styles.label}>Max retry:</Text>
|
|
<Text>{String(jail.max_retry)}</Text>
|
|
{jail.date_pattern && (
|
|
<>
|
|
<Text className={styles.label}>Date pattern:</Text>
|
|
<Text className={styles.mono}>{jail.date_pattern}</Text>
|
|
</>
|
|
)}
|
|
{jail.log_encoding && (
|
|
<>
|
|
<Text className={styles.label}>Log encoding:</Text>
|
|
<Text className={styles.mono}>{jail.log_encoding}</Text>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|