Compare commits
	
		
			3 Commits
		
	
	
		
			74d636117d
			...
			feature/mo
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 51d5552156 | ||
|   | 5a12c0e0d0 | ||
|   | ee181cf6cb | 
							
								
								
									
										34
									
								
								.gitea/workflows/docker.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								.gitea/workflows/docker.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | name: Build and Push Docker Image | ||||||
|  |  | ||||||
|  | on: | ||||||
|  |   push: | ||||||
|  |     branches: | ||||||
|  |       - main | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   docker: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - name: Checkout code | ||||||
|  |         uses: actions/checkout@v4 | ||||||
|  |  | ||||||
|  |       - name: Set up Docker Buildx | ||||||
|  |         uses: docker/setup-buildx-action@v3 | ||||||
|  |  | ||||||
|  |       - name: Login to Docker Registry | ||||||
|  |         uses: docker/login-action@v3 | ||||||
|  |         with: | ||||||
|  |           registry: ${{ secrets.DOCKER_REGISTRY }} | ||||||
|  |           username: ${{ secrets.DOCKER_USERNAME }} | ||||||
|  |           password: ${{ secrets.DOCKER_PASSWORD }} | ||||||
|  |  | ||||||
|  |       - name: Build and push | ||||||
|  |         uses: docker/build-push-action@v5 | ||||||
|  |         with: | ||||||
|  |           context: . | ||||||
|  |           push: true | ||||||
|  |           tags: | | ||||||
|  |             ${{ secrets.DOCKER_REGISTRY }}/calendar:latest | ||||||
|  |             ${{ secrets.DOCKER_REGISTRY }}/calendar:${{ github.sha }} | ||||||
|  |           cache-from: type=gha | ||||||
|  |           cache-to: type=gha,mode=max | ||||||
| @@ -201,6 +201,7 @@ pub struct UpdateEventSeriesRequest { | |||||||
|     // Update scope control |     // Update scope control | ||||||
|     pub update_scope: String,      // "this_only", "this_and_future", "all_in_series" |     pub update_scope: String,      // "this_only", "this_and_future", "all_in_series" | ||||||
|     pub occurrence_date: Option<String>, // ISO date string for specific occurrence being updated |     pub occurrence_date: Option<String>, // ISO date string for specific occurrence being updated | ||||||
|  |     pub changed_fields: Option<Vec<String>>, // List of field names that were changed (for optimization) | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Serialize)] | #[derive(Debug, Serialize)] | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ use yew::prelude::*; | |||||||
| use yew_router::prelude::*; | use yew_router::prelude::*; | ||||||
| use gloo_storage::{LocalStorage, Storage}; | use gloo_storage::{LocalStorage, Storage}; | ||||||
| use web_sys::MouseEvent; | use web_sys::MouseEvent; | ||||||
| use crate::components::{Sidebar, ViewMode, Theme, CreateCalendarModal, ContextMenu, EventContextMenu, CalendarContextMenu, CreateEventModal, EventCreationData, RouteHandler, EventStatus, EventClass, ReminderType, RecurrenceType, DeleteAction}; | use crate::components::{Sidebar, ViewMode, Theme, CreateCalendarModal, ContextMenu, EventContextMenu, CalendarContextMenu, CreateEventModal, EventCreationData, RouteHandler, EventStatus, EventClass, ReminderType, RecurrenceType, DeleteAction, EditAction}; | ||||||
| use crate::services::{CalendarService, calendar_service::UserInfo}; | use crate::services::{CalendarService, calendar_service::UserInfo}; | ||||||
| use crate::models::ical::VEvent; | use crate::models::ical::VEvent; | ||||||
| use chrono::NaiveDate; | use chrono::NaiveDate; | ||||||
| @@ -54,6 +54,7 @@ pub fn App() -> Html { | |||||||
|     let calendar_context_menu_date = use_state(|| -> Option<NaiveDate> { None }); |     let calendar_context_menu_date = use_state(|| -> Option<NaiveDate> { None }); | ||||||
|     let create_event_modal_open = use_state(|| false); |     let create_event_modal_open = use_state(|| false); | ||||||
|     let selected_date_for_event = use_state(|| -> Option<NaiveDate> { None }); |     let selected_date_for_event = use_state(|| -> Option<NaiveDate> { None }); | ||||||
|  |     let event_edit_scope = use_state(|| -> Option<EditAction> { None }); | ||||||
|     let _recurring_edit_modal_open = use_state(|| false); |     let _recurring_edit_modal_open = use_state(|| false); | ||||||
|     let _recurring_edit_event = use_state(|| -> Option<VEvent> { None }); |     let _recurring_edit_event = use_state(|| -> Option<VEvent> { None }); | ||||||
|     let _recurring_edit_data = use_state(|| -> Option<EventCreationData> { None }); |     let _recurring_edit_data = use_state(|| -> Option<EventCreationData> { None }); | ||||||
| @@ -738,8 +739,10 @@ pub fn App() -> Html { | |||||||
|                         let _event_context_menu_event = event_context_menu_event.clone(); |                         let _event_context_menu_event = event_context_menu_event.clone(); | ||||||
|                         let event_context_menu_open = event_context_menu_open.clone(); |                         let event_context_menu_open = event_context_menu_open.clone(); | ||||||
|                         let create_event_modal_open = create_event_modal_open.clone(); |                         let create_event_modal_open = create_event_modal_open.clone(); | ||||||
|                         move |_| { |                         let event_edit_scope = event_edit_scope.clone(); | ||||||
|                             // Close the context menu and open the edit modal |                         move |edit_action: EditAction| { | ||||||
|  |                             // Set the edit scope and close the context menu | ||||||
|  |                             event_edit_scope.set(Some(edit_action)); | ||||||
|                             event_context_menu_open.set(false); |                             event_context_menu_open.set(false); | ||||||
|                             create_event_modal_open.set(true); |                             create_event_modal_open.set(true); | ||||||
|                         } |                         } | ||||||
| @@ -840,13 +843,16 @@ pub fn App() -> Html { | |||||||
|                     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()} | ||||||
|                     event_to_edit={(*event_context_menu_event).clone()} |                     event_to_edit={(*event_context_menu_event).clone()} | ||||||
|  |                     edit_scope={(*event_edit_scope).clone()} | ||||||
|                     on_close={Callback::from({ |                     on_close={Callback::from({ | ||||||
|                         let create_event_modal_open = create_event_modal_open.clone(); |                         let create_event_modal_open = create_event_modal_open.clone(); | ||||||
|                         let event_context_menu_event = event_context_menu_event.clone(); |                         let event_context_menu_event = event_context_menu_event.clone(); | ||||||
|  |                         let event_edit_scope = event_edit_scope.clone(); | ||||||
|                         move |_| { |                         move |_| { | ||||||
|                             create_event_modal_open.set(false); |                             create_event_modal_open.set(false); | ||||||
|                             // Clear the event being edited |                             // Clear the event being edited and edit scope | ||||||
|                             event_context_menu_event.set(None); |                             event_context_menu_event.set(None); | ||||||
|  |                             event_edit_scope.set(None); | ||||||
|                         } |                         } | ||||||
|                     })} |                     })} | ||||||
|                     on_create={on_event_create} |                     on_create={on_event_create} | ||||||
| @@ -854,10 +860,12 @@ pub fn App() -> Html { | |||||||
|                         let auth_token = auth_token.clone(); |                         let auth_token = auth_token.clone(); | ||||||
|                         let create_event_modal_open = create_event_modal_open.clone(); |                         let create_event_modal_open = create_event_modal_open.clone(); | ||||||
|                         let event_context_menu_event = event_context_menu_event.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)| { |                         move |(original_event, updated_data): (VEvent, EventCreationData)| { | ||||||
|                             web_sys::console::log_1(&format!("Updating event: {:?}", updated_data).into()); |                             web_sys::console::log_1(&format!("Updating event: {:?}, edit_scope: {:?}", updated_data, updated_data.edit_scope).into()); | ||||||
|                             create_event_modal_open.set(false); |                             create_event_modal_open.set(false); | ||||||
|                             event_context_menu_event.set(None); |                             event_context_menu_event.set(None); | ||||||
|  |                             event_edit_scope.set(None); | ||||||
|                              |                              | ||||||
|                             if let Some(token) = (*auth_token).clone() { |                             if let Some(token) = (*auth_token).clone() { | ||||||
|                                 wasm_bindgen_futures::spawn_local(async move { |                                 wasm_bindgen_futures::spawn_local(async move { | ||||||
| @@ -988,7 +996,60 @@ 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 | ||||||
|  |                                         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( |                                             match calendar_service.update_event( | ||||||
|                                             &token, |                                             &token, | ||||||
|                                             &password, |                                             &password, | ||||||
| @@ -1026,6 +1087,7 @@ pub fn App() -> Html { | |||||||
|                                             } |                                             } | ||||||
|                                         } |                                         } | ||||||
|                                         } |                                         } | ||||||
|  |                                     } | ||||||
|                                 }); |                                 }); | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ use wasm_bindgen::JsCast; | |||||||
| use chrono::{NaiveDate, NaiveTime, Local, TimeZone, Utc, Datelike}; | use chrono::{NaiveDate, NaiveTime, Local, TimeZone, Utc, Datelike}; | ||||||
| use crate::services::calendar_service::CalendarInfo; | use crate::services::calendar_service::CalendarInfo; | ||||||
| use crate::models::ical::VEvent; | use crate::models::ical::VEvent; | ||||||
|  | use crate::components::EditAction; | ||||||
|  |  | ||||||
| #[derive(Properties, PartialEq)] | #[derive(Properties, PartialEq)] | ||||||
| pub struct CreateEventModalProps { | pub struct CreateEventModalProps { | ||||||
| @@ -18,6 +19,8 @@ pub struct CreateEventModalProps { | |||||||
|     pub initial_start_time: Option<NaiveTime>, |     pub initial_start_time: Option<NaiveTime>, | ||||||
|     #[prop_or_default] |     #[prop_or_default] | ||||||
|     pub initial_end_time: Option<NaiveTime>, |     pub initial_end_time: Option<NaiveTime>, | ||||||
|  |     #[prop_or_default] | ||||||
|  |     pub edit_scope: Option<EditAction>, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Clone, PartialEq, Debug)] | #[derive(Clone, PartialEq, Debug)] | ||||||
| @@ -330,6 +333,10 @@ pub struct EventCreationData { | |||||||
|     pub monthly_by_day: Option<String>, // For monthly: "1MO" = first Monday, "2TU" = second Tuesday, etc. |     pub monthly_by_day: Option<String>, // For monthly: "1MO" = first Monday, "2TU" = second Tuesday, etc. | ||||||
|     pub monthly_by_monthday: Option<u8>, // For monthly: day of month (1-31) |     pub monthly_by_monthday: Option<u8>, // For monthly: day of month (1-31) | ||||||
|     pub yearly_by_month: Vec<bool>, // For yearly: [Jan, Feb, Mar, ..., Dec] |     pub yearly_by_month: Vec<bool>, // For yearly: [Jan, Feb, Mar, ..., Dec] | ||||||
|  |      | ||||||
|  |     // Edit scope and tracking fields | ||||||
|  |     pub edit_scope: Option<EditAction>, | ||||||
|  |     pub changed_fields: Vec<String>, // List of field names that were changed | ||||||
| } | } | ||||||
|  |  | ||||||
| impl Default for EventCreationData { | impl Default for EventCreationData { | ||||||
| @@ -365,6 +372,10 @@ impl Default for EventCreationData { | |||||||
|             monthly_by_day: None, |             monthly_by_day: None, | ||||||
|             monthly_by_monthday: None, |             monthly_by_monthday: None, | ||||||
|             yearly_by_month: vec![false; 12], // [Jan, Feb, ..., Dec] - all false by default |             yearly_by_month: vec![false; 12], // [Jan, Feb, ..., Dec] - all false by default | ||||||
|  |              | ||||||
|  |             // Edit scope and tracking defaults | ||||||
|  |             edit_scope: None, | ||||||
|  |             changed_fields: vec![], | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -566,6 +577,10 @@ impl EventCreationData { | |||||||
|             } else { |             } else { | ||||||
|                 vec![false; 12] |                 vec![false; 12] | ||||||
|             }, |             }, | ||||||
|  |              | ||||||
|  |             // Edit scope and tracking defaults (will be set later if needed) | ||||||
|  |             edit_scope: None, | ||||||
|  |             changed_fields: vec![], | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -593,9 +608,9 @@ pub fn create_event_modal(props: &CreateEventModalProps) -> Html { | |||||||
|     let active_tab = use_state(|| ModalTab::default()); |     let active_tab = use_state(|| ModalTab::default()); | ||||||
|      |      | ||||||
|     // Initialize with selected date or event data if provided |     // Initialize with selected date or event data if provided | ||||||
|     use_effect_with((props.selected_date, props.event_to_edit.clone(), props.is_open, props.available_calendars.clone(), props.initial_start_time, props.initial_end_time), { |     use_effect_with((props.selected_date, props.event_to_edit.clone(), props.is_open, props.available_calendars.clone(), props.initial_start_time, props.initial_end_time, props.edit_scope.clone()), { | ||||||
|         let event_data = event_data.clone(); |         let event_data = event_data.clone(); | ||||||
|         move |(selected_date, event_to_edit, is_open, available_calendars, initial_start_time, initial_end_time)| { |         move |(selected_date, event_to_edit, is_open, available_calendars, initial_start_time, initial_end_time, edit_scope)| { | ||||||
|             if *is_open { |             if *is_open { | ||||||
|                 let mut data = if let Some(event) = event_to_edit { |                 let mut data = if let Some(event) = event_to_edit { | ||||||
|                     // Pre-populate with event data for editing |                     // Pre-populate with event data for editing | ||||||
| @@ -625,6 +640,11 @@ pub fn create_event_modal(props: &CreateEventModalProps) -> Html { | |||||||
|                     data.selected_calendar = Some(available_calendars[0].path.clone()); |                     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); |                 event_data.set(data); | ||||||
|             } |             } | ||||||
|             || () |             || () | ||||||
| @@ -644,12 +664,25 @@ pub fn create_event_modal(props: &CreateEventModalProps) -> Html { | |||||||
|         }) |         }) | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  |     // Helper function to track field changes | ||||||
|  |     let _track_field_change = |data: &mut EventCreationData, field_name: &str| { | ||||||
|  |         if !data.changed_fields.contains(&field_name.to_string()) { | ||||||
|  |             data.changed_fields.push(field_name.to_string()); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|     let on_title_input = { |     let on_title_input = { | ||||||
|         let event_data = event_data.clone(); |         let event_data = event_data.clone(); | ||||||
|         Callback::from(move |e: InputEvent| { |         Callback::from(move |e: InputEvent| { | ||||||
|             if let Some(input) = e.target_dyn_into::<HtmlInputElement>() { |             if let Some(input) = e.target_dyn_into::<HtmlInputElement>() { | ||||||
|                 let mut data = (*event_data).clone(); |                 let mut data = (*event_data).clone(); | ||||||
|                 data.title = input.value(); |                 let new_value = input.value(); | ||||||
|  |                 if data.title != new_value { | ||||||
|  |                     data.title = new_value; | ||||||
|  |                     if !data.changed_fields.contains(&"title".to_string()) { | ||||||
|  |                         data.changed_fields.push("title".to_string()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|                 event_data.set(data); |                 event_data.set(data); | ||||||
|             } |             } | ||||||
|         }) |         }) | ||||||
| @@ -661,7 +694,13 @@ pub fn create_event_modal(props: &CreateEventModalProps) -> Html { | |||||||
|             if let Some(select) = e.target_dyn_into::<HtmlSelectElement>() { |             if let Some(select) = e.target_dyn_into::<HtmlSelectElement>() { | ||||||
|                 let mut data = (*event_data).clone(); |                 let mut data = (*event_data).clone(); | ||||||
|                 let value = select.value(); |                 let value = select.value(); | ||||||
|                 data.selected_calendar = if value.is_empty() { None } else { Some(value) }; |                 let new_calendar = if value.is_empty() { None } else { Some(value) }; | ||||||
|  |                 if data.selected_calendar != new_calendar { | ||||||
|  |                     data.selected_calendar = new_calendar; | ||||||
|  |                     if !data.changed_fields.contains(&"selected_calendar".to_string()) { | ||||||
|  |                         data.changed_fields.push("selected_calendar".to_string()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|                 event_data.set(data); |                 event_data.set(data); | ||||||
|             } |             } | ||||||
|         }) |         }) | ||||||
|   | |||||||
| @@ -9,13 +9,20 @@ pub enum DeleteAction { | |||||||
|     DeleteSeries, |     DeleteSeries, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[derive(Clone, PartialEq, Debug)] | ||||||
|  | pub enum EditAction { | ||||||
|  |     EditThis, | ||||||
|  |     EditFuture, | ||||||
|  |     EditAll, | ||||||
|  | } | ||||||
|  |  | ||||||
| #[derive(Properties, PartialEq)] | #[derive(Properties, PartialEq)] | ||||||
| pub struct EventContextMenuProps { | pub struct EventContextMenuProps { | ||||||
|     pub is_open: bool, |     pub is_open: bool, | ||||||
|     pub x: i32, |     pub x: i32, | ||||||
|     pub y: i32, |     pub y: i32, | ||||||
|     pub event: Option<VEvent>, |     pub event: Option<VEvent>, | ||||||
|     pub on_edit: Callback<()>, |     pub on_edit: Callback<EditAction>, | ||||||
|     pub on_delete: Callback<DeleteAction>, |     pub on_delete: Callback<DeleteAction>, | ||||||
|     pub on_close: Callback<()>, |     pub on_close: Callback<()>, | ||||||
| } | } | ||||||
| @@ -38,11 +45,11 @@ pub fn event_context_menu(props: &EventContextMenuProps) -> Html { | |||||||
|         .map(|event| event.rrule.is_some()) |         .map(|event| event.rrule.is_some()) | ||||||
|         .unwrap_or(false); |         .unwrap_or(false); | ||||||
|  |  | ||||||
|     let on_edit_click = { |     let create_edit_callback = |action: EditAction| { | ||||||
|         let on_edit = props.on_edit.clone(); |         let on_edit = props.on_edit.clone(); | ||||||
|         let on_close = props.on_close.clone(); |         let on_close = props.on_close.clone(); | ||||||
|         Callback::from(move |_: MouseEvent| { |         Callback::from(move |_: MouseEvent| { | ||||||
|             on_edit.emit(()); |             on_edit.emit(action.clone()); | ||||||
|             on_close.emit(()); |             on_close.emit(()); | ||||||
|         }) |         }) | ||||||
|     }; |     }; | ||||||
| @@ -62,9 +69,29 @@ pub fn event_context_menu(props: &EventContextMenuProps) -> Html { | |||||||
|             class="context-menu"  |             class="context-menu"  | ||||||
|             style={style} |             style={style} | ||||||
|         > |         > | ||||||
|             <div class="context-menu-item" onclick={on_edit_click}> |             { | ||||||
|  |                 if is_recurring { | ||||||
|  |                     html! { | ||||||
|  |                         <> | ||||||
|  |                             <div class="context-menu-item" onclick={create_edit_callback(EditAction::EditThis)}> | ||||||
|  |                                 {"Edit This Event"} | ||||||
|  |                             </div> | ||||||
|  |                             <div class="context-menu-item" onclick={create_edit_callback(EditAction::EditFuture)}> | ||||||
|  |                                 {"Edit This and Future Events"} | ||||||
|  |                             </div> | ||||||
|  |                             <div class="context-menu-item" onclick={create_edit_callback(EditAction::EditAll)}> | ||||||
|  |                                 {"Edit All Events in Series"} | ||||||
|  |                             </div> | ||||||
|  |                         </> | ||||||
|  |                     } | ||||||
|  |                 } else { | ||||||
|  |                     html! { | ||||||
|  |                         <div class="context-menu-item" onclick={create_edit_callback(EditAction::EditThis)}> | ||||||
|                             {"Edit Event"} |                             {"Edit Event"} | ||||||
|                         </div> |                         </div> | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|             { |             { | ||||||
|                 if is_recurring { |                 if is_recurring { | ||||||
|                     html! { |                     html! { | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ pub use week_view::WeekView; | |||||||
| pub use event_modal::EventModal; | pub use event_modal::EventModal; | ||||||
| pub use create_calendar_modal::CreateCalendarModal; | pub use create_calendar_modal::CreateCalendarModal; | ||||||
| pub use context_menu::ContextMenu; | pub use context_menu::ContextMenu; | ||||||
| pub use event_context_menu::{EventContextMenu, DeleteAction}; | pub use event_context_menu::{EventContextMenu, DeleteAction, EditAction}; | ||||||
| pub use calendar_context_menu::CalendarContextMenu; | pub use calendar_context_menu::CalendarContextMenu; | ||||||
| pub use create_event_modal::{CreateEventModal, EventCreationData, EventStatus, EventClass, ReminderType, RecurrenceType}; | pub use create_event_modal::{CreateEventModal, EventCreationData, EventStatus, EventClass, ReminderType, RecurrenceType}; | ||||||
| pub use sidebar::{Sidebar, ViewMode, Theme}; | pub use sidebar::{Sidebar, ViewMode, Theme}; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user