Skip to content

feat: long-range timeline view and sprint numbering on the Schedule tab - #98

Merged
atman-33 merged 3 commits into
mainfrom
feature/T-0111-schedule-timeline
Aug 2, 2026
Merged

feat: long-range timeline view and sprint numbering on the Schedule tab#98
atman-33 merged 3 commits into
mainfrom
feature/T-0111-schedule-timeline

Conversation

@atman-33

@atman-33 atman-33 commented Aug 2, 2026

Copy link
Copy Markdown
Owner

What

Adds a Timeline mode to the Schedule tab — the long-range ("大日程") reading
of a schedule note — plus optional sprint numbering. Closes T-0111.

Mode Use Form
Calendar (default, unchanged) day-level planning continuous week grid
Timeline (new) month/quarter planning months across the top, phases as bands

Why this and not a separate feature

Long-range and day-level planning are the same plan at two scales. A separate
note format or tab would duplicate the elements, the non-working days, the
schedule-edit skill, the export and the conflict check — and leave two copies
of a plan with no rule for which is right. The note's notation already carries
everything a long-range chart needs; what was missing was the drawing.

The design note rejected a gantt-like form in §4, but for the day-level case
("the position of holidays is invisible"). At month scale that objection does
not apply, and the week grid does break down: half a year is 26 rows and a
three-month phase is cut into thirteen segments.

Notable decisions

  • Geometry as fractions of the window, not column indexes. A bar starting
    mid-week must start mid-column; a column coordinate system would misalign the
    bars, the rules, the sprint band and the today line against each other.
  • timeline.ts is DOM-free and rendered by both the React view and the HTML
    export, the same arrangement layout.ts already has with the calendar.
  • Column unit follows window length (weeks up to ~a quarter, months beyond)
    rather than adding a control nobody would set two ways for a given span.
  • Sprint cadence lives on the note (sprint_start / sprint_weeks, flat
    scalars) so 案A.md and 案B.md can compare different cadences. It is a
    reading of the calendar only — nothing rounds an element to a boundary, and
    days before sprint 1 are left unnumbered rather than given an S0.
  • Timeline drags are measured in days like the calendar's, with Shift
    snapping to whole weeks — the unit a long-range plan is actually adjusted in.
  • Task due dates are read-only ticks here; at month width a chip is wider than
    the month it belongs to. Nudging a due date stays on the calendar.

Files

New: src/lib/schedule/{timeline,sprint}.ts,
src/components/schedule/{timeline-grid,sprint-settings}.tsx.
Changed: parse.ts (sprint frontmatter round-trip), export.ts (mode),
schedule-view.tsx (mode switch, range presets). No backend change — the note
format is unchanged.

Docs: design note §17, vault CLAUDE.md, schedule template, schedule-edit
skill (plugin version bumped), Help tab, CHANGELOG, app version 0.68.0.

Verification

npm run build, npx vitest run (175 passed, incl. 36 new),
cargo fmt --check, cargo clippy --release --all-targets -- -D warnings,
cargo test --release (191 passed) all green. Visual check on the running app
is with the reviewer.

🤖 Generated with Claude Code

The Schedule tab could only draw a schedule note as the continuous week grid,
which answers "which days do I have" but turns a quarter into 26 rows and cuts
a three-month phase into thirteen segments. Long-range planning is drawn the
other way round: months across the top, phases as bands, milestones on the
line.

Add a Timeline mode alongside the calendar rather than a second feature. The
note, its elements, its non-working days, the AI editing and the export are
all shared -- the mode is a change of drawing, never of data. (The design
note's original rejection of a gantt-like form was about day-level planning,
where the position of holidays matters; at month scale it does not apply.)

Geometry is expressed as fractions of the window rather than column indexes,
so bars, column rules, sprint bands and the today line share one measure. It
lives in a DOM-free `timeline.ts` that the screen and the HTML export both
render, keeping the two from drifting apart.

A note may also declare a sprint cadence (`sprint_start` / `sprint_weeks`,
flat scalars the existing frontmatter parser already handles). It is stored on
the note, not in app settings, because comparing two plans with different
cadences is the point of the feature. Sprints are a reading of the calendar
only: nothing rounds an element to a boundary.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e8525d4d-88cf-44ef-9ffa-5e9f763647cd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

atman-33 and others added 2 commits August 2, 2026 16:38
…verlapping

Two problems found while checking the timeline on screen.

**New was dead under "All projects".** It gated on the project dropdown alone,
but a schedule belongs to exactly one project and an open note names it — so
"give me another plan like this one" required re-picking a project the open
file was already in. Resolve the target from the dropdown, falling back to the
open note, and show which project the new note lands in.

**The toolbar drew its controls on top of each other.** `DatePicker`'s trigger
is `w-full`, which is right for the form fields it was built for and means
"the whole toolbar" in a flex row; the row then overflowed and the range
collided with the buttons after it. This was latent before the timeline added
enough controls to expose it. Give the toolbar's pickers an explicit width,
mark the groups `shrink-0` so they wrap onto a second line instead of
colliding, and gather the range presets into one bordered group.

Also drop the ✕ from those two pickers: the handler ignores an empty value, so
it was a control that did nothing when pressed. `DatePicker` gains a
`clearable` prop (default true, unchanged for every other caller).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Moving the displayed range meant a modified wheel; grabbing the plan and
pulling it is the gesture people reach for first.

The right button already opens a context menu on both views, so the gesture is
arbitrated by travel rather than simply taken: a press that stays put is a
menu, a press that moves is a hand, and once it has become a hand that
gesture's `contextmenu` is swallowed. The suppression runs in the capture
phase at the grid root -- the menu's trigger sits below it, so an event that
bubbled back up would arrive after the menu had already begun opening.

The two views pan along the axis they flow in, with different quantization.
The timeline converts pointer travel through the track's width, so the day you
grabbed stays under the pointer; a week-snapped pan would only stutter under a
smooth gesture. The calendar pans vertically in whole weeks, because its
weekday columns must not shift, at a fixed rate rather than one tied to a row
-- row height depends on how many bar lanes a week needs, which would make the
plan pan faster over its empty stretches. Sub-unit remainders carry across
moves so a slow drag over a year-wide window still moves.

The gesture itself lives in one hook both views share; written twice it would
drift.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@atman-33
atman-33 merged commit 4328f11 into main Aug 2, 2026
2 checks passed
@atman-33
atman-33 deleted the feature/T-0111-schedule-timeline branch August 2, 2026 07:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant