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

Custom notifications in notification drawer #2001

Conversation

benjaminapetersen
Copy link
Contributor

@benjaminapetersen benjaminapetersen commented Sep 2, 2017

Integrates our internal notifications into the notification drawer.
Enhancement to #1326

screen shot 2017-09-01 at 11 03 13 pm

@spadgett

@benjaminapetersen benjaminapetersen force-pushed the bpeterse/notifications-to-notification-drawer branch from 1c9e134 to 697843e Compare September 2, 2017 03:04
// internal notifications have different types than API events
var notificationEventTypeMap = {
success: 'Normal',
error: 'Warning'
Copy link
Member

Choose a reason for hiding this comment

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

We should handle all four types in the drawer: info, success, error, and warning. Then we just map event "normal" -> "info"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Eliminating both maps via PR to common


var iconClassByEventSeverity = {
Normal: 'pficon pficon-info',
Warning: 'pficon pficon-warning-triangle-o'
Copy link
Member

Choose a reason for hiding this comment

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

We should check what toast notifications are doing for these icon mappings. Ideally we have one map somewhere so we're always consistent.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looks like they use alertIcon :

<span class="{{notification.type | alertIcon}}" aria-hidden="true"></span>

I'll update & use that

notificationListener = null;
var makeProjectGroup = function(projectName, notifications) {
return {
heading: $filter('displayName')(projects[projectName]) || projectName,
Copy link
Member

Choose a reason for hiding this comment

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

The || is not necessary since displayName default to name if there's no display name.

var project = projects[projectName]
return {
  heading: $filter('displayName')(project),
  project: project,
  notifications: notifications
};

};
}
return result;
}, {});
Copy link
Member

Choose a reason for hiding this comment

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

@benjaminapetersen I know you prefer this indentation style, but the rest of the code uses

return _.reduce(events, function(result, event) {
  // ...
});

Let's try to keep consistent styles.

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'll update this.

Ref #1121 for when we have time.

var proj = $routeParams.project;
return _.orderBy(
_.assign({}, firstMap[proj], secondMap[proj]),
['event.lastTimestamp', 'event.firstTimestamp'],
Copy link
Member

Choose a reason for hiding this comment

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

We need to be assigning timestamps to events in notification service to get proper ordering.

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 can follow-up a PR to origin-web-common to do some work on NotificationsService. This line should just be a fallback.

Copy link
Member

Choose a reason for hiding this comment

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

Sure, OK as a follow on

drawer.drawerHidden = true;
var deregisterEventsWatch = function() {
if(eventsWatcher) {
DataService.unwatch(eventsWatcher);
Copy link
Member

Choose a reason for hiding this comment

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

eventsWatcher = null;

// clientGeneratedNotifications.push(notification);
// };
var notificationWatchCallback = function(event, notification) {
var uid = notification.id || _.uniqueId('notification-');
Copy link
Member

Choose a reason for hiding this comment

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

Ideally we should add in an ID for those that don't have one in NotificationsService.

unread: true,
uid: uid,
// emulating an API event to simplify the template
event: {
Copy link
Member

Choose a reason for hiding this comment

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

I'd rather not add a dummy event. I'd rather copy necessary properties like uid and timestamp from the event to top-level properties, and use those in the view.

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 ill update

uid: uid,
// emulating an API event to simplify the template
event: {
lastTimestamp: notification.lastTimestamp || moment.parseZone(new Date()).utc().format(),
Copy link
Member

Choose a reason for hiding this comment

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

Better to add the timestamp in NotificationsService

if(!projectName) {
return;
}
notificationListener = $rootScope.$on('NotificationsService.onNotificationAdded', cb);
Copy link
Member

Choose a reason for hiding this comment

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

We should be able to add this once instead of registering and removing on project changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True. no need to update this one like the events watch.

@benjaminapetersen
Copy link
Contributor Author

Updated. Will need a release of origin-web-common with PR 170 before this can go.

@openshift-bot openshift-bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 6, 2017
@dtaylor113
Copy link
Contributor

Hi @benjaminapetersen, The 'Clear All' doesn't appear to be working correctly. I start out with 3 notifications:

image

I think click on an 'X' to remove one:

image

Then click on 'Clear All' and all three re-appear instead of removing them all as I was expecting:

image

@dtaylor113
Copy link
Contributor

Hi, the 'View Build' link in this notification doesn't seem to do anything/navigation anywhere:

image

@benjaminapetersen
Copy link
Contributor Author

Thanks @dtaylor113! I made a few updates last night & have another push coming this morn that addresses these items. I updated EventsService a bit & am reconciling the ids.

@benjaminapetersen benjaminapetersen force-pushed the bpeterse/notifications-to-notification-drawer branch from 4d1a986 to 8316f01 Compare September 6, 2017 14:53
@benjaminapetersen
Copy link
Contributor Author

Updated & squashed the last 5 commits down.
Think I need a rebase on latest master, thats coming in a few mins.

@benjaminapetersen
Copy link
Contributor Author

btw, Id's are still janky w/o the update to origin-web-common. I'll PR a version bump.

@benjaminapetersen
Copy link
Contributor Author

Rebased, also put a fallback id in otherwise the notifications just act too weird (until common version bump happens).

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);
Copy link
Member

Choose a reason for hiding this comment

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

If we're saving read and clear status by ID in session storage, we should really change NotificationService to generated a UID instead of using _.uniqueId. With _.uniqueId the IDs will be reused if you refresh the page, and notification might be incorrectly hidden from the drawer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is true. I could pull the generateSecret function from ApplicationGenerator:

    scope._generateSecret = function(){
        //http://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
        function s4() {
          return Math.floor((1 + Math.random()) * 0x10000)
              .toString(16)
              .substring(1);
          }
        return s4()+s4()+s4()+s4();
      };

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Simpler could just be _.uniqueId('notification_') + Date.now().

@spadgett
Copy link
Member

spadgett commented Sep 6, 2017

Looks like the sort is still wrong. (I should have latest common changes with the timestamps.)

screen shot 2017-09-06 at 1 27 35 pm

@openshift-bot openshift-bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 6, 2017
@benjaminapetersen
Copy link
Contributor Author

benjaminapetersen commented Sep 6, 2017

@openshift/team-ux-review

Need some feedback! We have our notifications integrated into the drawer with the curated api events. This creates some quirks that we think need to be addressed before we can merge this feature.

  1. As a user, if I click deploy I will get 1. a toast indicating the action (deploy) and a notification indicating the same action. I know I initiated the action, so double affirmation is a bit much.

  2. If I close the toast, I might expect that the notification in the drawer should be marked read. It is no longer news to me.

  3. The API Events have only 2 types, Warning and Normal. Our notifications have 4: Warning, Error, Success, Info. This can cause mismatch, like with the icons here:

screen shot 2017-09-06 at 3 11 10 pm

These two events should be the same level (actually the "Deployment Created" event might be more weighty than "Deployment Started"), but the icons seem to indicate that "Deployment Created" is of lesser value.

  1. There is a difference in the way we format the two event types. I'll add another screenshot after Start Build to illustrate this further:

screen shot 2017-09-06 at 3 12 15 pm

With the API event we link the name of the object, with the internal notification we add a view build link as a separate component.

  1. I really think we should add the counts back to the header, it is definitely easy to miss a "warning" event that gets pushed below the fold:

screen shot 2017-09-06 at 3 14 41 pm

However, since internal events have 4 states (explained above) we probably don't want 4 icons with counts in the header.

  1. We have discussed that the large toast for a success message is perhaps more obtrusive than it needs to be:

screen shot 2017-09-06 at 3 16 51 pm

It might be ideal to make these smaller similar to how gmail gives a centered sent message toast. This could solve the problem of toasts frequently covering action buttons:

screen shot 2017-09-06 at 3 16 27 pm

And save the large toasts for bad things:

screen shot 2017-09-06 at 3 19 13 pm 1

  1. We have also discussed adding a way to configure what internal events end up as a toast, and which can just go directly into the drawer.

Thoughts?

Observations gathered from earlier discussion with @ncameronbritt @spadgett

@ncameronbritt
Copy link

The toast notifications are helpful when a user takes an action in the sense that they provide feedback to the user. But obviously toasts aren't the only way we could provide the user feedback that the system registered their input. The little message like gmail provides is another option. Having the button itself do something is yet another. May be worth thinking about this from a PF perspective too for actions that don't obviously change a user's context.

@benjaminapetersen
Copy link
Contributor Author

Right! @ncameronbritt you suggested something like this for a button effect:

2017-09-06 16 12 51

I dunno why github made the gif huge 😕

@ncameronbritt
Copy link

Right on @benjaminapetersen! I like that that communicates that something is happening right in the place where the user took an action.

@serenamarie125
Copy link

Looks cool, but not consistent with what we do in PatternFly. I'd suggest we wait on that behavior and do some
Research to see if that's what we want to consistently throughout Openshift and the rest of the portfolio. Or in what situations we want to do it :)

@spadgett
Copy link
Member

spadgett commented Sep 6, 2017

@serenamarie125 We've had some feedback from @smarterclayton and @sspeiche that some of the confirmation toasts are annoying. ("I know I just clicked that button. Why are you telling me?") See also #1911. I remember you and @jeff-phillips-18 had similar concerns.

The problem is that on some pages, depending on what tab is selected, nothing on the page changes in response to an action. So it can look like the button didn't do anything. One example is clicking "Start Build" on the build config page with the "Configuration" tab selected. Nothing changes, and it seems like the action didn't work. The user might try clicking the button several times and accidentally creating several builds.

What we'd really like is a way to let users know an action succeeded that is a little less in-your-face than a toast. A more subtle, "Yep, that worked" message. The Gmail screenshot from @benjaminapetersen is good example. The button changing is also interesting, although I'd like something that works in contexts where there isn't a button.

Do you think this make sense to explore as a pattern in Patternfly?

@serenamarie125
Copy link

@spadgett I agree that the toasts can be annoying. IMO, we should be identifying a strategy for default usage of toasts & availability in the notification drawer. Ultimately the user should be able to configure what they would like to see where as well.

That being said, I do agree that we need a solution so that users are aware that they have performed an action. @spadgett is this something we can do for 3.8? If so, i think that will give us the ability to perform some research and come up with a solution which should be used for similar use cases across products. (thus my answer is yes i think we should explore a PatternFly solution 😄 )

@serenamarie125
Copy link

@jeff-phillips-18 shouldn't the toast be UNDER the top banner? Maybe this is a bug in PatternFly, although I thought we had fixed it?

@openshift-bot openshift-bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 7, 2017
@openshift-bot openshift-bot added needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. and removed needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. labels Sep 18, 2017
@dtaylor113
Copy link
Contributor

Hi, common was bumped to 0.0.57

@benjaminapetersen
Copy link
Contributor Author

@dtaylor113 yup think this PR will wait on all the version bumps in #2103.

@benjaminapetersen benjaminapetersen force-pushed the bpeterse/notifications-to-notification-drawer branch 3 times, most recently from 7cb97e9 to 7b7a4b5 Compare September 19, 2017 15:21
@benjaminapetersen
Copy link
Contributor Author

benjaminapetersen commented Sep 19, 2017

Reviewed & rebased.

[test]

Quite a few moving parts here, once I finish the test overhaul I want to circle back around & provide some coverage to these components.

@spadgett spadgett removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 19, 2017
@spadgett
Copy link
Member

[merge]

@benjaminapetersen
Copy link
Contributor Author

########## FINISHED STAGE: FAILURE: PROVISION CLOUD RESOURCES [00h 02m 39s] 
##########

[merge]

@benjaminapetersen
Copy link
Contributor Author

wake up...

[merge]

@benjaminapetersen
Copy link
Contributor Author

Another flake

########## FINISHED STAGE: FAILURE: PROVISION CLOUD RESOURCES [00h 02m 39s] ##########
Build step 'Execute shell' marked build as failure
[PostBuildScript] - Execution post build scripts.

@benjaminapetersen
Copy link
Contributor Author

flakes, and travis keeps hanging...

[merge]

@spadgett
Copy link
Member

Needs rebase

- 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
@benjaminapetersen benjaminapetersen force-pushed the bpeterse/notifications-to-notification-drawer branch from 7b7a4b5 to 966b580 Compare September 19, 2017 20:50
@benjaminapetersen
Copy link
Contributor Author

rebased again.

@openshift-bot
Copy link

Evaluated for origin web console test up to 966b580

@openshift-bot
Copy link

Evaluated for origin web console merge up to 966b580

@openshift-bot
Copy link

openshift-bot commented Sep 19, 2017

Origin Web Console Merge Results: SUCCESS (https://ci.openshift.redhat.com/jenkins/job/merge_pull_request_origin_web_console/232/) (Base Commit: c63e2f5) (PR Branch Commit: 966b580)

@openshift-bot
Copy link

Origin Web Console Test Results: SUCCESS (https://ci.openshift.redhat.com/jenkins/job/test_pull_request_origin_web_console/236/) (Base Commit: 2041c75) (PR Branch Commit: 966b580)

@openshift-bot openshift-bot merged commit 1ceb0ff into openshift:master Sep 19, 2017
@benjaminapetersen benjaminapetersen deleted the bpeterse/notifications-to-notification-drawer branch September 19, 2017 21:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants