Complete event modal migration: remove original and rename V2
Remove the original create_event_modal.rs and rename create_event_modal_v2.rs to complete the modal migration started earlier. This eliminates duplicate code and consolidates to a single, clean event modal implementation. Changes: - Remove original create_event_modal.rs (2,300+ lines) - Rename create_event_modal_v2.rs → create_event_modal.rs - Update component/function names: CreateEventModalV2 → CreateEventModal - Fix all imports in app.rs and calendar.rs - Add missing to_create_event_params() method to EventCreationData - Resolve EditAction type conflicts between modules - Clean up duplicate types and unused imports - Maintain backwards compatibility with EventCreationData export Result: -2440 lines, +160 lines - massive code cleanup with zero functionality loss. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
use crate::components::{
|
use crate::components::{
|
||||||
CalendarContextMenu, ContextMenu, CreateCalendarModal, CreateEventModalV2, DeleteAction,
|
CalendarContextMenu, ContextMenu, CreateCalendarModal, CreateEventModal, DeleteAction,
|
||||||
EditAction, EventClass, EventContextMenu, EventCreationData, EventStatus, RecurrenceType,
|
EditAction, EventContextMenu, EventCreationData, RouteHandler, Sidebar, Theme, ViewMode,
|
||||||
ReminderType, RouteHandler, Sidebar, Theme, ViewMode,
|
|
||||||
};
|
};
|
||||||
use crate::components::sidebar::{Style};
|
use crate::components::sidebar::{Style};
|
||||||
use crate::models::ical::VEvent;
|
use crate::models::ical::VEvent;
|
||||||
@@ -1031,7 +1030,7 @@ pub fn App() -> Html {
|
|||||||
on_create_event={on_create_event_click}
|
on_create_event={on_create_event_click}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<CreateEventModalV2
|
<CreateEventModal
|
||||||
is_open={*create_event_modal_open}
|
is_open={*create_event_modal_open}
|
||||||
selected_date={(*selected_date_for_event).clone()}
|
selected_date={(*selected_date_for_event).clone()}
|
||||||
initial_start_time={None}
|
initial_start_time={None}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::components::{
|
use crate::components::{
|
||||||
CalendarHeader, CreateEventModalV2, EventCreationData, EventModal, MonthView, ViewMode, WeekView,
|
CalendarHeader, CreateEventModal, EventCreationData, EventModal, MonthView, ViewMode, WeekView,
|
||||||
};
|
};
|
||||||
use crate::models::ical::VEvent;
|
use crate::models::ical::VEvent;
|
||||||
use crate::services::{calendar_service::UserInfo, CalendarService};
|
use crate::services::{calendar_service::UserInfo, CalendarService};
|
||||||
@@ -492,7 +492,7 @@ pub fn Calendar(props: &CalendarProps) -> Html {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
// Create event modal
|
// Create event modal
|
||||||
<CreateEventModalV2
|
<CreateEventModal
|
||||||
is_open={*show_create_modal}
|
is_open={*show_create_modal}
|
||||||
selected_date={create_event_data.as_ref().map(|(date, _, _)| *date)}
|
selected_date={create_event_data.as_ref().map(|(date, _, _)| *date)}
|
||||||
event_to_edit={None}
|
event_to_edit={None}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,210 +0,0 @@
|
|||||||
use crate::components::event_form::*;
|
|
||||||
use crate::components::create_event_modal::{EventCreationData}; // Use the existing types
|
|
||||||
use crate::components::{EditAction};
|
|
||||||
use crate::models::ical::VEvent;
|
|
||||||
use crate::services::calendar_service::CalendarInfo;
|
|
||||||
use yew::prelude::*;
|
|
||||||
|
|
||||||
#[derive(Properties, PartialEq)]
|
|
||||||
pub struct CreateEventModalProps {
|
|
||||||
pub is_open: bool,
|
|
||||||
pub on_close: Callback<()>,
|
|
||||||
pub on_create: Callback<EventCreationData>,
|
|
||||||
pub available_calendars: Vec<CalendarInfo>,
|
|
||||||
pub selected_date: Option<chrono::NaiveDate>,
|
|
||||||
pub initial_start_time: Option<chrono::NaiveTime>,
|
|
||||||
pub initial_end_time: Option<chrono::NaiveTime>,
|
|
||||||
#[prop_or_default]
|
|
||||||
pub event_to_edit: Option<VEvent>,
|
|
||||||
#[prop_or_default]
|
|
||||||
pub edit_scope: Option<EditAction>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[function_component(CreateEventModalV2)]
|
|
||||||
pub fn create_event_modal_v2(props: &CreateEventModalProps) -> Html {
|
|
||||||
let active_tab = use_state(|| ModalTab::default());
|
|
||||||
let event_data = use_state(|| EventCreationData::default());
|
|
||||||
|
|
||||||
// Initialize data when modal opens
|
|
||||||
{
|
|
||||||
let event_data = event_data.clone();
|
|
||||||
let is_open = props.is_open;
|
|
||||||
let event_to_edit = props.event_to_edit.clone();
|
|
||||||
let selected_date = props.selected_date;
|
|
||||||
let initial_start_time = props.initial_start_time;
|
|
||||||
let initial_end_time = props.initial_end_time;
|
|
||||||
let edit_scope = props.edit_scope.clone();
|
|
||||||
let available_calendars = props.available_calendars.clone();
|
|
||||||
|
|
||||||
use_effect_with(is_open, move |&is_open| {
|
|
||||||
if is_open {
|
|
||||||
let mut data = if let Some(_event) = &event_to_edit {
|
|
||||||
// TODO: Convert VEvent to EventCreationData
|
|
||||||
EventCreationData::default()
|
|
||||||
} else if let Some(date) = selected_date {
|
|
||||||
let mut data = EventCreationData::default();
|
|
||||||
data.start_date = date;
|
|
||||||
data.end_date = date;
|
|
||||||
if let Some(start_time) = initial_start_time {
|
|
||||||
data.start_time = start_time;
|
|
||||||
}
|
|
||||||
if let Some(end_time) = initial_end_time {
|
|
||||||
data.end_time = end_time;
|
|
||||||
}
|
|
||||||
data
|
|
||||||
} else {
|
|
||||||
EventCreationData::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set default calendar
|
|
||||||
if data.selected_calendar.is_none() && !available_calendars.is_empty() {
|
|
||||||
data.selected_calendar = Some(available_calendars[0].path.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set edit scope if provided
|
|
||||||
if let Some(scope) = &edit_scope {
|
|
||||||
data.edit_scope = Some(scope.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
event_data.set(data);
|
|
||||||
}
|
|
||||||
|| ()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if !props.is_open {
|
|
||||||
return html! {};
|
|
||||||
}
|
|
||||||
|
|
||||||
let on_backdrop_click = {
|
|
||||||
let on_close = props.on_close.clone();
|
|
||||||
Callback::from(move |e: MouseEvent| {
|
|
||||||
if e.target() == e.current_target() {
|
|
||||||
on_close.emit(());
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let switch_to_tab = {
|
|
||||||
let active_tab = active_tab.clone();
|
|
||||||
Callback::from(move |tab: ModalTab| {
|
|
||||||
active_tab.set(tab);
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let on_save = {
|
|
||||||
let event_data = event_data.clone();
|
|
||||||
let on_create = props.on_create.clone();
|
|
||||||
Callback::from(move |_: MouseEvent| {
|
|
||||||
on_create.emit((*event_data).clone());
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let on_close = props.on_close.clone();
|
|
||||||
let on_close_header = on_close.clone();
|
|
||||||
|
|
||||||
let tab_props = TabProps {
|
|
||||||
data: event_data.clone(),
|
|
||||||
available_calendars: props.available_calendars.clone(),
|
|
||||||
};
|
|
||||||
|
|
||||||
html! {
|
|
||||||
<div class="modal-backdrop" onclick={on_backdrop_click}>
|
|
||||||
<div class="modal-content create-event-modal">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h3>
|
|
||||||
{if props.event_to_edit.is_some() { "Edit Event" } else { "Create Event" }}
|
|
||||||
</h3>
|
|
||||||
<button class="modal-close" onclick={Callback::from(move |_| on_close_header.emit(()))}>
|
|
||||||
{"×"}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal-tabs">
|
|
||||||
<div class="tab-navigation">
|
|
||||||
<button
|
|
||||||
class={if *active_tab == ModalTab::BasicDetails { "tab-button active" } else { "tab-button" }}
|
|
||||||
onclick={{
|
|
||||||
let switch_to_tab = switch_to_tab.clone();
|
|
||||||
Callback::from(move |_| switch_to_tab.emit(ModalTab::BasicDetails))
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{"Basic"}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class={if *active_tab == ModalTab::Advanced { "tab-button active" } else { "tab-button" }}
|
|
||||||
onclick={{
|
|
||||||
let switch_to_tab = switch_to_tab.clone();
|
|
||||||
Callback::from(move |_| switch_to_tab.emit(ModalTab::Advanced))
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{"Advanced"}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class={if *active_tab == ModalTab::People { "tab-button active" } else { "tab-button" }}
|
|
||||||
onclick={{
|
|
||||||
let switch_to_tab = switch_to_tab.clone();
|
|
||||||
Callback::from(move |_| switch_to_tab.emit(ModalTab::People))
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{"People"}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class={if *active_tab == ModalTab::Categories { "tab-button active" } else { "tab-button" }}
|
|
||||||
onclick={{
|
|
||||||
let switch_to_tab = switch_to_tab.clone();
|
|
||||||
Callback::from(move |_| switch_to_tab.emit(ModalTab::Categories))
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{"Categories"}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class={if *active_tab == ModalTab::Location { "tab-button active" } else { "tab-button" }}
|
|
||||||
onclick={{
|
|
||||||
let switch_to_tab = switch_to_tab.clone();
|
|
||||||
Callback::from(move |_| switch_to_tab.emit(ModalTab::Location))
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{"Location"}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class={if *active_tab == ModalTab::Reminders { "tab-button active" } else { "tab-button" }}
|
|
||||||
onclick={{
|
|
||||||
let switch_to_tab = switch_to_tab.clone();
|
|
||||||
Callback::from(move |_| switch_to_tab.emit(ModalTab::Reminders))
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{"Reminders"}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal-body">
|
|
||||||
<div class="tab-content">
|
|
||||||
{
|
|
||||||
match *active_tab {
|
|
||||||
ModalTab::BasicDetails => html! { <BasicDetailsTab ..tab_props /> },
|
|
||||||
ModalTab::Advanced => html! { <AdvancedTab ..tab_props /> },
|
|
||||||
ModalTab::People => html! { <PeopleTab ..tab_props /> },
|
|
||||||
ModalTab::Categories => html! { <CategoriesTab ..tab_props /> },
|
|
||||||
ModalTab::Location => html! { <LocationTab ..tab_props /> },
|
|
||||||
ModalTab::Reminders => html! { <RemindersTab ..tab_props /> },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal-footer">
|
|
||||||
<div class="modal-actions">
|
|
||||||
<button class="btn btn-secondary" onclick={Callback::from(move |_| on_close.emit(()))}>
|
|
||||||
{"Cancel"}
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-primary" onclick={on_save}>
|
|
||||||
{if props.event_to_edit.is_some() { "Update Event" } else { "Create Event" }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
use super::types::*;
|
use super::types::*;
|
||||||
use crate::components::create_event_modal::{EventStatus, EventClass};
|
// Types are already imported from super::types::*
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
use web_sys::{HtmlInputElement, HtmlSelectElement};
|
use web_sys::{HtmlInputElement, HtmlSelectElement};
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use super::types::*;
|
use super::types::*;
|
||||||
use crate::components::create_event_modal::{EventStatus, EventClass, RecurrenceType, ReminderType};
|
// Types are already imported from super::types::*
|
||||||
use chrono::{Datelike, NaiveDate};
|
use chrono::{Datelike, NaiveDate};
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
use web_sys::{HtmlInputElement, HtmlSelectElement, HtmlTextAreaElement};
|
use web_sys::{HtmlInputElement, HtmlSelectElement, HtmlTextAreaElement};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use super::types::*;
|
use super::types::*;
|
||||||
use crate::components::create_event_modal::ReminderType;
|
// Types are already imported from super::types::*
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
use web_sys::HtmlSelectElement;
|
use web_sys::HtmlSelectElement;
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|||||||
@@ -78,12 +78,7 @@ impl Default for ModalTab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
// EditAction is now imported from event_context_menu - this duplicate removed
|
||||||
pub enum EditAction {
|
|
||||||
ThisOnly,
|
|
||||||
ThisAndFuture,
|
|
||||||
AllInSeries,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub struct EventCreationData {
|
pub struct EventCreationData {
|
||||||
@@ -130,10 +125,54 @@ pub struct EventCreationData {
|
|||||||
pub selected_calendar: Option<String>,
|
pub selected_calendar: Option<String>,
|
||||||
|
|
||||||
// Edit tracking (for recurring events)
|
// Edit tracking (for recurring events)
|
||||||
pub edit_scope: Option<EditAction>,
|
pub edit_scope: Option<crate::components::EditAction>,
|
||||||
pub changed_fields: Vec<String>,
|
pub changed_fields: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EventCreationData {
|
||||||
|
pub fn to_create_event_params(&self) -> (
|
||||||
|
String, // title
|
||||||
|
String, // description
|
||||||
|
String, // start_date
|
||||||
|
String, // start_time
|
||||||
|
String, // end_date
|
||||||
|
String, // end_time
|
||||||
|
String, // location
|
||||||
|
bool, // all_day
|
||||||
|
String, // status
|
||||||
|
String, // class
|
||||||
|
Option<u8>, // priority
|
||||||
|
String, // organizer
|
||||||
|
String, // attendees
|
||||||
|
String, // categories
|
||||||
|
String, // reminder
|
||||||
|
String, // recurrence
|
||||||
|
Vec<bool>, // recurrence_days
|
||||||
|
Option<String>, // calendar_path
|
||||||
|
) {
|
||||||
|
(
|
||||||
|
self.title.clone(),
|
||||||
|
self.description.clone(),
|
||||||
|
self.start_date.format("%Y-%m-%d").to_string(),
|
||||||
|
self.start_time.format("%H:%M").to_string(),
|
||||||
|
self.end_date.format("%Y-%m-%d").to_string(),
|
||||||
|
self.end_time.format("%H:%M").to_string(),
|
||||||
|
self.location.clone(),
|
||||||
|
self.all_day,
|
||||||
|
format!("{:?}", self.status).to_uppercase(),
|
||||||
|
format!("{:?}", self.class).to_uppercase(),
|
||||||
|
self.priority,
|
||||||
|
self.organizer.clone(),
|
||||||
|
self.attendees.clone(),
|
||||||
|
self.categories.clone(),
|
||||||
|
format!("{:?}", self.reminder),
|
||||||
|
format!("{:?}", self.recurrence),
|
||||||
|
self.recurrence_days.clone(),
|
||||||
|
self.selected_calendar.clone(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for EventCreationData {
|
impl Default for EventCreationData {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let now_local = Local::now();
|
let now_local = Local::now();
|
||||||
@@ -175,6 +214,6 @@ impl Default for EventCreationData {
|
|||||||
// Common props for all tab components
|
// Common props for all tab components
|
||||||
#[derive(Properties, PartialEq)]
|
#[derive(Properties, PartialEq)]
|
||||||
pub struct TabProps {
|
pub struct TabProps {
|
||||||
pub data: UseStateHandle<crate::components::create_event_modal::EventCreationData>,
|
pub data: UseStateHandle<EventCreationData>,
|
||||||
pub available_calendars: Vec<CalendarInfo>,
|
pub available_calendars: Vec<CalendarInfo>,
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,6 @@ pub mod calendar_list_item;
|
|||||||
pub mod context_menu;
|
pub mod context_menu;
|
||||||
pub mod create_calendar_modal;
|
pub mod create_calendar_modal;
|
||||||
pub mod create_event_modal;
|
pub mod create_event_modal;
|
||||||
pub mod create_event_modal_v2;
|
|
||||||
pub mod event_context_menu;
|
pub mod event_context_menu;
|
||||||
pub mod event_form;
|
pub mod event_form;
|
||||||
pub mod event_modal;
|
pub mod event_modal;
|
||||||
@@ -22,10 +21,9 @@ pub use calendar_header::CalendarHeader;
|
|||||||
pub use calendar_list_item::CalendarListItem;
|
pub use calendar_list_item::CalendarListItem;
|
||||||
pub use context_menu::ContextMenu;
|
pub use context_menu::ContextMenu;
|
||||||
pub use create_calendar_modal::CreateCalendarModal;
|
pub use create_calendar_modal::CreateCalendarModal;
|
||||||
pub use create_event_modal::{
|
pub use create_event_modal::CreateEventModal;
|
||||||
CreateEventModal, EventClass, EventCreationData, EventStatus, RecurrenceType, ReminderType,
|
// Re-export event form types for backwards compatibility
|
||||||
};
|
pub use event_form::EventCreationData;
|
||||||
pub use create_event_modal_v2::CreateEventModalV2;
|
|
||||||
pub use event_form::{
|
pub use event_form::{
|
||||||
EventClass as EventFormClass, EventCreationData as EventFormData, EventStatus as EventFormStatus,
|
EventClass as EventFormClass, EventCreationData as EventFormData, EventStatus as EventFormStatus,
|
||||||
RecurrenceType as EventFormRecurrenceType, ReminderType as EventFormReminderType,
|
RecurrenceType as EventFormRecurrenceType, ReminderType as EventFormReminderType,
|
||||||
|
|||||||
Reference in New Issue
Block a user