Enhance drag and drop interactions across calendar views

Adds support for dragging events between header and grid views
Improves drag-and-drop state management and event persistence
Enables converting all-day events to timed events when dropped in grid

Refactors drag handling to support more flexible event interactions
This commit is contained in:
Janus C. H. Knudsen 2025-12-12 00:36:10 +01:00
parent f7f1f8afe0
commit bc5854e09a
5 changed files with 259 additions and 67 deletions

View file

@ -7,7 +7,8 @@ import { DateService } from '../../core/DateService';
import {
IDragEnterHeaderPayload,
IDragMoveHeaderPayload,
IDragLeaveHeaderPayload
IDragLeaveHeaderPayload,
IDragEndPayload
} from '../../types/DragTypes';
/**
@ -199,8 +200,9 @@ export class HeaderDrawerRenderer {
this.handleDragLeave(payload);
});
this.eventBus.on(CoreEvents.EVENT_DRAG_END, () => {
this.handleDragEnd();
this.eventBus.on(CoreEvents.EVENT_DRAG_END, (e) => {
const payload = (e as CustomEvent<IDragEndPayload>).detail;
this.handleDragEnd(payload);
});
this.eventBus.on(CoreEvents.EVENT_DRAG_CANCEL, () => {
@ -290,22 +292,23 @@ export class HeaderDrawerRenderer {
}
/**
* Handle drag end - finalize the item (it stays in header)
* Note: EventRenderer handles removing the original element from the grid
* via EVENT_DRAG_END with target === 'header'
* Handle drag end - finalize based on drop target
*/
private handleDragEnd(): void {
if (!this.currentItem) return;
// Remove dragging state
this.currentItem.classList.remove('dragging');
// Recalculate layout for all items in drawer
this.recalculateDrawerLayout();
// Clear references
this.currentItem = null;
this.sourceElement = null;
private handleDragEnd(payload: IDragEndPayload): void {
if (payload.target === 'header') {
// Grid→Header: Finalize the header item (it stays in header)
if (this.currentItem) {
this.currentItem.classList.remove('dragging');
this.recalculateDrawerLayout();
this.currentItem = null;
this.sourceElement = null;
}
} else {
// Header→Grid: Remove ghost header item and recalculate
const ghost = document.querySelector(`swp-header-item.drag-ghost[data-event-id="${payload.swpEvent.eventId}"]`);
ghost?.remove();
this.recalculateDrawerLayout();
}
}
/**