From 457e22226235d582453cba03ab0fe988d7471274 Mon Sep 17 00:00:00 2001 From: Janus Knudsen Date: Sun, 24 Aug 2025 21:31:52 +0200 Subject: [PATCH] Improves drag-and-drop event handling Enhances the drag-and-drop experience for event elements by introducing snapping to a configurable time interval and fading out the original element upon successful drop. This change allows users to configure the snap interval in minutes, making it easier to align events to specific time slots. It also adds visual feedback by making the original event transparent during the drag and fading it out on drop, providing a clearer indication of the event's movement. --- src/managers/ColumnDetector.ts | 86 +++++++++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 11 deletions(-) diff --git a/src/managers/ColumnDetector.ts b/src/managers/ColumnDetector.ts index 412ef68..1354fc0 100644 --- a/src/managers/ColumnDetector.ts +++ b/src/managers/ColumnDetector.ts @@ -8,11 +8,54 @@ export class ColumnDetector { private lastMousePosition = { x: 0, y: 0 }; private lastLoggedPosition = { x: 0, y: 0 }; private draggedClone: HTMLElement | null = null; + private originalEvent: HTMLElement | null = null; private mouseOffset = { x: 0, y: 0 }; + // Konfiguration for snap interval + private snapIntervalMinutes = 15; // 15 minutter + private hourHeightPx = 60; // Fra CSS --hour-height + private get snapDistancePx(): number { + return (this.snapIntervalMinutes / 60) * this.hourHeightPx; // 15/60 * 60 = 15px + } + constructor() { this.init(); } + + /** + * Konfigurer snap interval + */ + public setSnapInterval(minutes: number): void { + this.snapIntervalMinutes = minutes; + console.log(`Snap interval set to ${minutes} minutes (${this.snapDistancePx}px)`); + } + + /** + * Fade out og fjern element fra DOM + */ + private fadeOutAndRemove(element: HTMLElement): void { + element.style.transition = 'opacity 0.3s ease-out'; + element.style.opacity = '0'; + + setTimeout(() => { + element.remove(); + }, 300); + } + + /** + * Fjern "clone-" prefix fra event ID og gendan pointer events + */ + private removeClonePrefix(clone: HTMLElement): void { + const cloneId = clone.dataset.eventId; + if (cloneId && cloneId.startsWith('clone-')) { + const originalId = cloneId.replace('clone-', ''); + clone.dataset.eventId = originalId; + console.log(`Removed clone prefix: ${cloneId} -> ${originalId}`); + } + + // Gendan pointer events så klonen kan dragges igen + clone.style.pointerEvents = ''; + } private init(): void { // Lyt til mouse move på hele body @@ -27,19 +70,20 @@ export class ColumnDetector { } private handleMouseMove(event: MouseEvent): void { - // Hvis musen er holdt nede, tjek for 25px vertikal bevægelse + // Hvis musen er holdt nede, tjek for snap interval vertikal bevægelse if (this.isMouseDown) { const deltaY = Math.abs(event.clientY - this.lastLoggedPosition.y); - if (deltaY >= 25) { - console.log('Mouse dragged 25px vertically:', { + if (deltaY >= this.snapDistancePx) { + console.log(`Mouse dragged ${this.snapIntervalMinutes} minutes (${this.snapDistancePx}px) vertically:`, { from: this.lastLoggedPosition, to: { x: event.clientX, y: event.clientY }, - verticalDistance: Math.round(deltaY) + verticalDistance: Math.round(deltaY), + snapInterval: `${this.snapIntervalMinutes} minutes` }); this.lastLoggedPosition = { x: event.clientX, y: event.clientY }; - // Opdater klonens Y-position ved 25px snap (relativt til kolonne) + // Opdater klonens Y-position ved snap interval (relativt til kolonne) if (this.draggedClone && this.draggedClone.parentElement) { const columnRect = this.draggedClone.parentElement.getBoundingClientRect(); const relativeY = event.clientY - columnRect.top - this.mouseOffset.y; @@ -149,7 +193,12 @@ export class ColumnDetector { // Hvis vi fandt et event, lav en clone if (eventElement) { + // Gem reference til original event + this.originalEvent = eventElement; this.cloneEvent(eventElement, event); + // Sæt originalen til gennemsigtig og forhindre text selection mens der trækkes + eventElement.style.opacity = '0.6'; + eventElement.style.userSelect = 'none'; } } @@ -208,12 +257,27 @@ export class ColumnDetector { this.isMouseDown = false; console.log('Mouse up at:', { x: event.clientX, y: event.clientY }); - // Ryd op - fjern klonen (DISABLED FOR DEBUGGING) - // if (this.draggedClone) { - // this.draggedClone.remove(); - // this.draggedClone = null; - // console.log('Removed clone'); - // } + // Drop operationen: fade out original og remove clone suffix + if (this.originalEvent && this.draggedClone) { + // Fade out og fjern originalen + this.fadeOutAndRemove(this.originalEvent); + + // Fjern clone suffix fra klonen + this.removeClonePrefix(this.draggedClone); + + // Ryd op + this.originalEvent = null; + this.draggedClone = null; + + console.log('Drop completed: original faded out and removed, clone became permanent'); + } + + // Cleanup hvis ingen drop (ingen clone var aktiv) + if (this.originalEvent && !this.draggedClone) { + this.originalEvent.style.opacity = ''; + this.originalEvent.style.userSelect = ''; + this.originalEvent = null; + } } public destroy(): void {