Fix recurring event editing: restore proper update flow and fix API parameters
Fixed multiple issues with recurring event editing via modal that were causing
events to be created instead of updated, and API parameter mismatches.
Key fixes:
1. **Restore Update Flow**:
- Added original_uid tracking to EventCreationData to distinguish create vs update
- Modal now routes to update endpoints when editing existing events instead of always creating new ones
- Implemented dual-path logic in on_event_create callback to handle both operations
2. **Fix "This and Future" Updates**:
- Added occurrence_date field to EventCreationData for recurring event context
- Backend now receives required occurrence_date parameter for this_and_future scope
- Populated occurrence_date from event start date in modal conversion
3. **Fix Update Scope Parameters**:
- Corrected scope parameter mapping to match backend API expectations:
* EditAll: "entire_series" → "all_in_series"
* EditFuture: "this_and_future" (correct)
* EditThis: "this_event_only" → "this_only"
4. **Enhanced Backend Integration**:
- Proper routing between update_event() and update_series() based on event type
- Correct parameter handling for both single and recurring event updates
- Added missing parameters (exception_dates, update_action, until_date)
Result: All recurring event edit operations now work correctly:
- ✅ "Edit all events in series" updates existing series instead of creating new
- ✅ "Edit this and future events" properly handles occurrence dates
- ✅ "Edit this event only" works for single instance modifications
- ✅ No more duplicate events created during editing
- ✅ Proper CalDAV server synchronization maintained
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -412,6 +412,132 @@ pub fn App() -> Html {
|
||||
let create_event_modal_open = create_event_modal_open.clone();
|
||||
let auth_token = auth_token.clone();
|
||||
Callback::from(move |event_data: EventCreationData| {
|
||||
// Check if this is an update operation (has original_uid) or a create operation
|
||||
if let Some(original_uid) = event_data.original_uid.clone() {
|
||||
web_sys::console::log_1(&format!("Updating event via modal: {:?}", event_data).into());
|
||||
|
||||
create_event_modal_open.set(false);
|
||||
|
||||
// Handle the update operation using the existing backend update logic
|
||||
if let Some(token) = (*auth_token).clone() {
|
||||
let event_data_for_update = event_data.clone();
|
||||
wasm_bindgen_futures::spawn_local(async move {
|
||||
let calendar_service = CalendarService::new();
|
||||
|
||||
// Get CalDAV password from storage
|
||||
let password = if let Ok(credentials_str) =
|
||||
LocalStorage::get::<String>("caldav_credentials")
|
||||
{
|
||||
if let Ok(credentials) =
|
||||
serde_json::from_str::<serde_json::Value>(&credentials_str)
|
||||
{
|
||||
credentials["password"].as_str().unwrap_or("").to_string()
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
// Convert EventCreationData to update parameters
|
||||
let params = event_data_for_update.to_create_event_params();
|
||||
|
||||
// Determine if this is a recurring event update
|
||||
let is_recurring = matches!(event_data_for_update.recurrence, crate::components::event_form::RecurrenceType::Daily |
|
||||
crate::components::event_form::RecurrenceType::Weekly |
|
||||
crate::components::event_form::RecurrenceType::Monthly |
|
||||
crate::components::event_form::RecurrenceType::Yearly);
|
||||
|
||||
let update_result = if is_recurring && event_data_for_update.edit_scope.is_some() {
|
||||
// Use series update endpoint for recurring events
|
||||
let edit_action = event_data_for_update.edit_scope.unwrap();
|
||||
let scope = match edit_action {
|
||||
crate::components::EditAction::EditAll => "all_in_series".to_string(),
|
||||
crate::components::EditAction::EditFuture => "this_and_future".to_string(),
|
||||
crate::components::EditAction::EditThis => "this_only".to_string(),
|
||||
};
|
||||
|
||||
calendar_service
|
||||
.update_series(
|
||||
&token,
|
||||
&password,
|
||||
original_uid.clone(),
|
||||
params.0, // title
|
||||
params.1, // description
|
||||
params.2, // start_date
|
||||
params.3, // start_time
|
||||
params.4, // end_date
|
||||
params.5, // end_time
|
||||
params.6, // location
|
||||
params.7, // all_day
|
||||
params.8, // status
|
||||
params.9, // class
|
||||
params.10, // priority
|
||||
params.11, // organizer
|
||||
params.12, // attendees
|
||||
params.13, // categories
|
||||
params.14, // reminder
|
||||
params.15, // recurrence
|
||||
params.17, // calendar_path (skipping recurrence_days)
|
||||
scope,
|
||||
event_data_for_update.occurrence_date.map(|d| d.format("%Y-%m-%d").to_string()), // occurrence_date
|
||||
)
|
||||
.await
|
||||
} else {
|
||||
// Use regular update endpoint for single events
|
||||
calendar_service
|
||||
.update_event(
|
||||
&token,
|
||||
&password,
|
||||
original_uid.clone(),
|
||||
params.0, // title
|
||||
params.1, // description
|
||||
params.2, // start_date
|
||||
params.3, // start_time
|
||||
params.4, // end_date
|
||||
params.5, // end_time
|
||||
params.6, // location
|
||||
params.7, // all_day
|
||||
params.8, // status
|
||||
params.9, // class
|
||||
params.10, // priority
|
||||
params.11, // organizer
|
||||
params.12, // attendees
|
||||
params.13, // categories
|
||||
params.14, // reminder
|
||||
params.15, // recurrence
|
||||
params.16, // recurrence_days
|
||||
params.17, // calendar_path
|
||||
vec![], // exception_dates - empty for simple updates
|
||||
None, // update_action - None for regular updates
|
||||
None, // until_date - None for regular updates
|
||||
)
|
||||
.await
|
||||
};
|
||||
|
||||
match update_result {
|
||||
Ok(_) => {
|
||||
web_sys::console::log_1(&"Event updated successfully via modal".into());
|
||||
// Trigger a page reload to refresh events from all calendars
|
||||
if let Some(window) = web_sys::window() {
|
||||
let _ = window.location().reload();
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
web_sys::console::error_1(
|
||||
&format!("Failed to update event: {}", err).into(),
|
||||
);
|
||||
web_sys::window()
|
||||
.unwrap()
|
||||
.alert_with_message(&format!("Failed to update event: {}", err))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
web_sys::console::log_1(&format!("Creating event: {:?}", event_data).into());
|
||||
|
||||
// Save the selected calendar as the last used calendar
|
||||
|
||||
Reference in New Issue
Block a user