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:
@@ -16,8 +16,8 @@ import {
|
||||
} from "@fluentui/react-components";
|
||||
import { BanTable } from "../components/BanTable";
|
||||
import { ServerStatusBar } from "../components/ServerStatusBar";
|
||||
import type { TimeRange } from "../types/ban";
|
||||
import { TIME_RANGE_LABELS } from "../types/ban";
|
||||
import type { BanOriginFilter, TimeRange } from "../types/ban";
|
||||
import { BAN_ORIGIN_FILTER_LABELS, TIME_RANGE_LABELS } from "../types/ban";
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -73,6 +73,9 @@ const useStyles = makeStyles({
|
||||
/** Ordered time-range presets for the toolbar. */
|
||||
const TIME_RANGES: TimeRange[] = ["24h", "7d", "30d", "365d"];
|
||||
|
||||
/** Ordered origin filter options for the toolbar. */
|
||||
const ORIGIN_FILTERS: BanOriginFilter[] = ["all", "blocklist", "selfblock"];
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Component
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -86,6 +89,7 @@ const TIME_RANGES: TimeRange[] = ["24h", "7d", "30d", "365d"];
|
||||
export function DashboardPage(): React.JSX.Element {
|
||||
const styles = useStyles();
|
||||
const [timeRange, setTimeRange] = useState<TimeRange>("24h");
|
||||
const [originFilter, setOriginFilter] = useState<BanOriginFilter>("all");
|
||||
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
@@ -119,11 +123,28 @@ export function DashboardPage(): React.JSX.Element {
|
||||
</ToggleButton>
|
||||
))}
|
||||
</Toolbar>
|
||||
|
||||
{/* Origin filter */}
|
||||
<Toolbar aria-label="Origin filter" size="small">
|
||||
{ORIGIN_FILTERS.map((f) => (
|
||||
<ToggleButton
|
||||
key={f}
|
||||
size="small"
|
||||
checked={originFilter === f}
|
||||
onClick={() => {
|
||||
setOriginFilter(f);
|
||||
}}
|
||||
aria-pressed={originFilter === f}
|
||||
>
|
||||
{BAN_ORIGIN_FILTER_LABELS[f]}
|
||||
</ToggleButton>
|
||||
))}
|
||||
</Toolbar>
|
||||
</div>
|
||||
|
||||
{/* Ban table */}
|
||||
<div className={styles.tabContent}>
|
||||
<BanTable timeRange={timeRange} />
|
||||
<BanTable timeRange={timeRange} origin={originFilter} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user