Fix modal series editing to use correct backend endpoint

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 <noreply@anthropic.com>
This commit is contained in:
Connor Johnstone
2025-08-31 19:06:11 -04:00
parent 5a12c0e0d0
commit 51d5552156

View File

@@ -996,8 +996,61 @@ pub fn App() -> Html {
web_sys::window().unwrap().alert_with_message("Cannot move event - original event missing calendar path").unwrap(); web_sys::window().unwrap().alert_with_message("Cannot move event - original event missing calendar path").unwrap();
} }
} else { } else {
// Calendar hasn't changed - normal update // Calendar hasn't changed - check if we should use series endpoint
match calendar_service.update_event( 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, &token,
&password, &password,
original_event.uid, 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(); web_sys::window().unwrap().alert_with_message(&format!("Failed to update event: {}", err)).unwrap();
} }
} }
}
} }
}); });
} }