refactored search, resolve #821

This commit is contained in:
2020-07-26 13:33:22 +02:00
parent 3ed132147c
commit c29b86a5ae
5 changed files with 118 additions and 89 deletions
+3 -3
View File
@@ -8,7 +8,7 @@
> >
<header class="col-1"> <header class="col-1">
<h2>Resultats</h2> <h2>Resultats</h2>
<span class="search-keys">{{ keys }}</span><br> <span class="search-keys">{{ searchedKeys }}</span><br>
<span v-if="resultsQuantity" class="results-count">{{ resultsCount }}</span> <span v-if="resultsQuantity" class="results-count">{{ resultsCount }}</span>
<v-select <v-select
id="sorting" id="sorting"
@@ -29,8 +29,8 @@
</li> </li>
<infinite-loading <infinite-loading
v-if="offset < resultsQuantity.quantity" v-if="offset < resultsQuantity.quantity"
@infinite="nextResultsBatch"
:identifier="isloading" :identifier="isloading"
@infinite="nextResultsBatch"
/> />
</ul> </ul>
</div> </div>
@@ -68,7 +68,7 @@ export default {
}, },
...mapState({ ...mapState({
isloading: state => state.Search.isloading, isloading: state => state.Search.isloading,
keys: state => state.Search.keys, searchedKeys: state => state.Search.searchedKeys,
results: state => state.Search.results, results: state => state.Search.results,
resultsQuantity: state => state.Search.resultsQuantity, resultsQuantity: state => state.Search.resultsQuantity,
offset: state => state.Search.offset, offset: state => state.Search.offset,
+3 -2
View File
@@ -91,6 +91,7 @@ export default {
data: () => ({ data: () => ({
}), }),
computed: { computed: {
// TODO: do not synch keys instantetly (infinite loading will drop)
keys: { keys: {
get () { return this.$store.state.Search.keys }, get () { return this.$store.state.Search.keys },
set (value) { this.$store.commit('Search/setKeys', value) } set (value) { this.$store.commit('Search/setKeys', value) }
@@ -115,15 +116,15 @@ export default {
}, },
methods: { methods: {
...mapMutations({ ...mapMutations({
setSearchTypeValue: 'Search/setSearchTypeValue',
setActiveFilters: 'Search/setActiveFilters' setActiveFilters: 'Search/setActiveFilters'
}), }),
...mapActions({ ...mapActions({
newSearch: 'Search/newSearch', newSearch: 'Search/newSearch',
setSearchTypeValue: 'Search/setSearchTypeValue',
updateSearch: 'Search/updateSearch' updateSearch: 'Search/updateSearch'
}), }),
submit () { submit () {
console.log('submited', this.keys) // console.log('submited', this.keys)
this.newSearch() this.newSearch()
}, },
dropDownMenuPos (dropdownList, component, { width }) { dropDownMenuPos (dropdownList, component, { width }) {
+2 -1
View File
@@ -22,7 +22,8 @@ Vue.use(InfiniteLoading, {
}, },
slots: { slots: {
noMore: '', noMore: '',
noResult: '' noResults: '',
error: ''
} }
// system: { // system: {
// throttleLimit: 50, // throttleLimit: 50,
+7 -6
View File
@@ -34,7 +34,7 @@ export default {
console.log('corpus editionsbyuuid', state.editionsbyuuid) console.log('corpus editionsbyuuid', state.editionsbyuuid)
}, },
setTocs (state, tocslist) { setTocs (state, tocslist) {
console.log('setTocs', tocslist) // console.log('setTocs', tocslist)
tocslist.forEach((toc, i) => { tocslist.forEach((toc, i) => {
state.editionsbyuuid[toc.uuid].toc = Array.isArray(toc.toc) ? toc.toc : [toc.toc] state.editionsbyuuid[toc.uuid].toc = Array.isArray(toc.toc) ? toc.toc : [toc.toc]
}) })
@@ -58,13 +58,14 @@ export default {
}) })
}, },
setPaginations (state, paginationslist) { setPaginations (state, paginationslist) {
console.log('setPaginations', paginationslist) // console.log('setPaginations', paginationslist)
paginationslist.forEach((pagination, i) => { paginationslist.forEach((pagination, i) => {
state.editionsbyuuid[pagination.uuid].pagination = pagination.pagination state.editionsbyuuid[pagination.uuid].pagination = pagination.pagination
}) })
// console.log('corpus editionsbyuuid', state.editionsbyuuid) // console.log('corpus editionsbyuuid', state.editionsbyuuid)
}, },
setCorpusLoaded (state) { setCorpusLoaded (state) {
console.info('corpusLoaded')
state.corpusLoaded = true state.corpusLoaded = true
} }
}, },
@@ -76,7 +77,7 @@ export default {
// get the list of corpuses (aka authors) // get the list of corpuses (aka authors)
dispatch('getAuthors') dispatch('getAuthors')
.then(({ data }) => { .then(({ data }) => {
console.log('getCorpuses authors data', data) // console.log('getCorpuses authors data', data)
commit('setAuthors', data.content) commit('setAuthors', data.content)
// get the texts list for each corpus (aka author) // get the texts list for each corpus (aka author)
// let authorsUuids = [] // let authorsUuids = []
@@ -124,7 +125,7 @@ export default {
return Promise.all(authors.map(function (author) { return Promise.all(authors.map(function (author) {
return REST.get(`${window.apipath}/corpus/` + author.uuid, {}) return REST.get(`${window.apipath}/corpus/` + author.uuid, {})
.then(({ data }) => { .then(({ data }) => {
console.log('corpus getEditionsList REST: author, data', author, data) // console.log('corpus getEditionsList REST: author, data', author, data)
// work arround // work arround
if (!Array.isArray(data.content)) { if (!Array.isArray(data.content)) {
data.content = [data.content] data.content = [data.content]
@@ -145,7 +146,7 @@ export default {
return Promise.all(state.editionsuuids.map(function (uuid) { return Promise.all(state.editionsuuids.map(function (uuid) {
return REST.get(`${window.apipath}/texts/${uuid}/toc`, {}) return REST.get(`${window.apipath}/texts/${uuid}/toc`, {})
.then(({ data }) => { .then(({ data }) => {
console.log('corpus getEditionsTocs REST: uuid, data', uuid, data) // console.log('corpus getEditionsTocs REST: uuid, data', uuid, data)
// work arround // work arround
// if (!Array.isArray(data.content)) { // if (!Array.isArray(data.content)) {
// data.content = [data.content] // data.content = [data.content]
@@ -166,7 +167,7 @@ export default {
return Promise.all(state.editionsuuids.map(function (uuid) { return Promise.all(state.editionsuuids.map(function (uuid) {
return REST.get(`${window.apipath}/texts/${uuid}/pagination`, {}) return REST.get(`${window.apipath}/texts/${uuid}/pagination`, {})
.then(({ data }) => { .then(({ data }) => {
console.log('corpus getEditionsPaginations REST: uuid, data', uuid, data) // console.log('corpus getEditionsPaginations REST: uuid, data', uuid, data)
// work arround // work arround
// if (!Array.isArray(data.content)) { // if (!Array.isArray(data.content)) {
// data.content = [data.content] // data.content = [data.content]
+103 -77
View File
@@ -1,11 +1,12 @@
// import axios from 'axios' import axios from 'axios'
import { REST } from 'api/rest-axios' import { REST } from 'api/rest-axios'
import qs from 'querystring' import qs from 'querystring'
// const _CancelToken = axios.CancelToken const _filterskeys = ['persons', 'places', 'objects']
const _CancelToken = axios.CancelToken
// const _cancelTokenSource = _CancelToken.source() // const _cancelTokenSource = _CancelToken.source()
// let _cancel let _cancelTokens = []
export default { export default {
namespaced: true, namespaced: true,
@@ -14,6 +15,7 @@ export default {
// initial state // initial state
state: { state: {
keys: '', keys: '',
searchedKeys: '',
searchTypeOptions: [ searchTypeOptions: [
{ 'code': 'text', 'label': 'Dans les textes' }, { 'code': 'text', 'label': 'Dans les textes' },
{ 'code': 'persons', 'label': 'Dans les personnes' }, { 'code': 'persons', 'label': 'Dans les personnes' },
@@ -32,9 +34,6 @@ export default {
results: [], results: [],
resultsQuantity: null, resultsQuantity: null,
isloading: false, isloading: false,
// infiniteLoadingIsLoading: false,
// infiniteLoadingCancelToken: null,
// infiniteLoadingCancelTokenSource: null,
limit: 10, limit: 10,
offset: 0, offset: 0,
opened: false opened: false
@@ -48,11 +47,17 @@ export default {
setKeys (state, keys) { setKeys (state, keys) {
state.keys = keys state.keys = keys
}, },
setSearchKeys (state) {
state.searchedKeys = state.keys
},
setResults (state, content) { setResults (state, content) {
state.results = state.results.concat(content) state.results = state.results.concat(content)
}, },
resetResults (state) { resetResults (state) {
console.log('resetResults')
state.results = [] state.results = []
},
resetOffset (state) {
state.offset = 0 state.offset = 0
}, },
setResultsCount (state, quantity) { setResultsCount (state, quantity) {
@@ -62,6 +67,7 @@ export default {
state.offset += state.limit state.offset += state.limit
}, },
setIsloading (state, isloading) { setIsloading (state, isloading) {
console.log('setIsloading', isloading)
state.isloading = isloading state.isloading = isloading
}, },
setOpened (state, opened) { setOpened (state, opened) {
@@ -106,7 +112,7 @@ export default {
// console.log('state.activeFilters', state.activeFilters) // console.log('state.activeFilters', state.activeFilters)
}, },
resetActiveFilters (state) { resetActiveFilters (state) {
for (var index of ['persons', 'places', 'objects']) { for (var index of _filterskeys) {
state.activeFilters[index] = [] state.activeFilters[index] = []
} }
}, },
@@ -118,18 +124,23 @@ export default {
// actions // actions
actions: { actions: {
getResults ({ dispatch, commit, state }, $infiniteLoadingState = null) { getResults ({ dispatch, commit, state }, pl) {
console.log('getResults', state.keys, $infiniteLoadingState) console.log(`getResults keys: ${pl.keys}, infiniteLoading:`, pl.infiniteLoading)
// reset results on new search
if (!$infiniteLoadingState) {
commit('setIsloading', true)
}
// else {
// state.infiniteLoadingIsLoading = true
// }
if (!pl.infiniteLoading) {
// loading indicator unless we are on infiniteloading
commit('setIsloading', true)
commit('resetOffset')
// cancel infiniteloading requests
_cancelTokens.forEach((ct, i) => {
console.log('_cancelTokens forEach ct', ct)
ct.cancel('new or updated search fired')
})
}
// construct params
let params = { let params = {
search: `${state.keys}`, search: `${pl.keys}`,
start: state.offset, start: state.offset,
count: state.limit count: state.limit
} }
@@ -137,7 +148,7 @@ export default {
params.type = state.searchTypeValue.code params.type = state.searchTypeValue.code
} }
let f let f
for (var index of ['persons', 'places', 'objects']) { for (var index of _filterskeys) {
if (state.activeFilters[index].length) { if (state.activeFilters[index].length) {
f = `filter${index.charAt(0).toUpperCase()}${index.slice(1)}` f = `filter${index.charAt(0).toUpperCase()}${index.slice(1)}`
params[f] = [] params[f] = []
@@ -146,94 +157,109 @@ export default {
} }
} }
} }
// params.filterPersons = ['nomLouisXIII', 'nomChampagnePhilippeDe']
if (state.sorting) { if (state.sorting) {
params.sort = state.sorting.code params.sort = state.sorting.code
} }
// console.log('Search getResults params', params); // console.log('Search getResults params', params);
let q = qs.stringify(params) let q = qs.stringify(params)
// construct options
let ops = {} let ops = {}
// if ($infiniteLoadingState) { if (pl.infiniteLoading) {
// ops.cancelToken = new _CancelToken(function executor (c) { ops.cancelToken = pl.infiniteLoading.cancelToken
// _cancel = c }
// })
// }
return REST.get(`${window.apipath}/search?` + q, ops) return REST.get(`${window.apipath}/search?` + q, ops)
.then(({ data }) => { .then(({ data }) => {
console.log('search REST: data', data.meta.quantity.quantity, state.offset + state.limit, data) console.log(`search REST quantity: ${data.meta.quantity.quantity}, offset+limit: ${state.offset + state.limit}, data:`, data)
commit('setResultsCount', data.meta.quantity) commit('setResultsCount', data.meta.quantity)
commit('setFilters', data.meta.filters) commit('setFilters', data.meta.filters)
if ($infiniteLoadingState) {
if (state.isLoading) { if (state.isloading) {
// we are in a new search or an update so we dont apply the infinite loading received results // a new or updated search has been launched :
$infiniteLoadingState.complete() // we dont apply the infinite loading received results
} else { // and we reset the infinite loader
commit('setResults', data.content) // pl.infiniteLoading.$state.reset()
if (state.offset + state.limit > data.meta.quantity.quantity) { _cancelTokens.forEach((ct, i) => {
console.log('Search infinite completed') console.log('_cancelTokens forEach AFTER ct', ct)
// tell to vue-infinite-loading plugin that there si no new page ct.cancel('new or updated search fired')
$infiniteLoadingState.complete() ct.$state.complete()
} else { })
console.log('Search infinite loaded') _cancelTokens = []
// tell to vue-infinite-loading plugin that newpage is loaded }
$infiniteLoadingState.loaded()
} if (!pl.infiniteLoading) {
// state.infiniteLoadingIsLoading = false // we are not on infiniteloading
} // new or updated search
} else {
commit('resetResults') commit('resetResults')
commit('setSearchKeys')
commit('setResults', data.content)
commit('setIsloading', false) commit('setIsloading', false)
commit('setOpened', true) commit('setOpened', true)
} else {
// we are on infiniteloading
// normal InfiniteLoading procedure
commit('setResults', data.content) commit('setResults', data.content)
if (state.offset + state.limit > data.meta.quantity.quantity) {
// tell to vue-infinite-loading plugin that there is no new page
pl.infiniteLoading.$state.complete()
} else {
// tell to vue-infinite-loading plugin that newpage is loaded
pl.infiniteLoading.$state.loaded()
}
} }
}) })
.catch((error) => { .catch((error) => {
console.warn('Issue with search', error) // console.warn('Issue with search', error)
commit('setIsloading', false) if (axios.isCancel(error)) {
// if (axios.isCancel(error)) { console.info(`Request canceled, message: ${error.message}`)
// console.log('Request canceled', error.message) // TODO: the $state here is probably not the good one
// if ($infiniteLoadingState) { // Promise.reject(error)
// $infiniteLoadingState.complete() // pl.infiniteLoading.$state.reset()
// } } else {
// } else { commit('setIsloading', false)
Promise.reject(error) if (pl.infiniteLoading) {
if ($infiniteLoadingState) { pl.infiniteLoading.$state.error()
$infiniteLoadingState.error() }
Promise.reject(error)
} }
// }
}) })
}, },
newSearch ({ dispatch, commit, state }) { newSearch ({ dispatch, commit, state }) {
// commit('resetResults')
commit('resetActiveFilters') commit('resetActiveFilters')
// if (_cancel) { dispatch('getResults', { keys: state.keys })
// _cancel('new search fired') // .then((e) => {
// } // console.log('dispatch get results then', e)
dispatch('getResults') // })
}, },
updateSearch ({ dispatch, commit, state }) { updateSearch ({ dispatch, commit, state }) {
// TODO: wait for new results came to reset results list dispatch('getResults', { keys: state.searchedKeys })
// TODO: indicate loading state
// commit('resetResults')
dispatch('getResults')
}, },
nextResultsBatch ({ dispatch, commit, state }, $infiniteLoadingState) { nextResultsBatch ({ dispatch, commit, state }, $infiniteLoadingState) {
console.log('nextResultsBatch', $infiniteLoadingState) console.log(`nextResultsBatch, isloading: ${state.isloading}`, $infiniteLoadingState)
commit('incrementOffset') if (state.isloading) {
if (state.offset < state.resultsQuantity.quantity) { // we are loading a new or updated searche
dispatch('getResults', $infiniteLoadingState) // we stop the infinite
} else {
$infiniteLoadingState.complete() $infiniteLoadingState.complete()
} else {
commit('incrementOffset')
if (state.offset < state.resultsQuantity.quantity) {
dispatch('getResults', {
keys: state.searchedKeys,
infiniteLoading: {
$state: $infiniteLoadingState,
cancelToken: new _CancelToken((c) => {
_cancelTokens.push({
cancel: c,
$state: $infiniteLoadingState
})
})
}
})
} else {
$infiniteLoadingState.complete()
}
} }
},
setSearchTypeValue ({ dispatch, commit, state }, value) {
commit('setSearchTypeValue', value)
} }
// setSearchActiveFilters ({ dispatch, commit, state }, filters) {
// // console.log('setSearchFiltersValue', filters)
// commit('setActiveFilters', filters)
// dispatch('updateSearch')
// }
} }
} }