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 { eventBus } from '../core/EventBus';
import { CoreEvents } from '../constants/CoreEvents';
//import { SimpleEventOverlapManager, OverlapType } from '../managers/SimpleEventOverlapManager';
import { OverlapDetector, OverlapResult, EventId } from '../utils/OverlapDetector';
/**
@ -305,11 +304,7 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
console.log('handleDragStart:', eventId);
this.originalEvent = originalElement;
// Remove stacking styling during drag
// TODO: Replace with new system
// if (this.overlapManager.isStackedEvent(originalElement)) {
// this.overlapManager.removeStackedStyling(originalElement);
// }
// Remove stacking styling during drag will be handled by new system
// Create clone
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
//this.detectAndHandleOverlaps(this.draggedClone, finalColumn);
// TODO: Implement new drag overlap handling
//this.new_handleEventOverlaps(columnEvents, eventsLayer);
this.handleDragDropOverlaps(this.draggedClone, finalColumn);
// Clean up
this.draggedClone = null;
this.originalEvent = null;
@ -471,12 +464,75 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
}, 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
* TODO: Replace with new system
* In the new system, this is handled automatically by re-rendering overlaps
*/
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
}
/**