mirror of
https://gitlab.com/animath/si/plateforme.git
synced 2024-12-24 17:42:23 +00:00
Add update note menu
This commit is contained in:
parent
be8904079d
commit
ef785a5eb8
@ -12,6 +12,8 @@ class ParticipationConfig(AppConfig):
|
|||||||
name = 'participation'
|
name = 'participation'
|
||||||
|
|
||||||
def ready(self):
|
def ready(self):
|
||||||
from participation.signals import create_team_participation, update_mailing_list
|
from participation.signals import create_notes, create_team_participation, update_mailing_list
|
||||||
pre_save.connect(update_mailing_list, "participation.Team")
|
pre_save.connect(update_mailing_list, "participation.Team")
|
||||||
post_save.connect(create_team_participation, "participation.Team")
|
post_save.connect(create_team_participation, "participation.Team")
|
||||||
|
post_save.connect(create_notes, "participation.Passage")
|
||||||
|
post_save.connect(create_notes, "participation.Pool")
|
||||||
|
@ -9,7 +9,7 @@ from django.core.exceptions import ValidationError
|
|||||||
from django.utils import formats
|
from django.utils import formats
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from .models import Participation, Passage, Pool, Team, Tournament, Solution, Synthesis
|
from .models import Note, Participation, Passage, Pool, Team, Tournament, Solution, Synthesis
|
||||||
|
|
||||||
|
|
||||||
class TeamForm(forms.ModelForm):
|
class TeamForm(forms.ModelForm):
|
||||||
@ -173,3 +173,10 @@ class SynthesisForm(forms.ModelForm):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Synthesis
|
model = Synthesis
|
||||||
fields = ('type', 'file',)
|
fields = ('type', 'file',)
|
||||||
|
|
||||||
|
|
||||||
|
class NoteForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Note
|
||||||
|
fields = ('defender_writing', 'defender_oral', 'opponent_writing',
|
||||||
|
'opponent_oral', 'reporter_writing', 'reporter_oral', )
|
||||||
|
@ -379,7 +379,8 @@ class Passage(models.Model):
|
|||||||
final_solution=self.pool.tournament.final)
|
final_solution=self.pool.tournament.final)
|
||||||
|
|
||||||
def avg(self, iterator) -> int:
|
def avg(self, iterator) -> int:
|
||||||
return sum(iterator) / len(list(iterator))
|
items = [i for i in iterator if i]
|
||||||
|
return sum(items) / len(items) if items else 0
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def average_defender_writing(self):
|
def average_defender_writing(self):
|
||||||
@ -581,6 +582,9 @@ class Note(models.Model):
|
|||||||
default=0,
|
default=0,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_absolute_url(self):
|
||||||
|
return reverse_lazy("participation:passage_detail", args=(self.passage.pk,))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return _("Notes of {jury} for {passage}").format(jury=self.jury, passage=self.passage)
|
return _("Notes of {jury} for {passage}").format(jury=self.jury, passage=self.passage)
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
# Copyright (C) 2020 by Animath
|
# Copyright (C) 2020 by Animath
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
from participation.models import Participation, Team
|
from participation.models import Note, Participation, Passage, Pool, Team
|
||||||
from tfjm.lists import get_sympa_client
|
from tfjm.lists import get_sympa_client
|
||||||
|
|
||||||
|
|
||||||
@ -33,3 +34,13 @@ def update_mailing_list(instance: Team, **_):
|
|||||||
for coach in instance.coachs.all():
|
for coach in instance.coachs.all():
|
||||||
get_sympa_client().subscribe(coach.user.email, f"equipe-{instance.trigram.lower()}", False,
|
get_sympa_client().subscribe(coach.user.email, f"equipe-{instance.trigram.lower()}", False,
|
||||||
f"{coach.user.first_name} {coach.user.last_name}")
|
f"{coach.user.first_name} {coach.user.last_name}")
|
||||||
|
|
||||||
|
|
||||||
|
def create_notes(instance: Union[Passage, Pool], **_):
|
||||||
|
if isinstance(instance, Pool):
|
||||||
|
for passage in instance.passages.all():
|
||||||
|
create_notes(passage)
|
||||||
|
return
|
||||||
|
|
||||||
|
for jury in instance.pool.juries.all():
|
||||||
|
Note.objects.get_or_create(jury=jury, passage=instance)
|
||||||
|
13
apps/participation/templates/participation/note_form.html
Normal file
13
apps/participation/templates/participation/note_form.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% load crispy_forms_filters i18n %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form method="post">
|
||||||
|
<div id="form-content">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form|crispy }}
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary" type="submit">{% trans "Update" %}</button>
|
||||||
|
</form>
|
||||||
|
{% endblock content %}
|
@ -40,6 +40,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% if user.registration.is_admin %}
|
{% if user.registration.is_admin %}
|
||||||
<div class="card-footer text-center">
|
<div class="card-footer text-center">
|
||||||
|
<button class="btn btn-info" data-toggle="modal" data-target="#updateNotesModal">{% trans "Update notes" %}</button>
|
||||||
<button class="btn btn-primary" data-toggle="modal" data-target="#updatePassageModal">{% trans "Update" %}</button>
|
<button class="btn btn-primary" data-toggle="modal" data-target="#updatePassageModal">{% trans "Update" %}</button>
|
||||||
</div>
|
</div>
|
||||||
{% elif user.registration.participates %}
|
{% elif user.registration.participates %}
|
||||||
@ -54,6 +55,11 @@
|
|||||||
{% trans "Update" as modal_button %}
|
{% trans "Update" as modal_button %}
|
||||||
{% url "participation:passage_update" pk=passage.pk as modal_action %}
|
{% url "participation:passage_update" pk=passage.pk as modal_action %}
|
||||||
{% include "base_modal.html" with modal_id="updatePassage" %}
|
{% include "base_modal.html" with modal_id="updatePassage" %}
|
||||||
|
|
||||||
|
{% trans "Update notes" as modal_title %}
|
||||||
|
{% trans "Update" as modal_button %}
|
||||||
|
{% url "participation:update_notes" pk=my_note.pk as modal_action %}
|
||||||
|
{% include "base_modal.html" with modal_id="updateNotes" %}
|
||||||
{% elif user.registration.participates %}
|
{% elif user.registration.participates %}
|
||||||
{% trans "Upload synthesis" as modal_title %}
|
{% trans "Upload synthesis" as modal_title %}
|
||||||
{% trans "Upload" as modal_button %}
|
{% trans "Upload" as modal_button %}
|
||||||
@ -71,6 +77,12 @@
|
|||||||
if (!modalBody.html().trim())
|
if (!modalBody.html().trim())
|
||||||
modalBody.load("{% url "participation:passage_update" pk=passage.pk %} #form-content")
|
modalBody.load("{% url "participation:passage_update" pk=passage.pk %} #form-content")
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('button[data-target="#updateNotesModal"]').click(function() {
|
||||||
|
let modalBody = $("#updateNotesModal div.modal-body");
|
||||||
|
if (!modalBody.html().trim())
|
||||||
|
modalBody.load("{% url "participation:update_notes" pk=my_note.pk %} #form-content")
|
||||||
|
});
|
||||||
{% elif user.registration.participates %}
|
{% elif user.registration.participates %}
|
||||||
$('button[data-target="#uploadSynthesisModal"]').click(function() {
|
$('button[data-target="#uploadSynthesisModal"]').click(function() {
|
||||||
let modalBody = $("#uploadSynthesisModal div.modal-body");
|
let modalBody = $("#uploadSynthesisModal div.modal-body");
|
||||||
|
@ -5,7 +5,7 @@ from django.urls import path
|
|||||||
from django.views.generic import TemplateView
|
from django.views.generic import TemplateView
|
||||||
|
|
||||||
from .views import CreateTeamView, JoinTeamView, \
|
from .views import CreateTeamView, JoinTeamView, \
|
||||||
MyParticipationDetailView, MyTeamDetailView, ParticipationDetailView, \
|
MyParticipationDetailView, MyTeamDetailView, NoteUpdateView, ParticipationDetailView, \
|
||||||
PassageCreateView, PassageDetailView, PassageUpdateView, PoolCreateView, PoolDetailView, \
|
PassageCreateView, PassageDetailView, PassageUpdateView, PoolCreateView, PoolDetailView, \
|
||||||
PoolUpdateView, PoolUpdateTeamsView, TeamAuthorizationsView, TeamDetailView, TeamLeaveView, TeamListView, \
|
PoolUpdateView, PoolUpdateTeamsView, TeamAuthorizationsView, TeamDetailView, TeamLeaveView, TeamListView, \
|
||||||
TeamUpdateView, TournamentCreateView, TournamentDetailView, TournamentListView, TournamentUpdateView, \
|
TeamUpdateView, TournamentCreateView, TournamentDetailView, TournamentListView, TournamentUpdateView, \
|
||||||
@ -38,5 +38,6 @@ urlpatterns = [
|
|||||||
path("pools/passages/<int:pk>/", PassageDetailView.as_view(), name="passage_detail"),
|
path("pools/passages/<int:pk>/", PassageDetailView.as_view(), name="passage_detail"),
|
||||||
path("pools/passages/<int:pk>/update/", PassageUpdateView.as_view(), name="passage_update"),
|
path("pools/passages/<int:pk>/update/", PassageUpdateView.as_view(), name="passage_update"),
|
||||||
path("pools/passages/<int:pk>/solution/", SynthesisUploadView.as_view(), name="upload_synthesis"),
|
path("pools/passages/<int:pk>/solution/", SynthesisUploadView.as_view(), name="upload_synthesis"),
|
||||||
|
path("pools/passages/notes/<int:pk>/", NoteUpdateView.as_view(), name="update_notes"),
|
||||||
path("chat/", TemplateView.as_view(template_name="participation/chat.html"), name="chat")
|
path("chat/", TemplateView.as_view(template_name="participation/chat.html"), name="chat")
|
||||||
]
|
]
|
||||||
|
@ -23,9 +23,9 @@ from tfjm.lists import get_sympa_client
|
|||||||
from tfjm.matrix import Matrix
|
from tfjm.matrix import Matrix
|
||||||
from tfjm.views import AdminMixin
|
from tfjm.views import AdminMixin
|
||||||
|
|
||||||
from .forms import JoinTeamForm, ParticipationForm, PassageForm, PoolForm, PoolTeamsForm, RequestValidationForm, \
|
from .forms import JoinTeamForm, NoteForm, ParticipationForm, PassageForm, PoolForm, PoolTeamsForm, \
|
||||||
TeamForm, TournamentForm, ValidateParticipationForm, SolutionForm, SynthesisForm
|
RequestValidationForm, TeamForm, TournamentForm, ValidateParticipationForm, SolutionForm, SynthesisForm
|
||||||
from .models import Participation, Passage, Pool, Team, Tournament, Solution, Synthesis
|
from .models import Note, Participation, Passage, Pool, Team, Tournament, Solution, Synthesis
|
||||||
from .tables import TeamTable, TournamentTable, ParticipationTable, PoolTable
|
from .tables import TeamTable, TournamentTable, ParticipationTable, PoolTable
|
||||||
|
|
||||||
|
|
||||||
@ -513,6 +513,12 @@ class PassageCreateView(AdminMixin, CreateView):
|
|||||||
class PassageDetailView(LoginRequiredMixin, DetailView):
|
class PassageDetailView(LoginRequiredMixin, DetailView):
|
||||||
model = Passage
|
model = Passage
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
if self.request.user.registration in self.object.pool.juries.all():
|
||||||
|
context["my_note"] = Note.objects.get(passage=self.object, jury=self.request.user.registration)
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
class PassageUpdateView(AdminMixin, UpdateView):
|
class PassageUpdateView(AdminMixin, UpdateView):
|
||||||
model = Passage
|
model = Passage
|
||||||
@ -551,3 +557,8 @@ class SynthesisUploadView(LoginRequiredMixin, FormView):
|
|||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
return reverse_lazy("participation:passage_detail", args=(self.passage.pk,))
|
return reverse_lazy("participation:passage_detail", args=(self.passage.pk,))
|
||||||
|
|
||||||
|
|
||||||
|
class NoteUpdateView(LoginRequiredMixin, UpdateView):
|
||||||
|
model = Note
|
||||||
|
form_class = NoteForm
|
||||||
|
Loading…
Reference in New Issue
Block a user