feat(filters): programmatic filter links + navbar playtime links (#56)

Add filter_url(), a reverse()-style helper that builds a URL to a filtered
list view from a filter object (target inferred from the filter type).

Add OperatorFilter.where(**lookups), a Django-.filter()-style ergonomic
constructor that resolves each field's criterion class from its annotation
(shared with from_json via _criterion_class_for, removing duplication).

Make SessionFilter.timestamp_start/timestamp_end DateCriterion applied via
the __date lookup, so date ranges over the timestamp columns are expressible.

Wire the navbar 'today' / 'last 7 days' totals as links to the matching
filtered session lists, and align the 'last 7 days' total to the same
calendar-day window so the number matches the list it links to.

Stats-table and game-detail links remain a follow-up (see spec).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RF5L4HtbcykTfY9YUYGds3
This commit is contained in:
2026-06-21 08:53:06 +02:00
parent b9545a780b
commit 3fd02bbcf9
9 changed files with 402 additions and 22 deletions
+7 -1
View File
@@ -308,7 +308,13 @@ def _row_with_navbar(request: HttpRequest, session: Session) -> HttpResponse:
counts = model_counts(request)
fragment = Fragment(
session_row(session, device_list, get_token(request)),
NavbarPlaytime(counts["today_played"], counts["last_7_played"], oob=True),
NavbarPlaytime(
counts["today_played"],
counts["last_7_played"],
today_url=counts["today_url"],
last_7_url=counts["last_7_url"],
oob=True,
),
)
return HttpResponse(str(fragment))