More cleanup

This commit is contained in:
Janus C. H. Knudsen 2025-10-14 19:21:28 +02:00
parent ee4b9b3707
commit 4bd94d3be2
4 changed files with 36 additions and 217 deletions

View file

@ -1,15 +1,10 @@
import { EventBus } from '../core/EventBus';
import { CoreEvents } from '../constants/CoreEvents'; import { CoreEvents } from '../constants/CoreEvents';
import { calendarConfig } from '../core/CalendarConfig'; import { calendarConfig } from '../core/CalendarConfig';
import { CalendarEvent, CalendarView, IEventBus } from '../types/CalendarTypes'; import { CalendarView, IEventBus } from '../types/CalendarTypes';
import { EventManager } from './EventManager'; import { EventManager } from './EventManager';
import { GridManager } from './GridManager'; import { GridManager } from './GridManager';
import { HeaderManager } from './HeaderManager';
import { EventRenderingService } from '../renderers/EventRendererManager'; import { EventRenderingService } from '../renderers/EventRendererManager';
import { ScrollManager } from './ScrollManager'; import { ScrollManager } from './ScrollManager';
import { DateService } from '../utils/DateService';
import { EventFilterManager } from './EventFilterManager';
import { InitializationReport } from '../types/ManagerTypes';
/** /**
* CalendarManager - Main coordinator for all calendar managers * CalendarManager - Main coordinator for all calendar managers
@ -19,11 +14,8 @@ export class CalendarManager {
private eventBus: IEventBus; private eventBus: IEventBus;
private eventManager: EventManager; private eventManager: EventManager;
private gridManager: GridManager; private gridManager: GridManager;
private headerManager: HeaderManager;
private eventRenderer: EventRenderingService; private eventRenderer: EventRenderingService;
private scrollManager: ScrollManager; private scrollManager: ScrollManager;
private eventFilterManager: EventFilterManager;
private dateService: DateService;
private currentView: CalendarView = 'week'; private currentView: CalendarView = 'week';
private currentDate: Date = new Date(); private currentDate: Date = new Date();
private isInitialized: boolean = false; private isInitialized: boolean = false;
@ -38,12 +30,9 @@ export class CalendarManager {
this.eventBus = eventBus; this.eventBus = eventBus;
this.eventManager = eventManager; this.eventManager = eventManager;
this.gridManager = gridManager; this.gridManager = gridManager;
this.headerManager = new HeaderManager();
this.eventRenderer = eventRenderer; this.eventRenderer = eventRenderer;
this.scrollManager = scrollManager; this.scrollManager = scrollManager;
this.eventFilterManager = new EventFilterManager();
const timezone = calendarConfig.getTimezone?.(); const timezone = calendarConfig.getTimezone?.();
this.dateService = new DateService(timezone);
this.setupEventListeners(); this.setupEventListeners();
} }
@ -55,55 +44,34 @@ export class CalendarManager {
return; return;
} }
try { try {
// Debug: Check calendar type // Debug: Check calendar type
const calendarType = calendarConfig.getCalendarMode(); const calendarType = calendarConfig.getCalendarMode();
// Step 1: Load data // Step 1: Load data
await this.eventManager.loadData(); await this.eventManager.loadData();
// Step 2: Pass data to GridManager and render grid structure // Step 2: Pass data to GridManager and render grid structure
if (calendarType === 'resource') { if (calendarType === 'resource') {
const resourceData = this.eventManager.getResourceData(); const resourceData = this.eventManager.getResourceData();
this.gridManager.setResourceData(this.eventManager.getRawData() as import('../types/CalendarTypes').ResourceCalendarData); this.gridManager.setResourceData(this.eventManager.getRawData() as import('../types/CalendarTypes').ResourceCalendarData);
} }
await this.gridManager.render(); await this.gridManager.render();
// Step 2a: Setup header drag listeners after grid render (when DOM is available)
this.headerManager.setupHeaderDragListeners();
// Step 2b: Trigger event rendering now that data is loaded
// Re-emit GRID_RENDERED to trigger EventRendererManager
const gridContainer = document.querySelector('swp-calendar-container');
if (gridContainer) {
const periodRange = this.gridManager.getDisplayDates();
this.eventBus.emit(CoreEvents.GRID_RENDERED, {
container: gridContainer,
currentDate: new Date(),
startDate: periodRange[0],
endDate: periodRange[periodRange.length - 1],
columnCount: periodRange.length
});
}
// Step 3: Initialize scroll synchronization
this.scrollManager.initialize(); this.scrollManager.initialize();
// Step 4: Set initial view and date BEFORE event rendering
this.setView(this.currentView); this.setView(this.currentView);
this.setCurrentDate(this.currentDate); this.setCurrentDate(this.currentDate);
// Step 5: Event rendering will be triggered by GRID_RENDERED event
this.isInitialized = true; this.isInitialized = true;
// Emit initialization complete event // Emit initialization complete event
this.eventBus.emit(CoreEvents.INITIALIZED, { this.eventBus.emit(CoreEvents.INITIALIZED, {
currentDate: this.currentDate, currentDate: this.currentDate,
currentView: this.currentView currentView: this.currentView
}); });
} catch (error) { } catch (error) {
throw error; throw error;
} }
@ -128,109 +96,29 @@ export class CalendarManager {
date: this.currentDate date: this.currentDate
}); });
// Grid re-rendering will trigger event rendering automatically via GRID_RENDERED event
} }
/** /**
* Sæt aktuel dato * Sæt aktuel dato
*/ */
public setCurrentDate(date: Date): void { public setCurrentDate(date: Date): void {
// Validate input date
if (!date || !(date instanceof Date) || isNaN(date.getTime())) {
return;
}
const previousDate = this.currentDate; const previousDate = this.currentDate;
this.currentDate = new Date(date); this.currentDate = new Date(date);
// Validate that both dates are valid before logging
const prevDateStr = previousDate && !isNaN(previousDate.getTime()) ? previousDate.toISOString() : 'Invalid Date';
const newDateStr = this.currentDate.toISOString();
// Emit date change event // Emit date change event
this.eventBus.emit(CoreEvents.DATE_CHANGED, { this.eventBus.emit(CoreEvents.DATE_CHANGED, {
previousDate, previousDate,
currentDate: this.currentDate, currentDate: this.currentDate,
view: this.currentView view: this.currentView
}); });
// Grid update for new date will trigger event rendering automatically via GRID_RENDERED event
}
/**
* Naviger til i dag
*/
public goToToday(): void {
this.setCurrentDate(new Date());
}
/**
* Naviger til næste periode (dag/uge/måned afhængig af view)
*/
public goToNext(): void {
const nextDate = this.calculateNextDate();
this.setCurrentDate(nextDate);
}
/**
* Naviger til forrige periode (dag/uge/måned afhængig af view)
*/
public goToPrevious(): void {
const previousDate = this.calculatePreviousDate();
this.setCurrentDate(previousDate);
}
/**
* Hent aktuel view
*/
public getCurrentView(): CalendarView {
return this.currentView;
}
/**
* Hent aktuel dato
*/
public getCurrentDate(): Date {
return new Date(this.currentDate);
}
/**
* Hent calendar konfiguration
*/
public getConfig() {
return calendarConfig;
}
/**
* Check om calendar er initialiseret
*/
public isCalendarInitialized(): boolean {
return this.isInitialized;
}
/**
* Get initialization report for debugging
*/
public getInitializationReport(): InitializationReport {
return {
initialized: this.isInitialized,
timestamp: Date.now(),
managers: {
calendar: { initialized: this.isInitialized },
event: { initialized: true },
grid: { initialized: true },
header: { initialized: true },
scroll: { initialized: true }
}
};
} }
/** /**
* Genindlæs calendar data * Genindlæs calendar data
*/ */
public refresh(): void { public refresh(): void {
this.eventBus.emit(CoreEvents.REFRESH_REQUESTED, { this.eventBus.emit(CoreEvents.REFRESH_REQUESTED, {
view: this.currentView, view: this.currentView,
date: this.currentDate date: this.currentDate
@ -241,10 +129,10 @@ export class CalendarManager {
* Ryd calendar og nulstil til standard tilstand * Ryd calendar og nulstil til standard tilstand
*/ */
public reset(): void { public reset(): void {
this.currentView = 'week'; this.currentView = 'week';
this.currentDate = new Date(); this.currentDate = new Date();
this.eventBus.emit(CoreEvents.REFRESH_REQUESTED, { this.eventBus.emit(CoreEvents.REFRESH_REQUESTED, {
view: this.currentView, view: this.currentView,
date: this.currentDate date: this.currentDate
@ -257,11 +145,10 @@ export class CalendarManager {
private setupEventListeners(): void { private setupEventListeners(): void {
// Listen for workweek changes only // Listen for workweek changes only
this.eventBus.on(CoreEvents.WORKWEEK_CHANGED, (event: Event) => { this.eventBus.on(CoreEvents.WORKWEEK_CHANGED, (event: Event) => {
const customEvent = event as CustomEvent; const customEvent = event as CustomEvent;
this.handleWorkweekChange(); this.handleWorkweekChange();
// Also update week info display since workweek affects date range display
this.updateWeekInfoForWorkweekChange();
}); });
} }
@ -270,7 +157,7 @@ export class CalendarManager {
*/ */
private calculateNextDate(): Date { private calculateNextDate(): Date {
const nextDate = new Date(this.currentDate); const nextDate = new Date(this.currentDate);
switch (this.currentView) { switch (this.currentView) {
case 'day': case 'day':
nextDate.setDate(nextDate.getDate() + 1); nextDate.setDate(nextDate.getDate() + 1);
@ -283,7 +170,7 @@ export class CalendarManager {
nextDate.setMonth(nextDate.getMonth() + 1); nextDate.setMonth(nextDate.getMonth() + 1);
break; break;
} }
return nextDate; return nextDate;
} }
@ -292,7 +179,7 @@ export class CalendarManager {
*/ */
private calculatePreviousDate(): Date { private calculatePreviousDate(): Date {
const previousDate = new Date(this.currentDate); const previousDate = new Date(this.currentDate);
switch (this.currentView) { switch (this.currentView) {
case 'day': case 'day':
previousDate.setDate(previousDate.getDate() - 1); previousDate.setDate(previousDate.getDate() - 1);
@ -305,7 +192,7 @@ export class CalendarManager {
previousDate.setMonth(previousDate.getMonth() - 1); previousDate.setMonth(previousDate.getMonth() - 1);
break; break;
} }
return previousDate; return previousDate;
} }
@ -314,7 +201,7 @@ export class CalendarManager {
*/ */
private calculateCurrentPeriod(): { start: string; end: string } { private calculateCurrentPeriod(): { start: string; end: string } {
const current = new Date(this.currentDate); const current = new Date(this.currentDate);
switch (this.currentView) { switch (this.currentView) {
case 'day': case 'day':
const dayStart = new Date(current); const dayStart = new Date(current);
@ -325,7 +212,7 @@ export class CalendarManager {
start: dayStart.toISOString(), start: dayStart.toISOString(),
end: dayEnd.toISOString() end: dayEnd.toISOString()
}; };
case 'week': case 'week':
// Find start of week (Monday) // Find start of week (Monday)
const weekStart = new Date(current); const weekStart = new Date(current);
@ -333,17 +220,17 @@ export class CalendarManager {
const daysToMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1; // Sunday = 0, so 6 days back to Monday const daysToMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1; // Sunday = 0, so 6 days back to Monday
weekStart.setDate(weekStart.getDate() - daysToMonday); weekStart.setDate(weekStart.getDate() - daysToMonday);
weekStart.setHours(0, 0, 0, 0); weekStart.setHours(0, 0, 0, 0);
// Find end of week (Sunday) // Find end of week (Sunday)
const weekEnd = new Date(weekStart); const weekEnd = new Date(weekStart);
weekEnd.setDate(weekEnd.getDate() + 6); weekEnd.setDate(weekEnd.getDate() + 6);
weekEnd.setHours(23, 59, 59, 999); weekEnd.setHours(23, 59, 59, 999);
return { return {
start: weekStart.toISOString(), start: weekStart.toISOString(),
end: weekEnd.toISOString() end: weekEnd.toISOString()
}; };
case 'month': case 'month':
const monthStart = new Date(current.getFullYear(), current.getMonth(), 1); const monthStart = new Date(current.getFullYear(), current.getMonth(), 1);
const monthEnd = new Date(current.getFullYear(), current.getMonth() + 1, 0, 23, 59, 59, 999); const monthEnd = new Date(current.getFullYear(), current.getMonth() + 1, 0, 23, 59, 59, 999);
@ -351,7 +238,7 @@ export class CalendarManager {
start: monthStart.toISOString(), start: monthStart.toISOString(),
end: monthEnd.toISOString() end: monthEnd.toISOString()
}; };
default: default:
// Fallback to week view // Fallback to week view
const fallbackStart = new Date(current); const fallbackStart = new Date(current);
@ -371,22 +258,22 @@ export class CalendarManager {
* Handle workweek configuration changes * Handle workweek configuration changes
*/ */
private handleWorkweekChange(): void { private handleWorkweekChange(): void {
// Force a complete grid rebuild by clearing existing structure // Force a complete grid rebuild by clearing existing structure
const container = document.querySelector('swp-calendar-container'); const container = document.querySelector('swp-calendar-container');
if (container) { if (container) {
container.innerHTML = ''; // Clear everything to force full rebuild container.innerHTML = ''; // Clear everything to force full rebuild
} }
// Re-render the grid with new workweek settings (will now rebuild everything) // Re-render the grid with new workweek settings (will now rebuild everything)
this.gridManager.render(); this.gridManager.render();
// Re-initialize scroll manager after grid rebuild // Re-initialize scroll manager after grid rebuild
this.scrollManager.initialize(); this.scrollManager.initialize();
// Re-render events in the new grid structure // Re-render events in the new grid structure
this.rerenderEvents(); this.rerenderEvents();
// Notify HeaderManager with correct current date after grid rebuild // Notify HeaderManager with correct current date after grid rebuild
this.eventBus.emit('workweek:header-update', { this.eventBus.emit('workweek:header-update', {
currentDate: this.currentDate, currentDate: this.currentDate,
@ -399,71 +286,22 @@ export class CalendarManager {
* Re-render events after grid structure changes * Re-render events after grid structure changes
*/ */
private rerenderEvents(): void { private rerenderEvents(): void {
// Get current period data to determine date range // Get current period data to determine date range
const periodData = this.calculateCurrentPeriod(); const periodData = this.calculateCurrentPeriod();
// Find the grid container to render events in // Find the grid container to render events in
const container = document.querySelector('swp-calendar-container'); const container = document.querySelector('swp-calendar-container');
if (!container) { if (!container) {
return; return;
} }
// Trigger event rendering for the current date range using correct method // Trigger event rendering for the current date range using correct method
this.eventRenderer.renderEvents({ this.eventRenderer.renderEvents({
container: container as HTMLElement, container: container as HTMLElement,
startDate: new Date(periodData.start), startDate: new Date(periodData.start),
endDate: new Date(periodData.end) endDate: new Date(periodData.end)
}); });
} }
/**
* Update week info display after workweek changes
*/
private updateWeekInfoForWorkweekChange(): void {
// Don't do anything here - let GRID_RENDERED event handle it
}
/**
* Update week info based on actual rendered columns
*/
private updateWeekInfoFromRenderedColumns(): void {
// Get actual dates from rendered columns
const columns = document.querySelectorAll('swp-day-column');
if (columns.length === 0) {
return;
}
// Get first and last column dates
const firstColumn = columns[0] as HTMLElement;
const lastColumn = columns[columns.length - 1] as HTMLElement;
const firstDateStr = firstColumn.dataset.date;
const lastDateStr = lastColumn.dataset.date;
if (!firstDateStr || !lastDateStr) {
return;
}
// Parse dates
const firstDate = new Date(firstDateStr);
const lastDate = new Date(lastDateStr);
// Calculate week number from first date
const weekNumber = this.dateService.getWeekNumber(firstDate);
// Format date range
const dateRange = this.dateService.formatDateRange(firstDate, lastDate);
// Emit week info update
this.eventBus.emit(CoreEvents.PERIOD_INFO_UPDATE, {
weekNumber,
dateRange,
weekStart: firstDate,
weekEnd: lastDate
});
}
} }

View file

@ -224,6 +224,7 @@ export class EventRenderingService {
} }
private setupDragMouseLeaveHeaderListener(): void { private setupDragMouseLeaveHeaderListener(): void {
this.dragMouseLeaveHeaderListener = (event: Event) => { this.dragMouseLeaveHeaderListener = (event: Event) => {
const { targetDate, mousePosition, originalElement, draggedClone: cloneElement } = (event as CustomEvent<DragMouseLeaveHeaderEventPayload>).detail; const { targetDate, mousePosition, originalElement, draggedClone: cloneElement } = (event as CustomEvent<DragMouseLeaveHeaderEventPayload>).detail;

View file

@ -193,15 +193,7 @@ export class GridRenderer {
parentContainer.appendChild(newGrid); parentContainer.appendChild(newGrid);
console.log('Grid created using createOptimizedGridContainer:', newGrid); console.log('Grid created using createOptimizedGridContainer:', newGrid);
console.log('Emitting GRID_RENDERED'); console.log('Grid creation complete - caller will emit GRID_RENDERED');
eventBus.emit(CoreEvents.GRID_RENDERED, {
container: newGrid, // Specific grid container, not parent
currentDate: weekStart,
startDate: weekStart,
endDate: weekEnd,
isNavigation: true // Flag to indicate this is navigation rendering
});
console.groupEnd(); console.groupEnd();
return newGrid; return newGrid;

View file

@ -62,7 +62,6 @@ export interface ViewManager extends IManager {
export interface CalendarManager extends IManager { export interface CalendarManager extends IManager {
setView(view: CalendarView): void; setView(view: CalendarView): void;
setCurrentDate(date: Date): void; setCurrentDate(date: Date): void;
getInitializationReport(): InitializationReport;
} }
export interface DragDropManager extends IManager { export interface DragDropManager extends IManager {
@ -93,14 +92,3 @@ export interface ResourceAssignment {
resourceId: string; resourceId: string;
eventId: string; eventId: string;
} }
export interface InitializationReport {
initialized: boolean;
timestamp: number;
managers: {
[key: string]: {
initialized: boolean;
error?: string;
};
};
}