Refactors calendar architecture for month view
Prepares the calendar component for month view implementation by introducing a strategy pattern for view management, splitting configuration settings, and consolidating events into a core set. It also removes dead code and enforces type safety, improving overall code quality and maintainability. Addresses critical issues identified in the code review, laying the groundwork for efficient feature addition.
This commit is contained in:
parent
7d513600d8
commit
3ddc6352f2
17 changed files with 1347 additions and 428 deletions
|
|
@ -1,7 +1,6 @@
|
|||
import { EventBus } from '../core/EventBus';
|
||||
import { IEventBus, CalendarEvent, ResourceCalendarData } from '../types/CalendarTypes';
|
||||
import { EventTypes } from '../constants/EventTypes';
|
||||
import { StateEvents } from '../types/CalendarState';
|
||||
import { calendarConfig } from '../core/CalendarConfig';
|
||||
|
||||
/**
|
||||
|
|
@ -96,7 +95,7 @@ export class EventManager {
|
|||
}
|
||||
|
||||
private syncEvents(): void {
|
||||
// Events are now synced via StateEvents.DATA_LOADED during initialization
|
||||
// Events are synced during initialization
|
||||
// This method maintained for internal state management only
|
||||
console.log(`EventManager: Internal sync - ${this.events.length} events in memory`);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
import { eventBus } from '../core/EventBus';
|
||||
import { calendarConfig } from '../core/CalendarConfig';
|
||||
import { EventTypes } from '../constants/EventTypes';
|
||||
import { StateEvents } from '../types/CalendarState';
|
||||
import { DateCalculator } from '../utils/DateCalculator';
|
||||
import { ResourceCalendarData } from '../types/CalendarTypes';
|
||||
import { AllDayEvent } from '../types/EventTypes';
|
||||
import { GridRenderer } from '../renderers/GridRenderer';
|
||||
import { GridStyleManager } from '../renderers/GridStyleManager';
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ export class GridManager {
|
|||
private container: HTMLElement | null = null;
|
||||
private grid: HTMLElement | null = null;
|
||||
private currentWeek: Date | null = null;
|
||||
private allDayEvents: any[] = []; // Store all-day events for current week
|
||||
private allDayEvents: AllDayEvent[] = []; // Store all-day events for current week
|
||||
private resourceData: ResourceCalendarData | null = null; // Store resource data for resource calendar
|
||||
private gridRenderer: GridRenderer;
|
||||
private styleManager: GridStyleManager;
|
||||
|
|
@ -111,17 +111,6 @@ export class GridManager {
|
|||
this.updateAllDayEvents(detail.events);
|
||||
});
|
||||
|
||||
// Handle data loaded for resource mode
|
||||
eventBus.on(StateEvents.DATA_LOADED, (e: Event) => {
|
||||
const detail = (e as CustomEvent).detail;
|
||||
console.log(`GridManager: Received DATA_LOADED`);
|
||||
|
||||
if (detail.data && detail.data.calendarMode === 'resource') {
|
||||
// Resource data will be passed in the state event
|
||||
// For now just update grid styles
|
||||
this.styleManager.updateGridStyles(this.resourceData);
|
||||
}
|
||||
});
|
||||
|
||||
// Handle grid clicks
|
||||
this.setupGridInteractions();
|
||||
|
|
@ -176,7 +165,7 @@ export class GridManager {
|
|||
/**
|
||||
* Update all-day events data and re-render if needed
|
||||
*/
|
||||
private updateAllDayEvents(events: any[]): void {
|
||||
private updateAllDayEvents(events: AllDayEvent[]): void {
|
||||
if (!this.currentWeek) return;
|
||||
|
||||
// Filter all-day events for current week
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
import { eventBus } from '../core/EventBus';
|
||||
import { calendarConfig } from '../core/CalendarConfig';
|
||||
import { EventTypes } from '../constants/EventTypes';
|
||||
import { StateEvents } from '../types/CalendarState';
|
||||
|
||||
/**
|
||||
* Manages scrolling functionality for the calendar using native scrollbars
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ import { EventTypes } from '../constants/EventTypes';
|
|||
export class ViewManager {
|
||||
private eventBus: IEventBus;
|
||||
private currentView: CalendarView = 'week';
|
||||
private eventCleanup: (() => void)[] = [];
|
||||
private buttonListeners: Map<Element, EventListener> = new Map();
|
||||
|
||||
constructor(eventBus: IEventBus) {
|
||||
this.eventBus = eventBus;
|
||||
|
|
@ -17,19 +19,26 @@ export class ViewManager {
|
|||
}
|
||||
|
||||
private setupEventListeners(): void {
|
||||
this.eventBus.on(EventTypes.CALENDAR_INITIALIZED, () => {
|
||||
this.initializeView();
|
||||
});
|
||||
// Track event bus listeners for cleanup
|
||||
this.eventCleanup.push(
|
||||
this.eventBus.on(EventTypes.CALENDAR_INITIALIZED, () => {
|
||||
this.initializeView();
|
||||
})
|
||||
);
|
||||
|
||||
this.eventBus.on(EventTypes.VIEW_CHANGE_REQUESTED, (event: Event) => {
|
||||
const customEvent = event as CustomEvent;
|
||||
const { currentView } = customEvent.detail;
|
||||
this.changeView(currentView);
|
||||
});
|
||||
this.eventCleanup.push(
|
||||
this.eventBus.on(EventTypes.VIEW_CHANGE_REQUESTED, (event: Event) => {
|
||||
const customEvent = event as CustomEvent;
|
||||
const { currentView } = customEvent.detail;
|
||||
this.changeView(currentView);
|
||||
})
|
||||
);
|
||||
|
||||
this.eventBus.on(EventTypes.DATE_CHANGED, () => {
|
||||
this.refreshCurrentView();
|
||||
});
|
||||
this.eventCleanup.push(
|
||||
this.eventBus.on(EventTypes.DATE_CHANGED, () => {
|
||||
this.refreshCurrentView();
|
||||
})
|
||||
);
|
||||
|
||||
// Setup view button handlers
|
||||
this.setupViewButtonHandlers();
|
||||
|
|
@ -42,26 +51,30 @@ export class ViewManager {
|
|||
private setupViewButtonHandlers(): void {
|
||||
const viewButtons = document.querySelectorAll('swp-view-button[data-view]');
|
||||
viewButtons.forEach(button => {
|
||||
button.addEventListener('click', (event) => {
|
||||
const handler = (event: Event) => {
|
||||
event.preventDefault();
|
||||
const view = button.getAttribute('data-view') as CalendarView;
|
||||
if (view && this.isValidView(view)) {
|
||||
this.changeView(view);
|
||||
}
|
||||
});
|
||||
};
|
||||
button.addEventListener('click', handler);
|
||||
this.buttonListeners.set(button, handler);
|
||||
});
|
||||
}
|
||||
|
||||
private setupWorkweekButtonHandlers(): void {
|
||||
const workweekButtons = document.querySelectorAll('swp-preset-button[data-workweek]');
|
||||
workweekButtons.forEach(button => {
|
||||
button.addEventListener('click', (event) => {
|
||||
const handler = (event: Event) => {
|
||||
event.preventDefault();
|
||||
const workweekId = button.getAttribute('data-workweek');
|
||||
if (workweekId) {
|
||||
this.changeWorkweek(workweekId);
|
||||
}
|
||||
});
|
||||
};
|
||||
button.addEventListener('click', handler);
|
||||
this.buttonListeners.set(button, handler);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -149,6 +162,14 @@ export class ViewManager {
|
|||
}
|
||||
|
||||
public destroy(): void {
|
||||
// Event listeners bliver automatisk fjernet af EventBus
|
||||
// Clean up event bus listeners
|
||||
this.eventCleanup.forEach(cleanup => cleanup());
|
||||
this.eventCleanup = [];
|
||||
|
||||
// Clean up button listeners
|
||||
this.buttonListeners.forEach((handler, button) => {
|
||||
button.removeEventListener('click', handler);
|
||||
});
|
||||
this.buttonListeners.clear();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue