diff --git a/api/js/etemplate/Et2Select/Et2SelectAccount.ts b/api/js/etemplate/Et2Select/Et2SelectAccount.ts index a4c77e7598..3ab73ab421 100644 --- a/api/js/etemplate/Et2Select/Et2SelectAccount.ts +++ b/api/js/etemplate/Et2Select/Et2SelectAccount.ts @@ -10,13 +10,14 @@ import {Et2Select} from "./Et2Select"; import {SelectOption} from "./FindSelectOptions"; import {Et2Image} from "../Et2Image/Et2Image"; +import {SelectAccountMixin} from "./SelectAccountMixin"; export type AccountType = 'accounts'|'groups'|'both'|'owngroups'; /** * @customElement et2-select-account */ -export class Et2SelectAccount extends Et2Select +export class Et2SelectAccount extends SelectAccountMixin(Et2Select) { static get properties() { diff --git a/api/js/etemplate/Et2Select/Et2SelectReadonly.ts b/api/js/etemplate/Et2Select/Et2SelectReadonly.ts index e5aceb405e..5792dde514 100644 --- a/api/js/etemplate/Et2Select/Et2SelectReadonly.ts +++ b/api/js/etemplate/Et2Select/Et2SelectReadonly.ts @@ -13,6 +13,7 @@ import {et2_IDetachedDOM} from "../et2_core_interfaces"; import {Et2Widget} from "../Et2Widget/Et2Widget"; import {StaticOptions} from "./StaticOptions"; import {find_select_options, SelectOption} from "./FindSelectOptions"; +import {SelectAccountMixin} from "./SelectAccountMixin"; const so = new StaticOptions(); @@ -216,53 +217,10 @@ li { // @ts-ignore TypeScript is not recognizing that this widget is a LitElement customElements.define("et2-select_ro", Et2SelectReadonly); -export class Et2SelectAccountReadonly extends Et2SelectReadonly +export class Et2SelectAccountReadonly extends SelectAccountMixin(Et2SelectReadonly) { - protected account_options = []; - get select_options() - { - return [...this.account_options, ...super.select_options]; - } - - set select_options(value : SelectOption[]) - { - super.select_options = value; - } - - set value(new_value) - { - super.value = new_value; - if(!new_value) - { - return; - } - for(let id of this.value) - { - let account_name = null; - let option = {value: id, label: id + " ..."}; - this.account_options.push(option); - if(new_value && (account_name = this.egw().link_title('api-accounts', id, false))) - { - option.label = account_name; - } - else if(!account_name) - { - // Not already cached, need to fetch it - this.egw().link_title('api-accounts', id, true).then(title => - { - option.label = title; - this.requestUpdate(); - }); - } - } - } - - get value() - { - return super.value; - } } // @ts-ignore TypeScript is not recognizing that this widget is a LitElement diff --git a/api/js/etemplate/Et2Select/SelectAccountMixin.ts b/api/js/etemplate/Et2Select/SelectAccountMixin.ts new file mode 100644 index 0000000000..af0234c6e1 --- /dev/null +++ b/api/js/etemplate/Et2Select/SelectAccountMixin.ts @@ -0,0 +1,93 @@ +import {SelectOption} from "./FindSelectOptions"; +import {LitElement} from "@lion/core"; + +/** + * EGroupware eTemplate2 - SelectAccountMixin + * + * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License + * @package api + * @link https://www.egroupware.org + * @author Nathan Gray + */ + +/** + * Common code for editable & read-only select account + * Moved out so we don't have copy+paste code in both + */ +export declare class SelectAccountInterface +{ + set value(new_value : string | string[]) + + get value() : string | string[] + + set select_options(new_options : SelectOption[]) + get select_options() : SelectOption[] +} + +type Constructor = new (...args : any[]) => T; +export const SelectAccountMixin = >(superclass : T) => +{ + class SelectAccount extends superclass + { + + /** + * Hold on to accounts we had to fetch from the server + * @type {any[]} + * @protected + */ + protected account_options = []; + + /** + * If the value has an account that's not already in the list, check with the server. + * We probably don't have all the accounts client side. This is similar to freeEntries, + * but a little safer because we don't allow just anything. + * + * @param {any} new_value + */ + set value(new_value : string | string[]) + { + super.value = new_value; + if(!new_value) + { + return; + } + let val = Array.isArray(this.value) ? this.value : [this.value]; + for(let id of val) + { + let account_name = null; + let option = {value: id, label: id + " ..."}; + this.account_options.push(option); + if(new_value && (account_name = this.egw().link_title('api-accounts', id, false))) + { + option.label = account_name; + } + else if(!account_name) + { + // Not already cached, need to fetch it + this.egw().link_title('api-accounts', id, true).then(title => + { + option.label = title; + this.requestUpdate(); + }); + } + } + } + + get value() + { + return super.value; + } + + get select_options() + { + return [...this.account_options, ...super.select_options]; + } + + set select_options(value : SelectOption[]) + { + super.select_options = value; + } + } + + return SelectAccount as unknown as Constructor & T; +} \ No newline at end of file