feat: add JMAP Calendar integration with month/week/day/agenda views

Full calendar support via JMAP Calendars (RFC 8984):
- Event create/edit/delete with recurrence rules and reminders
- Multi-day event spanning, column-based overlap layout
- Locale-aware date formatting, first day of week and time format settings
- Real-time updates via push notifications
- ARIA accessibility, input validation, color sanitization
- Keyboard shortcuts, mobile touch targets, focus trap
- ICU pluralization for all 8 supported languages
This commit is contained in:
Matthieu MALVACHE
2026-02-16 20:34:29 +01:00
committed by Matthieu MALVACHE
parent fb414bf2c9
commit e6f67c24cb
28 changed files with 3922 additions and 39 deletions
+112 -1
View File
@@ -32,6 +32,7 @@
"storage": "Storage",
"sign_out": "Sign out",
"contacts": "Contacts",
"calendar": "Calendar",
"settings": "Settings",
"loading_mailboxes": "Loading mailboxes...",
"push_connected": "Real-time updates active",
@@ -375,7 +376,8 @@
"account": "Account",
"identities": "Identities",
"vacation": "Vacation Responder",
"advanced": "Advanced"
"advanced": "Advanced",
"calendar": "Calendar"
},
"appearance": {
"title": "Appearance",
@@ -902,6 +904,115 @@
"error_delete": "Failed to delete contact"
}
},
"calendar": {
"title": "Calendar",
"back_to_email": "Back to email",
"my_calendars": "My calendars",
"views": {
"month": "Month",
"week": "Week",
"day": "Day",
"agenda": "Agenda",
"today": "Today"
},
"events": {
"create": "Create event",
"edit": "Edit event",
"delete": "Delete event",
"details": "Event details",
"no_events": "No events",
"all_day": "All day",
"more": "+{count} more",
"no_title": "(No title)",
"today_header": "Today",
"tomorrow_header": "Tomorrow"
},
"form": {
"title": "Title",
"description": "Description",
"location": "Location",
"start_date": "Start date",
"end_date": "End date",
"start_time": "Start time",
"end_time": "End time",
"all_day_event": "All-day event",
"calendar_select": "Calendar",
"save": "Save",
"cancel": "Cancel",
"delete_confirm": "Are you sure you want to delete this event?",
"color": "Color"
},
"participants": {
"title": "Participants",
"add": "Add participant",
"organizer": "Organizer",
"attendee": "Attendee",
"accepted": "Accepted",
"declined": "Declined",
"tentative": "Tentative",
"needs_action": "Needs action"
},
"recurrence": {
"title": "Recurrence",
"none": "Does not repeat",
"daily": "Daily",
"weekly": "Weekly",
"monthly": "Monthly",
"yearly": "Yearly",
"every_n_days": "Every {count} days",
"every_n_weeks": "Every {count} weeks",
"every_n_months": "Every {count} months",
"until": "Until",
"occurrences": "{count} occurrences"
},
"alerts": {
"title": "Reminder",
"none": "No reminder",
"at_time": "At time of event",
"minutes_before": "{count, plural, one {# minute before} other {# minutes before}}",
"hours_before": "{count, plural, one {# hour before} other {# hours before}}",
"days_before": "{count, plural, one {# day before} other {# days before}}"
},
"settings": {
"title": "Calendar settings",
"default_view": "Default view",
"week_starts_on": "Week starts on",
"time_format": "Time format",
"default_calendar": "Default calendar",
"default_reminder": "Default reminder",
"time_format_12h": "12-hour",
"time_format_24h": "24-hour"
},
"days": {
"monday": "Monday",
"tuesday": "Tuesday",
"wednesday": "Wednesday",
"thursday": "Thursday",
"friday": "Friday",
"saturday": "Saturday",
"sunday": "Sunday",
"mon": "Mon",
"tue": "Tue",
"wed": "Wed",
"thu": "Thu",
"fri": "Fri",
"sat": "Sat",
"sun": "Sun"
},
"notifications": {
"event_created": "Event created",
"event_updated": "Event updated",
"event_deleted": "Event deleted",
"calendar_created": "Calendar created",
"calendar_deleted": "Calendar deleted"
},
"status": {
"loading_calendars": "Loading calendars...",
"loading_events": "Loading events..."
},
"nav_prev": "Previous",
"nav_next": "Next"
},
"advanced_search": {
"title": "Advanced Search",
"from": "From",