diff --git a/draw/consumers.py b/draw/consumers.py index ef021e7..27803a3 100644 --- a/draw/consumers.py +++ b/draw/consumers.py @@ -67,19 +67,18 @@ class DrawConsumer(AsyncJsonWebsocketConsumer): match content['type']: case 'start_draw': await self.start_draw(**content) + case 'abort': + await self.abort(**content) case 'dice': await self.process_dice(**content) @ensure_orga async def start_draw(self, fmt, **kwargs): - print(fmt, kwargs) try: fmt = list(map(int, fmt.split('+'))) except ValueError as e: return await self.alert(_("Invalid format"), 'danger') - print(fmt, sum(fmt), len(self.participations)) - if sum(fmt) != len(self.participations): return await self.alert( _("The sum must be equal to the number of teams: expected {len}, got {sum}")\ @@ -117,6 +116,16 @@ class DrawConsumer(AsyncJsonWebsocketConsumer): await self.send_json({'type': 'draw_start', 'fmt': content['fmt'], 'trigrams': [p.team.trigram for p in self.participations]}) + @ensure_orga + async def abort(self, **kwargs): + await sync_to_async(self.tournament.draw.delete)() + await self.channel_layer.group_send(f"tournament-{self.tournament.id}", {'type': 'draw_abort'}) + + async def draw_abort(self, content): + await self.alert(_("The draw for the tournament {tournament} is aborted.")\ + .format(tournament=self.tournament.name), 'danger') + await self.send_json({'type': 'abort'}) + async def process_dice(self, trigram: str | None = None, **kwargs): if self.registration.is_volunteer: diff --git a/draw/static/draw.js b/draw/static/draw.js index aceb599..4580002 100644 --- a/draw/static/draw.js +++ b/draw/static/draw.js @@ -8,6 +8,10 @@ const sockets = {} const messages = document.getElementById('messages') +function abortDraw(tid) { + sockets[tid].send(JSON.stringify({'type': 'abort'})) +} + function drawDice(tid, trigram = null) { sockets[tid].send(JSON.stringify({'type': 'dice', 'trigram': trigram})) } @@ -55,9 +59,34 @@ document.addEventListener('DOMContentLoaded', () => { document.getElementById(`messages-${tournament.id}`).innerHTML = info } - function drawStart() { + function drawStart(teams) { document.getElementById(`banner-not-started-${tournament.id}`).classList.add('d-none') document.getElementById(`draw-content-${tournament.id}`).classList.remove('d-none') + + let dicesDiv = document.getElementById(`dices-${tournament.id}`) + for (let team of teams) { + let col = document.createElement('div') + col.classList.add('col-md-1') + dicesDiv.append(col) + + let diceDiv = document.createElement('div') + diceDiv.id = `dice-${tournament.id}-${team}` + diceDiv.classList.add('badge', 'rounded-pill', 'text-bg-warning') + if (document.getElementById(`abort-${tournament.id}`) !== null) { + // Check if this is a volunteer + diceDiv.onclick = (e) => drawDice(tournament.id, team) + } + diceDiv.textContent = `${team} 🎲 ??` + col.append(diceDiv) + } + } + + function drawAbort() { + document.getElementById(`banner-not-started-${tournament.id}`).classList.remove('d-none') + document.getElementById(`draw-content-${tournament.id}`).classList.add('d-none') + document.getElementById(`dices-${tournament.id}`).innerHTML = "" + document.getElementById(`recap-${tournament.id}-round-list`).innerHTML = "" + document.getElementById(`tables-${tournament.id}`).innerHTML = "" } function updateDiceInfo(trigram, result) { @@ -186,6 +215,9 @@ document.addEventListener('DOMContentLoaded', () => { } for (let poule of poules) { + if (poule.teams.length === 0) + continue + let pouleTable = document.getElementById(`table-${tournament.id}-${round}-${poule.letter}`) if (pouleTable === null) { // Create table @@ -219,7 +251,7 @@ document.addEventListener('DOMContentLoaded', () => { teamTh.textContent = "Équipe" phaseTr.append(teamTh) - for (let i = 1; i <= 3; ++i) { + for (let i = 1; i <= (poule.teams.length === 4 ? 4 : 3); ++i) { let phaseTh = document.createElement('th') phaseTh.classList.add('text-center') if (poule.teams.length === 5 && i < 3) @@ -246,7 +278,7 @@ document.addEventListener('DOMContentLoaded', () => { for (let team of poule.teams) { let problemTh = document.createElement('th') problemTh.classList.add('text-center') - problemTh.innerHTML = `Problème ?` + problemTh.innerHTML = `Pb. ?` problemTr.append(problemTh) } @@ -266,17 +298,18 @@ document.addEventListener('DOMContentLoaded', () => { let defenderTd = document.createElement('td') defenderTd.classList.add('text-center') - defenderTd.innerText = 'Défenseur⋅se' + defenderTd.innerText = 'Déf' let opponentTd = document.createElement('td') opponentTd.classList.add('text-center') - opponentTd.innerText = 'Opposant⋅e' + opponentTd.innerText = 'Opp' let reporterTd = document.createElement('td') reporterTd.classList.add('text-center') - reporterTd.innerText = 'Rapporteur⋅e' + reporterTd.innerText = 'Rap' let emptyTd = document.createElement('td') + let emptyTd2 = document.createElement('td') if (poule.teams.length === 3) { @@ -311,19 +344,19 @@ document.addEventListener('DOMContentLoaded', () => { else if (poule.teams.length === 5) { switch (i) { case 0: - teamTr.append(defenderTd, emptyTd, opponentTd, reporterTd, emptyTd) + teamTr.append(defenderTd, emptyTd, opponentTd, reporterTd, emptyTd2) break case 1: - teamTr.append(emptyTd, defenderTd, reporterTd, emptyTd, opponentTd) + teamTr.append(emptyTd, defenderTd, reporterTd, emptyTd2, opponentTd) break case 2: - teamTr.append(opponentTd, emptyTd, defenderTd, emptyTd, reporterTd) + teamTr.append(opponentTd, emptyTd, defenderTd, emptyTd2, reporterTd) break case 3: - teamTr.append(reporterTd, opponentTd, emptyTd, defenderTd, emptyTd) + teamTr.append(reporterTd, opponentTd, emptyTd, defenderTd, emptyTd2) break case 4: - teamTr.append(emptyTd, reporterTd, emptyTd, opponentTd, defenderTd) + teamTr.append(emptyTd, reporterTd, emptyTd2, opponentTd, defenderTd) break } } @@ -369,7 +402,10 @@ document.addEventListener('DOMContentLoaded', () => { setInfo(data.information) break case 'draw_start': - drawStart() + drawStart(data.trigrams) + break + case 'abort': + drawAbort() break case 'dice': updateDiceInfo(data.team, data.result) diff --git a/draw/templates/draw/tournament_content.html b/draw/templates/draw/tournament_content.html index 826dc36..22d451f 100644 --- a/draw/templates/draw/tournament_content.html +++ b/draw/templates/draw/tournament_content.html @@ -28,7 +28,7 @@

{% trans "Last dices" %}

-
+
{% for td in tournament.draw.current_round.team_draws %}
Recap + {% if user.registration.is_volunteer %} + + {% endif %}
    @@ -170,7 +175,7 @@ {% for td in pool.team_draws.all %} - {% trans "Problem"|capfirst %} + Pb. {{ td.accepted|default:"?" }} {% endfor %} @@ -182,71 +187,71 @@ {{ td.participation.team.trigram }} {% if pool.size == 3 %} {% if forloop.counter == 1 %} - {% trans "defender"|capfirst %} - {% trans "reporter"|capfirst %} - {% trans "opponent"|capfirst %} + Déf + Rap + Opp {% elif forloop.counter == 2 %} - {% trans "opponent"|capfirst %} - {% trans "defender"|capfirst %} - {% trans "reporter"|capfirst %} + Opp + Déf + Rap {% elif forloop.counter == 3 %} - {% trans "reporter"|capfirst %} - {% trans "opponent"|capfirst %} - {% trans "defender"|capfirst %} + Rap + Opp + Déf {% endif %} {% elif pool.size == 4 %} {% if forloop.counter == 1 %} - {% trans "defender"|capfirst %} + Déf - {% trans "reporter"|capfirst %} - {% trans "opponent"|capfirst %} + Rap + Opp {% elif forloop.counter == 2 %} - {% trans "opponent"|capfirst %} - {% trans "defender"|capfirst %} + Opp + Déf - {% trans "reporter"|capfirst %} + Rap {% elif forloop.counter == 3 %} - {% trans "reporter"|capfirst %} - {% trans "opponent"|capfirst %} - {% trans "defender"|capfirst %} + Rap + Opp + Déf {% elif forloop.counter == 4 %} - {% trans "reporter"|capfirst %} - {% trans "opponent"|capfirst %} - {% trans "defender"|capfirst %} + Rap + Opp + Déf {% endif %} {% elif pool.size == 5 %} {% if forloop.counter == 1 %} - {% trans "defender"|capfirst %} + Déf - {% trans "opponent"|capfirst %} - {% trans "reporter"|capfirst %} + Opp + Rap {% elif forloop.counter == 2 %} - {% trans "defender"|capfirst %} - {% trans "reporter"|capfirst %} + Déf + Rap - {% trans "opponent"|capfirst %} + Opp {% elif forloop.counter == 3 %} - {% trans "opponent"|capfirst %} + Opp - {% trans "defender"|capfirst %} + Déf - {% trans "reporter"|capfirst %} + Rap {% elif forloop.counter == 4 %} - {% trans "reporter"|capfirst %} - {% trans "opponent"|capfirst %} + Rap + Opp - {% trans "defender"|capfirst %} + Déf - {% elif forloop.counter == 4 %} + {% elif forloop.counter == 5 %} - {% trans "reporter"|capfirst %} + Rap - {% trans "opponent"|capfirst %} - {% trans "defender"|capfirst %} + Opp + Déf {% endif %} {% endif %} diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index 9682925..dbc592a 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: TFJM\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-03-24 11:14+0100\n" +"POT-Creation-Date: 2023-03-24 12:29+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Emmy D'Anello \n" "Language-Team: LANGUAGE \n" @@ -29,7 +29,7 @@ msgstr "Tirage au sort" msgid "You are not an organizer." msgstr "Vous n'êtes pas un⋅e organisateur⋅rice." -#: draw/consumers.py:79 +#: draw/consumers.py:81 msgid "Invalid format" msgstr "Format invalide" @@ -48,25 +48,30 @@ msgstr "Le tirage a commencé !" msgid "The draw for the tournament {tournament} will start." msgstr "Le tirage au sort du tournoi {tournament} va commencer." -#: draw/consumers.py:136 draw/consumers.py:139 +#: draw/consumers.py:121 +#, python-brace-format +msgid "The draw for the tournament {tournament} is aborted." +msgstr "Le tirage au sort du tournoi {tournament} est annulé." + +#: draw/consumers.py:141 draw/consumers.py:144 msgid "You've already launched the dice." msgstr "Vous avez déjà lancé le dé." -#: draw/consumers.py:142 +#: draw/consumers.py:147 msgid "It is not your turn." msgstr "Ce n'est pas votre tour." -#: draw/consumers.py:144 +#: draw/consumers.py:149 msgid "This is not the time for this." msgstr "Ce n'est pas le moment pour cela." -#: draw/consumers.py:177 draw/consumers.py:266 +#: draw/consumers.py:182 draw/consumers.py:279 #, python-brace-format msgid "Dices from teams {teams} are identical. Please relaunch your dices." msgstr "" "Les dés des équipes {teams} sont identiques. Merci de relancer vos dés." -#: draw/consumers.py:211 +#: draw/consumers.py:216 msgid "Two pools are identical. Please relaunch your dices." msgstr "Deux poules sont identiques. Merci de relancer vos dés." @@ -79,98 +84,102 @@ msgstr "tournoi" msgid "current round" msgstr "tour actuel" -#: draw/models.py:76 draw/models.py:84 +#: draw/models.py:31 +msgid "last message" +msgstr "dernier message" + +#: draw/models.py:102 draw/models.py:110 msgid "draw" msgstr "tirage au sort" -#: draw/models.py:77 +#: draw/models.py:103 msgid "draws" msgstr "tirages au sort" -#: draw/models.py:89 +#: draw/models.py:115 msgid "Round 1" msgstr "Tour 1" -#: draw/models.py:90 +#: draw/models.py:116 msgid "Round 2" msgstr "Tour 2" -#: draw/models.py:92 +#: draw/models.py:118 msgid "number" msgstr "numéro" -#: draw/models.py:101 +#: draw/models.py:127 msgid "current pool" msgstr "poule actuelle" -#: draw/models.py:112 draw/models.py:173 participation/models.py:355 +#: draw/models.py:138 draw/models.py:199 participation/models.py:355 msgid "round" msgstr "tour" -#: draw/models.py:113 +#: draw/models.py:139 msgid "rounds" msgstr "tours" -#: draw/models.py:128 +#: draw/models.py:154 msgid "letter" msgstr "lettre" -#: draw/models.py:132 +#: draw/models.py:158 #: participation/templates/participation/tournament_detail.html:15 msgid "size" msgstr "taille" -#: draw/models.py:141 +#: draw/models.py:167 msgid "current team" msgstr "équipe actuelle" -#: draw/models.py:159 draw/models.py:181 -#: draw/templates/draw/tournament_content.html:65 -#: draw/templates/draw/tournament_content.html:146 participation/models.py:407 +#: draw/models.py:185 draw/models.py:207 +#: draw/templates/draw/tournament_content.html:70 +#: draw/templates/draw/tournament_content.html:151 participation/models.py:407 #: participation/models.py:415 msgid "pool" msgstr "poule" -#: draw/models.py:160 participation/models.py:408 +#: draw/models.py:186 participation/models.py:408 msgid "pools" msgstr "poules" -#: draw/models.py:167 participation/models.py:342 participation/models.py:539 +#: draw/models.py:193 participation/models.py:342 participation/models.py:539 #: participation/models.py:569 participation/models.py:607 msgid "participation" msgstr "participation" -#: draw/models.py:188 +#: draw/models.py:214 msgid "passage index" msgstr "numéro de passage" -#: draw/models.py:195 +#: draw/models.py:221 msgid "choose index" msgstr "numéro de choix" -#: draw/models.py:200 draw/models.py:216 participation/models.py:422 +#: draw/models.py:226 draw/models.py:242 participation/models.py:422 #: participation/models.py:576 #, python-brace-format msgid "Problem #{problem}" msgstr "Problème n°{problem}" -#: draw/models.py:204 draw/models.py:220 +#: draw/models.py:230 draw/models.py:246 msgid "accepted problem" msgstr "problème accepté" -#: draw/models.py:211 +#: draw/models.py:237 msgid "last dice" msgstr "dernier dé" -#: draw/models.py:225 +#: draw/models.py:251 msgid "rejected problems" msgstr "problèmes rejetés" -#: draw/models.py:232 +#: draw/models.py:258 msgid "team draw" msgstr "tirage d'équipe" -#: draw/models.py:233 +#: draw/models.py:259 msgid "team draws" msgstr "tirages d'équipe" @@ -190,83 +199,35 @@ msgstr "Démarrer !" msgid "Last dices" msgstr "Derniers jets de dés" -#: draw/templates/draw/tournament_content.html:113 +#: draw/templates/draw/tournament_content.html:53 +msgid "Abort" +msgstr "Annuler" + +#: draw/templates/draw/tournament_content.html:118 msgid "Launch dice" msgstr "Lancer le dé" -#: draw/templates/draw/tournament_content.html:120 +#: draw/templates/draw/tournament_content.html:125 msgid "Accept" msgstr "Accepter" -#: draw/templates/draw/tournament_content.html:123 +#: draw/templates/draw/tournament_content.html:128 msgid "Decline" msgstr "Refuser" -#: draw/templates/draw/tournament_content.html:153 participation/models.py:125 +#: draw/templates/draw/tournament_content.html:158 participation/models.py:125 #: participation/models.py:310 registration/models.py:127 msgid "team" msgstr "équipe" -#: draw/templates/draw/tournament_content.html:163 -#: draw/templates/draw/tournament_content.html:164 -#: draw/templates/draw/tournament_content.html:165 -#: draw/templates/draw/tournament_content.html:166 -#: draw/templates/draw/tournament_content.html:167 +#: draw/templates/draw/tournament_content.html:168 +#: draw/templates/draw/tournament_content.html:169 +#: draw/templates/draw/tournament_content.html:170 +#: draw/templates/draw/tournament_content.html:171 +#: draw/templates/draw/tournament_content.html:172 msgid "Room" msgstr "Salle" -#: draw/templates/draw/tournament_content.html:173 -msgid "Problem" -msgstr "Problème" - -#: draw/templates/draw/tournament_content.html:185 -#: draw/templates/draw/tournament_content.html:190 -#: draw/templates/draw/tournament_content.html:195 -#: draw/templates/draw/tournament_content.html:199 -#: draw/templates/draw/tournament_content.html:205 -#: draw/templates/draw/tournament_content.html:211 -#: draw/templates/draw/tournament_content.html:217 -#: draw/templates/draw/tournament_content.html:221 -#: draw/templates/draw/tournament_content.html:228 -#: draw/templates/draw/tournament_content.html:235 -#: draw/templates/draw/tournament_content.html:242 -#: draw/templates/draw/tournament_content.html:249 participation/models.py:429 -#: participation/tables.py:102 -msgid "defender" -msgstr "défenseur⋅se" - -#: draw/templates/draw/tournament_content.html:186 -#: draw/templates/draw/tournament_content.html:191 -#: draw/templates/draw/tournament_content.html:193 -#: draw/templates/draw/tournament_content.html:201 -#: draw/templates/draw/tournament_content.html:207 -#: draw/templates/draw/tournament_content.html:209 -#: draw/templates/draw/tournament_content.html:215 -#: draw/templates/draw/tournament_content.html:224 -#: draw/templates/draw/tournament_content.html:229 -#: draw/templates/draw/tournament_content.html:237 -#: draw/templates/draw/tournament_content.html:239 -#: draw/templates/draw/tournament_content.html:246 participation/models.py:443 -#: participation/models.py:620 -msgid "reporter" -msgstr "rapporteur⋅e" - -#: draw/templates/draw/tournament_content.html:187 -#: draw/templates/draw/tournament_content.html:189 -#: draw/templates/draw/tournament_content.html:194 -#: draw/templates/draw/tournament_content.html:202 -#: draw/templates/draw/tournament_content.html:204 -#: draw/templates/draw/tournament_content.html:210 -#: draw/templates/draw/tournament_content.html:216 -#: draw/templates/draw/tournament_content.html:223 -#: draw/templates/draw/tournament_content.html:231 -#: draw/templates/draw/tournament_content.html:233 -#: draw/templates/draw/tournament_content.html:240 -#: draw/templates/draw/tournament_content.html:248 participation/models.py:436 -#: participation/models.py:619 -msgid "opponent" -msgstr "opposant⋅e" - #: logs/apps.py:11 msgid "Logs" msgstr "Logs" @@ -577,6 +538,18 @@ msgstr "Poule du jour {round} du tournoi {tournament} avec les équipes {teams}" msgid "defended solution" msgstr "solution défendue" +#: participation/models.py:429 participation/tables.py:102 +msgid "defender" +msgstr "défenseur⋅se" + +#: participation/models.py:436 participation/models.py:619 +msgid "opponent" +msgstr "opposant⋅e" + +#: participation/models.py:443 participation/models.py:620 +msgid "reporter" +msgstr "rapporteur⋅e" + #: participation/models.py:448 msgid "penalties" msgstr "pénalités" @@ -2234,5 +2207,8 @@ msgstr "Résultats" msgid "No results found." msgstr "Aucun résultat." +#~ msgid "Problem" +#~ msgstr "Problème" + #~ msgid "index" #~ msgstr "position"