diff --git a/bundles.json b/bundles.json index 48429bdf88..291553ba11 100644 --- a/bundles.json +++ b/bundles.json @@ -11,6 +11,7 @@ "platform/commonUI/inspect", "platform/commonUI/mobile", "platform/commonUI/themes/espresso", + "platform/commonUI/notification", "platform/containment", "platform/execution", "platform/telemetry", diff --git a/example/notifications/bundle.json b/example/notifications/bundle.json new file mode 100644 index 0000000000..bb2d464d64 --- /dev/null +++ b/example/notifications/bundle.json @@ -0,0 +1,47 @@ +{ + "extensions": { + "templates": [ + { + "key": "dialogLaunchTemplate", + "templateUrl": "dialog-launch.html" + }, + { + "key": "notificationLaunchTemplate", + "templateUrl": "notification-launch.html" + } + ], + "controllers": [ + { + "key": "DialogLaunchController", + "implementation": "DialogLaunchController.js", + "depends": [ + "$scope", + "$timeout", + "$log", + "dialogService", + "notificationService" + ] + }, + { + "key": "NotificationLaunchController", + "implementation": "NotificationLaunchController.js", + "depends": [ + "$scope", + "$timeout", + "$log", + "notificationService" + ] + } + ], + "indicators": [ + { + "implementation": "DialogLaunchIndicator.js", + "priority": "fallback" + }, + { + "implementation": "NotificationLaunchIndicator.js", + "priority": "fallback" + } + ] + } +} diff --git a/example/notifications/res/dialog-launch.html b/example/notifications/res/dialog-launch.html new file mode 100644 index 0000000000..bc56e6b4f2 --- /dev/null +++ b/example/notifications/res/dialog-launch.html @@ -0,0 +1,10 @@ + + + + Known | + Unknown | + Error | + Info + + Dialogs + \ No newline at end of file diff --git a/example/notifications/res/notification-launch.html b/example/notifications/res/notification-launch.html new file mode 100644 index 0000000000..1e077bf3be --- /dev/null +++ b/example/notifications/res/notification-launch.html @@ -0,0 +1,10 @@ + + + + Success | + Error | + Alert | + Progress + + Notifications + \ No newline at end of file diff --git a/example/notifications/src/DialogLaunchController.js b/example/notifications/src/DialogLaunchController.js new file mode 100644 index 0000000000..f35d008cd0 --- /dev/null +++ b/example/notifications/src/DialogLaunchController.js @@ -0,0 +1,150 @@ +/***************************************************************************** + * 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"; + + /** + * 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", + progress: 0, + hint: "Do not navigate away from this page or close this browser tab while this operation is in progress.", + actionText: "Calculating...", + unknownProgress: !knownProgress, + unknownDuration: false, + severity: "info", + options: [ + { + label: "Cancel Operation", + callback: function () { + $log.debug("Operation cancelled"); + dialogService.dismiss(); + } + }, + { + label: "Do something else...", + callback: 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.actionText = "Processing 100 objects..."; + if (knownProgress) { + $timeout(incrementProgress, 1000); + } + } else { + $log.error("Could not display modal dialog"); + } + }; + + + /* + Demonstrates launching an error dialog + */ + $scope.launchError = function () { + var model = { + title: "Error Dialog Example", + actionText: "Something happened, and it was not good.", + severity: "error", + options: [ + { + label: "Try Again", + callback: function () { + $log.debug("Try Again Pressed"); + dialogService.dismiss(); + } + }, + { + label: "Cancel", + callback: function () { + $log.debug("Cancel Pressed"); + dialogService.dismiss(); + } + } + ] + }; + + if (!dialogService.showBlockingMessage(model)) { + $log.error("Could not display modal dialog"); + } + }; + + /* + Demonstrates launching an error dialog + */ + $scope.launchInfo = function () { + var model = { + 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(); + } + } + }; + + if (!dialogService.showBlockingMessage(model)) { + $log.error("Could not display modal dialog"); + } + }; + + } + return DialogLaunchController; + } +); diff --git a/example/notifications/src/DialogLaunchIndicator.js b/example/notifications/src/DialogLaunchIndicator.js new file mode 100644 index 0000000000..9330ce2194 --- /dev/null +++ b/example/notifications/src/DialogLaunchIndicator.js @@ -0,0 +1,56 @@ +/***************************************************************************** + * 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"; + + /** + * 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() { + + } + + 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; + } +); diff --git a/example/notifications/src/NotificationLaunchController.js b/example/notifications/src/NotificationLaunchController.js new file mode 100644 index 0000000000..851e0575f5 --- /dev/null +++ b/example/notifications/src/NotificationLaunchController.js @@ -0,0 +1,172 @@ +/***************************************************************************** + * 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"; + + /** + * 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; + + 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)]; + } + + function getExampleActions() { + var actions = [ + { + label: "Try Again", + callback: function () { + $log.debug("Try Again pressed"); + } + }, + { + label: "Remove", + callback: function () { + $log.debug("Remove pressed"); + } + }, + { + label: "Cancel", + callback: 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 = [ + "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: "Example error notification " + messageCounter++, + hint: "An error has occurred", + severity: "error", + primaryOption: { + label: 'Retry', + callback: function() { + $log.info('Retry clicked'); + } + }, + options: getExampleActions()}); + }; + /** + * Launch a new notification with a severity of 'Alert'. + */ + $scope.newAlert = function(){ + + notificationService.notify({ + title: "Alert notification " + (messageCounter++), + hint: "This is an alert message", + severity: "alert", + primaryOption: { + label: 'Retry', + callback: function() { + $log.info('Retry clicked'); + } + }, + options: getExampleActions()}); + }; + + + /** + * Launch a new notification with a progress bar that is updated + * periodically, tracking an ongoing process. + */ + $scope.newProgress = function(){ + + var notificationModel = { + title: "Progress notification example", + severity: "info", + progress: 0, + actionText: getExampleActionText(), + unknownProgress: false + }; + + /** + * 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(notificationModel); + incrementProgress(notificationModel); + }; + + /** + * Launch a new notification with severity level of INFO. + */ + $scope.newInfo = function(){ + + notificationService.info({ + title: "Example Info notification " + messageCounter++ + }); + }; + + } + return NotificationLaunchController; + } +); diff --git a/example/notifications/src/NotificationLaunchIndicator.js b/example/notifications/src/NotificationLaunchIndicator.js new file mode 100644 index 0000000000..174810d721 --- /dev/null +++ b/example/notifications/src/NotificationLaunchIndicator.js @@ -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 NotificationLaunchIndicator() { + + } + + NotificationLaunchIndicator.template = 'notificationLaunchTemplate'; + + NotificationLaunchIndicator.prototype.getGlyph = function () { + return "i"; + }; + NotificationLaunchIndicator.prototype.getGlyphClass = function () { + return 'caution'; + }; + NotificationLaunchIndicator.prototype.getText = function () { + return "Launch notification"; + }; + NotificationLaunchIndicator.prototype.getDescription = function () { + return "Launch notification"; + }; + + return NotificationLaunchIndicator; + } +); diff --git a/platform/commonUI/dialog/bundle.json b/platform/commonUI/dialog/bundle.json index 9a2d541419..80cd456c20 100644 --- a/platform/commonUI/dialog/bundle.json +++ b/platform/commonUI/dialog/bundle.json @@ -24,6 +24,18 @@ { "key": "form-dialog", "templateUrl": "templates/dialog.html" + }, + { + "key": "overlay-blocking-message", + "templateUrl": "templates/overlay-blocking-message.html" + }, + { + "key": "message", + "templateUrl": "templates/message.html" + }, + { + "key": "overlay-message-list", + "templateUrl": "templates/overlay-message-list.html" } ], "containers": [ diff --git a/platform/commonUI/dialog/res/templates/dialog.html b/platform/commonUI/dialog/res/templates/dialog.html index e3379b034e..2fe2411875 100644 --- a/platform/commonUI/dialog/res/templates/dialog.html +++ b/platform/commonUI/dialog/res/templates/dialog.html @@ -21,17 +21,13 @@ -->
{{ngModel.title}}
-
- All fields marked * are required. -
+
All fields marked * are required.
-
-
- - -
+
+ +
+
+
+
\ No newline at end of file diff --git a/platform/commonUI/dialog/res/templates/overlay-blocking-message.html b/platform/commonUI/dialog/res/templates/overlay-blocking-message.html new file mode 100644 index 0000000000..17fdcf152c --- /dev/null +++ b/platform/commonUI/dialog/res/templates/overlay-blocking-message.html @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/platform/commonUI/dialog/res/templates/overlay-message-list.html b/platform/commonUI/dialog/res/templates/overlay-message-list.html new file mode 100644 index 0000000000..026ef1cbb1 --- /dev/null +++ b/platform/commonUI/dialog/res/templates/overlay-message-list.html @@ -0,0 +1,19 @@ + +
+
+
{{ngModel.dialog.title}}
+
Displaying {{ngModel.dialog.messages.length}} messages +
+
+
+ +
+ +
+
\ No newline at end of file diff --git a/platform/commonUI/dialog/res/templates/overlay-options.html b/platform/commonUI/dialog/res/templates/overlay-options.html index 2f572e20a5..7de75df31c 100644 --- a/platform/commonUI/dialog/res/templates/overlay-options.html +++ b/platform/commonUI/dialog/res/templates/overlay-options.html @@ -24,13 +24,11 @@
{{ngModel.dialog.title}}
{{ngModel.dialog.hint}}
-
-
- - -
+
+ +
- - x - -
- -
+ class="clk-icon icon ui-symbol close">x +
\ No newline at end of file diff --git a/platform/commonUI/dialog/src/DialogService.js b/platform/commonUI/dialog/src/DialogService.js index 25e8943c06..27ffa9ae8b 100644 --- a/platform/commonUI/dialog/src/DialogService.js +++ b/platform/commonUI/dialog/src/DialogService.js @@ -55,7 +55,7 @@ define( this.dialogVisible = false; }; - DialogService.prototype.getDialogResponse = function (key, model, resultGetter) { + DialogService.prototype.getDialogResponse = function (key, model, resultGetter, typeClass) { // We will return this result as a promise, because user // input is asynchronous. var deferred = this.$q.defer(), @@ -84,27 +84,20 @@ 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( key, - model + model, + typeClass || "t-dialog" ); // 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 +150,99 @@ 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; + } + }; + + /** + * A user action that can be performed from a blocking dialog. These + * actions will be rendered as buttons within a blocking dialog. + * + * @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 + * button is clicked + */ + + /** + * A description of the model options that may be passed to the + * showBlockingMessage method. Note that the DialogModel desribed + * here is shared with the Notifications framework. + * @see NotificationService + * + * @typedef DialogModel + * @property {string} title the title to use for the dialog + * @property {string} severity the severity level of this message. + * These are defined in a bundle constant with key 'dialogSeverity' + * @property {string} hint the 'hint' message to show below the title + * @property {string} actionText text that indicates a current action, + * shown above a progress bar to indicate what's happening. + * @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 {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 {DialogOption[]} options a list of actions that will + * be added to the dialog as buttons. + */ + + /** + * 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 + * @param {typeClass} string tells overlayService that this overlay should use appropriate CSS class + * @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( + "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; + } + }; return DialogService; } diff --git a/platform/commonUI/dialog/src/OverlayService.js b/platform/commonUI/dialog/src/OverlayService.js index 5faba5dcf6..5e9703cb42 100644 --- a/platform/commonUI/dialog/src/OverlayService.js +++ b/platform/commonUI/dialog/src/OverlayService.js @@ -28,7 +28,7 @@ define( // Template to inject into the DOM to show the dialog; really just points to // the a specific template that can be included via mct-include - var TEMPLATE = ''; + var TEMPLATE = ''; /** @@ -71,8 +71,11 @@ define( * @param {object} overlayModel the model to pass to the * included overlay template (this will be passed * in via ng-model) + * @param {string} typeClass the element class to use in rendering + * the overlay. Can be specified to provide custom styling of + * overlays */ - OverlayService.prototype.createOverlay = function (key, overlayModel) { + OverlayService.prototype.createOverlay = function (key, overlayModel, typeClass) { // Create a new scope for this overlay var scope = this.newScope(), element; @@ -90,6 +93,7 @@ define( // Populate the scope; will be passed directly to the template scope.overlay = overlayModel; scope.key = key; + scope.typeClass = typeClass || 't-dialog'; // Create the overlay element and add it to the document's body element = this.$compile(TEMPLATE)(scope); diff --git a/platform/commonUI/dialog/test/DialogServiceSpec.js b/platform/commonUI/dialog/test/DialogServiceSpec.js index 689979f129..2dc109ac44 100644 --- a/platform/commonUI/dialog/test/DialogServiceSpec.js +++ b/platform/commonUI/dialog/test/DialogServiceSpec.js @@ -116,10 +116,22 @@ define( dialog: dialogModel, confirm: jasmine.any(Function), cancel: jasmine.any(Function) - } + }, + 't-dialog' + ); + }); + + 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" ); }); }); } -); \ No newline at end of file +); diff --git a/platform/commonUI/formats/bundle.json b/platform/commonUI/formats/bundle.json index 798bcc7369..99925657b2 100644 --- a/platform/commonUI/formats/bundle.json +++ b/platform/commonUI/formats/bundle.json @@ -7,7 +7,7 @@ "provides": "formatService", "type": "provider", "implementation": "FormatProvider.js", - "depends": [ "formats[]", "$log" ] + "depends": [ "formats[]" ] } ], "formats": [ diff --git a/platform/commonUI/formats/src/FormatProvider.js b/platform/commonUI/formats/src/FormatProvider.js index 421d9bfd39..e6d38fbcee 100644 --- a/platform/commonUI/formats/src/FormatProvider.js +++ b/platform/commonUI/formats/src/FormatProvider.js @@ -72,9 +72,11 @@ define([ /** * Look up a format by its symbolic identifier. + * @method getFormat + * @memberof FormatService# * @param {string} key the identifier for this format - * @returns {Format} the format, or `undefined` if no such format - * is known. + * @returns {Format} the format + * @throws {Error} errors when the requested format is unrecognized */ /** @@ -85,7 +87,7 @@ define([ * @param {Array.} format constructors, * from the `formats` extension category. */ - function FormatProvider(formats, $log) { + function FormatProvider(formats) { var formatMap = {}; function addToMap(Format) { @@ -97,13 +99,12 @@ define([ formats.forEach(addToMap); this.formatMap = formatMap; - this.$log = $log; } FormatProvider.prototype.getFormat = function (key) { var format = this.formatMap[key]; if (!format) { - this.$log.warn("No format found for " + key); + throw new Error("FormatProvider: No format found for " + key); } return format; }; diff --git a/platform/commonUI/formats/test/FormatProviderSpec.js b/platform/commonUI/formats/test/FormatProviderSpec.js index 2a102909cc..4f68c106f7 100644 --- a/platform/commonUI/formats/test/FormatProviderSpec.js +++ b/platform/commonUI/formats/test/FormatProviderSpec.js @@ -41,14 +41,13 @@ define( [ 'parse', 'validate', 'format' ] ); }); - mockLog = jasmine.createSpyObj('$log', ['error', 'warn']); // Return constructors mockFormats = KEYS.map(function (k, i) { function MockFormat() { return mockFormatInstances[i]; } MockFormat.key = k; return MockFormat; }); - provider = new FormatProvider(mockFormats, mockLog); + provider = new FormatProvider(mockFormats); }); it("looks up formats by key", function () { @@ -58,11 +57,10 @@ define( }); }); - it("warns about unknown formats", function () { - provider.getFormat('a'); // known format - expect(mockLog.warn).not.toHaveBeenCalled(); - provider.getFormat('some-unknown-format'); - expect(mockLog.warn).toHaveBeenCalledWith(jasmine.any(String)); + it("throws an error about unknown formats", function () { + expect(function () { + provider.getFormat('some-unknown-format'); + }).toThrow(); }); }); diff --git a/platform/commonUI/general/bundle.json b/platform/commonUI/general/bundle.json index 09e523d105..8e9eafc5e9 100644 --- a/platform/commonUI/general/bundle.json +++ b/platform/commonUI/general/bundle.json @@ -44,6 +44,14 @@ "key": "indicator", "templateUrl": "templates/indicator.html" }, + { + "key": "message-banner", + "templateUrl": "templates/message-banner.html" + }, + { + "key": "progress-bar", + "templateUrl": "templates/progress-bar.html" + }, { "key": "time-controller", "templateUrl": "templates/controls/time-controller.html" @@ -112,6 +120,11 @@ "key": "SelectorController", "implementation": "controllers/SelectorController.js", "depends": [ "objectService", "$scope" ] + }, + { + "key": "BannerController", + "implementation": "controllers/BannerController.js", + "depends": ["$scope", "notificationService", "dialogService"] } ], "directives": [ diff --git a/platform/commonUI/general/res/fonts/symbols/icomoon.io-WTD-symbols-project.json b/platform/commonUI/general/res/fonts/symbols/icomoon.io-WTD-symbols-project.json index 7982d57200..a742a1c8eb 100644 --- a/platform/commonUI/general/res/fonts/symbols/icomoon.io-WTD-symbols-project.json +++ b/platform/commonUI/general/res/fonts/symbols/icomoon.io-WTD-symbols-project.json @@ -1,14 +1,30 @@ { "metadata": { - "name": "WTD Symbols v24", - "lastOpened": 1441992412958, - "created": 1441992410384 + "name": "WTD Symbols v2.3", + "lastOpened": 1444267493342, + "created": 1444266013303 }, "iconSets": [ { "selection": [ { - "order": 86, + "order": 90, + "id": 87, + "prevSize": 32, + "code": 58896, + "name": "icon-bell", + "tempChar": "" + }, + { + "order": 91, + "id": 86, + "prevSize": 32, + "code": 58889, + "name": "icon-hourglass", + "tempChar": "" + }, + { + "order": 92, "id": 85, "prevSize": 32, "code": 58888, @@ -18,119 +34,119 @@ 58890 ], "name": "icon-info-v15", - "tempChar": "" + "tempChar": "" }, { - "order": 82, + "order": 93, "id": 84, "prevSize": 32, "code": 58887, "name": "icon-x-in-circle", - "tempChar": "" + "tempChar": "" }, { - "order": 77, + "order": 94, "id": 83, "prevSize": 32, "code": 58881, "name": "icon-datatable", - "tempChar": "" + "tempChar": "" }, { - "order": 78, + "order": 95, "id": 82, "prevSize": 32, "code": 58882, "name": "icon-tabular-scrolling", - "tempChar": "" + "tempChar": "" }, { - "order": 79, + "order": 96, "id": 81, "prevSize": 32, "code": 58884, "name": "icon-tabular", - "tempChar": "" + "tempChar": "" }, { - "order": 80, + "order": 97, "id": 80, "prevSize": 32, "code": 58885, "name": "icon-calendar", - "tempChar": "" + "tempChar": "" }, { - "order": 83, + "order": 98, "id": 78, "prevSize": 32, "code": 58886, "name": "icon-paint-bucket", - "tempChar": "" + "tempChar": "" }, { - "order": 1, + "order": 99, "id": 75, "prevSize": 32, "code": 123, "name": "icon-pointer-left", - "tempChar": "" + "tempChar": "" }, { - "order": 3, + "order": 100, "id": 74, "prevSize": 32, "code": 125, "name": "icon-pointer-right", - "tempChar": "" + "tempChar": "" }, { - "order": 4, + "order": 101, "id": 73, "prevSize": 32, "code": 80, "name": "icon-person", - "tempChar": "" + "tempChar": "" }, { - "order": 5, + "order": 102, "id": 72, "prevSize": 32, "code": 232, "name": "icon-chain-links", - "tempChar": "" + "tempChar": "" }, { - "order": 6, + "order": 103, "id": 71, "prevSize": 32, "code": 115, "name": "icon-database-in-brackets", - "tempChar": "" + "tempChar": "" }, { - "order": 7, + "order": 104, "id": 70, "prevSize": 32, "code": 114, "name": "icon-refresh", - "tempChar": "" + "tempChar": "" }, { - "order": 8, + "order": 105, "id": 69, "prevSize": 32, "code": 108, "name": "icon-lock", - "tempChar": "" + "tempChar": "" }, { - "order": 9, + "order": 106, "id": 68, "prevSize": 32, "code": 51, "name": "icon-box-with-dashed-lines", - "tempChar": "" + "tempChar": "" }, { "order": 10, @@ -138,7 +154,7 @@ "prevSize": 32, "code": 58880, "name": "icon-box-with-arrow-cursor", - "tempChar": "" + "tempChar": "" }, { "order": 11, @@ -146,7 +162,7 @@ "prevSize": 32, "code": 65, "name": "icon-activity-mode", - "tempChar": "" + "tempChar": "" }, { "order": 12, @@ -154,15 +170,15 @@ "prevSize": 32, "code": 97, "name": "icon-activity", - "tempChar": "" + "tempChar": "" }, { - "order": 13, + "order": 87, "id": 64, "prevSize": 32, "code": 33, "name": "icon-alert-rect", - "tempChar": "" + "tempChar": "" }, { "order": 14, @@ -170,7 +186,7 @@ "prevSize": 32, "code": 58883, "name": "icon-alert-triangle", - "tempChar": "" + "tempChar": "" }, { "order": 15, @@ -178,7 +194,7 @@ "prevSize": 32, "code": 238, "name": "icon-arrow-double-down", - "tempChar": "" + "tempChar": "" }, { "order": 16, @@ -186,7 +202,7 @@ "prevSize": 32, "code": 235, "name": "icon-arrow-double-up", - "tempChar": "" + "tempChar": "" }, { "order": 2, @@ -194,7 +210,7 @@ "prevSize": 32, "code": 118, "name": "icon-arrow-down", - "tempChar": "" + "tempChar": "" }, { "order": 19, @@ -202,7 +218,7 @@ "prevSize": 32, "code": 60, "name": "icon-arrow-left", - "tempChar": "" + "tempChar": "" }, { "order": 20, @@ -210,7 +226,7 @@ "prevSize": 32, "code": 62, "name": "icon-arrow-right", - "tempChar": "" + "tempChar": "" }, { "order": 21, @@ -218,7 +234,7 @@ "prevSize": 32, "code": 236, "name": "icon-arrow-tall-down", - "tempChar": "" + "tempChar": "" }, { "order": 22, @@ -226,7 +242,7 @@ "prevSize": 32, "code": 237, "name": "icon-arrow-tall-up", - "tempChar": "" + "tempChar": "" }, { "order": 23, @@ -234,7 +250,7 @@ "prevSize": 32, "code": 94, "name": "icon-arrow-up", - "tempChar": "" + "tempChar": "" }, { "order": 24, @@ -242,7 +258,7 @@ "prevSize": 32, "code": 73, "name": "icon-arrows-out", - "tempChar": "" + "tempChar": "" }, { "order": 25, @@ -250,7 +266,7 @@ "prevSize": 32, "code": 58893, "name": "icon-arrows-right-left", - "tempChar": "" + "tempChar": "" }, { "order": 33, @@ -258,7 +274,7 @@ "prevSize": 32, "code": 53, "name": "icon-arrows-up-down", - "tempChar": "" + "tempChar": "" }, { "order": 26, @@ -266,7 +282,7 @@ "prevSize": 32, "code": 42, "name": "icon-asterisk", - "tempChar": "" + "tempChar": "" }, { "order": 27, @@ -274,7 +290,7 @@ "prevSize": 32, "code": 72, "name": "icon-autoflow-tabular", - "tempChar": "" + "tempChar": "" }, { "order": 28, @@ -282,7 +298,7 @@ "prevSize": 32, "code": 224, "name": "icon-box", - "tempChar": "" + "tempChar": "" }, { "order": 29, @@ -290,7 +306,7 @@ "prevSize": 32, "code": 50, "name": "icon-check", - "tempChar": "" + "tempChar": "" }, { "order": 30, @@ -298,7 +314,7 @@ "prevSize": 32, "code": 67, "name": "icon-clock", - "tempChar": "" + "tempChar": "" }, { "order": 31, @@ -306,7 +322,7 @@ "prevSize": 32, "code": 46, "name": "icon-connectivity", - "tempChar": "" + "tempChar": "" }, { "order": 32, @@ -314,7 +330,7 @@ "prevSize": 32, "code": 100, "name": "icon-database-query", - "tempChar": "" + "tempChar": "" }, { "order": 17, @@ -322,7 +338,7 @@ "prevSize": 32, "code": 68, "name": "icon-database", - "tempChar": "" + "tempChar": "" }, { "order": 35, @@ -330,7 +346,7 @@ "prevSize": 32, "code": 81, "name": "icon-dictionary", - "tempChar": "" + "tempChar": "" }, { "order": 36, @@ -338,7 +354,7 @@ "prevSize": 32, "code": 242, "name": "icon-duplicate", - "tempChar": "" + "tempChar": "" }, { "order": 37, @@ -346,7 +362,7 @@ "prevSize": 32, "code": 102, "name": "icon-folder-new", - "tempChar": "" + "tempChar": "" }, { "order": 38, @@ -354,7 +370,7 @@ "prevSize": 32, "code": 70, "name": "icon-folder", - "tempChar": "" + "tempChar": "" }, { "order": 39, @@ -362,7 +378,7 @@ "prevSize": 32, "code": 95, "name": "icon-fullscreen-collapse", - "tempChar": "" + "tempChar": "" }, { "order": 40, @@ -370,7 +386,7 @@ "prevSize": 32, "code": 122, "name": "icon-fullscreen-expand", - "tempChar": "" + "tempChar": "" }, { "order": 41, @@ -378,7 +394,7 @@ "prevSize": 32, "code": 71, "name": "icon-gear", - "tempChar": "" + "tempChar": "" }, { "order": 49, @@ -386,7 +402,7 @@ "prevSize": 32, "code": 227, "name": "icon-image", - "tempChar": "" + "tempChar": "" }, { "order": 42, @@ -394,7 +410,7 @@ "prevSize": 32, "code": 225, "name": "icon-layers", - "tempChar": "" + "tempChar": "" }, { "order": 43, @@ -402,7 +418,7 @@ "prevSize": 32, "code": 76, "name": "icon-layout", - "tempChar": "" + "tempChar": "" }, { "order": 44, @@ -410,7 +426,7 @@ "prevSize": 32, "code": 226, "name": "icon-line-horz", - "tempChar": "" + "tempChar": "" }, { "order": 75, @@ -418,7 +434,7 @@ "prevSize": 32, "code": 244, "name": "icon-link", - "tempChar": "" + "tempChar": "" }, { "order": 46, @@ -426,7 +442,7 @@ "prevSize": 32, "code": 88, "name": "icon-magnify-in", - "tempChar": "" + "tempChar": "" }, { "order": 47, @@ -434,7 +450,7 @@ "prevSize": 32, "code": 89, "name": "icon-magnify-out", - "tempChar": "" + "tempChar": "" }, { "order": 48, @@ -442,7 +458,7 @@ "prevSize": 32, "code": 77, "name": "icon-magnify", - "tempChar": "" + "tempChar": "" }, { "order": 34, @@ -450,7 +466,7 @@ "prevSize": 32, "code": 109, "name": "icon-menu", - "tempChar": "" + "tempChar": "" }, { "order": 50, @@ -458,7 +474,7 @@ "prevSize": 32, "code": 243, "name": "icon-move", - "tempChar": "" + "tempChar": "" }, { "order": 51, @@ -466,7 +482,7 @@ "prevSize": 32, "code": 121, "name": "icon-new-window", - "tempChar": "" + "tempChar": "" }, { "order": 52, @@ -474,7 +490,7 @@ "prevSize": 32, "code": 111, "name": "icon-object", - "tempChar": "" + "tempChar": "" }, { "order": 73, @@ -482,7 +498,7 @@ "prevSize": 32, "code": 63, "name": "icon-object-unknown", - "tempChar": "" + "tempChar": "" }, { "order": 53, @@ -490,7 +506,7 @@ "prevSize": 32, "code": 86, "name": "icon-packet", - "tempChar": "" + "tempChar": "" }, { "order": 54, @@ -498,7 +514,7 @@ "prevSize": 32, "code": 234, "name": "icon-page", - "tempChar": "" + "tempChar": "" }, { "order": 55, @@ -506,7 +522,7 @@ "prevSize": 32, "code": 241, "name": "icon-pause", - "tempChar": "" + "tempChar": "" }, { "order": 56, @@ -514,7 +530,7 @@ "prevSize": 32, "code": 112, "name": "icon-pencil", - "tempChar": "" + "tempChar": "" }, { "order": 65, @@ -522,7 +538,7 @@ "prevSize": 32, "code": 79, "name": "icon-people", - "tempChar": "" + "tempChar": "" }, { "order": 57, @@ -530,7 +546,7 @@ "prevSize": 32, "code": 239, "name": "icon-play", - "tempChar": "" + "tempChar": "" }, { "order": 58, @@ -538,7 +554,7 @@ "prevSize": 32, "code": 233, "name": "icon-plot-resource", - "tempChar": "" + "tempChar": "" }, { "order": 59, @@ -546,7 +562,7 @@ "prevSize": 32, "code": 43, "name": "icon-plus", - "tempChar": "" + "tempChar": "" }, { "order": 60, @@ -554,7 +570,7 @@ "prevSize": 32, "code": 45, "name": "icon-minus", - "tempChar": "" + "tempChar": "" }, { "order": 61, @@ -562,7 +578,7 @@ "prevSize": 32, "code": 54, "name": "icon-sine", - "tempChar": "" + "tempChar": "" }, { "order": 62, @@ -570,7 +586,7 @@ "prevSize": 32, "code": 228, "name": "icon-T", - "tempChar": "" + "tempChar": "" }, { "order": 63, @@ -578,7 +594,7 @@ "prevSize": 32, "code": 116, "name": "icon-telemetry-panel", - "tempChar": "" + "tempChar": "" }, { "order": 64, @@ -586,7 +602,7 @@ "prevSize": 32, "code": 84, "name": "icon-telemetry", - "tempChar": "" + "tempChar": "" }, { "order": 18, @@ -594,7 +610,7 @@ "prevSize": 32, "code": 246, "name": "icon-thumbs-strip", - "tempChar": "" + "tempChar": "" }, { "order": 67, @@ -602,7 +618,7 @@ "prevSize": 32, "code": 83, "name": "icon-timeline", - "tempChar": "" + "tempChar": "" }, { "order": 68, @@ -610,7 +626,7 @@ "prevSize": 32, "code": 245, "name": "icon-timer", - "tempChar": "" + "tempChar": "" }, { "order": 69, @@ -618,7 +634,7 @@ "prevSize": 32, "code": 90, "name": "icon-trash", - "tempChar": "" + "tempChar": "" }, { "order": 70, @@ -626,7 +642,7 @@ "prevSize": 32, "code": 229, "name": "icon-two-parts-both", - "tempChar": "" + "tempChar": "" }, { "order": 71, @@ -634,7 +650,7 @@ "prevSize": 32, "code": 231, "name": "icon-two-parts-one-only", - "tempChar": "" + "tempChar": "" }, { "order": 72, @@ -642,7 +658,7 @@ "prevSize": 32, "code": 120, "name": "icon-x-heavy", - "tempChar": "" + "tempChar": "" }, { "order": 66, @@ -650,7 +666,7 @@ "prevSize": 32, "code": 58946, "name": "icon-x", - "tempChar": "" + "tempChar": "" } ], "id": 2, @@ -665,6 +681,58 @@ "height": 1024, "prevSize": 32, "icons": [ + { + "id": 87, + "paths": [ + "M512 1024c106 0 192-86 192-192h-384c0 106 86 192 192 192z", + "M896 448v-64c0-212-172-384-384-384s-384 172-384 384v64c0 70.6-57.4 128-128 128v128h1024v-128c-70.6 0-128-57.4-128-128z" + ], + "attrs": [ + { + "fill": "rgb(6, 161, 75)" + }, + { + "fill": "rgb(6, 161, 75)" + } + ], + "isMulticolor": false, + "grid": 0, + "tags": [ + "icon-bell" + ], + "colorPermutations": { + "125525525516161751": [ + 1, + 1 + ] + } + }, + { + "id": 86, + "paths": [ + "M1024 0h-1024c0 282.8 229.2 512 512 512s512-229.2 512-512zM512 384c-102.6 0-199-40-271.6-112.4-41.2-41.2-72-90.2-90.8-143.6h724.6c-18.8 53.4-49.6 102.4-90.8 143.6-72.4 72.4-168.8 112.4-271.4 112.4z", + "M512 512c-282.8 0-512 229.2-512 512h1024c0-282.8-229.2-512-512-512z" + ], + "attrs": [ + { + "fill": "rgb(6, 161, 75)" + }, + { + "fill": "rgb(6, 161, 75)" + } + ], + "isMulticolor": false, + "grid": 0, + "tags": [ + "icon-hourglass" + ], + "colorPermutations": { + "125525525516161751": [ + 1, + 1 + ] + } + }, { "id": 85, "paths": [ @@ -698,7 +766,8 @@ "icon-x-in-circle" ], "colorPermutations": { - "16161751": [] + "16161751": [], + "125525525516161751": [] } }, { @@ -899,6 +968,11 @@ 1, 1, 1 + ], + "125525525516161751": [ + 1, + 1, + 1 ] } }, @@ -1051,18 +1125,28 @@ { "id": 67, "paths": [ - "M832 512.4c0-0.2 0-0.2 0-0.4v-320c0-105.6-86.4-192-192-192h-448c-105.6 0-192 86.4-192 192v320c0 105.6 86.4 192 192 192h263.6l-197.2-445.6 573.6 254z", - "M766.8 659.8l193.8-20.4-576.6-255.4 255.4 576.6 20.4-193.8 257 257.2 107.2-107.2z" + "M894-2h-768c-70.4 0-128 57.6-128 128v768c0 70.4 57.6 128 128 128h400c-2.2-3.8-4-7.6-5.8-11.4l-255.2-576.8c-21.4-48.4-10.8-105 26.6-142.4 24.4-24.4 57.2-37.4 90.4-37.4 17.4 0 35.2 3.6 51.8 11l576.6 255.4c4 1.8 7.8 3.8 11.4 5.8v-400.2c0.2-70.4-57.4-128-127.8-128z", + "M958.6 637.4l-576.6-255.4 255.4 576.6 64.6-128.6 192 192 128-128-192-192z" ], "attrs": [ - {}, - {} + { + "fill": "rgb(0, 0, 0)" + }, + { + "fill": "rgb(0, 0, 0)" + } ], "isMulticolor": false, "grid": 0, "tags": [ "icon-box-with-arrow-cursor" - ] + ], + "colorPermutations": { + "125525525516161751": [ + 0, + 0 + ] + } }, { "id": 66, @@ -1338,6 +1422,9 @@ "colorPermutations": { "16161751": [ 0 + ], + "125525525516161751": [ + 0 ] } }, @@ -14853,6 +14940,5 @@ "gridSize": 16, "showLiga": false }, - "uid": -1, - "time": 1441993324496 + "uid": -1 } \ No newline at end of file diff --git a/platform/commonUI/general/res/fonts/symbols/wtdsymbols.eot b/platform/commonUI/general/res/fonts/symbols/wtdsymbols.eot index 95887455fe..a721dd3384 100755 Binary files a/platform/commonUI/general/res/fonts/symbols/wtdsymbols.eot and b/platform/commonUI/general/res/fonts/symbols/wtdsymbols.eot differ diff --git a/platform/commonUI/general/res/fonts/symbols/wtdsymbols.svg b/platform/commonUI/general/res/fonts/symbols/wtdsymbols.svg index 596a5dd3e9..7d0e70d400 100755 --- a/platform/commonUI/general/res/fonts/symbols/wtdsymbols.svg +++ b/platform/commonUI/general/res/fonts/symbols/wtdsymbols.svg @@ -76,7 +76,7 @@ - + @@ -85,6 +85,8 @@ + + \ No newline at end of file diff --git a/platform/commonUI/general/res/fonts/symbols/wtdsymbols.ttf b/platform/commonUI/general/res/fonts/symbols/wtdsymbols.ttf index 8f0f1d9610..5bc0ca5290 100755 Binary files a/platform/commonUI/general/res/fonts/symbols/wtdsymbols.ttf and b/platform/commonUI/general/res/fonts/symbols/wtdsymbols.ttf differ diff --git a/platform/commonUI/general/res/fonts/symbols/wtdsymbols.woff b/platform/commonUI/general/res/fonts/symbols/wtdsymbols.woff index d5bc74071c..68386425cc 100755 Binary files a/platform/commonUI/general/res/fonts/symbols/wtdsymbols.woff and b/platform/commonUI/general/res/fonts/symbols/wtdsymbols.woff differ diff --git a/platform/commonUI/general/res/sass/_constants.scss b/platform/commonUI/general/res/sass/_constants.scss index 6ef636cdcd..e64b5f5aaa 100644 --- a/platform/commonUI/general/res/sass/_constants.scss +++ b/platform/commonUI/general/res/sass/_constants.scss @@ -47,8 +47,8 @@ $ueEditLeftPaneW: 75%; $treeSearchInputBarH: 25px; $ueTimeControlH: (33px, 20px, 20px); // Overlay -$ovrTopBarH: 60px; -$ovrFooterH: 30px; +$ovrTopBarH: 45px; +$ovrFooterH: 24px; $overlayMargin: 25px; // Items $ueBrowseGridItemLg: 200px; diff --git a/platform/commonUI/general/res/sass/_main.scss b/platform/commonUI/general/res/sass/_main.scss index 80023f55ac..05d814f3be 100644 --- a/platform/commonUI/general/res/sass/_main.scss +++ b/platform/commonUI/general/res/sass/_main.scss @@ -29,7 +29,6 @@ @import "helpers/bubbles"; @import "helpers/splitter"; @import "helpers/wait-spinner"; -@import "messages"; @import "properties"; /********************************* CONTROLS */ @@ -39,6 +38,7 @@ @import "controls/controls"; @import "controls/lists"; @import "controls/menus"; +@import "controls/messages"; @import "controls/time-controller"; @import "mobile/controls/menus"; @@ -62,7 +62,6 @@ @import "mobile/tree"; @import "user-environ/frame"; @import "user-environ/top-bar"; -@import "user-environ/bottom-bar"; @import "user-environ/tool-bar"; /********************************* VIEWS */ diff --git a/platform/commonUI/general/res/sass/_messages.scss b/platform/commonUI/general/res/sass/_messages.scss deleted file mode 100644 index db4de4c946..0000000000 --- a/platform/commonUI/general/res/sass/_messages.scss +++ /dev/null @@ -1,12 +0,0 @@ -/* Styles for messages */ - -.message { - &.block { - @include border-radius($basicCr); - padding: $interiorMarginLg; - } - &.error { - background-color: rgba($colorAlert,0.3); - color: lighten($colorAlert, 20%); - } -} \ No newline at end of file diff --git a/platform/commonUI/general/res/sass/_mixins.scss b/platform/commonUI/general/res/sass/_mixins.scss index c3d2ecc781..784b054669 100644 --- a/platform/commonUI/general/res/sass/_mixins.scss +++ b/platform/commonUI/general/res/sass/_mixins.scss @@ -94,7 +94,6 @@ } @mixin triangle($dir: "left", $size: 5px, $ratio: 1, $color: red) { - //$size: $size*2; width: 0; height: 0; $slopedB: $size/$ratio solid transparent; @@ -129,6 +128,24 @@ background-size: $d $d; } +@mixin bgVertStripes($c: yellow, $a: 0.1, $d: 40px) { + @include background-image(linear-gradient(-90deg, + rgba($c, $a) 0%, rgba($c, $a) 50%, + transparent 50%, transparent 100% + )); + background-repeat: repeat; + background-size: $d $d; +} + +@mixin bgVertFuzzyStripes($c: yellow, $a: 0.1, $d: 40px) { + @include background-image(linear-gradient(-90deg, + rgba($c, $a) 0%, transparent 50%, + transparent 50%, rgba($c, $a) 100% + )); + background-repeat: repeat; + background-size: $d $d; +} + @mixin bgTicks($c: $colorBodyFg, $repeatDir: 'x') { $deg: 90deg; @if ($repeatDir != 'x') { diff --git a/platform/commonUI/general/res/sass/controls/_controls.scss b/platform/commonUI/general/res/sass/controls/_controls.scss index eef87c3439..f7457d9dd6 100644 --- a/platform/commonUI/general/res/sass/controls/_controls.scss +++ b/platform/commonUI/general/res/sass/controls/_controls.scss @@ -19,34 +19,6 @@ * this source code distribution or the Licensing information page available * at runtime from the About dialog for additional information. *****************************************************************************/ -/*.control { - // UNUSED? - &.view-control { - .icon { - display: inline-block; - margin: -1px 5px 1px 2px; - vertical-align: middle; - &.triangle-down { - margin: 2px 2px -2px 0px; - } - } - - .label { - display: inline-block; - font-size: 11px; - vertical-align: middle; - } - - .toggle { - @include border-radius(3px); - display: inline-block; - padding: 1px 6px 4px 4px; - &:hover { - background: rgba(white, 0.1); - } - } - } -}*/ .accordion { $accordionHeadH: 18px; @@ -291,6 +263,88 @@ label.checkbox.custom { } } +/******************************************************** PROGRESS BAR */ +@include keyframes(progress) { + 100% { background-position: $progressBarStripeW center; } +} + +@mixin bgProgressAnim($c: yellow, $a: 0.1, $d: 20px) { + @include background-image(linear-gradient(-90deg, + rgba($c, $a) 0%, transparent 50%, + transparent 50%, rgba($c, $a) 100% + )); + background-position: 0 center; + background-repeat: repeat-x; + background-size: $d 40%; +} + +.l-progress-bar { + // Assume will be determinate by default + display: inline-block; + overflow: hidden; + position: relative; + + .progress-amt-holder { + @include absPosDefault(1px); + } + .progress-amt, + .progress-amt:before, + .progress-amt:after { + @include absPosDefault(); + display: block; + content: ''; + } + + .progress-amt { + right: auto; // Allow inline width to control } + } + + &.indeterminate { + .progress-amt { + width: 100% !important; + } + } +} + +.s-progress-bar { + @include border-radius($basicCr); + @include boxIncised(0.3, 4px); + background: $colorProgressBarOuter; + //border:1px solid $colorProgressBarOuter; + .progress-amt { + @include border-radius($basicCr); + @include boxShdw(); + @include border-radius($basicCr - 1); + @include trans-prop-nice(width); + &:before { + background-color: $colorProgressBarAmt; + } + &:after { + // Sheen + @include background-image(linear-gradient( + transparent 5%, rgba(#fff,0.25) 30%, transparent 100% + )); + } + } + + &:not(.indeterminate) { + .progress-amt:before { + // More subtle anim for determinate progress + @include animation(progress .4s linear infinite); + @include bgProgressAnim(#fff, 0.1, $progressBarStripeW); + } + } + + &.indeterminate .progress-amt { + &:before { + // More visible std diag stripe anim for indeterminate progress + @include animation(progress .6s linear infinite); + @include bgDiagonalStripes(#fff, 0.2, $progressBarStripeW); + } + &:after { display: none; } + } +} + /******************************************************** SLIDERS */ .slider { diff --git a/platform/commonUI/general/res/sass/controls/_messages.scss b/platform/commonUI/general/res/sass/controls/_messages.scss new file mode 100644 index 0000000000..740df6ba8d --- /dev/null +++ b/platform/commonUI/general/res/sass/controls/_messages.scss @@ -0,0 +1,306 @@ +/***************************************************************************** + * 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. + *****************************************************************************/ + +@mixin statusBannerColors($bg, $fg: $colorStatusFg) { + $bgPb: 30%; + $bgPbD: 10%; + background-color: darken($bg, $bgPb); + color: $fg; + &:hover { + background-color: darken($bg, $bgPb - $bgPbD); + } + .s-action { + background-color: darken($bg, $bgPb + $bgPbD); + &:hover { + background-color: darken($bg, $bgPb); + } + } +} + +.status.block { + color: $colorStatusDefault; + cursor: default; + display: inline-block; + margin-right: $interiorMargin; + .status-indicator, + .label, + .count { + //@include test(#00ff00); + display: inline-block; + vertical-align: top; + } + .status-indicator { + margin-right: $interiorMarginSm; + } + &.ok .status-indicator, + &.info .status-indicator { + color: $colorStatusInfo; + } + &.alert .status-indicator, + &.warning .status-indicator, + &.caution .status-indicator { + color: $colorStatusAlert; + } + &.error .status-indicator { + color: $colorStatusError; + } + .label { + // Max-width silliness is necessary for width transition + @include trans-prop-nice(max-width, .25s); + overflow: hidden; + max-width: 0px; + } + .count { + @include trans-prop-nice(opacity, .25s); + font-weight: bold; + opacity: 1; + } + &:hover { + .label { + max-width: 450px; + width: auto; + } + .count { + opacity: 0; + } + } +} + +/* Styles for messages and message banners */ +.message { + &.block { + @include border-radius($basicCr); + padding: $interiorMarginLg; + } + &.error { + background-color: rgba($colorAlert,0.3); + color: lighten($colorAlert, 20%); + } +} + +.l-message-banner { + $m: $interiorMarginSm; + $lh: $ueFooterH - ($m*2) - 1; + @include box-sizing(border-box); + @include ellipsize(); + @include display-flex; + @include flex-direction(row); + @include align-items(center); + position: absolute; + top: $m; right: auto; bottom: $m; left: 50%; + height: auto; width: auto; + line-height: $lh; + max-width: 300px; + padding: 0 $interiorMargin 0 $interiorMargin; + @include transform(translateX(-50%)); + + &.minimized { + @include transition-property(left, opacity); + @include transition-duration(0.3s); + @include transition-timing-function(ease-in-out); + left: 0; + opacity: 0; + } + + &.new { + left: 50%; + opacity: 1; + &:not(.info) { + @include pulse(100ms, 10); + } + } + + .banner-elem { + @include flex(0 1 auto); + margin-left: $interiorMargin; + } + a { + display: inline-block; + } + .l-action { + line-height: $lh - 3; + padding: 0 $interiorMargin; + } + .close { + //@include test(red, 0.7); + cursor: pointer; + font-size: 7px; + width: 8px; + } + .l-progress-bar { + $h: $lh - 10; + height: $h; + line-height: $h; + width: 100px; + } + .progress-info { display: none; } + z-index: 10; +} + +.s-message-banner { + //@include transition-property(left, opacity); + //@include transition-duration(0.35s); + //@include transition-timing-function(ease-in-out); +} + +.s-message-banner { + @include border-radius($controlCr); + @include statusBannerColors($colorStatusDefault, $colorStatusFg); + cursor: pointer; + a { color: inherit; } + .s-action { + @include border-radius($basicCr); + @include trans-prop-nice(background-color); + } + .close { + opacity: 0.5; + &:hover { + opacity: 1; + } + } + &.ok, + &.info { + @include statusBannerColors($colorStatusInfo); + } + &.caution, + &.warning, + &.alert { + @include statusBannerColors($colorStatusAlert); + } + &.error { + @include statusBannerColors($colorStatusError); + } +} + +@mixin messageBlock($iconW: 32px) { + .type-icon.message-type { + @include txtShdw($shdwStatusIc); + &:before { content:"\e608"; } + color: $colorStatusDefault; + font-size: $iconW; + padding: 1px; + width: $iconW + 2; + } + + .message-severity-info .type-icon.message-type { + &:before { content:"\e608"; } + color: $colorStatusInfo; + } + .message-severity-alert .type-icon.message-type { + &:before { content:"\e610"; } + color: $colorStatusAlert; + } + .message-severity-error .type-icon.message-type { + &:before { content:"\21"; } + color: $colorStatusError; + } +} +/* Paths: + t-dialog | t-dialog-sm > t-message-single | t-message-list > overlay > holder > contents > l-message > + message-type > (icon) + message-contents > + top-bar > + title + hint + editor > + (if displaying list of messages) + ul > li > l-message > + ... same as above + bottom-bar +*/ + +.l-message { + @include display-flex; + @include flex-direction(row); + @include align-items(stretch); + .type-icon.message-type { + //@include test(red); + @include flex(0 1 auto); + position: relative; + } + .message-contents { + //@include test(blue); + @include flex(1 1 auto); + margin-left: $overlayMargin; + position: relative; + + .top-bar, + .message-body { + margin-bottom: $interiorMarginLg * 2; + } + } +} + + +// Message as singleton +.t-message-single { + @include messageBlock(80px); + + @include desktop { + .l-message, + .bottom-bar { + @include absPosDefault(); + } + + .bottom-bar { + top: auto; + height: $ovrFooterH; + } + } +} + +// Messages in list +.t-message-list { + @include messageBlock(32px); + + .message-contents { + .l-message { + //border-bottom: 1px solid pullForward($colorOvrBg, 20%); + @include border-radius($controlCr); + background: rgba($colorOvrFg, 0.1); + margin-bottom: $interiorMargin; + padding: $interiorMarginLg; + + .message-contents, + .bottom-bar { + //@include test(green); + position: relative; + } + + .message-contents { + font-size: 0.9em; + margin-left: $interiorMarginLg; + .message-action { color: pushBack($colorOvrFg, 20%); } + .bottom-bar { text-align: left; } + } + + .top-bar, + .message-body { + margin-bottom: $interiorMarginLg; + } + } + } + + @include desktop { + .message-contents .l-message { margin-right: $interiorMarginLg; } + } +} \ No newline at end of file diff --git a/platform/commonUI/general/res/sass/mobile/_constants.scss b/platform/commonUI/general/res/sass/mobile/_constants.scss index bd9443cc50..067bbef6ca 100644 --- a/platform/commonUI/general/res/sass/mobile/_constants.scss +++ b/platform/commonUI/general/res/sass/mobile/_constants.scss @@ -23,7 +23,7 @@ /************************** MOBILE REPRESENTATION ITEMS DIMENSIONS */ $mobileListIconSize: 30px; $mobileTitleDescH: 35px; -$mobileOverlayMargin: 10px; +$mobileOverlayMargin: 20px; $phoneItemH: floor($ueBrowseGridItemLg/4); $tabletItemH: floor($ueBrowseGridItemLg/3); diff --git a/platform/commonUI/general/res/sass/mobile/overlay/_overlay.scss b/platform/commonUI/general/res/sass/mobile/overlay/_overlay.scss index caa6df0967..9fd6721130 100644 --- a/platform/commonUI/general/res/sass/mobile/overlay/_overlay.scss +++ b/platform/commonUI/general/res/sass/mobile/overlay/_overlay.scss @@ -1,16 +1,12 @@ @include phoneandtablet { .overlay { - $m: 0; .clk-icon.close { top: $mobileOverlayMargin; right: $mobileOverlayMargin; } > .holder { - @include border-radius($m); - top: $m; - right: $m; - bottom: $m; - left: $m; + height: 90%; width: 90%; + > .contents { top: $mobileOverlayMargin; right: $mobileOverlayMargin; @@ -22,35 +18,64 @@ margin-right: 1.2em; } } - - .form.editor { - border: none; - - .contents { - top: 0; - right: 0; - bottom: 0; - left: 0; - } - } } } } } @include phone { - .overlay > .holder > .contents .form.editor .contents .form-row { - > .label, - > .controls { - //@include test(blue); - display: block; - float: none; - width: 100%; + .overlay > .holder { + //@include test(orange); // This works! + $m: 0; + @include border-radius($m); + top: $m; + right: $m; + bottom: $m; + left: $m; + height: auto; width: auto; + min-width: 200px; min-height: 200px; + max-height: 100%; max-width: 100%; + overflow: auto; + @include transform(none); + + .editor .form .form-row { + > .label, + > .controls { + //@include test(blue); + display: block; + float: none; + width: 100%; + } + > .label { + &:after { + float: none; + } + } + } + + .contents { + .abs.top-bar, + .abs.editor, + .abs.message-body, + .abs.bottom-bar { + //@include test(orange); + top: auto; right: auto; bottom: auto; left: auto; + height: auto; width: auto; + margin-bottom: $interiorMarginLg * 2; + position: relative; + } + } + } + .t-dialog-sm .overlay > .holder { + //@include test(blue); + height: auto; max-height: 100%; + } +} + +@include phonePortrait { + .overlay > .holder { + .contents .bottom-bar { + text-align: center; } - > .label { - &:after { - float: none; - } - } } } \ No newline at end of file diff --git a/platform/commonUI/general/res/sass/overlay/_overlay.scss b/platform/commonUI/general/res/sass/overlay/_overlay.scss index 2dce492563..602af62887 100644 --- a/platform/commonUI/general/res/sass/overlay/_overlay.scss +++ b/platform/commonUI/general/res/sass/overlay/_overlay.scss @@ -20,79 +20,124 @@ * at runtime from the About dialog for additional information. *****************************************************************************/ .overlay { - .blocker { - background: $colorOvrBlocker; - z-index: 100; - } + font-size: 90%; + .blocker { + background: $colorOvrBlocker; + z-index: 100; + } .clk-icon.close { font-size: 0.8rem; position: absolute; - top: $interiorMarginLg; right: $interiorMarginLg; bottom: auto; left: auto; - z-index: 100; + top: $interiorMarginLg; + right: $interiorMarginLg; + bottom: auto; + left: auto; + z-index: 100; } - >.holder { - $i: 15%; - @include containerSubtle($colorOvrBg, $colorOvrFg); - @include border-radius($basicCr * 3); - color: $colorOvrFg; - top: $i; right: $i; bottom: $i; left: $i; - z-index: 101; - >.contents { + > .holder { + //$i: 15%; + @include containerSubtle($colorOvrBg, $colorOvrFg); + @include border-radius($basicCr * 3); + color: $colorOvrFg; + top: 50%; + right: auto; + bottom: auto; + left: 50%; + @include transform(translateX(-50%) translateY(-50%)); + height: 70%; + width: 50%; + min-height: 300px; + max-height: 800px; + min-width: 600px; + max-width: 1000px; + z-index: 101; + > .contents { $m: $overlayMargin; - top: $m; right: $m; bottom: $m; left: $m; + top: $m; + right: $m; + bottom: $m; + left: $m; + + //.top-bar, + //.editor, + //.bottom-bar { + // @include absPosDefault(); + //} } - } - .title { - @include ellipsize(); - font-size: 1.2em; - margin-bottom: $interiorMargin; } - - .top-bar { + + .title { + @include ellipsize(); + font-size: 1.2em; + line-height: 120%; + margin-bottom: $interiorMargin; + } + + .hint { + color: pushBack($colorOvrFg, 20%); + } + + .abs.top-bar { height: $ovrTopBarH; } - - .editor { - top: $ovrTopBarH + ($interiorMargin * 2); - bottom: $ovrFooterH + $interiorMargin * 2; - left: 0; right: 0; - } - - .bottom-bar { - top: auto; right: 0; bottom: 0; left: 0; - overflow: visible; - //font-size: 1em; - height: $ovrFooterH; - text-align: right; - .s-btn { - $bg: $colorOvrBtnBg; - &:not(.major) { - @include btnSubtle($bg, pullForward($bg, 10%), $colorOvrBtnFg, $colorOvrBtnFg); - } - font-size: 95%; - height: $ovrFooterH; - line-height: $ovrFooterH; - margin-left: $interiorMargin; - padding: 0 $interiorMargin * 3; - //&.major { - // @extend .s-btn.major; - // &:hover { - // @extend .s-btn.major:hover; - // } - //} + + .abs.editor, + .abs.message-body { + top: $ovrTopBarH + $interiorMarginLg; + bottom: $ovrFooterH + $interiorMarginLg; + left: 0; + right: 0; + overflow: auto; + .field.l-med { + input[type='text'] { + width: 100%; + } } } - .contents.l-dialog { - $myM: $interiorMargin; - top: $myM; - right: $myM; - bottom: $myM; - left: $myM; - overflow: auto; - .field.l-med { - input[type='text'] { - width: 100%; - } - } + + .bottom-bar { + text-align: right; + .s-btn { + $bg: $colorOvrBtnBg; + &:not(.major) { + @include btnSubtle($bg, pullForward($bg, 10%), $colorOvrBtnFg, $colorOvrBtnFg); + } + font-size: 95%; + height: $ovrFooterH; + line-height: $ovrFooterH; + margin-left: $interiorMargin; + padding: 0 $interiorMargin * 3; + &:first-child { + margin-left: 0; + } + } + } + + .abs.bottom-bar { + top: auto; + right: 0; + bottom: 0; + left: 0; + overflow: visible; + //font-size: 1em; + height: $ovrFooterH; + } + + .l-progress-bar { + $h: $progressBarHOverlay; + display: block; + height: $h; + line-height: $h; + margin: .5em 0; + width: 100%; + } +} + +.t-dialog-sm .overlay > .holder { + // Used for blocker and in-progress dialogs, modal alerts, etc. + //@include test(red); + $h: 225px; + min-height: $h; + height: $h; } \ No newline at end of file diff --git a/platform/commonUI/general/res/sass/user-environ/_bottom-bar.scss b/platform/commonUI/general/res/sass/user-environ/_bottom-bar.scss deleted file mode 100644 index dd705b0000..0000000000 --- a/platform/commonUI/general/res/sass/user-environ/_bottom-bar.scss +++ /dev/null @@ -1,72 +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. - *****************************************************************************/ -.ue-bottom-bar { - background: $colorFooterBg; - color: lighten($colorBodyBg, 30%); - font-size: .7rem; - //line-height: $ueFooterH - 4px; - //line-height: $ueFooterH; // New status bar design - .status-holder { - //@include border-radius($basicCr * 1.75); // New status bar design - @include box-sizing(border-box); - //background: $colorFooterBg; - //border-bottom: 1px solid lighten($colorBodyBg, 10%); // New status bar design - @include absPosDefault($interiorMargin); - @include ellipsize(); - line-height: $ueFooterH - ($interiorMargin * 2); - right: 120px; - text-transform: uppercase; - } - .app-logo { - @include box-sizing(border-box); - @include absPosDefault($interiorMargin); - left: auto; - cursor: pointer; - //font-size: 0.8em; - //line-height: $ueFooterH - 10px; - //padding-top: 1px; - //text-transform: uppercase; - &.logo-openmctweb { - background: url($dirImgs + 'logo-openmctweb.svg') no-repeat center center; - } - } -} - -.status.block { - //display: inline-block; - display: inline; // New status bar design. Inline to support ellipsis overflow - margin-right: $interiorMarginLg; - .status-indicator { - //@include border-radius($controlCr * 0.9); - //@include box-shadow(inset rgba(black, 0.5) 0 0 3px); - //@include text-shadow(rgba(black, 0.3) 0 0 2px); - display: inline-block; - margin-right: $interiorMarginSm; - color: $colorKey; - &.ok { - color: #009900; - } - &.caution { - color: #ffaa00; - } - } -} \ No newline at end of file diff --git a/platform/commonUI/general/res/sass/user-environ/_layout.scss b/platform/commonUI/general/res/sass/user-environ/_layout.scss index 0d8983c182..e03db83c04 100644 --- a/platform/commonUI/general/res/sass/user-environ/_layout.scss +++ b/platform/commonUI/general/res/sass/user-environ/_layout.scss @@ -43,9 +43,9 @@ position: absolute; } -.editor { - @include border-radius($basicCr * 1.5); -} +//.editor { +// @include border-radius($basicCr * 1.5); +//} .contents { $myM: 0; //$interiorMargin; @@ -125,21 +125,37 @@ } } - .ue-bottom-bar { - //@include absPosDefault($bodyMargin); - @include absPosDefault(0); // New status bar design - top: auto; - height: $ueFooterH; - .status-holder { - //right: $ueAppLogoW + $bodyMargin; New status bar design - z-index: 1; - } - .app-logo { - left: auto; - width: $ueAppLogoW; - z-index: 2; - } - } + // from _bottom-bar.scss + .ue-bottom-bar { + @include absPosDefault(0);// New status bar design + top: auto; + height: $ueFooterH; + line-height: $ueFooterH - ($interiorMargin * 2); + background: $colorFooterBg; + color: lighten($colorBodyBg, 30%); + font-size: .7rem; + + .status-holder { + @include box-sizing(border-box); + @include absPosDefault($interiorMargin); + @include ellipsize(); + //line-height: $ueFooterH - ($interiorMargin * 2); + right: 120px; + text-transform: uppercase; + z-index: 1; + } + .app-logo { + @include box-sizing(border-box); + @include absPosDefault($interiorMargin); + cursor: pointer; + left: auto; + width: $ueAppLogoW; + z-index: 2; + &.logo-openmctweb { + background: url($dirImgs + 'logo-openmctweb.svg') no-repeat center center; + } + } + } } .cols { @@ -343,4 +359,4 @@ @include webkitProp(flex, '1 1 0'); padding-right: $interiorMarginLg; } -} \ No newline at end of file +} diff --git a/platform/commonUI/general/res/templates/bottombar.html b/platform/commonUI/general/res/templates/bottombar.html index 4da2686fa1..f0d3799542 100644 --- a/platform/commonUI/general/res/templates/bottombar.html +++ b/platform/commonUI/general/res/templates/bottombar.html @@ -26,5 +26,6 @@ key="indicator.template">
+ \ No newline at end of file diff --git a/platform/commonUI/general/res/templates/indicator.html b/platform/commonUI/general/res/templates/indicator.html index 34ea2fe9c8..e9be598b18 100644 --- a/platform/commonUI/general/res/templates/indicator.html +++ b/platform/commonUI/general/res/templates/indicator.html @@ -19,20 +19,21 @@ this source code distribution or the Licensing information page available at runtime from the About dialog for additional information. --> + +
- - {{ngModel.getGlyph()}} - - - {{ngModel.getText()}} - - + + {{ngModel.getGlyph()}} + + {{ngModel.getText()}} + + + G diff --git a/platform/commonUI/general/res/templates/message-banner.html b/platform/commonUI/general/res/templates/message-banner.html new file mode 100644 index 0000000000..44c7f915b6 --- /dev/null +++ b/platform/commonUI/general/res/templates/message-banner.html @@ -0,0 +1,21 @@ +
+ + + + + + +
\ No newline at end of file diff --git a/platform/commonUI/general/res/templates/progress-bar.html b/platform/commonUI/general/res/templates/progress-bar.html new file mode 100644 index 0000000000..a24a4fab29 --- /dev/null +++ b/platform/commonUI/general/res/templates/progress-bar.html @@ -0,0 +1,10 @@ + + + + + +
+ {{ngModel.progress}}% complete. + {{ngModel.progressText}} +
\ No newline at end of file diff --git a/platform/commonUI/general/src/controllers/BannerController.js b/platform/commonUI/general/src/controllers/BannerController.js new file mode 100644 index 0000000000..4be9304cc6 --- /dev/null +++ b/platform/commonUI/general/src/controllers/BannerController.js @@ -0,0 +1,68 @@ +/***************************************************************************** + * 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"; + + /** + * 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.action = function (action, $event){ + /* + Prevents default 'maximize' behaviour when clicking on + notification button + */ + $event.stopPropagation(); + return action(); + }; + $scope.dismiss = function(notification, $event) { + $event.stopPropagation(); + notification.dismissOrMinimize(); + }; + $scope.maximize = function(notification) { + if (notification.model.severity !== "info"){ + + notification.model.cancel = function(){ + dialogService.dismiss(); + }; + dialogService.showBlockingMessage(notification.model); + } + }; + } + return BannerController; + }); \ No newline at end of file diff --git a/platform/commonUI/general/src/controllers/DateTimeFieldController.js b/platform/commonUI/general/src/controllers/DateTimeFieldController.js index 7b58834aa5..b87268dc5a 100644 --- a/platform/commonUI/general/src/controllers/DateTimeFieldController.js +++ b/platform/commonUI/general/src/controllers/DateTimeFieldController.js @@ -26,9 +26,6 @@ define( function () { 'use strict'; - var UNRECOGNIZED_FORMAT_ERROR = - "Unrecognized format for date-time field."; - /** * Controller to support the date-time entry field. * @@ -69,9 +66,6 @@ define( function setFormat(format) { formatter = formatService.getFormat(format || defaultFormat); - if (!formatter) { - throw new Error(UNRECOGNIZED_FORMAT_ERROR); - } updateFromModel($scope.ngModel[$scope.field]); } diff --git a/platform/commonUI/general/src/controllers/TimeRangeController.js b/platform/commonUI/general/src/controllers/TimeRangeController.js index b0ef5efe70..cdcdb7f8d0 100644 --- a/platform/commonUI/general/src/controllers/TimeRangeController.js +++ b/platform/commonUI/general/src/controllers/TimeRangeController.js @@ -26,9 +26,7 @@ define( function (moment) { "use strict"; - var TICK_SPACING_PX = 150, - UNRECOGNIZED_FORMAT_ERROR = - "Unrecognized format for time range control."; + var TICK_SPACING_PX = 150; /** @@ -221,11 +219,6 @@ define( function updateFormat(key) { formatter = formatService.getFormat(key || defaultFormat); - - if (!formatter) { - throw new Error(UNRECOGNIZED_FORMAT_ERROR); - } - updateViewForInnerSpanFromModel($scope.ngModel); updateTicks(); } diff --git a/platform/commonUI/notification/bundle.json b/platform/commonUI/notification/bundle.json new file mode 100644 index 0000000000..4851dd28b6 --- /dev/null +++ b/platform/commonUI/notification/bundle.json @@ -0,0 +1,45 @@ +{ + "extensions": { + "constants": [ + { + "key": "DEFAULT_AUTO_DISMISS", + "value": 3000 + }, + { + "key": "FORCE_AUTO_DISMISS", + "value": 1000 + }, + { + "key": "MINIMIZE_TIMEOUT", + "value": 300 + } + ], + "templates": [ + { + "key":"notificationIndicatorTemplate", + "templateUrl": "notification-indicator.html" + } + ], + "controllers": [ + { + "key": "NotificationIndicatorController", + "implementation": "NotificationIndicatorController.js", + "depends": ["$scope", "notificationService", "dialogService"] + } + ], + "indicators": [ + { + "implementation": "NotificationIndicator.js", + "priority": "fallback" + } + ], + "services": [ + { + "key": "notificationService", + "implementation": "NotificationService.js", + "depends": [ "$timeout", "DEFAULT_AUTO_DISMISS", + "MINIMIZE_TIMEOUT" ] + } + ] + } +} diff --git a/platform/commonUI/notification/res/notification-indicator.html b/platform/commonUI/notification/res/notification-indicator.html new file mode 100644 index 0000000000..9c7e80a639 --- /dev/null +++ b/platform/commonUI/notification/res/notification-indicator.html @@ -0,0 +1,10 @@ + + + + {{notifications.length}} + Notifications + + {{notifications.length}} + \ No newline at end of file diff --git a/platform/commonUI/notification/src/NotificationIndicator.js b/platform/commonUI/notification/src/NotificationIndicator.js new file mode 100644 index 0000000000..29a831d251 --- /dev/null +++ b/platform/commonUI/notification/src/NotificationIndicator.js @@ -0,0 +1,35 @@ +/***************************************************************************** + * 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 NotificationIndicator() {} + + NotificationIndicator.template = 'notificationIndicatorTemplate'; + + return NotificationIndicator; + } +); diff --git a/platform/commonUI/notification/src/NotificationIndicatorController.js b/platform/commonUI/notification/src/NotificationIndicatorController.js new file mode 100644 index 0000000000..e58b0a606b --- /dev/null +++ b/platform/commonUI/notification/src/NotificationIndicatorController.js @@ -0,0 +1,67 @@ +/***************************************************************************** + * 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"; + + /** + * 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; + + /** + * Launch a dialog showing a list of current notifications. + */ + $scope.showNotificationsList = function(){ + dialogService.getDialogResponse('overlay-message-list', { + 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(); + } + }); + + }; + } + return NotificationIndicatorController; + } +); + diff --git a/platform/commonUI/notification/src/NotificationService.js b/platform/commonUI/notification/src/NotificationService.js new file mode 100644 index 0000000000..568d31beb5 --- /dev/null +++ b/platform/commonUI/notification/src/NotificationService.js @@ -0,0 +1,387 @@ +/***************************************************************************** + * 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*/ + +/** + * This bundle implements the notification service, which can be used to + * show banner notifications to the user. Banner notifications + * are used to inform users of events in a non-intrusive way. As + * much as possible, notifications share a model with blocking + * dialogs so that the same information can be provided in a dialog + * and then minimized to a banner notification if needed. + * + * @namespace platform/commonUI/notification + */ +define( + [], + function () { + "use strict"; + + /** + * A representation of a user action. Options are provided to + * dialogs and notifications and are shown as buttons. + * + * @typedef {object} NotificationOption + * @property {string} label the label to appear on the button for + * this action + * @property {function} callback a callback function to be invoked + * when the button is clicked + */ + + /** + * A representation of a banner notification. Banner notifications + * are used to inform users of events in a non-intrusive way. As + * much as possible, notifications share a model with blocking + * dialogs so that the same information can be provided in a dialog + * and then minimized to a banner notification if needed, or vice-versa. + * + * @typedef {object} NotificationModel + * @property {string} title The title of the message + * @property {string} severity The importance of the message (one of + * 'info', 'alert', or 'error' where info < alert