diff --git a/data/model.py b/data/model.py
index 9eec9f841..99e3e52f7 100644
--- a/data/model.py
+++ b/data/model.py
@@ -1566,4 +1566,4 @@ def list_notifications(user, kind=None):
def delete_notifications_by_kind(user, kind):
kind_ref = NotificationKind.get(name=kind)
- Notification.delete().where(Notification.user == user, Notification.kind == kind_ref).execute()
+ Notification.delete().where(Notification.notification_user == user, Notification.kind == kind_ref).execute()
diff --git a/initdb.py b/initdb.py
index 561d98992..78f694f67 100644
--- a/initdb.py
+++ b/initdb.py
@@ -266,6 +266,9 @@ def populate_database():
new_user_4.verified = True
new_user_4.save()
+ new_user_5 = model.create_user('unverified', 'password', 'no5@thanks.com')
+ new_user_5.save()
+
reader = model.create_user('reader', 'password', 'no1@thanks.com')
reader.verified = True
reader.save()
diff --git a/static/css/quay.css b/static/css/quay.css
index dc80d0608..f706a8c5e 100644
--- a/static/css/quay.css
+++ b/static/css/quay.css
@@ -9,6 +9,43 @@
}
}
+.notification-view-element {
+ cursor: pointer;
+ margin-bottom: 10px;
+ border-bottom: 1px solid #eee;
+ padding-bottom: 10px;
+ position: relative;
+ max-width: 320px;
+}
+
+.notification-view-element .circle {
+ position: absolute;
+ top: 14px;
+ left: 0px;
+
+ width: 12px;
+ height: 12px;
+ display: inline-block;
+ border-radius: 50%;
+}
+
+.notification-view-element .datetime {
+ margin-top: 10px;
+ font-size: 12px;
+ color: #aaa;
+ text-align: right;
+}
+
+.notification-view-element .container {
+ padding: 10px;
+ border-radius: 6px;
+ margin-left: 16px;
+}
+
+.notification-view-element .container:hover {
+ background: rgba(66, 139, 202, 0.1);
+}
+
.dockerfile-path {
margin-top: 10px;
padding: 20px;
@@ -507,22 +544,22 @@ i.toggle-icon:hover {
min-width: 200px;
}
-.user-notification.notification-primary {
+.notification-primary {
background: #428bca;
color: white;
}
-.user-notification.notification-info {
+.notification-info {
color: black;
background: #d9edf7;
}
-.user-notification.notification-warning {
+.notification-warning {
color: #8a6d3b;
background: #fcf8e3;
}
-.user-notification.notification-error {
+.notification-error {
background: red;
}
diff --git a/static/directives/notification-bar.html b/static/directives/notification-bar.html
index f0f5f3363..5d25a40b4 100644
--- a/static/directives/notification-bar.html
+++ b/static/directives/notification-bar.html
@@ -3,12 +3,13 @@
diff --git a/static/directives/notification-view.html b/static/directives/notification-view.html
new file mode 100644
index 000000000..6d5751995
--- /dev/null
+++ b/static/directives/notification-view.html
@@ -0,0 +1,7 @@
+
+
+
{{ getMessage(notification) }}
+
{{ parseDate(notification.created) | date:'medium'}}
+
+
+
diff --git a/static/js/app.js b/static/js/app.js
index 63fd27024..acf97b97d 100644
--- a/static/js/app.js
+++ b/static/js/app.js
@@ -494,10 +494,26 @@ quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'angu
'test_notification': {
'level': 'primary',
'summary': 'This is a test notification',
- 'message': 'This notification is a long message for testing'
+ 'message': 'This notification is a long message for testing',
+ 'page': '/about/'
+ },
+ 'password_required': {
+ 'level': 'error',
+ 'summary': 'A password is needed for your account',
+ 'message': 'In order to begin pushing and pulling repositories to Quay.io, a password must be set for your account',
+ 'page': '/user?tab=password'
}
};
+ notificationService.getPage = function(notification) {
+ return notificationKinds[notification['kind']]['page'];
+ };
+
+ notificationService.getMessage = function(notification) {
+ var kindInfo = notificationKinds[notification['kind']];
+ return StringBuilderService.buildString(kindInfo['message'], notification['metadata']);
+ };
+
notificationService.getSummary = function(notification) {
var kindInfo = notificationKinds[notification['kind']];
return StringBuilderService.buildString(kindInfo['summary'], notification['metadata']);
@@ -512,16 +528,25 @@ quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'angu
return summaries.join('
');
};
+ notificationService.getClass = function(notification) {
+ return 'notification-' + notificationKinds[notification['kind']]['level'];
+ };
+
notificationService.getClasses = function(notifications) {
var classes = [];
for (var i = 0; i < notifications.length; ++i) {
var notification = notifications[i];
- classes.push('notification-' + notificationKinds[notification['kind']]['level']);
+ classes.push(notificationService.getClass(notification));
}
return classes.join(' ');
};
notificationService.update = function() {
+ var user = UserService.currentUser();
+ if (!user || user.anonymous) {
+ return;
+ }
+
ApiService.listUserNotifications().then(function(resp) {
notificationService.notifications = resp['notifications'];
notificationService.notificationClasses = notificationService.getClasses(notificationService.notifications);
@@ -3320,6 +3345,49 @@ quayApp.directive('buildProgress', function () {
});
+quayApp.directive('notificationView', function () {
+ var directiveDefinitionObject = {
+ priority: 0,
+ templateUrl: '/static/directives/notification-view.html',
+ replace: false,
+ transclude: false,
+ restrict: 'C',
+ scope: {
+ 'notification': '=notification',
+ 'parent': '=parent'
+ },
+ controller: function($scope, $element, $location, NotificationService) {
+ $scope.getMessage = function(notification) {
+ return NotificationService.getMessage(notification);
+ };
+
+ $scope.parseDate = function(dateString) {
+ return Date.parse(dateString);
+ };
+
+ $scope.showNotification = function() {
+ var url = NotificationService.getPage($scope.notification);
+ if (url) {
+ var parts = url.split('?')
+ $location.path(parts[0]);
+
+ if (parts.length > 1) {
+ $location.search(parts[1]);
+ }
+
+ $scope.parent.$hide();
+ }
+ };
+
+ $scope.getClass = function(notification) {
+ return NotificationService.getClass(notification);
+ };
+ }
+ };
+ return directiveDefinitionObject;
+});
+
+
quayApp.directive('dockerfileBuildDialog', function () {
var directiveDefinitionObject = {
priority: 0,
diff --git a/test/data/test.db b/test/data/test.db
index dd1b56708..168be98ba 100644
Binary files a/test/data/test.db and b/test/data/test.db differ