compass icon indicating copy to clipboard operation
compass copied to clipboard

⛰️ EPIC: Edit recurring events

Open tyler-dane opened this issue 1 year ago • 0 comments

Feature Description

As a user, I want to be able to change a recurring event in Compass, so that I can manage my schedule in one place.

This issue is just about editing existing recurring events, which the user previously created in their Google Calendar; You do not need to create recurring events in Compass as part of this issue.

Acceptance Criteria

GIVEN that a user has recurring events in Compass AND the user opens a recurring event and makes a change THEN the event(s) should update in Compass AND the event(s) should update in Google Calendar

Additional AC

  • [ ] Works for changing a single instance, this and future instances, and all instances
  • [ ] Includes unit tests for updating the recurrence rule

Implementation Guidance

Backend

  • DateTime changes to a single event does not change the recurrence(This Event)
  • DateTime changes using All Events or This and Following counts as recurrence changes.
graph TD
    CompassEvent[Compass Calendar Event]
    CompassRecurringEventInstances[Compass Calendar Recurring Event Instances]

    GCalEvent[Google Calendar Event]
    GCalRecurringEventInstances[Google Calendar Recurring Event Instances]

    IsRecurringCompassEvent{Is Recurring Event?}
    IsRecurringCompassEventYes[Yes]

    CompassEventRecurrenceChanged{Recurrence Changed?}
    CompassEventRecurrenceRemoved{Recurrence Removed?}
    GcalEventRecurrenceChanged{Recurrence Changed?}

    ThisEventNo[This Event]

    ThisAndFollowingEvents[This And Following Events]
    ThisAndFollowingEventsNo[This And Following Events]

    AllEvents[All Events]
    AllEventsNo[All Events]

    NoCompassEventRecurrenceChange[No]
    YesCompassEventRecurrenceChange[Yes]
    YesCompassEventRecurrenceRemoved[Yes]

    ExistingSeries[Existing Series]
    NewSeries[New Series]

    subgraph "Event Modification Flow"
        subgraph "Compass Calendar"
            CompassEvent --> CompassEventRecurrenceChanged
            CompassEvent --> CompassEventRecurrenceRemoved

            CompassEventRecurrenceRemoved --> YesCompassEventRecurrenceRemoved
            YesCompassEventRecurrenceRemoved --> IsRecurringCompassEvent
            IsRecurringCompassEvent --> IsRecurringCompassEventYes
            IsRecurringCompassEventYes --> |1.Delete| CompassRecurringEventInstances
            YesCompassEventRecurrenceRemoved --> |2.Update| CompassEvent

            CompassEventRecurrenceChanged --> NoCompassEventRecurrenceChange
            CompassEventRecurrenceChanged --> YesCompassEventRecurrenceChange

            NoCompassEventRecurrenceChange --> |Apply Changes to| ThisEventNo
            ThisEventNo --> |Update| CompassEvent

            NoCompassEventRecurrenceChange --> |Apply Changes to| ThisAndFollowingEventsNo
            ThisAndFollowingEventsNo --> |Update| CompassEvent
            ThisAndFollowingEventsNo --> |Update| CompassRecurringEventInstances

            NoCompassEventRecurrenceChange --> |Apply Changes to| AllEventsNo
            AllEventsNo --> |Update| CompassEvent
            AllEventsNo --> |Update| CompassRecurringEventInstances

            YesCompassEventRecurrenceChange --> |Apply Changes to| AllEvents
            AllEvents --> |1.Delete| CompassRecurringEventInstances
            AllEvents --> |2.Create| CompassRecurringEventInstances
            AllEvents --> |3.Update| CompassEvent

            YesCompassEventRecurrenceChange --> |Apply Changes to| ThisAndFollowingEvents
            ThisAndFollowingEvents --> |Split Series| ExistingSeries
            ThisAndFollowingEvents --> |Split Series| NewSeries
            ExistingSeries --> |1.Cancel After Until| CompassRecurringEventInstances
            ExistingSeries --> |2.Update Recurrence UNTIL|CompassEvent
            NewSeries --> |Create| CompassRecurringEventInstances
            NewSeries --> |3.Update| CompassEvent
        end

        CompassEvent --> |Updates| GCalEvent
        GCalEvent --> |Syncs With| CompassEvent
        GCalRecurringEventInstances --> |Syncs With| CompassRecurringEventInstances

        subgraph "Google Calendar"
            GCalEvent --> GcalEventRecurrenceChanged
            GcalEventRecurrenceChanged --> |Yes-Generates| GCalRecurringEventInstances
        end
    end

Compass Events Status

  • "confirmed" - The event is confirmed - event is not isSomeday.
  • "tentative" - The event is tentatively confirmed - event is isSomeday.
  • "cancelled" - The event is cancelled (deleted).

TODOS

  • Modify recurrence Options applyTo
    • Create Enum RecurrenceChangeType
      • This Event
      • This and Following Events
      • All Events
  • Generate Compass Events based on RecurrenceChangeType, update payload and http verb
  interface CompassEvent {
    id: string
    status: "confirmed" | "tenatative" | "cancelled" // status based on `isSomeday` and `http verb`
    ...
  }
  // include all whwn possible that can be use to discriminate event types: regular, standalone and recurring
  • Create a CompassEventParser modelled after the existing GcalEventParser that takes a CompassEvent
    • Event parsing should follow the rules defined in the "Event Modification Flow"
    • Parser should define event transitions similar to the ones defined in the GcalEventParser
  • Create a CompassSyncProcessor modelled after the existing `GcalSyncProcessor. and handle the following event scenarios
    • STANDALONE->>STANDALONE_CANCELLED
    • RECURRENCE_INSTANCE->>RECURRENCE_INSTANCE_CANCELLED
    • RECURRENCE_BASE->>RECURRENCE_BASE_CANCELLED
    • STANDALONE->>STANDALONE_CONFIRMED
    • RECURRENCE_INSTANCE->>RECURRENCE_INSTANCE_CONFIRMED
    • STANDALONE->>RECURRENCE_BASE_CONFIRMED
    • RECURRENCE_BASE->>STANDALONE_CONFIRMED
    • RECURRENCE_INSTANCE->>RECURRENCE_BASE_CONFIRMED
    • RECURRENCE_BASE->>RECURRENCE_BASE_CONFIRMED"
  • update the EventController.update method to use the CompassSyncProcessor to process the generated `CompassEvent

Frontend

Compass fields that trigger recurrence changes

  • startDate
  • endDate
  • recurrence.rule

Stories

  • Create the RecurringEventsUpdateScope component an html options form for selecting recurring event update changes
    • Option Values: This Event, This and Following Events, All Events
    • Form should emit selection changes
  • Generate recurrence rule for compass event
    • using the values from the RecurrenceSection component
    • Emit the recurrence rule
    • deprecate the generateRecurrenceDates method
    • update the compass event's recurrence field
  • Ask user to select recurrence update type before saving a compass instance event
    • Do not render the SaveSection component within the EventForm for recurrence instances
    • Open a toast popup containing the RecurringEventsUpdateScope and the SaveSection components
    • Update the events query payload to include the recurrence update type(applyTo)

Additional Context

We are gradually adding more support for recurring events in order to keep the PRs manageable. See for previous related work: #230, #225

https://developers.google.com/calendar/api/concepts/events-calendars#recurring_events

https://datatracker.ietf.org/doc/html/rfc5545

tyler-dane avatar Jan 25 '25 13:01 tyler-dane