Skip to content

Commit

Permalink
Add draft submission deletion feature for applicants (#4108)
Browse files Browse the repository at this point in the history
Fixes #4054
  • Loading branch information
sandeepsajan0 authored Sep 4, 2024
1 parent a3bd495 commit 2fcb25d
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% load i18n dashboard_statusbar_tags statusbar_tags workflow_tags heroicons %}
{% load i18n dashboard_statusbar_tags statusbar_tags workflow_tags heroicons submission_tags %}

{% for submission in page.object_list %}
<div class="wrapper wrapper--status-bar-outer">
Expand Down Expand Up @@ -28,6 +28,13 @@ <h4 class="heading mb-0 font-bold line-clamp-3 hover:line-clamp-none">
{% endif %}
</a>
{% endif %}
{% user_can_delete_submission submission request.user as can_delete_submission %}
{% if can_delete_submission %}
<a class="button button--white" href="{% url 'funds:submissions:delete' submission.id %}" hx-get="{% url 'funds:submissions:delete' submission.id %}" hx-target="#htmx-modal">
{% heroicon_micro "trash" class="inline me-1 mt-1 fill-red-600" aria_hidden=true %}
{% trans "Delete" %}
</a>
{% endif %}
</div>
{% status_bar submission.workflow submission.phase request.user css_class="status-bar--small" %}
</div>
Expand Down
11 changes: 11 additions & 0 deletions hypha/apply/funds/permissions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from django.conf import settings
from django.core.exceptions import PermissionDenied

from hypha.apply.funds.models.submissions import DRAFT_STATE

from ..users.groups import STAFF_GROUP_NAME, SUPERADMIN, TEAMADMIN_GROUP_NAME


Expand All @@ -24,6 +26,14 @@ def can_edit_submission(user, submission):
return True, ""


def can_delete_submission(user, submission):
if user.has_perm("funds.delete_applicationsubmission"):
return True, "User can delete submission"
elif user == submission.user and submission.status == DRAFT_STATE:
return True, "Applicant can delete draft submissions"
return False, "Forbidden Error"


def can_bulk_delete_submissions(user) -> bool:
if user.is_apply_staff:
return True
Expand Down Expand Up @@ -164,6 +174,7 @@ def can_view_submission_screening(user, submission):
permissions_map = {
"submission_view": is_user_has_access_to_view_submission,
"submission_edit": can_edit_submission,
"submission_delete": can_delete_submission,
"can_view_submission_screening": can_view_submission_screening,
"archive_alter": can_alter_archived_submissions,
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,18 @@
<div class="mt-3 text-center sm:ml-4 sm:mt-0 sm:text-left">
<h3 class="text-base font-semibold leading-6 text-gray-900" id="modal-title">Delete submission</h3>
<div class="mt-2">
<p class="text-sm text-gray-500">
Are you sure you want to delete submission? All of your data
will be permanently removed from our servers forever. This
includes reviews, determinations and comments. This action cannot be undone.
</p>
{% if request.user.is_applicant %}
<p class="text-sm text-gray-500">
Are you sure you want to delete draft submission? All of your data for this submission
will be permanently removed from our servers forever. This action cannot be undone.
</p>
{% else %}
<p class="text-sm text-gray-500">
Are you sure you want to delete submission? All of your data
will be permanently removed from our servers forever. This
includes reviews, determinations and comments. This action cannot be undone.
</p>
{% endif %}
</div>
<div>
<label for="delete-confirmation" class="block mb-2 text-sm font-semibold text-gray-600">Type "<em>delete</em>" below to confirm</label>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% extends "base-apply.html" %}
{% load i18n static workflow_tags wagtailcore_tags statusbar_tags archive_tags %}
{% load i18n static workflow_tags wagtailcore_tags statusbar_tags archive_tags submission_tags %}
{% load heroicons %}

{% block title %}#{{ object.public_id|default_if_none:object.id}}: {{ object.title }}{% endblock %}
Expand Down Expand Up @@ -119,7 +119,8 @@ <h5>{% blocktrans with stage=object.previous.stage %}Your {{ stage }} applicatio
</strong>
</span>
<div class="flex gap-4 justify-end flex-1 items-center">
{% if perms.funds.delete_applicationsubmission %}
{% user_can_delete_submission object request.user as can_delete_submission %}
{% if can_delete_submission %}
<a
class="flex items-center font-bold text-red-600 transition-opacity hover:opacity-70"
href="{% url 'funds:submissions:delete' object.id %}"
Expand Down
12 changes: 12 additions & 0 deletions hypha/apply/funds/templatetags/submission_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from django.utils.safestring import mark_safe

from hypha.apply.funds.models import ApplicationSubmission
from hypha.apply.funds.permissions import has_permission

register = template.Library()

Expand All @@ -29,3 +30,14 @@ def submission_links(value):
value = re.sub(rf"(?<!\w){sid}(?!\w)", link, value)

return mark_safe(value)


@register.simple_tag
def user_can_delete_submission(submission, user):
permission, _ = has_permission(
"submission_delete",
user=user,
object=submission,
raise_exception=False,
)
return permission
18 changes: 12 additions & 6 deletions hypha/apply/funds/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from django.contrib.auth import get_user_model
from django.contrib.auth.decorators import (
login_required,
permission_required,
user_passes_test,
)
from django.contrib.auth.mixins import UserPassesTestMixin
Expand Down Expand Up @@ -1764,13 +1763,20 @@ def get_queryset(self):
return RoundsAndLabs.objects.with_progress()


@method_decorator(
permission_required("funds.delete_applicationsubmission", raise_exception=True),
name="dispatch",
)
class SubmissionDeleteView(DeleteView):
model = ApplicationSubmission
success_url = reverse_lazy("funds:submissions:list")

def dispatch(self, request, *args, **kwargs):
submission = self.get_object()
permission, _ = has_permission(
"submission_delete", request.user, submission, raise_exception=True
)
return super().dispatch(request, *args, **kwargs)

def get_success_url(self):
if self.request.user.is_applicant:
return reverse_lazy("dashboard:dashboard")
return reverse_lazy("funds:submissions:list")

def form_valid(self, form):
submission = self.get_object()
Expand Down

0 comments on commit 2fcb25d

Please sign in to comment.