Implement event deletion with right-click context menu

- Add EventContextMenu component with delete option
- Create DELETE /api/calendar/events/delete endpoint
- Implement CalDAV event deletion in backend
- Add proper URL construction for CalDAV event hrefs
- Integrate context menu with calendar event right-clicks
- Auto-refresh UI after successful event deletion

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Connor Johnstone
2025-08-28 22:07:09 -04:00
parent b444ae710d
commit 7e62e3b7e3
10 changed files with 313 additions and 8 deletions

View File

@@ -528,6 +528,64 @@ impl CalendarService {
}
}
/// Delete an event from the CalDAV server
pub async fn delete_event(
&self,
token: &str,
password: &str,
calendar_path: String,
event_href: String
) -> Result<(), String> {
let window = web_sys::window().ok_or("No global window exists")?;
let opts = RequestInit::new();
opts.set_method("POST");
opts.set_mode(RequestMode::Cors);
let body = serde_json::json!({
"calendar_path": calendar_path,
"event_href": event_href
});
let body_string = serde_json::to_string(&body)
.map_err(|e| format!("JSON serialization failed: {}", e))?;
let url = format!("{}/calendar/events/delete", self.base_url);
opts.set_body(&body_string.into());
let request = Request::new_with_str_and_init(&url, &opts)
.map_err(|e| format!("Request creation failed: {:?}", e))?;
request.headers().set("Authorization", &format!("Bearer {}", token))
.map_err(|e| format!("Authorization header setting failed: {:?}", e))?;
request.headers().set("X-CalDAV-Password", password)
.map_err(|e| format!("Password header setting failed: {:?}", e))?;
request.headers().set("Content-Type", "application/json")
.map_err(|e| format!("Content-Type header setting failed: {:?}", e))?;
let resp_value = JsFuture::from(window.fetch_with_request(&request))
.await
.map_err(|e| format!("Network request failed: {:?}", e))?;
let resp: Response = resp_value.dyn_into()
.map_err(|e| format!("Response cast failed: {:?}", e))?;
let text = JsFuture::from(resp.text()
.map_err(|e| format!("Text extraction failed: {:?}", e))?)
.await
.map_err(|e| format!("Text promise failed: {:?}", e))?;
let text_string = text.as_string()
.ok_or("Response text is not a string")?;
if resp.ok() {
Ok(())
} else {
Err(format!("Request failed with status {}: {}", resp.status(), text_string))
}
}
/// Delete a calendar from the CalDAV server
pub async fn delete_calendar(
&self,