Et2Select: Fix selects with static options from the server would not consistently keep any additional options set.

Creation / lifecycle would sometimes set the extra options several times, and depending on the timing of the server response they might get overwritten, or overwrite the server options.  Now keeping them separate to avoid this.
This commit is contained in:
nathan 2022-07-15 12:56:24 -06:00
parent 5793b462ba
commit ddd72fd51a
4 changed files with 80 additions and 29 deletions

View File

@ -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()
{

View File

@ -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");
});
}
}

View File

@ -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
(<Promise<SelectOption[]>>so.country(this, {}, true)).then(options =>
{
this.select_options = options
this.static_options = options
this.requestUpdate("select_options");
});
}
}

View File

@ -14,6 +14,46 @@ import {Et2Select, Et2SelectNumber, Et2WidgetWithSelect} from "./Et2Select";
export type Et2SelectWidgets = Et2Select | Et2WidgetWithSelect | Et2SelectReadonly;
// Export the Interface for TypeScript
type Constructor<T = {}> = 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 = <T extends Constructor<Et2WidgetWithSelect>>(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 : [];