diff --git a/src/pretix/control/forms/filter.py b/src/pretix/control/forms/filter.py index 36cdea5b9..121fad66f 100644 --- a/src/pretix/control/forms/filter.py +++ b/src/pretix/control/forms/filter.py @@ -5,9 +5,19 @@ from django.utils.translation import ugettext_lazy as _ from pretix.base.models import Item, Order, Organizer from pretix.base.signals import register_payment_providers +from pretix.control.utils.i18n import i18ncomp -class OrderFilterForm(forms.Form): +class FilterForm(forms.Form): + def filter_qs(self, qs): + return qs + + @property + def filtered(self): + return self.is_valid() and any(self.cleaned_data.values()) + + +class OrderFilterForm(FilterForm): query = forms.CharField( label=_('Search for…'), widget=forms.TextInput(attrs={ @@ -61,10 +71,6 @@ class OrderFilterForm(forms.Form): return qs - @property - def filtered(self): - return self.is_valid() and any(self.cleaned_data.values()) - class EventOrderFilterForm(OrderFilterForm): item = forms.ModelChoiceField( @@ -137,3 +143,73 @@ class OrderSearchFilterForm(OrderFilterForm): qs = qs.filter(event__organizer=fdata.get('organizer')) return qs + + +class EventFilterForm(FilterForm): + status = forms.ChoiceField( + label=_('Status'), + choices=( + ('', _('All events')), + ('live', _('Shop live')), + ('running', _('Shop live and presale running')), + ('notlive', _('Shop not live')), + ('future', _('Presale not started')), + ('past', _('Presale over')), + ), + required=False + ) + organizer = forms.ModelChoiceField( + label=_('Organizer'), + queryset=Organizer.objects.none(), + required=False, + empty_label=_('All organizers') + ) + query = forms.CharField( + label=_('Event name'), + widget=forms.TextInput(attrs={ + 'placeholder': _('Event name'), + 'autofocus': 'autofocus' + }), + required=False + ) + + def __init__(self, *args, **kwargs): + request = kwargs.pop('request') + super().__init__(*args, **kwargs) + if request.user.is_superuser: + self.fields['organizer'].queryset = Organizer.objects.all() + else: + self.fields['organizer'].queryset = Organizer.objects.filter( + pk__in=request.user.teams.values_list('organizer', flat=True) + ) + + def filter_qs(self, qs): + fdata = self.cleaned_data + + if fdata.get('status') == 'live': + qs = qs.filter(live=True) + elif fdata.get('status') == 'running': + qs = qs.filter( + live=True + ).filter( + Q(presale_start__isnull=True) | Q(presale_start__lte=now()) + ).filter( + Q(presale_end__isnull=True) | Q(presale_end__gte=now()) + ) + elif fdata.get('status') == 'notlive': + qs = qs.filter(live=False) + elif fdata.get('status') == 'future': + qs = qs.filter(presale_start__gte=now()) + elif fdata.get('status') == 'past': + qs = qs.filter(presale_end__lte=now()) + + if fdata.get('organizer'): + qs = qs.filter(organizer=fdata.get('organizer')) + + if fdata.get('query'): + query = fdata.get('query') + qs = qs.filter( + Q(name__icontains=i18ncomp(query)) | Q(slug__icontains=query) + ) + + return qs diff --git a/src/pretix/control/templates/pretixcontrol/events/index.html b/src/pretix/control/templates/pretixcontrol/events/index.html index f6347b048..316543e2e 100644 --- a/src/pretix/control/templates/pretixcontrol/events/index.html +++ b/src/pretix/control/templates/pretixcontrol/events/index.html @@ -1,18 +1,49 @@ {% extends "pretixcontrol/base.html" %} {% load i18n %} +{% load bootstrap3 %} {% block title %}{% trans "Events" %}{% endblock %} {% block content %} -
{% trans "The list below shows all events you have administrative access to. Click on the event name to access event details." %}
- - - {% trans "Create a new event" %} - - {% if events|length == 0 %} -- {% trans "You currently do not have access to any events." %} -
+{% trans "The list below shows all events you have administrative access to. Click on the event name to access event details." %}
+ {% if events|length == 0 and not filter_form.filtered %} ++ {% blocktrans trimmed %} + You currently do not have access to any events. + {% endblocktrans %} +
+ + + + {% trans "Create a new event" %} + ++ + + {% trans "Create a new event" %} + +
| {% trans "Organizer" %} | {% trans "Start date" %} | {% trans "End date" %} | +{% trans "Status" %} | ||
|---|---|---|---|---|---|
| {{ e.name }} | ++ {{ e.name }} + | {{ e.organizer }} | {{ e.get_date_from_display }} | {{ e.get_date_to_display }} | ++ {% if not e.live %} + {% trans "Shop disabled" %} + {% elif e.presale_has_ended %} + {% trans "Presale over" %} + {% elif not e.presale_is_running %} + {% trans "Presale not started" %} + {% else %} + {% trans "On sale" %} + {% endif %} + |
| {{ o.code }} | ++ + + {{ o.code }} + + + | {{ o.email }} {% if o.invoice_address.name %} diff --git a/src/pretix/control/utils/i18n.py b/src/pretix/control/utils/i18n.py index 615cb8df6..3f527d1c9 100644 --- a/src/pretix/control/utils/i18n.py +++ b/src/pretix/control/utils/i18n.py @@ -1,5 +1,6 @@ # Inspired by https://github.com/asaglimbeni/django-datetime-widget/blob/master/datetimewidget/widgets.py # Copyright (c) 2013, Alfredo Saglimbeni (BSD license) +import json import re from django.utils import translation @@ -63,3 +64,7 @@ def get_moment_locale(locale=None): if main in moment_locales: return main return settings.LANGUAGE_CODE + + +def i18ncomp(query): + return json.dumps(str(query))[1:-1] diff --git a/src/pretix/control/views/main.py b/src/pretix/control/views/main.py index 7f735f4a8..4e8829367 100644 --- a/src/pretix/control/views/main.py +++ b/src/pretix/control/views/main.py @@ -3,6 +3,7 @@ from django.contrib import messages from django.core.urlresolvers import reverse from django.db import transaction from django.shortcuts import redirect +from django.utils.functional import cached_property from django.utils.translation import ugettext_lazy as _ from django.views.generic import ListView from formtools.wizard.views import SessionWizardView @@ -11,6 +12,7 @@ from pretix.base.models import Event, Team from pretix.control.forms.event import ( EventWizardBasicsForm, EventWizardCopyForm, EventWizardFoundationForm, ) +from pretix.control.forms.filter import EventFilterForm class EventList(ListView): @@ -20,9 +22,21 @@ class EventList(ListView): template_name = 'pretixcontrol/events/index.html' def get_queryset(self): - return self.request.user.get_events_with_any_permission().select_related('organizer').prefetch_related( + qs = self.request.user.get_events_with_any_permission().select_related('organizer').prefetch_related( '_settings_objects', 'organizer___settings_objects' ) + if self.filter_form.is_valid(): + qs = self.filter_form.filter_qs(qs) + return qs + + def get_context_data(self, **kwargs): + ctx = super().get_context_data(**kwargs) + ctx['filter_form'] = self.filter_form + return ctx + + @cached_property + def filter_form(self): + return EventFilterForm(data=self.request.GET, request=self.request) def condition_copy(wizard): diff --git a/src/pretix/control/views/typeahead.py b/src/pretix/control/views/typeahead.py index 6807d7dd2..a4599b280 100644 --- a/src/pretix/control/views/typeahead.py +++ b/src/pretix/control/views/typeahead.py @@ -1,12 +1,8 @@ -import json - from django.db.models import Q from django.http import JsonResponse from django.urls import reverse - -def i18ncomp(query): - return json.dumps(str(query))[1:-1] +from pretix.control.utils.i18n import i18ncomp def event_list(request): |