Added a personal dashboard

This commit is contained in:
Raphael Michel
2016-02-23 09:30:50 +01:00
parent afd8b944e7
commit 1014e3f0f4
7 changed files with 107 additions and 19 deletions

View File

@@ -6,6 +6,6 @@ class PretixControlConfig(AppConfig):
label = 'pretixcontrol' label = 'pretixcontrol'
def ready(self): def ready(self):
from .views import event_dashboard # noqa from .views import dashboards # noqa
default_app_config = 'pretix.control.PretixControlConfig' default_app_config = 'pretix.control.PretixControlConfig'

View File

@@ -1,3 +1,5 @@
from django.dispatch import Signal
from pretix.base.signals import EventPluginSignal from pretix.base.signals import EventPluginSignal
""" """
@@ -34,3 +36,16 @@ should return a list of dictionaries, where each dictionary can have the keys:
event_dashboard_widgets = EventPluginSignal( event_dashboard_widgets = EventPluginSignal(
providing_args=[] providing_args=[]
) )
"""
This signal is sent out to include widgets to the personal user dashboard. Receivers
should return a list of dictionaries, where each dictionary can have the keys:
* content (str, containing HTML)
* minimal width (int, widget width in 1/12ths of the page, default ist 3, can be
ignored on small displays)
* priority (int, used for ordering, higher comes first, default is 1)
* link (str, optional, if the full widget should be a link)
"""
user_dashboard_widgets = Signal(
providing_args=['user']
)

View File

@@ -3,11 +3,19 @@
{% block title %}{% trans "Dashboard" %}{% endblock %} {% block title %}{% trans "Dashboard" %}{% endblock %}
{% block content %} {% block content %}
<h1>{% trans "Dashboard" %}</h1> <h1>{% trans "Dashboard" %}</h1>
<p> <div class="row dashboard">
There is nothing yet to see on this dashboard. If you have any ideas what to put here, just <a {% for w in widgets %}
href="https://github.com/pretix/pretix/issues">tell us</a>! <div class="col-xs-12 col-sm-{% if w.width > 6 %}12{% else %}6{% endif %} col-md-{{ w.width }}">
</p> {% if w.url %}
<p> <a href="{{ w.url }}" class="widget">
Probably, you are looking for your <a href="{% url "control:events" %}">events</a>. {{ w.content|safe }}
</p> </a>
{% else %}
<div class="widget">
{{ w.content|safe }}
</div>
{% endif %}
</div>
{% endfor %}
</div>
{% endblock %} {% endblock %}

View File

@@ -1,8 +1,7 @@
from django.conf.urls import include, url from django.conf.urls import include, url
from pretix.control.views import ( from pretix.control.views import (
auth, event, event_dashboard, item, main, orders, organizer, user, auth, dashboards, event, item, main, orders, organizer, user, vouchers,
vouchers,
) )
urlpatterns = [ urlpatterns = [
@@ -11,7 +10,7 @@ urlpatterns = [
url(r'^register$', auth.register, name='auth.register'), url(r'^register$', auth.register, name='auth.register'),
url(r'^forgot$', auth.Forgot.as_view(), name='auth.forgot'), url(r'^forgot$', auth.Forgot.as_view(), name='auth.forgot'),
url(r'^forgot/recover$', auth.Recover.as_view(), name='auth.forgot.recover'), url(r'^forgot/recover$', auth.Recover.as_view(), name='auth.forgot.recover'),
url(r'^$', main.index, name='index'), url(r'^$', dashboards.user_index, name='index'),
url(r'^settings$', user.UserSettings.as_view(), name='user.settings'), url(r'^settings$', user.UserSettings.as_view(), name='user.settings'),
url(r'^organizers/$', organizer.OrganizerList.as_view(), name='organizers'), url(r'^organizers/$', organizer.OrganizerList.as_view(), name='organizers'),
url(r'^organizers/add$', organizer.OrganizerCreate.as_view(), name='organizers.add'), url(r'^organizers/add$', organizer.OrganizerCreate.as_view(), name='organizers.add'),
@@ -20,7 +19,7 @@ urlpatterns = [
url(r'^events/add$', main.EventCreateStart.as_view(), name='events.add'), url(r'^events/add$', main.EventCreateStart.as_view(), name='events.add'),
url(r'^event/(?P<organizer>[^/]+)/add', main.EventCreate.as_view(), name='events.create'), url(r'^event/(?P<organizer>[^/]+)/add', main.EventCreate.as_view(), name='events.create'),
url(r'^event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/', include([ url(r'^event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/', include([
url(r'^$', event_dashboard.index, name='event.index'), url(r'^$', dashboards.event_index, name='event.index'),
url(r'^live/$', event.EventLive.as_view(), name='event.live'), url(r'^live/$', event.EventLive.as_view(), name='event.live'),
url(r'^settings/$', event.EventUpdate.as_view(), name='event.settings'), url(r'^settings/$', event.EventUpdate.as_view(), name='event.settings'),
url(r'^settings/plugins$', event.EventPlugins.as_view(), name='event.settings.plugins'), url(r'^settings/plugins$', event.EventPlugins.as_view(), name='event.settings.plugins'),

View File

@@ -5,10 +5,13 @@ from django.db.models import Sum
from django.dispatch import receiver from django.dispatch import receiver
from django.shortcuts import render from django.shortcuts import render
from django.utils import formats from django.utils import formats
from django.utils.formats import date_format
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from pretix.base.models import Item, Order, OrderPosition from pretix.base.models import Event, Item, Order, OrderPosition
from pretix.control.signals import event_dashboard_widgets from pretix.control.signals import (
event_dashboard_widgets, user_dashboard_widgets,
)
NUM_WIDGET = '<div class="numwidget"><span class="num">{num}</span><span class="text">{text}</span></div>' NUM_WIDGET = '<div class="numwidget"><span class="num">{num}</span><span class="text">{text}</span></div>'
@@ -106,7 +109,7 @@ def shop_state_widget(sender, **kwargs):
}] }]
def index(request, organizer, event): def event_index(request, organizer, event):
widgets = [] widgets = []
for r, result in event_dashboard_widgets.send(sender=request.event): for r, result in event_dashboard_widgets.send(sender=request.event):
widgets.extend(result) widgets.extend(result)
@@ -116,6 +119,51 @@ def index(request, organizer, event):
return render(request, 'pretixcontrol/event/index.html', ctx) return render(request, 'pretixcontrol/event/index.html', ctx)
@receiver(signal=user_dashboard_widgets)
def user_event_widgets(**kwargs):
user = kwargs.pop('user')
widgets = []
events = Event.objects.filter(permitted__id__exact=user.pk).select_related("organizer").order_by('-date_from')
for event in events:
widgets.append({
'content': '<div class="event">{event}<span class="from">{df}</span><span class="to">{dt}</span></div>'.format(
event=event.name, df=date_format(event.date_from, 'SHORT_DATE_FORMAT'),
dt=date_format(event.date_to, 'SHORT_DATE_FORMAT')
),
'width': 3,
'priority': 100,
'url': reverse('control:event.index', kwargs={
'event': event.slug,
'organizer': event.organizer.slug
})
})
return widgets
@receiver(signal=user_dashboard_widgets)
def new_event_widgets(**kwargs):
return [
{
'content': '<div class="newevent"><span class="fa fa-plus-circle"></span>{t}</div>'.format(
t=_('Create a new event')
),
'width': 3,
'priority': 50,
'url': reverse('control:events.add')
}
]
def user_index(request):
widgets = []
for r, result in user_dashboard_widgets.send(request, user=request.user):
widgets.extend(result)
ctx = {
'widgets': rearrange(widgets),
}
return render(request, 'pretixcontrol/dashboard.html', ctx)
def rearrange(widgets: list): def rearrange(widgets: list):
""" """
Small and stupid algorithm to arrange widget boxes without too many gaps while respecting Small and stupid algorithm to arrange widget boxes without too many gaps while respecting

View File

@@ -24,10 +24,6 @@ class EventList(ListView):
) )
def index(request):
return render(request, 'pretixcontrol/dashboard.html', {})
class EventCreateStart(TemplateView): class EventCreateStart(TemplateView):
template_name = 'pretixcontrol/events/start.html' template_name = 'pretixcontrol/events/start.html'

View File

@@ -132,3 +132,25 @@ h1 .btn-sm {
color: @brand-danger; color: @brand-danger;
} }
} }
.dashboard .event {
text-align: center;
padding: 30px;
font-size: 20px;
span.from, span.to {
display: block;
font-size: 25px;
}
}
.dashboard .newevent {
text-align: center;
padding: 30px;
font-size: 20px;
span.fa {
display: block;
font-size: 60px;
padding-bottom: 15px;
}
}