Switch dashboard/map/history views to archive source for long-term data
Update fail2ban dbpurgeage to 648000 and history sync backfill/pagination for archive-based 7.5 day history.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import { useState } from "react";
|
||||
import { Text, makeStyles, tokens } from "@fluentui/react-components";
|
||||
import { Badge, Text, makeStyles, tokens } from "@fluentui/react-components";
|
||||
import { BanTable } from "../components/BanTable";
|
||||
import { BanTrendChart } from "../components/BanTrendChart";
|
||||
import { ChartStateWrapper } from "../components/ChartStateWrapper";
|
||||
@@ -71,8 +71,10 @@ export function DashboardPage(): React.JSX.Element {
|
||||
const [timeRange, setTimeRange] = useState<TimeRange>("24h");
|
||||
const [originFilter, setOriginFilter] = useState<BanOriginFilter>("all");
|
||||
|
||||
const source = timeRange === "24h" ? "fail2ban" : "archive";
|
||||
|
||||
const { countries, countryNames, isLoading: countryLoading, error: countryError, reload: reloadCountry } =
|
||||
useDashboardCountryData(timeRange, originFilter);
|
||||
useDashboardCountryData(timeRange, originFilter, source);
|
||||
|
||||
const sectionStyles = useCommonSectionStyles();
|
||||
|
||||
@@ -86,12 +88,17 @@ export function DashboardPage(): React.JSX.Element {
|
||||
{/* ------------------------------------------------------------------ */}
|
||||
{/* Global filter bar */}
|
||||
{/* ------------------------------------------------------------------ */}
|
||||
<DashboardFilterBar
|
||||
timeRange={timeRange}
|
||||
onTimeRangeChange={setTimeRange}
|
||||
originFilter={originFilter}
|
||||
onOriginFilterChange={setOriginFilter}
|
||||
/>
|
||||
<div style={{ display: "flex", alignItems: "center", gap: tokens.spacingHorizontalM, flexWrap: "wrap" }}>
|
||||
<DashboardFilterBar
|
||||
timeRange={timeRange}
|
||||
onTimeRangeChange={setTimeRange}
|
||||
originFilter={originFilter}
|
||||
onOriginFilterChange={setOriginFilter}
|
||||
/>
|
||||
<Badge appearance="filled" color={source === "archive" ? "brand" : "success"}>
|
||||
{source === "archive" ? "Archive (BanGUI DB)" : "Live (fail2ban DB)"}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
{/* ------------------------------------------------------------------ */}
|
||||
{/* Ban Trend section */}
|
||||
@@ -103,7 +110,7 @@ export function DashboardPage(): React.JSX.Element {
|
||||
</Text>
|
||||
</div>
|
||||
<div className={styles.tabContent}>
|
||||
<BanTrendChart timeRange={timeRange} origin={originFilter} />
|
||||
<BanTrendChart timeRange={timeRange} origin={originFilter} source={source} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -154,7 +161,7 @@ export function DashboardPage(): React.JSX.Element {
|
||||
|
||||
{/* Ban table */}
|
||||
<div className={styles.tabContent}>
|
||||
<BanTable timeRange={timeRange} origin={originFilter} />
|
||||
<BanTable timeRange={timeRange} origin={originFilter} source={source} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -143,6 +143,7 @@ function areHistoryQueriesEqual(
|
||||
a.origin === b.origin &&
|
||||
a.jail === b.jail &&
|
||||
a.ip === b.ip &&
|
||||
a.source === b.source &&
|
||||
a.page === b.page &&
|
||||
a.page_size === b.page_size
|
||||
);
|
||||
@@ -386,11 +387,12 @@ export function HistoryPage(): React.JSX.Element {
|
||||
const styles = useStyles();
|
||||
|
||||
// Filter state
|
||||
const [range, setRange] = useState<TimeRange>("24h");
|
||||
const [range, setRange] = useState<TimeRange>("7d");
|
||||
const [originFilter, setOriginFilter] = useState<BanOriginFilter>("all");
|
||||
const [jailFilter, setJailFilter] = useState("");
|
||||
const [ipFilter, setIpFilter] = useState("");
|
||||
const [appliedQuery, setAppliedQuery] = useState<HistoryQuery>({
|
||||
source: "archive",
|
||||
page_size: PAGE_SIZE,
|
||||
});
|
||||
|
||||
@@ -400,12 +402,15 @@ export function HistoryPage(): React.JSX.Element {
|
||||
const { items, total, page, loading, error, setPage, refresh } =
|
||||
useHistory(appliedQuery);
|
||||
|
||||
const sourceLabel = "Archive (BanGUI DB)";
|
||||
|
||||
useEffect((): void => {
|
||||
const nextQuery: HistoryQuery = {
|
||||
range,
|
||||
origin: originFilter !== "all" ? originFilter : undefined,
|
||||
jail: jailFilter.trim() || undefined,
|
||||
ip: ipFilter.trim() || undefined,
|
||||
source: "archive",
|
||||
page: 1,
|
||||
page_size: PAGE_SIZE,
|
||||
};
|
||||
@@ -485,6 +490,9 @@ export function HistoryPage(): React.JSX.Element {
|
||||
setIpFilter(value);
|
||||
}}
|
||||
/>
|
||||
<Badge appearance="filled" color="brand" style={{ alignSelf: "flex-start" }}>
|
||||
{sourceLabel}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
{/* ---------------------------------------------------------------- */}
|
||||
|
||||
@@ -98,8 +98,10 @@ export function MapPage(): React.JSX.Element {
|
||||
|
||||
const PAGE_SIZE_OPTIONS = [25, 50, 100] as const;
|
||||
|
||||
const source = range === "24h" ? "fail2ban" : "archive";
|
||||
|
||||
const { countries, countryNames, bans, total, loading, error, refresh } =
|
||||
useMapData(range, originFilter);
|
||||
useMapData(range, originFilter, source);
|
||||
|
||||
const {
|
||||
thresholds: mapThresholds,
|
||||
@@ -163,6 +165,9 @@ export function MapPage(): React.JSX.Element {
|
||||
setSelectedCountry(null);
|
||||
}}
|
||||
/>
|
||||
<Badge appearance="filled" color={source === "archive" ? "brand" : "success"}>
|
||||
{source === "archive" ? "Archive (BanGUI DB)" : "Live (fail2ban DB)"}
|
||||
</Badge>
|
||||
<Button
|
||||
icon={<ArrowCounterclockwiseRegular />}
|
||||
onClick={(): void => {
|
||||
|
||||
@@ -50,7 +50,8 @@ describe("HistoryPage", () => {
|
||||
// Initial load should include the auto-applied default query.
|
||||
await waitFor(() => {
|
||||
expect(lastQuery).toEqual({
|
||||
range: "24h",
|
||||
range: "7d",
|
||||
source: "archive",
|
||||
origin: undefined,
|
||||
jail: undefined,
|
||||
ip: undefined,
|
||||
|
||||
Reference in New Issue
Block a user