mirror of
https://github.com/nasa/openmct.git
synced 2024-12-20 05:37:53 +00:00
Indicators api (#1837)
* [API] Added Indicators API * [Indicators] Converted Follow Indicator to new Indicators API * [Indicators] Converted URL Indicator to new Indicators API * [Indicators] Changes to some legacy indicators for compatibility with new Indicators API * [Indicators] Addressed code review items from https://github.com/nasa/openmct/pull/1837 * Updated tests for URL Indicator * Adding Indicator API spec * Address linting issues * Switched to direct DOM manipulation rather than template compilation to avoid an unnecessary extra holder element * Updated documentation to reflect changes to API * Indicators api styling (#2076) Updated styling for Indicators * Update API TOC * Fix color of items w-mct-example areas of Style Guide Fixes #1837 * Status class refactoring and cleanups Fixes #1837 - Significant cleanups and name refactoring to allow more concise selector definitions, with changes in js, html and scss files; - Updates in Style Guide > Status page, with some content reorganization and clarification; * Corrected out of date API * de-zeptoed Indicator API test spec * Remove promise from URLIndicator * Separated legacy indicators support * Updated Indicator specs to Jasmine 3 * Fixed checkstyle and lint issues * Moved legacy indicators support to adapter folder * Various fixes for Indicators Fixes #1837 - Added SASS constants for Indicator colors; - Removed commented code; - Removed unused indicator classes from _messages.scss - Fixed missing s-status-on class; * Significant revisions to Style Guide Indicators content Fixes #1837 - Better documentation including recommendations; - Better and more concrete examples; * Style Guide example tweaks Fixes #1837 * Refinement to Style Guide Status and Limits content Fixes #1837 - More detail and clarification on Status and Limits; * Cleanup code Fixes #1837 - Remove commented styles; - Line return refinements;
This commit is contained in:
parent
8055e050b6
commit
3246480f82
88
API.md
88
API.md
@ -37,7 +37,7 @@
|
|||||||
- [Time Systems and Bounds](#time-systems-and-bounds)
|
- [Time Systems and Bounds](#time-systems-and-bounds)
|
||||||
- [Defining and Registering Time Systems](#defining-and-registering-time-systems)
|
- [Defining and Registering Time Systems](#defining-and-registering-time-systems)
|
||||||
- [Getting and Setting the Active Time System](#getting-and-setting-the-active-time-system)
|
- [Getting and Setting the Active Time System](#getting-and-setting-the-active-time-system)
|
||||||
- [Time Bounds](#time-bounds)
|
- [Time Bounds](#time-bounds)
|
||||||
- [Clocks](#clocks)
|
- [Clocks](#clocks)
|
||||||
- [Defining and registering clocks](#defining-and-registering-clocks)
|
- [Defining and registering clocks](#defining-and-registering-clocks)
|
||||||
- [Getting and setting active clock](#getting-and-setting-active-clock)
|
- [Getting and setting active clock](#getting-and-setting-active-clock)
|
||||||
@ -48,6 +48,10 @@
|
|||||||
- [The Time Conductor](#the-time-conductor)
|
- [The Time Conductor](#the-time-conductor)
|
||||||
- [Time Conductor Configuration](#time-conductor-configuration)
|
- [Time Conductor Configuration](#time-conductor-configuration)
|
||||||
- [Example conductor configuration](#example-conductor-configuration)
|
- [Example conductor configuration](#example-conductor-configuration)
|
||||||
|
- [Indicators](#indicators)
|
||||||
|
- [The URL Status Indicator](#the-url-status-indicator)
|
||||||
|
- [Creating a Simple Indicator](#creating-a-simple-indicator)
|
||||||
|
- [Custom Indicators](#custom-indicators)
|
||||||
- [Included Plugins](#included-plugins)
|
- [Included Plugins](#included-plugins)
|
||||||
|
|
||||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||||
@ -688,7 +692,7 @@ openmct.time.timeSystem(utcTimeSystem, bounds);
|
|||||||
Setting the active time system will trigger a [`'timeSystem'`](#time-events)
|
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.
|
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
|
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.
|
bounds are simply an object with a `start` and an end `end` attribute.
|
||||||
@ -977,6 +981,72 @@ 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.
|
||||||
|
Typically an indicator will display an icon (customizable with a CSS class) that will
|
||||||
|
reveal additional information when the mouse cursor is hovered over it.
|
||||||
|
|
||||||
|
### 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 Simple Indicator
|
||||||
|
|
||||||
|
A simple indicator with an icon and some text can be created and added with minimal code. An indicator
|
||||||
|
of this type exposes functions for customizing the text, icon, and style of the indicator.
|
||||||
|
|
||||||
|
eg.
|
||||||
|
``` javascript
|
||||||
|
var myIndicator = openmct.indicators.simpleIndicator();
|
||||||
|
myIndicator.text("Hello World!");
|
||||||
|
openmct.indicators.add(myIndicator);
|
||||||
|
```
|
||||||
|
|
||||||
|
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 simple providing a DOM element to place alongside other indicators.
|
||||||
|
|
||||||
|
``` javascript
|
||||||
|
var domNode = document.createElement('div');
|
||||||
|
domNode.innerText = new Date().toString();
|
||||||
|
setInterval(function () {
|
||||||
|
domNode.innerText = new Date().toString();
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
openmct.indicators.add({
|
||||||
|
element: domNode
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
## Included Plugins
|
## Included Plugins
|
||||||
|
|
||||||
Open MCT is packaged along with a few general-purpose plugins:
|
Open MCT is packaged along with a few general-purpose plugins:
|
||||||
@ -1000,18 +1070,18 @@ openmct.install(openmct.plugins.CouchDB('http://localhost:9200'))
|
|||||||
* `openmct.plugins.Espresso` and `openmct.plugins.Snow` are two different
|
* `openmct.plugins.Espresso` and `openmct.plugins.Snow` are two different
|
||||||
themes (dark and light) available for Open MCT. Note that at least one
|
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.
|
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:
|
availability of a URL with the following options:
|
||||||
- `url` : URL to indicate the status of
|
- `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`
|
- `interval`: Interval between checking the connection, defaults to `10000`
|
||||||
- `label` Name showing up as text in the status bar, defaults to url
|
- `label` Name showing up as text in the status bar, defaults to url
|
||||||
```javascript
|
```javascript
|
||||||
openmct.install(openmct.plugins.URLIndicatorPlugin({
|
openmct.install(openmct.plugins.URLIndicator({
|
||||||
url: 'http://google.com',
|
url: 'http://localhost:8080',
|
||||||
cssClass: 'check',
|
iconClass: 'check',
|
||||||
interval: 10000,
|
interval: 10000,
|
||||||
label: 'Google'
|
label: 'Localhost'
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
@ -38,7 +38,8 @@ define([
|
|||||||
"provides": "identityService",
|
"provides": "identityService",
|
||||||
"type": "provider",
|
"type": "provider",
|
||||||
"depends": [
|
"depends": [
|
||||||
"dialogService"
|
"dialogService",
|
||||||
|
"$q"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -55,21 +55,37 @@ define(
|
|||||||
* @implements {IdentityService}
|
* @implements {IdentityService}
|
||||||
* @memberof platform/identity
|
* @memberof platform/identity
|
||||||
*/
|
*/
|
||||||
function ExampleIdentityProvider(dialogService) {
|
function ExampleIdentityProvider(dialogService, $q) {
|
||||||
// Handle rejected dialog messages by treating the
|
this.dialogService = dialogService;
|
||||||
// current user as undefined.
|
this.$q = $q;
|
||||||
function echo(v) { return v; }
|
|
||||||
function giveUndefined() { return undefined; }
|
|
||||||
|
|
||||||
this.userPromise =
|
this.returnUser = this.returnUser.bind(this);
|
||||||
dialogService.getUserInput(DIALOG_STRUCTURE, DEFAULT_IDENTITY)
|
this.returnUndefined = this.returnUndefined.bind(this);
|
||||||
.then(echo, giveUndefined);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ExampleIdentityProvider.prototype.getUser = function () {
|
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;
|
return ExampleIdentityProvider;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
<span class="status block" ng-controller="DialogLaunchController">
|
<span class="h-indicator" ng-controller="DialogLaunchController">
|
||||||
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
|
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
|
||||||
<span class="status-indicator icon-box-with-arrow"></span><span class="label">
|
<div class="ls-indicator icon-box-with-arrow s-status-available"><span class="label">
|
||||||
<a ng-click="launchProgress(true)">Known</a> |
|
<a ng-click="launchProgress(true)">Known</a>
|
||||||
<a ng-click="launchProgress(false)">Unknown</a> |
|
<a ng-click="launchProgress(false)">Unknown</a>
|
||||||
<a ng-click="launchError()">Error</a> |
|
<a ng-click="launchError()">Error</a>
|
||||||
<a ng-click="launchInfo()">Info</a>
|
<a ng-click="launchInfo()">Info</a>
|
||||||
</span><span class="count"></span>
|
</span></div>
|
||||||
</span>
|
</span>
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
<span class="status block" ng-controller="NotificationLaunchController">
|
<span class="h-indicator" ng-controller="NotificationLaunchController">
|
||||||
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
|
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
|
||||||
<span class="status-indicator icon-bell"></span><span class="label">
|
<div class="ls-indicator icon-bell s-status-available"><span class="label">
|
||||||
<a ng-click="newInfo()">Success</a> |
|
<a ng-click="newInfo()">Success</a>
|
||||||
<a ng-click="newError()">Error</a> |
|
<a ng-click="newError()">Error</a>
|
||||||
<a ng-click="newAlert()">Alert</a> |
|
<a ng-click="newAlert()">Alert</a>
|
||||||
<a ng-click="newProgress()">Progress</a>
|
<a ng-click="newProgress()">Progress</a>
|
||||||
</span><span class="count"></span>
|
</span></div>
|
||||||
</span>
|
</span>
|
||||||
|
@ -58,7 +58,10 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.w-mct-example > div { margin-bottom: $interiorMarginLg; }
|
.w-mct-example {
|
||||||
|
color: #ccc;
|
||||||
|
> div { margin-bottom: $interiorMarginLg; }
|
||||||
|
}
|
||||||
|
|
||||||
code,
|
code,
|
||||||
pre {
|
pre {
|
||||||
|
@ -20,12 +20,12 @@
|
|||||||
at runtime from the About dialog for additional information.
|
at runtime from the About dialog for additional information.
|
||||||
-->
|
-->
|
||||||
<style>
|
<style>
|
||||||
.w-mct-example div[class*="s-limit"],
|
|
||||||
.w-mct-example div[class*="s-status"],
|
.w-mct-example div[class*="s-status"],
|
||||||
.w-mct-example div[class*="s-unsynced"],
|
.w-mct-example span[class*="s-status"],
|
||||||
|
.w-mct-example div[class*="s-limit"],
|
||||||
.w-mct-example span[class*="s-limit"] {
|
.w-mct-example span[class*="s-limit"] {
|
||||||
border-radius: 4px;
|
border-radius: 3px;
|
||||||
padding: 3px 7px;
|
padding: 2px 5px;
|
||||||
}
|
}
|
||||||
.w-mct-example table {
|
.w-mct-example table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -36,65 +36,12 @@
|
|||||||
<h1>Status Indication</h1>
|
<h1>Status Indication</h1>
|
||||||
|
|
||||||
<div class="l-section">
|
<div class="l-section">
|
||||||
<h2>Overview</h2>
|
<h2>Status Classes</h2>
|
||||||
<p>Many elements in Open MCT need to articulate a dynamic status; Open MCT provides the following styles and conventions to handle this:</p>
|
|
||||||
<ul>
|
|
||||||
<li><strong>Limits</strong>: when telemetry values exceed minimum or maximum values, they can be violating limits. Limit styles include both color and iconography; color is used to indicate severity while icons are used to indicate direction, upper or lower.</li>
|
|
||||||
<li><strong>Status</strong>: Open MCT also provides a number or built-in Status styles allowing telemetry or other displayed information to be visually classified by type. Common uses for these classes are to visually denote event records.</li>
|
|
||||||
<li><strong>Synchronization</strong>: When the system is displaying real-time data, it is very important that displays clearly indicate when they are not doing so, such as when a plot if frozen while panning or zooming. Open MCT provides a style for this.</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="l-section">
|
|
||||||
<h2>Limits</h2>
|
|
||||||
<div class="cols cols1-1">
|
<div class="cols cols1-1">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<p>Limit CSS classes can be applied to any block or inline element. Open MCT limit classes set color and optionally an icon, but don't effect other properties. Yellow and red limit classes can be used as is, or allow the application of any custom icon available in Open MCT's glyphs library. "Level" limit classes - upper and lower - always use an icon in addition to a color; Open MCT doesn't support level limits without color.</p>
|
<p>Status classes allow any block or inline-block element to be decorated in order to articulate a
|
||||||
<ul>
|
status. Provided classes include color-only and color plus icon; custom icons can easily be
|
||||||
<li>Color only</li>
|
employed by using a color-only status class in combination with an <a class="link" href="#/browse/styleguide:home/glyphs?tc.mode=local&tc.timeSystem=utc&tc.startDelta=1800000&tc.endDelta=0&view=styleguide.glyphs">glyph</a>.</p>
|
||||||
<ul>
|
|
||||||
<li><code>s-limit-yellow</code>: A yellow limit.</li>
|
|
||||||
<li><code>s-limit-red</code>: A red limit.</li>
|
|
||||||
</ul>
|
|
||||||
<li>Color and icon</li>
|
|
||||||
<ul>
|
|
||||||
<li><code>s-limit-yellow-icon</code>: A yellow limit with icon.</li>
|
|
||||||
<li><code>s-limit-red-icon</code>: A red limit with icon.</li>
|
|
||||||
</ul>
|
|
||||||
<li>Upper and lower limit indicators. Must be used with a color limit class to be visible.</li>
|
|
||||||
<ul>
|
|
||||||
<li><code>s-limit-upr</code>: Upper limit.
|
|
||||||
</li>
|
|
||||||
<li><code>s-limit-lwr</code>: Lower limit.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<mct-example><div class="s-limit-yellow">Yellow limit</div>
|
|
||||||
<div class="s-limit-red">Red limit</div>
|
|
||||||
<div class="s-limit-yellow-icon">Yellow limit with icon</div>
|
|
||||||
<div class="s-limit-red-icon">Red limit with icon</div>
|
|
||||||
<div class="s-limit-yellow s-limit-lwr">Lower yellow limit</div>
|
|
||||||
<div class="s-limit-red s-limit-upr">Upper red limit</div>
|
|
||||||
<div class="s-limit-red icon-bell">Red Limit with a custom icon</div>
|
|
||||||
<div>Some text with an <span class="s-limit-yellow-icon">inline element</span> showing a yellow limit.</div>
|
|
||||||
|
|
||||||
<!-- Limits applied in a table -->
|
|
||||||
<table>
|
|
||||||
<tr class='header'><td>Name</td><td>Value 1</td><td>Value 2</td></tr>
|
|
||||||
<tr><td>ENG_PWR 4991</td><td>7.023</td><td class="s-limit-yellow s-limit-upr">70.23</td></tr>
|
|
||||||
<tr><td>ENG_PWR 4992</td><td>49.784</td><td class="s-limit-red s-limit-lwr">-121.22</td></tr>
|
|
||||||
<tr><td>ENG_PWR 4993</td><td class="s-limit-yellow icon-bell">0.451</td><td>1.007</td></tr>
|
|
||||||
</table>
|
|
||||||
</mct-example>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="l-section">
|
|
||||||
<h2>Status</h2>
|
|
||||||
<div class="cols cols1-1">
|
|
||||||
<div class="col">
|
|
||||||
<p>Classes here can be applied to elements as needed.</p>
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Color only</li>
|
<li>Color only</li>
|
||||||
<ul>
|
<ul>
|
||||||
@ -106,36 +53,174 @@
|
|||||||
</ul>
|
</ul>
|
||||||
<li>Color and icon</li>
|
<li>Color and icon</li>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>s-status-warning-hi-icon</code></li>
|
<li><code>s-status-icon-warning-hi</code></li>
|
||||||
<li><code>s-status-warning-lo-icon</code></li>
|
<li><code>s-status-icon-warning-lo</code></li>
|
||||||
<li><code>s-status-diagnostic-icon</code></li>
|
<li><code>s-status-icon-diagnostic</code></li>
|
||||||
<li><code>s-status-info-icon</code></li>
|
<li><code>s-status-icon-info</code></li>
|
||||||
<li><code>s-status-ok-icon</code></li>
|
<li><code>s-status-icon-ok</code></li>
|
||||||
</ul>
|
</ul>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<mct-example><div class="s-status-warning-hi">WARNING HI</div>
|
<mct-example><!-- Color alone examples -->
|
||||||
|
<div class="s-status-warning-hi">WARNING HI</div>
|
||||||
<div class="s-status-warning-lo">WARNING LOW</div>
|
<div class="s-status-warning-lo">WARNING LOW</div>
|
||||||
<div class="s-status-diagnostic">DIAGNOSTIC</div>
|
<div class="s-status-diagnostic">DIAGNOSTIC</div>
|
||||||
<div class="s-status-info">INFO</div>
|
<div class="s-status-info">INFO</div>
|
||||||
<div class="s-status-ok">OK</div>
|
<div class="s-status-ok">OK</div>
|
||||||
<div class="s-status-warning-hi-icon">WARNING HI with icon</div>
|
|
||||||
<div class="s-status-warning-lo-icon">WARNING LOW with icon</div>
|
<!-- Color and icon examples -->
|
||||||
<div class="s-status-diagnostic-icon">DIAGNOSTIC with icon</div>
|
<div class="s-status-icon-warning-hi">WARNING HI with icon</div>
|
||||||
<div class="s-status-info-icon">INFO with icon</div>
|
<div class="s-status-icon-warning-lo">WARNING LOW with icon</div>
|
||||||
<div class="s-status-ok-icon">OK with icon</div>
|
<div class="s-status-icon-diagnostic">DIAGNOSTIC with icon</div>
|
||||||
<div class="s-status-warning-hi icon-gear">WARNING HI with custom icon</div>
|
<div class="s-status-icon-info">INFO with icon</div>
|
||||||
|
<div class="s-status-icon-ok">OK with icon</div>
|
||||||
|
<div class="s-status-warning-hi icon-alert-triangle">WARNING HI with custom icon</div>
|
||||||
|
<div>Some text with an <span class="s-status-icon-diagnostic">inline element</span> showing a Diagnostic status.</div>
|
||||||
</mct-example>
|
</mct-example>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="l-section">
|
<div class="l-section">
|
||||||
<h2>Synchronization</h2>
|
<h2>Limit Classes</h2>
|
||||||
<div class="cols cols1-1">
|
<div class="cols cols1-1">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<p>When the system is operating in real-time streaming mode, it is important for views that display real-time data to clearly articulate when they are not, such as when a user zooms or pans a plot view, freezing that view. In that case, the CSS class <code>s-unsynced</code> should be applied to that view.</p>
|
<p>Limit classes are a specialized form of status, specifically meant to be applied to telemetry
|
||||||
|
displays to indicate that a limit threshold has been violated. Open MCT provides both severity
|
||||||
|
and direction classes; severity (yellow and red) can be used alone or in combination
|
||||||
|
with direction (upper or lower). Direction classes cannot be used on their own.</p>
|
||||||
|
<p>Like Status classes, Limits can be used as color-only, or color plus icon. Custom icons can
|
||||||
|
be applied in the same fashion as described above.</p>
|
||||||
|
<ul>
|
||||||
|
<li>Severity color alone</li>
|
||||||
|
<ul>
|
||||||
|
<li><code>s-limit-yellow</code>: A yellow limit.</li>
|
||||||
|
<li><code>s-limit-red</code>: A red limit.</li>
|
||||||
|
</ul>
|
||||||
|
<li>Severity color and icon</li>
|
||||||
|
<ul>
|
||||||
|
<li><code>s-limit-icon-yellow</code>: A yellow limit with icon.</li>
|
||||||
|
<li><code>s-limit-icon-red</code>: A red limit with icon.</li>
|
||||||
|
</ul>
|
||||||
|
<li>Direction indicators. MUST be used with a "color alone" limit class. See
|
||||||
|
examples for more.</li>
|
||||||
|
<ul>
|
||||||
|
<li><code>s-limit-upr</code>: Upper limit.</li>
|
||||||
|
<li><code>s-limit-lwr</code>: Lower limit.</li>
|
||||||
|
</ul>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<mct-example><div class="s-unsynced">This element is unsynced</div>
|
<mct-example><!-- Color alone examples -->
|
||||||
|
<div class="s-limit-yellow">Yellow limit</div>
|
||||||
|
<div class="s-limit-red">Red limit</div>
|
||||||
|
|
||||||
|
<!-- Color and icon examples -->
|
||||||
|
<div class="s-limit-icon-yellow">Yellow limit with icon</div>
|
||||||
|
<div class="s-limit-icon-red">Red limit with icon</div>
|
||||||
|
<div class="s-limit-red icon-alert-rect">Red Limit with a custom icon</div>
|
||||||
|
<div>Some text with an <span class="s-limit-icon-yellow">inline element</span> showing a yellow limit.</div>
|
||||||
|
|
||||||
|
<!-- Severity and direction examples -->
|
||||||
|
<div class="s-limit-yellow s-limit-lwr">Lower yellow limit</div>
|
||||||
|
<div class="s-limit-red s-limit-upr">Upper red limit</div>
|
||||||
|
|
||||||
|
<!-- Limits applied in a table -->
|
||||||
|
<table>
|
||||||
|
<tr class='header'><td>Name</td><td>Value 1</td><td>Value 2</td></tr>
|
||||||
|
<tr><td>ENG_PWR 4991</td><td>7.023</td><td class="s-limit-yellow s-limit-upr">70.23</td></tr>
|
||||||
|
<tr><td>ENG_PWR 4992</td><td>49.784</td><td class="s-limit-red s-limit-lwr">-121.22</td></tr>
|
||||||
|
<tr><td>ENG_PWR 4993</td><td class="s-limit-yellow icon-alert-triangle">0.451</td><td>1.007</td></tr>
|
||||||
|
</table>
|
||||||
|
</mct-example>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="l-section">
|
||||||
|
<h2>Status Bar Indicators</h2>
|
||||||
|
<div class="cols cols1-1">
|
||||||
|
<div class="col">
|
||||||
|
<p>Indicators are small iconic notification elements that appear in the Status Bar area of
|
||||||
|
the application at the window's bottom. Indicators should be used to articulate the state of a
|
||||||
|
system and optionally provide gestures related to that system. They use a combination of icon and
|
||||||
|
color to identify themselves and articulate a state respectively.</p>
|
||||||
|
<h3>Recommendations</h3>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Keep the icon consistent</strong>. The icon is the principal identifier of the system and is a valuable
|
||||||
|
recall aid for the user. Don't change the icon as a system's state changes, use color and
|
||||||
|
text for that purpose.</li>
|
||||||
|
<li><strong>Don't use the same icon more than once</strong>. Select meaningful and distinct icons so the user
|
||||||
|
will be able to quickly identify what they're looking for.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3>States</h3>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Disabled</strong>: The system is not available to the user.</li>
|
||||||
|
<li><strong>Off / Available</strong>: The system is accessible to the user but is not currently
|
||||||
|
"On" or has not been configured. If the Indicator directly provides gestures
|
||||||
|
related to the system, such as opening a configuration dialog box, then use
|
||||||
|
"Available"; if the user must act elsewhere or the system isn't user-controllable,
|
||||||
|
use "Off".</li>
|
||||||
|
<li><strong>On</strong>: The system is enabled or configured; it is having an effect on the larger application.</li>
|
||||||
|
<li><strong>Alert / Error</strong>: There has been a problem with the system. Generally, "Alert"
|
||||||
|
should be used to call attention to an issue that isn't critical, while "Error"
|
||||||
|
should be used to call attention to a problem that the user should really be aware of or do
|
||||||
|
something about.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3>Structure</h3>
|
||||||
|
<p>Indicators consist of a <code>.ls-indicator</code>
|
||||||
|
wrapper element with <code>.icon-*</code> classes for the type of thing they represent and
|
||||||
|
<code>.s-status-*</code> classes to articulate the current state. Title attributes should be used
|
||||||
|
to provide more verbose information about the thing and/or its status.</p>
|
||||||
|
<p>The wrapper encloses a <code>.label</code> element that is displayed on hover. This element should
|
||||||
|
include a brief statement of the current status, and can also include clickable elements
|
||||||
|
as <code><a></code> tags. An optional <code>.count</code> element can be included to display
|
||||||
|
information such as a number of messages.</p>
|
||||||
|
<p>Icon classes are as defined on the
|
||||||
|
<a class="link" href="#/browse/styleguide:home/glyphs?tc.mode=local&tc.timeSystem=utc&tc.startDelta=1800000&tc.endDelta=0&view=styleguide.glyphs">
|
||||||
|
Glyphs page</a>. Status classes applicable to Indicators are as follows:</p>
|
||||||
|
<ul>
|
||||||
|
<li><code>s-status-disabled</code></li>
|
||||||
|
<li><code>s-status-off</code></li>
|
||||||
|
<li><code>s-status-available</code></li>
|
||||||
|
<li><code>s-status-on</code></li>
|
||||||
|
<li><code>s-status-alert</code></li>
|
||||||
|
<li><code>s-status-error</code></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<mct-example><div class="s-ue-bottom-bar status-holder s-status-bar">
|
||||||
|
<span class="ls-indicator icon-database s-status-disabled" title="The system is currently disabled.">
|
||||||
|
<span class="label">System not enabled.</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="s-ue-bottom-bar status-holder s-status-bar">
|
||||||
|
<span class="ls-indicator icon-database s-status-available" title="Configure data connection.">
|
||||||
|
<span class="label">Data connection available
|
||||||
|
<a class="icon-gear">Configure</a>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="s-ue-bottom-bar status-holder s-status-bar">
|
||||||
|
<span class="ls-indicator icon-database s-status-on" title="Data connected.">
|
||||||
|
<span class="label">Connected to Skynet
|
||||||
|
<a class="icon-gear">Change</a>
|
||||||
|
<a>Disconnect</a>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="s-ue-bottom-bar status-holder s-status-bar">
|
||||||
|
<span class="ls-indicator icon-database s-status-alert" title="System is self-aware.">
|
||||||
|
<span class="label">Skynet at Turing Level 5</span>
|
||||||
|
</span>
|
||||||
|
<span class="ls-indicator icon-bell s-status-error" title="You have alerts.">
|
||||||
|
<span class="label">
|
||||||
|
<a class="icon-alert-triangle">View Alerts</a>
|
||||||
|
</span>
|
||||||
|
<span class="count">495</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</mct-example>
|
</mct-example>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -54,7 +54,7 @@ define(
|
|||||||
return "icon-object-unknown";
|
return "icon-object-unknown";
|
||||||
},
|
},
|
||||||
getText: function () {
|
getText: function () {
|
||||||
return latest;
|
return "" + latest;
|
||||||
},
|
},
|
||||||
getDescription: function () {
|
getDescription: function () {
|
||||||
return "";
|
return "";
|
||||||
|
@ -34,7 +34,6 @@ define([
|
|||||||
"./src/controllers/ContextMenuController",
|
"./src/controllers/ContextMenuController",
|
||||||
"./src/controllers/ClickAwayController",
|
"./src/controllers/ClickAwayController",
|
||||||
"./src/controllers/ViewSwitcherController",
|
"./src/controllers/ViewSwitcherController",
|
||||||
"./src/controllers/BottomBarController",
|
|
||||||
"./src/controllers/GetterSetterController",
|
"./src/controllers/GetterSetterController",
|
||||||
"./src/controllers/SelectorController",
|
"./src/controllers/SelectorController",
|
||||||
"./src/controllers/ObjectInspectorController",
|
"./src/controllers/ObjectInspectorController",
|
||||||
@ -49,13 +48,14 @@ define([
|
|||||||
"./src/directives/MCTSplitPane",
|
"./src/directives/MCTSplitPane",
|
||||||
"./src/directives/MCTSplitter",
|
"./src/directives/MCTSplitter",
|
||||||
"./src/directives/MCTTree",
|
"./src/directives/MCTTree",
|
||||||
|
"./src/directives/MCTIndicators",
|
||||||
"./src/directives/MCTPreview",
|
"./src/directives/MCTPreview",
|
||||||
"./src/actions/MCTPreviewAction",
|
"./src/actions/MCTPreviewAction",
|
||||||
"./src/filters/ReverseFilter",
|
"./src/filters/ReverseFilter",
|
||||||
"text!./res/templates/bottombar.html",
|
"text!./res/templates/bottombar.html",
|
||||||
"text!./res/templates/controls/action-button.html",
|
"text!./res/templates/controls/action-button.html",
|
||||||
"text!./res/templates/controls/input-filter.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/message-banner.html",
|
||||||
"text!./res/templates/progress-bar.html",
|
"text!./res/templates/progress-bar.html",
|
||||||
"text!./res/templates/controls/time-controller.html",
|
"text!./res/templates/controls/time-controller.html",
|
||||||
@ -87,7 +87,6 @@ define([
|
|||||||
ContextMenuController,
|
ContextMenuController,
|
||||||
ClickAwayController,
|
ClickAwayController,
|
||||||
ViewSwitcherController,
|
ViewSwitcherController,
|
||||||
BottomBarController,
|
|
||||||
GetterSetterController,
|
GetterSetterController,
|
||||||
SelectorController,
|
SelectorController,
|
||||||
ObjectInspectorController,
|
ObjectInspectorController,
|
||||||
@ -102,6 +101,7 @@ define([
|
|||||||
MCTSplitPane,
|
MCTSplitPane,
|
||||||
MCTSplitter,
|
MCTSplitter,
|
||||||
MCTTree,
|
MCTTree,
|
||||||
|
MCTIndicators,
|
||||||
MCTPreview,
|
MCTPreview,
|
||||||
MCTPreviewAction,
|
MCTPreviewAction,
|
||||||
ReverseFilter,
|
ReverseFilter,
|
||||||
@ -281,13 +281,6 @@ define([
|
|||||||
"$timeout"
|
"$timeout"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"key": "BottomBarController",
|
|
||||||
"implementation": BottomBarController,
|
|
||||||
"depends": [
|
|
||||||
"indicators[]"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"key": "GetterSetterController",
|
"key": "GetterSetterController",
|
||||||
"implementation": GetterSetterController,
|
"implementation": GetterSetterController,
|
||||||
@ -403,6 +396,11 @@ define([
|
|||||||
"implementation": MCTTree,
|
"implementation": MCTTree,
|
||||||
"depends": ['gestureService', 'openmct']
|
"depends": ['gestureService', 'openmct']
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "mctIndicators",
|
||||||
|
"implementation": MCTIndicators,
|
||||||
|
"depends": ['openmct']
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "mctPreview",
|
"key": "mctPreview",
|
||||||
"implementation": MCTPreview,
|
"implementation": MCTPreview,
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
@import "controls/lists";
|
@import "controls/lists";
|
||||||
@import "controls/menus";
|
@import "controls/menus";
|
||||||
@import "controls/messages";
|
@import "controls/messages";
|
||||||
|
@import "controls/indicators";
|
||||||
@import "mobile/controls/menus";
|
@import "mobile/controls/menus";
|
||||||
|
|
||||||
/********************************* FORMS */
|
/********************************* FORMS */
|
||||||
|
@ -20,66 +20,120 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
/*************************************************** MIXINS */
|
/*************************************************** MIXINS */
|
||||||
@mixin formulateStatusColors($c) {
|
@mixin elementStatusColors($c) {
|
||||||
// Sets bg and icon colors for elements
|
// Sets bg and icon colors for elements
|
||||||
background: rgba($c, 0.4) !important;
|
background: rgba($c, 0.5) !important;
|
||||||
&:before { color: $c !important; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************** GENERAL */
|
|
||||||
.s-limit-yellow,
|
|
||||||
.s-limit-red,
|
|
||||||
.s-limit-yellow-icon,
|
|
||||||
.s-limit-red-icon,
|
|
||||||
.s-status-warning-lo,
|
|
||||||
.s-status-warning-hi,
|
|
||||||
.s-status-diagnostic,
|
|
||||||
.s-status-command,
|
|
||||||
.s-status-info,
|
|
||||||
.s-status-ok,
|
|
||||||
.s-status-warning-lo-icon,
|
|
||||||
.s-status-warning-hi-icon,
|
|
||||||
.s-status-diagnostic-icon,
|
|
||||||
.s-status-command-icon,
|
|
||||||
.s-status-info-icon,
|
|
||||||
.s-status-ok-icon {
|
|
||||||
@include trans-prop-nice($props: background, $dur: 500ms);
|
|
||||||
&:before {
|
&:before {
|
||||||
content:'';
|
color: $c !important;
|
||||||
font-family: symbolsfont;
|
|
||||||
font-size: 0.8em;
|
|
||||||
margin-right: $interiorMarginSm;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin indicatorStatusColors($c) {
|
||||||
|
&:before, .count {
|
||||||
|
color: $c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************** GENERAL */
|
||||||
|
.s-limit-upr,
|
||||||
|
.s-limit-lwr,
|
||||||
|
[class*='s-limit-icon'],
|
||||||
|
[class*='s-status-icon'] {
|
||||||
|
&:before {
|
||||||
|
content:'';
|
||||||
|
display: inline-block;
|
||||||
|
font-family: symbolsfont;
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************** LIMITS */
|
/*************************************************** LIMITS */
|
||||||
.s-limit-yellow, .s-limit-yellow-icon {
|
[class*='s-limit'] {
|
||||||
@include formulateStatusColors($colorWarningLo);
|
&[class*='icon-'] {
|
||||||
|
&:before {
|
||||||
|
margin-right: $interiorMargin;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.s-limit-red, .s-limit-red-icon {
|
.s-limit-yellow, .s-limit-icon-yellow {
|
||||||
@include formulateStatusColors($colorWarningHi);
|
@include elementStatusColors($colorWarningLo);
|
||||||
}
|
}
|
||||||
|
|
||||||
.s-limit-upr:before { content: $glyph-icon-arrow-double-up; }
|
.s-limit-red, .s-limit-icon-red {
|
||||||
.s-limit-lwr:before { content: $glyph-icon-arrow-double-down; }
|
@include elementStatusColors($colorWarningHi);
|
||||||
.s-limit-yellow-icon:before,
|
}
|
||||||
.s-limit-red-icon:before { content: $glyph-icon-alert-triangle; }
|
|
||||||
|
.s-limit {
|
||||||
|
&-upr,
|
||||||
|
&-lwr {
|
||||||
|
&:before {
|
||||||
|
margin-right: $interiorMargin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-upr:before { content: $glyph-icon-arrow-double-up; }
|
||||||
|
&-lwr:before { content: $glyph-icon-arrow-double-down; }
|
||||||
|
|
||||||
|
&-icon-yellow,
|
||||||
|
&-icon-red {
|
||||||
|
&:before {
|
||||||
|
content: $glyph-icon-alert-triangle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************** STATUS */
|
/*************************************************** STATUS */
|
||||||
.s-status-warning-hi, .s-status-warning-hi-icon { @include formulateStatusColors($colorWarningHi); }
|
[class*='s-status'] {
|
||||||
.s-status-warning-lo, .s-status-warning-lo-icon { @include formulateStatusColors($colorWarningLo); }
|
&[class*='icon-'] {
|
||||||
.s-status-diagnostic, .s-status-diagnostic-icon { @include formulateStatusColors($colorDiagnostic); }
|
&:before {
|
||||||
.s-status-info, .s-status-info-icon { @include formulateStatusColors($colorInfo); }
|
margin-right: $interiorMargin;
|
||||||
.s-status-ok, .s-status-ok-icon { @include formulateStatusColors($colorOk); }
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.s-status-warning-hi-icon:before { content: $glyph-icon-alert-triangle; }
|
.s-status-warning-hi, .s-status-icon-warning-hi { @include elementStatusColors($colorWarningHi); }
|
||||||
.s-status-warning-lo-icon:before { content: $glyph-icon-alert-rect; }
|
.s-status-warning-lo, .s-status-icon-warning-lo { @include elementStatusColors($colorWarningLo); }
|
||||||
.s-status-diagnostic-icon:before { content: $glyph-icon-eye-open; }
|
.s-status-diagnostic, .s-status-icon-diagnostic { @include elementStatusColors($colorDiagnostic); }
|
||||||
.s-status-info-icon:before { content: $glyph-icon-info; }
|
.s-status-info, .s-status-icon-info { @include elementStatusColors($colorInfo); }
|
||||||
.s-status-ok-icon:before { content: $glyph-icon-check; }
|
.s-status-ok, .s-status-icon-ok { @include elementStatusColors($colorOk); }
|
||||||
|
|
||||||
|
.s-status-icon-warning-hi:before { content: $glyph-icon-alert-triangle; }
|
||||||
|
.s-status-icon-warning-lo:before { content: $glyph-icon-alert-rect; }
|
||||||
|
.s-status-icon-diagnostic:before { content: $glyph-icon-eye-open; }
|
||||||
|
.s-status-icon-info:before { content: $glyph-icon-info; }
|
||||||
|
.s-status-icon-ok:before { content: $glyph-icon-check; }
|
||||||
|
|
||||||
|
/*************************************************** INDICATOR COLORING */
|
||||||
|
.ls-indicator {
|
||||||
|
&.s-status-info {
|
||||||
|
@include indicatorStatusColors($colorInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.s-status-disabled {
|
||||||
|
@include indicatorStatusColors($colorIndicatorDisabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.s-status-available {
|
||||||
|
@include indicatorStatusColors($colorIndicatorAvailable);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.s-status-on,
|
||||||
|
&.s-status-enabled {
|
||||||
|
@include indicatorStatusColors($colorIndicatorOn);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.s-status-off {
|
||||||
|
@include indicatorStatusColors($colorIndicatorOff);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.s-status-caution,
|
||||||
|
&.s-status-warning,
|
||||||
|
&.s-status-alert {
|
||||||
|
@include indicatorStatusColors($colorStatusAlert);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.s-status-error {
|
||||||
|
@include indicatorStatusColors($colorStatusError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
146
platform/commonUI/general/res/sass/controls/_indicators.scss
Normal file
146
platform/commonUI/general/res/sass/controls/_indicators.scss
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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 */
|
||||||
|
|
||||||
|
.h-indicator,
|
||||||
|
mct-indicators mct-include {
|
||||||
|
display: inline; // Fallback for display: contents
|
||||||
|
display: contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ls-indicator {
|
||||||
|
$bg: rgba(white, 0.2) !important;
|
||||||
|
$hbg: $colorStatusBarBg;
|
||||||
|
$hshdw: rgba(white, 0.4) 0 0 3px;
|
||||||
|
$br: $controlCr;
|
||||||
|
$hoverYOffset: -35px;
|
||||||
|
background: transparent !important;
|
||||||
|
border-radius: $br;
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
padding: 1px $interiorMarginSm; // Use padding instead of margin to keep hover chatter to a minimum
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
display: inline-block;
|
||||||
|
a,
|
||||||
|
button,
|
||||||
|
.s-button {
|
||||||
|
// Make <a> in label look like buttons
|
||||||
|
@include trans-prop-nice($props: all, $dur: 100ms);
|
||||||
|
background: transparent;
|
||||||
|
border: 1px solid rgba($colorStatusBarFg, 0.5);
|
||||||
|
border-radius: $br;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
height: auto;
|
||||||
|
line-height: normal;
|
||||||
|
padding: 0 2px;
|
||||||
|
&:hover {
|
||||||
|
background: $bg;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> [class*='icon-'] {
|
||||||
|
&:before {
|
||||||
|
font-size: 0.8em;
|
||||||
|
margin-right: $interiorMarginSm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button { text-transform: uppercase !important; }
|
||||||
|
}
|
||||||
|
|
||||||
|
&.no-collapse {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
> *,
|
||||||
|
&:before {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
margin-right: $interiorMarginSm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.no-collapse) {
|
||||||
|
z-index: 0;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
margin-right: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
transition: all 250ms ease-in 100ms;
|
||||||
|
background: $hbg;
|
||||||
|
border-radius: $br;
|
||||||
|
font-size: .6rem;
|
||||||
|
left: 0;
|
||||||
|
bottom: 140%;
|
||||||
|
opacity: 0;
|
||||||
|
padding: $interiorMarginSm $interiorMargin;
|
||||||
|
position: absolute;
|
||||||
|
transform-origin: 10px 100%;
|
||||||
|
transform: scale(0.0);
|
||||||
|
white-space: nowrap;
|
||||||
|
&:before {
|
||||||
|
// Infobubble-style arrow element
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
@include triangle('down', $size: 4px, $ratio: 1, $color: $hbg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $bg;
|
||||||
|
z-index: 1;
|
||||||
|
.label {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1.0);
|
||||||
|
transition: all 100ms ease-out 0s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.float-right {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mobile */
|
||||||
|
// Hide the clock indicator when we're phone portrait
|
||||||
|
body.phone.portrait {
|
||||||
|
.ls-indicator.t-indicator-clock {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
@ -19,9 +19,9 @@
|
|||||||
* this source code distribution or the Licensing information page available
|
* this source code distribution or the Licensing information page available
|
||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
/******************************************************************* STATUS BLOCK ELEMS */
|
|
||||||
@mixin statusBannerColors($bg, $fg: $colorStatusFg) {
|
@mixin statusBannerColors($bg, $fg: $colorStatusFg) {
|
||||||
$bgPb: 30%;
|
$bgPb: 10%;
|
||||||
$bgPbD: 10%;
|
$bgPbD: 10%;
|
||||||
background-color: darken($bg, $bgPb);
|
background-color: darken($bg, $bgPb);
|
||||||
color: $fg;
|
color: $fg;
|
||||||
@ -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 BANNERS */
|
||||||
.message {
|
.message {
|
||||||
&.block {
|
&.block {
|
||||||
@ -289,7 +185,6 @@
|
|||||||
|
|
||||||
> div,
|
> div,
|
||||||
> span {
|
> span {
|
||||||
//@include test(red);
|
|
||||||
margin-bottom: $interiorMargin;
|
margin-bottom: $interiorMargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +47,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.status-holder {
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.s-ue-bottom-bar {
|
||||||
|
background: $colorStatusBarBg;
|
||||||
|
color: $colorStatusBarFg;
|
||||||
|
cursor: default;
|
||||||
|
font-size: .7rem;
|
||||||
|
}
|
||||||
|
|
||||||
.user-environ {
|
.user-environ {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -81,21 +93,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ue-bottom-bar {
|
.l-ue-bottom-bar {
|
||||||
@include absPosDefault(0);// New status bar design
|
$m: $interiorMarginSm;
|
||||||
|
@include absPosDefault(0, $overflow: visible);// New status bar design
|
||||||
top: auto;
|
top: auto;
|
||||||
height: $ueFooterH;
|
height: $ueFooterH;
|
||||||
line-height: $ueFooterH - ($interiorMargin * 2);
|
line-height: $ueFooterH - ($m * 2);
|
||||||
background: $colorStatusBarBg;
|
|
||||||
color: lighten($colorBodyBg, 30%);
|
|
||||||
font-size: .7rem;
|
|
||||||
.status-holder {
|
.status-holder {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@include absPosDefault($interiorMargin);
|
@include absPosDefault($m, $overflow: visible);
|
||||||
@include ellipsize();
|
|
||||||
right: 120px;
|
right: 120px;
|
||||||
text-transform: uppercase;
|
z-index: 10;
|
||||||
z-index: 1;
|
|
||||||
}
|
}
|
||||||
.app-logo {
|
.app-logo {
|
||||||
background-position: right center;
|
background-position: right center;
|
||||||
|
@ -20,14 +20,8 @@
|
|||||||
at runtime from the About dialog for additional information.
|
at runtime from the About dialog for additional information.
|
||||||
-->
|
-->
|
||||||
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
|
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
|
||||||
<div class='status block'
|
<div class="ls-indicator {{ngModel.getCssClass()}}"
|
||||||
title="{{ngModel.getDescription()}}"
|
title="{{ngModel.getDescription()}}"
|
||||||
ng-click='ngModel.configure()'
|
|
||||||
ng-show="ngModel.getText().length > 0">
|
ng-show="ngModel.getText().length > 0">
|
||||||
<span class="status-indicator {{ngModel.getCssClass()}}"></span><span class="label"
|
<span class="label">{{ngModel.getText()}}</span>
|
||||||
ng-class='ngModel.getTextClass()'>
|
|
||||||
{{ngModel.getText()}}
|
|
||||||
<a class="s-button icon-gear" ng-if="ngModel.configure"></a>
|
|
||||||
</span><span class="count">
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
@ -19,14 +19,9 @@
|
|||||||
this source code distribution or the Licensing information page available
|
this source code distribution or the Licensing information page available
|
||||||
at runtime from the About dialog for additional information.
|
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 class='abs bottom-bar l-ue-bottom-bar s-ue-bottom-bar mobile-disable-select'>
|
||||||
<div id='status' class='status-holder'>
|
<div id='status' class='status-holder'>
|
||||||
<mct-include ng-repeat="indicator in bar.getIndicators()"
|
<mct-indicators></mct-indicators>
|
||||||
ng-model="indicator.ngModel"
|
|
||||||
key="indicator.template"
|
|
||||||
class="status-block-holder"
|
|
||||||
ng-class='indicator.ngModel.getGlyphClass()'>
|
|
||||||
</mct-include>
|
|
||||||
</div>
|
</div>
|
||||||
<mct-include key="'message-banner'"></mct-include>
|
<mct-include key="'message-banner'"></mct-include>
|
||||||
<mct-include key="'about-logo'"></mct-include>
|
<mct-include key="'about-logo'"></mct-include>
|
||||||
|
@ -23,37 +23,18 @@
|
|||||||
define(
|
define(
|
||||||
[],
|
[],
|
||||||
function () {
|
function () {
|
||||||
|
function MCTIndicators(openmct) {
|
||||||
/**
|
return {
|
||||||
* Controller for the bottombar template. Exposes
|
restrict: "E",
|
||||||
* available indicators (of extension category "indicators")
|
link: function link(scope, element) {
|
||||||
* @memberof platform/commonUI/general
|
openmct.indicators.indicatorElements
|
||||||
* @constructor
|
.forEach(function (indicatorElement) {
|
||||||
*/
|
element.append(indicatorElement);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
return MCTIndicators;
|
||||||
* 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 BottomBarController;
|
|
||||||
}
|
}
|
||||||
);
|
);
|
@ -1,76 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* 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(
|
|
||||||
["../../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,8 @@
|
|||||||
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
|
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
|
||||||
<a ng-click="showNotificationsList()" ng-show="notifications.length > 0" class="status block"
|
<div ng-show="notifications.length > 0" class="ls-indicator s-status-{{highest.severity}} icon-bell"
|
||||||
ng-class="highest.severity"
|
|
||||||
ng-controller="NotificationIndicatorController">
|
ng-controller="NotificationIndicatorController">
|
||||||
<span class="status-indicator icon-bell"></span><span class="label">
|
<span class="label">
|
||||||
{{notifications.length}} Notifications
|
<a ng-click="showNotificationsList()">
|
||||||
|
{{notifications.length}} Notification<span ng-show="notifications.length > 1">s</span></a>
|
||||||
</span><span class="count">{{notifications.length}}</span>
|
</span><span class="count">{{notifications.length}}</span>
|
||||||
|
</div>
|
||||||
</a>
|
|
||||||
|
@ -3,6 +3,8 @@ $colorBodyBg: #333;
|
|||||||
$colorBodyFg: #999;
|
$colorBodyFg: #999;
|
||||||
$colorGenBg: #222;
|
$colorGenBg: #222;
|
||||||
$colorStatusBarBg: #000;
|
$colorStatusBarBg: #000;
|
||||||
|
$colorStatusBarFg: #999;
|
||||||
|
$colorStatusBarFgHov: #aaa;
|
||||||
$colorKey: #0099cc;
|
$colorKey: #0099cc;
|
||||||
$colorKeySelectedBg: #005177;
|
$colorKeySelectedBg: #005177;
|
||||||
$colorKeyFg: #fff;
|
$colorKeyFg: #fff;
|
||||||
@ -55,7 +57,7 @@ $colorTransLucBg: #666; // Used as a visual blocking element over variable backg
|
|||||||
|
|
||||||
// Foundation Colors
|
// Foundation Colors
|
||||||
$colorAlt1: #ffc700;
|
$colorAlt1: #ffc700;
|
||||||
$colorAlert: #ff3c00;
|
$colorAlert: #ff9900;
|
||||||
$colorWarningHi: #cc0000;
|
$colorWarningHi: #cc0000;
|
||||||
$colorWarningLo: #ff9900;
|
$colorWarningLo: #ff9900;
|
||||||
$colorDiagnostic: #a4b442;
|
$colorDiagnostic: #a4b442;
|
||||||
@ -72,7 +74,6 @@ $colorObjHdrTxt: $colorBodyFg;
|
|||||||
$colorObjHdrIc: lighten($colorObjHdrTxt, 20%);
|
$colorObjHdrIc: lighten($colorObjHdrTxt, 20%);
|
||||||
$colorTick: rgba(white, 0.2);
|
$colorTick: rgba(white, 0.2);
|
||||||
$colorSelectableSelectedPrimary: $colorKey;
|
$colorSelectableSelectedPrimary: $colorKey;
|
||||||
//$colorSelectableSelectedSecondary: pushBack($colorSelectableSelectedPrimary, 20%);
|
|
||||||
$colorSelectableHov: rgba($colorBodyFg, 0.3);
|
$colorSelectableHov: rgba($colorBodyFg, 0.3);
|
||||||
|
|
||||||
// Menu colors
|
// Menu colors
|
||||||
@ -114,11 +115,10 @@ $colorInspectorSectionHeaderFg: pullForward($colorInspectorBg, 40%);
|
|||||||
|
|
||||||
// Status colors, mainly used for messaging and item ancillary symbols
|
// Status colors, mainly used for messaging and item ancillary symbols
|
||||||
$colorStatusFg: #ccc;
|
$colorStatusFg: #ccc;
|
||||||
$colorStatusDefault: #ccc;
|
$colorStatusDefault: #999;
|
||||||
$colorStatusInfo: $colorInfo;
|
$colorStatusInfo: $colorInfo;
|
||||||
$colorStatusAlert: $colorAlert;
|
$colorStatusAlert: $colorAlert;
|
||||||
$colorStatusError: #d4585c;
|
$colorStatusError: #da0004;
|
||||||
$colorStatusAvailable: $colorKey;
|
|
||||||
$colorStatusBtnBg: $colorBtnBg;
|
$colorStatusBtnBg: $colorBtnBg;
|
||||||
$colorProgressBarOuter: rgba(#000, 0.1);
|
$colorProgressBarOuter: rgba(#000, 0.1);
|
||||||
$colorProgressBarAmt: $colorKey;
|
$colorProgressBarAmt: $colorKey;
|
||||||
@ -127,6 +127,12 @@ $progressBarStripeW: 20px;
|
|||||||
$shdwStatusIc: rgba(black, 0.4) 0 1px 2px;
|
$shdwStatusIc: rgba(black, 0.4) 0 1px 2px;
|
||||||
$animPausedPulseDur: 500ms;
|
$animPausedPulseDur: 500ms;
|
||||||
|
|
||||||
|
// Indicator colors
|
||||||
|
$colorIndicatorAvailable: $colorKey;
|
||||||
|
$colorIndicatorDisabled: #444;
|
||||||
|
$colorIndicatorOn: $colorOk;
|
||||||
|
$colorIndicatorOff: #666;
|
||||||
|
|
||||||
// Selects
|
// Selects
|
||||||
$colorSelectBg: $colorBtnBg;
|
$colorSelectBg: $colorBtnBg;
|
||||||
$colorSelectFg: $colorBtnFg;
|
$colorSelectFg: $colorBtnFg;
|
||||||
|
@ -3,6 +3,8 @@ $colorBodyBg: #fcfcfc;
|
|||||||
$colorBodyFg: #666;
|
$colorBodyFg: #666;
|
||||||
$colorGenBg: #fff;
|
$colorGenBg: #fff;
|
||||||
$colorStatusBarBg: #000;
|
$colorStatusBarBg: #000;
|
||||||
|
$colorStatusBarFg: #999;
|
||||||
|
$colorStatusBarFgHov: #aaa;
|
||||||
$colorKey: #0099cc;
|
$colorKey: #0099cc;
|
||||||
$colorKeySelectedBg: $colorKey;
|
$colorKeySelectedBg: $colorKey;
|
||||||
$colorKeyFg: #fff;
|
$colorKeyFg: #fff;
|
||||||
@ -72,7 +74,6 @@ $colorObjHdrTxt: $colorBodyFg;
|
|||||||
$colorObjHdrIc: lighten($colorObjHdrTxt, 30%);
|
$colorObjHdrIc: lighten($colorObjHdrTxt, 30%);
|
||||||
$colorTick: rgba(black, 0.2);
|
$colorTick: rgba(black, 0.2);
|
||||||
$colorSelectableSelectedPrimary: $colorKey;
|
$colorSelectableSelectedPrimary: $colorKey;
|
||||||
//$colorSelectableSelectedSecondary: pushBack($colorSelectableSelectedPrimary, 20%);
|
|
||||||
$colorSelectableHov: rgba($colorBodyFg, 0.4);
|
$colorSelectableHov: rgba($colorBodyFg, 0.4);
|
||||||
|
|
||||||
// Menu colors
|
// Menu colors
|
||||||
@ -117,8 +118,7 @@ $colorStatusFg: #999;
|
|||||||
$colorStatusDefault: #ccc;
|
$colorStatusDefault: #ccc;
|
||||||
$colorStatusInfo: #60ba7b;
|
$colorStatusInfo: #60ba7b;
|
||||||
$colorStatusAlert: #ffb66c;
|
$colorStatusAlert: #ffb66c;
|
||||||
$colorStatusError: #c96b68;
|
$colorStatusError: #da0004;
|
||||||
$colorStatusAvailable: $colorKey;
|
|
||||||
$colorStatusBtnBg: #666;
|
$colorStatusBtnBg: #666;
|
||||||
$colorProgressBarOuter: rgba(#000, 0.1);
|
$colorProgressBarOuter: rgba(#000, 0.1);
|
||||||
$colorProgressBarAmt: #0a0;
|
$colorProgressBarAmt: #0a0;
|
||||||
@ -127,6 +127,12 @@ $progressBarStripeW: 20px;
|
|||||||
$shdwStatusIc: rgba(white, 0.8) 0 0px 5px;
|
$shdwStatusIc: rgba(white, 0.8) 0 0px 5px;
|
||||||
$animPausedPulseDur: 1s;
|
$animPausedPulseDur: 1s;
|
||||||
|
|
||||||
|
// Indicator colors
|
||||||
|
$colorIndicatorAvailable: $colorKey;
|
||||||
|
$colorIndicatorDisabled: #444;
|
||||||
|
$colorIndicatorOn: $colorOk;
|
||||||
|
$colorIndicatorOff: #666;
|
||||||
|
|
||||||
// Selects
|
// Selects
|
||||||
$colorSelectBg: $colorBtnBg;
|
$colorSelectBg: $colorBtnBg;
|
||||||
$colorSelectFg: $colorBtnFg;
|
$colorSelectFg: $colorBtnFg;
|
||||||
|
@ -55,7 +55,6 @@ define([
|
|||||||
timerTemplate,
|
timerTemplate,
|
||||||
legacyRegistry
|
legacyRegistry
|
||||||
) {
|
) {
|
||||||
|
|
||||||
legacyRegistry.register("platform/features/clock", {
|
legacyRegistry.register("platform/features/clock", {
|
||||||
"name": "Clocks/Timers",
|
"name": "Clocks/Timers",
|
||||||
"descriptions": "Domain objects for displaying current & relative times.",
|
"descriptions": "Domain objects for displaying current & relative times.",
|
||||||
@ -86,11 +85,6 @@ define([
|
|||||||
"CLOCK_INDICATOR_FORMAT"
|
"CLOCK_INDICATOR_FORMAT"
|
||||||
],
|
],
|
||||||
"priority": "preferred"
|
"priority": "preferred"
|
||||||
},
|
|
||||||
{
|
|
||||||
"implementation": FollowIndicator,
|
|
||||||
"depends": ["timerService"],
|
|
||||||
"priority": "fallback"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"services": [
|
"services": [
|
||||||
@ -305,6 +299,10 @@ define([
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"runs": [{
|
||||||
|
"implementation": FollowIndicator,
|
||||||
|
"depends": ["openmct", "timerService"]
|
||||||
|
}],
|
||||||
"licenses": [
|
"licenses": [
|
||||||
{
|
{
|
||||||
"name": "moment-duration-format",
|
"name": "moment-duration-format",
|
||||||
|
@ -45,11 +45,11 @@ define(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ClockIndicator.prototype.getGlyphClass = function () {
|
ClockIndicator.prototype.getGlyphClass = function () {
|
||||||
return "no-collapse float-right subdued";
|
return "";
|
||||||
};
|
};
|
||||||
|
|
||||||
ClockIndicator.prototype.getCssClass = function () {
|
ClockIndicator.prototype.getCssClass = function () {
|
||||||
return "icon-clock";
|
return "t-indicator-clock icon-clock no-collapse float-right";
|
||||||
};
|
};
|
||||||
|
|
||||||
ClockIndicator.prototype.getText = function () {
|
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
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
* Administration. All rights reserved.
|
* Administration. All rights reserved.
|
||||||
*
|
*
|
||||||
@ -20,38 +20,32 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
define(
|
define([], function () {
|
||||||
['moment'],
|
|
||||||
function (moment) {
|
|
||||||
var NO_TIMER = "No timer being followed";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicator that displays the active timer, as well as its
|
* Indicator that displays the active timer, as well as its
|
||||||
* current state.
|
* current state.
|
||||||
* @implements {Indicator}
|
* @memberof platform/features/clock
|
||||||
* @memberof platform/features/clock
|
*/
|
||||||
*/
|
return function installFollowIndicator(openmct, timerService) {
|
||||||
function FollowIndicator(timerService) {
|
var indicator = openmct.indicators.simpleIndicator();
|
||||||
this.timerService = timerService;
|
var timer = timerService.getTimer();
|
||||||
|
setIndicatorStatus(timer);
|
||||||
|
|
||||||
|
function setIndicatorStatus(newTimer) {
|
||||||
|
if (newTimer !== undefined) {
|
||||||
|
indicator.iconClass('icon-timer');
|
||||||
|
indicator.statusClass('s-status-on');
|
||||||
|
indicator.text('Following timer ' + newTimer.name);
|
||||||
|
} else {
|
||||||
|
indicator.iconClass('icon-timer');
|
||||||
|
indicator.statusClass('s-status-disabled');
|
||||||
|
indicator.text('No timer being followed');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FollowIndicator.prototype.getGlyphClass = function () {
|
timerService.on('change', setIndicatorStatus);
|
||||||
return "";
|
|
||||||
};
|
|
||||||
|
|
||||||
FollowIndicator.prototype.getCssClass = function () {
|
openmct.indicators.add(indicator);
|
||||||
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;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
@ -44,7 +44,7 @@ define(['EventEmitter'], function (EventEmitter) {
|
|||||||
*/
|
*/
|
||||||
TimerService.prototype.setTimer = function (timer) {
|
TimerService.prototype.setTimer = function (timer) {
|
||||||
this.timer = timer;
|
this.timer = timer;
|
||||||
this.emit('change');
|
this.emit('change', timer);
|
||||||
|
|
||||||
if (this.stopObserving) {
|
if (this.stopObserving) {
|
||||||
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
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
* Administration. All rights reserved.
|
* Administration. All rights reserved.
|
||||||
*
|
*
|
||||||
@ -20,39 +20,77 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
define(["../../src/indicators/FollowIndicator"], function (FollowIndicator) {
|
define([
|
||||||
var TIMER_SERVICE_METHODS =
|
"../../src/indicators/FollowIndicator",
|
||||||
['setTimer', 'getTimer', 'clearTimer', 'on', 'off'];
|
"../../src/services/TimerService",
|
||||||
|
"../../../../../src/MCT",
|
||||||
|
'zepto'
|
||||||
|
], function (
|
||||||
|
FollowIndicator,
|
||||||
|
TimerService,
|
||||||
|
MCT,
|
||||||
|
$
|
||||||
|
) {
|
||||||
describe("The timer-following indicator", function () {
|
describe("The timer-following indicator", function () {
|
||||||
var mockTimerService;
|
var timerService;
|
||||||
var indicator;
|
var openmct;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
mockTimerService =
|
openmct = new MCT();
|
||||||
jasmine.createSpyObj('timerService', TIMER_SERVICE_METHODS);
|
timerService = new TimerService(openmct);
|
||||||
indicator = new FollowIndicator(mockTimerService);
|
spyOn(openmct.indicators, "add");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("implements the Indicator interface", function () {
|
it("adds an indicator when installed", function () {
|
||||||
expect(indicator.getGlyphClass()).toEqual(jasmine.any(String));
|
FollowIndicator(openmct, timerService);
|
||||||
expect(indicator.getCssClass()).toEqual(jasmine.any(String));
|
expect(openmct.indicators.add).toHaveBeenCalled();
|
||||||
expect(indicator.getText()).toEqual(jasmine.any(String));
|
});
|
||||||
expect(indicator.getDescription()).toEqual(jasmine.any(String));
|
|
||||||
|
it("indicates that no timer is being followed", function () {
|
||||||
|
FollowIndicator(openmct, timerService);
|
||||||
|
var simpleIndicator = openmct.indicators.add.calls.mostRecent().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 () {
|
describe("when a timer is set", function () {
|
||||||
var testObject;
|
var testObject;
|
||||||
|
var simpleIndicator;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
testObject = { name: "some timer!" };
|
testObject = {
|
||||||
mockTimerService.getTimer.and.returnValue(testObject);
|
identifier: {
|
||||||
|
namespace: 'namespace',
|
||||||
|
key: 'key'
|
||||||
|
},
|
||||||
|
name: "some timer!"
|
||||||
|
};
|
||||||
|
timerService.setTimer(testObject);
|
||||||
|
FollowIndicator(openmct, timerService);
|
||||||
|
simpleIndicator = openmct.indicators.add.calls.mostRecent().args[0];
|
||||||
});
|
});
|
||||||
|
|
||||||
it("displays the timer's name", function () {
|
it("displays the timer's name", function () {
|
||||||
expect(indicator.getText().indexOf(testObject.name))
|
var element = simpleIndicator.element;
|
||||||
.not.toEqual(-1);
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -33,20 +33,24 @@ define(
|
|||||||
var CONNECTED = {
|
var CONNECTED = {
|
||||||
text: "Connected",
|
text: "Connected",
|
||||||
glyphClass: "ok",
|
glyphClass: "ok",
|
||||||
|
statusClass: "s-status-ok",
|
||||||
description: "Connected to the domain object database."
|
description: "Connected to the domain object database."
|
||||||
},
|
},
|
||||||
DISCONNECTED = {
|
DISCONNECTED = {
|
||||||
text: "Disconnected",
|
text: "Disconnected",
|
||||||
glyphClass: "err",
|
glyphClass: "err",
|
||||||
|
statusClass: "s-status-caution",
|
||||||
description: "Unable to connect to the domain object database."
|
description: "Unable to connect to the domain object database."
|
||||||
},
|
},
|
||||||
SEMICONNECTED = {
|
SEMICONNECTED = {
|
||||||
text: "Unavailable",
|
text: "Unavailable",
|
||||||
glyphClass: "caution",
|
glyphClass: "caution",
|
||||||
|
statusClass: "s-status-caution",
|
||||||
description: "Database does not exist or is unavailable."
|
description: "Database does not exist or is unavailable."
|
||||||
},
|
},
|
||||||
PENDING = {
|
PENDING = {
|
||||||
text: "Checking connection..."
|
text: "Checking connection...",
|
||||||
|
statusClass: "s-status-caution"
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -96,7 +100,7 @@ define(
|
|||||||
}
|
}
|
||||||
|
|
||||||
CouchIndicator.prototype.getCssClass = function () {
|
CouchIndicator.prototype.getCssClass = function () {
|
||||||
return "icon-database";
|
return "icon-database " + this.state.statusClass;
|
||||||
};
|
};
|
||||||
|
|
||||||
CouchIndicator.prototype.getGlyphClass = function () {
|
CouchIndicator.prototype.getGlyphClass = function () {
|
||||||
|
@ -57,7 +57,7 @@ define(
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("has a database icon", function () {
|
it("has a database icon", function () {
|
||||||
expect(indicator.getCssClass()).toEqual("icon-database");
|
expect(indicator.getCssClass()).toEqual("icon-database s-status-caution");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("consults the database at the configured path", function () {
|
it("consults the database at the configured path", function () {
|
||||||
|
@ -32,11 +32,13 @@ define(
|
|||||||
var CONNECTED = {
|
var CONNECTED = {
|
||||||
text: "Connected",
|
text: "Connected",
|
||||||
glyphClass: "ok",
|
glyphClass: "ok",
|
||||||
|
statusClass: "s-status-ok",
|
||||||
description: "Connected to the domain object database."
|
description: "Connected to the domain object database."
|
||||||
},
|
},
|
||||||
DISCONNECTED = {
|
DISCONNECTED = {
|
||||||
text: "Disconnected",
|
text: "Disconnected",
|
||||||
glyphClass: "err",
|
glyphClass: "err",
|
||||||
|
statusClass: "s-status-caution",
|
||||||
description: "Unable to connect to the domain object database."
|
description: "Unable to connect to the domain object database."
|
||||||
},
|
},
|
||||||
PENDING = {
|
PENDING = {
|
||||||
|
@ -26,7 +26,7 @@ define(
|
|||||||
|
|
||||||
var LOCAL_STORAGE_WARNING = [
|
var LOCAL_STORAGE_WARNING = [
|
||||||
"Using browser local storage for persistence.",
|
"Using browser local storage for persistence.",
|
||||||
"Anything you create or change will be visible only",
|
"Anything you create or change will only be saved",
|
||||||
"in this browser on this machine."
|
"in this browser on this machine."
|
||||||
].join(' ');
|
].join(' ');
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ define(
|
|||||||
}
|
}
|
||||||
|
|
||||||
LocalStorageIndicator.prototype.getCssClass = function () {
|
LocalStorageIndicator.prototype.getCssClass = function () {
|
||||||
return "icon-database";
|
return "icon-database s-status-caution";
|
||||||
};
|
};
|
||||||
LocalStorageIndicator.prototype.getGlyphClass = function () {
|
LocalStorageIndicator.prototype.getGlyphClass = function () {
|
||||||
return 'caution';
|
return 'caution';
|
||||||
|
@ -38,7 +38,7 @@ define(
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("has a database icon", function () {
|
it("has a database icon", function () {
|
||||||
expect(indicator.getCssClass()).toEqual("icon-database");
|
expect(indicator.getCssClass()).toEqual("icon-database s-status-caution");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("has a 'caution' class to draw attention", function () {
|
it("has a 'caution' class to draw attention", function () {
|
||||||
|
18
src/MCT.js
18
src/MCT.js
@ -30,7 +30,8 @@ define([
|
|||||||
'./plugins/plugins',
|
'./plugins/plugins',
|
||||||
'./ui/ViewRegistry',
|
'./ui/ViewRegistry',
|
||||||
'./ui/InspectorViewRegistry',
|
'./ui/InspectorViewRegistry',
|
||||||
'./ui/ToolbarRegistry'
|
'./ui/ToolbarRegistry',
|
||||||
|
'./adapter/indicators/legacy-indicators-plugin'
|
||||||
], function (
|
], function (
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
legacyRegistry,
|
legacyRegistry,
|
||||||
@ -41,7 +42,8 @@ define([
|
|||||||
plugins,
|
plugins,
|
||||||
ViewRegistry,
|
ViewRegistry,
|
||||||
InspectorViewRegistry,
|
InspectorViewRegistry,
|
||||||
ToolbarRegistry
|
ToolbarRegistry,
|
||||||
|
LegacyIndicatorsPlugin
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
* Open MCT is an extensible web application for building mission
|
* Open MCT is an extensible web application for building mission
|
||||||
@ -192,6 +194,15 @@ define([
|
|||||||
*/
|
*/
|
||||||
this.telemetry = new api.TelemetryAPI(this);
|
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;
|
this.Dialog = api.Dialog;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -266,6 +277,9 @@ define([
|
|||||||
|
|
||||||
legacyRegistry.register('adapter', this.legacyBundle);
|
legacyRegistry.register('adapter', this.legacyBundle);
|
||||||
legacyRegistry.enable('adapter');
|
legacyRegistry.enable('adapter');
|
||||||
|
|
||||||
|
this.install(LegacyIndicatorsPlugin());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fired by [MCT]{@link module:openmct.MCT} when the application
|
* Fired by [MCT]{@link module:openmct.MCT} when the application
|
||||||
* is started.
|
* is started.
|
||||||
|
68
src/adapter/indicators/legacy-indicators-plugin.js
Normal file
68
src/adapter/indicators/legacy-indicators-plugin.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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([], function () {
|
||||||
|
var LEGACY_INDICATOR_TEMPLATE =
|
||||||
|
'<mct-include ' +
|
||||||
|
' ng-model="indicator" ' +
|
||||||
|
' class="h-indicator" ' +
|
||||||
|
' key="template">' +
|
||||||
|
' </mct-include>';
|
||||||
|
|
||||||
|
return function () {
|
||||||
|
return function (openmct) {
|
||||||
|
openmct.legacyExtension('runs', {
|
||||||
|
depends: ['indicators[]'],
|
||||||
|
implementation: addLegacyIndicators
|
||||||
|
});
|
||||||
|
|
||||||
|
function addLegacyIndicators(legacyIndicators) {
|
||||||
|
legacyIndicators.forEach(function (legacyIndicatorDef) {
|
||||||
|
var legacyIndicator = initializeIfNeeded(legacyIndicatorDef);
|
||||||
|
var legacyIndicatorElement = buildLegacyIndicator(legacyIndicator, legacyIndicatorDef.template);
|
||||||
|
openmct.indicators.add({
|
||||||
|
element: legacyIndicatorElement
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function initializeIfNeeded(LegacyIndicatorDef) {
|
||||||
|
var legacyIndicator;
|
||||||
|
if (typeof LegacyIndicatorDef === 'function') {
|
||||||
|
legacyIndicator = new LegacyIndicatorDef();
|
||||||
|
} else {
|
||||||
|
legacyIndicator = LegacyIndicatorDef;
|
||||||
|
}
|
||||||
|
return legacyIndicator;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildLegacyIndicator(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];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
114
src/adapter/indicators/legacy-indicators-pluginSpec.js
Normal file
114
src/adapter/indicators/legacy-indicators-pluginSpec.js
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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",
|
||||||
|
"./legacy-indicators-plugin"
|
||||||
|
],
|
||||||
|
function (
|
||||||
|
MCT,
|
||||||
|
MCTIndicators,
|
||||||
|
LegacyIndicatorsPlugin
|
||||||
|
) {
|
||||||
|
var openmct;
|
||||||
|
var directive;
|
||||||
|
var holderElement;
|
||||||
|
var legacyExtensionFunction = MCT.prototype.legacyExtension;
|
||||||
|
var legacyIndicatorsRunsFunction;
|
||||||
|
|
||||||
|
describe('The legacy indicators plugin', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
mockLegacyExtensionFunction();
|
||||||
|
|
||||||
|
openmct = new MCT();
|
||||||
|
directive = new MCTIndicators(openmct);
|
||||||
|
holderElement = document.createElement('div');
|
||||||
|
|
||||||
|
mockAngularComponents();
|
||||||
|
LegacyIndicatorsPlugin()(openmct);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
MCT.prototype.legacyExtension = legacyExtensionFunction;
|
||||||
|
});
|
||||||
|
|
||||||
|
function mockLegacyExtensionFunction() {
|
||||||
|
spyOn(MCT.prototype, "legacyExtension");
|
||||||
|
MCT.prototype.legacyExtension.and.callFake(function (extensionName, definition) {
|
||||||
|
if (extensionName === 'runs') {
|
||||||
|
legacyIndicatorsRunsFunction = 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.and.returnValue(mockScope);
|
||||||
|
mockInjector.get.and.callFake(function (service) {
|
||||||
|
return {
|
||||||
|
'$compile': mockCompile,
|
||||||
|
'$rootScope': mockRootScope
|
||||||
|
}[service];
|
||||||
|
});
|
||||||
|
|
||||||
|
openmct.$injector = mockInjector;
|
||||||
|
mockCompile.and.callFake(function () {
|
||||||
|
return function () {
|
||||||
|
return [document.createElement('div')];
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
it("Displays any legacy indicators ", function () {
|
||||||
|
var legacyIndicators = [{},{},{},{}];
|
||||||
|
|
||||||
|
legacyIndicatorsRunsFunction(legacyIndicators);
|
||||||
|
renderIndicators();
|
||||||
|
|
||||||
|
expect(holderElement.children.length).toBe(legacyIndicators.length);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it("If legacy indicator is defined as a constructor function, executes function ", function () {
|
||||||
|
var mockConstructorFunction = jasmine.createSpy('mockIndicatorConstructor');
|
||||||
|
var legacyIndicators = [{}, mockConstructorFunction];
|
||||||
|
|
||||||
|
mockConstructorFunction.and.returnValue({});
|
||||||
|
legacyIndicatorsRunsFunction(legacyIndicators);
|
||||||
|
renderIndicators();
|
||||||
|
|
||||||
|
expect(holderElement.children.length).toBe(legacyIndicators.length);
|
||||||
|
expect(mockConstructorFunction).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
function renderIndicators() {
|
||||||
|
directive.link({}, holderElement);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
@ -27,7 +27,8 @@ define([
|
|||||||
'./types/TypeRegistry',
|
'./types/TypeRegistry',
|
||||||
'./ui/Dialog',
|
'./ui/Dialog',
|
||||||
'./ui/GestureAPI',
|
'./ui/GestureAPI',
|
||||||
'./telemetry/TelemetryAPI'
|
'./telemetry/TelemetryAPI',
|
||||||
|
'./indicators/IndicatorAPI'
|
||||||
], function (
|
], function (
|
||||||
TimeAPI,
|
TimeAPI,
|
||||||
ObjectAPI,
|
ObjectAPI,
|
||||||
@ -35,7 +36,8 @@ define([
|
|||||||
TypeRegistry,
|
TypeRegistry,
|
||||||
Dialog,
|
Dialog,
|
||||||
GestureAPI,
|
GestureAPI,
|
||||||
TelemetryAPI
|
TelemetryAPI,
|
||||||
|
IndicatorAPI
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
TimeAPI: TimeAPI,
|
TimeAPI: TimeAPI,
|
||||||
@ -44,6 +46,7 @@ define([
|
|||||||
Dialog: Dialog,
|
Dialog: Dialog,
|
||||||
TypeRegistry: TypeRegistry,
|
TypeRegistry: TypeRegistry,
|
||||||
GestureAPI: GestureAPI,
|
GestureAPI: GestureAPI,
|
||||||
TelemetryAPI: TelemetryAPI
|
TelemetryAPI: TelemetryAPI,
|
||||||
|
IndicatorAPI: IndicatorAPI
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
68
src/api/indicators/IndicatorAPI.js
Normal file
68
src/api/indicators/IndicatorAPI.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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',
|
||||||
|
'lodash'
|
||||||
|
], function (
|
||||||
|
SimpleIndicator,
|
||||||
|
_
|
||||||
|
) {
|
||||||
|
function IndicatorAPI(openmct) {
|
||||||
|
this.openmct = openmct;
|
||||||
|
this.indicatorElements = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = 'h-indicator';
|
||||||
|
wrapperNode.appendChild(indicator.element);
|
||||||
|
this.indicatorElements.push(wrapperNode);
|
||||||
|
};
|
||||||
|
|
||||||
|
return IndicatorAPI;
|
||||||
|
|
||||||
|
});
|
115
src/api/indicators/IndicatorAPISpec.js
Normal file
115
src/api/indicators/IndicatorAPISpec.js
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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"
|
||||||
|
],
|
||||||
|
function (
|
||||||
|
MCT,
|
||||||
|
MCTIndicators
|
||||||
|
) {
|
||||||
|
describe("The Indicator API", function () {
|
||||||
|
var openmct;
|
||||||
|
var directive;
|
||||||
|
var holderElement;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
openmct = new MCT();
|
||||||
|
directive = new MCTIndicators(openmct);
|
||||||
|
holderElement = document.createElement('div');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("The simple indicator", function () {
|
||||||
|
var simpleIndicator;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
simpleIndicator = openmct.indicators.simpleIndicator();
|
||||||
|
openmct.indicators.add(simpleIndicator);
|
||||||
|
renderIndicators();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("applies the set icon class", function () {
|
||||||
|
simpleIndicator.iconClass('testIconClass');
|
||||||
|
|
||||||
|
expect(getIconElement().classList.contains('testIconClass')).toBe(true);
|
||||||
|
|
||||||
|
simpleIndicator.iconClass('anotherIconClass');
|
||||||
|
expect(getIconElement().classList.contains('testIconClass')).toBe(false);
|
||||||
|
expect(getIconElement().classList.contains('anotherIconClass')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("applies the set status class", function () {
|
||||||
|
simpleIndicator.statusClass('testStatusClass');
|
||||||
|
|
||||||
|
expect(getIconElement().classList.contains('testStatusClass')).toBe(true);
|
||||||
|
simpleIndicator.statusClass('anotherStatusClass');
|
||||||
|
expect(getIconElement().classList.contains('testStatusClass')).toBe(false);
|
||||||
|
expect(getIconElement().classList.contains('anotherStatusClass')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("displays the set text", function () {
|
||||||
|
simpleIndicator.text('some test text');
|
||||||
|
expect(getTextElement().textContent.trim()).toEqual('some test text');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("sets the indicator's title", function () {
|
||||||
|
simpleIndicator.description('a test description');
|
||||||
|
expect(getIndicatorElement().getAttribute('title')).toEqual('a test description');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Hides indicator icon if no text is set", function () {
|
||||||
|
simpleIndicator.text('');
|
||||||
|
expect(getIndicatorElement().classList.contains('hidden')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
function getIconElement() {
|
||||||
|
return holderElement.querySelector('.ls-indicator');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getIndicatorElement() {
|
||||||
|
return holderElement.querySelector('.ls-indicator');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTextElement() {
|
||||||
|
return holderElement.querySelector('.indicator-text');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Supports registration of a completely custom indicator", function () {
|
||||||
|
var customIndicator = document.createElement('div');
|
||||||
|
customIndicator.classList.add('customIndicator');
|
||||||
|
customIndicator.textContent = 'A custom indicator';
|
||||||
|
|
||||||
|
openmct.indicators.add({element: customIndicator});
|
||||||
|
renderIndicators();
|
||||||
|
|
||||||
|
expect(holderElement.querySelector('.customIndicator').textContent.trim()).toEqual('A custom indicator');
|
||||||
|
});
|
||||||
|
|
||||||
|
function renderIndicators() {
|
||||||
|
directive.link({}, holderElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
96
src/api/indicators/SimpleIndicator.js
Normal file
96
src/api/indicators/SimpleIndicator.js
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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(['zepto', 'text!./res/indicator-template.html'],
|
||||||
|
function ($, indicatorTemplate) {
|
||||||
|
var DEFAULT_ICON_CLASS = 'icon-info';
|
||||||
|
|
||||||
|
function SimpleIndicator(openmct) {
|
||||||
|
this.openmct = openmct;
|
||||||
|
this.element = $(indicatorTemplate)[0];
|
||||||
|
|
||||||
|
this.textElement = this.element.querySelector('.indicator-text');
|
||||||
|
|
||||||
|
//Set defaults
|
||||||
|
this.text('New Indicator');
|
||||||
|
this.description('A simple indicator');
|
||||||
|
this.iconClass(DEFAULT_ICON_CLASS);
|
||||||
|
this.statusClass('');
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleIndicator.prototype.text = function (text) {
|
||||||
|
if (text !== undefined && text !== this.textValue) {
|
||||||
|
this.textValue = text;
|
||||||
|
this.textElement.innerText = text;
|
||||||
|
|
||||||
|
if (!text) {
|
||||||
|
this.element.classList.add('hidden');
|
||||||
|
} else {
|
||||||
|
this.element.classList.remove('hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.textValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
SimpleIndicator.prototype.description = function (description) {
|
||||||
|
if (description !== undefined && description !== this.descriptionValue) {
|
||||||
|
this.descriptionValue = description;
|
||||||
|
this.element.title = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.descriptionValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
SimpleIndicator.prototype.iconClass = function (iconClass) {
|
||||||
|
if (iconClass !== undefined && iconClass !== this.iconClassValue) {
|
||||||
|
// element.classList is precious and throws errors if you try and add
|
||||||
|
// or remove empty strings
|
||||||
|
if (this.iconClassValue) {
|
||||||
|
this.element.classList.remove(this.iconClassValue);
|
||||||
|
}
|
||||||
|
if (iconClass) {
|
||||||
|
this.element.classList.add(iconClass);
|
||||||
|
}
|
||||||
|
this.iconClassValue = iconClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.iconClassValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
SimpleIndicator.prototype.statusClass = function (statusClass) {
|
||||||
|
if (statusClass !== undefined && statusClass !== this.statusClassValue) {
|
||||||
|
if (this.statusClassValue) {
|
||||||
|
this.element.classList.remove(this.statusClassValue);
|
||||||
|
}
|
||||||
|
if (statusClass) {
|
||||||
|
this.element.classList.add(statusClass);
|
||||||
|
}
|
||||||
|
this.statusClassValue = statusClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.statusClassValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
return SimpleIndicator;
|
||||||
|
}
|
||||||
|
);
|
3
src/api/indicators/res/indicator-template.html
Normal file
3
src/api/indicators/res/indicator-template.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<div class="ls-indicator" title="">
|
||||||
|
<span class="label indicator-text"></span>
|
||||||
|
</div>
|
@ -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
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
* Administration. All rights reserved.
|
* Administration. All rights reserved.
|
||||||
*
|
*
|
||||||
@ -21,8 +21,8 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
define(
|
define(
|
||||||
[],
|
['zepto'],
|
||||||
function () {
|
function ($) {
|
||||||
|
|
||||||
// Set of connection states; changing among these states will be
|
// Set of connection states; changing among these states will be
|
||||||
// reflected in the indicator's appearance.
|
// reflected in the indicator's appearance.
|
||||||
@ -30,68 +30,78 @@ define(
|
|||||||
// DISCONNECTED: HTTP failed; maybe misconfigured, disconnected.
|
// DISCONNECTED: HTTP failed; maybe misconfigured, disconnected.
|
||||||
// PENDING: Still trying to connect, and haven't failed yet.
|
// PENDING: Still trying to connect, and haven't failed yet.
|
||||||
var CONNECTED = {
|
var CONNECTED = {
|
||||||
glyphClass: "ok"
|
statusClass: "s-status-ok"
|
||||||
},
|
},
|
||||||
PENDING = {
|
PENDING = {
|
||||||
glyphClass: 'caution'
|
statusClass: "s-status-warning-lo"
|
||||||
},
|
},
|
||||||
DISCONNECTED = {
|
DISCONNECTED = {
|
||||||
glyphClass: "err"
|
statusClass: "s-status-warning-hi"
|
||||||
};
|
};
|
||||||
function URLIndicator($http, $interval) {
|
function URLIndicator(options, simpleIndicator) {
|
||||||
var self = this;
|
this.bindMethods();
|
||||||
this.cssClass = this.options.cssClass ? this.options.cssClass : "icon-database";
|
this.count = 0;
|
||||||
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 handleError(e) {
|
this.indicator = simpleIndicator;
|
||||||
self.state = DISCONNECTED;
|
this.setDefaultsFromOptions(options);
|
||||||
}
|
this.setIndicatorToState(PENDING);
|
||||||
function handleResponse() {
|
|
||||||
self.state = CONNECTED;
|
this.fetchUrl();
|
||||||
}
|
setInterval(this.fetchUrl, this.interval);
|
||||||
function updateIndicator() {
|
|
||||||
$http.get(self.URLpath).then(handleResponse, handleError);
|
|
||||||
}
|
|
||||||
updateIndicator();
|
|
||||||
$interval(updateIndicator, self.interval, 0, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
URLIndicator.prototype.getCssClass = function () {
|
URLIndicator.prototype.setIndicatorToState = function (state) {
|
||||||
return this.cssClass;
|
switch (state) {
|
||||||
};
|
|
||||||
URLIndicator.prototype.getGlyphClass = function () {
|
|
||||||
return this.state.glyphClass;
|
|
||||||
};
|
|
||||||
URLIndicator.prototype.getText = function () {
|
|
||||||
switch (this.state) {
|
|
||||||
case CONNECTED: {
|
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: {
|
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: {
|
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) {
|
URLIndicator.prototype.fetchUrl = function () {
|
||||||
case CONNECTED: {
|
$.ajax({
|
||||||
return this.label + " is online, checking status every " +
|
type: 'GET',
|
||||||
this.interval + " milliseconds.";
|
url: this.URLpath,
|
||||||
}
|
success: this.handleSuccess,
|
||||||
case PENDING: {
|
error: this.handleError
|
||||||
return "Checking status of " + this.label + " please stand by...";
|
});
|
||||||
}
|
|
||||||
case DISCONNECTED: {
|
|
||||||
return this.label + " is offline, checking status every " +
|
|
||||||
this.interval + " milliseconds";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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-chain-links');
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
return URLIndicator;
|
||||||
});
|
});
|
||||||
|
@ -1,20 +1,35 @@
|
|||||||
define(
|
/*****************************************************************************
|
||||||
[
|
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||||
'./URLIndicator'
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
],
|
* Administration. All rights reserved.
|
||||||
function URLIndicatorPlugin(URLIndicator) {
|
*
|
||||||
return function (opts) {
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
// Wrap the plugin in a function so we can apply the arguments.
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
function URLIndicatorWrapper() {
|
* You may obtain a copy of the License at
|
||||||
this.options = opts;
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
URLIndicator.apply(this, arguments);
|
*
|
||||||
}
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
URLIndicatorWrapper.prototype = Object.create(URLIndicator.prototype);
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
return function install(openmct) {
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
openmct.legacyExtension('indicators', {
|
* License for the specific language governing permissions and limitations
|
||||||
"implementation": URLIndicatorWrapper,
|
* under the License.
|
||||||
"depends": ["$http", "$interval"]
|
*
|
||||||
});
|
* 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, 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
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
* Administration. All rights reserved.
|
* Administration. All rights reserved.
|
||||||
*
|
*
|
||||||
@ -21,137 +21,115 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
define(
|
define(
|
||||||
["./URLIndicator"],
|
[
|
||||||
function (URLIndicator) {
|
"./URLIndicator",
|
||||||
|
"./URLIndicatorPlugin",
|
||||||
|
"../../MCT",
|
||||||
|
"zepto"
|
||||||
|
],
|
||||||
|
function (
|
||||||
|
URLIndicator,
|
||||||
|
URLIndicatorPlugin,
|
||||||
|
MCT,
|
||||||
|
$
|
||||||
|
) {
|
||||||
|
var defaultAjaxFunction = $.ajax;
|
||||||
|
|
||||||
describe("The URLIndicator", function () {
|
describe("The URLIndicator", function () {
|
||||||
var mockHttp,
|
var openmct;
|
||||||
mockInterval,
|
var indicatorElement;
|
||||||
mockPromise,
|
var pluginOptions;
|
||||||
opts,
|
var ajaxOptions;
|
||||||
Indicator,
|
var urlIndicator;
|
||||||
indicatorWrapper;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
mockHttp = jasmine.createSpyObj("$http", ["get"]);
|
jasmine.clock().install();
|
||||||
mockInterval = jasmine.createSpy("$interval");
|
openmct = new MCT();
|
||||||
mockPromise = jasmine.createSpyObj("promise", ["then"]);
|
spyOn(openmct.indicators, 'add');
|
||||||
opts = {
|
spyOn($, 'ajax');
|
||||||
url: "http://localhost:8080",
|
$.ajax.and.callFake(function (options) {
|
||||||
interval: 1337 //some number
|
ajaxOptions = options;
|
||||||
};
|
});
|
||||||
mockHttp.get.and.returnValue(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
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("has a database cssClass as default", function () {
|
afterEach(function () {
|
||||||
expect(indicatorWrapper.getCssClass()).toEqual("icon-database");
|
$.ajax = defaultAjaxFunction;
|
||||||
|
jasmine.clock().uninstall();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("consults the url with the path supplied", function () {
|
describe("on initialization", function () {
|
||||||
expect(mockHttp.get).toHaveBeenCalledWith(opts.url);
|
describe("with default options", function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
pluginOptions = {
|
||||||
|
url: "someURL"
|
||||||
|
};
|
||||||
|
urlIndicator = URLIndicatorPlugin(pluginOptions)(openmct);
|
||||||
|
indicatorElement = openmct.indicators.add.calls.mostRecent().args[0].element;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("has a default icon class if none supplied", function () {
|
||||||
|
expect(indicatorElement.classList.contains('icon-chain-links')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("defaults to the URL if no label supplied", function () {
|
||||||
|
expect(indicatorElement.textContent.indexOf(pluginOptions.url) >= 0).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("with custom options", function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
pluginOptions = {
|
||||||
|
url: "customURL",
|
||||||
|
interval: 1814,
|
||||||
|
iconClass: "iconClass-checked",
|
||||||
|
label: "custom label"
|
||||||
|
};
|
||||||
|
urlIndicator = URLIndicatorPlugin(pluginOptions)(openmct);
|
||||||
|
indicatorElement = openmct.indicators.add.calls.mostRecent().args[0].element;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("uses the custom iconClass", function () {
|
||||||
|
expect(indicatorElement.classList.contains('iconClass-checked')).toBe(true);
|
||||||
|
});
|
||||||
|
it("uses custom interval", function () {
|
||||||
|
expect($.ajax.calls.count()).toEqual(1);
|
||||||
|
jasmine.clock().tick(1);
|
||||||
|
expect($.ajax.calls.count()).toEqual(1);
|
||||||
|
jasmine.clock().tick(pluginOptions.interval + 1);
|
||||||
|
expect($.ajax.calls.count()).toEqual(2);
|
||||||
|
});
|
||||||
|
it("uses custom label if supplied in initialization", function () {
|
||||||
|
expect(indicatorElement.textContent.indexOf(pluginOptions.label) >= 0).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("changes when the database connection is nominal", function () {
|
describe("when running", function () {
|
||||||
var initialText = indicatorWrapper.getText(),
|
beforeEach(function () {
|
||||||
initialDescrption = indicatorWrapper.getDescription(),
|
pluginOptions = {
|
||||||
initialGlyphClass = indicatorWrapper.getGlyphClass();
|
url: "someURL",
|
||||||
|
interval: 100
|
||||||
|
};
|
||||||
|
urlIndicator = URLIndicatorPlugin(pluginOptions)(openmct);
|
||||||
|
indicatorElement = openmct.indicators.add.calls.mostRecent().args[0].element;
|
||||||
|
});
|
||||||
|
|
||||||
// Nominal just means getting back an object, without
|
it("requests the provided URL", function () {
|
||||||
// an error field.
|
jasmine.clock().tick(pluginOptions.interval + 1);
|
||||||
mockPromise.then.calls.mostRecent().args[0]({ data: {} });
|
expect(ajaxOptions.url).toEqual(pluginOptions.url);
|
||||||
|
});
|
||||||
|
|
||||||
// Verify that these values changed;
|
it("indicates success if connection is nominal", function () {
|
||||||
// don't test for specific text.
|
jasmine.clock().tick(pluginOptions.interval + 1);
|
||||||
expect(indicatorWrapper.getText()).not.toEqual(initialText);
|
ajaxOptions.success();
|
||||||
expect(indicatorWrapper.getGlyphClass()).not.toEqual(initialGlyphClass);
|
expect(indicatorElement.classList.contains('s-status-ok')).toBe(true);
|
||||||
expect(indicatorWrapper.getDescription()).not.toEqual(initialDescrption);
|
});
|
||||||
|
|
||||||
// Do check for specific class
|
it("indicates an error when the server cannot be reached", function () {
|
||||||
expect(indicatorWrapper.getGlyphClass()).toEqual("ok");
|
jasmine.clock().tick(pluginOptions.interval + 1);
|
||||||
});
|
ajaxOptions.error();
|
||||||
|
expect(indicatorElement.classList.contains('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();
|
|
||||||
|
|
||||||
// Nominal just means getting back an object, without
|
|
||||||
// an error field.
|
|
||||||
mockPromise.then.calls.mostRecent().args[1]({ data: {} });
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// 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
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ define([
|
|||||||
|
|
||||||
plugins.SummaryWidget = SummaryWidget;
|
plugins.SummaryWidget = SummaryWidget;
|
||||||
plugins.TelemetryMean = TelemetryMean;
|
plugins.TelemetryMean = TelemetryMean;
|
||||||
plugins.URLIndicatorPlugin = URLIndicatorPlugin;
|
plugins.URLIndicator = URLIndicatorPlugin;
|
||||||
|
|
||||||
return plugins;
|
return plugins;
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user