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.

196 lines
4.5 KiB

3 years ago
3 years ago
3 years ago
3 years ago
  1. <template>
  2. <v-card>
  3. <v-card-title>
  4. <action-menu
  5. @create="dialogCreate=true"
  6. @upload="dialogUpload=true"
  7. @download="download"
  8. />
  9. <v-btn
  10. class="text-capitalize ms-2"
  11. :disabled="!canDelete"
  12. outlined
  13. @click.stop="dialogDelete=true"
  14. >
  15. {{ $t('generic.delete') }}
  16. </v-btn>
  17. <v-dialog v-model="dialogCreate">
  18. <form-create
  19. v-bind.sync="editedItem"
  20. :used-keys="usedKeys"
  21. :used-names="usedNames"
  22. @cancel="close"
  23. @save="save"
  24. />
  25. </v-dialog>
  26. <v-dialog v-model="dialogUpload">
  27. <form-upload
  28. :error-message="errorMessage"
  29. @cancel="closeUpload"
  30. @clear="clearErrorMessage"
  31. @upload="upload"
  32. />
  33. </v-dialog>
  34. <v-dialog v-model="dialogDelete">
  35. <form-delete
  36. :selected="selected"
  37. @cancel="dialogDelete=false"
  38. @remove="remove"
  39. />
  40. </v-dialog>
  41. </v-card-title>
  42. <label-list
  43. v-model="selected"
  44. :items="items"
  45. :is-loading="isLoading"
  46. @edit="editItem"
  47. />
  48. </v-card>
  49. </template>
  50. <script lang="ts">
  51. import Vue from 'vue'
  52. import ActionMenu from '@/components/label/ActionMenu.vue'
  53. import FormCreate from '@/components/label/FormCreate.vue'
  54. import FormDelete from '@/components/label/FormDelete.vue'
  55. import FormUpload from '@/components/label/FormUpload.vue'
  56. import LabelList from '@/components/label/LabelList.vue'
  57. import { LabelDTO } from '~/services/application/label/labelData'
  58. export default Vue.extend({
  59. layout: 'project',
  60. components: {
  61. ActionMenu,
  62. FormCreate,
  63. FormDelete,
  64. FormUpload,
  65. LabelList
  66. },
  67. async fetch() {
  68. this.isLoading = true
  69. this.items = await this.$services.label.list(this.projectId)
  70. this.isLoading = false
  71. },
  72. data() {
  73. return {
  74. dialogCreate: false,
  75. dialogDelete: false,
  76. dialogUpload: false,
  77. editedIndex: -1,
  78. editedItem: {
  79. text: '',
  80. prefixKey: null,
  81. suffixKey: null,
  82. backgroundColor: '#2196F3',
  83. textColor: '#ffffff'
  84. } as LabelDTO,
  85. defaultItem: {
  86. text: '',
  87. prefixKey: null,
  88. suffixKey: null,
  89. backgroundColor: '#2196F3',
  90. textColor: '#ffffff'
  91. } as LabelDTO,
  92. items: [] as LabelDTO[],
  93. selected: [] as LabelDTO[],
  94. isLoading: false,
  95. errorMessage: ''
  96. }
  97. },
  98. computed: {
  99. canDelete(): boolean {
  100. return this.selected.length > 0
  101. },
  102. projectId(): string {
  103. return this.$route.params.id
  104. },
  105. usedNames(): string[] {
  106. const item = this.items[this.editedIndex] // to remove myself
  107. return this.items.filter(_ => _ !== item).map(item => item.text)
  108. },
  109. usedKeys(): string[] {
  110. const item = this.items[this.editedIndex] // to remove myself
  111. return this.items.filter(_ => _ !== item).map(item => item.suffixKey)
  112. .filter(item => item !==null) as string[]
  113. }
  114. },
  115. methods: {
  116. async create() {
  117. await this.$services.label.create(this.projectId, this.editedItem)
  118. },
  119. async update() {
  120. await this.$services.label.update(this.projectId, this.editedItem)
  121. },
  122. save() {
  123. if (this.editedIndex > -1) {
  124. this.update()
  125. } else {
  126. this.create()
  127. }
  128. this.$fetch()
  129. this.close()
  130. },
  131. close() {
  132. this.dialogCreate = false
  133. this.$nextTick(() => {
  134. this.editedItem = Object.assign({}, this.defaultItem)
  135. this.editedIndex = -1
  136. })
  137. },
  138. async remove() {
  139. await this.$services.label.bulkDelete(this.projectId, this.selected)
  140. this.$fetch()
  141. this.dialogDelete = false
  142. this.selected = []
  143. },
  144. async download() {
  145. await this.$services.label.export(this.projectId)
  146. },
  147. async upload(file: File) {
  148. try {
  149. await this.$services.label.upload(this.projectId, file)
  150. this.$fetch()
  151. this.closeUpload()
  152. } catch(e) {
  153. this.errorMessage = e.message
  154. }
  155. },
  156. closeUpload() {
  157. this.clearErrorMessage()
  158. this.dialogUpload = false
  159. },
  160. clearErrorMessage() {
  161. this.errorMessage = ''
  162. },
  163. editItem(item: LabelDTO) {
  164. this.editedIndex = this.items.indexOf(item)
  165. this.editedItem = Object.assign({}, item)
  166. this.dialogCreate = true
  167. }
  168. },
  169. validate({ params }) {
  170. return /^\d+$/.test(params.id)
  171. }
  172. })
  173. </script>
  174. <style scoped>
  175. ::v-deep .v-dialog {
  176. width: 800px;
  177. }
  178. </style>