Skip to content

feat(dashboard): log navigation — range presets, date jumps, and search for both security logs - #838

Merged
VijitSingh97 merged 2 commits into
developfrom
feat/823-log-navigation
Aug 2, 2026
Merged

feat(dashboard): log navigation — range presets, date jumps, and search for both security logs#838
VijitSingh97 merged 2 commits into
developfrom
feat/823-log-navigation

Conversation

@VijitSingh97

Copy link
Copy Markdown
Collaborator

Closes #823 — the Security view's two log tables were navigable only by scrolling (and the config-change card's lone grouping dropdown).

What

Both panels gain one shared control row: the chart's range presets (24 Hr / 1 Wk / 1 Mo / All) for following a live log, two native date inputs for jumping to a specific day or span (the "to" date covers its whole day via a half-open next-midnight bound), and a debounced search box matching any field. Filters compose; the existing hour/day/month grouping still applies on top.

Filtering is server-side (?from&to&q on /api/access and /api/audit) so a match deeper than the glance tail is found: one filter_log_entries helper serves both surfaces by normalizing each entry's ts (epoch on access rows, canonical UTC ISO on audit rows) onto one epoch axis — an undatable row matches no time window but still matches a pure text search. Malformed bounds read as absent (a bad query never 500s a log view); q is trimmed, length-capped, and only ever compared — the existing sanitation path is untouched. The access read deepens to a bounded 1000-row tail only while filtering; the failed-login counters always describe the whole tail. Filtered views lift the 20-row glance cap and report an honest "No entries match this filter".

Verified live (harness)

Preset click narrows to the window and lifts the cap; search composes with the active range — including the honest empty intersection when the searched entry sits outside it; the audit card filters independently; controls render in both cards with the active preset marked.

Coverage

  • test_audit_service.py: the filter helper — half-open window across both ts shapes on one axis, undatable-row semantics, case-insensitive any-field search incl. numeric values, composition, non-string/non-number ts.
  • test_server.py: both routes' param handling — window + search + whole-tail counters + malformed-bounds degradation.
  • securityview.test.mjs: buildLogQuery (presets, date-override, next-midnight bound, URL encoding), controls rendering with active-preset marking, cap-lift under filter vs glance cap, honest empty messages.
  • Dashboard 1649 pass / 96.9% total / patch 100%; frontend suite green; make lint clean; docs updated in docs/dashboard.md.

🤖 Generated with Claude Code

VijitSingh97 and others added 2 commits August 1, 2026 20:53
…ch for both security logs (#823)

Both Security panels gain one shared control row: the chart's range
presets (24 Hr / 1 Wk / 1 Mo / All) for following a live log, two
native date inputs for jumping to a specific day or span (the 'to'
date covers its whole day via a half-open next-midnight bound), and a
debounced search box matching any field. Filters compose.

Filtering is SERVER-side (?from&to&q on /api/access and /api/audit) so
a match deeper than the glance tail is still found: one filter helper
serves both surfaces by normalizing each entry's ts (epoch seconds on
access rows, the canonical UTC ISO string on audit rows) onto one
epoch axis; an undatable row matches no time window but still matches
a pure text search. Malformed bounds read as absent — a bad query must
never 500 a log view; q is trimmed and length-capped and only ever
compared, never stored or echoed unsanitized. The access read deepens
to a bounded 1000-row tail only while filtering, and its failed-login
counters always describe the whole tail. A filtered view lifts the
20-row glance cap and says 'No entries match this filter' honestly.

Verified live in the harness: preset refetch narrows to the window and
lifts the cap, search composes with the active range (including the
honest empty intersection), the audit card filters independently.

Closes #823

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Non-finite from/to bounds (inf/nan parse via float()) now read as
  absent — nan compares False with everything and would silently warp
  the window; the malformed-bounds contract is now true, and tested.
- A per-surface sequence guard stops a slow stale response from
  overwriting a fresher filter's view.
- Pending search debounce timers are cleared on unmount.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@VijitSingh97
VijitSingh97 merged commit 7b3af11 into develop Aug 2, 2026
16 checks passed
@VijitSingh97
VijitSingh97 deleted the feat/823-log-navigation branch August 2, 2026 02:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Security view logs: date-range navigation, jump-to-time, and search for the access log and config changes

1 participant