347 lines
16 KiB
Markdown
347 lines
16 KiB
Markdown
# SLICE 9 — Include opted-in note cards in 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.** Phases 1–7 are complete. Automated validation, production packaging, and manual Joplin acceptance all passed.
|
||
|
||
## Goal
|
||
|
||
Allow ordinary Joplin notes (`is_todo: 0`) containing a `gtd` fenced block to
|
||
appear as cards in kanban and matrix views. Preserve existing to-do behavior and
|
||
continue excluding normal notes that have not explicitly opted in.
|
||
|
||
## Confirmed behavior
|
||
|
||
- A normal note is eligible only when `extractGtdBlock` reports `found: true`.
|
||
- An empty `gtd` block is a valid opt-in, matching existing calendar semantics.
|
||
- A malformed `gtd` block still opts the note in and surfaces the existing
|
||
warning; fallback card properties come from the source note.
|
||
- The existing `todos:` option continues to govern only to-dos. It does not
|
||
disable or broaden normal-note inclusion.
|
||
- No new `notes:` option is introduced in this slice.
|
||
- Kanban placement for normal notes:
|
||
- configured in-progress tag -> In Progress;
|
||
- otherwise -> Backlog;
|
||
- never -> Done.
|
||
- Matrix placement for normal notes:
|
||
- Eisenhower mode uses the existing important and urgent tags;
|
||
- Skeleton mode uses the existing in-progress tag plus urgent tag/date rules.
|
||
- A note date comes only from the `gtd` block. To-do date resolution remains
|
||
block date first, then `todo_due`.
|
||
- Note cards reuse block title, colours, icon, and text; missing values fall back
|
||
exactly as existing cards do.
|
||
- Normal notes are never completed and never show the recurring-to-do marker,
|
||
even if they happen to carry the configured recurrence tag.
|
||
- The host kanban/matrix note remains excluded from its own results.
|
||
- SLICE8 batching counts note and to-do cards together after final sorting.
|
||
|
||
## Inclusion decision table
|
||
|
||
| Item | `gtd` block | `todos:` | Kanban | Matrix |
|
||
|---|---:|---|---|---|
|
||
| Normal note | absent | any | excluded | excluded |
|
||
| Normal note | present/empty/malformed | any | included | included |
|
||
| To-do | absent | `gtd-only` | excluded | excluded |
|
||
| To-do | absent | `all` | included | included if incomplete |
|
||
| To-do | present | `gtd-only` or `all` | included | included if incomplete |
|
||
| To-do | any | `none` | excluded | excluded |
|
||
| Completed to-do | any included mode | any | Done-window rules | excluded |
|
||
|
||
## Architecture and data flow
|
||
|
||
```text
|
||
scoped RawNote
|
||
|
|
||
+-- host note? ------------------------------> exclude
|
||
|
|
||
+-- ordinary note
|
||
| extract gtd block
|
||
| absent -> exclude
|
||
| found -> build note card -> tags -> bucket
|
||
|
|
||
+-- to-do
|
||
existing todos/completion rules
|
||
-> extract block -> tags -> build card -> bucket
|
||
|
||
combined bucket -> existing sort -> SLICE8 incremental rendering
|
||
```
|
||
|
||
Collection remains responsible for eligibility, card normalization, tags,
|
||
bucketing, sorting, warnings, and totals. The webview should not need separate
|
||
rendering logic for note cards.
|
||
|
||
## Implementation plan
|
||
|
||
### Phase 1 — Card model and shared builder
|
||
|
||
- [x] Add an explicit card discriminator to `KanbanCard` in `src/Gtd/types.ts`,
|
||
preferably `isTodo: boolean`, so completion/recurrence rendering does not
|
||
infer item kind indirectly.
|
||
- [x] Extract duplicated kanban/matrix card construction into a small shared
|
||
helper only if doing so reduces real duplication without changing public
|
||
collector contracts.
|
||
- [x] For normal notes set:
|
||
- `isTodo: false`;
|
||
- `completed: false` and `completedTime: 0`;
|
||
- `isRecurring: false`;
|
||
- date via `resolveEventDate(note, block)`, which correctly ignores `todo_due`
|
||
for normal notes.
|
||
- [x] For to-dos preserve current completion and recurrence behavior and set
|
||
`isTodo: true`.
|
||
- [x] Update `renderCard` only as needed to choose a neutral note glyph when a
|
||
normal note has no custom icon; retain current checkbox glyphs for to-dos.
|
||
- [x] Decide and document the neutral fallback glyph during implementation using
|
||
an existing project-compatible symbol; do not alter custom icons.
|
||
|
||
### Phase 1 completion record
|
||
|
||
- Added `isTodo` to the shared card model and centralized kanban/matrix card
|
||
normalization in `buildKanbanCard`.
|
||
- Normal-note cards are forced incomplete and non-recurring; to-do completion,
|
||
recurrence, due-date, styling, and override behavior remain unchanged.
|
||
- The neutral fallback is `📄`, matching the existing calendar note glyph.
|
||
Custom icons still take precedence, and absent `isTodo` values retain the
|
||
legacy checkbox fallback for compatibility.
|
||
- Focused validation: 3 suites and 63 tests passed.
|
||
- Full validation: 13 suites and 168 tests passed.
|
||
- TypeScript validation and webview JavaScript syntax checks passed.
|
||
- No manual Joplin test is required for Phase 1 because normal-note collection
|
||
is not enabled until later phases.
|
||
|
||
### Phase 2 — Kanban eligibility and bucketing
|
||
|
||
- [x] Refactor the `collectKanban.ts` loop so host exclusion occurs first, then
|
||
item-kind-specific eligibility.
|
||
- [x] For to-dos, preserve `todos: none`, `gtd-only`, and `all` behavior exactly.
|
||
- [x] For normal notes, call `extractGtdBlock` and exclude only when no block is
|
||
found.
|
||
- [x] Surface malformed-block warnings for included notes with the existing
|
||
message format.
|
||
- [x] Fetch tags only after an item is eligible.
|
||
- [x] Bucket completed to-dos into Done using the existing done-window cutoff.
|
||
- [x] Bucket incomplete to-dos and normal notes by the configured in-progress
|
||
tag; untagged eligible notes go to Backlog.
|
||
- [x] Sort the combined note/to-do arrays with the existing configured sorter.
|
||
|
||
### Phase 2 completion record
|
||
|
||
- Kanban eligibility now branches by item kind after host-note exclusion.
|
||
- Ordinary notes require a found `gtd` block; to-dos retain the existing
|
||
`none`, `gtd-only`, and `all` rules.
|
||
- Eligible note cards use existing warning, tag, bucketing, sorting, styling,
|
||
count, and navigation paths. They can enter Backlog or In Progress, never Done.
|
||
- Tag lookup occurs only after eligibility is established.
|
||
- Focused validation: 2 suites and 38 tests passed.
|
||
- Full validation: 13 suites and 174 tests passed.
|
||
- TypeScript, whitespace, and prohibited-reference checks passed.
|
||
- Phase 4 still must request bodies in `todos: none` mode before opted-in notes
|
||
work with that setting against the Joplin data adapter.
|
||
- No manual Joplin test is required yet; mixed-view acceptance remains Phase 7.
|
||
|
||
### Phase 3 — Matrix eligibility and bucketing
|
||
|
||
- [x] Apply the same host, item-kind, and shortcode eligibility split in
|
||
`collectMatrix.ts`.
|
||
- [x] Preserve completed-to-do exclusion.
|
||
- [x] Allow eligible normal notes through because they have no completion state.
|
||
- [x] Fetch tags only after eligibility is established.
|
||
- [x] Reuse the current Eisenhower tag axes without note-specific exceptions.
|
||
- [x] Reuse the current Skeleton active/due-soon rules; dateless normal notes
|
||
naturally fall into the not-due-soon column unless marked urgent.
|
||
- [x] Sort combined note/to-do quadrant arrays with the existing sorter.
|
||
|
||
### Phase 3 completion record
|
||
|
||
- Matrix eligibility now branches by item kind after host-note exclusion.
|
||
- Completed to-dos remain excluded; ordinary notes require a found `gtd` block
|
||
and are not excluded by to-do completion fields.
|
||
- Eligible notes reuse the existing Eisenhower and Skeleton axes, sorting,
|
||
warnings, tags, styling, totals, and navigation paths.
|
||
- `todos: none` continues to exclude only to-dos at the collector level.
|
||
- Tag lookup occurs only after eligibility is established.
|
||
- Focused validation: 2 suites and 37 tests passed.
|
||
- Full validation: 13 suites and 176 tests passed.
|
||
- TypeScript, webview syntax, whitespace, and prohibited-reference checks passed.
|
||
- Phase 4 still must request bodies in `todos: none` mode for the real Joplin
|
||
adapter; the collector contract itself is covered.
|
||
- No manual Joplin test is required yet; mixed-view acceptance remains Phase 7.
|
||
|
||
### Phase 4 — Body-fetch contract
|
||
|
||
Normal-note eligibility can be known only by reading the body. Consequently,
|
||
kanban and matrix collectors must request bodies for every scanned folder even
|
||
when `todos: none`. The previous `needsBody = config.todos !== "none"`
|
||
optimization is no longer valid for these two views.
|
||
|
||
- [x] Set `includeBody: true` for kanban and matrix folder-note fetches.
|
||
- [x] Update collector comments so they no longer claim `todos: none` guarantees
|
||
an empty board.
|
||
- [x] Update `src/tests/Gtd/fieldsHint.test.ts` to expect body fetches in all
|
||
kanban/matrix modes.
|
||
- [x] Leave calendar and Gantt body-fetch behavior unchanged.
|
||
- [x] Document this intentional performance tradeoff in SPEC.md: explicit note
|
||
opt-in requires body inspection, but tag requests remain limited to
|
||
eligible items.
|
||
|
||
### Phase 4 completion record
|
||
|
||
- Kanban and matrix now request bodies for every in-scope note, including under
|
||
`todos: none`, so ordinary-note `gtd` opt-in can always be evaluated.
|
||
- Calendar body-fetch behavior remains unchanged; Gantt code was not modified.
|
||
- Tag requests remain deferred until an item passes eligibility.
|
||
- `fieldsHint.test.ts` now records the new board contract in all to-do modes.
|
||
- SPEC.md documents the intentional performance tradeoff.
|
||
- Focused validation: 3 suites and 76 tests passed.
|
||
- Full validation: 13 suites and 176 tests passed.
|
||
- TypeScript, webview syntax, whitespace, and prohibited-reference checks passed.
|
||
- No manual Joplin test is required for this data-fetch contract; mixed-view
|
||
acceptance remains Phase 7.
|
||
|
||
### Phase 5 — Automated tests
|
||
|
||
#### Kanban
|
||
|
||
- [x] Include a normal note with a valid block.
|
||
- [x] Include a normal note with an empty block.
|
||
- [x] Include a malformed-block note and retain its warning.
|
||
- [x] Exclude a normal note without a block.
|
||
- [x] Exclude the host note even when it has a block.
|
||
- [x] Place tagged notes in In Progress and untagged notes in Backlog.
|
||
- [x] Prove normal notes never enter Done and never become recurring.
|
||
- [x] Preserve all `todos:` modes and done-window behavior.
|
||
- [x] Verify mixed sorting for due date, title, and modified date.
|
||
|
||
#### Matrix
|
||
|
||
- [x] Cover all four Eisenhower quadrants with normal notes.
|
||
- [x] Cover Skeleton active/inactive and due-soon/not-due-soon combinations.
|
||
- [x] Cover dateless and explicitly urgent normal notes.
|
||
- [x] Include empty and malformed blocks; exclude absent blocks and the host.
|
||
- [x] Preserve completed-to-do exclusion and all `todos:` modes.
|
||
- [x] Verify mixed sorting for due date, title, and modified date.
|
||
|
||
#### Shared/integration contracts
|
||
|
||
- [x] Update existing `KanbanCard` fixtures for the item discriminator.
|
||
- [x] Verify tags are not requested for ineligible plain notes or excluded to-dos.
|
||
- [x] Verify `cardCount` includes all eligible note and to-do cards once.
|
||
- [x] Verify SLICE8 works on the combined ordered arrays without renderer changes.
|
||
- [x] Run focused kanban, matrix, and fields-hint suites.
|
||
- [x] Run the complete Jest suite and record suite/test totals.
|
||
- [x] Run `npm run dist` and record the produced `.jpl` path.
|
||
- [x] Run `git diff --check` and the prohibited-reference audit.
|
||
|
||
### Phase 5 completion record
|
||
|
||
- Added comprehensive mixed note/to-do coverage for valid, empty, malformed,
|
||
absent, and host-note blocks.
|
||
- Covered kanban placement, both matrix modes, all to-do modes, completion and
|
||
recurrence invariants, source IDs, warnings, and exact card totals.
|
||
- Verified mixed due-date, title, and modified-date sorting.
|
||
- Verified `page-size: 1` does not truncate complete collector arrays or totals;
|
||
existing SLICE8 rendering consumes those combined arrays unchanged.
|
||
- Focused validation: 4 suites and 89 tests passed.
|
||
- Full validation: 13 suites and 185 tests passed.
|
||
- TypeScript validation passed.
|
||
- Production build passed: `publish/com.victorwiebe.joplin.plugin.gtd-calendar.jpl`
|
||
(155 KB; SHA-256
|
||
`7257bb2bdbb8340539cdad3f88a2ac5f8b55bfa960816f16e472e047311db1cc`).
|
||
- `git diff --check` and the prohibited-reference audit passed.
|
||
- No manual Joplin acceptance was performed; that remains Phase 7.
|
||
|
||
### Phase 6 — Documentation
|
||
|
||
- [x] Update README.md kanban and matrix sections with a normal-note example.
|
||
- [x] State clearly that normal notes require a `gtd` block and that `todos:`
|
||
controls only to-dos.
|
||
- [x] Document kanban placement, both matrix placement modes, note date rules,
|
||
malformed/empty block behavior, and fallback glyph behavior.
|
||
- [x] Update SPEC.md inclusion tables, collection flow, card model, and body-fetch
|
||
tradeoff.
|
||
- [x] Add an unreleased SLICE9 entry to CHANGELOG.md without changing the package
|
||
version until release scope is decided.
|
||
|
||
### Phase 6 completion record
|
||
|
||
- README.md now documents ordinary-note opt-in, kanban placement, both matrix
|
||
modes, note dates, `todos:` isolation, empty/malformed blocks, fallback
|
||
glyphs, custom icons, and clickable source-note behavior.
|
||
- SPEC.md now records the inclusion table, shared card model, collection flow,
|
||
rendering rules, body-fetch tradeoff, and completed unreleased feature.
|
||
- CHANGELOG.md includes the unreleased SLICE9 feature and validation results
|
||
without changing the package version.
|
||
- The strict prohibited-reference and contradictory-wording audits passed.
|
||
|
||
### Phase 7 — Manual Joplin acceptance
|
||
|
||
Use mixed views containing ordinary notes, incomplete to-dos, completed to-dos,
|
||
empty blocks, malformed blocks, and plain notes.
|
||
|
||
**Acceptance package:** `publish/com.victorwiebe.joplin.plugin.gtd-calendar.jpl`
|
||
(SHA-256
|
||
`7257bb2bdbb8340539cdad3f88a2ac5f8b55bfa960816f16e472e047311db1cc`).
|
||
|
||
**Accepted:** the user reported all manual checks passed on 2026-07-27.
|
||
|
||
- [x] Confirm only opted-in normal notes appear.
|
||
- [x] Confirm empty blocks opt in and malformed blocks warn without disappearing.
|
||
- [x] Confirm normal-note Backlog/In Progress placement on kanban.
|
||
- [x] Confirm normal notes never appear in Done.
|
||
- [x] Confirm all four quadrants in both matrix modes behave as specified.
|
||
- [x] Confirm block title/date/colour/icon/text overrides render on normal notes.
|
||
- [x] Confirm neutral note glyph and custom-icon precedence.
|
||
- [x] Confirm normal notes do not show completion or recurrence styling.
|
||
- [x] Confirm clicking note cards opens the correct source note.
|
||
- [x] Confirm `todos: none`, `gtd-only`, and `all` still affect only to-dos.
|
||
- [x] Confirm SLICE8 limits and remaining counts include the mixed card total.
|
||
- [x] Confirm sorting, warnings, headings, statistics, and reload behavior.
|
||
- [x] Record user sign-off here; do not mark manual acceptance complete before
|
||
confirmation.
|
||
|
||
## Acceptance criteria
|
||
|
||
SLICE9 is complete only when:
|
||
|
||
- Every normal note with a found `gtd` block appears exactly once in its expected
|
||
bucket, while every plain normal note remains excluded.
|
||
- Existing to-do inclusion, completion, recurrence, done-window, and matrix rules
|
||
remain unchanged.
|
||
- Note styling, dates, navigation, warnings, totals, and sorting are correct.
|
||
- Mixed arrays obey SLICE8 batching without special renderer branches.
|
||
- 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/collectKanban.ts`
|
||
- `src/Gtd/collectMatrix.ts`
|
||
- Optional shared card-builder module if justified by implementation
|
||
- `src/gtd-calendar-webview.js`
|
||
- `src/tests/Gtd/kanban.test.ts`
|
||
- `src/tests/Gtd/matrix.test.ts`
|
||
- `src/tests/Gtd/fieldsHint.test.ts`
|
||
- `README.md`
|
||
- `SPEC.md`
|
||
- `CHANGELOG.md`
|
||
- `SLICE9.md`
|
||
- `TASKS.md`
|
||
|
||
## Out of scope
|
||
|
||
- Including normal notes that lack a `gtd` block.
|
||
- Adding a general `notes: all` or `notes: none` option.
|
||
- Giving normal notes a completion workflow.
|
||
- Editing notes or tags from a kanban/matrix card.
|
||
- Changing calendar or Gantt inclusion behavior.
|
||
- Child-notebook grouping from SLICE10.
|
||
|
||
## Dependency and resume point
|
||
|
||
Implement after SLICE8. Start with collector tests and the explicit card-kind
|
||
model, then change eligibility/body fetching. Finish automated regression checks
|
||
before documentation and manual acceptance. |