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": "Speicher",
"sign_out": "Abmelden",
"contacts": "Kontakte",
"calendar": "Kalender",
"settings": "Einstellungen",
"loading_mailboxes": "Postfächer werden geladen...",
"push_connected": "Echtzeit-Updates aktiv",
@@ -375,7 +376,8 @@
"account": "Konto",
"identities": "Identitäten",
"vacation": "Abwesenheitsnotiz",
"advanced": "Erweitert"
"advanced": "Erweitert",
"calendar": "Kalender"
},
"appearance": {
"title": "Darstellung",
@@ -902,6 +904,115 @@
"error_delete": "Kontakt konnte nicht gelöscht werden"
}
},
"calendar": {
"title": "Kalender",
"back_to_email": "Zurück zu E-Mails",
"my_calendars": "Meine Kalender",
"views": {
"month": "Monat",
"week": "Woche",
"day": "Tag",
"agenda": "Agenda",
"today": "Heute"
},
"events": {
"create": "Termin erstellen",
"edit": "Termin bearbeiten",
"delete": "Termin löschen",
"details": "Termindetails",
"no_events": "Keine Termine",
"all_day": "Ganztägig",
"more": "+{count} weitere",
"no_title": "(Kein Titel)",
"today_header": "Heute",
"tomorrow_header": "Morgen"
},
"form": {
"title": "Titel",
"description": "Beschreibung",
"location": "Ort",
"start_date": "Startdatum",
"end_date": "Enddatum",
"start_time": "Startzeit",
"end_time": "Endzeit",
"all_day_event": "Ganztägiger Termin",
"calendar_select": "Kalender",
"save": "Speichern",
"cancel": "Abbrechen",
"delete_confirm": "Sind Sie sicher, dass Sie diesen Termin löschen möchten?",
"color": "Farbe"
},
"participants": {
"title": "Teilnehmer",
"add": "Teilnehmer hinzufügen",
"organizer": "Organisator",
"attendee": "Teilnehmer",
"accepted": "Zugesagt",
"declined": "Abgelehnt",
"tentative": "Vorläufig",
"needs_action": "Antwort ausstehend"
},
"recurrence": {
"title": "Wiederholung",
"none": "Keine Wiederholung",
"daily": "Täglich",
"weekly": "Wöchentlich",
"monthly": "Monatlich",
"yearly": "Jährlich",
"every_n_days": "Alle {count} Tage",
"every_n_weeks": "Alle {count} Wochen",
"every_n_months": "Alle {count} Monate",
"until": "Bis",
"occurrences": "{count} Wiederholungen"
},
"alerts": {
"title": "Erinnerung",
"none": "Keine Erinnerung",
"at_time": "Zum Zeitpunkt des Termins",
"minutes_before": "{count, plural, one {# Minute vorher} other {# Minuten vorher}}",
"hours_before": "{count, plural, one {# Stunde vorher} other {# Stunden vorher}}",
"days_before": "{count, plural, one {# Tag vorher} other {# Tage vorher}}"
},
"settings": {
"title": "Kalendereinstellungen",
"default_view": "Standardansicht",
"week_starts_on": "Woche beginnt am",
"time_format": "Zeitformat",
"default_calendar": "Standardkalender",
"default_reminder": "Standarderinnerung",
"time_format_12h": "12-Stunden",
"time_format_24h": "24-Stunden"
},
"days": {
"monday": "Montag",
"tuesday": "Dienstag",
"wednesday": "Mittwoch",
"thursday": "Donnerstag",
"friday": "Freitag",
"saturday": "Samstag",
"sunday": "Sonntag",
"mon": "Mo",
"tue": "Di",
"wed": "Mi",
"thu": "Do",
"fri": "Fr",
"sat": "Sa",
"sun": "So"
},
"notifications": {
"event_created": "Termin erstellt",
"event_updated": "Termin aktualisiert",
"event_deleted": "Termin gelöscht",
"calendar_created": "Kalender erstellt",
"calendar_deleted": "Kalender gelöscht"
},
"status": {
"loading_calendars": "Kalender werden geladen...",
"loading_events": "Termine werden geladen..."
},
"nav_prev": "Zurück",
"nav_next": "Weiter"
},
"advanced_search": {
"title": "Erweiterte Suche",
"from": "Von",