add new signal so reports can render just where event dashboard is

This commit is contained in:
rash
2026-07-26 21:59:18 +02:00
committed by Raphael Michel
parent 0254788124
commit e82573e443
4 changed files with 76 additions and 35 deletions
+1 -1
View File
@@ -83,7 +83,7 @@ Dashboards
.. automodule:: pretix.control.signals
:no-index:
:members: event_dashboard_widgets, user_dashboard_widgets, event_dashboard_top
:members: event_dashboard_widgets, event_dashboard_widgets_override, user_dashboard_widgets, event_dashboard_top
Ticket designs
""""""""""""""
+25
View File
@@ -149,6 +149,31 @@ should return a list of dictionaries, where each dictionary can have the keys:
As with all event plugin signals, the ``sender`` keyword argument will contain the event.
An additional keyword argument ``subevent`` *can* contain a sub-event.
The keyword argument ``widgets_override_active`` is set to ``True`` when a plugin
has returned content from :py:data:`event_dashboard_widgets_override` and is taking
over the KPI section of the dashboard. Receivers that produce widgets which would
be redundant with such a replacement (e.g. the built-in attendees/revenue/products
KPI tiles) should return an empty list in that case. Receivers that provide widgets
unrelated to the KPI tiles (waitinglist, quotas, check-in lists, shop state, etc.)
should ignore the flag and continue to return their widgets — those will render
below the override block.
"""
event_dashboard_widgets_override = EventPluginSignal()
"""
This signal allows a plugin to take over the KPI section of the event dashboard
with custom HTML. Receivers should return an HTML string (or an empty string /
``None`` to opt out). If any receiver returns non-empty HTML, that HTML is
rendered at the top of the dashboard, and receivers of
:py:data:`event_dashboard_widgets` are informed via the
``widgets_override_active=True`` keyword argument so they can suppress widgets
that the override replaces. The remaining widgets (those that don't opt out)
still render below the override block. Multiple receivers' return values are
concatenated.
As with all event plugin signals, the ``sender`` keyword argument will contain
the event. An additional keyword argument ``subevent`` *can* contain a sub-event.
"""
user_dashboard_widgets = GlobalSignal()
@@ -43,37 +43,42 @@
{% if not request.event.has_subevents or subevent %}
{% include "pretixcontrol/event/fragment_timeline.html" %}
{% endif %}
<div class="dashboard">
{% for w in widgets %}
<div class="widget-container widget-{{ w.display_size|default:"small" }} {% if w.lazy %}widget-lazy-loading{% endif %}" data-lazy-id="{{ w.lazy }}">
{% if w.url %}{# backwards compatibility #}
<a href="{{ w.url }}" class="widget">
{% if w.lazy %}
<span class="fa fa-cog fa-4x"></span>
{% else %}
{{ w.content }}
{% endif %}
</a>
{% elif w.link %}
<a href="{{ w.link }}" class="widget">
{% if w.lazy %}
<span class="fa fa-cog fa-4x´"></span>
{% else %}
{{ w.content }}
{% endif %}
</a>
{% else %}
<div class="widget">
{% if w.lazy %}
<span class="fa fa-cog fa-4x"></span>
{% else %}
{{ w.content }}
{% endif %}
</div>
{% endif %}
</div>
{% endfor %}
</div>
{% if widgets_override %}
{{ widgets_override|safe }}
{% endif %}
{% if widgets %}
<div class="dashboard">
{% for w in widgets %}
<div class="widget-container widget-{{ w.display_size|default:"small" }} {% if w.lazy %}widget-lazy-loading{% endif %}" data-lazy-id="{{ w.lazy }}">
{% if w.url %}{# backwards compatibility #}
<a href="{{ w.url }}" class="widget">
{% if w.lazy %}
<span class="fa fa-cog fa-4x"></span>
{% else %}
{{ w.content }}
{% endif %}
</a>
{% elif w.link %}
<a href="{{ w.link }}" class="widget">
{% if w.lazy %}
<span class="fa fa-cog fa-4x´"></span>
{% else %}
{{ w.content }}
{% endif %}
</a>
{% else %}
<div class="widget">
{% if w.lazy %}
<span class="fa fa-cog fa-4x"></span>
{% else %}
{{ w.content }}
{% endif %}
</div>
{% endif %}
</div>
{% endfor %}
</div>
{% endif %}
<p>&nbsp;</p>
<div class="panel panel-default items">
+14 -3
View File
@@ -61,7 +61,8 @@ from pretix.base.models import (
from pretix.base.services.quotas import QuotaAvailability
from pretix.base.timeline import timeline_for_event
from pretix.control.signals import (
event_dashboard_widgets, user_dashboard_widgets,
event_dashboard_widgets, event_dashboard_widgets_override,
user_dashboard_widgets,
)
from pretix.helpers.daterange import daterange
@@ -74,7 +75,9 @@ NUM_WIDGET = '<div class="numwidget"><span class="num">{num}</span><span class="
@receiver(signal=event_dashboard_widgets)
def base_widgets(sender, subevent=None, lazy=False, **kwargs):
def base_widgets(sender, subevent=None, lazy=False, widgets_override_active=False, **kwargs):
if widgets_override_active:
return []
if not lazy:
prodc = Item.objects.filter(
event=sender, active=True,
@@ -369,12 +372,20 @@ def event_index(request, organizer, event):
'event.settings.general:write', request=request)
widgets = []
widgets_override = ''
if can_view_orders:
for r, result in event_dashboard_widgets.send(sender=request.event, subevent=subevent, lazy=True):
for r, result in event_dashboard_widgets_override.send(sender=request.event, subevent=subevent, request=request):
if result:
widgets_override += result
for r, result in event_dashboard_widgets.send(
sender=request.event, subevent=subevent, lazy=True,
widgets_override_active=bool(widgets_override),
):
widgets.extend(result)
ctx = {
'widgets': rearrange(widgets),
'widgets_override': widgets_override,
'subevent': subevent,
'comment_form': CommentForm(initial={'comment': request.event.comment}, readonly=not can_change_event_settings),
}