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.

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