Lazy-load user game list status tabs #59

Closed
opened 2024-01-14 14:52:37 -06:00 by jimmyb · 1 comment
Owner

Large user game lists should load faster by rendering only the initial status tab first, then loading other status groups when the user asks for them.

The current Laravel checkout has game_lists persistence, status values for Playing, Completed, On Hold, Dropped, Plan to Play, and Continuously Playing, list-entry create/update/delete logic, and profile/header links that reserve /list/{username}. The public list route and rebuilt list page are not wired up yet, so this issue should rebuild the list surface with status-scoped loading from the start instead of loading every list entry for every status on the first request.

Scope

  • Public user list pages at /list/{username} and the current user’s own list shortcut where supported.
  • Status-tabbed game list rendering.
  • Initial page load limited to the default Playing tab.
  • Lazy loading for Completed, On Hold, Dropped, Plan to Play, and Continuously Playing tabs.
  • Active, non-deleted game_lists rows only.
  • Game and platform metadata needed for each visible row.
  • Lightweight per-status counts where practical.
  • Accessible no-JavaScript fallback and existing Laravel/Tailwind layout patterns.

Acceptance Criteria

  • Visiting a user’s game list renders the page shell and the Playing tab without loading every status group.
  • Other status tabs load their entries only when selected.
  • The list supports all existing status values: Playing, Completed, On Hold, Dropped, Plan to Play, and Continuously Playing.
  • Status tab URLs or query parameters are shareable and can render the selected status directly.
  • JavaScript-enhanced tab switching updates the visible list without a full page reload where practical.
  • Users without JavaScript can still navigate between status tabs through normal links.
  • Counts per status are shown without requiring every row for every status to be hydrated on initial page load.
  • Soft-deleted list rows are excluded from counts and tab contents.
  • Deleted, disabled, or soft-deleted games and missing platform data do not break list rendering.
  • List rows include useful compact metadata such as game title, platform, ownership/status, rating, progress dates where available, and a canonical game profile link.
  • Empty status tabs show a clear empty state.
  • The existing owner-only list update/delete behavior remains intact.
  • The implementation avoids N+1 queries and performs acceptably for lists with 1,600+ entries.
  • User-facing UI supports light/dark mode and follows existing Laravel/Tailwind list/profile patterns.

Test Coverage Required

  • Feature test confirming /list/{username} renders the default Playing tab and does not render entries from other statuses in the initial content.
  • Feature tests confirming each status tab can be requested directly and renders only matching active rows.
  • Regression test confirming status counts are correct across multiple statuses.
  • Regression test confirming soft-deleted list rows are excluded from counts and rendered rows.
  • Regression test confirming unavailable or missing related game/platform data does not crash rendering.
  • Feature test confirming canonical game links and compact row metadata render correctly.
  • Regression test confirming empty status tabs show an empty state.
  • Authorization/regression tests confirming owner-only list mutation rules still apply.
  • Performance-oriented test or query-count regression confirming the default list load avoids N+1 behavior and does not hydrate all statuses.
  • Tests should use Pest and focused list-page coverage.
  • Run the focused list tests, then run vendor/bin/pint --dirty before closing the issue.

Progress Checklist

  • game_lists table exists
  • GameList model exists
  • Game-list status values exist for Playing, Completed, On Hold, Dropped, Plan to Play, and Continuously Playing
  • Game-list rows store game, platform, rating, ownership, dates, and notes metadata
  • Game-list create/update/delete controller logic exists
  • Profile/header links reserve user list URLs
  • Add or restore public list routes for /list/{username} and current-user list access
  • Build the public list page shell and status-tab UI
  • Load only the Playing status entries on the default page render
  • Add status-scoped tab loading for the remaining statuses
  • Add shareable status-tab URLs or query parameters with no-JavaScript fallback
  • Add lightweight grouped status counts
  • Exclude soft-deleted list rows and handle missing related game/platform data
  • Preserve owner-only list edit/delete behavior
  • Add tests for default loading, tab loading, status filtering, counts, empty states, authorization, and query efficiency
  • Confirm large lists render faster without sacrificing tab usability
Large user game lists should load faster by rendering only the initial status tab first, then loading other status groups when the user asks for them. The current Laravel checkout has `game_lists` persistence, status values for Playing, Completed, On Hold, Dropped, Plan to Play, and Continuously Playing, list-entry create/update/delete logic, and profile/header links that reserve `/list/{username}`. The public list route and rebuilt list page are not wired up yet, so this issue should rebuild the list surface with status-scoped loading from the start instead of loading every list entry for every status on the first request. ## Scope - Public user list pages at `/list/{username}` and the current user’s own list shortcut where supported. - Status-tabbed game list rendering. - Initial page load limited to the default Playing tab. - Lazy loading for Completed, On Hold, Dropped, Plan to Play, and Continuously Playing tabs. - Active, non-deleted `game_lists` rows only. - Game and platform metadata needed for each visible row. - Lightweight per-status counts where practical. - Accessible no-JavaScript fallback and existing Laravel/Tailwind layout patterns. ## Acceptance Criteria - Visiting a user’s game list renders the page shell and the Playing tab without loading every status group. - Other status tabs load their entries only when selected. - The list supports all existing status values: Playing, Completed, On Hold, Dropped, Plan to Play, and Continuously Playing. - Status tab URLs or query parameters are shareable and can render the selected status directly. - JavaScript-enhanced tab switching updates the visible list without a full page reload where practical. - Users without JavaScript can still navigate between status tabs through normal links. - Counts per status are shown without requiring every row for every status to be hydrated on initial page load. - Soft-deleted list rows are excluded from counts and tab contents. - Deleted, disabled, or soft-deleted games and missing platform data do not break list rendering. - List rows include useful compact metadata such as game title, platform, ownership/status, rating, progress dates where available, and a canonical game profile link. - Empty status tabs show a clear empty state. - The existing owner-only list update/delete behavior remains intact. - The implementation avoids N+1 queries and performs acceptably for lists with 1,600+ entries. - User-facing UI supports light/dark mode and follows existing Laravel/Tailwind list/profile patterns. ## Test Coverage Required - Feature test confirming `/list/{username}` renders the default Playing tab and does not render entries from other statuses in the initial content. - Feature tests confirming each status tab can be requested directly and renders only matching active rows. - Regression test confirming status counts are correct across multiple statuses. - Regression test confirming soft-deleted list rows are excluded from counts and rendered rows. - Regression test confirming unavailable or missing related game/platform data does not crash rendering. - Feature test confirming canonical game links and compact row metadata render correctly. - Regression test confirming empty status tabs show an empty state. - Authorization/regression tests confirming owner-only list mutation rules still apply. - Performance-oriented test or query-count regression confirming the default list load avoids N+1 behavior and does not hydrate all statuses. - Tests should use Pest and focused list-page coverage. - Run the focused list tests, then run `vendor/bin/pint --dirty` before closing the issue. ## Progress Checklist - [x] `game_lists` table exists - [x] `GameList` model exists - [x] Game-list status values exist for Playing, Completed, On Hold, Dropped, Plan to Play, and Continuously Playing - [x] Game-list rows store game, platform, rating, ownership, dates, and notes metadata - [x] Game-list create/update/delete controller logic exists - [x] Profile/header links reserve user list URLs - [ ] Add or restore public list routes for `/list/{username}` and current-user list access - [ ] Build the public list page shell and status-tab UI - [ ] Load only the Playing status entries on the default page render - [ ] Add status-scoped tab loading for the remaining statuses - [ ] Add shareable status-tab URLs or query parameters with no-JavaScript fallback - [ ] Add lightweight grouped status counts - [ ] Exclude soft-deleted list rows and handle missing related game/platform data - [ ] Preserve owner-only list edit/delete behavior - [ ] Add tests for default loading, tab loading, status filtering, counts, empty states, authorization, and query efficiency - [ ] Confirm large lists render faster without sacrificing tab usability
Codex changed title from Implement New Loading Method for Game Lists to Lazy-load user game list status tabs 2026-05-26 01:14:20 -05:00
Member

This issue is incorporated into #348, which now tracks the full user game list rebuild including lazy/status-scoped loading. Closing this as superseded to keep the list rebuild work centralized.

This issue is incorporated into #348, which now tracks the full user game list rebuild including lazy/status-scoped loading. Closing this as superseded to keep the list rebuild work centralized.
Codex closed this issue 2026-06-01 21:58:25 -05:00
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
MyVideoGameList/myvideogamelist.com#59
No description provided.