Add origin field and filter for ban sources (Tasks 1 & 2)
- Task 1: Mark imported blocklist IP addresses
- Add BanOrigin type and _derive_origin() to ban.py model
- Populate origin field in ban_service list_bans() and bans_by_country()
- BanTable and MapPage companion table show origin badge column
- Tests: origin derivation in test_ban_service.py and test_dashboard.py
- Task 2: Add origin filter to dashboard and world map
- ban_service: _origin_sql_filter() helper; origin param on list_bans()
and bans_by_country()
- dashboard router: optional origin query param forwarded to service
- Frontend: BanOriginFilter type + BAN_ORIGIN_FILTER_LABELS in ban.ts
- fetchBans / fetchBansByCountry forward origin to API
- useBans / useMapData accept and pass origin; page resets on change
- BanTable accepts origin prop; DashboardPage adds segmented filter
- MapPage adds origin Select next to time-range picker
- Tests: origin filter assertions in test_ban_service and test_dashboard
This commit is contained in:
@@ -27,7 +27,7 @@ import {
|
||||
import { PageEmpty, PageError, PageLoading } from "./PageFeedback";
|
||||
import { ChevronLeftRegular, ChevronRightRegular } from "@fluentui/react-icons";
|
||||
import { useBans } from "../hooks/useBans";
|
||||
import type { DashboardBanItem, TimeRange } from "../types/ban";
|
||||
import type { DashboardBanItem, TimeRange, BanOriginFilter } from "../types/ban";
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Types
|
||||
@@ -40,6 +40,11 @@ interface BanTableProps {
|
||||
* Changing this value triggers a re-fetch.
|
||||
*/
|
||||
timeRange: TimeRange;
|
||||
/**
|
||||
* Active origin filter — controlled by the parent `DashboardPage`.
|
||||
* Changing this value triggers a re-fetch and resets to page 1.
|
||||
*/
|
||||
origin?: BanOriginFilter;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -159,6 +164,18 @@ function buildBanColumns(styles: ReturnType<typeof useStyles>): TableColumnDefin
|
||||
renderHeaderCell: () => "Jail",
|
||||
renderCell: (item) => <Text size={200}>{item.jail}</Text>,
|
||||
}),
|
||||
createTableColumn<DashboardBanItem>({
|
||||
columnId: "origin",
|
||||
renderHeaderCell: () => "Origin",
|
||||
renderCell: (item) => (
|
||||
<Badge
|
||||
appearance="tint"
|
||||
color={item.origin === "blocklist" ? "brand" : "informative"}
|
||||
>
|
||||
{item.origin === "blocklist" ? "Blocklist" : "Selfblock"}
|
||||
</Badge>
|
||||
),
|
||||
}),
|
||||
createTableColumn<DashboardBanItem>({
|
||||
columnId: "ban_count",
|
||||
renderHeaderCell: () => "Bans",
|
||||
@@ -183,10 +200,11 @@ function buildBanColumns(styles: ReturnType<typeof useStyles>): TableColumnDefin
|
||||
* Data table for the dashboard ban-list view.
|
||||
*
|
||||
* @param props.timeRange - Active time-range preset from the parent page.
|
||||
* @param props.origin - Active origin filter from the parent page.
|
||||
*/
|
||||
export function BanTable({ timeRange }: BanTableProps): React.JSX.Element {
|
||||
export function BanTable({ timeRange, origin = "all" }: BanTableProps): React.JSX.Element {
|
||||
const styles = useStyles();
|
||||
const { banItems, total, page, setPage, loading, error, refresh } = useBans(timeRange);
|
||||
const { banItems, total, page, setPage, loading, error, refresh } = useBans(timeRange, origin);
|
||||
|
||||
const banColumns = buildBanColumns(styles);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user