Search.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <template>
  2. <div id="search" class="col-11" :class="{ loading: isloading }">
  3. <form class="search-form row">
  4. <fieldset class="search">
  5. <div>
  6. <label for="keys">Search</label>
  7. <input
  8. id="keys"
  9. v-model="keys"
  10. type="text"
  11. placeholder="search"
  12. @keydown.enter.prevent="submit"
  13. >
  14. <v-select
  15. id="search-type"
  16. type="select"
  17. placeholder="dans ..."
  18. append-to-body
  19. :calculate-position="dropDownMenuPos"
  20. :options="searchTypeOptions"
  21. :clearable="false"
  22. :value="searchTypeValue"
  23. @input="onSearchTypeSelected"
  24. />
  25. </div>
  26. <span
  27. v-if="!isloading"
  28. class="mdi mdi-magnify"
  29. title="rechercher"
  30. @click.prevent="submit"
  31. @keydown.enter.prevent="submit"
  32. />
  33. <span
  34. v-else
  35. class="mdi mdi-loading"
  36. title="chargement"
  37. />
  38. </fieldset>
  39. <fieldset v-if="filters.persons.length" class="filters filters-nominum col-2">
  40. <v-select
  41. id="filters-nominum"
  42. type="select"
  43. placeholder="filtrer par personne"
  44. append-to-body
  45. :calculate-position="dropDownMenuPos"
  46. :options="personsOptions"
  47. :value="activeFilters.persons"
  48. multiple
  49. @input="onFiltersNominumSelected"
  50. />
  51. </fieldset>
  52. <fieldset v-if="filters.places.length" class="filters filters-locorum col-2">
  53. <v-select
  54. id="filters-locorum"
  55. type="select"
  56. placeholder="filtrer par lieux"
  57. append-to-body
  58. :calculate-position="dropDownMenuPos"
  59. :options="placesOptions"
  60. :value="activeFilters.places"
  61. multiple
  62. @input="onFiltersLocorumSelected"
  63. />
  64. </fieldset>
  65. <fieldset v-if="filters.objects.length" class="filters filters-operum col-2">
  66. <v-select
  67. id="filters-operum"
  68. type="select"
  69. placeholder="filtrer par objet"
  70. append-to-body
  71. :calculate-position="dropDownMenuPos"
  72. :options="objectsOptions"
  73. :value="activeFilters.objects"
  74. multiple
  75. @input="onFiltersOperumSelected"
  76. />
  77. </fieldset>
  78. </form>
  79. </div>
  80. </template>
  81. <script>
  82. import { createPopper } from '@popperjs/core'
  83. import { mapActions, mapMutations, mapState } from 'vuex'
  84. export default {
  85. name: 'Search',
  86. data: () => ({
  87. }),
  88. computed: {
  89. keys: {
  90. get () { return this.$store.state.Search.keys },
  91. set (value) { this.$store.commit('Search/setKeys', value) }
  92. },
  93. ...mapState({
  94. isloading: state => state.Search.isloading,
  95. searchTypeOptions: state => state.Search.searchTypeOptions,
  96. searchTypeValue: state => state.Search.searchTypeValue,
  97. filters: state => state.Search.filters,
  98. activeFilters: state => state.Search.activeFilters,
  99. corpusLoaded: state => state.Corpus.corpusLoaded
  100. }),
  101. personsOptions () {
  102. return this.filters.persons.filter(option => !this.activeFilters.persons.includes(option))
  103. },
  104. placesOptions () {
  105. return this.filters.places.filter(option => !this.activeFilters.places.includes(option))
  106. },
  107. objectsOptions () {
  108. return this.filters.objects.filter(option => !this.activeFilters.objects.includes(option))
  109. }
  110. },
  111. methods: {
  112. ...mapMutations({
  113. setActiveFilters: 'Search/setActiveFilters'
  114. }),
  115. ...mapActions({
  116. newSearch: 'Search/newSearch',
  117. setSearchTypeValue: 'Search/setSearchTypeValue',
  118. updateSearch: 'Search/updateSearch'
  119. }),
  120. submit () {
  121. console.log('submited', this.keys)
  122. this.newSearch()
  123. },
  124. dropDownMenuPos (dropdownList, component, { width }) {
  125. /**
  126. * We need to explicitly define the dropdown width since
  127. * it is usually inherited from the parent with CSS.
  128. */
  129. dropdownList.style.width = width
  130. /**
  131. * Here we position the dropdownList relative to the $refs.toggle Element.
  132. *
  133. * The 'offset' modifier aligns the dropdown so that the $refs.toggle and
  134. * the dropdownList overlap by 1 pixel.
  135. *
  136. * The 'toggleClass' modifier adds a 'drop-up' class to the Vue Select
  137. * wrapper so that we can set some styles for when the dropdown is placed
  138. * above.
  139. */
  140. const popper = createPopper(component.$refs.toggle, dropdownList, {
  141. placement: 'top',
  142. modifiers: [
  143. {
  144. name: 'offset',
  145. options: {
  146. offset: [0, -1]
  147. }
  148. },
  149. {
  150. name: 'toggleClass',
  151. enabled: true,
  152. phase: 'write',
  153. fn ({ state }) {
  154. component.$el.classList.toggle('drop-up', state.placement === 'top')
  155. }
  156. }]
  157. })
  158. /**
  159. * To prevent memory leaks Popper needs to be destroyed.
  160. * If you return function, it will be called just before dropdown is removed from DOM.
  161. */
  162. return () => popper.destroy()
  163. },
  164. onSearchTypeSelected (e) {
  165. console.log('onSearchTypeSelected', e)
  166. this.setSearchTypeValue(e)
  167. },
  168. onFiltersNominumSelected (e) {
  169. console.log('onFiltersNominumSelected', e)
  170. this.setActiveFilters({ index: 'persons', value: e })
  171. this.updateSearch()
  172. },
  173. onFiltersLocorumSelected (e) {
  174. console.log('onFiltersLocorumSelected', e)
  175. this.setActiveFilters({ index: 'places', value: e })
  176. this.updateSearch()
  177. },
  178. onFiltersOperumSelected (e) {
  179. console.log('onFiltersOperumSelected', e)
  180. this.setActiveFilters({ index: 'objects', value: e })
  181. this.updateSearch()
  182. }
  183. }
  184. }
  185. </script>
  186. <style lang="scss" scoped>
  187. </style>