From 5c9e16f634dc36727142bf245001c13956cce915 Mon Sep 17 00:00:00 2001 From: Till JS Date: Fri, 20 Mar 2026 19:22:28 +0100 Subject: [PATCH] fix(calendar): integrate recurrence dialog and external calendars into UI - Wire RecurrenceEditDialog into EventDetailModal and QuickEventOverlay so deleting recurring events shows "this/all/future" options - Add external calendars section to CalendarSidebar with visibility toggle and sync error indicator - Update COMPLEXITY_AUDIT.md to mark sync and recurrence as implemented Co-Authored-By: Claude Opus 4.6 (1M context) --- .../calendar/CalendarSidebar.svelte | 63 +++++++++++++++++++ .../components/event/EventDetailModal.svelte | 33 ++++++++++ .../components/event/QuickEventOverlay.svelte | 35 +++++++++++ apps/calendar/docs/COMPLEXITY_AUDIT.md | 17 +++-- 4 files changed, 142 insertions(+), 6 deletions(-) diff --git a/apps/calendar/apps/web/src/lib/components/calendar/CalendarSidebar.svelte b/apps/calendar/apps/web/src/lib/components/calendar/CalendarSidebar.svelte index e8dbef1a8..e0b9bf5c5 100644 --- a/apps/calendar/apps/web/src/lib/components/calendar/CalendarSidebar.svelte +++ b/apps/calendar/apps/web/src/lib/components/calendar/CalendarSidebar.svelte @@ -1,14 +1,27 @@
@@ -41,6 +54,41 @@

Keine Kalender vorhanden

{/if}
+ + {#if externalCalendarsStore.calendars.length > 0} +
+

Externe Kalender

+ +
+ +
+ {#each externalCalendarsStore.calendars as cal} + + {/each} +
+ {/if} diff --git a/apps/calendar/apps/web/src/lib/components/event/EventDetailModal.svelte b/apps/calendar/apps/web/src/lib/components/event/EventDetailModal.svelte index 84a6ae38b..ab7ed9feb 100644 --- a/apps/calendar/apps/web/src/lib/components/event/EventDetailModal.svelte +++ b/apps/calendar/apps/web/src/lib/components/event/EventDetailModal.svelte @@ -3,8 +3,10 @@ import { eventsStore } from '$lib/stores/events.svelte'; import { calendarsStore } from '$lib/stores/calendars.svelte'; import EventForm from './EventForm.svelte'; + import RecurrenceEditDialog from './RecurrenceEditDialog.svelte'; import { TagBadge, toastStore as toast } from '@manacore/shared-ui'; import type { CalendarEvent, UpdateEventInput } from '@calendar/shared'; + import { describeRecurrence, parseRRule } from '@calendar/shared'; import * as api from '$lib/api/events'; import { format } from 'date-fns'; import { de } from 'date-fns/locale'; @@ -21,6 +23,8 @@ let event = $state(null); let loading = $state(true); let isEditing = $state(false); + let showRecurrenceDialog = $state(false); + let recurrenceDialogMode = $state<'edit' | 'delete'>('delete'); // Load event data $effect(() => { @@ -60,6 +64,13 @@ async function handleDelete() { if (!event) return; + // For recurring events, show the recurrence dialog + if (event.recurrenceRule || eventsStore.isRecurrenceOccurrence(event.id)) { + recurrenceDialogMode = 'delete'; + showRecurrenceDialog = true; + return; + } + if (!confirm('Möchten Sie diesen Termin wirklich löschen?')) { return; } @@ -75,6 +86,21 @@ onClose(); } + async function handleRecurrenceAction(action: 'this' | 'all' | 'this_and_future') { + if (!event) return; + showRecurrenceDialog = false; + + if (recurrenceDialogMode === 'delete') { + let result; + if (action === 'this') { + result = await eventsStore.deleteRecurrenceOccurrence(event.id); + } else { + result = await eventsStore.deleteRecurrenceSeries(event.id); + } + if (!result.error) onClose(); + } + } + function handleCancel() { if (isEditing) { isEditing = false; @@ -145,6 +171,13 @@ + (showRecurrenceDialog = false)} +/> +