search.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. import axios from 'axios'
  2. import { REST } from 'api/rest-axios'
  3. import qs from 'querystring'
  4. const _filterskeys = ['persons', 'places', 'objects', 'texts']
  5. const _CancelToken = axios.CancelToken
  6. // const _cancelTokenSource = _CancelToken.source()
  7. let _cancelTokens = []
  8. export default {
  9. namespaced: true,
  10. testconst: 'Hello',
  11. // initial state
  12. state: {
  13. keys: '',
  14. searchedKeys: '',
  15. searchTypeOptions: [
  16. { 'code': 'text', 'label': 'Dans les textes' },
  17. { 'code': 'persons', 'label': 'Dans les personnes' },
  18. { 'code': 'places', 'label': 'Dans les lieux' },
  19. { 'code': 'objects', 'label': 'Dans les œuvres' }
  20. ],
  21. searchTypeValue: { 'code': 'text', 'label': 'Dans les textes' },
  22. filters: { persons: [], places: [], objects: [], texts: [] },
  23. activeFilters: { persons: [], places: [], objects: [], texts: [] },
  24. sortOptions: [
  25. { code: 'date', label: 'date' },
  26. { code: 'score', label: 'pertinence' },
  27. { code: 'size', label: 'nombre de mots' }
  28. ],
  29. sorting: null,
  30. results: [],
  31. resultsQuantity: null,
  32. isloading: false,
  33. limit: 10,
  34. offset: 0,
  35. opened: false
  36. },
  37. // getters
  38. getters: {},
  39. // mutations
  40. mutations: {
  41. setKeys (state, keys) {
  42. state.keys = keys
  43. },
  44. setSearchKeys (state) {
  45. state.searchedKeys = state.keys
  46. },
  47. setResults (state, content) {
  48. state.results = state.results.concat(content)
  49. },
  50. resetResults (state) {
  51. console.log('resetResults')
  52. state.results = []
  53. },
  54. resetOffset (state) {
  55. state.offset = 0
  56. },
  57. setResultsCount (state, quantity) {
  58. state.resultsQuantity = quantity
  59. },
  60. incrementOffset (state) {
  61. state.offset += state.limit
  62. },
  63. setIsloading (state, isloading) {
  64. console.log('setIsloading', isloading)
  65. state.isloading = isloading
  66. },
  67. setOpened (state, opened) {
  68. state.opened = opened
  69. },
  70. setSearchTypeValue (state, value) {
  71. state.searchTypeValue = value
  72. },
  73. setFilters (state, filters) {
  74. for (let filter in filters) {
  75. if (filters.hasOwnProperty(filter)) {
  76. console.log('filter', filter)
  77. if (filters[filter]) {
  78. if (Array.isArray(filters[filter])) {
  79. state.filters[filter] = []
  80. for (var i = 0; i < filters[filter].length; i++) {
  81. if (filters[filter][i].uuid && filters[filter][i].title) {
  82. state.filters[filter].push({
  83. code: filters[filter][i].uuid,
  84. label: `${filters[filter][i].title} [${filters[filter][i].quantity}]`
  85. })
  86. }
  87. }
  88. } else {
  89. if (filters[filter].uuid && filters[filter].title) {
  90. state.filters[filter] = [{
  91. code: filters[filter].uuid,
  92. label: filters[filter].title
  93. }]
  94. }
  95. }
  96. } else {
  97. state.filters[filter] = []
  98. }
  99. }
  100. }
  101. console.log('filters', state.filters)
  102. },
  103. setActiveFilters (state, filters) {
  104. // console.log('setActiveFilters', filters)
  105. state.activeFilters[filters.filter] = filters.value
  106. // console.log('state.activeFilters', state.activeFilters)
  107. },
  108. resetActiveFilters (state) {
  109. for (var index of _filterskeys) {
  110. state.activeFilters[index] = []
  111. }
  112. },
  113. setSorting (state, sort) {
  114. console.log('setSorting', sort)
  115. state.sorting = sort
  116. }
  117. },
  118. // actions
  119. actions: {
  120. getResults ({ dispatch, commit, state }, pl) {
  121. console.log(`getResults keys: ${pl.keys}, infiniteLoading:`, pl.infiniteLoading)
  122. if (!pl.infiniteLoading) {
  123. // loading indicator unless we are on infiniteloading
  124. commit('setIsloading', true)
  125. commit('resetOffset')
  126. // cancel infiniteloading requests
  127. _cancelTokens.forEach((ct, i) => {
  128. console.log('_cancelTokens forEach ct', ct)
  129. ct.cancel('new or updated search fired')
  130. })
  131. }
  132. // construct params
  133. let params = {
  134. search: `${pl.keys}`,
  135. start: state.offset,
  136. count: state.limit
  137. }
  138. if (state.searchTypeValue.code !== 'text') {
  139. params.type = state.searchTypeValue.code
  140. }
  141. let f
  142. for (var filter of _filterskeys) {
  143. // console.log(`state.activeFilters[${filter}]`, state.activeFilters[filter])
  144. if (state.activeFilters[filter].length) {
  145. f = filter === 'texts' ? 'text' : `filter${filter.charAt(0).toUpperCase()}${filter.slice(1)}`
  146. params[f] = []
  147. for (var i = 0; i < state.activeFilters[filter].length; i++) {
  148. params[f].push(state.activeFilters[filter][i].code)
  149. }
  150. }
  151. }
  152. if (state.sorting) {
  153. params.sort = state.sorting.code
  154. }
  155. console.log('Search getResults params', params)
  156. let q = qs.stringify(params)
  157. // construct options
  158. let ops = {}
  159. if (pl.infiniteLoading) {
  160. ops.cancelToken = pl.infiniteLoading.cancelToken
  161. }
  162. return REST.get(`${window.apipath}/search?` + q, ops)
  163. .then(({ data }) => {
  164. console.log(`search REST quantity: ${data.meta.quantity.quantity}, offset+limit: ${state.offset + state.limit}, data:`, data)
  165. commit('setResultsCount', data.meta.quantity)
  166. commit('setFilters', data.meta.filters)
  167. if (state.isloading) {
  168. // a new or updated search has been launched :
  169. // we dont apply the infinite loading received results
  170. // and we reset the infinite loader
  171. // pl.infiniteLoading.$state.reset()
  172. _cancelTokens.forEach((ct, i) => {
  173. console.log('_cancelTokens forEach AFTER ct', ct)
  174. ct.cancel('new or updated search fired')
  175. ct.$state.complete()
  176. })
  177. _cancelTokens = []
  178. }
  179. if (!pl.infiniteLoading) {
  180. // we are not on infiniteloading
  181. // new or updated search
  182. commit('resetResults')
  183. commit('setSearchKeys')
  184. commit('setResults', data.content)
  185. commit('setIsloading', false)
  186. commit('setOpened', true)
  187. } else {
  188. // we are on infiniteloading
  189. // normal InfiniteLoading procedure
  190. commit('setResults', data.content)
  191. if (state.offset + state.limit > data.meta.quantity.quantity) {
  192. // tell to vue-infinite-loading plugin that there is no new page
  193. pl.infiniteLoading.$state.complete()
  194. } else {
  195. // tell to vue-infinite-loading plugin that newpage is loaded
  196. pl.infiniteLoading.$state.loaded()
  197. }
  198. }
  199. })
  200. .catch((error) => {
  201. // console.warn('Issue with search', error)
  202. if (axios.isCancel(error)) {
  203. console.info(`Request canceled, message: ${error.message}`)
  204. // TODO: the $state here is probably not the good one
  205. // Promise.reject(error)
  206. // pl.infiniteLoading.$state.reset()
  207. } else {
  208. commit('setIsloading', false)
  209. if (pl.infiniteLoading) {
  210. pl.infiniteLoading.$state.error()
  211. }
  212. Promise.reject(error)
  213. }
  214. })
  215. },
  216. newSearch ({ dispatch, commit, state }) {
  217. commit('resetActiveFilters')
  218. dispatch('getResults', { keys: state.keys })
  219. // .then((e) => {
  220. // console.log('dispatch get results then', e)
  221. // })
  222. },
  223. updateSearch ({ dispatch, commit, state }) {
  224. dispatch('getResults', { keys: state.searchedKeys })
  225. },
  226. nextResultsBatch ({ dispatch, commit, state }, $infiniteLoadingState) {
  227. console.log(`nextResultsBatch, isloading: ${state.isloading}`, $infiniteLoadingState)
  228. if (state.isloading) {
  229. // we are loading a new or updated searche
  230. // we stop the infinite
  231. $infiniteLoadingState.complete()
  232. } else {
  233. commit('incrementOffset')
  234. if (state.offset < state.resultsQuantity.quantity) {
  235. dispatch('getResults', {
  236. keys: state.searchedKeys,
  237. infiniteLoading: {
  238. $state: $infiniteLoadingState,
  239. cancelToken: new _CancelToken((c) => {
  240. _cancelTokens.push({
  241. cancel: c,
  242. $state: $infiniteLoadingState
  243. })
  244. })
  245. }
  246. })
  247. } else {
  248. $infiniteLoadingState.complete()
  249. }
  250. }
  251. }
  252. }
  253. }