Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions bullet/bullet_admin/templates/bullet_admin/teams/contact.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{% load access %}
{% is_any_admin as admin %}
<div>{{ object.contact_name }}</div>
{% if admin %}
<div class="text-sm">
<a href="mailto:{{ object.contact_email }}" class="hover:text-primary-dark text-primary underline relative z-10z">
{{ object.contact_email }}
</a>
</div>
{% if object.contact_phone %}
<div class="text-sm">
<a href="tel:{{ object.contact_phone }}" class="hover:text-primary-dark text-primary underline relative z-10">
{{ object.contact_phone_pretty }}
</a>
</div>
{% endif %}
{% endif %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<ul class="text-xs">
{% for contestant in object.contestants.all %}
<li>{{ contestant.full_name }}</li>
{% endfor %}
</ul>
8 changes: 8 additions & 0 deletions bullet/bullet_admin/templates/bullet_admin/teams/number.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<span class="font-mono tracking-wider">
{% if object.number %}
<span class="text-gray-500">{{ object.venue.shortcode }}</span>{{ object.number|stringformat:"03d" }}
{% else %}
<span class="text-gray-500">---</span>
{% endif %}
<div class="text-gray-500 text-xs">{{ object.id_display }}</div>
</span>
7 changes: 7 additions & 0 deletions bullet/bullet_admin/templates/bullet_admin/teams/school.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<div class="font-bold">
{{ object.school.name }}
{% if object.in_school_symbol %}
<span class="text-primary">{{ object.in_school_symbol }}</span>
{% endif %}
</div>
<div class="text-sm">{{ object.school.address }}</div>
23 changes: 23 additions & 0 deletions bullet/bullet_admin/templates/bullet_admin/teams/status.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<div class="whitespace-nowrap text-xs tracking-wide font-bold text-white flex gap-1">
{% if object.status == object.status.UNCONFIRMED %}
<span class="bg-gray-500 px-2 py-1 rounded">Unconfirmed</span>
{% elif object.status == object.status.WAITINGLIST %}
<span class="bg-amber-600 px-2 py-1 rounded">Waiting list</span>
{% elif object.status == object.status.CHECKEDIN %}
<span class="bg-purple-600 px-2 py-1 rounded">Checked in</span>
{% elif object.status == object.status.REVIEWED %}
<span class="bg-blue-600 px-2 py-1 rounded">Reviewed</span>
{% elif object.status == object.status.REGISTERED %}
<span class="bg-green-600 px-2 py-1 rounded">Registered</span>
{% elif object.status == object.status.DISQUALIFIED %}
<span class="bg-red-600 px-2 py-1 rounded">Disqualified</span>
{% endif %}

{% if not object.venue.is_online %}
<span class="iconify p-1 w-7 h-6 {% if object.consent_photos %}bg-green-500{% else %}bg-red-600{% endif %} rounded" data-icon="mdi:camera"></span>
{% endif %}

{% if object.venue.registration_flow.get_admin_row_template %}
{% include object.venue.registration_flow.get_admin_row_template %}
{% endif %}
</div>
41 changes: 34 additions & 7 deletions bullet/bullet_admin/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,12 @@ def get_context_data(self, *, object_list=None, **kwargs):
ctx["table_row"] = map(self.create_row, ctx["object_list"])
ctx["list_title"] = self.get_list_title()
ctx["object_name"] = self.get_object_name()
ctx["help_url"] = self.help_url
ctx["create_url"] = self.create_url
ctx["upload_url"] = self.upload_url
ctx["export_url"] = self.export_url
ctx["new_folder_url"] = self.new_folder_url
ctx["assign_numbers_url"] = self.assign_numbers_url
ctx["help_url"] = self.get_help_url()
ctx["create_url"] = self.get_create_url()
ctx["upload_url"] = self.get_upload_url()
ctx["export_url"] = self.get_export_url()
ctx["new_folder_url"] = self.get_new_folder_url()
ctx["assign_numbers_url"] = self.get_assign_numbers_url()
ctx["subtitle"] = self.subtitle
ctx["labels"] = self.get_labels()
ctx["view_type"] = self.view_type
Expand Down Expand Up @@ -226,7 +226,10 @@ def create_row(self, object):
getattr(object, field)
if field not in self.field_templates
else mark_safe(
render_to_string(self.field_templates[field], {"object": object})
render_to_string(
self.field_templates[field],
{"object": object, "request": self.request},
)
)
for field in self.get_fields()
],
Expand All @@ -244,6 +247,30 @@ def get_delete_url(self, obj) -> str | None:
def get_view_url(self, obj) -> str | None:
return None

def get_download_url(self, obj) -> str | None:
return None

def get_generate_url(self, obj) -> str | None:
return None

def get_help_url(self) -> str | None:
return self.help_url if self.help_url else None

def get_create_url(self) -> str | None:
return self.create_url if self.create_url else None

def get_upload_url(self) -> str | None:
return self.upload_url if self.upload_url else None

def get_export_url(self) -> str | None:
return self.export_url if self.export_url else None

def get_new_folder_url(self) -> str | None:
return self.new_folder_url if self.new_folder_url else None

def get_assign_numbers_url(self) -> str | None:
return self.assign_numbers_url if self.assign_numbers_url else None


class CompetitionSwitchView(LoginRequiredMixin, TemplateView):
template_name = "bullet_admin/competition_switch.html"
Expand Down
103 changes: 92 additions & 11 deletions bullet/bullet_admin/views/teams.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,49 @@
RedirectBackMixin,
VenueMixin,
)
from bullet_admin.utils import can_access_venue, get_active_competition
from bullet_admin.views import GenericForm
from bullet_admin.utils import (
can_access_venue,
get_active_competition,
get_allowed_countries,
)
from bullet_admin.views import GenericForm, GenericList


class TeamListView(OperatorRequiredMixin, IsOperatorContext, GenericList, ListView):
labels = {
"contact_name": "Contact Informations",
"venue": "Venue / Category",
"consent_photos": "Status",
}

field_templates = {
"number": "bullet_admin/teams/number.html",
"school": "bullet_admin/teams/school.html",
"contact_name": "bullet_admin/teams/contact.html",
"contestants": "bullet_admin/teams/contestants.html",
"consent_photos": "bullet_admin/teams/status.html",
}

def get_assign_numbers_url(self) -> str | None:
if self.request.user.get_competition_role(
get_active_competition(self.request)
).is_operator:
return None
return reverse("badmin:team_assign_numbers")

def get_export_url(self) -> str | None:
if self.request.user.get_competition_role(
get_active_competition(self.request)
).is_operator:
return None
return reverse("badmin:team_export")

class TeamListView(OperatorRequiredMixin, IsOperatorContext, ListView):
template_name = "bullet_admin/teams/list.html"
paginate_by = 100
def get_create_url(self) -> str | None:
if self.request.user.get_competition_role(
get_active_competition(self.request)
).is_operator:
return None
return reverse("badmin:team_create")

def get_form(self):
return TeamFilterForm(
Expand Down Expand Up @@ -95,17 +131,60 @@ def get_queryset(self):

return qs

def get_context_data(self, *args, **kwargs):
ctx = super().get_context_data(*args, **kwargs)
def get_edit_url(self, team: Team) -> str | None:
if self.request.user.get_competition_role(
get_active_competition(self.request)
).is_operator:
return None
return reverse("badmin:team_edit", kwargs={"pk": team.id})

def get_fields(self):
brole = self.request.user.get_branch_role(self.request.BRANCH)
crole = self.request.user.get_competition_role(
get_active_competition(self.request)
)
ctx["hide_venue"] = (
not brole.is_admin and not crole.countries and len(crole.venues) < 2
if not brole.is_admin and not crole.countries and len(crole.venues) < 2:
return [
"number",
"school",
"contact_name",
"contestants",
"consent_photos",
]
return [
"number",
"school",
"contact_name",
"contestants",
"venue",
"consent_photos",
]

def get_country_queryset(self, qs):
country = self.request.GET.get("country")
if country:
qs = qs.filter(venue__country=country)

allowed_countries = get_allowed_countries(self.request)
if allowed_countries is not None:
qs = qs.filter(venue__country__in=allowed_countries)
return qs

def country_navigation(self):
allowed_countries = get_allowed_countries(self.request)
countries = (
self.get_queryset()
.values_list("venue__country", flat=True)
.order_by("venue__country")
.distinct()
)
ctx["search_form"] = self.get_form()
return ctx

if allowed_countries is not None:
countries = countries.filter(country__in=allowed_countries)

if countries.count() <= 1:
return None
return countries


class TeamExportView(AdminRequiredMixin, FormView):
Expand Down Expand Up @@ -537,6 +616,8 @@ class RecentlyDeletedTeamsView(AdminAccess, ListView):
template_name = "bullet_admin/teams/deleted.html"
paginate_by = 20

require_unlocked_competition = False

def get_queryset(self, *args, **kwargs):
qs = Team.history.filter(
history_type="-", history_date__gte=datetime.now() - timedelta(days=100)
Expand Down