UNPKG

@serenity-is/corelib

Version:
153 lines (116 loc) 4.58 kB
import { getInstanceType, getLookupAsync, getTypeFullName, nsSerenity, type Lookup } from "../../base"; import { ScriptData, getLookup, reloadLookup } from "../../compat"; import { ComboboxItem, ComboboxSearchQuery, ComboboxSearchResult } from "./combobox"; import { ComboboxEditor, ComboboxEditorOptions } from "./comboboxeditor"; import { EditorProps } from "./editorwidget"; export interface LookupEditorOptions extends ComboboxEditorOptions { lookupKey?: string; async?: boolean; } export abstract class LookupEditorBase<P extends LookupEditorOptions, TItem> extends ComboboxEditor<P, TItem> { static [Symbol.typeInfo] = this.registerEditor(nsSerenity); declare private lookupChangeUnbind: any; constructor(props: EditorProps<P>) { super(props); if (!this.hasAsyncSource()) { this.updateItems(); this.lookupChangeUnbind = ScriptData.bindToChange('Lookup.' + this.getLookupKey(), this.updateItems.bind(this)); } } hasAsyncSource(): boolean { return !!this.options.async; } destroy(): void { if (this.lookupChangeUnbind) { this.lookupChangeUnbind(); this.lookupChangeUnbind = null; } super.destroy(); } protected getLookupKey(): string { if (this.options.lookupKey != null) { return this.options.lookupKey; } var key = getTypeFullName(getInstanceType(this)); var idx = key.indexOf('.'); if (idx >= 0) { key = key.substring(idx + 1); } if (key.endsWith('Editor')) { key = key.substring(0, key.length - 6); } return key; } declare protected lookup: Lookup<TItem>; protected getLookupAsync(): PromiseLike<Lookup<TItem>> { return getLookupAsync<TItem>(this.getLookupKey()); } protected getLookup(): Lookup<TItem> { return getLookup<TItem>(this.getLookupKey()); } protected getItems(lookup: Lookup<TItem>) { return this.filterItems(this.cascadeItems(lookup.items)); } protected getIdField() { return this.lookup != null ? this.lookup.idField : super.getIdField(); } protected getItemText(item: TItem, lookup: Lookup<TItem>) { if (lookup == null) return super.itemText(item); var textValue = (item as any)[lookup.textField]; return textValue == null ? '' : textValue.toString(); } protected mapItem(item: TItem): ComboboxItem<TItem> { return { id: this.itemId(item), text: this.getItemText(item, this.lookup), disabled: this.getItemDisabled(item, this.lookup), source: item }; } protected getItemDisabled(item: TItem, lookup: Lookup<TItem>) { return super.itemDisabled(item); } public updateItems() { if (this.hasAsyncSource()) return; this.clearItems(); this.lookup = this.getLookup(); var items = this.getItems(this.lookup); for (var item of items) this.addItem(this.mapItem(item)); } protected override async asyncSearch(query: ComboboxSearchQuery): Promise<ComboboxSearchResult<TItem>> { this.lookup = await this.getLookupAsync(); var items = this.getItems(this.lookup); if (query.idList != null) { items = items.filter(x => query.idList.indexOf(this.itemId(x)) >= 0); } function getText(item: TItem) { return this.getItemText(item, this.lookup); } items = ComboboxEditor.filterByText(items, getText.bind(this), query.searchTerm); return { items: items.slice(query.skip, query.take ? (query.skip + query.take) : items.length), more: query.take && items.length > 0 && items.length > query.skip + query.take }; } protected getDialogTypeKey() { var dialogTypeKey = super.getDialogTypeKey(); if (dialogTypeKey) return dialogTypeKey; return this.getLookupKey(); } protected setCreateTermOnNewEntity(entity: TItem, term: string) { (entity as any)[this.getLookup().textField] = term; } protected editDialogDataChange() { reloadLookup(this.getLookupKey()); } } export class LookupEditor<P extends LookupEditorOptions = LookupEditorOptions> extends LookupEditorBase<P, {}> { static [Symbol.typeInfo] = this.registerEditor(nsSerenity); constructor(props: EditorProps<P>) { super(props); } }