# Tasks: Pagination Controls Redesign **Input**: Design documents from `specs/018-pagination-controls/` **Branch**: `018-pagination-controls` **Scope**: Two files change — `library.component.ts` (template, styles, class) and `library.component.spec.ts` (tests). No API, no data model, no new files. --- ## Phase 1: Setup **Purpose**: Baseline verification before touching the component. - [X] T001 Confirm existing library component tests pass by running `ng test --include=**/library.component.spec.ts --watch=false` in ui/ --- ## Phase 2: Foundational **Purpose**: No blocking infrastructure work required — all three user stories build directly on the existing `LibraryComponent`. Skipped. --- ## Phase 3: User Story 1 — Page Number Navigation (Priority: P1) 🎯 MVP **Goal**: Replace the "Page X of Y" text with up to four clickable numbered page buttons. User can jump directly to any visible page. **Independent Test**: With more than four pages of images, four numbered buttons appear; clicking a button loads that page and the button shows as active. ### Tests for User Story 1 (REQUIRED per §5.1) - [X] T002 [US1] Write failing tests for `pageWindow` getter covering: first page (→ [1,2,3,4]), last page (→ last 4), middle page (current in window), total pages < 4 (all shown) in ui/src/app/library/library.component.spec.ts ### Implementation for User Story 1 - [X] T003 [US1] Add `get pageWindow(): number[]` getter to `LibraryComponent` using the sliding-window algorithm from plan.md in ui/src/app/library/library.component.ts - [X] T004 [US1] Add `goToPage(page: number)` method to `LibraryComponent` (navigate via router queryParam, call `load()`) in ui/src/app/library/library.component.ts - [X] T005 [US1] Replace the `Page {{ currentPage }} of {{ totalPages }}` with `*ngFor` numbered page buttons; add `.page-btn` and `.page-btn.active` styles; verify T002 tests pass in ui/src/app/library/library.component.ts **Checkpoint**: Four numbered page buttons visible; clicking one loads the correct page; active button is highlighted. --- ## Phase 4: User Story 2 — Previous/Next Chevrons (Priority: P2) **Goal**: Replace text "← Previous" / "Next →" buttons with ‹ › chevrons that are always rendered but visually disabled and non-interactive when at the first or last page. **Independent Test**: On page 1 ‹ is disabled; on last page › is disabled; clicking either on a valid page advances or retreats by one. ### Tests for User Story 2 (REQUIRED per §5.1) - [X] T006 [US2] Write failing tests for ‹ › disabled attribute and non-interactivity: disabled on page 1, disabled on last page, enabled otherwise in ui/src/app/library/library.component.spec.ts ### Implementation for User Story 2 - [X] T007 [US2] Replace the `*ngIf`-gated ← Previous / Next → buttons with always-rendered `` and ``; add `.pag-btn:disabled` style; verify T006 tests pass in ui/src/app/library/library.component.ts **Checkpoint**: ‹ and › always visible; disabled at bounds; single-page step works. --- ## Phase 5: User Story 3 — First/Last Jump Buttons (Priority: P3) **Goal**: Add « and » buttons that jump directly to page 1 and the last page, disabled when already there. **Independent Test**: From any middle page, « jumps to page 1 and » jumps to the last page; both are disabled when already at the respective bound. ### Tests for User Story 3 (REQUIRED per §5.1) - [X] T008 [US3] Write failing tests for `firstPage()` and `lastPage()` methods and disabled states of « » at page boundaries in ui/src/app/library/library.component.spec.ts ### Implementation for User Story 3 - [X] T009 [US3] Add `firstPage()` and `lastPage()` methods to `LibraryComponent`; add `` and `` to each end of the pagination bar; verify T008 tests pass in ui/src/app/library/library.component.ts **Checkpoint**: Full bar renders as `« ‹ [1][2][3][4] › »`; all disabled states correct. --- ## Phase 6: Polish & Cross-Cutting Concerns - [X] T010 Apply final styles: consistent button sizing, gap spacing, and mobile-friendly layout (flex-wrap or min-width as needed) for the full pagination bar in ui/src/app/library/library.component.ts - [X] T011 Run ESLint and Prettier on ui/src/app/library/ and resolve any issues --- ## Dependencies & Execution Order - **T001**: Run first — baseline gate - **T002 → T003 → T004 → T005**: Sequential (tests before implementation; each method before its template usage) - **T006 → T007**: Sequential (tests before implementation) - **T008 → T009**: Sequential (tests before implementation) - **T010, T011**: After all story phases complete; can run in either order ### User Story Dependencies - **US1 (P1)**: Independent — starts after T001 - **US2 (P2)**: Starts after US1 is complete (shares same template section) - **US3 (P3)**: Starts after US2 is complete (adds to the same template section) All three stories touch the same two files, so parallel execution is not applicable here. --- ## Implementation Strategy ### MVP (User Story 1 only) 1. T001: Baseline check 2. T002–T005: Numbered buttons + goToPage 3. **Validate**: Four page buttons work, active state correct 4. Defer US2 and US3 if shipping early ### Full Delivery 1. T001 baseline → US1 (T002–T005) → US2 (T006–T007) → US3 (T008–T009) → Polish (T010–T011) 2. Each story checkpoint validates independence before moving on --- ## Notes - `pageWindow` algorithm: `start = max(1, currentPage-1); end = min(totalPages, start+3); start = max(1, end-3); pages = [start..end]` - No `[P]` markers — all tasks share the same two files and must run sequentially - Entire pagination bar hidden when `totalPages <= 1` (existing behaviour; do not regress)