You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

201 lines
5.0 KiB

  1. <template>
  2. <v-app>
  3. <the-header>
  4. <template #leftDrawerIcon>
  5. <v-app-bar-nav-icon @click="drawerLeft = !drawerLeft" />
  6. </template>
  7. </the-header>
  8. <v-navigation-drawer
  9. v-model="drawerLeft"
  10. app
  11. clipped
  12. color=""
  13. >
  14. <the-side-bar
  15. :link="getLink"
  16. :role="getCurrentUserRole"
  17. />
  18. </v-navigation-drawer>
  19. <v-main>
  20. <v-overlay :value="loading">
  21. <v-progress-circular indeterminate size="64" />
  22. </v-overlay>
  23. <v-container fluid>
  24. <v-row
  25. no-gutters
  26. class="d-none d-sm-flex"
  27. >
  28. <v-col>
  29. <approve-button
  30. v-if="canViewApproveButton"
  31. v-model="page"
  32. :length="total"
  33. :approved="approved"
  34. :disabled="currentDoc ? false : true"
  35. />
  36. <filter-button
  37. v-model="filterOption"
  38. />
  39. <guideline-button />
  40. <clear-annotations-button />
  41. </v-col>
  42. <v-spacer />
  43. <v-col>
  44. <pagination
  45. v-model="page"
  46. :length="total"
  47. />
  48. </v-col>
  49. </v-row>
  50. <v-row justify="center">
  51. <v-col cols="12" md="9">
  52. <nuxt />
  53. </v-col>
  54. <v-col cols="12" md="3">
  55. <metadata-box
  56. v-if="currentDoc && !loading"
  57. :metadata="JSON.parse(currentDoc.meta)"
  58. />
  59. </v-col>
  60. </v-row>
  61. </v-container>
  62. </v-main>
  63. <bottom-navigator
  64. v-model="page"
  65. :length="total"
  66. class="d-flex d-sm-none"
  67. />
  68. </v-app>
  69. </template>
  70. <script>
  71. import { mapActions, mapGetters, mapState, mapMutations } from 'vuex'
  72. import BottomNavigator from '@/components/containers/annotation/BottomNavigator'
  73. import ClearAnnotationsButton from '@/components/containers/annotation/ClearAnnotationsButton.vue'
  74. import GuidelineButton from '@/components/containers/annotation/GuidelineButton'
  75. import MetadataBox from '@/components/organisms/annotation/MetadataBox'
  76. import FilterButton from '@/components/containers/annotation/FilterButton'
  77. import ApproveButton from '@/components/containers/annotation/ApproveButton'
  78. import Pagination from '~/components/containers/annotation/Pagination'
  79. import TheHeader from '~/components/organisms/layout/TheHeader'
  80. import TheSideBar from '~/components/organisms/layout/TheSideBar'
  81. export default {
  82. middleware: ['check-auth', 'auth', 'set-project'],
  83. components: {
  84. TheSideBar,
  85. TheHeader,
  86. BottomNavigator,
  87. Pagination,
  88. GuidelineButton,
  89. FilterButton,
  90. ApproveButton,
  91. MetadataBox,
  92. ClearAnnotationsButton
  93. },
  94. fetch() {
  95. this.getDocumentList({
  96. projectId: this.$route.params.id,
  97. limit: this.limit,
  98. offset: this.offset,
  99. q: this.$route.query.q,
  100. isChecked: this.filterOption,
  101. filterName: this.getFilterOption
  102. })
  103. },
  104. data() {
  105. return {
  106. drawerLeft: null,
  107. limit: 10
  108. }
  109. },
  110. computed: {
  111. ...mapGetters('projects', ['getLink', 'getCurrentUserRole', 'getFilterOption', 'canViewApproveButton']),
  112. ...mapState('documents', ['loading', 'total']),
  113. ...mapGetters('documents', ['currentDoc', 'approved']),
  114. page: {
  115. get() {
  116. return parseInt(this.$route.query.page, 10)
  117. },
  118. set(value) {
  119. this.$router.push({
  120. query: {
  121. isChecked: this.$route.query.isChecked,
  122. page: parseInt(value, 10),
  123. q: this.$route.query.q
  124. }
  125. })
  126. }
  127. },
  128. filterOption: {
  129. get() {
  130. return this.$route.query.isChecked
  131. },
  132. set(value) {
  133. this.$router.push({
  134. query: {
  135. isChecked: value,
  136. page: 1,
  137. q: this.$route.query.q
  138. }
  139. })
  140. }
  141. },
  142. offset() {
  143. return Math.floor((this.page - 1) / this.limit) * this.limit
  144. },
  145. current() {
  146. return (this.page - 1) % this.limit
  147. },
  148. searchOptions() {
  149. // a bit tricky technique to capture variables change simultaneously.
  150. // see https://github.com/vuejs/vue/issues/844#issuecomment-265315349
  151. return JSON.stringify({
  152. page: this.page,
  153. q: this.$route.query.q,
  154. isChecked: this.filterOption
  155. })
  156. }
  157. },
  158. watch: {
  159. total() {
  160. // To validate the range of page variable on reloading the annotation page.
  161. if (this.total !== 0 && this.page > this.total) {
  162. this.$router.push({
  163. path: this.localePath(`/projects/${this.$route.params.id}/`)
  164. })
  165. }
  166. },
  167. offset() {
  168. this.$fetch()
  169. },
  170. filterOption() {
  171. this.page = 1
  172. this.$fetch()
  173. },
  174. current: {
  175. handler() {
  176. this.setCurrent(this.current)
  177. },
  178. immediate: true
  179. },
  180. searchOptions() {
  181. this.saveSearchOptions(JSON.parse(this.searchOptions))
  182. }
  183. },
  184. methods: {
  185. ...mapActions('documents', ['getDocumentList']),
  186. ...mapMutations('documents', ['setCurrent']),
  187. ...mapMutations('projects', ['saveSearchOptions'])
  188. }
  189. }
  190. </script>