Refactor useHistory hook: replace HistoryQuery with explicit parameters and add documentation
- Split useHistory interface to accept explicit parameters (page, pageSize, range, origin, jail, ip, source) instead of HistoryQuery object - Add comprehensive JSDoc for useHistory function - Update HistoryPage and tests to use new parameter structure - Move TaskList documentation from Tasks.md to Web-Development.md - Improve type safety with explicit TimeRange and BanOriginFilter types Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
* Rows with repeatedly-banned IPs are highlighted in amber.
|
||||
*/
|
||||
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
@@ -32,8 +32,7 @@ import {
|
||||
import { DashboardFilterBar } from "../components/DashboardFilterBar";
|
||||
import { useHistory } from "../hooks/useHistory";
|
||||
import { IpDetailView } from "./history/IpDetailView";
|
||||
import { areHistoryQueriesEqual } from "../utils/queryUtils";
|
||||
import type { HistoryBanItem, HistoryQuery, TimeRange } from "../types/history";
|
||||
import type { HistoryBanItem, TimeRange } from "../types/history";
|
||||
import type { BanOriginFilter } from "../types/ban";
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -199,20 +198,21 @@ export function HistoryPage(): React.JSX.Element {
|
||||
const [originFilter, setOriginFilter] = useState<BanOriginFilter>("all");
|
||||
const [jailFilter, setJailFilter] = useState("");
|
||||
const [ipFilter, setIpFilter] = useState("");
|
||||
const defaultQuery: HistoryQuery = {
|
||||
range: "7d",
|
||||
source: "archive",
|
||||
page_size: PAGE_SIZE,
|
||||
page: 1,
|
||||
};
|
||||
const [appliedQuery, setAppliedQuery] = useState<HistoryQuery>(defaultQuery);
|
||||
const appliedQueryRef = useRef<HistoryQuery>(defaultQuery);
|
||||
const [page, setPage] = useState(1);
|
||||
|
||||
// Per-IP detail navigation
|
||||
const [selectedIp, setSelectedIp] = useState<string | null>(null);
|
||||
|
||||
const { items, total, page, loading, error, setPage, refresh } =
|
||||
useHistory(appliedQuery);
|
||||
const { items, total, page: currentPage, loading, error, setPage: setCurrentPage, refresh } =
|
||||
useHistory(
|
||||
page,
|
||||
PAGE_SIZE,
|
||||
range,
|
||||
originFilter !== "all" ? originFilter : undefined,
|
||||
jailFilter.trim() || undefined,
|
||||
ipFilter.trim() || undefined,
|
||||
"archive",
|
||||
);
|
||||
|
||||
const handleIpClick = useCallback((ip: string): void => {
|
||||
setSelectedIp(ip);
|
||||
@@ -223,25 +223,10 @@ export function HistoryPage(): React.JSX.Element {
|
||||
[handleIpClick, styles],
|
||||
);
|
||||
|
||||
// Reset to page 1 when filters change
|
||||
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,
|
||||
};
|
||||
|
||||
if (areHistoryQueriesEqual(nextQuery, appliedQueryRef.current)) {
|
||||
return;
|
||||
}
|
||||
|
||||
setPage(1);
|
||||
setAppliedQuery(nextQuery);
|
||||
appliedQueryRef.current = nextQuery;
|
||||
}, [range, originFilter, jailFilter, ipFilter, setPage]);
|
||||
}, [range, originFilter, jailFilter, ipFilter]);
|
||||
|
||||
const totalPages = Math.max(1, Math.ceil(total / PAGE_SIZE));
|
||||
|
||||
@@ -310,7 +295,7 @@ export function HistoryPage(): React.JSX.Element {
|
||||
{!loading && !error && (
|
||||
<Text size={300} style={{ color: tokens.colorNeutralForeground3 }}>
|
||||
{String(total)} record{total !== 1 ? "s" : ""} found ·
|
||||
Page {String(page)} of {String(totalPages)} ·
|
||||
Page {String(currentPage)} of {String(totalPages)} ·
|
||||
Rows highlighted in yellow have {String(HIGH_BAN_THRESHOLD)}+ repeat bans
|
||||
</Text>
|
||||
)}
|
||||
@@ -362,21 +347,21 @@ export function HistoryPage(): React.JSX.Element {
|
||||
icon={<ChevronLeftRegular />}
|
||||
appearance="subtle"
|
||||
size="small"
|
||||
disabled={page <= 1}
|
||||
disabled={currentPage <= 1}
|
||||
onClick={(): void => {
|
||||
setPage(page - 1);
|
||||
setCurrentPage(currentPage - 1);
|
||||
}}
|
||||
/>
|
||||
<Text size={200}>
|
||||
Page {String(page)} / {String(totalPages)}
|
||||
Page {String(currentPage)} / {String(totalPages)}
|
||||
</Text>
|
||||
<Button
|
||||
icon={<ChevronRightRegular />}
|
||||
appearance="subtle"
|
||||
size="small"
|
||||
disabled={page >= totalPages}
|
||||
disabled={currentPage >= totalPages}
|
||||
onClick={(): void => {
|
||||
setPage(page + 1);
|
||||
setCurrentPage(currentPage + 1);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user