mirror of
https://github.com/pretix/pretix.git
synced 2026-05-09 15:54:03 +00:00
Lazy-load logs on event dashboard
This commit is contained in:
@@ -167,59 +167,10 @@
|
|||||||
{% trans "Event logs" %}
|
{% trans "Event logs" %}
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<ul class="list-group">
|
<ul class="list-group" id="logs_target">
|
||||||
{% for log in logs %}
|
<div class="logs-lazy-loading">
|
||||||
<li class="list-group-item logentry">
|
<span class="fa fa-cog fa-4x"></span>
|
||||||
<div class="row">
|
</div>
|
||||||
<div class="col-lg-2 col-sm-6 col-xs-12">
|
|
||||||
<span class="fa fa-clock-o"></span> {{ log.datetime|date:"SHORT_DATETIME_FORMAT" }}
|
|
||||||
{% if log.shredded %}
|
|
||||||
<span class="fa fa-eraser fa-danger fa-fw"
|
|
||||||
data-toggle="tooltip"
|
|
||||||
title="{% trans "Personal data was cleared from this log entry." %}">
|
|
||||||
</span>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-2 col-sm-6 col-xs-12">
|
|
||||||
{% if log.user %}
|
|
||||||
{% if log.user.is_staff %}
|
|
||||||
<span class="fa fa-id-card fa-danger fa-fw"
|
|
||||||
data-toggle="tooltip"
|
|
||||||
title="{% trans "This change was performed by a pretix administrator." %}">
|
|
||||||
</span>
|
|
||||||
{% else %}
|
|
||||||
<span class="fa fa-user fa-fw"></span>
|
|
||||||
{% endif %}
|
|
||||||
{{ log.user.get_full_name }}
|
|
||||||
{% if log.oauth_application %}
|
|
||||||
<br><span class="fa fa-plug fa-fw"></span>
|
|
||||||
{{ log.oauth_application.name }}
|
|
||||||
{% endif %}
|
|
||||||
{% elif log.device %}
|
|
||||||
<span class="fa fa-mobile fa-fw"></span>
|
|
||||||
{{ log.device.name }}
|
|
||||||
{% elif log.api_token %}
|
|
||||||
<span class="fa fa-key fa-fw"></span>
|
|
||||||
{{ log.api_token.name }}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-2 col-sm-12 col-xs-12">
|
|
||||||
{% if log.display_object %}
|
|
||||||
<span class="fa fa-flag"></span> {{ log.display_object|safe }}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-6 col-sm-12 col-xs-12">
|
|
||||||
{{ log.display }}
|
|
||||||
{% if staff_session %}
|
|
||||||
<a href="" class="btn btn-default btn-xs" data-expandlogs data-id="{{ log.pk }}">
|
|
||||||
<span class="fa-eye fa fa-fw"></span>
|
|
||||||
{% trans "Inspect" %}
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
</ul>
|
||||||
<div class="panel-footer">
|
<div class="panel-footer">
|
||||||
<a href="{% url "control:event.log" event=request.event.slug organizer=request.event.organizer.slug %}">
|
<a href="{% url "control:event.log" event=request.event.slug organizer=request.event.organizer.slug %}">
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
{% load i18n %}
|
||||||
|
{% for log in logs %}
|
||||||
|
<li class="list-group-item logentry">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-2 col-sm-6 col-xs-12">
|
||||||
|
<span class="fa fa-clock-o"></span> {{ log.datetime|date:"SHORT_DATETIME_FORMAT" }}
|
||||||
|
{% if log.shredded %}
|
||||||
|
<span class="fa fa-eraser fa-danger fa-fw"
|
||||||
|
data-toggle="tooltip"
|
||||||
|
title="{% trans "Personal data was cleared from this log entry." %}">
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-2 col-sm-6 col-xs-12">
|
||||||
|
{% if log.user %}
|
||||||
|
{% if log.user.is_staff %}
|
||||||
|
<span class="fa fa-id-card fa-danger fa-fw"
|
||||||
|
data-toggle="tooltip"
|
||||||
|
title="{% trans "This change was performed by a pretix administrator." %}">
|
||||||
|
</span>
|
||||||
|
{% else %}
|
||||||
|
<span class="fa fa-user fa-fw"></span>
|
||||||
|
{% endif %}
|
||||||
|
{{ log.user.get_full_name }}
|
||||||
|
{% if log.oauth_application %}
|
||||||
|
<br><span class="fa fa-plug fa-fw"></span>
|
||||||
|
{{ log.oauth_application.name }}
|
||||||
|
{% endif %}
|
||||||
|
{% elif log.device %}
|
||||||
|
<span class="fa fa-mobile fa-fw"></span>
|
||||||
|
{{ log.device.name }}
|
||||||
|
{% elif log.api_token %}
|
||||||
|
<span class="fa fa-key fa-fw"></span>
|
||||||
|
{{ log.api_token.name }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-2 col-sm-12 col-xs-12">
|
||||||
|
{% if log.display_object %}
|
||||||
|
<span class="fa fa-flag"></span> {{ log.display_object|safe }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-6 col-sm-12 col-xs-12">
|
||||||
|
{{ log.display }}
|
||||||
|
{% if staff_session %}
|
||||||
|
<a href="" class="btn btn-default btn-xs" data-expandlogs data-id="{{ log.pk }}">
|
||||||
|
<span class="fa-eye fa fa-fw"></span>
|
||||||
|
{% trans "Inspect" %}
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
@@ -193,6 +193,7 @@ urlpatterns = [
|
|||||||
re_path(r'^event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/', include([
|
re_path(r'^event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/', include([
|
||||||
re_path(r'^$', dashboards.event_index, name='event.index'),
|
re_path(r'^$', dashboards.event_index, name='event.index'),
|
||||||
re_path(r'^widgets.json$', dashboards.event_index_widgets_lazy, name='event.index.widgets'),
|
re_path(r'^widgets.json$', dashboards.event_index_widgets_lazy, name='event.index.widgets'),
|
||||||
|
re_path(r'^logs/embed$', dashboards.event_index_log_lazy, name='event.index.logs'),
|
||||||
re_path(r'^live/$', event.EventLive.as_view(), name='event.live'),
|
re_path(r'^live/$', event.EventLive.as_view(), name='event.live'),
|
||||||
re_path(r'^logs/$', event.EventLog.as_view(), name='event.log'),
|
re_path(r'^logs/$', event.EventLog.as_view(), name='event.log'),
|
||||||
re_path(r'^delete/$', event.EventDelete.as_view(), name='event.delete'),
|
re_path(r'^delete/$', event.EventDelete.as_view(), name='event.delete'),
|
||||||
|
|||||||
@@ -353,40 +353,16 @@ def event_index(request, organizer, event):
|
|||||||
request=request)
|
request=request)
|
||||||
can_change_event_settings = request.user.has_event_permission(request.organizer, request.event,
|
can_change_event_settings = request.user.has_event_permission(request.organizer, request.event,
|
||||||
'can_change_event_settings', request=request)
|
'can_change_event_settings', request=request)
|
||||||
can_view_vouchers = request.user.has_event_permission(request.organizer, request.event, 'can_view_vouchers',
|
|
||||||
request=request)
|
|
||||||
|
|
||||||
widgets = []
|
widgets = []
|
||||||
if can_view_orders:
|
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.send(sender=request.event, subevent=subevent, lazy=True):
|
||||||
widgets.extend(result)
|
widgets.extend(result)
|
||||||
|
|
||||||
qs = request.event.logentry_set.all().select_related('user', 'content_type', 'api_token', 'oauth_application',
|
|
||||||
'device').order_by('-datetime')
|
|
||||||
qs = qs.exclude(action_type__in=OVERVIEW_BANLIST)
|
|
||||||
if not can_view_orders:
|
|
||||||
qs = qs.exclude(content_type=ContentType.objects.get_for_model(Order))
|
|
||||||
if not can_view_vouchers:
|
|
||||||
qs = qs.exclude(content_type=ContentType.objects.get_for_model(Voucher))
|
|
||||||
if not can_change_event_settings:
|
|
||||||
allowed_types = [
|
|
||||||
ContentType.objects.get_for_model(Voucher),
|
|
||||||
ContentType.objects.get_for_model(Order)
|
|
||||||
]
|
|
||||||
if request.user.has_event_permission(request.organizer, request.event, 'can_change_items', request=request):
|
|
||||||
allowed_types += [
|
|
||||||
ContentType.objects.get_for_model(Item),
|
|
||||||
ContentType.objects.get_for_model(ItemCategory),
|
|
||||||
ContentType.objects.get_for_model(Quota),
|
|
||||||
ContentType.objects.get_for_model(Question),
|
|
||||||
]
|
|
||||||
qs = qs.filter(content_type__in=allowed_types)
|
|
||||||
|
|
||||||
a_qs = request.event.requiredaction_set.filter(done=False)
|
a_qs = request.event.requiredaction_set.filter(done=False)
|
||||||
|
|
||||||
ctx = {
|
ctx = {
|
||||||
'widgets': rearrange(widgets),
|
'widgets': rearrange(widgets),
|
||||||
'logs': qs[:5],
|
|
||||||
'subevent': subevent,
|
'subevent': subevent,
|
||||||
'actions': a_qs[:5] if can_change_orders else [],
|
'actions': a_qs[:5] if can_change_orders else [],
|
||||||
'comment_form': CommentForm(initial={'comment': request.event.comment}, readonly=not can_change_event_settings),
|
'comment_form': CommentForm(initial={'comment': request.event.comment}, readonly=not can_change_event_settings),
|
||||||
@@ -445,6 +421,45 @@ def event_index_widgets_lazy(request, organizer, event):
|
|||||||
return JsonResponse({'widgets': widgets})
|
return JsonResponse({'widgets': widgets})
|
||||||
|
|
||||||
|
|
||||||
|
def event_index_log_lazy(request, organizer, event):
|
||||||
|
qs = request.event.logentry_set.all().select_related('user', 'content_type', 'api_token', 'oauth_application',
|
||||||
|
'device').order_by('-datetime')
|
||||||
|
qs = qs.exclude(action_type__in=OVERVIEW_BANLIST)
|
||||||
|
|
||||||
|
can_view_orders = request.user.has_event_permission(request.organizer, request.event, 'can_view_orders',
|
||||||
|
request=request)
|
||||||
|
can_change_event_settings = request.user.has_event_permission(request.organizer, request.event,
|
||||||
|
'can_change_event_settings', request=request)
|
||||||
|
can_view_vouchers = request.user.has_event_permission(request.organizer, request.event, 'can_view_vouchers',
|
||||||
|
request=request)
|
||||||
|
|
||||||
|
if not can_view_orders:
|
||||||
|
qs = qs.exclude(content_type=ContentType.objects.get_for_model(Order))
|
||||||
|
if not can_view_vouchers:
|
||||||
|
qs = qs.exclude(content_type=ContentType.objects.get_for_model(Voucher))
|
||||||
|
if not can_change_event_settings:
|
||||||
|
allowed_types = [
|
||||||
|
ContentType.objects.get_for_model(Voucher),
|
||||||
|
ContentType.objects.get_for_model(Order)
|
||||||
|
]
|
||||||
|
if request.user.has_event_permission(request.organizer, request.event, 'can_change_items', request=request):
|
||||||
|
allowed_types += [
|
||||||
|
ContentType.objects.get_for_model(Item),
|
||||||
|
ContentType.objects.get_for_model(ItemCategory),
|
||||||
|
ContentType.objects.get_for_model(Quota),
|
||||||
|
ContentType.objects.get_for_model(Question),
|
||||||
|
]
|
||||||
|
qs = qs.filter(content_type__in=allowed_types)
|
||||||
|
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
'pretixcontrol/event/logs_embed.html',
|
||||||
|
{
|
||||||
|
'logs': qs[:5]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def annotated_event_query(request, lazy=False):
|
def annotated_event_query(request, lazy=False):
|
||||||
active_orders = Order.objects.filter(
|
active_orders = Order.objects.filter(
|
||||||
event=OuterRef('pk'),
|
event=OuterRef('pk'),
|
||||||
|
|||||||
@@ -11,3 +11,12 @@ $(function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
$(function () {
|
||||||
|
if ($("#logs_target").length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$.get("logs/embed", function (data) {
|
||||||
|
$("#logs_target").html(data)
|
||||||
|
add_log_expand_handlers($("#logs_target"))
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -840,28 +840,6 @@ $(function () {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$("a[data-expandlogs], a[data-expandrefund], a[data-expandpayment]").click(function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
var $a = $(this);
|
|
||||||
var id = $(this).attr("data-id");
|
|
||||||
$a.find(".fa").removeClass("fa-eye").addClass("fa-cog fa-spin");
|
|
||||||
var url = '/control/logdetail/';
|
|
||||||
if ($a.is("[data-expandrefund]")) {
|
|
||||||
url += 'refund/'
|
|
||||||
} else if ($a.is("[data-expandpayment]")) {
|
|
||||||
url += 'payment/'
|
|
||||||
}
|
|
||||||
$.getJSON(url + '?pk=' + id, function (data) {
|
|
||||||
if ($a.parent().tagName === "p") {
|
|
||||||
$("<pre>").text(JSON.stringify(data.data, null, 2)).insertAfter($a.parent());
|
|
||||||
} else {
|
|
||||||
$("<pre>").text(JSON.stringify(data.data, null, 2)).appendTo($a.parent());
|
|
||||||
}
|
|
||||||
$a.remove();
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
$("button[data-toggle=qrcode]").click(function (e) {
|
$("button[data-toggle=qrcode]").click(function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var $current = $(".qr-code-overlay[data-qrcode='" + $(this).attr("data-qrcode") + "']");
|
var $current = $(".qr-code-overlay[data-qrcode='" + $(this).attr("data-qrcode") + "']");
|
||||||
@@ -894,8 +872,34 @@ $(function () {
|
|||||||
|
|
||||||
$("#ajaxerr").on("click", ".ajaxerr-close", ajaxErrDialog.hide);
|
$("#ajaxerr").on("click", ".ajaxerr-close", ajaxErrDialog.hide);
|
||||||
moment.locale($("body").attr("data-datetimelocale"));
|
moment.locale($("body").attr("data-datetimelocale"));
|
||||||
|
add_log_expand_handlers($("body"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function add_log_expand_handlers(el) {
|
||||||
|
el.find("a[data-expandlogs], a[data-expandrefund], a[data-expandpayment]").click(function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var $a = $(this);
|
||||||
|
var id = $(this).attr("data-id");
|
||||||
|
$a.find(".fa").removeClass("fa-eye").addClass("fa-cog fa-spin");
|
||||||
|
var url = '/control/logdetail/';
|
||||||
|
if ($a.is("[data-expandrefund]")) {
|
||||||
|
url += 'refund/'
|
||||||
|
} else if ($a.is("[data-expandpayment]")) {
|
||||||
|
url += 'payment/'
|
||||||
|
}
|
||||||
|
$.getJSON(url + '?pk=' + id, function (data) {
|
||||||
|
if ($a.parent().tagName === "p") {
|
||||||
|
$("<pre>").text(JSON.stringify(data.data, null, 2)).insertAfter($a.parent());
|
||||||
|
} else {
|
||||||
|
$("<pre>").text(JSON.stringify(data.data, null, 2)).appendTo($a.parent());
|
||||||
|
}
|
||||||
|
$a.remove();
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$('form[method=post]').filter(function () {
|
$('form[method=post]').filter(function () {
|
||||||
return $(this).find("button:not([type=button]), input[type=submit]").length > 0;
|
return $(this).find("button:not([type=button]), input[type=submit]").length > 0;
|
||||||
|
|||||||
@@ -176,6 +176,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.logs-lazy-loading {
|
||||||
|
text-align: center;
|
||||||
|
.fa-cog {
|
||||||
|
color: #ccc;
|
||||||
|
margin: 30px;
|
||||||
|
-webkit-animation: fa-spin 4s infinite linear;
|
||||||
|
animation: fa-spin 4s infinite linear;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: $screen-sm-max) {
|
@media (max-width: $screen-sm-max) {
|
||||||
.dashboard .widget-container.widget-small {
|
.dashboard .widget-container.widget-small {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
|
|||||||
Reference in New Issue
Block a user