SciPost Code Repository

Skip to content
Snippets Groups Projects
Commit 29742095 authored by George Katsikas's avatar George Katsikas :goat:
Browse files

add veto form to nominations

parent 1643f6b8
No related branches found
No related tags found
No related merge requests found
...@@ -35,6 +35,7 @@ from .models import ( ...@@ -35,6 +35,7 @@ from .models import (
FellowshipNominationComment, FellowshipNominationComment,
FellowshipNominationDecision, FellowshipNominationDecision,
FellowshipNominationVotingRound, FellowshipNominationVotingRound,
FellowshipNominationEvent,
FellowshipInvitation, FellowshipInvitation,
) )
from .constants import ( from .constants import (
...@@ -1088,6 +1089,65 @@ class FellowshipNominationVotingRoundStartForm(forms.ModelForm): ...@@ -1088,6 +1089,65 @@ class FellowshipNominationVotingRoundStartForm(forms.ModelForm):
) )
class FellowshipNominationVetoForm(forms.Form):
edadmin_comments = forms.CharField(
label="Comments for editorial administration",
widget=forms.Textarea(attrs={"rows": 4}),
required=True,
)
fellow_comments = forms.CharField(
label="Comments for voting Fellows",
widget=forms.Textarea(attrs={"rows": 4}),
required=True,
)
def __init__(self, *args, **kwargs):
self.fellow = kwargs.pop("fellow", None)
self.nomination = kwargs.pop("nomination", None)
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.attrs = {
"hx-post": reverse(
"colleges:_hx_nomination_veto",
kwargs={"nomination_id": self.nomination.id},
),
"hx-target": "closest .veto-btn-container",
"hx-swap": "outerHTML",
}
self.helper.layout = Layout(
Div(
Div(Field("edadmin_comments"), css_class="col"),
Div(Field("fellow_comments"), css_class="col"),
Div(
ButtonHolder(Submit("submit", "Veto", css_class="btn btn-dark")),
css_class="col-auto d-flex align-items-end",
),
css_class="row mb-0",
),
)
def save(self):
self.nomination.vetoes.add(self.fellow)
self.nomination.save()
# Fellow's comments are added as a regular comment
FellowshipNominationComment.objects.create(
nomination=self.nomination,
by=self.fellow.contributor,
text=self.cleaned_data["fellow_comments"],
)
# EdAdmin's comments are added as an event
FellowshipNominationEvent.objects.create(
nomination=self.nomination,
by=self.fellow.contributor,
description=f"Vetoed with justification: {self.cleaned_data['edadmin_comments']}",
)
############### ###############
# Invitations # # Invitations #
############### ###############
......
...@@ -7,16 +7,29 @@ ...@@ -7,16 +7,29 @@
<div id="profile-{{ nomination.profile.id }}-specialties" <div id="profile-{{ nomination.profile.id }}-specialties"
class="border border-danger mb-4 d-none-empty"></div> class="border border-danger mb-4 d-none-empty"></div>
{% if nomination.nominator_comments %} <div class="col mb-3">
<div class="col-12 mb-3"> <div class="card">
<div class="card"> <div class="card-header">Nominator motivation</div>
<div class="card-header">Nominator motivation</div> <div class="card-body">
<div class="card-body">{{ nomination.nominated_by.profile.full_name }}: {{ nomination.nominator_comments }}</div>
{% if nomination.nominator_comments %}
<strong>{{ nomination.nominated_by.profile.full_name }}:</strong> {{ nomination.nominator_comments }}
{% else %}
No motivation provided.
{% endif %}
</div> </div>
</div> </div>
</div>
{% if not is_ed_admin %}
{% include "colleges/_hx_nomination_veto_btn.html" %}
{% endif %} {% endif %}
<div class="col-12 col-md mb-3"> </div>
<div class="row mb-0">
<div class="col-12 col-md-6 mb-3">
<div class="card"> <div class="card">
<div class="card-header">Details</div> <div class="card-header">Details</div>
<div class="card-body p-0"> <div class="card-body p-0">
...@@ -65,7 +78,7 @@ ...@@ -65,7 +78,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="col-12 col-md mb-3"> <div class="col-12 col-md-6 mb-3">
<div class="card"> <div class="card">
<div class="card-header">Publications in SciPost Journals</div> <div class="card-header">Publications in SciPost Journals</div>
<div class="card-body"> <div class="card-body">
......
{% load crispy_forms_tags %}
<div class="veto-btn-container col-12 border border-dark p-2">
<h3>Exercise your right to veto:</h3>
<p>
Use this form to veto a nomination by providing some justification for your decision.
Comments provided to fellows will be visible to all other fellows, while those to editorial administration will remain private.
</p>
{% crispy form %}
</div>
<div class="col-auto d-flex flex-column justify-content-between mb-3 veto-btn-container">
{% if fellow in nomination.vetoes.all %}
<div class="bg-dark p-2 text-center">
<span class="fs-5 text-white">Nomination
<br />
Vetoed</span>
</div>
{% else %}
<div class="fs-5 text-muted align-self-center">Something wrong?</div>
<button class="btn btn-sm btn-dark"
hx-get="{% url "colleges:_hx_nomination_veto" nomination_id=nomination.id %}"
hx-target="closest .veto-btn-container">
<span class="text-white">Veto</span>
</button>
{% endif %}
</div>
...@@ -216,6 +216,11 @@ urlpatterns = [ ...@@ -216,6 +216,11 @@ urlpatterns = [
views._hx_nomination_comments, views._hx_nomination_comments,
name="_hx_nomination_comments", name="_hx_nomination_comments",
), ),
path(
"_hx_veto",
views._hx_nomination_veto,
name="_hx_nomination_veto",
),
] ]
), ),
), ),
......
...@@ -43,6 +43,7 @@ from .constants import ( ...@@ -43,6 +43,7 @@ from .constants import (
from .forms import ( from .forms import (
CollegeChoiceForm, CollegeChoiceForm,
FellowshipNominationSearchForm, FellowshipNominationSearchForm,
FellowshipNominationVetoForm,
FellowshipNominationVotingRoundStartForm, FellowshipNominationVotingRoundStartForm,
FellowshipSearchForm, FellowshipSearchForm,
FellowshipDynSelForm, FellowshipDynSelForm,
...@@ -770,12 +771,14 @@ def _hx_nomination_round_remove_voter(request, round_id, voter_id): ...@@ -770,12 +771,14 @@ def _hx_nomination_round_remove_voter(request, round_id, voter_id):
def _hx_nomination_details_contents(request, nomination_id): def _hx_nomination_details_contents(request, nomination_id):
"""For (re)loading the details if modified.""" """For (re)loading the details if modified."""
nomination = get_object_or_404(FellowshipNomination, pk=nomination_id) nomination = get_object_or_404(FellowshipNomination, pk=nomination_id)
fellow = request.user.contributor.session_fellowship(request)
start_email_sent = nomination.events.filter( start_email_sent = nomination.events.filter(
description__contains="start email sent", description__contains="start email sent",
).exists() ).exists()
context = { context = {
"nomination": nomination, "nomination": nomination,
"start_email_sent": start_email_sent, "start_email_sent": start_email_sent,
"fellow": fellow,
} }
return render(request, "colleges/_hx_nomination_details_contents.html", context) return render(request, "colleges/_hx_nomination_details_contents.html", context)
...@@ -942,6 +945,42 @@ def _hx_nomination_vote(request, round_id): ...@@ -942,6 +945,42 @@ def _hx_nomination_vote(request, round_id):
return render(request, "colleges/_hx_nomination_vote.html", context) return render(request, "colleges/_hx_nomination_vote.html", context)
@login_required
@user_passes_test(is_edadmin_or_advisory_or_active_regular_or_senior_fellow)
def _hx_nomination_veto(request, nomination_id):
fellow = request.user.contributor.session_fellowship(request)
nomination = get_object_or_404(FellowshipNomination, pk=nomination_id)
# Check that vetoer is a sneior fellow is in the same college as the nomination
if (
not fellow.contributor.fellowships.filter(college=nomination.college)
.senior()
.active()
.exists()
):
return HTMXResponse(
"""You are not an active senior fellow of this college.""",
tag="danger",
)
form = FellowshipNominationVetoForm(
request.POST or None, fellow=fellow, nomination=nomination
)
if form.is_valid():
form.save()
return render(
request,
"colleges/_hx_nomination_veto_btn.html",
{
"nomination": nomination,
"fellow": fellow,
},
)
return render(request, "colleges/_hx_nomination_veto.html", {"form": form})
@login_required @login_required
@user_passes_test(is_edadmin) @user_passes_test(is_edadmin)
def _hx_voting_round_start_form(request, round_id): def _hx_voting_round_start_form(request, round_id):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment