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:
parent
0553089085
commit
9dfd4574d8
5 changed files with 62 additions and 45 deletions
|
|
@ -16,7 +16,7 @@ import { DragOffset, StackLinkData } from '../types/DragDropTypes';
|
|||
export interface EventRendererStrategy {
|
||||
renderEvents(events: CalendarEvent[], container: HTMLElement): void;
|
||||
clearEvents(container?: HTMLElement): void;
|
||||
handleDragStart?(originalElement: HTMLElement, eventId: string, mouseOffset: DragOffset, column: string): void;
|
||||
handleDragStart?(payload: import('../types/EventTypes').DragStartEventPayload): void;
|
||||
handleDragMove?(eventId: string, snappedY: number, column: string, mouseOffset: DragOffset): void;
|
||||
handleDragAutoScroll?(eventId: string, snappedY: number): void;
|
||||
handleDragEnd?(eventId: string, originalElement: HTMLElement, draggedClone: HTMLElement, finalColumn: string, finalY: number): void;
|
||||
|
|
@ -160,30 +160,31 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
/**
|
||||
* Handle drag start event
|
||||
*/
|
||||
public handleDragStart(originalElement: HTMLElement, eventId: string, mouseOffset: DragOffset, column: string): void {
|
||||
public handleDragStart(payload: import('../types/EventTypes').DragStartEventPayload): void {
|
||||
const originalElement = payload.draggedElement;
|
||||
const eventId = originalElement.dataset.eventId || '';
|
||||
const mouseOffset = payload.mouseOffset;
|
||||
const column = payload.column || '';
|
||||
|
||||
this.originalEvent = originalElement;
|
||||
|
||||
// Remove stacking styling during drag will be handled by new system
|
||||
// Use the clone from the payload instead of creating a new one
|
||||
this.draggedClone = payload.draggedClone;
|
||||
|
||||
// Create SwpEventElement from existing DOM element and clone it
|
||||
const originalSwpEvent = SwpEventElement.fromExistingElement(originalElement);
|
||||
const clonedSwpEvent = originalSwpEvent.createClone();
|
||||
if (this.draggedClone) {
|
||||
// Apply drag styling
|
||||
this.applyDragStyling(this.draggedClone);
|
||||
|
||||
// Get the cloned DOM element
|
||||
this.draggedClone = clonedSwpEvent.getElement();
|
||||
|
||||
// Apply drag styling
|
||||
this.applyDragStyling(this.draggedClone);
|
||||
|
||||
// Add to current column's events layer (not directly to column)
|
||||
const columnElement = document.querySelector(`swp-day-column[data-date="${column}"]`);
|
||||
if (columnElement) {
|
||||
const eventsLayer = columnElement.querySelector('swp-events-layer');
|
||||
if (eventsLayer) {
|
||||
eventsLayer.appendChild(this.draggedClone);
|
||||
} else {
|
||||
// Fallback to column if events layer not found
|
||||
columnElement.appendChild(this.draggedClone);
|
||||
// Add to current column's events layer (not directly to column)
|
||||
const columnElement = document.querySelector(`swp-day-column[data-date="${column}"]`);
|
||||
if (columnElement) {
|
||||
const eventsLayer = columnElement.querySelector('swp-events-layer');
|
||||
if (eventsLayer) {
|
||||
eventsLayer.appendChild(this.draggedClone);
|
||||
} else {
|
||||
// Fallback to column if events layer not found
|
||||
columnElement.appendChild(this.draggedClone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -179,11 +179,10 @@ export class EventRenderingService {
|
|||
private setupDragEventListeners(): void {
|
||||
// Handle drag start
|
||||
this.eventBus.on('drag:start', (event: Event) => {
|
||||
const { draggedElement, mouseOffset, column } = (event as CustomEvent<DragStartEventPayload>).detail;
|
||||
const dragStartPayload = (event as CustomEvent<DragStartEventPayload>).detail;
|
||||
// Use the draggedElement directly - no need for DOM query
|
||||
if (draggedElement && this.strategy.handleDragStart && column) {
|
||||
const eventId = draggedElement.dataset.eventId || '';
|
||||
this.strategy.handleDragStart(draggedElement, eventId, mouseOffset, column);
|
||||
if (dragStartPayload.draggedElement && this.strategy.handleDragStart && dragStartPayload.column) {
|
||||
this.strategy.handleDragStart(dragStartPayload);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -246,10 +245,16 @@ export class EventRenderingService {
|
|||
|
||||
// Handle column change
|
||||
this.eventBus.on('drag:column-change', (event: Event) => {
|
||||
const { draggedElement, newColumn } = (event as CustomEvent<DragColumnChangeEventPayload>).detail;
|
||||
const { draggedElement, draggedClone, newColumn } = (event as CustomEvent<DragColumnChangeEventPayload>).detail;
|
||||
|
||||
// Filter: Only handle events where clone is NOT an all-day event (normal timed events)
|
||||
if (draggedClone && draggedClone.hasAttribute('data-allday')) {
|
||||
return; // This is an all-day event, let AllDayManager handle it
|
||||
}
|
||||
|
||||
if (this.strategy.handleColumnChange) {
|
||||
const eventId = draggedElement.dataset.eventId || '';
|
||||
this.strategy.handleColumnChange(eventId, newColumn);
|
||||
this.strategy.handleColumnChange(eventId, newColumn); //TODO: Should be refactored to use payload, no need to lookup clone again inside
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue