From 2cca0322d132b7e6d2d7f836ee1e009d2b125e2f Mon Sep 17 00:00:00 2001 From: Jean-Marie Favreau Date: Fri, 13 Dec 2024 00:06:36 +0100 Subject: [PATCH] =?UTF-8?q?Ajout=20d'une=20visualisation=20des=20mod=C3=A9?= =?UTF-8?q?rations=20=C3=A0=20venir?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix #247 --- src/agenda_culturel/static/style.scss | 47 ++++++++++++++++++- .../agenda_culturel/administration.html | 38 ++++++++++++--- src/agenda_culturel/views.py | 37 +++++++++++++-- 3 files changed, 112 insertions(+), 10 deletions(-) diff --git a/src/agenda_culturel/static/style.scss b/src/agenda_culturel/static/style.scss index 6469970..b558e64 100644 --- a/src/agenda_culturel/static/style.scss +++ b/src/agenda_culturel/static/style.scss @@ -1603,4 +1603,49 @@ label.required::after { width: 14em; margin-right: 1.2em; } -} \ No newline at end of file +} + +.moderation_heatmap { + border-spacing: 0.1em; + border-collapse: separate; + + max-width: 600px; + margin: auto; + th { + font-size: 70%; + text-align: center; + } + td { + font-size: 60%; + text-align: center; + } + tbody th { + text-align: right; + } + .ratio { + border-radius: var(--border-radius); + padding: 0.2em; + color: black; + } + .score_0 { + background: rgb(0, 128, 0); + } + .score_1 { + background: rgb(255, 255, 0); + } + .score_2 { + background: rgb(255, 166, 0); + } + .score_3 { + background: rgb(255, 0, 0); + } + .score_4 { + background: rgb(128, 0, 128); + color: white; + } + @media only screen and (max-width: 300px) { + .ratio, .month, .label { + font-size: 0; + } + } +} diff --git a/src/agenda_culturel/templates/agenda_culturel/administration.html b/src/agenda_culturel/templates/agenda_culturel/administration.html index dbf94dd..715ba0d 100644 --- a/src/agenda_culturel/templates/agenda_culturel/administration.html +++ b/src/agenda_culturel/templates/agenda_culturel/administration.html @@ -17,13 +17,38 @@ {% block content %}
+
+
+
+ +

Modération à venir

+
+ + {% for w in nb_not_moderated %} + + + + {% for m in w %} + + {% endfor %} + + + + + {% endfor %} + + +
{{ m.start_day|date:"d" }} {{ m.start_day|date:"M"|lower }}
reste à modérer + {% for m in w %} + {{ m.not_moderated }} / {{ m.nb_events }}
+ {% endfor %} + +
-
+
diff --git a/src/agenda_culturel/views.py b/src/agenda_culturel/views.py index 8446a82..62b1c25 100644 --- a/src/agenda_culturel/views.py +++ b/src/agenda_culturel/views.py @@ -76,7 +76,7 @@ from django.utils import timezone from django.utils.html import escape from datetime import date, timedelta from django.utils.timezone import datetime -from django.db.models import Q, Subquery, OuterRef, Count, F, Func +from django.db.models import Q, Subquery, OuterRef, Count, F, Func, BooleanField, ExpressionWrapper from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ @@ -873,9 +873,13 @@ def activite(request): @login_required(login_url="/accounts/login/") @permission_required("agenda_culturel.view_event") def administration(request): + nb_mod_days = 21 + nb_classes = 4 + today = date.today() + start_time = datetime.now().time() # get information about recent modifications - days = [date.today()] + days = [today] for i in range(0, 2): days.append(days[-1] + timedelta(days=-1)) daily_modifications = Event.get_count_modifications([(d, 1) for d in days]) @@ -905,13 +909,40 @@ def administration(request): .count()) nb_all = imported_events.count() + window_end = today + timedelta(days=nb_mod_days) + # get all non moderated events + nb_not_moderated = Event.objects.filter(~Q(status=Event.STATUS.TRASH)). \ + filter(Q(start_day__gte=today)&Q(start_day__lte=window_end)). \ + filter( + Q(other_versions__isnull=True) | + Q(other_versions__representative=F('pk')) | + Q(other_versions__representative__isnull=True)).values("start_day").\ + annotate(not_moderated=Count("start_day", filter=Q(moderated_date__isnull=True))). \ + annotate(nb_events=Count("start_day")). \ + order_by("start_day") + + max_not_moderated = max([x["not_moderated"] for x in nb_not_moderated]) + if max_not_moderated == 0: + max_not_moderated = 1 + nb_not_moderated_dict = dict([(x["start_day"], (x["not_moderated"], x["nb_events"])) for x in nb_not_moderated]) + # add missing dates + date_list = [today + timedelta(days=x) for x in range(0, nb_mod_days)] + nb_not_moderated = [{"start_day": d, + "nb_events": nb_not_moderated_dict[d][1] if d in nb_not_moderated_dict else 0, + "not_moderated": nb_not_moderated_dict[d][0] if d in nb_not_moderated_dict else 0} for d in date_list] + nb_not_moderated = [ x | { "note": 0 if x["not_moderated"] == 0 else int((nb_classes - 1) * x["not_moderated"] / max_not_moderated) + 1 } for x in nb_not_moderated] + nb_not_moderated = [nb_not_moderated[x:x + 7] for x in range(0, len(nb_not_moderated), 7)] + + + return render( request, "agenda_culturel/administration.html", {"daily_modifications": daily_modifications, "events": events, "batch_imports": batch_imports, "nb_failed": nb_failed, "nb_canceled": nb_canceled, - "nb_running": nb_running, "nb_all": nb_all}, + "nb_running": nb_running, "nb_all": nb_all, + "nb_not_moderated": nb_not_moderated}, )