mirror of
https://github.com/nasa/openmct.git
synced 2024-12-20 05:37:53 +00:00
Merge remote-tracking branch 'github/master' into open116
Merge in latest from master into topic branch for https://github.com/nasa/openmctweb/issues/116 Conflicts: platform/features/layout/test/FixedControllerSpec.js platform/features/plot/test/PlotControllerSpec.js
This commit is contained in:
commit
a49deb5ab1
@ -106,7 +106,7 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define
|
||||
}
|
||||
|
||||
// Convert from Github-flavored Markdown to HTML
|
||||
function gfmifier() {
|
||||
function gfmifier(renderTOC) {
|
||||
var transform = new stream.Transform({ objectMode: true }),
|
||||
markdown = "";
|
||||
transform._transform = function (chunk, encoding, done) {
|
||||
@ -114,9 +114,11 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define
|
||||
done();
|
||||
};
|
||||
transform._flush = function (done) {
|
||||
// Prepend table of contents
|
||||
markdown =
|
||||
[ TOC_HEAD, toc(markdown).content, "", markdown ].join("\n");
|
||||
if (renderTOC){
|
||||
// Prepend table of contents
|
||||
markdown =
|
||||
[ TOC_HEAD, toc(markdown).content, "", markdown ].join("\n");
|
||||
}
|
||||
this.push(header);
|
||||
this.push(marked(markdown));
|
||||
this.push(footer);
|
||||
@ -168,13 +170,16 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define
|
||||
var destination = file.replace(options['in'], options.out)
|
||||
.replace(/md$/, "html"),
|
||||
destPath = path.dirname(destination),
|
||||
prefix = path.basename(destination).replace(/\.html$/, "");
|
||||
prefix = path.basename(destination).replace(/\.html$/, ""),
|
||||
//Determine whether TOC should be rendered for this file based
|
||||
//on regex provided as command line option
|
||||
renderTOC = file.match(options['suppress-toc'] || "") === null;
|
||||
|
||||
mkdirp(destPath, function (err) {
|
||||
fs.createReadStream(file, { encoding: 'utf8' })
|
||||
.pipe(split())
|
||||
.pipe(nomnomlifier(destPath, prefix))
|
||||
.pipe(gfmifier())
|
||||
.pipe(gfmifier(renderTOC))
|
||||
.pipe(fs.createWriteStream(destination, {
|
||||
encoding: 'utf8'
|
||||
}));
|
||||
|
@ -1,38 +0,0 @@
|
||||
<!--
|
||||
Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
as represented by the Administrator of the National Aeronautics and Space
|
||||
Administration. All rights reserved.
|
||||
|
||||
Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
Open MCT Web includes source code licensed under additional open source
|
||||
licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title>Open MCT Web Documentation</title>
|
||||
</head>
|
||||
<body class="user-environ" ng-view>
|
||||
Sections:
|
||||
<ul>
|
||||
<li><a href="api/">API</a></li>
|
||||
<li><a href="architecture/">Architecture Overview</a></li>
|
||||
<li><a href="guide/">Developer Guide</a></li>
|
||||
<li><a href="tutorials/">Tutorials</a></li>
|
||||
<li><a href="process/">Development Process</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
35
docs/src/index.md
Normal file
35
docs/src/index.md
Normal file
@ -0,0 +1,35 @@
|
||||
# Open MCT Web Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
Documentation is provided to support the use and development of
|
||||
Open MCT Web. It's recommended that before doing
|
||||
any development with Open MCT Web you take some time to familiarize yourself
|
||||
with the documentation below.
|
||||
|
||||
Open MCT Web provides functionality out of the box, but it's also a platform for
|
||||
building rich mission operations applications based on modern web technology.
|
||||
The platform is configured declaratively, and defines conventions for
|
||||
building on the provided capabilities by creating modular 'bundles' that
|
||||
extend the platform at a variety of extension points. The details of how to
|
||||
extend the platform are provided in the following documentation.
|
||||
|
||||
## Sections
|
||||
|
||||
* The [Architecture Overview](architecture/) describes the concepts used
|
||||
throughout Open MCT Web, and gives a high level overview of the platform's design.
|
||||
|
||||
* The [Developer's Guide](guide/) goes into more detail about how to use the
|
||||
platform and the functionality that it provides.
|
||||
|
||||
* The [Tutorials](tutorials/) give examples of extending the platform to add
|
||||
functionality,
|
||||
and integrate with data sources.
|
||||
|
||||
* The [API](api/) document is generated from inline documentation
|
||||
using [JSDoc](http://usejsdoc.org/), and describes the JavaScript objects and
|
||||
functions that make up the software platform.
|
||||
|
||||
* Finally, the [Development Process](process/) document describes the
|
||||
Open MCT Web software development cycle.
|
||||
|
@ -31,7 +31,7 @@
|
||||
"jshint": "jshint platform example || exit 0",
|
||||
"watch": "karma start",
|
||||
"jsdoc": "jsdoc -c jsdoc.json -r -d target/docs/api",
|
||||
"otherdoc": "node docs/gendocs.js --in docs/src --out target/docs",
|
||||
"otherdoc": "node docs/gendocs.js --in docs/src --out target/docs --suppress-toc 'docs/src/index.md|docs/src/process/index.md'",
|
||||
"docs": "npm run jsdoc ; npm run otherdoc"
|
||||
},
|
||||
"repository": {
|
||||
|
@ -24,7 +24,9 @@
|
||||
<ul class="tree">
|
||||
<li ng-repeat="containedObject in composition">
|
||||
<span class="tree-item">
|
||||
<mct-representation key="'label'" mct-object="containedObject">
|
||||
<mct-representation key="'label'"
|
||||
mct-object="containedObject"
|
||||
class="rep-object-label">
|
||||
</mct-representation>
|
||||
</span>
|
||||
</li>
|
||||
|
@ -71,7 +71,7 @@ $itemPadLR: 5px;
|
||||
$treeVCW: 10px;
|
||||
$treeTypeIconH: 1.4em; // was 16px
|
||||
$treeTypeIconHPx: 16px;
|
||||
$treeTypeIconW: 20px;
|
||||
$treeTypeIconW: 18px;
|
||||
$treeContextTriggerW: 20px;
|
||||
// Tabular
|
||||
$tabularHeaderH: 22px; //18px
|
||||
|
@ -73,31 +73,34 @@
|
||||
}
|
||||
|
||||
.l-icon-alert {
|
||||
display: none !important; // Remove this when alerts are enabled
|
||||
display: none !important;
|
||||
&:before {
|
||||
color: $colorAlert;
|
||||
content: "!";
|
||||
}
|
||||
}
|
||||
|
||||
// NEW!!
|
||||
.t-item-icon {
|
||||
// Used in grid-item.html, tree-item, inspector location, more?
|
||||
@extend .ui-symbol;
|
||||
@extend .icon;
|
||||
display: inline-block;
|
||||
line-height: normal; // This is Ok for the symbolsfont
|
||||
position: relative;
|
||||
.t-item-icon-glyph {
|
||||
position: absolute;
|
||||
}
|
||||
&.l-icon-link {
|
||||
&:before {
|
||||
color: $colorIconLink;
|
||||
content: "\f4";
|
||||
height: auto; width: auto;
|
||||
position: absolute;
|
||||
left: 0; top: 0; right: 0; bottom: 10%;
|
||||
@include transform-origin(bottom, left);
|
||||
@include transform(scale(0.3));
|
||||
z-index: 2;
|
||||
.t-item-icon-glyph {
|
||||
&:before {
|
||||
color: $colorIconLink;
|
||||
content: "\f4";
|
||||
height: auto; width: auto;
|
||||
position: absolute;
|
||||
left: 0; top: 0; right: 0; bottom: 10%;
|
||||
@include transform-origin(bottom, left);
|
||||
@include transform(scale(0.3));
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -84,12 +84,20 @@
|
||||
}
|
||||
|
||||
.inspector-location {
|
||||
//line-height: 180%;
|
||||
.location-item {
|
||||
$h: 1.2em;
|
||||
@include box-sizing(border-box);
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
line-height: $h;
|
||||
position: relative;
|
||||
padding: 2px 4px;
|
||||
.t-object-label {
|
||||
.t-item-icon {
|
||||
height: $h;
|
||||
width: 0.7rem;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background: $colorItemTreeHoverBg;
|
||||
color: $colorItemTreeHoverFg;
|
||||
@ -104,6 +112,7 @@
|
||||
display: inline-block;
|
||||
font-family: symbolsfont;
|
||||
font-size: 8px;
|
||||
font-style: normal !important;
|
||||
line-height: inherit;
|
||||
margin-left: $interiorMarginSm;
|
||||
width: 4px;
|
||||
|
@ -60,6 +60,7 @@
|
||||
@import "overlay/overlay";
|
||||
@import "mobile/overlay/overlay";
|
||||
@import "tree/tree";
|
||||
@import "object-label";
|
||||
@import "mobile/tree";
|
||||
@import "user-environ/frame";
|
||||
@import "user-environ/top-bar";
|
||||
|
@ -300,7 +300,7 @@
|
||||
@include desktop {
|
||||
@if $bgHov != none {
|
||||
&:not(.disabled):hover {
|
||||
background: $bgHov;
|
||||
@include background-image($bgHov);
|
||||
>.icon {
|
||||
color: lighten($ic, $ltGamma);
|
||||
}
|
||||
|
69
platform/commonUI/general/res/sass/_object-label.scss
Normal file
69
platform/commonUI/general/res/sass/_object-label.scss
Normal file
@ -0,0 +1,69 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
// mct-representation surrounding an object-label key="'label'"
|
||||
.rep-object-label {
|
||||
@include flex-direction(row);
|
||||
@include flex(1 1 auto);
|
||||
height: inherit;
|
||||
line-height: inherit;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.t-object-label {
|
||||
.t-item-icon {
|
||||
margin-right: $interiorMargin;
|
||||
}
|
||||
}
|
||||
|
||||
mct-representation {
|
||||
&.s-status-pending {
|
||||
.t-object-label {
|
||||
.t-item-icon {
|
||||
&:before {
|
||||
$spinBW: 4px;
|
||||
$spinD: 0;
|
||||
@include spinner($spinBW);
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
padding: 30%;
|
||||
width: $spinD;
|
||||
height: $spinD;
|
||||
}
|
||||
.t-item-icon-glyph {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.t-title-label {
|
||||
font-style: italic;
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.selected mct-representation.s-status-pending .t-object-label .t-item-icon:before {
|
||||
border-color: rgba($colorItemTreeSelectedFg, 0.25);
|
||||
border-top-color: rgba($colorItemTreeSelectedFg, 1.0);
|
||||
}
|
@ -37,6 +37,8 @@
|
||||
}
|
||||
|
||||
.status.block {
|
||||
$transDelay: 1.5s;
|
||||
$transSpeed: .25s;
|
||||
color: $colorStatusDefault;
|
||||
cursor: default;
|
||||
display: inline-block;
|
||||
@ -44,13 +46,47 @@
|
||||
.status-indicator,
|
||||
.label,
|
||||
.count {
|
||||
//@include test(#00ff00);
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
&.no-icon {
|
||||
.status-indicator {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.float-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
&.subtle {
|
||||
opacity: 0.5;
|
||||
}
|
||||
.status-indicator {
|
||||
margin-right: $interiorMarginSm;
|
||||
}
|
||||
|
||||
&:not(.no-collapse) {
|
||||
.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: 450px;
|
||||
width: auto;
|
||||
}
|
||||
.count {
|
||||
@include trans-prop-nice(max-width, $transSpeed, 0s);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.ok .status-indicator,
|
||||
&.info .status-indicator {
|
||||
color: $colorStatusInfo;
|
||||
@ -63,26 +99,11 @@
|
||||
&.error .status-indicator {
|
||||
color: $colorStatusError;
|
||||
}
|
||||
.label {
|
||||
// Max-width silliness is necessary for width transition
|
||||
@include trans-prop-nice(max-width, .25s);
|
||||
overflow: hidden;
|
||||
max-width: 0px;
|
||||
}
|
||||
.count {
|
||||
@include trans-prop-nice(opacity, .25s);
|
||||
@include trans-prop-nice(opacity, $transSpeed, $transDelay);
|
||||
font-weight: bold;
|
||||
opacity: 1;
|
||||
}
|
||||
&:hover {
|
||||
.label {
|
||||
max-width: 450px;
|
||||
width: auto;
|
||||
}
|
||||
.count {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Styles for messages and message banners */
|
||||
|
@ -24,21 +24,27 @@
|
||||
100% { transform: rotate(359deg); }
|
||||
}
|
||||
|
||||
@mixin wait-spinner2($b: 5px, $c: $colorAlt1) {
|
||||
@mixin spinner($b: 5px) {
|
||||
@include keyframes(rotateCentered) {
|
||||
0% { transform: translateX(-50%) translateY(-50%) rotate(0deg); }
|
||||
100% { transform: translateX(-50%) translateY(-50%) rotate(359deg); }
|
||||
}
|
||||
0% { @include transform(translateX(-50%) translateY(-50%) rotate(0deg)); }
|
||||
100% { @include transform(translateX(-50%) translateY(-50%) rotate(359deg)); }
|
||||
}
|
||||
@include animation-name(rotateCentered);
|
||||
@include animation-duration(0.5s);
|
||||
@include animation-iteration-count(infinite);
|
||||
@include animation-timing-function(linear);
|
||||
@include transform-origin(center);
|
||||
border-style: solid;
|
||||
border-width: $b;
|
||||
@include border-radius(100%);
|
||||
}
|
||||
|
||||
|
||||
@mixin wait-spinner2($b: 5px, $c: $colorAlt1) {
|
||||
@include spinner($b);
|
||||
@include box-sizing(border-box);
|
||||
border-color: rgba($c, 0.25);
|
||||
border-top-color: rgba($c, 1.0);
|
||||
border-style: solid;
|
||||
border-width: 5px;
|
||||
@include border-radius(100%);
|
||||
@include box-sizing(border-box);
|
||||
display: block;
|
||||
position: absolute;
|
||||
height: 0; width: 0;
|
||||
|
@ -31,7 +31,7 @@ $tabletItemH: floor($ueBrowseGridItemLg/3);
|
||||
|
||||
/************************** MOBILE TREE MENU DIMENSIONS */
|
||||
$mobileTreeItemH: 35px;
|
||||
$mobileTreeItemIndent: 20px;
|
||||
$mobileTreeItemIndent: 15px;
|
||||
$mobileTreeRightArrowW: 30px;
|
||||
|
||||
/************************** DEVICE WIDTHS */
|
||||
|
@ -30,25 +30,30 @@
|
||||
}
|
||||
.tree-item,
|
||||
.search-result-item {
|
||||
height: $mobileTreeItemH;
|
||||
line-height: $mobileTreeItemH;
|
||||
margin-bottom: 0px;
|
||||
height: $mobileTreeItemH !important;
|
||||
line-height: $mobileTreeItemH !important;
|
||||
margin-bottom: 0px !important;
|
||||
.view-control {
|
||||
//@include test(red);
|
||||
position: absolute;
|
||||
font-size: 1.1em;
|
||||
height: $mobileTreeItemH;
|
||||
line-height: inherit;
|
||||
right: 0px;
|
||||
width: $mobileTreeRightArrowW;
|
||||
text-align: center;
|
||||
font-size: 1.2em;
|
||||
margin-right: 0;
|
||||
order: 2;
|
||||
width: $mobileTreeItemH;
|
||||
&.has-children {
|
||||
&:before {
|
||||
content: "\7d";
|
||||
left: 50%;
|
||||
@include transform(translateX(-50%) rotate(90deg));
|
||||
}
|
||||
&.expanded:before {
|
||||
@include transform(translateX(-50%) rotate(270deg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.label,
|
||||
.t-object-label {
|
||||
left: 0;
|
||||
right: $mobileTreeRightArrowW + $interiorMargin; // Allows tree item name to stop prior to the arrow
|
||||
line-height: inherit;
|
||||
.t-item-icon.l-icon-link .t-item-icon-glyph:before {
|
||||
bottom: 20%; // Shift up due to height of mobile menu items
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
@include phone {
|
||||
.search {
|
||||
.search-holder {
|
||||
.search-bar {
|
||||
// Hide menu-icon and adjust spacing when in phone mode
|
||||
.menu-icon {
|
||||
|
@ -82,6 +82,7 @@
|
||||
left: $interiorMarginSm;
|
||||
@include trans-prop-nice(color, 250ms);
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
// Make icon lighten when hovering over search bar
|
||||
@ -127,7 +128,7 @@
|
||||
}
|
||||
|
||||
.active-filter-display {
|
||||
$s: 0.65em;
|
||||
$s: 0.7em;
|
||||
$p: $interiorMargin;
|
||||
@include box-sizing(border-box);
|
||||
line-height: 130%;
|
||||
@ -146,7 +147,6 @@
|
||||
|
||||
.search-results {
|
||||
@include trans-prop-nice((opacity, visibility), 250ms);
|
||||
margin-top: $interiorMarginLg; // Always include margin here to fend off the search input
|
||||
padding-right: $interiorMargin;
|
||||
.hint {
|
||||
margin-bottom: $interiorMarginLg;
|
||||
|
@ -35,23 +35,35 @@ ul.tree {
|
||||
.tree-item,
|
||||
.search-result-item {
|
||||
$runningItemW: 0;
|
||||
@extend .l-flex-row;
|
||||
@include box-sizing(border-box);
|
||||
@include border-radius($basicCr);
|
||||
@include single-transition(background-color, 0.25s);
|
||||
display: block;
|
||||
font-size: 0.8rem;
|
||||
height: $menuLineH;
|
||||
line-height: $menuLineH;
|
||||
margin-bottom: $interiorMarginSm;
|
||||
padding: 0 $interiorMarginSm;
|
||||
position: relative;
|
||||
|
||||
.view-control {
|
||||
color: $colorItemTreeVC;
|
||||
display: inline-block;
|
||||
margin-left: $interiorMargin;
|
||||
font-size: 0.75em;
|
||||
font-size: 0.75em;
|
||||
margin-right: $interiorMargin;
|
||||
height: 100%;
|
||||
line-height: inherit;
|
||||
width: $treeVCW;
|
||||
$runningItemW: $interiorMargin + $treeVCW;
|
||||
&.has-children {
|
||||
&:before {
|
||||
position: absolute;
|
||||
@include trans-prop-nice(transform, 100ms);
|
||||
content: "\3e";
|
||||
@include transform-origin(center);
|
||||
}
|
||||
&.expanded:before {
|
||||
@include transform(rotate(90deg));
|
||||
}
|
||||
}
|
||||
@include desktop {
|
||||
&:hover {
|
||||
color: $colorItemTreeVCHover !important;
|
||||
@ -59,64 +71,17 @@ ul.tree {
|
||||
}
|
||||
}
|
||||
|
||||
.label,
|
||||
.t-object-label {
|
||||
display: block;
|
||||
@include absPosDefault();
|
||||
line-height: $menuLineH;
|
||||
|
||||
.t-item-icon {
|
||||
@include txtShdwSubtle($shdwItemTreeIcon);
|
||||
font-size: $treeTypeIconH;
|
||||
color: $colorItemTreeIcon;
|
||||
position: absolute;
|
||||
left: $interiorMargin;
|
||||
top: 50%;
|
||||
width: $treeTypeIconH;
|
||||
@include transform(translateY(-50%));
|
||||
width: $treeTypeIconW;
|
||||
}
|
||||
|
||||
.type-icon {
|
||||
//@include absPosDefault(0, false);
|
||||
$d: $treeTypeIconH;
|
||||
@include txtShdwSubtle($shdwItemTreeIcon);
|
||||
font-size: $treeTypeIconH;
|
||||
color: $colorItemTreeIcon;
|
||||
left: $interiorMargin;
|
||||
position: absolute;
|
||||
@include verticalCenterBlock($menuLineHPx, $treeTypeIconHPx);
|
||||
line-height: 100%;
|
||||
right: auto; width: $treeTypeIconH;
|
||||
|
||||
.icon {
|
||||
&.l-icon-link,
|
||||
&.l-icon-alert {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
}
|
||||
&.l-icon-alert {
|
||||
$d: 8px;
|
||||
@include ancillaryIcon($d, $colorAlert);
|
||||
top: 1px;
|
||||
right: -2px;
|
||||
}
|
||||
&.l-icon-link {
|
||||
$d: 8px;
|
||||
@include ancillaryIcon($d, $colorIconLink);
|
||||
left: -3px;
|
||||
bottom: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.title-label,
|
||||
.t-title-label {
|
||||
@include absPosDefault();
|
||||
display: block;
|
||||
left: $runningItemW + ($interiorMargin * 3);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
@include ellipsize();
|
||||
}
|
||||
}
|
||||
|
||||
&.selected {
|
||||
@ -126,12 +91,11 @@ ul.tree {
|
||||
color: $colorItemTreeSelectedVC;
|
||||
}
|
||||
.t-object-label .t-item-icon {
|
||||
color: $colorItemTreeSelectedFg; //$colorItemTreeIconHover;
|
||||
color: $colorItemTreeSelectedFg;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.selected) {
|
||||
// NOTE: [Mobile] Removed Hover on Mobile
|
||||
@include desktop {
|
||||
&:hover {
|
||||
background: $colorItemTreeHoverBg;
|
||||
@ -160,8 +124,28 @@ ul.tree {
|
||||
}
|
||||
}
|
||||
|
||||
.tree-item {
|
||||
.t-object-label {
|
||||
left: $interiorMargin + $treeVCW;
|
||||
}
|
||||
}
|
||||
mct-representation {
|
||||
&.s-status-pending {
|
||||
.t-object-label {
|
||||
.t-item-icon {
|
||||
&:before {
|
||||
$spinBW: 4px;
|
||||
@include spinner($spinBW);
|
||||
border-color: rgba($colorItemTreeIcon, 0.25);
|
||||
border-top-color: rgba($colorItemTreeIcon, 1.0);
|
||||
}
|
||||
.t-item-icon-glyph {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.t-title-label {
|
||||
font-style: italic;
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.selected mct-representation.s-status-pending .t-object-label .t-item-icon:before {
|
||||
border-color: rgba($colorItemTreeSelectedFg, 0.25);
|
||||
border-top-color: rgba($colorItemTreeSelectedFg, 1.0);
|
||||
}
|
||||
|
@ -20,7 +20,6 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
|
||||
<!--<div ng-init="reps = [1,2,3]"></div>-->
|
||||
<div class='status block'
|
||||
title="{{ngModel.getDescription()}}"
|
||||
ng-click='ngModel.configure()'
|
||||
|
@ -19,7 +19,9 @@
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<span class="t-object-label">
|
||||
<span class="t-item-icon" ng-class="{ 'l-icon-link':location.isLink() }">{{type.getGlyph()}}</span>
|
||||
<span class='t-title-label'>{{model.name}}</span>
|
||||
</span>
|
||||
<div class="t-object-label l-flex-row flex-elem grows">
|
||||
<div class="t-item-icon flex-elem" ng-class="{ 'l-icon-link':location.isLink() }">
|
||||
<div class="t-item-icon-glyph">{{type.getGlyph()}}</div>
|
||||
</div>
|
||||
<div class='t-title-label flex-elem grows'>{{model.name}}</div>
|
||||
</div>
|
||||
|
@ -41,7 +41,7 @@
|
||||
mct-object="parent"
|
||||
ng-model="ngModel"
|
||||
ng-click="ngModel.selectedObject = parent"
|
||||
class="location-item">
|
||||
class="location-item rep-object-label">
|
||||
</mct-representation>
|
||||
</span>
|
||||
</li>
|
||||
@ -54,7 +54,7 @@
|
||||
mct-object="parent"
|
||||
ng-model="ngModel"
|
||||
ng-click="ngModel.selectedObject = parent"
|
||||
class="location-item">
|
||||
class="location-item rep-object-label">
|
||||
</mct-representation>
|
||||
</span>
|
||||
</li>
|
||||
|
@ -26,41 +26,18 @@
|
||||
ng-class="{selected: treeNode.isSelected()}"
|
||||
>
|
||||
<span
|
||||
mct-device="desktop"
|
||||
class='ui-symbol view-control'
|
||||
class='ui-symbol view-control flex-elem'
|
||||
ng-class="{ 'has-children': model.composition !== undefined, expanded: toggle.isActive() }"
|
||||
ng-click="toggle.toggle(); treeNode.trackExpansion()"
|
||||
ng-if="model.composition !== undefined"
|
||||
>
|
||||
{{toggle.isActive() ? "v" : ">"}}
|
||||
</span>
|
||||
|
||||
<mct-representation
|
||||
mct-device="desktop"
|
||||
class="mobile-hide"
|
||||
class="rep-object-label"
|
||||
key="'label'"
|
||||
mct-object="domainObject"
|
||||
ng-click="treeNode.select()"
|
||||
>
|
||||
</mct-representation>
|
||||
<mct-representation
|
||||
mct-device="mobile"
|
||||
class="desktop-hide"
|
||||
key="'label'"
|
||||
mct-object="domainObject"
|
||||
ng-click="(model.composition === undefined) && treeNode.select();
|
||||
toggle.toggle();
|
||||
treeNode.trackExpansion();"
|
||||
>
|
||||
</mct-representation>
|
||||
|
||||
<span
|
||||
mct-device="mobile"
|
||||
class='ui-symbol view-control'
|
||||
ng-model="ngModel"
|
||||
ng-click="treeNode.select()"
|
||||
>
|
||||
}
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="tree-item-subtree"
|
||||
|
@ -13,6 +13,12 @@
|
||||
"implementation": "AgentService.js",
|
||||
"depends": [ "$window" ]
|
||||
}
|
||||
],
|
||||
"runs": [
|
||||
{
|
||||
"implementation": "DeviceClassifier.js",
|
||||
"depends": [ "agentService", "$document" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ define(
|
||||
this.userAgent = userAgent;
|
||||
this.mobileName = matches[0];
|
||||
this.$window = $window;
|
||||
this.touchEnabled = ($window.ontouchstart !== undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -92,6 +93,14 @@ define(
|
||||
return !this.isPortrait();
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the user's device supports a touch interface.
|
||||
* @returns {boolean} true if touch is supported
|
||||
*/
|
||||
AgentService.prototype.isTouch = function () {
|
||||
return this.touchEnabled;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the user agent matches a certain named device,
|
||||
* as indicated by checking for a case-insensitive substring
|
||||
|
59
platform/commonUI/mobile/src/DeviceClassifier.js
Normal file
59
platform/commonUI/mobile/src/DeviceClassifier.js
Normal file
@ -0,0 +1,59 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,Promise*/
|
||||
|
||||
define(
|
||||
['./DeviceMatchers'],
|
||||
function (DeviceMatchers) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Runs at application startup and adds a subset of the following
|
||||
* CSS classes to the body of the document, depending on device
|
||||
* attributes:
|
||||
*
|
||||
* * `mobile`: Phones or tablets.
|
||||
* * `phone`: Phones specifically.
|
||||
* * `tablet`: Tablets specifically.
|
||||
* * `desktop`: Non-mobile devices.
|
||||
* * `portrait`: Devices in a portrait-style orientation.
|
||||
* * `landscape`: Devices in a landscape-style orientation.
|
||||
* * `touch`: Device supports touch events.
|
||||
*
|
||||
* @param {platform/commonUI/mobile.AgentService} agentService
|
||||
* the service used to examine the user agent
|
||||
* @param $document Angular's jqLite-wrapped document element
|
||||
* @constructor
|
||||
*/
|
||||
function MobileClassifier(agentService, $document) {
|
||||
var body = $document.find('body');
|
||||
Object.keys(DeviceMatchers).forEach(function (key) {
|
||||
if (DeviceMatchers[key](agentService)) {
|
||||
body.addClass(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return MobileClassifier;
|
||||
|
||||
}
|
||||
);
|
60
platform/commonUI/mobile/src/DeviceMatchers.js
Normal file
60
platform/commonUI/mobile/src/DeviceMatchers.js
Normal file
@ -0,0 +1,60 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
define(function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* An object containing key-value pairs, where keys are symbolic of
|
||||
* device attributes, and values are functions that take the
|
||||
* `agentService` as inputs and return boolean values indicating
|
||||
* whether or not the current device has these attributes.
|
||||
*
|
||||
* For internal use by the mobile support bundle.
|
||||
*
|
||||
* @memberof platform/commonUI/mobile
|
||||
* @private
|
||||
*/
|
||||
return {
|
||||
mobile: function (agentService) {
|
||||
return agentService.isMobile();
|
||||
},
|
||||
phone: function (agentService) {
|
||||
return agentService.isPhone();
|
||||
},
|
||||
tablet: function (agentService) {
|
||||
return agentService.isTablet();
|
||||
},
|
||||
desktop: function (agentService) {
|
||||
return !agentService.isMobile();
|
||||
},
|
||||
portrait: function (agentService) {
|
||||
return agentService.isPortrait();
|
||||
},
|
||||
landscape: function (agentService) {
|
||||
return agentService.isLandscape();
|
||||
},
|
||||
touch: function (agentService) {
|
||||
return agentService.isTouch();
|
||||
}
|
||||
};
|
||||
});
|
@ -22,31 +22,10 @@
|
||||
/*global define,Promise*/
|
||||
|
||||
define(
|
||||
function () {
|
||||
['./DeviceMatchers'],
|
||||
function (DeviceMatchers) {
|
||||
'use strict';
|
||||
|
||||
var DEVICE_MATCHERS = {
|
||||
mobile: function (agentService) {
|
||||
return agentService.isMobile();
|
||||
},
|
||||
phone: function (agentService) {
|
||||
return agentService.isPhone();
|
||||
},
|
||||
tablet: function (agentService) {
|
||||
return agentService.isTablet();
|
||||
},
|
||||
desktop: function (agentService) {
|
||||
return !agentService.isMobile();
|
||||
},
|
||||
portrait: function (agentService) {
|
||||
return agentService.isPortrait();
|
||||
},
|
||||
landscape: function (agentService) {
|
||||
return agentService.isLandscape();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The `mct-device` directive, when applied as an attribute,
|
||||
* only includes the element when the device being used matches
|
||||
@ -68,6 +47,7 @@ define(
|
||||
* * `desktop`: Non-mobile devices.
|
||||
* * `portrait`: Devices in a portrait-style orientation.
|
||||
* * `landscape`: Devices in a landscape-style orientation.
|
||||
* * `touch`: Device supports touch events.
|
||||
*
|
||||
* @param {AgentService} agentService used to detect device type
|
||||
* based on information about the user agent
|
||||
@ -77,7 +57,7 @@ define(
|
||||
function deviceMatches(tokens) {
|
||||
tokens = tokens || "";
|
||||
return tokens.split(" ").every(function (token) {
|
||||
var fn = DEVICE_MATCHERS[token];
|
||||
var fn = DeviceMatchers[token];
|
||||
return fn && fn(agentService);
|
||||
});
|
||||
}
|
||||
|
@ -82,6 +82,15 @@ define(
|
||||
expect(agentService.isLandscape()).toBeFalsy();
|
||||
});
|
||||
|
||||
it("detects touch support", function () {
|
||||
testWindow.ontouchstart = null;
|
||||
expect(new AgentService(testWindow).isTouch())
|
||||
.toBe(true);
|
||||
delete testWindow.ontouchstart;
|
||||
expect(new AgentService(testWindow).isTouch())
|
||||
.toBe(false);
|
||||
});
|
||||
|
||||
it("allows for checking browser type", function () {
|
||||
testWindow.navigator.userAgent = "Chromezilla Safarifox";
|
||||
agentService = new AgentService(testWindow);
|
||||
|
112
platform/commonUI/mobile/test/DeviceClassifierSpec.js
Normal file
112
platform/commonUI/mobile/test/DeviceClassifierSpec.js
Normal file
@ -0,0 +1,112 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/
|
||||
|
||||
|
||||
define(
|
||||
["../src/DeviceClassifier", "../src/DeviceMatchers"],
|
||||
function (DeviceClassifier, DeviceMatchers) {
|
||||
"use strict";
|
||||
|
||||
var AGENT_SERVICE_METHODS = [
|
||||
'isMobile',
|
||||
'isPhone',
|
||||
'isTablet',
|
||||
'isPortrait',
|
||||
'isLandscape',
|
||||
'isTouch'
|
||||
],
|
||||
TEST_PERMUTATIONS = [
|
||||
[ 'isMobile', 'isPhone', 'isTouch', 'isPortrait' ],
|
||||
[ 'isMobile', 'isPhone', 'isTouch', 'isLandscape' ],
|
||||
[ 'isMobile', 'isTablet', 'isTouch', 'isPortrait' ],
|
||||
[ 'isMobile', 'isTablet', 'isTouch', 'isLandscape' ],
|
||||
[ 'isTouch' ],
|
||||
[]
|
||||
];
|
||||
|
||||
describe("DeviceClassifier", function () {
|
||||
var mockAgentService,
|
||||
mockDocument,
|
||||
mockBody;
|
||||
|
||||
beforeEach(function () {
|
||||
mockAgentService = jasmine.createSpyObj(
|
||||
'agentService',
|
||||
AGENT_SERVICE_METHODS
|
||||
);
|
||||
mockDocument = jasmine.createSpyObj(
|
||||
'$document',
|
||||
[ 'find' ]
|
||||
);
|
||||
mockBody = jasmine.createSpyObj(
|
||||
'body',
|
||||
[ 'addClass' ]
|
||||
);
|
||||
mockDocument.find.andCallFake(function (sel) {
|
||||
return sel === 'body' && mockBody;
|
||||
});
|
||||
AGENT_SERVICE_METHODS.forEach(function (m) {
|
||||
mockAgentService[m].andReturn(false);
|
||||
});
|
||||
});
|
||||
|
||||
TEST_PERMUTATIONS.forEach(function (trueMethods) {
|
||||
var summary = trueMethods.length === 0 ?
|
||||
"device has no detected characteristics" :
|
||||
"device " + (trueMethods.join(", "));
|
||||
|
||||
describe("when " + summary, function () {
|
||||
var classifier;
|
||||
|
||||
beforeEach(function () {
|
||||
trueMethods.forEach(function (m) {
|
||||
mockAgentService[m].andReturn(true);
|
||||
});
|
||||
classifier = new DeviceClassifier(
|
||||
mockAgentService,
|
||||
mockDocument
|
||||
);
|
||||
});
|
||||
|
||||
it("adds classes for matching, detected characteristics", function () {
|
||||
Object.keys(DeviceMatchers).filter(function (m) {
|
||||
return DeviceMatchers[m](mockAgentService);
|
||||
}).forEach(function (key) {
|
||||
expect(mockBody.addClass)
|
||||
.toHaveBeenCalledWith(key);
|
||||
});
|
||||
});
|
||||
|
||||
it("does not add classes for non-matching characteristics", function () {
|
||||
Object.keys(DeviceMatchers).filter(function (m) {
|
||||
return !DeviceMatchers[m](mockAgentService);
|
||||
}).forEach(function (key) {
|
||||
expect(mockBody.addClass)
|
||||
.not.toHaveBeenCalledWith(key);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
81
platform/commonUI/mobile/test/DeviceMatchersSpec.js
Normal file
81
platform/commonUI/mobile/test/DeviceMatchersSpec.js
Normal file
@ -0,0 +1,81 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/
|
||||
|
||||
|
||||
define(
|
||||
["../src/DeviceMatchers"],
|
||||
function (DeviceMatchers) {
|
||||
'use strict';
|
||||
|
||||
describe("DeviceMatchers", function () {
|
||||
var mockAgentService;
|
||||
|
||||
beforeEach(function () {
|
||||
mockAgentService = jasmine.createSpyObj(
|
||||
'agentService',
|
||||
[
|
||||
'isMobile',
|
||||
'isPhone',
|
||||
'isTablet',
|
||||
'isPortrait',
|
||||
'isLandscape',
|
||||
'isTouch'
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
it("detects when a device is a desktop device", function () {
|
||||
mockAgentService.isMobile.andReturn(false);
|
||||
expect(DeviceMatchers.desktop(mockAgentService))
|
||||
.toBe(true);
|
||||
mockAgentService.isMobile.andReturn(true);
|
||||
expect(DeviceMatchers.desktop(mockAgentService))
|
||||
.toBe(false);
|
||||
});
|
||||
|
||||
function method(deviceType) {
|
||||
return "is" + deviceType[0].toUpperCase() + deviceType.slice(1);
|
||||
}
|
||||
|
||||
[
|
||||
"mobile",
|
||||
"phone",
|
||||
"tablet",
|
||||
"landscape",
|
||||
"portrait",
|
||||
"landscape",
|
||||
"touch"
|
||||
].forEach(function (deviceType) {
|
||||
it("detects when a device is a " + deviceType + " device", function () {
|
||||
mockAgentService[method(deviceType)].andReturn(true);
|
||||
expect(DeviceMatchers[deviceType](mockAgentService))
|
||||
.toBe(true);
|
||||
mockAgentService[method(deviceType)].andReturn(false);
|
||||
expect(DeviceMatchers[deviceType](mockAgentService))
|
||||
.toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
@ -1,4 +1,6 @@
|
||||
[
|
||||
"AgentService",
|
||||
"DeviceClassifier",
|
||||
"DeviceMatchers",
|
||||
"MCTDevice"
|
||||
]
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -42,7 +42,7 @@ define(
|
||||
return "C";
|
||||
},
|
||||
getGlyphClass: function () {
|
||||
return "";
|
||||
return "no-icon no-collapse float-right subtle";
|
||||
},
|
||||
getText: function () {
|
||||
return text;
|
||||
|
@ -476,6 +476,42 @@ define(
|
||||
|
||||
});
|
||||
|
||||
it("reflects limit status", function () {
|
||||
var elements;
|
||||
|
||||
mockHandle.getDatum.andReturn({});
|
||||
mockHandle.getTelemetryObjects().forEach(function (mockObject) {
|
||||
var id = mockObject.getId(),
|
||||
mockLimitCapability =
|
||||
jasmine.createSpyObj('limit-' + id, ['evaluate']);
|
||||
|
||||
mockObject.getCapability.andCallFake(function (key) {
|
||||
return (key === 'limit') && mockLimitCapability;
|
||||
});
|
||||
|
||||
mockLimitCapability.evaluate
|
||||
.andReturn({ cssClass: 'alarm-' + id });
|
||||
});
|
||||
|
||||
// Initialize
|
||||
mockScope.domainObject = mockDomainObject;
|
||||
mockScope.model = testModel;
|
||||
findWatch("domainObject")(mockDomainObject);
|
||||
findWatch("model.modified")(1);
|
||||
findWatch("model.composition")(mockScope.model.composition);
|
||||
|
||||
// Invoke the subscription callback
|
||||
mockHandler.handle.mostRecentCall.args[1]();
|
||||
|
||||
// Get elements that controller is now exposing
|
||||
elements = controller.getElements();
|
||||
|
||||
// Limit-based CSS classes should be available
|
||||
expect(elements[0].cssClass).toEqual("alarm-a");
|
||||
expect(elements[1].cssClass).toEqual("alarm-b");
|
||||
expect(elements[2].cssClass).toEqual("alarm-c");
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
|
@ -286,6 +286,7 @@ define(
|
||||
expect(mockHandle.request.calls.length).toEqual(2);
|
||||
});
|
||||
|
||||
|
||||
it("maintains externally-provided domain axis bounds after data is received", function () {
|
||||
mockSeries.getPointCount.andReturn(3);
|
||||
mockSeries.getRangeValue.andReturn(42);
|
||||
@ -296,7 +297,7 @@ define(
|
||||
mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
|
||||
fireEvent("telemetry:display:bounds", [
|
||||
{},
|
||||
{ start: 0, end: 10000 }
|
||||
{start: 0, end: 10000}
|
||||
]);
|
||||
mockHandle.request.mostRecentCall.args[1](
|
||||
mockDomainObject,
|
||||
@ -312,6 +313,33 @@ define(
|
||||
controller.getSubPlots()[0].panZoomStack.getDimensions()[0]
|
||||
).toEqual(10000);
|
||||
});
|
||||
|
||||
it("provides classes for legends based on limit state", function () {
|
||||
var mockTelemetryObjects = mockHandle.getTelemetryObjects();
|
||||
|
||||
mockHandle.getDatum.andReturn({});
|
||||
mockTelemetryObjects.forEach(function (mockObject, i) {
|
||||
var id = 'object-' + i,
|
||||
mockLimitCapability =
|
||||
jasmine.createSpyObj('limit-' + id, ['evaluate']);
|
||||
|
||||
mockObject.getId.andReturn(id);
|
||||
mockObject.getCapability.andCallFake(function (key) {
|
||||
return (key === 'limit') && mockLimitCapability;
|
||||
});
|
||||
|
||||
mockLimitCapability.evaluate
|
||||
.andReturn({ cssClass: 'alarm-' + id });
|
||||
});
|
||||
|
||||
mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
|
||||
mockHandler.handle.mostRecentCall.args[1]();
|
||||
|
||||
mockTelemetryObjects.forEach(function (mockTelemetryObject) {
|
||||
expect(controller.getLegendClass(mockTelemetryObject))
|
||||
.toEqual('alarm-' + mockTelemetryObject.getId());
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
103
platform/features/plot/test/elements/PlotLimitTrackerSpec.js
Normal file
103
platform/features/plot/test/elements/PlotLimitTrackerSpec.js
Normal file
@ -0,0 +1,103 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/
|
||||
|
||||
define(
|
||||
["../../src/elements/PlotLimitTracker"],
|
||||
function (PlotLimitTracker) {
|
||||
"use strict";
|
||||
|
||||
describe("A plot's limit tracker", function () {
|
||||
var mockHandle,
|
||||
testRange,
|
||||
mockTelemetryObjects,
|
||||
testData,
|
||||
mockLimitCapabilities,
|
||||
tracker;
|
||||
|
||||
beforeEach(function () {
|
||||
testRange = "some-range";
|
||||
testData = {};
|
||||
mockHandle = jasmine.createSpyObj(
|
||||
'handle',
|
||||
['getTelemetryObjects', 'getDatum']
|
||||
);
|
||||
mockTelemetryObjects = ['a', 'b', 'c'].map(function (id, i) {
|
||||
var mockTelemetryObject = jasmine.createSpyObj(
|
||||
'object-' + id,
|
||||
[ 'getId', 'getCapability', 'getModel' ]
|
||||
),
|
||||
mockLimitCapability = jasmine.createSpyObj(
|
||||
'limit-' + id,
|
||||
[ 'evaluate' ]
|
||||
);
|
||||
testData[id] = { id: id, value: i };
|
||||
mockTelemetryObject.getId.andReturn(id);
|
||||
mockTelemetryObject.getCapability.andCallFake(function (key) {
|
||||
return key === 'limit' && mockLimitCapability;
|
||||
});
|
||||
mockLimitCapability.evaluate
|
||||
.andReturn({ cssClass: 'alarm-' + id});
|
||||
return mockTelemetryObject;
|
||||
});
|
||||
mockHandle.getTelemetryObjects.andReturn(mockTelemetryObjects);
|
||||
mockHandle.getDatum.andCallFake(function (telemetryObject) {
|
||||
return testData[telemetryObject.getId()];
|
||||
});
|
||||
|
||||
tracker = new PlotLimitTracker(mockHandle, testRange);
|
||||
});
|
||||
|
||||
it("initially provides no limit state", function () {
|
||||
mockTelemetryObjects.forEach(function (mockTelemetryObject) {
|
||||
expect(tracker.getLegendClass(mockTelemetryObject))
|
||||
.toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("when asked to update", function () {
|
||||
beforeEach(function () {
|
||||
tracker.update();
|
||||
});
|
||||
|
||||
it("evaluates limits using the limit capability", function () {
|
||||
mockTelemetryObjects.forEach(function (mockTelemetryObject) {
|
||||
var id = mockTelemetryObject.getId(),
|
||||
mockLimit =
|
||||
mockTelemetryObject.getCapability('limit');
|
||||
expect(mockLimit.evaluate)
|
||||
.toHaveBeenCalledWith(testData[id], testRange);
|
||||
});
|
||||
});
|
||||
|
||||
it("exposes legend classes returned by the limit capability", function () {
|
||||
mockTelemetryObjects.forEach(function (mockTelemetryObject) {
|
||||
var id = mockTelemetryObject.getId();
|
||||
expect(tracker.getLegendClass(mockTelemetryObject))
|
||||
.toEqual('alarm-' + id);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
@ -6,6 +6,7 @@
|
||||
"SubPlot",
|
||||
"SubPlotFactory",
|
||||
"elements/PlotAxis",
|
||||
"elements/PlotLimitTracker",
|
||||
"elements/PlotLine",
|
||||
"elements/PlotLineBuffer",
|
||||
"elements/PlotPalette",
|
||||
|
@ -20,11 +20,12 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
|
||||
<div class="search-result-item"
|
||||
<div class="search-result-item l-flex-row flex-elem grows"
|
||||
ng-class="{selected: ngModel.selectedObject.getId() === domainObject.getId()}">
|
||||
<mct-representation key="'label'"
|
||||
mct-object="domainObject"
|
||||
ng-model="ngModel"
|
||||
ng-click="ngModel.selectedObject = domainObject">
|
||||
ng-click="ngModel.selectedObject = domainObject"
|
||||
class="l-flex-row flex-elem grows">
|
||||
</mct-representation>
|
||||
</div>
|
@ -20,11 +20,13 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<div class="l-flex-col flex-elem grows holder holder-search" ng-controller="SearchController as controller">
|
||||
<div class="search-bar flex-elem" ng-controller="ClickAwayController as toggle">
|
||||
<div class="search-bar flex-elem"
|
||||
ng-controller="ClickAwayController as toggle"
|
||||
ng-class="{ holder: !(ngModel.input === '' || ngModel.input === undefined) }">
|
||||
<input class="search-input"
|
||||
type="text"
|
||||
ng-model="ngModel.input"
|
||||
ng-keyup="controller.search()" />
|
||||
ng-keyup="controller.search()"/>
|
||||
<a class="clear-icon"
|
||||
ng-class="{show: !(ngModel.input === '' || ngModel.input === undefined)}"
|
||||
ng-click="ngModel.input = ''; controller.search()"></a>
|
||||
@ -37,18 +39,19 @@
|
||||
ng-click="toggle.setState(true)">
|
||||
</mct-include>
|
||||
</div>
|
||||
<div class="active-filter-display flex-elem"
|
||||
<div class="active-filter-display flex-elem holder"
|
||||
ng-class="{off: ngModel.filtersString === '' || ngModel.filtersString === undefined || !ngModel.search}"
|
||||
ng-controller="SearchMenuController as menuController">
|
||||
<a class="clear-icon clear-filters-icon"
|
||||
ng-click="ngModel.checkAll = true; menuController.checkAll()"></a>Filtered by: {{ ngModel.filtersString }}
|
||||
</div>
|
||||
<div class="search-results flex-elem grows vscroll"
|
||||
<div class="search-results flex-elem holder grows vscroll"
|
||||
ng-class="{ off: !(loading || results.length > 0), loading: loading }">
|
||||
<mct-representation key="'search-item'"
|
||||
ng-repeat="result in results"
|
||||
mct-object="result.object"
|
||||
ng-model="ngModel">
|
||||
ng-model="ngModel"
|
||||
class="l-flex-row flex-elem grows">
|
||||
</mct-representation>
|
||||
<a class="load-more-button s-btn vsm" ng-if="controller.areMore()" ng-click="controller.loadMore()">More Results</a>
|
||||
</div>
|
||||
|
@ -243,6 +243,26 @@ define(
|
||||
subscription.unsubscribe();
|
||||
expect(mockUnlisten).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("provides telemetry as datum objects", function () {
|
||||
var testDatum = { a: 1, b: 13, c: 42, d: -1977 };
|
||||
|
||||
function lookup(index, key) {
|
||||
return testDatum[key];
|
||||
}
|
||||
|
||||
mockSeries.getDomainValue.andCallFake(lookup);
|
||||
mockSeries.getRangeValue.andCallFake(lookup);
|
||||
|
||||
testMetadata.domains = [ { key: 'a' }, { key: 'b'} ];
|
||||
testMetadata.ranges = [ { key: 'c' }, { key: 'd'} ];
|
||||
|
||||
mockTelemetry.subscribe.mostRecentCall.args[0](mockSeries);
|
||||
mockTimeout.mostRecentCall.args[0]();
|
||||
|
||||
expect(subscription.getDatum(mockDomainObject))
|
||||
.toEqual(testDatum);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user