Add comprehensive iCal properties support to event creation modal
Enhanced the create event modal to include all major iCalendar properties: - Event status (confirmed/tentative/cancelled) - Privacy classification (public/private/confidential) - Priority levels (0-9 numeric scale) - Organizer email field - Attendees list (comma-separated emails) - Categories (comma-separated tags) - Reminder options (none to 1 week before) - Recurrence patterns (none/daily/weekly/monthly/yearly) Updated backend to parse and handle all new fields, with proper enum conversion and comma-separated list parsing. Events now generate complete iCal data with STATUS, CLASS, PRIORITY, ORGANIZER, ATTENDEE, CATEGORIES, VALARM, and RRULE properties. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -415,6 +415,63 @@ pub async fn create_event(
|
||||
// Generate a unique UID for the event
|
||||
let uid = format!("{}-{}", uuid::Uuid::new_v4(), chrono::Utc::now().timestamp());
|
||||
|
||||
// Parse status
|
||||
let status = match request.status.to_lowercase().as_str() {
|
||||
"tentative" => crate::calendar::EventStatus::Tentative,
|
||||
"cancelled" => crate::calendar::EventStatus::Cancelled,
|
||||
_ => crate::calendar::EventStatus::Confirmed,
|
||||
};
|
||||
|
||||
// Parse class
|
||||
let class = match request.class.to_lowercase().as_str() {
|
||||
"private" => crate::calendar::EventClass::Private,
|
||||
"confidential" => crate::calendar::EventClass::Confidential,
|
||||
_ => crate::calendar::EventClass::Public,
|
||||
};
|
||||
|
||||
// Parse attendees (comma-separated email list)
|
||||
let attendees: Vec<String> = if request.attendees.trim().is_empty() {
|
||||
Vec::new()
|
||||
} else {
|
||||
request.attendees
|
||||
.split(',')
|
||||
.map(|s| s.trim().to_string())
|
||||
.filter(|s| !s.is_empty())
|
||||
.collect()
|
||||
};
|
||||
|
||||
// Parse categories (comma-separated list)
|
||||
let categories: Vec<String> = if request.categories.trim().is_empty() {
|
||||
Vec::new()
|
||||
} else {
|
||||
request.categories
|
||||
.split(',')
|
||||
.map(|s| s.trim().to_string())
|
||||
.filter(|s| !s.is_empty())
|
||||
.collect()
|
||||
};
|
||||
|
||||
// Parse reminders (for now, just store as a simple reminder duration)
|
||||
let reminders: Vec<chrono::Duration> = match request.reminder.to_lowercase().as_str() {
|
||||
"15min" => vec![chrono::Duration::minutes(15)],
|
||||
"30min" => vec![chrono::Duration::minutes(30)],
|
||||
"1hour" => vec![chrono::Duration::hours(1)],
|
||||
"2hours" => vec![chrono::Duration::hours(2)],
|
||||
"1day" => vec![chrono::Duration::days(1)],
|
||||
"2days" => vec![chrono::Duration::days(2)],
|
||||
"1week" => vec![chrono::Duration::weeks(1)],
|
||||
_ => Vec::new(),
|
||||
};
|
||||
|
||||
// Parse recurrence (basic implementation)
|
||||
let recurrence_rule = match request.recurrence.to_lowercase().as_str() {
|
||||
"daily" => Some("FREQ=DAILY".to_string()),
|
||||
"weekly" => Some("FREQ=WEEKLY".to_string()),
|
||||
"monthly" => Some("FREQ=MONTHLY".to_string()),
|
||||
"yearly" => Some("FREQ=YEARLY".to_string()),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
// Create the CalendarEvent struct
|
||||
let event = crate::calendar::CalendarEvent {
|
||||
uid,
|
||||
@@ -431,17 +488,21 @@ pub async fn create_event(
|
||||
} else {
|
||||
Some(request.location.clone())
|
||||
},
|
||||
status: crate::calendar::EventStatus::Confirmed,
|
||||
class: crate::calendar::EventClass::Public,
|
||||
priority: None,
|
||||
organizer: None,
|
||||
attendees: Vec::new(),
|
||||
categories: Vec::new(),
|
||||
status,
|
||||
class,
|
||||
priority: request.priority,
|
||||
organizer: if request.organizer.trim().is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(request.organizer.clone())
|
||||
},
|
||||
attendees,
|
||||
categories,
|
||||
created: Some(chrono::Utc::now()),
|
||||
last_modified: Some(chrono::Utc::now()),
|
||||
recurrence_rule: None,
|
||||
recurrence_rule,
|
||||
all_day: request.all_day,
|
||||
reminders: Vec::new(),
|
||||
reminders,
|
||||
etag: None,
|
||||
href: None,
|
||||
calendar_path: Some(calendar_path.clone()),
|
||||
|
||||
@@ -80,6 +80,14 @@ pub struct CreateEventRequest {
|
||||
pub end_time: String, // HH:MM format
|
||||
pub location: String,
|
||||
pub all_day: bool,
|
||||
pub status: String, // confirmed, tentative, cancelled
|
||||
pub class: String, // public, private, confidential
|
||||
pub priority: Option<u8>, // 0-9 priority level
|
||||
pub organizer: String, // organizer email
|
||||
pub attendees: String, // comma-separated attendee emails
|
||||
pub categories: String, // comma-separated categories
|
||||
pub reminder: String, // reminder type
|
||||
pub recurrence: String, // recurrence type
|
||||
pub calendar_path: Option<String>, // Optional - use first calendar if not specified
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user