Adds ColumnDetector manager
Introduces a new manager responsible for detecting the column the mouse is currently over. This enables event cloning and repositioning within the calendar columns during drag operations, enhancing the user experience.
This commit is contained in:
parent
9c65143df2
commit
906616fe7b
2 changed files with 227 additions and 0 deletions
225
src/managers/ColumnDetector.ts
Normal file
225
src/managers/ColumnDetector.ts
Normal file
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue