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.

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