search.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. import axios from 'axios'
  2. import { REST } from 'api/rest-axios'
  3. import qs from 'querystring'
  4. const _filterskeys = ['persons', 'places', 'objects']
  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 objets' }
  20. ],
  21. searchTypeValue: { 'code': 'text', 'label': 'Dans les textes' },
  22. filters: { persons: [], places: [], objects: [] },
  23. activeFilters: { persons: [], places: [], objects: [] },
  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 index in filters) {
  75. if (filters.hasOwnProperty(index)) {
  76. console.log('index', index)
  77. if (filters[index]) {
  78. if (Array.isArray(filters[index])) {
  79. state.filters[index] = []
  80. for (var i = 0; i < filters[index].length; i++) {
  81. if (filters[index][i].uuid && filters[index][i].title) {
  82. state.filters[index].push({
  83. code: filters[index][i].uuid,
  84. label: filters[index][i].title
  85. })
  86. }
  87. }
  88. } else {
  89. if (filters[index].uuid && filters[index].title) {
  90. state.filters[index] = [{
  91. code: filters[index].uuid,
  92. label: filters[index].title
  93. }]
  94. }
  95. }
  96. } else {
  97. state.filters[index] = []
  98. }
  99. }
  100. }
  101. console.log('filters', state.filters)
  102. },
  103. setActiveFilters (state, filters) {
  104. // console.log('setActiveFilters', filters)
  105. state.activeFilters[filters.index] = 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 index of _filterskeys) {
  143. if (state.activeFilters[index].length) {
  144. f = `filter${index.charAt(0).toUpperCase()}${index.slice(1)}`
  145. params[f] = []
  146. for (var i = 0; i < state.activeFilters[index].length; i++) {
  147. params[f].push(state.activeFilters[index][i].code)
  148. }
  149. }
  150. }
  151. if (state.sorting) {
  152. params.sort = state.sorting.code
  153. }
  154. // console.log('Search getResults params', params);
  155. let q = qs.stringify(params)
  156. // construct options
  157. let ops = {}
  158. if (pl.infiniteLoading) {
  159. ops.cancelToken = pl.infiniteLoading.cancelToken
  160. }
  161. return REST.get(`${window.apipath}/search?` + q, ops)
  162. .then(({ data }) => {
  163. console.log(`search REST quantity: ${data.meta.quantity.quantity}, offset+limit: ${state.offset + state.limit}, data:`, data)
  164. commit('setResultsCount', data.meta.quantity)
  165. commit('setFilters', data.meta.filters)
  166. if (state.isloading) {
  167. // a new or updated search has been launched :
  168. // we dont apply the infinite loading received results
  169. // and we reset the infinite loader
  170. // pl.infiniteLoading.$state.reset()
  171. _cancelTokens.forEach((ct, i) => {
  172. console.log('_cancelTokens forEach AFTER ct', ct)
  173. ct.cancel('new or updated search fired')
  174. ct.$state.complete()
  175. })
  176. _cancelTokens = []
  177. }
  178. if (!pl.infiniteLoading) {
  179. // we are not on infiniteloading
  180. // new or updated search
  181. commit('resetResults')
  182. commit('setSearchKeys')
  183. commit('setResults', data.content)
  184. commit('setIsloading', false)
  185. commit('setOpened', true)
  186. } else {
  187. // we are on infiniteloading
  188. // normal InfiniteLoading procedure
  189. commit('setResults', data.content)
  190. if (state.offset + state.limit > data.meta.quantity.quantity) {
  191. // tell to vue-infinite-loading plugin that there is no new page
  192. pl.infiniteLoading.$state.complete()
  193. } else {
  194. // tell to vue-infinite-loading plugin that newpage is loaded
  195. pl.infiniteLoading.$state.loaded()
  196. }
  197. }
  198. })
  199. .catch((error) => {
  200. // console.warn('Issue with search', error)
  201. if (axios.isCancel(error)) {
  202. console.info(`Request canceled, message: ${error.message}`)
  203. // TODO: the $state here is probably not the good one
  204. // Promise.reject(error)
  205. // pl.infiniteLoading.$state.reset()
  206. } else {
  207. commit('setIsloading', false)
  208. if (pl.infiniteLoading) {
  209. pl.infiniteLoading.$state.error()
  210. }
  211. Promise.reject(error)
  212. }
  213. })
  214. },
  215. newSearch ({ dispatch, commit, state }) {
  216. commit('resetActiveFilters')
  217. dispatch('getResults', { keys: state.keys })
  218. // .then((e) => {
  219. // console.log('dispatch get results then', e)
  220. // })
  221. },
  222. updateSearch ({ dispatch, commit, state }) {
  223. dispatch('getResults', { keys: state.searchedKeys })
  224. },
  225. nextResultsBatch ({ dispatch, commit, state }, $infiniteLoadingState) {
  226. console.log(`nextResultsBatch, isloading: ${state.isloading}`, $infiniteLoadingState)
  227. if (state.isloading) {
  228. // we are loading a new or updated searche
  229. // we stop the infinite
  230. $infiniteLoadingState.complete()
  231. } else {
  232. commit('incrementOffset')
  233. if (state.offset < state.resultsQuantity.quantity) {
  234. dispatch('getResults', {
  235. keys: state.searchedKeys,
  236. infiniteLoading: {
  237. $state: $infiniteLoadingState,
  238. cancelToken: new _CancelToken((c) => {
  239. _cancelTokens.push({
  240. cancel: c,
  241. $state: $infiniteLoadingState
  242. })
  243. })
  244. }
  245. })
  246. } else {
  247. $infiniteLoadingState.complete()
  248. }
  249. }
  250. }
  251. }
  252. }