Blocking: count Advanced Blocking, Dashboard layout and KPI cards
CI / check (push) Successful in 3m7s
Hub / check (push) Successful in 53s
CI / image (push) Successful in 1m29s
Hub / image (push) Successful in 1m19s

- Status, sidebar mark and header treat a server that blocks with the
  Advanced Blocking app as blocking, per server behind the hub.
- Overview panel summarising the app's groups; Lists and Rules show and
  edit the app's list URLs and rules (read, change one field, write back).
- Block List Domains adds the app's list domains, counted by the hub
  (hub/blocking/app-lists/count, public hosts only unless
  HUB_LISTS_ALLOW_PRIVATE=1) or by the browser where CORS allows.
- Header and KPI cards follow the Dashboard: selector in the chrome slot,
  Compare servers in the header actions, period under the title, StatCard
  tiles without sparklines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
DenozordecandClaude Opus 5.5 committed 2026-11-01 18:34:17 +07:00
1 parent b396bfd317
commit 172e06f1ce
40 files changed
+3126 -208

No files matched your search

+26
View File
@@ -0,0 +1,26 @@
import { apiRequest, type ApiOutcome } from './client'
/*
`hub/blocking/app-lists/count`: how many domains the block lists of the Advanced Blocking app
hold on one server. The hub downloads them (the app has no API for it) and caches the counts
for hours. A list it could not read has `count: null` and the reason in `error`.
*/
export interface ListCount {
url: string
count: number | null
error?: string
}
export interface ListCounts {
lists: ListCount[]
/** The sum of the lists that were counted. */
total: number
}
export function getAppListCounts(
token: string | null,
name: string,
node: string,
): Promise<ApiOutcome<{ response: ListCounts }>> {
return apiRequest('hub/blocking/app-lists/count', { token, body: { name, node } })
}