⛰️ EPIC: Edit recurring events
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 EventsorThis and Followingcounts 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
- Create Enum
- 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
CompassEventParsermodelled after the existingGcalEventParserthat takes aCompassEvent- 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
CompassSyncProcessormodelled 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.updatemethod to use theCompassSyncProcessorto process the generated `CompassEvent
Frontend
Compass fields that trigger recurrence changes
- startDate
- endDate
- recurrence.rule
Stories
- Create the
RecurringEventsUpdateScopecomponent anhtml optionsform 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
generateRecurrenceDatesmethod - update the compass event's recurrence field
- Ask user to select recurrence update type before saving a compass instance event
- Do not render the
SaveSectioncomponent within theEventFormfor recurrence instances - Open a toast popup containing the
RecurringEventsUpdateScopeand theSaveSectioncomponents - Update the events query payload to include the recurrence update type(
applyTo)
- Do not render the
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