diff --git a/Docs/Tasks.md b/Docs/Tasks.md index e99ff34..9f4ae19 100644 --- a/Docs/Tasks.md +++ b/Docs/Tasks.md @@ -331,7 +331,11 @@ Rewrite the four hooks listed above as thin wrappers around `useListData`. --- -### TASK-017 — Move `source` derivation out of page components +### TASK-017 — Move `source` derivation out of page components (done) + +**Where fixed:** `frontend/src/utils/queryUtils.ts`, `frontend/src/pages/DashboardPage.tsx`, `frontend/src/pages/MapPage.tsx` + +**Summary:** Added `getDataSource` to `frontend/src/utils/queryUtils.ts` and replaced inline `timeRange === "24h"` ternaries with the shared function in both dashboard and map pages. **Where found:** `frontend/src/pages/DashboardPage.tsx` and `frontend/src/pages/MapPage.tsx` both contain the identical line: ```ts diff --git a/frontend/src/pages/DashboardPage.tsx b/frontend/src/pages/DashboardPage.tsx index d0a235b..a7cd5ca 100644 --- a/frontend/src/pages/DashboardPage.tsx +++ b/frontend/src/pages/DashboardPage.tsx @@ -17,6 +17,7 @@ import { TopCountriesBarChart } from "../components/TopCountriesBarChart"; import { TopCountriesPieChart } from "../components/TopCountriesPieChart"; import { useCommonSectionStyles } from "../components/commonStyles"; import { useDashboardCountryData } from "../hooks/useDashboardCountryData"; +import { getDataSource } from "../utils/queryUtils"; import type { BanOriginFilter, TimeRange } from "../types/ban"; @@ -71,7 +72,7 @@ export function DashboardPage(): React.JSX.Element { const [timeRange, setTimeRange] = useState("24h"); const [originFilter, setOriginFilter] = useState("all"); - const source = timeRange === "24h" ? "fail2ban" : "archive"; + const source = getDataSource(timeRange); const { countries, countryNames, isLoading: countryLoading, error: countryError, reload: reloadCountry } = useDashboardCountryData(timeRange, originFilter, source); diff --git a/frontend/src/pages/MapPage.tsx b/frontend/src/pages/MapPage.tsx index 46362cf..a62ef7d 100644 --- a/frontend/src/pages/MapPage.tsx +++ b/frontend/src/pages/MapPage.tsx @@ -25,6 +25,7 @@ import { WorldMap } from "../components/WorldMap"; import { useMapData } from "../hooks/useMapData"; import { useMapColorThresholds } from "../hooks/useMapColorThresholds"; import { MapBansTable } from "./map/MapBansTable"; +import { getDataSource } from "../utils/queryUtils"; import type { TimeRange } from "../types/map"; import type { BanOriginFilter } from "../types/ban"; @@ -96,7 +97,7 @@ export function MapPage(): React.JSX.Element { const [page, setPage] = useState(1); const [pageSize, setPageSize] = useState(100); - const source = range === "24h" ? "fail2ban" : "archive"; + const source = getDataSource(range); const { countries, countryNames, bans, total, loading, error, refresh } = useMapData(range, originFilter, source, selectedCountry ?? undefined); diff --git a/frontend/src/utils/__tests__/queryUtils.test.ts b/frontend/src/utils/__tests__/queryUtils.test.ts index cf8214d..4de3151 100644 --- a/frontend/src/utils/__tests__/queryUtils.test.ts +++ b/frontend/src/utils/__tests__/queryUtils.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "vitest"; -import { areHistoryQueriesEqual } from "../queryUtils"; +import { areHistoryQueriesEqual, getDataSource } from "../queryUtils"; import type { HistoryQuery } from "../../types/history"; describe("areHistoryQueriesEqual", () => { @@ -38,3 +38,15 @@ describe("areHistoryQueriesEqual", () => { ).toBe(false); }); }); + +describe("getDataSource", () => { + it("returns fail2ban for the 24h range", () => { + expect(getDataSource("24h")).toBe("fail2ban"); + }); + + it("returns archive for ranges other than 24h", () => { + expect(getDataSource("7d")).toBe("archive"); + expect(getDataSource("30d")).toBe("archive"); + expect(getDataSource("365d")).toBe("archive"); + }); +}); diff --git a/frontend/src/utils/queryUtils.ts b/frontend/src/utils/queryUtils.ts index 6f757f6..21eaeed 100644 --- a/frontend/src/utils/queryUtils.ts +++ b/frontend/src/utils/queryUtils.ts @@ -3,6 +3,7 @@ */ import type { HistoryQuery } from "../types/history"; +import type { TimeRange } from "../types/ban"; /** * Compare two history query objects for semantic equality. @@ -25,3 +26,13 @@ export function areHistoryQueriesEqual( a.page_size === b.page_size ); } + +/** + * Return the data source for the given dashboard time range. + * + * @param range - The selected time range. + * @returns The backend source to query. + */ +export function getDataSource(range: TimeRange): "fail2ban" | "archive" { + return range === "24h" ? "fail2ban" : "archive"; +}