Browse Source

Add project delete component

pull/1230/head
Hironsan 3 years ago
parent
commit
7d827e2752
4 changed files with 111 additions and 9 deletions
  1. 6
      app/api/tests/test_api.py
  2. 15
      app/api/views/project.py
  3. 58
      frontend/components/project/FormDelete.vue
  4. 41
      frontend/pages/projects/index.vue

6
app/api/tests/test_api.py

@ -138,12 +138,6 @@ class TestProjectListAPI(APITestCase):
self.assertTrue(response.json().get('collaborative_annotation'))
self.assertTrue(response.json().get('randomize_document_order'))
def test_disallows_project_member_to_create_project(self):
self.client.login(username=self.main_project_member_name,
password=self.main_project_member_pass)
response = self.client.post(self.url, format='json', data=self.data)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
@classmethod
def doCleanups(cls):
remove_all_role_mappings()

15
app/api/views/project.py

@ -1,5 +1,7 @@
from rest_framework import generics
from django.conf import settings
from rest_framework import generics, status
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from ..models import Project
from ..permissions import IsInProjectReadOnlyOrAdmin
@ -9,7 +11,7 @@ from ..serializers import ProjectPolymorphicSerializer, ProjectSerializer
class ProjectList(generics.ListCreateAPIView):
serializer_class = ProjectPolymorphicSerializer
pagination_class = None
permission_classes = [IsAuthenticated & IsInProjectReadOnlyOrAdmin]
permission_classes = [IsAuthenticated]
def get_queryset(self):
return self.request.user.projects
@ -17,6 +19,15 @@ class ProjectList(generics.ListCreateAPIView):
def perform_create(self, serializer):
serializer.save(users=[self.request.user])
def delete(self, request, *args, **kwargs):
delete_ids = request.data['ids']
Project.objects.filter(
role_mappings__user=self.request.user,
role_mappings__role__name=settings.ROLE_PROJECT_ADMIN,
pk__in=delete_ids
).delete()
return Response(status=status.HTTP_204_NO_CONTENT)
class ProjectDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Project.objects.all()

58
frontend/components/project/FormDelete.vue

@ -0,0 +1,58 @@
<template>
<base-card
:title="$t('overview.deleteProjectTitle')"
:agree-text="$t('generic.yes')"
:cancel-text="$t('generic.cancel')"
@agree="$emit('remove')"
@cancel="$emit('cancel')"
>
<template #content>
{{ $t('overview.deleteProjectMessage') }}
<v-list dense>
<v-list-item v-for="(item, i) in selected" :key="i">
<v-list-item-content>
<v-list-item-title>{{ item.name }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
<span v-show="hasNonDeletableProjects" class="font-weight-bold">
You don't have permission to delete the following projects. We try to delete the projects except for the following.
</span>
<v-list dense>
<v-list-item v-for="(item, i) in nonDeletableProjects" :key="i">
<v-list-item-content>
<v-list-item-title>{{ item.name }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</template>
</base-card>
</template>
<script lang="ts">
import Vue, { PropType } from 'vue'
import BaseCard from '@/components/molecules/BaseCard.vue'
import { ProjectDTO } from '@/services/application/project.service'
export default Vue.extend({
components: {
BaseCard
},
props: {
selected: {
type: Array as PropType<ProjectDTO[]>,
default: () => []
}
},
computed: {
nonDeletableProjects(): ProjectDTO[] {
return this.selected.filter(item => !item.current_users_role.is_project_admin)
},
hasNonDeletableProjects(): boolean {
return this.nonDeletableProjects.length > 0
}
}
})
</script>

41
frontend/pages/projects/index.vue

@ -1,6 +1,21 @@
<template>
<v-card>
<v-card-title>
<v-btn
class="text-capitalize ms-2"
:disabled="!canDelete"
outlined
@click.stop="dialogDelete=true"
>
{{ $t('generic.delete') }}
</v-btn>
<v-dialog v-model="dialogDelete">
<form-delete
:selected="selected"
@cancel="dialogDelete=false"
@remove="remove"
/>
</v-dialog>
</v-card-title>
<project-list
v-model="selected"
@ -14,6 +29,7 @@
import Vue from 'vue'
import ProjectList from '@/components/project/ProjectList.vue'
import { ProjectDTO } from '@/services/application/project.service'
import FormDelete from '~/components/project/FormDelete.vue'
export default Vue.extend({
layout: 'projects',
@ -21,6 +37,7 @@ export default Vue.extend({
middleware: ['check-auth', 'auth'],
components: {
FormDelete,
ProjectList,
},
@ -32,10 +49,32 @@ export default Vue.extend({
data() {
return {
dialogDelete: false,
items: [] as ProjectDTO[],
selected: [] as ProjectDTO[],
isLoading: false
}
}
},
computed: {
canDelete(): boolean {
return this.selected.length > 0
},
},
methods: {
async remove() {
await this.$services.project.bulkDelete(this.selected)
this.$fetch()
this.dialogDelete = false
this.selected = []
},
}
})
</script>
<style scoped>
::v-deep .v-dialog {
width: 800px;
}
</style>
Loading…
Cancel
Save