forked from CGM_Public/pretix_original
Added a personal dashboard
This commit is contained in:
@@ -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'
|
||||||
|
|||||||
@@ -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']
|
||||||
|
)
|
||||||
|
|||||||
@@ -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 %}
|
||||||
|
|||||||
@@ -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'),
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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'
|
||||||
|
|
||||||
|
|||||||
@@ -131,4 +131,26 @@ h1 .btn-sm {
|
|||||||
span.off {
|
span.off {
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user