Add visibility toggles for CalDAV calendars with event filtering
Users can now toggle visibility of CalDAV calendars using checkboxes in the sidebar, matching the behavior of external calendars. Events from hidden calendars are automatically filtered out of the calendar view. Changes: - Add is_visible field to CalendarInfo (frontend & backend) - Add visibility checkboxes to CalDAV calendar list items - Implement real-time event filtering based on calendar visibility - Add CSS styling matching external calendar checkboxes - Default new calendars to visible state 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ pub struct CalendarListItemProps {
|
||||
pub on_color_picker_toggle: Callback<String>, // calendar_path
|
||||
pub available_colors: Vec<String>,
|
||||
pub on_context_menu: Callback<(MouseEvent, String)>, // (event, calendar_path)
|
||||
pub on_visibility_toggle: Callback<String>, // calendar_path
|
||||
}
|
||||
|
||||
#[function_component(CalendarListItem)]
|
||||
@@ -32,44 +33,59 @@ pub fn calendar_list_item(props: &CalendarListItemProps) -> Html {
|
||||
})
|
||||
};
|
||||
|
||||
let on_visibility_toggle = {
|
||||
let cal_path = props.calendar.path.clone();
|
||||
let on_visibility_toggle = props.on_visibility_toggle.clone();
|
||||
Callback::from(move |_| {
|
||||
on_visibility_toggle.emit(cal_path.clone());
|
||||
})
|
||||
};
|
||||
|
||||
html! {
|
||||
<li key={props.calendar.path.clone()} oncontextmenu={on_context_menu}>
|
||||
<span class="calendar-color"
|
||||
style={format!("background-color: {}", props.calendar.color)}
|
||||
onclick={on_color_click}>
|
||||
{
|
||||
if props.color_picker_open {
|
||||
html! {
|
||||
<div class="color-picker">
|
||||
{
|
||||
props.available_colors.iter().map(|color| {
|
||||
let color_str = color.clone();
|
||||
let cal_path = props.calendar.path.clone();
|
||||
let on_color_change = props.on_color_change.clone();
|
||||
<div class="calendar-info">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={props.calendar.is_visible}
|
||||
onchange={on_visibility_toggle}
|
||||
/>
|
||||
<span class="calendar-color"
|
||||
style={format!("background-color: {}", props.calendar.color)}
|
||||
onclick={on_color_click}>
|
||||
{
|
||||
if props.color_picker_open {
|
||||
html! {
|
||||
<div class="color-picker">
|
||||
{
|
||||
props.available_colors.iter().map(|color| {
|
||||
let color_str = color.clone();
|
||||
let cal_path = props.calendar.path.clone();
|
||||
let on_color_change = props.on_color_change.clone();
|
||||
|
||||
let on_color_select = Callback::from(move |_: MouseEvent| {
|
||||
on_color_change.emit((cal_path.clone(), color_str.clone()));
|
||||
});
|
||||
let on_color_select = Callback::from(move |_: MouseEvent| {
|
||||
on_color_change.emit((cal_path.clone(), color_str.clone()));
|
||||
});
|
||||
|
||||
let is_selected = props.calendar.color == *color;
|
||||
let class_name = if is_selected { "color-option selected" } else { "color-option" };
|
||||
let is_selected = props.calendar.color == *color;
|
||||
let class_name = if is_selected { "color-option selected" } else { "color-option" };
|
||||
|
||||
html! {
|
||||
<div class={class_name}
|
||||
style={format!("background-color: {}", color)}
|
||||
onclick={on_color_select}>
|
||||
</div>
|
||||
}
|
||||
}).collect::<Html>()
|
||||
}
|
||||
</div>
|
||||
html! {
|
||||
<div class={class_name}
|
||||
style={format!("background-color: {}", color)}
|
||||
onclick={on_color_select}>
|
||||
</div>
|
||||
}
|
||||
}).collect::<Html>()
|
||||
}
|
||||
</div>
|
||||
}
|
||||
} else {
|
||||
html! {}
|
||||
}
|
||||
} else {
|
||||
html! {}
|
||||
}
|
||||
}
|
||||
</span>
|
||||
<span class="calendar-name">{&props.calendar.display_name}</span>
|
||||
</span>
|
||||
<span class="calendar-name">{&props.calendar.display_name}</span>
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user