Complete CreateEventModalV2 integration and fix styling
All checks were successful
Build and Push Docker Image / docker (push) Successful in 1m11s
All checks were successful
Build and Push Docker Image / docker (push) Successful in 1m11s
- Replace CreateEventModal with new modular CreateEventModalV2 throughout app - Fix compilation errors by aligning event_form types with create_event_modal types - Add missing props (initial_start_time, initial_end_time) to modal interface - Fix styling issues: use tab-navigation class and add modal-body wrapper - Remove duplicate on_create prop causing compilation failure - All recurrence options now properly positioned below repeat/reminder pickers 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
use crate::components::{
|
||||
CalendarContextMenu, ContextMenu, CreateCalendarModal, CreateEventModal, DeleteAction,
|
||||
CalendarContextMenu, ContextMenu, CreateCalendarModal, CreateEventModalV2, DeleteAction,
|
||||
EditAction, EventClass, EventContextMenu, EventCreationData, EventStatus, RecurrenceType,
|
||||
ReminderType, RouteHandler, Sidebar, Theme, ViewMode,
|
||||
};
|
||||
@@ -1031,9 +1031,11 @@ pub fn App() -> Html {
|
||||
on_create_event={on_create_event_click}
|
||||
/>
|
||||
|
||||
<CreateEventModal
|
||||
<CreateEventModalV2
|
||||
is_open={*create_event_modal_open}
|
||||
selected_date={(*selected_date_for_event).clone()}
|
||||
initial_start_time={None}
|
||||
initial_end_time={None}
|
||||
event_to_edit={(*event_context_menu_event).clone()}
|
||||
edit_scope={(*event_edit_scope).clone()}
|
||||
on_close={Callback::from({
|
||||
@@ -1048,242 +1050,6 @@ pub fn App() -> Html {
|
||||
}
|
||||
})}
|
||||
on_create={on_event_create}
|
||||
on_update={Callback::from({
|
||||
let auth_token = auth_token.clone();
|
||||
let create_event_modal_open = create_event_modal_open.clone();
|
||||
let event_context_menu_event = event_context_menu_event.clone();
|
||||
let event_edit_scope = event_edit_scope.clone();
|
||||
move |(original_event, updated_data): (VEvent, EventCreationData)| {
|
||||
web_sys::console::log_1(&format!("Updating event: {:?}, edit_scope: {:?}", updated_data, updated_data.edit_scope).into());
|
||||
create_event_modal_open.set(false);
|
||||
event_context_menu_event.set(None);
|
||||
event_edit_scope.set(None);
|
||||
|
||||
if let Some(token) = (*auth_token).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 local times to UTC for backend storage
|
||||
let start_local = updated_data.start_date.and_time(updated_data.start_time);
|
||||
let end_local = updated_data.end_date.and_time(updated_data.end_time);
|
||||
|
||||
let start_utc = start_local.and_local_timezone(chrono::Local).unwrap().to_utc();
|
||||
let end_utc = end_local.and_local_timezone(chrono::Local).unwrap().to_utc();
|
||||
|
||||
// Format UTC date and time strings for backend
|
||||
let start_date = start_utc.format("%Y-%m-%d").to_string();
|
||||
let start_time = start_utc.format("%H:%M").to_string();
|
||||
let end_date = end_utc.format("%Y-%m-%d").to_string();
|
||||
let end_time = end_utc.format("%H:%M").to_string();
|
||||
|
||||
// Convert enums to strings for backend
|
||||
let status_str = match updated_data.status {
|
||||
EventStatus::Tentative => "tentative",
|
||||
EventStatus::Cancelled => "cancelled",
|
||||
_ => "confirmed",
|
||||
}.to_string();
|
||||
|
||||
let class_str = match updated_data.class {
|
||||
EventClass::Private => "private",
|
||||
EventClass::Confidential => "confidential",
|
||||
_ => "public",
|
||||
}.to_string();
|
||||
|
||||
let reminder_str = match updated_data.reminder {
|
||||
ReminderType::Minutes15 => "15min",
|
||||
ReminderType::Minutes30 => "30min",
|
||||
ReminderType::Hour1 => "1hour",
|
||||
ReminderType::Hours2 => "2hours",
|
||||
ReminderType::Day1 => "1day",
|
||||
ReminderType::Days2 => "2days",
|
||||
ReminderType::Week1 => "1week",
|
||||
_ => "none",
|
||||
}.to_string();
|
||||
|
||||
let recurrence_str = match updated_data.recurrence {
|
||||
RecurrenceType::Daily => "daily",
|
||||
RecurrenceType::Weekly => "weekly",
|
||||
RecurrenceType::Monthly => "monthly",
|
||||
RecurrenceType::Yearly => "yearly",
|
||||
_ => "none",
|
||||
}.to_string();
|
||||
|
||||
// Check if the calendar has changed
|
||||
let calendar_changed = original_event.calendar_path.as_ref() != updated_data.selected_calendar.as_ref();
|
||||
|
||||
if calendar_changed {
|
||||
// Calendar changed - need to delete from original and create in new
|
||||
web_sys::console::log_1(&"Calendar changed - performing delete + create".into());
|
||||
|
||||
// First delete from original calendar
|
||||
if let Some(original_calendar_path) = &original_event.calendar_path {
|
||||
if let Some(event_href) = &original_event.href {
|
||||
match calendar_service.delete_event(
|
||||
&token,
|
||||
&password,
|
||||
original_calendar_path.clone(),
|
||||
event_href.clone(),
|
||||
"single".to_string(), // delete single occurrence
|
||||
None
|
||||
).await {
|
||||
Ok(_) => {
|
||||
web_sys::console::log_1(&"Original event deleted successfully".into());
|
||||
|
||||
// Now create the event in the new calendar
|
||||
match calendar_service.create_event(
|
||||
&token,
|
||||
&password,
|
||||
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.recurrence_days,
|
||||
updated_data.selected_calendar
|
||||
).await {
|
||||
Ok(_) => {
|
||||
web_sys::console::log_1(&"Event moved to new calendar successfully".into());
|
||||
// Trigger a page reload to refresh events from all calendars
|
||||
web_sys::window().unwrap().location().reload().unwrap();
|
||||
}
|
||||
Err(err) => {
|
||||
web_sys::console::error_1(&format!("Failed to create event in new calendar: {}", err).into());
|
||||
web_sys::window().unwrap().alert_with_message(&format!("Failed to move event to new calendar: {}", err)).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
web_sys::console::error_1(&format!("Failed to delete original event: {}", err).into());
|
||||
web_sys::window().unwrap().alert_with_message(&format!("Failed to delete original event: {}", err)).unwrap();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
web_sys::console::error_1(&"Original event missing href for deletion".into());
|
||||
web_sys::window().unwrap().alert_with_message("Cannot move event - original event missing href").unwrap();
|
||||
}
|
||||
} else {
|
||||
web_sys::console::error_1(&"Original event missing calendar_path for deletion".into());
|
||||
web_sys::window().unwrap().alert_with_message("Cannot move event - original event missing calendar path").unwrap();
|
||||
}
|
||||
} else {
|
||||
// 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,
|
||||
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.recurrence_days,
|
||||
updated_data.selected_calendar,
|
||||
original_event.exdate.clone(),
|
||||
Some("update_series".to_string()), // This is for event edit modal, preserve original RRULE
|
||||
None // No until_date for edit modal
|
||||
).await {
|
||||
Ok(_) => {
|
||||
web_sys::console::log_1(&"Event updated successfully".into());
|
||||
// Trigger a page reload to refresh events from all calendars
|
||||
web_sys::window().unwrap().location().reload().unwrap();
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
})}
|
||||
available_calendars={user_info.as_ref().map(|ui| ui.calendars.clone()).unwrap_or_default()}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user