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:
parent
4859f42450
commit
6bbf2d8adb
17 changed files with 159 additions and 749 deletions
|
|
@ -7,7 +7,7 @@ import { GridManager } from './GridManager';
|
|||
import { HeaderManager } from './HeaderManager';
|
||||
import { EventRenderingService } from '../renderers/EventRendererManager';
|
||||
import { ScrollManager } from './ScrollManager';
|
||||
import { DateCalculator } from '../utils/DateCalculator';
|
||||
import { DateService } from '../utils/DateService';
|
||||
import { EventFilterManager } from './EventFilterManager';
|
||||
import { InitializationReport } from '../types/ManagerTypes';
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ export class CalendarManager {
|
|||
private eventRenderer: EventRenderingService;
|
||||
private scrollManager: ScrollManager;
|
||||
private eventFilterManager: EventFilterManager;
|
||||
private dateCalculator: DateCalculator;
|
||||
private dateService: DateService;
|
||||
private currentView: CalendarView = 'week';
|
||||
private currentDate: Date = new Date();
|
||||
private isInitialized: boolean = false;
|
||||
|
|
@ -42,8 +42,8 @@ export class CalendarManager {
|
|||
this.eventRenderer = eventRenderer;
|
||||
this.scrollManager = scrollManager;
|
||||
this.eventFilterManager = new EventFilterManager();
|
||||
DateCalculator.initialize(calendarConfig);
|
||||
this.dateCalculator = new DateCalculator();
|
||||
const timezone = calendarConfig.getTimezone?.() || 'Europe/Copenhagen';
|
||||
this.dateService = new DateService(timezone);
|
||||
this.setupEventListeners();
|
||||
}
|
||||
|
||||
|
|
@ -451,10 +451,10 @@ export class CalendarManager {
|
|||
const lastDate = new Date(lastDateStr);
|
||||
|
||||
// Calculate week number from first date
|
||||
const weekNumber = DateCalculator.getWeekNumber(firstDate);
|
||||
const weekNumber = this.dateService.getWeekNumber(firstDate);
|
||||
|
||||
// Format date range
|
||||
const dateRange = DateCalculator.formatDateRange(firstDate, lastDate);
|
||||
const dateRange = this.dateService.formatDateRange(firstDate, lastDate);
|
||||
|
||||
// Emit week info update
|
||||
this.eventBus.emit(CoreEvents.PERIOD_INFO_UPDATE, {
|
||||
|
|
|
|||
|
|
@ -42,9 +42,6 @@ export class DragDropManager {
|
|||
private currentColumnBounds: ColumnBounds | null = null;
|
||||
private isDragStarted = false;
|
||||
|
||||
// Header tracking state
|
||||
private isInHeader = false;
|
||||
|
||||
// Movement threshold to distinguish click from drag
|
||||
private readonly dragThreshold = 5; // pixels
|
||||
|
||||
|
|
@ -460,7 +457,6 @@ export class DragDropManager {
|
|||
this.draggedElement = null;
|
||||
this.draggedClone = null;
|
||||
this.isDragStarted = false;
|
||||
this.isInHeader = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -492,15 +488,11 @@ export class DragDropManager {
|
|||
const elementAtPosition = document.elementFromPoint(event.clientX, event.clientY);
|
||||
if (!elementAtPosition) return;
|
||||
|
||||
// Check if we're in a header area
|
||||
const headerElement = elementAtPosition.closest('swp-day-header, swp-calendar-header');
|
||||
const isCurrentlyInHeader = !!headerElement;
|
||||
|
||||
// Detect header enter
|
||||
if (!this.isInHeader && isCurrentlyInHeader && this.draggedClone) {
|
||||
this.isInHeader = true;
|
||||
if (isCurrentlyInHeader && !this.draggedClone?.hasAttribute("data-allday")) {
|
||||
|
||||
// Calculate target date using existing method
|
||||
const targetColumn = ColumnDetectionUtils.getColumnBounds(position);
|
||||
|
||||
if (targetColumn) {
|
||||
|
|
@ -510,15 +502,14 @@ export class DragDropManager {
|
|||
targetColumn: targetColumn,
|
||||
mousePosition: { x: event.clientX, y: event.clientY },
|
||||
originalElement: this.draggedElement,
|
||||
draggedClone: this.draggedClone
|
||||
draggedClone: this.draggedClone!!
|
||||
};
|
||||
this.eventBus.emit('drag:mouseenter-header', dragMouseEnterPayload);
|
||||
}
|
||||
}
|
||||
|
||||
// Detect header leave
|
||||
if (this.isInHeader && !isCurrentlyInHeader) {
|
||||
this.isInHeader = false;
|
||||
if (isCurrentlyInHeader && this.draggedClone?.hasAttribute("data-allday")) {
|
||||
|
||||
console.log('🚪 DragDropManager: Emitting drag:mouseleave-header');
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { EventBus } from '../core/EventBus';
|
|||
import { IEventBus, CalendarEvent, ResourceCalendarData } from '../types/CalendarTypes';
|
||||
import { CoreEvents } from '../constants/CoreEvents';
|
||||
import { calendarConfig } from '../core/CalendarConfig';
|
||||
import { DateCalculator } from '../utils/DateCalculator';
|
||||
import { DateService } from '../utils/DateService';
|
||||
import { ResourceData } from '../types/ManagerTypes';
|
||||
|
||||
interface RawEventData {
|
||||
|
|
@ -26,9 +26,12 @@ export class EventManager {
|
|||
private rawData: ResourceCalendarData | RawEventData[] | null = null;
|
||||
private eventCache = new Map<string, CalendarEvent[]>(); // Cache for period queries
|
||||
private lastCacheKey: string = '';
|
||||
private dateService: DateService;
|
||||
|
||||
constructor(eventBus: IEventBus) {
|
||||
this.eventBus = eventBus;
|
||||
const timezone = calendarConfig.getTimezone?.() || 'Europe/Copenhagen';
|
||||
this.dateService = new DateService(timezone);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -196,11 +199,11 @@ export class EventManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Optimized events for period with caching and DateCalculator
|
||||
* Optimized events for period with caching and DateService
|
||||
*/
|
||||
public getEventsForPeriod(startDate: Date, endDate: Date): CalendarEvent[] {
|
||||
// Create cache key using DateCalculator for consistent formatting
|
||||
const cacheKey = `${DateCalculator.formatISODate(startDate)}_${DateCalculator.formatISODate(endDate)}`;
|
||||
// Create cache key using DateService for consistent formatting
|
||||
const cacheKey = `${this.dateService.formatISODate(startDate)}_${this.dateService.formatISODate(endDate)}`;
|
||||
|
||||
// Return cached result if available
|
||||
if (this.lastCacheKey === cacheKey && this.eventCache.has(cacheKey)) {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { CoreEvents } from '../constants/CoreEvents';
|
|||
import { ResourceCalendarData, CalendarView } from '../types/CalendarTypes';
|
||||
import { GridRenderer } from '../renderers/GridRenderer';
|
||||
import { GridStyleManager } from '../renderers/GridStyleManager';
|
||||
import { DateCalculator } from '../utils/DateCalculator';
|
||||
import { DateService } from '../utils/DateService';
|
||||
|
||||
/**
|
||||
* Simplified GridManager focused on coordination, delegates rendering to GridRenderer
|
||||
|
|
@ -21,18 +21,35 @@ export class GridManager {
|
|||
private currentView: CalendarView = 'week';
|
||||
private gridRenderer: GridRenderer;
|
||||
private styleManager: GridStyleManager;
|
||||
private dateService: DateService;
|
||||
|
||||
constructor() {
|
||||
// Initialize GridRenderer and StyleManager with config
|
||||
this.gridRenderer = new GridRenderer();
|
||||
this.styleManager = new GridStyleManager();
|
||||
this.dateService = new DateService('Europe/Copenhagen');
|
||||
this.init();
|
||||
}
|
||||
|
||||
private init(): void {
|
||||
this.findElements();
|
||||
this.subscribeToEvents();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the start of the ISO week (Monday) for a given date
|
||||
*/
|
||||
private getISOWeekStart(date: Date): Date {
|
||||
const weekBounds = this.dateService.getWeekBounds(date);
|
||||
return this.dateService.startOfDay(weekBounds.start);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the end of the ISO week (Sunday) for a given date
|
||||
*/
|
||||
private getWeekEnd(date: Date): Date {
|
||||
const weekBounds = this.dateService.getWeekBounds(date);
|
||||
return this.dateService.endOfDay(weekBounds.end);
|
||||
}
|
||||
|
||||
private findElements(): void {
|
||||
|
|
@ -91,7 +108,7 @@ export class GridManager {
|
|||
this.resourceData
|
||||
);
|
||||
|
||||
// Calculate period range using DateCalculator
|
||||
// Calculate period range
|
||||
const periodRange = this.getPeriodRange();
|
||||
|
||||
// Get layout config based on current view
|
||||
|
|
@ -110,42 +127,42 @@ export class GridManager {
|
|||
|
||||
|
||||
/**
|
||||
* Get current period label using DateCalculator
|
||||
* Get current period label
|
||||
*/
|
||||
public getCurrentPeriodLabel(): string {
|
||||
switch (this.currentView) {
|
||||
case 'week':
|
||||
case 'day':
|
||||
const weekStart = DateCalculator.getISOWeekStart(this.currentDate);
|
||||
const weekEnd = DateCalculator.getWeekEnd(this.currentDate);
|
||||
return DateCalculator.formatDateRange(weekStart, weekEnd);
|
||||
const weekStart = this.getISOWeekStart(this.currentDate);
|
||||
const weekEnd = this.getWeekEnd(this.currentDate);
|
||||
return this.dateService.formatDateRange(weekStart, weekEnd);
|
||||
case 'month':
|
||||
return this.currentDate.toLocaleDateString('en-US', { month: 'long', year: 'numeric' });
|
||||
default:
|
||||
const defaultWeekStart = DateCalculator.getISOWeekStart(this.currentDate);
|
||||
const defaultWeekEnd = DateCalculator.getWeekEnd(this.currentDate);
|
||||
return DateCalculator.formatDateRange(defaultWeekStart, defaultWeekEnd);
|
||||
const defaultWeekStart = this.getISOWeekStart(this.currentDate);
|
||||
const defaultWeekEnd = this.getWeekEnd(this.currentDate);
|
||||
return this.dateService.formatDateRange(defaultWeekStart, defaultWeekEnd);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigate to next period using DateCalculator
|
||||
* Navigate to next period
|
||||
*/
|
||||
public navigateNext(): void {
|
||||
let nextDate: Date;
|
||||
|
||||
switch (this.currentView) {
|
||||
case 'week':
|
||||
nextDate = DateCalculator.addWeeks(this.currentDate, 1);
|
||||
nextDate = this.dateService.addWeeks(this.currentDate, 1);
|
||||
break;
|
||||
case 'month':
|
||||
nextDate = this.addMonths(this.currentDate, 1);
|
||||
break;
|
||||
case 'day':
|
||||
nextDate = DateCalculator.addDays(this.currentDate, 1);
|
||||
nextDate = this.dateService.addDays(this.currentDate, 1);
|
||||
break;
|
||||
default:
|
||||
nextDate = DateCalculator.addWeeks(this.currentDate, 1);
|
||||
nextDate = this.dateService.addWeeks(this.currentDate, 1);
|
||||
}
|
||||
|
||||
this.currentDate = nextDate;
|
||||
|
|
@ -160,23 +177,23 @@ export class GridManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Navigate to previous period using DateCalculator
|
||||
* Navigate to previous period
|
||||
*/
|
||||
public navigatePrevious(): void {
|
||||
let prevDate: Date;
|
||||
|
||||
switch (this.currentView) {
|
||||
case 'week':
|
||||
prevDate = DateCalculator.addWeeks(this.currentDate, -1);
|
||||
prevDate = this.dateService.addWeeks(this.currentDate, -1);
|
||||
break;
|
||||
case 'month':
|
||||
prevDate = this.addMonths(this.currentDate, -1);
|
||||
break;
|
||||
case 'day':
|
||||
prevDate = DateCalculator.addDays(this.currentDate, -1);
|
||||
prevDate = this.dateService.addDays(this.currentDate, -1);
|
||||
break;
|
||||
default:
|
||||
prevDate = DateCalculator.addWeeks(this.currentDate, -1);
|
||||
prevDate = this.dateService.addWeeks(this.currentDate, -1);
|
||||
}
|
||||
|
||||
this.currentDate = prevDate;
|
||||
|
|
@ -205,20 +222,20 @@ export class GridManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get current view's display dates using DateCalculator
|
||||
* Get current view's display dates
|
||||
*/
|
||||
public getDisplayDates(): Date[] {
|
||||
switch (this.currentView) {
|
||||
case 'week':
|
||||
const weekStart = DateCalculator.getISOWeekStart(this.currentDate);
|
||||
return DateCalculator.getFullWeekDates(weekStart);
|
||||
const weekStart = this.getISOWeekStart(this.currentDate);
|
||||
return this.dateService.getFullWeekDates(weekStart);
|
||||
case 'month':
|
||||
return this.getMonthDates(this.currentDate);
|
||||
case 'day':
|
||||
return [this.currentDate];
|
||||
default:
|
||||
const defaultWeekStart = DateCalculator.getISOWeekStart(this.currentDate);
|
||||
return DateCalculator.getFullWeekDates(defaultWeekStart);
|
||||
const defaultWeekStart = this.getISOWeekStart(this.currentDate);
|
||||
return this.dateService.getFullWeekDates(defaultWeekStart);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -228,8 +245,8 @@ export class GridManager {
|
|||
private getPeriodRange(): { startDate: Date; endDate: Date } {
|
||||
switch (this.currentView) {
|
||||
case 'week':
|
||||
const weekStart = DateCalculator.getISOWeekStart(this.currentDate);
|
||||
const weekEnd = DateCalculator.getWeekEnd(this.currentDate);
|
||||
const weekStart = this.getISOWeekStart(this.currentDate);
|
||||
const weekEnd = this.getWeekEnd(this.currentDate);
|
||||
return {
|
||||
startDate: weekStart,
|
||||
endDate: weekEnd
|
||||
|
|
@ -245,8 +262,8 @@ export class GridManager {
|
|||
endDate: this.currentDate
|
||||
};
|
||||
default:
|
||||
const defaultWeekStart = DateCalculator.getISOWeekStart(this.currentDate);
|
||||
const defaultWeekEnd = DateCalculator.getWeekEnd(this.currentDate);
|
||||
const defaultWeekStart = this.getISOWeekStart(this.currentDate);
|
||||
const defaultWeekEnd = this.getWeekEnd(this.currentDate);
|
||||
return {
|
||||
startDate: defaultWeekStart,
|
||||
endDate: defaultWeekEnd
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { IEventBus } from '../types/CalendarTypes';
|
||||
import { EventRenderingService } from '../renderers/EventRendererManager';
|
||||
import { DateCalculator } from '../utils/DateCalculator';
|
||||
import { DateService } from '../utils/DateService';
|
||||
import { CoreEvents } from '../constants/CoreEvents';
|
||||
import { NavigationRenderer } from '../renderers/NavigationRenderer';
|
||||
import { GridRenderer } from '../renderers/GridRenderer';
|
||||
|
|
@ -14,18 +14,17 @@ export class NavigationManager {
|
|||
private eventBus: IEventBus;
|
||||
private navigationRenderer: NavigationRenderer;
|
||||
private gridRenderer: GridRenderer;
|
||||
private dateCalculator: DateCalculator;
|
||||
private dateService: DateService;
|
||||
private currentWeek: Date;
|
||||
private targetWeek: Date;
|
||||
private animationQueue: number = 0;
|
||||
|
||||
constructor(eventBus: IEventBus, eventRenderer: EventRenderingService) {
|
||||
this.eventBus = eventBus;
|
||||
DateCalculator.initialize(calendarConfig);
|
||||
this.dateCalculator = new DateCalculator();
|
||||
this.dateService = new DateService('Europe/Copenhagen');
|
||||
this.navigationRenderer = new NavigationRenderer(eventBus, eventRenderer);
|
||||
this.gridRenderer = new GridRenderer();
|
||||
this.currentWeek = DateCalculator.getISOWeekStart(new Date());
|
||||
this.currentWeek = this.getISOWeekStart(new Date());
|
||||
this.targetWeek = new Date(this.currentWeek);
|
||||
this.init();
|
||||
}
|
||||
|
|
@ -34,6 +33,16 @@ export class NavigationManager {
|
|||
this.setupEventListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the start of the ISO week (Monday) for a given date
|
||||
* @param date - Any date in the week
|
||||
* @returns The Monday of the ISO week
|
||||
*/
|
||||
private getISOWeekStart(date: Date): Date {
|
||||
const weekBounds = this.dateService.getWeekBounds(date);
|
||||
return this.dateService.startOfDay(weekBounds.start);
|
||||
}
|
||||
|
||||
|
||||
private getCalendarContainer(): HTMLElement | null {
|
||||
return document.querySelector('swp-calendar-container');
|
||||
|
|
@ -113,7 +122,7 @@ export class NavigationManager {
|
|||
* Navigate to specific event date and emit scroll event after navigation
|
||||
*/
|
||||
private navigateToEventDate(eventDate: Date, eventStartTime: string): void {
|
||||
const weekStart = DateCalculator.getISOWeekStart(eventDate);
|
||||
const weekStart = this.getISOWeekStart(eventDate);
|
||||
this.targetWeek = new Date(weekStart);
|
||||
|
||||
const currentTime = this.currentWeek.getTime();
|
||||
|
|
@ -159,7 +168,7 @@ export class NavigationManager {
|
|||
|
||||
private navigateToToday(): void {
|
||||
const today = new Date();
|
||||
const todayWeekStart = DateCalculator.getISOWeekStart(today);
|
||||
const todayWeekStart = this.getISOWeekStart(today);
|
||||
|
||||
// Reset to today
|
||||
this.targetWeek = new Date(todayWeekStart);
|
||||
|
|
@ -177,7 +186,7 @@ export class NavigationManager {
|
|||
}
|
||||
|
||||
private navigateToDate(date: Date): void {
|
||||
const weekStart = DateCalculator.getISOWeekStart(date);
|
||||
const weekStart = this.getISOWeekStart(date);
|
||||
this.targetWeek = new Date(weekStart);
|
||||
|
||||
const currentTime = this.currentWeek.getTime();
|
||||
|
|
@ -277,9 +286,9 @@ export class NavigationManager {
|
|||
}
|
||||
|
||||
private updateWeekInfo(): void {
|
||||
const weekNumber = DateCalculator.getWeekNumber(this.currentWeek);
|
||||
const weekEnd = DateCalculator.addDays(this.currentWeek, 6);
|
||||
const dateRange = DateCalculator.formatDateRange(this.currentWeek, weekEnd);
|
||||
const weekNumber = this.dateService.getWeekNumber(this.currentWeek);
|
||||
const weekEnd = this.dateService.addDays(this.currentWeek, 6);
|
||||
const dateRange = this.dateService.formatDateRange(this.currentWeek, weekEnd);
|
||||
|
||||
// Notify other managers about week info update - DOM manipulation should happen via events
|
||||
this.eventBus.emit(CoreEvents.PERIOD_INFO_UPDATE, {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Work hours management for per-column scheduling
|
||||
|
||||
import { DateCalculator } from '../utils/DateCalculator';
|
||||
import { DateService } from '../utils/DateService';
|
||||
import { calendarConfig } from '../core/CalendarConfig';
|
||||
import { PositionUtils } from '../utils/PositionUtils';
|
||||
|
||||
|
|
@ -34,12 +34,12 @@ export interface WorkScheduleConfig {
|
|||
* Manages work hours scheduling with weekly defaults and date-specific overrides
|
||||
*/
|
||||
export class WorkHoursManager {
|
||||
private dateCalculator: DateCalculator;
|
||||
private dateService: DateService;
|
||||
private workSchedule: WorkScheduleConfig;
|
||||
|
||||
constructor() {
|
||||
DateCalculator.initialize(calendarConfig);
|
||||
this.dateCalculator = new DateCalculator();
|
||||
const timezone = calendarConfig.getTimezone?.() || 'Europe/Copenhagen';
|
||||
this.dateService = new DateService(timezone);
|
||||
|
||||
// Default work schedule - will be loaded from JSON later
|
||||
this.workSchedule = {
|
||||
|
|
@ -64,7 +64,7 @@ export class WorkHoursManager {
|
|||
* Get work hours for a specific date
|
||||
*/
|
||||
getWorkHoursForDate(date: Date): DayWorkHours | 'off' {
|
||||
const dateString = DateCalculator.formatISODate(date);
|
||||
const dateString = this.dateService.formatISODate(date);
|
||||
|
||||
// Check for date-specific override first
|
||||
if (this.workSchedule.dateOverrides[dateString]) {
|
||||
|
|
@ -83,7 +83,7 @@ export class WorkHoursManager {
|
|||
const workHoursMap = new Map<string, DayWorkHours | 'off'>();
|
||||
|
||||
dates.forEach(date => {
|
||||
const dateString = DateCalculator.formatISODate(date);
|
||||
const dateString = this.dateService.formatISODate(date);
|
||||
const workHours = this.getWorkHoursForDate(date);
|
||||
workHoursMap.set(dateString, workHours);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue