Replaces global singleton configuration with dependency injection Introduces more modular and testable approach to configuration Removes direct references to calendarConfig in multiple components Adds explicit configuration passing to constructors Improves code maintainability and reduces global state dependencies
242 lines
No EOL
7.7 KiB
TypeScript
242 lines
No EOL
7.7 KiB
TypeScript
import { CoreEvents } from '../constants/CoreEvents';
|
|
import { CalendarConfig } from '../core/CalendarConfig';
|
|
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;
|
|
private eventManager: EventManager;
|
|
private gridManager: GridManager;
|
|
private eventRenderer: EventRenderingService;
|
|
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;
|
|
this.eventManager = eventManager;
|
|
this.gridManager = gridManager;
|
|
this.eventRenderer = eventRenderingService;
|
|
this.scrollManager = scrollManager;
|
|
this.config = config;
|
|
this.setupEventListeners();
|
|
}
|
|
|
|
/**
|
|
* Initialize calendar system using simple direct calls
|
|
*/
|
|
public async initialize(): Promise<void> {
|
|
if (this.isInitialized) {
|
|
return;
|
|
}
|
|
|
|
|
|
try {
|
|
// Debug: Check calendar type
|
|
const calendarType = this.config.getCalendarMode();
|
|
|
|
// Step 1: Load data
|
|
await this.eventManager.loadData();
|
|
|
|
// 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);
|
|
}
|
|
await this.gridManager.render();
|
|
|
|
this.scrollManager.initialize();
|
|
|
|
this.setView(this.currentView);
|
|
this.setCurrentDate(this.currentDate);
|
|
|
|
this.isInitialized = true;
|
|
|
|
// Emit initialization complete event
|
|
this.eventBus.emit(CoreEvents.INITIALIZED, {
|
|
currentDate: this.currentDate,
|
|
currentView: this.currentView
|
|
});
|
|
|
|
} catch (error) {
|
|
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 {
|
|
|
|
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) => {
|
|
|
|
const customEvent = event as CustomEvent;
|
|
// this.handleWorkweekChange();
|
|
|
|
});
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Calculate the current period based on view and date
|
|
*/
|
|
private calculateCurrentPeriod(): { start: string; end: string } {
|
|
const current = new Date(this.currentDate);
|
|
|
|
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()
|
|
};
|
|
|
|
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);
|
|
|
|
// Find end of week (Sunday)
|
|
const weekEnd = new Date(weekStart);
|
|
weekEnd.setDate(weekEnd.getDate() + 6);
|
|
weekEnd.setHours(23, 59, 59, 999);
|
|
|
|
return {
|
|
start: weekStart.toISOString(),
|
|
end: weekEnd.toISOString()
|
|
};
|
|
|
|
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()
|
|
};
|
|
|
|
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 {
|
|
|
|
// 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
|
|
}
|
|
|
|
// Re-render the grid with new workweek settings (will now rebuild everything)
|
|
this.gridManager.render();
|
|
|
|
// Re-initialize scroll manager after grid rebuild
|
|
this.scrollManager.initialize();
|
|
|
|
// Re-render events in the new grid structure
|
|
this.rerenderEvents();
|
|
|
|
// 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 {
|
|
|
|
// Get current period data to determine date range
|
|
const periodData = this.calculateCurrentPeriod();
|
|
|
|
// Find the grid container to render events in
|
|
const container = document.querySelector('swp-calendar-container');
|
|
if (!container) {
|
|
return;
|
|
}
|
|
|
|
// Trigger event rendering for the current date range using correct method
|
|
this.eventRenderer.renderEvents({
|
|
container: container as HTMLElement,
|
|
startDate: new Date(periodData.start),
|
|
endDate: new Date(periodData.end)
|
|
});
|
|
}
|
|
|
|
} |