2022-01-21 21:45:12 +01:00
|
|
|
/**
|
|
|
|
* EGroupware eTemplate2 - Readonly time since WebComponent
|
|
|
|
*
|
|
|
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
|
|
|
* @package api
|
|
|
|
* @link https://www.egroupware.org
|
|
|
|
* @author Nathan Gray
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
import {html} from "@lion/core";
|
|
|
|
import {parseDate, parseDateTime} from "./Et2Date";
|
|
|
|
import {Et2DateReadonly} from "./Et2DateReadonly";
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Formatter for time since widget.
|
|
|
|
*
|
|
|
|
* @param {Date} date
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
|
|
|
const formatDate = function(date : Date, options = {units: "YmdHis"})
|
|
|
|
{
|
|
|
|
const unit2label = {
|
|
|
|
'Y': 'years',
|
|
|
|
'm': 'month',
|
|
|
|
'd': 'days',
|
|
|
|
'H': 'hours',
|
|
|
|
'i': 'minutes',
|
|
|
|
's': 'seconds'
|
|
|
|
};
|
|
|
|
let unit2s : Object = {
|
|
|
|
'Y': 31536000,
|
|
|
|
'm': 2628000,
|
|
|
|
'd': 86400,
|
|
|
|
'H': 3600,
|
|
|
|
'i': 60,
|
|
|
|
's': 1
|
|
|
|
};
|
|
|
|
var d = new Date();
|
2022-05-05 11:38:33 +02:00
|
|
|
var diff = Math.round(d.valueOf() / 1000) - Math.round(date.valueOf() / 1000 + egw.getTimezoneOffset() * 60);
|
2022-01-21 21:45:12 +01:00
|
|
|
let display = '';
|
|
|
|
|
|
|
|
// limit units used to display
|
|
|
|
let smallest = 's';
|
|
|
|
if(options.units)
|
|
|
|
{
|
|
|
|
const valid = Object.entries(unit2s).filter((e) => (<string>options.units).includes(e[0]));
|
|
|
|
unit2s = Object.fromEntries(valid);
|
|
|
|
smallest = (valid.pop() || [])[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
for(var unit in unit2s)
|
|
|
|
{
|
|
|
|
var unit_s = unit2s[unit];
|
|
|
|
if(diff >= unit_s || unit === smallest)
|
|
|
|
{
|
|
|
|
display = Math.round(diff / unit_s) + ' ' + this.egw().lang(unit2label[unit]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return display;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Displays the elapsed time since the given date
|
|
|
|
*
|
|
|
|
* The time units (years, months, days, etc) will be calculated automatically to best match the
|
|
|
|
* time scale being dealt with, unless the units property is set.
|
|
|
|
*
|
|
|
|
* This is a stripped-down read-only widget used in nextmatch
|
|
|
|
*/
|
|
|
|
export class Et2DateSinceReadonly extends Et2DateReadonly
|
|
|
|
{
|
|
|
|
static get properties()
|
|
|
|
{
|
|
|
|
return {
|
|
|
|
...super.properties,
|
|
|
|
/**
|
|
|
|
* Allowed display units, default 'YmdHis', e.g. 'd' to display a value only in days"
|
|
|
|
*/
|
|
|
|
units: {type: String, reflect: true},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
constructor()
|
|
|
|
{
|
|
|
|
super();
|
|
|
|
|
|
|
|
this.parser = parseDateTime;
|
|
|
|
this.formatter = formatDate;
|
|
|
|
}
|
|
|
|
|
|
|
|
set_value(value)
|
|
|
|
{
|
|
|
|
this.value = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
render()
|
|
|
|
{
|
|
|
|
let parsed : Date | Boolean = this.value ? this.parser(this.value) : false
|
|
|
|
|
|
|
|
// Be more forgiving if time is missing
|
|
|
|
if(!parsed && this.value)
|
|
|
|
{
|
|
|
|
parsed = parseDate(this.value) || false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return html`
|
|
|
|
<span ${this.id ? html`id="${this._dom_id}"` : ''}
|
|
|
|
datetime="${parsed ? (<Date>parsed).toJSON() : ""}">
|
|
|
|
${this.value ? this.formatter(<Date>parsed, {units: this.units}) : ''}
|
|
|
|
</span>
|
|
|
|
`;
|
|
|
|
}
|
|
|
|
|
|
|
|
getDetachedAttributes(attrs)
|
|
|
|
{
|
|
|
|
attrs.push("id", "value", "class");
|
|
|
|
}
|
|
|
|
|
|
|
|
getDetachedNodes() : HTMLElement[]
|
|
|
|
{
|
|
|
|
return [<HTMLElement><unknown>this];
|
|
|
|
}
|
|
|
|
|
|
|
|
setDetachedAttributes(_nodes : HTMLElement[], _values : object, _data? : any) : void
|
|
|
|
{
|
|
|
|
// Do nothing, since we can't actually stop being a DOM node...
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
|
2022-01-22 10:01:24 +01:00
|
|
|
customElements.define("et2-date-since", Et2DateSinceReadonly);
|