From bf80dc37c531c83515d614bc2eb5079476481f2b Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Tue, 17 Mar 2026 10:26:22 +0100 Subject: [PATCH] Navigation and dashboard: Hide useless items (#5995) * Navigation and dashboard: Hide useless items If a user has access to *no organizer teams*, hide a number of things from navigation and dashboard. This happens e.g. if a user only has permissions in scope of the pretix-resellers or pretix-scheduling plugins. * New mechanism --- src/pretix/base/models/auth.py | 6 ++ src/pretix/control/navigation.py | 69 ++++++++++--------- .../templates/pretixcontrol/dashboard.html | 42 +++++------ 3 files changed, 65 insertions(+), 52 deletions(-) diff --git a/src/pretix/base/models/auth.py b/src/pretix/base/models/auth.py index d3987d566..83d82a287 100644 --- a/src/pretix/base/models/auth.py +++ b/src/pretix/base/models/auth.py @@ -49,6 +49,7 @@ from django.core.exceptions import BadRequest, PermissionDenied from django.db import IntegrityError, models, transaction from django.db.models import Q from django.utils.crypto import get_random_string, salted_hmac +from django.utils.functional import cached_property from django.utils.timezone import now from django.utils.translation import gettext_lazy as _ from django_otp.models import Device @@ -667,6 +668,11 @@ class User(AbstractBaseUser, PermissionsMixin, LoggingMixin): self.session_token = generate_session_token() self.save(update_fields=['session_token']) + @cached_property + @scopes_disabled() + def is_in_any_teams(self): + return self.teams.exists() + class UserKnownLoginSource(models.Model): user = models.ForeignKey('User', on_delete=models.CASCADE, related_name="known_login_sources") diff --git a/src/pretix/control/navigation.py b/src/pretix/control/navigation.py index a6e320978..7e1f9e0b2 100644 --- a/src/pretix/control/navigation.py +++ b/src/pretix/control/navigation.py @@ -340,38 +340,43 @@ def get_global_navigation(request): 'active': (url.url_name == 'index'), 'icon': 'dashboard', }, - { - 'label': _('Events'), - 'url': reverse('control:events'), - 'active': 'events' in url.url_name, - 'icon': 'calendar', - }, - { - 'label': _('Organizers'), - 'url': reverse('control:organizers'), - 'active': 'organizers' in url.url_name, - 'icon': 'group', - }, - { - 'label': _('Search'), - 'url': reverse('control:search.orders'), - 'active': False, - 'icon': 'search', - 'children': [ - { - 'label': _('Orders'), - 'url': reverse('control:search.orders'), - 'active': 'search.orders' in url.url_name, - 'icon': 'search', - }, - { - 'label': _('Payments'), - 'url': reverse('control:search.payments'), - 'active': 'search.payments' in url.url_name, - 'icon': 'search', - }, - ] - }, + ] + if request.user.is_in_any_teams: + nav += [ + { + 'label': _('Events'), + 'url': reverse('control:events'), + 'active': 'events' in url.url_name, + 'icon': 'calendar', + }, + { + 'label': _('Organizers'), + 'url': reverse('control:organizers'), + 'active': 'organizers' in url.url_name, + 'icon': 'group', + }, + { + 'label': _('Search'), + 'url': reverse('control:search.orders'), + 'active': False, + 'icon': 'search', + 'children': [ + { + 'label': _('Orders'), + 'url': reverse('control:search.orders'), + 'active': 'search.orders' in url.url_name, + 'icon': 'search', + }, + { + 'label': _('Payments'), + 'url': reverse('control:search.payments'), + 'active': 'search.payments' in url.url_name, + 'icon': 'search', + }, + ] + }, + ] + nav += [ { 'label': _('User settings'), 'url': reverse('control:user.settings'), diff --git a/src/pretix/control/templates/pretixcontrol/dashboard.html b/src/pretix/control/templates/pretixcontrol/dashboard.html index c1bf3e49b..7dace3937 100644 --- a/src/pretix/control/templates/pretixcontrol/dashboard.html +++ b/src/pretix/control/templates/pretixcontrol/dashboard.html @@ -12,27 +12,29 @@ class="event-dropdown dropdown-menu"> -

{% trans "Your upcoming events" %}

-
- {% if can_create_event %} - - {% endif %} - {% for w in upcoming %} -
-
- {% if w.lazy %} - - {% else %} - {{ w.content|safe }} - {% endif %} + {% if upcoming or can_create_event %} +

{% trans "Your upcoming events" %}

+
+ {% if can_create_event %} + -
- {% endfor %} -
+ {% endif %} + {% for w in upcoming %} +
+
+ {% if w.lazy %} + + {% else %} + {{ w.content|safe }} + {% endif %} +
+
+ {% endfor %} +
+ {% endif %} {% if upcoming %}