Refactors date handling with DateService

Replaces DateCalculator with DateService for improved date and time operations, including timezone handling.

This change enhances the calendar's accuracy and flexibility in managing dates, especially concerning timezone configurations.
It also corrects a typo in the `allDay` dataset attribute.
This commit is contained in:
Janus C. H. Knudsen 2025-10-03 20:50:40 +02:00
parent 4859f42450
commit 6bbf2d8adb
17 changed files with 159 additions and 749 deletions

View file

@ -2,7 +2,7 @@
import { CalendarConfig } from '../core/CalendarConfig';
import { ResourceCalendarData } from '../types/CalendarTypes';
import { DateCalculator } from '../utils/DateCalculator';
import { DateService } from '../utils/DateService';
import { WorkHoursManager } from '../managers/WorkHoursManager';
/**
@ -25,25 +25,26 @@ export interface ColumnRenderContext {
* Date-based column renderer (original functionality)
*/
export class DateColumnRenderer implements ColumnRenderer {
private dateCalculator!: DateCalculator;
private dateService!: DateService;
private workHoursManager!: WorkHoursManager;
render(columnContainer: HTMLElement, context: ColumnRenderContext): void {
const { currentWeek, config } = context;
// Initialize date calculator and work hours manager
DateCalculator.initialize(config);
this.dateCalculator = new DateCalculator();
// Initialize date service and work hours manager
const timezone = config.getTimezone?.() || 'Europe/Copenhagen';
this.dateService = new DateService(timezone);
this.workHoursManager = new WorkHoursManager();
const dates = DateCalculator.getWorkWeekDates(currentWeek);
const workWeekSettings = config.getWorkWeekSettings();
const dates = this.dateService.getWorkWeekDates(currentWeek, workWeekSettings.workDays);
const dateSettings = config.getDateViewSettings();
const daysToShow = dates.slice(0, dateSettings.weekDays);
daysToShow.forEach((date) => {
const column = document.createElement('swp-day-column');
(column as any).dataset.date = DateCalculator.formatISODate(date);
(column as any).dataset.date = this.dateService.formatISODate(date);
// Apply work hours styling
this.applyWorkHoursToColumn(column, date);

View file

@ -2,7 +2,6 @@
import { CalendarEvent } from '../types/CalendarTypes';
import { calendarConfig } from '../core/CalendarConfig';
import { DateCalculator } from '../utils/DateCalculator';
import { eventBus } from '../core/EventBus';
import { OverlapDetector, OverlapResult } from '../utils/OverlapDetector';
import { SwpEventElement } from '../elements/SwpEventElement';
@ -38,18 +37,13 @@ export interface EventRendererStrategy {
*/
export class DateEventRenderer implements EventRendererStrategy {
private dateService: DateService;
constructor(dateCalculator?: DateCalculator) {
if (!dateCalculator) {
DateCalculator.initialize(calendarConfig);
}
this.dateCalculator = dateCalculator || new DateCalculator();
constructor() {
const timezone = calendarConfig.getTimezone?.() || 'Europe/Copenhagen';
this.dateService = new DateService(timezone);
this.setupDragEventListeners();
}
private dateCalculator: DateCalculator;
private draggedClone: HTMLElement | null = null;
private originalEvent: HTMLElement | null = null;
@ -634,10 +628,9 @@ export class DateEventRenderer implements EventRendererStrategy {
}
const columnEvents = events.filter(event => {
const eventDateStr = DateCalculator.formatISODate(event.start);
const eventDateStr = this.dateService.formatISODate(event.start);
const matches = eventDateStr === columnDate;
return matches;
});

View file

@ -3,7 +3,7 @@ import { ResourceCalendarData, CalendarView } from '../types/CalendarTypes';
import { CalendarTypeFactory } from '../factories/CalendarTypeFactory';
import { ColumnRenderContext } from './ColumnRenderer';
import { eventBus } from '../core/EventBus';
import { DateCalculator } from '../utils/DateCalculator';
import { DateService } from '../utils/DateService';
import { CoreEvents } from '../constants/CoreEvents';
/**
@ -13,8 +13,11 @@ import { CoreEvents } from '../constants/CoreEvents';
export class GridRenderer {
private cachedGridContainer: HTMLElement | null = null;
private cachedTimeAxis: HTMLElement | null = null;
private dateService: DateService;
constructor() {
const timezone = calendarConfig.getTimezone?.() || 'Europe/Copenhagen';
this.dateService = new DateService(timezone);
}
/**
@ -239,7 +242,7 @@ export class GridRenderer {
console.log('Parent container:', parentContainer);
console.log('Using same grid creation as initial load');
const weekEnd = DateCalculator.addDays(weekStart, 6);
const weekEnd = this.dateService.addDays(weekStart, 6);
// Use SAME method as initial load - respects workweek and resource settings
const newGrid = this.createOptimizedGridContainer(weekStart, null, 'week');

View file

@ -2,7 +2,7 @@
import { CalendarConfig } from '../core/CalendarConfig';
import { ResourceCalendarData } from '../types/CalendarTypes';
import { DateCalculator } from '../utils/DateCalculator';
import { DateService } from '../utils/DateService';
/**
* Interface for header rendering strategies
@ -25,7 +25,7 @@ export interface HeaderRenderContext {
* Date-based header renderer (original functionality)
*/
export class DateHeaderRenderer implements HeaderRenderer {
private dateCalculator!: DateCalculator;
private dateService!: DateService;
render(calendarHeader: HTMLElement, context: HeaderRenderContext): void {
const { currentWeek, config } = context;
@ -34,27 +34,28 @@ export class DateHeaderRenderer implements HeaderRenderer {
const allDayContainer = document.createElement('swp-allday-container');
calendarHeader.appendChild(allDayContainer);
// Initialize date calculator with config
DateCalculator.initialize(config);
this.dateCalculator = new DateCalculator();
// Initialize date service with config
const timezone = config.getTimezone?.() || 'Europe/Copenhagen';
this.dateService = new DateService(timezone);
const dates = DateCalculator.getWorkWeekDates(currentWeek);
const workWeekSettings = config.getWorkWeekSettings();
const dates = this.dateService.getWorkWeekDates(currentWeek, workWeekSettings.workDays);
const weekDays = config.getDateViewSettings().weekDays;
const daysToShow = dates.slice(0, weekDays);
daysToShow.forEach((date, index) => {
const header = document.createElement('swp-day-header');
if (DateCalculator.isToday(date)) {
if (this.dateService.isSameDay(date, new Date())) {
(header as any).dataset.today = 'true';
}
const dayName = DateCalculator.getDayName(date, 'short');
const dayName = this.dateService.getDayName(date, 'short');
header.innerHTML = `
<swp-day-name>${dayName}</swp-day-name>
<swp-day-date>${date.getDate()}</swp-day-date>
`;
(header as any).dataset.date = DateCalculator.formatISODate(date);
(header as any).dataset.date = this.dateService.formatISODate(date);
calendarHeader.appendChild(header);
});