Skip to content

Full recurrence implementation #21

@sylvinus

Description

@sylvinus

What works today

  • Create recurring events with DAILY/WEEKLY/MONTHLY/YEARLY, INTERVAL,
    BYDAY, BYMONTHDAY, BYMONTH, COUNT, UNTIL via RecurrenceEditor component
  • Edit recurring events (modifies the entire series)
  • Delete with three options: this occurrence (EXDATE), this & future
    (modifies UNTIL), or all (deletes event)
  • CalDAV expansion — backend uses expand=True so recurring instances
    show as individual events in the calendar view
  • EXDATE handlingCalDavService.addExdateToEvent() correctly adds
    exception dates matching the event's date format (DATE vs DATE-TIME)
  • Recurrence propagationEventCalendarAdapter copies the source
    event's recurrenceRule to expanded instances so the UI knows they're
    recurring
  • Helper functionshasRecurrence(), isRecurringInstance(),
    describeRecurrence() exist in event-calendar-helper.ts with unit tests

What's missing

1. Edit single instance vs entire series (high priority)

When editing a recurring event (via modal, drag-and-drop, or resize), the
entire series is modified. There is no prompt asking "Edit this occurrence
only" or "Edit all events in the series."

What needs to happen:

  • When opening a recurring instance for edit, show a modal similar to
    DeleteEventModal asking: "This event" / "This and future events" /
    "All events"
  • "This event" should create a new VEVENT with RECURRENCE-ID matching
    the occurrence date (override instance) + add EXDATE to the parent
  • "All events" should update the source event (current behavior)
  • "This and future events" should split the series: truncate the original
    with UNTIL, create a new recurring event starting from the edited
    occurrence
  • handleEventDrop and handleEventResize in useSchedulerHandlers.ts
    currently have no recurring instance check — they silently modify the
    whole series. They need the same this/all prompt.

Files involved:

  • useSchedulerHandlers.tshandleEventDrop, handleEventResize,
    handleModalSave
  • CalDavService.ts — needs a method to create override instances
    (RECURRENCE-ID)
  • New component or extend DeleteEventModal into a generic
    RecurringEditModal

2. Recurring event indicator in calendar view (medium priority)

There is no visual indicator on the calendar that an event is recurring. The
describeRecurrence() helper exists and is tested but is not used anywhere
in the UI.

  • Show a repeat icon or recurrence summary on recurring events in the
    calendar grid
  • Optionally show the recurrence description (e.g. "Every 2 weeks") in
    the event tooltip or detail view

3. BYSETPOS patterns (low priority)

The RecurrenceEditor does not support positional patterns like "1st Monday
of month" or "last Friday of month." This requires BYSETPOS in the RRULE.

  • Add UI for position selection (1st, 2nd, 3rd, 4th, last) combined with
    weekday selection
  • Wire to BYSETPOS + BYDAY in the recurrence rule

4. No frontend tests for RecurrenceEditor (medium priority)

There are no unit tests for the RecurrenceEditor component itself. The only
recurrence-related tests are for helper functions in
event-calendar-helper.test.ts.

  • Add tests for RecurrenceEditor rendering and interactions
  • Add tests for recurrence flow in useEventForm (setting/clearing
    recurrence)
  • Add e2e test for creating and deleting a recurring event

5. No natural language recurrence summary in event modal (low priority)

When editing an existing recurring event, the recurrence section shows the
raw editor controls. There is no human-readable summary like "Repeats every
2 weeks on Monday and Friday, 10 times."

  • Use describeRecurrence() (already implemented) to show a summary
    in the event modal or as a collapsed preview of the recurrence section

6. Unsupported RRULE properties silently dropped on edit (high priority)

The RecurrenceEditor does not display or manage BYSETPOS, WKST,
BYYEARDAY, or BYWEEKNO. When editing an event that has these properties:

  • Custom mode: properties are preserved via ...value spread (safe)
  • Simple mode presets (Daily/Weekly/Monthly/Yearly/None): a new object
    is built with only the known fields — BYSETPOS, WKST, BYYEARDAY,
    BYWEEKNO are silently dropped, changing the recurrence pattern
    without any warning

This can happen when editing events imported from other calendar apps
(Outlook, Google Calendar) that use positional patterns like "1st Monday
of month" (BYDAY=MO;BYSETPOS=1).

Minimal fix:

  • When the incoming recurrenceRule contains properties the editor
    can't represent (bySetPos, weekStart, byYearDay, byWeekNo),
    show a warning: "This event has a recurrence pattern that can't be
    fully edited here. Saving may simplify it."
  • Alternatively, preserve all unknown properties in both code paths
    (pass them through in handleSimpleChange too)

Files: RecurrenceEditor.tsx lines 169-178 (handleSimpleChange)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions