4.5 KiB
SLICE 5 — gtd-gantt rendering
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). All rendering code landed; 140/140 unit tests pass;
tsc clean; npm run dist builds the .jpl. User manually verified in Joplin
desktop. README + SPEC gantt docs added (beyond the original task list, at user
request). No automated front-end tests (per the earlier webview-testing
decision; disambiguation mirrors the unit-tested collectGantt).
Goal
Render the gantt in the webview: fence interception, message plumbing, DOM, CSS.
Tasks
src/gtd-calendar-renderer.ts: interceptsgtd-ganttfences. A block with a non-emptyproject:value (cheap regexGANTT_PROJECT_LINE, no YAML lib) → inline<span class="gtd-gantt-badge">gantt: <project></span>; otherwise emits the chart placeholder (data-block-type="gantt"). Project value is HTML-escaped and unquoted. Empty-project alignment matches collectGantt (empty ⇒ chart).src/index.ts:handleGetGantt+getGanttswitch case, mirroring handleGetKanban (parse → selectedNote → resolveScanFolder → collectGantt → payload with title/cardDetail/scopeAll/configError/warnings+softcap/chart/ stats). No-selectedNote path returns an empty chart.src/gtd-calendar-webview.js:renderGantt+buildGanttGridand helpers (offsetDays, clampOffset, monthTicks, todayLocalISO, tooltips). Single CSS grid: label column (sticky) +repeat(totalDays, 26px); month tick header row; project header rows; bars viagrid-columnfrom day offsets (bg/fg colour orcolourFromIdhash); milestones as ◆ markers (done → dimmed + struck label, ↻ for recurring); today line spanning body rows; click → openNote; hover text via nativetitle(suppressed when card-detail:none); title/configError/warnings/stats blocks as in other views (stats footnote carries the scope: all marker).src/event-calendar.css:.gtd-gantt-*styles (badge, scroll container, grid, sticky corner/labels, ticks, bars, milestones, today line), using the same rgba/theme-var conventions as existing styles.- Manual verification in Joplin desktop — CONFIRMED 2026-07-15. Verified
live: item-block badge (
gantt: bluesky) renders inline (not a chart); chart renders with title, month tick header, alphabetical project header (bluesky (3)), a note bar spanning begin→end (Jul 1–14), ◆ milestones on to-do due dates, and the red today line at Jul 15. Footnote reports item/note/folder counts. Host-note exclusion confirmed (an item block in the chart's own note is correctly omitted — put items in separate notes). Unknown-option warning fires correctly for stray keys liketodos(gantt has no notes/todos inclusion option). - Docs (added at user request; not in the original task list): README gantt section (item vs chart, bar/milestone rules, chart options table) + SPEC.md §2.5 (dual-role disambiguation rule, item/chart schemas). Screenshots not committed — verified interactively instead.
Resume notes
Code complete. Files touched:
src/gtd-calendar-renderer.ts(gantt fence + badge/chart disambiguation)src/index.ts(handleGetGantt + switch case + imports)src/gtd-calendar-webview.js(dispatch + renderGantt/buildGanttGrid + helpers)src/event-calendar.css(.gtd-gantt-* styles)
Design choices worth noting for a resumed session:
- Grid layout is a single
display:gridwith explicit gridRow/gridColumn per element (label col = 1, day columns = 2..N+1). Bars:grid-column: off+2 / endOff+3(inclusive end). Milestones:off+2 / span 1. Today line:grid-row: 1 / <rowIndex>at the today column. - Hover uses native
titletooltips (not the calendar's hover-card DOM) — simpler and reliable; revisit if richer hover cards are wanted. card-detail:none suppresses tooltips; "always" currently behaves like "hover" (no inline text on bars) — a possible future refinement, noted but out of scope. - No automated renderer/webview tests by design (front-end testing deferred, per the SLICE-boundary discussion). Disambiguation regex mirrors the unit-tested collectGantt classification.
Next after manual sign-off: SLICE6.