From 0ea4e4732458943e9d8dab1cc7ece2b07fc6f683 Mon Sep 17 00:00:00 2001 From: Janus Knudsen Date: Wed, 20 Aug 2025 21:51:49 +0200 Subject: [PATCH] Refactors calendar type to calendar mode Updates the codebase to utilize `CalendarMode` instead of the deprecated `CalendarType`. Simplifies `CalendarConfig` by removing legacy methods and related type aliases, enhancing code maintainability and clarity. Improves event rendering by ensuring `GRID_RENDERED` events include explicit start and end dates, preventing errors and ensuring correct data filtering. --- src/core/CalendarConfig.ts | 40 +-------------------------- src/factories/CalendarTypeFactory.ts | 28 +++++++++---------- src/managers/CalendarManager.ts | 1 - src/managers/GridManager.ts | 28 +++++-------------- src/managers/NavigationManager.ts | 6 ++-- src/renderers/EventRendererManager.ts | 11 ++------ src/strategies/MonthViewStrategy.ts | 16 +++++++++++ src/strategies/ViewStrategy.ts | 5 ++++ src/strategies/WeekViewStrategy.ts | 10 +++++++ src/types/CalendarTypes.ts | 7 ++--- 10 files changed, 61 insertions(+), 91 deletions(-) diff --git a/src/core/CalendarConfig.ts b/src/core/CalendarConfig.ts index 0e6b1ab..d1765bd 100644 --- a/src/core/CalendarConfig.ts +++ b/src/core/CalendarConfig.ts @@ -2,7 +2,7 @@ import { eventBus } from './EventBus'; import { CoreEvents } from '../constants/CoreEvents'; -import { CalendarConfig as ICalendarConfig, ViewPeriod, CalendarMode, DateViewType, CalendarType } from '../types/CalendarTypes'; +import { CalendarConfig as ICalendarConfig, ViewPeriod, CalendarMode } from '../types/CalendarTypes'; /** * Layout and timing settings for the calendar grid @@ -305,13 +305,6 @@ export class CalendarConfig { getDateViewSettings(): DateViewSettings { return { ...this.dateViewSettings }; } - - /** - * Legacy method - for backwards compatibility - */ - getDateHeaderSettings(): DateViewSettings { - return this.getDateViewSettings(); - } /** * Update date view settings @@ -326,13 +319,6 @@ export class CalendarConfig { oldValue: this.dateViewSettings }); } - - /** - * Legacy method - for backwards compatibility - */ - updateDateHeaderSettings(updates: Partial): void { - this.updateDateViewSettings(updates); - } /** * Get resource view settings @@ -340,13 +326,6 @@ export class CalendarConfig { getResourceViewSettings(): ResourceViewSettings { return { ...this.resourceViewSettings }; } - - /** - * Legacy method - for backwards compatibility - */ - getResourceHeaderSettings(): ResourceViewSettings { - return this.getResourceViewSettings(); - } /** * Update resource view settings @@ -361,13 +340,6 @@ export class CalendarConfig { oldValue: this.resourceViewSettings }); } - - /** - * Legacy method - for backwards compatibility - */ - updateResourceHeaderSettings(updates: Partial): void { - this.updateResourceViewSettings(updates); - } /** * Check if current mode is resource-based @@ -383,16 +355,6 @@ export class CalendarConfig { return this.calendarMode === 'date'; } - /** - * Legacy methods - for backwards compatibility - */ - isResourceView(): boolean { - return this.isResourceMode(); - } - - isDateView(): boolean { - return this.isDateMode(); - } /** * Get calendar mode diff --git a/src/factories/CalendarTypeFactory.ts b/src/factories/CalendarTypeFactory.ts index 45a66cc..dedf483 100644 --- a/src/factories/CalendarTypeFactory.ts +++ b/src/factories/CalendarTypeFactory.ts @@ -1,6 +1,6 @@ // Factory for creating calendar type-specific renderers -import { CalendarType } from '../types/CalendarTypes'; +import { CalendarMode } from '../types/CalendarTypes'; import { HeaderRenderer, DateHeaderRenderer, ResourceHeaderRenderer } from '../renderers/HeaderRenderer'; import { ColumnRenderer, DateColumnRenderer, ResourceColumnRenderer } from '../renderers/ColumnRenderer'; import { EventRendererStrategy, DateEventRenderer, ResourceEventRenderer } from '../renderers/EventRenderer'; @@ -19,7 +19,7 @@ export interface RendererConfig { * Factory for creating calendar type-specific renderers */ export class CalendarTypeFactory { - private static renderers: Map = new Map(); + private static renderers: Map = new Map(); private static isInitialized: boolean = false; /** @@ -27,7 +27,7 @@ export class CalendarTypeFactory { */ static initialize(): void { if (this.isInitialized) { - console.warn('CalendarTypeFactory: Already initialized, skipping'); + console.warn('CalendarModeFactory: Already initialized, skipping'); return; } @@ -45,25 +45,25 @@ export class CalendarTypeFactory { }); this.isInitialized = true; - console.log('CalendarTypeFactory: Initialized with default renderers', Array.from(this.renderers.keys())); + console.log('CalendarModeFactory: Initialized with default renderers', Array.from(this.renderers.keys())); } /** * Register renderers for a calendar type */ - static registerRenderers(type: CalendarType, config: RendererConfig): void { + static registerRenderers(type: CalendarMode, config: RendererConfig): void { this.renderers.set(type, config); - console.log(`CalendarTypeFactory: Registered renderers for type '${type}'`); + console.log(`CalendarModeFactory: Registered renderers for type '${type}'`); } /** * Get renderers for a calendar type */ - static getRenderers(type: CalendarType): RendererConfig { + static getRenderers(type: CalendarMode): RendererConfig { const renderers = this.renderers.get(type); if (!renderers) { - console.warn(`CalendarTypeFactory: No renderers found for type '${type}', falling back to 'date'`); + console.warn(`CalendarModeFactory: No renderers found for type '${type}', falling back to 'date'`); return this.renderers.get('date')!; } @@ -73,35 +73,35 @@ export class CalendarTypeFactory { /** * Get header renderer for a calendar type */ - static getHeaderRenderer(type: CalendarType): HeaderRenderer { + static getHeaderRenderer(type: CalendarMode): HeaderRenderer { return this.getRenderers(type).headerRenderer; } /** * Get column renderer for a calendar type */ - static getColumnRenderer(type: CalendarType): ColumnRenderer { + static getColumnRenderer(type: CalendarMode): ColumnRenderer { return this.getRenderers(type).columnRenderer; } /** * Get event renderer for a calendar type */ - static getEventRenderer(type: CalendarType): EventRendererStrategy { + static getEventRenderer(type: CalendarMode): EventRendererStrategy { return this.getRenderers(type).eventRenderer; } /** * Check if a calendar type is supported */ - static isSupported(type: CalendarType): boolean { + static isSupported(type: CalendarMode): boolean { return this.renderers.has(type); } /** * Get all supported calendar types */ - static getSupportedTypes(): CalendarType[] { + static getSupportedTypes(): CalendarMode[] { return Array.from(this.renderers.keys()); } @@ -110,6 +110,6 @@ export class CalendarTypeFactory { */ static clear(): void { this.renderers.clear(); - console.log('CalendarTypeFactory: All renderers cleared'); + console.log('CalendarModeFactory: All renderers cleared'); } } \ No newline at end of file diff --git a/src/managers/CalendarManager.ts b/src/managers/CalendarManager.ts index cb10156..19fefa8 100644 --- a/src/managers/CalendarManager.ts +++ b/src/managers/CalendarManager.ts @@ -144,7 +144,6 @@ export class CalendarManager { this.eventBus.emit(CoreEvents.DATE_CHANGED, { previousDate, currentDate: this.currentDate, - date: this.currentDate, // Add for backward compatibility view: this.currentView }); diff --git a/src/managers/GridManager.ts b/src/managers/GridManager.ts index dededf7..f751751 100644 --- a/src/managers/GridManager.ts +++ b/src/managers/GridManager.ts @@ -54,25 +54,6 @@ export class GridManager { ); // Listen for data changes - // REMOVED: GridManager should not re-render on DATE_CHANGED - // Date navigation is handled by NavigationManager - // this.eventCleanup.push( - // eventBus.on(CoreEvents.DATE_CHANGED, (e: Event) => { - // const detail = (e as CustomEvent).detail; - // this.currentDate = detail.currentDate; - // this.render(); - // }) - // ); - - // REMOVED: GridManager should not re-render on WEEK_CHANGED - // Navigation is handled by NavigationManager + NavigationRenderer - // this.eventCleanup.push( - // eventBus.on(CoreEvents.WEEK_CHANGED, (e: Event) => { - // const detail = (e as CustomEvent).detail; - // this.currentDate = detail.weekStart; - // this.render(); - // }) - // ); this.eventCleanup.push( eventBus.on(CoreEvents.DATA_LOADED, (e: Event) => { @@ -156,12 +137,17 @@ export class GridManager { // Get layout info from strategy const layoutConfig = this.currentStrategy.getLayoutConfig(); - console.log(`GridManager: Emitting GRID_RENDERED for main container`); + // Get period range from current strategy + const periodRange = this.currentStrategy.getPeriodRange(this.currentDate); - // Emit grid rendered event + console.log(`GridManager: Emitting GRID_RENDERED for main container with period ${periodRange.startDate.toDateString()} - ${periodRange.endDate.toDateString()}`); + + // Emit grid rendered event with explicit date range eventBus.emit(CoreEvents.GRID_RENDERED, { container: this.container, currentDate: this.currentDate, + startDate: periodRange.startDate, + endDate: periodRange.endDate, layoutConfig: layoutConfig, columnCount: layoutConfig.columnCount }); diff --git a/src/managers/NavigationManager.ts b/src/managers/NavigationManager.ts index 908b822..2f90710 100644 --- a/src/managers/NavigationManager.ts +++ b/src/managers/NavigationManager.ts @@ -65,17 +65,17 @@ export class NavigationManager { // Listen for external navigation requests this.eventBus.on(CoreEvents.DATE_CHANGED, (event: Event) => { const customEvent = event as CustomEvent; - const dateFromEvent = customEvent.detail.date || customEvent.detail.currentDate; + const dateFromEvent = customEvent.detail.currentDate; // Validate date before processing if (!dateFromEvent) { - console.warn('NavigationManager: No date provided in DATE_CHANGED event', customEvent.detail); + console.warn('NavigationManager: No currentDate provided in DATE_CHANGED event', customEvent.detail); return; } const targetDate = new Date(dateFromEvent); if (isNaN(targetDate.getTime())) { - console.warn('NavigationManager: Invalid date in DATE_CHANGED event', dateFromEvent); + console.warn('NavigationManager: Invalid currentDate in DATE_CHANGED event', dateFromEvent); return; } diff --git a/src/renderers/EventRendererManager.ts b/src/renderers/EventRendererManager.ts index 38076f6..3130db1 100644 --- a/src/renderers/EventRendererManager.ts +++ b/src/renderers/EventRendererManager.ts @@ -90,17 +90,12 @@ export class EventRenderingService { let periodEnd: Date; if (startDate && endDate) { - // Legacy format with explicit dates + // Direct date format - use as provided periodStart = startDate; periodEnd = endDate; } else if (currentDate) { - // New format - calculate period from current date - // For now, use a week period. This could be improved by getting the actual period from the strategy - const baseDate = new Date(currentDate); - periodStart = new Date(baseDate); - periodStart.setDate(baseDate.getDate() - baseDate.getDay() + 1); // Monday - periodEnd = new Date(periodStart); - periodEnd.setDate(periodStart.getDate() + 6); // Sunday + console.error('EventRenderer: GRID_RENDERED events must include explicit startDate and endDate', event.detail); + return; } else { console.error('EventRenderer: No date information in GRID_RENDERED event', event.detail); return; diff --git a/src/strategies/MonthViewStrategy.ts b/src/strategies/MonthViewStrategy.ts index b921fe8..dd30043 100644 --- a/src/strategies/MonthViewStrategy.ts +++ b/src/strategies/MonthViewStrategy.ts @@ -142,6 +142,22 @@ export class MonthViewStrategy implements ViewStrategy { return this.getMonthDates(baseDate); } + getPeriodRange(baseDate: Date): { startDate: Date; endDate: Date } { + // Month view shows events for the entire month grid (including partial weeks) + const firstOfMonth = new Date(baseDate.getFullYear(), baseDate.getMonth(), 1); + + // Get Monday of the week containing first day + const startDate = this.dateCalculator.getISOWeekStart(firstOfMonth); + + // End date is 41 days after start (42 total days) + const endDate = this.dateCalculator.addDays(startDate, 41); + + return { + startDate, + endDate + }; + } + destroy(): void { console.log('MonthViewStrategy: Cleaning up'); } diff --git a/src/strategies/ViewStrategy.ts b/src/strategies/ViewStrategy.ts index 577bf87..7594ac9 100644 --- a/src/strategies/ViewStrategy.ts +++ b/src/strategies/ViewStrategy.ts @@ -60,6 +60,11 @@ export interface ViewStrategy { */ getDisplayDates(baseDate: Date): Date[]; + /** + * Get the period start and end dates for event filtering + */ + getPeriodRange(baseDate: Date): { startDate: Date; endDate: Date }; + /** * Clean up any view-specific resources */ diff --git a/src/strategies/WeekViewStrategy.ts b/src/strategies/WeekViewStrategy.ts index 1eaf839..83dca7f 100644 --- a/src/strategies/WeekViewStrategy.ts +++ b/src/strategies/WeekViewStrategy.ts @@ -67,6 +67,16 @@ export class WeekViewStrategy implements ViewStrategy { return this.dateCalculator.getWorkWeekDates(baseDate); } + getPeriodRange(baseDate: Date): { startDate: Date; endDate: Date } { + const weekStart = this.dateCalculator.getISOWeekStart(baseDate); + const weekEnd = this.dateCalculator.addDays(weekStart, 6); + + return { + startDate: weekStart, + endDate: weekEnd + }; + } + destroy(): void { // Clean up any week-specific resources // For now, just log diff --git a/src/types/CalendarTypes.ts b/src/types/CalendarTypes.ts index 97756c1..c3fe617 100644 --- a/src/types/CalendarTypes.ts +++ b/src/types/CalendarTypes.ts @@ -6,11 +6,8 @@ export type ViewPeriod = 'day' | 'week' | 'month'; // Calendar mode types (how to organize the data) export type CalendarMode = 'date' | 'resource'; -// Legacy aliases for backwards compatibility -export type DateViewType = ViewPeriod; -export type ViewType = DateViewType; -export type CalendarView = ViewType; -export type CalendarType = CalendarMode; +// Type aliases +export type CalendarView = ViewPeriod; export type SyncStatus = 'synced' | 'pending' | 'error';