diff --git a/src/factories/ManagerFactory.ts b/src/factories/ManagerFactory.ts index db24bb7..9a370b2 100644 --- a/src/factories/ManagerFactory.ts +++ b/src/factories/ManagerFactory.ts @@ -7,6 +7,7 @@ import { ScrollManager } from '../managers/ScrollManager'; import { NavigationManager } from '../managers/NavigationManager'; import { ViewManager } from '../managers/ViewManager'; import { CalendarManager } from '../managers/CalendarManager'; +import { ColumnDetector } from '../managers/ColumnDetector'; /** * Factory for creating and managing calendar managers with proper dependency injection @@ -44,6 +45,7 @@ export class ManagerFactory { const scrollManager = new ScrollManager(); const navigationManager = new NavigationManager(eventBus, eventRenderer); const viewManager = new ViewManager(eventBus); + const columnDetector = new ColumnDetector(); // CalendarManager depends on all other managers const calendarManager = new CalendarManager( diff --git a/src/managers/ColumnDetector.ts b/src/managers/ColumnDetector.ts new file mode 100644 index 0000000..412ef68 --- /dev/null +++ b/src/managers/ColumnDetector.ts @@ -0,0 +1,225 @@ +/** + * ColumnDetector - Bare detect hvilken kolonne musen er over + */ + +export class ColumnDetector { + private currentColumn: string | null = null; + private isMouseDown = false; + private lastMousePosition = { x: 0, y: 0 }; + private lastLoggedPosition = { x: 0, y: 0 }; + private draggedClone: HTMLElement | null = null; + private mouseOffset = { x: 0, y: 0 }; + + constructor() { + this.init(); + } + + private init(): void { + // Lyt til mouse move på hele body + document.body.addEventListener('mousemove', this.handleMouseMove.bind(this)); + + // Lyt til click på hele body + document.body.addEventListener('click', this.handleClick.bind(this)); + + // Lyt til mouse down og up + document.body.addEventListener('mousedown', this.handleMouseDown.bind(this)); + document.body.addEventListener('mouseup', this.handleMouseUp.bind(this)); + } + + private handleMouseMove(event: MouseEvent): void { + // Hvis musen er holdt nede, tjek for 25px vertikal bevægelse + if (this.isMouseDown) { + const deltaY = Math.abs(event.clientY - this.lastLoggedPosition.y); + + if (deltaY >= 25) { + console.log('Mouse dragged 25px vertically:', { + from: this.lastLoggedPosition, + to: { x: event.clientX, y: event.clientY }, + verticalDistance: Math.round(deltaY) + }); + this.lastLoggedPosition = { x: event.clientX, y: event.clientY }; + + // Opdater klonens Y-position ved 25px snap (relativt til kolonne) + if (this.draggedClone && this.draggedClone.parentElement) { + const columnRect = this.draggedClone.parentElement.getBoundingClientRect(); + const relativeY = event.clientY - columnRect.top - this.mouseOffset.y; + this.draggedClone.style.top = relativeY + 'px'; + } + } + } + + // Find hvilket element musen er over (altid) + { + const elementUnder = document.elementFromPoint(event.clientX, event.clientY); + if (!elementUnder) { + // Ingen element under musen + if (this.currentColumn !== null) { + console.log('Left all columns'); + this.currentColumn = null; + } + return; + } + + // Gå op gennem DOM træet for at finde swp-day-column + let element = elementUnder as HTMLElement; + while (element && element.tagName !== 'SWP-DAY-COLUMN') { + element = element.parentElement as HTMLElement; + if (!element) { + // Ikke i en kolonne + if (this.currentColumn !== null) { + console.log('Left all columns'); + this.currentColumn = null; + } + return; + } + } + + // Vi fandt en kolonne + const date = element.dataset.date; + if (date && date !== this.currentColumn) { + console.log('Entered column:', date); + this.currentColumn = date; + + // Flyt klonen til ny kolonne ved kolonneskift + if (this.draggedClone && this.isMouseDown) { + // Flyt klonen til den nye kolonne + const newColumnElement = document.querySelector(`swp-day-column[data-date="${date}"]`); + if (newColumnElement) { + newColumnElement.appendChild(this.draggedClone); + // Opdater Y-position relativt til den nye kolonne + const columnRect = newColumnElement.getBoundingClientRect(); + const relativeY = event.clientY - columnRect.top - this.mouseOffset.y; + this.draggedClone.style.top = relativeY + 'px'; + } + } + } + } + } + + private handleClick(event: MouseEvent): void { + const target = event.target as HTMLElement; + + // Find event element + let eventElement = target; + while (eventElement && eventElement.tagName !== 'SWP-EVENTS-LAYER') { + if (eventElement.tagName === 'SWP-EVENT' || eventElement.tagName === 'SWP-ALLDAY-EVENT') { + break; + } + eventElement = eventElement.parentElement as HTMLElement; + if (!eventElement) return; + } + + // Hvis vi nåede til SWP-EVENTS-LAYER uden at finde et event, så return + if (!eventElement || eventElement.tagName === 'SWP-EVENTS-LAYER') { + return; + } + + // Log event info + const eventId = eventElement.dataset.eventId; + const eventType = eventElement.dataset.type; + console.log('Clicked event:', { + id: eventId, + type: eventType, + element: eventElement, + title: eventElement.textContent + }); + } + + private handleMouseDown(event: MouseEvent): void { + this.isMouseDown = true; + this.lastMousePosition = { x: event.clientX, y: event.clientY }; + this.lastLoggedPosition = { x: event.clientX, y: event.clientY }; + console.log('Mouse down at:', this.lastMousePosition); + + // Tjek om mousedown er på et event + const target = event.target as HTMLElement; + let eventElement = target; + while (eventElement && eventElement.tagName !== 'SWP-EVENTS-LAYER') { + if (eventElement.tagName === 'SWP-EVENT' || eventElement.tagName === 'SWP-ALLDAY-EVENT') { + break; + } + eventElement = eventElement.parentElement as HTMLElement; + if (!eventElement) return; + } + + // Hvis vi nåede til SWP-EVENTS-LAYER uden at finde et event, så return + if (!eventElement || eventElement.tagName === 'SWP-EVENTS-LAYER') { + return; + } + + // Hvis vi fandt et event, lav en clone + if (eventElement) { + this.cloneEvent(eventElement, event); + } + } + + private cloneEvent(originalEvent: HTMLElement, mouseEvent: MouseEvent): void { + // Lav en clone + const clone = originalEvent.cloneNode(true) as HTMLElement; + + // Præfiks ID med "clone-" + const originalId = originalEvent.dataset.eventId; + if (originalId) { + clone.dataset.eventId = `clone-${originalId}`; + } + + // Beregn hvor på event'et musen klikkede + const eventRect = originalEvent.getBoundingClientRect(); + this.mouseOffset = { + x: mouseEvent.clientX - eventRect.left, // Stadig nødvendig for cursor placering + y: mouseEvent.clientY - eventRect.top + }; + + // Gør klonen ready til at blive trukket + clone.style.position = 'absolute'; + clone.style.zIndex = '999999'; + clone.style.pointerEvents = 'none'; + + // Sæt størrelse fra det originale event + clone.style.width = eventRect.width + 'px'; + clone.style.height = eventRect.height + 'px'; + + // Find den aktuelle kolonne og placer klonen der + const currentColumnElement = document.querySelector(`swp-day-column[data-date="${this.currentColumn}"]`); + if (currentColumnElement) { + // Sæt initial position relativt til kolonnen + const columnRect = currentColumnElement.getBoundingClientRect(); + const relativeY = mouseEvent.clientY - columnRect.top - this.mouseOffset.y; + clone.style.top = relativeY + 'px'; + + currentColumnElement.appendChild(clone); + } else { + console.error('Could not find current column element:', this.currentColumn); + // Fallback til original placering + originalEvent.parentNode?.insertBefore(clone, originalEvent.nextSibling); + } + + // Gem reference til klonen + this.draggedClone = clone; + + console.log('Cloned event:', { + original: originalId, + clone: clone.dataset.eventId, + offset: this.mouseOffset + }); + } + + private handleMouseUp(event: MouseEvent): void { + 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'); + // } + } + + public destroy(): void { + document.body.removeEventListener('mousemove', this.handleMouseMove.bind(this)); + document.body.removeEventListener('click', this.handleClick.bind(this)); + document.body.removeEventListener('mousedown', this.handleMouseDown.bind(this)); + document.body.removeEventListener('mouseup', this.handleMouseUp.bind(this)); + } +} \ No newline at end of file