From 30c3000e87ab25986bcce45d7bf7af0dd6370dcc Mon Sep 17 00:00:00 2001 From: nathan <nathangray.bsc+github@gmail.com> Date: Fri, 16 Sep 2022 10:20:47 -0600 Subject: [PATCH] Et2Select fixes - Search with no results blocked any futher searches from displaying results - Only show "no suggestions" after searching --- api/js/etemplate/Et2Link/Et2LinkSearch.ts | 4 +-- api/js/etemplate/Et2Select/SearchMixin.ts | 43 +++++++++++++++++------ 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/api/js/etemplate/Et2Link/Et2LinkSearch.ts b/api/js/etemplate/Et2Link/Et2LinkSearch.ts index e0dcd1aa5b..6c65ecfb63 100644 --- a/api/js/etemplate/Et2Link/Et2LinkSearch.ts +++ b/api/js/etemplate/Et2Link/Et2LinkSearch.ts @@ -69,10 +69,10 @@ export class Et2LinkSearch extends Et2Select { if(!this.query(request, this)) { - return; + return Promise.resolve(); } } - request.then((result) => + return request.then((result) => { this.processRemoteResults(result); }); diff --git a/api/js/etemplate/Et2Select/SearchMixin.ts b/api/js/etemplate/Et2Select/SearchMixin.ts index 585e6b8a02..8e5b094996 100644 --- a/api/js/etemplate/Et2Select/SearchMixin.ts +++ b/api/js/etemplate/Et2Select/SearchMixin.ts @@ -359,8 +359,6 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass super.updateComplete.then(() => { - this.menu.querySelector("slot").textContent = this.egw().lang("No suggestions"); - let control = this.shadowRoot.querySelector(".form-control-input"); control.append(div); }); @@ -760,8 +758,10 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass * If we have local options, we'll search & display any matches. * If serverUrl is set, we'll ask the server for results as well. */ - public startSearch() + public async startSearch() { + this.menu.querySelector("slot").textContent = ""; + // Stop timeout timer clearTimeout(this._searchTimeout); @@ -777,18 +777,31 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass clear_button.style.display = "none"; } + // Clear previous results + this._clearResults(); + await this.updateComplete; + // Start the searches - Promise.all([ + return Promise.all([ this.localSearch(this._searchInputNode.value, this.searchOptions), this.remoteSearch(this._searchInputNode.value, this.searchOptions) ]).then(() => { + // Show / hide no results indicator + this.menu.querySelector("slot").textContent = this.menuItems.length == 0 ? this.egw().lang("No suggestions") : ""; + + // Remove spinner spinner.remove(); + // Restore clear button if(clear_button) { clear_button.style.display = ""; } + }).then(() => + { + // Not sure why this stays hidden if there's no results but it sticks and hides all results afterward + this.dropdown.shadowRoot.querySelector(".dropdown__panel").removeAttribute("hidden"); }); } @@ -802,6 +815,17 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass // Stop timeout timer clearTimeout(this._searchTimeout); + this._clearResults(); + + // Clear search term + if(this._searchInputNode) + { + this._searchInputNode.value = ""; + } + } + + protected _clearResults() + { // Remove remote options that aren't used let target = this._optionTargetNode || this; let keepers = this._selected_remote.reduce((prev, current) => @@ -824,12 +848,6 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass item.classList.remove("match"); item.classList.remove("no-match"); }); - - // Clear search term - if(this._searchInputNode) - { - this._searchInputNode.value = ""; - } } /** @@ -904,8 +922,13 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass */ protected processRemoteResults(results) { + let entries = cleanSelectOptions(results); + if(entries.length == 0) + { + return Promise.resolve(); + } // Add a "remote" class so we can tell these apart from any local results entries.forEach((entry) => entry.class = (entry.class || "") + " remote");