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 @@
-

Some title

-
-
- +
+
+
+
+
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