Skip to content

fix(calendar): show occurrence dates read-only on list cards (#2503) - #2505

Merged
callumalpass merged 3 commits into
mainfrom
fix/2503-projected-occurrence-chips
Nov 5, 2026
Merged

callumalpass merged 3 commits into
mainfrom
fix/2503-projected-occurrence-chips

Conversation

@callumalpass

@callumalpass callumalpass commented Nov 5, 2026 •

Copy link
Copy Markdown
Owner

Refs #2503

Problem

In a Bases calendar in list mode, and the Agenda view, which uses the same cards, each occurrence other than the pending one got a card built from the series task. Reproduced on 106a0551e in an isolated Obsidian with scheduled: 2026-11-08 and a weekly rule:

  • The card under 15 Nov read scheduled: Nov 8, and past occurrences did the same.
  • Its chip was the normal edit-date control. Choosing Tomorrow on that card wrote scheduled: 2026-11-06 and recurrence_original_date: 2026-11-08, moving the current occurrence.
  • A due chip behaved the same way.
  • A second report on the issue covers a timed daily series with matching scheduled and due: every row showed the first occurrence's date, marked past and overdue. Reproduced on unfixed main (Received: scheduled: Nov 4 19:00 (past)).

Change

  • Cards for pattern and recorded occurrences now get occurrenceScheduled, built from the instanceDate and recurringTemplateTime the model already provides, using the model's own placement rule.
  • That date renders as read-only text. Clicking it reaches the card, as a click anywhere else on the card does.
  • Past state comes from the occurrence's own complete_instances and skipped_instances, not the series' status, so a completed or skipped past occurrence is not marked as past.
  • The series' due date is left off these cards.
  • The pending occurrence and occurrence notes are unchanged.

Why read-only

There is no single-occurrence move to reuse. A pattern drop only rewrites DTSTART's clock for the whole series and ignores the target date. recurrence_original_date holds one identity, for the pending occurrence. The model and docs say gestures never materialize a note. Acting on the occurrence would therefore be a new feature, and the existing way to give one occurrence its own dates is an occurrence note.

Why no due date

The model treats due as a standalone deadline rather than projecting it onto each recurrence date, so a projected occurrence has no due date of its own. The series' due date still appears on the pending card and as its own calendar row.

Testing

  • e2e/issues/issue-2503-projected-occurrence-dates.spec.ts: fails on the unfixed build (Received: scheduled: Nov 8) and passes with the fix. It includes a control that the pending occurrence's chip still moves it, and a timed daily series, where the pending occurrence alone stays past and overdue.
  • Unit tests for which rows get an occurrence date, read-only rendering, and unresolved, completed and skipped past occurrences.
  • npm run lint, npm run typecheck, the full Jest suite and check:bundle-size pass. So do the related e2e specs (calendar-batch, 685, 983, pr-2492); 603 and 921 are test.fixme, so they skipped.
  • Not run: check-docs.mjs, because the docs/spec submodule isn't checked out in this worktree.

Not changed here

These are the same class of problem but need separate decisions or fixes:

  • The ⋮ menu on a projected list card has no occurrenceDate. From the 15 Nov card, Skip instance recorded skipped_instances: [2026-11-08] and advanced the series. The docs say a selected pattern instance acts on its own date, and the grid's right-click menu already passes occurrenceDate. The Mark complete options are built without it too, but were not tested.
  • The menu's Scheduled date and Due date items still edit the series, from both list cards and grid events.

Calendar list and Agenda cards for occurrences other than the pending one
were built from the series task, so they showed its dates and their chips
wrote to the series. Selecting a date on a later occurrence's card moved
the current occurrence.

Those cards now show their own occurrence's scheduled date as read-only
text and leave out the series' due date, which the model treats as a
standalone deadline. The calendar has no way to move one projected
occurrence: a pattern drop edits DTSTART's clock for the whole series, and
gestures never materialize a note.
…2503)

The read-only chip still took completion from the series' status, so a
completed or skipped past occurrence was marked as past. Use the
occurrence's own complete_instances and skipped_instances, as the card's
state already does.

Adds an e2e case for a timed daily series with matching scheduled and due
dates, reported on the issue by a second user.
…currence-chips

# Conflicts:
#	docs/releases/unreleased.md
@callumalpass
callumalpass merged commit 1a17a01 into main Nov 5, 2026
3 checks passed
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