Add form to add juries in a pool

Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
Emmy D'Anello 2023-04-05 16:54:16 +02:00
parent c1482d4802
commit 2840a15fd5
Signed by: ynerant
GPG Key ID: 3A75C55819C8CF85
10 changed files with 308 additions and 96 deletions

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: TFJM\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-04-05 10:43+0200\n"
"POT-Creation-Date: 2023-04-05 16:46+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -422,80 +422,94 @@ msgstr "rapporteur⋅e"
msgid "problem"
msgstr "numéro de problème"
#: participation/forms.py:27
#: participation/forms.py:30
msgid "This name is already used."
msgstr "Ce nom est déjà utilisé."
#: participation/forms.py:34 participation/models.py:40
#: participation/forms.py:37 participation/models.py:40
msgid "The trigram must be composed of three uppercase letters."
msgstr "Le trigramme doit être composé de trois lettres majuscules."
#: participation/forms.py:37
#: participation/forms.py:40
msgid "This trigram is already used."
msgstr "Ce trigramme est déjà utilisé."
#: participation/forms.py:52
#: participation/forms.py:55
msgid "No team was found with this access code."
msgstr "Aucune équipe n'a été trouvée avec ce code d'accès."
#: participation/forms.py:81 participation/forms.py:289
#: participation/forms.py:84 participation/forms.py:334
#: registration/forms.py:113 registration/forms.py:135
#: registration/forms.py:157 registration/forms.py:179
#: registration/forms.py:224
msgid "The uploaded file size must be under 2 Mo."
msgstr "Le fichier envoyé doit peser moins de 2 Mo."
#: participation/forms.py:83 registration/forms.py:115
#: participation/forms.py:86 registration/forms.py:115
#: registration/forms.py:137 registration/forms.py:159
#: registration/forms.py:181 registration/forms.py:226
msgid "The uploaded file must be a PDF, PNG of JPEG file."
msgstr "Le fichier envoyé doit être au format PDF, PNG ou JPEG."
#: participation/forms.py:101
#: participation/forms.py:104
msgid "I engage myself to participate to the whole TFJM²."
msgstr "Je m'engage à participer à l'intégralité du TFJM²."
#: participation/forms.py:116
#: participation/forms.py:119
msgid "Message to address to the team:"
msgstr "Message à adresser à l'équipe :"
#: participation/forms.py:151
#: participation/forms.py:154
msgid "The uploaded file size must be under 5 Mo."
msgstr "Le fichier envoyé doit peser moins de 5 Mo."
#: participation/forms.py:153 participation/forms.py:291
#: participation/forms.py:156 participation/forms.py:336
msgid "The uploaded file must be a PDF file."
msgstr "Le fichier envoyé doit être au format PDF."
#: participation/forms.py:157
#: participation/forms.py:160
msgid "The PDF file must not have more than 30 pages."
msgstr "Le fichier PDF ne doit pas avoir plus de 30 pages."
#: participation/forms.py:203
#: participation/forms.py:209
msgid "Add new jury"
msgstr "Ajouter un⋅e nouvelleau juré⋅e"
#: participation/forms.py:224
#: participation/templates/participation/pool_detail.html:77
#: participation/templates/participation/tournament_detail.html:111
msgid "Add"
msgstr "Ajouter"
#: participation/forms.py:237 registration/forms.py:35 registration/forms.py:60
msgid "This email address is already used."
msgstr "Cette adresse e-mail est déjà utilisée."
#: participation/forms.py:248
msgid "CSV file:"
msgstr "Tableur au format CSV :"
#: participation/forms.py:220
#: participation/forms.py:265
msgid ""
"This file contains non-UTF-8 content. Please send your sheet as a CSV file."
msgstr ""
"Ce fichier contient des éléments non-UTF-8. Merci d'envoyer votre tableur au "
"format CSV."
#: participation/forms.py:247
#: participation/forms.py:292
msgid "The following note is higher of the maximum expected value:"
msgstr "La note suivante est supérieure au maximum attendu :"
#: participation/forms.py:255
#: participation/forms.py:300
msgid "The following user was not found:"
msgstr "L'utilisateur⋅rice suivant n'a pas été trouvé :"
#: participation/forms.py:272
#: participation/forms.py:317
msgid "The defender, the opponent and the reporter must be different."
msgstr ""
"Læ défenseur⋅se, l'opposant⋅e et læ rapporteur⋅e doivent être différent⋅es."
#: participation/forms.py:276
#: participation/forms.py:321
msgid "This defender did not work on this problem."
msgstr "Ce⋅tte défenseur⋅se ne travaille pas sur ce problème."
@ -853,12 +867,12 @@ msgstr ""
#: participation/templates/participation/create_team.html:11
#: participation/templates/participation/tournament_form.html:14
#: tfjm/templates/base.html:248
#: tfjm/templates/base.html:255
msgid "Create"
msgstr "Créer"
#: participation/templates/participation/join_team.html:11
#: tfjm/templates/base.html:243
#: tfjm/templates/base.html:250
msgid "Join"
msgstr "Rejoindre"
@ -866,9 +880,10 @@ msgstr "Rejoindre"
#: participation/templates/participation/passage_detail.html:46
#: participation/templates/participation/passage_detail.html:102
#: participation/templates/participation/passage_detail.html:108
#: participation/templates/participation/pool_detail.html:58
#: participation/templates/participation/pool_detail.html:77
#: participation/templates/participation/pool_add_jurys.html:35
#: participation/templates/participation/pool_detail.html:63
#: participation/templates/participation/pool_detail.html:82
#: participation/templates/participation/pool_detail.html:87
#: participation/templates/participation/team_detail.html:126
#: participation/templates/participation/team_detail.html:190
#: participation/templates/participation/tournament_form.html:12
@ -932,7 +947,7 @@ msgstr "Envoyer une solution"
#: participation/templates/participation/participation_detail.html:59
#: participation/templates/participation/passage_detail.html:114
#: participation/templates/participation/pool_detail.html:87
#: participation/templates/participation/pool_detail.html:92
#: participation/templates/participation/team_detail.html:185
#: participation/templates/participation/upload_motivation_letter.html:13
#: participation/templates/participation/upload_notes.html:24
@ -1037,6 +1052,37 @@ msgstr "Points de læ rapporteur⋅e :"
msgid "Update passage"
msgstr "Modifier le passage"
#: participation/templates/participation/pool_add_jurys.html:9
msgid "You can here register juries for the pool."
msgstr "Vous pouvez inscrire ici les juré⋅es de la poule."
#: participation/templates/participation/pool_add_jurys.html:10
msgid ""
"Be careful: this form register new users. To add existing users into the "
"jury, please use this form:"
msgstr ""
"Attention : ce formulaire inscrit des nouvelleaux utilisateur⋅rices. "
"Pour ajouter des utilisateur⋅rices au jury, utilisez ce formulaire :"
#: participation/templates/participation/pool_add_jurys.html:11
#: participation/templates/participation/pool_add_jurys.html:34
#: participation/templates/participation/pool_detail.html:81
#: participation/templates/participation/pool_form.html:11
msgid "Update pool"
msgstr "Modifier la poule"
#: participation/templates/participation/pool_add_jurys.html:14
msgid "For now, the registered juries for the tournament are:"
msgstr "Pour l'instant, les juré⋅es inscrit⋅es au tournoi sont :"
#: participation/templates/participation/pool_add_jurys.html:19
msgid "There is no jury yet."
msgstr "Il n'y a pas de juré⋅e pour le moment."
#: participation/templates/participation/pool_add_jurys.html:30
msgid "Back to pool detail"
msgstr "Retour aux détails de la poule"
#: participation/templates/participation/pool_detail.html:15
msgid "Round:"
msgstr "Tour :"
@ -1053,48 +1099,42 @@ msgstr "Équipes :"
msgid "Juries:"
msgstr "Juré⋅es :"
#: participation/templates/participation/pool_detail.html:31
#: participation/templates/participation/pool_detail.html:32
msgid "Add jurys"
msgstr "Ajouter des juré⋅es"
#: participation/templates/participation/pool_detail.html:36
msgid "Defended solutions:"
msgstr "Solutions défendues :"
#: participation/templates/participation/pool_detail.html:38
#: participation/templates/participation/pool_detail.html:43
msgid "BigBlueButton link:"
msgstr "Lien BigBlueButton :"
#: participation/templates/participation/pool_detail.html:44
#: participation/templates/participation/pool_detail.html:49
#: participation/templates/participation/tournament_detail.html:97
msgid "Ranking"
msgstr "Classement"
#: participation/templates/participation/pool_detail.html:57
#: participation/templates/participation/pool_detail.html:71
#: participation/templates/participation/pool_detail.html:62
#: participation/templates/participation/pool_detail.html:76
msgid "Add passage"
msgstr "Ajouter un passage"
#: participation/templates/participation/pool_detail.html:59
#: participation/templates/participation/pool_detail.html:81
#: participation/templates/participation/pool_detail.html:64
#: participation/templates/participation/pool_detail.html:86
msgid "Update teams"
msgstr "Modifier les équipes"
#: participation/templates/participation/pool_detail.html:60
#: participation/templates/participation/pool_detail.html:65
msgid "Upload notes from a CSV file"
msgstr "Soumettre les notes à partir d'un fichier CSV"
#: participation/templates/participation/pool_detail.html:67
#: participation/templates/participation/pool_detail.html:72
msgid "Passages"
msgstr "Passages"
#: participation/templates/participation/pool_detail.html:72
#: participation/templates/participation/tournament_detail.html:111
msgid "Add"
msgstr "Ajouter"
#: participation/templates/participation/pool_detail.html:76
#: participation/templates/participation/pool_form.html:11
msgid "Update pool"
msgstr "Modifier la poule"
#: participation/templates/participation/pool_detail.html:86
#: participation/templates/participation/pool_detail.html:91
msgid "Upload notes"
msgstr "Envoyer les notes"
@ -1228,7 +1268,7 @@ msgid "Invalidate"
msgstr "Invalider"
#: participation/templates/participation/team_detail.html:184
#: participation/views.py:333
#: participation/views.py:335
msgid "Upload motivation letter"
msgstr "Envoyer la lettre de motivation"
@ -1237,7 +1277,7 @@ msgid "Update team"
msgstr "Modifier l'équipe"
#: participation/templates/participation/team_detail.html:194
#: participation/views.py:442
#: participation/views.py:444
msgid "Leave team"
msgstr "Quitter l'équipe"
@ -1246,7 +1286,7 @@ msgid "Are you sure that you want to leave this team?"
msgstr "Êtes-vous sûr·e de vouloir quitter cette équipe ?"
#: participation/templates/participation/team_list.html:6
#: tfjm/templates/base.html:236
#: tfjm/templates/base.html:243
msgid "All teams"
msgstr "Toutes les équipes"
@ -1329,7 +1369,7 @@ msgid "Add pool"
msgstr "Ajouter une poule"
#: participation/templates/participation/tournament_list.html:6
#: tfjm/templates/base.html:232
#: tfjm/templates/base.html:239
msgid "All tournaments"
msgstr "Tous les tournois"
@ -1349,49 +1389,49 @@ msgstr "Télécharger la fiche de notation vierge"
msgid "Templates:"
msgstr "Modèles :"
#: participation/views.py:44 tfjm/templates/base.html:73
#: tfjm/templates/base.html:247
#: participation/views.py:46 tfjm/templates/base.html:73
#: tfjm/templates/base.html:254
msgid "Create team"
msgstr "Créer une équipe"
#: participation/views.py:53 participation/views.py:98
#: participation/views.py:55 participation/views.py:100
msgid "You don't participate, so you can't create a team."
msgstr "Vous ne participez pas, vous ne pouvez pas créer d'équipe."
#: participation/views.py:55 participation/views.py:100
#: participation/views.py:57 participation/views.py:102
msgid "You are already in a team."
msgstr "Vous êtes déjà dans une équipe."
#: participation/views.py:89 tfjm/templates/base.html:78
#: tfjm/templates/base.html:242
#: participation/views.py:91 tfjm/templates/base.html:78
#: tfjm/templates/base.html:249
msgid "Join team"
msgstr "Rejoindre une équipe"
#: participation/views.py:151 participation/views.py:448
#: participation/views.py:482
#: participation/views.py:153 participation/views.py:450
#: participation/views.py:484
msgid "You are not in a team."
msgstr "Vous n'êtes pas dans une équipe."
#: participation/views.py:152 participation/views.py:483
#: participation/views.py:154 participation/views.py:485
msgid "You don't participate, so you don't have any team."
msgstr "Vous ne participez pas, vous n'avez donc pas d'équipe."
#: participation/views.py:178
#: participation/views.py:180
#, python-brace-format
msgid "Detail of team {trigram}"
msgstr "Détails de l'équipe {trigram}"
#: participation/views.py:215
#: participation/views.py:217
msgid "You don't participate, so you can't request the validation of the team."
msgstr ""
"Vous ne participez pas, vous ne pouvez pas demander la validation de "
"l'équipe."
#: participation/views.py:218
#: participation/views.py:220
msgid "The validation of the team is already done or pending."
msgstr "La validation de l'équipe est déjà faite ou en cours."
#: participation/views.py:221
#: participation/views.py:223
msgid ""
"The team can't be validated: missing email address confirmations, "
"authorizations, people, motivation letter or the tournament is not set."
@ -1400,79 +1440,93 @@ msgstr ""
"d'adresse e-mail, soit une autorisation, soit des personnes, soit la lettre "
"de motivation, soit le tournoi n'a pas été choisi."
#: participation/views.py:243
#: participation/views.py:245
msgid "You are not an organizer of the tournament."
msgstr "Vous n'êtes pas un⋅e organisateur⋅rice du tournoi."
#: participation/views.py:246
#: participation/views.py:248
msgid "This team has no pending validation."
msgstr "L'équipe n'a pas de validation en attente."
#: participation/views.py:276
#: participation/views.py:278
msgid "You must specify if you validate the registration or not."
msgstr "Vous devez spécifier si vous validez l'inscription ou non."
#: participation/views.py:311
#: participation/views.py:313
#, python-brace-format
msgid "Update team {trigram}"
msgstr "Mise à jour de l'équipe {trigram}"
#: participation/views.py:372 participation/views.py:428
#: participation/views.py:374 participation/views.py:430
#, python-brace-format
msgid "Motivation letter of {team}.{ext}"
msgstr "Lettre de motivation de {team}.{ext}"
#: participation/views.py:403
#: participation/views.py:405
#, python-brace-format
msgid "Photo authorization of {participant}.{ext}"
msgstr "Autorisation de droit à l'image de {participant}.{ext}"
#: participation/views.py:409
#: participation/views.py:411
#, python-brace-format
msgid "Parental authorization of {participant}.{ext}"
msgstr "Autorisation parentale de {participant}.{ext}"
#: participation/views.py:416
#: participation/views.py:418
#, python-brace-format
msgid "Health sheet of {participant}.{ext}"
msgstr "Fiche sanitaire de {participant}.{ext}"
#: participation/views.py:422
#: participation/views.py:424
#, python-brace-format
msgid "Vaccine sheet of {participant}.{ext}"
msgstr "Carnet de vaccination de {participant}.{ext}"
#: participation/views.py:432
#: participation/views.py:434
#, python-brace-format
msgid "Photo authorizations of team {trigram}.zip"
msgstr "Autorisations de droit à l'image de l'équipe {trigram}.zip"
#: participation/views.py:450
#: participation/views.py:452
msgid "The team is already validated or the validation is pending."
msgstr "La validation de l'équipe est déjà faite ou en cours."
#: participation/views.py:497
#: participation/views.py:499
msgid "The team is not validated yet."
msgstr "L'équipe n'est pas encore validée."
#: participation/views.py:511
#: participation/views.py:513
#, python-brace-format
msgid "Participation of team {trigram}"
msgstr "Participation de l'équipe {trigram}"
#: participation/views.py:637
#: participation/views.py:639
msgid "You can't upload a solution after the deadline."
msgstr "Vous ne pouvez pas envoyer de solution après la date limite."
#: participation/views.py:740
#: participation/views.py:727
#, python-brace-format
msgid "Jurys of {pool}"
msgstr "Juré⋅es de la {pool}"
#: participation/views.py:749
msgid "New TFJM² jury account"
msgstr "Nouveau compte de juré⋅e pour le TFJM²"
#: participation/views.py:761
#, python-brace-format
msgid "The jury {name} has been successfully added!"
msgstr "Læ juré⋅e {name} a été ajouté⋅e avec succès !"
#: participation/views.py:796
msgid "The following user is not registered as a jury:"
msgstr "L'utilisateur⋅rice suivant n'est pas inscrit⋅e en tant que juré⋅e :"
#: participation/views.py:748
#: participation/views.py:804
msgid "Notes were successfully uploaded."
msgstr "Les notes ont bien été envoyées."
#: participation/views.py:860
#: participation/views.py:916
msgid "You can't upload a synthesis after the deadline."
msgstr "Vous ne pouvez pas envoyer de note de synthèse après la date limite."
@ -1502,10 +1556,6 @@ msgstr "participant⋅e"
msgid "coach"
msgstr "encadrant⋅e"
#: registration/forms.py:35 registration/forms.py:60
msgid "This email address is already used."
msgstr "Cette adresse e-mail est déjà utilisée."
#: registration/forms.py:218
msgid "Pending"
msgstr "En attente"
@ -1850,8 +1900,8 @@ msgid "Your password has been set. You may go ahead and log in now."
msgstr "Votre mot de passe a été changé. Vous pouvez désormais vous connecter."
#: registration/templates/registration/password_reset_complete.html:10
#: tfjm/templates/base.html:133 tfjm/templates/base.html:252
#: tfjm/templates/base.html:253 tfjm/templates/registration/login.html:7
#: tfjm/templates/base.html:133 tfjm/templates/base.html:259
#: tfjm/templates/base.html:260 tfjm/templates/registration/login.html:7
#: tfjm/templates/registration/login.html:8
#: tfjm/templates/registration/login.html:25
msgid "Log in"
@ -2305,15 +2355,15 @@ msgstr ""
"avez reçu par mail. Vous pouvez renvoyer un mail en cliquant sur <a "
"href=\"%(send_email_url)s\">ce lien</a>."
#: tfjm/templates/base.html:190
#: tfjm/templates/base.html:197
msgid "Contact us"
msgstr "Nous contacter"
#: tfjm/templates/base.html:217
#: tfjm/templates/base.html:224
msgid "About"
msgstr "À propos"
#: tfjm/templates/base.html:239
#: tfjm/templates/base.html:246
msgid "Search results"
msgstr "Résultats de la recherche"

View File

@ -6,6 +6,9 @@ from io import StringIO
import re
from typing import Iterable
from crispy_forms.bootstrap import InlineField
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, Fieldset, Layout, Div
from django import forms
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
@ -197,6 +200,48 @@ class PoolTeamsForm(forms.ModelForm):
}),
}
class AddJuryForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_class = 'form-inline'
self.helper.layout = Fieldset(
_("Add new jury"),
Div(
Div(
InlineField('first_name', autofocus="autofocus"),
css_class='col-xl-3',
),
Div(
InlineField('last_name'),
css_class='col-xl-3',
),
Div(
InlineField('email'),
css_class='col-xl-5',
),
Div(
Submit('submit', _("Add")),
css_class='col-xl-1',
),
css_class='row',
)
)
def clean_email(self):
"""
Ensure that the email address is unique.
"""
email = self.data["email"]
if User.objects.filter(email=email).exists():
self.add_error("email", _("This email address is already used."))
return email
class Meta:
model = User
fields = ('first_name', 'last_name', 'email',)
class UploadNotesForm(forms.Form):
file = forms.FileField(

View File

@ -0,0 +1,47 @@
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% load i18n %}
{% block content %}
<div class="alert alert-info">
<p>
{% trans "You can here register juries for the pool." %}
{% trans "Be careful: this form register new users. To add existing users into the jury, please use this form:" %}
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#updatePoolModal">{% trans "Update pool" %}</button>
</p>
<p>
{% trans "For now, the registered juries for the tournament are:" %}
<ul>
{% for jury in pool.juries.all %}
<li>{{ jury.user.first_name }} {{ jury.user.last_name }} (<a class="alert-link" href="mailto:{{ jury.user.email }}">{{ jury.user.email }}</a>)</li>
{% empty %}
<li><i>{% trans "There is no jury yet." %}</i></li>
{% endfor %}
</ul>
</p>
</div>
{% crispy form %}
<hr>
<div class="row text-center">
<a href="{% url 'participation:pool_detail' pk=pool.pk %}" class="btn btn-secondary">
<i class="fas fa-arrow-left"></i> {% trans "Back to pool detail" %}
</a>
</div>
{% trans "Update pool" as modal_title %}
{% trans "Update" as modal_button %}
{% url "participation:pool_update" pk=pool.pk as modal_action %}
{% include "base_modal.html" with modal_id="updatePool" %}
{% endblock %}
{% block extrajavascript %}
<script>
document.addEventListener('DOMContentLoaded', () => {
initModal("updatePool", "{% url "participation:pool_update" pk=pool.pk %}")
})
</script>
{% endblock %}

View File

@ -26,7 +26,12 @@
</dd>
<dt class="col-sm-3">{% trans "Juries:" %}</dt>
<dd class="col-sm-9">{{ pool.juries.all|join:", " }}</dd>
<dd class="col-sm-9">
{{ pool.juries.all|join:", " }}
<a class="badge rounded-pill text-bg-info" href="{% url 'participation:pool_add_jurys' pk=pool.pk %}">
<i class="fas fa-plus"></i> {% trans "Add jurys" %}
</a>
</dd>
<dt class="col-sm-3">{% trans "Defended solutions:" %}</dt>
<dd class="col-sm-9">

View File

@ -5,8 +5,8 @@ from django.urls import path
from django.views.generic import TemplateView
from .views import CreateTeamView, JoinTeamView, MyParticipationDetailView, MyTeamDetailView, NoteUpdateView, \
ParticipationDetailView, PassageCreateView, PassageDetailView, PassageUpdateView, PoolCreateView, PoolDetailView, \
PoolUpdateTeamsView, PoolUpdateView, PoolUploadNotesView, SolutionUploadView, SynthesisUploadView,\
ParticipationDetailView, PassageCreateView, PassageDetailView, PassageUpdateView, PoolAddJurysView, PoolCreateView,\
PoolDetailView, PoolUpdateTeamsView, PoolUpdateView, PoolUploadNotesView, SolutionUploadView, SynthesisUploadView,\
TeamAuthorizationsView, TeamDetailView, TeamLeaveView, TeamListView, TeamUpdateView, \
TeamUploadMotivationLetterView, TournamentCreateView, TournamentDetailView, TournamentExportCSVView, \
TournamentListView, TournamentUpdateView
@ -37,6 +37,7 @@ urlpatterns = [
path("pools/<int:pk>/", PoolDetailView.as_view(), name="pool_detail"),
path("pools/<int:pk>/update/", PoolUpdateView.as_view(), name="pool_update"),
path("pools/<int:pk>/update-teams/", PoolUpdateTeamsView.as_view(), name="pool_update_teams"),
path("pools/<int:pk>/add-jurys/", PoolAddJurysView.as_view(), name="pool_add_jurys"),
path("pools/<int:pk>/upload-notes/", PoolUploadNotesView.as_view(), name="pool_upload_notes"),
path("pools/passages/add/<int:pk>/", PassageCreateView.as_view(), name="passage_create"),
path("pools/passages/<int:pk>/", PassageDetailView.as_view(), name="passage_detail"),

View File

@ -1,5 +1,6 @@
# Copyright (C) 2020 by Animath
# SPDX-License-Identifier: GPL-3.0-or-later
import csv
from io import BytesIO
import os
@ -17,18 +18,19 @@ from django.shortcuts import redirect
from django.template.loader import render_to_string
from django.urls import reverse_lazy
from django.utils import timezone
from django.utils.crypto import get_random_string
from django.utils.translation import gettext_lazy as _
from django.views.generic import CreateView, DetailView, FormView, RedirectView, TemplateView, UpdateView, View
from django.views.generic.edit import FormMixin, ProcessFormView
from django_tables2 import SingleTableView
from magic import Magic
from registration.models import StudentRegistration
from registration.models import StudentRegistration, VolunteerRegistration
from tfjm.lists import get_sympa_client
from tfjm.matrix import Matrix
from tfjm.views import AdminMixin, VolunteerMixin
from .forms import JoinTeamForm, MotivationLetterForm, NoteForm, ParticipationForm, PassageForm, PoolForm, \
PoolTeamsForm, RequestValidationForm, SolutionForm, SynthesisForm, TeamForm, TournamentForm, \
from .forms import AddJuryForm, JoinTeamForm, MotivationLetterForm, NoteForm, ParticipationForm, PassageForm, \
PoolForm, PoolTeamsForm, RequestValidationForm, SolutionForm, SynthesisForm, TeamForm, TournamentForm, \
UploadNotesForm, ValidateParticipationForm
from .models import Note, Participation, Passage, Pool, Solution, Synthesis, Team, Tournament
from .tables import NoteTable, ParticipationTable, PassageTable, PoolTable, TeamTable, TournamentTable
@ -715,6 +717,60 @@ class PoolUpdateTeamsView(VolunteerMixin, UpdateView):
return self.handle_no_permission()
class PoolAddJurysView(VolunteerMixin, FormView, DetailView):
model = Pool
form_class = AddJuryForm
template_name = 'participation/pool_add_jurys.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['title'] = _("Jurys of {pool}").format(pool=self.object)
return context
@transaction.atomic
def form_valid(self, form):
self.object = self.get_object()
form.save()
user = form.instance
reg = VolunteerRegistration.objects.create(
user=user,
professional_activity="Juré⋅e du tournoi " + self.object.tournament.name,
)
self.object.juries.add(reg)
self.object.save()
reg.send_email_validation_link()
password = get_random_string(16)
user.set_password(password)
user.save()
subject = "[TFJM²] " + str(_("New TFJM² jury account"))
site = Site.objects.first()
message = render_to_string('registration/mails/add_organizer.txt', dict(user=user,
inviter=self.request.user,
password=password,
domain=site.domain))
html = render_to_string('registration/mails/add_organizer.html', dict(user=user,
inviter=self.request.user,
password=password,
domain=site.domain))
user.email_user(subject, message, html_message=html)
messages.success(self.request, _("The jury {name} has been successfully added!")\
.format(name=f"{user.first_name} {user.last_name}"))
return super().form_valid(form)
def form_invalid(self, form):
self.object = self.get_object()
return super().form_invalid(form)
def get_success_url(self):
return reverse_lazy('participation:pool_add_jurys', args=(self.kwargs['pk'],))
class PoolUploadNotesView(VolunteerMixin, FormView, DetailView):
model = Pool
form_class = UploadNotesForm

View File

@ -14,7 +14,7 @@
<p>
Vous avez été invités par {{ inviter.registration }} à rejoindre la plateforme du TFJM², accessible à l'adresse
<a href="https://{{ domain }}/">https://{{ domain }}/</a>. Vous disposez d'un compte d'organisateur.
<a href="https://{{ domain }}/">https://{{ domain }}/</a>. Vous disposez d'un compte de bénévole.
</p>
<p>

View File

@ -3,7 +3,7 @@
Bonjour {{ user.registration }},
Vous avez été invités par {{ inviter.registration }} à rejoindre la plateforme du TFJM², accessible à l'adresse
https://{{ domain }}/. Vous disposez d'un compte d'organisateur.
https://{{ domain }}/. Vous disposez d'un compte de bénévole.
Un mot de passe aléatoire a été défini : {{ password }}.
Par sécurité, merci de le changer dès votre connexion.

View File

@ -194,6 +194,7 @@ MEDIA_ROOT = os.path.join(BASE_DIR, "media")
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
CRISPY_ALLOWED_TEMPLATE_PACKS = 'bootstrap5'
CRISPY_TEMPLATE_PACK = 'bootstrap5'
DJANGO_TABLES2_TEMPLATE = 'django_tables2/bootstrap5.html'

View File

@ -160,7 +160,7 @@
<main class="mb-auto flex-shrink-0">
{% block fullcontent %}
<div class="{% block containertype %}container{% endblock %} my-3">
{% block contenttitle %}{% endblock %}
{% block contenttitle %}<h1>{{ title }}</h1>{% endblock %}
{% if user.is_authenticated and not user.registration.email_confirmed %}
<div class="alert alert-warning alert-dismissible" role="alert">
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
@ -171,7 +171,14 @@
{% endblocktrans %}
</div>
{% endif %}
<div id="messages"></div>
<div id="messages">
{% for message in messages %}
<div class="alert alert-{{ message.tags }} alert-dismissible fade" role="alert">
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
{{ message | safe }}
</div>
{% endfor %}
</div>
<div id="content">
{% block content %}
<p>Default content...</p>