From 7e42d2dedff58cd7e447a701693d9cf0c9f9011b Mon Sep 17 00:00:00 2001 From: Matthieu MALVACHE Date: Sun, 22 Feb 2026 17:50:53 +0100 Subject: [PATCH] fix(calendar): produce correct JMAP patch when removing recurrence rules When editing a recurring event and clearing its recurrence, the update patch was omitting recurrenceRules entirely instead of setting it to null. The server never received the change. Also clear recurrenceOverrides and excludedRecurrenceRules so orphaned exceptions don't persist. Same fix applied to locations and alerts removal. Fix "this_and_future" scope overriding recurrence removal by reordering the spread so user updates take precedence over master's original rules. Closes root-fr/jmap-webmail#14 --- app/[locale]/calendar/page.tsx | 2 +- components/calendar/event-modal.tsx | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/[locale]/calendar/page.tsx b/app/[locale]/calendar/page.tsx index 5dfb7a1..1567ac8 100644 --- a/app/[locale]/calendar/page.tsx +++ b/app/[locale]/calendar/page.tsx @@ -349,9 +349,9 @@ export default function CalendarPage() { freeBusyStatus: master.freeBusyStatus, privacy: master.privacy, showWithoutTime: master.showWithoutTime, + recurrenceRules: originalRules, ...updates, start: updates.start || occurrenceStart, - recurrenceRules: originalRules, }; delete (newEventData as Record).id; delete (newEventData as Record).uid; diff --git a/components/calendar/event-modal.tsx b/components/calendar/event-modal.tsx index 89dafcf..7b8977f 100644 --- a/components/calendar/event-modal.tsx +++ b/components/calendar/event-modal.tsx @@ -237,6 +237,8 @@ export function EventModal({ relativeTo: null, }, }; + } else if (isEdit && event?.locations && Object.keys(event.locations).length > 0) { + data.locations = null; } if (recurrence !== "none") { @@ -259,6 +261,10 @@ export function EventModal({ count: null, until: null, }]; + } else if (isEdit && event?.recurrenceRules?.length) { + data.recurrenceRules = null; + if (event.recurrenceOverrides) data.recurrenceOverrides = null; + if (event.excludedRecurrenceRules) data.excludedRecurrenceRules = null; } if (alert !== "none") { @@ -272,6 +278,8 @@ export function EventModal({ relatedTo: null, }, }; + } else if (isEdit && event?.alerts && Object.keys(event.alerts).length > 0) { + data.alerts = null; } if (attendees.length > 0 && currentUserEmails.length > 0) {