Moment.js has a large bundle size and it causes a performance overhead. Change-Id: Ida5c2642006d5018300527cb2b5eaab3c61772d2
241 lines
6.4 KiB
JavaScript
241 lines
6.4 KiB
JavaScript
/**
|
|
* @license
|
|
* Copyright (C) 2015 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
import '../gr-rest-api-interface/gr-rest-api-interface.js';
|
|
import '../../../styles/shared-styles.js';
|
|
import {mixinBehaviors} from '@polymer/polymer/lib/legacy/class.js';
|
|
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
|
|
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
|
|
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
|
|
import {htmlTemplate} from './gr-date-formatter_html.js';
|
|
import {TooltipBehavior} from '../../../behaviors/gr-tooltip-behavior/gr-tooltip-behavior.js';
|
|
import {parseDate, fromNow, isValidDate, isWithinDay, isWithinHalfYear, formatDate, utcOffsetString} from '../../../utils/date-util.js';
|
|
|
|
const TimeFormats = {
|
|
TIME_12: 'h:mm A', // 2:14 PM
|
|
TIME_12_WITH_SEC: 'h:mm:ss A', // 2:14:00 PM
|
|
TIME_24: 'HH:mm', // 14:14
|
|
TIME_24_WITH_SEC: 'HH:mm:ss', // 14:14:00
|
|
};
|
|
|
|
const DateFormats = {
|
|
STD: {
|
|
short: 'MMM DD', // Aug 29
|
|
full: 'MMM DD, YYYY', // Aug 29, 1997
|
|
},
|
|
US: {
|
|
short: 'MM/DD', // 08/29
|
|
full: 'MM/DD/YY', // 08/29/97
|
|
},
|
|
ISO: {
|
|
short: 'MM-DD', // 08-29
|
|
full: 'YYYY-MM-DD', // 1997-08-29
|
|
},
|
|
EURO: {
|
|
short: 'DD. MMM', // 29. Aug
|
|
full: 'DD.MM.YYYY', // 29.08.1997
|
|
},
|
|
UK: {
|
|
short: 'DD/MM', // 29/08
|
|
full: 'DD/MM/YYYY', // 29/08/1997
|
|
},
|
|
};
|
|
|
|
/**
|
|
* @extends PolymerElement
|
|
*/
|
|
class GrDateFormatter extends mixinBehaviors( [
|
|
TooltipBehavior,
|
|
], GestureEventListeners(
|
|
LegacyElementMixin(
|
|
PolymerElement))) {
|
|
static get template() { return htmlTemplate; }
|
|
|
|
static get is() { return 'gr-date-formatter'; }
|
|
|
|
static get properties() {
|
|
return {
|
|
dateStr: {
|
|
type: String,
|
|
value: null,
|
|
notify: true,
|
|
},
|
|
showDateAndTime: {
|
|
type: Boolean,
|
|
value: false,
|
|
},
|
|
|
|
/**
|
|
* When true, the detailed date appears in a GR-TOOLTIP rather than in the
|
|
* native browser tooltip.
|
|
*/
|
|
hasTooltip: Boolean,
|
|
|
|
/**
|
|
* The title to be used as the native tooltip or by the tooltip behavior.
|
|
*/
|
|
title: {
|
|
type: String,
|
|
reflectToAttribute: true,
|
|
computed: '_computeFullDateStr(dateStr, _timeFormat, _dateFormat)',
|
|
},
|
|
|
|
/** @type {?{short: string, full: string}} */
|
|
_dateFormat: Object,
|
|
_timeFormat: String, // No default value to prevent flickering.
|
|
_relative: Boolean, // No default value to prevent flickering.
|
|
};
|
|
}
|
|
|
|
constructor() {
|
|
super();
|
|
}
|
|
|
|
/** @override */
|
|
attached() {
|
|
super.attached();
|
|
this._loadPreferences();
|
|
}
|
|
|
|
_getUtcOffsetString() {
|
|
return utcOffsetString();
|
|
}
|
|
|
|
_loadPreferences() {
|
|
return this._getLoggedIn().then(loggedIn => {
|
|
if (!loggedIn) {
|
|
this._timeFormat = TimeFormats.TIME_24;
|
|
this._dateFormat = DateFormats.STD;
|
|
this._relative = false;
|
|
return;
|
|
}
|
|
return Promise.all([
|
|
this._loadTimeFormat(),
|
|
this._loadRelative(),
|
|
]);
|
|
});
|
|
}
|
|
|
|
_loadTimeFormat() {
|
|
return this._getPreferences().then(preferences => {
|
|
const timeFormat = preferences && preferences.time_format;
|
|
const dateFormat = preferences && preferences.date_format;
|
|
this._decideTimeFormat(timeFormat);
|
|
this._decideDateFormat(dateFormat);
|
|
});
|
|
}
|
|
|
|
_decideTimeFormat(timeFormat) {
|
|
switch (timeFormat) {
|
|
case 'HHMM_12':
|
|
this._timeFormat = TimeFormats.TIME_12;
|
|
break;
|
|
case 'HHMM_24':
|
|
this._timeFormat = TimeFormats.TIME_24;
|
|
break;
|
|
default:
|
|
throw Error('Invalid time format: ' + timeFormat);
|
|
}
|
|
}
|
|
|
|
_decideDateFormat(dateFormat) {
|
|
switch (dateFormat) {
|
|
case 'STD':
|
|
this._dateFormat = DateFormats.STD;
|
|
break;
|
|
case 'US':
|
|
this._dateFormat = DateFormats.US;
|
|
break;
|
|
case 'ISO':
|
|
this._dateFormat = DateFormats.ISO;
|
|
break;
|
|
case 'EURO':
|
|
this._dateFormat = DateFormats.EURO;
|
|
break;
|
|
case 'UK':
|
|
this._dateFormat = DateFormats.UK;
|
|
break;
|
|
default:
|
|
throw Error('Invalid date format: ' + dateFormat);
|
|
}
|
|
}
|
|
|
|
_loadRelative() {
|
|
return this._getPreferences().then(prefs => {
|
|
// prefs.relative_date_in_change_table is not set when false.
|
|
this._relative = !!(prefs && prefs.relative_date_in_change_table);
|
|
});
|
|
}
|
|
|
|
_getLoggedIn() {
|
|
return this.$.restAPI.getLoggedIn();
|
|
}
|
|
|
|
_getPreferences() {
|
|
return this.$.restAPI.getPreferences();
|
|
}
|
|
|
|
_computeDateStr(
|
|
dateStr, timeFormat, dateFormat, relative, showDateAndTime
|
|
) {
|
|
if (!dateStr || !timeFormat || !dateFormat) { return ''; }
|
|
const date = parseDate(dateStr);
|
|
if (!isValidDate(date)) { return ''; }
|
|
if (relative) {
|
|
return fromNow(date);
|
|
}
|
|
const now = new Date();
|
|
let format = dateFormat.full;
|
|
if (isWithinDay(now, date)) {
|
|
format = timeFormat;
|
|
} else {
|
|
if (isWithinHalfYear(now, date)) {
|
|
format = dateFormat.short;
|
|
}
|
|
if (this.showDateAndTime) {
|
|
format = `${format} ${timeFormat}`;
|
|
}
|
|
}
|
|
return formatDate(date, format);
|
|
}
|
|
|
|
_timeToSecondsFormat(timeFormat) {
|
|
return timeFormat === TimeFormats.TIME_12 ?
|
|
TimeFormats.TIME_12_WITH_SEC :
|
|
TimeFormats.TIME_24_WITH_SEC;
|
|
}
|
|
|
|
_computeFullDateStr(dateStr, timeFormat, dateFormat) {
|
|
// Polymer 2: check for undefined
|
|
if ([
|
|
dateStr,
|
|
timeFormat,
|
|
dateFormat,
|
|
].some(arg => arg === undefined)) {
|
|
return undefined;
|
|
}
|
|
|
|
if (!dateStr) { return ''; }
|
|
const date = parseDate(dateStr);
|
|
if (!isValidDate(date)) { return ''; }
|
|
let format = dateFormat.full + ', ';
|
|
format += this._timeToSecondsFormat(timeFormat);
|
|
return formatDate(date, format) + this._getUtcOffsetString();
|
|
}
|
|
}
|
|
|
|
customElements.define(GrDateFormatter.is, GrDateFormatter);
|