2022-01-04 23:38:10 +01:00
|
|
|
/**
|
|
|
|
* EGroupware eTemplate2 - Readonly select WebComponent
|
|
|
|
*
|
|
|
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
|
|
|
* @package api
|
|
|
|
* @link https://www.egroupware.org
|
|
|
|
* @author Nathan Gray
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2022-01-19 21:17:07 +01:00
|
|
|
import {css, html, LitElement, repeat, TemplateResult} from "@lion/core";
|
2022-01-04 23:38:10 +01:00
|
|
|
import {et2_IDetachedDOM} from "../et2_core_interfaces";
|
|
|
|
import {Et2Widget} from "../Et2Widget/Et2Widget";
|
|
|
|
import {find_select_options, SelectOption} from "./Et2Select";
|
2022-01-13 23:28:52 +01:00
|
|
|
import {StaticOptions} from "./StaticOptions";
|
|
|
|
|
|
|
|
const so = new StaticOptions();
|
2022-01-04 23:38:10 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This is a stripped-down read-only widget used in nextmatch
|
|
|
|
* (and other read-only usages)
|
|
|
|
*/
|
|
|
|
export class Et2SelectReadonly extends Et2Widget(LitElement) implements et2_IDetachedDOM
|
|
|
|
{
|
|
|
|
static get styles()
|
|
|
|
{
|
|
|
|
return [
|
2022-01-19 21:17:07 +01:00
|
|
|
...super.styles,
|
|
|
|
css`
|
|
|
|
ul {
|
|
|
|
margin: 0px;
|
|
|
|
padding: 0px;
|
|
|
|
display: inline-block;
|
|
|
|
}
|
|
|
|
|
|
|
|
li {
|
|
|
|
text-decoration: none;
|
|
|
|
list-style-image: none;
|
|
|
|
list-style-type: none;
|
|
|
|
}
|
|
|
|
`
|
2022-01-04 23:38:10 +01:00
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
static get properties()
|
|
|
|
{
|
|
|
|
return {
|
|
|
|
...super.properties,
|
|
|
|
value: String,
|
2022-02-18 00:37:59 +01:00
|
|
|
select_options: Array
|
2022-01-04 23:38:10 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
constructor()
|
|
|
|
{
|
|
|
|
super();
|
2022-01-13 23:28:52 +01:00
|
|
|
this.type = "";
|
2022-02-18 00:37:59 +01:00
|
|
|
this.select_options = [];
|
2022-01-13 23:28:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected find_select_options(_attrs)
|
|
|
|
{
|
2022-02-18 00:37:59 +01:00
|
|
|
let sel_options = find_select_options(this, _attrs['select_options']);
|
2022-01-13 23:28:52 +01:00
|
|
|
if(sel_options.length > 0)
|
|
|
|
{
|
|
|
|
this.set_select_options(sel_options);
|
|
|
|
}
|
2022-01-04 23:38:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
transformAttributes(_attrs)
|
|
|
|
{
|
2022-01-05 21:14:28 +01:00
|
|
|
/*
|
|
|
|
TODO: Check with more / different nextmatch data to see if this becomes faster.
|
|
|
|
Currently it's faster for the nextmatch to re-do transformAttributes() and find_select_options()
|
|
|
|
on every row than it is to use widget.clone()
|
|
|
|
|
|
|
|
// If there's no parent, there's a good chance we're in a nextmatch row so skip the transform
|
|
|
|
if(!this.getParent())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
2022-01-04 23:38:10 +01:00
|
|
|
super.transformAttributes(_attrs);
|
|
|
|
|
2022-01-13 23:28:52 +01:00
|
|
|
this.find_select_options(_attrs)
|
2022-01-04 23:38:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
set_value(value)
|
|
|
|
{
|
2022-02-07 21:49:50 +01:00
|
|
|
this.value = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
set value(new_value)
|
|
|
|
{
|
|
|
|
// Split anything that is still a CSV
|
|
|
|
if(typeof new_value == "string" && new_value.indexOf(",") > 0)
|
2022-01-19 21:17:07 +01:00
|
|
|
{
|
2022-02-07 21:49:50 +01:00
|
|
|
new_value = new_value.split(",");
|
2022-01-19 21:17:07 +01:00
|
|
|
}
|
2022-02-07 21:49:50 +01:00
|
|
|
// Wrap any single value into an array for consistent rendering
|
|
|
|
if(typeof new_value == "string" || typeof new_value == "number")
|
|
|
|
{
|
|
|
|
new_value = ["" + new_value];
|
|
|
|
}
|
|
|
|
|
|
|
|
super.value = new_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
get value()
|
|
|
|
{
|
|
|
|
return super.value;
|
2022-01-04 23:38:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the select options
|
|
|
|
*
|
|
|
|
* @param {SelectOption[]} new_options
|
|
|
|
*/
|
|
|
|
set_select_options(new_options : SelectOption[] | { [key : string] : string })
|
|
|
|
{
|
|
|
|
if(!Array.isArray(new_options))
|
|
|
|
{
|
|
|
|
let fixed_options : SelectOption[] = [];
|
|
|
|
for(let key in new_options)
|
|
|
|
{
|
|
|
|
fixed_options.push(<SelectOption>{value: key, label: new_options[key]});
|
|
|
|
}
|
|
|
|
console.warn(this.id + " passed a key => value map instead of array");
|
2022-02-18 00:37:59 +01:00
|
|
|
this.select_options = fixed_options;
|
2022-01-04 23:38:10 +01:00
|
|
|
return;
|
|
|
|
}
|
2022-02-18 00:37:59 +01:00
|
|
|
this.select_options = new_options;
|
2022-01-04 23:38:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
render()
|
|
|
|
{
|
2022-01-19 21:17:07 +01:00
|
|
|
if(!this.value)
|
2022-01-17 23:12:46 +01:00
|
|
|
{
|
2022-02-18 00:37:59 +01:00
|
|
|
return this._readonlyRender({label: this.empty_label, value: ""});
|
2022-01-17 23:12:46 +01:00
|
|
|
}
|
|
|
|
|
2022-01-19 21:17:07 +01:00
|
|
|
return html`
|
|
|
|
<ul>
|
|
|
|
${repeat(this.value, (val : string) => val, (val) =>
|
|
|
|
{
|
2022-02-18 00:37:59 +01:00
|
|
|
let option = this.select_options.find(option => option.value == val);
|
2022-01-19 21:17:07 +01:00
|
|
|
if(!option)
|
|
|
|
{
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
return this._readonlyRender(option);
|
|
|
|
})}
|
|
|
|
</ul>
|
|
|
|
`;
|
2022-01-17 23:12:46 +01:00
|
|
|
}
|
2022-01-04 23:38:10 +01:00
|
|
|
|
2022-01-19 21:17:07 +01:00
|
|
|
_readonlyRender(option : SelectOption) : TemplateResult
|
2022-01-17 23:12:46 +01:00
|
|
|
{
|
2022-01-04 23:38:10 +01:00
|
|
|
return html`
|
2022-01-19 21:17:07 +01:00
|
|
|
<li>${option.label}</li>
|
2022-01-04 23:38:10 +01:00
|
|
|
`;
|
|
|
|
}
|
|
|
|
|
|
|
|
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...
|
|
|
|
}
|
|
|
|
|
|
|
|
loadFromXML()
|
|
|
|
{
|
|
|
|
// nope
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
|
2022-01-13 23:28:52 +01:00
|
|
|
customElements.define("et2-select_ro", Et2SelectReadonly);
|
|
|
|
|
2022-01-19 21:17:07 +01:00
|
|
|
export class Et2SelectAccountReadonly extends Et2SelectReadonly
|
|
|
|
{
|
|
|
|
set value(new_value)
|
|
|
|
{
|
|
|
|
if(!new_value)
|
|
|
|
{
|
|
|
|
super.value = new_value;
|
|
|
|
return;
|
|
|
|
}
|
2022-02-16 09:35:09 +01:00
|
|
|
// fix scalar (number or string) values
|
|
|
|
if (typeof new_value !== 'object')
|
|
|
|
{
|
|
|
|
new_value = [new_value];
|
|
|
|
}
|
2022-01-19 21:17:07 +01:00
|
|
|
for(let id of new_value)
|
|
|
|
{
|
|
|
|
let account_name = null;
|
|
|
|
let option = <SelectOption>{value: id, label: id + " ..."};
|
2022-02-18 00:37:59 +01:00
|
|
|
this.select_options.push(option);
|
2022-01-19 21:17:07 +01:00
|
|
|
if(new_value && (account_name = this.egw().link_title('api-accounts', id)))
|
|
|
|
{
|
|
|
|
option.label = account_name;
|
|
|
|
}
|
|
|
|
else if(!account_name)
|
|
|
|
{
|
|
|
|
// Not already cached, need to fetch it
|
|
|
|
this.egw().link_title('api-accounts', id, function(title)
|
|
|
|
{
|
|
|
|
this.option.label = title;
|
|
|
|
this.select.requestUpdate();
|
|
|
|
}, {select: this, option: option});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
super.value = new_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
get value()
|
|
|
|
{
|
|
|
|
return super.value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
|
|
|
|
customElements.define("et2-select-account_ro", Et2SelectAccountReadonly);
|
|
|
|
|
2022-01-17 23:12:46 +01:00
|
|
|
export class Et2SelectAppReadonly extends Et2SelectReadonly
|
|
|
|
{
|
|
|
|
constructor()
|
|
|
|
{
|
|
|
|
super();
|
|
|
|
|
2022-02-18 00:37:59 +01:00
|
|
|
this.select_options = so.app(this, {other: this.other || []});
|
2022-01-17 23:12:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected find_select_options(_attrs) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
|
|
|
|
customElements.define("et2-select-app_ro", Et2SelectAppReadonly);
|
|
|
|
|
|
|
|
export class Et2SelectBitwiseReadonly extends Et2SelectReadonly
|
|
|
|
{
|
|
|
|
render()
|
|
|
|
{
|
|
|
|
let new_value = [];
|
2022-02-18 00:37:59 +01:00
|
|
|
for(let index in this.select_options)
|
2022-01-17 23:12:46 +01:00
|
|
|
{
|
2022-02-18 00:37:59 +01:00
|
|
|
let option = this.select_options[index];
|
2022-01-19 21:17:07 +01:00
|
|
|
let right = parseInt(option && option.value ? option.value : index);
|
2022-01-17 23:12:46 +01:00
|
|
|
if(!!(this.value & right))
|
|
|
|
{
|
|
|
|
new_value.push(right);
|
|
|
|
}
|
|
|
|
}
|
2022-01-19 21:17:07 +01:00
|
|
|
return html`
|
|
|
|
<ul>
|
|
|
|
${repeat(new_value, (val : string) => val, (val) =>
|
|
|
|
{
|
2022-02-18 00:37:59 +01:00
|
|
|
let option = this.select_options.find(option => option.value == val);
|
2022-01-19 21:17:07 +01:00
|
|
|
if(!option)
|
|
|
|
{
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
return this._readonlyRender(option);
|
|
|
|
})}
|
|
|
|
</ul>`;
|
2022-01-17 23:12:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
|
|
|
|
customElements.define("et2-select-bitwise_ro", Et2SelectBitwiseReadonly);
|
|
|
|
|
2022-01-13 23:28:52 +01:00
|
|
|
export class Et2SelectBoolReadonly extends Et2SelectReadonly
|
|
|
|
{
|
|
|
|
constructor()
|
|
|
|
{
|
|
|
|
super();
|
2022-02-18 00:37:59 +01:00
|
|
|
this.select_options = so.bool(this);
|
2022-01-13 23:28:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected find_select_options(_attrs) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
|
|
|
|
customElements.define("et2-select-bool_ro", Et2SelectBoolReadonly);
|
|
|
|
|
2022-01-14 17:29:14 +01:00
|
|
|
export class Et2SelectCategoryReadonly extends Et2SelectReadonly
|
|
|
|
{
|
|
|
|
constructor()
|
|
|
|
{
|
|
|
|
super();
|
|
|
|
|
2022-02-18 00:37:59 +01:00
|
|
|
this.select_options = so.cat(this, {other: this.other || []});
|
2022-01-14 17:29:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected find_select_options(_attrs) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
|
|
|
|
customElements.define("et2-select-cat_ro", Et2SelectCategoryReadonly);
|
2022-01-13 23:28:52 +01:00
|
|
|
|
|
|
|
export class Et2SelectPercentReadonly extends Et2SelectReadonly
|
|
|
|
{
|
|
|
|
constructor()
|
|
|
|
{
|
|
|
|
super();
|
2022-02-18 00:37:59 +01:00
|
|
|
this.select_options = so.percent(this, {});
|
2022-01-13 23:28:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected find_select_options(_attrs) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
|
2022-01-17 23:12:46 +01:00
|
|
|
customElements.define("et2-select-percent_ro", Et2SelectPercentReadonly);
|
|
|
|
|
|
|
|
export class Et2SelectCountryReadonly extends Et2SelectReadonly
|
|
|
|
{
|
|
|
|
constructor()
|
|
|
|
{
|
|
|
|
super();
|
2022-02-18 00:37:59 +01:00
|
|
|
this.select_options = so.country(this, {});
|
2022-01-17 23:12:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected find_select_options(_attrs) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
|
|
|
|
customElements.define("et2-select-country_ro", Et2SelectCountryReadonly);
|
|
|
|
|
|
|
|
export class Et2SelectDayReadonly extends Et2SelectReadonly
|
|
|
|
{
|
|
|
|
constructor()
|
|
|
|
{
|
|
|
|
super();
|
|
|
|
|
2022-02-18 00:37:59 +01:00
|
|
|
this.select_options = so.day(this, {other: this.other || []});
|
2022-01-17 23:12:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected find_select_options(_attrs) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
|
|
|
|
customElements.define("et2-select-day_ro", Et2SelectDayReadonly);
|
|
|
|
|
|
|
|
export class Et2SelectDayOfWeekReadonly extends Et2SelectReadonly
|
|
|
|
{
|
|
|
|
constructor()
|
|
|
|
{
|
|
|
|
super();
|
|
|
|
|
2022-02-18 00:37:59 +01:00
|
|
|
this.select_options = so.dow(this, {other: this.other || []});
|
2022-01-17 23:12:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected find_select_options(_attrs) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
|
|
|
|
customElements.define("et2-select-dow_ro", Et2SelectDayOfWeekReadonly);
|
|
|
|
|
|
|
|
export class Et2SelectHourReadonly extends Et2SelectReadonly
|
|
|
|
{
|
|
|
|
constructor()
|
|
|
|
{
|
|
|
|
super();
|
|
|
|
|
2022-02-18 00:37:59 +01:00
|
|
|
this.select_options = so.hour(this, {other: this.other || []});
|
2022-01-17 23:12:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected find_select_options(_attrs) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
|
|
|
|
customElements.define("et2-select-hour_ro", Et2SelectHourReadonly);
|
|
|
|
|
|
|
|
export class Et2SelectMonthReadonly extends Et2SelectReadonly
|
|
|
|
{
|
|
|
|
constructor()
|
|
|
|
{
|
|
|
|
super();
|
|
|
|
|
2022-02-18 00:37:59 +01:00
|
|
|
this.select_options = so.month(this);
|
2022-01-17 23:12:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected find_select_options(_attrs) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
|
|
|
|
customElements.define("et2-select-month_ro", Et2SelectMonthReadonly);
|
|
|
|
|
|
|
|
export class Et2SelectNumberReadonly extends Et2SelectReadonly
|
|
|
|
{
|
|
|
|
constructor()
|
|
|
|
{
|
|
|
|
super();
|
|
|
|
|
2022-02-18 00:37:59 +01:00
|
|
|
this.select_options = so.number(this, {other: this.other || []});
|
2022-01-17 23:12:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected find_select_options(_attrs) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
|
|
|
|
customElements.define("et2-select-number_ro", Et2SelectNumberReadonly);
|
|
|
|
|
|
|
|
export class Et2SelectPriorityReadonly extends Et2SelectReadonly
|
|
|
|
{
|
|
|
|
constructor()
|
|
|
|
{
|
|
|
|
super();
|
2022-02-18 00:37:59 +01:00
|
|
|
this.select_options = so.priority(this);
|
2022-01-17 23:12:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected find_select_options(_attrs) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
|
|
|
|
customElements.define("et2-select-priority_ro", Et2SelectPriorityReadonly);
|
|
|
|
|
|
|
|
export class Et2SelectStateReadonly extends Et2SelectReadonly
|
|
|
|
{
|
|
|
|
constructor()
|
|
|
|
{
|
|
|
|
super();
|
|
|
|
|
2022-02-18 00:37:59 +01:00
|
|
|
this.select_options = so.state(this, {other: this.other || []});
|
2022-01-17 23:12:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected find_select_options(_attrs) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
|
|
|
|
customElements.define("et2-select-state_ro", Et2SelectStateReadonly);
|
|
|
|
|
|
|
|
export class Et2SelectTimezoneReadonly extends Et2SelectReadonly
|
|
|
|
{
|
|
|
|
constructor()
|
|
|
|
{
|
|
|
|
super();
|
|
|
|
|
2022-02-18 00:37:59 +01:00
|
|
|
this.select_options = so.timezone(this, {other: this.other || []});
|
2022-01-17 23:12:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected find_select_options(_attrs) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
|
|
|
|
customElements.define("et2-select-timezone_ro", Et2SelectTimezoneReadonly);
|
|
|
|
|
|
|
|
export class Et2SelectYearReadonly extends Et2SelectReadonly
|
|
|
|
{
|
|
|
|
constructor()
|
|
|
|
{
|
|
|
|
super();
|
|
|
|
|
2022-02-18 00:37:59 +01:00
|
|
|
this.select_options = so.year(this, {other: this.other || []});
|
2022-01-17 23:12:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected find_select_options(_attrs) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
|
2022-02-16 09:35:09 +01:00
|
|
|
customElements.define("et2-select-year_ro", Et2SelectYearReadonly);
|