87 lines
5.0 KiB
Markdown
87 lines
5.0 KiB
Markdown
# SLICE 4 — gtd-gantt data layer
|
|
|
|
> **State-saving rule:** update this file immediately after EVERY completed task (tick the checkbox, update Status and Resume notes) and whenever pausing for input — automatically, without being asked. State on disk must always match reality.
|
|
|
|
## Status
|
|
**COMPLETE** (2026-07-15). Pure data layer landed; 140/140 tests pass;
|
|
`tsc --noEmit` clean. No rendering/index wiring yet — that is SLICE5.
|
|
|
|
Resolved open question (2026-07-15): dateless/invalid-date gantt items are
|
|
**excluded with a warning** (the recorded default) — no Unscheduled strip. If a
|
|
strip is wanted later it's an additive change to collectGantt + the payload.
|
|
|
|
## Goal
|
|
Pure data layer for the gantt: item opt-in parsing, project grouping,
|
|
collection, config parsing. No rendering yet.
|
|
|
|
## Design (agreed with user 2026-07-13)
|
|
- Items opt in with their own ```gtd-gantt fenced block (separate from ```gtd):
|
|
- **Notes** (bars): `project: bluesky`, `begin-date: yyyy-mm-dd`,
|
|
`end-date: yyyy-mm-dd` (accept same date formats as resolveDate.ts).
|
|
- **To-dos** (milestones): `project: bluesky`; the milestone date is the
|
|
to-do's native **due date**. begin/end on a to-do → warning, treated as
|
|
milestone anyway.
|
|
- Rows/swimlanes are grouped by `project:`.
|
|
- **Chart block vs item block disambiguation** (same fence name!): a
|
|
`gtd-gantt` block containing a `project:` key is an ITEM declaration;
|
|
without `project:` it is the CHART config block. The markdown-it renderer
|
|
must apply the same rule (SLICE5). Item blocks render as a small inline
|
|
badge ("gantt: bluesky"), not a chart.
|
|
- Chart config keys: `title`, `notebook`, `scope`, `filter-project`
|
|
(optional; limit to one project), `sort` / `sort-type` (row order within
|
|
project), `card-detail` semantics for hover text. Defaults follow the
|
|
existing parsers' conventions; invalid values warn + fall back.
|
|
- Semantics: completed to-do milestones render checked/struck (consistent
|
|
with calendar). Items with unparseable/missing dates → warning +
|
|
excluded (a gantt has no Unscheduled section — confirm with user if one
|
|
is wanted; see open questions).
|
|
- Reuse styling keys? Item gtd-gantt block also accepts `bg-colour`,
|
|
`fg-colour`, `title`, `text` mirroring the gtd block.
|
|
|
|
## Open questions for user (non-blocking, defaults chosen)
|
|
- Dateless gantt items: currently planned as warn+exclude. Alternative:
|
|
an "Unscheduled" strip like the calendar. DEFAULT: exclude with warning.
|
|
|
|
## Tasks
|
|
- [x] `src/Gtd/ganttBlock.ts` — `extractGanttBlock` mirrors gtdBlock.ts
|
|
(fence regex for `gtd-gantt`, same YAML/empty/malformed handling). Parses
|
|
project / begin-date / end-date + styling keys (bg-colour/fg-colour/title/
|
|
text). Classification is the caller's job via `block.project` (non-null ⇒
|
|
item, null ⇒ chart).
|
|
- [x] `src/Gtd/parseGanttConfig.ts` — chart config: title, scope (+ scope: all
|
|
+ notebook conflict warning), notebook, filter-project, sort, sort-type
|
|
(`begin-date`|`title`|`modified-date`), card-detail. Invalid → warn + default.
|
|
- [x] `src/Gtd/collectGantt.ts` — scope (scopeAll-aware) → fetch (always with
|
|
body) → item filter (project present, ≠ chart) → filter-project → bar vs
|
|
milestone → group by project → sort → compute range. Returns typed
|
|
`GanttChart { projects, rangeStart, rangeEnd, warnings, scannedFolders,
|
|
scannedNotes, itemCount }`.
|
|
Rules: notes → bars (begin+end required & valid, end≥begin else warn+exclude);
|
|
to-dos → milestones on their due date (begin/end on a to-do → warning;
|
|
no due date → warn+exclude); completed/recurring flags on milestones;
|
|
projects merged case-insensitively, output alphabetical.
|
|
- [x] Types in `src/Gtd/types.ts` — GanttSortType, GanttItemBlock,
|
|
GanttBlockResult, GanttConfig, GanttBar, GanttMilestone, GanttProject,
|
|
GanttChart.
|
|
- [x] Thorough unit tests — `src/tests/Gtd/gantt.test.ts` (20 cases): block
|
|
extraction (chart vs item, styling, Date coercion, malformed), config
|
|
(defaults/full/conflict/invalid), collector (grouping+range, ignore
|
|
chart/plain/host, bar bad/reversed dates, milestone due-date + begin/end
|
|
warning, milestone no-due-date, completed+recurring, filter-project,
|
|
begin-date sort + direction, case-insensitive project merge).
|
|
- [x] Full test run: **140 passed, 140 total** (12 suites) on 2026-07-15.
|
|
`tsc --noEmit` clean for src/.
|
|
|
|
## Resume notes
|
|
SLICE4 complete — pure data layer only. New files:
|
|
- `src/Gtd/ganttBlock.ts`, `parseGanttConfig.ts`, `collectGantt.ts`
|
|
- gantt types appended to `src/Gtd/types.ts`
|
|
- `src/tests/Gtd/gantt.test.ts`
|
|
|
|
NOT done here (belongs to SLICE5): the markdown-it renderer's chart-vs-item
|
|
disambiguation, the `getGantt` message handler in `src/index.ts`, and any
|
|
webview rendering. `collectGantt`'s signature mirrors the other collectors
|
|
(`adapter, hostNoteId, hostFolderId, config`) so index wiring will look like
|
|
handleGetKanban. Item blocks must render as a small inline badge (not a chart) —
|
|
that's a SLICE5 renderer concern. Next: SLICE5.
|