From f2b00690108b4477c3644295d29e4cb36eeef1f5 Mon Sep 17 00:00:00 2001 From: Chris Zubak-Skees <chriszs@gmail.com> Date: Tue, 22 Feb 2022 03:30:33 -0500 Subject: [PATCH 1/6] feat: add submission withdrawal Closes #3296 --- hypha/apply/funds/models/submissions.py | 3 +- ...pplicationsubmission_confirm_withdraw.html | 23 ++++++++++ .../funds/applicationsubmission_detail.html | 7 +++ hypha/apply/funds/urls.py | 2 + hypha/apply/funds/views.py | 33 +++++++++++++- hypha/apply/funds/workflow.py | 43 ++++++++++++++++++- .../src/sass/apply/custom/_custom.scss | 7 ++- 7 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 hypha/apply/funds/templates/funds/applicationsubmission_confirm_withdraw.html diff --git a/hypha/apply/funds/models/submissions.py b/hypha/apply/funds/models/submissions.py index 50e61b63bc..1ccbee128e 100644 --- a/hypha/apply/funds/models/submissions.py +++ b/hypha/apply/funds/models/submissions.py @@ -829,7 +829,8 @@ def in_external_review_phase(self): def is_finished(self): accepted = self.status in PHASES_MAPPING['accepted']['statuses'] dismissed = self.status in PHASES_MAPPING['dismissed']['statuses'] - return accepted or dismissed + withdrawn = self.status in PHASES_MAPPING['withdrawn']['statuses'] + return accepted or dismissed or withdrawn # Methods for accessing data on the submission diff --git a/hypha/apply/funds/templates/funds/applicationsubmission_confirm_withdraw.html b/hypha/apply/funds/templates/funds/applicationsubmission_confirm_withdraw.html new file mode 100644 index 0000000000..d0830b01b6 --- /dev/null +++ b/hypha/apply/funds/templates/funds/applicationsubmission_confirm_withdraw.html @@ -0,0 +1,23 @@ +{% extends "base-apply.html" %} +{% load i18n static %} + +{% block title %}{% trans "Withdrawing" %}: {{object.title }}{% endblock %} + +{% block content %} +<div class="admin-bar"> + <div class="admin-bar__inner"> + <h2 class="heading heading--no-margin">{% trans "Withdrawing" %}: {{ object.title }}</h2> + </div> +</div> + +<div class="wrapper wrapper--light-grey-bg wrapper--form wrapper--sidebar"> + <div class="wrapper--sidebar--inner"> + <form class="form" action="" method="post"> + {% csrf_token %} + <p><strong>{% blocktrans %}Are you sure you want to withdraw "{{ object }}" from consideration?{% endblocktrans %}</strong></p> + <button class="button button--warning button--submit button--top-space" type="submit">{% trans "Confirm" %}</button> + </form> + </div> +</div> + +{% endblock %} diff --git a/hypha/apply/funds/templates/funds/applicationsubmission_detail.html b/hypha/apply/funds/templates/funds/applicationsubmission_detail.html index da587109ea..cabd6fe5b8 100644 --- a/hypha/apply/funds/templates/funds/applicationsubmission_detail.html +++ b/hypha/apply/funds/templates/funds/applicationsubmission_detail.html @@ -102,6 +102,13 @@ <h5>{% blocktrans with stage=object.previous.stage %}Your {{ stage }} applicatio <svg class="icon icon--delete"><use xlink:href="#delete"></use></svg> </a> {% endif %} + {% if request.user|has_edit_perm:object %} + {% if request.user.is_applicant %} + <a class="link link--withdraw-submission is-active" href="{% url 'funds:submissions:withdraw' object.id %}"> + {% trans "Withdraw" %} + </a> + {% endif %} + {% endif %} {% if request.user|has_edit_perm:object %} <a class="link link--edit-submission is-active" href="{% url 'funds:submissions:edit' object.id %}"> {% trans "Edit" %} diff --git a/hypha/apply/funds/urls.py b/hypha/apply/funds/urls.py index d241b31757..d8c50948dc 100644 --- a/hypha/apply/funds/urls.py +++ b/hypha/apply/funds/urls.py @@ -27,6 +27,7 @@ SubmissionSealedView, SubmissionStaffFlaggedView, SubmissionUserFlaggedView, + SubmissionWithdrawView, ) from .views_beta import ( bulk_archive_submissions, @@ -101,6 +102,7 @@ path('simplified/', SubmissionDetailSimplifiedView.as_view(), name="simplified"), path('download/', SubmissionDetailPDFView.as_view(), name="download"), path('delete/', SubmissionDeleteView.as_view(), name="delete"), + path('withdraw/', SubmissionWithdrawView.as_view(), name="withdraw"), path( 'documents/<uuid:field_id>/<str:file_name>', SubmissionPrivateMediaView.as_view(), name='serve_private_media' diff --git a/hypha/apply/funds/views.py b/hypha/apply/funds/views.py index 5dfcb0aa7c..c30e4e9afe 100644 --- a/hypha/apply/funds/views.py +++ b/hypha/apply/funds/views.py @@ -30,7 +30,11 @@ UpdateView, ) from django.views.generic.base import TemplateView -from django.views.generic.detail import SingleObjectMixin +from django.views.generic.detail import ( + BaseDetailView, + SingleObjectMixin, + SingleObjectTemplateResponseMixin, +) from django_file_form.models import PlaceholderUploadedFile from django_filters.views import FilterView from django_tables2.paginators import LazyPaginator @@ -1414,6 +1418,33 @@ def delete(self, request, *args, **kwargs): response = super().delete(request, *args, **kwargs) return response +class SubmissionWithdrawView(SingleObjectTemplateResponseMixin, BaseDetailView): + model = ApplicationSubmission + success_url = reverse_lazy('funds:submissions:list') + template_name_suffix = '_confirm_withdraw' + + def post(self, request, *args, **kwargs): + return self.withdraw(request, *args, **kwargs) + + def withdraw(self, request, *args, **kwargs): + obj = self.get_object() + + if not obj.phase.permissions.can_edit(request.user): + raise PermissionDenied + + withdraw_actions = [action for action in obj.workflow[obj.status].transitions.keys() if 'withdraw' in action] + + if len(withdraw_actions) > 0: + action = withdraw_actions[0] + obj.perform_transition( + action, + self.request.user, + request=self.request, + notify=False + ) + + success_url = obj.get_absolute_url() + return HttpResponseRedirect(success_url) @method_decorator(login_required, name='dispatch') class SubmissionPrivateMediaView(UserPassesTestMixin, PrivateMediaView): diff --git a/hypha/apply/funds/workflow.py b/hypha/apply/funds/workflow.py index 9eaa707c6b..8aa372d749 100644 --- a/hypha/apply/funds/workflow.py +++ b/hypha/apply/funds/workflow.py @@ -358,6 +358,7 @@ def make_permissions(edit=None, review=None, view=None): 'ext_internal_review': _('Open Review'), 'ext_determination': _('Ready For Determination'), 'ext_rejected': _('Dismiss'), + 'ext_screening_withdrawn': _('Withdraw'), }, 'display': _('Need screening'), 'public': _('Application Received'), @@ -371,16 +372,23 @@ def make_permissions(edit=None, review=None, view=None): 'permissions': {UserPermissions.APPLICANT, UserPermissions.STAFF, UserPermissions.LEAD, UserPermissions.ADMIN}, 'method': 'create_revision', }, + 'ext_screening_withdrawn': _('Withdraw'), }, 'display': _('More information required'), 'stage': RequestExt, 'permissions': applicant_edit_permissions, }, + 'ext_screening_withdrawn': { + 'display': _('Withdrawn'), + 'stage': RequestExt, + 'permissions': staff_edit_permissions, + }, }, { 'ext_internal_review': { 'transitions': { 'ext_post_review_discussion': _('Close Review'), + 'ext_review_withdrawn': _('Withdraw'), INITIAL_STATE: _('Need screening (revert)'), }, 'display': _('Internal Review'), @@ -409,6 +417,7 @@ def make_permissions(edit=None, review=None, view=None): 'permissions': {UserPermissions.APPLICANT, UserPermissions.STAFF, UserPermissions.LEAD, UserPermissions.ADMIN}, 'method': 'create_revision', }, + 'ext_review_withdrawn': _('Withdraw'), }, 'display': _('More information required'), 'stage': RequestExt, @@ -425,6 +434,11 @@ def make_permissions(edit=None, review=None, view=None): 'stage': RequestExt, 'permissions': reviewer_review_permissions, }, + 'ext_review_withdrawn': { + 'display': _('Withdrawn'), + 'stage': RequestExt, + 'permissions': staff_edit_permissions, + }, }, { 'ext_post_external_review_discussion': { @@ -435,6 +449,7 @@ def make_permissions(edit=None, review=None, view=None): 'ext_almost': _('Accept but additional info required'), 'ext_accepted': _('Accept'), 'ext_rejected': _('Dismiss'), + 'ext_external_review_withdrawn': _('Withdraw'), }, 'display': _('Ready For Discussion'), 'stage': RequestExt, @@ -447,11 +462,17 @@ def make_permissions(edit=None, review=None, view=None): 'permissions': {UserPermissions.APPLICANT, UserPermissions.STAFF, UserPermissions.LEAD, UserPermissions.ADMIN}, 'method': 'create_revision', }, + 'ext_external_review_withdrawn': _('Withdraw'), }, 'display': _('More information required'), 'stage': RequestExt, 'permissions': applicant_edit_permissions, }, + 'ext_external_review_withdrawn': { + 'display': _('Withdrawn'), + 'stage': RequestExt, + 'permissions': staff_edit_permissions, + }, }, { 'ext_determination': { @@ -460,6 +481,7 @@ def make_permissions(edit=None, review=None, view=None): 'ext_almost': _('Accept but additional info required'), 'ext_accepted': _('Accept'), 'ext_rejected': _('Dismiss'), + 'ext_withdrawn': _('Withdraw'), }, 'display': _('Ready for Determination'), 'permissions': hidden_from_applicant_permissions, @@ -485,7 +507,12 @@ def make_permissions(edit=None, review=None, view=None): 'ext_rejected': { 'display': _('Dismissed'), 'stage': RequestExt, - 'permissions': no_permissions, + 'permissions': staff_edit_permissions, + }, + 'ext_withdrawn': { + 'display': _('Withdrawn'), + 'stage': RequestExt, + 'permissions': staff_edit_permissions, }, }, ] @@ -1076,11 +1103,21 @@ def get_dismissed_statuses(): return dismissed_statuses +def get_withdrawn_statuses(): + withdrawn_statuses = set() + for phase_name, phase in PHASES: + if phase.display_name == 'Dismissed': + withdrawn_statuses.add(phase_name) + return withdrawn_statuses + + +ext_or_higher_statuses = get_ext_or_higher_statuses() review_statuses = get_review_statuses() ext_review_statuses = get_ext_review_statuses() ext_or_higher_statuses = get_ext_or_higher_statuses() accepted_statuses = get_accepted_statuses() dismissed_statuses = get_dismissed_statuses() +withdrawn_statuses = get_withdrawn_statuses() DETERMINATION_PHASES = [phase_name for phase_name, _ in PHASES if '_discussion' in phase_name] DETERMINATION_RESPONSE_PHASES = [ @@ -1174,6 +1211,10 @@ def phases_matching(phrase, exclude=None): 'name': _('Dismissed'), 'statuses': phases_matching('rejected'), }, + 'withdrawn': { + 'name': _('Withdrawn'), + 'statuses': phases_matching('withdrawn'), + }, } OPEN_CALL_PHASES = [ diff --git a/hypha/static_src/src/sass/apply/custom/_custom.scss b/hypha/static_src/src/sass/apply/custom/_custom.scss index 061b3d43d2..cc17f79c15 100644 --- a/hypha/static_src/src/sass/apply/custom/_custom.scss +++ b/hypha/static_src/src/sass/apply/custom/_custom.scss @@ -1 +1,6 @@ -// stylelint-disable no-empty-source +.link--withdraw-submission { + margin-right: 1rem; + padding-right: 1rem; + border-right: 2px solid #cfcfcf; + font-weight: 700; +} From 6652c78fea67f0a281de31d8aa80d8f6df300954 Mon Sep 17 00:00:00 2001 From: Chris Zubak-Skees <chriszs@opentechstrategies.com> Date: Tue, 22 Feb 2022 21:30:30 +0000 Subject: [PATCH 2/6] fix: remove refs to dismiss while adding withdrawn --- hypha/apply/funds/workflow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hypha/apply/funds/workflow.py b/hypha/apply/funds/workflow.py index 8aa372d749..5bddccf840 100644 --- a/hypha/apply/funds/workflow.py +++ b/hypha/apply/funds/workflow.py @@ -1106,7 +1106,7 @@ def get_dismissed_statuses(): def get_withdrawn_statuses(): withdrawn_statuses = set() for phase_name, phase in PHASES: - if phase.display_name == 'Dismissed': + if phase.display_name == 'Withdrawn': withdrawn_statuses.add(phase_name) return withdrawn_statuses From 997f653413566625873415c13cc98efab035d7e9 Mon Sep 17 00:00:00 2001 From: Frank Duncan <frank@kank.net> Date: Thu, 23 Mar 2023 05:20:20 -0500 Subject: [PATCH 3/6] Add ENABLE_SUBMISSION_WITHDRAWAL to allow enabling withdrawals This only affects about enabling them, not whether they are in the system. That means that if the configuration is changed over the lifetime of a system, things that were withdrawn when it was enabled retain that status. --- docs/setup/administrators/configuration.md | 4 ++++ hypha/apply/funds/views.py | 3 +++ hypha/apply/funds/workflow.py | 2 +- hypha/core/context_processors.py | 1 + hypha/settings/base.py | 3 +++ 5 files changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/setup/administrators/configuration.md b/docs/setup/administrators/configuration.md index e52c0b2f00..b890261ace 100644 --- a/docs/setup/administrators/configuration.md +++ b/docs/setup/administrators/configuration.md @@ -76,6 +76,10 @@ The corrosponding locale dir is named: en, en_GB, en_US FORCE_LOGIN_FOR_APPLICATION = env.bool('FORCE_LOGIN_FOR_APPLICATION', False) +### Allow Withdrawing of Submissions + + ENABLE_SUBMISSION_WITHDRAWAL = env.bool('ENABLE_SUBMISSION_WITHDRAWAL', False) + ### Set the allowed file extension for all uploads fields. FILE_ALLOWED_EXTENSIONS = ['doc', 'docx', 'odp', 'ods', 'odt', 'pdf', 'ppt', 'pptx', 'rtf', 'txt', 'xls', 'xlsx'] diff --git a/hypha/apply/funds/views.py b/hypha/apply/funds/views.py index c30e4e9afe..c360ce3409 100644 --- a/hypha/apply/funds/views.py +++ b/hypha/apply/funds/views.py @@ -1427,6 +1427,9 @@ def post(self, request, *args, **kwargs): return self.withdraw(request, *args, **kwargs) def withdraw(self, request, *args, **kwargs): + if not settings.ENABLE_SUBMISSION_WITHDRAWAL: + raise PermissionDenied + obj = self.get_object() if not obj.phase.permissions.can_edit(request.user): diff --git a/hypha/apply/funds/workflow.py b/hypha/apply/funds/workflow.py index 5bddccf840..a865ac1400 100644 --- a/hypha/apply/funds/workflow.py +++ b/hypha/apply/funds/workflow.py @@ -363,7 +363,7 @@ def make_permissions(edit=None, review=None, view=None): 'display': _('Need screening'), 'public': _('Application Received'), 'stage': RequestExt, - 'permissions': default_permissions, + 'permissions': applicant_edit_permissions, }, 'ext_more_info': { 'transitions': { diff --git a/hypha/core/context_processors.py b/hypha/core/context_processors.py index 5e41caf971..4282171e2a 100644 --- a/hypha/core/context_processors.py +++ b/hypha/core/context_processors.py @@ -18,4 +18,5 @@ def global_vars(request): 'SENTRY_DENY_URLS': settings.SENTRY_DENY_URLS, 'SENTRY_DEBUG': settings.SENTRY_DEBUG, 'SENTRY_PUBLIC_KEY': settings.SENTRY_PUBLIC_KEY, + 'ENABLE_SUBMISSION_WITHDRAWAL': settings.ENABLE_SUBMISSION_WITHDRAWAL, } diff --git a/hypha/settings/base.py b/hypha/settings/base.py index b502805ab2..68c40fa9ce 100644 --- a/hypha/settings/base.py +++ b/hypha/settings/base.py @@ -107,6 +107,9 @@ # Enable users to create accounts without submitting an application. ENABLE_REGISTRATION_WITHOUT_APPLICATION = env.bool('ENABLE_REGISTRATION_WITHOUT_APPLICATION', False) +# Allow Withdrawing of Submissions +ENABLE_SUBMISSION_WITHDRAWAL = env.bool('ENABLE_SUBMISSION_WITHDRAWAL', False) + # Project settings. # SECRET_KEY is required From 14758f25714b742fff564c132c6a5968f5abaf6d Mon Sep 17 00:00:00 2001 From: Frank Duncan <frank@kank.net> Date: Sat, 15 Apr 2023 09:02:09 -0500 Subject: [PATCH 4/6] Change permissions to withdraw to just being an applicant Based on Review in #3298, the decision was made that an applicant can withdraw at any time, without edit permissions, and edit permissions should not be to applicants for their own submissions. --- .../funds/templates/funds/applicationsubmission_detail.html | 4 +--- hypha/apply/funds/views.py | 2 +- hypha/apply/funds/workflow.py | 2 +- hypha/static_src/src/sass/apply/custom/_custom.scss | 1 - 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/hypha/apply/funds/templates/funds/applicationsubmission_detail.html b/hypha/apply/funds/templates/funds/applicationsubmission_detail.html index cabd6fe5b8..eb41290caf 100644 --- a/hypha/apply/funds/templates/funds/applicationsubmission_detail.html +++ b/hypha/apply/funds/templates/funds/applicationsubmission_detail.html @@ -102,12 +102,10 @@ <h5>{% blocktrans with stage=object.previous.stage %}Your {{ stage }} applicatio <svg class="icon icon--delete"><use xlink:href="#delete"></use></svg> </a> {% endif %} - {% if request.user|has_edit_perm:object %} - {% if request.user.is_applicant %} + {% if ENABLE_SUBMISSION_WITHDRAWAL and request.user.is_applicant %} <a class="link link--withdraw-submission is-active" href="{% url 'funds:submissions:withdraw' object.id %}"> {% trans "Withdraw" %} </a> - {% endif %} {% endif %} {% if request.user|has_edit_perm:object %} <a class="link link--edit-submission is-active" href="{% url 'funds:submissions:edit' object.id %}"> diff --git a/hypha/apply/funds/views.py b/hypha/apply/funds/views.py index c360ce3409..737eea50bb 100644 --- a/hypha/apply/funds/views.py +++ b/hypha/apply/funds/views.py @@ -1432,7 +1432,7 @@ def withdraw(self, request, *args, **kwargs): obj = self.get_object() - if not obj.phase.permissions.can_edit(request.user): + if not request.user.is_applicant: raise PermissionDenied withdraw_actions = [action for action in obj.workflow[obj.status].transitions.keys() if 'withdraw' in action] diff --git a/hypha/apply/funds/workflow.py b/hypha/apply/funds/workflow.py index a865ac1400..5bddccf840 100644 --- a/hypha/apply/funds/workflow.py +++ b/hypha/apply/funds/workflow.py @@ -363,7 +363,7 @@ def make_permissions(edit=None, review=None, view=None): 'display': _('Need screening'), 'public': _('Application Received'), 'stage': RequestExt, - 'permissions': applicant_edit_permissions, + 'permissions': default_permissions, }, 'ext_more_info': { 'transitions': { diff --git a/hypha/static_src/src/sass/apply/custom/_custom.scss b/hypha/static_src/src/sass/apply/custom/_custom.scss index cc17f79c15..55e678b65a 100644 --- a/hypha/static_src/src/sass/apply/custom/_custom.scss +++ b/hypha/static_src/src/sass/apply/custom/_custom.scss @@ -1,6 +1,5 @@ .link--withdraw-submission { margin-right: 1rem; padding-right: 1rem; - border-right: 2px solid #cfcfcf; font-weight: 700; } From 5d0405eef7426c5dc6f6715973232826fdb1181e Mon Sep 17 00:00:00 2001 From: Frank Duncan <frank@kank.net> Date: Sat, 15 Apr 2023 09:04:03 -0500 Subject: [PATCH 5/6] Add withdraw to all workflows, move to end of workflow This creates a single withdrawn status for each workflow, living at the end (next to accepted/rejected), and adds transistions for all the different workflow types. --- hypha/apply/funds/workflow.py | 81 ++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 21 deletions(-) diff --git a/hypha/apply/funds/workflow.py b/hypha/apply/funds/workflow.py index 5bddccf840..2fd827b02e 100644 --- a/hypha/apply/funds/workflow.py +++ b/hypha/apply/funds/workflow.py @@ -233,6 +233,7 @@ def make_permissions(edit=None, review=None, view=None): 'almost': _('Accept but additional info required'), 'accepted': _('Accept'), 'rejected': _('Dismiss'), + 'withdrawn': _('Withdraw'), }, 'display': _('Need screening'), 'public': _('Application Received'), @@ -250,6 +251,7 @@ def make_permissions(edit=None, review=None, view=None): 'almost': _('Accept but additional info required'), 'accepted': _('Accept'), 'rejected': _('Dismiss'), + 'withdrawn': _('Withdraw'), }, 'display': _('More information required'), 'stage': Request, @@ -261,6 +263,7 @@ def make_permissions(edit=None, review=None, view=None): 'transitions': { 'post_review_discussion': _('Close Review'), INITIAL_STATE: _('Need screening (revert)'), + 'withdrawn': _('Withdraw'), }, 'display': _('Internal Review'), 'public': _('{org_short_name} Review').format(org_short_name=settings.ORG_SHORT_NAME), @@ -277,6 +280,7 @@ def make_permissions(edit=None, review=None, view=None): 'almost': _('Accept but additional info required'), 'accepted': _('Accept'), 'rejected': _('Dismiss'), + 'withdrawn': _('Withdraw'), }, 'display': _('Ready For Discussion'), 'stage': Request, @@ -293,6 +297,7 @@ def make_permissions(edit=None, review=None, view=None): 'almost': _('Accept but additional info required'), 'accepted': _('Accept'), 'rejected': _('Dismiss'), + 'withdrawn': _('Withdraw'), }, 'display': _('More information required'), 'stage': Request, @@ -306,6 +311,7 @@ def make_permissions(edit=None, review=None, view=None): 'almost': _('Accept but additional info required'), 'accepted': _('Accept'), 'rejected': _('Dismiss'), + 'withdrawn': _('Withdraw'), }, 'display': _('Ready for Determination'), 'permissions': hidden_from_applicant_permissions, @@ -323,6 +329,7 @@ def make_permissions(edit=None, review=None, view=None): 'transitions': { 'accepted': _('Accept'), 'post_review_discussion': _('Ready For Discussion (revert)'), + 'withdrawn': _('Withdraw'), }, 'display': _('Accepted but additional info required'), 'stage': Request, @@ -333,6 +340,11 @@ def make_permissions(edit=None, review=None, view=None): 'stage': Request, 'permissions': no_permissions, }, + 'withdrawn': { + 'display': _('Withdrawn'), + 'stage': Request, + 'permissions': staff_edit_permissions, + }, }, ] @@ -358,7 +370,7 @@ def make_permissions(edit=None, review=None, view=None): 'ext_internal_review': _('Open Review'), 'ext_determination': _('Ready For Determination'), 'ext_rejected': _('Dismiss'), - 'ext_screening_withdrawn': _('Withdraw'), + 'ext_withdrawn': _('Withdraw'), }, 'display': _('Need screening'), 'public': _('Application Received'), @@ -372,23 +384,18 @@ def make_permissions(edit=None, review=None, view=None): 'permissions': {UserPermissions.APPLICANT, UserPermissions.STAFF, UserPermissions.LEAD, UserPermissions.ADMIN}, 'method': 'create_revision', }, - 'ext_screening_withdrawn': _('Withdraw'), + 'ext_withdrawn': _('Withdraw'), }, 'display': _('More information required'), 'stage': RequestExt, 'permissions': applicant_edit_permissions, }, - 'ext_screening_withdrawn': { - 'display': _('Withdrawn'), - 'stage': RequestExt, - 'permissions': staff_edit_permissions, - }, }, { 'ext_internal_review': { 'transitions': { 'ext_post_review_discussion': _('Close Review'), - 'ext_review_withdrawn': _('Withdraw'), + 'ext_withdrawn': _('Withdraw'), INITIAL_STATE: _('Need screening (revert)'), }, 'display': _('Internal Review'), @@ -417,7 +424,7 @@ def make_permissions(edit=None, review=None, view=None): 'permissions': {UserPermissions.APPLICANT, UserPermissions.STAFF, UserPermissions.LEAD, UserPermissions.ADMIN}, 'method': 'create_revision', }, - 'ext_review_withdrawn': _('Withdraw'), + 'ext_withdrawn': _('Withdraw'), }, 'display': _('More information required'), 'stage': RequestExt, @@ -434,11 +441,6 @@ def make_permissions(edit=None, review=None, view=None): 'stage': RequestExt, 'permissions': reviewer_review_permissions, }, - 'ext_review_withdrawn': { - 'display': _('Withdrawn'), - 'stage': RequestExt, - 'permissions': staff_edit_permissions, - }, }, { 'ext_post_external_review_discussion': { @@ -449,7 +451,7 @@ def make_permissions(edit=None, review=None, view=None): 'ext_almost': _('Accept but additional info required'), 'ext_accepted': _('Accept'), 'ext_rejected': _('Dismiss'), - 'ext_external_review_withdrawn': _('Withdraw'), + 'ext_withdrawn': _('Withdraw'), }, 'display': _('Ready For Discussion'), 'stage': RequestExt, @@ -462,17 +464,12 @@ def make_permissions(edit=None, review=None, view=None): 'permissions': {UserPermissions.APPLICANT, UserPermissions.STAFF, UserPermissions.LEAD, UserPermissions.ADMIN}, 'method': 'create_revision', }, - 'ext_external_review_withdrawn': _('Withdraw'), + 'ext_withdrawn': _('Withdraw'), }, 'display': _('More information required'), 'stage': RequestExt, 'permissions': applicant_edit_permissions, }, - 'ext_external_review_withdrawn': { - 'display': _('Withdrawn'), - 'stage': RequestExt, - 'permissions': staff_edit_permissions, - }, }, { 'ext_determination': { @@ -499,6 +496,7 @@ def make_permissions(edit=None, review=None, view=None): 'transitions': { 'ext_accepted': _('Accept'), 'ext_post_external_review_discussion': _('Ready For Discussion (revert)'), + 'ext_withdrawn': _('Withdraw'), }, 'display': _('Accepted but additional info required'), 'stage': RequestExt, @@ -542,6 +540,7 @@ def make_permissions(edit=None, review=None, view=None): 'com_community_review': _('Open Community Review'), 'com_determination': _('Ready For Determination'), 'com_rejected': _('Dismiss'), + 'com_withdrawn': _('Withdraw'), }, 'display': _('Need screening'), 'public': _('Application Received'), @@ -564,6 +563,7 @@ def make_permissions(edit=None, review=None, view=None): 'transitions': { INITIAL_STATE: _('Need screening (revert)'), 'com_rejected': _('Dismiss'), + 'com_withdrawn': _('Withdraw'), }, 'display': 'Open Call (public)', 'stage': RequestCom, @@ -577,6 +577,7 @@ def make_permissions(edit=None, review=None, view=None): 'com_post_review_discussion': _('Close Review'), INITIAL_STATE: _('Need screening (revert)'), 'com_rejected': _('Dismiss'), + 'com_withdrawn': _('Withdraw'), }, 'display': _('Internal Review'), 'public': _('{org_short_name} Review').format(org_short_name=settings.ORG_SHORT_NAME), @@ -588,6 +589,7 @@ def make_permissions(edit=None, review=None, view=None): 'com_post_review_discussion': _('Close Review'), 'com_internal_review': _('Open Internal Review (revert)'), 'com_rejected': _('Dismiss'), + 'com_withdrawn': _('Withdraw'), }, 'display': _('Community Review'), 'public': _('{org_short_name} Review').format(org_short_name=settings.ORG_SHORT_NAME), @@ -603,6 +605,7 @@ def make_permissions(edit=None, review=None, view=None): 'com_determination': _('Ready For Determination'), 'com_internal_review': _('Open Internal Review (revert)'), 'com_rejected': _('Dismiss'), + 'com_withdrawn': _('Withdraw'), }, 'display': _('Ready For Discussion'), 'stage': RequestCom, @@ -615,6 +618,7 @@ def make_permissions(edit=None, review=None, view=None): 'permissions': {UserPermissions.APPLICANT, UserPermissions.STAFF, UserPermissions.LEAD, UserPermissions.ADMIN}, 'method': 'create_revision', }, + 'com_withdrawn': _('Withdraw'), }, 'display': _('More information required'), 'stage': RequestCom, @@ -626,6 +630,7 @@ def make_permissions(edit=None, review=None, view=None): 'transitions': { 'com_post_external_review_discussion': _('Close Review'), 'com_post_review_discussion': _('Ready For Discussion (revert)'), + 'com_withdrawn': _('Withdraw'), }, 'display': _('External Review'), 'stage': RequestCom, @@ -641,6 +646,7 @@ def make_permissions(edit=None, review=None, view=None): 'com_almost': _('Accept but additional info required'), 'com_accepted': _('Accept'), 'com_rejected': _('Dismiss'), + 'com_withdrawn': _('Withdraw'), }, 'display': _('Ready For Discussion'), 'stage': RequestCom, @@ -653,6 +659,7 @@ def make_permissions(edit=None, review=None, view=None): 'permissions': {UserPermissions.APPLICANT, UserPermissions.STAFF, UserPermissions.LEAD, UserPermissions.ADMIN}, 'method': 'create_revision', }, + 'com_withdrawn': _('Withdraw'), }, 'display': _('More information required'), 'stage': RequestCom, @@ -666,6 +673,7 @@ def make_permissions(edit=None, review=None, view=None): 'com_almost': _('Accept but additional info required'), 'com_accepted': _('Accept'), 'com_rejected': _('Dismiss'), + 'com_withdrawn': _('Withdraw'), }, 'display': _('Ready for Determination'), 'permissions': hidden_from_applicant_permissions, @@ -683,6 +691,7 @@ def make_permissions(edit=None, review=None, view=None): 'transitions': { 'com_accepted': _('Accept'), 'com_post_external_review_discussion': _('Ready For Discussion (revert)'), + 'com_withdrawn': _('Withdraw'), }, 'display': _('Accepted but additional info required'), 'stage': RequestCom, @@ -693,6 +702,11 @@ def make_permissions(edit=None, review=None, view=None): 'stage': RequestCom, 'permissions': no_permissions, }, + 'com_withdrawn': { + 'display': _('Withdrawn'), + 'stage': RequestCom, + 'permissions': staff_edit_permissions, + }, }, ] @@ -720,6 +734,7 @@ def make_permissions(edit=None, review=None, view=None): 'concept_determination': _('Ready For Preliminary Determination'), 'invited_to_proposal': _('Invite to Proposal'), 'concept_rejected': _('Dismiss'), + 'concept_withdrawn': _('Withdraw'), }, 'display': _('Need screening'), 'public': _('Concept Note Received'), @@ -736,6 +751,7 @@ def make_permissions(edit=None, review=None, view=None): 'concept_rejected': _('Dismiss'), 'invited_to_proposal': _('Invite to Proposal'), 'concept_determination': _('Ready For Preliminary Determination'), + 'concept_withdrawn': _('Withdraw'), }, 'display': _('More information required'), 'stage': Concept, @@ -748,6 +764,7 @@ def make_permissions(edit=None, review=None, view=None): 'concept_review_discussion': _('Close Review'), INITIAL_STATE: _('Need screening (revert)'), 'invited_to_proposal': _('Invite to Proposal'), + 'concept_withdrawn': _('Withdraw'), }, 'display': _('Internal Review'), 'public': _('{org_short_name} Review').format(org_short_name=settings.ORG_SHORT_NAME), @@ -763,6 +780,7 @@ def make_permissions(edit=None, review=None, view=None): 'concept_internal_review': _('Open Review (revert)'), 'invited_to_proposal': _('Invite to Proposal'), 'concept_rejected': _('Dismiss'), + 'concept_withdrawn': _('Withdraw'), }, 'display': _('Ready For Discussion'), 'stage': Concept, @@ -776,6 +794,7 @@ def make_permissions(edit=None, review=None, view=None): 'method': 'create_revision', }, 'invited_to_proposal': _('Invite to Proposal'), + 'concept_withdrawn': _('Withdraw'), }, 'display': _('More information required'), 'stage': Concept, @@ -788,6 +807,7 @@ def make_permissions(edit=None, review=None, view=None): 'concept_review_discussion': _('Ready For Discussion (revert)'), 'invited_to_proposal': _('Invite to Proposal'), 'concept_rejected': _('Dismiss'), + 'concept_withdrawn': _('Withdraw'), }, 'display': _('Ready for Preliminary Determination'), 'permissions': hidden_from_applicant_permissions, @@ -814,6 +834,11 @@ def make_permissions(edit=None, review=None, view=None): 'stage': Concept, 'permissions': no_permissions, }, + 'concept_withdrawn': { + 'display': _('Withdrawn'), + 'stage': Concept, + 'permissions': staff_edit_permissions, + }, }, { 'draft_proposal': { @@ -836,6 +861,7 @@ def make_permissions(edit=None, review=None, view=None): 'external_review': _('Open External Review'), 'proposal_determination': _('Ready For Final Determination'), 'proposal_rejected': _('Dismiss'), + 'proposal_withdrawn': _('Withdraw'), }, 'display': _('Proposal Received'), 'stage': Proposal, @@ -851,6 +877,7 @@ def make_permissions(edit=None, review=None, view=None): 'external_review': _('Open External Review'), 'proposal_determination': _('Ready For Final Determination'), 'proposal_rejected': _('Dismiss'), + 'proposal_withdrawn': _('Withdraw'), }, 'display': _('More information required'), 'stage': Proposal, @@ -862,6 +889,7 @@ def make_permissions(edit=None, review=None, view=None): 'transitions': { 'post_proposal_review_discussion': _('Close Review'), 'proposal_discussion': _('Proposal Received (revert)'), + 'proposal_withdrawn': _('Withdraw'), }, 'display': _('Internal Review'), 'public': _('{org_short_name} Review').format(org_short_name=settings.ORG_SHORT_NAME), @@ -877,6 +905,7 @@ def make_permissions(edit=None, review=None, view=None): 'proposal_determination': _('Ready For Final Determination'), 'proposal_internal_review': _('Open Internal Review (revert)'), 'proposal_rejected': _('Dismiss'), + 'proposal_withdrawn': _('Withdraw'), }, 'display': _('Ready For Discussion'), 'stage': Proposal, @@ -890,6 +919,7 @@ def make_permissions(edit=None, review=None, view=None): 'method': 'create_revision', }, 'external_review': _('Open External Review'), + 'proposal_withdrawn': _('Withdraw'), }, 'display': _('More information required'), 'stage': Proposal, @@ -901,6 +931,7 @@ def make_permissions(edit=None, review=None, view=None): 'transitions': { 'post_external_review_discussion': _('Close Review'), 'post_proposal_review_discussion': _('Ready For Discussion (revert)'), + 'proposal_withdrawn': _('Withdraw'), }, 'display': _('External Review'), 'stage': Proposal, @@ -916,6 +947,7 @@ def make_permissions(edit=None, review=None, view=None): 'proposal_almost': _('Accept but additional info required'), 'proposal_accepted': _('Accept'), 'proposal_rejected': _('Dismiss'), + 'proposal_withdrawn': _('Withdraw'), }, 'display': _('Ready For Discussion'), 'stage': Proposal, @@ -928,6 +960,7 @@ def make_permissions(edit=None, review=None, view=None): 'permissions': {UserPermissions.APPLICANT, UserPermissions.STAFF, UserPermissions.LEAD, UserPermissions.ADMIN}, 'method': 'create_revision', }, + 'proposal_withdrawn': _('Withdraw'), }, 'display': _('More information required'), 'stage': Proposal, @@ -941,6 +974,7 @@ def make_permissions(edit=None, review=None, view=None): 'proposal_almost': _('Accept but additional info required'), 'proposal_accepted': _('Accept'), 'proposal_rejected': _('Dismiss'), + 'proposal_withdrawn': _('Withdraw'), }, 'display': _('Ready for Final Determination'), 'permissions': hidden_from_applicant_permissions, @@ -968,6 +1002,11 @@ def make_permissions(edit=None, review=None, view=None): 'stage': Proposal, 'permissions': no_permissions, }, + 'proposal_withdrawn': { + 'display': _('Withdrawn'), + 'stage': Proposal, + 'permissions': staff_edit_permissions, + }, }, ] From 1d7b8297a47301b46a430e5b9430d48e651c81ee Mon Sep 17 00:00:00 2001 From: Fredrik Jonsson <frjo@xdeb.org> Date: Wed, 26 Jul 2023 10:16:57 +0200 Subject: [PATCH 6/6] Move css from custom file. --- hypha/apply/funds/views.py | 4 ++-- hypha/static_src/src/sass/apply/components/_link.scss | 8 +++++--- hypha/static_src/src/sass/apply/custom/_custom.scss | 6 +----- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/hypha/apply/funds/views.py b/hypha/apply/funds/views.py index 737eea50bb..2054fb8351 100644 --- a/hypha/apply/funds/views.py +++ b/hypha/apply/funds/views.py @@ -1430,11 +1430,11 @@ def withdraw(self, request, *args, **kwargs): if not settings.ENABLE_SUBMISSION_WITHDRAWAL: raise PermissionDenied - obj = self.get_object() - if not request.user.is_applicant: raise PermissionDenied + obj = self.get_object() + withdraw_actions = [action for action in obj.workflow[obj.status].transitions.keys() if 'withdraw' in action] if len(withdraw_actions) > 0: diff --git a/hypha/static_src/src/sass/apply/components/_link.scss b/hypha/static_src/src/sass/apply/components/_link.scss index 0edca13edc..989ff2ca37 100644 --- a/hypha/static_src/src/sass/apply/components/_link.scss +++ b/hypha/static_src/src/sass/apply/components/_link.scss @@ -230,7 +230,8 @@ } &--edit-submission, - &--delete-submission { + &--delete-submission, + &--withdraw-submission { display: flex; align-items: center; font-weight: $weight--bold; @@ -249,12 +250,13 @@ } } - &--delete-submission { + &--delete-submission, + &--withdraw-submission { margin-right: 1rem; padding-right: 1rem; border-right: 2px solid $color--mid-grey; - &:only-child { + &:last-child { border-right: 0; padding-right: 0; margin-right: 0; diff --git a/hypha/static_src/src/sass/apply/custom/_custom.scss b/hypha/static_src/src/sass/apply/custom/_custom.scss index 55e678b65a..061b3d43d2 100644 --- a/hypha/static_src/src/sass/apply/custom/_custom.scss +++ b/hypha/static_src/src/sass/apply/custom/_custom.scss @@ -1,5 +1 @@ -.link--withdraw-submission { - margin-right: 1rem; - padding-right: 1rem; - font-weight: 700; -} +// stylelint-disable no-empty-source