Improves event rendering by introducing dedicated event renderers and streamlining event display logic. - Adds a base event renderer and specialized date and resource-based renderers to handle event display logic. - Renders all-day events within a dedicated container in the calendar header. - Removes the direct filtering of all-day events from the `GridManager`. - Fixes an issue where the 'Summer Festival' event started on the wrong date. The changes enhance the flexibility and maintainability of the calendar, provide dedicated containers and styling for allday events and fix date issues related to certain events
191 lines
No EOL
6.4 KiB
TypeScript
191 lines
No EOL
6.4 KiB
TypeScript
import { EventBus } from '../core/EventBus';
|
|
import { IEventBus, CalendarEvent, ResourceCalendarData } from '../types/CalendarTypes';
|
|
import { CoreEvents } from '../constants/CoreEvents';
|
|
import { calendarConfig } from '../core/CalendarConfig';
|
|
|
|
/**
|
|
* EventManager - Administrerer event lifecycle og CRUD operationer
|
|
* Håndterer mock data og event synchronization
|
|
*/
|
|
export class EventManager {
|
|
private eventBus: IEventBus;
|
|
private events: CalendarEvent[] = [];
|
|
|
|
constructor(eventBus: IEventBus) {
|
|
console.log('EventManager: Constructor called');
|
|
this.eventBus = eventBus;
|
|
this.setupEventListeners();
|
|
console.log('EventManager: Waiting for CALENDAR_INITIALIZED before loading data');
|
|
}
|
|
|
|
private setupEventListeners(): void {
|
|
// NOTE: Removed POC event listener to prevent interference with production code
|
|
// POC sliding animation should not trigger separate event rendering
|
|
// this.eventBus.on(CoreEvents.WEEK_CONTENT_RENDERED, ...);
|
|
}
|
|
|
|
/**
|
|
* Public method to load data - called directly by CalendarManager
|
|
*/
|
|
public async loadData(): Promise<void> {
|
|
console.log('EventManager: Loading data via direct call');
|
|
await this.loadMockData();
|
|
console.log(`EventManager: Data loaded successfully - ${this.events.length} events`);
|
|
|
|
// Debug: Log first few events
|
|
if (this.events.length > 0) {
|
|
console.log('EventManager: First event:', {
|
|
title: this.events[0].title,
|
|
start: this.events[0].start,
|
|
end: this.events[0].end
|
|
});
|
|
}
|
|
}
|
|
|
|
private async loadMockData(): Promise<void> {
|
|
try {
|
|
const calendarType = calendarConfig.getCalendarMode();
|
|
let jsonFile: string;
|
|
|
|
console.log(`EventManager: Calendar type detected: '${calendarType}'`);
|
|
|
|
if (calendarType === 'resource') {
|
|
jsonFile = '/src/data/mock-resource-events.json';
|
|
} else {
|
|
jsonFile = '/src/data/mock-events.json';
|
|
}
|
|
|
|
console.log(`EventManager: Loading ${calendarType} calendar data from ${jsonFile}`);
|
|
|
|
const response = await fetch(jsonFile);
|
|
if (!response.ok) {
|
|
throw new Error(`Failed to load mock events: ${response.status}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
console.log(`EventManager: Loaded data for ${calendarType} calendar`);
|
|
|
|
// Store raw data for GridManager
|
|
this.rawData = data;
|
|
|
|
// Process data for internal use
|
|
this.processCalendarData(calendarType, data);
|
|
} catch (error) {
|
|
console.error('EventManager: Failed to load mock events:', error);
|
|
this.events = []; // Fallback to empty array
|
|
}
|
|
}
|
|
|
|
private processCalendarData(calendarType: string, data: any): void {
|
|
if (calendarType === 'resource') {
|
|
const resourceData = data as ResourceCalendarData;
|
|
this.events = resourceData.resources.flatMap(resource =>
|
|
resource.events.map(event => ({
|
|
...event,
|
|
resourceName: resource.name,
|
|
resourceDisplayName: resource.displayName,
|
|
resourceEmployeeId: resource.employeeId
|
|
}))
|
|
);
|
|
console.log(`EventManager: Processed ${this.events.length} events from ${resourceData.resources.length} resources`);
|
|
} else {
|
|
this.events = data as CalendarEvent[];
|
|
console.log(`EventManager: Processed ${this.events.length} date events`);
|
|
}
|
|
}
|
|
|
|
private syncEvents(): void {
|
|
// Events are synced during initialization
|
|
// This method maintained for internal state management only
|
|
console.log(`EventManager: Internal sync - ${this.events.length} events in memory`);
|
|
}
|
|
|
|
public getEvents(): CalendarEvent[] {
|
|
return [...this.events];
|
|
}
|
|
|
|
/**
|
|
* Get raw resource data for resource calendar mode
|
|
*/
|
|
public getResourceData(): any {
|
|
return this.rawData;
|
|
}
|
|
|
|
private rawData: any = null;
|
|
|
|
|
|
public getEventById(id: string): CalendarEvent | undefined {
|
|
return this.events.find(event => event.id === id);
|
|
}
|
|
|
|
/**
|
|
* Get events for a specific time period
|
|
*/
|
|
public getEventsForPeriod(startDate: Date, endDate: Date): CalendarEvent[] {
|
|
console.log(`EventManager.getEventsForPeriod: Checking ${this.events.length} events for period ${startDate.toDateString()} - ${endDate.toDateString()}`);
|
|
return this.events.filter(event => {
|
|
const eventStart = new Date(event.start);
|
|
const eventEnd = new Date(event.end);
|
|
|
|
// Event overlaps period if it starts before period ends AND ends after period starts
|
|
return eventStart <= endDate && eventEnd >= startDate;
|
|
});
|
|
}
|
|
|
|
public addEvent(event: Omit<CalendarEvent, 'id'>): CalendarEvent {
|
|
const newEvent: CalendarEvent = {
|
|
...event,
|
|
id: Date.now().toString()
|
|
};
|
|
|
|
this.events.push(newEvent);
|
|
this.syncEvents();
|
|
|
|
this.eventBus.emit(CoreEvents.EVENT_CREATED, {
|
|
event: newEvent
|
|
});
|
|
|
|
return newEvent;
|
|
}
|
|
|
|
public updateEvent(id: string, updates: Partial<CalendarEvent>): CalendarEvent | null {
|
|
const eventIndex = this.events.findIndex(event => event.id === id);
|
|
if (eventIndex === -1) return null;
|
|
|
|
const updatedEvent = { ...this.events[eventIndex], ...updates };
|
|
this.events[eventIndex] = updatedEvent;
|
|
|
|
this.syncEvents();
|
|
|
|
this.eventBus.emit(CoreEvents.EVENT_UPDATED, {
|
|
event: updatedEvent
|
|
});
|
|
|
|
return updatedEvent;
|
|
}
|
|
|
|
public deleteEvent(id: string): boolean {
|
|
const eventIndex = this.events.findIndex(event => event.id === id);
|
|
if (eventIndex === -1) return false;
|
|
|
|
const deletedEvent = this.events[eventIndex];
|
|
this.events.splice(eventIndex, 1);
|
|
|
|
this.syncEvents();
|
|
|
|
this.eventBus.emit(CoreEvents.EVENT_DELETED, {
|
|
event: deletedEvent
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
public refresh(): void {
|
|
this.syncEvents();
|
|
}
|
|
|
|
|
|
public destroy(): void {
|
|
this.events = [];
|
|
}
|
|
} |