From a2853bb100e47a0dc4661b6a099216fc2d123565 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Benjamin=20H=C3=A4ttasch?=
 <benjamin.haettasch@fachschaft.informatik.tu-darmstadt.de>
Date: Sat, 10 Jun 2023 12:25:45 +0200
Subject: [PATCH] Improve documentation and resolve quality issues for
 AKDashboard

---
 AKDashboard/admin.py  |  3 +++
 AKDashboard/apps.py   |  3 +++
 AKDashboard/models.py | 11 ++++++++++
 AKDashboard/views.py  | 50 ++++++++++++++++++++++++++++++-------------
 4 files changed, 52 insertions(+), 15 deletions(-)

diff --git a/AKDashboard/admin.py b/AKDashboard/admin.py
index 724ac31c..ffc7b41c 100644
--- a/AKDashboard/admin.py
+++ b/AKDashboard/admin.py
@@ -4,6 +4,9 @@ from AKDashboard.models import DashboardButton
 
 @admin.register(DashboardButton)
 class DashboardButtonAdmin(admin.ModelAdmin):
+    """
+    Admin interface for dashboard buttons
+    """
     list_display = ['text', 'url', 'event']
     list_filter = ['event']
     search_fields = ['text', 'url']
diff --git a/AKDashboard/apps.py b/AKDashboard/apps.py
index ad0d4316..c71dc240 100644
--- a/AKDashboard/apps.py
+++ b/AKDashboard/apps.py
@@ -2,4 +2,7 @@ from django.apps import AppConfig
 
 
 class AkdashboardConfig(AppConfig):
+    """
+    App configuration for dashboard (default)
+    """
     name = 'AKDashboard'
diff --git a/AKDashboard/models.py b/AKDashboard/models.py
index 130a8e37..6691e962 100644
--- a/AKDashboard/models.py
+++ b/AKDashboard/models.py
@@ -6,6 +6,17 @@ from AKModel.models import Event
 
 
 class DashboardButton(models.Model):
+    """
+    Model for a single dashboard button
+
+    Allows to specify
+    * a text (currently without possibility to translate),
+    * a color (based on predefined design colors)
+    * a url the button should point to (internal or external)
+    * an icon (from the collection of fontawesome)
+
+    Each button is associated with a single event and will be deleted when the event is deleted.
+    """
     class Meta:
         verbose_name = _("Dashboard Button")
         verbose_name_plural = _("Dashboard Buttons")
diff --git a/AKDashboard/views.py b/AKDashboard/views.py
index 88e3443e..601edda2 100644
--- a/AKDashboard/views.py
+++ b/AKDashboard/views.py
@@ -1,5 +1,4 @@
 from django.apps import apps
-from django.urls import reverse_lazy
 from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import ensure_csrf_cookie
 from django.views.generic import TemplateView, DetailView
@@ -10,6 +9,11 @@ from AKPlanning import settings
 
 
 class DashboardView(TemplateView):
+    """
+    Index view of dashboard and therefore the main entry point for AKPlanning
+
+    Displays information and buttons for all public events
+    """
     template_name = 'AKDashboard/dashboard.html'
 
     @method_decorator(ensure_csrf_cookie)
@@ -23,6 +27,14 @@ class DashboardView(TemplateView):
 
 
 class DashboardEventView(DetailView):
+    """
+    Dashboard view for a single event
+
+    In addition to the basic information and the buttons,
+    an overview over recent events (new and changed AKs, moved AKSlots) for the given event is shown.
+
+    The event dashboard also exists for non-public events (one only needs to know the URL/slug of the event).
+    """
     template_name = 'AKDashboard/dashboard_event.html'
     context_object_name = 'event'
     model = Event
@@ -32,11 +44,16 @@ class DashboardEventView(DetailView):
 
         # Show feed of recent changes (if activated)
         if settings.DASHBOARD_SHOW_RECENT:
+            # Create a list of chronically sorted events (both AK and plan changes):
             recent_changes = []
 
-            # Newest AKs
+            # Newest AKs (if AKSubmission is used)
             if apps.is_installed("AKSubmission"):
-                submission_changes = AK.history.filter(event=context['event'])[:int(settings.DASHBOARD_RECENT_MAX)]
+                # Get the latest x changes (if there are that many),
+                # where x corresponds to the entry threshold configured in the settings
+                # (such that the list will be completely filled even if there are no (newer) plan changes)
+                submission_changes = AK.history.filter(event=context['event'])[:int(settings.DASHBOARD_RECENT_MAX)] # pylint: disable=no-member, line-too-long
+                # Create textual representation including icons
                 for s in submission_changes:
                     if s.history_type == '+':
                         text = _('New AK: %(ak)s.') % {'ak': s.name}
@@ -48,18 +65,21 @@ class DashboardEventView(DetailView):
                         text = _('AK "%(ak)s" deleted.') % {'ak': s.name}
                         icon = ('times', 'fas')
 
-                    recent_changes.append({'icon': icon, 'text': text, 'link': s.instance.detail_url, 'timestamp': s.history_date})
-
-            # Changes in plan
-            if apps.is_installed("AKPlan"):
-                if not context['event'].plan_hidden:
-                    last_changed_slots = AKSlot.objects.select_related('ak').filter(event=context['event'], start__isnull=False).order_by('-updated')[
-                                         :int(settings.DASHBOARD_RECENT_MAX)]
-                    for changed_slot in last_changed_slots:
-                        recent_changes.append({'icon': ('clock', 'far'),
-                                               'text': _('AK "%(ak)s" (re-)scheduled.') % {'ak': changed_slot.ak.name},
-                                               'link': changed_slot.ak.detail_url,
-                                               'timestamp': changed_slot.updated})
+                    # Store representation in change list (still unsorted)
+                    recent_changes.append(
+                        {'icon': icon, 'text': text, 'link': s.instance.detail_url, 'timestamp': s.history_date}
+                    )
+
+            # Changes in plan (if AKPlan is used and plan is publicly visible)
+            if apps.is_installed("AKPlan") and not context['event'].plan_hidden:
+                # Get the latest plan changes (again using a threshold, see above)
+                last_changed_slots = AKSlot.objects.select_related('ak').filter(event=context['event'], start__isnull=False).order_by('-updated')[:int(settings.DASHBOARD_RECENT_MAX)] #pylint: disable=line-too-long
+                for changed_slot in last_changed_slots:
+                    # Create textual representation including icons and links and store in list (still unsorted)
+                    recent_changes.append({'icon': ('clock', 'far'),
+                                           'text': _('AK "%(ak)s" (re-)scheduled.') % {'ak': changed_slot.ak.name},
+                                           'link': changed_slot.ak.detail_url,
+                                           'timestamp': changed_slot.updated})
 
             # Sort by change date...
             recent_changes.sort(key=lambda x: x['timestamp'], reverse=True)
-- 
GitLab