From 02f6436fd09def9435bb24ee9b102a9b49414dc6 Mon Sep 17 00:00:00 2001 From: Gregor Vostrak Date: Tue, 3 Mar 2026 15:00:46 +0100 Subject: [PATCH] keep calendar event data while resizing event --- .../FullCalendar/FullCalendarEventContent.vue | 2 +- .../ui/src/FullCalendar/useVisualSnap.ts | 23 ++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/resources/js/packages/ui/src/FullCalendar/FullCalendarEventContent.vue b/resources/js/packages/ui/src/FullCalendar/FullCalendarEventContent.vue index 35530cd0..7e8523c5 100644 --- a/resources/js/packages/ui/src/FullCalendar/FullCalendarEventContent.vue +++ b/resources/js/packages/ui/src/FullCalendar/FullCalendarEventContent.vue @@ -51,7 +51,7 @@ const formattedDuration = computed(() =>
{{ clientName }}
-
+
{{ formattedDuration }}
diff --git a/resources/js/packages/ui/src/FullCalendar/useVisualSnap.ts b/resources/js/packages/ui/src/FullCalendar/useVisualSnap.ts index 68f57101..438ca4ef 100644 --- a/resources/js/packages/ui/src/FullCalendar/useVisualSnap.ts +++ b/resources/js/packages/ui/src/FullCalendar/useVisualSnap.ts @@ -38,6 +38,21 @@ export function useVisualSnap({ return { mirror, harness }; } + /** + * Copy the Vue-rendered event content from the original event into the + * FC mirror element (which only gets FC's default time-only rendering). + */ + function copyEventContentToMirror(calendarEl: HTMLElement, mirror: HTMLElement) { + const originalEvent = calendarEl.querySelector( + '.fc-event-resizing:not(.fc-event-mirror), .fc-event-dragging:not(.fc-event-mirror)' + ) as HTMLElement | null; + if (!originalEvent) return; + const originalMain = originalEvent.querySelector('.fc-event-main') as HTMLElement | null; + const mirrorMain = mirror.querySelector('.fc-event-main') as HTMLElement | null; + if (!originalMain || !mirrorMain) return; + mirrorMain.innerHTML = originalMain.innerHTML; + } + function updateMirrorDurationLabel( mirror: HTMLElement, snappedTop: number, @@ -46,7 +61,7 @@ export function useVisualSnap({ ) { const snappedDurationMin = Math.round((snappedEnd - snappedTop) / snapPx) * snapMinutes(); const durationText = formatDuration(snappedDurationMin * 60); - const durationEl = mirror.querySelector('.fc-event-main')?.querySelector('div:last-child'); + const durationEl = mirror.querySelector('[data-duration]'); if (durationEl) { durationEl.textContent = durationText; } @@ -115,11 +130,17 @@ export function useVisualSnap({ let initialTop: number | null = null; let initialEnd: number | null = null; let resizeEdge: 'top' | 'bottom' | null = null; + let contentCopied = false; startLoop((calendarEl, snapPx) => { const { mirror, harness } = findMirrorHarness(calendarEl); if (!harness) return; + if (mirror && !contentCopied) { + copyEventContentToMirror(calendarEl, mirror); + contentCopied = true; + } + const top = parseFloat(harness.style.top) || 0; const endPos = -(parseFloat(harness.style.bottom) || 0);