# 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 `<span class="page-indicator">Page {{ currentPage }} of {{ totalPages }}</span>` 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 `<button [disabled]="currentPage === 1">‹</button>` and `<button [disabled]="currentPage === totalPages">›</button>`; 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 `<button [disabled]="currentPage === 1">«</button>` and `<button [disabled]="currentPage === totalPages">»</button>` 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)
