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.

147 lines
3.4 KiB

3 years ago
3 years ago
3 years ago
3 years ago
  1. <template>
  2. <v-card>
  3. <v-card-title v-if="isStaff">
  4. <v-btn
  5. class="text-capitalize"
  6. color="primary"
  7. @click.stop="dialogCreate=true"
  8. >
  9. {{ $t('generic.create') }}
  10. </v-btn>
  11. <v-btn
  12. class="text-capitalize ms-2"
  13. :disabled="!canDelete"
  14. outlined
  15. @click.stop="dialogDelete=true"
  16. >
  17. {{ $t('generic.delete') }}
  18. </v-btn>
  19. <v-dialog v-model="dialogCreate">
  20. <form-create
  21. v-bind.sync="editedItem"
  22. @cancel="close"
  23. @save="create"
  24. />
  25. </v-dialog>
  26. <v-dialog v-model="dialogDelete">
  27. <form-delete
  28. :selected="selected"
  29. @cancel="dialogDelete=false"
  30. @remove="remove"
  31. />
  32. </v-dialog>
  33. </v-card-title>
  34. <project-list
  35. v-model="selected"
  36. :items="projects.items"
  37. :is-loading="isLoading"
  38. :total="projects.count"
  39. @update:query="updateQuery"
  40. />
  41. </v-card>
  42. </template>
  43. <script lang="ts">
  44. import _ from 'lodash'
  45. import Vue from 'vue'
  46. import { mapGetters } from 'vuex'
  47. import ProjectList from '@/components/project/ProjectList.vue'
  48. import { ProjectDTO, ProjectWriteDTO, ProjectListDTO } from '~/services/application/project/projectData'
  49. import FormDelete from '~/components/project/FormDelete.vue'
  50. import FormCreate from '~/components/project/FormCreate.vue'
  51. export default Vue.extend({
  52. components: {
  53. FormCreate,
  54. FormDelete,
  55. ProjectList,
  56. },
  57. layout: 'projects',
  58. middleware: ['check-auth', 'auth'],
  59. data() {
  60. return {
  61. dialogCreate: false,
  62. dialogDelete: false,
  63. editedItem: {
  64. name: '',
  65. description: '',
  66. projectType: 'DocumentClassification',
  67. enableRandomOrder: false,
  68. enableShareAnnotation: false,
  69. singleClassClassification: false,
  70. allowOverlapping: false,
  71. graphemeMode: false
  72. } as ProjectWriteDTO,
  73. defaultItem: {
  74. name: '',
  75. description: '',
  76. projectType: 'DocumentClassification',
  77. enableRandomOrder: false,
  78. enableShareAnnotation: false,
  79. singleClassClassification: false,
  80. allowOverlapping: false,
  81. graphemeMode: false
  82. } as ProjectWriteDTO,
  83. projects: {} as ProjectListDTO,
  84. selected: [] as ProjectDTO[],
  85. isLoading: false
  86. }
  87. },
  88. async fetch() {
  89. this.isLoading = true
  90. this.projects = await this.$services.project.list(this.$route.query)
  91. this.isLoading = false
  92. },
  93. computed: {
  94. ...mapGetters('auth', ['isStaff']),
  95. canDelete(): boolean {
  96. return this.selected.length > 0
  97. },
  98. },
  99. watch: {
  100. '$route.query': _.debounce(function() {
  101. // @ts-ignore
  102. this.$fetch()
  103. }, 1000
  104. ),
  105. },
  106. methods: {
  107. async create() {
  108. const project = await this.$services.project.create(this.editedItem)
  109. this.$router.push(`/projects/${project.id}`)
  110. this.close()
  111. },
  112. close() {
  113. this.dialogCreate = false
  114. this.$nextTick(() => {
  115. this.editedItem = Object.assign({}, this.defaultItem)
  116. })
  117. },
  118. async remove() {
  119. await this.$services.project.bulkDelete(this.selected)
  120. this.$fetch()
  121. this.dialogDelete = false
  122. this.selected = []
  123. },
  124. updateQuery(query: object) {
  125. this.$router.push(query)
  126. }
  127. }
  128. })
  129. </script>
  130. <style scoped>
  131. ::v-deep .v-dialog {
  132. width: 800px;
  133. }
  134. </style>