Added support for external calendars #14
@@ -1029,6 +1029,39 @@ pub fn App() -> Html {
|
||||
});
|
||||
}
|
||||
})}
|
||||
on_external_calendar_delete={Callback::from({
|
||||
let external_calendars = external_calendars.clone();
|
||||
let external_calendar_events = external_calendar_events.clone();
|
||||
move |id: i32| {
|
||||
let external_calendars = external_calendars.clone();
|
||||
let external_calendar_events = external_calendar_events.clone();
|
||||
wasm_bindgen_futures::spawn_local(async move {
|
||||
// Delete the external calendar from the server
|
||||
if let Err(err) = CalendarService::delete_external_calendar(id).await {
|
||||
web_sys::console::log_1(
|
||||
&format!("Failed to delete external calendar: {}", err).into(),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove calendar from local state
|
||||
let mut calendars = (*external_calendars).clone();
|
||||
calendars.retain(|c| c.id != id);
|
||||
external_calendars.set(calendars.clone());
|
||||
|
||||
// Remove events from this calendar
|
||||
let mut events = (*external_calendar_events).clone();
|
||||
events.retain(|e| {
|
||||
if let Some(ref calendar_path) = e.calendar_path {
|
||||
calendar_path != &format!("external_{}", id)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
});
|
||||
external_calendar_events.set(events);
|
||||
});
|
||||
}
|
||||
})}
|
||||
color_picker_open={(*color_picker_open).clone()}
|
||||
on_color_change={on_color_change}
|
||||
on_color_picker_toggle={on_color_picker_toggle}
|
||||
|
||||
@@ -104,6 +104,7 @@ pub struct SidebarProps {
|
||||
pub on_create_external_calendar: Callback<()>,
|
||||
pub external_calendars: Vec<ExternalCalendar>,
|
||||
pub on_external_calendar_toggle: Callback<i32>,
|
||||
pub on_external_calendar_delete: Callback<i32>,
|
||||
pub color_picker_open: Option<String>,
|
||||
pub on_color_change: Callback<(String, String)>,
|
||||
pub on_color_picker_toggle: Callback<String>,
|
||||
@@ -119,6 +120,7 @@ pub struct SidebarProps {
|
||||
|
||||
#[function_component(Sidebar)]
|
||||
pub fn sidebar(props: &SidebarProps) -> Html {
|
||||
let external_context_menu_open = use_state(|| None::<i32>);
|
||||
let on_view_change = {
|
||||
let on_view_change = props.on_view_change.clone();
|
||||
Callback::from(move |e: Event| {
|
||||
@@ -158,6 +160,30 @@ pub fn sidebar(props: &SidebarProps) -> Html {
|
||||
})
|
||||
};
|
||||
|
||||
let on_external_calendar_context_menu = {
|
||||
let external_context_menu_open = external_context_menu_open.clone();
|
||||
Callback::from(move |(e, cal_id): (MouseEvent, i32)| {
|
||||
e.prevent_default();
|
||||
external_context_menu_open.set(Some(cal_id));
|
||||
})
|
||||
};
|
||||
|
||||
let on_external_calendar_delete = {
|
||||
let on_external_calendar_delete = props.on_external_calendar_delete.clone();
|
||||
let external_context_menu_open = external_context_menu_open.clone();
|
||||
Callback::from(move |cal_id: i32| {
|
||||
on_external_calendar_delete.emit(cal_id);
|
||||
external_context_menu_open.set(None);
|
||||
})
|
||||
};
|
||||
|
||||
let close_external_context_menu = {
|
||||
let external_context_menu_open = external_context_menu_open.clone();
|
||||
Callback::from(move |_| {
|
||||
external_context_menu_open.set(None);
|
||||
})
|
||||
};
|
||||
|
||||
html! {
|
||||
<aside class="app-sidebar">
|
||||
<div class="sidebar-header">
|
||||
@@ -228,8 +254,17 @@ pub fn sidebar(props: &SidebarProps) -> Html {
|
||||
};
|
||||
|
||||
html! {
|
||||
<li class="external-calendar-item">
|
||||
<div class="external-calendar-info">
|
||||
<li class="external-calendar-item" style="position: relative;">
|
||||
<div
|
||||
class="external-calendar-info"
|
||||
oncontextmenu={{
|
||||
let on_context_menu = on_external_calendar_context_menu.clone();
|
||||
let cal_id = cal.id;
|
||||
Callback::from(move |e: MouseEvent| {
|
||||
on_context_menu.emit((e, cal_id));
|
||||
})
|
||||
}}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={cal.is_visible}
|
||||
@@ -242,6 +277,36 @@ pub fn sidebar(props: &SidebarProps) -> Html {
|
||||
<span class="external-calendar-name">{&cal.name}</span>
|
||||
<span class="external-calendar-indicator">{"📅"}</span>
|
||||
</div>
|
||||
{
|
||||
if *external_context_menu_open == Some(cal.id) {
|
||||
html! {
|
||||
<>
|
||||
<div
|
||||
class="context-menu-overlay"
|
||||
onclick={close_external_context_menu.clone()}
|
||||
style="position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: 999;"
|
||||
/>
|
||||
<div class="context-menu" style="position: absolute; top: 0; right: 0; background: white; border: 1px solid #ccc; border-radius: 4px; box-shadow: 0 2px 8px rgba(0,0,0,0.15); z-index: 1000; min-width: 120px;">
|
||||
<div
|
||||
class="context-menu-item"
|
||||
style="padding: 8px 12px; cursor: pointer; color: #d73a49;"
|
||||
onclick={{
|
||||
let on_delete = on_external_calendar_delete.clone();
|
||||
let cal_id = cal.id;
|
||||
Callback::from(move |_| {
|
||||
on_delete.emit(cal_id);
|
||||
})
|
||||
}}
|
||||
>
|
||||
{"Delete Calendar"}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
} else {
|
||||
html! {}
|
||||
}
|
||||
}
|
||||
</li>
|
||||
}
|
||||
}).collect::<Html>()
|
||||
|
||||
Reference in New Issue
Block a user