Coach lineup polish, referee level/position delete, feature-flag nav gating, per-job pause

- Coach line-up screen: more breathing room above the sheet, brighter event
  subtitle, and the "Schedule" button now matches the date input's height.
- Positions and referee levels can now be deleted from Settings (blocked with
  a friendly message if still in use on a roster/referee profile/inheritance
  chain).
- The Evaluations nav placeholder is now gated on the formbuilder flag, same
  as Forms itself, since the design reuses formbuilder underneath.
- Control panel: each scheduled platform job can now be paused/resumed
  individually (features.models.JobToggle), independent of the platform-wide
  Maintenance lock.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-23 11:17:46 +02:00
parent e621086f37
commit 1365dcf18e
23 changed files with 422 additions and 3029 deletions

View File

@@ -1861,6 +1861,23 @@ class PositionUpdateView(ClubAdminRequiredMixin, UpdateView):
return super().get_context_data(update_view=True, **kwargs)
class PositionDeleteView(ClubAdminRequiredMixin, View):
def post(self, request, pk):
position = get_object_or_404(Position.objects.filter(club=request.club), pk=pk)
name = str(position)
try:
position.delete()
except ProtectedError:
title = _("Can't delete")
body = _("%(position)s” is still assigned on a team roster, and can't be deleted.") % {"position": name}
notify(request, f"e|{title}|{body}")
return redirect("management:position_list")
body = _("%(position)s” has been deleted.") % {"position": name}
notify(request, f"w|{_('Position deleted')}|{body}")
return redirect("management:position_list")
class RefereeLevelListView(ClubStaffRequiredMixin, ListView):
"""Visible to any staff, same reasoning as PositionListView; creating/
editing a level is admin-only."""
@@ -1915,6 +1932,23 @@ class RefereeLevelUpdateView(MemberAdminRequiredMixin, UpdateView):
return super().get_context_data(update_view=True, **kwargs)
class RefereeLevelDeleteView(MemberAdminRequiredMixin, View):
def post(self, request, pk):
level = get_object_or_404(RefereeLevel.objects.filter(club=request.club), pk=pk)
name = str(level)
try:
level.delete()
except ProtectedError:
title = _("Can't delete")
body = _("%(level)s” is still held by a referee or inherited by another level, and can't be deleted.") % {"level": name}
notify(request, f"e|{title}|{body}")
return redirect("management:referee_level_list")
body = _("%(level)s” has been deleted.") % {"level": name}
notify(request, f"w|{_('Referee level deleted')}|{body}")
return redirect("management:referee_level_list")
class RefereeListView(ClubStaffRequiredMixin, ListView):
"""Every referee in the club, at a glance: level, eligible teams, validity
-- see teams.RefereeProfile. Read-only; editing happens on the member's