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:
@@ -13,6 +13,8 @@ import type {
|
||||
JailConfigUpdate,
|
||||
LogPreviewRequest,
|
||||
LogPreviewResponse,
|
||||
MapColorThresholdsResponse,
|
||||
MapColorThresholdsUpdate,
|
||||
RegexTestRequest,
|
||||
RegexTestResponse,
|
||||
ServerSettingsResponse,
|
||||
@@ -119,3 +121,21 @@ export async function flushLogs(
|
||||
);
|
||||
return resp.message;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Map color thresholds
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export async function fetchMapColorThresholds(
|
||||
): Promise<MapColorThresholdsResponse> {
|
||||
return get<MapColorThresholdsResponse>(ENDPOINTS.configMapColorThresholds);
|
||||
}
|
||||
|
||||
export async function updateMapColorThresholds(
|
||||
update: MapColorThresholdsUpdate
|
||||
): Promise<MapColorThresholdsResponse> {
|
||||
return put<MapColorThresholdsResponse>(
|
||||
ENDPOINTS.configMapColorThresholds,
|
||||
update,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import { get } from "./client";
|
||||
import { ENDPOINTS } from "./endpoints";
|
||||
import type { DashboardBanListResponse, TimeRange } from "../types/ban";
|
||||
import type { DashboardBanListResponse, TimeRange, BanOriginFilter } from "../types/ban";
|
||||
import type { ServerStatusResponse } from "../types/server";
|
||||
|
||||
/**
|
||||
@@ -26,6 +26,8 @@ export async function fetchServerStatus(): Promise<ServerStatusResponse> {
|
||||
* @param range - Time-range preset: `"24h"`, `"7d"`, `"30d"`, or `"365d"`.
|
||||
* @param page - 1-based page number (default `1`).
|
||||
* @param pageSize - Items per page (default `100`).
|
||||
* @param origin - Origin filter: `"blocklist"`, `"selfblock"`, or `"all"`
|
||||
* (default `"all"`, which omits the parameter entirely).
|
||||
* @returns Paginated {@link DashboardBanListResponse}.
|
||||
* @throws {ApiError} When the server returns a non-2xx status.
|
||||
*/
|
||||
@@ -33,12 +35,16 @@ export async function fetchBans(
|
||||
range: TimeRange,
|
||||
page = 1,
|
||||
pageSize = 100,
|
||||
origin: BanOriginFilter = "all",
|
||||
): Promise<DashboardBanListResponse> {
|
||||
const params = new URLSearchParams({
|
||||
range,
|
||||
page: String(page),
|
||||
page_size: String(pageSize),
|
||||
});
|
||||
if (origin !== "all") {
|
||||
params.set("origin", origin);
|
||||
}
|
||||
return get<DashboardBanListResponse>(`${ENDPOINTS.dashboardBans}?${params.toString()}`);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ export const ENDPOINTS = {
|
||||
configReload: "/config/reload",
|
||||
configRegexTest: "/config/regex-test",
|
||||
configPreviewLog: "/config/preview-log",
|
||||
configMapColorThresholds: "/config/map-color-thresholds",
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Server settings
|
||||
|
||||
@@ -5,15 +5,22 @@
|
||||
import { get } from "./client";
|
||||
import { ENDPOINTS } from "./endpoints";
|
||||
import type { BansByCountryResponse, TimeRange } from "../types/map";
|
||||
import type { BanOriginFilter } from "../types/ban";
|
||||
|
||||
/**
|
||||
* Fetch ban counts aggregated by country for the given time window.
|
||||
*
|
||||
* @param range - Time-range preset.
|
||||
* @param range - Time-range preset.
|
||||
* @param origin - Origin filter: `"blocklist"`, `"selfblock"`, or `"all"`
|
||||
* (default `"all"`, which omits the parameter entirely).
|
||||
*/
|
||||
export async function fetchBansByCountry(
|
||||
range: TimeRange = "24h",
|
||||
origin: BanOriginFilter = "all",
|
||||
): Promise<BansByCountryResponse> {
|
||||
const url = `${ENDPOINTS.dashboardBansByCountry}?range=${encodeURIComponent(range)}`;
|
||||
return get<BansByCountryResponse>(url);
|
||||
const params = new URLSearchParams({ range });
|
||||
if (origin !== "all") {
|
||||
params.set("origin", origin);
|
||||
}
|
||||
return get<BansByCountryResponse>(`${ENDPOINTS.dashboardBansByCountry}?${params.toString()}`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user