mirror of
https://github.com/nasa/openmct.git
synced 2024-12-21 14:07:50 +00:00
Merge remote-tracking branch 'origin/open1170' into open-1318
This commit is contained in:
commit
a3f3f5bb27
@ -11,6 +11,7 @@
|
||||
"platform/containment",
|
||||
"platform/execution",
|
||||
"platform/telemetry",
|
||||
"platform/features/imagery",
|
||||
"platform/features/layout",
|
||||
"platform/features/pages",
|
||||
"platform/features/plot",
|
||||
@ -19,6 +20,7 @@
|
||||
"platform/persistence/queue",
|
||||
"platform/policy",
|
||||
|
||||
"example/imagery",
|
||||
"example/persistence",
|
||||
"example/generator"
|
||||
]
|
||||
|
42
example/imagery/bundle.json
Normal file
42
example/imagery/bundle.json
Normal file
@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "Imagery",
|
||||
"description": "Example of a component that produces image telemetry.",
|
||||
"extensions": {
|
||||
"components": [
|
||||
{
|
||||
"implementation": "ImageTelemetryProvider.js",
|
||||
"type": "provider",
|
||||
"provides": "telemetryService",
|
||||
"depends": [ "$q", "$timeout" ]
|
||||
}
|
||||
],
|
||||
"types": [
|
||||
{
|
||||
"key": "imagery",
|
||||
"name": "Example Imagery",
|
||||
"glyph": "T",
|
||||
"features": "creation",
|
||||
"model": {
|
||||
"telemetry": {}
|
||||
},
|
||||
"telemetry": {
|
||||
"source": "imagery",
|
||||
"domains": [
|
||||
{
|
||||
"name": "Time",
|
||||
"key": "time",
|
||||
"format": "timestamp"
|
||||
}
|
||||
],
|
||||
"ranges": [
|
||||
{
|
||||
"name": "Image",
|
||||
"key": "url",
|
||||
"format": "imageUrl"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
66
example/imagery/src/ImageTelemetry.js
Normal file
66
example/imagery/src/ImageTelemetry.js
Normal file
@ -0,0 +1,66 @@
|
||||
/*****************************************************************************
|
||||
* 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 SinewaveTelemetry. Created by vwoeltje on 11/12/14.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
var firstObservedTime = Date.now(),
|
||||
images = [
|
||||
"http://www.nasa.gov/393811main_Palomar_ao_bouchez_10s_after_impact_4x3_946-710.png",
|
||||
"http://www.nasa.gov/393821main_Palomar_ao_bouchez_15s_after_impact_4x3_946-710.png",
|
||||
"http://www.nasa.gov/images/content/393801main_CfhtVeillet2_4x3_516-387.jpg",
|
||||
"http://www.nasa.gov/images/content/392790main_1024_768_GeminiNorth_NightBeforeImpact_946-710.jpg"
|
||||
].map(function (url, index) {
|
||||
return {
|
||||
timestamp: firstObservedTime + 1000 * index,
|
||||
url: url
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
function ImageTelemetry() {
|
||||
return {
|
||||
getPointCount: function () {
|
||||
return Math.floor((Date.now() - firstObservedTime) / 1000);
|
||||
},
|
||||
getDomainValue: function (i, domain) {
|
||||
return images[i % images.length].timestamp;
|
||||
},
|
||||
getRangeValue: function (i, range) {
|
||||
return images[i % images.length].url;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return ImageTelemetry;
|
||||
}
|
||||
);
|
115
example/imagery/src/ImageTelemetryProvider.js
Normal file
115
example/imagery/src/ImageTelemetryProvider.js
Normal file
@ -0,0 +1,115 @@
|
||||
/*****************************************************************************
|
||||
* 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 SinewaveTelemetryProvider. Created by vwoeltje on 11/12/14.
|
||||
*/
|
||||
define(
|
||||
["./ImageTelemetry"],
|
||||
function (ImageTelemetry) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
function ImageTelemetryProvider($q, $timeout) {
|
||||
var subscriptions = [];
|
||||
|
||||
//
|
||||
function matchesSource(request) {
|
||||
return request.source === "imagery";
|
||||
}
|
||||
|
||||
// Used internally; this will be repacked by doPackage
|
||||
function generateData(request) {
|
||||
return {
|
||||
key: request.key,
|
||||
telemetry: new ImageTelemetry()
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
function doPackage(results) {
|
||||
var packaged = {};
|
||||
results.forEach(function (result) {
|
||||
packaged[result.key] = result.telemetry;
|
||||
});
|
||||
// Format as expected (sources -> keys -> telemetry)
|
||||
return { imagery: packaged };
|
||||
}
|
||||
|
||||
function requestTelemetry(requests) {
|
||||
return $timeout(function () {
|
||||
return doPackage(requests.filter(matchesSource).map(generateData));
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function handleSubscriptions() {
|
||||
subscriptions.forEach(function (subscription) {
|
||||
var requests = subscription.requests;
|
||||
subscription.callback(doPackage(
|
||||
requests.filter(matchesSource).map(generateData)
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
function startGenerating() {
|
||||
$timeout(function () {
|
||||
handleSubscriptions();
|
||||
if (subscriptions.length > 0) {
|
||||
startGenerating();
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function subscribe(callback, requests) {
|
||||
var subscription = {
|
||||
callback: callback,
|
||||
requests: requests
|
||||
};
|
||||
|
||||
function unsubscribe() {
|
||||
subscriptions = subscriptions.filter(function (s) {
|
||||
return s !== subscription;
|
||||
});
|
||||
}
|
||||
|
||||
subscriptions.push(subscription);
|
||||
|
||||
if (subscriptions.length === 1) {
|
||||
startGenerating();
|
||||
}
|
||||
|
||||
return unsubscribe;
|
||||
}
|
||||
|
||||
return {
|
||||
requestTelemetry: requestTelemetry,
|
||||
subscribe: subscribe
|
||||
};
|
||||
}
|
||||
|
||||
return ImageTelemetryProvider;
|
||||
}
|
||||
);
|
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"
|
||||
]
|
@ -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"
|
||||
]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user