import { EventBus } from '../core/EventBus'; import { IEventBus, CalendarEvent } from '../types/CalendarTypes'; import { EventTypes } from '../constants/EventTypes'; import { calendarConfig } from '../core/CalendarConfig'; import { CalendarTypeFactory } from '../factories/CalendarTypeFactory'; /** * EventRenderer - Render events i DOM med positionering using Strategy Pattern * Håndterer event positioning og overlap detection */ export class EventRenderer { private eventBus: IEventBus; private pendingEvents: CalendarEvent[] = []; constructor(eventBus: IEventBus) { this.eventBus = eventBus; this.setupEventListeners(); // Initialize the factory (if not already done) CalendarTypeFactory.initialize(); } private setupEventListeners(): void { this.eventBus.on(EventTypes.EVENTS_LOADED, (event: Event) => { const customEvent = event as CustomEvent; const { events } = customEvent.detail; console.log('EventRenderer: Received EVENTS_LOADED with', events.length, 'events'); // Store events but don't render yet - wait for grid to be ready this.pendingEvents = events; this.tryRenderEvents(); }); this.eventBus.on(EventTypes.GRID_RENDERED, () => { // Grid is ready, now we can render events this.tryRenderEvents(); }); this.eventBus.on(EventTypes.VIEW_RENDERED, () => { // Clear existing events when view changes this.clearEvents(); }); // Handle calendar type changes this.eventBus.on(EventTypes.CALENDAR_TYPE_CHANGED, () => { // Re-render events with new strategy this.tryRenderEvents(); }); } private tryRenderEvents(): void { // Only render if we have both events and appropriate columns are ready console.log('EventRenderer: tryRenderEvents called, pending events:', this.pendingEvents.length); if (this.pendingEvents.length > 0) { const calendarType = calendarConfig.getCalendarType(); let columnsSelector = calendarType === 'resource' ? 'swp-resource-column' : 'swp-day-column'; const columns = document.querySelectorAll(columnsSelector); console.log(`EventRenderer: Found ${columns.length} ${columnsSelector} elements for ${calendarType} calendar`); if (columns.length > 0) { this.renderEvents(this.pendingEvents); this.pendingEvents = []; // Clear pending events after rendering } } } private renderEvents(events: CalendarEvent[]): void { console.log('EventRenderer: renderEvents called with', events.length, 'events'); // Get the appropriate event renderer strategy const calendarType = calendarConfig.getCalendarType(); const eventRenderer = CalendarTypeFactory.getEventRenderer(calendarType); console.log(`EventRenderer: Using ${calendarType} event renderer strategy`); // Use strategy to render events eventRenderer.renderEvents(events, calendarConfig); // Emit event rendered this.eventBus.emit(EventTypes.EVENT_RENDERED, { count: events.filter(e => !e.allDay).length }); } private clearEvents(): void { const calendarType = calendarConfig.getCalendarType(); const eventRenderer = CalendarTypeFactory.getEventRenderer(calendarType); eventRenderer.clearEvents(); } public refresh(): void { this.tryRenderEvents(); } public destroy(): void { this.pendingEvents = []; this.clearEvents(); } }