Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add delete button for read only projects #1354

Merged
merged 1 commit into from
Jun 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion app/api/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,12 @@ def edit(self, request, pk=None):
return Response({'success': True}, status=status.HTTP_200_OK)

def destroy(self, request, pk=None):
project = get_and_check_project(request, pk, ('delete_project', ))
project = get_and_check_project(request, pk, ('view_project', ))

# Owner? Delete the project
if project.owner == request.user or request.user.is_superuser:
get_and_check_project(request, pk, ('delete_project', ))

return super().destroy(self, request, pk=pk)
else:
# Do not remove the project, simply remove all user's permissions to the project
Expand Down
20 changes: 20 additions & 0 deletions app/static/app/js/components/ProjectListItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,20 @@ class ProjectListItem extends React.Component {
this.editProjectDialog.show();
}

handleHideProject = (deleteWarning, deleteAction) => {
return () => {
if (window.confirm(deleteWarning)){
this.setState({error: "", refreshing: true});
deleteAction()
.fail(e => {
this.setState({error: e.message || (e.responseJSON || {}).detail || e.responseText || _("Could not delete item")});
}).always(() => {
this.setState({refreshing: false});
});
}
}
}

updateProject(project){
return $.ajax({
url: `/api/projects/${this.state.data.id}/edit/`,
Expand Down Expand Up @@ -683,6 +697,12 @@ class ProjectListItem extends React.Component {
</a>]
: ""}

{!canEdit && !data.owned ?
[<i key="edit-icon" className='far fa-eye-slash'></i>
,<a key="edit-text" href="javascript:void(0);" onClick={this.handleHideProject(deleteWarning, this.handleDelete)}> {_("Delete")}
</a>]
: ""}

</div>
</div>
<i className="drag-drop-icon fa fa-inbox"></i>
Expand Down
15 changes: 9 additions & 6 deletions app/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,14 +253,17 @@ def test_projects_and_tasks(self):
for perm in ['delete', 'change', 'add']:
self.assertFalse(perm in res.data['permissions'])

# Can't delete a project for which we just have view permissions
res = client.delete('/api/projects/{}/'.format(other_temp_project.id))
self.assertTrue(res.status_code == status.HTTP_404_NOT_FOUND)

# Can delete a project for which we have delete permissions
assign_perm('delete_project', user, other_temp_project)
# Can delete a project for which we just have view permissions
# (we will just remove our read permissions without deleting the project)
res = client.delete('/api/projects/{}/'.format(other_temp_project.id))
self.assertTrue(res.status_code == status.HTTP_204_NO_CONTENT)

# Project still exists
self.assertTrue(Project.objects.filter(id=other_temp_project.id).count() == 1)

# We just can't access it
res = client.get('/api/projects/{}/'.format(other_temp_project.id))
self.assertTrue(res.status_code == status.HTTP_404_NOT_FOUND)

# A user cannot reassign a task to a
# project for which he/she has no permissions
Expand Down