Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Notifications drawer #1326

Merged
merged 1 commit into from
Aug 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
<!-- Add your site or application content here -->

<toast-notifications></toast-notifications>
<notification-drawer-wrapper></notification-drawer-wrapper>

<div ng-view>
<!-- Include default simple nav and shaded background as a placeholder until API discovery finishes -->
<nav class="navbar navbar-pf-alt top-header" role="navigation">
Expand Down Expand Up @@ -190,6 +192,7 @@ <h1>JavaScript Required</h1>

<script src="scripts/constants.js"></script>
<script src="scripts/app.js"></script>
<script src="scripts/services/browserStore.js"></script>
<script src="scripts/services/discovery.js"></script>
<script src="scripts/services/applicationGenerator.js"></script>
<script src="scripts/services/navigate.js"></script>
Expand Down Expand Up @@ -233,6 +236,7 @@ <h1>JavaScript Required</h1>
<script src="scripts/services/listRowUtils.js"></script>
<script src="scripts/services/ownerReferences.js"></script>
<script src="scripts/controllers/landingPage.js"></script>
<script src="scripts/services/events.js"></script>
<script src="scripts/controllers/projects.js"></script>
<script src="scripts/controllers/pods.js"></script>
<script src="scripts/controllers/pod.js"></script>
Expand Down Expand Up @@ -391,6 +395,8 @@ <h1>JavaScript Required</h1>
<script src="scripts/directives/affix.js"></script>
<script src="scripts/directives/editEnvironmentVariables.js"></script>
<script src="scripts/directives/initContainersSummary.js"></script>
<script src="scripts/directives/notifications/notificationCounter.js"></script>
<script src="scripts/directives/notifications/notificationDrawerWrapper.js"></script>
<script src="scripts/filters/date.js"></script>
<script src="scripts/filters/resources.js"></script>
<script src="scripts/filters/canI.js"></script>
Expand Down
1 change: 1 addition & 0 deletions app/scripts/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ angular
'patternfly.charts',
'patternfly.navigation',
'patternfly.sort',
'patternfly.notification',
'openshiftConsoleTemplates',
'ui.ace',
'extension-registry',
Expand Down
56 changes: 55 additions & 1 deletion app/scripts/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ angular.extend(window.OPENSHIFT_CONSTANTS, {

// This blacklist hides certain kinds from the "Other Resources" page because they are unpersisted, disallowed for most end users, or not supported by openshift but exist in kubernetes
AVAILABLE_KINDS_BLACKLIST: [],

// Currently disables watch on events used by the drawer
DISABLE_GLOBAL_EVENT_WATCH: false,
ENABLE_TECH_PREVIEW_FEATURE: {
// Enable the new landing page and service catalog experience
service_catalog_landing_page: false,
Expand Down Expand Up @@ -139,6 +140,59 @@ angular.extend(window.OPENSHIFT_CONSTANTS, {
{resource: 'services', group: ''},
{resource: 'statefulsets', group: 'apps'}
],
// TODO:
// This map can drive both the drawer & toast messages by
// updating it to the following format:
// { drawer: true, toast: true }
// or perhaps this, where an event may apply to multiple resources
// (though reuse of events is not super common, this could be overkill):
// Failed: {
// resources: [{ group: 'apps', resource: 'deployments' }],
// drawer: true,
// toast: true
// }
// TODO: Also consider an API_OBJECTS_TO_IGNORE
// map that can blacklist some, for example, if FailedCreate
// applies to many but we don't want to see all.
EVENTS_TO_SHOW: {
// CRUD events that apply to more than one api object
FailedCreate: true,
FailedDelete: true,
FailedUpdate: true,
// Build
BuildStarted: true,
BuildCompleted: true,
BuildFailed: true,
BuildCancelled: true,
// BuildConfig
//
// Deployment
Failed: true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of these are so general, I'd rather pair it to a specific kind. Although API groups make it a little harder. Maybe something like

Failed: {
  resources: [{ group: 'apps', resource: 'deployments' }],
  drawer: true,
  toast: true
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can make this a follow on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok sounds good. I can definitely iterate on this.

ScalingReplicaSet: true,
DeploymentCancelled: true,
// DeploymentConfig
DeploymentCreated: true,
DeploymentCreationFailed: true,
// Pod
FailedSync: true,
BackOff: true,
Unhealthy: true,
// Image/Pod
Pulling: true,
Pulled: true,
// SuccessfulDelete: true,
// Cron
//
// PodAutoscaler
SuccessfulRescale: true,
FailedRescale: true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some events for when the autoscaler can't get metrics. We should show those.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was able to find the following related to autoscalers:

  PodAutoscaler 
    Normal 
      DesiredReplicasComputed 
      DesiredReplicasComputedCustomMetric
      SuccessfulRescale 
    Warning 
        FailedRescale 

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind, I'm thinking of a condition on the HPA object, not an event.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

// Service
LoadBalancerUpdateFailed: true,
// PVC
VolumeDeleted: true,
FailedBinding: true,
ProvisioningFailed: true
},

// href's will be prefixed with /project/{{projectName}} unless they are absolute URLs
PROJECT_NAVIGATION: [
Expand Down
109 changes: 109 additions & 0 deletions app/scripts/directives/notifications/notificationCounter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
'use strict';
(function() {

angular
.module('openshiftConsole')
.component('notificationCounter', {
templateUrl: 'views/directives/notifications/notification-counter.html',
bindings: {},
controller: [
'$filter',
'$routeParams',
'$rootScope',
'Constants',
NotificationCounter
]
});

function NotificationCounter($filter, $routeParams, $rootScope, Constants) {

var counter = this;
var DISABLE_GLOBAL_EVENT_WATCH = _.get(Constants, 'DISABLE_GLOBAL_EVENT_WATCH');
var LIMIT_WATCHES = $filter('isIE')() || $filter('isEdge')();

counter.hide = true;

var rootScopeWatches = [];
// this one is treated separately from the rootScopeWatches as
// it may need to be updated outside of the lifecycle of init/destroy
var notificationListeners = [];

var watchNotificationDrawerCount = function(projectName, cb) {
if(!projectName) {
return;
}
notificationListeners.push($rootScope.$on('NotificationDrawerWrapper.count', cb));
};

var deregisterNotificationListeners = function() {
_.each(notificationListeners, function(listener) {
listener && listener();
});
notificationListeners = [];
};

var deregisterRootScopeWatches = function() {
_.each(rootScopeWatches, function(deregister) {
deregister();
});
rootScopeWatches = [];
};

var hideIfNoProject = function(projectName) {
if(!projectName) {
counter.hide = true;
} else {
counter.hide = false;
}
};

counter.onClick = function() {
$rootScope.$emit('NotificationDrawerWrapper.toggle');
};

var drawerCountCallback = function(event, newCount) {
// NOTE: unread !== seen. We do not automatically mark
// notifications unread when the drawer is closed.
if(newCount) {
counter.showUnreadNotificationsIndicator = true;
} else {
counter.showUnreadNotificationsIndicator = false;
}
};

var projectChanged = function(next, current) {
return _.get(next, 'params.project') !== _.get(current, 'params.project');
};

var reset = function() {
watchNotificationDrawerCount($routeParams.project, drawerCountCallback);
hideIfNoProject($routeParams.project);
};

var initWatches = function() {
reset();
rootScopeWatches.push($rootScope.$on("$routeChangeSuccess", function (evt, next, current) {
if(projectChanged(next, current)) {
reset();
}
}));

rootScopeWatches.push($rootScope.$on('NotificationDrawerWrapper.onMarkAllRead', function() {
counter.showUnreadNotificationsIndicator = false;
}));
};

counter.$onInit = function() {
if(DISABLE_GLOBAL_EVENT_WATCH || LIMIT_WATCHES) {
counter.hide = true;
return;
}
initWatches();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@spadgett the Auth items removed.

};

counter.$onDestroy = function() {
deregisterNotificationListeners();
deregisterRootScopeWatches();
};
}
})();
Loading