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:
parent
78ca23c07a
commit
0a3d274164
3 changed files with 615 additions and 2 deletions
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { CalendarTypeFactory } from '../factories/CalendarTypeFactory';
|
|||
import { EventManager } from '../managers/EventManager';
|
||||
import { EventRendererStrategy } from './EventRenderer';
|
||||
import { SwpEventElement } from '../elements/SwpEventElement';
|
||||
import { DragStartEventPayload, DragMoveEventPayload, DragEndEventPayload, DragMouseEnterHeaderEventPayload, DragMouseLeaveHeaderEventPayload, DragColumnChangeEventPayload, HeaderReadyEventPayload, ResizeEndEventPayload } from '../types/EventTypes';
|
||||
import { DragStartEventPayload, DragMoveEventPayload, DragEndEventPayload, DragMouseEnterHeaderEventPayload, DragMouseLeaveHeaderEventPayload, DragMouseEnterColumnEventPayload, DragColumnChangeEventPayload, HeaderReadyEventPayload, ResizeEndEventPayload } from '../types/EventTypes';
|
||||
import { DateService } from '../utils/DateService';
|
||||
import { ColumnBounds } from '../utils/ColumnDetectionUtils';
|
||||
/**
|
||||
|
|
@ -130,6 +130,7 @@ export class EventRenderingService {
|
|||
this.setupDragEndListener();
|
||||
this.setupDragColumnChangeListener();
|
||||
this.setupDragMouseLeaveHeaderListener();
|
||||
this.setupDragMouseEnterColumnListener();
|
||||
this.setupResizeEndListener();
|
||||
this.setupNavigationCompletedListener();
|
||||
}
|
||||
|
|
@ -250,6 +251,31 @@ export class EventRenderingService {
|
|||
this.eventBus.on('drag:mouseleave-header', this.dragMouseLeaveHeaderListener);
|
||||
}
|
||||
|
||||
private setupDragMouseEnterColumnListener(): void {
|
||||
this.eventBus.on('drag:mouseenter-column', (event: Event) => {
|
||||
const payload = (event as CustomEvent<DragMouseEnterColumnEventPayload>).detail;
|
||||
|
||||
// Only handle if clone is an all-day event
|
||||
if (!payload.draggedClone.hasAttribute('data-allday')) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('🎯 EventRendererManager: Received drag:mouseenter-column', {
|
||||
targetColumn: payload.targetColumn,
|
||||
snappedY: payload.snappedY,
|
||||
calendarEvent: payload.calendarEvent
|
||||
});
|
||||
|
||||
// Remove the old all-day clone from header
|
||||
payload.draggedClone.remove();
|
||||
|
||||
// Delegate to strategy for conversion
|
||||
if (this.strategy.handleConvertAllDayToTimed) {
|
||||
this.strategy.handleConvertAllDayToTimed(payload);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private setupResizeEndListener(): void {
|
||||
this.eventBus.on('resize:end', (event: Event) => {
|
||||
const { eventId, element } = (event as CustomEvent<ResizeEndEventPayload>).detail;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue