Merging in Andrew's work so far on progress and blocking dialogs

open #163
open #170

Squashed commit of the following:

commit ec7edb58ca75b409d330b5434999c67a0ec14e33
Author: Henry <akhenry@aitutaki.ndc.nasa.gov>
Date:   Mon Oct 5 10:39:06 2015 -0700

    Rename dialogSeverity to messageServity for reuse with notifications

commit d20abe01dda50f7508444ed65b207cb6210e5fff
Author: Henry <akhenry@aitutaki.ndc.nasa.gov>
Date:   Fri Oct 2 16:40:29 2015 -0700

    Fixed docs

commit 227da1849826af54c66932dba55f692e085194b5
Author: Henry <akhenry@aitutaki.ndc.nasa.gov>
Date:   Fri Oct 2 16:27:41 2015 -0700

    Added semicolon

commit 22d424f96e74e44230f100cde2108aff4ef10944
Author: Henry <akhenry@aitutaki.ndc.nasa.gov>
Date:   Fri Oct 2 16:26:29 2015 -0700

    Fixed code errors

commit 2c77c3647c326f91fdbe2d63a8e3f1c3040d7397
Author: Henry <akhenry@aitutaki.ndc.nasa.gov>
Date:   Fri Oct 2 16:24:01 2015 -0700

    Initial commit of blocking dialog service with test code to demonstrate usage
This commit is contained in:
Charles Hacskaylo 2015-10-06 14:41:58 -07:00
parent 471a25a625
commit 2aeebff652
8 changed files with 321 additions and 12 deletions

View File

@ -29,5 +29,7 @@
"example/imagery",
"example/eventGenerator",
"example/generator"
"example/generator",
"testing/dialogTest"
]

View File

@ -1,5 +1,15 @@
{
"extensions": {
"constants": [
{
"key": "messageSeverity",
"value": {
"ERROR": "error",
"INFO": "info",
"SUCCESS": "success"
}
}
],
"services": [
{
"key": "dialogService",
@ -24,6 +34,10 @@
{
"key": "form-dialog",
"templateUrl": "templates/dialog.html"
},
{
"key": "blocking-message",
"templateUrl": "templates/blocking-message.html"
}
],
"containers": [

View File

@ -0,0 +1,30 @@
<style>
.severity-error {
color: #d9534f;
}
.severity-info {
}
.time-estimate {
color: darkgray;
}
.dialog-content {
margin-top: 5em;
}
</style>
<mct-container key="overlay">
<div class="abs top-bar severity-{{ngModel.dialog.severity}}">
<div class="title">{{ngModel.dialog.title}}</div>
</div>
<div class="abs outline">
<div class='abs contents l-dialog dialog-content'>
<div class="hint">{{ngModel.dialog.hint}}</div>
<br />
<div ng-hide="ngModel.dialog.progress === undefined" style="background-color: darkgray; width: 100%; height: 1em;"><div ng-show="ngModel.dialog.progress > 0" style="color: #2e2e2e; background-color: lightgray; text-align: center; min-width: 2em; width: {{ngModel.dialog.progress}}%">{{ngModel.dialog.progress}} %</div></div>
<div class="time-estimate" ng-hide="ngModel.dialog.progressText === undefined">{{ngModel.dialog.progressText}}</div>
</div>
</div>
<div class="abs bottom-bar">
<span ng-repeat="dialogAction in ngModel.dialog.actions"><input type="button" value="{{dialogAction.label}}" ng-click="dialogAction.action()"></span>
</div>
</mct-container>

View File

@ -84,17 +84,7 @@ define(
model.confirm = confirm;
model.cancel = cancel;
if (this.dialogVisible) {
// Only one dialog should be shown at a time.
// The application design should be such that
// we never even try to do this.
this.$log.warn([
"Dialog already showing; ",
"unable to show ",
model.name
].join(""));
deferred.reject();
} else {
if (this.canShowDialog(model)) {
// Add the overlay using the OverlayService, which
// will handle actual insertion into the DOM
this.overlay = this.overlayService.createOverlay(
@ -105,6 +95,8 @@ define(
// Track that a dialog is already visible, to
// avoid spawning multiple dialogs at once.
this.dialogVisible = true;
} else {
deferred.reject();
}
return deferred.promise;
@ -157,6 +149,104 @@ define(
);
};
/**
* Tests if a dialog can be displayed. A modal dialog may only be
* displayed if one is not already visible.
* Will log a warning message if it can't display a dialog.
* @returns {boolean} true if dialog is currently visible, false
* otherwise
*/
DialogService.prototype.canShowDialog = function(dialogModel){
if (this.dialogVisible){
// Only one dialog should be shown at a time.
// The application design should be such that
// we never even try to do this.
this.$log.warn([
"Dialog already showing; ",
"unable to show ",
dialogModel.title
].join(""));
return false;
} else {
return true;
}
};
/**
* dialogModel: {
* severity: string "error" | "info",
* title: string,
* hint: string,
* progress: int,
* progressText: string,
* unknownProgress: boolean,
* actions: [{
* label: String,
* action: function
* }]
*/
/**
* A user action that can be performed from a blocking dialog. These
* actions will be rendered as buttons within a blocking dialog.
*
* @typedef DialogAction
* @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
* button is clicked
*/
/**
* A description of the model options that may be passed to the
* showBlockingMessage method
*
* @typedef DialogModel
* @property {string} severity the severity level of this message.
* These are defined in a bundle constant with key 'dialogSeverity'
* @property {string} title the title to use for the dialog
* @property {string} hint the 'hint' message to show below the title
* @property {number} progress a percentage value (1-100)
* indicating the completion of the blocking task
* @property {string} progressText the message to show below a
* progress bar to indicate progress. For example, this might be
* used to indicate time remaining, or items still to process.
* @property {boolean} unknownProgress some tasks may be
* 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[]} actions a list of actions that will
* be added to the dialog as buttons. These buttons are
*/
/**
* Displays a blocking (modal) dialog. This dialog can be used for
* displaying messages that require the user's
* immediate attention. The message may include an indication of
* progress, as well as a series of actions that
* the user can take if necessary
* @param {DialogModel} dialogModel defines options for the dialog
* @returns {boolean}
*/
DialogService.prototype.showBlockingMessage = function(dialogModel) {
if (this.canShowDialog(dialogModel)) {
// Add the overlay using the OverlayService, which
// will handle actual insertion into the DOM
this.overlay = this.overlayService.createOverlay(
"blocking-message",
{dialog: dialogModel}
);
this.dialogVisible = true;
return true;
} else {
//Could not show a dialog, so return indication of this to
//client code.
return false;
}
};
return DialogService;
}

View File

@ -0,0 +1,28 @@
{
"extensions": {
"templates": [
{
"key": "dialogLaunchTemplate",
"templateUrl": "dialog-launch.html"
}
],
"controllers": [
{
"key": "DialogLaunchController",
"implementation": "DialogLaunchController.js",
"depends": [
"$scope",
"dialogService",
"$timeout",
"$log",
"messageSeverity"
]
}
],
"indicators": [
{
"implementation": "DialogLaunchIndicator.js"
}
]
}
}

View File

@ -0,0 +1 @@
<span ng-controller="DialogLaunchController"><input type="button" value="Launch progress" ng-click="launchProgress()" /></span>&nbsp;&nbsp;<span ng-controller="DialogLaunchController"><input type="button" value="Launch error" ng-click="launchError()" /></span>

View File

@ -0,0 +1,94 @@
/*****************************************************************************
* 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(
[],
function () {
"use strict";
function DialogLaunchController($scope, dialogService, $timeout, $log, messageSeverity) {
$scope.launchProgress = function () {
var model = {
title: "Progress dialog example",
progress: 0,
hint: "Calculating...",
unknownDuration: false,
severity: messageSeverity.INFO,
actions: [
{
label: "Cancel Operation",
action: function () {
$log.debug("Operation cancelled");
dialogService.dismiss();
}
},
{
label: "Do something else...",
action: function () {
$log.debug("Something else pressed");
}
}
]
};
function incrementProgress() {
model.progress = Math.min(100, Math.floor(model.progress + Math.random() * 30));
model.progressText = ["Estimated time remaining: about ", 60 - Math.floor((model.progress / 100) * 60), " seconds"].join(" ");
if (model.progress < 100) {
$timeout(incrementProgress, 1000);
}
}
if (dialogService.showBlockingMessage(model)) {
//Do processing here
model.hint = "Processing 100 objects...";
$timeout(incrementProgress, 1000);
} else {
$log.error("Could not display modal dialog");
}
};
$scope.launchError = function () {
var model = {
title: "Error Message Title",
hint: "Something happened. It was not so good.",
severity: messageSeverity.ERROR,
actions: [
{
label: "OK",
action: function () {
$log.debug("OK Pressed");
dialogService.dismiss();
}
}
]
};
if (!dialogService.showBlockingMessage(model)) {
$log.error("Could not display modal dialog");
}
};
}
return DialogLaunchController;
}
);

View File

@ -0,0 +1,50 @@
/*****************************************************************************
* 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,window*/
define(
[],
function () {
"use strict";
function DialogLaunchIndicator() {
}
DialogLaunchIndicator.template = 'dialogLaunchTemplate';
DialogLaunchIndicator.prototype.getGlyph = function () {
return "i";
};
DialogLaunchIndicator.prototype.getGlyphClass = function () {
return 'caution';
};
DialogLaunchIndicator.prototype.getText = function () {
return "Launch test dialog";
};
DialogLaunchIndicator.prototype.getDescription = function () {
return "Launch test dialog";
};
return DialogLaunchIndicator;
}
);