import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget"; import {FormControlMixin} from "@lion/form-core"; import {classMap, css, html, ifDefined, LitElement, render, TemplateResult} from "@lion/core"; import shoelace from "../Styles/shoelace"; import {dateStyles} from "./DateStyles"; import flatpickr from "flatpickr"; import "flatpickr/dist/plugins/rangePlugin"; import {Et2Date, formatDate, parseDate} from "./Et2Date"; import {egw} from "../../jsapi/egw_global"; /** * Display a time duration (eg: 3 days, 6 hours) * * If not specified, the time is in assumed to be minutes and will be displayed with a calculated unit * but this can be specified with the properties. */ export class Et2DateRange extends Et2InputWidget(FormControlMixin(LitElement)) { static get styles() { return [ ...super.styles, shoelace, ...dateStyles, css` .input-group { display: flex; flex-direction: row; flex-wrap: nowrap; align-items: baseline; } `, ]; } static get properties() { return { ...super.properties, /** * Is the date range relative (this week) or absolute (2016-02-15 - 2016-02-21). This will affect the value returned. */ relative: {type: Boolean}, /** * An object with keys 'from' and 'to' for absolute ranges, or a relative range string */ value: {type: Object} } } constructor() { super(); } getUpdateComplete() { const p = super.getUpdateComplete(); if(!this.relative) { p.then(() => this.setupFlatpickr()); } return p; } protected setupFlatpickr() { if(!this.fromElement || !this.fromElement._inputElement) return; this.fromElement._instance = flatpickr((this.fromElement).findInputField(), { ...(this.fromElement).getOptions(), ...{ plugins: [ // @ts-ignore ts can't find rangePlugin in IDE rangePlugin({ input: this.toElement }) ] } }); } render() { const hasLabel = this.label ? true : false const hasHelpText = this.helpText ? true : false; return html`
${this._inputGroupTemplate()}
${this.helpText}
`; } protected _inputGroupTemplate() : TemplateResult { return html` ${this.relative ? this._inputRelativeTemplate() : this._inputAbsoluteTemplate()} `; } /** * We're doing a relative date range, show the relative options * @returns {TemplateResult} * @protected */ protected _inputRelativeTemplate() : TemplateResult { return html``; } /** * We're doing an absolute date range, we need start and end dates * * @returns {TemplateResult} * @protected */ protected _inputAbsoluteTemplate() : TemplateResult { return html` `; } public get fromElement() : HTMLElement { return this.shadowRoot?.querySelector("[name='from']"); } public get toElement() : HTMLElement { return this.shadowRoot?.querySelector("[name='to']"); } public get relativeElement() : HTMLElement { return this.shadowRoot?.querySelector("[name='relative']"); } public get value() : {to:string,from:string}|string { if(this.relative) { return this.relativeElement?.value || ""; } let val = { from: this.fromElement?.findInputField()?.value || null, to: this.toElement?.value || null } if(val.from) val.from = formatDate(parseDate(val.from), {dateFormat:"Y-m-dT00:00:00Z"}); if(val.to) val.to = formatDate(parseDate(val.to), {dateFormat:"Y-m-dT00:00:00Z"}); return (val.from || val.to) ? val : null; } public set value(new_value : {to:string,from:string}|string) { if(this.relative) { this.relativeElement.value = new_value; } else if (this.fromElement && this.toElement) { this.fromElement._instance.setDate( [new_value?.from, new_value?.to],true); } } // Class Constants static readonly relative_dates = [ // Start and end are relative offsets, see et2_date.set_min() // or Date objects { value: 'Today', label: egw.lang('Today'), from(date) {return date;}, to(date) {return date;} }, { label: egw.lang('Yesterday'), value: 'Yesterday', from(date) { date.setUTCDate(date.getUTCDate() - 1); return date; }, to: '' }, { label: egw.lang('This week'), value: 'This week', from(date) {return egw.week_start(date);}, to(date) { date.setUTCDate(date.getUTCDate() + 6); return date; } }, { label: egw.lang('Last week'), value: 'Last week', from(date) { var d = egw.week_start(date); d.setUTCDate(d.getUTCDate() - 7); return d; }, to(date) { date.setUTCDate(date.getUTCDate() + 6); return date; } }, { label: egw.lang('This month'), value: 'This month', from(date) { date.setUTCDate(1); return date; }, to(date) { date.setUTCMonth(date.getUTCMonth()+1); date.setUTCDate(0); return date; } }, { label: egw.lang('Last month'), value: 'Last month', from(date) { date.setUTCMonth(date.getUTCMonth() - 1); date.setUTCDate(1); return date; }, to(date) { date.setUTCMonth(date.getUTCMonth()+1); date.setUTCDate(0); return date; } }, { label: egw.lang('Last 3 months'), value: 'Last 3 months', from(date) { date.setUTCMonth(date.getUTCMonth() - 2); date.setUTCDate(1); return date; }, to(date) { date.setUTCMonth(date.getUTCMonth()+3); date.setUTCDate(0); return date; } }, { label: egw.lang('This year'), value: 'This year', from(d) { d.setUTCMonth(0); d.setUTCDate(1); return d; }, to(d) { d.setUTCMonth(11); d.setUTCDate(31); return d; } }, { label: egw.lang('Last year'), value: 'Last year', from(d) { d.setUTCMonth(0); d.setUTCDate(1); d.setUTCYear(d.getUTCYear() - 1); return d; }, to(d) { d.setUTCMonth(11); d.setUTCDate(31); d.setUTCYear(d.getUTCYear() - 1); return d; } } ]; } customElements.define("et2-date-range", Et2DateRange);