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.

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