diff --git a/public/js/components/searchbar/searchbar.js b/public/js/components/searchbar/searchbar.js index d6c93198e..34060239c 100644 --- a/public/js/components/searchbar/searchbar.js +++ b/public/js/components/searchbar/searchbar.js @@ -8,6 +8,7 @@ import dms from "./result/dms.js"; import cms from "./result/cms.js"; import mergedStudent from "./result/mergedstudent.js"; import mergedPerson from "./result/mergedperson.js"; +import { debounce } from "../../helpers/DebounceHelper.js"; export default { name: "FhcSearchbar", @@ -52,9 +53,114 @@ export default { showresult: false, searching: false, error: null, - abortController: null, - settingsDropdown: null, - lastQuery: '' + abortController: null, + settingsDropdown: null, + lastQuery: '', + callsearchApi: debounce(() => { + this.error = null; + this.searchresult.splice(0, this.searchresult.length); + this.searching = true; + this.showsearchresult(); + if (this.searchsettings.types.length === 0) { + this.error = this.$p.t("search/error_missing_type"); + this.searching = false; + return; + } + + if (this.abortController) this.abortController.abort(); + this.abortController = new AbortController(); + + this.searchfunction(this.searchsettings, { + timeout: 50000, + signal: this.abortController.signal, + }) + .then((response) => { + if (!response.data) { + this.error = this.$p.t("search/error_general"); + } else { + let res = response.data.map((el) => + el.data + ? { ...el, ...JSON.parse(el.data) } + : el, + ); + this.lastQuery = response.meta.searchstring; + if (this.searchoptions.mergeResults) { + let counter = 0; + let mergeTypes = []; + let mergedType = "merged-"; + let mergeKey = ""; + + switch (this.searchoptions.mergeResults) { + case "student": + mergeTypes = ["student", "prestudent"]; + mergedType += + this.searchoptions.mergeResults; + mergeKey = "uid"; + break; + case "person": + mergeTypes = [ + "person", + "employee", + "student", + "prestudent", + ]; + mergedType += + this.searchoptions.mergeResults; + mergeKey = "person_id"; + break; + } + + if (mergeTypes.length) { + res = Object.values( + res.reduce((a, c) => { + if ( + !mergeTypes.includes(c.renderer) + ) { + a["nomerge" + counter++] = c; + } else if (c[mergeKey] === null) { + a["nomerge" + counter++] = c; + } else if ( + a[c[mergeKey]] === undefined + ) { + a[c[mergeKey]] = { + rank: c.rank, + renderer: mergedType, + type: mergedType, + list: [c], + }; + } else { + a[c[mergeKey]].list.push(c); + if ( + c.rank > a[c[mergeKey]].rank + ) + a[c[mergeKey]].rank = + c.rank; + } + return a; + }, {}), + ).sort((a, b) => b.rank - a.rank); + } + } + this.searchresult = res; + this.searchmode = response.meta.mode; + } + this.searching = false; + this.retry = 0; + }) + .catch((error) => { + if (error.code == "ERR_CANCELED") { + return (this.retry = 0); + } + if (error.code == "ECONNABORTED" && this.retry) { + this.retry--; + return this.callsearchapi(); + } + + this.error = this.$p.t("search/error_general", error); + this.searching = false; + this.retry = 0; + }); + }, 500), }; }, computed: { @@ -309,107 +415,18 @@ export default { this.abort(); if( this.searchsettings.searchstr.length >= 2 ) { this.calcSearchResultExtent(); - this.searchtimer = setTimeout( - this.callsearchapi, - 500 - ); + this.callsearchApi(); } else { this.showresult = false; } }, abort() { - if (this.searchtimer !== null) { - clearTimeout(this.searchtimer); - } - if (this.abortController) { + if (this.abortController) { this.abortController.abort(); this.abortController = null; } this.searchresult = []; }, - callsearchapi: function() { - this.error = null; - this.searchresult.splice(0, this.searchresult.length); - this.searching = true; - this.showsearchresult(); - if(this.searchsettings.types.length === 0) { - this.error = this.$p.t('search/error_missing_type'); - this.searching = false; - return; - } - - if (this.abortController) - this.abortController.abort(); - this.abortController = new AbortController(); - - this.searchfunction(this.searchsettings, { timeout: 50000, signal: this.abortController.signal }) - .then(response=>{ - if (!response.data) { - this.error = this.$p.t('search/error_general'); - } else { - let res = response.data.map(el => el.data ? {...el, ...JSON.parse(el.data)} : el); - this.lastQuery = response.meta.searchstring; - if (this.searchoptions.mergeResults) { - let counter = 0; - let mergeTypes = []; - let mergedType = 'merged-'; - let mergeKey = ''; - - switch (this.searchoptions.mergeResults) { - case 'student': - mergeTypes = ['student', 'prestudent']; - mergedType += this.searchoptions.mergeResults; - mergeKey = 'uid'; - break; - case 'person': - mergeTypes = ['person', 'employee', 'student', 'prestudent']; - mergedType += this.searchoptions.mergeResults; - mergeKey = 'person_id'; - break; - } - - if (mergeTypes.length) { - res = Object.values(res.reduce((a, c) => { - if (!mergeTypes.includes(c.renderer)) { - a['nomerge' + counter++] = c; - } else if (c[mergeKey] === null) { - a['nomerge' + counter++] = c; - } else if (a[c[mergeKey]] === undefined) { - a[c[mergeKey]] = { - rank: c.rank, - renderer: mergedType, - type: mergedType, - list: [c] - }; - } else { - a[c[mergeKey]].list.push(c); - if (c.rank > a[c[mergeKey]].rank) - a[c[mergeKey]].rank = c.rank; - } - return a; - }, {})).sort((a, b) => b.rank - a.rank); - } - } - this.searchresult = res; - this.searchmode = response.meta.mode; - } - this.searching = false; - this.retry = 0; - }) - .catch(error=> { - if (error.code == "ERR_CANCELED") { - return this.retry = 0; - } - if (error.code == "ECONNABORTED" && this.retry) { - this.retry--; - return this.callsearchapi(); - } - - this.error = this.$p.t('search/error_general', error); - this.searching = false; - this.retry = 0; - }); - }, refreshsearch: function() { this.search(); this.togglesettings();