Enables all-day event to timed event conversion

Implements drag-and-drop conversion from all-day events to timed events in day columns. This change introduces a new event type (`drag:mouseenter-column`) and delegates rendering logic to the `DateEventRenderer` to maintain architectural consistency.
This commit is contained in:
Janus C. H. Knudsen 2025-10-10 19:37:10 +02:00
parent 78ca23c07a
commit 0a3d274164
3 changed files with 615 additions and 2 deletions

View file

@ -5,7 +5,7 @@ import { calendarConfig } from '../core/CalendarConfig';
import { SwpEventElement } from '../elements/SwpEventElement';
import { PositionUtils } from '../utils/PositionUtils';
import { ColumnBounds } from '../utils/ColumnDetectionUtils';
import { DragColumnChangeEventPayload, DragMoveEventPayload, DragStartEventPayload } from '../types/EventTypes';
import { DragColumnChangeEventPayload, DragMoveEventPayload, DragStartEventPayload, DragMouseEnterColumnEventPayload } from '../types/EventTypes';
import { DateService } from '../utils/DateService';
import { EventStackManager } from '../managers/EventStackManager';
import { EventLayoutCoordinator, GridGroupLayout, StackedEventLayout } from '../managers/EventLayoutCoordinator';
@ -23,6 +23,7 @@ export interface EventRendererStrategy {
handleEventClick?(eventId: string, originalElement: HTMLElement): void;
handleColumnChange?(payload: DragColumnChangeEventPayload): void;
handleNavigationCompleted?(): void;
handleConvertAllDayToTimed?(payload: DragMouseEnterColumnEventPayload): void;
}
/**
@ -128,6 +129,64 @@ export class DateEventRenderer implements EventRendererStrategy {
}
}
/**
* Handle conversion of all-day event to timed event
*/
public handleConvertAllDayToTimed(payload: DragMouseEnterColumnEventPayload): void {
const { calendarEvent, targetColumn, snappedY, replaceClone } = payload;
console.log('🎯 DateEventRenderer: Converting all-day to timed event', {
eventId: calendarEvent.id,
targetColumn: targetColumn.date,
snappedY
});
// Create timed event element from CalendarEvent
const timedClone = SwpEventElement.fromCalendarEvent(calendarEvent);
// Calculate proper height from event duration
const position = this.calculateEventPosition(calendarEvent);
// Calculate actual duration in minutes from CalendarEvent (important for all-day conversions)
const durationMinutes = (calendarEvent.end.getTime() - calendarEvent.start.getTime()) / (1000 * 60);
timedClone.dataset.duration = durationMinutes.toString();
timedClone.dataset.originalDuration = durationMinutes.toString();
// Set position at snapped Y
timedClone.style.top = `${snappedY}px`;
// Set complete styling for dragged clone (matching normal event rendering)
timedClone.style.height = `${position.height - 3}px`;
timedClone.style.left = '2px';
timedClone.style.right = '2px';
timedClone.style.width = 'auto';
timedClone.style.pointerEvents = 'none';
// Apply drag styling
this.applyDragStyling(timedClone);
// Find the events layer in the target column
const eventsLayer = targetColumn.element.querySelector('swp-events-layer');
if (!eventsLayer) {
console.warn('DateEventRenderer: Events layer not found in column');
return;
}
// Append new timed clone to events layer
eventsLayer.appendChild(timedClone);
// Update instance state
this.draggedClone = timedClone;
// Update DragDropManager's reference to the new clone
replaceClone(timedClone);
console.log('✅ DateEventRenderer: Converted all-day to timed event', {
eventId: calendarEvent.id,
position: snappedY
});
}
/**
* Handle drag end event
*/