From 2630a1190bf2b20a4390603b767e155e884ccec4 Mon Sep 17 00:00:00 2001 From: Ivymaster Date: Tue, 23 Jun 2026 17:10:08 +0200 Subject: [PATCH] add update of kalender event location before req refetch --- public/css/Tempus.css | 34 ++++++- public/js/components/Tempus/Tempus.js | 122 +++++++++++++++++++++++--- public/js/composables/EventLoader.js | 2 +- 3 files changed, 141 insertions(+), 17 deletions(-) diff --git a/public/css/Tempus.css b/public/css/Tempus.css index 6903325b3..2430a9b53 100644 --- a/public/css/Tempus.css +++ b/public/css/Tempus.css @@ -185,15 +185,19 @@ body { } +.fhc-calendar-base-grid-line-event { + position: relative !important; +} + .updated-event { - position: relative; + position: relative !important; z-index: 10; animation: modernFocus 1s ease-out; border-radius: 0.25rem; } .updated-event-long { - position: relative; + position: relative !important; z-index: 10; animation: modernFocus 1.8s ease-out; border-radius: 0.25rem; @@ -252,4 +256,30 @@ body { opacity: 1; filter: saturate(1) brightness(1); } +} + +.spinner-overlay { + position: absolute; + inset: 0; /* top:0 right:0 bottom:0 left:0 */ + display: flex; + align-items: center; + justify-content: center; + z-index: 9999; + background: rgba(255, 255, 255, 1); + opacity: 0.4; +} + +.spinner { + width: 40px; + height: 40px; + border: 4px solid #ddd; + border-top: 4px solid #007bff; + border-radius: 50%; + animation: spin 0.8s linear infinite; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } } \ No newline at end of file diff --git a/public/js/components/Tempus/Tempus.js b/public/js/components/Tempus/Tempus.js index 9094d481a..7d9978be5 100644 --- a/public/js/components/Tempus/Tempus.js +++ b/public/js/components/Tempus/Tempus.js @@ -530,9 +530,21 @@ export default { return alert("Kein gültiges Kalender-Event zum Resizen"); const dates = this._parseDates(start, end); - if (!dates) return; + if ( + luxon.DateTime.fromISO(obj.orig.isostart).toMillis() === dates.startDT.toMillis() && + luxon.DateTime.fromISO(obj.orig.isoend).toMillis() === + dates.endDT.toMillis() + ) + return; + + this.updateKalenderEventElementDisplay( + obj.orig.kalender_id, + dates.startDT, + dates.endDT, + ); + return this._updateKalenderEvent( obj, dates.startDT, @@ -558,8 +570,21 @@ export default { const dates = this._parseDates(start, end); if (!dates) return; + if ( + luxon.DateTime.fromISO(obj.orig.isostart).toMillis() === dates.startDT.toMillis() && + luxon.DateTime.fromISO(obj.orig.isoend).toMillis() === + dates.endDT.toMillis() + ) + return; + const { startDT, endDT, start_time, end_time } = dates; + this.updateKalenderEventElementDisplay( + obj.orig.kalender_id, + startDT, + endDT, + ); + if (obj.type === "reservierung") { this.reservierungPending = true; this.$refs.reservierung.show(start_time, end_time); @@ -861,18 +886,29 @@ export default { scrollToAndEmphasizeUpdatedEvent() { if (!this.currentlyUpdatedEvent) return; - document.querySelectorAll(".updated-event").forEach((el) => { - el.classList.remove("updated-event"); - }); - document.querySelectorAll(".updated-event-long").forEach((el) => { - el.classList.remove("updated-event-long"); - }); - document.querySelectorAll(".deemphasized-event").forEach((el) => { - el.classList.remove("deemphasized-event"); - }); - document.querySelectorAll(".deemphasized-event-long").forEach((el) => { - el.classList.remove("deemphasized-event-long"); - }); + document + .querySelectorAll(".fhc-calendar-base-grid .part-body") + .forEach((el) => { + el.classList.remove("deemphasized-event", "deemphasized-event-long"); + }); + document + .querySelectorAll( + ".fhc-calendar-base-grid .fhc-calendar-base-grid-line-event", + ) + .forEach((el) => { + const spinner = el.querySelector(".spinner-overlay"); + if (spinner) { + spinner.remove(); + } + + el.classList.remove( + "updating-event", + "updated-event", + "updated-event-long", + "deemphasized-event", + "deemphasized-event-long", + ); + }); setTimeout(() => { const eventEl = document.querySelector( @@ -912,8 +948,18 @@ export default { setTimeout(() => { eventEl.classList.add(emphasizeUpdateClassName); + document - .querySelectorAll(".fhc-calendar-base-grid-line-event") + .querySelectorAll( + ".fhc-calendar-base-grid .fhc-calendar-base-grid-line-event", + ) + .forEach((el) => { + if (el !== eventEl) { + el.classList.add(deemphasizedUpdateClassName); + } + }); + document + .querySelectorAll(".fhc-calendar-base-grid .part-body") .forEach((el) => { if (el !== eventEl) { el.classList.add(deemphasizedUpdateClassName); @@ -924,6 +970,54 @@ export default { this.currentlyUpdatedEvent = null; }, 100); }, + updateKalenderEventElementDisplay(calendarId, startDT, endDT) { + if (!calendarId) return alert("Kein gültiges Kalender-Event zum Resizen"); + + let newPotentialStart = + startDT.diff(luxon.DateTime.fromISO("2026-06-22T00:00")).toMillis() ?? + 1; + let newPotentialEnd = endDT + .diff(luxon.DateTime.fromISO("2026-06-22T00:00")) + .toMillis(); + + let element = document.querySelector(`[data-id="event-${calendarId}"]`); + if (!element) return alert("Kein gültiges Kalender-Event zum Resizen"); + + setTimeout(() => { + element.style.gridRowEnd = "t_" + newPotentialEnd; + element.style.gridRowStart = "t_" + newPotentialStart; + }, 100); + + const outerDiv = document.createElement("div"); + outerDiv.className = "spinner-overlay"; + + const innerDiv = document.createElement("div"); + innerDiv.className = "spinner"; + + outerDiv.appendChild(innerDiv); + + element.appendChild(outerDiv); + + const calendar = document.querySelector(".fhc-calendar-base-grid"); + const eventRect = element.getBoundingClientRect(); + + const offset = 300; + + const isInsideScrolledView = + element.offsetLeft < calendar.scrollLeft + calendar.clientWidth && + element.offsetLeft + element.offsetWidth > calendar.scrollLeft && + element.offsetTop < calendar.scrollTop + calendar.clientHeight && + element.offsetTop + element.offsetHeight > calendar.scrollTop; + + const rect = element.getBoundingClientRect(); + if (!isInsideScrolledView) { + element.scrollIntoView({ + behavior: "smooth", + inline: "center", + block: "nearest", + }); + } + }, }, watch: { lecturers: { diff --git a/public/js/composables/EventLoader.js b/public/js/composables/EventLoader.js index 9be7c55c6..6627b985b 100644 --- a/public/js/composables/EventLoader.js +++ b/public/js/composables/EventLoader.js @@ -158,7 +158,7 @@ export function useEventLoader(rangeInterval, getPromiseFunc, isLoaderVisible = const reset = () => { loading_id = 0; tempEventsHolder = []; - loadingEvents.value = []; + //loadingEvents.value = []; eventsLoaded.splice(0, eventsLoaded.length); reload(); }