forked from CGM_Public/pretix_original
Lazy-load widgets on global dashboard
This commit is contained in:
@@ -20,9 +20,13 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% for w in upcoming %}
|
{% for w in upcoming %}
|
||||||
<div class="widget-{{ w.display_size|default:"small" }} {{ w.container_class|default:"widget-container" }}">
|
<div class="widget-{{ w.display_size|default:"small" }} {{ w.container_class|default:"widget-container" }} {% if w.lazy %}widget-lazy-loading{% endif %}" data-lazy-id="{{ w.lazy }}">
|
||||||
<div class="widget">
|
<div class="widget">
|
||||||
{{ w.content|safe }}
|
{% if w.lazy %}
|
||||||
|
<span class="fa fa-cog fa-4x"></span>
|
||||||
|
{% else %}
|
||||||
|
{{ w.content|safe }}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -38,9 +42,13 @@
|
|||||||
<h2>{% trans "Your most recent events" %}</h2>
|
<h2>{% trans "Your most recent events" %}</h2>
|
||||||
<div class="dashboard">
|
<div class="dashboard">
|
||||||
{% for w in past %}
|
{% for w in past %}
|
||||||
<div class="widget-{{ w.display_size|default:"small" }} {{ w.container_class|default:"widget-container" }}">
|
<div class="widget-{{ w.display_size|default:"small" }} {{ w.container_class|default:"widget-container" }} {% if w.lazy %}widget-lazy-loading{% endif %}" data-lazy-id="{{ w.lazy }}">
|
||||||
<div class="widget">
|
<div class="widget">
|
||||||
{{ w.content|safe }}
|
{% if w.lazy %}
|
||||||
|
<span class="fa fa-cog fa-4x"></span>
|
||||||
|
{% else %}
|
||||||
|
{{ w.content|safe }}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -55,9 +63,13 @@
|
|||||||
<h2>{% trans "Your event series" %}</h2>
|
<h2>{% trans "Your event series" %}</h2>
|
||||||
<div class="dashboard">
|
<div class="dashboard">
|
||||||
{% for w in series %}
|
{% for w in series %}
|
||||||
<div class="widget-{{ w.display_size|default:"small" }} {{ w.container_class|default:"widget-container" }}">
|
<div class="widget-{{ w.display_size|default:"small" }} {{ w.container_class|default:"widget-container" }} {% if w.lazy %}widget-lazy-loading{% endif %}" data-lazy-id="{{ w.lazy }}">
|
||||||
<div class="widget">
|
<div class="widget">
|
||||||
{{ w.content|safe }}
|
{% if w.lazy %}
|
||||||
|
<span class="fa fa-cog fa-4x"></span>
|
||||||
|
{% else %}
|
||||||
|
{{ w.content|safe }}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -72,14 +84,22 @@
|
|||||||
<h2>{% trans "Other features" %}</h2>
|
<h2>{% trans "Other features" %}</h2>
|
||||||
<div class="dashboard">
|
<div class="dashboard">
|
||||||
{% for w in widgets %}
|
{% for w in widgets %}
|
||||||
<div class="widget-{{ w.display_size|default:"small" }} {{ w.container_class|default:"widget-container" }}">
|
<div class="widget-{{ w.display_size|default:"small" }} {{ w.container_class|default:"widget-container" }} {% if w.lazy %}widget-lazy-loading{% endif %}" data-lazy-id="{{ w.lazy }}">
|
||||||
{% if w.url %}
|
{% if w.url %}
|
||||||
<a href="{{ w.url }}" class="widget">
|
<a href="{{ w.url }}" class="widget">
|
||||||
{{ w.content|safe }}
|
{% if w.lazy %}
|
||||||
|
<span class="fa fa-cog fa-4x"></span>
|
||||||
|
{% else %}
|
||||||
|
{{ w.content|safe }}
|
||||||
|
{% endif %}
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="widget">
|
<div class="widget">
|
||||||
{{ w.content|safe }}
|
{% if w.lazy %}
|
||||||
|
<span class="fa fa-cog fa-4x"></span>
|
||||||
|
{% else %}
|
||||||
|
{{ w.content|safe }}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ urlpatterns = [
|
|||||||
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'^$', dashboards.user_index, name='index'),
|
url(r'^$', dashboards.user_index, name='index'),
|
||||||
|
url(r'^widgets.json$', dashboards.user_index_widgets_lazy, name='index.widgets'),
|
||||||
url(r'^global/settings/$', global_settings.GlobalSettingsView.as_view(), name='global.settings'),
|
url(r'^global/settings/$', global_settings.GlobalSettingsView.as_view(), name='global.settings'),
|
||||||
url(r'^global/update/$', global_settings.UpdateCheckView.as_view(), name='global.update'),
|
url(r'^global/update/$', global_settings.UpdateCheckView.as_view(), name='global.update'),
|
||||||
url(r'^global/message/$', global_settings.MessageView.as_view(), name='global.message'),
|
url(r'^global/message/$', global_settings.MessageView.as_view(), name='global.message'),
|
||||||
|
|||||||
@@ -352,7 +352,7 @@ def event_index_widgets_lazy(request, organizer, event):
|
|||||||
return JsonResponse({'widgets': widgets})
|
return JsonResponse({'widgets': widgets})
|
||||||
|
|
||||||
|
|
||||||
def annotated_event_query(request):
|
def annotated_event_query(request, lazy=False):
|
||||||
active_orders = Order.objects.filter(
|
active_orders = Order.objects.filter(
|
||||||
event=OuterRef('pk'),
|
event=OuterRef('pk'),
|
||||||
status__in=[Order.STATUS_PENDING, Order.STATUS_PAID]
|
status__in=[Order.STATUS_PENDING, Order.STATUS_PAID]
|
||||||
@@ -366,10 +366,13 @@ def annotated_event_query(request):
|
|||||||
event=OuterRef('pk'),
|
event=OuterRef('pk'),
|
||||||
done=False
|
done=False
|
||||||
)
|
)
|
||||||
qs = request.user.get_events_with_any_permission(request).annotate(
|
qs = request.user.get_events_with_any_permission(request)
|
||||||
order_count=Subquery(active_orders, output_field=IntegerField()),
|
if not lazy:
|
||||||
has_ra=Exists(required_actions)
|
qs = qs.annotate(
|
||||||
).annotate(
|
order_count=Subquery(active_orders, output_field=IntegerField()),
|
||||||
|
has_ra=Exists(required_actions)
|
||||||
|
)
|
||||||
|
qs = qs.annotate(
|
||||||
min_from=Min('subevents__date_from'),
|
min_from=Min('subevents__date_from'),
|
||||||
max_from=Max('subevents__date_from'),
|
max_from=Max('subevents__date_from'),
|
||||||
max_to=Max('subevents__date_to'),
|
max_to=Max('subevents__date_to'),
|
||||||
@@ -380,14 +383,15 @@ def annotated_event_query(request):
|
|||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|
||||||
def widgets_for_event_qs(request, qs, user, nmax):
|
def widgets_for_event_qs(request, qs, user, nmax, lazy=False):
|
||||||
widgets = []
|
widgets = []
|
||||||
|
|
||||||
# Get set of events where we have the permission to show the # of orders
|
# Get set of events where we have the permission to show the # of orders
|
||||||
events_with_orders = set(qs.filter(
|
if not lazy:
|
||||||
Q(organizer_id__in=user.teams.filter(all_events=True, can_view_orders=True).values_list('organizer', flat=True))
|
events_with_orders = set(qs.filter(
|
||||||
| Q(id__in=user.teams.filter(can_view_orders=True).values_list('limit_events__id', flat=True))
|
Q(organizer_id__in=user.teams.filter(all_events=True, can_view_orders=True).values_list('organizer', flat=True))
|
||||||
).values_list('id', flat=True))
|
| Q(id__in=user.teams.filter(can_view_orders=True).values_list('limit_events__id', flat=True))
|
||||||
|
).values_list('id', flat=True))
|
||||||
|
|
||||||
tpl = """
|
tpl = """
|
||||||
<a href="{url}" class="event">
|
<a href="{url}" class="event">
|
||||||
@@ -403,36 +407,40 @@ def widgets_for_event_qs(request, qs, user, nmax):
|
|||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
events = qs.prefetch_related(
|
if lazy:
|
||||||
'_settings_objects', 'organizer___settings_objects'
|
events = qs[:nmax]
|
||||||
).select_related('organizer')[:nmax]
|
else:
|
||||||
|
events = qs.prefetch_related(
|
||||||
|
'_settings_objects', 'organizer___settings_objects'
|
||||||
|
).select_related('organizer')[:nmax]
|
||||||
for event in events:
|
for event in events:
|
||||||
tzname = event.cache.get_or_set('timezone', lambda: event.settings.timezone)
|
if not lazy:
|
||||||
tz = pytz.timezone(tzname)
|
tzname = event.cache.get_or_set('timezone', lambda: event.settings.timezone)
|
||||||
if event.has_subevents:
|
tz = pytz.timezone(tzname)
|
||||||
if event.min_from is None:
|
if event.has_subevents:
|
||||||
dr = pgettext("subevent", "No dates")
|
if event.min_from is None:
|
||||||
|
dr = pgettext("subevent", "No dates")
|
||||||
|
else:
|
||||||
|
dr = daterange(
|
||||||
|
(event.min_from).astimezone(tz),
|
||||||
|
(event.max_fromto or event.max_to or event.max_from).astimezone(tz)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
dr = daterange(
|
if event.date_to:
|
||||||
(event.min_from).astimezone(tz),
|
dr = daterange(event.date_from.astimezone(tz), event.date_to.astimezone(tz))
|
||||||
(event.max_fromto or event.max_to or event.max_from).astimezone(tz)
|
else:
|
||||||
)
|
dr = date_format(event.date_from.astimezone(tz), "DATE_FORMAT")
|
||||||
else:
|
|
||||||
if event.date_to:
|
|
||||||
dr = daterange(event.date_from.astimezone(tz), event.date_to.astimezone(tz))
|
|
||||||
else:
|
|
||||||
dr = date_format(event.date_from.astimezone(tz), "DATE_FORMAT")
|
|
||||||
|
|
||||||
if event.has_ra:
|
if event.has_ra:
|
||||||
status = ('danger', _('Action required'))
|
status = ('danger', _('Action required'))
|
||||||
elif not event.live:
|
elif not event.live:
|
||||||
status = ('warning', _('Shop disabled'))
|
status = ('warning', _('Shop disabled'))
|
||||||
elif event.presale_has_ended:
|
elif event.presale_has_ended:
|
||||||
status = ('default', _('Sale over'))
|
status = ('default', _('Sale over'))
|
||||||
elif not event.presale_is_running:
|
elif not event.presale_is_running:
|
||||||
status = ('default', _('Soon'))
|
status = ('default', _('Soon'))
|
||||||
else:
|
else:
|
||||||
status = ('success', _('On sale'))
|
status = ('success', _('On sale'))
|
||||||
|
|
||||||
widgets.append({
|
widgets.append({
|
||||||
'content': tpl.format(
|
'content': tpl.format(
|
||||||
@@ -463,8 +471,9 @@ def widgets_for_event_qs(request, qs, user, nmax):
|
|||||||
daterange=dr,
|
daterange=dr,
|
||||||
status=status[1],
|
status=status[1],
|
||||||
statusclass=status[0],
|
statusclass=status[0],
|
||||||
),
|
) if not lazy else '',
|
||||||
'display_size': 'small',
|
'display_size': 'small',
|
||||||
|
'lazy': 'event-{}'.format(event.pk),
|
||||||
'priority': 100,
|
'priority': 100,
|
||||||
'container_class': 'widget-container widget-container-event',
|
'container_class': 'widget-container widget-container-event',
|
||||||
})
|
})
|
||||||
@@ -482,6 +491,43 @@ def widgets_for_event_qs(request, qs, user, nmax):
|
|||||||
return widgets
|
return widgets
|
||||||
|
|
||||||
|
|
||||||
|
def user_index_widgets_lazy(request):
|
||||||
|
widgets = []
|
||||||
|
widgets += widgets_for_event_qs(
|
||||||
|
request,
|
||||||
|
annotated_event_query(request).filter(
|
||||||
|
Q(has_subevents=False) &
|
||||||
|
Q(
|
||||||
|
Q(Q(date_to__isnull=True) & Q(date_from__gte=now()))
|
||||||
|
| Q(Q(date_to__isnull=False) & Q(date_to__gte=now()))
|
||||||
|
)
|
||||||
|
).order_by('date_from'),
|
||||||
|
request.user,
|
||||||
|
7
|
||||||
|
)
|
||||||
|
widgets += widgets_for_event_qs(
|
||||||
|
request,
|
||||||
|
annotated_event_query(request).filter(
|
||||||
|
Q(has_subevents=False) &
|
||||||
|
Q(
|
||||||
|
Q(Q(date_to__isnull=True) & Q(date_from__lt=now()))
|
||||||
|
| Q(Q(date_to__isnull=False) & Q(date_to__lt=now()))
|
||||||
|
)
|
||||||
|
).order_by('-order_to'),
|
||||||
|
request.user,
|
||||||
|
8
|
||||||
|
)
|
||||||
|
widgets += widgets_for_event_qs(
|
||||||
|
request,
|
||||||
|
annotated_event_query(request).filter(
|
||||||
|
has_subevents=True
|
||||||
|
).order_by('-order_to'),
|
||||||
|
request.user,
|
||||||
|
8
|
||||||
|
)
|
||||||
|
return JsonResponse({'widgets': widgets})
|
||||||
|
|
||||||
|
|
||||||
def user_index(request):
|
def user_index(request):
|
||||||
widgets = []
|
widgets = []
|
||||||
for r, result in user_dashboard_widgets.send(request, user=request.user):
|
for r, result in user_dashboard_widgets.send(request, user=request.user):
|
||||||
@@ -491,7 +537,7 @@ def user_index(request):
|
|||||||
'widgets': rearrange(widgets),
|
'widgets': rearrange(widgets),
|
||||||
'upcoming': widgets_for_event_qs(
|
'upcoming': widgets_for_event_qs(
|
||||||
request,
|
request,
|
||||||
annotated_event_query(request).filter(
|
annotated_event_query(request, lazy=True).filter(
|
||||||
Q(has_subevents=False) &
|
Q(has_subevents=False) &
|
||||||
Q(
|
Q(
|
||||||
Q(Q(date_to__isnull=True) & Q(date_from__gte=now()))
|
Q(Q(date_to__isnull=True) & Q(date_from__gte=now()))
|
||||||
@@ -499,11 +545,12 @@ def user_index(request):
|
|||||||
)
|
)
|
||||||
).order_by('date_from'),
|
).order_by('date_from'),
|
||||||
request.user,
|
request.user,
|
||||||
7
|
7,
|
||||||
|
lazy=True
|
||||||
),
|
),
|
||||||
'past': widgets_for_event_qs(
|
'past': widgets_for_event_qs(
|
||||||
request,
|
request,
|
||||||
annotated_event_query(request).filter(
|
annotated_event_query(request, lazy=True).filter(
|
||||||
Q(has_subevents=False) &
|
Q(has_subevents=False) &
|
||||||
Q(
|
Q(
|
||||||
Q(Q(date_to__isnull=True) & Q(date_from__lt=now()))
|
Q(Q(date_to__isnull=True) & Q(date_from__lt=now()))
|
||||||
@@ -511,15 +558,17 @@ def user_index(request):
|
|||||||
)
|
)
|
||||||
).order_by('-order_to'),
|
).order_by('-order_to'),
|
||||||
request.user,
|
request.user,
|
||||||
8
|
8,
|
||||||
|
lazy=True
|
||||||
),
|
),
|
||||||
'series': widgets_for_event_qs(
|
'series': widgets_for_event_qs(
|
||||||
request,
|
request,
|
||||||
annotated_event_query(request).filter(
|
annotated_event_query(request, lazy=True).filter(
|
||||||
has_subevents=True
|
has_subevents=True
|
||||||
).order_by('-order_to'),
|
).order_by('-order_to'),
|
||||||
request.user,
|
request.user,
|
||||||
8
|
8,
|
||||||
|
lazy=True
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
return render(request, 'pretixcontrol/dashboard.html', ctx)
|
return render(request, 'pretixcontrol/dashboard.html', ctx)
|
||||||
|
|||||||
Reference in New Issue
Block a user