Compare commits
	
		
			13 Commits
		
	
	
		
			vue-toolba
			...
			style-guid
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 91263b0f6d | ||
|   | c458666173 | ||
|   | e21906d1fd | ||
|   | f2193495ec | ||
|   | dd05f29210 | ||
|   | b35be0c559 | ||
|   | 9e6a2de585 | ||
|   | c7392db6f5 | ||
|   | 6ee4740f5f | ||
|   | 74401ed2de | ||
|   | c4fd3bc997 | ||
|   | 55bac65cad | ||
|   | ed327f5211 | 
							
								
								
									
										108
									
								
								API.md
									
									
									
									
									
								
							
							
						
						
									
										108
									
								
								API.md
									
									
									
									
									
								
							| @@ -567,7 +567,7 @@ openmct.time.timeSystem(utcTimeSystem, bounds); | ||||
| Setting the active time system will trigger a [`'timeSystem'`](#time-events)  | ||||
| event.  If you supplied bounds, a [`'bounds'`](#time-events) event will be triggered afterwards with your newly supplied bounds. | ||||
|  | ||||
| ### Time Bounds | ||||
| #### Time Bounds | ||||
|  | ||||
| The TimeAPI provides a getter/setter for querying and setting time bounds. Time  | ||||
| bounds are simply an object with a `start` and an end `end` attribute. | ||||
| @@ -591,7 +591,7 @@ openmct.time.bounds({start: now - ONE_HOUR, now); | ||||
| To respond to bounds change events, listen for the [`'bounds'`](#time-events) | ||||
| event. | ||||
|  | ||||
| ## Clocks | ||||
| ### Clocks | ||||
|  | ||||
| The Time API can be set to follow a clock source which will cause the bounds | ||||
| to be updated automatically whenever the clock source "ticks". A clock is simply | ||||
| @@ -610,7 +610,7 @@ be defined to tick on some remote timing source. | ||||
| The values provided by clocks are simple `number`s, which are interpreted in the | ||||
| context of the active [Time System](#defining-and-registering-time-systems). | ||||
|  | ||||
| ### Defining and registering clocks | ||||
| #### Defining and registering clocks | ||||
|  | ||||
| A clock is an object that defines certain required metadata and functions: | ||||
|  | ||||
| @@ -724,7 +724,7 @@ __Note:__ Setting the clock offsets will trigger an immediate bounds change, as | ||||
| new bounds will be calculated based on the `currentValue()` of the active clock.  | ||||
| Clock offsets are only relevant when a clock source is active. | ||||
|  | ||||
| ## Time Events | ||||
| ### Time Events | ||||
|  | ||||
| The Time API is a standard event emitter; you can register callbacks for events using the `on` method and remove callbacks for events with the `off` method. | ||||
|  | ||||
| @@ -766,7 +766,7 @@ The events emitted by the Time API are: | ||||
|   * `clockOffsets`: The new [clock offsets](#clock-offsets). | ||||
|  | ||||
|  | ||||
| ## The Time Conductor | ||||
| ### The Time Conductor | ||||
|  | ||||
| The Time Conductor provides a user interface for managing time bounds in Open  | ||||
| MCT. It allows a user to select from configured time systems and clocks, and to set bounds and clock offsets. | ||||
| @@ -856,6 +856,90 @@ openmct.install(openmct.plugins.Conductor({ | ||||
| })); | ||||
| ``` | ||||
|  | ||||
| ## Indicators | ||||
|  | ||||
| Indicators are small widgets that reside at the bottom of the screen and are visible from  | ||||
| every screen in Open MCT. They can be used to convey system state using an icon and text. | ||||
| Indicators tend to be collapsed to an icon by default (though this behavior can be customized  | ||||
| by defining a [custom indicator](#custom-indicators)), and hovering over them will reveal  | ||||
| text providing more information. | ||||
|  | ||||
| ### The URL Status Indicator | ||||
|  | ||||
| A common use case for indicators is to convey the state of some external system such as a  | ||||
| persistence backend or HTTP server. So long as this system is accessible via http request,  | ||||
| Open MCT provides a general purpose indicator to show whether the server is available and  | ||||
| returing a 2xx status code. The URL Status Indicator is made available as a default plugin. See | ||||
| [Included Plugins](#included-plugins) below for details on how to install and configure the  | ||||
| URL Status Indicator. | ||||
|  | ||||
| ### Creating a New Indicator | ||||
|  | ||||
| A new indicator can be created with a simple API call, eg. | ||||
|  | ||||
| ``` javascript | ||||
| var myIndicator = openmct.indicators.create(); | ||||
| myIndicator.text("Hello World!"); | ||||
| ``` | ||||
|  | ||||
| This will create a new indicator and add it to the bottom of the screen in Open MCT. | ||||
| By default, the indicator will appear as an information icon. Hovering over the icon will | ||||
| reveal the text set via the call to `.text()`. The Indicator object returned by the API  | ||||
| call exposes a number of functions for customizing the content and appearance of the indicator: | ||||
|  | ||||
| * `.text([text])`: Gets or sets the text shown when the user hovers over the indicator. | ||||
| Accepts an __optional__ `string` argument that, if provided, will be used to set the text.  | ||||
| Hovering over the indicator will expand it to its full size, revealing this text alongside  | ||||
| the icon. Returns the currently set text as a `string`. | ||||
| * `.description([description])`: Gets or sets the indicator's description. Accepts an  | ||||
| __optional__ `string` argument that, if provided, will be used to set the text. The description  | ||||
| allows for more detail to be provided in a tooltip when the user hovers over the indicator.  | ||||
| Returns the currently set text as a `string`. | ||||
| * `.iconClass([className])`: Gets or sets the CSS class used to define the icon. Accepts an __optional__  | ||||
| `string` parameter to be used to set the class applied to the indicator. Any of  | ||||
| [the built-in glyphs](https://nasa.github.io/openmct/style-guide/#/browse/styleguide:home/glyphs?view=styleguide.glyphs)  | ||||
| may be used here, or a custom CSS class can be provided. Returns the currently defined CSS  | ||||
| class as a `string`. | ||||
| * `.statusClass([className])`: Gets or sets the CSS class used to determine status. Accepts an __optional __ | ||||
| `string` parameter to be used to set a status class applied to the indicator. May be used to apply  | ||||
| different colors to indicate status. | ||||
|  | ||||
| ### Custom Indicators | ||||
|  | ||||
| A completely custom indicator can be added by registering a factory function that produces  | ||||
| a DOM element for your custom indicator. eg. | ||||
|  | ||||
| ``` javascript | ||||
| openmct.indicators.create(function () { | ||||
|     var domNode = document.createElement('div'); | ||||
|     domNode.innerText = new Date().toString(); | ||||
|     setInterval(function () { | ||||
|         domNode.innerText = new Date().toString(); | ||||
|     }, 1000); | ||||
|     return domNode; | ||||
| }); | ||||
| ``` | ||||
|  | ||||
| ### Priority | ||||
|  | ||||
| When creating a new indicator or defining a custom indicator, a `number` can optionally be  | ||||
| provided that will determine the order that the indicator appears on the screen. An indicator  | ||||
| with a higher `priority` number will be shown to the left of indicators with lower  | ||||
| priority numbers. The lowest possible `priority` (and the default value if no `priority` is specified)  | ||||
| is `Number.NEGATIVE_INFINTY`, and the highest possible priority is `Number.POSITIVE_INFINITY`. | ||||
|  | ||||
| eg. | ||||
| ``` javascript | ||||
| var myIndicator = openmct.indicators.create(1); | ||||
| myIndicator.text("I'm on the left!"); | ||||
|  | ||||
| openmct.indicators.create(0, function () { | ||||
|     var domNode = document.createElement('div'); | ||||
|     domNode.innerText = "I'm on the right!"; | ||||
|     return domNode; | ||||
| }); | ||||
| ``` | ||||
|  | ||||
| ## Included Plugins | ||||
|  | ||||
| Open MCT is packaged along with a few general-purpose plugins: | ||||
| @@ -879,18 +963,18 @@ openmct.install(openmct.plugins.CouchDB('http://localhost:9200')) | ||||
| * `openmct.plugins.Espresso` and `openmct.plugins.Snow` are two different | ||||
|   themes (dark and light) available for Open MCT. Note that at least one | ||||
|   of these themes must be installed for Open MCT to appear correctly. | ||||
| * `openmct.plugins.URLIndicatorPlugin` adds an indicator which shows the | ||||
| * `openmct.plugins.URLIndicator` adds an indicator which shows the | ||||
| availability of a URL with the following options:  | ||||
|   - `url` : URL to indicate the status of | ||||
|   - `cssClass`: Icon to show in the status bar, defaults to `icon-database`, [list of all icons](https://nasa.github.io/openmct/style-guide/#/browse/styleguide:home?view=items) | ||||
|   - `iconClass`: Icon to show in the status bar, defaults to `icon-database`, [list of all icons](https://nasa.github.io/openmct/style-guide/#/browse/styleguide:home?view=items) | ||||
|   - `interval`: Interval between checking the connection, defaults to `10000` | ||||
|   - `label` Name showing up as text in the status bar, defaults to url | ||||
| ```javascript | ||||
| openmct.install(openmct.plugins.URLIndicatorPlugin({ | ||||
|   url: 'http://google.com', | ||||
|   cssClass: 'check', | ||||
|   interval: 10000, | ||||
|   label: 'Google' | ||||
| openmct.install(openmct.plugins.URLIndicator({ | ||||
|   url: 'http://localhost:8080', | ||||
|     iconClass: 'check', | ||||
|     interval: 10000, | ||||
|     label: 'Localhost' | ||||
|  }) | ||||
| ); | ||||
| ``` | ||||
|   | ||||
| @@ -38,7 +38,8 @@ define([ | ||||
|                     "provides": "identityService", | ||||
|                     "type": "provider", | ||||
|                     "depends": [ | ||||
|                         "dialogService" | ||||
|                         "dialogService", | ||||
|                         "$q" | ||||
|                     ] | ||||
|                 } | ||||
|             ] | ||||
|   | ||||
| @@ -55,21 +55,37 @@ define( | ||||
|          * @implements {IdentityService} | ||||
|          * @memberof platform/identity | ||||
|          */ | ||||
|         function ExampleIdentityProvider(dialogService) { | ||||
|             // Handle rejected dialog messages by treating the | ||||
|             // current user as undefined. | ||||
|             function echo(v) { return v; } | ||||
|             function giveUndefined() { return undefined; } | ||||
|         function ExampleIdentityProvider(dialogService, $q) { | ||||
|             this.dialogService = dialogService; | ||||
|             this.$q = $q; | ||||
|  | ||||
|             this.userPromise = | ||||
|                 dialogService.getUserInput(DIALOG_STRUCTURE, DEFAULT_IDENTITY) | ||||
|                     .then(echo, giveUndefined); | ||||
|             this.returnUser = this.returnUser.bind(this); | ||||
|             this.returnUndefined = this.returnUndefined.bind(this); | ||||
|         } | ||||
|  | ||||
|         ExampleIdentityProvider.prototype.getUser = function () { | ||||
|             return this.userPromise; | ||||
|             if (this.user) { | ||||
|                 return this.$q.when(this.user); | ||||
|             } else { | ||||
|                 return this.dialogService.getUserInput(DIALOG_STRUCTURE, DEFAULT_IDENTITY) | ||||
|                     .then(this.returnUser, this.returnUndefined); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * @private | ||||
|          */ | ||||
|         ExampleIdentityProvider.prototype.returnUser = function (user) { | ||||
|             return this.user = user; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * @private | ||||
|          */ | ||||
|         ExampleIdentityProvider.prototype.returnUndefined = function () { | ||||
|             return undefined; | ||||
|         } | ||||
|  | ||||
|         return ExampleIdentityProvider; | ||||
|     } | ||||
| ); | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| <span class="status block" ng-controller="DialogLaunchController"> | ||||
| <span class="l-indicator s-indicator icon-box-with-arrow" ng-controller="DialogLaunchController"> | ||||
|     <!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! --> | ||||
|     <span class="status-indicator icon-box-with-arrow"></span><span class="label"> | ||||
|     <span class="label"> | ||||
|         <a ng-click="launchProgress(true)">Known</a> | | ||||
|         <a ng-click="launchProgress(false)">Unknown</a> | | ||||
|         <a ng-click="launchError()">Error</a> | | ||||
|         <a ng-click="launchInfo()">Info</a> | ||||
|     </span><span class="count"></span> | ||||
|     </span> | ||||
| </span> | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| <span class="status block" ng-controller="NotificationLaunchController"> | ||||
| <span class="l-indicator s-indicator icon-bell" ng-controller="NotificationLaunchController"> | ||||
|     <!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! --> | ||||
|     <span class="status-indicator icon-bell"></span><span class="label"> | ||||
|     <span class="label"> | ||||
|         <a ng-click="newInfo()">Success</a> | | ||||
|         <a ng-click="newError()">Error</a> | | ||||
|         <a ng-click="newAlert()">Alert</a> | | ||||
|         <a ng-click="newProgress()">Progress</a> | ||||
|     </span><span class="count"></span> | ||||
|     </span> | ||||
| </span> | ||||
|   | ||||
| @@ -129,6 +129,44 @@ | ||||
|         </div> | ||||
|     </div> | ||||
|  | ||||
|     <div class="l-section"> | ||||
|         <h2>Status Bar Indicators</h2> | ||||
|         <div class="cols cols1-1"> | ||||
|             <div class="col"> | ||||
|                 <p>Indicators content goes here.</p> | ||||
|             </div> | ||||
| <mct-example><div class="status-holder s-status-bar"> | ||||
| <span class="status-block-holder"> | ||||
|     <span class="l-indicator s-indicator"> | ||||
|         <span class="status-indicator icon-bell"></span> | ||||
|         <span class="label">Collapsible Indicator</span> | ||||
|     </span> | ||||
| </span> | ||||
| <span class="status-block-holder no-collapse caution"> | ||||
|     <span class="l-indicator s-indicator"> | ||||
|         <span class="status-indicator icon-bell"></span> | ||||
|         <span class="label">No collapse</span> | ||||
|     </span> | ||||
| </span> | ||||
| </div> | ||||
| <div class="status-holder s-status-bar"> | ||||
| <span class="status-block-holder"> | ||||
|     <span class="l-indicator s-indicator"> | ||||
|         <span class="status-indicator icon-bell"></span> | ||||
|         <span class="label">Collapsible Indicator</span> | ||||
|     </span> | ||||
| </span> | ||||
|     <span class="status-block-holder"> | ||||
|     <span class="status block s-status-info icon-info"> | ||||
|         <span class="label">No collapse</span> | ||||
|     </span> | ||||
| </span> | ||||
| </div> | ||||
| </mct-example> | ||||
|         </div> | ||||
|     </div> | ||||
|  | ||||
|  | ||||
|     <div class="l-section"> | ||||
|         <h2>Synchronization</h2> | ||||
|         <div class="cols cols1-1"> | ||||
|   | ||||
| @@ -54,7 +54,7 @@ define( | ||||
|                     return "icon-object-unknown"; | ||||
|                 }, | ||||
|                 getText: function () { | ||||
|                     return latest; | ||||
|                     return "" + latest; | ||||
|                 }, | ||||
|                 getDescription: function () { | ||||
|                     return ""; | ||||
|   | ||||
| @@ -34,7 +34,6 @@ define([ | ||||
|     "./src/controllers/ContextMenuController", | ||||
|     "./src/controllers/ClickAwayController", | ||||
|     "./src/controllers/ViewSwitcherController", | ||||
|     "./src/controllers/BottomBarController", | ||||
|     "./src/controllers/GetterSetterController", | ||||
|     "./src/controllers/SelectorController", | ||||
|     "./src/controllers/ObjectInspectorController", | ||||
| @@ -49,11 +48,12 @@ define([ | ||||
|     "./src/directives/MCTSplitPane", | ||||
|     "./src/directives/MCTSplitter", | ||||
|     "./src/directives/MCTTree", | ||||
|     "./src/directives/MCTIndicators", | ||||
|     "./src/filters/ReverseFilter", | ||||
|     "text!./res/templates/bottombar.html", | ||||
|     "text!./res/templates/controls/action-button.html", | ||||
|     "text!./res/templates/controls/input-filter.html", | ||||
|     "text!./res/templates/indicator.html", | ||||
|     "text!./res/templates/angular-indicator.html", | ||||
|     "text!./res/templates/message-banner.html", | ||||
|     "text!./res/templates/progress-bar.html", | ||||
|     "text!./res/templates/controls/time-controller.html", | ||||
| @@ -84,7 +84,6 @@ define([ | ||||
|     ContextMenuController, | ||||
|     ClickAwayController, | ||||
|     ViewSwitcherController, | ||||
|     BottomBarController, | ||||
|     GetterSetterController, | ||||
|     SelectorController, | ||||
|     ObjectInspectorController, | ||||
| @@ -99,6 +98,7 @@ define([ | ||||
|     MCTSplitPane, | ||||
|     MCTSplitter, | ||||
|     MCTTree, | ||||
|     MCTIndicators, | ||||
|     ReverseFilter, | ||||
|     bottombarTemplate, | ||||
|     actionButtonTemplate, | ||||
| @@ -275,13 +275,6 @@ define([ | ||||
|                         "$timeout" | ||||
|                     ] | ||||
|                 }, | ||||
|                 { | ||||
|                     "key": "BottomBarController", | ||||
|                     "implementation": BottomBarController, | ||||
|                     "depends": [ | ||||
|                         "indicators[]" | ||||
|                     ] | ||||
|                 }, | ||||
|                 { | ||||
|                     "key": "GetterSetterController", | ||||
|                     "implementation": GetterSetterController, | ||||
| @@ -395,6 +388,11 @@ define([ | ||||
|                     "key": "mctTree", | ||||
|                     "implementation": MCTTree, | ||||
|                     "depends": ['gestureService'] | ||||
|                 }, | ||||
|                 { | ||||
|                     "key": "mctIndicators", | ||||
|                     "implementation": MCTIndicators, | ||||
|                     "depends": ['openmct'] | ||||
|                 } | ||||
|             ], | ||||
|             "constants": [ | ||||
|   | ||||
| @@ -42,6 +42,7 @@ | ||||
| @import "controls/lists"; | ||||
| @import "controls/menus"; | ||||
| @import "controls/messages"; | ||||
| @import "controls/indicators"; | ||||
| @import "mobile/controls/menus"; | ||||
|  | ||||
| /********************************* FORMS */ | ||||
|   | ||||
| @@ -20,13 +20,15 @@ | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
| /*************************************************** MIXINS */ | ||||
| @mixin formulateStatusColors($c) { | ||||
| @mixin elementStatusColors($c) { | ||||
|     // Sets bg and icon colors for elements | ||||
|     background: rgba($c, 0.4) !important; | ||||
|     &:before { color: $c !important; } | ||||
| } | ||||
|  | ||||
|  | ||||
| @mixin indicatorStatusColors($c) { | ||||
|     &:before, .count { color: $c; } | ||||
| } | ||||
|  | ||||
| /*************************************************** GENERAL */ | ||||
| .s-limit-yellow, | ||||
| @@ -54,14 +56,13 @@ | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| /*************************************************** LIMITS */ | ||||
| .s-limit-yellow, .s-limit-yellow-icon { | ||||
|     @include formulateStatusColors($colorWarningLo); | ||||
|     @include elementStatusColors($colorWarningLo); | ||||
| } | ||||
|  | ||||
| .s-limit-red, .s-limit-red-icon { | ||||
|     @include formulateStatusColors($colorWarningHi); | ||||
|     @include elementStatusColors($colorWarningHi); | ||||
| } | ||||
|  | ||||
| .s-limit-upr:before { content: $glyph-icon-arrow-double-up; } | ||||
| @@ -70,11 +71,11 @@ | ||||
| .s-limit-red-icon:before { content: $glyph-icon-alert-triangle; } | ||||
|  | ||||
| /*************************************************** STATUS */ | ||||
| .s-status-warning-hi, .s-status-warning-hi-icon {  @include formulateStatusColors($colorWarningHi); } | ||||
| .s-status-warning-lo, .s-status-warning-lo-icon {  @include formulateStatusColors($colorWarningLo); } | ||||
| .s-status-diagnostic, .s-status-diagnostic-icon {  @include formulateStatusColors($colorDiagnostic); } | ||||
| .s-status-info, .s-status-info-icon {  @include formulateStatusColors($colorInfo); } | ||||
| .s-status-ok, .s-status-ok-icon {  @include formulateStatusColors($colorOk); } | ||||
| .s-status-warning-hi, .s-status-warning-hi-icon {  @include elementStatusColors($colorWarningHi); } | ||||
| .s-status-warning-lo, .s-status-warning-lo-icon {  @include elementStatusColors($colorWarningLo); } | ||||
| .s-status-diagnostic, .s-status-diagnostic-icon {  @include elementStatusColors($colorDiagnostic); } | ||||
| .s-status-info, .s-status-info-icon {  @include elementStatusColors($colorInfo); } | ||||
| .s-status-ok, .s-status-ok-icon {  @include elementStatusColors($colorOk); } | ||||
|  | ||||
| .s-status-warning-hi-icon:before { content: $glyph-icon-alert-triangle; } | ||||
| .s-status-warning-lo-icon:before { content: $glyph-icon-alert-rect; } | ||||
| @@ -82,4 +83,25 @@ | ||||
| .s-status-info-icon:before { content: $glyph-icon-info; } | ||||
| .s-status-ok-icon:before { content: $glyph-icon-check; } | ||||
|  | ||||
| /*************************************************** INDICATORS */ | ||||
| .s-indicator-status-info { | ||||
|     @include indicatorStatusColors($colorInfo); | ||||
| } | ||||
| .s-indicator-status-ok { | ||||
|     @include indicatorStatusColors($colorOk); | ||||
| } | ||||
| .s-indicator-status-caution, .s-indicator-status-warning, .s-indicator-status-alert { | ||||
|     @include indicatorStatusColors($colorStatusAlert); | ||||
| } | ||||
| .s-indicator-status-error, .s-indicator-status-err { | ||||
|     @include indicatorStatusColors($colorStatusError); | ||||
| } | ||||
| .s-indicator-status-available { | ||||
|     @include indicatorStatusColors($colorStatusAvailable); | ||||
| } | ||||
| .s-indicator-status-subdued { | ||||
|     opacity: 0.7; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										99
									
								
								platform/commonUI/general/res/sass/controls/_indicators.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								platform/commonUI/general/res/sass/controls/_indicators.scss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,99 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2017, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT 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 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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| /* Indicators are generally only displayed in the ue-bottom-bar element of the main interface */ | ||||
|  | ||||
| .l-indicator { | ||||
|     $transDelayHover: 1.5s; | ||||
|     $transDelayWhileExpanded: 2.5s; | ||||
|     $transSpeed: .25s; | ||||
|     display: inline-block; | ||||
|     margin-right: $interiorMarginSm; | ||||
|  | ||||
|     &:before { | ||||
|         // Icon | ||||
|         display: inline-block; | ||||
|         opacity: 0.85; | ||||
|     } | ||||
|  | ||||
|     .label, | ||||
|     .count { | ||||
|         display: inline-block; | ||||
|         vertical-align: top; | ||||
|     } | ||||
|  | ||||
|     &.float-right { | ||||
|         float: right; | ||||
|     } | ||||
|  | ||||
|     &.no-icon { | ||||
|         &:before { | ||||
|             display: none; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     &:not(.no-collapse) { | ||||
|         .label { | ||||
|             // Max-width silliness is necessary for width transition | ||||
|             @include trans-prop-nice((max-width, margin-right), $transSpeed, $transDelayWhileExpanded); | ||||
|             overflow: hidden; | ||||
|             margin-right: 0; | ||||
|             max-width: 0px; | ||||
|             white-space: nowrap; | ||||
|         } | ||||
|         &:hover { | ||||
|             &:before { | ||||
|                 opacity: 1; | ||||
|             } | ||||
|  | ||||
|             .label { | ||||
|                 @include trans-prop-nice((max-width, margin-right), 0s); | ||||
|                 margin-right: $interiorMargin; | ||||
|                 max-width: 600px; | ||||
|                 width: auto; | ||||
|             } | ||||
|  | ||||
|             .count { | ||||
|                 @include trans-prop-nice(max-width, 0s); | ||||
|                 opacity: 0; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     .count { | ||||
|         @include trans-prop-nice(opacity, $transSpeed, $transDelayWhileExpanded); | ||||
|         font-weight: bold; | ||||
|         opacity: 1; | ||||
|     } | ||||
|  | ||||
|     .s-button { | ||||
|         background: $colorStatusBtnBg; | ||||
|         padding: 0 $interiorMargin; | ||||
|         height: auto; | ||||
|         line-height: inherit; | ||||
|     } | ||||
| } | ||||
|  | ||||
| .s-indicator { | ||||
|     color: $colorStatusDefault; | ||||
|  | ||||
| } | ||||
| @@ -19,7 +19,7 @@ | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
| /******************************************************************* STATUS BLOCK ELEMS */ | ||||
|  | ||||
| @mixin statusBannerColors($bg, $fg: $colorStatusFg) { | ||||
| 	$bgPb: 30%; | ||||
| 	$bgPbD: 10%; | ||||
| @@ -36,110 +36,6 @@ | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Status coloring | ||||
| .ok, .info { | ||||
|     .status-indicator { | ||||
|         color: $colorInfo; | ||||
|     } | ||||
| } | ||||
|  | ||||
| .alert, .caution, .warning { | ||||
|     .status-indicator, .count { | ||||
|         color: $colorStatusAlert; | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| .error, .err { | ||||
|     .status-indicator, .count { | ||||
|         color: $colorStatusError; | ||||
|     } | ||||
| } | ||||
|  | ||||
| .available { | ||||
|     .status-indicator, .count { | ||||
|         color: $colorStatusAvailable; | ||||
|     } | ||||
| } | ||||
|  | ||||
| .subdued { | ||||
|     .status-indicator { | ||||
|         color: pullForward($colorStatusBarBg, 40%); | ||||
|     } | ||||
| } | ||||
|  | ||||
| .status-block-holder { | ||||
|     // Applied to mct-include element | ||||
|     // Contains status.block elements | ||||
|     $transDelay: 1.5s; | ||||
|     $transSpeed: .25s; | ||||
|     display: inline-block; | ||||
|     &.clickable { cursor: pointer; } | ||||
|     &:not(.clickable) { cursor: default; } | ||||
|     &.no-icon .status.block { | ||||
|         .status-indicator { | ||||
|             display: none; | ||||
|         } | ||||
|     } | ||||
|     &.float-right { | ||||
|         float: right; | ||||
|     } | ||||
|     &:not(.no-collapse) .status.block { | ||||
|         .label { | ||||
|             // Max-width silliness is necessary for width transition | ||||
|             @include trans-prop-nice(max-width, $transSpeed, $transDelay); | ||||
|             overflow: hidden; | ||||
|             max-width: 0px; | ||||
|         } | ||||
|         &:hover { | ||||
|             .label { | ||||
|                 @include trans-prop-nice(max-width, $transSpeed, 0s); | ||||
|                 max-width: 600px; | ||||
|                 width: auto; | ||||
|             } | ||||
|             .count { | ||||
|                 @include trans-prop-nice(max-width, $transSpeed, 0s); | ||||
|                 opacity: 0; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| .status.block { | ||||
|     $transDelay: 1.5s; | ||||
|     $transSpeed: .25s; | ||||
| 	color: $colorStatusDefault; | ||||
| 	display: inline-block; | ||||
| 	margin-right: $interiorMargin; | ||||
| 	.status-indicator, | ||||
| 	.label, | ||||
| 	.count { | ||||
| 		display: inline-block; | ||||
| 		vertical-align: top; | ||||
| 	} | ||||
|  | ||||
| 	.status-indicator { | ||||
|         background: none !important; | ||||
| 		margin-right: $interiorMarginSm; | ||||
|         &[class*='s-status']:before { | ||||
|             font-size: 1em; | ||||
|         } | ||||
| 	} | ||||
|  | ||||
| 	.count { | ||||
| 		@include trans-prop-nice(opacity, $transSpeed, $transDelay); | ||||
| 		font-weight: bold; | ||||
| 		opacity: 1; | ||||
| 	} | ||||
|     .s-button { | ||||
|         background: $colorStatusBtnBg; | ||||
|         padding: 0 $interiorMargin; | ||||
|         height: auto; | ||||
|         line-height: inherit; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /******************************************************************* MESSAGE BANNERS */ | ||||
| .message { | ||||
| 	&.block { | ||||
|   | ||||
| @@ -81,16 +81,14 @@ | ||||
|         @include absPosDefault(0);// New status bar design | ||||
|         top: auto; | ||||
|         height: $ueFooterH; | ||||
|         line-height: $ueFooterH - ($interiorMargin * 2); | ||||
|         background: $colorStatusBarBg; | ||||
|         color: lighten($colorBodyBg, 30%); | ||||
|         font-size: .7rem; | ||||
|         .status-holder { | ||||
|  | ||||
|         mct-indicators { display: block; } | ||||
|          | ||||
|         .indicator-holder { | ||||
|             box-sizing: border-box; | ||||
|             @include absPosDefault($interiorMargin); | ||||
|             @include ellipsize(); | ||||
|             right: 120px; | ||||
|             text-transform: uppercase; | ||||
|             z-index: 1; | ||||
|         } | ||||
|         .app-logo { | ||||
| @@ -105,6 +103,14 @@ | ||||
|     } | ||||
| } | ||||
|  | ||||
| .s-status-bar { | ||||
|     background: $colorStatusBarBg; | ||||
|     color: lighten($colorBodyBg, 30%); | ||||
|     font-size: .7rem; | ||||
|     line-height: $ueFooterH - ($interiorMargin * 2); | ||||
|     text-transform: uppercase; | ||||
| } | ||||
|  | ||||
| .edit-mode { | ||||
|     // Old edit mode | ||||
|     .split-layout { | ||||
|   | ||||
| @@ -20,14 +20,12 @@ | ||||
|  at runtime from the About dialog for additional information. | ||||
| --> | ||||
| <!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! --> | ||||
| <div class='status block' | ||||
| <div class='l-indicator s-indicator s-indicator-status-{{ngModel.getGlyphClass()}}' | ||||
| 	 title="{{ngModel.getDescription()}}" | ||||
| 	 ng-click='ngModel.configure()' | ||||
| 	 ng-show="ngModel.getText().length > 0"> | ||||
| 	<span class="status-indicator {{ngModel.getCssClass()}}"></span><span class="label" | ||||
| 		  ng-class='ngModel.getTextClass()'> | ||||
| 	 ng-show="ngModel.getText().length > 0" | ||||
|      ng-class="ngModel.getCssClass()"> | ||||
| 	<span class="label" ng-class='ngModel.getTextClass()'> | ||||
| 		{{ngModel.getText()}} | ||||
|         <a class="s-button icon-gear" ng-if="ngModel.configure"></a> | ||||
| 	</span><span class="count"> | ||||
| 	</span> | ||||
| </div> | ||||
| @@ -19,14 +19,9 @@ | ||||
|  this source code distribution or the Licensing information page available | ||||
|  at runtime from the About dialog for additional information. | ||||
| --> | ||||
| <div class='abs bottom-bar ue-bottom-bar mobile-disable-select' ng-controller="BottomBarController as bar"> | ||||
|     <div id='status' class='status-holder'> | ||||
|         <mct-include ng-repeat="indicator in bar.getIndicators()" | ||||
|                      ng-model="indicator.ngModel" | ||||
|                      key="indicator.template" | ||||
|                      class="status-block-holder" | ||||
|                      ng-class='indicator.ngModel.getGlyphClass()'> | ||||
|         </mct-include> | ||||
| <div class='abs bottom-bar ue-bottom-bar s-status-bar mobile-disable-select'> | ||||
|     <div id='status' class='indicator-holder'> | ||||
|         <mct-indicators></mct-indicators> | ||||
|     </div> | ||||
|     <mct-include key="'message-banner'"></mct-include> | ||||
|     <mct-include key="'about-logo'"></mct-include> | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2017, United States Government | ||||
|  * Open MCT, Copyright (c) 2014-2018, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
| @@ -23,37 +23,20 @@ | ||||
| define( | ||||
|     [], | ||||
|     function () { | ||||
| 
 | ||||
|         /** | ||||
|          * Controller for the bottombar template. Exposes | ||||
|          * available indicators (of extension category "indicators") | ||||
|          * @memberof platform/commonUI/general | ||||
|          * @constructor | ||||
|          */ | ||||
|         function BottomBarController(indicators) { | ||||
|             // Utility function used to make indicators presentable
 | ||||
|             // for display.
 | ||||
|             function present(Indicator) { | ||||
|                 return { | ||||
|                     template: Indicator.template || "indicator", | ||||
|                     ngModel: typeof Indicator === 'function' ? | ||||
|                             new Indicator() : Indicator | ||||
|                 }; | ||||
|             } | ||||
| 
 | ||||
|             this.indicators = indicators.map(present); | ||||
|         function MCTIndicators(openmct) { | ||||
|             return { | ||||
|                 restrict: "E", | ||||
|                 link: function link(scope, element) { | ||||
|                     openmct.indicators.allIndicatorElements().then(function (elements) { | ||||
|                         elements.forEach(function (indicatorElement) { | ||||
|                             element.append(indicatorElement); | ||||
|                         }); | ||||
|                     }); | ||||
|                 } | ||||
|             }; | ||||
|         } | ||||
| 
 | ||||
|         /** | ||||
|          * Get all indicators to display. | ||||
|          * @returns {Indicator[]} all indicators | ||||
|          *          to display in the bottom bar. | ||||
|          * @memberof platform/commonUI/general.BottomBarController# | ||||
|          */ | ||||
|         BottomBarController.prototype.getIndicators = function () { | ||||
|             return this.indicators; | ||||
|         }; | ||||
|         return MCTIndicators; | ||||
| 
 | ||||
|         return BottomBarController; | ||||
|     } | ||||
| ); | ||||
| @@ -1,76 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2017, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT 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 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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ["../../src/controllers/BottomBarController"], | ||||
|     function (BottomBarController) { | ||||
|  | ||||
|         describe("The bottom bar controller", function () { | ||||
|             var testIndicators, | ||||
|                 testIndicatorA, | ||||
|                 testIndicatorB, | ||||
|                 testIndicatorC, | ||||
|                 mockIndicator, | ||||
|                 controller; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockIndicator = jasmine.createSpyObj( | ||||
|                     "indicator", | ||||
|                     ["getGlyph", "getCssClass", "getText"] | ||||
|                 ); | ||||
|  | ||||
|                 testIndicatorA = {}; | ||||
|                 testIndicatorB = function () { | ||||
|                     return mockIndicator; | ||||
|                 }; | ||||
|                 testIndicatorC = { template: "someTemplate" }; | ||||
|  | ||||
|                 testIndicators = [ | ||||
|                     testIndicatorA, | ||||
|                     testIndicatorB, | ||||
|                     testIndicatorC | ||||
|                 ]; | ||||
|  | ||||
|                 controller = new BottomBarController(testIndicators); | ||||
|             }); | ||||
|  | ||||
|             it("exposes one indicator description per extension", function () { | ||||
|                 expect(controller.getIndicators().length) | ||||
|                     .toEqual(testIndicators.length); | ||||
|             }); | ||||
|  | ||||
|             it("uses template field provided, or its own default", function () { | ||||
|                 // "indicator" is the default; | ||||
|                 // only testIndicatorC overrides this. | ||||
|                 var indicators = controller.getIndicators(); | ||||
|                 expect(indicators[0].template).toEqual("indicator"); | ||||
|                 expect(indicators[1].template).toEqual("indicator"); | ||||
|                 expect(indicators[2].template).toEqual("someTemplate"); | ||||
|             }); | ||||
|  | ||||
|             it("instantiates indicators given as constructors", function () { | ||||
|                 // testIndicatorB constructs to mockIndicator | ||||
|                 expect(controller.getIndicators()[1].ngModel).toBe(mockIndicator); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,9 +1,7 @@ | ||||
| <!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! --> | ||||
| <a ng-click="showNotificationsList()" ng-show="notifications.length > 0" class="status block" | ||||
|       ng-class="highest.severity" | ||||
| <a ng-click="showNotificationsList()" ng-show="notifications.length > 0" class="l-indicator s-indicator s-indicator-status-{{highest.severity}} icon-bell" | ||||
|       ng-controller="NotificationIndicatorController"> | ||||
|     <span class="status-indicator icon-bell"></span><span class="label"> | ||||
|       {{notifications.length}} Notifications | ||||
|     <span class="label"> | ||||
|         {{notifications.length}} Notification<span ng-show="notifications.length > 1">s</span> | ||||
|     </span><span class="count">{{notifications.length}}</span> | ||||
|  | ||||
| </a> | ||||
|   | ||||
| @@ -55,7 +55,7 @@ $colorTransLucBg: #666; // Used as a visual blocking element over variable backg | ||||
|  | ||||
| // Foundation Colors | ||||
| $colorAlt1: #ffc700; | ||||
| $colorAlert: #ff3c00; | ||||
| $colorAlert: #ff6600; | ||||
| $colorWarningHi: #cc0000; | ||||
| $colorWarningLo: #ff9900; | ||||
| $colorDiagnostic: #a4b442; | ||||
| @@ -114,10 +114,10 @@ $colorInspectorSectionHeaderFg: pullForward($colorInspectorBg, 40%); | ||||
|  | ||||
| // Status colors, mainly used for messaging and item ancillary symbols | ||||
| $colorStatusFg: #ccc; | ||||
| $colorStatusDefault: #ccc; | ||||
| $colorStatusDefault: #999; | ||||
| $colorStatusInfo: $colorInfo; | ||||
| $colorStatusAlert: $colorAlert; | ||||
| $colorStatusError: #d4585c; | ||||
| $colorStatusError: #ff3300; | ||||
| $colorStatusAvailable: $colorKey; | ||||
| $colorStatusBtnBg: $colorBtnBg; | ||||
| $colorProgressBarOuter: rgba(#000, 0.1); | ||||
|   | ||||
| @@ -55,7 +55,6 @@ define([ | ||||
|     timerTemplate, | ||||
|     legacyRegistry | ||||
| ) { | ||||
|  | ||||
|     legacyRegistry.register("platform/features/clock", { | ||||
|         "name": "Clocks/Timers", | ||||
|         "descriptions": "Domain objects for displaying current & relative times.", | ||||
| @@ -86,11 +85,6 @@ define([ | ||||
|                         "CLOCK_INDICATOR_FORMAT" | ||||
|                     ], | ||||
|                     "priority": "preferred" | ||||
|                 }, | ||||
|                 { | ||||
|                     "implementation": FollowIndicator, | ||||
|                     "depends": ["timerService"], | ||||
|                     "priority": "fallback" | ||||
|                 } | ||||
|             ], | ||||
|             "services": [ | ||||
| @@ -305,6 +299,10 @@ define([ | ||||
|                     } | ||||
|                 } | ||||
|             ], | ||||
|             "runs": [{ | ||||
|                 "implementation": FollowIndicator, | ||||
|                 "depends": ["openmct", "timerService"] | ||||
|             }], | ||||
|             "licenses": [ | ||||
|                 { | ||||
|                     "name": "moment-duration-format", | ||||
|   | ||||
| @@ -45,11 +45,11 @@ define( | ||||
|         } | ||||
|  | ||||
|         ClockIndicator.prototype.getGlyphClass = function () { | ||||
|             return "no-collapse float-right subdued"; | ||||
|             return "subdued"; | ||||
|         }; | ||||
|  | ||||
|         ClockIndicator.prototype.getCssClass = function () { | ||||
|             return "icon-clock"; | ||||
|             return "icon-clock no-collapse float-right"; | ||||
|         }; | ||||
|  | ||||
|         ClockIndicator.prototype.getText = function () { | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2009-2016, United States Government | ||||
|  * Open MCT, Copyright (c) 2009-2018, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
| @@ -20,38 +20,32 @@ | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['moment'], | ||||
|     function (moment) { | ||||
|         var NO_TIMER = "No timer being followed"; | ||||
| define([], function () { | ||||
|  | ||||
|         /** | ||||
|          * Indicator that displays the active timer, as well as its | ||||
|          * current state. | ||||
|          * @implements {Indicator} | ||||
|          * @memberof platform/features/clock | ||||
|          */ | ||||
|         function FollowIndicator(timerService) { | ||||
|             this.timerService = timerService; | ||||
|     /** | ||||
|      * Indicator that displays the active timer, as well as its | ||||
|      * current state. | ||||
|      * @memberof platform/features/clock | ||||
|      */ | ||||
|     return function installFollowIndicator(openmct, timerService) { | ||||
|         var indicator = openmct.indicators.simpleIndicator(); | ||||
|         var timer = timerService.getTimer(); | ||||
|         setIndicatorStatus(timer); | ||||
|  | ||||
|         function setIndicatorStatus(newTimer) { | ||||
|             if (newTimer !== undefined) { | ||||
|                 indicator.iconClass('icon-timer'); | ||||
|                 indicator.statusClass('s-status-ok'); | ||||
|                 indicator.text('Following timer ' + newTimer.name); | ||||
|             } else { | ||||
|                 indicator.iconClass('icon-timer'); | ||||
|                 indicator.statusClass(''); | ||||
|                 indicator.text('No timer being followed'); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         FollowIndicator.prototype.getGlyphClass = function () { | ||||
|             return ""; | ||||
|         }; | ||||
|         timerService.on('change', setIndicatorStatus); | ||||
|  | ||||
|         FollowIndicator.prototype.getCssClass = function () { | ||||
|             return (this.timerService.getTimer()) ? "icon-timer s-status-ok" : "icon-timer"; | ||||
|         }; | ||||
|  | ||||
|         FollowIndicator.prototype.getText = function () { | ||||
|             var timer = this.timerService.getTimer(); | ||||
|             return timer ? ('Following timer ' + timer.name) : NO_TIMER; | ||||
|         }; | ||||
|  | ||||
|         FollowIndicator.prototype.getDescription = function () { | ||||
|             return ""; | ||||
|         }; | ||||
|  | ||||
|         return FollowIndicator; | ||||
|     } | ||||
| ); | ||||
|         openmct.indicators.add(indicator); | ||||
|     }; | ||||
| }); | ||||
|   | ||||
| @@ -44,7 +44,7 @@ define(['EventEmitter'], function (EventEmitter) { | ||||
|      */ | ||||
|     TimerService.prototype.setTimer = function (timer) { | ||||
|         this.timer = timer; | ||||
|         this.emit('change'); | ||||
|         this.emit('change', timer); | ||||
|  | ||||
|         if (this.stopObserving) { | ||||
|             this.stopObserving(); | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2009-2016, United States Government | ||||
|  * Open MCT, Copyright (c) 2009-2018, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
| @@ -20,39 +20,77 @@ | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define(["../../src/indicators/FollowIndicator"], function (FollowIndicator) { | ||||
|     var TIMER_SERVICE_METHODS = | ||||
|         ['setTimer', 'getTimer', 'clearTimer', 'on', 'off']; | ||||
|  | ||||
| define([ | ||||
|     "../../src/indicators/FollowIndicator", | ||||
|     "../../src/services/TimerService", | ||||
|     "../../../../../src/MCT", | ||||
|     'zepto' | ||||
| ], function ( | ||||
|     FollowIndicator, | ||||
|     TimerService, | ||||
|     MCT, | ||||
|     $ | ||||
| ) { | ||||
|     describe("The timer-following indicator", function () { | ||||
|         var mockTimerService; | ||||
|         var indicator; | ||||
|         var timerService; | ||||
|         var openmct; | ||||
|  | ||||
|         beforeEach(function () { | ||||
|             mockTimerService = | ||||
|                 jasmine.createSpyObj('timerService', TIMER_SERVICE_METHODS); | ||||
|             indicator = new FollowIndicator(mockTimerService); | ||||
|             openmct = new MCT(); | ||||
|             timerService = new TimerService(openmct); | ||||
|             spyOn(openmct.indicators, "add"); | ||||
|         }); | ||||
|  | ||||
|         it("implements the Indicator interface", function () { | ||||
|             expect(indicator.getGlyphClass()).toEqual(jasmine.any(String)); | ||||
|             expect(indicator.getCssClass()).toEqual(jasmine.any(String)); | ||||
|             expect(indicator.getText()).toEqual(jasmine.any(String)); | ||||
|             expect(indicator.getDescription()).toEqual(jasmine.any(String)); | ||||
|         it("adds an indicator when installed", function () { | ||||
|             FollowIndicator(openmct, timerService); | ||||
|             expect(openmct.indicators.add).toHaveBeenCalled(); | ||||
|         }); | ||||
|  | ||||
|         it("indicates that no timer is being followed", function () { | ||||
|             FollowIndicator(openmct, timerService); | ||||
|             var simpleIndicator = openmct.indicators.add.mostRecentCall.args[0]; | ||||
|             var element = simpleIndicator.element; | ||||
|             var text = $('.indicator-text', element).text().trim(); | ||||
|             expect(text).toEqual('No timer being followed'); | ||||
|         }); | ||||
|  | ||||
|         describe("when a timer is set", function () { | ||||
|             var testObject; | ||||
|             var simpleIndicator; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 testObject = { name: "some timer!" }; | ||||
|                 mockTimerService.getTimer.andReturn(testObject); | ||||
|                 testObject = { | ||||
|                     identifier: { | ||||
|                         namespace: 'namespace', | ||||
|                         key: 'key' | ||||
|                     }, | ||||
|                     name: "some timer!" | ||||
|                 }; | ||||
|                 timerService.setTimer(testObject); | ||||
|                 FollowIndicator(openmct, timerService); | ||||
|                 simpleIndicator = openmct.indicators.add.mostRecentCall.args[0]; | ||||
|             }); | ||||
|  | ||||
|             it("displays the timer's name", function () { | ||||
|                 expect(indicator.getText().indexOf(testObject.name)) | ||||
|                     .not.toEqual(-1); | ||||
|                 var element = simpleIndicator.element; | ||||
|                 var text = $('.indicator-text', element).text().trim(); | ||||
|                 expect(text).toEqual('Following timer ' + testObject.name); | ||||
|             }); | ||||
|  | ||||
|             it("displays the timer's name when it changes", function () { | ||||
|                 var secondTimer = { | ||||
|                     identifier: { | ||||
|                         namespace: 'namespace', | ||||
|                         key: 'key2' | ||||
|                     }, | ||||
|                     name: "Some other timer" | ||||
|                 }; | ||||
|                 var element = simpleIndicator.element; | ||||
|                 timerService.setTimer(secondTimer); | ||||
|                 var text = $('.indicator-text', element).text().trim(); | ||||
|                 expect(text).toEqual('Following timer ' + secondTimer.name); | ||||
|             }); | ||||
|  | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
|   | ||||
							
								
								
									
										11
									
								
								src/MCT.js
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/MCT.js
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2017, United States Government | ||||
|  * Open MCT, Copyright (c) 2014-2018, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
| @@ -194,6 +194,15 @@ define([ | ||||
|          */ | ||||
|         this.telemetry = new api.TelemetryAPI(this); | ||||
|  | ||||
|         /** | ||||
|          * An interface for creating new indicators and changing them dynamically. | ||||
|          * | ||||
|          * @type {module:openmct.IndicatorAPI} | ||||
|          * @memberof module:openmct.MCT# | ||||
|          * @name indicators | ||||
|          */ | ||||
|         this.indicators = new api.IndicatorAPI(this); | ||||
|  | ||||
|         this.Dialog = api.Dialog; | ||||
|  | ||||
|     } | ||||
|   | ||||
| @@ -27,7 +27,8 @@ define([ | ||||
|     './types/TypeRegistry', | ||||
|     './ui/Dialog', | ||||
|     './ui/GestureAPI', | ||||
|     './telemetry/TelemetryAPI' | ||||
|     './telemetry/TelemetryAPI', | ||||
|     './indicators/IndicatorAPI' | ||||
| ], function ( | ||||
|     TimeAPI, | ||||
|     ObjectAPI, | ||||
| @@ -35,7 +36,8 @@ define([ | ||||
|     TypeRegistry, | ||||
|     Dialog, | ||||
|     GestureAPI, | ||||
|     TelemetryAPI | ||||
|     TelemetryAPI, | ||||
|     IndicatorAPI | ||||
| ) { | ||||
|     return { | ||||
|         TimeAPI: TimeAPI, | ||||
| @@ -44,6 +46,7 @@ define([ | ||||
|         Dialog: Dialog, | ||||
|         TypeRegistry: TypeRegistry, | ||||
|         GestureAPI: GestureAPI, | ||||
|         TelemetryAPI: TelemetryAPI | ||||
|         TelemetryAPI: TelemetryAPI, | ||||
|         IndicatorAPI: IndicatorAPI | ||||
|     }; | ||||
| }); | ||||
|   | ||||
							
								
								
									
										129
									
								
								src/api/indicators/IndicatorAPI.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								src/api/indicators/IndicatorAPI.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,129 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2018, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT 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 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. | ||||
|  *****************************************************************************/ | ||||
| define([ | ||||
|     './SimpleIndicator', | ||||
|     '../../../platform/framework/src/Constants', | ||||
|     'lodash' | ||||
| ], function ( | ||||
|     SimpleIndicator, | ||||
|     Constants, | ||||
|     _ | ||||
| ) { | ||||
|     /* jshint validthis: true */ | ||||
|     var LEGACY_INDICATOR_TEMPLATE = | ||||
|         '<mct-include ' + | ||||
|         '   ng-model="indicator" ' + | ||||
|         '   key="template" ' + | ||||
|         ' </mct-include>'; | ||||
|  | ||||
|     function IndicatorAPI(openmct) { | ||||
|         this.openmct = openmct; | ||||
|         this.indicatorElements = []; | ||||
|         this.promiseForAllElements = | ||||
|             fetchLegacyIndicators.call(this) | ||||
|             .then(addLegacyIndicators.bind(this)) | ||||
|             .then(resolveWithAllIndicatorElements.bind(this)); | ||||
|     } | ||||
|  | ||||
|     IndicatorAPI.prototype.simpleIndicator = function () { | ||||
|         return new SimpleIndicator(this.openmct); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Accepts an indicator object, which is a simple object | ||||
|      * with a single attribute, 'element' which has an HTMLElement | ||||
|      * as its value. | ||||
|      * | ||||
|      * We provide .simpleIndicator() as a convenience function | ||||
|      * which will create a default Open MCT indicator that can | ||||
|      * be passed to .add(indicator). This indicator also exposes | ||||
|      * functions for changing its appearance to support customization | ||||
|      * and dynamic behavior. | ||||
|      * | ||||
|      * Eg. | ||||
|      * var myIndicator = openmct.indicators.simpleIndicator(); | ||||
|      * openmct.indicators.add(myIndicator); | ||||
|      * | ||||
|      * myIndicator.text("Hello World!"); | ||||
|      * myIndicator.iconClass("icon-info"); | ||||
|      * | ||||
|      */ | ||||
|     IndicatorAPI.prototype.add = function (indicator) { | ||||
|         // So that we can consistently position indicator elements, | ||||
|         // guarantee that they are wrapped in an element we control | ||||
|         var wrapperNode = document.createElement('div'); | ||||
|         wrapperNode.className = 'l-indicator s-indicator'; | ||||
|         wrapperNode.appendChild(indicator.element); | ||||
|         this.indicatorElements.push(wrapperNode); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      */ | ||||
|     IndicatorAPI.prototype.allIndicatorElements = function () { | ||||
|         return this.promiseForAllElements; | ||||
|     }; | ||||
|  | ||||
|     function fetchLegacyIndicators() { | ||||
|         return new Promise(function (resolve) { | ||||
|             this.openmct.legacyExtension('runs', { | ||||
|                 depends: ['indicators[]'], | ||||
|                 implementation: resolve | ||||
|             }); | ||||
|         }.bind(this)); | ||||
|     } | ||||
|  | ||||
|     function addLegacyIndicators(legacyIndicators) { | ||||
|         legacyIndicators.forEach(function (legacyIndicatorDef) { | ||||
|             var legacyIndicator = initializeIfNeeded(legacyIndicatorDef); | ||||
|             var legacyIndicatorElement = buildLegacyIndicator(this.openmct, legacyIndicator, legacyIndicatorDef.template); | ||||
|             this.indicatorElements.push(legacyIndicatorElement); | ||||
|         }.bind(this)); | ||||
|     } | ||||
|  | ||||
|     function initializeIfNeeded(LegacyIndicatorDef) { | ||||
|         var legacyIndicator; | ||||
|         if (typeof LegacyIndicatorDef === 'function') { | ||||
|             legacyIndicator = new LegacyIndicatorDef(); | ||||
|         } else { | ||||
|             legacyIndicator = LegacyIndicatorDef; | ||||
|         } | ||||
|         return legacyIndicator; | ||||
|     } | ||||
|  | ||||
|     function buildLegacyIndicator(openmct, legacyIndicator, template) { | ||||
|         var $compile = openmct.$injector.get('$compile'); | ||||
|         var $rootScope = openmct.$injector.get('$rootScope'); | ||||
|         var scope = $rootScope.$new(true); | ||||
|         scope.indicator = legacyIndicator; | ||||
|         scope.template = template || 'indicator'; | ||||
|  | ||||
|         return $compile(LEGACY_INDICATOR_TEMPLATE)(scope)[0]; | ||||
|     } | ||||
|  | ||||
|     function resolveWithAllIndicatorElements() { | ||||
|         return this.indicatorElements; | ||||
|     } | ||||
|  | ||||
|     return IndicatorAPI; | ||||
|  | ||||
| }); | ||||
							
								
								
									
										214
									
								
								src/api/indicators/IndicatorAPISpec.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										214
									
								
								src/api/indicators/IndicatorAPISpec.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,214 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2018, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT 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 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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         "../../MCT", | ||||
|         "../../../platform/commonUI/general/src/directives/MCTIndicators", | ||||
|         "zepto" | ||||
|     ], | ||||
|     function ( | ||||
|         MCT, | ||||
|         MCTIndicators, | ||||
|         $ | ||||
|     ) { | ||||
|         describe("The Indicator API", function () { | ||||
|             var openmct; | ||||
|             var directive; | ||||
|             var holderElement; | ||||
|             var legacyExtensionFunction = MCT.prototype.legacyExtension; | ||||
|             var legacyIndicatorsResolved = false; | ||||
|             var legacyIndicatorsCallback; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockLegacyExtensionFunction(); | ||||
|  | ||||
|                 openmct = new MCT(); | ||||
|                 directive = new MCTIndicators(openmct); | ||||
|                 holderElement = document.createElement('div'); | ||||
|  | ||||
|                 mockAngularComponents(); | ||||
|             }); | ||||
|  | ||||
|             afterEach(function () { | ||||
|                 MCT.prototype.legacyExtension = legacyExtensionFunction; | ||||
|             }); | ||||
|  | ||||
|             it("Displays any legacy indicators ", function () { | ||||
|                 var legacyIndicators = [{},{},{},{}]; | ||||
|  | ||||
|                 mockLegacyIndicatorsWith(legacyIndicators); | ||||
|  | ||||
|                 renderIndicators(); | ||||
|  | ||||
|                 waitsFor(legacyIndicatorsToResolve, 1000); | ||||
|                 runs(function () { | ||||
|                     expectIndicatorsShownToBe(legacyIndicators.length); | ||||
|                 }); | ||||
|  | ||||
|             }); | ||||
|  | ||||
|             it("If legacy indicator is defined as a constructor function, executes function ", function () { | ||||
|                 var mockConstructorFunction = jasmine.createSpy('mockIndicatorConstructor'); | ||||
|                 var legacyIndicators = [{}, mockConstructorFunction]; | ||||
|  | ||||
|                 mockConstructorFunction.andReturn({}); | ||||
|                 mockLegacyIndicatorsWith(legacyIndicators); | ||||
|                 renderIndicators(); | ||||
|  | ||||
|                 waitsFor(legacyIndicatorsToResolve, 1000); | ||||
|                 runs(function () { | ||||
|                     expectIndicatorsShownToBe(legacyIndicators.length); | ||||
|                     expect(mockConstructorFunction).toHaveBeenCalled(); | ||||
|                 }); | ||||
|  | ||||
|             }); | ||||
|  | ||||
|             describe("The simple indicator", function () { | ||||
|                 var simpleIndicator; | ||||
|  | ||||
|                 beforeEach(function () { | ||||
|                     simpleIndicator = openmct.indicators.simpleIndicator(); | ||||
|                     mockLegacyIndicatorsWith([]); | ||||
|                     openmct.indicators.add(simpleIndicator); | ||||
|                     renderIndicators(); | ||||
|                 }); | ||||
|                 it("applies the set icon class", function () { | ||||
|                     simpleIndicator.iconClass('testIconClass'); | ||||
|  | ||||
|                     waitsFor(legacyIndicatorsToResolve); | ||||
|                     runs(function () { | ||||
|                         expect(getIconElement().hasClass('testIconClass')).toBe(true); | ||||
|                     }); | ||||
|                 }); | ||||
|                 it("applies the set status class", function () { | ||||
|                     simpleIndicator.statusClass('testStatusClass'); | ||||
|  | ||||
|                     waitsFor(legacyIndicatorsToResolve); | ||||
|                     runs(function () { | ||||
|                         expect(getIconElement().hasClass('testStatusClass')).toBe(true); | ||||
|                     }); | ||||
|                 }); | ||||
|                 it("displays the set text", function () { | ||||
|                     simpleIndicator.text('some test text'); | ||||
|  | ||||
|                     waitsFor(legacyIndicatorsToResolve); | ||||
|                     runs(function () { | ||||
|                         expect(getTextElement().text().trim()).toEqual('some test text'); | ||||
|                     }); | ||||
|                 }); | ||||
|                 it("sets the indicator's title", function () { | ||||
|                     simpleIndicator.description('a test description'); | ||||
|  | ||||
|                     waitsFor(legacyIndicatorsToResolve); | ||||
|                     runs(function () { | ||||
|                         expect(getIndicatorElement().attr('title')).toEqual('a test description'); | ||||
|                     }); | ||||
|                 }); | ||||
|  | ||||
|                 it("Hides indicator text if no text is set", function () { | ||||
|                     simpleIndicator.text(''); | ||||
|  | ||||
|                     waitsFor(legacyIndicatorsToResolve); | ||||
|                     runs(function () { | ||||
|                         expect(getIndicatorElement().hasClass('hidden')).toBe(true); | ||||
|                     }); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("Supports registration of a completely custom indicator", function () { | ||||
|                 var customIndicator = $('<div class="customIndicator">A custom indicator</div>')[0]; | ||||
|                 mockLegacyIndicatorsWith([]); | ||||
|                 openmct.indicators.add({element: customIndicator}); | ||||
|                 renderIndicators(); | ||||
|  | ||||
|                 waitsFor(legacyIndicatorsToResolve); | ||||
|                 runs(function () { | ||||
|                     expect($('.customIndicator', holderElement).text().trim()).toEqual('A custom indicator'); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             function mockLegacyExtensionFunction() { | ||||
|                 spyOn(MCT.prototype, "legacyExtension"); | ||||
|                 MCT.prototype.legacyExtension.andCallFake(function (extensionName, definition) { | ||||
|                     if (extensionName === 'runs') { | ||||
|                         legacyIndicatorsCallback = definition.implementation; | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             function mockAngularComponents() { | ||||
|                 var mockInjector = jasmine.createSpyObj('$injector', ['get']); | ||||
|                 var mockCompile = jasmine.createSpy('$compile'); | ||||
|                 var mockRootScope = jasmine.createSpyObj('rootScope', ['$new']); | ||||
|                 var mockScope = {}; | ||||
|  | ||||
|                 mockRootScope.$new.andReturn(mockScope); | ||||
|                 mockInjector.get.andCallFake(function (service) { | ||||
|                     return { | ||||
|                         '$compile': mockCompile, | ||||
|                         '$rootScope': mockRootScope | ||||
|                     }[service]; | ||||
|                 }); | ||||
|                 openmct.$injector = mockInjector; | ||||
|                 mockCompile.andCallFake(function () { | ||||
|                     return function () { | ||||
|                         return $('<div></div>'); | ||||
|                     }; | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             function renderIndicators() { | ||||
|                 directive.link({}, holderElement); | ||||
|             } | ||||
|  | ||||
|             function mockLegacyIndicatorsWith(legacyIndicators) { | ||||
|                 legacyIndicatorsResolved = false; | ||||
|  | ||||
|                 openmct.indicators.allIndicatorElements().then(function () { | ||||
|                     legacyIndicatorsResolved = true; | ||||
|                 }); | ||||
|  | ||||
|                 legacyIndicatorsCallback(legacyIndicators); | ||||
|             } | ||||
|  | ||||
|             function legacyIndicatorsToResolve() { | ||||
|                 return legacyIndicatorsResolved; | ||||
|             } | ||||
|  | ||||
|             function expectIndicatorsShownToBe(number) { | ||||
|                 expect(holderElement.children.length).toBe(number); | ||||
|             } | ||||
|  | ||||
|             function getIconElement() { | ||||
|                 return $('.indicator-icon', holderElement); | ||||
|             } | ||||
|  | ||||
|             function getIndicatorElement() { | ||||
|                 return $('.status', holderElement); | ||||
|             } | ||||
|  | ||||
|             function getTextElement() { | ||||
|                 return $('.indicator-text', holderElement); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
							
								
								
									
										100
									
								
								src/api/indicators/SimpleIndicator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								src/api/indicators/SimpleIndicator.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,100 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2018, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT 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 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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define(['text!./res/indicator-template.html'], | ||||
|     function (indicatorTemplate) { | ||||
|         var DEFAULT_ICON_CLASS = 'icon-info'; | ||||
|  | ||||
|         function SimpleIndicator(openmct) { | ||||
|             this.openmct = openmct; | ||||
|             this.textValue = 'New Indicator'; | ||||
|             this.descriptionValue = 'A simple indicator'; | ||||
|             this.iconClassValue = DEFAULT_ICON_CLASS; | ||||
|             this.statusClassValue = ''; | ||||
|  | ||||
|             // We need to remove this element | ||||
|             this.element = document.createElement('div'); | ||||
|             this.element.className = 'status-block-holder'; | ||||
|  | ||||
|             SimpleIndicator.defaultDisplayFunction.call(this); | ||||
|         } | ||||
|  | ||||
|         SimpleIndicator.prototype.text = function (text) { | ||||
|             if (text !== undefined && text !== this.textValue) { | ||||
|                 this.textValue = text; | ||||
|                 SimpleIndicator.defaultDisplayFunction.call(this); | ||||
|             } | ||||
|  | ||||
|             return this.textValue; | ||||
|         }; | ||||
|  | ||||
|         SimpleIndicator.prototype.description = function (description) { | ||||
|             if (description !== undefined && description !== this.descriptionValue) { | ||||
|                 this.descriptionValue = description; | ||||
|                 SimpleIndicator.defaultDisplayFunction.call(this); | ||||
|             } | ||||
|  | ||||
|             return this.descriptionValue; | ||||
|         }; | ||||
|  | ||||
|         SimpleIndicator.prototype.iconClass = function (iconClass) { | ||||
|             if (iconClass !== undefined && iconClass !== this.iconClassValue) { | ||||
|                 this.iconClassValue = iconClass; | ||||
|                 SimpleIndicator.defaultDisplayFunction.call(this); | ||||
|             } | ||||
|  | ||||
|             return this.iconClassValue; | ||||
|         }; | ||||
|  | ||||
|         SimpleIndicator.prototype.statusClass = function (statusClass) { | ||||
|             if (statusClass !== undefined && statusClass !== this.statusClassValue) { | ||||
|                 this.statusClassValue = statusClass; | ||||
|                 SimpleIndicator.defaultDisplayFunction.call(this); | ||||
|             } | ||||
|  | ||||
|             return this.statusClassValue; | ||||
|         }; | ||||
|  | ||||
|         function hideOrShowText(text) { | ||||
|             if (text && text.length > 0) { | ||||
|                 return ''; | ||||
|             } else { | ||||
|                 return 'hidden'; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         SimpleIndicator.defaultDisplayFunction = function () { | ||||
|             var html = indicatorTemplate | ||||
|                 .replace('{{indicator.text}}', this.text()) | ||||
|                 .replace('{{indicator.iconClass}}', this.iconClass()) | ||||
|                 .replace('{{indicator.statusClass}}', this.statusClass()) | ||||
|                 .replace('{{indicator.description}}', this.description()) | ||||
|                 .replace('{{hideOrShowText}}', hideOrShowText(this.text())); | ||||
|  | ||||
|             this.element.innerHTML = html; | ||||
|  | ||||
|             return this.element; | ||||
|         }; | ||||
|  | ||||
|         return SimpleIndicator; | ||||
|     } | ||||
| ); | ||||
							
								
								
									
										24
									
								
								src/api/indicators/res/indicator-template.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/api/indicators/res/indicator-template.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| <!-- | ||||
|  Open MCT, Copyright (c) 2014-2018, United States Government | ||||
|  as represented by the Administrator of the National Aeronautics and Space | ||||
|  Administration. All rights reserved. | ||||
|  | ||||
|  Open MCT 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 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. | ||||
| --> | ||||
| <span class="{{hideOrShowText}} {{indicator.iconClass}} {{indicator.statusClass}}" title="{{indicator.description}}"> | ||||
|     <span class="label indicator-text">{{indicator.text}}</span> | ||||
| </span> | ||||
| @@ -1,5 +1,5 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2016, United States Government | ||||
|  * Open MCT, Copyright (c) 2014-2018, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
| @@ -21,8 +21,8 @@ | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     [], | ||||
|     function () { | ||||
|     ['zepto'], | ||||
|     function ($) { | ||||
|  | ||||
|         // Set of connection states; changing among these states will be | ||||
|         // reflected in the indicator's appearance. | ||||
| @@ -30,68 +30,86 @@ define( | ||||
|         // DISCONNECTED: HTTP failed; maybe misconfigured, disconnected. | ||||
|         // PENDING: Still trying to connect, and haven't failed yet. | ||||
|         var CONNECTED = { | ||||
|                 glyphClass: "ok" | ||||
|                 statusClass: "s-status-ok" | ||||
|             }, | ||||
|             PENDING = { | ||||
|                 glyphClass: 'caution' | ||||
|                 statusClass: "s-status-warning-lo" | ||||
|             }, | ||||
|             DISCONNECTED = { | ||||
|                 glyphClass: "err" | ||||
|                 statusClass: "s-status-warning-hi" | ||||
|             }; | ||||
|         function URLIndicator($http, $interval) { | ||||
|             var self = this; | ||||
|             this.cssClass = this.options.cssClass ? this.options.cssClass : "icon-database"; | ||||
|             this.URLpath = this.options.url; | ||||
|             this.label = this.options.label ? this.options.label : this.options.url; | ||||
|             this.interval = this.options.interval || 10000; | ||||
|             this.state = PENDING; | ||||
|         function URLIndicator(options, openmct, simpleIndicator) { | ||||
|             this.bindMethods(); | ||||
|             this.count = 0; | ||||
|  | ||||
|             function handleError(e) { | ||||
|                 self.state = DISCONNECTED; | ||||
|             } | ||||
|             function handleResponse() { | ||||
|                 self.state = CONNECTED; | ||||
|             } | ||||
|             function updateIndicator() { | ||||
|                 $http.get(self.URLpath).then(handleResponse, handleError); | ||||
|             } | ||||
|             updateIndicator(); | ||||
|             $interval(updateIndicator, self.interval, 0, false); | ||||
|             this.indicator = simpleIndicator; | ||||
|             this.setDefaultsFromOptions(options); | ||||
|             this.setIndicatorToState(PENDING); | ||||
|  | ||||
|             this.fetchUrl(); | ||||
|             setInterval(this.fetchUrl, this.interval); | ||||
|         } | ||||
|  | ||||
|         URLIndicator.prototype.getCssClass = function () { | ||||
|             return this.cssClass; | ||||
|         }; | ||||
|         URLIndicator.prototype.getGlyphClass = function () { | ||||
|             return this.state.glyphClass; | ||||
|         }; | ||||
|         URLIndicator.prototype.getText = function () { | ||||
|             switch (this.state) { | ||||
|         URLIndicator.prototype.setIndicatorToState = function (state) { | ||||
|             switch (state) { | ||||
|                 case CONNECTED: { | ||||
|                     return this.label + " is connected"; | ||||
|                     this.indicator.text(this.label + " is connected"); | ||||
|                     this.indicator.description(this.label + " is online, checking status every " + this.interval + " milliseconds."); | ||||
|                     break; | ||||
|                 } | ||||
|                 case PENDING: { | ||||
|                     return "Checking status of " + this.label + " please stand by..."; | ||||
|                     this.indicator.text("Checking status of " + this.label + " please stand by..."); | ||||
|                     this.indicator.description("Checking status of " + this.label + " please stand by..."); | ||||
|                     break; | ||||
|                 } | ||||
|                 case DISCONNECTED: { | ||||
|                     return this.label + " is offline"; | ||||
|                     this.indicator.text(this.label + " is offline"); | ||||
|                     this.indicator.description(this.label + " is offline, checking status every " + this.interval + " milliseconds"); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             this.indicator.statusClass(state.statusClass); | ||||
|         }; | ||||
|         URLIndicator.prototype.getDescription = function () { | ||||
|             switch (this.state) { | ||||
|                 case CONNECTED: { | ||||
|                     return this.label + " is online, checking status every " + | ||||
|                     this.interval + " milliseconds."; | ||||
|                 } | ||||
|                 case PENDING: { | ||||
|                     return "Checking status of " + this.label + " please stand by..."; | ||||
|                 } | ||||
|                 case DISCONNECTED: { | ||||
|                     return this.label + " is offline, checking status every " + | ||||
|                     this.interval + " milliseconds"; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|         URLIndicator.prototype.fetchUrl = function () { | ||||
|             this.get(this.URLpath) | ||||
|                 .then(this.handleSuccess) | ||||
|                 .catch(this.handleError); | ||||
|         }; | ||||
|  | ||||
|         URLIndicator.prototype.get = function (url) { | ||||
|             return new Promise(function (resolve, reject) { | ||||
|                 $.ajax({ | ||||
|                     type: 'GET', | ||||
|                     url: url, | ||||
|                     success: resolve, | ||||
|                     error: reject | ||||
|                 }); | ||||
|             }); | ||||
|         }; | ||||
|  | ||||
|         URLIndicator.prototype.handleError = function (e) { | ||||
|             this.setIndicatorToState(DISCONNECTED); | ||||
|         }; | ||||
|  | ||||
|         URLIndicator.prototype.handleSuccess = function () { | ||||
|             this.setIndicatorToState(CONNECTED); | ||||
|         }; | ||||
|  | ||||
|         URLIndicator.prototype.setDefaultsFromOptions = function (options) { | ||||
|             this.URLpath = options.url; | ||||
|             this.label = options.label || options.url; | ||||
|             this.interval = options.interval || 10000; | ||||
|             this.indicator.iconClass(options.iconClass || 'icon-connectivity'); | ||||
|         }; | ||||
|  | ||||
|         URLIndicator.prototype.bindMethods = function () { | ||||
|             this.fetchUrl = this.fetchUrl.bind(this); | ||||
|             this.handleSuccess = this.handleSuccess.bind(this); | ||||
|             this.handleError = this.handleError.bind(this); | ||||
|             this.setIndicatorToState = this.setIndicatorToState.bind(this); | ||||
|         }; | ||||
|  | ||||
|         return URLIndicator; | ||||
|     }); | ||||
|   | ||||
| @@ -1,20 +1,35 @@ | ||||
| define( | ||||
|   [ | ||||
|     './URLIndicator' | ||||
|   ], | ||||
|   function URLIndicatorPlugin(URLIndicator) { | ||||
|     return function (opts) { | ||||
|         // Wrap the plugin in a function so we can apply the arguments. | ||||
|         function URLIndicatorWrapper() { | ||||
|             this.options = opts; | ||||
|             URLIndicator.apply(this, arguments); | ||||
|         } | ||||
|         URLIndicatorWrapper.prototype = Object.create(URLIndicator.prototype); | ||||
|         return function install(openmct) { | ||||
|             openmct.legacyExtension('indicators', { | ||||
|                   "implementation": URLIndicatorWrapper, | ||||
|                   "depends": ["$http", "$interval"] | ||||
|               }); | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2018, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT 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 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. | ||||
|  *****************************************************************************/ | ||||
| define(['./URLIndicator'], | ||||
|     function URLIndicatorPlugin(URLIndicator) { | ||||
|         return function (opts) { | ||||
|             return function install(openmct) { | ||||
|                 var simpleIndicator = openmct.indicators.simpleIndicator(); | ||||
|                 var urlIndicator = new URLIndicator(opts, openmct, simpleIndicator); | ||||
|  | ||||
|                 openmct.indicators.add(simpleIndicator); | ||||
|  | ||||
|                 return urlIndicator; | ||||
|             }; | ||||
|         }; | ||||
|     }; | ||||
| }); | ||||
|     } | ||||
| ); | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2016, United States Government | ||||
|  * Open MCT, Copyright (c) 2014-2018, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
| @@ -21,138 +21,167 @@ | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ["./URLIndicator"], | ||||
|     function (URLIndicator) { | ||||
|  | ||||
|     [ | ||||
|         "./URLIndicator", | ||||
|         "./URLIndicatorPlugin", | ||||
|         "../../MCT", | ||||
|         "zepto" | ||||
|     ], | ||||
|     function ( | ||||
|         URLIndicator, | ||||
|         URLIndicatorPlugin, | ||||
|         MCT, | ||||
|         $ | ||||
|     ) { | ||||
|         var defaultPrototypeFunction = URLIndicator.prototype.get; | ||||
|         describe("The URLIndicator", function () { | ||||
|             var mockHttp, | ||||
|                 mockInterval, | ||||
|                 mockPromise, | ||||
|                 opts, | ||||
|                 Indicator, | ||||
|                 indicatorWrapper; | ||||
|             var openmct; | ||||
|             var indicatorElement; | ||||
|             var urlIndicator; | ||||
|             var mockHttpRequestFunction; | ||||
|             var returned; | ||||
|             var options; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockHttp = jasmine.createSpyObj("$http", ["get"]); | ||||
|                 mockInterval = jasmine.createSpy("$interval"); | ||||
|                 mockPromise = jasmine.createSpyObj("promise", ["then"]); | ||||
|                 opts = { | ||||
|                     url: "http://localhost:8080", | ||||
|                     interval: 1337 //some number | ||||
|                 }; | ||||
|                 mockHttp.get.andReturn(mockPromise); | ||||
|                 Indicator = function () { | ||||
|                     this.options = opts; | ||||
|                     URLIndicator.call(this, mockHttp, mockInterval); | ||||
|                 }; | ||||
|                 Indicator.prototype = Object.create(URLIndicator.prototype); | ||||
|                 indicatorWrapper = new Indicator(); | ||||
|             }); | ||||
|             it("polls for changes", function () { | ||||
|                 expect(mockInterval).toHaveBeenCalledWith( | ||||
|                     jasmine.any(Function), | ||||
|                     opts.interval, | ||||
|                     0, | ||||
|                     false | ||||
|                 ); | ||||
|                 returned = false; | ||||
|                 jasmine.Clock.useMock(); | ||||
|                 openmct = new MCT(); | ||||
|                 spyOn(openmct.indicators, 'add'); | ||||
|  | ||||
|                 mockHttpRequest(); | ||||
|             }); | ||||
|  | ||||
|             it("has a database cssClass as default", function () { | ||||
|                 expect(indicatorWrapper.getCssClass()).toEqual("icon-database"); | ||||
|             afterEach(function () { | ||||
|                 URLIndicator.prototype.get = defaultPrototypeFunction; | ||||
|                 jasmine.Clock.reset(); | ||||
|             }); | ||||
|  | ||||
|             it("consults the url with the path supplied", function () { | ||||
|                 expect(mockHttp.get).toHaveBeenCalledWith(opts.url); | ||||
|             describe("on initialization", function () { | ||||
|                 describe("with default options", function () { | ||||
|                     beforeEach(function () { | ||||
|                         options = { | ||||
|                             url: "someURL" | ||||
|                         }; | ||||
|                         urlIndicator = URLIndicatorPlugin(options)(openmct); | ||||
|                         indicatorElement = openmct.indicators.add.mostRecentCall.args[0].element; | ||||
|                     }); | ||||
|  | ||||
|                     it("has a default icon class if none supplied", function () { | ||||
|                         var iconElement = getIconElement(); | ||||
|                         expect(iconElement.hasClass('icon-connectivity')).toBe(true); | ||||
|                     }); | ||||
|  | ||||
|                     it("defaults to the URL if no label supplied", function () { | ||||
|                         var textElement = getTextElement(); | ||||
|                         expect(textElement.text().indexOf(options.url) >= 0).toBe(true); | ||||
|                     }); | ||||
|                 }); | ||||
|  | ||||
|                 describe("with custom options", function () { | ||||
|                     beforeEach(function () { | ||||
|                         options = { | ||||
|                             url: "customURL", | ||||
|                             interval: 1814, | ||||
|                             iconClass: "iconClass-checked", | ||||
|                             label: "custom label" | ||||
|                         }; | ||||
|                         urlIndicator = URLIndicatorPlugin(options)(openmct); | ||||
|                         indicatorElement = openmct.indicators.add.mostRecentCall.args[0].element; | ||||
|                     }); | ||||
|  | ||||
|                     it("uses the custom iconClass", function () { | ||||
|                         var iconElement = getIconElement(); | ||||
|                         expect(iconElement.hasClass('iconClass-checked')).toBe(true); | ||||
|                     }); | ||||
|                     it("uses custom interval", function () { | ||||
|                         expect(mockHttpRequestFunction.calls.length).toEqual(1); | ||||
|                         jasmine.Clock.tick(1); | ||||
|                         expect(mockHttpRequestFunction.calls.length).toEqual(1); | ||||
|                         mockInterval(options.interval + 1); | ||||
|                         expect(mockHttpRequestFunction.calls.length).toEqual(2); | ||||
|                     }); | ||||
|                     it("uses custom label if supplied in initialization", function () { | ||||
|                         var textElement = getTextElement(); | ||||
|                         expect(textElement.text().indexOf(options.label) >= 0).toBe(true); | ||||
|                     }); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("changes when the database connection is nominal", function () { | ||||
|                 var initialText = indicatorWrapper.getText(), | ||||
|                     initialDescrption = indicatorWrapper.getDescription(), | ||||
|                     initialGlyphClass = indicatorWrapper.getGlyphClass(); | ||||
|             describe("when running", function () { | ||||
|                 beforeEach(function () { | ||||
|                     options = { | ||||
|                         url: "someURL", | ||||
|                         interval: 100 | ||||
|                     }; | ||||
|                     urlIndicator = URLIndicatorPlugin(options)(openmct); | ||||
|                     indicatorElement = openmct.indicators.add.mostRecentCall.args[0].element; | ||||
|                 }); | ||||
|  | ||||
|                 // Nominal just means getting back an object, without | ||||
|                 // an error field. | ||||
|                 mockPromise.then.mostRecentCall.args[0]({ data: {} }); | ||||
|                 it("requests the provided URL", function () { | ||||
|                     mockInterval(options.interval + 1); | ||||
|                     expect(mockHttpRequestFunction).toHaveBeenCalledWith(options.url); | ||||
|                 }); | ||||
|  | ||||
|                 // Verify that these values changed; | ||||
|                 // don't test for specific text. | ||||
|                 expect(indicatorWrapper.getText()).not.toEqual(initialText); | ||||
|                 expect(indicatorWrapper.getGlyphClass()).not.toEqual(initialGlyphClass); | ||||
|                 expect(indicatorWrapper.getDescription()).not.toEqual(initialDescrption); | ||||
|                 it("indicates success if connection is nominal", function () { | ||||
|                     mockSuccess(); | ||||
|                     mockInterval(options.interval + 1); | ||||
|  | ||||
|                 // Do check for specific class | ||||
|                 expect(indicatorWrapper.getGlyphClass()).toEqual("ok"); | ||||
|                     waitsFor(httpRequestReturned); | ||||
|                     runs(function () { | ||||
|                         var iconElement = getIconElement(); | ||||
|                         expect(iconElement.hasClass('s-status-ok')).toBe(true); | ||||
|                     }); | ||||
|                 }); | ||||
|  | ||||
|                 it("indicates an error when the server cannot be reached", function () { | ||||
|                     mockError(); | ||||
|                     mockInterval(options.interval + 1); | ||||
|  | ||||
|                     waitsFor(httpRequestReturned); | ||||
|                     runs(function () { | ||||
|                         var iconElement = getIconElement(); | ||||
|                         expect(iconElement.hasClass('s-status-warning-hi')).toBe(true); | ||||
|                     }); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("changes when the server cannot be reached", function () { | ||||
|                 var initialText = indicatorWrapper.getText(), | ||||
|                     initialDescrption = indicatorWrapper.getDescription(), | ||||
|                     initialGlyphClass = indicatorWrapper.getGlyphClass(); | ||||
|             function mockHttpRequest() { | ||||
|                 mockHttpRequestFunction = jasmine.createSpy('get'); | ||||
|                 URLIndicator.prototype.get = mockHttpRequestFunction; | ||||
|                 mockSuccess(); | ||||
|             } | ||||
|  | ||||
|                 // Nominal just means getting back an object, without | ||||
|                 // an error field. | ||||
|                 mockPromise.then.mostRecentCall.args[1]({ data: {} }); | ||||
|             function mockSuccess() { | ||||
|                 mockHttpRequestFunction | ||||
|                     .andReturn(Promise.resolve().then(function () { | ||||
|                         returned = true; | ||||
|                     })); | ||||
|             } | ||||
|  | ||||
|                 // Verify that these values changed; | ||||
|                 // don't test for specific text. | ||||
|                 expect(indicatorWrapper.getText()).not.toEqual(initialText); | ||||
|                 expect(indicatorWrapper.getGlyphClass()).not.toEqual(initialGlyphClass); | ||||
|                 expect(indicatorWrapper.getDescription()).not.toEqual(initialDescrption); | ||||
|             function mockError() { | ||||
|                 mockHttpRequestFunction | ||||
|                     .andReturn(Promise.reject().then(function () { | ||||
|                         returned = true; | ||||
|                         //Throw error to ensure chained catch is invoked | ||||
|                         throw undefined; | ||||
|                     })); | ||||
|             } | ||||
|  | ||||
|                 // Do check for specific class | ||||
|                 expect(indicatorWrapper.getGlyphClass()).toEqual("err"); | ||||
|             }); | ||||
|             it("has a customized cssClass if supplied in initialization", function () { | ||||
|                 opts = { | ||||
|                     url: "http://localhost:8080", | ||||
|                     cssClass: "cssClass-checked", | ||||
|                     interval: 10000 | ||||
|                 }; | ||||
|                 indicatorWrapper = new Indicator(); | ||||
|                 expect(indicatorWrapper.getCssClass()).toEqual("cssClass-checked"); | ||||
|             }); | ||||
|             it("has a customized interval if supplied in initialization", function () { | ||||
|                 opts = { | ||||
|                     url: "http://localhost:8080", | ||||
|                     interval: 1814 | ||||
|                 }; | ||||
|                 indicatorWrapper = new Indicator(); | ||||
|                 expect(mockInterval).toHaveBeenCalledWith( | ||||
|                     jasmine.any(Function), | ||||
|                     1814, | ||||
|                     0, | ||||
|                     false | ||||
|                 ); | ||||
|             }); | ||||
|             it("has a custom label if supplied in initialization", function () { | ||||
|                 opts = { | ||||
|                     url: "http://localhost:8080", | ||||
|                     label: "Localhost" | ||||
|                 }; | ||||
|                 indicatorWrapper = new Indicator(); | ||||
|                 expect(indicatorWrapper.getText()).toEqual("Checking status of Localhost please stand by..."); | ||||
|             }); | ||||
|             it("has a default label if not supplied in initialization", function () { | ||||
|                 opts = { | ||||
|                     url: "http://localhost:8080" | ||||
|                 }; | ||||
|                 indicatorWrapper = new Indicator(); | ||||
|                 expect(indicatorWrapper.getText()).toEqual( | ||||
|                   "Checking status of http://localhost:8080 please stand by..." | ||||
|                 ); | ||||
|             }); | ||||
|             it("has a default interval if not supplied in initialization", function () { | ||||
|                 opts = { | ||||
|                     url: "http://localhost:8080" | ||||
|                 }; | ||||
|                 indicatorWrapper = new Indicator(); | ||||
|                 expect(mockInterval).toHaveBeenCalledWith( | ||||
|                     jasmine.any(Function), | ||||
|                     10000, | ||||
|                     0, | ||||
|                     false | ||||
|                 ); | ||||
|             }); | ||||
|             function httpRequestReturned() { | ||||
|                 return returned; | ||||
|             } | ||||
|  | ||||
|             function mockInterval(interval) { | ||||
|                 jasmine.Clock.tick(interval); | ||||
|             } | ||||
|  | ||||
|             function getIconElement() { | ||||
|                 return $('.indicator-icon', indicatorElement); | ||||
|             } | ||||
|  | ||||
|             function getTextElement() { | ||||
|                 return $('.indicator-text', indicatorElement); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
|   | ||||
| @@ -128,7 +128,7 @@ define([ | ||||
|     plugins.ExampleImagery = ExampleImagery; | ||||
|     plugins.SummaryWidget = SummaryWidget; | ||||
|     plugins.TelemetryMean = TelemetryMean; | ||||
|     plugins.URLIndicatorPlugin = URLIndicatorPlugin; | ||||
|     plugins.URLIndicator = URLIndicatorPlugin; | ||||
|  | ||||
|     return plugins; | ||||
| }); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user