From 8529022f63bb5af3f63a5569788c948a7e71b599 Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa Date: Thu, 30 Jan 2020 13:26:45 -0800 Subject: [PATCH] notification: Show a drop down from main navbar for notifications Closes: #1042. Signed-off-by: Sunil Mohan Adapa Reviewed-by: James Valleroy --- plinth/context_processors.py | 11 ++- plinth/templates/base.html | 12 +++- plinth/templates/notifications-dropdown.html | 36 ++++++++++ plinth/templates/notifications.html | 75 ++++++++++++++++++++ plinth/tests/test_context_processors.py | 8 ++- static/themes/default/css/plinth.css | 74 +++++++++++++++++++ 6 files changed, 210 insertions(+), 6 deletions(-) create mode 100644 plinth/templates/notifications-dropdown.html create mode 100644 plinth/templates/notifications.html diff --git a/plinth/context_processors.py b/plinth/context_processors.py index 3af5d73a0..1b3edfc70 100644 --- a/plinth/context_processors.py +++ b/plinth/context_processors.py @@ -18,9 +18,11 @@ Django context processors to provide common data to templates. """ -from django.utils.translation import ugettext as _, ugettext_noop import re +from django.utils.translation import ugettext as _ +from django.utils.translation import ugettext_noop + from plinth import cfg, menu from plinth.utils import is_user_admin @@ -35,6 +37,9 @@ def common(request): # the brand name 'FreedomBox' itself to be translated. ugettext_noop('FreedomBox') + from plinth.notification import Notification + notifications_context = Notification.get_display_context(user=request.user) + slash_indices = [match.start() for match in re.finditer('/', request.path)] active_menu_urls = [request.path[:index + 1] for index in slash_indices] return { @@ -42,5 +47,7 @@ def common(request): 'submenu': menu.main_menu.active_item(request), 'active_menu_urls': active_menu_urls, 'box_name': _(cfg.box_name), - 'user_is_admin': is_user_admin(request, True) + 'user_is_admin': is_user_admin(request, True), + 'notifications': notifications_context['notifications'], + 'notifications_max_severity': notifications_context['max_severity'] } diff --git a/plinth/templates/base.html b/plinth/templates/base.html index e75df0f3b..74131a205 100644 --- a/plinth/templates/base.html +++ b/plinth/templates/base.html @@ -98,6 +98,11 @@ + + + {% block mainmenu_left %} - + + {% include "notifications.html" %} diff --git a/plinth/templates/notifications-dropdown.html b/plinth/templates/notifications-dropdown.html new file mode 100644 index 000000000..a096fdce4 --- /dev/null +++ b/plinth/templates/notifications-dropdown.html @@ -0,0 +1,36 @@ +{% comment %} +# +# This file is part of FreedomBox. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +{% endcomment %} + +{# Template to display a drop down button for notifications in the navbar #} + +{% load i18n %} + +{% if notifications %} + +{% endif %} diff --git a/plinth/templates/notifications.html b/plinth/templates/notifications.html new file mode 100644 index 000000000..b264131b1 --- /dev/null +++ b/plinth/templates/notifications.html @@ -0,0 +1,75 @@ +{% comment %} +# +# This file is part of FreedomBox. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +{% endcomment %} + +{# Template to display notifications under the navbar #} + +{% load i18n %} +{% load static %} + +{% if notifications %} + +{% endif %} diff --git a/plinth/tests/test_context_processors.py b/plinth/tests/test_context_processors.py index d2782bd0e..0df93bcf2 100644 --- a/plinth/tests/test_context_processors.py +++ b/plinth/tests/test_context_processors.py @@ -18,7 +18,7 @@ Test module for custom context processors. """ -from unittest.mock import MagicMock, Mock +from unittest.mock import MagicMock, Mock, patch import pytest from django.http import HttpRequest @@ -34,7 +34,8 @@ def fixture_menu(): menu_module.init() -def test_common(): +@patch('plinth.notification.Notification') +def test_common(Notification): """Verify that the common() function returns the correct values.""" cfg.read() # initialize config settings @@ -62,7 +63,8 @@ def test_common(): assert response['user_is_admin'] -def test_common_border_conditions(): +@patch('plinth.notification.Notification') +def test_common_border_conditions(Notification): """Verify that the common() function works for border conditions.""" request = HttpRequest() request.path = '' diff --git a/static/themes/default/css/plinth.css b/static/themes/default/css/plinth.css index f9e461b53..6c3808c7e 100644 --- a/static/themes/default/css/plinth.css +++ b/static/themes/default/css/plinth.css @@ -609,3 +609,77 @@ a.menu_link_active { transform: scale(1.2); } } + +/* + * Notifications + */ +.notifications { + margin-left: -15px; + margin-right: -15px; +} + +.notifications .dropdown-menu { + width: 100%; + padding: 0; + float: none; + border-top-left-radius: 0; + border-top-right-radius: 0; + margin-top: 0; +} + +/* Style for individual notification */ +.notification { + padding: 1rem 1.5rem; + font-size: 15px; +} + +.notification:not(:first-child) { + border-top: 1px solid #ddd; +} + +.notification-title { + font-weight: bold; +} + +img.notification-icon { + display: inline-block; + width: 1.4rem; + height: 1.4rem; + margin-top: -0.4rem; +} + +/* Show badge with various colors and overlap it onto icon */ +.notifications-dropdown .badge { + padding: 2px 5px; + margin-left: -12px; + color: #fff; +} + +.badge-exception, .badge-error { + background-color: #d9534f; +} + +.badge-warning { + background-color: #ec971f; +} + +.badge-info, badge-debug { + background-color: #5bc0de; +} + +/* Don't collapse notifications on small screens */ +.collapsing .notifications-dropdown, +.collapse.in .notifications-dropdown { + display: none; +} + +.navbar-header .navbar-nav { + float: right; + margin: 6px 10px; +} + +@media(min-width:768px) { + .navbar-header .navbar-nav { + display: none; + } +}