Calendar/src/datasources/DateColumnDataSource.ts

130 lines
3.4 KiB
TypeScript
Raw Normal View History

import { IColumnDataSource, IColumnInfo } from '../types/ColumnDataSource';
import { DateService } from '../utils/DateService';
import { Configuration } from '../configurations/CalendarConfig';
import { CalendarView } from '../types/CalendarTypes';
/**
* DateColumnDataSource - Provides date-based columns
*
* Calculates which dates to display based on:
* - Current date
* - Current view (day/week/month)
* - Workweek settings
*/
export class DateColumnDataSource implements IColumnDataSource {
private dateService: DateService;
private config: Configuration;
private currentDate: Date;
private currentView: CalendarView;
constructor(
dateService: DateService,
config: Configuration
) {
this.dateService = dateService;
this.config = config;
this.currentDate = new Date();
this.currentView = this.config.currentView;
}
/**
* Get columns (dates) to display
*/
public async getColumns(): Promise<IColumnInfo[]> {
let dates: Date[];
switch (this.currentView) {
case 'week':
dates = this.getWeekDates();
break;
case 'month':
dates = this.getMonthDates();
break;
case 'day':
dates = [this.currentDate];
break;
default:
dates = this.getWeekDates();
}
// Convert Date[] to IColumnInfo[]
return dates.map(date => ({
identifier: this.dateService.formatISODate(date),
data: date
}));
}
/**
* Get type of datasource
*/
public getType(): 'date' | 'resource' {
return 'date';
}
/**
* Update current date
*/
public setCurrentDate(date: Date): void {
this.currentDate = date;
}
/**
* Update current view
*/
public setCurrentView(view: CalendarView): void {
this.currentView = view;
}
/**
* Get dates for week view based on workweek settings
*/
private getWeekDates(): Date[] {
const weekStart = this.getISOWeekStart(this.currentDate);
const workWeekSettings = this.config.getWorkWeekSettings();
return this.dateService.getWorkWeekDates(weekStart, workWeekSettings.workDays);
}
/**
* Get all dates in current month
*/
private getMonthDates(): Date[] {
const dates: Date[] = [];
const monthStart = this.getMonthStart(this.currentDate);
const monthEnd = this.getMonthEnd(this.currentDate);
const totalDays = Math.ceil((monthEnd.getTime() - monthStart.getTime()) / (1000 * 60 * 60 * 24)) + 1;
for (let i = 0; i < totalDays; i++) {
dates.push(this.dateService.addDays(monthStart, i));
}
return dates;
}
/**
* Get ISO week start (Monday)
*/
private getISOWeekStart(date: Date): Date {
const weekBounds = this.dateService.getWeekBounds(date);
return this.dateService.startOfDay(weekBounds.start);
}
/**
* Get month start
*/
private getMonthStart(date: Date): Date {
const year = date.getFullYear();
const month = date.getMonth();
return this.dateService.startOfDay(new Date(year, month, 1));
}
/**
* Get month end
*/
private getMonthEnd(date: Date): Date {
const nextMonth = this.dateService.addMonths(date, 1);
const firstOfNextMonth = this.getMonthStart(nextMonth);
return this.dateService.endOfDay(this.dateService.addDays(firstOfNextMonth, -1));
}
}