diff --git a/draw/consumers.py b/draw/consumers.py
index d6e93e7..6e8adb7 100644
--- a/draw/consumers.py
+++ b/draw/consumers.py
@@ -115,6 +115,9 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
case 'abort':
# Abort the current draw
await self.abort(**content)
+ case 'cancel':
+ # Cancel the last step
+ await self.cancel_last_step(**content)
case 'dice':
# Launch a dice
await self.process_dice(**content)
@@ -647,7 +650,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
:param pool: The pool to end.
"""
msg = self.tournament.draw.last_message
- r = pool.round
+ r = self.tournament.draw.current_round
if pool.size == 5:
# Maybe reorder teams if the same problem is presented twice
@@ -925,6 +928,49 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_active', 'draw': self.tournament.draw})
+ @ensure_orga
+ async def cancel_last_step(self, **kwargs):
+ """
+ Cancel the last step of the draw.
+ """
+ if not await Draw.objects.filter(tournament=self.tournament).aexists():
+ return await self.alert(_("The draw has not started yet."), 'danger')
+
+ state = self.tournament.draw.get_state()
+
+ self.tournament.draw.last_message = ""
+ await self.tournament.draw.asave()
+
+ r = self.tournament.draw.current_round
+
+ if state == 'DRAW_ENDED' or state == 'WAITING_FINAL':
+ td = self.tournament.draw.current_round.current_pool.current_team
+ td.purposed = td.accepted
+ td.accepted = None
+ await td.asave()
+
+ await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
+ {'type': 'draw.continue_visibility', 'visible': False})
+
+ await self.channel_layer.group_send(f"team-{td.participation.team.trigram}",
+ {'type': 'draw.buttons_visibility', 'visible': True})
+ await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
+ {'type': 'draw.buttons_visibility', 'visible': True})
+
+ await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
+ {'type': 'draw.set_problem',
+ 'round': r.number,
+ 'team': td.participation.team.trigram,
+ 'problem': td.accepted})
+ elif state == 'WAITING_DRAW_PROBLEM':
+ pass
+
+ await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
+ {'type': 'draw.set_info', 'draw': self.tournament.draw})
+ await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
+ {'type': 'draw.set_active', 'draw': self.tournament.draw})
+
+
async def draw_alert(self, content):
"""
Send alert to the current user.
diff --git a/draw/static/draw.js b/draw/static/draw.js
index 3fe612f..200107b 100644
--- a/draw/static/draw.js
+++ b/draw/static/draw.js
@@ -20,6 +20,15 @@ function abortDraw(tid) {
sockets[tid].send(JSON.stringify({'type': 'abort'}))
}
+/**
+ * Request to cancel the last step.
+ * Only volunteers are allowed to do this.
+ * @param tid The tournament id
+ */
+function cancelLastStep(tid) {
+ sockets[tid].send(JSON.stringify({'type': 'cancel'}))
+}
+
/**
* Request to launch a dice between 1 and 100, for the two first steps.
* The parameter `trigram` can be specified (by volunteers) to launch a dice for a specific team.
@@ -583,13 +592,19 @@ document.addEventListener('DOMContentLoaded', () => {
function setProblemAccepted(round, team, problem) {
// Update recap
let recapDiv = document.getElementById(`recap-${tournament.id}-round-${round}-team-${team}-accepted`)
- recapDiv.classList.remove('text-bg-warning')
- recapDiv.classList.add('text-bg-success')
- recapDiv.textContent = `${team} đ ${problem}`
+ if (problem !== null) {
+ recapDiv.classList.remove('text-bg-warning')
+ recapDiv.classList.add('text-bg-success')
+ }
+ else {
+ recapDiv.classList.add('text-bg-warning')
+ recapDiv.classList.remove('text-bg-success')
+ }
+ recapDiv.textContent = `${team} đ ${problem ? problem : '?'}`
// Update table
let tableSpan = document.getElementById(`table-${tournament.id}-round-${round}-problem-${team}`)
- tableSpan.textContent = problem
+ tableSpan.textContent = problem ? problem : '?'
}
/**
diff --git a/draw/templates/draw/tournament_content.html b/draw/templates/draw/tournament_content.html
index 957e10f..6269920 100644
--- a/draw/templates/draw/tournament_content.html
+++ b/draw/templates/draw/tournament_content.html
@@ -177,6 +177,12 @@
{% endif %}
+
{% endif %}
diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po
index 12aff66..74f25be 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-04-05 18:37+0200\n"
+"POT-Creation-Date: 2023-04-05 18:54+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Emmy D'Anello \n"
"Language-Team: LANGUAGE \n"
@@ -46,64 +46,64 @@ msgstr "Tirage au sort"
msgid "You are not an organizer."
msgstr "Vous n'ĂȘtes pas unâ
e organisateurâ
rice."
-#: draw/consumers.py:145
+#: draw/consumers.py:148
msgid "The draw is already started."
msgstr "Le tirage a déjà commencé."
-#: draw/consumers.py:151
+#: draw/consumers.py:154
msgid "Invalid format"
msgstr "Format invalide"
-#: draw/consumers.py:156
+#: draw/consumers.py:159
#, python-brace-format
msgid "The sum must be equal to the number of teams: expected {len}, got {sum}"
msgstr ""
"La somme doit ĂȘtre Ă©gale au nombre d'Ă©quipes : attendu {len}, obtenu {sum}"
-#: draw/consumers.py:161
+#: draw/consumers.py:164
msgid "There can be at most one pool with 5 teams."
msgstr "Il ne peut y avoir au plus qu'une seule poule de 5 Ă©quipes."
-#: draw/consumers.py:189
+#: draw/consumers.py:192
msgid "Draw started!"
msgstr "Le tirage a commencé !"
-#: draw/consumers.py:209
+#: draw/consumers.py:212
#, python-brace-format
msgid "The draw for the tournament {tournament} will start."
msgstr "Le tirage au sort du tournoi {tournament} va commencer."
-#: draw/consumers.py:220 draw/consumers.py:245 draw/consumers.py:576
-#: draw/consumers.py:765 draw/consumers.py:847 draw/consumers.py:864
-#: draw/templates/draw/tournament_content.html:5
+#: draw/consumers.py:223 draw/consumers.py:248 draw/consumers.py:579
+#: draw/consumers.py:768 draw/consumers.py:850 draw/consumers.py:867
+#: draw/consumers.py:937 draw/templates/draw/tournament_content.html:5
msgid "The draw has not started yet."
msgstr "Le tirage au sort n'a pas encore commencé."
-#: draw/consumers.py:232
+#: draw/consumers.py:235
#, 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:272 draw/consumers.py:293 draw/consumers.py:522
-#: draw/consumers.py:581 draw/consumers.py:770
+#: draw/consumers.py:275 draw/consumers.py:296 draw/consumers.py:525
+#: draw/consumers.py:584 draw/consumers.py:773
msgid "This is not the time for this."
msgstr "Ce n'est pas le moment pour cela."
-#: draw/consumers.py:285 draw/consumers.py:288
+#: draw/consumers.py:288 draw/consumers.py:291
msgid "You've already launched the dice."
msgstr "Vous avez déjà lancé le dé."
-#: draw/consumers.py:291
+#: draw/consumers.py:294
msgid "It is not your turn."
msgstr "Ce n'est pas votre tour."
-#: draw/consumers.py:369
+#: draw/consumers.py:372
#, 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:867
+#: draw/consumers.py:870
msgid "This is only available for the final tournament."
msgstr "Cela n'est possible que pour la finale."
@@ -312,42 +312,46 @@ msgstr "Exporter"
msgid "Continue draw"
msgstr "Continuer le tirage"
-#: draw/templates/draw/tournament_content.html:209 participation/admin.py:100
+#: draw/templates/draw/tournament_content.html:183
+msgid "Cancel last step"
+msgstr "Annuler la derniĂšre Ă©tape"
+
+#: draw/templates/draw/tournament_content.html:215 participation/admin.py:100
#: participation/models.py:125 participation/models.py:310
#: registration/models.py:127
msgid "team"
msgstr "Ă©quipe"
-#: draw/templates/draw/tournament_content.html:219
-#: draw/templates/draw/tournament_content.html:220
-#: draw/templates/draw/tournament_content.html:221
-#: draw/templates/draw/tournament_content.html:222
-#: draw/templates/draw/tournament_content.html:223
+#: draw/templates/draw/tournament_content.html:225
+#: draw/templates/draw/tournament_content.html:226
+#: draw/templates/draw/tournament_content.html:227
+#: draw/templates/draw/tournament_content.html:228
+#: draw/templates/draw/tournament_content.html:229
msgid "Room"
msgstr "Salle"
-#: draw/templates/draw/tournament_content.html:329
-#: draw/templates/draw/tournament_content.html:347
+#: draw/templates/draw/tournament_content.html:335
+#: draw/templates/draw/tournament_content.html:353
msgid "Abort"
msgstr "Annuler"
-#: draw/templates/draw/tournament_content.html:338
+#: draw/templates/draw/tournament_content.html:344
msgid "Are you sure?"
msgstr "Ătes-vous sĂ»râ
e ?"
-#: draw/templates/draw/tournament_content.html:342
+#: draw/templates/draw/tournament_content.html:348
msgid "This will reset the draw from the beginning."
msgstr "Cela va réinitialiser le tirage au sort depuis le début."
-#: draw/templates/draw/tournament_content.html:343
+#: draw/templates/draw/tournament_content.html:349
msgid "This operation is irreversible."
msgstr "Cette opération est irréversible."
-#: draw/templates/draw/tournament_content.html:344
+#: draw/templates/draw/tournament_content.html:350
msgid "Are you sure you want to abort this draw?"
msgstr "Ătes-vous sĂ»r·e de vouloir annuler le tirage au sort ?"
-#: draw/templates/draw/tournament_content.html:348
+#: draw/templates/draw/tournament_content.html:354
#: tfjm/templates/base_modal.html:17
msgid "Close"
msgstr "Fermer"