Merge branch 'open-master' into open1233
This commit is contained in:
@@ -68,6 +68,8 @@ define(
|
||||
* @returns {DomainObject} the domain object in an editable form
|
||||
*/
|
||||
getEditableObject: function (domainObject) {
|
||||
var type = domainObject.getCapability('type');
|
||||
|
||||
// Track the top-level domain object; this will have
|
||||
// some special behavior for its context capability.
|
||||
root = root || domainObject;
|
||||
@@ -77,6 +79,11 @@ define(
|
||||
return domainObject;
|
||||
}
|
||||
|
||||
// Don't bother wrapping non-editable objects
|
||||
if (!type || !type.hasFeature('creation')) {
|
||||
return domainObject;
|
||||
}
|
||||
|
||||
// Provide an editable form of the object
|
||||
return new EditableDomainObject(
|
||||
domainObject,
|
||||
@@ -142,4 +149,4 @@ define(
|
||||
|
||||
return EditableDomainObjectCache;
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
@@ -31,7 +31,7 @@ define(
|
||||
mockQ,
|
||||
mockNavigationService,
|
||||
mockObject,
|
||||
mockCapability,
|
||||
mockType,
|
||||
controller;
|
||||
|
||||
beforeEach(function () {
|
||||
@@ -48,15 +48,18 @@ define(
|
||||
"domainObject",
|
||||
[ "getId", "getModel", "getCapability", "hasCapability" ]
|
||||
);
|
||||
mockCapability = jasmine.createSpyObj(
|
||||
"capability",
|
||||
[ "invoke" ]
|
||||
mockType = jasmine.createSpyObj(
|
||||
"type",
|
||||
[ "hasFeature" ]
|
||||
);
|
||||
|
||||
mockNavigationService.getNavigation.andReturn(mockObject);
|
||||
mockObject.getId.andReturn("test");
|
||||
mockObject.getModel.andReturn({ name: "Test object" });
|
||||
mockObject.getCapability.andReturn(mockCapability);
|
||||
mockObject.getCapability.andCallFake(function (key) {
|
||||
return key === 'type' && mockType;
|
||||
});
|
||||
mockType.hasFeature.andReturn(true);
|
||||
|
||||
controller = new EditController(
|
||||
mockScope,
|
||||
@@ -76,7 +79,7 @@ define(
|
||||
.toBeDefined();
|
||||
// Shouldn't have been the mock capability we provided
|
||||
expect(controller.navigatedObject().getCapability("editor"))
|
||||
.not.toEqual(mockCapability);
|
||||
.not.toEqual(mockType);
|
||||
});
|
||||
|
||||
it("detaches its navigation listener when destroyed", function () {
|
||||
@@ -119,4 +122,4 @@ define(
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
@@ -32,6 +32,7 @@ define(
|
||||
completionCapability,
|
||||
object,
|
||||
mockQ,
|
||||
mockType,
|
||||
cache;
|
||||
|
||||
|
||||
@@ -40,10 +41,13 @@ define(
|
||||
return {
|
||||
getId: function () { return id; },
|
||||
getModel: function () { return {}; },
|
||||
getCapability: function (name) {
|
||||
return completionCapability;
|
||||
getCapability: function (key) {
|
||||
return {
|
||||
editor: completionCapability,
|
||||
type: mockType
|
||||
}[key];
|
||||
},
|
||||
hasCapability: function (name) {
|
||||
hasCapability: function (key) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -62,6 +66,8 @@ define(
|
||||
|
||||
beforeEach(function () {
|
||||
mockQ = jasmine.createSpyObj('$q', ['when', 'all']);
|
||||
mockType = jasmine.createSpyObj('type', ['hasFeature']);
|
||||
mockType.hasFeature.andReturn(true);
|
||||
captured = {};
|
||||
completionCapability = {
|
||||
save: function () {
|
||||
@@ -152,6 +158,17 @@ define(
|
||||
.toBe(wrappedObject);
|
||||
});
|
||||
|
||||
it("does not wrap non-editable objects", function () {
|
||||
var domainObject = new TestObject('test-id');
|
||||
|
||||
mockType.hasFeature.andCallFake(function (key) {
|
||||
return key !== 'creation';
|
||||
});
|
||||
|
||||
expect(cache.getEditableObject(domainObject))
|
||||
.toBe(domainObject);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -226,20 +226,20 @@ a.disabled {
|
||||
|
||||
@-moz-keyframes pulse {
|
||||
0% {
|
||||
opacity: 0.5; }
|
||||
opacity: 0.2; }
|
||||
100% {
|
||||
opacity: 1; } }
|
||||
@-webkit-keyframes pulse {
|
||||
0% {
|
||||
opacity: 0.5; }
|
||||
opacity: 0.2; }
|
||||
100% {
|
||||
opacity: 1; } }
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
opacity: 0.5; }
|
||||
opacity: 0.2; }
|
||||
100% {
|
||||
opacity: 1; } }
|
||||
/* line 59, ../sass/_effects.scss */
|
||||
/* line 69, ../sass/_effects.scss */
|
||||
.pulse {
|
||||
-moz-animation-name: pulse;
|
||||
-webkit-animation-name: pulse;
|
||||
@@ -657,26 +657,26 @@ mct-container {
|
||||
overflow-y: auto; }
|
||||
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
/* line 23, ../sass/_fixed-position.scss */
|
||||
.t-fixed-position.l-fixed-position {
|
||||
position: absolute;
|
||||
@@ -686,33 +686,33 @@ mct-container {
|
||||
left: 0;
|
||||
width: auto;
|
||||
height: auto; }
|
||||
/* line 29, ../sass/_fixed-position.scss */
|
||||
/* line 33, ../sass/_fixed-position.scss */
|
||||
.t-fixed-position.l-fixed-position .l-grid-holder {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%; }
|
||||
/* line 32, ../sass/_fixed-position.scss */
|
||||
/* line 37, ../sass/_fixed-position.scss */
|
||||
.t-fixed-position.l-fixed-position .l-grid-holder .l-grid {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
pointer-events: none;
|
||||
z-index: 0; }
|
||||
/* line 42, ../sass/_fixed-position.scss */
|
||||
/* line 48, ../sass/_fixed-position.scss */
|
||||
.t-fixed-position .l-fixed-position-item {
|
||||
position: absolute;
|
||||
border: 1px solid transparent; }
|
||||
/* line 46, ../sass/_fixed-position.scss */
|
||||
/* line 52, ../sass/_fixed-position.scss */
|
||||
.t-fixed-position .l-fixed-position-item.s-selected {
|
||||
-moz-box-shadow: rgba(0, 0, 0, 0.7) 0 3px 10px;
|
||||
-webkit-box-shadow: rgba(0, 0, 0, 0.7) 0 3px 10px;
|
||||
box-shadow: rgba(0, 0, 0, 0.7) 0 3px 10px;
|
||||
border-color: #0099cc;
|
||||
cursor: move; }
|
||||
/* line 51, ../sass/_fixed-position.scss */
|
||||
/* line 57, ../sass/_fixed-position.scss */
|
||||
.t-fixed-position .l-fixed-position-item.s-not-selected {
|
||||
opacity: 0.8; }
|
||||
/* line 55, ../sass/_fixed-position.scss */
|
||||
/* line 61, ../sass/_fixed-position.scss */
|
||||
.t-fixed-position .l-fixed-position-item .l-fixed-position-box,
|
||||
.t-fixed-position .l-fixed-position-item .l-fixed-position-image,
|
||||
.t-fixed-position .l-fixed-position-item .l-fixed-position-text {
|
||||
@@ -721,62 +721,56 @@ mct-container {
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
width: 100%; }
|
||||
/* line 65, ../sass/_fixed-position.scss */
|
||||
/* line 72, ../sass/_fixed-position.scss */
|
||||
.t-fixed-position .l-fixed-position-item .l-fixed-position-image {
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center; }
|
||||
/* line 71, ../sass/_fixed-position.scss */
|
||||
/* line 78, ../sass/_fixed-position.scss */
|
||||
.t-fixed-position .l-fixed-position-item .l-fixed-position-text {
|
||||
text-shadow: rgba(0, 0, 0, 0.1) 0 1px 2px;
|
||||
border: 1px solid transparent;
|
||||
font-size: 0.8rem;
|
||||
line-height: 100%; }
|
||||
/* line 77, ../sass/_fixed-position.scss */
|
||||
/* line 84, ../sass/_fixed-position.scss */
|
||||
.t-fixed-position .l-fixed-position-item .l-fixed-position-text.l-static-text {
|
||||
padding: 1px; }
|
||||
/* line 82, ../sass/_fixed-position.scss */
|
||||
/* line 89, ../sass/_fixed-position.scss */
|
||||
.t-fixed-position .l-fixed-position-item .l-fixed-position-text.l-telemetry .l-elem {
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: auto;
|
||||
height: auto;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
padding: 2px;
|
||||
width: 50%; }
|
||||
/* line 88, ../sass/_fixed-position.scss */
|
||||
display: block;
|
||||
padding: 2px; }
|
||||
/* line 96, ../sass/_fixed-position.scss */
|
||||
.t-fixed-position .l-fixed-position-item .l-fixed-position-text.l-telemetry .l-elem.l-title {
|
||||
right: auto;
|
||||
left: 1px; }
|
||||
/* line 92, ../sass/_fixed-position.scss */
|
||||
float: none;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: auto; }
|
||||
/* line 105, ../sass/_fixed-position.scss */
|
||||
.t-fixed-position .l-fixed-position-item .l-fixed-position-text.l-telemetry .l-elem.l-value {
|
||||
right: 1px;
|
||||
left: auto;
|
||||
-moz-border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
float: right;
|
||||
margin-left: 5px;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
text-align: right; }
|
||||
/* line 97, ../sass/_fixed-position.scss */
|
||||
/* line 116, ../sass/_fixed-position.scss */
|
||||
.t-fixed-position .l-fixed-position-item .l-fixed-position-text.l-telemetry .l-elem.l-value.telem-only {
|
||||
left: 1px;
|
||||
width: auto; }
|
||||
/* line 102, ../sass/_fixed-position.scss */
|
||||
.t-fixed-position .l-fixed-position-item .l-fixed-position-text.l-telemetry .l-elem.l-value .l-value-bg {
|
||||
-moz-border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
padding: 0 4px; }
|
||||
/* line 112, ../sass/_fixed-position.scss */
|
||||
margin-left: 0;
|
||||
width: 100%; }
|
||||
/* line 126, ../sass/_fixed-position.scss */
|
||||
.t-fixed-position .l-fixed-position-item-handle {
|
||||
background: rgba(0, 153, 204, 0.5);
|
||||
cursor: crosshair;
|
||||
border: 1px solid #0099cc;
|
||||
position: absolute; }
|
||||
|
||||
/* line 126, ../sass/_fixed-position.scss */
|
||||
/* line 140, ../sass/_fixed-position.scss */
|
||||
.edit-mode .t-fixed-position.l-fixed-position .l-grid-holder .l-grid.l-grid-x {
|
||||
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuMCIgeTE9IjAuNSIgeDI9IjEuMCIgeTI9IjAuNSI+PHN0b3Agb2Zmc2V0PSIxcHgiIHN0b3AtY29sb3I9IiNmZmZmZmYiIHN0b3Atb3BhY2l0eT0iMC4wNSIvPjxzdG9wIG9mZnNldD0iMXB4IiBzdG9wLWNvbG9yPSIjMDAwMDAwIiBzdG9wLW9wYWNpdHk9IjAuMCIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjAiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');
|
||||
background-size: 100%;
|
||||
@@ -784,7 +778,7 @@ mct-container {
|
||||
background-image: -webkit-linear-gradient(0deg, rgba(255, 255, 255, 0.05) 1px, rgba(0, 0, 0, 0) 1px, rgba(0, 0, 0, 0) 100%);
|
||||
background-image: linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, rgba(0, 0, 0, 0) 1px, rgba(0, 0, 0, 0) 100%);
|
||||
background-repeat: repeat-x; }
|
||||
/* line 130, ../sass/_fixed-position.scss */
|
||||
/* line 144, ../sass/_fixed-position.scss */
|
||||
.edit-mode .t-fixed-position.l-fixed-position .l-grid-holder .l-grid.l-grid-y {
|
||||
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjEuMCIgeDI9IjAuNSIgeTI9IjAuMCI+PHN0b3Agb2Zmc2V0PSIxcHgiIHN0b3AtY29sb3I9IiNmZmZmZmYiIHN0b3Atb3BhY2l0eT0iMC4wNSIvPjxzdG9wIG9mZnNldD0iMXB4IiBzdG9wLWNvbG9yPSIjMDAwMDAwIiBzdG9wLW9wYWNpdHk9IjAuMCIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjAiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');
|
||||
background-size: 100%;
|
||||
@@ -792,10 +786,10 @@ mct-container {
|
||||
background-image: -webkit-linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, rgba(0, 0, 0, 0) 1px, rgba(0, 0, 0, 0) 100%);
|
||||
background-image: linear-gradient(0deg, rgba(255, 255, 255, 0.05) 1px, rgba(0, 0, 0, 0) 1px, rgba(0, 0, 0, 0) 100%);
|
||||
background-repeat: repeat-y; }
|
||||
/* line 138, ../sass/_fixed-position.scss */
|
||||
/* line 152, ../sass/_fixed-position.scss */
|
||||
.edit-mode .t-fixed-position .l-fixed-position-item:not(.s-selected) {
|
||||
border: 1px dotted rgba(0, 153, 204, 0.75); }
|
||||
/* line 140, ../sass/_fixed-position.scss */
|
||||
/* line 154, ../sass/_fixed-position.scss */
|
||||
.edit-mode .t-fixed-position .l-fixed-position-item:not(.s-selected):hover {
|
||||
border: 1px dotted #0099cc; }
|
||||
|
||||
@@ -1191,104 +1185,101 @@ mct-container {
|
||||
border-collapse: collapse;
|
||||
color: #fff;
|
||||
display: table;
|
||||
font-size: 0.8em;
|
||||
font-size: 0.75em;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%; }
|
||||
/* line 37, ../sass/lists/_tabular.scss */
|
||||
.tabular thead, .tabular .thead,
|
||||
.tabular tbody tr, .tabular .tbody .tr {
|
||||
display: table;
|
||||
width: 100%; }
|
||||
/* line 45, ../sass/lists/_tabular.scss */
|
||||
.tabular thead tr, .tabular thead .tr, .tabular .thead tr, .tabular .thead .tr {
|
||||
height: 18px; }
|
||||
/* line 48, ../sass/lists/_tabular.scss */
|
||||
.tabular thead:before, .tabular .thead:before {
|
||||
content: "";
|
||||
display: block;
|
||||
z-index: 0;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
table-layout: fixed; }
|
||||
/* line 43, ../sass/lists/_tabular.scss */
|
||||
.tabular thead, .tabular .thead {
|
||||
width: calc(100% - 10px); }
|
||||
/* line 45, ../sass/lists/_tabular.scss */
|
||||
.tabular thead tr, .tabular thead .tr, .tabular .thead tr, .tabular .thead .tr {
|
||||
height: 18px; }
|
||||
/* line 48, ../sass/lists/_tabular.scss */
|
||||
.tabular thead:before, .tabular .thead:before {
|
||||
content: "";
|
||||
display: block;
|
||||
z-index: 0;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 18px;
|
||||
background: rgba(255, 255, 255, 0.15); }
|
||||
height: 18px;
|
||||
background: rgba(255, 255, 255, 0.15); }
|
||||
/* line 58, ../sass/lists/_tabular.scss */
|
||||
.tabular tbody, .tabular .tbody {
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: auto;
|
||||
height: auto;
|
||||
top: 18px;
|
||||
display: block;
|
||||
overflow-y: scroll; }
|
||||
/* line 66, ../sass/lists/_tabular.scss */
|
||||
display: table-row-group; }
|
||||
/* line 65, ../sass/lists/_tabular.scss */
|
||||
.tabular tbody tr:hover, .tabular tbody .tr:hover, .tabular .tbody tr:hover, .tabular .tbody .tr:hover {
|
||||
background: rgba(255, 255, 255, 0.1); }
|
||||
/* line 74, ../sass/lists/_tabular.scss */
|
||||
.tabular tr:first-child .td, .tabular .tr:first-child .td {
|
||||
border-top: none; }
|
||||
/* line 77, ../sass/lists/_tabular.scss */
|
||||
.tabular tr th, .tabular tr .th, .tabular tr td, .tabular tr .td, .tabular .tr th, .tabular .tr .th, .tabular .tr td, .tabular .tr .td {
|
||||
display: table-cell; }
|
||||
/* line 80, ../sass/lists/_tabular.scss */
|
||||
.tabular tr th, .tabular tr .th, .tabular .tr th, .tabular .tr .th {
|
||||
border: none;
|
||||
border-left: 1px solid rgba(255, 255, 255, 0.1);
|
||||
color: #b3b3b3;
|
||||
padding: 0 5px;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
/* em {
|
||||
//background: rgba(green, 0.2);
|
||||
border-left: 1px solid $tabularColorBorder;
|
||||
color: $tabularColorHeaderFg;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
height: $tabularHeaderH;
|
||||
line-height: $tabularHeaderH;
|
||||
margin-left: - $tabularTdPadLR;
|
||||
padding: 0 $tabularTdPadLR;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
vertical-align: middle;
|
||||
&:hover {
|
||||
color: lighten($tabularColorHeaderFg, 20%);
|
||||
}
|
||||
}*/ }
|
||||
/* line 87, ../sass/lists/_tabular.scss */
|
||||
.tabular tr th:first-child, .tabular tr .th:first-child, .tabular .tr th:first-child, .tabular .tr .th:first-child {
|
||||
border-left: none; }
|
||||
/* line 91, ../sass/lists/_tabular.scss */
|
||||
.tabular tr th.sort .icon-sorting:before, .tabular tr .th.sort .icon-sorting:before, .tabular .tr th.sort .icon-sorting:before, .tabular .tr .th.sort .icon-sorting:before {
|
||||
display: inline-block;
|
||||
font-family: symbolsfont;
|
||||
margin-left: 5px; }
|
||||
/* line 96, ../sass/lists/_tabular.scss */
|
||||
.tabular tr th.sort.asc .icon-sorting:before, .tabular tr .th.sort.asc .icon-sorting:before, .tabular .tr th.sort.asc .icon-sorting:before, .tabular .tr .th.sort.asc .icon-sorting:before {
|
||||
content: '0'; }
|
||||
/* line 99, ../sass/lists/_tabular.scss */
|
||||
.tabular tr th.sort.desc .icon-sorting:before, .tabular tr .th.sort.desc .icon-sorting:before, .tabular .tr th.sort.desc .icon-sorting:before, .tabular .tr .th.sort.desc .icon-sorting:before {
|
||||
content: '1'; }
|
||||
/* line 123, ../sass/lists/_tabular.scss */
|
||||
.tabular tr td, .tabular tr .td, .tabular .tr td, .tabular .tr .td {
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||
padding: 2px 5px; }
|
||||
/* line 126, ../sass/lists/_tabular.scss */
|
||||
.tabular tr td.numeric, .tabular tr .td.numeric, .tabular .tr td.numeric, .tabular .tr .td.numeric {
|
||||
text-align: right; }
|
||||
/* line 132, ../sass/lists/_tabular.scss */
|
||||
/* line 70, ../sass/lists/_tabular.scss */
|
||||
.tabular tr, .tabular .tr {
|
||||
display: table-row; }
|
||||
/* line 72, ../sass/lists/_tabular.scss */
|
||||
.tabular tr:first-child .td, .tabular .tr:first-child .td {
|
||||
border-top: none; }
|
||||
/* line 75, ../sass/lists/_tabular.scss */
|
||||
.tabular tr th, .tabular tr .th, .tabular tr td, .tabular tr .td, .tabular .tr th, .tabular .tr .th, .tabular .tr td, .tabular .tr .td {
|
||||
display: table-cell; }
|
||||
/* line 78, ../sass/lists/_tabular.scss */
|
||||
.tabular tr th, .tabular tr .th, .tabular .tr th, .tabular .tr .th {
|
||||
border: none;
|
||||
border-left: 1px solid rgba(255, 255, 255, 0.1);
|
||||
color: #b3b3b3;
|
||||
padding: 0 5px;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle; }
|
||||
/* line 85, ../sass/lists/_tabular.scss */
|
||||
.tabular tr th:first-child, .tabular tr .th:first-child, .tabular .tr th:first-child, .tabular .tr .th:first-child {
|
||||
border-left: none; }
|
||||
/* line 89, ../sass/lists/_tabular.scss */
|
||||
.tabular tr th.sort .icon-sorting:before, .tabular tr .th.sort .icon-sorting:before, .tabular .tr th.sort .icon-sorting:before, .tabular .tr .th.sort .icon-sorting:before {
|
||||
display: inline-block;
|
||||
font-family: symbolsfont;
|
||||
margin-left: 5px; }
|
||||
/* line 94, ../sass/lists/_tabular.scss */
|
||||
.tabular tr th.sort.asc .icon-sorting:before, .tabular tr .th.sort.asc .icon-sorting:before, .tabular .tr th.sort.asc .icon-sorting:before, .tabular .tr .th.sort.asc .icon-sorting:before {
|
||||
content: '0'; }
|
||||
/* line 97, ../sass/lists/_tabular.scss */
|
||||
.tabular tr th.sort.desc .icon-sorting:before, .tabular tr .th.sort.desc .icon-sorting:before, .tabular .tr th.sort.desc .icon-sorting:before, .tabular .tr .th.sort.desc .icon-sorting:before {
|
||||
content: '1'; }
|
||||
/* line 102, ../sass/lists/_tabular.scss */
|
||||
.tabular tr td, .tabular tr .td, .tabular .tr td, .tabular .tr .td {
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||
min-width: 110px;
|
||||
padding: 2px 5px;
|
||||
vertical-align: top; }
|
||||
/* line 107, ../sass/lists/_tabular.scss */
|
||||
.tabular tr td.numeric, .tabular tr .td.numeric, .tabular .tr td.numeric, .tabular .tr .td.numeric {
|
||||
text-align: right; }
|
||||
/* line 113, ../sass/lists/_tabular.scss */
|
||||
.tabular.filterable tbody, .tabular.filterable .tbody {
|
||||
top: 36px; }
|
||||
/* line 118, ../sass/lists/_tabular.scss */
|
||||
.tabular.fixed-header {
|
||||
height: 100%; }
|
||||
/* line 120, ../sass/lists/_tabular.scss */
|
||||
.tabular.fixed-header thead, .tabular.fixed-header .thead,
|
||||
.tabular.fixed-header tbody tr, .tabular.fixed-header .tbody .tr {
|
||||
display: table;
|
||||
table-layout: fixed; }
|
||||
/* line 125, ../sass/lists/_tabular.scss */
|
||||
.tabular.fixed-header thead, .tabular.fixed-header .thead {
|
||||
width: calc(100% - 10px); }
|
||||
/* line 128, ../sass/lists/_tabular.scss */
|
||||
.tabular.fixed-header tbody, .tabular.fixed-header .tbody {
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: auto;
|
||||
height: auto;
|
||||
top: 18px;
|
||||
display: block;
|
||||
overflow-y: scroll; }
|
||||
/* line 136, ../sass/lists/_tabular.scss */
|
||||
.tabular.t-event-messages td, .tabular.t-event-messages .td {
|
||||
min-width: 150px; }
|
||||
|
||||
/* line 1, ../sass/controls/_breadcrumb.scss */
|
||||
.l-breadcrumb {
|
||||
@@ -4824,8 +4815,8 @@ input[type="text"] {
|
||||
border-radius: 2px;
|
||||
float: right;
|
||||
margin-left: 5px;
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
text-align: right; }
|
||||
/* line 110, ../sass/_autoflow.scss */
|
||||
.autoflow .l-autoflow-items .l-autoflow-col:first-child {
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
$colMargin: $interiorMargin;
|
||||
$colW: 225px;
|
||||
$valW: 70px;
|
||||
$valPad: 2px;
|
||||
$valPad: 5px;
|
||||
$rowH: 15px;
|
||||
font-size: 0.75rem;
|
||||
.l-autoflow-header {
|
||||
|
||||
@@ -43,16 +43,26 @@ a.disabled {
|
||||
@include test();
|
||||
}
|
||||
|
||||
@mixin customKeyframes($animName: pulse, $op0: 0.5) {
|
||||
@include keyframes($animName) {
|
||||
0% { opacity: $op0; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
@include animation-name(pulse, 0.2);
|
||||
}
|
||||
|
||||
@include keyframes(pulse) {
|
||||
0% { opacity: 0.5; }
|
||||
0% { opacity: 0.2; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
@mixin pulse($dur: 500ms) {
|
||||
|
||||
@mixin pulse($dur: 500ms, $iteration: infinite) {
|
||||
//@include customKeyframes(pulse, 0.2);
|
||||
@include animation-name(pulse);
|
||||
@include animation-duration($dur);
|
||||
@include animation-direction(alternate);
|
||||
@include animation-iteration-count(infinite);
|
||||
@include animation-iteration-count($iteration);
|
||||
@include animation-timing-function(ease-in-out);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,38 +1,44 @@
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
.t-fixed-position {
|
||||
&.l-fixed-position {
|
||||
// @include test(red);
|
||||
// @include test(red);
|
||||
position: absolute;
|
||||
top: 0; right: 0; bottom: 0; left: 0;
|
||||
width: auto; height: auto;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: auto;
|
||||
height: auto;
|
||||
|
||||
.l-grid-holder {
|
||||
position: relative;
|
||||
height: 100%; width: 100%;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
.l-grid {
|
||||
// @include test(orange);
|
||||
// @include test(orange);
|
||||
position: absolute;
|
||||
height: 100%; width: 100%;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
@@ -56,12 +62,13 @@
|
||||
.l-fixed-position-image,
|
||||
.l-fixed-position-text {
|
||||
@include box-sizing(border-box);
|
||||
height: 100%; width: 100%;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.l-fixed-position-box {
|
||||
}
|
||||
|
||||
|
||||
.l-fixed-position-image {
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
@@ -70,38 +77,45 @@
|
||||
|
||||
.l-fixed-position-text {
|
||||
@include txtShdwSubtle();
|
||||
border:1px solid transparent;
|
||||
border: 1px solid transparent;
|
||||
font-size: 0.8rem;
|
||||
$p: 1px; //$interiorMarginSm;
|
||||
line-height: 100%;
|
||||
&.l-static-text {
|
||||
// overflow: auto;
|
||||
// overflow: auto;
|
||||
padding: $p;
|
||||
}
|
||||
&.l-telemetry {
|
||||
.l-elem {
|
||||
//@include absPosDefault($p);
|
||||
@include absPosDefault(0);
|
||||
//@include absPosDefault(0);
|
||||
@include box-sizing(border-box);
|
||||
display: block;
|
||||
padding: 2px;
|
||||
width: 50%;
|
||||
//width: 50%;
|
||||
&.l-title {
|
||||
right: auto;
|
||||
left: $p;
|
||||
//right: auto;
|
||||
//left: $p;
|
||||
float: none;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: auto;
|
||||
}
|
||||
&.l-value {
|
||||
// @include test(blue);
|
||||
right: $p;
|
||||
left: auto;
|
||||
// @include test(blue);
|
||||
// right: $p;
|
||||
// left: auto;
|
||||
@include border-radius($smallCr);
|
||||
$valPad: 5px;
|
||||
float: right;
|
||||
margin-left: $interiorMargin;
|
||||
padding-left: $valPad;
|
||||
padding-right: $valPad;
|
||||
text-align: right;
|
||||
&.telem-only {
|
||||
// @include test(red);
|
||||
left: $p;
|
||||
width: auto;
|
||||
}
|
||||
.l-value-bg {
|
||||
@include border-radius($smallCr);
|
||||
padding: 0 4px;
|
||||
margin-left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
width: auto; height: auto;
|
||||
}
|
||||
|
||||
@mixin trans-prop-nice($props, $t) {
|
||||
@mixin trans-prop-nice($props, $t: 500ms) {
|
||||
@if $t == 0 {
|
||||
@include transition-property(none);
|
||||
} @else {
|
||||
|
||||
@@ -30,18 +30,18 @@
|
||||
border-collapse: collapse;
|
||||
color: #fff;
|
||||
display: table;
|
||||
font-size: 0.8em;
|
||||
font-size: 0.75em;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
//height: 100%; MOVED
|
||||
width: 100%;
|
||||
thead, .thead,
|
||||
tbody tr, .tbody .tr {
|
||||
display: table;
|
||||
//display: table; MOVED
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
//table-layout: fixed; MOVED
|
||||
}
|
||||
thead, .thead {
|
||||
width: calc(100% - 10px);
|
||||
//width: calc(100% - 10px); MOVED
|
||||
tr, .tr {
|
||||
height: $tabularHeaderH;
|
||||
}
|
||||
@@ -56,12 +56,11 @@
|
||||
}
|
||||
}
|
||||
tbody, .tbody {
|
||||
@include absPosDefault(0);
|
||||
top: $tabularHeaderH;
|
||||
//display: table-row-group;
|
||||
display: block;
|
||||
//width: 100%;
|
||||
overflow-y: scroll;
|
||||
//@include absPosDefault(0); MOVED
|
||||
//top: $tabularHeaderH; MOVED
|
||||
//display: block; MOVED
|
||||
//overflow-y: scroll; MOVED
|
||||
display: table-row-group;
|
||||
tr, .tr {
|
||||
&:hover {
|
||||
background: rgba(white, 0.1);
|
||||
@@ -69,8 +68,7 @@
|
||||
}
|
||||
}
|
||||
tr, .tr {
|
||||
//display: table-row;
|
||||
//width: 100%;
|
||||
display: table-row;
|
||||
&:first-child .td {
|
||||
border-top: none;
|
||||
}
|
||||
@@ -100,29 +98,12 @@
|
||||
content: '1';
|
||||
}
|
||||
}
|
||||
/* em {
|
||||
//background: rgba(green, 0.2);
|
||||
border-left: 1px solid $tabularColorBorder;
|
||||
color: $tabularColorHeaderFg;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
height: $tabularHeaderH;
|
||||
line-height: $tabularHeaderH;
|
||||
margin-left: - $tabularTdPadLR;
|
||||
padding: 0 $tabularTdPadLR;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
vertical-align: middle;
|
||||
&:hover {
|
||||
color: lighten($tabularColorHeaderFg, 20%);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
td, .td {
|
||||
border-top: 1px solid $tabularColorBorder;
|
||||
min-width: 110px;
|
||||
padding: $tabularTdPadTB $tabularTdPadLR;
|
||||
vertical-align: top;
|
||||
&.numeric {
|
||||
text-align: right;
|
||||
}
|
||||
@@ -133,4 +114,27 @@
|
||||
top: $tabularHeaderH * 2;
|
||||
}
|
||||
}
|
||||
|
||||
&.fixed-header {
|
||||
height: 100%;
|
||||
thead, .thead,
|
||||
tbody tr, .tbody .tr {
|
||||
display: table;
|
||||
table-layout: fixed;
|
||||
}
|
||||
thead, .thead {
|
||||
width: calc(100% - 10px);
|
||||
}
|
||||
tbody, .tbody {
|
||||
@include absPosDefault(0);
|
||||
top: $tabularHeaderH;
|
||||
display: block;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
&.t-event-messages {
|
||||
td, .td {
|
||||
min-width: 150px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,6 +70,12 @@
|
||||
"type": "decorator",
|
||||
"implementation": "models/CachingModelDecorator.js"
|
||||
},
|
||||
{
|
||||
"provides": "modelService",
|
||||
"type": "decorator",
|
||||
"priority": "fallback",
|
||||
"implementation": "models/MissingModelDecorator.js"
|
||||
},
|
||||
{
|
||||
"provides": "typeService",
|
||||
"type": "provider",
|
||||
@@ -132,6 +138,11 @@
|
||||
"features": "creation",
|
||||
"description": "Useful for storing and organizing domain objects.",
|
||||
"model": { "composition": [] }
|
||||
},
|
||||
{
|
||||
"key": "unknown",
|
||||
"name": "Unknown Type",
|
||||
"glyph": "?"
|
||||
}
|
||||
],
|
||||
"capabilities": [
|
||||
@@ -202,4 +213,4 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
59
platform/core/src/models/MissingModelDecorator.js
Normal file
59
platform/core/src/models/MissingModelDecorator.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*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Adds placeholder domain object models for any models which
|
||||
* fail to load from the underlying model service.
|
||||
* @implements {ModelService}
|
||||
*/
|
||||
function MissingModelDecorator(modelService) {
|
||||
function missingModel(id) {
|
||||
return {
|
||||
type: "unknown",
|
||||
name: "Missing: " + id
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
getModels: function (ids) {
|
||||
function addMissingModels(models) {
|
||||
var result = {};
|
||||
ids.forEach(function (id) {
|
||||
result[id] = models[id] || missingModel(id);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
return modelService.getModels(ids).then(addMissingModels);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return MissingModelDecorator;
|
||||
}
|
||||
);
|
||||
37
platform/features/events/bundle.json
Normal file
37
platform/features/events/bundle.json
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "Event Messages",
|
||||
"description": "List of time-ordered event messages",
|
||||
"extensions": {
|
||||
"views": [
|
||||
{
|
||||
"key": "messages",
|
||||
"name": "Messages",
|
||||
"glyph": "5",
|
||||
"description": "Scrolling list of messages.",
|
||||
"templateUrl": "templates/messages.html",
|
||||
"needs": [ "telemetry" ],
|
||||
"delegation": true
|
||||
}
|
||||
],
|
||||
"controllers": [
|
||||
{
|
||||
"key": "EventListController",
|
||||
"implementation": "EventListController.js",
|
||||
"depends": [ "$scope", "telemetryFormatter" ]
|
||||
}
|
||||
],
|
||||
"directives": [
|
||||
{
|
||||
"key": "mctDataTable",
|
||||
"implementation": "directives/MCTDataTable.js",
|
||||
"depends": [ "$window" ]
|
||||
}
|
||||
],
|
||||
"policies": [
|
||||
{
|
||||
"category": "view",
|
||||
"implementation": "policies/MessagesViewPolicy.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
37
platform/features/events/res/templates/mct-data-table.html
Normal file
37
platform/features/events/res/templates/mct-data-table.html
Normal file
@@ -0,0 +1,37 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<table class="tabular">
|
||||
<thead>
|
||||
<tr>
|
||||
<th ng-repeat="header in headers">
|
||||
{{header}}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="row in rows">
|
||||
<td ng-repeat="cell in row">
|
||||
{{cell}}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
29
platform/features/events/res/templates/messages.html
Normal file
29
platform/features/events/res/templates/messages.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<div class="w1" ng-controller="TelemetryController as telemetry">
|
||||
<div class="w2"
|
||||
ng-controller="EventListController">
|
||||
<mct-data-table headers="headers" rows="rows" ascending-scroll="true"></mct-data-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
67
platform/features/events/src/DomainColumn.js
Normal file
67
platform/features/events/src/DomainColumn.js
Normal file
@@ -0,0 +1,67 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,moment*/
|
||||
|
||||
/**
|
||||
* Module defining DomainColumn. Created by vwoeltje on 11/18/14.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* A column which will report telemetry domain values
|
||||
* (typically, timestamps.) Used by the ScrollingListController.
|
||||
*
|
||||
* @constructor
|
||||
* @param domainMetadata an object with the machine- and human-
|
||||
* readable names for this domain (in `key` and `name`
|
||||
* fields, respectively.)
|
||||
* @param {TelemetryFormatter} telemetryFormatter the telemetry
|
||||
* formatting service, for making values human-readable.
|
||||
*/
|
||||
function DomainColumn(domainMetadata, telemetryFormatter) {
|
||||
return {
|
||||
/**
|
||||
* Get the title to display in this column's header.
|
||||
* @returns {string} the title to display
|
||||
*/
|
||||
getTitle: function () {
|
||||
return domainMetadata.name;
|
||||
},
|
||||
/**
|
||||
* Get the text to display inside a row under this
|
||||
* column.
|
||||
* @returns {string} the text to display
|
||||
*/
|
||||
getValue: function (domainObject, data, index) {
|
||||
return telemetryFormatter.formatDomainValue(
|
||||
data.getDomainValue(index, domainMetadata.key)
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return DomainColumn;
|
||||
}
|
||||
);
|
||||
133
platform/features/events/src/EventListController.js
Normal file
133
platform/features/events/src/EventListController.js
Normal file
@@ -0,0 +1,133 @@
|
||||
/*****************************************************************************
|
||||
* 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*/
|
||||
|
||||
/**
|
||||
* Module defining EventListController.
|
||||
* Created by chacskaylo on 06/18/2015.
|
||||
* Modified by shale on 06/23/2015.
|
||||
*/
|
||||
define(
|
||||
["./DomainColumn", "./RangeColumn", "./EventListPopulator"],
|
||||
function (DomainColumn, RangeColumn, EventListPopulator) {
|
||||
"use strict";
|
||||
|
||||
var ROW_COUNT = 100;
|
||||
|
||||
/**
|
||||
* The EventListController is responsible for populating
|
||||
* the contents of the event list view.
|
||||
* @constructor
|
||||
*/
|
||||
function EventListController($scope, formatter) {
|
||||
var populator;
|
||||
|
||||
// Get a set of populated, ready-to-display rows for the
|
||||
// latest data values.
|
||||
function getRows(telemetry) {
|
||||
var datas = telemetry.getResponse(),
|
||||
objects = telemetry.getTelemetryObjects();
|
||||
|
||||
return populator.getRows(datas, objects, ROW_COUNT);
|
||||
}
|
||||
|
||||
// Update the contents
|
||||
function updateRows() {
|
||||
var telemetry = $scope.telemetry;
|
||||
$scope.rows = telemetry ? getRows(telemetry) : [];
|
||||
}
|
||||
|
||||
// Set up columns based on telemetry metadata. This will
|
||||
// include one column for each domain and range type, as
|
||||
// well as a column for the domain object name.
|
||||
function setupColumns(telemetry) {
|
||||
var domainKeys = {},
|
||||
rangeKeys = {},
|
||||
columns = [],
|
||||
metadata;
|
||||
|
||||
// Add a domain to the set of columns, if a domain
|
||||
// with the same key has not yet been inclued.
|
||||
function addDomain(domain) {
|
||||
var key = domain.key;
|
||||
if (key && !domainKeys[key]) {
|
||||
domainKeys[key] = true;
|
||||
columns.push(new DomainColumn(domain, formatter));
|
||||
}
|
||||
}
|
||||
|
||||
// Add a range col to the set of columns, if a range
|
||||
// with the same key has not yet been included.
|
||||
function addRange(range) {
|
||||
var key = range.key;
|
||||
if (key && !rangeKeys[key]) {
|
||||
rangeKeys[key] = true;
|
||||
columns.push(new RangeColumn(range, formatter));
|
||||
}
|
||||
}
|
||||
|
||||
// We cannot proceed if the telemetry controller
|
||||
// is not available; clear all rows/columns.
|
||||
if (!telemetry) {
|
||||
columns = [];
|
||||
$scope.rows = [];
|
||||
$scope.headers = [];
|
||||
return;
|
||||
}
|
||||
|
||||
// Add domain, range, event msg columns
|
||||
metadata = telemetry.getMetadata();
|
||||
(metadata || []).forEach(function (metadata) {
|
||||
(metadata.domains || []).forEach(addDomain);
|
||||
});
|
||||
(metadata || []).forEach(function (metadata) {
|
||||
(metadata.ranges || []).forEach(addRange);
|
||||
});
|
||||
|
||||
// Add default domain and range columns if none
|
||||
// were described in metadata.
|
||||
if (Object.keys(domainKeys).length < 1) {
|
||||
columns.push(new DomainColumn({name: "Time"}, formatter));
|
||||
}
|
||||
if (Object.keys(rangeKeys).length < 1) {
|
||||
columns.push(new RangeColumn({name: "Message"}, formatter));
|
||||
}
|
||||
|
||||
// We have all columns now; use them to initializer
|
||||
// the populator, which will use them to generate
|
||||
// actual rows and headers.
|
||||
populator = new EventListPopulator(columns);
|
||||
|
||||
// Initialize headers
|
||||
$scope.headers = populator.getHeaders();
|
||||
|
||||
// Fill in the contents of the rows.
|
||||
updateRows();
|
||||
}
|
||||
|
||||
$scope.$on("telemetryUpdate", updateRows);
|
||||
$scope.$watch("telemetry", setupColumns);
|
||||
}
|
||||
|
||||
return EventListController;
|
||||
}
|
||||
);
|
||||
161
platform/features/events/src/EventListPopulator.js
Normal file
161
platform/features/events/src/EventListPopulator.js
Normal file
@@ -0,0 +1,161 @@
|
||||
/*****************************************************************************
|
||||
* 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";
|
||||
|
||||
/**
|
||||
* The EventListPopulator is responsible for filling in the
|
||||
* values which should appear within columns of a event list
|
||||
* view, based on received telemetry data.
|
||||
* @constructor
|
||||
* @param {Column[]} columns the columns to be populated
|
||||
*/
|
||||
function EventListPopulator(columns) {
|
||||
/**
|
||||
* Look up the most recent values from a set of data objects.
|
||||
* Returns an array of objects in the order in which data
|
||||
* should be displayed; each element is an object with
|
||||
* two properties:
|
||||
*
|
||||
* * objectIndex: The index of the domain object associated
|
||||
* with the data point to be displayed in that
|
||||
* row.
|
||||
* * pointIndex: The index of the data point itself, within
|
||||
* its data set.
|
||||
*
|
||||
* @param {Array<Telemetry>} datas an array of the most recent
|
||||
* data objects; expected to be in the same order
|
||||
* as the domain objects provided at constructor
|
||||
* @param {number} count the number of rows to provide
|
||||
*/
|
||||
function getLatestDataValues(datas, count) {
|
||||
var latest = [],
|
||||
candidate,
|
||||
candidateTime,
|
||||
used = datas.map(function () { return 0; });
|
||||
|
||||
// This algorithm is O(nk) for n rows and k telemetry elements;
|
||||
// one O(k) linear search for a max is made for each of n rows.
|
||||
// This could be done in O(n lg k + k lg k), using a priority
|
||||
// queue (where priority is max-finding) containing k initial
|
||||
// values. For n rows, pop the max from the queue and replenish
|
||||
// the queue with a value from the data at the same
|
||||
// objectIndex, if available.
|
||||
// But k is small, so this might not give an observable
|
||||
// improvement in performance.
|
||||
|
||||
// Find the most recent unused data point (this will be used
|
||||
// in a loop to find and the N most recent data points)
|
||||
function findCandidate(data, i) {
|
||||
var nextTime,
|
||||
pointCount = data.getPointCount(),
|
||||
pointIndex = pointCount - used[i] - 1;
|
||||
if (data && pointIndex >= 0) {
|
||||
nextTime = data.getDomainValue(pointIndex);
|
||||
if (nextTime > candidateTime) {
|
||||
candidateTime = nextTime;
|
||||
candidate = {
|
||||
objectIndex: i,
|
||||
pointIndex: pointIndex
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assemble a list of the most recent data points
|
||||
while (latest.length < count) {
|
||||
// Reset variables pre-search
|
||||
candidateTime = Number.NEGATIVE_INFINITY;
|
||||
candidate = undefined;
|
||||
|
||||
// Linear search for most recent
|
||||
datas.forEach(findCandidate);
|
||||
|
||||
if (candidate) {
|
||||
// Record this data point - it is the most recent
|
||||
latest.push(candidate);
|
||||
|
||||
// Track the data points used so we can look farther back
|
||||
// in the data set on the next iteration
|
||||
used[candidate.objectIndex] = used[candidate.objectIndex] + 1;
|
||||
} else {
|
||||
// Ran out of candidates; not enough data points
|
||||
// available to fill all rows.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return latest;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
/**
|
||||
* Get the text which should appear in headers for the
|
||||
* provided columns.
|
||||
* @returns {string[]} column headers
|
||||
*/
|
||||
getHeaders: function () {
|
||||
return columns.map(function (column) {
|
||||
return column.getTitle();
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Get the contents of rows for the event list view.
|
||||
* @param {TelemetrySeries[]} datas the data sets
|
||||
* @param {DomainObject[]} objects the domain objects which
|
||||
* provided the data sets; these should match
|
||||
* index-to-index with the `datas` argument
|
||||
* @param {number} count the number of rows to populate
|
||||
* @returns {string[][]} an array of rows, each of which
|
||||
* is an array of values which should appear
|
||||
* in that row
|
||||
*/
|
||||
getRows: function (datas, objects, count) {
|
||||
var values = getLatestDataValues(datas, count);
|
||||
|
||||
// Each value will become a row, which will contain
|
||||
// some value in each column (rendering by the
|
||||
// column object itself)
|
||||
// Additionally, we want to display the rows in reverse
|
||||
// order. (i.e. from the top to the bottom of the page)
|
||||
return values.map(function (value) {
|
||||
return columns.map(function (column) {
|
||||
return column.getValue(
|
||||
objects[value.objectIndex],
|
||||
datas[value.objectIndex],
|
||||
value.pointIndex
|
||||
);
|
||||
});
|
||||
}).reverse();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return EventListPopulator;
|
||||
|
||||
}
|
||||
);
|
||||
67
platform/features/events/src/RangeColumn.js
Normal file
67
platform/features/events/src/RangeColumn.js
Normal file
@@ -0,0 +1,67 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,Promise*/
|
||||
|
||||
/**
|
||||
* Module defining DomainColumn. Created by vwoeltje on 11/18/14.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* A column which will report telemetry range values
|
||||
* (typically, measurements.) Used by the ScrollingListController.
|
||||
*
|
||||
* @constructor
|
||||
* @param rangeMetadata an object with the machine- and human-
|
||||
* readable names for this range (in `key` and `name`
|
||||
* fields, respectively.)
|
||||
* @param {TelemetryFormatter} telemetryFormatter the telemetry
|
||||
* formatting service, for making values human-readable.
|
||||
*/
|
||||
function RangeColumn(rangeMetadata, telemetryFormatter) {
|
||||
return {
|
||||
/**
|
||||
* Get the title to display in this column's header.
|
||||
* @returns {string} the title to display
|
||||
*/
|
||||
getTitle: function () {
|
||||
return rangeMetadata.name;
|
||||
},
|
||||
/**
|
||||
* Get the text to display inside a row under this
|
||||
* column.
|
||||
* @returns {string} the text to display
|
||||
*/
|
||||
getValue: function (domainObject, data, index) {
|
||||
return telemetryFormatter.formatRangeValue(
|
||||
data.getRangeValue(index, rangeMetadata.key)
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return RangeColumn;
|
||||
}
|
||||
);
|
||||
74
platform/features/events/src/directives/MCTDataTable.js
Normal file
74
platform/features/events/src/directives/MCTDataTable.js
Normal file
@@ -0,0 +1,74 @@
|
||||
/*****************************************************************************
|
||||
* 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*/
|
||||
|
||||
/**
|
||||
* Module defining MCTDataTable. Created by shale on 06/22/2015.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
function MCTDataTable($window) {
|
||||
return {
|
||||
restrict: "E",
|
||||
templateUrl: "platform/features/events/res/templates/mct-data-table.html",
|
||||
scope: {
|
||||
headers: "=",
|
||||
rows: "=",
|
||||
ascendingScroll: "="
|
||||
},
|
||||
link: function ($scope, $element) {
|
||||
var currentHeight,
|
||||
previousHeight,
|
||||
scrollParent;
|
||||
|
||||
// If the scroll is set to ascending, we want to
|
||||
// check when elements are added to the table, and move the scroll
|
||||
// bar accordingly.
|
||||
// (When viewing at the bottom of the page, the scroll bar will
|
||||
// stay at the bottom despite additions to the table)
|
||||
if ($scope.ascendingScroll) {
|
||||
$scope.$watch("rows", function () {
|
||||
// Wait until the page as been repainted (otherwise the
|
||||
// height will always be zero)
|
||||
$window.requestAnimationFrame(function () {
|
||||
previousHeight = currentHeight;
|
||||
// The height of the table body
|
||||
currentHeight = $element[0].firstElementChild.firstElementChild.nextElementSibling.clientHeight;
|
||||
|
||||
// One of the parents is a div that has vscroll
|
||||
scrollParent = $element[0].parentElement.parentElement.parentElement.parentElement.parentElement;
|
||||
|
||||
// Move the scrollbar down the amount that the height has changed
|
||||
scrollParent.scrollTop = scrollParent.scrollTop + (currentHeight - previousHeight);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return MCTDataTable;
|
||||
}
|
||||
);
|
||||
74
platform/features/events/src/policies/MessagesViewPolicy.js
Normal file
74
platform/features/events/src/policies/MessagesViewPolicy.js
Normal file
@@ -0,0 +1,74 @@
|
||||
/*****************************************************************************
|
||||
* 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*/
|
||||
|
||||
/**
|
||||
* Module defining MessagesViewPolicy. Created by shale on 06/24/2015.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Policy controlling when the Messages view should be avaliable.
|
||||
* @constructor
|
||||
*/
|
||||
function MessagesViewPolicy() {
|
||||
|
||||
function hasStringTelemetry(domainObject) {
|
||||
var telemetry = domainObject &&
|
||||
domainObject.getCapability('telemetry'),
|
||||
metadata = telemetry ? telemetry.getMetadata() : {},
|
||||
ranges = metadata.ranges || [];
|
||||
|
||||
return ranges.some(function (range) {
|
||||
return range.format === 'string';
|
||||
});
|
||||
}
|
||||
return {
|
||||
/**
|
||||
* Check whether or not a given action is allowed by this
|
||||
* policy.
|
||||
* @param {Action} action the action
|
||||
* @param domainObject the domain object which will be viewed
|
||||
* @returns {boolean} true if not disallowed
|
||||
*/
|
||||
allow: function (view, domainObject) {
|
||||
// This policy only applies for the Messages view
|
||||
if (view.key === 'messages') {
|
||||
// The Messages view is allowed only if the domain
|
||||
// object has string telemetry
|
||||
if (!hasStringTelemetry(domainObject)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Like all policies, allow by default.
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return MessagesViewPolicy;
|
||||
}
|
||||
);
|
||||
84
platform/features/events/test/DomainColumnSpec.js
Normal file
84
platform/features/events/test/DomainColumnSpec.js
Normal file
@@ -0,0 +1,84 @@
|
||||
/*****************************************************************************
|
||||
* 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,describe,it,expect,beforeEach,waitsFor,jasmine*/
|
||||
|
||||
/**
|
||||
* EventSpec. Created by vwoeltje on 11/6/14. Modified by shale on 06/23/2015.
|
||||
*/
|
||||
define(
|
||||
["../src/DomainColumn"],
|
||||
function (DomainColumn) {
|
||||
"use strict";
|
||||
|
||||
var TEST_DOMAIN_VALUE = "some formatted domain value";
|
||||
|
||||
describe("An event list domain column", function () {
|
||||
var mockDataSet,
|
||||
testMetadata,
|
||||
mockFormatter,
|
||||
column;
|
||||
|
||||
beforeEach(function () {
|
||||
mockDataSet = jasmine.createSpyObj(
|
||||
"data",
|
||||
[ "getDomainValue" ]
|
||||
);
|
||||
mockFormatter = jasmine.createSpyObj(
|
||||
"formatter",
|
||||
[ "formatDomainValue", "formatRangeValue" ]
|
||||
);
|
||||
testMetadata = {
|
||||
key: "testKey",
|
||||
name: "Test Name"
|
||||
};
|
||||
mockFormatter.formatDomainValue.andReturn(TEST_DOMAIN_VALUE);
|
||||
|
||||
column = new DomainColumn(testMetadata, mockFormatter);
|
||||
});
|
||||
|
||||
it("reports a column header from domain metadata", function () {
|
||||
expect(column.getTitle()).toEqual("Test Name");
|
||||
});
|
||||
|
||||
it("looks up data from a data set", function () {
|
||||
column.getValue(undefined, mockDataSet, 42);
|
||||
expect(mockDataSet.getDomainValue)
|
||||
.toHaveBeenCalledWith(42, "testKey");
|
||||
});
|
||||
|
||||
it("formats domain values as time", function () {
|
||||
mockDataSet.getDomainValue.andReturn(402513731000);
|
||||
|
||||
// Should have just given the value the formatter gave
|
||||
expect(column.getValue(undefined, mockDataSet, 42))
|
||||
.toEqual(TEST_DOMAIN_VALUE);
|
||||
|
||||
// Make sure that service interactions were as expected
|
||||
expect(mockFormatter.formatDomainValue)
|
||||
.toHaveBeenCalledWith(402513731000);
|
||||
expect(mockFormatter.formatRangeValue)
|
||||
.not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
110
platform/features/events/test/EventListControllerSpec.js
Normal file
110
platform/features/events/test/EventListControllerSpec.js
Normal file
@@ -0,0 +1,110 @@
|
||||
/*****************************************************************************
|
||||
* 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,describe,it,expect,beforeEach,waitsFor,jasmine*/
|
||||
|
||||
/**
|
||||
* EventSpec. Created by shale on 06/24/2015.
|
||||
*/
|
||||
define(
|
||||
["../src/EventListController"],
|
||||
function (EventListController) {
|
||||
"use strict";
|
||||
|
||||
describe("The event list controller", function () {
|
||||
var mockScope,
|
||||
mockTelemetry,
|
||||
testMetadata,
|
||||
controller;
|
||||
|
||||
beforeEach(function () {
|
||||
mockScope = jasmine.createSpyObj(
|
||||
"$scope",
|
||||
[ "$on", "$watch" ]
|
||||
);
|
||||
mockTelemetry = jasmine.createSpyObj(
|
||||
"telemetryController",
|
||||
[ "getResponse", "getMetadata", "getTelemetryObjects" ]
|
||||
);
|
||||
testMetadata = [
|
||||
{
|
||||
domains: [
|
||||
{ key: "d0", name: "D0" },
|
||||
{ key: "d1", name: "D1" }
|
||||
],
|
||||
ranges: [
|
||||
{ key: "r0", name: "R0" },
|
||||
{ key: "r1", name: "R1" }
|
||||
]
|
||||
},
|
||||
{
|
||||
domains: [
|
||||
{ key: "d0", name: "D0" },
|
||||
{ key: "d2", name: "D2" }
|
||||
],
|
||||
ranges: [
|
||||
{ key: "r0", name: "R0" }
|
||||
]
|
||||
}
|
||||
];
|
||||
mockTelemetry.getMetadata.andReturn(testMetadata);
|
||||
mockTelemetry.getResponse.andReturn([]);
|
||||
mockTelemetry.getTelemetryObjects.andReturn([]);
|
||||
mockScope.telemetry = mockTelemetry;
|
||||
controller = new EventListController(mockScope);
|
||||
});
|
||||
|
||||
it("listens for telemetry data updates", function () {
|
||||
expect(mockScope.$on).toHaveBeenCalledWith(
|
||||
"telemetryUpdate",
|
||||
jasmine.any(Function)
|
||||
);
|
||||
});
|
||||
|
||||
it("watches for telemetry controller changes", function () {
|
||||
expect(mockScope.$watch).toHaveBeenCalledWith(
|
||||
"telemetry",
|
||||
jasmine.any(Function)
|
||||
);
|
||||
});
|
||||
|
||||
it("provides a column for each unique domain and range", function () {
|
||||
// Should have five columns based on metadata above,
|
||||
// (d0, d1, d2, r0, r1)
|
||||
mockScope.$watch.mostRecentCall.args[1](mockTelemetry);
|
||||
expect(mockScope.headers).toEqual(["D0", "D1", "D2", "R0", "R1"]);
|
||||
});
|
||||
|
||||
it("does not throw if telemetry controller is undefined", function () {
|
||||
// Just a general robustness check
|
||||
mockScope.telemetry = undefined;
|
||||
expect(mockScope.$watch.mostRecentCall.args[1])
|
||||
.not.toThrow();
|
||||
});
|
||||
|
||||
it("provides default columns if domain/range metadata is unavailable", function () {
|
||||
mockTelemetry.getMetadata.andReturn([]);
|
||||
mockScope.$watch.mostRecentCall.args[1](mockTelemetry);
|
||||
expect(mockScope.headers).toEqual(["Time", "Message"]);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
103
platform/features/events/test/EventListPopulatorSpec.js
Normal file
103
platform/features/events/test/EventListPopulatorSpec.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,describe,it,expect,beforeEach,waitsFor,jasmine*/
|
||||
|
||||
/**
|
||||
* EventSpec. Created by shale on 06/24/2015.
|
||||
*/
|
||||
define(
|
||||
["../src/EventListPopulator"],
|
||||
function (EventListPopulator) {
|
||||
"use strict";
|
||||
|
||||
describe("The event list populator", function () {
|
||||
var mockColumns,
|
||||
mockDatas,
|
||||
mockDomainObjects,
|
||||
populator;
|
||||
|
||||
function makeMockColumn(name, index) {
|
||||
var mockColumn = jasmine.createSpyObj(
|
||||
"column" + index,
|
||||
[ "getTitle", "getValue" ]
|
||||
);
|
||||
mockColumn.getTitle.andReturn(name);
|
||||
mockColumn.getValue.andCallFake(function (obj, data, i) {
|
||||
return data.getDomainValue(i);
|
||||
});
|
||||
return mockColumn;
|
||||
}
|
||||
|
||||
function makeMockData(bias, index) {
|
||||
var mockData = jasmine.createSpyObj(
|
||||
"data" + index,
|
||||
[ "getDomainValue", "getPointCount" ]
|
||||
);
|
||||
mockData.getPointCount.andReturn(1000);
|
||||
mockData.getDomainValue.andCallFake(function (i) {
|
||||
return i + bias;
|
||||
});
|
||||
return mockData;
|
||||
}
|
||||
|
||||
function makeMockDomainObject(name, index) {
|
||||
var mockDomainObject = jasmine.createSpyObj(
|
||||
"domainObject" + index,
|
||||
[ "getId", "getModel" ]
|
||||
);
|
||||
return mockDomainObject;
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
mockColumns = ["A", "B", "C", "D"].map(makeMockColumn);
|
||||
mockDatas = [ 10, 0, 3 ].map(makeMockData);
|
||||
mockDomainObjects = ["A", "B", "C"].map(makeMockDomainObject);
|
||||
populator = new EventListPopulator(mockColumns);
|
||||
});
|
||||
|
||||
it("returns column headers", function () {
|
||||
expect(populator.getHeaders()).toEqual(["A", "B", "C", "D"]);
|
||||
});
|
||||
|
||||
it("provides rows on request, with all columns in each row", function () {
|
||||
var rows = populator.getRows(mockDatas, mockDomainObjects, 84);
|
||||
expect(rows.length).toEqual(84);
|
||||
rows.forEach(function (row) {
|
||||
expect(row.length).toEqual(4); // number of columns
|
||||
});
|
||||
});
|
||||
|
||||
it("returns rows in most-recent-last order", function () {
|
||||
var rows = populator.getRows(mockDatas, mockDomainObjects, 84),
|
||||
previous = Number.NEGATIVE_INFINITY;
|
||||
|
||||
// Should always be most-recent-last
|
||||
rows.forEach(function (row) {
|
||||
expect(row[0]).not.toBeLessThan(previous);
|
||||
previous = row[0];
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
81
platform/features/events/test/RangeColumnSpec.js
Normal file
81
platform/features/events/test/RangeColumnSpec.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,describe,it,expect,beforeEach,waitsFor,jasmine*/
|
||||
|
||||
/**
|
||||
* EventSpec. Created by vwoeltje on 11/6/14. Modified by shale on 06/23/2015.
|
||||
*/
|
||||
define(
|
||||
["../src/RangeColumn"],
|
||||
function (RangeColumn) {
|
||||
"use strict";
|
||||
|
||||
var TEST_RANGE_VALUE = "some formatted range value";
|
||||
|
||||
describe("An event list range column", function () {
|
||||
var mockDataSet,
|
||||
testMetadata,
|
||||
mockFormatter,
|
||||
column;
|
||||
|
||||
beforeEach(function () {
|
||||
mockDataSet = jasmine.createSpyObj(
|
||||
"data",
|
||||
[ "getRangeValue" ]
|
||||
);
|
||||
mockFormatter = jasmine.createSpyObj(
|
||||
"formatter",
|
||||
[ "formatDomainValue", "formatRangeValue" ]
|
||||
);
|
||||
testMetadata = {
|
||||
key: "testKey",
|
||||
name: "Test Name"
|
||||
};
|
||||
mockFormatter.formatRangeValue.andReturn(TEST_RANGE_VALUE);
|
||||
|
||||
column = new RangeColumn(testMetadata, mockFormatter);
|
||||
});
|
||||
|
||||
it("reports a column header from range metadata", function () {
|
||||
expect(column.getTitle()).toEqual("Test Name");
|
||||
});
|
||||
|
||||
it("looks up data from a data set", function () {
|
||||
column.getValue(undefined, mockDataSet, 42);
|
||||
expect(mockDataSet.getRangeValue)
|
||||
.toHaveBeenCalledWith(42, "testKey");
|
||||
});
|
||||
|
||||
it("formats range values as time", function () {
|
||||
mockDataSet.getRangeValue.andReturn(123.45678);
|
||||
expect(column.getValue(undefined, mockDataSet, 42))
|
||||
.toEqual(TEST_RANGE_VALUE);
|
||||
|
||||
// Make sure that service interactions were as expected
|
||||
expect(mockFormatter.formatRangeValue)
|
||||
.toHaveBeenCalledWith(123.45678);
|
||||
expect(mockFormatter.formatDomainValue)
|
||||
.not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -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,describe,it,expect,beforeEach,jasmine*/
|
||||
|
||||
/**
|
||||
* EventSpec. Created by shale on 06/24/2015.
|
||||
*/
|
||||
define(
|
||||
["../../src/policies/MessagesViewPolicy"],
|
||||
function (MessagesViewPolicy) {
|
||||
"use strict";
|
||||
|
||||
describe("The messages view policy", function () {
|
||||
var mockDomainObject,
|
||||
mockTelemetry,
|
||||
telemetryType,
|
||||
testType,
|
||||
testView,
|
||||
testMetadata,
|
||||
policy;
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
testView = { key: "string" };
|
||||
testMetadata = {};
|
||||
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
'domainObject',
|
||||
['getModel', 'getCapability']
|
||||
);
|
||||
mockTelemetry = jasmine.createSpyObj(
|
||||
'telemetry',
|
||||
['getMetadata']
|
||||
);
|
||||
|
||||
mockDomainObject.getModel.andCallFake(function (c) {
|
||||
return {type: testType};
|
||||
});
|
||||
mockDomainObject.getCapability.andCallFake(function (c) {
|
||||
return c === 'telemetry' ? mockTelemetry : undefined;
|
||||
});
|
||||
mockTelemetry.getMetadata.andReturn(testMetadata);
|
||||
|
||||
policy = new MessagesViewPolicy();
|
||||
});
|
||||
|
||||
it("disallows the message view for objects without string telemetry", function () {
|
||||
testMetadata.ranges = [ { format: 'notString' } ];
|
||||
expect(policy.allow({ key: 'messages' }, mockDomainObject)).toBeFalsy();
|
||||
});
|
||||
|
||||
it("allows the message view for objects with string telemetry", function () {
|
||||
testMetadata.ranges = [ { format: 'string' } ];
|
||||
expect(policy.allow({ key: 'messages' }, mockDomainObject)).toBeTruthy();
|
||||
});
|
||||
|
||||
it("returns true when the current view is not the Messages view", function () {
|
||||
expect(policy.allow({ key: 'notMessages' }, mockDomainObject)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
7
platform/features/events/test/suite.json
Normal file
7
platform/features/events/test/suite.json
Normal file
@@ -0,0 +1,7 @@
|
||||
[
|
||||
"DomainColumn",
|
||||
"EventListController",
|
||||
"EventListPopulator",
|
||||
"policies/MessagesViewPolicy",
|
||||
"RangeColumn"
|
||||
]
|
||||
35
platform/features/imagery/bundle.json
Normal file
35
platform/features/imagery/bundle.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "Plot view for telemetry",
|
||||
"extensions": {
|
||||
"views": [
|
||||
{
|
||||
"name": "Imagery",
|
||||
"key": "imagery",
|
||||
"glyph": "\u00E3",
|
||||
"templateUrl": "templates/imagery.html",
|
||||
"priority": "preferred",
|
||||
"needs": [ "telemetry" ]
|
||||
}
|
||||
],
|
||||
"policies": [
|
||||
{
|
||||
"category": "view",
|
||||
"implementation": "policies/ImageryViewPolicy.js"
|
||||
}
|
||||
],
|
||||
"controllers": [
|
||||
{
|
||||
"key": "ImageryController",
|
||||
"implementation": "controllers/ImageryController.js",
|
||||
"depends": [ "$scope", "telemetryHandler" ]
|
||||
}
|
||||
],
|
||||
"directives": [
|
||||
{
|
||||
"key": "mctBackgroundImage",
|
||||
"implementation": "directives/MCTBackgroundImage.js",
|
||||
"depends": [ "$document" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
67
platform/features/imagery/res/templates/imagery.html
Normal file
67
platform/features/imagery/res/templates/imagery.html
Normal file
@@ -0,0 +1,67 @@
|
||||
<div class="t-imagery" ng-controller="ImageryController as imagery">
|
||||
<!-- Main image -->
|
||||
<div
|
||||
class="l-image-main-wrapper"
|
||||
ng-mouseenter="showLocalControls = true;"
|
||||
ng-mouseleave="showLocalControls = false;"
|
||||
>
|
||||
<div
|
||||
class="l-local-controls s-local-controls"
|
||||
ng-show="false && showLocalControls"
|
||||
>
|
||||
<a
|
||||
class="t-btn l-btn s-btn s-icon-btn s-very-subtle"
|
||||
ng-click="plot.stepBackPanZoom()"
|
||||
ng-show="1"
|
||||
title="Restore previous pan/zoom">
|
||||
<span class="ui-symbol icon"><</span>
|
||||
</a>
|
||||
|
||||
<a
|
||||
class="t-btn l-btn s-btn s-icon-btn s-very-subtle"
|
||||
ng-click="plot.unzoom()"
|
||||
ng-show="1"
|
||||
title="Reset pan/zoom">
|
||||
<span class="ui-symbol icon">I</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="l-image-main s-image-main"
|
||||
ng-class="{ paused: imagery.paused(), stale:false }"
|
||||
mct-background-image="imagery.getImageUrl()"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="l-image-main-controlbar bar">
|
||||
<div class="left">
|
||||
<a
|
||||
class="t-btn l-btn s-btn s-icon-btn s-very-subtle show-thumbs sm"
|
||||
ng-click="showThumbsBubble = (showThumbsBubble)? false:true"
|
||||
><span class="ui-symbol icon"></span></a>
|
||||
<span class="l-timezone">{{imagery.getZone()}}</span>
|
||||
<span class="l-time">{{imagery.getTime()}}</span>
|
||||
<span class="l-date">{{imagery.getDate()}}</span>
|
||||
</div>
|
||||
<div class="right">
|
||||
<a
|
||||
class="t-btn l-btn s-btn s-icon-btn s-very-subtle pause-play sm"
|
||||
ng-click="imagery.paused(!imagery.paused())"
|
||||
ng-class="{ paused: imagery.paused() }"
|
||||
><span class="ui-symbol icon"></span></a>
|
||||
<a href="{{imagery.getImageUrl()}}"
|
||||
ng-if="imagery.getImageUrl()"
|
||||
target="_blank"
|
||||
title="Open image in new tab."
|
||||
class="t-btn l-btn s-btn s-icon-btn s-very-subtle sm">
|
||||
<span class="ui-symbol icon">y</span></a>
|
||||
<a href=""
|
||||
class="l-btn s-btn s-icon-btn l-mag s-mag ui-symbol vsm"
|
||||
ng-click="clipped = false"
|
||||
ng-show="clipped === true"
|
||||
title="Not all of image is visible; click to reset."
|
||||
></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
133
platform/features/imagery/src/controllers/ImageryController.js
Normal file
133
platform/features/imagery/src/controllers/ImageryController.js
Normal file
@@ -0,0 +1,133 @@
|
||||
/*****************************************************************************
|
||||
* 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(
|
||||
['moment'],
|
||||
function (moment) {
|
||||
"use strict";
|
||||
|
||||
var DATE_FORMAT = "YYYY-MM-DD",
|
||||
TIME_FORMAT = "HH:mm:ss.SSS";
|
||||
|
||||
/**
|
||||
* Controller for the "Imagery" view of a domain object which
|
||||
* provides image telemetry.
|
||||
*/
|
||||
function ImageryController($scope, telemetryHandler) {
|
||||
var date = "",
|
||||
time = "",
|
||||
imageUrl = "",
|
||||
paused = false,
|
||||
handle;
|
||||
|
||||
function releaseSubscription() {
|
||||
if (handle) {
|
||||
handle.unsubscribe();
|
||||
handle = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function updateValues() {
|
||||
var imageObject = handle && handle.getTelemetryObjects()[0],
|
||||
m;
|
||||
if (imageObject && !paused) {
|
||||
m = moment.utc(handle.getDomainValue(imageObject));
|
||||
date = m.format(DATE_FORMAT);
|
||||
time = m.format(TIME_FORMAT);
|
||||
imageUrl = handle.getRangeValue(imageObject);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new subscription; telemetrySubscriber gets
|
||||
// to do the meaningful work here.
|
||||
function subscribe(domainObject) {
|
||||
releaseSubscription();
|
||||
date = "";
|
||||
time = "";
|
||||
imageUrl = "";
|
||||
handle = domainObject && telemetryHandler.handle(
|
||||
domainObject,
|
||||
updateValues,
|
||||
true // Lossless
|
||||
);
|
||||
}
|
||||
|
||||
// Subscribe to telemetry when a domain object becomes available
|
||||
$scope.$watch('domainObject', subscribe);
|
||||
|
||||
// Unsubscribe when the plot is destroyed
|
||||
$scope.$on("$destroy", releaseSubscription);
|
||||
|
||||
return {
|
||||
/**
|
||||
* Get the time portion (hours, minutes, seconds) of the
|
||||
* timestamp associated with the incoming image telemetry.
|
||||
* @returns {string} the time
|
||||
*/
|
||||
getTime: function () {
|
||||
return time;
|
||||
},
|
||||
/**
|
||||
* Get the date portion (month, year) of the
|
||||
* timestamp associated with the incoming image telemetry.
|
||||
* @returns {string} the date
|
||||
*/
|
||||
getDate: function () {
|
||||
return date;
|
||||
},
|
||||
/**
|
||||
* Get the time zone for the displayed time/date corresponding
|
||||
* to the timestamp associated with the incoming image
|
||||
* telemetry.
|
||||
* @returns {string} the time
|
||||
*/
|
||||
getZone: function () {
|
||||
return "UTC";
|
||||
},
|
||||
/**
|
||||
* Get the URL of the image telemetry to display.
|
||||
* @returns {string} URL for telemetry image
|
||||
*/
|
||||
getImageUrl: function () {
|
||||
return imageUrl;
|
||||
},
|
||||
/**
|
||||
* Getter-setter for paused state of the view (true means
|
||||
* paused, false means not.)
|
||||
* @param {boolean} [state] the state to set
|
||||
* @returns {boolean} the current state
|
||||
*/
|
||||
paused: function (state) {
|
||||
if (arguments.length > 0 && state !== paused) {
|
||||
paused = state;
|
||||
// Switch to latest image
|
||||
updateValues();
|
||||
}
|
||||
return paused;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return ImageryController;
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,89 @@
|
||||
/*****************************************************************************
|
||||
* 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";
|
||||
|
||||
/**
|
||||
* Defines the `mct-background-image` directive.
|
||||
*
|
||||
* Used as an attribute, this will set the `background-image`
|
||||
* property to the URL given in its value, but only after that
|
||||
* image has loaded; this avoids "flashing" as images change.
|
||||
*
|
||||
* If `src` is falsy, no image will be displayed (immediately.)
|
||||
*
|
||||
*/
|
||||
function MCTBackgroundImage($document) {
|
||||
function link(scope, element, attrs) {
|
||||
// General strategy here:
|
||||
// - Keep count of how many images have been requested; this
|
||||
// counter will be used as an internal identifier or sorts
|
||||
// for each image that loads.
|
||||
// - As the src attribute changes, begin loading those images.
|
||||
// - When images do load, update the background-image property
|
||||
// of the element, but only if a more recently
|
||||
// requested image has not already been loaded.
|
||||
// The order in which URLs are passed in and the order
|
||||
// in which images are actually loaded may be different, so
|
||||
// some strategy like this is necessary to ensure that images
|
||||
// do not display out-of-order.
|
||||
var div, requested = 0, loaded = 0;
|
||||
|
||||
function nextImage(url) {
|
||||
var myCounter = requested,
|
||||
image;
|
||||
|
||||
function useImage() {
|
||||
if (loaded <= myCounter) {
|
||||
loaded = myCounter;
|
||||
element.css('background-image', "url('" + url + "')");
|
||||
}
|
||||
}
|
||||
|
||||
if (!url) {
|
||||
loaded = myCounter;
|
||||
element.css('background-image', undefined);
|
||||
} else {
|
||||
image = $document[0].createElement('img');
|
||||
image.src = url;
|
||||
image.onload = useImage;
|
||||
}
|
||||
|
||||
requested += 1;
|
||||
}
|
||||
|
||||
scope.$watch('mctBackgroundImage', nextImage);
|
||||
}
|
||||
|
||||
return {
|
||||
restrict: "A",
|
||||
scope: { mctBackgroundImage: "=" },
|
||||
link: link
|
||||
};
|
||||
}
|
||||
|
||||
return MCTBackgroundImage;
|
||||
}
|
||||
);
|
||||
59
platform/features/imagery/src/policies/ImageryViewPolicy.js
Normal file
59
platform/features/imagery/src/policies/ImageryViewPolicy.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*/
|
||||
|
||||
define(
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Policy preventing the Imagery view from being made available for
|
||||
* domain objects which do not have associated image telemetry.
|
||||
* @implements {Policy}
|
||||
*/
|
||||
function ImageryViewPolicy() {
|
||||
function hasImageTelemetry(domainObject) {
|
||||
var telemetry = domainObject &&
|
||||
domainObject.getCapability('telemetry'),
|
||||
metadata = telemetry ? telemetry.getMetadata() : {},
|
||||
ranges = metadata.ranges || [];
|
||||
|
||||
return ranges.some(function (range) {
|
||||
return range.format === 'imageUrl' ||
|
||||
range.format === 'image';
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
allow: function (view, domainObject) {
|
||||
if (view.key === 'imagery') {
|
||||
return hasImageTelemetry(domainObject);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return ImageryViewPolicy;
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,152 @@
|
||||
/*****************************************************************************
|
||||
* 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,describe,it,expect,beforeEach,jasmine,xit*/
|
||||
|
||||
define(
|
||||
["../../src/controllers/ImageryController"],
|
||||
function (ImageryController) {
|
||||
"use strict";
|
||||
|
||||
describe("The Imagery controller", function () {
|
||||
var mockScope,
|
||||
mockTelemetryHandler,
|
||||
mockHandle,
|
||||
mockDomainObject,
|
||||
controller;
|
||||
|
||||
function invokeWatch(expr, value) {
|
||||
mockScope.$watch.calls.forEach(function (call) {
|
||||
if (call.args[0] === expr) {
|
||||
call.args[1](value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
mockScope = jasmine.createSpyObj('$scope', ['$on', '$watch']);
|
||||
mockTelemetryHandler = jasmine.createSpyObj(
|
||||
'telemetryHandler',
|
||||
['handle']
|
||||
);
|
||||
mockHandle = jasmine.createSpyObj(
|
||||
'handle',
|
||||
[
|
||||
'getDomainValue',
|
||||
'getRangeValue',
|
||||
'getTelemetryObjects',
|
||||
'unsubscribe'
|
||||
]
|
||||
);
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
'domainObject',
|
||||
['getId', 'getModel', 'getCapability']
|
||||
);
|
||||
|
||||
mockTelemetryHandler.handle.andReturn(mockHandle);
|
||||
mockHandle.getTelemetryObjects.andReturn([mockDomainObject]);
|
||||
|
||||
controller = new ImageryController(
|
||||
mockScope,
|
||||
mockTelemetryHandler
|
||||
);
|
||||
invokeWatch('domainObject', mockDomainObject);
|
||||
});
|
||||
|
||||
it("unsubscribes when scope is destroyed", function () {
|
||||
expect(mockHandle.unsubscribe).not.toHaveBeenCalled();
|
||||
|
||||
// Find the $destroy listener and call it
|
||||
mockScope.$on.calls.forEach(function (call) {
|
||||
if (call.args[0] === '$destroy') {
|
||||
call.args[1]();
|
||||
}
|
||||
});
|
||||
expect(mockHandle.unsubscribe).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("exposes the latest telemetry values", function () {
|
||||
// 06/18/2015 4:04am UTC
|
||||
var testTimestamp = 1434600258123,
|
||||
testUrl = "some/url",
|
||||
nextTimestamp = 1434600259456, // 4:05.456
|
||||
nextUrl = "some/other/url";
|
||||
|
||||
mockHandle.getDomainValue.andReturn(testTimestamp);
|
||||
mockHandle.getRangeValue.andReturn(testUrl);
|
||||
|
||||
// Call the subscription listener
|
||||
mockTelemetryHandler.handle.mostRecentCall.args[1]();
|
||||
|
||||
expect(controller.getTime()).toEqual("04:04:18.123");
|
||||
expect(controller.getDate()).toEqual("2015-06-18");
|
||||
expect(controller.getZone()).toEqual("UTC");
|
||||
expect(controller.getImageUrl()).toEqual(testUrl);
|
||||
|
||||
mockHandle.getDomainValue.andReturn(nextTimestamp);
|
||||
mockHandle.getRangeValue.andReturn(nextUrl);
|
||||
mockTelemetryHandler.handle.mostRecentCall.args[1]();
|
||||
|
||||
expect(controller.getTime()).toEqual("04:04:19.456");
|
||||
expect(controller.getDate()).toEqual("2015-06-18");
|
||||
expect(controller.getZone()).toEqual("UTC");
|
||||
expect(controller.getImageUrl()).toEqual(nextUrl);
|
||||
});
|
||||
|
||||
it("allows updates to be paused", function () {
|
||||
// 06/18/2015 4:04am UTC
|
||||
var testTimestamp = 1434600258123,
|
||||
testUrl = "some/url",
|
||||
nextTimestamp = 1434600259456, // 4:05.456
|
||||
nextUrl = "some/other/url";
|
||||
|
||||
// As above, but pause in between. Expect details
|
||||
// not to change this time
|
||||
|
||||
mockHandle.getDomainValue.andReturn(testTimestamp);
|
||||
mockHandle.getRangeValue.andReturn(testUrl);
|
||||
|
||||
// Call the subscription listener
|
||||
mockTelemetryHandler.handle.mostRecentCall.args[1]();
|
||||
|
||||
expect(controller.getTime()).toEqual("04:04:18.123");
|
||||
expect(controller.getDate()).toEqual("2015-06-18");
|
||||
expect(controller.getZone()).toEqual("UTC");
|
||||
expect(controller.getImageUrl()).toEqual(testUrl);
|
||||
|
||||
expect(controller.paused()).toBeFalsy();
|
||||
controller.paused(true); // Pause!
|
||||
expect(controller.paused()).toBeTruthy();
|
||||
|
||||
mockHandle.getDomainValue.andReturn(nextTimestamp);
|
||||
mockHandle.getRangeValue.andReturn(nextUrl);
|
||||
mockTelemetryHandler.handle.mostRecentCall.args[1]();
|
||||
|
||||
expect(controller.getTime()).toEqual("04:04:18.123");
|
||||
expect(controller.getDate()).toEqual("2015-06-18");
|
||||
expect(controller.getZone()).toEqual("UTC");
|
||||
expect(controller.getImageUrl()).toEqual(testUrl);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*****************************************************************************
|
||||
* 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,describe,it,expect,beforeEach,jasmine,xit*/
|
||||
|
||||
define(
|
||||
["../../src/directives/MCTBackgroundImage"],
|
||||
function (MCTBackgroundImage) {
|
||||
"use strict";
|
||||
|
||||
describe("The mct-background-image directive", function () {
|
||||
var mockDocument,
|
||||
mockScope,
|
||||
mockElement,
|
||||
testImage,
|
||||
directive;
|
||||
|
||||
beforeEach(function () {
|
||||
mockDocument = [
|
||||
jasmine.createSpyObj('document', ['createElement'])
|
||||
];
|
||||
mockScope = jasmine.createSpyObj('scope', ['$watch']);
|
||||
mockElement = jasmine.createSpyObj('element', [ 'css' ]);
|
||||
testImage = {};
|
||||
|
||||
mockDocument[0].createElement.andReturn(testImage);
|
||||
|
||||
directive = new MCTBackgroundImage(mockDocument);
|
||||
});
|
||||
|
||||
it("is applicable as an attribute", function () {
|
||||
expect(directive.restrict).toEqual("A");
|
||||
});
|
||||
|
||||
it("two-way-binds its own value", function () {
|
||||
expect(directive.scope.mctBackgroundImage).toEqual("=");
|
||||
});
|
||||
|
||||
it("watches for changes to the URL", function () {
|
||||
directive.link(mockScope, mockElement, {});
|
||||
expect(mockScope.$watch).toHaveBeenCalledWith(
|
||||
'mctBackgroundImage',
|
||||
jasmine.any(Function)
|
||||
);
|
||||
});
|
||||
|
||||
it("updates images in-order, even when they load out-of-order", function () {
|
||||
var firstOnload;
|
||||
|
||||
directive.link(mockScope, mockElement);
|
||||
|
||||
mockScope.$watch.mostRecentCall.args[1]("some/url/0");
|
||||
firstOnload = testImage.onload;
|
||||
|
||||
mockScope.$watch.mostRecentCall.args[1]("some/url/1");
|
||||
|
||||
// Resolve in a different order
|
||||
testImage.onload();
|
||||
firstOnload();
|
||||
|
||||
// Should still have taken the more recent value
|
||||
expect(mockElement.css.mostRecentCall.args).toEqual([
|
||||
"background-image",
|
||||
"url('some/url/1')"
|
||||
]);
|
||||
});
|
||||
|
||||
it("clears the background image when undefined is passed in", function () {
|
||||
directive.link(mockScope, mockElement);
|
||||
|
||||
mockScope.$watch.mostRecentCall.args[1]("some/url/0");
|
||||
testImage.onload();
|
||||
mockScope.$watch.mostRecentCall.args[1](undefined);
|
||||
|
||||
expect(mockElement.css.mostRecentCall.args).toEqual([
|
||||
"background-image",
|
||||
undefined
|
||||
]);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
/*****************************************************************************
|
||||
* 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,describe,it,expect,beforeEach,jasmine,xit*/
|
||||
|
||||
define(
|
||||
["../../src/policies/ImageryViewPolicy"],
|
||||
function (ImageryViewPolicy) {
|
||||
"use strict";
|
||||
|
||||
describe("Imagery view policy", function () {
|
||||
var testView,
|
||||
mockDomainObject,
|
||||
mockTelemetry,
|
||||
testMetadata,
|
||||
policy;
|
||||
|
||||
beforeEach(function () {
|
||||
testView = { key: "imagery" };
|
||||
testMetadata = {};
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
'domainObject',
|
||||
['getId', 'getModel', 'getCapability']
|
||||
);
|
||||
mockTelemetry = jasmine.createSpyObj(
|
||||
'telemetry',
|
||||
['getMetadata']
|
||||
);
|
||||
mockDomainObject.getCapability.andCallFake(function (c) {
|
||||
return c === 'telemetry' ? mockTelemetry : undefined;
|
||||
});
|
||||
mockTelemetry.getMetadata.andReturn(testMetadata);
|
||||
|
||||
policy = new ImageryViewPolicy();
|
||||
});
|
||||
|
||||
it("allows the imagery view for domain objects with image telemetry", function () {
|
||||
testMetadata.ranges = [ { key: "foo", format: "imageUrl" } ];
|
||||
expect(policy.allow(testView, mockDomainObject)).toBeTruthy();
|
||||
});
|
||||
|
||||
it("disallows the imagery view for domain objects without image telemetry", function () {
|
||||
testMetadata.ranges = [ { key: "foo", format: "somethingElse" } ];
|
||||
expect(policy.allow(testView, mockDomainObject)).toBeFalsy();
|
||||
});
|
||||
|
||||
it("disallows the imagery view for domain objects without telemetry", function () {
|
||||
testMetadata.ranges = [ { key: "foo", format: "imageUrl" } ];
|
||||
mockDomainObject.getCapability.andReturn(undefined);
|
||||
expect(policy.allow(testView, mockDomainObject)).toBeFalsy();
|
||||
});
|
||||
|
||||
it("allows other views", function () {
|
||||
testView.key = "somethingElse";
|
||||
testMetadata.ranges = [ { key: "foo", format: "somethingElse" } ];
|
||||
expect(policy.allow(testView, mockDomainObject)).toBeTruthy();
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
5
platform/features/imagery/test/suite.json
Normal file
5
platform/features/imagery/test/suite.json
Normal file
@@ -0,0 +1,5 @@
|
||||
[
|
||||
"controllers/ImageryController",
|
||||
"directives/MCTBackgroundImage",
|
||||
"policies/ImageryViewPolicy"
|
||||
]
|
||||
@@ -23,16 +23,17 @@
|
||||
class="l-fixed-position-text l-telemetry"
|
||||
ng-style="{ background: ngModel.fill(), 'border-color': ngModel.stroke(), color: ngModel.color() }"
|
||||
>
|
||||
<div
|
||||
<span
|
||||
class="l-elem l-value l-obj-val-format"
|
||||
data-value="{{ngModel.value}}"
|
||||
ng-class="{ 'telem-only': !ngModel.element.titled }"
|
||||
>
|
||||
{{ngModel.value}}
|
||||
</span>
|
||||
<span
|
||||
class="l-elem l-title"
|
||||
ng-show="ngModel.element.titled"
|
||||
>
|
||||
{{ngModel.name}}
|
||||
</div>
|
||||
<div
|
||||
class="l-elem l-value"
|
||||
ng-class="{ 'telem-only': !ngModel.element.titled }"
|
||||
>
|
||||
{{ngModel.value}}
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
@@ -25,6 +25,12 @@
|
||||
"implementation": "PlotController.js",
|
||||
"depends": [ "$scope", "telemetryFormatter", "telemetryHandler", "throttle" ]
|
||||
}
|
||||
],
|
||||
"policies": [
|
||||
{
|
||||
"category": "view",
|
||||
"implementation": "policies/PlotViewPolicy.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
65
platform/features/plot/src/policies/PlotViewPolicy.js
Normal file
65
platform/features/plot/src/policies/PlotViewPolicy.js
Normal file
@@ -0,0 +1,65 @@
|
||||
/*****************************************************************************
|
||||
* 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";
|
||||
|
||||
/**
|
||||
* Policy preventing the Plot view from being made available for
|
||||
* domain objects which have non-numeric telemetry.
|
||||
* @implements {Policy}
|
||||
*/
|
||||
function PlotViewPolicy() {
|
||||
function hasImageTelemetry(domainObject) {
|
||||
var telemetry = domainObject &&
|
||||
domainObject.getCapability('telemetry'),
|
||||
metadata = telemetry ? telemetry.getMetadata() : {},
|
||||
ranges = metadata.ranges || [];
|
||||
|
||||
// Generally, we want to allow Plot for telemetry-providing
|
||||
// objects (most telemetry is plottable.) We only want to
|
||||
// suppress this for telemetry which only has explicitly
|
||||
// non-numeric values.
|
||||
return ranges.length === 0 || ranges.some(function (range) {
|
||||
// Assume format is numeric if it is undefined
|
||||
// (numeric telemetry is the common case)
|
||||
return range.format === undefined ||
|
||||
range.format === 'number';
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
allow: function (view, domainObject) {
|
||||
if (view.key === 'plot') {
|
||||
return hasImageTelemetry(domainObject);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return PlotViewPolicy;
|
||||
}
|
||||
);
|
||||
79
platform/features/plot/test/policies/PlotViewPolicySpec.js
Normal file
79
platform/features/plot/test/policies/PlotViewPolicySpec.js
Normal file
@@ -0,0 +1,79 @@
|
||||
/*****************************************************************************
|
||||
* 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,describe,it,expect,beforeEach,jasmine,xit*/
|
||||
|
||||
define(
|
||||
["../../src/policies/PlotViewPolicy"],
|
||||
function (PlotViewPolicy) {
|
||||
"use strict";
|
||||
|
||||
describe("Plot view policy", function () {
|
||||
var testView,
|
||||
mockDomainObject,
|
||||
mockTelemetry,
|
||||
testMetadata,
|
||||
policy;
|
||||
|
||||
beforeEach(function () {
|
||||
testView = { key: "plot" };
|
||||
testMetadata = {};
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
'domainObject',
|
||||
['getId', 'getModel', 'getCapability']
|
||||
);
|
||||
mockTelemetry = jasmine.createSpyObj(
|
||||
'telemetry',
|
||||
['getMetadata']
|
||||
);
|
||||
mockDomainObject.getCapability.andCallFake(function (c) {
|
||||
return c === 'telemetry' ? mockTelemetry : undefined;
|
||||
});
|
||||
mockTelemetry.getMetadata.andReturn(testMetadata);
|
||||
|
||||
policy = new PlotViewPolicy();
|
||||
});
|
||||
|
||||
it("allows the imagery view for domain objects with numeric telemetry", function () {
|
||||
testMetadata.ranges = [ { key: "foo", format: "number" } ];
|
||||
expect(policy.allow(testView, mockDomainObject)).toBeTruthy();
|
||||
});
|
||||
|
||||
it("allows the imagery view for domain objects with unspecified telemetry", function () {
|
||||
testMetadata.ranges = [ { key: "foo" } ];
|
||||
expect(policy.allow(testView, mockDomainObject)).toBeTruthy();
|
||||
});
|
||||
|
||||
it("disallows the imagery view for domain objects without image telemetry", function () {
|
||||
testMetadata.ranges = [ { key: "foo", format: "somethingElse" } ];
|
||||
expect(policy.allow(testView, mockDomainObject)).toBeFalsy();
|
||||
});
|
||||
|
||||
it("allows other views", function () {
|
||||
testView.key = "somethingElse";
|
||||
testMetadata.ranges = [ { key: "foo", format: "somethingElse" } ];
|
||||
expect(policy.allow(testView, mockDomainObject)).toBeTruthy();
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
"elements/PlotUpdater",
|
||||
"modes/PlotModeOptions",
|
||||
"modes/PlotOverlayMode",
|
||||
"modes/PlotStackMode"
|
||||
"modes/PlotStackMode",
|
||||
"policies/PlotViewPolicy"
|
||||
]
|
||||
|
||||
|
||||
37
platform/features/rtevents/bundle.json
Normal file
37
platform/features/rtevents/bundle.json
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "Event Messages",
|
||||
"description": "List of time-ordered event messages",
|
||||
"extensions": {
|
||||
"views": [
|
||||
{
|
||||
"key": "rtmessages",
|
||||
"name": "RT Messages",
|
||||
"glyph": "5",
|
||||
"description": "Scrolling list of real time messages.",
|
||||
"templateUrl": "templates/rtmessages.html",
|
||||
"needs": [ "telemetry" ],
|
||||
"delegation": true
|
||||
}
|
||||
],
|
||||
"controllers": [
|
||||
{
|
||||
"key": "RTEventListController",
|
||||
"implementation": "RTEventListController.js",
|
||||
"depends": [ "$scope", "telemetryHandler", "telemetryFormatter" ]
|
||||
}
|
||||
],
|
||||
"directives": [
|
||||
{
|
||||
"key": "mctRtDataTable",
|
||||
"implementation": "directives/MCTRTDataTable.js",
|
||||
"depends": [ "$window" ]
|
||||
}
|
||||
],
|
||||
"policies": [
|
||||
{
|
||||
"category": "view",
|
||||
"implementation": "policies/RTMessagesViewPolicy.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<table class="tabular">
|
||||
<thead>
|
||||
<tr>
|
||||
<th ng-repeat="header in headers">
|
||||
{{header}}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="row in rows">
|
||||
<td ng-repeat="cell in row">
|
||||
{{cell}}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
29
platform/features/rtevents/res/templates/rtmessages.html
Normal file
29
platform/features/rtevents/res/templates/rtmessages.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<div class="w1">
|
||||
<div class="w2"
|
||||
ng-controller="RTEventListController as rtevent">
|
||||
<mct-rt-data-table headers="rtevent.headers()" rows="rtevent.rows()" ascending-scroll="true"></mct-rt-data-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
69
platform/features/rtevents/src/DomainColumn.js
Normal file
69
platform/features/rtevents/src/DomainColumn.js
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.
|
||||
*****************************************************************************/
|
||||
/*global define,moment*/
|
||||
|
||||
/**
|
||||
* Module defining DomainColumn. Created by vwoeltje on 11/18/14.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* A column which will report telemetry domain values
|
||||
* (typically, timestamps.) Used by the ScrollingListController.
|
||||
*
|
||||
* @constructor
|
||||
* @param domainMetadata an object with the machine- and human-
|
||||
* readable names for this domain (in `key` and `name`
|
||||
* fields, respectively.)
|
||||
* @param {TelemetryFormatter} telemetryFormatter the telemetry
|
||||
* formatting service, for making values human-readable.
|
||||
*/
|
||||
function DomainColumn(telemetryFormatter) {
|
||||
return {
|
||||
/**
|
||||
* Get the title to display in this column's header.
|
||||
* @returns {string} the title to display
|
||||
*/
|
||||
getTitle: function () {
|
||||
return "Time";
|
||||
},
|
||||
/**
|
||||
* Get the text to display inside a row under this
|
||||
* column.
|
||||
* @returns {string} the text to display
|
||||
*/
|
||||
getValue: function (domainObject, handle) {
|
||||
return {
|
||||
text: telemetryFormatter.formatDomainValue(
|
||||
handle.getDomainValue(domainObject)
|
||||
)
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return DomainColumn;
|
||||
}
|
||||
);
|
||||
138
platform/features/rtevents/src/RTEventListController.js
Normal file
138
platform/features/rtevents/src/RTEventListController.js
Normal file
@@ -0,0 +1,138 @@
|
||||
/*****************************************************************************
|
||||
* 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*/
|
||||
|
||||
/**
|
||||
* Module defining RTEventListController.
|
||||
* Created by shale on 06/25/2014. Based on RT Scrolling lists.
|
||||
*/
|
||||
define(
|
||||
["./DomainColumn", "./RangeColumn"],
|
||||
function (DomainColumn, RangeColumn) {
|
||||
"use strict";
|
||||
|
||||
var ROW_COUNT = 100;
|
||||
|
||||
/**
|
||||
* The RTEventListController is responsible for populating
|
||||
* the contents of the messages view.
|
||||
* @constructor
|
||||
*/
|
||||
function RTEventListController($scope, telemetryHandler, telemetryFormatter) {
|
||||
var handle,
|
||||
lastUpdated = {},
|
||||
lastIds = [],
|
||||
columns = [],
|
||||
headers = [],
|
||||
rows = [];
|
||||
|
||||
function getTelemetryObjects() {
|
||||
return handle ? handle.getTelemetryObjects() : [];
|
||||
}
|
||||
|
||||
function idsChanged(telemetryObjects) {
|
||||
function mismatch(id, index) {
|
||||
return id !== telemetryObjects[index].getId();
|
||||
}
|
||||
|
||||
return lastIds.length !== telemetryObjects.length ||
|
||||
lastIds.some(mismatch);
|
||||
}
|
||||
|
||||
function setupColumns(telemetryObjects) {
|
||||
var id = $scope.domainObject && $scope.domainObject.getId(),
|
||||
firstId =
|
||||
telemetryObjects[0] && telemetryObjects[0].getId();
|
||||
|
||||
columns = [];
|
||||
|
||||
columns.push(new DomainColumn(telemetryFormatter));
|
||||
columns.push(new RangeColumn());
|
||||
|
||||
headers = columns.map(function (column) {
|
||||
return column.getTitle();
|
||||
});
|
||||
}
|
||||
|
||||
function updateObjects(telemetryObjects) {
|
||||
if (idsChanged(telemetryObjects)) {
|
||||
setupColumns(telemetryObjects);
|
||||
lastIds = telemetryObjects.map(function (telemetryObject) {
|
||||
return telemetryObject.getId();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function addRow(telemetryObject) {
|
||||
var id = telemetryObject.getId(),
|
||||
domainValue = handle.getDomainValue(telemetryObject);
|
||||
if (lastUpdated[id] !== domainValue &&
|
||||
domainValue !== undefined) {
|
||||
// Instead of unshift (scrolling), use push (messages)
|
||||
rows.push(columns.map(function (column) {
|
||||
return column.getValue(telemetryObject, handle).text;
|
||||
}));
|
||||
// Remove first rows when adding past the max rows limit
|
||||
//rows.splice(ROW_COUNT, Number.MAX_VALUE);
|
||||
rows.splice(0, rows.length - ROW_COUNT);
|
||||
lastUpdated[id] = domainValue;
|
||||
}
|
||||
}
|
||||
|
||||
function updateValues() {
|
||||
getTelemetryObjects().forEach(addRow);
|
||||
}
|
||||
|
||||
function releaseSubscription() {
|
||||
if (handle) {
|
||||
handle.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
function makeSubscription(domainObject) {
|
||||
releaseSubscription();
|
||||
rows = [];
|
||||
handle = telemetryHandler.handle(
|
||||
domainObject,
|
||||
updateValues,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
$scope.$on("$destroy", releaseSubscription);
|
||||
|
||||
$scope.$watch("domainObject", makeSubscription);
|
||||
$scope.$watch(getTelemetryObjects, updateObjects);
|
||||
|
||||
return {
|
||||
rows: function () {
|
||||
return rows;
|
||||
},
|
||||
headers: function () {
|
||||
return headers;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return RTEventListController;
|
||||
}
|
||||
);
|
||||
68
platform/features/rtevents/src/RangeColumn.js
Normal file
68
platform/features/rtevents/src/RangeColumn.js
Normal file
@@ -0,0 +1,68 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,moment*/
|
||||
|
||||
/**
|
||||
* Module defining DomainColumn.
|
||||
* Created by vwoeltje on 11/18/14. Modified by shale on 06/25/2015.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* A column which will report telemetry range values
|
||||
* (typically, measurements.) Used by the RTScrollingListController.
|
||||
*
|
||||
* @constructor
|
||||
* @param rangeMetadata an object with the machine- and human-
|
||||
* readable names for this range (in `key` and `name`
|
||||
* fields, respectively.)
|
||||
* @param {TelemetryFormatter} telemetryFormatter the telemetry
|
||||
* formatting service, for making values human-readable.
|
||||
*/
|
||||
function RangeColumn() {
|
||||
return {
|
||||
/**
|
||||
* Get the title to display in this column's header.
|
||||
* @returns {string} the title to display
|
||||
*/
|
||||
getTitle: function () {
|
||||
return "Message";
|
||||
},
|
||||
/**
|
||||
* Get the text to display inside a row under this
|
||||
* column.
|
||||
* @returns {string} the text to display
|
||||
*/
|
||||
getValue: function (domainObject, handle) {
|
||||
return {
|
||||
text: handle.getRangeValue(domainObject)
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return RangeColumn;
|
||||
}
|
||||
);
|
||||
74
platform/features/rtevents/src/directives/MCTRTDataTable.js
Normal file
74
platform/features/rtevents/src/directives/MCTRTDataTable.js
Normal file
@@ -0,0 +1,74 @@
|
||||
/*****************************************************************************
|
||||
* 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*/
|
||||
|
||||
/**
|
||||
* Module defining MCTRTDataTable. Created by shale on 06/25/2015.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
function MCTRTDataTable($window) {
|
||||
return {
|
||||
restrict: "E",
|
||||
templateUrl: "platform/features/rtevents/res/templates/mct-rt-data-table.html",
|
||||
scope: {
|
||||
headers: "=",
|
||||
rows: "=",
|
||||
ascendingScroll: "="
|
||||
},
|
||||
link: function ($scope, $element) {
|
||||
var currentHeight,
|
||||
previousHeight,
|
||||
scrollParent;
|
||||
|
||||
// If the scroll is set to ascending, we want to
|
||||
// check when elements are added to the table, and move the scroll
|
||||
// bar accordingly.
|
||||
// (When viewing at the bottom of the page, the scroll bar will
|
||||
// stay at the bottom despite additions to the table)
|
||||
if ($scope.ascendingScroll) {
|
||||
$scope.$watchCollection("rows", function () {
|
||||
// Wait until the page as been repainted (otherwise the
|
||||
// height will always be zero)
|
||||
$window.requestAnimationFrame(function () {
|
||||
previousHeight = currentHeight;
|
||||
// The height of the table body
|
||||
currentHeight = $element[0].firstElementChild.firstElementChild.nextElementSibling.clientHeight;
|
||||
|
||||
// One of the parents is a div that has vscroll
|
||||
scrollParent = $element[0].parentElement.parentElement.parentElement.parentElement.parentElement;
|
||||
|
||||
// Move the scrollbar down the amount that the height has changed
|
||||
scrollParent.scrollTop = scrollParent.scrollTop + (currentHeight - previousHeight);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return MCTRTDataTable;
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,75 @@
|
||||
/*****************************************************************************
|
||||
* 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*/
|
||||
|
||||
/**
|
||||
* Module defining MessagesViewPolicy. Created by shale on 06/24/2015.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Policy controlling when the Messages view should be avaliable.
|
||||
* @constructor
|
||||
*/
|
||||
function RTMessagesViewPolicy() {
|
||||
|
||||
function hasStringTelemetry(domainObject) {
|
||||
var telemetry = domainObject &&
|
||||
domainObject.getCapability('telemetry'),
|
||||
metadata = telemetry ? telemetry.getMetadata() : {},
|
||||
data = telemetry ? telemetry.requestData() : {},
|
||||
ranges = metadata.ranges || [];
|
||||
|
||||
return ranges.some(function (range) {
|
||||
return range.format === 'string';
|
||||
});
|
||||
}
|
||||
return {
|
||||
/**
|
||||
* Check whether or not a given action is allowed by this
|
||||
* policy.
|
||||
* @param {Action} action the action
|
||||
* @param domainObject the domain object which will be viewed
|
||||
* @returns {boolean} true if not disallowed
|
||||
*/
|
||||
allow: function (view, domainObject) {
|
||||
// This policy only applies for the RT Messages view
|
||||
if (view.key === 'rtmessages') {
|
||||
// The Messages view is allowed only if the domain
|
||||
// object has string telemetry
|
||||
if (!hasStringTelemetry(domainObject)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Like all policies, allow by default.
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return RTMessagesViewPolicy;
|
||||
}
|
||||
);
|
||||
0
platform/features/rtevents/test/DomainColumnSpec.js
Normal file
0
platform/features/rtevents/test/DomainColumnSpec.js
Normal file
0
platform/features/rtevents/test/RangeColumnSpec.js
Normal file
0
platform/features/rtevents/test/RangeColumnSpec.js
Normal file
0
platform/features/rtevents/test/suite.js
Normal file
0
platform/features/rtevents/test/suite.js
Normal file
@@ -23,7 +23,7 @@
|
||||
<div class="w2"
|
||||
ng-controller="ScrollingListController">
|
||||
<!-- To add filtering, add class 'filterable' to <table> and uncomment 2nd <tr> in <thead> -->
|
||||
<table class="tabular">
|
||||
<table class="tabular fixed-header">
|
||||
<thead>
|
||||
<tr>
|
||||
<th ng-repeat="header in headers">
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
{
|
||||
"key": "mctInclude",
|
||||
"implementation": "MCTInclude.js",
|
||||
"depends": [ "templates[]" ]
|
||||
"depends": [ "templates[]", "$sce" ]
|
||||
},
|
||||
{
|
||||
"key": "mctRepresentation",
|
||||
"implementation": "MCTRepresentation.js",
|
||||
"depends": [ "representations[]", "views[]", "representers[]", "$q", "$log" ]
|
||||
"depends": [ "representations[]", "views[]", "representers[]", "$q", "$sce", "$log" ]
|
||||
}
|
||||
],
|
||||
"gestures": [
|
||||
@@ -51,4 +51,4 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,17 +53,17 @@ define(
|
||||
* @param {TemplateDefinition[]} templates an array of
|
||||
* template extensions
|
||||
*/
|
||||
function MCTInclude(templates) {
|
||||
function MCTInclude(templates, $sce) {
|
||||
var templateMap = {};
|
||||
|
||||
// Prepopulate templateMap for easy look up by key
|
||||
templates.forEach(function (template) {
|
||||
var key = template.key,
|
||||
path = [
|
||||
path = $sce.trustAsResourceUrl([
|
||||
template.bundle.path,
|
||||
template.bundle.resources,
|
||||
template.templateUrl
|
||||
].join("/");
|
||||
].join("/"));
|
||||
// First found should win (priority ordering)
|
||||
templateMap[key] = templateMap[key] || path;
|
||||
});
|
||||
@@ -91,4 +91,4 @@ define(
|
||||
|
||||
return MCTInclude;
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
@@ -52,7 +52,7 @@ define(
|
||||
* representation extensions
|
||||
* @param {ViewDefinition[]} views an array of view extensions
|
||||
*/
|
||||
function MCTRepresentation(representations, views, representers, $q, $log) {
|
||||
function MCTRepresentation(representations, views, representers, $q, $sce, $log) {
|
||||
var representationMap = {},
|
||||
gestureMap = {};
|
||||
|
||||
@@ -69,11 +69,11 @@ define(
|
||||
|
||||
// Get a path to a representation
|
||||
function getPath(representation) {
|
||||
return [
|
||||
return $sce.trustAsResourceUrl([
|
||||
representation.bundle.path,
|
||||
representation.bundle.resources,
|
||||
representation.templateUrl
|
||||
].join("/");
|
||||
].join("/"));
|
||||
}
|
||||
|
||||
// Look up a matching representation for this domain object
|
||||
@@ -237,4 +237,4 @@ define(
|
||||
|
||||
return MCTRepresentation;
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
@@ -31,6 +31,7 @@ define(
|
||||
|
||||
describe("The mct-include directive", function () {
|
||||
var testTemplates,
|
||||
mockSce,
|
||||
mctInclude;
|
||||
|
||||
beforeEach(function () {
|
||||
@@ -46,7 +47,14 @@ define(
|
||||
templateUrl: "z/template.html"
|
||||
}
|
||||
];
|
||||
mctInclude = new MCTInclude(testTemplates);
|
||||
mockSce = jasmine.createSpyObj(
|
||||
'$sce',
|
||||
['trustAsResourceUrl']
|
||||
);
|
||||
mockSce.trustAsResourceUrl.andCallFake(function (url) {
|
||||
return url;
|
||||
});
|
||||
mctInclude = new MCTInclude(testTemplates, mockSce);
|
||||
});
|
||||
|
||||
it("has a built-in template, with ng-include src=inclusion", function () {
|
||||
@@ -69,6 +77,12 @@ define(
|
||||
expect(scope.inclusion).toEqual("x/y/z/template.html");
|
||||
});
|
||||
|
||||
it("trusts template URLs", function () {
|
||||
mctInclude.controller({ key: "xyz" });
|
||||
expect(mockSce.trustAsResourceUrl)
|
||||
.toHaveBeenCalledWith("x/y/z/template.html");
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
@@ -38,6 +38,7 @@ define(
|
||||
testViews,
|
||||
mockRepresenters,
|
||||
mockQ,
|
||||
mockSce,
|
||||
mockLog,
|
||||
mockScope,
|
||||
mockElement,
|
||||
@@ -95,8 +96,16 @@ define(
|
||||
});
|
||||
|
||||
mockQ = { when: mockPromise };
|
||||
mockSce = jasmine.createSpyObj(
|
||||
'$sce',
|
||||
['trustAsResourceUrl']
|
||||
);
|
||||
mockLog = jasmine.createSpyObj("$log", LOG_FUNCTIONS);
|
||||
|
||||
|
||||
mockSce.trustAsResourceUrl.andCallFake(function (url) {
|
||||
return url;
|
||||
});
|
||||
mockScope = jasmine.createSpyObj("scope", [ "$watch" ]);
|
||||
mockElement = jasmine.createSpyObj("element", JQLITE_FUNCTIONS);
|
||||
mockDomainObject = jasmine.createSpyObj("domainObject", DOMAIN_OBJECT_METHODS);
|
||||
@@ -108,6 +117,7 @@ define(
|
||||
testViews,
|
||||
mockRepresenters,
|
||||
mockQ,
|
||||
mockSce,
|
||||
mockLog
|
||||
);
|
||||
});
|
||||
@@ -125,9 +135,18 @@ define(
|
||||
|
||||
it("watches scope when linked", function () {
|
||||
mctRepresentation.link(mockScope, mockElement);
|
||||
expect(mockScope.$watch).toHaveBeenCalledWith("key", jasmine.any(Function));
|
||||
expect(mockScope.$watch).toHaveBeenCalledWith("domainObject", jasmine.any(Function));
|
||||
expect(mockScope.$watch).toHaveBeenCalledWith("domainObject.getModel().modified", jasmine.any(Function));
|
||||
expect(mockScope.$watch).toHaveBeenCalledWith(
|
||||
"key",
|
||||
jasmine.any(Function)
|
||||
);
|
||||
expect(mockScope.$watch).toHaveBeenCalledWith(
|
||||
"domainObject",
|
||||
jasmine.any(Function)
|
||||
);
|
||||
expect(mockScope.$watch).toHaveBeenCalledWith(
|
||||
"domainObject.getModel().modified",
|
||||
jasmine.any(Function)
|
||||
);
|
||||
});
|
||||
|
||||
it("recognizes keys for representations", function () {
|
||||
@@ -152,6 +171,18 @@ define(
|
||||
expect(mockScope.inclusion).toEqual("x/y/z/template.html");
|
||||
});
|
||||
|
||||
it("trusts template URLs", function () {
|
||||
mctRepresentation.link(mockScope, mockElement);
|
||||
|
||||
mockScope.key = "xyz";
|
||||
|
||||
// Trigger the watch
|
||||
mockScope.$watch.calls[0].args[1]();
|
||||
|
||||
expect(mockSce.trustAsResourceUrl)
|
||||
.toHaveBeenCalledWith("x/y/z/template.html");
|
||||
});
|
||||
|
||||
it("loads declared capabilities", function () {
|
||||
mctRepresentation.link(mockScope, mockElement);
|
||||
|
||||
@@ -202,4 +233,4 @@ define(
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
@@ -342,7 +342,7 @@ define(
|
||||
* the second form, it returns an array ordered in
|
||||
* same manner as `getMetadata()` or
|
||||
* `getTelemetryObjects()`; that is, the telemetry
|
||||
* response at agiven index will correspond to the
|
||||
* response at a given index will correspond to the
|
||||
* telemetry-providing domain object at the same index.
|
||||
* @returns {Array} an array of responses
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user