Calendar/src/managers/CalendarManager.ts

242 lines
7.7 KiB
TypeScript
Raw Normal View History

import { CoreEvents } from '../constants/CoreEvents';
import { CalendarConfig } from '../core/CalendarConfig';
2025-10-14 19:21:28 +02:00
import { CalendarView, IEventBus } from '../types/CalendarTypes';
import { EventManager } from './EventManager';
import { GridManager } from './GridManager';
import { EventRenderingService } from '../renderers/EventRendererManager';
import { ScrollManager } from './ScrollManager';
/**
* CalendarManager - Main coordinator for all calendar managers
*/
export class CalendarManager {
private eventBus: IEventBus;
2025-08-09 01:16:04 +02:00
private eventManager: EventManager;
private gridManager: GridManager;
private eventRenderer: EventRenderingService;
2025-08-09 01:16:04 +02:00
private scrollManager: ScrollManager;
private config: CalendarConfig;
private currentView: CalendarView = 'week';
private currentDate: Date = new Date();
private isInitialized: boolean = false;
constructor(
eventBus: IEventBus,
eventManager: EventManager,
gridManager: GridManager,
eventRenderingService: EventRenderingService,
scrollManager: ScrollManager,
config: CalendarConfig
) {
this.eventBus = eventBus;
2025-08-09 01:16:04 +02:00
this.eventManager = eventManager;
this.gridManager = gridManager;
this.eventRenderer = eventRenderingService;
2025-08-09 01:16:04 +02:00
this.scrollManager = scrollManager;
this.config = config;
this.setupEventListeners();
2025-08-09 01:16:04 +02:00
}
/**
* Initialize calendar system using simple direct calls
*/
public async initialize(): Promise<void> {
if (this.isInitialized) {
return;
}
2025-10-14 19:21:28 +02:00
try {
// Debug: Check calendar type
const calendarType = this.config.getCalendarMode();
2025-10-14 19:21:28 +02:00
2025-08-09 01:16:04 +02:00
// Step 1: Load data
await this.eventManager.loadData();
2025-10-14 19:21:28 +02:00
// Step 2: Pass data to GridManager and render grid structure
if (calendarType === 'resource') {
const resourceData = this.eventManager.getResourceData();
this.gridManager.setResourceData(this.eventManager.getRawData() as import('../types/CalendarTypes').ResourceCalendarData);
}
2025-08-09 01:16:04 +02:00
await this.gridManager.render();
2025-10-14 19:21:28 +02:00
2025-08-09 01:16:04 +02:00
this.scrollManager.initialize();
2025-10-14 19:21:28 +02:00
this.setView(this.currentView);
this.setCurrentDate(this.currentDate);
2025-10-14 19:21:28 +02:00
this.isInitialized = true;
2025-10-14 19:21:28 +02:00
// Emit initialization complete event
this.eventBus.emit(CoreEvents.INITIALIZED, {
currentDate: this.currentDate,
currentView: this.currentView
});
2025-10-14 19:21:28 +02:00
} catch (error) {
2025-08-09 01:16:04 +02:00
throw error;
}
}
/**
* Skift calendar view (dag/uge/måned)
*/
public setView(view: CalendarView): void {
if (this.currentView === view) {
return;
}
const previousView = this.currentView;
this.currentView = view;
// Emit view change event
this.eventBus.emit(CoreEvents.VIEW_CHANGED, {
previousView,
currentView: view,
date: this.currentDate
});
}
/**
* Sæt aktuel dato
*/
public setCurrentDate(date: Date): void {
2025-10-14 19:21:28 +02:00
const previousDate = this.currentDate;
this.currentDate = new Date(date);
// Emit date change event
this.eventBus.emit(CoreEvents.DATE_CHANGED, {
previousDate,
currentDate: this.currentDate,
view: this.currentView
});
}
/**
* Setup event listeners for at håndtere events fra andre managers
*/
private setupEventListeners(): void {
// Listen for workweek changes only
this.eventBus.on(CoreEvents.WORKWEEK_CHANGED, (event: Event) => {
2025-10-14 19:21:28 +02:00
const customEvent = event as CustomEvent;
// this.handleWorkweekChange();
2025-10-14 19:21:28 +02:00
});
}
/**
* Calculate the current period based on view and date
*/
private calculateCurrentPeriod(): { start: string; end: string } {
const current = new Date(this.currentDate);
2025-10-14 19:21:28 +02:00
switch (this.currentView) {
case 'day':
const dayStart = new Date(current);
dayStart.setHours(0, 0, 0, 0);
const dayEnd = new Date(current);
dayEnd.setHours(23, 59, 59, 999);
return {
start: dayStart.toISOString(),
end: dayEnd.toISOString()
};
2025-10-14 19:21:28 +02:00
case 'week':
// Find start of week (Monday)
const weekStart = new Date(current);
const dayOfWeek = weekStart.getDay();
const daysToMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1; // Sunday = 0, so 6 days back to Monday
weekStart.setDate(weekStart.getDate() - daysToMonday);
weekStart.setHours(0, 0, 0, 0);
2025-10-14 19:21:28 +02:00
// Find end of week (Sunday)
const weekEnd = new Date(weekStart);
weekEnd.setDate(weekEnd.getDate() + 6);
weekEnd.setHours(23, 59, 59, 999);
2025-10-14 19:21:28 +02:00
return {
start: weekStart.toISOString(),
end: weekEnd.toISOString()
};
2025-10-14 19:21:28 +02:00
case 'month':
const monthStart = new Date(current.getFullYear(), current.getMonth(), 1);
const monthEnd = new Date(current.getFullYear(), current.getMonth() + 1, 0, 23, 59, 59, 999);
return {
start: monthStart.toISOString(),
end: monthEnd.toISOString()
};
2025-10-14 19:21:28 +02:00
default:
// Fallback to week view
const fallbackStart = new Date(current);
fallbackStart.setDate(fallbackStart.getDate() - 3);
fallbackStart.setHours(0, 0, 0, 0);
const fallbackEnd = new Date(current);
fallbackEnd.setDate(fallbackEnd.getDate() + 3);
fallbackEnd.setHours(23, 59, 59, 999);
return {
start: fallbackStart.toISOString(),
end: fallbackEnd.toISOString()
};
}
}
/**
* Handle workweek configuration changes
*/
private handleWorkweekChange(): void {
2025-10-14 19:21:28 +02:00
// Force a complete grid rebuild by clearing existing structure
const container = document.querySelector('swp-calendar-container');
if (container) {
container.innerHTML = ''; // Clear everything to force full rebuild
}
2025-10-14 19:21:28 +02:00
// Re-render the grid with new workweek settings (will now rebuild everything)
this.gridManager.render();
2025-10-14 19:21:28 +02:00
// Re-initialize scroll manager after grid rebuild
this.scrollManager.initialize();
2025-10-14 19:21:28 +02:00
// Re-render events in the new grid structure
this.rerenderEvents();
2025-10-14 19:21:28 +02:00
// Notify HeaderManager with correct current date after grid rebuild
this.eventBus.emit('workweek:header-update', {
currentDate: this.currentDate,
currentView: this.currentView,
workweek: this.config.getCurrentWorkWeek()
});
}
/**
* Re-render events after grid structure changes
*/
private rerenderEvents(): void {
2025-10-14 19:21:28 +02:00
// Get current period data to determine date range
const periodData = this.calculateCurrentPeriod();
2025-10-14 19:21:28 +02:00
// Find the grid container to render events in
const container = document.querySelector('swp-calendar-container');
if (!container) {
return;
}
2025-10-14 19:21:28 +02:00
// Trigger event rendering for the current date range using correct method
this.eventRenderer.renderEvents({
container: container as HTMLElement,
2025-10-14 19:21:28 +02:00
startDate: new Date(periodData.start),
endDate: new Date(periodData.end)
});
}
}