Refactors event positioning and drag-and-drop
Centralizes event position calculations into `PositionUtils` for consistency and reusability across managers and renderers. Improves drag-and-drop functionality by emitting events for all-day event conversion and streamlining position calculations during drag operations. Introduces `AllDayManager` and `AllDayEventRenderer` to manage and render all-day events in the calendar header. This allows dragging events to the header to convert them to all-day events.
This commit is contained in:
parent
8b96376d1f
commit
7054c0d40a
9 changed files with 404 additions and 72 deletions
|
|
@ -1,15 +1,61 @@
|
|||
// All-day event rendering using factory pattern
|
||||
|
||||
import { CalendarEvent } from '../types/CalendarTypes';
|
||||
import { SwpAllDayEventElement } from '../elements/SwpEventElement';
|
||||
import { DateCalculator } from '../utils/DateCalculator';
|
||||
|
||||
/**
|
||||
* AllDayEventRenderer - Handles rendering of all-day events in header row
|
||||
* Uses factory pattern with SwpAllDayEventElement for clean DOM creation
|
||||
* AllDayEventRenderer - Simple rendering of all-day events
|
||||
* Handles adding and removing all-day events from the header container
|
||||
*/
|
||||
export class AllDayEventRenderer {
|
||||
|
||||
private container: HTMLElement | null = null;
|
||||
|
||||
|
||||
constructor() {
|
||||
this.getContainer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or cache all-day container
|
||||
*/
|
||||
private getContainer(): HTMLElement | null {
|
||||
if (!this.container) {
|
||||
const header = document.querySelector('swp-calendar-header');
|
||||
if (header) {
|
||||
this.container = header.querySelector('swp-allday-container');
|
||||
}
|
||||
}
|
||||
return this.container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an all-day event using factory pattern
|
||||
*/
|
||||
public renderAllDayEvent(event: CalendarEvent, targetDate: string): HTMLElement | null {
|
||||
const container = this.getContainer();
|
||||
if (!container) return null;
|
||||
|
||||
const allDayElement = SwpAllDayEventElement.fromCalendarEvent(event, targetDate);
|
||||
const element = allDayElement.getElement();
|
||||
|
||||
container.appendChild(element);
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an all-day event by ID
|
||||
*/
|
||||
public removeAllDayEvent(eventId: string): void {
|
||||
const container = this.getContainer();
|
||||
if (!container) return;
|
||||
|
||||
const eventElement = container.querySelector(`swp-allday-event[data-event-id="${eventId}"]`);
|
||||
if (eventElement) {
|
||||
eventElement.remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear cache when DOM changes
|
||||
*/
|
||||
public clearCache(): void {
|
||||
this.container = null;
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import { CoreEvents } from '../constants/CoreEvents';
|
|||
import { OverlapDetector, OverlapResult, EventId } from '../utils/OverlapDetector';
|
||||
import { SwpEventElement, SwpAllDayEventElement } from '../elements/SwpEventElement';
|
||||
import { TimeFormatter } from '../utils/TimeFormatter';
|
||||
import { PositionUtils } from '../utils/PositionUtils';
|
||||
|
||||
/**
|
||||
* Interface for event rendering strategies
|
||||
|
|
@ -695,26 +696,8 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
}
|
||||
|
||||
protected calculateEventPosition(event: CalendarEvent): { top: number; height: number } {
|
||||
|
||||
const gridSettings = calendarConfig.getGridSettings();
|
||||
const dayStartHour = gridSettings.dayStartHour;
|
||||
const hourHeight = gridSettings.hourHeight;
|
||||
|
||||
// Calculate minutes from midnight
|
||||
const startMinutes = event.start.getHours() * 60 + event.start.getMinutes();
|
||||
const endMinutes = event.end.getHours() * 60 + event.end.getMinutes();
|
||||
const dayStartMinutes = dayStartHour * 60;
|
||||
|
||||
// Calculate top position relative to visible grid start
|
||||
// If dayStartHour=6 and event starts at 09:00 (540 min), then:
|
||||
// top = ((540 - 360) / 60) * hourHeight = 3 * hourHeight (3 hours from grid start)
|
||||
const top = ((startMinutes - dayStartMinutes) / 60) * hourHeight;
|
||||
|
||||
// Calculate height based on event duration
|
||||
const durationMinutes = endMinutes - startMinutes;
|
||||
const height = (durationMinutes / 60) * hourHeight;
|
||||
|
||||
return { top, height };
|
||||
// Delegate to PositionUtils for centralized position calculation
|
||||
return PositionUtils.calculateEventPosition(event.start, event.end);
|
||||
}
|
||||
|
||||
clearEvents(container?: HTMLElement): void {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue