Fix Events sidebar highlight broken by a context variable name collision

EventListView's calendar prev/next/today context was keyed "nav", shadowing
management.context_processors.active_nav_section's identically-named "nav"
(the value _nav_items.html uses to mark the Events sub-item active) -- so
clicking Calendar never highlighted Events underneath it. Renamed to
"calendar_nav".

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ECGMEwrc2k4D8VQuwjstj9
This commit is contained in:
2026-08-20 08:17:51 +02:00
parent 441367362d
commit 2b4cc7d527
3 changed files with 29 additions and 9 deletions

View File

@@ -50,9 +50,9 @@
{% if calendar_range != "season" %} {% if calendar_range != "season" %}
<div class="flex items-center gap-1"> <div class="flex items-center gap-1">
<a href="{% querystring date=nav.prev|date:"Y-m-d" %}" class="btn btn-square btn-outline btn-sm" aria-label="{% trans 'Previous' %}">{% lucide "chevron-left" size=14 %}</a> <a href="{% querystring date=calendar_nav.prev|date:"Y-m-d" %}" class="btn btn-square btn-outline btn-sm" aria-label="{% trans 'Previous' %}">{% lucide "chevron-left" size=14 %}</a>
<a href="{% querystring date=today|date:"Y-m-d" %}" class="btn btn-outline btn-sm">{% trans "Today" %}</a> <a href="{% querystring date=today|date:"Y-m-d" %}" class="btn btn-outline btn-sm">{% trans "Today" %}</a>
<a href="{% querystring date=nav.next|date:"Y-m-d" %}" class="btn btn-square btn-outline btn-sm" aria-label="{% trans 'Next' %}">{% lucide "chevron-right" size=14 %}</a> <a href="{% querystring date=calendar_nav.next|date:"Y-m-d" %}" class="btn btn-square btn-outline btn-sm" aria-label="{% trans 'Next' %}">{% lucide "chevron-right" size=14 %}</a>
</div> </div>
{% endif %} {% endif %}
{% endif %} {% endif %}

View File

@@ -4634,6 +4634,19 @@ class EventManagementTests(ManagementTestBase):
self.assertContains(response, reverse("management:event_delete", args=[own_event.pk])) self.assertContains(response, reverse("management:event_delete", args=[own_event.pk]))
self.assertNotContains(response, reverse("management:event_delete", args=[other_event.pk])) self.assertNotContains(response, reverse("management:event_delete", args=[other_event.pk]))
def test_the_calendar_page_highlights_the_events_sidebar_item(self):
# Regression: EventListView's own "calendar_nav" context (prev/next/today
# for the Week/Month view) used to be keyed "nav", shadowing
# management.context_processors.active_nav_section's identically-named
# "nav" -- the value _nav_items.html reads to mark the Events sub-item
# active. That silently broke the highlight on this page alone.
self.client.force_login(self.admin_user)
response = self.club_get("event_list")
self.assertContains(response, '<a class="nav-item active" href="/manage/events/">')
self.assertContains(response, '<a class="nav-subitem active" href="/manage/events/">')
def test_the_week_calendar_marks_a_series_occurrence_with_the_repeat_icon(self): def test_the_week_calendar_marks_a_series_occurrence_with_the_repeat_icon(self):
series = EventSeries.objects.create(club=self.club, title="Weekly Training", kind=Event.EventKind.TRAINING, dtstart=timezone.now(), rrule="FREQ=WEEKLY;COUNT=1") series = EventSeries.objects.create(club=self.club, title="Weekly Training", kind=Event.EventKind.TRAINING, dtstart=timezone.now(), rrule="FREQ=WEEKLY;COUNT=1")
occurrence = Event.objects.create(club=self.club, title="Weekly Training", start=timezone.now(), series=series) occurrence = Event.objects.create(club=self.club, title="Weekly Training", start=timezone.now(), series=series)
@@ -6985,3 +6998,5 @@ class MemberAdminAccessTests(ManagementTestBase):
def test_cannot_reach_positions(self): def test_cannot_reach_positions(self):
self.assertEqual(self.club_get("position_create").status_code, 403) self.assertEqual(self.club_get("position_create").status_code, 403)

View File

@@ -2206,14 +2206,14 @@ class EventListView(ClubStaffRequiredMixin, ListView):
events = self.object_list events = self.object_list
if range_kind == "week": if range_kind == "week":
grid = week_grid(events, week_bounds(anchor)[0]) grid = week_grid(events, week_bounds(anchor)[0])
nav = {"prev": anchor - timedelta(days=7), "next": anchor + timedelta(days=7)} calendar_nav = {"prev": anchor - timedelta(days=7), "next": anchor + timedelta(days=7)}
elif range_kind == "season": elif range_kind == "season":
grid = {"months": season_grid(events, selected_season)} if selected_season else None grid = {"months": season_grid(events, selected_season)} if selected_season else None
nav = {} calendar_nav = {}
else: else:
grid = month_grid(events, anchor) grid = month_grid(events, anchor)
nav = {"prev": add_months(anchor, -1), "next": add_months(anchor, 1)} calendar_nav = {"prev": add_months(anchor, -1), "next": add_months(anchor, 1)}
return grid, nav return grid, calendar_nav
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
club, user = self.request.club, self.request.user club, user = self.request.club, self.request.user
@@ -2222,9 +2222,9 @@ class EventListView(ClubStaffRequiredMixin, ListView):
anchor = self._anchor_date() anchor = self._anchor_date()
selected_season = selected_season_from_request(self.request, club) selected_season = selected_season_from_request(self.request, club)
calendar, nav = (None, None) calendar, calendar_nav = (None, None)
if view_mode == "calendar": if view_mode == "calendar":
calendar, nav = self._calendar_context(range_kind, anchor, selected_season) calendar, calendar_nav = self._calendar_context(range_kind, anchor, selected_season)
return super().get_context_data( return super().get_context_data(
seasons=Season.objects.filter(club=club).order_by("-start_date"), seasons=Season.objects.filter(club=club).order_by("-start_date"),
@@ -2238,7 +2238,12 @@ class EventListView(ClubStaffRequiredMixin, ListView):
anchor=anchor, anchor=anchor,
today=timezone.localdate(), today=timezone.localdate(),
calendar=calendar, calendar=calendar,
nav=nav, # Not "nav" -- that key belongs to management.context_processors.
# active_nav_section (the sidebar's own active-item marker, set from
# the URL name and used app-wide by _nav_items.html); reusing it here
# for the calendar's prev/next pair silently shadowed the sidebar's
# value and broke the Events sub-item's highlight on this page only.
calendar_nav=calendar_nav,
**kwargs, **kwargs,
) )