summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/booking/quick_deployer.py2
-rw-r--r--src/notifier/manager.py4
-rw-r--r--src/notifier/migrations/0003_auto_20190123_1741.py23
-rw-r--r--src/notifier/migrations/0004_auto_20190124_2115.py23
-rw-r--r--src/notifier/models.py4
-rw-r--r--src/notifier/views.py39
-rw-r--r--src/templates/notifier/inbox.html34
-rw-r--r--src/templates/notifier/notification.html65
-rw-r--r--src/templates/workflow/viewport-base.html1
9 files changed, 165 insertions, 30 deletions
diff --git a/src/booking/quick_deployer.py b/src/booking/quick_deployer.py
index d838de9..7946ebf 100644
--- a/src/booking/quick_deployer.py
+++ b/src/booking/quick_deployer.py
@@ -33,6 +33,7 @@ from resource_inventory.models import (
OPNFVConfig
)
from resource_inventory.resource_manager import ResourceManager
+from notifier.manager import NotificationHandler
from booking.models import Booking
from dashboard.exceptions import (
InvalidHostnameException,
@@ -241,6 +242,7 @@ def create_from_form(form, request):
# generate job
JobFactory.makeCompleteJob(booking)
+ NotificationHandler.notify_new_booking(booking)
def drop_filter(user):
diff --git a/src/notifier/manager.py b/src/notifier/manager.py
index f03c2cc..240cf85 100644
--- a/src/notifier/manager.py
+++ b/src/notifier/manager.py
@@ -18,13 +18,13 @@ class NotificationHandler(object):
@classmethod
def notify_new_booking(cls, booking):
template = "notifier/new_booking.html"
- titles = ["You have a new Booking", "You have been added to a Booking"]
+ titles = ["You have a new booking (" + str(booking.id) + ")", "You have been added to a booking (" + str(booking.id) + ")"]
cls.booking_notify(booking, template, titles)
@classmethod
def notify_booking_end(cls, booking):
template = "notifier/end_booking.html"
- titles = ["Your booking has ended", "A booking you collaborate on has ended"]
+ titles = ["Your booking (" + str(booking.id) + ") has ended", "A booking (" + str(booking.id) + ") that you collaborate on has ended"]
cls.booking_notify(booking, template, titles)
@classmethod
diff --git a/src/notifier/migrations/0003_auto_20190123_1741.py b/src/notifier/migrations/0003_auto_20190123_1741.py
new file mode 100644
index 0000000..f491993
--- /dev/null
+++ b/src/notifier/migrations/0003_auto_20190123_1741.py
@@ -0,0 +1,23 @@
+# Generated by Django 2.1 on 2019-01-23 17:41
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('notifier', '0002_auto_20181102_1631'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='notification',
+ name='is_html',
+ field=models.BooleanField(default=True),
+ ),
+ migrations.AddField(
+ model_name='notification',
+ name='is_read',
+ field=models.BooleanField(default=True),
+ ),
+ ]
diff --git a/src/notifier/migrations/0004_auto_20190124_2115.py b/src/notifier/migrations/0004_auto_20190124_2115.py
new file mode 100644
index 0000000..306ec7b
--- /dev/null
+++ b/src/notifier/migrations/0004_auto_20190124_2115.py
@@ -0,0 +1,23 @@
+# Generated by Django 2.1 on 2019-01-24 21:15
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('account', '0003_publicnetwork'),
+ ('notifier', '0003_auto_20190123_1741'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='notification',
+ name='is_read',
+ ),
+ migrations.AddField(
+ model_name='notification',
+ name='read_by',
+ field=models.ManyToManyField(related_name='read_notifications', to='account.UserProfile'),
+ ),
+ ]
diff --git a/src/notifier/models.py b/src/notifier/models.py
index 5e7c60e..49189e8 100644
--- a/src/notifier/models.py
+++ b/src/notifier/models.py
@@ -14,7 +14,9 @@ from account.models import UserProfile
class Notification(models.Model):
title = models.CharField(max_length=150)
content = models.TextField()
- recipients = models.ManyToManyField(UserProfile)
+ recipients = models.ManyToManyField(UserProfile, related_name='notifications')
+ is_html = models.BooleanField(default=True)
+ read_by = models.ManyToManyField(UserProfile, related_name='read_notifications')
def __str__(self):
return self.title
diff --git a/src/notifier/views.py b/src/notifier/views.py
index 4ee757f..3a85eda 100644
--- a/src/notifier/views.py
+++ b/src/notifier/views.py
@@ -7,27 +7,52 @@
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-from notifier.models import Notification
from django.shortcuts import render
+from notifier.models import Notification
+from django.db.models import Q
def InboxView(request):
if request.user.is_authenticated:
user = request.user
else:
- return render(request, "dashboard/login.html", {'title': 'Authentication Required'})
+ return render(request, "dashboard/login.html",
+ {'title': 'Authentication Required'})
- return render(request, "notifier/inbox.html", {'notifications': Notification.objects.filter(recipients=user.userprofile)})
+ return render(request,
+ "notifier/inbox.html",
+ {'unread_notifications': Notification.objects.filter(recipients=user.userprofile).order_by('-id').filter(~Q(read_by=user.userprofile)),
+ 'read_notifications': Notification.objects.filter(recipients=user.userprofile).order_by('-id').filter(read_by=user.userprofile)})
def NotificationView(request, notification_id):
+
if request.user.is_authenticated:
user = request.user
else:
- return render(request, "dashboard/login.html", {'title': 'Authentication Required'})
+ return render(request,
+ "dashboard/login.html",
+ {'title': 'Authentication Required'})
notification = Notification.objects.get(id=notification_id)
if user.userprofile not in notification.recipients.all():
- return render(request, "dashboard/login.html", {'title': 'Access Denied'})
-
- return render(request, "notifier/notification.html", {'notification': notification})
+ return render(request,
+ "dashboard/login.html", {'title': 'Access Denied'})
+
+ notification.read_by.add(user.userprofile)
+ notification.save()
+ if request.method == 'POST':
+ if 'delete' in request.POST:
+ # handle deleting
+ notification.recipients.remove(user.userprofile)
+ if not notification.recipients.exists():
+ notification.delete()
+ else:
+ notification.save()
+
+ if 'unread' in request.POST:
+ notification.read_by.remove(user.userprofile)
+ notification.save()
+
+ return render(request,
+ "notifier/notification.html", {'notification': notification})
diff --git a/src/templates/notifier/inbox.html b/src/templates/notifier/inbox.html
index 471eae4..4184d1d 100644
--- a/src/templates/notifier/inbox.html
+++ b/src/templates/notifier/inbox.html
@@ -9,7 +9,7 @@
.inbox-panel {
display: grid;
- grid-template-columns: 30% 70%;
+ grid-template-columns: 30% 5% 65%;
}
.section-panel {
@@ -22,7 +22,8 @@
}
.card-container {
- box-shadow: 0 0 5px 2px #cccccc;
+ border: 1px solid #cccccc;
+ border-bottom: 0px;
}
.card {
height: 50px;
@@ -43,7 +44,7 @@
}
#inbox-iframe {
- height: calc(100vh - 130px);
+ height: calc(100vh - 57px);
}
.half_width {
@@ -51,29 +52,45 @@
}
.card-wrapper {
}
+
+ #page-wrapper{
+ padding: 0px;
+ }
+
+ .read_notification{
+ background-color: #efefef;
+ }
</style>
<div class="inbox-panel">
<div class="section-panel">
+ <h4>New:</h4>
<div class="card-container">
- {% for notification in notifications %}
+ {% for notification in unread_notifications %}
<div class="inbox-entry card" onclick="showmessage({{notification.id}}); setactive(this);">
{{ notification }}
</div>
{% endfor %}
</div>
+ <h4>Read:</h4>
+ <div class="card-container">
+ {% for notification in read_notifications %}
+ <div class="inbox-entry card read_notification" onclick="showmessage({{notification.id}}); setactive(this);">
+ {{ notification }}
+ </div>
+ {% endfor %}
+ </div>
+ </div>
+ <div>
</div>
<div class="iframe-panel inbox-expanded-view">
<div class="inbox-iframe-div">
- <iframe id="inbox-iframe" frameBorder="0" width="100%" height="100vh" scrolling="yes" onload="sizetoiframe(this);">Please select a notification</iframe>
+ <iframe id="inbox-iframe" frameBorder="0" width="100%" height="100vh" scrolling="yes">Please select a notification</iframe>
</div>
</div>
</div>
<script type="text/javascript">
- $('#inbox-iframe').load(function() {
- sizetoiframe(this);
- })
function showmessage(msg_id)
{
@@ -82,5 +99,4 @@
}
</script>
-
{% endblock %}
diff --git a/src/templates/notifier/notification.html b/src/templates/notifier/notification.html
index 65d26c9..0eafa60 100644
--- a/src/templates/notifier/notification.html
+++ b/src/templates/notifier/notification.html
@@ -2,19 +2,55 @@
{% block extrahead %}
<base target="_parent">
{% endblock %}
+
{% block basecontent %}
-<div class="card-container">
-<h3 class="msg_header">{{notification.title}}</h3>
-<p class="content"></p>
-<pre>
-{{notification.content|safe}}
-</pre>
+<script>
+ function send_request(post_data){
+ var form = $("#notification_action_form");
+ var formData = form.serialize() + '&' + post_data + '=true';
+ var req = new XMLHttpRequest();
+ req.open("POST", ".", false);
+ req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
+ req.onerror = function() { alert("problem occurred while trying to cancel current workflow"); }
+ req.onreadystatechange = function() { if(req.readyState === 4){
+ window.top.location.href += '';
+ }};
+ req.send(formData);
+ }
+ function delete_notification()
+ {
+ send_request("delete");
+ }
+ function mark_unread()
+ {
+ send_request("unread");
+ }
+</script>
+<div>
+ <h3 class="msg_header">{{notification.title}}
+ <div class="btn_group">
+ <button class="btn btn-primary inbox-btn" onclick="mark_unread()">Mark Unread</button>
+ <button class="btn btn-danger inbox-btn" onclick="delete_notification()">Delete</button>
+ </div>
+ </h3>
</div>
+<p class="content-divider"></p>
+
+{% if not notification.is_html %}
+<pre>
+{% endif %}
+ {{notification.content|safe}}
+{% if not notification.is_html %}
+</pre>
+{% endif %}
+<form id="notification_action_form" action="." method="post">
+ {% csrf_token %}
+</form>
+
<style media="screen">
.card-container {
- box-shadow: 0 0 5px 2px #cccccc;
border: 1px solid #ffffff;
margin-top: 11px;
}
@@ -28,11 +64,20 @@
background-color: #ffffff;
z-index: 5;
}
-
.sender {
color: #636363;
}
-
-
+ .content-divider {
+ border-bottom: 1px solid #cccccc;
+ padding-bottom: 15px;
+ clear: right;
+ }
+ .inbox-btn{
+ display: inline;
+ margin: 3px;
+ }
+ .btn_group{
+ float: right;
+ }
</style>
{% endblock %}
diff --git a/src/templates/workflow/viewport-base.html b/src/templates/workflow/viewport-base.html
index 9ddb4b8..f78bc01 100644
--- a/src/templates/workflow/viewport-base.html
+++ b/src/templates/workflow/viewport-base.html
@@ -419,7 +419,6 @@
var page_rect = document.getElementById("wrapper").getBoundingClientRect();
var title_rect = document.getElementById("iframe_header").getBoundingClientRect();
var iframe_height = page_rect.bottom - title_rect.bottom;
- console.log("setting height to " + iframe_height);
document.getElementById("viewport-iframe").height = iframe_height;
}