mirror of
				https://gitlab.com/animath/si/plateforme.git
				synced 2025-11-04 13:52:17 +01:00 
			
		
		
		
	The draw is now fully reversible
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
		@@ -1,7 +1,8 @@
 | 
				
			|||||||
# Copyright (C) 2023 by Animath
 | 
					# Copyright (C) 2023 by Animath
 | 
				
			||||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
					# SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
import json
 | 
					
 | 
				
			||||||
from collections import OrderedDict
 | 
					from collections import OrderedDict
 | 
				
			||||||
 | 
					import json
 | 
				
			||||||
from random import randint, shuffle
 | 
					from random import randint, shuffle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from channels.generic.websocket import AsyncJsonWebsocketConsumer
 | 
					from channels.generic.websocket import AsyncJsonWebsocketConsumer
 | 
				
			||||||
@@ -350,11 +351,14 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
 | 
				
			|||||||
            if values.count(v) > 1:
 | 
					            if values.count(v) > 1:
 | 
				
			||||||
                # v is a duplicate value
 | 
					                # v is a duplicate value
 | 
				
			||||||
                # Get all teams that have the same result
 | 
					                # Get all teams that have the same result
 | 
				
			||||||
                dups = [td for td in tds if td.passage_dice == v]
 | 
					                dups = [td for td in tds if (td.passage_dice if state == 'DICE_SELECT_POULES' else td.choice_dice) == v]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                for dup in dups:
 | 
					                for dup in dups:
 | 
				
			||||||
                    # Reset the dice
 | 
					                    # Reset the dice
 | 
				
			||||||
                    dup.passage_dice = None
 | 
					                    if state == 'DICE_SELECT_POULES':
 | 
				
			||||||
 | 
					                        dup.passage_dice = None
 | 
				
			||||||
 | 
					                    else:
 | 
				
			||||||
 | 
					                        dup.choice_dice = None
 | 
				
			||||||
                    await dup.asave()
 | 
					                    await dup.asave()
 | 
				
			||||||
                    await self.channel_layer.group_send(
 | 
					                    await self.channel_layer.group_send(
 | 
				
			||||||
                        f"tournament-{self.tournament.id}",
 | 
					                        f"tournament-{self.tournament.id}",
 | 
				
			||||||
@@ -938,6 +942,9 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
 | 
				
			|||||||
        if not await Draw.objects.filter(tournament=self.tournament).aexists():
 | 
					        if not await Draw.objects.filter(tournament=self.tournament).aexists():
 | 
				
			||||||
            return await self.alert(_("The draw has not started yet."), 'danger')
 | 
					            return await self.alert(_("The draw has not started yet."), 'danger')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        content_type = await ContentType.objects.aget(app_label=TeamDraw._meta.app_label,
 | 
				
			||||||
 | 
					                                                      model=TeamDraw._meta.model_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        state = self.tournament.draw.get_state()
 | 
					        state = self.tournament.draw.get_state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.tournament.draw.last_message = ""
 | 
					        self.tournament.draw.last_message = ""
 | 
				
			||||||
@@ -952,7 +959,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
 | 
				
			|||||||
            await td.asave()
 | 
					            await td.asave()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
 | 
					            await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
 | 
				
			||||||
                                               {'type': 'draw.continue_visibility', 'visible': False})
 | 
					                                                {'type': 'draw.continue_visibility', 'visible': False})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await self.channel_layer.group_send(f"team-{td.participation.team.trigram}",
 | 
					            await self.channel_layer.group_send(f"team-{td.participation.team.trigram}",
 | 
				
			||||||
                                                {'type': 'draw.buttons_visibility', 'visible': True})
 | 
					                                                {'type': 'draw.buttons_visibility', 'visible': True})
 | 
				
			||||||
@@ -989,8 +996,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
 | 
				
			|||||||
            if accepted_tds or has_rejected_one_tds:
 | 
					            if accepted_tds or has_rejected_one_tds:
 | 
				
			||||||
                # One team of the already accepted or its problem, we fetch the last one
 | 
					                # One team of the already accepted or its problem, we fetch the last one
 | 
				
			||||||
                changelogs = Changelog.objects.filter(
 | 
					                changelogs = Changelog.objects.filter(
 | 
				
			||||||
                    model=await ContentType.objects.aget(app_label=TeamDraw._meta.app_label,
 | 
					                    model=content_type,
 | 
				
			||||||
                                                         model=TeamDraw._meta.model_name),
 | 
					 | 
				
			||||||
                    action='edit',
 | 
					                    action='edit',
 | 
				
			||||||
                    instance_pk__in=set(accepted_tds.keys()).union(set(has_rejected_one_tds.keys()))
 | 
					                    instance_pk__in=set(accepted_tds.keys()).union(set(has_rejected_one_tds.keys()))
 | 
				
			||||||
                ).order_by('-timestamp')
 | 
					                ).order_by('-timestamp')
 | 
				
			||||||
@@ -999,7 +1005,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
 | 
				
			|||||||
                    previous = json.loads(changelog.previous)
 | 
					                    previous = json.loads(changelog.previous)
 | 
				
			||||||
                    data = json.loads(changelog.data)
 | 
					                    data = json.loads(changelog.data)
 | 
				
			||||||
                    pk = int(changelog.instance_pk)
 | 
					                    pk = int(changelog.instance_pk)
 | 
				
			||||||
                    print(previous, data, pk)
 | 
					
 | 
				
			||||||
                    if 'accepted' in data and data['accepted'] and pk in accepted_tds:
 | 
					                    if 'accepted' in data and data['accepted'] and pk in accepted_tds:
 | 
				
			||||||
                        # Undo the last acceptance
 | 
					                        # Undo the last acceptance
 | 
				
			||||||
                        last_td = accepted_tds[pk]
 | 
					                        last_td = accepted_tds[pk]
 | 
				
			||||||
@@ -1043,7 +1049,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
 | 
				
			|||||||
                # Return to the dice choice
 | 
					                # Return to the dice choice
 | 
				
			||||||
                pool_tds = {td.id: td async for td in p.team_draws.prefetch_related('participation__team')}
 | 
					                pool_tds = {td.id: td async for td in p.team_draws.prefetch_related('participation__team')}
 | 
				
			||||||
                changelogs = Changelog.objects.filter(
 | 
					                changelogs = Changelog.objects.filter(
 | 
				
			||||||
                    model=ContentType.objects.get_for_model(TeamDraw),
 | 
					                    model=content_type,
 | 
				
			||||||
                    action='edit',
 | 
					                    action='edit',
 | 
				
			||||||
                    instance_pk__in=set(pool_tds.keys())
 | 
					                    instance_pk__in=set(pool_tds.keys())
 | 
				
			||||||
                ).order_by('-timestamp')
 | 
					                ).order_by('-timestamp')
 | 
				
			||||||
@@ -1076,13 +1082,202 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
					            await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
				
			||||||
                                                {'type': 'draw.box_visibility', 'visible': False})
 | 
					                                                {'type': 'draw.box_visibility', 'visible': False})
 | 
				
			||||||
 | 
					        elif state == 'DICE_ORDER_POULE':
 | 
				
			||||||
 | 
					            p = r.current_pool
 | 
				
			||||||
 | 
					            already_launched_tds = {td.id: td async for td in p.team_draws.filter(choice_dice__isnull=False)
 | 
				
			||||||
 | 
					                                    .prefetch_related('participation__team')}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if already_launched_tds:
 | 
				
			||||||
 | 
					                # Reset the last dice
 | 
				
			||||||
 | 
					                changelogs = Changelog.objects.filter(
 | 
				
			||||||
 | 
					                    model=content_type,
 | 
				
			||||||
 | 
					                    action='edit',
 | 
				
			||||||
 | 
					                    instance_pk__in=set(already_launched_tds.keys())
 | 
				
			||||||
 | 
					                ).order_by('-timestamp')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                # Find the last dice that was launched
 | 
				
			||||||
 | 
					                async for changelog in changelogs:
 | 
				
			||||||
 | 
					                    data = json.loads(changelog.data)
 | 
				
			||||||
 | 
					                    if 'choice_dice' in data and data['choice_dice']:
 | 
				
			||||||
 | 
					                        last_td = already_launched_tds[int(changelog.instance_pk)]
 | 
				
			||||||
 | 
					                        # Reset the dice
 | 
				
			||||||
 | 
					                        last_td.choice_dice = None
 | 
				
			||||||
 | 
					                        await last_td.asave()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        # Reset the dice on the interface
 | 
				
			||||||
 | 
					                        await self.channel_layer.group_send(
 | 
				
			||||||
 | 
					                            f"tournament-{self.tournament.id}", {'type': 'draw.dice',
 | 
				
			||||||
 | 
					                                                                 'team': last_td.participation.team.trigram,
 | 
				
			||||||
 | 
					                                                                 'result': None})
 | 
				
			||||||
 | 
					                        break
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                # Go to the previous pool if possible
 | 
				
			||||||
 | 
					                if p.letter > 1:
 | 
				
			||||||
 | 
					                    # Go to the previous pool
 | 
				
			||||||
 | 
					                    previous_pool = await r.pool_set.prefetch_related('current_team__participation__team')\
 | 
				
			||||||
 | 
					                        .aget(letter=p.letter - 1)
 | 
				
			||||||
 | 
					                    r.current_pool = previous_pool
 | 
				
			||||||
 | 
					                    await r.asave()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    td = previous_pool.current_team
 | 
				
			||||||
 | 
					                    td.purposed = td.accepted
 | 
				
			||||||
 | 
					                    td.accepted = None
 | 
				
			||||||
 | 
					                    await td.asave()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
				
			||||||
 | 
					                                                        {'type': 'draw.dice_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 r.number == 2:
 | 
				
			||||||
 | 
					                    if not self.tournament.final:
 | 
				
			||||||
 | 
					                        # Go to the previous round
 | 
				
			||||||
 | 
					                        r1 = await self.tournament.draw.round_set\
 | 
				
			||||||
 | 
					                            .prefetch_related('current_pool__current_team__participation__team').aget(number=1)
 | 
				
			||||||
 | 
					                        self.tournament.draw.current_round = r1
 | 
				
			||||||
 | 
					                        await self.tournament.draw.asave()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        async for td in r1.team_draws.prefetch_related('participation__team').all():
 | 
				
			||||||
 | 
					                            await self.channel_layer.group_send(
 | 
				
			||||||
 | 
					                                f"tournament-{self.tournament.id}", {'type': 'draw.dice',
 | 
				
			||||||
 | 
					                                                                     'team': td.participation.team.trigram,
 | 
				
			||||||
 | 
					                                                                     'result': td.choice_dice})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
				
			||||||
 | 
					                                                            {'type': 'draw.send_poules', 'round': r1})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        previous_pool = r1.current_pool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        td = previous_pool.current_team
 | 
				
			||||||
 | 
					                        td.purposed = td.accepted
 | 
				
			||||||
 | 
					                        td.accepted = None
 | 
				
			||||||
 | 
					                        await td.asave()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
				
			||||||
 | 
					                                                            {'type': 'draw.dice_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': r1.number,
 | 
				
			||||||
 | 
					                                                             'team': td.participation.team.trigram,
 | 
				
			||||||
 | 
					                                                             'problem': td.accepted})
 | 
				
			||||||
 | 
					                    else:
 | 
				
			||||||
 | 
					                        # Don't continue the final tournament
 | 
				
			||||||
 | 
					                        r1 = await self.tournament.draw.round_set \
 | 
				
			||||||
 | 
					                            .prefetch_related('current_pool__current__team__participation__team').aget(number=1)
 | 
				
			||||||
 | 
					                        self.tournament.draw.current_round = r1
 | 
				
			||||||
 | 
					                        await self.tournament.draw.asave()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        async for td in r.teamdraw_set.all():
 | 
				
			||||||
 | 
					                            td.pool = None
 | 
				
			||||||
 | 
					                            td.choose_index = None
 | 
				
			||||||
 | 
					                            td.choice_dice = None
 | 
				
			||||||
 | 
					                            await td.asave()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        async for td in r1.team_draws.prefetch_related('participation__team').all():
 | 
				
			||||||
 | 
					                            await self.channel_layer.group_send(
 | 
				
			||||||
 | 
					                                f"tournament-{self.tournament.id}", {'type': 'draw.dice',
 | 
				
			||||||
 | 
					                                                                     'team': td.participation.team.trigram,
 | 
				
			||||||
 | 
					                                                                     'result': td.choice_dice})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
				
			||||||
 | 
					                                                            {'type': 'draw.dice_visibility', 'visible': False})
 | 
				
			||||||
 | 
					                        await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
 | 
				
			||||||
 | 
					                                                            {'type': 'draw.continue_visibility', 'visible': True})
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    # Go to the dice order
 | 
				
			||||||
 | 
					                    async for r0 in self.tournament.draw.round_set.all():
 | 
				
			||||||
 | 
					                        async for td in r0.teamdraw_set.all():
 | 
				
			||||||
 | 
					                            td.pool = None
 | 
				
			||||||
 | 
					                            td.passage_index = None
 | 
				
			||||||
 | 
					                            td.choose_index = None
 | 
				
			||||||
 | 
					                            td.choice_dice = None
 | 
				
			||||||
 | 
					                            await td.asave()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    r.current_pool = None
 | 
				
			||||||
 | 
					                    await r.asave()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    round_tds = {td.id: td async for td in r.team_draws.prefetch_related('participation__team')}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    # Reset the last dice
 | 
				
			||||||
 | 
					                    changelogs = Changelog.objects.filter(
 | 
				
			||||||
 | 
					                        model=content_type,
 | 
				
			||||||
 | 
					                        action='edit',
 | 
				
			||||||
 | 
					                        instance_pk__in=set(round_tds.keys())
 | 
				
			||||||
 | 
					                    ).order_by('-timestamp')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    # Find the last dice that was launched
 | 
				
			||||||
 | 
					                    async for changelog in changelogs:
 | 
				
			||||||
 | 
					                        data = json.loads(changelog.data)
 | 
				
			||||||
 | 
					                        if 'passage_dice' in data and data['passage_dice']:
 | 
				
			||||||
 | 
					                            last_td = round_tds[int(changelog.instance_pk)]
 | 
				
			||||||
 | 
					                            # Reset the dice
 | 
				
			||||||
 | 
					                            last_td.passage_dice = None
 | 
				
			||||||
 | 
					                            await last_td.asave()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            # Reset the dice on the interface
 | 
				
			||||||
 | 
					                            await self.channel_layer.group_send(
 | 
				
			||||||
 | 
					                                f"tournament-{self.tournament.id}", {'type': 'draw.dice',
 | 
				
			||||||
 | 
					                                                                     'team': last_td.participation.team.trigram,
 | 
				
			||||||
 | 
					                                                                     'result': None})
 | 
				
			||||||
 | 
					                            break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    async for td in r.team_draws.prefetch_related('participation__team').all():
 | 
				
			||||||
 | 
					                        await self.channel_layer.group_send(
 | 
				
			||||||
 | 
					                            f"tournament-{self.tournament.id}", {'type': 'draw.dice',
 | 
				
			||||||
 | 
					                                                                 'team': td.participation.team.trigram,
 | 
				
			||||||
 | 
					                                                                 'result': td.passage_dice})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
				
			||||||
 | 
					                                                        {'type': 'draw.dice_visibility', 'visible': True})
 | 
				
			||||||
 | 
					        elif state == 'DICE_SELECT_POULES':
 | 
				
			||||||
 | 
					            already_launched_tds = {td.id: td async for td in r.team_draws.filter(passage_dice__isnull=False)
 | 
				
			||||||
 | 
					                                    .prefetch_related('participation__team')}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if already_launched_tds:
 | 
				
			||||||
 | 
					                # Reset the last dice
 | 
				
			||||||
 | 
					                changelogs = Changelog.objects.filter(
 | 
				
			||||||
 | 
					                    model=content_type,
 | 
				
			||||||
 | 
					                    action='edit',
 | 
				
			||||||
 | 
					                    instance_pk__in=set(already_launched_tds.keys())
 | 
				
			||||||
 | 
					                ).order_by('-timestamp')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                # Find the last dice that was launched
 | 
				
			||||||
 | 
					                async for changelog in changelogs:
 | 
				
			||||||
 | 
					                    data = json.loads(changelog.data)
 | 
				
			||||||
 | 
					                    if 'passage_dice' in data and data['passage_dice']:
 | 
				
			||||||
 | 
					                        last_td = already_launched_tds[int(changelog.instance_pk)]
 | 
				
			||||||
 | 
					                        # Reset the dice
 | 
				
			||||||
 | 
					                        last_td.passage_dice = None
 | 
				
			||||||
 | 
					                        await last_td.asave()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        # Reset the dice on the interface
 | 
				
			||||||
 | 
					                        await self.channel_layer.group_send(
 | 
				
			||||||
 | 
					                            f"tournament-{self.tournament.id}", {'type': 'draw.dice',
 | 
				
			||||||
 | 
					                                                                 'team': last_td.participation.team.trigram,
 | 
				
			||||||
 | 
					                                                                 'result': None})
 | 
				
			||||||
 | 
					                        break
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                await self.abort()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
					        await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
				
			||||||
                                            {'type': 'draw.set_info', 'draw': self.tournament.draw})
 | 
					                                            {'type': 'draw.set_info', 'draw': self.tournament.draw})
 | 
				
			||||||
        await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
					        await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
				
			||||||
                                            {'type': 'draw.set_active', 'draw': self.tournament.draw})
 | 
					                                            {'type': 'draw.set_active', 'draw': self.tournament.draw})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    async def draw_alert(self, content):
 | 
					    async def draw_alert(self, content):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Send alert to the current user.
 | 
					        Send alert to the current user.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,6 +54,13 @@
 | 
				
			|||||||
                <div class="card">
 | 
					                <div class="card">
 | 
				
			||||||
                    <div class="card-header">
 | 
					                    <div class="card-header">
 | 
				
			||||||
                        Recap
 | 
					                        Recap
 | 
				
			||||||
 | 
					                        {% if user.registration.is_volunteer %}
 | 
				
			||||||
 | 
					                            <button id="cancel-last-step-{{ tournament.id }}"
 | 
				
			||||||
 | 
					                                    class="badge rounded-pill text-bg-warning"
 | 
				
			||||||
 | 
					                                    onclick="cancelLastStep({{ tournament.id }})">
 | 
				
			||||||
 | 
					                                🔙 {% trans "Cancel last step" %}
 | 
				
			||||||
 | 
					                            </button>
 | 
				
			||||||
 | 
					                        {% endif %}
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                    <div class="card-body">
 | 
					                    <div class="card-body">
 | 
				
			||||||
                        <div id="recap-{{ tournament.id }}-round-list" class="row">
 | 
					                        <div id="recap-{{ tournament.id }}-round-list" class="row">
 | 
				
			||||||
@@ -177,12 +184,6 @@
 | 
				
			|||||||
                                </button>
 | 
					                                </button>
 | 
				
			||||||
                            </div>
 | 
					                            </div>
 | 
				
			||||||
                        {% endif %}
 | 
					                        {% endif %}
 | 
				
			||||||
                        <div id="cancel-last-step-{{ tournament.id }}"
 | 
					 | 
				
			||||||
                             class="card-footer text-center">
 | 
					 | 
				
			||||||
                            <button class="badge rounded-pill text-bg-warning" onclick="cancelLastStep({{ tournament.id }})">
 | 
					 | 
				
			||||||
                                🔙 {% trans "Cancel last step" %}
 | 
					 | 
				
			||||||
                            </button>
 | 
					 | 
				
			||||||
                        </div>
 | 
					 | 
				
			||||||
                    {% endif %}
 | 
					                    {% endif %}
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
@@ -326,16 +327,16 @@
 | 
				
			|||||||
            {% endfor %}
 | 
					            {% endfor %}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% if user.registration.is_volunteer %}
 | 
					    {% if user.registration.is_volunteer %}
 | 
				
			||||||
    {# Volunteers can click on this button to abort the draw #}
 | 
					        {# Volunteers can click on this button to abort the draw #}
 | 
				
			||||||
    <div class="text-center mt-3">
 | 
					        <div class="text-center mt-3">
 | 
				
			||||||
        <button id="abort-{{ tournament.id }}" class="badge rounded-pill text-bg-danger" data-bs-toggle="modal" data-bs-target="#abort{{ tournament.id }}Modal">
 | 
					            <button id="abort-{{ tournament.id }}" class="badge rounded-pill text-bg-danger" data-bs-toggle="modal" data-bs-target="#abort{{ tournament.id }}Modal">
 | 
				
			||||||
            {% trans "Abort" %}
 | 
					                {% trans "Abort" %}
 | 
				
			||||||
        </button>
 | 
					            </button>
 | 
				
			||||||
    </div>
 | 
					        </div>
 | 
				
			||||||
{% endif %}
 | 
					    {% endif %}
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div id="abort{{ tournament.id }}Modal" class="modal fade" tabindex="-1" role="dialog">
 | 
					<div id="abort{{ tournament.id }}Modal" class="modal fade" tabindex="-1" role="dialog">
 | 
				
			||||||
    <div class="modal-dialog" role="document">
 | 
					    <div class="modal-dialog" role="document">
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user