# SLICE 8 — Incremental card limits for kanban and matrix views > **State-saving rule:** update this file and `TASKS.md` after every completed > task and whenever work pauses. Automated checks and manual Joplin acceptance > must be recorded separately. ## Status **COMPLETE (2026-07-27). All seven phases passed, including automated validation, production packaging, documentation, and user-confirmed manual Joplin acceptance.** ## Goal Keep large kanban columns and matrix quadrants readable by rendering cards in configurable batches. Every bucket initially shows 10 cards by default. A local "List more" control reveals the next batch without changing the source note or persisting UI state. Reloading the rendered note resets all buckets. ## Confirmed behavior - Add `page-size:` to both `gtd-kanban` and `gtd-matrix` blocks. - Default: `10`. - Valid values: positive integers only. - Invalid values produce a warning and fall back to 10. - Apply the limit independently after existing filtering and sorting to: - Backlog, In Progress, and Done on kanban boards. - All four quadrants in both matrix modes. - "List more" reveals the next `page-size` entries in only that bucket. - Show the control only when hidden entries remain. - Hovering or focusing the control shows the exact number of additional entries remaining, for example `13 more entries`. - Clicking updates the remaining count and removes the control after the final batch. - Expansion exists only in the current webview DOM. It is not written to the note, settings, plugin process, or project data. - Column/quadrant headings continue to show total card counts, not visible counts. - Collector results and overall statistics continue to represent all cards. ## Architecture and data flow ```text gtd-kanban / gtd-matrix YAML | v parseKanbanConfig / parseMatrixConfig validates page-size -> normalized pageSize | v handleGetKanban / handleGetMatrix returns pageSize alongside the complete sorted board | v renderKanban / renderMatrix gives each column or quadrant its own visibleCount | v renderIncrementalCardList renders slice(0, visibleCount), remaining summary, and List more ``` The collectors (`collectKanban.ts` and `collectMatrix.ts`) must not paginate or truncate. Keeping pagination in the webview avoids corrupting totals, changing sort semantics, or requiring another plugin-process request on every click. ## Implementation plan ### Phase 1 — Configuration contract - [x] Add `pageSize: number` to `KanbanConfig` and `MatrixConfig` in `src/Gtd/types.ts`. - [x] Add `page-size` to each parser's known-key list. - [x] Normalize omitted `page-size` to 10. - [x] Accept numeric or YAML numeric-string values only when they resolve to a finite positive integer. - [x] Warn with consistent wording for zero, negative, fractional, non-numeric, `NaN`, or infinite values and use 10. - [x] Add parser tests in `src/tests/Gtd/kanban.test.ts` and `src/tests/Gtd/matrix.test.ts` for: - omitted/default value; - `1`, `10`, and a larger valid override; - numeric-string compatibility; - zero, negative, fractional, and non-numeric fallback; - recognition as a known key (no unknown-option warning). ## Progress log - 2026-07-27 — Phase 1 complete. Added shared `page-size` normalization and required `pageSize` fields for kanban/matrix config. Focused validation: 2 suites passed, 59/59 tests. Full validation: 12 suites passed, 164/164 tests. No manual testing applies yet because the value is not sent to or used by the webview until later phases. ### Phase 2 — Plugin-to-webview payload - [x] Add `pageSize: config.pageSize` to successful kanban and matrix responses in `src/index.ts`. - [x] Add the same normalized value to missing-source-note/error responses so rendering behavior is structurally consistent. - [x] Do not change collector arguments, result shapes, sorting, card totals, or scope behavior. - 2026-07-27 — Phase 2 complete. Added normalized `pageSize` to successful and missing-source-note responses for both kanban and matrix handlers. No collector or rendering changes. Full Jest validation: 12 suites passed, 164/164 tests. `npx tsc --noEmit --skipLibCheck` passed; the unmodified command remains blocked by unresolved generated Joplin declarations and the repository's Jest/TypeScript library mismatch. No manual testing applies yet. ### Phase 3 — Shared incremental renderer - [x] Add one shared helper in `src/gtd-calendar-webview.js`, tentatively `renderIncrementalCardList(cards, pageSize, detail, contentScriptId)`. - [x] Keep `visibleCount` in the helper's closure, initialized to `Math.min(pageSize, cards.length)`. - [x] Render cards through the existing `renderCard` function so styling and click-to-open behavior remain unchanged. - [x] On each click, increase `visibleCount` by `pageSize`, capped at the full card count, then render only the newly revealed cards or refresh the local list without affecting other buckets. - [x] Reuse the helper from `renderColumn` and `matrixQuadrant`; pass `payload.pageSize || 10` from both top-level renderers as a defensive fallback for stale payloads. - [x] Preserve the existing total-count text in every column/quadrant heading. - 2026-07-27 — Phase 3 complete. Added one incremental card-list helper and wired it to all three kanban columns and all four matrix quadrants. Each bucket owns independent closure state, initially renders one batch, appends one batch per click, removes the basic control when complete, and preserves total heading/stat counts. Validation: JavaScript syntax and `git diff --check` passed, `npx tsc --noEmit --skipLibCheck` passed, and 12 Jest suites passed with 164/164 tests. Full-file formatting was intentionally not applied because the legacy webview does not match the default formatter and doing so rewrites roughly 2,000 unrelated lines. Tooltip, accessibility association, and final CSS remain Phase 4; manual Joplin acceptance is deferred until then. ### Phase 4 — Control, summary popup, and accessibility - [x] Render "List more" as a real `button` with `type="button"`. - [x] Place the button outside card elements so its click cannot bubble into a card's note-open handler. - [x] Add a dedicated tooltip element whose text is generated from the remaining count with correct singular/plural wording (`1 more entry`, `N more entries`). - [x] Associate the button and tooltip with `aria-describedby` using a unique ID. - [x] Show the tooltip on both `:hover` and `:focus-visible`; do not rely only on the native `title` attribute. - [x] Add focused styles in `src/event-calendar.css` for the control, tooltip, positioning, keyboard focus, and light/dark theme compatibility. - [x] Update or remove the button and tooltip atomically after every expansion. - 2026-07-27 — Phase 4 complete. Added a real button, unique tooltip IDs, `aria-describedby`, exact singular/plural remaining counts, an updating accessible label, and pointer-hover/keyboard-focus popup behavior. New cards insert before the control so focus survives intermediate expansion; the control is removed only after the final batch. Added scoped, theme-aware CSS. Validation: JavaScript syntax, `npx tsc --noEmit --skipLibCheck`, and `git diff --check` passed; 12 Jest suites passed with 164/164 tests. Visual and keyboard behavior still requires manual Joplin acceptance after a current package is built. ### Phase 5 — Automated verification The current Jest configuration uses `jest-environment-node` and the webview is a browser IIFE with no DOM-test harness. This slice will not add a new DOM runtime solely for one interaction. Automated coverage will therefore focus on the stable configuration contract, while DOM behavior receives explicit manual acceptance. If implementation exposes a genuinely reusable pure batching helper without duplicating browser logic, add focused unit tests for it; otherwise do not create a test-only abstraction. - [x] Run focused parser tests for kanban and matrix configuration. - [x] Run the complete Jest suite and record suite/test totals. - [x] Run `npm run dist`, which includes the repository's full test/build/package workflow, and record the produced `.jpl` path. - [x] Run `git diff --check`. - [x] Re-run the repository-wide prohibited-reference audit. - 2026-07-27 — Phase 5 complete. Focused kanban/matrix validation passed 2/2 suites and 59/59 tests; the full suite passed 12/12 suites and 164/164 tests. JavaScript syntax, `npx tsc --noEmit --skipLibCheck`, and `git diff --check` passed. `npm run dist` archived the previous package to `build-archive/com.victorwiebe.joplin.plugin.gtd-calendar-0.7.0-20260727-150417.jpl` and created `publish/com.victorwiebe.joplin.plugin.gtd-calendar.jpl` (158,720 bytes, manifest version 0.7.0). The JPL tar contains all five expected runtime files, and its webview contains the `pageSize` and tooltip markers. Both prohibited-reference audits returned no matches. No browser-only test abstraction was added because the batching helper remains a DOM-owning closure; its visual and keyboard behavior stays within explicit manual acceptance. ### Phase 6 — Documentation - [x] Add `page-size` to the kanban and matrix option tables in README.md. - [x] Add examples showing the default and a custom batch size. - [x] Explain that expansion is per bucket, advances one batch per click, and resets on reload. - [x] Update SPEC.md with config validation, rendering ownership, and transient state semantics. - [x] Add an unreleased SLICE8 entry to CHANGELOG.md without changing the package version until release scope is decided. - 2026-07-27 — Phase 6 README work complete. Added `page-size` to both option tables, an explicit default kanban example, a custom matrix example, and the per-bucket expansion, remaining-count popup, full-total, and reload reset behavior. Updated the README test count to the current 164. README diff validation passed. SPEC.md and CHANGELOG.md were completed after Phase 7 acceptance; Phase 6 and SLICE8 are now complete. ### Phase 7 — Manual Joplin acceptance **PASSED — USER SIGN-OFF RECEIVED 2026-07-27.** All manual checks below passed against the Phase 5 package. Use a test dashboard that includes a kanban, Skeleton matrix, and Eisenhower matrix. Prepare buckets containing 0, 1, 10, 11, 20, and 21+ cards. - [x] Confirm 0–10 cards show no "List more" control. - [x] Confirm 11 cards show 10 initially and reveal the final card with one click. - [x] Confirm 21+ cards expand by exactly 10 per click with the default. - [x] Confirm a custom `page-size` changes both initial and subsequent batches. - [x] Confirm the hover and keyboard-focus popup always reports the exact number still hidden. - [x] Confirm expansion in one column/quadrant does not alter another. - [x] Confirm multiple blocks in one note maintain independent state. - [x] Confirm card order, styling, hover detail, recurrence glyphs, completion styling, and click-to-open behavior remain unchanged. - [x] Confirm headings and overall statistics retain full totals. - [x] Confirm reloading the rendered note resets every expanded bucket. - [x] Confirm invalid `page-size` values warn and render with the default of 10. - [x] Record user sign-off here; do not mark manual acceptance complete before confirmation. **Confirmed by user 2026-07-27: all passed.** - 2026-07-27 — User reported "all passed" for the complete Phase 7 checklist. ## Acceptance criteria SLICE8 is complete only when: - Every kanban column and matrix quadrant initially renders no more than its normalized `page-size`. - Every click reveals at most one further batch in only the selected bucket. - The remaining-count popup is exact and usable with pointer and keyboard. - Fully expanded buckets have no "List more" control. - Reloading resets expansion. - Full card collections, ordering, headings, statistics, navigation, styling, and warnings remain correct. - Focused tests, the full suite, and the production package build pass. - Manual Joplin acceptance is explicitly confirmed. ## Files expected to change - `src/Gtd/types.ts` - `src/Gtd/parseKanbanConfig.ts` - `src/Gtd/parseMatrixConfig.ts` - `src/index.ts` - `src/gtd-calendar-webview.js` - `src/event-calendar.css` - `src/tests/Gtd/kanban.test.ts` - `src/tests/Gtd/matrix.test.ts` - `README.md` - `SPEC.md` - `CHANGELOG.md` - `SLICE8.md` - `TASKS.md` ## Out of scope - Server-side pagination or lazy fetching from Joplin. - Persisting expanded state across reloads. - A global "expand all" control. - Limits for calendar, unscheduled, or Gantt views. - Notebook grouping from SLICE10. - Inclusion of normal note cards from SLICE9. ## Outcome and resume point SLICE8 is complete. `page-size` is implemented for kanban and matrix views, the current production JPL is in `publish/`, all 164 automated tests pass, and manual Joplin acceptance is signed off. Nothing remains in this slice; proceed to SLICE9.