Improves drag and drop for timed and all-day events

Refactors drag and drop handling to use a cloned event element,
ensuring correct positioning and styling during drag operations
for both regular timed events and all-day events.

This change streamlines the drag and drop process by:
- Creating a clone of the dragged event at the start of the drag.
- Passing the clone through the drag events.
- Handling all-day events with the AllDayManager
- Handling regular timed events with the EventRendererManager

This resolves issues with event positioning and styling during
drag, especially when moving events across columns or between
all-day and timed sections.
This commit is contained in:
Janus C. H. Knudsen 2025-09-26 22:53:49 +02:00
parent 0553089085
commit 9dfd4574d8
5 changed files with 62 additions and 45 deletions

View file

@ -65,7 +65,7 @@ export class AllDayManager {
// Listen for drag operations on all-day events
eventBus.on('drag:start', (event) => {
const { draggedElement, mouseOffset } = (event as CustomEvent<DragStartEventPayload>).detail;
const { draggedElement, draggedClone, mouseOffset } = (event as CustomEvent<DragStartEventPayload>).detail;
// Check if this is an all-day event by checking if it's in all-day container
const isAllDayEvent = draggedElement.closest('swp-allday-container');
@ -77,26 +77,22 @@ export class AllDayManager {
});
eventBus.on('drag:column-change', (event) => {
const { draggedElement, mousePosition } = (event as CustomEvent<DragColumnChangeEventPayload>).detail;
const { draggedElement, draggedClone, mousePosition } = (event as CustomEvent<DragColumnChangeEventPayload>).detail;
if(draggedClone == null)
return;
// Check if there's an all-day clone for this event
const eventId = draggedElement.dataset.eventId;
const dragClone = document.querySelector(`swp-allday-container swp-event[data-event-id="clone-${eventId}"]`) as HTMLElement;
// Filter: Only handle events where clone IS an all-day event
if (!draggedClone.hasAttribute('data-allday')) {
return; // This is not an all-day event, let EventRendererManager handle it
}
console.log('🔄 AllDayManager: Handling drag:column-change for all-day event', {
eventId : draggedElement.dataset.eventId,
cloneId: draggedClone.dataset.eventId
});
if (!dragClone.hasAttribute('data-allday')) {
return;
}
// If we find an all-day clone, handle the drag move
if (dragClone) {
console.log('🔄 AllDayManager: Found all-day clone, handling drag:column-change', {
eventId,
cloneId: dragClone.dataset.eventId
});
this.handleColumnChange(dragClone, mousePosition);
}
this.handleColumnChange(draggedClone, mousePosition);
});
eventBus.on('drag:end', (event) => {

View file

@ -7,6 +7,7 @@ import { IEventBus } from '../types/CalendarTypes';
import { calendarConfig } from '../core/CalendarConfig';
import { PositionUtils } from '../utils/PositionUtils';
import { ColumnDetectionUtils } from '../utils/ColumnDetectionUtils';
import { SwpEventElement } from '../elements/SwpEventElement';
import {
DragStartEventPayload,
DragMoveEventPayload,
@ -40,6 +41,7 @@ export class DragDropManager {
// Drag state
private draggedElement!: HTMLElement | null;
private draggedClone!: HTMLElement | null;
private currentColumn: string | null = null;
private isDragStarted = false;
@ -198,8 +200,17 @@ export class DragDropManager {
// Start drag - emit drag:start event
this.isDragStarted = true;
// Create SwpEventElement from existing DOM element and clone it
const originalSwpEvent = SwpEventElement.fromExistingElement(this.draggedElement);
const clonedSwpEvent = originalSwpEvent.createClone();
// Get the cloned DOM element
this.draggedClone = clonedSwpEvent.getElement();
const dragStartPayload: DragStartEventPayload = {
draggedElement: this.draggedElement,
draggedClone: this.draggedClone,
mousePosition: this.initialMousePosition,
mouseOffset: this.mouseOffset,
column: this.currentColumn
@ -244,6 +255,7 @@ export class DragDropManager {
const dragColumnChangePayload: DragColumnChangeEventPayload = {
draggedElement: this.draggedElement,
draggedClone: this.draggedClone,
previousColumn,
newColumn,
mousePosition: currentPosition
@ -514,6 +526,7 @@ export class DragDropManager {
*/
private cleanupDragState(): void {
this.draggedElement = null;
this.draggedClone = null;
this.currentColumn = null;
this.isDragStarted = false;
this.isInHeader = false;