Commit Graph

18 Commits

Author SHA1 Message Date
lukas b26a92248b docs(spec): scope backlog-decrease into #65 Tier 2; add sorting parity (#68)
Backlog decrease is expressible with the existing prereq #67 (no new
machinery), so it moves into Tier 2. List-view sort support is filed as
non-prereq #68; view-all links carry a TODO at each site until it lands.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RF5L4HtbcykTfY9YUYGds3
2026-06-21 15:04:36 +02:00
lukas 69f8d441eb docs(spec): stats-page filtered links for issue #65
Tier 1 (game/platform/month row links, session/games/purchased/refunded
count links, list capping + view-all, remove All purchases list) ships
independently. Tier 2 (finished/dropped/unfinished links) is gated on the
PlayEventFilter date-range prereq (#67).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RF5L4HtbcykTfY9YUYGds3
2026-06-21 15:04:36 +02:00
lukas e19f0ee63b docs(sorting): implementation plan for list-view sort param (#68)
Six TDD tasks: sorting.py core types + parse_sort_terms; per-model maps +
apply_sort + parse_find_filter; wire each of the three list views (sort +
N+1 eager-load + unknown-key warning toast); regression smoke. Links new
follow-up #77 (presets persist/restore sort) in spec + plan.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 13:40:03 +02:00
lukas 74805a7019 docs(sorting): design spec for sort query param on list views (#68)
Honor a signed comma-list ?sort= param on list_games/list_sessions/
list_purchases via a new games/sorting.py (SortSpec + per-model maps +
parse_sort_terms + apply_sort). Backend applies the full multi-term list.
Unknown sort keys are ignored with a user-facing warning toast (never a
400), surfacing #65 link drift without breaking hand-editable URLs.

Named string/compound roles throughout (SortKey, SortString, AnnotationName,
OrderField, SortTerm, SortResult) so signatures say which value goes where.

Includes an N+1 select_related/prefetch_related prereq on the list
querysets. Adjacent follow-ups filed: #73 (header UI), #74 (FindFilter
unify; also owns the unused FindFilter.direction/page/per_page fields),
#75 (purchase search), #76 (shared list_view helper).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 13:35:00 +02:00
lukas b9545a780b docs(spec): add OperatorFilter.where() ergonomic constructor
Adds a Django-.filter()-style where(**lookups) classmethod (Component 1b)
to issue #56 spec. Additive: keeps the typed explicit constructor intact.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RF5L4HtbcykTfY9YUYGds3
2026-06-21 08:38:36 +02:00
lukas 260169b521 docs(spec): programmatic filter links for issue #56
Design for a reverse()-style filter_url() helper plus navbar 'today' /
'last 7 days' links. Stats-table and view_game-table links deferred to a
follow-up issue.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RF5L4HtbcykTfY9YUYGds3
2026-06-21 07:50:25 +02:00
lukas 796753e3c9 docs: implementation plan for issue #53
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 21:14:39 +02:00
lukas 7a3b275d2f docs: return Node not SafeText in issue #53 spec
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 21:14:39 +02:00
lukas 644b9944da docs: design spec for issue #53 rebuild session row fragment
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 21:14:39 +02:00
lukas 2a1585831f feat(session): reset running session start time to now from list
Adds a confirm-gated button on running sessions in the session list that
sets timestamp_start to now (issue #33). The htmx path returns HX-Refresh;
ButtonGroup gains optional hx_confirm/hx_swap keys.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 20:38:48 +02:00
lukas bf60a2a06b docs: design spec for issue #33 reset session start to now
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 20:37:52 +02:00
lukas 82416e149d Convert onSwap widgets to custom elements (issue #18)
Replaces the four onSwap-based widgets with TypeScript custom elements
following the pattern from PR #16. Each widget gets a class extending
HTMLElement with connectedCallback/disconnectedCallback, typed props via
register_element + gen_element_types codegen, and lives in ts/elements/.

- range-slider: RangeSliderElement; Python uses _RangeSlider builder
- date-range-picker: DateRangePickerElement; Python uses _DateRangePicker builder
- search-select: SearchSelectElement; Python uses _SearchSelect builder;
  data-* attrs become plain attrs (data-name -> name, data-search-url -> search-url, etc.)
- filter-bar: FilterBarElement; props carry preset URLs; onclick/onsubmit
  attrs replaced with data-filter-bar-* sentinel attrs; all window.* globals removed

Deletes ts/range_slider.ts, ts/search_select.ts, ts/date_range_picker.ts,
ts/filter_bar.ts. Updates all tests and e2e pages to use the new element
selectors and script paths (dist/elements/<tag>.js).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 14:22:59 +02:00
lukas 3ff3eed164 Implementation plan: typed custom-element + htpy-style authoring
Bite-sized TDD plan for the design spec: TS toolchain scaffold, htpy-style
Element sugar, custom-element registry + codegen, then the three exemplar
conversions (GameStatusSelector, SessionDeviceSelector, played-row) retiring
their inline Alpine/@@TOKEN@@ f-strings, plus CI/Docker/docs wiring.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 20:51:08 +02:00
lukas 7d46cc24b9 Design spec: typed custom-element + htpy-style HTML authoring
Brainstormed design for replacing the trusted HTML/JS f-strings (Alpine
selectors, @@TOKEN@@ played-row) with three composing layers:

- htpy-style sugar on the existing Element (kwargs attrs + [] children),
  additive, keeps Media/collect_media — no build step.
- Custom Elements (light DOM, TypeScript) for behavior, with the native
  connectedCallback lifecycle replacing the onSwap shim.
- A typed contract: one Python Props type per component, codegen'd into a TS
  interface + attribute reader, so server↔client drift fails `tsc`.

Toolchain: tsc per-module (no bundler, preserves per-component Media),
build-only/gitignored output, wired into make + Docker. Exemplars:
GameStatusSelector, SessionDeviceSelector, played-row. Alpine retired for
those three; existing .js migrated later.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 20:43:35 +02:00
lukas 3c7ccbdd2b docs: add implementation plan for unifying form checkboxes 2026-06-12 22:45:25 +02:00
lukas e309ff1b30 docs: add design spec and implementation plan for boolean filters improvement 2026-06-12 22:45:25 +02:00
lukas 4e77934d06 feat: implement frontend filter bars and integration across all list views 2026-06-12 22:45:25 +02:00
lukas b8d807d302 feat: implement comprehensive filters and cross-entity queries 2026-06-12 22:45:25 +02:00