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:
committed by
Pete Richards
parent
8055e050b6
commit
3246480f82
@@ -34,7 +34,6 @@ define([
|
||||
"./src/controllers/ContextMenuController",
|
||||
"./src/controllers/ClickAwayController",
|
||||
"./src/controllers/ViewSwitcherController",
|
||||
"./src/controllers/BottomBarController",
|
||||
"./src/controllers/GetterSetterController",
|
||||
"./src/controllers/SelectorController",
|
||||
"./src/controllers/ObjectInspectorController",
|
||||
@@ -49,13 +48,14 @@ define([
|
||||
"./src/directives/MCTSplitPane",
|
||||
"./src/directives/MCTSplitter",
|
||||
"./src/directives/MCTTree",
|
||||
"./src/directives/MCTIndicators",
|
||||
"./src/directives/MCTPreview",
|
||||
"./src/actions/MCTPreviewAction",
|
||||
"./src/filters/ReverseFilter",
|
||||
"text!./res/templates/bottombar.html",
|
||||
"text!./res/templates/controls/action-button.html",
|
||||
"text!./res/templates/controls/input-filter.html",
|
||||
"text!./res/templates/indicator.html",
|
||||
"text!./res/templates/angular-indicator.html",
|
||||
"text!./res/templates/message-banner.html",
|
||||
"text!./res/templates/progress-bar.html",
|
||||
"text!./res/templates/controls/time-controller.html",
|
||||
@@ -87,7 +87,6 @@ define([
|
||||
ContextMenuController,
|
||||
ClickAwayController,
|
||||
ViewSwitcherController,
|
||||
BottomBarController,
|
||||
GetterSetterController,
|
||||
SelectorController,
|
||||
ObjectInspectorController,
|
||||
@@ -102,6 +101,7 @@ define([
|
||||
MCTSplitPane,
|
||||
MCTSplitter,
|
||||
MCTTree,
|
||||
MCTIndicators,
|
||||
MCTPreview,
|
||||
MCTPreviewAction,
|
||||
ReverseFilter,
|
||||
@@ -281,13 +281,6 @@ define([
|
||||
"$timeout"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "BottomBarController",
|
||||
"implementation": BottomBarController,
|
||||
"depends": [
|
||||
"indicators[]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "GetterSetterController",
|
||||
"implementation": GetterSetterController,
|
||||
@@ -403,6 +396,11 @@ define([
|
||||
"implementation": MCTTree,
|
||||
"depends": ['gestureService', 'openmct']
|
||||
},
|
||||
{
|
||||
"key": "mctIndicators",
|
||||
"implementation": MCTIndicators,
|
||||
"depends": ['openmct']
|
||||
},
|
||||
{
|
||||
"key": "mctPreview",
|
||||
"implementation": MCTPreview,
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
@import "controls/lists";
|
||||
@import "controls/menus";
|
||||
@import "controls/messages";
|
||||
@import "controls/indicators";
|
||||
@import "mobile/controls/menus";
|
||||
|
||||
/********************************* FORMS */
|
||||
|
||||
@@ -20,66 +20,120 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*************************************************** MIXINS */
|
||||
@mixin formulateStatusColors($c) {
|
||||
@mixin elementStatusColors($c) {
|
||||
// Sets bg and icon colors for elements
|
||||
background: rgba($c, 0.4) !important;
|
||||
&:before { color: $c !important; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************** 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);
|
||||
background: rgba($c, 0.5) !important;
|
||||
&:before {
|
||||
content:'';
|
||||
font-family: symbolsfont;
|
||||
font-size: 0.8em;
|
||||
margin-right: $interiorMarginSm;
|
||||
color: $c !important;
|
||||
}
|
||||
}
|
||||
|
||||
@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 */
|
||||
.s-limit-yellow, .s-limit-yellow-icon {
|
||||
@include formulateStatusColors($colorWarningLo);
|
||||
[class*='s-limit'] {
|
||||
&[class*='icon-'] {
|
||||
&:before {
|
||||
margin-right: $interiorMargin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.s-limit-red, .s-limit-red-icon {
|
||||
@include formulateStatusColors($colorWarningHi);
|
||||
.s-limit-yellow, .s-limit-icon-yellow {
|
||||
@include elementStatusColors($colorWarningLo);
|
||||
}
|
||||
|
||||
.s-limit-upr:before { content: $glyph-icon-arrow-double-up; }
|
||||
.s-limit-lwr:before { content: $glyph-icon-arrow-double-down; }
|
||||
.s-limit-yellow-icon:before,
|
||||
.s-limit-red-icon:before { content: $glyph-icon-alert-triangle; }
|
||||
.s-limit-red, .s-limit-icon-red {
|
||||
@include elementStatusColors($colorWarningHi);
|
||||
}
|
||||
|
||||
.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 */
|
||||
.s-status-warning-hi, .s-status-warning-hi-icon { @include formulateStatusColors($colorWarningHi); }
|
||||
.s-status-warning-lo, .s-status-warning-lo-icon { @include formulateStatusColors($colorWarningLo); }
|
||||
.s-status-diagnostic, .s-status-diagnostic-icon { @include formulateStatusColors($colorDiagnostic); }
|
||||
.s-status-info, .s-status-info-icon { @include formulateStatusColors($colorInfo); }
|
||||
.s-status-ok, .s-status-ok-icon { @include formulateStatusColors($colorOk); }
|
||||
[class*='s-status'] {
|
||||
&[class*='icon-'] {
|
||||
&:before {
|
||||
margin-right: $interiorMargin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.s-status-warning-hi-icon:before { content: $glyph-icon-alert-triangle; }
|
||||
.s-status-warning-lo-icon:before { content: $glyph-icon-alert-rect; }
|
||||
.s-status-diagnostic-icon:before { content: $glyph-icon-eye-open; }
|
||||
.s-status-info-icon:before { content: $glyph-icon-info; }
|
||||
.s-status-ok-icon:before { content: $glyph-icon-check; }
|
||||
.s-status-warning-hi, .s-status-icon-warning-hi { @include elementStatusColors($colorWarningHi); }
|
||||
.s-status-warning-lo, .s-status-icon-warning-lo { @include elementStatusColors($colorWarningLo); }
|
||||
.s-status-diagnostic, .s-status-icon-diagnostic { @include elementStatusColors($colorDiagnostic); }
|
||||
.s-status-info, .s-status-icon-info { @include elementStatusColors($colorInfo); }
|
||||
.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
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/******************************************************************* STATUS BLOCK ELEMS */
|
||||
|
||||
@mixin statusBannerColors($bg, $fg: $colorStatusFg) {
|
||||
$bgPb: 30%;
|
||||
$bgPb: 10%;
|
||||
$bgPbD: 10%;
|
||||
background-color: darken($bg, $bgPb);
|
||||
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 {
|
||||
&.block {
|
||||
@@ -289,7 +185,6 @@
|
||||
|
||||
> div,
|
||||
> span {
|
||||
//@include test(red);
|
||||
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 {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
@@ -81,21 +93,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
.ue-bottom-bar {
|
||||
@include absPosDefault(0);// New status bar design
|
||||
.l-ue-bottom-bar {
|
||||
$m: $interiorMarginSm;
|
||||
@include absPosDefault(0, $overflow: visible);// New status bar design
|
||||
top: auto;
|
||||
height: $ueFooterH;
|
||||
line-height: $ueFooterH - ($interiorMargin * 2);
|
||||
background: $colorStatusBarBg;
|
||||
color: lighten($colorBodyBg, 30%);
|
||||
font-size: .7rem;
|
||||
line-height: $ueFooterH - ($m * 2);
|
||||
.status-holder {
|
||||
box-sizing: border-box;
|
||||
@include absPosDefault($interiorMargin);
|
||||
@include ellipsize();
|
||||
@include absPosDefault($m, $overflow: visible);
|
||||
right: 120px;
|
||||
text-transform: uppercase;
|
||||
z-index: 1;
|
||||
z-index: 10;
|
||||
}
|
||||
.app-logo {
|
||||
background-position: right center;
|
||||
|
||||
@@ -20,14 +20,8 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
|
||||
<div class='status block'
|
||||
<div class="ls-indicator {{ngModel.getCssClass()}}"
|
||||
title="{{ngModel.getDescription()}}"
|
||||
ng-click='ngModel.configure()'
|
||||
ng-show="ngModel.getText().length > 0">
|
||||
<span class="status-indicator {{ngModel.getCssClass()}}"></span><span class="label"
|
||||
ng-class='ngModel.getTextClass()'>
|
||||
{{ngModel.getText()}}
|
||||
<a class="s-button icon-gear" ng-if="ngModel.configure"></a>
|
||||
</span><span class="count">
|
||||
</span>
|
||||
<span class="label">{{ngModel.getText()}}</span>
|
||||
</div>
|
||||
@@ -19,14 +19,9 @@
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<div class='abs bottom-bar ue-bottom-bar mobile-disable-select' ng-controller="BottomBarController as bar">
|
||||
<div class='abs bottom-bar l-ue-bottom-bar s-ue-bottom-bar mobile-disable-select'>
|
||||
<div id='status' class='status-holder'>
|
||||
<mct-include ng-repeat="indicator in bar.getIndicators()"
|
||||
ng-model="indicator.ngModel"
|
||||
key="indicator.template"
|
||||
class="status-block-holder"
|
||||
ng-class='indicator.ngModel.getGlyphClass()'>
|
||||
</mct-include>
|
||||
<mct-indicators></mct-indicators>
|
||||
</div>
|
||||
<mct-include key="'message-banner'"></mct-include>
|
||||
<mct-include key="'about-logo'"></mct-include>
|
||||
|
||||
@@ -23,37 +23,18 @@
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
|
||||
/**
|
||||
* Controller for the bottombar template. Exposes
|
||||
* available indicators (of extension category "indicators")
|
||||
* @memberof platform/commonUI/general
|
||||
* @constructor
|
||||
*/
|
||||
function BottomBarController(indicators) {
|
||||
// Utility function used to make indicators presentable
|
||||
// for display.
|
||||
function present(Indicator) {
|
||||
return {
|
||||
template: Indicator.template || "indicator",
|
||||
ngModel: typeof Indicator === 'function' ?
|
||||
new Indicator() : Indicator
|
||||
};
|
||||
}
|
||||
|
||||
this.indicators = indicators.map(present);
|
||||
function MCTIndicators(openmct) {
|
||||
return {
|
||||
restrict: "E",
|
||||
link: function link(scope, element) {
|
||||
openmct.indicators.indicatorElements
|
||||
.forEach(function (indicatorElement) {
|
||||
element.append(indicatorElement);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all indicators to display.
|
||||
* @returns {Indicator[]} all indicators
|
||||
* to display in the bottom bar.
|
||||
* @memberof platform/commonUI/general.BottomBarController#
|
||||
*/
|
||||
BottomBarController.prototype.getIndicators = function () {
|
||||
return this.indicators;
|
||||
};
|
||||
|
||||
return BottomBarController;
|
||||
return MCTIndicators;
|
||||
}
|
||||
);
|
||||
@@ -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!! -->
|
||||
<a ng-click="showNotificationsList()" ng-show="notifications.length > 0" class="status block"
|
||||
ng-class="highest.severity"
|
||||
<div ng-show="notifications.length > 0" class="ls-indicator s-status-{{highest.severity}} icon-bell"
|
||||
ng-controller="NotificationIndicatorController">
|
||||
<span class="status-indicator icon-bell"></span><span class="label">
|
||||
{{notifications.length}} Notifications
|
||||
<span class="label">
|
||||
<a ng-click="showNotificationsList()">
|
||||
{{notifications.length}} Notification<span ng-show="notifications.length > 1">s</span></a>
|
||||
</span><span class="count">{{notifications.length}}</span>
|
||||
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,8 @@ $colorBodyBg: #333;
|
||||
$colorBodyFg: #999;
|
||||
$colorGenBg: #222;
|
||||
$colorStatusBarBg: #000;
|
||||
$colorStatusBarFg: #999;
|
||||
$colorStatusBarFgHov: #aaa;
|
||||
$colorKey: #0099cc;
|
||||
$colorKeySelectedBg: #005177;
|
||||
$colorKeyFg: #fff;
|
||||
@@ -55,7 +57,7 @@ $colorTransLucBg: #666; // Used as a visual blocking element over variable backg
|
||||
|
||||
// Foundation Colors
|
||||
$colorAlt1: #ffc700;
|
||||
$colorAlert: #ff3c00;
|
||||
$colorAlert: #ff9900;
|
||||
$colorWarningHi: #cc0000;
|
||||
$colorWarningLo: #ff9900;
|
||||
$colorDiagnostic: #a4b442;
|
||||
@@ -72,7 +74,6 @@ $colorObjHdrTxt: $colorBodyFg;
|
||||
$colorObjHdrIc: lighten($colorObjHdrTxt, 20%);
|
||||
$colorTick: rgba(white, 0.2);
|
||||
$colorSelectableSelectedPrimary: $colorKey;
|
||||
//$colorSelectableSelectedSecondary: pushBack($colorSelectableSelectedPrimary, 20%);
|
||||
$colorSelectableHov: rgba($colorBodyFg, 0.3);
|
||||
|
||||
// Menu colors
|
||||
@@ -114,11 +115,10 @@ $colorInspectorSectionHeaderFg: pullForward($colorInspectorBg, 40%);
|
||||
|
||||
// Status colors, mainly used for messaging and item ancillary symbols
|
||||
$colorStatusFg: #ccc;
|
||||
$colorStatusDefault: #ccc;
|
||||
$colorStatusDefault: #999;
|
||||
$colorStatusInfo: $colorInfo;
|
||||
$colorStatusAlert: $colorAlert;
|
||||
$colorStatusError: #d4585c;
|
||||
$colorStatusAvailable: $colorKey;
|
||||
$colorStatusError: #da0004;
|
||||
$colorStatusBtnBg: $colorBtnBg;
|
||||
$colorProgressBarOuter: rgba(#000, 0.1);
|
||||
$colorProgressBarAmt: $colorKey;
|
||||
@@ -127,6 +127,12 @@ $progressBarStripeW: 20px;
|
||||
$shdwStatusIc: rgba(black, 0.4) 0 1px 2px;
|
||||
$animPausedPulseDur: 500ms;
|
||||
|
||||
// Indicator colors
|
||||
$colorIndicatorAvailable: $colorKey;
|
||||
$colorIndicatorDisabled: #444;
|
||||
$colorIndicatorOn: $colorOk;
|
||||
$colorIndicatorOff: #666;
|
||||
|
||||
// Selects
|
||||
$colorSelectBg: $colorBtnBg;
|
||||
$colorSelectFg: $colorBtnFg;
|
||||
|
||||
@@ -3,6 +3,8 @@ $colorBodyBg: #fcfcfc;
|
||||
$colorBodyFg: #666;
|
||||
$colorGenBg: #fff;
|
||||
$colorStatusBarBg: #000;
|
||||
$colorStatusBarFg: #999;
|
||||
$colorStatusBarFgHov: #aaa;
|
||||
$colorKey: #0099cc;
|
||||
$colorKeySelectedBg: $colorKey;
|
||||
$colorKeyFg: #fff;
|
||||
@@ -72,7 +74,6 @@ $colorObjHdrTxt: $colorBodyFg;
|
||||
$colorObjHdrIc: lighten($colorObjHdrTxt, 30%);
|
||||
$colorTick: rgba(black, 0.2);
|
||||
$colorSelectableSelectedPrimary: $colorKey;
|
||||
//$colorSelectableSelectedSecondary: pushBack($colorSelectableSelectedPrimary, 20%);
|
||||
$colorSelectableHov: rgba($colorBodyFg, 0.4);
|
||||
|
||||
// Menu colors
|
||||
@@ -117,8 +118,7 @@ $colorStatusFg: #999;
|
||||
$colorStatusDefault: #ccc;
|
||||
$colorStatusInfo: #60ba7b;
|
||||
$colorStatusAlert: #ffb66c;
|
||||
$colorStatusError: #c96b68;
|
||||
$colorStatusAvailable: $colorKey;
|
||||
$colorStatusError: #da0004;
|
||||
$colorStatusBtnBg: #666;
|
||||
$colorProgressBarOuter: rgba(#000, 0.1);
|
||||
$colorProgressBarAmt: #0a0;
|
||||
@@ -127,6 +127,12 @@ $progressBarStripeW: 20px;
|
||||
$shdwStatusIc: rgba(white, 0.8) 0 0px 5px;
|
||||
$animPausedPulseDur: 1s;
|
||||
|
||||
// Indicator colors
|
||||
$colorIndicatorAvailable: $colorKey;
|
||||
$colorIndicatorDisabled: #444;
|
||||
$colorIndicatorOn: $colorOk;
|
||||
$colorIndicatorOff: #666;
|
||||
|
||||
// Selects
|
||||
$colorSelectBg: $colorBtnBg;
|
||||
$colorSelectFg: $colorBtnFg;
|
||||
|
||||
@@ -55,7 +55,6 @@ define([
|
||||
timerTemplate,
|
||||
legacyRegistry
|
||||
) {
|
||||
|
||||
legacyRegistry.register("platform/features/clock", {
|
||||
"name": "Clocks/Timers",
|
||||
"descriptions": "Domain objects for displaying current & relative times.",
|
||||
@@ -86,11 +85,6 @@ define([
|
||||
"CLOCK_INDICATOR_FORMAT"
|
||||
],
|
||||
"priority": "preferred"
|
||||
},
|
||||
{
|
||||
"implementation": FollowIndicator,
|
||||
"depends": ["timerService"],
|
||||
"priority": "fallback"
|
||||
}
|
||||
],
|
||||
"services": [
|
||||
@@ -305,6 +299,10 @@ define([
|
||||
}
|
||||
}
|
||||
],
|
||||
"runs": [{
|
||||
"implementation": FollowIndicator,
|
||||
"depends": ["openmct", "timerService"]
|
||||
}],
|
||||
"licenses": [
|
||||
{
|
||||
"name": "moment-duration-format",
|
||||
|
||||
@@ -45,11 +45,11 @@ define(
|
||||
}
|
||||
|
||||
ClockIndicator.prototype.getGlyphClass = function () {
|
||||
return "no-collapse float-right subdued";
|
||||
return "";
|
||||
};
|
||||
|
||||
ClockIndicator.prototype.getCssClass = function () {
|
||||
return "icon-clock";
|
||||
return "t-indicator-clock icon-clock no-collapse float-right";
|
||||
};
|
||||
|
||||
ClockIndicator.prototype.getText = function () {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-2016, United States Government
|
||||
* Open MCT, Copyright (c) 2009-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
@@ -20,38 +20,32 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
['moment'],
|
||||
function (moment) {
|
||||
var NO_TIMER = "No timer being followed";
|
||||
define([], function () {
|
||||
|
||||
/**
|
||||
* Indicator that displays the active timer, as well as its
|
||||
* current state.
|
||||
* @implements {Indicator}
|
||||
* @memberof platform/features/clock
|
||||
*/
|
||||
function FollowIndicator(timerService) {
|
||||
this.timerService = timerService;
|
||||
/**
|
||||
* Indicator that displays the active timer, as well as its
|
||||
* current state.
|
||||
* @memberof platform/features/clock
|
||||
*/
|
||||
return function installFollowIndicator(openmct, timerService) {
|
||||
var indicator = openmct.indicators.simpleIndicator();
|
||||
var timer = timerService.getTimer();
|
||||
setIndicatorStatus(timer);
|
||||
|
||||
function setIndicatorStatus(newTimer) {
|
||||
if (newTimer !== undefined) {
|
||||
indicator.iconClass('icon-timer');
|
||||
indicator.statusClass('s-status-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 () {
|
||||
return "";
|
||||
};
|
||||
timerService.on('change', setIndicatorStatus);
|
||||
|
||||
FollowIndicator.prototype.getCssClass = function () {
|
||||
return (this.timerService.getTimer()) ? "icon-timer s-status-ok" : "icon-timer";
|
||||
};
|
||||
|
||||
FollowIndicator.prototype.getText = function () {
|
||||
var timer = this.timerService.getTimer();
|
||||
return timer ? ('Following timer ' + timer.name) : NO_TIMER;
|
||||
};
|
||||
|
||||
FollowIndicator.prototype.getDescription = function () {
|
||||
return "";
|
||||
};
|
||||
|
||||
return FollowIndicator;
|
||||
}
|
||||
);
|
||||
openmct.indicators.add(indicator);
|
||||
};
|
||||
});
|
||||
|
||||
@@ -44,7 +44,7 @@ define(['EventEmitter'], function (EventEmitter) {
|
||||
*/
|
||||
TimerService.prototype.setTimer = function (timer) {
|
||||
this.timer = timer;
|
||||
this.emit('change');
|
||||
this.emit('change', timer);
|
||||
|
||||
if (this.stopObserving) {
|
||||
this.stopObserving();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-2016, United States Government
|
||||
* Open MCT, Copyright (c) 2009-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
@@ -20,39 +20,77 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(["../../src/indicators/FollowIndicator"], function (FollowIndicator) {
|
||||
var TIMER_SERVICE_METHODS =
|
||||
['setTimer', 'getTimer', 'clearTimer', 'on', 'off'];
|
||||
|
||||
define([
|
||||
"../../src/indicators/FollowIndicator",
|
||||
"../../src/services/TimerService",
|
||||
"../../../../../src/MCT",
|
||||
'zepto'
|
||||
], function (
|
||||
FollowIndicator,
|
||||
TimerService,
|
||||
MCT,
|
||||
$
|
||||
) {
|
||||
describe("The timer-following indicator", function () {
|
||||
var mockTimerService;
|
||||
var indicator;
|
||||
var timerService;
|
||||
var openmct;
|
||||
|
||||
beforeEach(function () {
|
||||
mockTimerService =
|
||||
jasmine.createSpyObj('timerService', TIMER_SERVICE_METHODS);
|
||||
indicator = new FollowIndicator(mockTimerService);
|
||||
openmct = new MCT();
|
||||
timerService = new TimerService(openmct);
|
||||
spyOn(openmct.indicators, "add");
|
||||
});
|
||||
|
||||
it("implements the Indicator interface", function () {
|
||||
expect(indicator.getGlyphClass()).toEqual(jasmine.any(String));
|
||||
expect(indicator.getCssClass()).toEqual(jasmine.any(String));
|
||||
expect(indicator.getText()).toEqual(jasmine.any(String));
|
||||
expect(indicator.getDescription()).toEqual(jasmine.any(String));
|
||||
it("adds an indicator when installed", function () {
|
||||
FollowIndicator(openmct, timerService);
|
||||
expect(openmct.indicators.add).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("indicates that no timer is being followed", function () {
|
||||
FollowIndicator(openmct, timerService);
|
||||
var simpleIndicator = openmct.indicators.add.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 () {
|
||||
var testObject;
|
||||
var simpleIndicator;
|
||||
|
||||
beforeEach(function () {
|
||||
testObject = { name: "some timer!" };
|
||||
mockTimerService.getTimer.and.returnValue(testObject);
|
||||
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 () {
|
||||
expect(indicator.getText().indexOf(testObject.name))
|
||||
.not.toEqual(-1);
|
||||
var element = simpleIndicator.element;
|
||||
var text = $('.indicator-text', element).text().trim();
|
||||
expect(text).toEqual('Following timer ' + testObject.name);
|
||||
});
|
||||
|
||||
it("displays the timer's name when it changes", function () {
|
||||
var secondTimer = {
|
||||
identifier: {
|
||||
namespace: 'namespace',
|
||||
key: 'key2'
|
||||
},
|
||||
name: "Some other timer"
|
||||
};
|
||||
var element = simpleIndicator.element;
|
||||
timerService.setTimer(secondTimer);
|
||||
var text = $('.indicator-text', element).text().trim();
|
||||
expect(text).toEqual('Following timer ' + secondTimer.name);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -33,20 +33,24 @@ define(
|
||||
var CONNECTED = {
|
||||
text: "Connected",
|
||||
glyphClass: "ok",
|
||||
statusClass: "s-status-ok",
|
||||
description: "Connected to the domain object database."
|
||||
},
|
||||
DISCONNECTED = {
|
||||
text: "Disconnected",
|
||||
glyphClass: "err",
|
||||
statusClass: "s-status-caution",
|
||||
description: "Unable to connect to the domain object database."
|
||||
},
|
||||
SEMICONNECTED = {
|
||||
text: "Unavailable",
|
||||
glyphClass: "caution",
|
||||
statusClass: "s-status-caution",
|
||||
description: "Database does not exist or is unavailable."
|
||||
},
|
||||
PENDING = {
|
||||
text: "Checking connection..."
|
||||
text: "Checking connection...",
|
||||
statusClass: "s-status-caution"
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -96,7 +100,7 @@ define(
|
||||
}
|
||||
|
||||
CouchIndicator.prototype.getCssClass = function () {
|
||||
return "icon-database";
|
||||
return "icon-database " + this.state.statusClass;
|
||||
};
|
||||
|
||||
CouchIndicator.prototype.getGlyphClass = function () {
|
||||
|
||||
@@ -57,7 +57,7 @@ define(
|
||||
});
|
||||
|
||||
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 () {
|
||||
|
||||
@@ -32,11 +32,13 @@ define(
|
||||
var CONNECTED = {
|
||||
text: "Connected",
|
||||
glyphClass: "ok",
|
||||
statusClass: "s-status-ok",
|
||||
description: "Connected to the domain object database."
|
||||
},
|
||||
DISCONNECTED = {
|
||||
text: "Disconnected",
|
||||
glyphClass: "err",
|
||||
statusClass: "s-status-caution",
|
||||
description: "Unable to connect to the domain object database."
|
||||
},
|
||||
PENDING = {
|
||||
|
||||
@@ -26,7 +26,7 @@ define(
|
||||
|
||||
var LOCAL_STORAGE_WARNING = [
|
||||
"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."
|
||||
].join(' ');
|
||||
|
||||
@@ -41,7 +41,7 @@ define(
|
||||
}
|
||||
|
||||
LocalStorageIndicator.prototype.getCssClass = function () {
|
||||
return "icon-database";
|
||||
return "icon-database s-status-caution";
|
||||
};
|
||||
LocalStorageIndicator.prototype.getGlyphClass = function () {
|
||||
return 'caution';
|
||||
|
||||
@@ -38,7 +38,7 @@ define(
|
||||
});
|
||||
|
||||
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 () {
|
||||
|
||||
Reference in New Issue
Block a user