Global tab provided the same four editable fields as Server tab: log_level, log_target, db_purge_age, db_max_matches. Server tab already has these fields plus additional read-only info (db_path, syslog_socket) and a Flush Logs button. - Add hint text to DB Purge Age and DB Max Matches fields in ServerTab - Remove GlobalTab component import from ConfigPage - Remove 'global' from TabValue type - Remove Global tab element from TabList - Remove conditional render for GlobalTab - Remove GlobalTab from barrel export (index.ts) - Delete GlobalTab.tsx file - Update ConfigPage test to remove Global tab test case All 123 frontend tests pass.
108 lines
3.0 KiB
TypeScript
108 lines
3.0 KiB
TypeScript
/**
|
|
* Configuration page — fail2ban jail and server configuration editor.
|
|
*
|
|
* Renders the top-level tab bar and delegates rendering to the appropriate
|
|
* tab component from {@link ../components/config}.
|
|
*
|
|
* Tabs:
|
|
* Jails — per-jail config accordion with inline editing
|
|
* Filters — structured filter.d form editor
|
|
* Actions — structured action.d form editor
|
|
* Server — server-level settings, logging, database config + flush logs
|
|
* Map — map color threshold configuration
|
|
* Regex Tester — live pattern tester
|
|
* Export — raw file editors for jail, filter, and action files
|
|
*/
|
|
|
|
import { useState } from "react";
|
|
import { Tab, TabList, Text, makeStyles, tokens } from "@fluentui/react-components";
|
|
import {
|
|
ActionsTab,
|
|
FiltersTab,
|
|
JailsTab,
|
|
LogTab,
|
|
MapTab,
|
|
RegexTesterTab,
|
|
ServerTab,
|
|
} from "../components/config";
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Page-level styles (tab shell only — component styles live in configStyles.ts)
|
|
// ---------------------------------------------------------------------------
|
|
|
|
const useStyles = makeStyles({
|
|
page: {
|
|
padding: tokens.spacingVerticalXXL,
|
|
maxWidth: "1100px",
|
|
},
|
|
header: {
|
|
marginBottom: tokens.spacingVerticalL,
|
|
},
|
|
tabContent: {
|
|
marginTop: tokens.spacingVerticalL,
|
|
animationName: "fadeInUp",
|
|
animationDuration: tokens.durationNormal,
|
|
animationTimingFunction: tokens.curveDecelerateMid,
|
|
animationFillMode: "both",
|
|
},
|
|
infoText: {
|
|
color: tokens.colorNeutralForeground3,
|
|
fontStyle: "italic",
|
|
},
|
|
});
|
|
|
|
|
|
type TabValue =
|
|
| "jails"
|
|
| "filters"
|
|
| "actions"
|
|
| "server"
|
|
| "map"
|
|
| "regex"
|
|
| "log";
|
|
|
|
export function ConfigPage(): React.JSX.Element {
|
|
const styles = useStyles();
|
|
const [tab, setTab] = useState<TabValue>("jails");
|
|
|
|
return (
|
|
<div className={styles.page}>
|
|
<div className={styles.header}>
|
|
<Text as="h1" size={700} weight="semibold" block>
|
|
Configuration
|
|
</Text>
|
|
<Text as="p" size={300} className={styles.infoText}>
|
|
Inspect and edit fail2ban jail configuration, global settings, and
|
|
server parameters.
|
|
</Text>
|
|
</div>
|
|
|
|
<TabList
|
|
selectedValue={tab}
|
|
onTabSelect={(_e, d) => {
|
|
setTab(d.value as TabValue);
|
|
}}
|
|
>
|
|
<Tab value="jails">Jails</Tab>
|
|
<Tab value="filters">Filters</Tab>
|
|
<Tab value="actions">Actions</Tab>
|
|
<Tab value="server">Server</Tab>
|
|
<Tab value="map">Map</Tab>
|
|
<Tab value="regex">Regex Tester</Tab>
|
|
<Tab value="log">Log</Tab>
|
|
</TabList>
|
|
|
|
<div className={styles.tabContent} key={tab}>
|
|
{tab === "jails" && <JailsTab />}
|
|
{tab === "filters" && <FiltersTab />}
|
|
{tab === "actions" && <ActionsTab />}
|
|
{tab === "server" && <ServerTab />}
|
|
{tab === "map" && <MapTab />}
|
|
{tab === "regex" && <RegexTesterTab />}
|
|
{tab === "log" && <LogTab />}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|