From c0526ca4a9ce82191f403aad01291ca96440b10f Mon Sep 17 00:00:00 2001 From: Mateus Machado Luna Date: Tue, 16 Oct 2018 17:11:01 -0300 Subject: [PATCH] Adds request cancelation to facet load options search --- .../tainacan-collection-subheader.vue | 1 + .../components/other/checkbox-radio-modal.vue | 11 +- .../autocomplete/Autocomplete.vue | 12 +- .../filter-types/checkbox/Checkbox.vue | 45 +-- .../filter-types/filter-types-mixin.js | 265 ++++++++++-------- .../filter-types/selectbox/Selectbox.vue | 24 +- .../filter-types/taginput/Taginput.vue | 18 +- src/js/store/modules/collection/actions.js | 1 - 8 files changed, 222 insertions(+), 155 deletions(-) diff --git a/src/admin/components/navigation/tainacan-collection-subheader.vue b/src/admin/components/navigation/tainacan-collection-subheader.vue index 6cf4daf6e..0a621c77f 100644 --- a/src/admin/components/navigation/tainacan-collection-subheader.vue +++ b/src/admin/components/navigation/tainacan-collection-subheader.vue @@ -168,6 +168,7 @@ export default { this.arrayRealPath = this.arrayRealPath.filter((item) => item.length != 0); this.generateViewPath(); + } }, methods: { diff --git a/src/admin/components/other/checkbox-radio-modal.vue b/src/admin/components/other/checkbox-radio-modal.vue index 94597f3f4..7d75a0896 100644 --- a/src/admin/components/other/checkbox-radio-modal.vue +++ b/src/admin/components/other/checkbox-radio-modal.vue @@ -359,13 +359,17 @@ getOptions(offset){ let promise = ''; + // Cancels previous Request + if (this.getOptionsValuesCancel != undefined) + this.getOptionsValuesCancel.cancel('Facet search Canceled.'); + if ( this.metadatum_type === 'Tainacan\\Metadata_Types\\Relationship' ) { let collectionTarget = ( this.metadatum_object && this.metadatum_object.metadata_type_options.collection_id ) ? this.metadatum_object.metadata_type_options.collection_id : this.collection_id; promise = this.getValuesRelationship( collectionTarget, this.optionName, [], offset, this.maxNumOptionsCheckboxList, true); - promise + promise.request .then(() => { this.isCheckboxListLoading = false; this.isSearchingLoading = false; @@ -376,7 +380,7 @@ } else { promise = this.getValuesPlainText( this.metadatum_id, this.optionName, this.isRepositoryLevel, [], offset, this.maxNumOptionsCheckboxList, true); - promise + promise.request .then(() => { this.isCheckboxListLoading = false; this.isSearchingLoading = false; @@ -385,6 +389,9 @@ this.$console.log(error); }) } + + // Search Request Token for cancelling + this.getOptionsValuesCancel = promise.source; }, autoComplete: _.debounce( function () { this.isSearching = !!this.optionName.length; diff --git a/src/classes/filter-types/autocomplete/Autocomplete.vue b/src/classes/filter-types/autocomplete/Autocomplete.vue index c31a77c60..3ebb7c13f 100644 --- a/src/classes/filter-types/autocomplete/Autocomplete.vue +++ b/src/classes/filter-types/autocomplete/Autocomplete.vue @@ -98,6 +98,12 @@ if (query != '') { let promise = null; this.options = []; + + // Cancels previous Request + if (this.getOptionsValuesCancel != undefined) + this.getOptionsValuesCancel.cancel('Facet search Canceled.'); + + if ( this.type === 'Tainacan\\Metadata_Types\\Relationship' ) { let collectionTarget = ( this.metadatum_object && this.metadatum_object.metadata_type_options.collection_id ) ? this.metadatum_object.metadata_type_options.collection_id : this.collection_id; @@ -107,9 +113,13 @@ promise = this.getValuesPlainText( this.metadatum, query, this.isRepositoryLevel ); } - promise.catch( error => { + promise.request.catch( error => { this.$console.log('error select', error ); }); + + // Search Request Token for cancelling + this.getOptionsValuesCancel = promise.source; + } else { this.cleanSearch(); } diff --git a/src/classes/filter-types/checkbox/Checkbox.vue b/src/classes/filter-types/checkbox/Checkbox.vue index 5c6ec9e11..1ad0b6f0b 100644 --- a/src/classes/filter-types/checkbox/Checkbox.vue +++ b/src/classes/filter-types/checkbox/Checkbox.vue @@ -32,6 +32,7 @@ export default { created(){ + this.collection = ( this.collection_id ) ? this.collection_id : this.filter.collection_id; this.metadatum = ( this.metadatum_id ) ? this.metadatum_id : this.filter.metadatum.metadatum_id; const vm = this; @@ -81,46 +82,56 @@ methods: { loadOptions(){ let promise = null; - this.isLoading = true; + + // Cancels previous Request + if (this.getOptionsValuesCancel != undefined) + this.getOptionsValuesCancel.cancel('Facet search Canceled.'); if ( this.type === 'Tainacan\\Metadata_Types\\Relationship' ) { + this.isLoading = true; let collectionTarget = ( this.metadatum_object && this.metadatum_object.metadata_type_options.collection_id ) ? this.metadatum_object.metadata_type_options.collection_id : this.collection_id; promise = this.getValuesRelationship( collectionTarget, null, [], 0, this.filter.max_options, false, '1'); - promise + promise.request .then(() => { - - this.isLoading = false; + this.isLoading = false; if(this.options.length > this.filter.max_options){ this.options.splice(this.filter.max_options); } + this.selectedValues(); }).catch((error) => { this.$console.error(error); - }) + }) } else { + this.isLoading = true; promise = this.getValuesPlainText( this.metadatum, null, this.isRepositoryLevel, [], 0, this.filter.max_options, false, '1' ); - promise + promise.request .then(() => { - this.isLoading = false; + this.isLoading = false; if(this.options.length > this.filter.max_options){ this.options.splice(this.filter.max_options); } + this.selectedValues(); }).catch((error) => { this.$console.error(error); - }) + }); } - promise - .then(() => { - this.isLoading = false; - this.selectedValues() - }) - .catch( error => { - this.$console.log('error select', error ); - this.isLoading = false; - }); + // promise.request + // .then(() => { + // this.isLoading = false; + + // }) + // .catch( error => { + // this.$console.log('error select', error ); + // this.isLoading = false; + // }); + + // Search Request Token for cancelling + this.getOptionsValuesCancel = promise.source; + }, onSelect(){ this.$emit('input', { diff --git a/src/classes/filter-types/filter-types-mixin.js b/src/classes/filter-types/filter-types-mixin.js index 4e9ff0b13..8bf142104 100644 --- a/src/classes/filter-types/filter-types-mixin.js +++ b/src/classes/filter-types/filter-types-mixin.js @@ -1,10 +1,11 @@ import qs from 'qs'; -import { tainacan as axios } from '../../js/axios/axios'; +import axios from '../../js/axios/axios'; export const filter_type_mixin = { data () { return { - thumbPlaceholderPath: tainacan_plugin.base_url + '/admin/images/placeholder_square.png' + thumbPlaceholderPath: tainacan_plugin.base_url + '/admin/images/placeholder_square.png', + getOptionsValuesCancel: undefined } }, props: { @@ -19,10 +20,15 @@ export const filter_type_mixin = { }, methods: { getValuesPlainText(metadatumId, search, isRepositoryLevel, valuesToIgnore, offset, number, isInCheckboxModal, getSelected = '0') { + + const source = axios.CancelToken.source(); + let currentQuery = JSON.parse(JSON.stringify(this.query)); - for (let key of Object.keys(currentQuery.fetch_only)) { - if (currentQuery.fetch_only[key] == null) - delete currentQuery.fetch_only[key]; + if (currentQuery.fetch_only != undefined) { + for (let key of Object.keys(currentQuery.fetch_only)) { + if (currentQuery.fetch_only[key] == null) + delete currentQuery.fetch_only[key]; + } } let query_items = { 'current_query': currentQuery }; @@ -44,74 +50,87 @@ export const filter_type_mixin = { url += qs.stringify(query_items); } - return axios.get(url) - .then(res => { - let sResults = []; - let opts = []; + return new Object ({ + request: + axios.tainacan.get(url, { cancelToken: source.token }) + .then(res => { + let sResults = []; + let opts = []; - for (let metadata of res.data) { - if (valuesToIgnore != undefined && valuesToIgnore.length > 0) { - let indexToIgnore = valuesToIgnore.findIndex(value => value == metadata.value); + for (let metadata of res.data) { + if (valuesToIgnore != undefined && valuesToIgnore.length > 0) { + let indexToIgnore = valuesToIgnore.findIndex(value => value == metadata.value); - if (search && isInCheckboxModal) { - sResults.push({ - label: metadata.label, - value: metadata.value - }); - } else if (indexToIgnore < 0) { - opts.push({ - label: metadata.label, - value: metadata.value - }); + if (search && isInCheckboxModal) { + sResults.push({ + label: metadata.label, + value: metadata.value + }); + } else if (indexToIgnore < 0) { + opts.push({ + label: metadata.label, + value: metadata.value + }); + } + } else { + if (search && isInCheckboxModal) { + sResults.push({ + label: metadata.label, + value: metadata.value + }); + } else { + opts.push({ + label: metadata.label, + value: metadata.value + }); + } + } } - } else { - if (search && isInCheckboxModal) { - sResults.push({ - label: metadata.label, - value: metadata.value - }); + + + this.searchResults = sResults; + + if (opts.length) { + this.options = opts; + } else if(!search) { + this.noMorePage = 1; + } + + if(this.options.length < this.maxNumOptionsCheckboxList && !search){ + this.noMorePage = 1; + } + + if (this.filter.max_options && this.options.length >= this.filter.max_options) { + let seeMoreLink = ` ${ this.$i18n.get('label_view_all') } `; + + if(this.options.length === this.filter.max_options){ + this.options[this.filter.max_options-1].seeMoreLink = seeMoreLink; + } else { + this.options[this.options.length-1].seeMoreLink = seeMoreLink; + } + } + + }) + .catch((thrown) => { + if (axios.isCancel(thrown)) { + console.log('Request canceled: ', thrown.message); } else { - opts.push({ - label: metadata.label, - value: metadata.value - }); + reject(thrown); } - } - } - - - this.searchResults = sResults; - - if (opts.length) { - this.options = opts; - } else if(!search) { - this.noMorePage = 1; - } - - if(this.options.length < this.maxNumOptionsCheckboxList && !search){ - this.noMorePage = 1; - } - - if (this.filter.max_options && this.options.length >= this.filter.max_options) { - let seeMoreLink = ` ${ this.$i18n.get('label_view_all') } `; - - if(this.options.length === this.filter.max_options){ - this.options[this.filter.max_options-1].seeMoreLink = seeMoreLink; - } else { - this.options[this.options.length-1].seeMoreLink = seeMoreLink; - } - } - - }) - .catch(error => { - this.$console.error(error); - }); + }), + source: source + }); }, getValuesRelationship(collectionTarget, search, valuesToIgnore, offset, number, isInCheckboxModal, getSelected = '0') { + + const source = axios.CancelToken.source(); + let currentQuery = JSON.parse(JSON.stringify(this.query)); - for (let key of Object.keys(currentQuery.fetch_only)) { - if (currentQuery.fetch_only[key] == null) - delete currentQuery.fetch_only[key]; + if (currentQuery.fetch_only != undefined) { + for (let key of Object.keys(currentQuery.fetch_only)) { + if (currentQuery.fetch_only[key] == null) + delete currentQuery.fetch_only[key]; + } } let query_items = { 'current_query': currentQuery }; let url = '/collection/' + this.filter.collection_id + '/facets/' + this.filter.metadatum.metadatum_id + `?getSelected=${getSelected}&`; @@ -126,72 +145,76 @@ export const filter_type_mixin = { url += `&search=${search}`; } - return axios.get(url + '&fetch_only[0]=thumbnail&fetch_only[1]=title&fetch_only[2]=id&' + qs.stringify(query_items)) - .then(res => { - let sResults = []; - let opts = []; + return new Object ({ + request: + axios.tainacan.get(url + '&fetch_only[0]=thumbnail&fetch_only[1]=title&fetch_only[2]=id&' + qs.stringify(query_items)) + .then(res => { + let sResults = []; + let opts = []; - if (res.data.length > 0) { - for (let item of res.data) { - if (valuesToIgnore != undefined && valuesToIgnore.length > 0) { - let indexToIgnore = valuesToIgnore.findIndex(value => value == item.value); + if (res.data.length > 0) { + for (let item of res.data) { + if (valuesToIgnore != undefined && valuesToIgnore.length > 0) { + let indexToIgnore = valuesToIgnore.findIndex(value => value == item.value); - if (search && isInCheckboxModal) { - sResults.push({ - label: item.label, - value: item.value - }); - } else if (indexToIgnore < 0) { - opts.push({ - label: item.label, - value: item.value, - img: (item.img ? item.img : this.thumbPlaceholderPath) - }); - } - } else { - if (search && isInCheckboxModal) { - sResults.push({ - label: item.label, - value: item.value, - img: (item.img ? item.img : this.thumbPlaceholderPath) - }); - } else { - opts.push({ - label: item.label, - value: item.value, - img: (item.img ? item.img : this.thumbPlaceholderPath) - }); + if (search && isInCheckboxModal) { + sResults.push({ + label: item.label, + value: item.value + }); + } else if (indexToIgnore < 0) { + opts.push({ + label: item.label, + value: item.value, + img: (item.img ? item.img : this.thumbPlaceholderPath) + }); + } + } else { + if (search && isInCheckboxModal) { + sResults.push({ + label: item.label, + value: item.value, + img: (item.img ? item.img : this.thumbPlaceholderPath) + }); + } else { + opts.push({ + label: item.label, + value: item.value, + img: (item.img ? item.img : this.thumbPlaceholderPath) + }); + } + } } } - } - } - this.searchResults = sResults; + this.searchResults = sResults; - if (opts.length) { - this.options = opts; - } else { - this.noMorePage = 1; - } + if (opts.length) { + this.options = opts; + } else { + this.noMorePage = 1; + } - if(this.options.length < this.maxNumOptionsCheckboxList){ - this.noMorePage = 1; - } + if(this.options.length < this.maxNumOptionsCheckboxList){ + this.noMorePage = 1; + } - if (this.filter.max_options && this.options.length >= this.filter.max_options) { - let seeMoreLink = ` ${ this.$i18n.get('label_view_all') } `; + if (this.filter.max_options && this.options.length >= this.filter.max_options) { + let seeMoreLink = ` ${ this.$i18n.get('label_view_all') } `; - if(this.options.length === this.filter.max_options){ - this.options[this.filter.max_options-1].seeMoreLink = seeMoreLink; - } else { - this.options[this.options.length-1].seeMoreLink = seeMoreLink; - } - } + if(this.options.length === this.filter.max_options){ + this.options[this.filter.max_options-1].seeMoreLink = seeMoreLink; + } else { + this.options[this.options.length-1].seeMoreLink = seeMoreLink; + } + } - }) - .catch(error => { - this.$console.error(error); - }); + }) + .catch(error => { + this.$console.error(error); + }), + source: source + }); } } }; \ No newline at end of file diff --git a/src/classes/filter-types/selectbox/Selectbox.vue b/src/classes/filter-types/selectbox/Selectbox.vue index 882a49752..7ac0e8e5b 100644 --- a/src/classes/filter-types/selectbox/Selectbox.vue +++ b/src/classes/filter-types/selectbox/Selectbox.vue @@ -73,21 +73,29 @@ } return undefined; } - }, + }, methods: { loadOptions(){ this.isLoading = true; + // Cancels previous Request + if (this.getOptionsValuesCancel != undefined) + this.getOptionsValuesCancel.cancel('Facet search Canceled.'); + let promise = null; promise = this.getValuesPlainText( this.metadatum, null, this.isRepositoryLevel ); - promise.then(() => { - this.isLoading = false; - }) - .catch( error => { - this.$console.error('error select', error ); - this.isLoading = false; - }); + promise.request + .then(() => { + this.isLoading = false; + }) + .catch( error => { + this.$console.error('error select', error ); + this.isLoading = false; + }); + + // Search Request Token for cancelling + this.getOptionsValuesCancel = promise.source; }, onSelect(value){ this.selected = value; diff --git a/src/classes/filter-types/taginput/Taginput.vue b/src/classes/filter-types/taginput/Taginput.vue index f6bd252a4..231c12020 100644 --- a/src/classes/filter-types/taginput/Taginput.vue +++ b/src/classes/filter-types/taginput/Taginput.vue @@ -112,19 +112,27 @@ for(let val of this.selected) valuesToIgnore.push( val.value ); + // Cancels previous Request + if (this.getOptionsValuesCancel != undefined) + this.getOptionsValuesCancel.cancel('Facet search Canceled.'); + if ( this.type === 'Tainacan\\Metadata_Types\\Relationship' ) { let collectionTarget = ( this.metadatum_object && this.metadatum_object.metadata_type_options.collection_id ) ? this.metadatum_object.metadata_type_options.collection_id : this.collection_id; promise = this.getValuesRelationship( collectionTarget, query, valuesToIgnore ); - + } else { promise = this.getValuesPlainText( this.metadatum, query, this.isRepositoryLevel, valuesToIgnore ); } - promise - .catch( error => { - this.$console.log('error select', error ); - }); + promise.request + .catch( error => { + this.$console.log('error select', error ); + }); + + // Search Request Token for cancelling + this.getOptionsValuesCancel = promise.source; + }, 500), selectedValues(){ const instance = this; diff --git a/src/js/store/modules/collection/actions.js b/src/js/store/modules/collection/actions.js index 3c8f09082..61b956128 100644 --- a/src/js/store/modules/collection/actions.js +++ b/src/js/store/modules/collection/actions.js @@ -104,7 +104,6 @@ export const fetchItems = ({ rootGetters, dispatch, commit }, { collectionId, is }), source: source }) - }; export const deleteItem = ({ commit }, { itemId, isPermanently }) => {