import { DateTime } from "luxon"; import { defaultAvailable, GanttViewType } from "./base"; import { CellDescriptor, DescriptorSet, IntervalDescriptor, TickDescriptor } from "./descriptors"; export class GanttViewMonth extends GanttViewType { constructor(date: DateTime) { super() this.start = date.startOf('week').startOf('day'); this.viewDuration = this.start.plus({ days: 4 * 7 - 1 }).endOf('day').diff(this.start).as('seconds'); this.cellWidth = this.viewDuration / (4 * 7); } override setToday(): void { this.start = DateTime.now().startOf('week').startOf('day'); } override calculateIntervalShift(action: "next" | "back"): void { if (action === 'next') this.start = this.start.plus({ weeks: 2 }); else this.start = this.start.minus({ weeks: 2 }); } override createDescriptorSet(): DescriptorSet { return { interval: this.createIntervals(), cell: this.createCells(), tick: this.createTicks() } }; // get duration of a day in seconds dayDuration(): number { return 24 * 3600; }; private createIntervals(): IntervalDescriptor[] { return Array.from({ length: 4 }, (_, i) => { return { title: `KW ${this.start.plus({ weeks: i }).get('weekNumber')}`, width: i === 3 ? '0px' : this.durationToWidth(this.start.endOf('week').diff(this.start).as('seconds')) } }) } private createCells(): CellDescriptor[] { return Array.from({ length: 4 * 7 }, (_, day) => { let date = this.start.plus({ days: day }); const duration = this.dayDuration(); const sunOrHoliday = this.isDaySunOrHoliday(date); const weekend = this.isDayOnWeekend(date); return { title: date.toFormat('dd.MM'), subTitle: date.toFormat('EEE'), width: this.durationToWidth(duration), firstTickOffset: '0px', sunOrHoliday, weekend, available: defaultAvailable.filter(item => ((!weekend && !sunOrHoliday) || (weekend && !sunOrHoliday) && item.onSaturday) || (sunOrHoliday && item.onSunOrHoliday)).map(item => { return { offset: this.getOffset(date.startOf('day').plus({ seconds: item.start_day_sec })), duration: this.durationToWidth(item.duration_sec) } }) } }); } private createTicks(): TickDescriptor[] { // TODO make calculation more sane!!! let test = Math.floor(24 / Math.ceil((1.2 * 0.8 * this.globalBaseFontSize) / (this.dayDuration() * this.pixelPerSecond / 24))); return Array.from({ length: test }, (_, i) => i * 24 / test).map(item => { return { title: item.toString(), width: this.durationToWidth(24 / test * 3600) } }); } }