/** * Service which defines the supported kinds of application notifications (those items that appear * in the sidebar) and provides helper methods for working with them. */ angular.module('quay').factory('NotificationService', ['$rootScope', '$interval', 'UserService', 'ApiService', 'StringBuilderService', 'PlanService', 'UserService', 'Config', '$location', function($rootScope, $interval, UserService, ApiService, StringBuilderService, PlanService, UserService, Config, $location) { var notificationService = { 'user': null, 'notifications': [], 'notificationClasses': [], 'notificationSummaries': [], 'additionalNotifications': false }; var pollTimerHandle = null; var notificationKinds = { 'test_notification': { 'level': 'primary', 'message': 'This notification is a long message for testing: {obj}', 'page': '/about/', 'dismissable': true }, 'org_team_invite': { 'level': 'primary', 'message': '{inviter} is inviting you to join team {team} under organization {org}', 'actions': [ { 'title': 'Join team', 'kind': 'primary', 'handler': function(notification) { window.location = '/confirminvite?code=' + notification.metadata['code']; } }, { 'title': 'Decline', 'kind': 'default', 'handler': function(notification) { ApiService.declineOrganizationTeamInvite(null, {'code': notification.metadata['code']}).then(function() { notificationService.update(); }); } } ] }, 'password_required': { 'level': 'error', 'message': 'In order to begin pushing and pulling repositories, a password must be set for your account', 'page': '/user?tab=password' }, 'over_private_usage': { 'level': 'error', 'message': 'Namespace {namespace} is over its allowed private repository count. ' + '

Please upgrade your plan to avoid disruptions in service.', 'page': function(metadata) { var organization = UserService.getOrganization(metadata['namespace']); if (organization) { return '/organization/' + metadata['namespace'] + '?tab=billing'; } else { return '/user/' + metadata['namespace'] + '?tab=billing'; } } }, 'expiring_license': { 'level': 'error', 'message': 'Your license will expire at: {expires_at} ' + '

Please contact support to purchase a new license.', 'page': '/contact/' }, 'maintenance': { 'level': 'warning', 'message': 'We will be down for schedule maintenance from {from_date} to {to_date} ' + 'for {reason}. We are sorry about any inconvenience.', 'page': 'http://status.quay.io/' }, 'repo_push': { 'level': 'info', 'message': function(metadata) { if (metadata.updated_tags && Object.getOwnPropertyNames(metadata.updated_tags).length) { return 'Repository {repository} has been pushed with the following tags updated: {updated_tags}'; } else { return 'Repository {repository} fhas been pushed'; } }, 'page': function(metadata) { return '/repository/' + metadata.repository; }, 'dismissable': true }, 'build_queued': { 'level': 'info', 'message': 'A build has been queued for repository {repository}', 'page': function(metadata) { return '/repository/' + metadata.repository + '/build?current=' + metadata.build_id; }, 'dismissable': true }, 'build_start': { 'level': 'info', 'message': 'A build has been started for repository {repository}', 'page': function(metadata) { return '/repository/' + metadata.repository + '/build?current=' + metadata.build_id; }, 'dismissable': true }, 'build_success': { 'level': 'info', 'message': 'A build has succeeded for repository {repository}', 'page': function(metadata) { return '/repository/' + metadata.repository + '/build?current=' + metadata.build_id; }, 'dismissable': true }, 'build_failure': { 'level': 'error', 'message': 'A build has failed for repository {repository}', 'page': function(metadata) { return '/repository/' + metadata.repository + '/build?current=' + metadata.build_id; }, 'dismissable': true } }; notificationService.dismissNotification = function(notification) { notification.dismissed = true; var params = { 'uuid': notification.id }; ApiService.updateUserNotification(notification, params, function() { notificationService.update(); }, ApiService.errorDisplay('Could not update notification')); var index = $.inArray(notification, notificationService.notifications); if (index >= 0) { notificationService.notifications.splice(index, 1); } }; notificationService.getActions = function(notification) { var kindInfo = notificationKinds[notification['kind']]; if (!kindInfo) { return []; } return kindInfo['actions'] || []; }; notificationService.canDismiss = function(notification) { var kindInfo = notificationKinds[notification['kind']]; if (!kindInfo) { return false; } return !!kindInfo['dismissable']; }; notificationService.getPage = function(notification) { var kindInfo = notificationKinds[notification['kind']]; if (!kindInfo) { return null; } var page = kindInfo['page']; if (page != null && typeof page != 'string') { page = page(notification['metadata']); } return page || ''; }; notificationService.getMessage = function(notification) { var kindInfo = notificationKinds[notification['kind']]; if (!kindInfo) { return '(Unknown notification kind: ' + notification['kind'] + ')'; } return StringBuilderService.buildTrustedString(kindInfo['message'], notification['metadata']); }; notificationService.getClass = function(notification) { var kindInfo = notificationKinds[notification['kind']]; if (!kindInfo) { return 'notification-info'; } return 'notification-' + kindInfo['level']; }; notificationService.getClasses = function(notifications) { if (!notifications.length) { return ''; } var classes = []; for (var i = 0; i < notifications.length; ++i) { var notification = notifications[i]; 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.additionalNotifications = resp['additional']; notificationService.notificationClasses = notificationService.getClasses(notificationService.notifications); }); }; notificationService.reset = function() { $interval.cancel(pollTimerHandle); pollTimerHandle = $interval(notificationService.update, 5 * 60 * 1000 /* five minutes */); }; // Watch for plan changes and update. PlanService.registerListener(this, function(plan) { notificationService.reset(); notificationService.update(); }); // Watch for user changes and update. $rootScope.$watch(function() { return UserService.currentUser(); }, function(currentUser) { notificationService.reset(); notificationService.update(); }); return notificationService; }]);