Skip to content
Snippets Groups Projects
Commit a6380ea0 authored by HeJ's avatar HeJ
Browse files

backoffice/schedules: revamp import details page and link latest from startpage

parent f5e6c665
No related branches found
No related tags found
No related merge requests found
......@@ -21,22 +21,57 @@
{% if object.errors %}
<div class="card mb-3 border-warning">
<div class="card-header bg-warning text-white">
<div class="card-header text-bg-warning">
Errors
</div>
<div class="card-body">
<code><pre>{{ object.errors|json_indent }}</pre></code>
</div>
<table class="card-body table table-sm table-hover">
<thead>
<tr><th>Type</th><th>Action</th><th>Source ID</th><th>Local ID</th><th>Message</th></tr>
</thead>
<tbody>
{% for error in object.errors %}
<tr>
<td>{{ error.type|default:"???" }}</td>
<td>{{ error.action|default:"???" }}</td>
<td>{{ error.source_id|default:"-/-" }}</td>
<td>{{ error.local_id|default:"-/-" }}</td>
<td>{{ error.message }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{%endif%}
<div class="card mb-3{% if object.data %} border-primary{% endif %}">
<div class="card-header{% if object.data %} bg-primary text-white{% endif %}">
Data
{% if activity %}
<div class="card mb-3 border-primary">
<div class="card-header text-bg-primary">
Activity
</div>
<div class="card-body">
<code><pre>{{ object.data|json_indent }}</pre></code>
<table class="card-body table table-sm table-hover">
<thead>
<tr><th>Type</th><th>Action</th><th>Source ID</th><th>Local ID</th></tr>
</thead>
<tbody>
{% for item in activity %}
<tr{% if item.action != "seen" %} class="fw-bold"{% endif %}>
<td class="{% if item.action == "seen" %}text-muted{% elif item.action == "error" %}text-danger{% endif %}">{{ item.type|default:"???" }}</td>
<td class="{% if item.action == "seen" %}text-muted{% elif item.action == "error" %}text-danger{% endif %}">{{ item.action|default:"???" }}</td>
<td class="{% if item.action == "seen" %}text-muted{% elif item.action == "error" %}text-danger{% endif %}">{{ item.source_id|default:"-/-" }}</td>
<td class="{% if item.action == "seen" %}text-muted{% elif item.action == "error" %}text-danger{% endif %}">{{ item.local_id|default:"-/-" }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{% if object.data %}
<div class="text-center">
<a href="{% url 'backoffice:schedulesourceimport-detail-data' pk=object.pk %}" class="btn btn-outline-primary">
data as JSON
</a>
</div>
{% endif %}
{% endblock %}
......@@ -13,8 +13,8 @@
{% for source in sources %}
{% with source.latest_import as latest %}
<div class="col">
<div class="card{% if source.has_running_import %} border-primary{% elif source.is_due %} border-warning{% endif %}">
<div class="card-header{% if source.has_running_import %} text-bg-primary{% elif source.is_due %} text-bg-warning{% endif %}">
<div class="card{% if source.has_running_import %} border-primary{% elif source.is_due %} border-warning{% elif latest.state == 'finished' %} border-success{% endif %}">
<div class="card-header{% if source.has_running_import %} text-bg-primary{% elif source.is_due %} text-bg-warning{% elif latest.state == 'finished' %} text-bg-success{% endif %}">
<a href="{% url 'backoffice:schedulesource-detail' pk=source.pk %}" class="float-end ms-3">Details</a>
{% if source.assembly %}
<abbr title="{% trans "Assembly" %}: {{ source.assembly.name }}">{{ source.assembly.slug }}</abbr>
......@@ -51,9 +51,10 @@
</p>
{% endif %}
</div>
{% if latest %}
<div class="card-footer">
<p>
<span class="text-muted small fw-bold">{% trans "ScheduleSource__latest_import" %}</span><br>
<a class="text-muted small fw-bold" href="{% url 'backoffice:schedulesourceimport-detail' pk=latest.pk %}">{% trans "ScheduleSource__latest_import" %}</a><br>
<span class="text-muted small">{% trans "start" %}:</span>
<abbr title="{{ latest.start }}">{{ latest.start|naturaltime|default:"-/-" }}</abbr><br>
<span class="text-muted small">{% trans "end" %}:</span>
......@@ -62,6 +63,7 @@
{{ latest.get_state_display }}<br>
</p>
</div>
{% endif %}
</div>
</div>
{% endwith %}
......
......@@ -124,6 +124,7 @@ urlpatterns = [
path('schedule/source/<uuid:pk>/import', schedules.ScheduleSourcesDoImportView.as_view(), name='schedulesource-import'),
path('schedule/source/<uuid:pk>/update', schedules.ScheduleSourcesUpdateView.as_view(), name='schedulesource-edit'),
path('schedule/import/<int:pk>', schedules.ScheduleSourceImportDetailView.as_view(), name='schedulesourceimport-detail'),
path('schedule/import/<int:pk>.json', schedules.ScheduleSourceImportDataView.as_view(), name='schedulesourceimport-detail-data'),
path('sos/', RedirectView.as_view(pattern_name='backoffice:sos', permanent=True)),
path('self-organized/', events.SoSIndexView.as_view(), name='sos'),
path('self-organized/projects/create', projects.CreateProjectView.as_view(), name='so-create-project'),
......
from django.contrib import messages
from django.http import JsonResponse
from django.shortcuts import redirect
from django.urls import reverse
from django.views import View
......@@ -26,7 +27,7 @@ class SchedulesIndexView(ScheduleAdminMixin, TemplateView):
def get_context_data(self, *args, **kwargs):
ctx = super().get_context_data(*args, **kwargs)
ctx['sources'] = self.conference.schedule_sources.select_related('assembly').all()
ctx['sources'] = self.conference.schedule_sources.select_related('assembly').all().order_by('assembly__name')
return ctx
......@@ -119,3 +120,23 @@ class ScheduleSourcesDeleteView(ScheduleAdminMixin, DeleteView):
class ScheduleSourceImportDetailView(ScheduleAdminMixin, DetailView):
template_name = 'backoffice/schedule_source_import-detail.html'
model = ScheduleSourceImport
def get_context_data(self, *args, **kwargs):
action2sort = {'error': '01', 'removed': '02', 'added': '03', 'seen': '08'}
type2sort = {'room': '10', 'event': '20', 'speaker': '50'}
ctx = super().get_context_data(*args, **kwargs)
if data := ctx['object'].data:
ctx['activity'] = sorted(
data.get('_activity', []),
key=lambda item: f'{action2sort.get(item["action"], "99")}__{type2sort.get(item["type"], "99")}__{item["source_id"]:>10}',
)
else:
ctx['activity'] = None
return ctx
class ScheduleSourceImportDataView(ScheduleAdminMixin, DetailView):
model = ScheduleSourceImport
def get(self, *args, **kwargs):
return JsonResponse(self.get_object().data, json_dumps_params={'indent': 2})
......@@ -770,6 +770,8 @@ class ScheduleSourceImport(models.Model):
@property
def errors(self):
if not self.data:
return None
errors = [x for x in self.data.get('_activity', []) if x['action'] == 'error']
return errors
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment