Updates drag-and-drop overlap handling

Replaces the old overlap handling system with a new approach.

The new system recalculates overlaps after a drag-and-drop action and re-renders the affected events, avoiding manual group management. This simplifies the overlap resolution logic and improves performance.
This commit is contained in:
Janus Knudsen 2025-09-09 17:30:44 +02:00
parent 80ef35c42c
commit 6402cd4565

View file

@ -5,7 +5,6 @@ import { calendarConfig } from '../core/CalendarConfig';
import { DateCalculator } from '../utils/DateCalculator'; import { DateCalculator } from '../utils/DateCalculator';
import { eventBus } from '../core/EventBus'; import { eventBus } from '../core/EventBus';
import { CoreEvents } from '../constants/CoreEvents'; import { CoreEvents } from '../constants/CoreEvents';
//import { SimpleEventOverlapManager, OverlapType } from '../managers/SimpleEventOverlapManager';
import { OverlapDetector, OverlapResult, EventId } from '../utils/OverlapDetector'; import { OverlapDetector, OverlapResult, EventId } from '../utils/OverlapDetector';
/** /**
@ -305,11 +304,7 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
console.log('handleDragStart:', eventId); console.log('handleDragStart:', eventId);
this.originalEvent = originalElement; this.originalEvent = originalElement;
// Remove stacking styling during drag // Remove stacking styling during drag will be handled by new system
// TODO: Replace with new system
// if (this.overlapManager.isStackedEvent(originalElement)) {
// this.overlapManager.removeStackedStyling(originalElement);
// }
// Create clone // Create clone
this.draggedClone = this.createEventClone(originalElement); this.draggedClone = this.createEventClone(originalElement);
@ -396,9 +391,7 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
// Detect overlaps with other events in the target column and reposition if needed // Detect overlaps with other events in the target column and reposition if needed
//this.detectAndHandleOverlaps(this.draggedClone, finalColumn); this.handleDragDropOverlaps(this.draggedClone, finalColumn);
// TODO: Implement new drag overlap handling
//this.new_handleEventOverlaps(columnEvents, eventsLayer);
// Clean up // Clean up
this.draggedClone = null; this.draggedClone = null;
this.originalEvent = null; this.originalEvent = null;
@ -471,12 +464,75 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
}, 100); }, 100);
} }
/**
* Handle overlap detection and re-rendering after drag-drop
*/
private handleDragDropOverlaps(droppedElement: HTMLElement, targetColumn: string): void {
const targetColumnElement = document.querySelector(`swp-day-column[data-date="${targetColumn}"]`);
if (!targetColumnElement) return;
const eventsLayer = targetColumnElement.querySelector('swp-events-layer') as HTMLElement;
if (!eventsLayer) return;
// Convert dropped element to CalendarEvent with new position
const droppedEvent = this.elementToCalendarEventWithNewPosition(droppedElement, targetColumn);
if (!droppedEvent) return;
// Get existing events in the column (excluding the dropped element)
const existingEvents = this.getEventsInColumn(eventsLayer, droppedElement.dataset.eventId);
// Find overlaps with the dropped event
const overlappingEvents = this.overlapDetector.resolveOverlap(droppedEvent, existingEvents);
if (overlappingEvents.length > 0) {
// Remove only affected events from DOM
const affectedEventIds = [droppedEvent.id, ...overlappingEvents.map(e => e.id)];
eventsLayer.querySelectorAll('swp-event').forEach(el => {
const eventId = (el as HTMLElement).dataset.eventId;
if (eventId && affectedEventIds.includes(eventId)) {
el.remove();
}
});
// Re-render affected events with overlap handling
const affectedEvents = [droppedEvent, ...overlappingEvents];
this.new_handleEventOverlaps(affectedEvents, eventsLayer);
}
// If no overlaps, the dropped element stays as is
}
/**
* Get all events in a column as CalendarEvent objects
*/
private getEventsInColumn(eventsLayer: HTMLElement, excludeEventId?: string): CalendarEvent[] {
const eventElements = eventsLayer.querySelectorAll('swp-event');
const events: CalendarEvent[] = [];
eventElements.forEach(el => {
const element = el as HTMLElement;
const eventId = element.dataset.eventId;
// Skip the excluded event (e.g., the dropped event)
if (excludeEventId && eventId === excludeEventId) {
return;
}
const event = this.elementToCalendarEvent(element);
if (event) {
events.push(event);
}
});
return events;
}
/** /**
* Remove event from any existing groups and cleanup empty containers * Remove event from any existing groups and cleanup empty containers
* TODO: Replace with new system * In the new system, this is handled automatically by re-rendering overlaps
*/ */
private removeEventFromExistingGroups(eventElement: HTMLElement): void { private removeEventFromExistingGroups(eventElement: HTMLElement): void {
// TODO: Implement with new system // With the new system, overlap relationships are recalculated on drop
// No need to manually track and remove from groups
} }
/** /**