feat(ui): quieten the dashboard — mute checks, hide app noise, honest sparkline (v0.23.6-beta)
Closes #101, #103, #104, #106, #111. Partially addresses #96. A batch of signal-to-noise fixes reported together. Individually small; together they are the difference between a dashboard someone reads and one they learn to ignore. #101 — security heuristics can be muted A warning you disagree with and cannot dismiss discredits every other finding beside it. Cleartext API is the reported case: on a fleet reachable only across WireGuard, TLS adds nothing to the threat model, and the check is permanent noise. Missing input-chain firewall is the same on a switch behind a router — the message even says "confirm that is the case", while offering no way to record that you did. Checks can now be muted per device or fleet-wide. Muted findings are still listed, greyed and labelled, and excluded from the score — not hidden. Hiding them would make the posture unauditable, which is a worse failure than noise. #103 — the app's own requests are hidden from Recent activity Audit entries for writes made through the UI are noise from an operations point of view. Off by default now, with a toggle that names how many are hidden, remembered per browser since it is a viewing preference rather than fleet configuration. #104 — quick actions moved into the header strip Matching the Wireless page. "Things to handle" takes the full width it was already overflowing. #106 — map lookups can be turned off Geocoding hits nominatim.openstreetmap.org and the map pulls OSM tiles. On an isolated network those hang; everywhere else they disclose where your devices are to a third party, which the report understates. A maps_enabled setting stops both requests; stored coordinates are still shown as plain text so nothing is lost. #111 — the CPU sparkline says something It was drawn in one colour and auto-scaled to each device's own peak, so an idle device and a saturated one produced an identical picture. Now plotted against a fixed 0-100 scale, coloured by the band its peak falls into — a flat line low in the box is an idle device and looks like one. #96 — groundwork TX-retry figures come from CCQ, which only the legacy `wireless` driver reports, so the panel is permanently empty on a RouterOS 7 fleet. The wireless package each device runs is now recorded, and a capabilities endpoint answers the fleet-wide question. The panel is dropped and the density chart takes the full width when nothing can supply the data — and shown when nothing has been polled yet, rather than hiding a panel that may populate a minute later. Verified against the fleet: muting cleartext API moved a device's score from 87 to 90 with the finding still listed and marked. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
4cc8c84ea6
commit
dcd89fe86b
@@ -174,6 +174,20 @@ export interface SecurityCheck {
|
||||
title: string;
|
||||
detail: string;
|
||||
serviceId?: string;
|
||||
/** Operator judged this inapplicable — still shown, but excluded from the score. */
|
||||
suppressed?: boolean;
|
||||
suppressed_scope?: 'device' | 'fleet';
|
||||
suppressed_reason?: string | null;
|
||||
}
|
||||
|
||||
export interface SecuritySuppression {
|
||||
id: number;
|
||||
check_id: string;
|
||||
device_id: number | null;
|
||||
device_name: string | null;
|
||||
reason: string | null;
|
||||
created_by: string | null;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -340,6 +354,12 @@ export const devicesApi = {
|
||||
setServiceDisabled: (id: number, serviceId: string, disabled: boolean, confirmLockout = false) =>
|
||||
api.put<Record<string, string>[]>(`/devices/${id}/services/${encodeURIComponent(serviceId)}`,
|
||||
{ disabled, ...(confirmLockout ? { confirm_lockout: true } : {}) }),
|
||||
listSecuritySuppressions: () =>
|
||||
api.get<SecuritySuppression[]>('/devices/security/suppressions'),
|
||||
suppressSecurityCheck: (check_id: string, device_id: number | null, reason?: string) =>
|
||||
api.post('/devices/security/suppressions', { check_id, device_id, reason }),
|
||||
unsuppressSecurityCheck: (id: number) =>
|
||||
api.delete(`/devices/security/suppressions/${id}`),
|
||||
getSecurityPosture: (id: number) =>
|
||||
api.get<{ score: number; checks: SecurityCheck[] }>(`/devices/${id}/security-posture`),
|
||||
// Config Health — cached findings load instantly; the scan re-reads the device.
|
||||
@@ -1035,6 +1055,9 @@ export const wirelessApi = {
|
||||
// RF Health (fleet-wide, or scoped to one AP via deviceId)
|
||||
getChannelUsage: (deviceId?: number) =>
|
||||
api.get<import('../types').RfChannelUsage>('/wireless/rf/channels', { params: { deviceId } }),
|
||||
getRfCapabilities: () =>
|
||||
api.get<{ packages: Record<string, number>; legacyRadios: number; txRetriesAvailable: boolean }>(
|
||||
'/wireless/rf/capabilities'),
|
||||
getClientSignals: (deviceId?: number) =>
|
||||
api.get<import('../types').RfSignalRow[]>('/wireless/rf/signals', { params: { deviceId } }),
|
||||
getTxQuality: (deviceId?: number, range = '6h') =>
|
||||
|
||||
Reference in New Issue
Block a user