Results.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <template>
  2. <transition name="accordeon" appear>
  3. <div
  4. v-if="opened"
  5. id="results"
  6. class="row"
  7. :class="{ loading: isloading }"
  8. >
  9. <header class="small-col-12 med-col-1 large-col-1">
  10. <h2>Resultats</h2>
  11. <div class="results-details">
  12. <span class="search-keys">{{ searchedKeys }}</span>
  13. <span v-if="resultsQuantity" class="results-count">{{ resultsCount }}</span>
  14. </div>
  15. <v-select
  16. id="sorting"
  17. type="select"
  18. placeholder="trier par"
  19. append-to-body
  20. :calculate-position="dropDownMenuPos"
  21. :options="sortOptions"
  22. :value="sorting"
  23. @input="onSortingSelected"
  24. />
  25. </header>
  26. <section class="small-col-12 med-col-10 large-col-10 results-list">
  27. <div class="wrapper">
  28. <ul v-if="results.length">
  29. <li v-for="result in results" :key="result.uuid" class="result">
  30. <ResultItem :result="result" :searchedkeys="searchedKeys" />
  31. </li>
  32. <infinite-loading
  33. v-if="offset < resultsQuantity.quantity"
  34. :identifier="isloading"
  35. @infinite="nextResultsBatch"
  36. />
  37. </ul>
  38. </div>
  39. </section>
  40. <nav class="col-1 tools">
  41. <span
  42. class="mdi mdi-close"
  43. title="Fermer les résultats de recherche"
  44. @click.prevent="close"
  45. @keydown.enter.prevent="close"
  46. />
  47. </nav>
  48. </div>
  49. </transition>
  50. </template>
  51. <script>
  52. import { createPopper } from '@popperjs/core'
  53. import ResultItem from '../Content/ResultItem'
  54. import { mapState, mapActions, mapMutations } from 'vuex'
  55. export default {
  56. name: 'Results',
  57. components: {
  58. ResultItem
  59. },
  60. // data: () => ({
  61. // }),
  62. computed: {
  63. opened: {
  64. get () { return this.$store.state.Search.opened },
  65. set (value) { this.$store.commit('Search/setOpened', value) }
  66. },
  67. ...mapState({
  68. isloading: state => state.Search.isloading,
  69. searchedKeys: state => state.Search.searchedKeys,
  70. results: state => state.Search.results,
  71. resultsQuantity: state => state.Search.resultsQuantity,
  72. offset: state => state.Search.offset,
  73. sortOptions: state => state.Search.sortOptions,
  74. sorting: state => state.Search.sorting
  75. }),
  76. resultsCount () {
  77. return `${this.$store.state.Search.resultsQuantity.quantity} ${this.$store.state.Search.resultsQuantity.unit}`
  78. }
  79. },
  80. methods: {
  81. close () {
  82. console.log('clicked on close results')
  83. this.opened = false
  84. },
  85. ...mapMutations({
  86. setSorting: 'Search/setSorting'
  87. }),
  88. ...mapActions({
  89. nextResultsBatch: 'Search/nextResultsBatch',
  90. updateSearch: 'Search/updateSearch'
  91. }),
  92. dropDownMenuPos (dropdownList, component, { width }) {
  93. /**
  94. * We need to explicitly define the dropdown width since
  95. * it is usually inherited from the parent with CSS.
  96. */
  97. dropdownList.style.width = width
  98. /**
  99. * Here we position the dropdownList relative to the $refs.toggle Element.
  100. *
  101. * The 'offset' modifier aligns the dropdown so that the $refs.toggle and
  102. * the dropdownList overlap by 1 pixel.
  103. *
  104. * The 'toggleClass' modifier adds a 'drop-up' class to the Vue Select
  105. * wrapper so that we can set some styles for when the dropdown is placed
  106. * above.
  107. */
  108. const popper = createPopper(component.$refs.toggle, dropdownList, {
  109. placement: 'bottom',
  110. modifiers: [
  111. {
  112. name: 'offset',
  113. options: {
  114. offset: [0, -1]
  115. }
  116. },
  117. {
  118. name: 'toggleClass',
  119. enabled: true,
  120. phase: 'write',
  121. fn ({ state }) {
  122. component.$el.classList.toggle('drop-up', state.placement === 'bottom')
  123. }
  124. }]
  125. })
  126. /**
  127. * To prevent memory leaks Popper needs to be destroyed.
  128. * If you return function, it will be called just before dropdown is removed from DOM.
  129. */
  130. return () => popper.destroy()
  131. },
  132. onSortingSelected (o) {
  133. this.setSorting(o)
  134. this.updateSearch()
  135. }
  136. }
  137. }
  138. </script>
  139. <style lang="scss" scoped>
  140. </style>