This commit is contained in:
Henry 2015-10-09 15:27:40 -07:00
parent 82ae9e72c1
commit 60dda8a7a4
10 changed files with 101 additions and 53 deletions

View File

@ -12,7 +12,7 @@
</div>
<div class="message-body">
<div class="message-action">
{{ngModel.actionText}} message-severity-{{ngModel.severity}}
{{ngModel.actionText}}
</div>
<mct-include key="'progress-bar'"
ng-model="ngModel"
@ -24,6 +24,13 @@
ng-click="dialogAction.action()">
{{dialogAction.label}}
</a>
<a class="s-btn major"
ng-if="ngModel.primaryAction"
ng-click="ngModel.primaryAction.action()">
{{ngModel.primaryAction.label}}
</a>
</div>
</div>
</div>

View File

@ -202,7 +202,9 @@ define(
/**
* A description of the model options that may be passed to the
* showBlockingMessage method
* showBlockingMessage method. Note that the DialogModel desribed
* here is shared with the Notifications framework.
* @see NotificationService
*
* @typedef DialogModel
* @property {string} severity the severity level of this message.
@ -220,8 +222,13 @@ define(
* impossible to provide an estimate for. Providing a true value for
* this attribute will indicate to the user that the progress and
* duration cannot be estimated.
* @property {DialogAction} primaryAction an action that will
* be added to the dialog as a button. The primary action can be
* used as the suggested course of action for the user. Making it
* distinct from other actions allows it to be styled differently,
* and treated preferentially in banner mode.
* @property {DialogAction[]} actions a list of actions that will
* be added to the dialog as buttons. These buttons are
* be added to the dialog as buttons.
*/
/**
@ -235,8 +242,17 @@ define(
* @returns {boolean}
*/
DialogService.prototype.showBlockingMessage = function(dialogModel) {
if (this.canShowDialog) {
this.getDialogResponse("overlay-blocking-message", dialogModel, undefined, "t-dialog-sm");
if (this.canShowDialog(dialogModel)) {
// Add the overlay using the OverlayService, which
// will handle actual insertion into the DOM
this.overlay = this.overlayService.createOverlay(
"overlay-blocking-message",
dialogModel,
"t-dialog-sm"
);
// Track that a dialog is already visible, to
// avoid spawning multiple dialogs at once.
this.dialogVisible = true;
return true;
} else {
return false;

View File

@ -104,7 +104,7 @@
{
"key": "BannerController",
"implementation": "controllers/BannerController.js",
"depends": ["$scope", "notificationService"]
"depends": ["$scope", "notificationService", "dialogService"]
}
],
"directives": [

View File

@ -1,20 +1,18 @@
<div ng-controller="BannerController">
<div ng-show="active.notification"
class="l-message-banner s-message-banner">
<span class="banner-elem label">
{{active.notification.title}}
</span>
<span ng-hide="active.notification.progress === undefined">
<mct-include key="'progress-bar'" class="banner-elem"
ng-model="ngModel">
</mct-include>
</span>
<a ng-hide="active.notification.primaryAction === undefined"
class="banner-elem l-action s-action"
ng-click="active.notification.primaryAction.action">
{{active.notification.primaryAction.label}}
</a>
<a class="banner-elem ui-symbol close" ng-click="dismiss(active.notification)">
&#x78;</a>
</div>
<div ng-controller="BannerController" ng-show="active.notification"
class="l-message-banner s-message-banner" ng-click="maximize(active.notification)">
<span class="banner-elem label">
{{active.notification.title}}
</span>
<span ng-hide="active.notification.progress === undefined">
<mct-include key="'progress-bar'" class="banner-elem"
ng-model="active.notification">
</mct-include>
</span>
<a ng-hide="active.notification.primaryAction === undefined"
class="banner-elem l-action s-action"
ng-click="active.notification.primaryAction.action()">
{{active.notification.primaryAction.label}}
</a>
<a class="banner-elem ui-symbol close" ng-click="dismiss(active.notification)">
&#x78;</a>
</div>

View File

@ -25,10 +25,16 @@ define(
[],
function () {
"use strict";
function BannerController($scope, notificationService){
function BannerController($scope, notificationService, dialogService) {
$scope.active = notificationService.active;
$scope.dismiss = function(notification){
$scope.dismiss = function(notification) {
notificationService.dismissOrMinimize(notification);
};
$scope.maximize = function(notification) {
notification.cancel = function(){
dialogService.dismiss();
}
dialogService.showBlockingMessage(notification);
}
}
return BannerController;

View File

@ -4,6 +4,10 @@
{
"key": "DEFAULT_AUTO_DISMISS",
"value": 3000
},
{
"key": "FORCE_AUTO_DISMISS",
"value": 1000
}
],
"controllers": [
@ -17,7 +21,8 @@
{
"key": "notificationService",
"implementation": "NotificationService.js",
"depends": [ "$timeout", "DEFAULT_AUTO_DISMISS" ]
"depends": [ "$timeout", "DEFAULT_AUTO_DISMISS",
"FORCE_AUTO_DISMISS" ]
}
]
}

View File

@ -59,7 +59,7 @@ define(
* @property {number} progress The completion status of a task
* represented numerically
* @property {MessageSeverity} messageSeverity The importance of the
* message (eg. error, success)
* message (eg. error, info)
* @property {boolean} unknownProgress a boolean indicating self the
* progress of the underlying task is unknown. This will result in a
* visually distinct progress bar.
@ -84,10 +84,11 @@ define(
* @memberof platform/commonUI/notification
* @constructor
*/
function NotificationService($timeout, DEFAULT_AUTO_DISMISS) {
function NotificationService($timeout, DEFAULT_AUTO_DISMISS, FORCE_AUTO_DISMISS) {
this.notifications = [];
this.$timeout = $timeout;
this.DEFAULT_AUTO_DISMISS = DEFAULT_AUTO_DISMISS;
this.FORCE_AUTO_DISMISS = FORCE_AUTO_DISMISS;
/*
* A context in which to hold the active notification and a
@ -105,12 +106,12 @@ define(
};
/**
* A convenience method for success notifications. Notifications
* A convenience method for info notifications. Notifications
* created via this method will be auto-dismissed after a default
* wait period
* @param {Notification} notification The notification to display
*/
NotificationService.prototype.success = function (notification) {
NotificationService.prototype.info = function (notification) {
notification.autoDismiss = notification.autoDismiss || true;
notification.severity = MessageSeverity.INFO;
this.notify(notification);
@ -145,17 +146,15 @@ define(
If there is already an active notification, time it out. If it's
already got a timeout in progress (either because it has had
timeout forced because of a queue of messages, or it had an
autodismiss specified), leave it to run.
autodismiss specified), leave it to run. Otherwise force a
timeout.
This notifcation has been added to queue and will be
serviced as soon as possible.
*/
timeout = notification.autoDismiss ?
notification.autoDismiss :
this.DEFAULT_AUTO_DISMISS;
this.active.timeout = this.$timeout(function () {
self.dismissOrMinimize(self.active.notification);
}, timeout);
}, this.FORCE_AUTO_DISMISS);
}
};
@ -217,7 +216,7 @@ define(
/**
* Minimize a notification. The notification will still be available
* from the notification list. Typically notifications with a
* severity of 'success' should not be minimized, but rather
* severity of 'info' should not be minimized, but rather
* dismissed. If you're not sure which is appropriate,
* use {@link NotificationService#dismissOrMinimize}
* @see dismiss
@ -236,7 +235,7 @@ define(
/**
* Completely removes a notification. This will dismiss it from the
* message banner and remove it from the list of notifications.
* Typically only notifications with a severity of success should be
* Typically only notifications with a severity of info should be
* dismissed. If you're not sure whether to dismiss or minimize a
* notification, use {@link NotificationService#dismissOrMinimize}.
* dismiss

View File

@ -43,7 +43,7 @@ define(
* 3) Calling .notify with autoDismiss results in an ERROR notification
* being MINIMIZED after a timeout has elapsed DONE
*
* 4) Calling .notify with an active success notification results in that
* 4) Calling .notify with an active info notification results in that
* notification being auto-dismissed, and the new notification becoming
* active. DONE
*
@ -80,7 +80,7 @@ define(
mockTimeout, mockAutoDismiss);
successModel = {
title: "Mock Success Notification",
severity: MessageSeverity.SUCCESS
severity: MessageSeverity.INFO
};
errorModel = {
title: "Mock Error Notification",
@ -124,11 +124,11 @@ define(
it("auto-dismisses the previously active notification, making" +
" the new notification active", function() {
var activeNotification;
//First pre-load with a success message
//First pre-load with a info message
notificationService.notify(successModel);
activeNotification =
notificationService.getActiveNotification();
//Initially expect the active notification to be success
//Initially expect the active notification to be info
expect(activeNotification).toBe(successModel);
//Then notify of an error
notificationService.notify(errorModel);
@ -140,20 +140,20 @@ define(
});
it("auto-dismisses an active success notification, removing" +
" it completely", function() {
//First pre-load with a success message
//First pre-load with a info message
notificationService.notify(successModel);
//Then notify of an error
notificationService.notify(errorModel);
expect(notificationService.notifications.length).toEqual(2);
mockTimeout.mostRecentCall.args[0]();
//Previous success message should be completely dismissed
//Previous info message should be completely dismissed
expect(notificationService.notifications.length).toEqual(1);
});
it("auto-minimizes an active error notification", function() {
var activeNotification;
//First pre-load with an error message
notificationService.notify(errorModel);
//Then notify of success
//Then notify of info
notificationService.notify(successModel);
expect(notificationService.notifications.length).toEqual(2);
//Mock the auto-minimize
@ -178,7 +178,7 @@ define(
severity: MessageSeverity.ERROR
};
//First pre-load with a success message
//First pre-load with a info message
notificationService.notify(errorModel);
//Then notify of a third error
notificationService.notify(error2);

View File

@ -27,6 +27,7 @@
"implementation": "NotificationLaunchController.js",
"depends": [
"$scope",
"$timeout",
"notificationService"
]
}

View File

@ -26,10 +26,11 @@ define(
function (MessageSeverity) {
"use strict";
function NotificationLaunchController($scope, notificationService) {
function NotificationLaunchController($scope, $timeout, notificationService) {
var messageCounter = 1;
$scope.newSuccess = function(){
notificationService.success({
notificationService.info({
title: "Success notification!"
})
};
@ -37,9 +38,14 @@ define(
$scope.newError = function(){
notificationService.notify({
title: "Error notification!",
severity: MessageSeverity.ERROR
})
title: "Error notification " + messageCounter++ + "!",
severity: MessageSeverity.ERROR,
primaryAction: {
label: 'Retry',
action: function() {
console.log('Retry clicked');
}
}});
};
$scope.newProgress = function(){
@ -52,7 +58,17 @@ define(
};
notificationService.notify(notification)
function incrementProgress(notification) {
notification.progress = Math.min(100, Math.floor(notification.progress + Math.random() * 30));
notification.progressText = ["Estimated time remaining:" +
" about ", 60 - Math.floor((notification.progress / 100) * 60), " seconds"].join(" ");
if (notification.progress < 100) {
$timeout(function(){incrementProgress(notification)}, 1000);
}
}
notificationService.notify(notification);
incrementProgress(notification);
};
}