Calendar/src/renderers/EventRendererManager.ts

144 lines
5.3 KiB
TypeScript
Raw Normal View History

import { EventBus } from '../core/EventBus';
import { IEventBus, CalendarEvent, RenderContext } from '../types/CalendarTypes';
import { EventTypes } from '../constants/EventTypes';
import { calendarConfig } from '../core/CalendarConfig';
2025-08-07 00:15:44 +02:00
import { CalendarTypeFactory } from '../factories/CalendarTypeFactory';
import { EventManager } from '../managers/EventManager';
import { EventRendererStrategy } from './EventRenderer';
/**
* EventRenderingService - Render events i DOM med positionering using Strategy Pattern
* Håndterer event positioning og overlap detection
*/
export class EventRenderingService {
private eventBus: IEventBus;
private eventManager: EventManager;
private strategy: EventRendererStrategy;
constructor(eventBus: IEventBus, eventManager: EventManager) {
this.eventBus = eventBus;
this.eventManager = eventManager;
// Cache strategy at initialization
const calendarType = calendarConfig.getCalendarMode();
this.strategy = CalendarTypeFactory.getEventRenderer(calendarType);
this.setupEventListeners();
}
2025-08-09 01:16:04 +02:00
/**
* Render events in a specific container for a given period
2025-08-09 01:16:04 +02:00
*/
public renderEvents(context: RenderContext): void {
console.log(` 📅 Getting events for ${context.startDate.toDateString()} - ${context.endDate.toDateString()}`);
// Get events from EventManager for the period
const events = this.eventManager.getEventsForPeriod(
context.startDate,
context.endDate
);
2025-08-02 23:59:52 +02:00
console.log(` 📊 Found ${events.length} events for period`);
2025-08-02 23:59:52 +02:00
if (events.length === 0) {
console.log(' ⚠️ No events to render for this period');
return;
}
2025-08-09 01:16:04 +02:00
// Use cached strategy to render events in the specific container
this.strategy.renderEvents(events, context.container, calendarConfig);
2025-08-09 01:16:04 +02:00
console.log(` ✅ Rendered ${events.length} events successfully`);
2025-08-09 01:16:04 +02:00
}
2025-08-02 23:59:52 +02:00
2025-08-09 01:16:04 +02:00
private setupEventListeners(): void {
// Event-driven rendering: React to grid and container events
this.eventBus.on(EventTypes.GRID_RENDERED, (event: Event) => {
console.log('EventRenderer: Received GRID_RENDERED event');
this.handleGridRendered(event as CustomEvent);
});
// CONTAINER_READY_FOR_EVENTS removed - events are now pre-rendered synchronously
// this.eventBus.on(EventTypes.CONTAINER_READY_FOR_EVENTS, (event: Event) => {
// console.log('EventRenderer: Received CONTAINER_READY_FOR_EVENTS event');
// this.handleContainerReady(event as CustomEvent);
// });
this.eventBus.on(EventTypes.VIEW_CHANGED, (event: Event) => {
console.log('EventRenderer: Received VIEW_CHANGED event');
this.handleViewChanged(event as CustomEvent);
2025-08-09 01:16:04 +02:00
});
// Handle calendar type changes - update cached strategy
2025-08-09 01:16:04 +02:00
this.eventBus.on(EventTypes.CALENDAR_TYPE_CHANGED, () => {
const calendarType = calendarConfig.getCalendarMode();
this.strategy = CalendarTypeFactory.getEventRenderer(calendarType);
console.log(`EventRenderer: Updated strategy to ${calendarType}`);
});
}
2025-08-09 01:16:04 +02:00
/**
* Handle GRID_RENDERED event - render events in the current grid
*/
private handleGridRendered(event: CustomEvent): void {
const { container, startDate, endDate } = event.detail;
if (!container) {
console.error('EventRenderer: No container in GRID_RENDERED event', event.detail);
return;
}
// Use period from event or fallback to calculated period
const periodStart = startDate;
const periodEnd = endDate;
this.renderEvents({
container: container,
startDate: periodStart,
endDate: periodEnd
});
}
/**
* Handle CONTAINER_READY_FOR_EVENTS event - render events in pre-rendered container
*/
private handleContainerReady(event: CustomEvent): void {
const { container, startDate, endDate } = event.detail;
if (!container || !startDate || !endDate) {
console.error('EventRenderer: Invalid CONTAINER_READY_FOR_EVENTS event data', event.detail);
return;
}
this.renderEvents({
container: container,
startDate: new Date(startDate),
endDate: new Date(endDate)
});
}
/**
* Handle VIEW_CHANGED event - clear and re-render for new view
*/
private handleViewChanged(event: CustomEvent): void {
// Clear all existing events since view structure may have changed
2025-08-09 01:16:04 +02:00
this.clearEvents();
// New rendering will be triggered by subsequent GRID_RENDERED event
console.log('EventRenderer: Cleared events for view change, waiting for GRID_RENDERED');
}
private clearEvents(container?: HTMLElement): void {
console.log(`EventRenderer: Clearing events`, container ? 'in container' : 'globally');
this.strategy.clearEvents(container);
}
public refresh(container?: HTMLElement): void {
// Clear events in specific container or globally
this.clearEvents(container);
}
public destroy(): void {
this.clearEvents();
}
}