mirror of
https://github.com/nasa/openmct.git
synced 2025-01-31 00:23:54 +00:00
Added basic notifications on copy
This commit is contained in:
commit
e37fa75289
@ -30,7 +30,5 @@
|
||||
|
||||
"example/imagery",
|
||||
"example/eventGenerator",
|
||||
"example/generator",
|
||||
|
||||
"testing/dialogTest"
|
||||
"example/generator"
|
||||
]
|
||||
|
@ -3,7 +3,8 @@
|
||||
<span class="label">
|
||||
<a ng-click="launchProgress(true)">Known</a> |
|
||||
<a ng-click="launchProgress(false)">Unknown</a> |
|
||||
<a ng-click="launchError()">Error</a>
|
||||
<a ng-click="launchError()">Error</a> |
|
||||
<a ng-click="launchInfo()">Info</a>
|
||||
</span>
|
||||
<span class="count">Dialogs</span>
|
||||
</span>
|
@ -1,7 +1,7 @@
|
||||
<span class="status block ok" ng-controller="NotificationLaunchController">
|
||||
<span class="ui-symbol status-indicator"></span>
|
||||
<span class="label">
|
||||
<a ng-click="newSuccess()">Success</a> |
|
||||
<a ng-click="newInfo()">Success</a> |
|
||||
<a ng-click="newError()">Error</a> |
|
||||
<a ng-click="newAlert()">Alert</a> |
|
||||
<a ng-click="newProgress()">Progress</a>
|
@ -22,11 +22,27 @@
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
['../../../platform/commonUI/notification/src/MessageSeverity'],
|
||||
function (MessageSeverity) {
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* A controller for the dialog launch view. This view allows manual
|
||||
* launching of dialogs for demonstration and testing purposes. It
|
||||
* also demonstrates the use of the DialogService.
|
||||
* @param $scope
|
||||
* @param $timeout
|
||||
* @param $log
|
||||
* @param dialogService
|
||||
* @param notificationService
|
||||
* @constructor
|
||||
*/
|
||||
function DialogLaunchController($scope, $timeout, $log, dialogService, notificationService) {
|
||||
|
||||
/*
|
||||
Demonstrates launching a progress dialog and updating it
|
||||
periodically with the progress of an ongoing process.
|
||||
*/
|
||||
$scope.launchProgress = function (knownProgress) {
|
||||
var model = {
|
||||
title: "Progress Dialog Example",
|
||||
@ -34,18 +50,19 @@ define(
|
||||
hint: "Do not navigate away from this page or close this browser tab while this operation is in progress.",
|
||||
actionText: "Calculating...",
|
||||
unknownProgress: !knownProgress,
|
||||
severity: MessageSeverity.INFO,
|
||||
actions: [
|
||||
unknownDuration: false,
|
||||
severity: "info",
|
||||
options: [
|
||||
{
|
||||
label: "Cancel Operation",
|
||||
action: function () {
|
||||
callback: function () {
|
||||
$log.debug("Operation cancelled");
|
||||
dialogService.dismiss();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "Do something else...",
|
||||
action: function () {
|
||||
callback: function () {
|
||||
$log.debug("Something else pressed");
|
||||
}
|
||||
}
|
||||
@ -71,22 +88,26 @@ define(
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Demonstrates launching an error dialog
|
||||
*/
|
||||
$scope.launchError = function () {
|
||||
var model = {
|
||||
title: "Error Dialog Example",
|
||||
actionText: "Something happened, and it was not good.",
|
||||
severity: MessageSeverity.ERROR,
|
||||
actions: [
|
||||
severity: "error",
|
||||
options: [
|
||||
{
|
||||
label: "Try Again",
|
||||
action: function () {
|
||||
callback: function () {
|
||||
$log.debug("Try Again Pressed");
|
||||
dialogService.dismiss();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "Cancel",
|
||||
action: function () {
|
||||
callback: function () {
|
||||
$log.debug("Cancel Pressed");
|
||||
dialogService.dismiss();
|
||||
}
|
||||
@ -99,87 +120,30 @@ define(
|
||||
}
|
||||
};
|
||||
|
||||
$scope.launchMessages = function () {
|
||||
/*
|
||||
Demonstrates launching an error dialog
|
||||
*/
|
||||
$scope.launchInfo = function () {
|
||||
var model = {
|
||||
title: "Messages",
|
||||
severity: MessageSeverity.INFO,
|
||||
actions: [
|
||||
{
|
||||
label: "Done",
|
||||
action: function () {
|
||||
title: "Info Dialog Example",
|
||||
actionText: "This is an example of a blocking info" +
|
||||
" dialog. This dialog can be used to draw the user's" +
|
||||
" attention to an event.",
|
||||
severity: "info",
|
||||
primaryOption: {
|
||||
label: "OK",
|
||||
callback: function () {
|
||||
$log.debug("OK Pressed");
|
||||
dialogService.dismiss();
|
||||
}
|
||||
}
|
||||
],
|
||||
messages: []
|
||||
};
|
||||
|
||||
function getExampleActionText() {
|
||||
var actionTexts = [
|
||||
"Adipiscing turpis mauris in enim elementu hac, enim aliquam etiam.",
|
||||
"Eros turpis, pulvinar turpis eros eu",
|
||||
"Lundium nascetur a, lectus montes ac, parturient in natoque, duis risus risus pulvinar pid rhoncus, habitasse auctor natoque!"
|
||||
];
|
||||
return actionTexts[Math.floor(Math.random()*3)];
|
||||
if (!dialogService.showBlockingMessage(model)) {
|
||||
$log.error("Could not display modal dialog");
|
||||
}
|
||||
|
||||
function getExampleActions() {
|
||||
var actions = [
|
||||
{
|
||||
label: "Try Again",
|
||||
action: function () {
|
||||
$log.debug("Try Again pressed");
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "Remove",
|
||||
action: function () {
|
||||
$log.debug("Remove pressed");
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "Cancel",
|
||||
action: function () {
|
||||
$log.debug("Cancel pressed");
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
// Randomly remove some actions off the top; leave at least one
|
||||
actions.splice(0,Math.floor(Math.random() * actions.length));
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
function getExampleSeverity() {
|
||||
var severities = [
|
||||
MessageSeverity.INFO,
|
||||
MessageSeverity.ALERT,
|
||||
MessageSeverity.ERROR
|
||||
];
|
||||
return severities[Math.floor(Math.random() * severities.length)];
|
||||
}
|
||||
|
||||
function createMessage (messageNumber) {
|
||||
var messageModel = {
|
||||
title: "Message Title " + messageNumber,
|
||||
actionText: getExampleActionText(),
|
||||
severity: getExampleSeverity(),
|
||||
actions: getExampleActions()
|
||||
};
|
||||
return messageModel;
|
||||
}
|
||||
|
||||
function dismiss() {
|
||||
dialogService.dismiss();
|
||||
}
|
||||
|
||||
model.messages = notificationService.notifications;
|
||||
dialogService.getDialogResponse('overlay-message-list', {
|
||||
dialog: model,
|
||||
cancel: dismiss
|
||||
});
|
||||
};
|
||||
|
||||
}
|
||||
return DialogLaunchController;
|
||||
}
|
@ -26,6 +26,12 @@ define(
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* A tool for manually invoking dialogs. When included this
|
||||
* indicator will allow for dialogs of different types to be
|
||||
* launched for demonstration and testing purposes.
|
||||
* @constructor
|
||||
*/
|
||||
function DialogLaunchIndicator() {
|
||||
|
||||
}
|
@ -22,18 +22,25 @@
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
['../../../platform/commonUI/notification/src/MessageSeverity'],
|
||||
function (MessageSeverity) {
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Allows launching of notification messages for the purposes of
|
||||
* demonstration and testing. Also demonstrates use of
|
||||
* the NotificationService. Notifications are non-blocking messages that
|
||||
* appear at the bottom of the screen to inform the user of events
|
||||
* in a non-intrusive way. For more information see the
|
||||
* {@link NotificationService}
|
||||
* @param $scope
|
||||
* @param $timeout
|
||||
* @param $log
|
||||
* @param notificationService
|
||||
* @constructor
|
||||
*/
|
||||
function NotificationLaunchController($scope, $timeout, $log, notificationService) {
|
||||
var messageCounter = 1;
|
||||
$scope.newSuccess = function(){
|
||||
|
||||
notificationService.info({
|
||||
title: "Success notification!"
|
||||
});
|
||||
};
|
||||
|
||||
function getExampleActionText() {
|
||||
var actionTexts = [
|
||||
@ -48,19 +55,19 @@ define(
|
||||
var actions = [
|
||||
{
|
||||
label: "Try Again",
|
||||
action: function () {
|
||||
callback: function () {
|
||||
$log.debug("Try Again pressed");
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "Remove",
|
||||
action: function () {
|
||||
callback: function () {
|
||||
$log.debug("Remove pressed");
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "Cancel",
|
||||
action: function () {
|
||||
callback: function () {
|
||||
$log.debug("Cancel pressed");
|
||||
}
|
||||
}
|
||||
@ -74,65 +81,89 @@ define(
|
||||
|
||||
function getExampleSeverity() {
|
||||
var severities = [
|
||||
MessageSeverity.INFO,
|
||||
MessageSeverity.ALERT,
|
||||
MessageSeverity.ERROR
|
||||
"info",
|
||||
"alert",
|
||||
"error"
|
||||
];
|
||||
return severities[Math.floor(Math.random() * severities.length)];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Launch a new notification with a severity level of 'Error'.
|
||||
*/
|
||||
$scope.newError = function(){
|
||||
|
||||
notificationService.notify({
|
||||
title: "Error notification " + messageCounter++ + "!",
|
||||
title: "Example error notification " + messageCounter++,
|
||||
hint: "An error has occurred",
|
||||
severity: MessageSeverity.ERROR,
|
||||
primaryAction: {
|
||||
severity: "error",
|
||||
primaryOption: {
|
||||
label: 'Retry',
|
||||
action: function() {
|
||||
callback: function() {
|
||||
$log.info('Retry clicked');
|
||||
}
|
||||
},
|
||||
actions: getExampleActions()});
|
||||
options: getExampleActions()});
|
||||
};
|
||||
|
||||
/**
|
||||
* Launch a new notification with a severity of 'Alert'.
|
||||
*/
|
||||
$scope.newAlert = function(){
|
||||
|
||||
notificationService.notify({
|
||||
title: "Alert notification " + (messageCounter++) + "!",
|
||||
title: "Alert notification " + (messageCounter++),
|
||||
hint: "This is an alert message",
|
||||
severity: MessageSeverity.ALERT,
|
||||
primaryAction: {
|
||||
severity: "alert",
|
||||
primaryOption: {
|
||||
label: 'Retry',
|
||||
action: function() {
|
||||
callback: function() {
|
||||
$log.info('Retry clicked');
|
||||
}
|
||||
},
|
||||
actions: getExampleActions()});
|
||||
options: getExampleActions()});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Launch a new notification with a progress bar that is updated
|
||||
* periodically, tracking an ongoing process.
|
||||
*/
|
||||
$scope.newProgress = function(){
|
||||
|
||||
var notification = {
|
||||
title: "Progress notification!",
|
||||
severity: MessageSeverity.INFO,
|
||||
var notificationModel = {
|
||||
title: "Progress notification example",
|
||||
severity: "info",
|
||||
progress: 0,
|
||||
actionText: getExampleActionText(),
|
||||
unknownProgress: false
|
||||
|
||||
};
|
||||
|
||||
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);
|
||||
/**
|
||||
* Simulate an ongoing process and update the progress bar.
|
||||
* @param notification
|
||||
*/
|
||||
function incrementProgress(notificationModel) {
|
||||
notificationModel.progress = Math.min(100, Math.floor(notificationModel.progress + Math.random() * 30));
|
||||
notificationModel.progressText = ["Estimated time" +
|
||||
" remaining:" +
|
||||
" about ", 60 - Math.floor((notificationModel.progress / 100) * 60), " seconds"].join(" ");
|
||||
if (notificationModel.progress < 100) {
|
||||
$timeout(function(){incrementProgress(notificationModel);}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
notificationService.notify(notification);
|
||||
incrementProgress(notification);
|
||||
notificationService.notify(notificationModel);
|
||||
incrementProgress(notificationModel);
|
||||
};
|
||||
|
||||
/**
|
||||
* Launch a new notification with severity level of INFO.
|
||||
*/
|
||||
$scope.newInfo = function(){
|
||||
|
||||
notificationService.info({
|
||||
title: "Example Info notification " + messageCounter++
|
||||
});
|
||||
};
|
||||
|
||||
}
|
@ -1,9 +1,5 @@
|
||||
<div ng-controller="MessageController"
|
||||
class="l-message"
|
||||
ng-class="{
|
||||
'message-severity-info': ngModel.severity===MessageSeverity.INFO,
|
||||
'message-severity-error': ngModel.severity===MessageSeverity.ERROR,
|
||||
'message-severity-alert': ngModel.severity===MessageSeverity.ALERT}">
|
||||
<div class="l-message"
|
||||
ng-class="'message-severity-' + ngModel.severity">
|
||||
<div class="ui-symbol type-icon message-type"></div>
|
||||
<div class="message-contents">
|
||||
<div class="top-bar">
|
||||
@ -19,15 +15,15 @@
|
||||
ng-show="ngModel.progress !== undefined || ngModel.unknownProgress"></mct-include>
|
||||
</div>
|
||||
<div class="bottom-bar">
|
||||
<a ng-repeat="dialogAction in ngModel.actions"
|
||||
<a ng-repeat="dialogOption in ngModel.options"
|
||||
class="s-btn major"
|
||||
ng-click="dialogAction.action()">
|
||||
{{dialogAction.label}}
|
||||
ng-click="dialogOption.callback()">
|
||||
{{dialogOption.label}}
|
||||
</a>
|
||||
<a class="s-btn major"
|
||||
ng-if="ngModel.primaryAction"
|
||||
ng-click="ngModel.primaryAction.action()">
|
||||
{{ngModel.primaryAction.label}}
|
||||
ng-if="ngModel.primaryOption"
|
||||
ng-click="ngModel.primaryOption.callback()">
|
||||
{{ngModel.primaryOption.label}}
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
@ -178,7 +178,7 @@ define(
|
||||
* A user action that can be performed from a blocking dialog. These
|
||||
* actions will be rendered as buttons within a blocking dialog.
|
||||
*
|
||||
* @typedef DialogAction
|
||||
* @typedef DialogOption
|
||||
* @property {string} label a label to be displayed as the button
|
||||
* text for this action
|
||||
* @property {function} action a function to be called when the
|
||||
@ -207,12 +207,12 @@ 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
|
||||
* @property {DialogOption} primaryOption 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
|
||||
* @property {DialogOption[]} options a list of actions that will
|
||||
* be added to the dialog as buttons.
|
||||
*/
|
||||
|
||||
|
@ -121,6 +121,17 @@ define(
|
||||
);
|
||||
});
|
||||
|
||||
it("invokes the overlay service with the correct parameters when" +
|
||||
" a blocking dialog is requested", function() {
|
||||
var dialogModel = {};
|
||||
expect(dialogService.showBlockingMessage(dialogModel)).toBe(true);
|
||||
expect(mockOverlayService.createOverlay).toHaveBeenCalledWith(
|
||||
"overlay-blocking-message",
|
||||
dialogModel,
|
||||
"t-dialog-sm"
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
);
|
||||
|
@ -1,23 +1,20 @@
|
||||
<div ng-controller="BannerController" ng-show="active.notification"
|
||||
class="l-message-banner s-message-banner" ng-class="{
|
||||
'info': active.notification.severity===MessageSeverity.INFO,
|
||||
'alert': active.notification.severity===MessageSeverity.ALERT,
|
||||
'error': active.notification.severity===MessageSeverity.ERROR,
|
||||
'minimized': active.notification.minimized,
|
||||
'new': !active.notification.minimized}"
|
||||
class="l-message-banner s-message-banner {{active.notification.model.severity}}" ng-class="{
|
||||
'minimized': active.notification.model.minimized,
|
||||
'new': !active.notification.model.minimized}"
|
||||
ng-click="maximize(active.notification)">
|
||||
<span class="banner-elem label">
|
||||
{{active.notification.title}}
|
||||
{{active.notification.model.title}}
|
||||
</span>
|
||||
<span ng-show="active.notification.progress !== undefined || active.notification.unknownProgress">
|
||||
<span ng-show="active.notification.model.progress !== undefined || active.notification.model.unknownProgress">
|
||||
<mct-include key="'progress-bar'" class="banner-elem"
|
||||
ng-model="active.notification">
|
||||
ng-model="active.notification.model">
|
||||
</mct-include>
|
||||
</span>
|
||||
<a ng-hide="active.notification.primaryAction === undefined"
|
||||
<a ng-hide="active.notification.model.primaryOption === undefined"
|
||||
class="banner-elem l-action s-action"
|
||||
ng-click="action(active.notification.primaryAction.action, $event)">
|
||||
{{active.notification.primaryAction.label}}
|
||||
ng-click="action(active.notification.model.primaryOption.callback, $event)">
|
||||
{{active.notification.model.primaryOption.label}}
|
||||
</a>
|
||||
<a class="banner-elem ui-symbol close" ng-click="dismiss(active.notification, $event)">
|
||||
x</a>
|
||||
|
@ -22,26 +22,45 @@
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
['../../../notification/src/MessageSeverity'],
|
||||
function (MessageSeverity) {
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* A controller for banner notifications. Banner notifications are a
|
||||
* non-blocking way of drawing the user's attention to an event such
|
||||
* as system errors, or the progress or successful completion of an
|
||||
* ongoing task. This controller provides scoped functions for
|
||||
* dismissing and 'maximizing' notifications. See {@link NotificationService}
|
||||
* for more details on Notifications.
|
||||
*
|
||||
* @param $scope
|
||||
* @param notificationService
|
||||
* @param dialogService
|
||||
* @constructor
|
||||
*/
|
||||
function BannerController($scope, notificationService, dialogService) {
|
||||
$scope.active = notificationService.active;
|
||||
$scope.MessageSeverity = MessageSeverity;
|
||||
|
||||
$scope.action = function (action, $event){
|
||||
/*
|
||||
Prevents default 'maximize' behaviour when clicking on
|
||||
notification button
|
||||
*/
|
||||
$event.stopPropagation();
|
||||
return action();
|
||||
};
|
||||
$scope.dismiss = function(notification, $event) {
|
||||
$event.stopPropagation();
|
||||
notificationService.dismissOrMinimize(notification);
|
||||
notification.dismissOrMinimize();
|
||||
};
|
||||
$scope.maximize = function(notification) {
|
||||
if (notification.severity > MessageSeverity.INFO){
|
||||
notification.cancel = function(){
|
||||
if (notification.model.severity !== "info"){
|
||||
|
||||
notification.model.cancel = function(){
|
||||
dialogService.dismiss();
|
||||
};
|
||||
dialogService.showBlockingMessage(notification);
|
||||
dialogService.showBlockingMessage(notification.model);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -21,11 +21,6 @@
|
||||
}
|
||||
],
|
||||
"controllers": [
|
||||
{
|
||||
"key": "MessageController",
|
||||
"implementation": "MessageController.js",
|
||||
"depends": ["$scope"]
|
||||
},
|
||||
{
|
||||
"key": "NotificationIndicatorController",
|
||||
"implementation": "NotificationIndicatorController.js",
|
||||
@ -47,4 +42,4 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,5 @@
|
||||
<span ng-show="notifications.length > 0" class="status block"
|
||||
ng-class="{
|
||||
'info': highest.severity===MessageSeverity.INFO,
|
||||
'error': highest.severity===MessageSeverity.ERROR,
|
||||
'alert': highest.severity===MessageSeverity.ALERT }"
|
||||
ng-class="highest.severity"
|
||||
ng-controller="NotificationIndicatorController">
|
||||
<span class="ui-symbol status-indicator"></span>
|
||||
<span class="label">
|
||||
|
@ -1,34 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
['./MessageSeverity'],
|
||||
function (MessageSeverity) {
|
||||
"use strict";
|
||||
|
||||
function MessageController($scope) {
|
||||
$scope.MessageSeverity = MessageSeverity;
|
||||
}
|
||||
return MessageController;
|
||||
}
|
||||
);
|
@ -1,11 +0,0 @@
|
||||
/**
|
||||
* Created by akhenry on 10/7/15.
|
||||
*/
|
||||
/*global define*/
|
||||
define(function(){
|
||||
return {
|
||||
INFO: 0,
|
||||
ALERT: 1,
|
||||
ERROR: 2
|
||||
};
|
||||
});
|
@ -26,25 +26,10 @@ define(
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
function NotificationIndicator() {
|
||||
|
||||
}
|
||||
function NotificationIndicator() {}
|
||||
|
||||
NotificationIndicator.template = 'notificationIndicatorTemplate';
|
||||
|
||||
NotificationIndicator.prototype.getGlyph = function () {
|
||||
return "A";
|
||||
};
|
||||
NotificationIndicator.prototype.getGlyphClass = function () {
|
||||
return 'caution';
|
||||
};
|
||||
NotificationIndicator.prototype.getText = function () {
|
||||
return "Notifications";
|
||||
};
|
||||
NotificationIndicator.prototype.getDescription = function () {
|
||||
return "Notifications";
|
||||
};
|
||||
|
||||
return NotificationIndicator;
|
||||
}
|
||||
);
|
||||
|
@ -22,34 +22,38 @@
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
['./MessageSeverity'],
|
||||
function (MessageSeverity) {
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Provides an indicator that is visible when there are
|
||||
* banner notifications that have been minimized. Will also indicate
|
||||
* the number of notifications. Notifications can be viewed by
|
||||
* clicking on the indicator to launch a dialog showing a list of
|
||||
* notifications.
|
||||
* @param $scope
|
||||
* @param notificationService
|
||||
* @param dialogService
|
||||
* @constructor
|
||||
*/
|
||||
function NotificationIndicatorController($scope, notificationService, dialogService) {
|
||||
$scope.notifications = notificationService.notifications;
|
||||
$scope.highest = notificationService.highest;
|
||||
$scope.MessageSeverity = MessageSeverity;
|
||||
|
||||
/**
|
||||
* Launch a dialog showing a list of current notifications.
|
||||
*/
|
||||
$scope.showNotificationsList = function(){
|
||||
|
||||
var model = {
|
||||
title: "Messages",
|
||||
severity: MessageSeverity.INFO,
|
||||
actions: [
|
||||
{
|
||||
label: "Done",
|
||||
action: function () {
|
||||
dialogService.dismiss();
|
||||
}
|
||||
}
|
||||
],
|
||||
messages: []
|
||||
};
|
||||
|
||||
model.messages = notificationService.notifications;
|
||||
dialogService.getDialogResponse('overlay-message-list', {
|
||||
dialog: model,
|
||||
dialog: {
|
||||
title: "Messages",
|
||||
//Launch the message list dialog with the models
|
||||
// from the notifications
|
||||
messages: notificationService.notifications && notificationService.notifications.map(function(notification){
|
||||
return notification.model;
|
||||
})
|
||||
},
|
||||
cancel: function(){
|
||||
dialogService.dismiss();
|
||||
}
|
||||
@ -60,3 +64,4 @@ define(
|
||||
return NotificationIndicatorController;
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -29,21 +29,21 @@
|
||||
* dialogs so that the same information can be provided in a dialog
|
||||
* and then minimized to a banner notification if needed.
|
||||
*
|
||||
* @namespace platform/commonUI/dialog
|
||||
* @namespace platform/commonUI/notification
|
||||
*/
|
||||
define(
|
||||
["./MessageSeverity"],
|
||||
function (MessageSeverity) {
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* A representation of a user action. Actions are provided to
|
||||
* A representation of a user action. Options are provided to
|
||||
* dialogs and notifications and are shown as buttons.
|
||||
*
|
||||
* @typedef {object} NotificationAction
|
||||
* @typedef {object} NotificationOption
|
||||
* @property {string} label the label to appear on the button for
|
||||
* this action
|
||||
* @property {function} action a callback function to be invoked
|
||||
* @property {function} callback a callback function to be invoked
|
||||
* when the button is clicked
|
||||
*/
|
||||
|
||||
@ -54,10 +54,10 @@ define(
|
||||
* dialogs so that the same information can be provided in a dialog
|
||||
* and then minimized to a banner notification if needed.
|
||||
*
|
||||
* @typedef {object} Notification
|
||||
* @typedef {object} NotificationModel
|
||||
* @property {string} title The title of the message
|
||||
* @property {MessageSeverity} severity The importance of the
|
||||
* message (eg. error, info)
|
||||
* @property {string} severity The importance of the message (one of
|
||||
* 'info', 'alert', or 'error' where info < alert <error)
|
||||
* @property {number} progress The completion status of a task
|
||||
* represented numerically
|
||||
* @property {boolean} unknownProgress a boolean indicating that the
|
||||
@ -67,31 +67,55 @@ define(
|
||||
* be automatically minimized or dismissed (depending on severity).
|
||||
* Additionally, if the provided value is a number, it will be used
|
||||
* as the delay period before being dismissed.
|
||||
* @property {NotificationAction} primaryAction the default user
|
||||
* @property {NotificationOption} primaryOption the default user
|
||||
* response to
|
||||
* this message. Will be represented as a button with the provided
|
||||
* label and action. May be used by banner notifications to display
|
||||
* only the most important option to users.
|
||||
* @property {NotificationAction[]} actions any additional
|
||||
* @property {NotificationOption[]} options any additional
|
||||
* actions the user can take. Will be represented as additional buttons
|
||||
* that may or may not be available from a banner.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A wrapper object that is returned as a handle to a newly created
|
||||
* notification. Wraps the notifications model and decorates with
|
||||
* functions to dismiss or minimize the notification.
|
||||
*
|
||||
* @typedef {object} Notification
|
||||
* @property {function} dismiss This method is added to the object
|
||||
* returned by {@link NotificationService#notify} and can be used to
|
||||
* dismiss this notification. Dismissing a notification will remove
|
||||
* it completely and it will not appear in the notification indicator
|
||||
* @property {function} minimize This method is added to the object
|
||||
* returned by {@link NotificationService#notify} and can be used to
|
||||
* minimize this notification. Minimizing a notification will send
|
||||
* it to the notification indicator
|
||||
* @property {function} dismissOrMinimize This method is added to the
|
||||
* object returned by {@link NotificationService#notify}. It will
|
||||
* hide the notification by either dismissing or minimizing it,
|
||||
* depending on severity. Typically this is the method that should
|
||||
* be used for dismissing a notification. If more control is
|
||||
* required, then the minimize or dismiss functions can be called
|
||||
* individually.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The notification service is responsible for informing the user of
|
||||
* events via the use of banner notifications.
|
||||
* @memberof platform/commonUI/notification
|
||||
* @constructor
|
||||
* @param $timeout the Angular $timeout service
|
||||
* @param DEFAULT_AUTO_DISMISS The period of time that an
|
||||
* auto-dismissed message will be displayed for.
|
||||
* @param MINIMIZE_TIMEOUT When notifications are minimized, a brief
|
||||
* animation is shown. This animation requires some time to execute,
|
||||
* so a timeout is required before the notification is hidden
|
||||
* @constructor
|
||||
*/
|
||||
function NotificationService($timeout, DEFAULT_AUTO_DISMISS, MINIMIZE_TIMEOUT) {
|
||||
this.notifications = [];
|
||||
this.$timeout = $timeout;
|
||||
this.highest ={ severity: MessageSeverity.INFO };
|
||||
this.highest ={ severity: "info" };
|
||||
this.DEFAULT_AUTO_DISMISS = DEFAULT_AUTO_DISMISS;
|
||||
this.MINIMIZE_TIMEOUT = MINIMIZE_TIMEOUT;
|
||||
|
||||
@ -102,6 +126,83 @@ define(
|
||||
this.active = {};
|
||||
}
|
||||
|
||||
/*
|
||||
* Minimize a notification. The notification will still be available
|
||||
* from the notification list. Typically notifications with a
|
||||
* severity of 'info' should not be minimized, but rather
|
||||
* dismissed. If you're not sure which is appropriate,
|
||||
* use {@link Notification#dismissOrMinimize}
|
||||
*/
|
||||
function minimize (service, notification) {
|
||||
//Check this is a known notification
|
||||
var index = service.notifications.indexOf(notification);
|
||||
|
||||
if (service.active.timeout){
|
||||
/*
|
||||
Method can be called manually (clicking dismiss) or
|
||||
automatically from an auto-timeout. this.active.timeout
|
||||
acts as a semaphore to prevent race conditions. Cancel any
|
||||
timeout in progress (for the case where a manual dismiss
|
||||
has shortcut an active auto-dismiss), and clear the
|
||||
semaphore.
|
||||
*/
|
||||
service.$timeout.cancel(service.active.timeout);
|
||||
delete service.active.timeout;
|
||||
}
|
||||
|
||||
if (index >= 0) {
|
||||
notification.model.minimized=true;
|
||||
//Add a brief timeout before showing the next notification
|
||||
// in order to allow the minimize animation to run through.
|
||||
service.$timeout(function() {
|
||||
service.setActiveNotification(service.selectNextNotification());
|
||||
}, service.MINIMIZE_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 info should be
|
||||
* dismissed. If you're not sure whether to dismiss or minimize a
|
||||
* notification, use {@link Notification#dismissOrMinimize}.
|
||||
* dismiss
|
||||
*/
|
||||
function dismiss (service, notification) {
|
||||
//Check this is a known notification
|
||||
var index = service.notifications.indexOf(notification);
|
||||
|
||||
if (service.active.timeout){
|
||||
/* Method can be called manually (clicking dismiss) or
|
||||
* automatically from an auto-timeout. this.active.timeout
|
||||
* acts as a semaphore to prevent race conditions. Cancel any
|
||||
* timeout in progress (for the case where a manual dismiss
|
||||
* has shortcut an active auto-dismiss), and clear the
|
||||
* semaphore.
|
||||
*/
|
||||
|
||||
service.$timeout.cancel(service.active.timeout);
|
||||
delete service.active.timeout;
|
||||
}
|
||||
|
||||
if (index >= 0) {
|
||||
service.notifications.splice(index, 1);
|
||||
}
|
||||
service.setActiveNotification(service.selectNextNotification());
|
||||
}
|
||||
|
||||
/*
|
||||
* Depending on the severity of the notification will selectively
|
||||
* dismiss or minimize where appropriate.
|
||||
*/
|
||||
function dismissOrMinimize (notification){
|
||||
|
||||
//For now minimize everything, and have discussion around which
|
||||
//kind of messages should or should not be in the minimized
|
||||
//notifications list
|
||||
notification.minimize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the notification that is currently visible in the banner area
|
||||
* @returns {Notification}
|
||||
@ -114,12 +215,15 @@ define(
|
||||
* 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
|
||||
* @param {NotificationModel} notificationModel Options describing the
|
||||
* notification to display
|
||||
* @returns {Notification} the provided notification decorated with
|
||||
* functions to dismiss or minimize
|
||||
*/
|
||||
NotificationService.prototype.info = function (notification) {
|
||||
notification.autoDismiss = notification.autoDismiss || true;
|
||||
notification.severity = MessageSeverity.INFO;
|
||||
this.notify(notification);
|
||||
NotificationService.prototype.info = function (notificationModel) {
|
||||
notificationModel.autoDismiss = notificationModel.autoDismiss || true;
|
||||
notificationModel.severity = "info";
|
||||
return this.notify(notificationModel);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -127,20 +231,45 @@ define(
|
||||
* already active, then it will be dismissed or minimized automatically,
|
||||
* and the provided notification displayed in its place.
|
||||
*
|
||||
* @param {Notification} notification The notification to display
|
||||
* @param {NotificationModel} notificationModel The notification to
|
||||
* display
|
||||
* @returns {Notification} the provided notification decorated with
|
||||
* functions to {@link Notification#dismiss} or {@link Notification#minimize}
|
||||
*/
|
||||
NotificationService.prototype.notify = function (notification) {
|
||||
var self = this;
|
||||
NotificationService.prototype.notify = function (notificationModel) {
|
||||
var self = this,
|
||||
notification,
|
||||
ordinality = {
|
||||
"info": 1,
|
||||
"alert": 2,
|
||||
"error": 3
|
||||
},
|
||||
activeNotification = self.active.notification;
|
||||
|
||||
if (notification.autoDismiss === true){
|
||||
notification.autoDismiss = this.DEFAULT_AUTO_DISMISS;
|
||||
notification = {
|
||||
model: notificationModel,
|
||||
minimize: function() {
|
||||
minimize(self, notification);
|
||||
},
|
||||
dismiss: function(){
|
||||
dismiss(self, notification);
|
||||
},
|
||||
dismissOrMinimize: function(){
|
||||
dismissOrMinimize(notification);
|
||||
}
|
||||
};
|
||||
|
||||
notificationModel.severity = notificationModel.severity || "info";
|
||||
if (notificationModel.autoDismiss === true){
|
||||
notificationModel.autoDismiss = this.DEFAULT_AUTO_DISMISS;
|
||||
}
|
||||
|
||||
if (notification.severity > this.highest.severity){
|
||||
this.highest.severity = notification.severity;
|
||||
if (ordinality[notificationModel.severity.toLowerCase()] > ordinality[this.highest.severity.toLowerCase()]){
|
||||
this.highest.severity = notificationModel.severity;
|
||||
}
|
||||
|
||||
this.notifications.push(notification);
|
||||
|
||||
/*
|
||||
Check if there is already an active (ie. visible) notification
|
||||
*/
|
||||
@ -159,10 +288,12 @@ define(
|
||||
serviced as soon as possible.
|
||||
*/
|
||||
this.active.timeout = this.$timeout(function () {
|
||||
self.dismissOrMinimize(self.active.notification);
|
||||
activeNotification.dismissOrMinimize();
|
||||
}, this.DEFAULT_AUTO_DISMISS);
|
||||
}
|
||||
|
||||
return notification;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@ -180,12 +311,12 @@ define(
|
||||
notifications queued for display, setup a timeout to
|
||||
dismiss the dialog.
|
||||
*/
|
||||
if (notification && (notification.autoDismiss
|
||||
if (notification && (notification.model.autoDismiss
|
||||
|| this.selectNextNotification())) {
|
||||
|
||||
timeout = notification.autoDismiss || this.DEFAULT_AUTO_DISMISS;
|
||||
timeout = notification.model.autoDismiss || this.DEFAULT_AUTO_DISMISS;
|
||||
this.active.timeout = this.$timeout(function () {
|
||||
self.dismissOrMinimize(notification);
|
||||
notification.dismissOrMinimize();
|
||||
}, timeout);
|
||||
} else {
|
||||
delete this.active.timeout;
|
||||
@ -208,7 +339,7 @@ define(
|
||||
for (; i< this.notifications.length; i++) {
|
||||
notification = this.notifications[i];
|
||||
|
||||
if (!notification.minimized
|
||||
if (!notification.model.minimized
|
||||
&& notification!== this.active.notification) {
|
||||
|
||||
return notification;
|
||||
@ -216,69 +347,6 @@ define(
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Minimize a notification. The notification will still be available
|
||||
* from the notification list. Typically notifications with a
|
||||
* severity of 'info' should not be minimized, but rather
|
||||
* dismissed. If you're not sure which is appropriate,
|
||||
* use {@link NotificationService#dismissOrMinimize}
|
||||
* @see dismiss
|
||||
* @see dismissOrMinimize
|
||||
* @param notification
|
||||
*/
|
||||
NotificationService.prototype.minimize = function (notification) {
|
||||
//Check this is a known notification
|
||||
var index = this.notifications.indexOf(notification),
|
||||
self = this;
|
||||
if (index >= 0) {
|
||||
notification.minimized=true;
|
||||
//Add a brief timeout before showing the next notification
|
||||
// in order to allow the minimize animation to run through.
|
||||
this.$timeout(function() {
|
||||
self.setActiveNotification(self.selectNextNotification());
|
||||
}, this.MINIMIZE_TIMEOUT);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 info should be
|
||||
* dismissed. If you're not sure whether to dismiss or minimize a
|
||||
* notification, use {@link NotificationService#dismissOrMinimize}.
|
||||
* dismiss
|
||||
* @see dismissOrMinimize
|
||||
* @param notification The notification to dismiss
|
||||
*/
|
||||
NotificationService.prototype.dismiss = function (notification) {
|
||||
//Check this is a known notification
|
||||
var index = this.notifications.indexOf(notification);
|
||||
if (index >= 0) {
|
||||
this.notifications.splice(index, 1);
|
||||
}
|
||||
this.setActiveNotification(this.selectNextNotification());
|
||||
};
|
||||
|
||||
/**
|
||||
* Depending on the severity of the notification will selectively
|
||||
* dismiss or minimize where appropriate.
|
||||
* @see dismiss
|
||||
* @see minimize
|
||||
* @param notification
|
||||
*/
|
||||
NotificationService.prototype.dismissOrMinimize = function (notification){
|
||||
|
||||
//For now minimize everything, and have discussion around which
|
||||
//kind of messages should or should not be in the minimized
|
||||
//notifications list
|
||||
/*if (notification.severity > MessageSeverity.INFO){
|
||||
this.minimize(notification);
|
||||
} else {
|
||||
this.dismiss(notification);
|
||||
}*/
|
||||
this.minimize(notification);
|
||||
};
|
||||
|
||||
return NotificationService;
|
||||
}
|
||||
);
|
@ -0,0 +1,78 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,describe,it,expect,beforeEach,waitsFor,jasmine */
|
||||
|
||||
define(
|
||||
['../src/NotificationIndicatorController'],
|
||||
function (NotificationIndicatorController) {
|
||||
"use strict";
|
||||
|
||||
describe("The notification indicator controller ", function () {
|
||||
var mockNotificationService,
|
||||
mockScope,
|
||||
mockDialogService;
|
||||
|
||||
beforeEach(function(){
|
||||
mockNotificationService = jasmine.createSpy("notificationService");
|
||||
mockScope = jasmine.createSpy("$scope");
|
||||
mockDialogService = jasmine.createSpyObj(
|
||||
"dialogService",
|
||||
["getDialogResponse","dismiss"]
|
||||
);
|
||||
});
|
||||
|
||||
it("exposes the highest notification severity to the template", function() {
|
||||
mockNotificationService.highest = {
|
||||
severity: "error"
|
||||
};
|
||||
var controller = new NotificationIndicatorController(mockScope, mockNotificationService, mockDialogService);
|
||||
expect(mockScope.highest).toBeTruthy();
|
||||
expect(mockScope.highest.severity).toBe("error");
|
||||
});
|
||||
|
||||
it("invokes the dialog service to show list of messages", function() {
|
||||
var controller = new NotificationIndicatorController(mockScope, mockNotificationService, mockDialogService);
|
||||
expect(mockScope.showNotificationsList).toBeDefined();
|
||||
mockScope.showNotificationsList();
|
||||
expect(mockDialogService.getDialogResponse).toHaveBeenCalled();
|
||||
expect(mockDialogService.getDialogResponse.mostRecentCall.args[0]).toBe('overlay-message-list');
|
||||
expect(mockDialogService.getDialogResponse.mostRecentCall.args[1].dialog).toBeDefined();
|
||||
expect(mockDialogService.getDialogResponse.mostRecentCall.args[1].cancel).toBeDefined();
|
||||
//Invoke the cancel callback
|
||||
mockDialogService.getDialogResponse.mostRecentCall.args[1].cancel();
|
||||
expect(mockDialogService.dismiss).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("provides a means of dismissing the message list", function() {
|
||||
var controller = new NotificationIndicatorController(mockScope, mockNotificationService, mockDialogService);
|
||||
expect(mockScope.showNotificationsList).toBeDefined();
|
||||
mockScope.showNotificationsList();
|
||||
expect(mockDialogService.getDialogResponse).toHaveBeenCalled();
|
||||
expect(mockDialogService.getDialogResponse.mostRecentCall.args[1].cancel).toBeDefined();
|
||||
//Invoke the cancel callback
|
||||
mockDialogService.getDialogResponse.mostRecentCall.args[1].cancel();
|
||||
expect(mockDialogService.dismiss).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
@ -22,8 +22,8 @@
|
||||
/*global define,describe,it,expect,beforeEach,waitsFor,jasmine */
|
||||
|
||||
define(
|
||||
['../src/NotificationService','../src/MessageSeverity'],
|
||||
function (NotificationService, MessageSeverity) {
|
||||
['../src/NotificationService'],
|
||||
function (NotificationService) {
|
||||
"use strict";
|
||||
|
||||
describe("The notification service ", function () {
|
||||
@ -34,46 +34,6 @@ define(
|
||||
successModel,
|
||||
errorModel;
|
||||
|
||||
/**
|
||||
* 1) Calling .notify results in a new notification being created
|
||||
* with the provided model and set to the active notification. DONE
|
||||
*
|
||||
* 2) Calling .notify with autoDismiss results in a SUCCESS notification
|
||||
* becoming dismissed after timeout has elapsed DONE
|
||||
*
|
||||
* 3) Calling .notify with autoDismiss results in an ERROR notification
|
||||
* being MINIMIZED after a timeout has elapsed DONE
|
||||
*
|
||||
* 4) Calling .notify with an active info notification results in that
|
||||
* notification being auto-dismissed, and the new notification becoming
|
||||
* active. DONE
|
||||
*
|
||||
* 5) Calling .notify with an active error notification results in that
|
||||
* notification being auto-minimized and the new notification becoming
|
||||
* active. DONE
|
||||
*
|
||||
* 6) Calling .notify with an active error notification, AND a
|
||||
* queued error notification results in the active notification
|
||||
* being auto-dismissed, the next message in the queue becoming
|
||||
* active, then auto-dismissed, and then the provided notification
|
||||
* becoming active.
|
||||
*/
|
||||
|
||||
/**
|
||||
var model = {
|
||||
title: string,
|
||||
progress: number,
|
||||
severity: MessageSeverity,
|
||||
unknownProgress: boolean,
|
||||
minimized: boolean,
|
||||
autoDismiss: boolean | number,
|
||||
actions: {
|
||||
label: string,
|
||||
action: function
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
beforeEach(function(){
|
||||
mockTimeout = jasmine.createSpy("$timeout");
|
||||
mockAutoDismiss = mockMinimizeTimeout = 1000;
|
||||
@ -81,11 +41,11 @@ define(
|
||||
mockTimeout, mockAutoDismiss, mockMinimizeTimeout);
|
||||
successModel = {
|
||||
title: "Mock Success Notification",
|
||||
severity: MessageSeverity.INFO
|
||||
severity: "info"
|
||||
};
|
||||
errorModel = {
|
||||
title: "Mock Error Notification",
|
||||
severity: MessageSeverity.ERROR
|
||||
severity: "error"
|
||||
};
|
||||
});
|
||||
|
||||
@ -94,7 +54,7 @@ define(
|
||||
var activeNotification;
|
||||
notificationService.notify(successModel);
|
||||
activeNotification = notificationService.getActiveNotification();
|
||||
expect(activeNotification).toBe(successModel);
|
||||
expect(activeNotification.model).toBe(successModel);
|
||||
});
|
||||
|
||||
it("gets a new success notification with" +
|
||||
@ -103,7 +63,7 @@ define(
|
||||
successModel.autoDismiss = 1000;
|
||||
notificationService.notify(successModel);
|
||||
activeNotification = notificationService.getActiveNotification();
|
||||
expect(activeNotification).toBe(successModel);
|
||||
expect(activeNotification.model).toBe(successModel);
|
||||
mockTimeout.mostRecentCall.args[0]();
|
||||
expect(mockTimeout.calls.length).toBe(2);
|
||||
mockTimeout.mostRecentCall.args[0]();
|
||||
@ -117,7 +77,7 @@ define(
|
||||
successModel.autoDismiss = true;
|
||||
notificationService.notify(successModel);
|
||||
activeNotification = notificationService.getActiveNotification();
|
||||
expect(activeNotification).toBe(successModel);
|
||||
expect(activeNotification.model).toBe(successModel);
|
||||
mockTimeout.mostRecentCall.args[0]();
|
||||
expect(mockTimeout.calls.length).toBe(2);
|
||||
mockTimeout.mostRecentCall.args[0]();
|
||||
@ -125,6 +85,37 @@ define(
|
||||
expect(activeNotification).toBeUndefined();
|
||||
});
|
||||
|
||||
it("allows minimization of notifications", function() {
|
||||
var notification,
|
||||
activeNotification;
|
||||
|
||||
successModel.autoDismiss = false;
|
||||
notification = notificationService.notify(successModel);
|
||||
|
||||
activeNotification = notificationService.getActiveNotification();
|
||||
expect(activeNotification.model).toBe(successModel);
|
||||
notification.minimize();
|
||||
mockTimeout.mostRecentCall.args[0]();
|
||||
activeNotification = notificationService.getActiveNotification();
|
||||
expect(activeNotification).toBeUndefined();
|
||||
expect(notificationService.notifications.length).toBe(1);
|
||||
});
|
||||
|
||||
it("allows dismissal of notifications", function() {
|
||||
var notification,
|
||||
activeNotification;
|
||||
|
||||
successModel.autoDismiss = false;
|
||||
notification = notificationService.notify(successModel);
|
||||
|
||||
activeNotification = notificationService.getActiveNotification();
|
||||
expect(activeNotification.model).toBe(successModel);
|
||||
notification.dismiss();
|
||||
activeNotification = notificationService.getActiveNotification();
|
||||
expect(activeNotification).toBeUndefined();
|
||||
expect(notificationService.notifications.length).toBe(0);
|
||||
});
|
||||
|
||||
describe(" gets called with multiple notifications", function(){
|
||||
it("auto-dismisses the previously active notification, making" +
|
||||
" the new notification active", function() {
|
||||
@ -134,7 +125,7 @@ define(
|
||||
activeNotification =
|
||||
notificationService.getActiveNotification();
|
||||
//Initially expect the active notification to be info
|
||||
expect(activeNotification).toBe(successModel);
|
||||
expect(activeNotification.model).toBe(successModel);
|
||||
//Then notify of an error
|
||||
notificationService.notify(errorModel);
|
||||
//But it should be auto-dismissed and replaced with the
|
||||
@ -145,25 +136,8 @@ define(
|
||||
// second is to allow minimization animation to take place.
|
||||
mockTimeout.mostRecentCall.args[0]();
|
||||
activeNotification = notificationService.getActiveNotification();
|
||||
expect(activeNotification).toBe(errorModel);
|
||||
expect(activeNotification.model).toBe(errorModel);
|
||||
});
|
||||
/* Test is temporarily invalid as info messages are being
|
||||
minimized
|
||||
it("auto-dismisses an active success notification, removing" +
|
||||
" it completely", function() {
|
||||
//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]();
|
||||
//Two timeouts, one is to force minimization after
|
||||
// displaying the message for a minimum period, the
|
||||
// second is to allow minimization animation to take place.
|
||||
mockTimeout.mostRecentCall.args[0]();
|
||||
//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
|
||||
@ -182,7 +156,7 @@ define(
|
||||
expect(notificationService.notifications.length).toEqual(2);
|
||||
activeNotification =
|
||||
notificationService.getActiveNotification();
|
||||
expect(activeNotification).toBe(successModel);
|
||||
expect(activeNotification.model).toBe(successModel);
|
||||
expect(errorModel.minimized).toEqual(true);
|
||||
});
|
||||
it("auto-minimizes errors when a number of them arrive in" +
|
||||
@ -190,11 +164,11 @@ define(
|
||||
var activeNotification,
|
||||
error2 = {
|
||||
title: "Second Mock Error Notification",
|
||||
severity: MessageSeverity.ERROR
|
||||
severity: "error"
|
||||
},
|
||||
error3 = {
|
||||
title: "Third Mock Error Notification",
|
||||
severity: MessageSeverity.ERROR
|
||||
severity: "error"
|
||||
};
|
||||
|
||||
//First pre-load with a info message
|
||||
@ -214,7 +188,7 @@ define(
|
||||
expect(notificationService.notifications.length).toEqual(3);
|
||||
activeNotification =
|
||||
notificationService.getActiveNotification();
|
||||
expect(activeNotification).toBe(error2);
|
||||
expect(activeNotification.model).toBe(error2);
|
||||
expect(errorModel.minimized).toEqual(true);
|
||||
|
||||
//Mock the second auto-minimize
|
||||
@ -225,10 +199,11 @@ define(
|
||||
mockTimeout.mostRecentCall.args[0]();
|
||||
activeNotification =
|
||||
notificationService.getActiveNotification();
|
||||
expect(activeNotification).toBe(error3);
|
||||
expect(activeNotification.model).toBe(error3);
|
||||
expect(error2.minimized).toEqual(true);
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
@ -1,3 +1,4 @@
|
||||
[
|
||||
"NotificationService"
|
||||
]
|
||||
"NotificationService",
|
||||
"NotificationIndicatorController"
|
||||
]
|
||||
|
@ -44,14 +44,12 @@ define(
|
||||
|
||||
function progress(phase, totalObjects, processed){
|
||||
if (phase.toLowerCase() === 'preparing'){
|
||||
console.log('preparing');
|
||||
dialogService.showBlockingMessage({
|
||||
title: "Preparing to copy objects",
|
||||
unknownProgress: true,
|
||||
severity: "info",
|
||||
});
|
||||
} else if (phase.toLowerCase() === "copying") {
|
||||
console.log('copying');
|
||||
dialogService.dismiss();
|
||||
if (!notification) {
|
||||
notification = notificationService.notify(notificationModel);
|
||||
|
@ -113,14 +113,14 @@ define(
|
||||
|
||||
function newPerform (domainObject, parent, progress) {
|
||||
var $q = this.$q,
|
||||
processed = 0,
|
||||
self = this;
|
||||
if (this.validate(domainObject, parent)) {
|
||||
progress("preparing");
|
||||
return this.buildCopyGraph(domainObject, parent)
|
||||
.then(function(clones){
|
||||
return $q.all(clones.map(function(clone, index){
|
||||
progress("copying", clones.length, index);
|
||||
return self.persistenceService.createObject(clone.persistence.getSpace(), clone.model.id, clone.model);
|
||||
return self.persistenceService.createObject(clone.persistence.getSpace(), clone.model.id, clone.model).then(function(){progress("copying", clones.length, processed++);});
|
||||
})).then(function(){ return clones});
|
||||
})
|
||||
.then(function(clones) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user