From 5ba3ea2c7e017970f7717786c75457f186b1600b Mon Sep 17 00:00:00 2001
From: Fredrik Jonsson <frjo@xdeb.org>
Date: Thu, 14 Jul 2022 13:29:34 +0200
Subject: [PATCH] Styling adjustments to notification dropdown.

---
 hypha/apply/activity/context_processors.py    |  2 +-
 hypha/apply/activity/models.py                |  4 ++
 .../templates/activity/notifications.html     |  4 +-
 hypha/apply/activity/views.py                 |  2 +-
 .../src/javascript/apply/notifications.js     | 32 +++++----
 .../components/_activity-notifications.scss   | 68 +++++++++----------
 hypha/templates/base-apply.html               | 16 ++---
 7 files changed, 65 insertions(+), 63 deletions(-)

diff --git a/hypha/apply/activity/context_processors.py b/hypha/apply/activity/context_processors.py
index 0a9a62168..975680a3c 100644
--- a/hypha/apply/activity/context_processors.py
+++ b/hypha/apply/activity/context_processors.py
@@ -5,5 +5,5 @@ def notification_context(request):
     context_data = dict()
     if hasattr(request, 'user'):
         if request.user.is_authenticated and request.user.is_apply_staff:
-            context_data['latest_notifications'] = Activity.objects.all().order_by('-timestamp')[:5]
+            context_data['latest_notifications'] = Activity.objects.latest().order_by('-timestamp')[:5]
     return context_data
diff --git a/hypha/apply/activity/models.py b/hypha/apply/activity/models.py
index 2b6c99ff2..99a401004 100644
--- a/hypha/apply/activity/models.py
+++ b/hypha/apply/activity/models.py
@@ -4,6 +4,7 @@ from django.contrib.contenttypes.models import ContentType
 from django.db import models
 from django.db.models import Case, Value, When
 from django.db.models.functions import Concat
+from django.utils import timezone
 
 from .options import MESSAGES
 
@@ -54,6 +55,9 @@ class ActivityQuerySet(BaseActivityQuerySet):
     def actions(self):
         return self.filter(type=ACTION)
 
+    def latest(self):
+        return self.filter(timestamp__gte=(timezone.now() - timezone.timedelta(days=30)))
+
 
 class ActivityBaseManager(models.Manager):
     def create(self, **kwargs):
diff --git a/hypha/apply/activity/templates/activity/notifications.html b/hypha/apply/activity/templates/activity/notifications.html
index bd48329c0..b4b2c26c0 100644
--- a/hypha/apply/activity/templates/activity/notifications.html
+++ b/hypha/apply/activity/templates/activity/notifications.html
@@ -6,8 +6,8 @@
     <div class="admin-bar__inner">
         <div class="admin-bar__inner--with-button">
             <h1 class="gamma heading heading--no-margin heading--bold">{% trans "Notifications" %}</h1>
-            <form class="form notification__filters" method="get">
-                {{ filter.form.as_p }}
+            <form class="form notifications__filters" method="get">
+                {{ filter.form }}
                 <button class="button button--primary" type="submit" value="Filter">{% trans "Filter" %}</button>
             </form>
         </div>
diff --git a/hypha/apply/activity/views.py b/hypha/apply/activity/views.py
index 09253b5ba..0af55e2b5 100644
--- a/hypha/apply/activity/views.py
+++ b/hypha/apply/activity/views.py
@@ -70,7 +70,7 @@ class NotificationsView(ListView):
 
     def get_queryset(self):
         # List only last 30 days' activities
-        queryset = Activity.objects.filter(timestamp__gte=(timezone.now() - timezone.timedelta(days=30)))
+        queryset = Activity.objects.latest()
         self.filterset = self.filterset_class(self.request.GET, queryset=queryset)
         return self.filterset.qs.distinct().order_by('-timestamp')
 
diff --git a/hypha/static_src/src/javascript/apply/notifications.js b/hypha/static_src/src/javascript/apply/notifications.js
index f3e619abd..a24bcd162 100644
--- a/hypha/static_src/src/javascript/apply/notifications.js
+++ b/hypha/static_src/src/javascript/apply/notifications.js
@@ -1,19 +1,21 @@
-function notificationToggle() {
-    'use strict';
-    document.getElementById('notificationDropdown').classList.toggle('show');
-}
+(function () {
 
-// Close the dropdown menu if the user clicks outside of it
-window.onclick = function (event) {
     'use strict';
-    if (!event.target.matches('.dropbtn, .dropbtn *')) {
-        var dropdowns = document.getElementsByClassName('dropdown-content');
-        var i;
-        for (i = 0; i < dropdowns.length; i++) {
-            var openDropdown = dropdowns[i];
-            if (openDropdown.classList.contains('show')) {
-                notificationToggle();
+
+    // Open/close dropdown when users clicks the bell.
+    document.querySelector('.notifications__bell').addEventListener('click', function () {
+        document.querySelector('.notifications__content').classList.toggle('hidden');
+    });
+
+    // Close the dropdown menu if the user clicks outside of it.
+    window.onclick = function (event) {
+        if (!event.target.matches('.notifications--dropdown, .notifications--dropdown *')) {
+            const dropdown = document.querySelector('.notifications__content');
+            if (!dropdown.classList.contains('hidden')) {
+                dropdown.classList.add('hidden');
             }
         }
-    }
-};
+    };
+
+
+})();
diff --git a/hypha/static_src/src/sass/apply/components/_activity-notifications.scss b/hypha/static_src/src/sass/apply/components/_activity-notifications.scss
index b949d7935..74cb4494b 100644
--- a/hypha/static_src/src/sass/apply/components/_activity-notifications.scss
+++ b/hypha/static_src/src/sass/apply/components/_activity-notifications.scss
@@ -1,55 +1,51 @@
-.dropbtn {
-    padding: 7px 12px;
-    cursor: pointer;
-}
-
-.dropdown {
-    position: relative;
-    display: inline-block;
-}
+.notifications {
+    &--dropdown {
+        position: relative;
+        display: inline-block;
+    }
 
-.dropdown-content {
-    display: none;
-    position: absolute;
-    right: 0;
-    font-size: 15px;
-    background-color: $color--light-grey;
-    min-width: 400px;
-    box-shadow: 1px 1px 6px 4px $color--light-mid-grey;
-
-    p {
-        color: $color--black;
-        padding: 0 10px;
-        display: block;
+    &__bell {
+        padding: 7px 12px;
+        cursor: pointer;
     }
-}
 
-.dropdown-item {
-    border-bottom: .1px solid $color--dark-grey;
-}
+    &__content {
+        position: absolute;
+        right: 1em;
+        padding: 1em;
+        margin-top: .5em;
+        background-color: $color--light-grey;
+        min-width: 400px;
+        box-shadow: 2px 2px 6px 1px $color--dark-grey;
+    }
 
-.show-all {
-    text-align: center;
-}
+    &__item {
+        padding-bottom: 1em;
+        border-bottom: 1px solid $color--dark-grey;
+    }
 
-.show {
-    display: block;
-}
+    &__more {
+        text-align: center;
+        font-weight: $weight--semibold;
+    }
 
-.notification {
     &__filters {
         display: flex;
         align-items: center;
         padding: 4px;
         justify-content: space-between;
 
-        p {
-            font-weight: 520;
-            padding-right: 10px;
+        label {
+            font-weight: $weight--semibold;
+            padding-right: 1em;
         }
 
         select {
             padding-right: 1em;
         }
+
+        .form__select {
+            margin-right: 1em;
+        }
     }
 }
diff --git a/hypha/templates/base-apply.html b/hypha/templates/base-apply.html
index f9706cdd2..d3a4bf058 100644
--- a/hypha/templates/base-apply.html
+++ b/hypha/templates/base-apply.html
@@ -30,7 +30,7 @@
         <script src="{% static 'js/jquery.min.js' %}"></script>
         <script src="{% static 'js/js.cookie.min.js' %}"></script>
         <script src="{% static 'js/main-top.js' %}"></script>
-        <script src="{% static 'js/apply/notifications.js' %}"></script>
+        <script defer src="{% static 'js/apply/notifications.js' %}"></script>
         {% if COOKIES_ACCEPTED and MATOMO_URL and MATOMO_SITEID %}
         {# we are only expecting strings, so make sure we escape the values #}
         <script>
@@ -106,21 +106,21 @@
 
                 <div class="header__button-container">
                     {% if latest_notifications %}
-                    <div class="dropdown">
-                        <a href="#" onclick="return notificationToggle()" class=" button--contains-icons dropbtn" aria-haspopup="activity" aria-expanded="false" role="button">
+                    <div class="notifications notifications--dropdown">
+                        <a href="#" class="button button--contains-icons notifications__bell" aria-label="{% trans "Notifications" %}" aria-haspopup="activity" aria-expanded="false" role="button">
                             <svg class="icon"><use xlink:href="#bell-icon"></use></svg>
                         </a>
-                        <div id="notificationDropdown" class="dropdown-content" role="activity">
-                            <p><b>Notifications</b></p>
+                        <div class="notifications__content zeta hidden" role="activity">
+                            <h5>Notifications</h5>
                             {% for notification in latest_notifications %}
-                            <p class="dropdown-item">
-                                <span><b>{{ notification.source_content_type.name|source_type }}</b></span>
+                            <p class="notifications__item">
+                                <strong>{{ notification.source_content_type.name|source_type }} </strong>
                                 <a href="{{ notification.source.get_absolute_url }}">{{ notification.source.title|capfirst|truncatechars:15 }}</a>
                                 : {{ notification.user }} {% ifequal notification.type 'comment' %}made a comment{% else %} {{ notification.message|safe }}
                                 {% if notification.related_object %}<a href="{{ notification.related_object.get_absolute_url }}">{{ notification.related_object|model_verbose_name }}</a>{% endif %}{% endifequal %}
                             </p>
                             {% endfor %}
-                            <p class="show-all"><a href="{% url "activity:notifications" %}">Show All</a></p>
+                            <p class="notifications__more"><a href="{% url "activity:notifications" %}">Show All</a></p>
                         </div>
                     </div>
                     {% endif %}
-- 
GitLab