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.

111 lines
2.6 KiB

2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
2 years ago
2 years ago
  1. <template>
  2. <v-card>
  3. <v-card-title v-if="isStaff">
  4. <v-btn class="text-capitalize" color="primary" @click.stop="$router.push('projects/create')">
  5. {{ $t('generic.create') }}
  6. </v-btn>
  7. <v-btn class="text-capitalize ms-2" color="primary" :disabled="!canClone" @click.stop="clone">
  8. Clone
  9. </v-btn>
  10. <v-btn
  11. class="text-capitalize ms-2"
  12. :disabled="!canDelete"
  13. outlined
  14. @click.stop="dialogDelete = true"
  15. >
  16. {{ $t('generic.delete') }}
  17. </v-btn>
  18. <v-dialog v-model="dialogDelete">
  19. <form-delete :selected="selected" @cancel="dialogDelete = false" @remove="remove" />
  20. </v-dialog>
  21. </v-card-title>
  22. <project-list
  23. v-model="selected"
  24. :items="projects.items"
  25. :is-loading="isLoading"
  26. :total="projects.count"
  27. @update:query="updateQuery"
  28. />
  29. </v-card>
  30. </template>
  31. <script lang="ts">
  32. import _ from 'lodash'
  33. import Vue from 'vue'
  34. import { mapGetters } from 'vuex'
  35. import ProjectList from '@/components/project/ProjectList.vue'
  36. import FormDelete from '~/components/project/FormDelete.vue'
  37. import { Page } from '~/domain/models/page'
  38. import { Project } from '~/domain/models/project/project'
  39. import { SearchQueryData } from '~/services/application/project/projectApplicationService'
  40. export default Vue.extend({
  41. components: {
  42. FormDelete,
  43. ProjectList
  44. },
  45. layout: 'projects',
  46. middleware: ['check-auth', 'auth'],
  47. data() {
  48. return {
  49. dialogDelete: false,
  50. projects: {} as Page<Project>,
  51. selected: [] as Project[],
  52. isLoading: false
  53. }
  54. },
  55. async fetch() {
  56. this.isLoading = true
  57. this.projects = await this.$services.project.list(
  58. this.$route.query as unknown as SearchQueryData
  59. )
  60. this.isLoading = false
  61. },
  62. computed: {
  63. ...mapGetters('auth', ['isStaff']),
  64. canDelete(): boolean {
  65. return this.selected.length > 0
  66. },
  67. canClone(): boolean {
  68. return this.selected.length === 1
  69. }
  70. },
  71. watch: {
  72. '$route.query': _.debounce(function () {
  73. // @ts-ignore
  74. this.$fetch()
  75. }, 1000)
  76. },
  77. methods: {
  78. async remove() {
  79. await this.$services.project.bulkDelete(this.selected)
  80. this.$fetch()
  81. this.dialogDelete = false
  82. this.selected = []
  83. },
  84. async clone() {
  85. const project = await this.$services.project.clone(this.selected[0])
  86. this.selected = []
  87. this.$router.push(`/projects/${project.id}/settings`)
  88. },
  89. updateQuery(query: object) {
  90. this.$router.push(query)
  91. }
  92. }
  93. })
  94. </script>
  95. <style scoped>
  96. ::v-deep .v-dialog {
  97. width: 800px;
  98. }
  99. </style>