diff --git a/api/js/etemplate/Et2Select/Et2Select.ts b/api/js/etemplate/Et2Select/Et2Select.ts index cc577627b4..59e56f1776 100644 --- a/api/js/etemplate/Et2Select/Et2Select.ts +++ b/api/js/etemplate/Et2Select/Et2Select.ts @@ -9,7 +9,7 @@ import {css, html, PropertyValues, TemplateResult} from "@lion/core"; -import {StaticOptions} from "./StaticOptions"; +import {Et2StaticSelectMixin, StaticOptions} from "./StaticOptions"; import {Et2widgetWithSelectMixin} from "./Et2WidgetWithSelectMixin"; import {SelectOption} from "./FindSelectOptions"; import {SlMenuItem, SlSelect} from "@shoelace-style/shoelace"; @@ -537,20 +537,20 @@ if(typeof customElements.get("lion-validation-feedback") === "undefined") const so = new StaticOptions(); -export class Et2SelectApp extends Et2Select +export class Et2SelectApp extends Et2StaticSelectMixin(Et2Select) { constructor() { super(); - this.select_options = so.app(this, {other: this.other || []}); + this.static_options = so.app(this, {other: this.other || []}); } } // @ts-ignore TypeScript is not recognizing that this widget is a LitElement customElements.define("et2-select-app", Et2SelectApp); -export class Et2SelectBitwise extends Et2Select +export class Et2SelectBitwise extends Et2StaticSelectMixin(Et2Select) { set value(new_value) { @@ -574,13 +574,13 @@ export class Et2SelectBitwise extends Et2Select // @ts-ignore TypeScript is not recognizing that this widget is a LitElement customElements.define("et2-select-bitwise", Et2SelectBitwise); -export class Et2SelectBool extends Et2Select +export class Et2SelectBool extends Et2StaticSelectMixin(Et2Select) { constructor() { super(); - this.select_options = so.bool(this); + this.static_options = so.bool(this); } } @@ -588,59 +588,59 @@ export class Et2SelectBool extends Et2Select customElements.define("et2-select-bool", Et2SelectBool); -export class Et2SelectDay extends Et2Select +export class Et2SelectDay extends Et2StaticSelectMixin(Et2Select) { constructor() { super(); - this.select_options = so.day(this, {other: this.other || []}); + this.static_options = so.day(this, {other: this.other || []}); } } // @ts-ignore TypeScript is not recognizing that this widget is a LitElement customElements.define("et2-select-day", Et2SelectDay); -export class Et2SelectDayOfWeek extends Et2Select +export class Et2SelectDayOfWeek extends Et2StaticSelectMixin(Et2Select) { constructor() { super(); - this.select_options = so.dow(this, {other: this.other || []}); + this.static_options = so.dow(this, {other: this.other || []}); } } // @ts-ignore TypeScript is not recognizing that this widget is a LitElement customElements.define("et2-select-dow", Et2SelectDayOfWeek); -export class Et2SelectHour extends Et2Select +export class Et2SelectHour extends Et2StaticSelectMixin(Et2Select) { constructor() { super(); - this.select_options = so.hour(this, {other: this.other || []}); + this.static_options = so.hour(this, {other: this.other || []}); } } // @ts-ignore TypeScript is not recognizing that this widget is a LitElement customElements.define("et2-select-hour", Et2SelectHour); -export class Et2SelectMonth extends Et2Select +export class Et2SelectMonth extends Et2StaticSelectMixin(Et2Select) { constructor() { super(); - this.select_options = so.month(this); + this.static_options = so.month(this); } } // @ts-ignore TypeScript is not recognizing that this widget is a LitElement customElements.define("et2-select-month", Et2SelectMonth); -export class Et2SelectNumber extends Et2Select +export class Et2SelectNumber extends Et2StaticSelectMixin(Et2Select) { static get properties() { @@ -681,7 +681,8 @@ export class Et2SelectNumber extends Et2Select if(changedProperties.has('min') || changedProperties.has('max') || changedProperties.has('interval') || changedProperties.has('suffix')) { - this.select_options = so.number(this); + this.static_options = so.number(this); + this.requestUpdate("select_options"); } } } @@ -704,20 +705,20 @@ export class Et2SelectPercent extends Et2SelectNumber // @ts-ignore TypeScript is not recognizing that this widget is a LitElement customElements.define("et2-select-percent", Et2SelectPercent); -export class Et2SelectPriority extends Et2Select +export class Et2SelectPriority extends Et2StaticSelectMixin(Et2Select) { constructor() { super(); - this.select_options = so.priority(this); + this.static_options = so.priority(this); } } // @ts-ignore TypeScript is not recognizing that this widget is a LitElement customElements.define("et2-select-priority", Et2SelectPriority); -export class Et2SelectState extends Et2Select +export class Et2SelectState extends Et2StaticSelectMixin(Et2Select) { /** * Two-letter ISO country code @@ -747,7 +748,8 @@ export class Et2SelectState extends Et2Select set country_code(code : string) { this.__country_code = code; - this.select_options = so.state(this, {country_code: this.__country_code}); + this.static_options = so.state(this, {country_code: this.__country_code}); + this.requestUpdate("select_options"); } set_country_code(code) @@ -759,7 +761,7 @@ export class Et2SelectState extends Et2Select // @ts-ignore TypeScript is not recognizing that this widget is a LitElement customElements.define("et2-select-state", Et2SelectState); -export class Et2SelectTimezone extends Et2Select +export class Et2SelectTimezone extends Et2StaticSelectMixin(Et2Select) { constructor() { diff --git a/api/js/etemplate/Et2Select/Et2SelectCategory.ts b/api/js/etemplate/Et2Select/Et2SelectCategory.ts index 9dac3856d8..418fe4bf9a 100644 --- a/api/js/etemplate/Et2Select/Et2SelectCategory.ts +++ b/api/js/etemplate/Et2Select/Et2SelectCategory.ts @@ -10,13 +10,13 @@ import {css, PropertyValues} from "@lion/core"; import {Et2Select} from "./Et2Select"; -import {StaticOptions} from "./StaticOptions"; +import {Et2StaticSelectMixin, StaticOptions} from "./StaticOptions"; /** * Customised Select widget for categories * This widget gives us category colors and icons in the options and selected value. */ -export class Et2SelectCategory extends Et2Select +export class Et2SelectCategory extends Et2StaticSelectMixin(Et2Select) { static get styles() { @@ -77,7 +77,8 @@ export class Et2SelectCategory extends Et2Select { so.cat(this).then(options => { - this.select_options = options + this.static_options = options + this.requestUpdate("select_options"); }); } } diff --git a/api/js/etemplate/Et2Select/Et2SelectCountry.ts b/api/js/etemplate/Et2Select/Et2SelectCountry.ts index 59dc3df5e9..1b0def85b8 100644 --- a/api/js/etemplate/Et2Select/Et2SelectCountry.ts +++ b/api/js/etemplate/Et2Select/Et2SelectCountry.ts @@ -9,9 +9,9 @@ import {Et2Select} from "./Et2Select"; -import {StaticOptions} from "./StaticOptions"; -import {SelectOption} from "./FindSelectOptions"; +import {Et2StaticSelectMixin, StaticOptions} from "./StaticOptions"; import {egw} from "../../jsapi/egw_global"; +import {SelectOption} from "./FindSelectOptions"; /** * Customised Select widget for countries @@ -19,7 +19,7 @@ import {egw} from "../../jsapi/egw_global"; */ egw(window).includeCSS("api/templates/default/css/flags.css") -export class Et2SelectCountry extends Et2Select +export class Et2SelectCountry extends Et2StaticSelectMixin(Et2Select) { static get properties() { @@ -38,7 +38,8 @@ export class Et2SelectCountry extends Et2Select (>so.country(this, {}, true)).then(options => { - this.select_options = options + this.static_options = options + this.requestUpdate("select_options"); }); } } diff --git a/api/js/etemplate/Et2Select/StaticOptions.ts b/api/js/etemplate/Et2Select/StaticOptions.ts index 74154f507f..5a02adfa8a 100644 --- a/api/js/etemplate/Et2Select/StaticOptions.ts +++ b/api/js/etemplate/Et2Select/StaticOptions.ts @@ -14,6 +14,46 @@ import {Et2Select, Et2SelectNumber, Et2WidgetWithSelect} from "./Et2Select"; export type Et2SelectWidgets = Et2Select | Et2WidgetWithSelect | Et2SelectReadonly; +// Export the Interface for TypeScript +type Constructor = new (...args : any[]) => T; + +/** + * Base class for things that have static options + * + * We keep static options separate and concatenate them in to allow for extra options without + * overwriting them when we get static options from the server + */ + +export const Et2StaticSelectMixin = >(superclass : T) => +{ + class Et2StaticSelectOptions extends (superclass) + { + + protected static_options : SelectOption[]; + + constructor(...args) + { + super(...args); + + this.static_options = []; + } + + get select_options() : SelectOption[] + { + // @ts-ignore + return [...super.select_options, ...this.static_options]; + } + + set select_options(new_options) + { + // @ts-ignore IDE doesn't recognise property + super.select_options = new_options; + } + } + + return Et2StaticSelectOptions; +} + /** * Some options change, or are too complicated to have twice, so we get the * options from the server once, then keep them to use if they're needed again. @@ -68,7 +108,14 @@ export class StaticOptions // Avoid errors if widget is destroyed before the timeout if(widget && typeof widget.id !== 'undefined') { - widget.set_select_options(find_select_options(widget, {}, cache)); + if(typeof widget.set_static_options == "function") + { + widget.set_static_options(cache); + } + else if(typeof widget.set_select_options == "function") + { + widget.set_select_options(find_select_options(widget, {}, cache)); + } } }); return return_promise ? promise : [];