Fix calendar event fetching to use visible date range
Some checks failed
Build and Push Docker Image / docker (push) Failing after 1m7s

Moved event fetching logic from CalendarView to Calendar component to properly
use the visible date range instead of hardcoded current month. The Calendar
component already tracks the current visible date through navigation, so events
now load correctly for August and other months when navigating.

Changes:
- Calendar component now manages its own events state and fetching
- Event fetching responds to current_date changes from navigation
- CalendarView simplified to just render Calendar component
- Fixed cargo fmt/clippy formatting across codebase

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Connor Johnstone
2025-09-01 18:31:51 -04:00
parent e55e6bf4dd
commit 79f287ed61
38 changed files with 3922 additions and 2590 deletions

View File

@@ -1,6 +1,6 @@
//! Common types and enums used across calendar components
use chrono::{DateTime, Utc, Duration};
use chrono::{DateTime, Duration, Utc};
use serde::{Deserialize, Serialize};
// ==================== ENUMS AND COMMON TYPES ====================
@@ -22,7 +22,7 @@ pub enum EventClass {
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum TimeTransparency {
Opaque, // OPAQUE - time is not available
Transparent, // TRANSPARENT - time is available
Transparent, // TRANSPARENT - time is available
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
@@ -64,11 +64,11 @@ pub enum AlarmAction {
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct CalendarUser {
pub cal_address: String, // Calendar user address (usually email)
pub common_name: Option<String>, // CN parameter - display name
pub dir_entry_ref: Option<String>, // DIR parameter - directory entry
pub sent_by: Option<String>, // SENT-BY parameter
pub language: Option<String>, // LANGUAGE parameter
pub cal_address: String, // Calendar user address (usually email)
pub common_name: Option<String>, // CN parameter - display name
pub dir_entry_ref: Option<String>, // DIR parameter - directory entry
pub sent_by: Option<String>, // SENT-BY parameter
pub language: Option<String>, // LANGUAGE parameter
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
@@ -78,130 +78,130 @@ pub struct Attendee {
pub role: Option<AttendeeRole>, // ROLE parameter
pub part_stat: Option<ParticipationStatus>, // PARTSTAT parameter
pub rsvp: Option<bool>, // RSVP parameter
pub cu_type: Option<String>, // CUTYPE parameter (INDIVIDUAL, GROUP, RESOURCE, ROOM, UNKNOWN)
pub member: Vec<String>, // MEMBER parameter
pub delegated_to: Vec<String>, // DELEGATED-TO parameter
pub delegated_from: Vec<String>, // DELEGATED-FROM parameter
pub sent_by: Option<String>, // SENT-BY parameter
pub dir_entry_ref: Option<String>, // DIR parameter
pub language: Option<String>, // LANGUAGE parameter
pub cu_type: Option<String>, // CUTYPE parameter (INDIVIDUAL, GROUP, RESOURCE, ROOM, UNKNOWN)
pub member: Vec<String>, // MEMBER parameter
pub delegated_to: Vec<String>, // DELEGATED-TO parameter
pub delegated_from: Vec<String>, // DELEGATED-FROM parameter
pub sent_by: Option<String>, // SENT-BY parameter
pub dir_entry_ref: Option<String>, // DIR parameter
pub language: Option<String>, // LANGUAGE parameter
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct VAlarm {
pub action: AlarmAction, // Action (ACTION) - REQUIRED
pub trigger: AlarmTrigger, // Trigger (TRIGGER) - REQUIRED
pub duration: Option<Duration>, // Duration (DURATION)
pub repeat: Option<u32>, // Repeat count (REPEAT)
pub description: Option<String>, // Description for DISPLAY/EMAIL
pub summary: Option<String>, // Summary for EMAIL
pub attendees: Vec<Attendee>, // Attendees for EMAIL
pub attach: Vec<Attachment>, // Attachments for AUDIO/EMAIL
pub action: AlarmAction, // Action (ACTION) - REQUIRED
pub trigger: AlarmTrigger, // Trigger (TRIGGER) - REQUIRED
pub duration: Option<Duration>, // Duration (DURATION)
pub repeat: Option<u32>, // Repeat count (REPEAT)
pub description: Option<String>, // Description for DISPLAY/EMAIL
pub summary: Option<String>, // Summary for EMAIL
pub attendees: Vec<Attendee>, // Attendees for EMAIL
pub attach: Vec<Attachment>, // Attachments for AUDIO/EMAIL
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum AlarmTrigger {
DateTime(DateTime<Utc>), // Absolute trigger time
Duration(Duration), // Duration relative to start/end
DateTime(DateTime<Utc>), // Absolute trigger time
Duration(Duration), // Duration relative to start/end
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Attachment {
pub format_type: Option<String>, // FMTTYPE parameter (MIME type)
pub encoding: Option<String>, // ENCODING parameter
pub value: Option<String>, // VALUE parameter (BINARY or URI)
pub uri: Option<String>, // URI reference
pub binary_data: Option<Vec<u8>>, // Binary data (when ENCODING=BASE64)
pub format_type: Option<String>, // FMTTYPE parameter (MIME type)
pub encoding: Option<String>, // ENCODING parameter
pub value: Option<String>, // VALUE parameter (BINARY or URI)
pub uri: Option<String>, // URI reference
pub binary_data: Option<Vec<u8>>, // Binary data (when ENCODING=BASE64)
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct GeographicPosition {
pub latitude: f64, // Latitude in decimal degrees
pub longitude: f64, // Longitude in decimal degrees
pub latitude: f64, // Latitude in decimal degrees
pub longitude: f64, // Longitude in decimal degrees
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct VTimeZone {
pub tzid: String, // Time zone ID (TZID) - REQUIRED
pub last_modified: Option<DateTime<Utc>>, // Last modified (LAST-MODIFIED)
pub tzurl: Option<String>, // Time zone URL (TZURL)
pub tzid: String, // Time zone ID (TZID) - REQUIRED
pub last_modified: Option<DateTime<Utc>>, // Last modified (LAST-MODIFIED)
pub tzurl: Option<String>, // Time zone URL (TZURL)
pub standard_components: Vec<TimeZoneComponent>, // STANDARD components
pub daylight_components: Vec<TimeZoneComponent>, // DAYLIGHT components
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct TimeZoneComponent {
pub dtstart: DateTime<Utc>, // Start of this time zone definition
pub tzoffset_to: String, // UTC offset for this component
pub tzoffset_from: String, // UTC offset before this component
pub rrule: Option<String>, // Recurrence rule
pub rdate: Vec<DateTime<Utc>>, // Recurrence dates
pub tzname: Vec<String>, // Time zone names
pub comment: Vec<String>, // Comments
pub dtstart: DateTime<Utc>, // Start of this time zone definition
pub tzoffset_to: String, // UTC offset for this component
pub tzoffset_from: String, // UTC offset before this component
pub rrule: Option<String>, // Recurrence rule
pub rdate: Vec<DateTime<Utc>>, // Recurrence dates
pub tzname: Vec<String>, // Time zone names
pub comment: Vec<String>, // Comments
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct VJournal {
// Required properties
pub dtstamp: DateTime<Utc>, // Date-time stamp (DTSTAMP) - REQUIRED
pub uid: String, // Unique identifier (UID) - REQUIRED
pub dtstamp: DateTime<Utc>, // Date-time stamp (DTSTAMP) - REQUIRED
pub uid: String, // Unique identifier (UID) - REQUIRED
// Optional properties
pub dtstart: Option<DateTime<Utc>>, // Start date-time (DTSTART)
pub summary: Option<String>, // Summary/title (SUMMARY)
pub description: Option<String>, // Description (DESCRIPTION)
pub dtstart: Option<DateTime<Utc>>, // Start date-time (DTSTART)
pub summary: Option<String>, // Summary/title (SUMMARY)
pub description: Option<String>, // Description (DESCRIPTION)
// Classification and status
pub class: Option<EventClass>, // Classification (CLASS)
pub status: Option<String>, // Status (STATUS)
pub class: Option<EventClass>, // Classification (CLASS)
pub status: Option<String>, // Status (STATUS)
// People and organization
pub organizer: Option<CalendarUser>, // Organizer (ORGANIZER)
pub attendees: Vec<Attendee>, // Attendees (ATTENDEE)
pub organizer: Option<CalendarUser>, // Organizer (ORGANIZER)
pub attendees: Vec<Attendee>, // Attendees (ATTENDEE)
// Categorization
pub categories: Vec<String>, // Categories (CATEGORIES)
pub categories: Vec<String>, // Categories (CATEGORIES)
// Versioning and modification
pub sequence: Option<u32>, // Sequence number (SEQUENCE)
pub created: Option<DateTime<Utc>>, // Creation time (CREATED)
pub last_modified: Option<DateTime<Utc>>, // Last modified (LAST-MODIFIED)
pub sequence: Option<u32>, // Sequence number (SEQUENCE)
pub created: Option<DateTime<Utc>>, // Creation time (CREATED)
pub last_modified: Option<DateTime<Utc>>, // Last modified (LAST-MODIFIED)
// Recurrence
pub rrule: Option<String>, // Recurrence rule (RRULE)
pub rdate: Vec<DateTime<Utc>>, // Recurrence dates (RDATE)
pub exdate: Vec<DateTime<Utc>>, // Exception dates (EXDATE)
pub recurrence_id: Option<DateTime<Utc>>, // Recurrence ID (RECURRENCE-ID)
pub rrule: Option<String>, // Recurrence rule (RRULE)
pub rdate: Vec<DateTime<Utc>>, // Recurrence dates (RDATE)
pub exdate: Vec<DateTime<Utc>>, // Exception dates (EXDATE)
pub recurrence_id: Option<DateTime<Utc>>, // Recurrence ID (RECURRENCE-ID)
// Attachments
pub attachments: Vec<Attachment>, // Attachments (ATTACH)
pub attachments: Vec<Attachment>, // Attachments (ATTACH)
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct VFreeBusy {
// Required properties
pub dtstamp: DateTime<Utc>, // Date-time stamp (DTSTAMP) - REQUIRED
pub uid: String, // Unique identifier (UID) - REQUIRED
pub dtstamp: DateTime<Utc>, // Date-time stamp (DTSTAMP) - REQUIRED
pub uid: String, // Unique identifier (UID) - REQUIRED
// Optional date-time properties
pub dtstart: Option<DateTime<Utc>>, // Start date-time (DTSTART)
pub dtend: Option<DateTime<Utc>>, // End date-time (DTEND)
pub dtstart: Option<DateTime<Utc>>, // Start date-time (DTSTART)
pub dtend: Option<DateTime<Utc>>, // End date-time (DTEND)
// People
pub organizer: Option<CalendarUser>, // Organizer (ORGANIZER)
pub attendees: Vec<Attendee>, // Attendees (ATTENDEE)
pub organizer: Option<CalendarUser>, // Organizer (ORGANIZER)
pub attendees: Vec<Attendee>, // Attendees (ATTENDEE)
// Free/busy time
pub freebusy: Vec<FreeBusyTime>, // Free/busy time periods
pub url: Option<String>, // URL (URL)
pub comment: Vec<String>, // Comments (COMMENT)
pub contact: Option<String>, // Contact information (CONTACT)
pub freebusy: Vec<FreeBusyTime>, // Free/busy time periods
pub url: Option<String>, // URL (URL)
pub comment: Vec<String>, // Comments (COMMENT)
pub contact: Option<String>, // Contact information (CONTACT)
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct FreeBusyTime {
pub fb_type: FreeBusyType, // Free/busy type
pub periods: Vec<Period>, // Time periods
pub fb_type: FreeBusyType, // Free/busy type
pub periods: Vec<Period>, // Time periods
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
@@ -214,7 +214,7 @@ pub enum FreeBusyType {
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Period {
pub start: DateTime<Utc>, // Period start
pub end: Option<DateTime<Utc>>, // Period end
pub duration: Option<Duration>, // Period duration (alternative to end)
}
pub start: DateTime<Utc>, // Period start
pub end: Option<DateTime<Utc>>, // Period end
pub duration: Option<Duration>, // Period duration (alternative to end)
}

View File

@@ -1,10 +1,10 @@
//! RFC 5545 Compliant Calendar Models
//!
//!
//! This crate provides shared data structures for calendar applications
//! that comply with RFC 5545 (iCalendar) specification.
pub mod vevent;
pub mod common;
pub mod vevent;
pub use common::*;
pub use vevent::*;
pub use common::*;

View File

@@ -1,66 +1,66 @@
//! VEvent - RFC 5545 compliant calendar event structure
use chrono::{DateTime, Utc, Duration};
use serde::{Deserialize, Serialize};
use crate::common::*;
use chrono::{DateTime, Duration, Utc};
use serde::{Deserialize, Serialize};
// ==================== VEVENT COMPONENT ====================
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct VEvent {
// Required properties
pub dtstamp: DateTime<Utc>, // Date-time stamp (DTSTAMP) - REQUIRED
pub uid: String, // Unique identifier (UID) - REQUIRED
pub dtstart: DateTime<Utc>, // Start date-time (DTSTART) - REQUIRED
pub dtstamp: DateTime<Utc>, // Date-time stamp (DTSTAMP) - REQUIRED
pub uid: String, // Unique identifier (UID) - REQUIRED
pub dtstart: DateTime<Utc>, // Start date-time (DTSTART) - REQUIRED
// Optional properties (commonly used)
pub dtend: Option<DateTime<Utc>>, // End date-time (DTEND)
pub duration: Option<Duration>, // Duration (DURATION) - alternative to DTEND
pub summary: Option<String>, // Summary/title (SUMMARY)
pub description: Option<String>, // Description (DESCRIPTION)
pub location: Option<String>, // Location (LOCATION)
pub dtend: Option<DateTime<Utc>>, // End date-time (DTEND)
pub duration: Option<Duration>, // Duration (DURATION) - alternative to DTEND
pub summary: Option<String>, // Summary/title (SUMMARY)
pub description: Option<String>, // Description (DESCRIPTION)
pub location: Option<String>, // Location (LOCATION)
// Classification and status
pub class: Option<EventClass>, // Classification (CLASS)
pub status: Option<EventStatus>, // Status (STATUS)
pub transp: Option<TimeTransparency>, // Time transparency (TRANSP)
pub priority: Option<u8>, // Priority 0-9 (PRIORITY)
pub class: Option<EventClass>, // Classification (CLASS)
pub status: Option<EventStatus>, // Status (STATUS)
pub transp: Option<TimeTransparency>, // Time transparency (TRANSP)
pub priority: Option<u8>, // Priority 0-9 (PRIORITY)
// People and organization
pub organizer: Option<CalendarUser>, // Organizer (ORGANIZER)
pub attendees: Vec<Attendee>, // Attendees (ATTENDEE)
pub contact: Option<String>, // Contact information (CONTACT)
pub organizer: Option<CalendarUser>, // Organizer (ORGANIZER)
pub attendees: Vec<Attendee>, // Attendees (ATTENDEE)
pub contact: Option<String>, // Contact information (CONTACT)
// Categorization and relationships
pub categories: Vec<String>, // Categories (CATEGORIES)
pub comment: Option<String>, // Comment (COMMENT)
pub resources: Vec<String>, // Resources (RESOURCES)
pub related_to: Option<String>, // Related component (RELATED-TO)
pub url: Option<String>, // URL (URL)
pub categories: Vec<String>, // Categories (CATEGORIES)
pub comment: Option<String>, // Comment (COMMENT)
pub resources: Vec<String>, // Resources (RESOURCES)
pub related_to: Option<String>, // Related component (RELATED-TO)
pub url: Option<String>, // URL (URL)
// Geographical
pub geo: Option<GeographicPosition>, // Geographic position (GEO)
pub geo: Option<GeographicPosition>, // Geographic position (GEO)
// Versioning and modification
pub sequence: Option<u32>, // Sequence number (SEQUENCE)
pub created: Option<DateTime<Utc>>, // Creation time (CREATED)
pub last_modified: Option<DateTime<Utc>>, // Last modified (LAST-MODIFIED)
pub sequence: Option<u32>, // Sequence number (SEQUENCE)
pub created: Option<DateTime<Utc>>, // Creation time (CREATED)
pub last_modified: Option<DateTime<Utc>>, // Last modified (LAST-MODIFIED)
// Recurrence
pub rrule: Option<String>, // Recurrence rule (RRULE)
pub rdate: Vec<DateTime<Utc>>, // Recurrence dates (RDATE)
pub exdate: Vec<DateTime<Utc>>, // Exception dates (EXDATE)
pub recurrence_id: Option<DateTime<Utc>>, // Recurrence ID (RECURRENCE-ID)
pub rrule: Option<String>, // Recurrence rule (RRULE)
pub rdate: Vec<DateTime<Utc>>, // Recurrence dates (RDATE)
pub exdate: Vec<DateTime<Utc>>, // Exception dates (EXDATE)
pub recurrence_id: Option<DateTime<Utc>>, // Recurrence ID (RECURRENCE-ID)
// Alarms and attachments
pub alarms: Vec<VAlarm>, // VALARM components
pub attachments: Vec<Attachment>, // Attachments (ATTACH)
pub alarms: Vec<VAlarm>, // VALARM components
pub attachments: Vec<Attachment>, // Attachments (ATTACH)
// CalDAV specific (for implementation)
pub etag: Option<String>, // ETag for CalDAV
pub href: Option<String>, // Href for CalDAV
pub calendar_path: Option<String>, // Calendar path
pub all_day: bool, // All-day event flag
pub etag: Option<String>, // ETag for CalDAV
pub href: Option<String>, // Href for CalDAV
pub calendar_path: Option<String>, // Calendar path
pub all_day: bool, // All-day event flag
}
impl VEvent {
@@ -129,7 +129,9 @@ impl VEvent {
/// Helper method to get display title (summary or "Untitled Event")
pub fn get_title(&self) -> String {
self.summary.clone().unwrap_or_else(|| "Untitled Event".to_string())
self.summary
.clone()
.unwrap_or_else(|| "Untitled Event".to_string())
}
/// Helper method to get start date for UI compatibility
@@ -151,7 +153,7 @@ impl VEvent {
pub fn get_status_display(&self) -> &'static str {
match &self.status {
Some(EventStatus::Tentative) => "Tentative",
Some(EventStatus::Confirmed) => "Confirmed",
Some(EventStatus::Confirmed) => "Confirmed",
Some(EventStatus::Cancelled) => "Cancelled",
None => "Confirmed", // Default
}
@@ -180,4 +182,4 @@ impl VEvent {
Some(p) => format!("Priority {}", p),
}
}
}
}