mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-06-03 10:50:20 +00:00
notification: Show a drop down from main navbar for notifications
Closes: #1042. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
parent
afe179d91d
commit
8529022f63
@ -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']
|
||||
}
|
||||
|
||||
@ -98,6 +98,11 @@
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
|
||||
<ul class="nav navbar-nav">
|
||||
{% include "notifications-dropdown.html" %}
|
||||
</ul>
|
||||
|
||||
{% block mainmenu_left %}
|
||||
<a href="{% url 'index' %}" class="navbar-brand
|
||||
{% if not submenu.url %} menu_link_active {% else %}
|
||||
@ -143,7 +148,11 @@
|
||||
{% block mainmenu_right %}
|
||||
|
||||
{% if user.is_authenticated %}
|
||||
|
||||
{% include "notifications-dropdown.html" %}
|
||||
|
||||
{% include "help-menu.html" %}
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="{% url 'users:edit' request.user.username %}"
|
||||
class="dropdown-toggle" data-toggle="dropdown"
|
||||
@ -215,8 +224,9 @@
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
{% include "notifications.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
36
plinth/templates/notifications-dropdown.html
Normal file
36
plinth/templates/notifications-dropdown.html
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
{% endcomment %}
|
||||
|
||||
{# Template to display a drop down button for notifications in the navbar #}
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
{% if notifications %}
|
||||
<li class="dropdown notifications-dropdown">
|
||||
<a href="#" title="{% trans "Notifications" %}" class="dropdown-toggle"
|
||||
data-toggle="dropdown" role="button" aria-expanded="false"
|
||||
data-target=".notifications">
|
||||
<span class="fa fa-bell nav-icon"></span>
|
||||
<span class="badge badge-{{ notifications_max_severity }}">
|
||||
{{ notifications|length }}
|
||||
</span>
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
75
plinth/templates/notifications.html
Normal file
75
plinth/templates/notifications.html
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
{% endcomment %}
|
||||
|
||||
{# Template to display notifications under the navbar #}
|
||||
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
|
||||
{% if notifications %}
|
||||
<div class="notifications dropdown">
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
{% for note in notifications %}
|
||||
<li class="notification">
|
||||
{% if note.data.app_name %}
|
||||
<div class="app-name">
|
||||
{% if note.data.app_icon %}
|
||||
<div class="app-icon fa {{ note.data.app_icon }}"></div>
|
||||
{% elif note.data.app_icon_filename %}
|
||||
<img src="{% static 'theme/icons/' %}{{ note.data.app_icon_filename }}.svg"
|
||||
alt="{{ note.data.app_name }}"
|
||||
class="notification-icon" />
|
||||
{% endif %}
|
||||
|
||||
{{ note.data.app_name }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if note.body %}
|
||||
{{ note.body.content.decode|safe }}
|
||||
{% else %}
|
||||
<div class="notification-title">{{ note.title }}</div>
|
||||
|
||||
{% if note.message %}
|
||||
<p>{{ note.message }}</p>
|
||||
{% endif %}
|
||||
|
||||
{% if note.actions %}
|
||||
<p>
|
||||
{% for action in note.actions %}
|
||||
{% if action.type == "dismiss" %}
|
||||
<a href="{% url 'notification_dismiss' id=note.id %}?next={{ request.path|iriencode }}"
|
||||
role="button" class="btn btn-default">
|
||||
{% trans "Dismiss" %}
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{% url action.url %}" role="button"
|
||||
class="btn btn-{{ action.class|default:'default' }}">
|
||||
{{ action.text }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
@ -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 = ''
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user