Neovici/cosmoz-omnitable

View on GitHub
lib/cosmoz-omnitable-time-range-input.js

Summary

Maintainability
A
2 hrs
Test Coverage
B
87%
import { _ } from '@neovici/cosmoz-i18next';
import { PolymerElement } from '@polymer/polymer';
import { html } from 'lit-html';
import { ifDefined } from 'lit-html/directives/if-defined.js';
import '@neovici/cosmoz-input';
import { dateInputMixin } from './cosmoz-omnitable-date-input-mixin';
import { polymerHauntedRender } from './polymer-haunted-render-mixin';

class TimeRangeInput extends dateInputMixin(polymerHauntedRender(PolymerElement)) {
    // eslint-disable-next-line max-lines-per-function
    render() {
        return html`
            <style>
                paper-dropdown-menu {
                    --iron-icon-width: 0;
                    display: block;
                }
            </style>

            <cosmoz-clear-button @click=${ () => this.resetFilter() } ?visible=${ this.hasFilter() }></cosmoz-clear-button>
            <paper-dropdown-menu
                label=${ this.title }
                placeholder=${ ifDefined(this._filterText) }
                class="external-values-${ this.externalValues }"
                title=${ this._tooltip }
                horizontal-align="right"
                ?opened=${ this.headerFocused }
                @opened-changed=${ event => this.set('headerFocused', event.detail.value) }>
            >
                <div class="dropdown-content" slot="dropdown-content" style="padding: 15px; min-width: 100px;">
                    <h3 style="margin: 0;">${ this.title }</h3>
                    <cosmoz-input
                        type="time"
                        label=${ _('From time') }
                        step=${ this.filterStep }
                        .value=${ this._filterInput.min }
                        @value-changed=${ event => this.set('_filterInput.min', event.detail.value) }
                    ></cosmoz-input>
                    <cosmoz-input
                        type="time"
                        label=${ _('Until time') }
                        step=${ this.filterStep }
                        .value=${ this._filterInput.max }
                        @value-changed=${ event => this.set('_filterInput.max', event.detail.value) }
                    ></cosmoz-input>
                </div>
            </paper-dropdown-menu>
        `;
    }

    get _fixedDate() {
        return '1970-01-01';
    }

    /**
     * Converts time to date optionaly limiting it.
     *
     * @param     {Date|Number} value     Date or Timestamp ( miliseconds since property _fixedDate ) to be converted
     * @param     {Date|Number} limit     Optional value to limit the date.
     * @param     {Function} limitFunc     Function used to limit the date (Math.min|Math.max)
     * @returns {Date|void}                     Value converted to date optionaly limitated
     */
    toDate(value, limit, limitFunc) {
        // Most browsers use local timezone when no timezone is specified
        // but Safari uses UTC, so we set it implicitly
        // TODO: Consider removing this when/if Safari handles local timezone correctly
        const date = typeof value === 'string' && value.length > 3 && value.length <= 9
            ? this.getAbsoluteISOString(this._fixedDate + 'T' + value)
            : value;
        return super.toDate(date, limit, limitFunc);
    }

    _toInputString(value) {
        const date = this.toValue(value);
        if (date == null) {
            return null;
        }
        return this._toLocalISOString(date).slice(11, 19);
    }
    /**
     *     Get the comparable value of an item.
     *
     * @param     {Object} item             Item to be processed
     * @param     {String} valuePath     Property path
     * @returns {Number|void}             Valid value or void
     */
    getComparableValue(item, valuePath) {
        if (item == null) {
            return;
        }
        let value = this._toInputString(valuePath == null ? item : this.get(valuePath, item));
        if (value == null) {
            return;
        }
        value = this.toValue(this.getAbsoluteISOString(this._fixedDate + 'T' + value));
        if (value == null) {
            return;
        }
        return this.toNumber(value.getTime());
    }

    _timeValueChanged(e) {
        const input = e.target,
            timeString = input.value,
            item = e.model.item,
            oldTime = this.toDate(item.date),
            newTime = this.toDate(oldTime != null
                ? oldTime.toISOString().slice(0, 10) + 'T' + timeString
                : timeString),
            formatFn = value => value;
        if (newTime != null) {
            return;
        }
        this.set(this.valuePath, newTime, item);
        this._fireItemChangeEvent(item, this.valuePath, oldTime, formatFn.bind(this));
    }

    // OVERRIDES

    _computeFormatter(locale) {
        const timeFormatOption = {
            hour: 'numeric',
            minute: 'numeric',
            second: 'numeric'
        };
        return new Intl.DateTimeFormat(locale || undefined, timeFormatOption);
    }
}


customElements.define('cosmoz-omnitable-time-range-input', TimeRangeInput);