From 51d55521561f4201c4c25a2f3bcec8e25e647d81 Mon Sep 17 00:00:00 2001 From: Connor Johnstone Date: Sun, 31 Aug 2025 19:06:11 -0400 Subject: [PATCH] Fix modal series editing to use correct backend endpoint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The modal update flow was calling the regular event update endpoint instead of the series endpoint, preventing proper handling of the three edit types (this event, this and future, all events). ## Changes: - Add logic to detect when edit_scope is set for recurring events - Route to update_series() when edit_scope is present and event has RRULE - Map EditAction enum to backend update_scope strings: - EditThis → "this_only" (creates exception + EXDATE) - EditFuture → "this_and_future" (new series + UNTIL on original) - EditAll → "all_in_series" (update existing series) - Pass occurrence date for single/future edits using original event date - Fall back to regular update_event() for non-recurring events Now the modal properly leverages the existing robust series endpoint that handles RFC 5545 compliant recurring event modifications. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- frontend/src/app.rs | 58 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/frontend/src/app.rs b/frontend/src/app.rs index 5c4580f..95da19b 100644 --- a/frontend/src/app.rs +++ b/frontend/src/app.rs @@ -996,8 +996,61 @@ pub fn App() -> Html { web_sys::window().unwrap().alert_with_message("Cannot move event - original event missing calendar path").unwrap(); } } else { - // Calendar hasn't changed - normal update - match calendar_service.update_event( + // Calendar hasn't changed - check if we should use series endpoint + let use_series_endpoint = updated_data.edit_scope.is_some() && original_event.rrule.is_some(); + + if use_series_endpoint { + // Use series endpoint for recurring event modal edits + let update_scope = match updated_data.edit_scope.as_ref().unwrap() { + EditAction::EditThis => "this_only", + EditAction::EditFuture => "this_and_future", + EditAction::EditAll => "all_in_series", + }; + + // For single occurrence edits, we need the occurrence date + let occurrence_date = if update_scope == "this_only" || update_scope == "this_and_future" { + // Use the original event's start date as the occurrence date + Some(original_event.dtstart.format("%Y-%m-%d").to_string()) + } else { + None + }; + + match calendar_service.update_series( + &token, + &password, + original_event.uid, + updated_data.title, + updated_data.description, + start_date, + start_time, + end_date, + end_time, + updated_data.location, + updated_data.all_day, + status_str, + class_str, + updated_data.priority, + updated_data.organizer, + updated_data.attendees, + updated_data.categories, + reminder_str, + recurrence_str, + updated_data.selected_calendar, + update_scope.to_string(), + occurrence_date, + ).await { + Ok(_) => { + web_sys::console::log_1(&"Series updated successfully".into()); + web_sys::window().unwrap().location().reload().unwrap(); + } + Err(err) => { + web_sys::console::error_1(&format!("Failed to update series: {}", err).into()); + web_sys::window().unwrap().alert_with_message(&format!("Failed to update series: {}", err)).unwrap(); + } + } + } else { + // Use regular event endpoint for non-recurring events or legacy updates + match calendar_service.update_event( &token, &password, original_event.uid, @@ -1033,6 +1086,7 @@ pub fn App() -> Html { web_sys::window().unwrap().alert_with_message(&format!("Failed to update event: {}", err)).unwrap(); } } + } } }); }