From 86ebd5cb524d3609fb2f6ec7422b2bd5c494a112 Mon Sep 17 00:00:00 2001 From: benjaminapetersen Date: Wed, 6 Sep 2017 12:16:13 -0400 Subject: [PATCH] Add internal notifications to notification drawer - previously only a curated list of API Events made it into the drawer - this change catches all "internal events" currently experienced as toasts & brings them into the drawer - future improvement may be to suppress the "toast" for certain internal events so as not to excessively message the user --- .../notifications/notificationCounter.js | 2 +- .../notificationDrawerWrapper.js | 285 ++++++++---------- app/scripts/services/events.js | 23 +- .../notifications/notification-body.html | 51 +++- dist/scripts/scripts.js | 194 ++++++------ dist/scripts/templates.js | 24 +- 6 files changed, 293 insertions(+), 286 deletions(-) diff --git a/app/scripts/directives/notifications/notificationCounter.js b/app/scripts/directives/notifications/notificationCounter.js index 5d32343579..83d26e8577 100644 --- a/app/scripts/directives/notifications/notificationCounter.js +++ b/app/scripts/directives/notifications/notificationCounter.js @@ -32,7 +32,7 @@ if(!projectName) { return; } - notificationListeners.push($rootScope.$on('NotificationDrawerWrapper.count', cb)); + notificationListeners.push($rootScope.$on('NotificationDrawerWrapper.onUnreadNotifications', cb)); }; var deregisterNotificationListeners = function() { diff --git a/app/scripts/directives/notifications/notificationDrawerWrapper.js b/app/scripts/directives/notifications/notificationDrawerWrapper.js index b10f18c721..8a6e4a4ea3 100644 --- a/app/scripts/directives/notifications/notificationDrawerWrapper.js +++ b/app/scripts/directives/notifications/notificationDrawerWrapper.js @@ -16,7 +16,6 @@ '$rootScope', 'Constants', 'DataService', - 'NotificationsService', 'EventsService', NotificationDrawerWrapper ] @@ -31,7 +30,6 @@ $rootScope, Constants, DataService, - NotificationsService, EventsService) { // kill switch if watching events is too expensive @@ -45,23 +43,26 @@ // this one is treated separately from the rootScopeWatches as // it may need to be updated outside of the lifecycle of init/destroy var notificationListener; - // our internal notifications - // var clientGeneratedNotifications = []; - - var eventsWatcher; - var eventsMap = {}; - - // TODO: - // include both Notifications & Events, - // rather than destroying the map each time maintain it & add new items + var apiEventsWatcher; + // data + var apiEventsMap = { + // projName: { events } + }; + var notificationsMap = { + // projName: { notifications } + }; - // final Processed set of notification groups for UI - // IF POSSIBLE, avoid having to convert back to an array. - // var notificationGroupsMap = {}; - var notificationGroups = []; + var projects = {}; + var hideIfNoProject = function(projectName) { + if(!projectName) { + drawer.drawerHidden = true; + } + }; - var projects = {}; + var projectChanged = function(next, current) { + return _.get(next, 'params.project') !== _.get(current, 'params.project'); + }; var getProject = function(projectName) { return DataService @@ -72,99 +73,70 @@ }); }; - var ensureProjectGroupExists = function(groups, projectName) { - if(projectName && !groups[projectName]) { - groups[projectName] = { - heading: $filter('displayName')(projects[projectName]) || projectName, - project: projects[projectName], - notifications: [] - }; - } - }; - - var deregisterEventsWatch = function() { - if(eventsWatcher) { - DataService.unwatch(eventsWatcher); - } - }; - - var watchEvents = function(projectName, cb) { - deregisterEventsWatch(); - if(projectName) { - eventsWatcher = DataService.watch('events', {namespace: projectName}, _.debounce(cb, 400), { skipDigest: true }); - } - }; - - // NotificationService notifications are minimal, they do no necessarily contain projectName info. - // ATM tacking this on via watching the current project. - // var watchNotifications = function(projectName, cb) { - // deregisterNotificationListener(); - // if(!projectName) { - // return; - // } - // notificationListener = $rootScope.$on('NotificationsService.onNotificationAdded', cb); - // }; - - var deregisterNotificationListener = function() { - notificationListener && notificationListener(); - notificationListener = null; + var makeProjectGroup = function(projectName, notifications) { + return { + heading: $filter('displayName')(projects[projectName]), + project: projects[projectName], + notifications: notifications + }; }; var unread = function(notifications) { return _.filter(notifications, 'unread'); }; - // returns a count for each type of notification, example: - // {Normal: 1, Warning: 5} - // TODO: eliminate this $rootScope.$applyAsync, - // there is a quirk here where the values are not picked up the - // first time the function runs, despite the same $applyAsync - // in the render() function - var countUnreadNotificationsForGroup = function(group) { - $rootScope.$applyAsync(function() { + + var countUnreadNotifications = function() { + _.each(drawer.notificationGroups, function(group) { group.totalUnread = unread(group.notifications).length; group.hasUnread = !!group.totalUnread; - $rootScope.$emit('NotificationDrawerWrapper.count', group.totalUnread); + $rootScope.$emit('NotificationDrawerWrapper.onUnreadNotifications', group.totalUnread); }); }; - // currently we only show 1 at a time anyway - var countUnreadNotificationsForAllGroups = function() { - _.each(notificationGroups, countUnreadNotificationsForGroup); + var formatAPIEvents = function(apiEvents) { + return _.map(apiEvents, function(event) { + return { + actions: null, + uid: event.metadata.uid, + unread: !EventsService.isRead(event.metadata.uid), + type: event.type, + lastTimestamp: event.lastTimestamp, + firstTimestamp: event.firstTimestamp, + event: event + }; + }); }; - var sortNotifications = function(notifications) { - return _.orderBy(notifications, ['event.lastTimestamp', 'event.firstTimestamp'], ['desc', 'desc']); + var filterAPIEvents = function(events) { + return _.reduce(events, function(result, event) { + if(EventsService.isImportantAPIEvent(event) && !EventsService.isCleared(event.metadata.uid)) { + result[event.metadata.uid] = event; + } + return result; + }, {}); }; - var sortNotificationGroups = function(groupsMap) { - // convert the map into a sorted array - var sortedGroups = _.sortBy(groupsMap, function(group) { - return group.heading; - }); - // and sort the notifications under each one - _.each(sortedGroups, function(group) { - group.notifications = sortNotifications(group.notifications); - group.counts = countUnreadNotificationsForGroup(group); - }); - return sortedGroups; + // we have to keep notifications & events separate as + // notifications are ephemerial, but events have a time to live + // set by the server. we can merge them right before we update + // the UI. + var mergeMaps = function(firstMap, secondMap) { + var proj = $routeParams.project; + return _.assign({}, firstMap[proj], secondMap[proj]); }; - var formatAndFilterEvents = function(eventMap) { - var filtered = {}; - ensureProjectGroupExists(filtered, $routeParams.project); - _.each(eventMap, function(event) { - if(EventsService.isImportantEvent(event) && !EventsService.isCleared(event)) { - ensureProjectGroupExists(filtered, event.metadata.namespace); - filtered[event.metadata.namespace].notifications.push({ - unread: !EventsService.isRead(event), - uid: event.metadata.uid, - event: event, - actions: null - }); - } + var sortMap = function(map) { + return _.orderBy(map, ['event.lastTimestamp', 'event.firstTimestamp'], ['desc', 'desc']); + }; + + var render = function() { + $rootScope.$evalAsync(function() { + drawer.notificationGroups = [ + makeProjectGroup($routeParams.project, sortMap( mergeMaps(apiEventsMap, notificationsMap ))) + ]; + countUnreadNotifications(); }); - return filtered; }; var deregisterRootScopeWatches = function() { @@ -174,50 +146,64 @@ rootScopeWatches = []; }; - var hideIfNoProject = function(projectName) { - if(!projectName) { - drawer.drawerHidden = true; + var deregisterAPIEventsWatch = function() { + if(apiEventsWatcher) { + DataService.unwatch(apiEventsWatcher); + apiEventsWatcher = null; } }; - var render = function() { - $rootScope.$evalAsync(function () { - countUnreadNotificationsForAllGroups(); - // NOTE: we are currently only showing one project in the drawer at a - // time. If we go back to multiple projects, we can eliminate the filter here - // and just pass the whole array as notificationGroups. - // if we do, we will have to handle group.open to keep track of what the - // user is viewing at the time & indicate to the user that the non-active - // project is "asleep"/not being watched. - drawer.notificationGroups = _.filter(notificationGroups, function(group) { - return group.project.metadata.name === $routeParams.project; - }); - }); + var deregisterNotificationListener = function() { + notificationListener && notificationListener(); + notificationListener = null; + }; + + var apiEventWatchCallback = function(eventData) { + apiEventsMap[$routeParams.project] = formatAPIEvents(filterAPIEvents(eventData.by('metadata.name'))); + render(); }; - // TODO: follow-on PR to decide which of these events to toast, - // via config in constants.js - var eventWatchCallback = function(eventData) { - eventsMap = formatAndFilterEvents(eventData.by('metadata.uid')); - // TODO: Update to an intermediate map, so that we can then combine both - // events + notifications into the final notificationGroups output - notificationGroups = sortNotificationGroups(eventsMap); + var notificationWatchCallback = function(event, notification) { + var project = notification.namespace || $routeParams.project; + var id = notification.id || _.uniqueId('notification_') + Date.now(); + notificationsMap[project] = notificationsMap[project] || {}; + notificationsMap[project][id] = { + actions: null, + unread: !EventsService.isRead(id), + // using uid to match API events and have one filed to pass + // to EventsService for read/cleared, etc + uid: id, + type: notification.type, + // API events have both lastTimestamp & firstTimestamp, + // but we sort based on lastTimestamp first. + lastTimestamp: notification.timestamp, + message: notification.message, + details: notification.details, + namespace: project, + links: notification.links + }; render(); }; - // TODO: Follow-on PR to update & add the internal notifications to the - // var notificationWatchCallback = function(event, notification) { - // // will need to add .event = {} and immitate structure - // if(!notification.lastTimestamp) { - // // creates a timestamp that matches event format: 2017-08-09T19:55:35Z - // notification.lastTimestamp = moment.parseZone(new Date()).utc().format(); - // } - // clientGeneratedNotifications.push(notification); - // }; - - var iconClassByEventSeverity = { - Normal: 'pficon pficon-info', - Warning: 'pficon pficon-warning-triangle-o' + var watchEvents = function(projectName, cb) { + deregisterAPIEventsWatch(); + if(projectName) { + apiEventsWatcher = DataService.watch('events', {namespace: projectName}, _.debounce(cb, 400), { skipDigest: true }); + } + }; + + var watchNotifications = _.once(function(projectName, cb) { + deregisterNotificationListener(); + notificationListener = $rootScope.$on('NotificationsService.onNotificationAdded', cb); + }); + + var reset = function() { + getProject($routeParams.project).then(function() { + watchEvents($routeParams.project, apiEventWatchCallback); + watchNotifications($routeParams.project, notificationWatchCallback); + hideIfNoProject($routeParams.project); + render(); + }); }; angular.extend(drawer, { @@ -234,58 +220,46 @@ onMarkAllRead: function(group) { _.each(group.notifications, function(notification) { notification.unread = false; - EventsService.markRead(notification.event); + EventsService.markRead(notification.uid); }); render(); $rootScope.$emit('NotificationDrawerWrapper.onMarkAllRead'); }, onClearAll: function(group) { _.each(group.notifications, function(notification) { - EventsService.markRead(notification.event); - EventsService.markCleared(notification.event); + notification.unread = false; + EventsService.markRead(notification.uid); + EventsService.markCleared(notification.uid); }); - group.notifications = []; + apiEventsMap[$routeParams.project] = {}; + notificationsMap[$routeParams.project] = {}; render(); $rootScope.$emit('NotificationDrawerWrapper.onMarkAllRead'); }, - notificationGroups: notificationGroups, + notificationGroups: [], headingInclude: 'views/directives/notifications/header.html', notificationBodyInclude: 'views/directives/notifications/notification-body.html', customScope: { clear: function(notification, index, group) { - EventsService.markCleared(notification.event); + EventsService.markCleared(notification.uid); group.notifications.splice(index, 1); - countUnreadNotificationsForAllGroups(); + countUnreadNotifications(); }, markRead: function(notification) { notification.unread = false; - EventsService.markRead(notification.event); - countUnreadNotificationsForAllGroups(); - }, - getNotficationStatusIconClass: function(event) { - return iconClassByEventSeverity[event.type] || iconClassByEventSeverity.info; - }, - getStatusForCount: function(countKey) { - return iconClassByEventSeverity[countKey] || iconClassByEventSeverity.info; + EventsService.markRead(notification.uid); + countUnreadNotifications(); }, close: function() { drawer.drawerHidden = true; + }, + onLinkClick: function(link) { + link.onClick(); + drawer.drawerHidden = true; } } }); - var projectChanged = function(next, current) { - return _.get(next, 'params.project') !== _.get(current, 'params.project'); - }; - - var reset = function() { - getProject($routeParams.project).then(function() { - watchEvents($routeParams.project, eventWatchCallback); - //watchNotifications($routeParams.project, notificationWatchCallback); - hideIfNoProject($routeParams.project); - render(); - }); - }; var initWatches = function() { if($routeParams.project) { @@ -318,10 +292,9 @@ drawer.$onDestroy = function() { deregisterNotificationListener(); - deregisterEventsWatch(); + deregisterAPIEventsWatch(); deregisterRootScopeWatches(); }; - } })(); diff --git a/app/scripts/services/events.js b/app/scripts/services/events.js index a892cba59e..a72b3d9198 100644 --- a/app/scripts/services/events.js +++ b/app/scripts/services/events.js @@ -12,31 +12,30 @@ angular.module('openshiftConsole') var EVENTS_TO_SHOW_BY_REASON = _.get(window, 'OPENSHIFT_CONSTANTS.EVENTS_TO_SHOW'); - var isImportantEvent = function(event) { - var reason = event.reason; - return EVENTS_TO_SHOW_BY_REASON[reason]; + var isImportantAPIEvent = function(event) { + return EVENTS_TO_SHOW_BY_REASON[event.reason]; }; - var markRead = function(event) { - _.set(cachedEvents, [event.metadata.uid, READ], true); + var markRead = function(id) { + _.set(cachedEvents, [id, READ], true); BrowserStore.saveJSON('session','events', cachedEvents); }; - var markCleared = function(event) { - _.set(cachedEvents, [event.metadata.uid, CLEARED], true); + var markCleared = function(id) { + _.set(cachedEvents, [id, CLEARED], true); BrowserStore.saveJSON('session','events', cachedEvents); }; - var isRead = function(event) { - return _.get(cachedEvents, [event.metadata.uid, READ]); + var isRead = function(id) { + return _.get(cachedEvents, [id, READ]); }; - var isCleared = function(event) { - return _.get(cachedEvents, [event.metadata.uid, CLEARED]); + var isCleared = function(id) { + return _.get(cachedEvents, [id, CLEARED]); }; return { - isImportantEvent: isImportantEvent, + isImportantAPIEvent: isImportantAPIEvent, // read removes the event bold effect markRead: markRead, isRead: isRead, diff --git a/app/views/directives/notifications/notification-body.html b/app/views/directives/notifications/notification-body.html index d0467a2b7e..8f6e30ab79 100644 --- a/app/views/directives/notifications/notification-body.html +++ b/app/views/directives/notifications/notification-body.html @@ -7,10 +7,7 @@ tabindex="0" ng-click="$ctrl.customScope.clear(notification, $index, notificationGroup)"> Clear notification - +
+ class="pull-left {{notification.type | alertIcon}}" + aria-hidden="true"> {{notification.event.type}}
+
- - {{notification.event.reason | humanize}} — {{notification.event.involvedObject.kind | humanize}} + + + {{notification.event.reason | humanize}} — {{notification.event.involvedObject.kind | humanize}} - + + {{notification.event.involvedObject.name}} + + + {{notification.message}} + + {{link.label}} + {{link.label}} + | + + +
{{notification.event.count}} times in the last - +
- {{notification.event.lastTimestamp | date:'shortDate'}} - {{notification.event.lastTimestamp | date:'mediumTime'}} + {{notification.lastTimestamp | date:'shortDate'}} + {{notification.lastTimestamp | date:'mediumTime'}}
- {{notification.event.message}} + {{notification.event.message || notification.details}}
diff --git a/dist/scripts/scripts.js b/dist/scripts/scripts.js index be8564f3ef..99bc14753a 100644 --- a/dist/scripts/scripts.js +++ b/dist/scripts/scripts.js @@ -4285,21 +4285,20 @@ f.search().startTour && (e.startGuidedTour(), t.preventDefault()); } ]), angular.module("openshiftConsole").factory("EventsService", [ "BrowserStore", function(e) { var t = e.loadJSON("session", "events") || {}, n = _.get(window, "OPENSHIFT_CONSTANTS.EVENTS_TO_SHOW"); return { -isImportantEvent: function(e) { -var t = e.reason; -return n[t]; +isImportantAPIEvent: function(e) { +return n[e.reason]; }, markRead: function(n) { -_.set(t, [ n.metadata.uid, "read" ], !0), e.saveJSON("session", "events", t); +_.set(t, [ n, "read" ], !0), e.saveJSON("session", "events", t); }, isRead: function(e) { -return _.get(t, [ e.metadata.uid, "read" ]); +return _.get(t, [ e, "read" ]); }, markCleared: function(n) { -_.set(t, [ n.metadata.uid, "cleared" ], !0), e.saveJSON("session", "events", t); +_.set(t, [ n, "cleared" ], !0), e.saveJSON("session", "events", t); }, isCleared: function(e) { -return _.get(t, [ e.metadata.uid, "cleared" ]); +return _.get(t, [ e, "cleared" ]); } }; } ]), angular.module("openshiftConsole").controller("ProjectsController", [ "$scope", "$filter", "$location", "$route", "$timeout", "AuthService", "DataService", "KeywordService", "Navigate", "Logger", "ProjectsService", function(e, t, n, a, r, o, i, s, c, l, u) { @@ -13925,7 +13924,7 @@ controller: [ "$filter", "$routeParams", "$rootScope", "Constants", function(e, var r = this, o = _.get(a, "DISABLE_GLOBAL_EVENT_WATCH"), i = e("isIE")() || e("isEdge")(); r.hide = !0; var s = [], c = [], l = function(e, t) { -e && c.push(n.$on("NotificationDrawerWrapper.count", t)); +e && c.push(n.$on("NotificationDrawerWrapper.onUnreadNotifications", t)); }, u = function() { _.each(c, function(e) { e && e(); @@ -13963,75 +13962,91 @@ u(), d(); }(), function() { angular.module("openshiftConsole").component("notificationDrawerWrapper", { templateUrl: "views/directives/notifications/notification-drawer-wrapper.html", -controller: [ "$filter", "$interval", "$location", "$timeout", "$routeParams", "$rootScope", "Constants", "DataService", "NotificationsService", "EventsService", function(e, t, n, a, r, o, i, s, c, l) { -var u, d, m = _.get(i, "DISABLE_GLOBAL_EVENT_WATCH"), p = e("isIE")() || e("isEdge")(), f = this, g = [], h = {}, v = [], y = {}, b = function(e) { +controller: [ "$filter", "$interval", "$location", "$timeout", "$routeParams", "$rootScope", "Constants", "DataService", "EventsService", function(e, t, n, a, r, o, i, s, c) { +var l, u, d = _.get(i, "DISABLE_GLOBAL_EVENT_WATCH"), m = e("isIE")() || e("isEdge")(), p = this, f = [], g = {}, h = {}, v = {}, y = function(e) { +e || (p.drawerHidden = !0); +}, b = function(e, t) { +return _.get(e, "params.project") !== _.get(t, "params.project"); +}, C = function(e) { return s.get("projects", e, {}, { errorNotification: !1 }).then(function(e) { -return y[e.metadata.name] = e, e; +return v[e.metadata.name] = e, e; }); -}, C = function(t, n) { -n && !t[n] && (t[n] = { -heading: e("displayName")(y[n]) || n, -project: y[n], -notifications: [] -}); -}, S = function() { -d && s.unwatch(d); -}, w = function(e, t) { -S(), e && (d = s.watch("events", { -namespace: e -}, _.debounce(t, 400), { -skipDigest: !0 -})); +}, S = function(t, n) { +return { +heading: e("displayName")(v[t]), +project: v[t], +notifications: n +}; +}, w = function(e) { +return _.filter(e, "unread"); }, k = function() { -u && u(), u = null; +_.each(p.notificationGroups, function(e) { +e.totalUnread = w(e.notifications).length, e.hasUnread = !!e.totalUnread, o.$emit("NotificationDrawerWrapper.onUnreadNotifications", e.totalUnread); +}); }, j = function(e) { -return _.filter(e, "unread"); -}, P = function(e) { -o.$applyAsync(function() { -e.totalUnread = j(e.notifications).length, e.hasUnread = !!e.totalUnread, o.$emit("NotificationDrawerWrapper.count", e.totalUnread); +return _.map(e, function(e) { +return { +actions: null, +uid: e.metadata.uid, +unread: !c.isRead(e.metadata.uid), +type: e.type, +lastTimestamp: e.lastTimestamp, +firstTimestamp: e.firstTimestamp, +event: e +}; }); -}, R = function() { -_.each(v, P); +}, P = function(e) { +return _.reduce(e, function(e, t) { +return c.isImportantAPIEvent(t) && !c.isCleared(t.metadata.uid) && (e[t.metadata.uid] = t), e; +}, {}); +}, R = function(e, t) { +var n = r.project; +return _.assign({}, e[n], t[n]); }, E = function(e) { return _.orderBy(e, [ "event.lastTimestamp", "event.firstTimestamp" ], [ "desc", "desc" ]); -}, T = function(e) { -var t = _.sortBy(e, function(e) { -return e.heading; -}); -return _.each(t, function(e) { -e.notifications = E(e.notifications), e.counts = P(e); -}), t; -}, I = function(e) { -var t = {}; -return C(t, r.project), _.each(e, function(e) { -l.isImportantEvent(e) && !l.isCleared(e) && (C(t, e.metadata.namespace), t[e.metadata.namespace].notifications.push({ -unread: !l.isRead(e), -uid: e.metadata.uid, -event: e, -actions: null -})); -}), t; -}, N = function() { -_.each(g, function(e) { -e(); -}), g = []; -}, D = function(e) { -e || (f.drawerHidden = !0); -}, $ = function() { +}, T = function() { o.$evalAsync(function() { -R(), f.notificationGroups = _.filter(v, function(e) { -return e.project.metadata.name === r.project; +p.notificationGroups = [ S(r.project, E(R(g, h))) ], k(); }); +}, I = function() { +_.each(f, function(e) { +e(); +}), f = []; +}, N = function() { +u && (s.unwatch(u), u = null); +}, D = function() { +l && l(), l = null; +}, $ = function(e) { +g[r.project] = j(P(e.by("metadata.name"))), T(); +}, A = function(e, t) { +var n = t.namespace || r.project, a = t.id || _.uniqueId("notification_") + Date.now(); +h[n] = h[n] || {}, h[n][a] = { +actions: null, +unread: !c.isRead(a), +uid: a, +type: t.type, +lastTimestamp: t.timestamp, +message: t.message, +details: t.details, +namespace: n, +links: t.links +}, T(); +}, B = function(e, t) { +N(), e && (u = s.watch("events", { +namespace: e +}, _.debounce(t, 400), { +skipDigest: !0 +})); +}, L = _.once(function(e, t) { +D(), l = o.$on("NotificationsService.onNotificationAdded", t); +}), U = function() { +C(r.project).then(function() { +B(r.project, $), L(r.project, A), y(r.project), T(); }); -}, A = function(e) { -h = I(e.by("metadata.uid")), v = T(h), $(); -}, B = { -Normal: "pficon pficon-info", -Warning: "pficon pficon-warning-triangle-o" }; -angular.extend(f, { +angular.extend(p, { drawerHidden: !0, allowExpand: !0, drawerExpanded: !1, @@ -14040,56 +14055,47 @@ hasUnread: !1, showClearAll: !0, showMarkAllRead: !0, onClose: function() { -f.drawerHidden = !0; +p.drawerHidden = !0; }, onMarkAllRead: function(e) { _.each(e.notifications, function(e) { -e.unread = !1, l.markRead(e.event); -}), $(), o.$emit("NotificationDrawerWrapper.onMarkAllRead"); +e.unread = !1, c.markRead(e.uid); +}), T(), o.$emit("NotificationDrawerWrapper.onMarkAllRead"); }, onClearAll: function(e) { _.each(e.notifications, function(e) { -l.markRead(e.event), l.markCleared(e.event); -}), e.notifications = [], $(), o.$emit("NotificationDrawerWrapper.onMarkAllRead"); +e.unread = !1, c.markRead(e.uid), c.markCleared(e.uid); +}), g[r.project] = {}, h[r.project] = {}, T(), o.$emit("NotificationDrawerWrapper.onMarkAllRead"); }, -notificationGroups: v, +notificationGroups: [], headingInclude: "views/directives/notifications/header.html", notificationBodyInclude: "views/directives/notifications/notification-body.html", customScope: { clear: function(e, t, n) { -l.markCleared(e.event), n.notifications.splice(t, 1), R(); +c.markCleared(e.uid), n.notifications.splice(t, 1), k(); }, markRead: function(e) { -e.unread = !1, l.markRead(e.event), R(); -}, -getNotficationStatusIconClass: function(e) { -return B[e.type] || B.info; -}, -getStatusForCount: function(e) { -return B[e] || B.info; +e.unread = !1, c.markRead(e.uid), k(); }, close: function() { -f.drawerHidden = !0; +p.drawerHidden = !0; +}, +onLinkClick: function(e) { +e.onClick(), p.drawerHidden = !0; } } }); -var L = function(e, t) { -return _.get(e, "params.project") !== _.get(t, "params.project"); -}, U = function() { -b(r.project).then(function() { -w(r.project, A), D(r.project), $(); -}); -}, O = function() { -r.project && U(), g.push(o.$on("$routeChangeSuccess", function(e, t, n) { -L(t, n) && (f.customScope.projectName = r.project, U()); -})), g.push(o.$on("NotificationDrawerWrapper.toggle", function() { -f.drawerHidden = !f.drawerHidden; +var O = function() { +r.project && U(), f.push(o.$on("$routeChangeSuccess", function(e, t, n) { +b(t, n) && (p.customScope.projectName = r.project, U()); +})), f.push(o.$on("NotificationDrawerWrapper.toggle", function() { +p.drawerHidden = !p.drawerHidden; })); }; -f.$onInit = function() { -m || p || O(); -}, f.$onDestroy = function() { -k(), S(), N(); +p.$onInit = function() { +d || m || O(); +}, p.$onDestroy = function() { +D(), N(), I(); }; } ] }); diff --git a/dist/scripts/templates.js b/dist/scripts/templates.js index 8bde2792c2..15e365102e 100644 --- a/dist/scripts/templates.js +++ b/dist/scripts/templates.js @@ -7478,7 +7478,7 @@ angular.module('openshiftConsoleTemplates', []).run(['$templateCache', function( "
\n" + "\n" + "Clear notification\n" + - "\n" + + "\n" + "\n" + "
\n" + "
\n" + - "\n" + + "\n" + "{{notification.event.type}}\n" + "
\n" + "
\n" + "
\n" + - "\n" + - "{{notification.event.reason | humanize}} — {{notification.event.involvedObject.kind | humanize}}\n" + + "\n" + + "{{notification.event.reason | humanize}} — {{notification.event.involvedObject.kind | humanize}}\n" + "\n" + - "\n" + + "\n" + "\n" + "{{notification.event.involvedObject.name}}\n" + "\n" + "{{notification.event.involvedObject.name}}\n" + "\n" + + "\n" + + "{{notification.message}}\n" + + "\n" + + "{{link.label}}\n" + + "{{link.label}}\n" + + "|\n" + + "\n" + + "\n" + "
\n" + "
1\" class=\"text-muted small\">\n" + "{{notification.event.count}} times in the last\n" + @@ -7513,12 +7521,12 @@ angular.module('openshiftConsoleTemplates', []).run(['$templateCache', function( "
\n" + "
\n" + "
\n" + - "{{notification.event.lastTimestamp | date:'shortDate'}}\n" + - "{{notification.event.lastTimestamp | date:'mediumTime'}}\n" + + "{{notification.lastTimestamp | date:'shortDate'}}\n" + + "{{notification.lastTimestamp | date:'mediumTime'}}\n" + "
\n" + "
\n" + "
\n" + - "{{notification.event.message}}\n" + + "{{notification.event.message || notification.details}}\n" + "
\n" + "
" );