Commit db42d716 by Bach Dániel

Merge branch 'notifications-enhancement'

Conflicts:
	circle/dashboard/static/dashboard/dashboard.less
parents 79e445c6 111d424d
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
"jquery-knob": "~1.2.9", "jquery-knob": "~1.2.9",
"jquery-simple-slider": "https://github.com/BME-IK/jquery-simple-slider.git", "jquery-simple-slider": "https://github.com/BME-IK/jquery-simple-slider.git",
"bootbox": "~4.3.0", "bootbox": "~4.3.0",
"intro.js": "0.9.0" "intro.js": "0.9.0",
"favico.js": "~0.3.5"
} }
} }
...@@ -197,6 +197,7 @@ PIPELINE_JS = { ...@@ -197,6 +197,7 @@ PIPELINE_JS = {
"intro.js/intro.js", "intro.js/intro.js",
"jquery-knob/dist/jquery.knob.min.js", "jquery-knob/dist/jquery.knob.min.js",
"jquery-simple-slider/js/simple-slider.js", "jquery-simple-slider/js/simple-slider.js",
"favico.js/favico.js",
"dashboard/dashboard.js", "dashboard/dashboard.js",
"dashboard/activity.js", "dashboard/activity.js",
"dashboard/group-details.js", "dashboard/group-details.js",
......
...@@ -31,6 +31,7 @@ from django.db.models import ( ...@@ -31,6 +31,7 @@ from django.db.models import (
) )
from django.db.models.signals import post_save, pre_delete, post_delete from django.db.models.signals import post_save, pre_delete, post_delete
from django.templatetags.static import static from django.templatetags.static import static
from django.utils.html import escape
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django_sshkey.models import UserKey from django_sshkey.models import UserKey
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
...@@ -87,7 +88,8 @@ class Notification(TimeStampedModel): ...@@ -87,7 +88,8 @@ class Notification(TimeStampedModel):
@property @property
def subject(self): def subject(self):
return HumanReadableObject.from_dict(self.subject_data) return HumanReadableObject.from_dict(
self.escape_dict(self.subject_data))
@subject.setter @subject.setter
def subject(self, value): def subject(self, value):
...@@ -95,7 +97,14 @@ class Notification(TimeStampedModel): ...@@ -95,7 +97,14 @@ class Notification(TimeStampedModel):
@property @property
def message(self): def message(self):
return HumanReadableObject.from_dict(self.message_data) return HumanReadableObject.from_dict(
self.escape_dict(self.message_data))
def escape_dict(self, data):
for k, v in data['params'].items():
if isinstance(v, basestring):
data['params'][k] = escape(v)
return data
@message.setter @message.setter
def message(self, value): def message(self, value):
......
$(function () { $(function () {
var favicon= new Favico({
animation:'none'
});
var notifications = $("#notification_count").data("notifications");
if(notifications)
favicon.badge(notifications);
$(".not-tab-pane").removeClass("not-tab-pane").addClass("tab-pane"); $(".not-tab-pane").removeClass("not-tab-pane").addClass("tab-pane");
$('.vm-create').click(function(e) { $('.vm-create').click(function(e) {
...@@ -314,6 +322,8 @@ $(function () { ...@@ -314,6 +322,8 @@ $(function () {
$("#notification-button a").click(function() { $("#notification-button a").click(function() {
$('#notification-messages').load("/dashboard/notifications/"); $('#notification-messages').load("/dashboard/notifications/");
$('#notification-button a span[class*="badge-pulse"]').remove(); $('#notification-button a span[class*="badge-pulse"]').remove();
favicon.reset();
}); });
/* on the client confirmation button fire the clientInstalledAction */ /* on the client confirmation button fire the clientInstalledAction */
...@@ -352,7 +362,6 @@ $(function () { ...@@ -352,7 +362,6 @@ $(function () {
li.addClass('panel-primary').find('input').prop("checked", true); li.addClass('panel-primary').find('input').prop("checked", true);
return true; return true;
}); });
}); });
function generateVmHTML(pk, name, host, icon, _status, fav, is_last) { function generateVmHTML(pk, name, host, icon, _status, fav, is_last) {
......
...@@ -1195,3 +1195,25 @@ textarea[name="new_members"] { ...@@ -1195,3 +1195,25 @@ textarea[name="new_members"] {
padding-left: 0px; padding-left: 0px;
} }
} }
#notifications-upper-pagination {
margin-top: 4px;
}
#notifications-bottom-pagination {
* {
display: inline-block;
}
a {
font-size: 20px;
&:hover {
text-decoration: none;
}
}
.page-numbers {
padding: 25px;
}
}
{% load i18n %} {% load i18n %}
{% load hro %} {% load hro %}
{% for n in notifications %} {% for n in page %}
<li class="notification-message" id="msg-{{n.id}}"> <li class="notification-message" id="msg-{{n.id}}">
<span class="notification-message-subject"> <span class="notification-message-subject">
{% if n.status == "new" %}<i class="fa fa-envelope-o"></i> {% endif %} {% if n.status == "new" %}<i class="fa fa-envelope-o"></i> {% endif %}
......
...@@ -48,10 +48,13 @@ ...@@ -48,10 +48,13 @@
</li> </li>
<li class="dropdown hidden-xs" id="notification-button"> <li class="dropdown hidden-xs" id="notification-button">
<a href="{% url "dashboard.views.notifications" %}" <a href="{% url "dashboard.views.notifications" %}"
class="dropdown-toggle" data-toggle="dropdown"> class="dropdown-toggle" data-toggle="dropdown"
id="notification_count" data-notifications="{{ NEW_NOTIFICATIONS_COUNT }}">
{% trans "Notifications" %} {% trans "Notifications" %}
{% if NEW_NOTIFICATIONS_COUNT > 0 %} {% if NEW_NOTIFICATIONS_COUNT > 0 %}
<span class="badge badge-pulse">{{ NEW_NOTIFICATIONS_COUNT }}</span> <span class="badge badge-pulse">
{{ NEW_NOTIFICATIONS_COUNT }}
</span>
{% endif %} {% endif %}
</a> </a>
<ul class="dropdown-menu" id="notification-messages"> <ul class="dropdown-menu" id="notification-messages">
......
...@@ -6,6 +6,18 @@ ...@@ -6,6 +6,18 @@
<div class="col-md-12"> <div class="col-md-12">
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<div id="notifications-upper-pagination" class="pull-right">
{% if page.has_previous %}
<a href="?page={{ page.previous_page_number }}">
<i class="fa fa-chevron-left"></i></a>
</a>
{% endif %}
{{ page.number }} / {{ paginator.num_pages }}
{% if page.has_next %}
<a href="?page={{ page.next_page_number }}"><i class="fa fa-chevron-right"></i></a>
{% endif %}
</div>
<h3 class="no-margin"><i class="fa fa-desktop"></i> {% trans "Notifications" %}</h3> <h3 class="no-margin"><i class="fa fa-desktop"></i> {% trans "Notifications" %}</h3>
</div> </div>
<div class="panel-body"> <div class="panel-body">
...@@ -13,6 +25,29 @@ ...@@ -13,6 +25,29 @@
{% include "dashboard/_notifications-timeline.html" %} {% include "dashboard/_notifications-timeline.html" %}
</ul> </ul>
</div> </div>
<div class="panel-body text-center" id="notifications-bottom-pagination">
{% if page.has_previous %}
<a href="?page=1">
<i class="fa fa-angle-double-left"></i>
</a>
<a href="{% if page.has_previous %}?page={{ page.previous_page_number}}{% else %}#{% endif %}">
<i class="fa fa-angle-left"></i>
</a>
{% endif %}
<div class="page-numbers">
{{ page.number }} / {{ paginator.num_pages }}
</div>
{% if page.has_next %}
<a href="{% if page.has_next %}?page={{ page.next_page_number}}{% else %}#{% endif %}">
<i class="fa fa-angle-right"></i>
</a>
<a href="?page={{ paginator.num_pages }}">
<i class="fa fa-angle-double-right"></i>
</a>
{% endif %}
</div>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -30,6 +30,7 @@ from django.core.exceptions import ( ...@@ -30,6 +30,7 @@ from django.core.exceptions import (
PermissionDenied, SuspiciousOperation, PermissionDenied, SuspiciousOperation,
) )
from django.core.urlresolvers import reverse, reverse_lazy from django.core.urlresolvers import reverse, reverse_lazy
from django.core.paginator import Paginator, InvalidPage
from django.http import HttpResponse, HttpResponseRedirect, Http404 from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import redirect, get_object_or_404 from django.shortcuts import redirect, get_object_or_404
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
...@@ -67,9 +68,18 @@ class NotificationView(LoginRequiredMixin, TemplateView): ...@@ -67,9 +68,18 @@ class NotificationView(LoginRequiredMixin, TemplateView):
def get_context_data(self, *args, **kwargs): def get_context_data(self, *args, **kwargs):
context = super(NotificationView, self).get_context_data( context = super(NotificationView, self).get_context_data(
*args, **kwargs) *args, **kwargs)
n = 10 if self.request.is_ajax() else 1000 paginate_by = 10 if self.request.is_ajax() else 25
context['notifications'] = list( page = self.request.GET.get("page", 1)
self.request.user.notification_set.all()[:n])
notifications = self.request.user.notification_set.all()
paginator = Paginator(notifications, paginate_by)
try:
current_page = paginator.page(page)
except InvalidPage:
current_page = paginator.page(1)
context['page'] = current_page
context['paginator'] = paginator
return context return context
def get(self, *args, **kwargs): def get(self, *args, **kwargs):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment