Refactors date handling for ISO week compatibility

Centralizes all date calculations into a new `DateCalculator` class for better maintainability and consistency.

Ensures correct ISO week handling (Monday as the first day) throughout the calendar.

Updates `CalendarConfig` to use ISO day numbering (1-7 for Mon-Sun) for work week definitions.

Fixes issue where date calculations were inconsistent.
Enhances event rendering and navigation.
Updates navigation logic to use pre-rendered events.
Removes the need for `CONTAINER_READY_FOR_EVENTS` event.
This commit is contained in:
Janus Knudsen 2025-08-20 00:39:31 +02:00
parent efc1742dad
commit 7d513600d8
13 changed files with 230 additions and 343 deletions

View file

@ -4,7 +4,6 @@ import { eventBus } from '../core/EventBus';
import { calendarConfig } from '../core/CalendarConfig';
import { EventTypes } from '../constants/EventTypes';
import { StateEvents } from '../types/CalendarState';
import { DateUtils } from '../utils/DateUtils';
import { DateCalculator } from '../utils/DateCalculator';
import { ResourceCalendarData } from '../types/CalendarTypes';
import { GridRenderer } from '../renderers/GridRenderer';
@ -105,6 +104,7 @@ export class GridManager {
this.render();
});
// Handle events loaded
eventBus.on(EventTypes.EVENTS_LOADED, (e: Event) => {
const detail = (e as CustomEvent).detail;
@ -147,12 +147,14 @@ export class GridManager {
}
}
console.log('GridManager: Starting render with grid element:', this.grid);
console.group(`🏗️ GRID RENDER: ${this.currentWeek?.toDateString()}`);
console.log('Updating grid styles and rendering structure...');
this.styleManager.updateGridStyles(this.resourceData);
this.gridRenderer.renderGrid(this.grid, this.currentWeek!, this.resourceData, this.allDayEvents);
const columnCount = this.styleManager.getColumnCount(this.resourceData);
console.log(`GridManager: Render complete - created ${columnCount} columns`);
console.log(`Grid structure complete - ${columnCount} columns created`);
// Emit GRID_RENDERED event to trigger event rendering
const weekEnd = this.currentWeek ? new Date(this.currentWeek.getTime() + 6 * 24 * 60 * 60 * 1000) : null;
@ -163,6 +165,8 @@ export class GridManager {
endDate: weekEnd,
columnCount: columnCount
});
console.groupEnd();
}
// Column count calculation moved to GridStyleManager

View file

@ -1,5 +1,6 @@
import { IEventBus } from '../types/CalendarTypes.js';
import { DateUtils } from '../utils/DateUtils.js';
import { EventRenderingService } from '../renderers/EventRendererManager.js';
import { DateCalculator } from '../utils/DateCalculator.js';
import { EventTypes } from '../constants/EventTypes.js';
import { NavigationRenderer } from '../renderers/NavigationRenderer.js';
import { calendarConfig } from '../core/CalendarConfig.js';
@ -11,15 +12,17 @@ import { calendarConfig } from '../core/CalendarConfig.js';
export class NavigationManager {
private eventBus: IEventBus;
private navigationRenderer: NavigationRenderer;
private dateCalculator: DateCalculator;
private currentWeek: Date;
private targetWeek: Date;
private animationQueue: number = 0;
constructor(eventBus: IEventBus) {
constructor(eventBus: IEventBus, eventRenderer: EventRenderingService) {
console.log('🧭 NavigationManager: Constructor called');
this.eventBus = eventBus;
this.navigationRenderer = new NavigationRenderer(eventBus, calendarConfig);
this.currentWeek = DateUtils.getWeekStart(new Date(), 0); // Sunday start like POC
this.dateCalculator = new DateCalculator(calendarConfig);
this.navigationRenderer = new NavigationRenderer(eventBus, calendarConfig, eventRenderer);
this.currentWeek = this.dateCalculator.getISOWeekStart(new Date());
this.targetWeek = new Date(this.currentWeek);
this.init();
}
@ -83,7 +86,7 @@ export class NavigationManager {
private navigateToToday(): void {
const today = new Date();
const todayWeekStart = DateUtils.getWeekStart(today, 0);
const todayWeekStart = this.dateCalculator.getISOWeekStart(today);
// Reset to today
this.targetWeek = new Date(todayWeekStart);
@ -101,7 +104,7 @@ export class NavigationManager {
}
private navigateToDate(date: Date): void {
const weekStart = DateUtils.getWeekStart(date, 0);
const weekStart = this.dateCalculator.getISOWeekStart(date);
this.targetWeek = new Date(weekStart);
const currentTime = this.currentWeek.getTime();
@ -128,14 +131,16 @@ export class NavigationManager {
return;
}
console.log(`NavigationManager: Starting ${direction} animation to ${targetWeek.toDateString()}`);
console.group(`🎬 NAVIGATION ANIMATION: ${direction} to ${targetWeek.toDateString()}`);
console.log('1. Creating new container with events...');
let newGrid: HTMLElement;
// Always create a fresh container for consistent behavior
console.log('NavigationManager: Creating new container');
newGrid = this.navigationRenderer.renderContainer(container as HTMLElement, targetWeek);
console.log('2. Starting slide animation...');
// Clear any existing transforms before animation
newGrid.style.transform = '';
(currentGrid as HTMLElement).style.transform = '';
@ -161,6 +166,8 @@ export class NavigationManager {
// Handle animation completion
slideInAnimation.addEventListener('finish', () => {
console.log('3. Animation finished, cleaning up...');
// Cleanup: Remove all old grids except the new one
const allGrids = container.querySelectorAll('swp-grid-container');
for (let i = 0; i < allGrids.length - 1; i++) {
@ -184,24 +191,24 @@ export class NavigationManager {
this.updateWeekInfo();
this.eventBus.emit(EventTypes.WEEK_CHANGED, {
weekStart: this.currentWeek,
weekEnd: DateUtils.addDays(this.currentWeek, 6)
weekEnd: this.dateCalculator.addDays(this.currentWeek, 6)
});
// Emit animation complete event for ScrollManager
this.eventBus.emit(EventTypes.NAVIGATION_ANIMATION_COMPLETE, {
direction,
weekStart: this.currentWeek
});
console.log(`NavigationManager: Completed ${direction} animation`);
console.log('✅ Animation completed successfully');
console.groupEnd();
});
}
private updateWeekInfo(): void {
const weekNumber = DateUtils.getWeekNumber(this.currentWeek);
const weekEnd = DateUtils.addDays(this.currentWeek, 6);
const dateRange = DateUtils.formatDateRange(this.currentWeek, weekEnd);
const weekNumber = this.dateCalculator.getWeekNumber(this.currentWeek);
const weekEnd = this.dateCalculator.addDays(this.currentWeek, 6);
const dateRange = this.dateCalculator.formatDateRange(this.currentWeek, weekEnd);
// Notify other managers about week info update - DOM manipulation should happen via events
this.eventBus.emit(EventTypes.WEEK_INFO_UPDATED, {

View file

@ -36,6 +36,7 @@ export class ViewManager {
// Setup workweek preset button handlers
this.setupWorkweekButtonHandlers();
}
private setupViewButtonHandlers(): void {
@ -64,6 +65,7 @@ export class ViewManager {
});
}
private initializeView(): void {
this.updateViewButtons();
this.updateWorkweekButtons();