import m from 'mithril'; import './calendar.style.css'; import { Component, ComponentAttributes } from '../common/Component'; import { Toolbar } from '../toolbar/Toolbar'; import { Space } from '../controls/space/Space'; import { Button } from '..'; import { addDaysToDate, addMonthsToDate, addYearsToDate, compareDatesByYearAndMonth, compareDatesIgnoringTime, getFirstDayOfMonth, getFirstDayOfWeek, getWeekNumber } from '../tools/Date'; import classNames from 'classnames'; import { getGlobalConfig } from '../tools/Global'; declare type ViewType = 'years' | 'months' | 'days'; declare type CalendarAttributes = ComponentAttributes & { value?: Date; focusOnDate?: Date; view?: ViewType; showWeekNumbers?: boolean; showWeekdayShortcuts?: boolean; }; declare type CalendarEventTypes = { change: (value: Date | undefined) => void; }; export class Calendar extends Component { private _toolbarTop: Toolbar; private _toolbarBottom: Toolbar; private _yearsOnPage = 16; constructor(attrs?: CalendarAttributes) { super(attrs); const { prev, next, today, clear } = getGlobalConfig().i18n.calendar; this._toolbarTop = new Toolbar({ items: [ new Button({ id: 'current_view', text: 'Sierpień', style: 'plain', events: { click: () => { switch(this._getView()) { case 'days': { this.setView('months'); break; } case 'months': { this.setView('years'); break; } default: { break; } } } } }), new Space(), new Button({ icon: 'icon-left-open', size: 'small', round: true, color: 'secondary', style: 'plain', tooltip: prev, events: { click: () => { this.prevPage(); } } }), new Button({ icon: 'icon-right-open', size: 'small', round: true, color: 'secondary', style: 'plain', tooltip: next, events: { click: () => { this.nextPage(); } } }), ] }); this._toolbarBottom = new Toolbar({ items: [ new Space(), new Button({ text: today, size: 'small', style: 'plain', events: { click: () => { this.setValue(new Date()); this.setView('days'); this.setFocusDate(new Date()); } } }), new Button({ text: clear, size: 'small', style: 'plain', events: { click: () => { this.clear(); } } }), ] }); this._updateCurrentViewButton(); } view(): m.Children | m.Vnode { let view; switch(this._getView()) { case 'days': { view = this._getDaysView(); break; } case 'months': { view = this._getMonthsView(); break; } case 'years': { view = this._getYearsView(); break; } } return m('div.webcraft_calendar', [ this._toolbarTop.view(), view, this._toolbarBottom.view(), ]); } clear(): void { this.setValue(undefined); } setValue(value: Date | undefined): void { const time = value?.getTime(); if (this.attrs.value === value || (typeof time === 'number' && isNaN(time))) { return; } this.attrs.value = value; this._updateCurrentViewButton(); this.events.emit('change', this.attrs.value); m.redraw(); } getValue(): Date | undefined { return this.attrs.value; } prevPage(): void { const focusDate = this._getFocusDate(); switch(this._getView()) { case 'years': { this.setFocusDate(addYearsToDate(focusDate, -this._yearsOnPage)); break; } case 'months': { this.setFocusDate(addYearsToDate(focusDate, - 1)); break; } default: { this.setFocusDate(addMonthsToDate(focusDate, - 1)); break; } } } nextPage(): void { const focusDate = this._getFocusDate(); switch(this._getView()) { case 'years': { this.setFocusDate(addYearsToDate(focusDate, this._yearsOnPage)); break; } case 'months': { this.setFocusDate(addYearsToDate(focusDate, + 1)); break; } default: { this.setFocusDate(addMonthsToDate(focusDate, + 1)); break; } } } setFocusDate(date: Date): void { this.attrs.focusOnDate = date; this._updateCurrentViewButton(); m.redraw(); } private setView(view: ViewType): void { this.attrs.view = view; this._updateCurrentViewButton(); m.redraw(); } private _getView(): ViewType { return this.attrs.view || 'days'; } private _updateCurrentViewButton(): void { const focusDate = this._getFocusDate(); let text; switch(this._getView()) { case 'years': { text = `${focusDate.getFullYear() - (this._yearsOnPage / 2)}-${focusDate.getFullYear() + (this._yearsOnPage / 2) - 1}`; break; } case 'months': { text = `${focusDate.getFullYear()}`; break; } default: { text = `${getGlobalConfig().i18n.calendar.months[focusDate.getMonth()]} ${focusDate.getFullYear()}`; break; } } this._toolbarTop.getItem