diff --git a/platform/features/imagery/bundle.js b/platform/features/imagery/bundle.js
deleted file mode 100644
index ce0745519f..0000000000
--- a/platform/features/imagery/bundle.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/*****************************************************************************
- * Open MCT, Copyright (c) 2014-2018, United States Government
- * as represented by the Administrator of the National Aeronautics and Space
- * Administration. All rights reserved.
- *
- * Open MCT is licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0.
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- * Open MCT includes source code licensed under additional open source
- * licenses. See the Open Source Licenses file (LICENSES.md) included with
- * this source code distribution or the Licensing information page available
- * at runtime from the About dialog for additional information.
- *****************************************************************************/
-
-define([
- "./src/policies/ImageryViewPolicy",
- "./src/controllers/ImageryController",
- "./src/directives/MCTBackgroundImage",
- "./res/templates/imagery.html"
-], function (
- ImageryViewPolicy,
- ImageryController,
- MCTBackgroundImage,
- imageryTemplate
-) {
-
- return {
- name:"platform/features/imagery",
- definition: {
- "name": "Plot view for telemetry",
- "extensions": {
- "views": [
- {
- "name": "Imagery",
- "key": "imagery",
- "cssClass": "icon-image",
- "template": imageryTemplate,
- "priority": "preferred",
- "needs": [
- "telemetry"
- ],
- "editable": false
- }
- ],
- "policies": [
- {
- "category": "view",
- "implementation": ImageryViewPolicy,
- "depends": [
- "openmct"
- ]
- }
- ],
- "controllers": [
- {
- "key": "ImageryController",
- "implementation": ImageryController,
- "depends": [
- "$scope",
- "$window",
- "$element",
- "openmct"
- ]
- }
- ],
- "directives": [
- {
- "key": "mctBackgroundImage",
- "implementation": MCTBackgroundImage,
- "depends": [
- "$document"
- ]
- }
- ]
- }
- }
- };
-});
diff --git a/platform/features/imagery/res/templates/imagery.html b/platform/features/imagery/res/templates/imagery.html
deleted file mode 100644
index 8aedff7163..0000000000
--- a/platform/features/imagery/res/templates/imagery.html
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
{{imagery.getTime()}}
-
-
-
-
-
-
-
-
![]()
-
{{imagery.getTime(image)}}
-
-
-
-
diff --git a/platform/features/imagery/src/controllers/ImageryController.js b/platform/features/imagery/src/controllers/ImageryController.js
deleted file mode 100644
index ef69903304..0000000000
--- a/platform/features/imagery/src/controllers/ImageryController.js
+++ /dev/null
@@ -1,284 +0,0 @@
-/*****************************************************************************
- * Open MCT, Copyright (c) 2014-2018, United States Government
- * as represented by the Administrator of the National Aeronautics and Space
- * Administration. All rights reserved.
- *
- * Open MCT is licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0.
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- * Open MCT includes source code licensed under additional open source
- * licenses. See the Open Source Licenses file (LICENSES.md) included with
- * this source code distribution or the Licensing information page available
- * at runtime from the About dialog for additional information.
- *****************************************************************************/
-
-/**
- * This bundle implements views of image telemetry.
- * @namespace platform/features/imagery
- */
-
-define(
- [
- 'zepto',
- 'lodash'
- ],
- function ($, _) {
-
- /**
- * Controller for the "Imagery" view of a domain object which
- * provides image telemetry.
- * @constructor
- * @memberof platform/features/imagery
- */
-
- function ImageryController($scope, $window, element, openmct) {
- this.$scope = $scope;
- this.$window = $window;
- this.openmct = openmct;
- this.date = "";
- this.time = "";
- this.zone = "";
- this.imageUrl = "";
- this.requestCount = 0;
- this.scrollable = $(".l-image-thumbs-wrapper");
- this.autoScroll = openmct.time.clock() ? true : false;
- this.$scope.imageHistory = [];
- this.$scope.filters = {
- brightness: 100,
- contrast: 100
- };
-
- this.subscribe = this.subscribe.bind(this);
- this.stopListening = this.stopListening.bind(this);
- this.updateValues = this.updateValues.bind(this);
- this.updateHistory = this.updateHistory.bind(this);
- this.onBoundsChange = this.onBoundsChange.bind(this);
- this.onScroll = this.onScroll.bind(this);
- this.setSelectedImage = this.setSelectedImage.bind(this);
-
- this.subscribe(this.$scope.domainObject);
-
- this.$scope.$on('$destroy', this.stopListening);
- this.openmct.time.on('bounds', this.onBoundsChange);
- this.scrollable.on('scroll', this.onScroll);
- }
-
- ImageryController.prototype.subscribe = function (domainObject) {
- this.date = "";
- this.imageUrl = "";
- this.openmct.objects.get(domainObject.getId())
- .then(function (object) {
- this.domainObject = object;
- var metadata = this.openmct
- .telemetry
- .getMetadata(this.domainObject);
- this.timeKey = this.openmct.time.timeSystem().key;
- this.timeFormat = this.openmct
- .telemetry
- .getValueFormatter(metadata.value(this.timeKey));
- this.imageFormat = this.openmct
- .telemetry
- .getValueFormatter(metadata.valuesForHints(['image'])[0]);
- this.unsubscribe = this.openmct.telemetry
- .subscribe(this.domainObject, function (datum) {
- this.updateHistory(datum);
- this.updateValues(datum);
- }.bind(this));
-
- this.requestHistory(this.openmct.time.bounds());
- }.bind(this));
- };
-
- ImageryController.prototype.requestHistory = function (bounds) {
- this.requestCount++;
- this.$scope.imageHistory = [];
- var requestId = this.requestCount;
- this.openmct.telemetry
- .request(this.domainObject, bounds)
- .then(function (values) {
- if (this.requestCount > requestId) {
- return Promise.resolve('Stale request');
- }
-
- values.forEach(function (datum) {
- this.updateHistory(datum);
- }, this);
-
- this.updateValues(values[values.length - 1]);
- }.bind(this));
- };
-
- ImageryController.prototype.stopListening = function () {
- this.openmct.time.off('bounds', this.onBoundsChange);
- this.scrollable.off('scroll', this.onScroll);
- if (this.unsubscribe) {
- this.unsubscribe();
- delete this.unsubscribe;
- }
- };
-
- /**
- * Responds to bound change event be requesting new
- * historical data if the bound change was manual.
- * @private
- * @param {object} [newBounds] new bounds object
- * @param {boolean} [tick] true when change is automatic
- */
- ImageryController.prototype.onBoundsChange = function (newBounds, tick) {
- if (this.domainObject && !tick) {
- this.requestHistory(newBounds);
- }
- };
-
- /**
- * Updates displayable values to match those of the most
- * recently received datum.
- * @param {object} [datum] the datum
- * @private
- */
- ImageryController.prototype.updateValues = function (datum) {
- if (this.isPaused) {
- this.nextDatum = datum;
- return;
- }
- this.time = this.timeFormat.format(datum);
- this.imageUrl = this.imageFormat.format(datum);
-
- };
-
- /**
- * Appends given imagery datum to running history.
- * @private
- * @param {object} [datum] target telemetry datum
- * @returns {boolean} falsy when a duplicate datum is given
- */
- ImageryController.prototype.updateHistory = function (datum) {
- if (!this.datumMatchesMostRecent(datum)) {
- var index = _.sortedIndex(this.$scope.imageHistory, datum, this.timeFormat.format.bind(this.timeFormat));
- this.$scope.imageHistory.splice(index, 0, datum);
- return true;
- } else {
- return false;
- }
- };
-
- /**
- * Checks to see if the given datum is the same as the most recent in history.
- * @private
- * @param {object} [datum] target telemetry datum
- * @returns {boolean} true if datum is most recent in history, false otherwise
- */
- ImageryController.prototype.datumMatchesMostRecent = function (datum) {
- if (this.$scope.imageHistory.length !== 0) {
- var datumTime = this.timeFormat.format(datum);
- var datumURL = this.imageFormat.format(datum);
- var lastHistoryTime = this.timeFormat.format(this.$scope.imageHistory.slice(-1)[0]);
- var lastHistoryURL = this.imageFormat.format(this.$scope.imageHistory.slice(-1)[0]);
-
- return datumTime === lastHistoryTime && datumURL === lastHistoryURL;
- }
- return false;
- };
-
- ImageryController.prototype.onScroll = function (event) {
- this.$window.requestAnimationFrame(function () {
- var thumbnailWrapperHeight = this.scrollable[0].offsetHeight;
- var thumbnailWrapperWidth = this.scrollable[0].offsetWidth;
- if (this.scrollable[0].scrollLeft <
- (this.scrollable[0].scrollWidth - this.scrollable[0].clientWidth) - (thumbnailWrapperWidth) ||
- this.scrollable[0].scrollTop <
- (this.scrollable[0].scrollHeight - this.scrollable[0].clientHeight) - (thumbnailWrapperHeight)) {
- this.autoScroll = false;
- } else {
- this.autoScroll = true;
- }
- }.bind(this));
- };
-
- /**
- * Force history imagery div to scroll to bottom.
- */
- ImageryController.prototype.scrollToBottom = function () {
- if (this.autoScroll) {
- this.scrollable[0].scrollTop = this.scrollable[0].scrollHeight;
- }
- };
-
-
- /**
- * Get the time portion (hours, minutes, seconds) of the
- * timestamp associated with the incoming image telemetry
- * if no parameter is given, or of a provided datum.
- * @param {object} [datum] target telemetry datum
- * @returns {string} the time
- */
- ImageryController.prototype.getTime = function (datum) {
- return datum ?
- this.timeFormat.format(datum) :
- this.time;
- };
-
- /**
- * Get the URL of the most recent image telemetry if no
- * parameter is given, or of a provided datum.
- * @param {object} [datum] target telemetry datum
- * @returns {string} URL for telemetry image
- */
- ImageryController.prototype.getImageUrl = function (datum) {
- return datum ?
- this.imageFormat.format(datum) :
- this.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
- */
- ImageryController.prototype.paused = function (state) {
- if (arguments.length > 0 && state !== this.isPaused) {
- this.unselectAllImages();
- this.isPaused = state;
- if (this.nextDatum) {
- this.updateValues(this.nextDatum);
- delete this.nextDatum;
- } else {
- this.updateValues(this.$scope.imageHistory[this.$scope.imageHistory.length - 1]);
- }
- this.autoScroll = true;
- }
- return this.isPaused;
- };
-
- /**
- * Set the selected image on the state for the large imagery div to use.
- * @param {object} [image] the image object to get url from.
- */
- ImageryController.prototype.setSelectedImage = function (image) {
- this.imageUrl = this.getImageUrl(image);
- this.time = this.getTime(image);
- this.paused(true);
- this.unselectAllImages();
- image.selected = true;
- };
-
- /**
- * Loop through the history imagery data to set all images to unselected.
- */
- ImageryController.prototype.unselectAllImages = function () {
- for (var i = 0; i < this.$scope.imageHistory.length; i++) {
- this.$scope.imageHistory[i].selected = false;
- }
- };
- return ImageryController;
- }
-);
diff --git a/platform/features/imagery/src/directives/MCTBackgroundImage.js b/platform/features/imagery/src/directives/MCTBackgroundImage.js
deleted file mode 100644
index ddae082fa0..0000000000
--- a/platform/features/imagery/src/directives/MCTBackgroundImage.js
+++ /dev/null
@@ -1,110 +0,0 @@
-/*****************************************************************************
- * Open MCT, Copyright (c) 2014-2018, United States Government
- * as represented by the Administrator of the National Aeronautics and Space
- * Administration. All rights reserved.
- *
- * Open MCT is licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0.
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- * Open MCT includes source code licensed under additional open source
- * licenses. See the Open Source Licenses file (LICENSES.md) included with
- * this source code distribution or the Licensing information page available
- * at runtime from the About dialog for additional information.
- *****************************************************************************/
-
-define(
- function () {
-
- /**
- * 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 the value of `mct-background-image`is falsy, no image
- * will be displayed (immediately.)
- *
- * Optionally, a `filters` attribute may be specified as an
- * object with `brightness` and/or `contrast` properties,
- * whose values are percentages. A value of 100 will make
- * no changes to the image's brightness or contrast.
- *
- * @constructor
- * @memberof platform/features/imagery
- */
- function MCTBackgroundImage($document) {
- function link(scope, element) {
- // 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 requested = 0, loaded = 0;
-
- function updateFilters(filters) {
- var styleValue = filters ?
- Object.keys(filters).map(function (k) {
- return k + "(" + filters[k] + "%)";
- }).join(' ') :
- "";
- element.css('filter', styleValue);
- element.css('webkitFilter', styleValue);
- }
-
- 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', 'none');
- } else {
- image = $document[0].createElement('img');
- image.src = url;
- image.onload = useImage;
- }
-
- requested += 1;
- }
-
- scope.$watch('mctBackgroundImage', nextImage);
- scope.$watchCollection('filters', updateFilters);
- }
-
- return {
- restrict: "A",
- scope: {
- mctBackgroundImage: "=",
- filters: "="
- },
- link: link
- };
- }
-
- return MCTBackgroundImage;
- }
-);
-
diff --git a/platform/features/imagery/src/policies/ImageryViewPolicy.js b/platform/features/imagery/src/policies/ImageryViewPolicy.js
deleted file mode 100644
index 43421e4da4..0000000000
--- a/platform/features/imagery/src/policies/ImageryViewPolicy.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/*****************************************************************************
- * Open MCT, Copyright (c) 2014-2018, United States Government
- * as represented by the Administrator of the National Aeronautics and Space
- * Administration. All rights reserved.
- *
- * Open MCT is licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0.
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- * Open MCT includes source code licensed under additional open source
- * licenses. See the Open Source Licenses file (LICENSES.md) included with
- * this source code distribution or the Licensing information page available
- * at runtime from the About dialog for additional information.
- *****************************************************************************/
-
-define([
- '../../../../../src/api/objects/object-utils'
-], function (
- objectUtils
-) {
- /**
- * Policy preventing the Imagery view from being made available for
- * domain objects which do not have associated image telemetry.
- * @implements {Policy.}
- * @constructor
- */
- function ImageryViewPolicy(openmct) {
- this.openmct = openmct;
- }
-
- ImageryViewPolicy.prototype.hasImageTelemetry = function (domainObject) {
- var newDO = objectUtils.toNewFormat(
- domainObject.getModel(),
- domainObject.getId()
- );
-
- var metadata = this.openmct.telemetry.getMetadata(newDO);
- var values = metadata.valuesForHints(['image']);
- return values.length >= 1;
- };
-
- ImageryViewPolicy.prototype.allow = function (view, domainObject) {
- if (view.key === 'imagery' || view.key === 'historical-imagery') {
- return this.hasImageTelemetry(domainObject);
- }
-
- return true;
- };
-
- return ImageryViewPolicy;
-});
-
diff --git a/platform/features/imagery/test/controllers/ImageryControllerSpec.js b/platform/features/imagery/test/controllers/ImageryControllerSpec.js
deleted file mode 100644
index 7edc1c6710..0000000000
--- a/platform/features/imagery/test/controllers/ImageryControllerSpec.js
+++ /dev/null
@@ -1,271 +0,0 @@
-/*****************************************************************************
- * Open MCT, Copyright (c) 2014-2018, United States Government
- * as represented by the Administrator of the National Aeronautics and Space
- * Administration. All rights reserved.
- *
- * Open MCT is licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0.
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- * Open MCT includes source code licensed under additional open source
- * licenses. See the Open Source Licenses file (LICENSES.md) included with
- * this source code distribution or the Licensing information page available
- * at runtime from the About dialog for additional information.
- *****************************************************************************/
-
-define(
- [
- "zepto",
- "../../src/controllers/ImageryController"
- ],
- function ($, ImageryController) {
-
- var MOCK_ELEMENT_TEMPLATE =
- '';
-
- xdescribe("The Imagery controller", function () {
- var $scope,
- openmct,
- oldDomainObject,
- newDomainObject,
- unsubscribe,
- metadata,
- prefix,
- controller,
- requestPromise,
- mockWindow,
- mockElement;
-
- beforeEach(function () {
- $scope = jasmine.createSpyObj('$scope', ['$on', '$watch']);
- oldDomainObject = jasmine.createSpyObj(
- 'domainObject',
- ['getId']
- );
- newDomainObject = { name: 'foo' };
- oldDomainObject.getId.and.returnValue('testID');
- openmct = {
- objects: jasmine.createSpyObj('objectAPI', [
- 'get'
- ]),
- time: jasmine.createSpyObj('timeAPI', [
- 'timeSystem',
- 'clock',
- 'on',
- 'off',
- 'bounds'
- ]),
- telemetry: jasmine.createSpyObj('telemetryAPI', [
- 'subscribe',
- 'request',
- 'getValueFormatter',
- 'getMetadata'
- ])
- };
- metadata = jasmine.createSpyObj('metadata', [
- 'value',
- 'valuesForHints'
- ]);
- metadata.value.and.returnValue("timestamp");
- metadata.valuesForHints.and.returnValue(["value"]);
-
- prefix = "formatted ";
- unsubscribe = jasmine.createSpy('unsubscribe');
- openmct.telemetry.subscribe.and.returnValue(unsubscribe);
- openmct.time.timeSystem.and.returnValue({
- key: 'testKey'
- });
- $scope.domainObject = oldDomainObject;
- openmct.objects.get.and.returnValue(Promise.resolve(newDomainObject));
- openmct.telemetry.getMetadata.and.returnValue(metadata);
- openmct.telemetry.getValueFormatter.and.callFake(function (property) {
- var formatter =
- jasmine.createSpyObj("formatter-" + property, ['format']);
- var isTime = (property === "timestamp");
- formatter.format.and.callFake(function (datum) {
- return (isTime ? prefix : "") + datum[property];
- });
- return formatter;
- });
-
- requestPromise = new Promise(function (resolve) {
- setTimeout(function () {
- resolve([{
- timestamp: 1434600258123,
- value: 'some/url'
- }]);
- }, 10);
- });
-
- openmct.telemetry.request.and.returnValue(requestPromise);
- mockElement = $(MOCK_ELEMENT_TEMPLATE);
- mockWindow = jasmine.createSpyObj('$window', ['requestAnimationFrame']);
- mockWindow.requestAnimationFrame.and.callFake(function (f) {
- return f();
- });
-
- controller = new ImageryController(
- $scope,
- mockWindow,
- mockElement,
- openmct
- );
- });
-
- describe("when loaded", function () {
- var callback,
- boundsListener,
- bounds;
-
- beforeEach(function () {
- return requestPromise.then(function () {
- openmct.time.on.calls.all().forEach(function (call) {
- if (call.args[0] === "bounds") {
- boundsListener = call.args[1];
- }
- });
- callback =
- openmct.telemetry.subscribe.calls.mostRecent().args[1];
- });
- });
-
- it("requests history", function () {
- expect(openmct.telemetry.request).toHaveBeenCalledWith(
- newDomainObject, bounds
- );
- expect(controller.getTime()).toEqual(prefix + 1434600258123);
- expect(controller.getImageUrl()).toEqual('some/url');
- });
-
-
- it("exposes the latest telemetry values", function () {
- callback({
- timestamp: 1434600259456,
- value: "some/other/url"
- });
-
- expect(controller.getTime()).toEqual(prefix + 1434600259456);
- expect(controller.getImageUrl()).toEqual("some/other/url");
- });
-
- it("allows updates to be paused and unpaused", function () {
- var newTimestamp = 1434600259456,
- newUrl = "some/other/url",
- initialTimestamp = controller.getTime(),
- initialUrl = controller.getImageUrl();
-
- expect(initialTimestamp).not.toBe(prefix + newTimestamp);
- expect(initialUrl).not.toBe(newUrl);
- expect(controller.paused()).toBeFalsy();
-
- controller.paused(true);
- expect(controller.paused()).toBeTruthy();
- callback({ timestamp: newTimestamp, value: newUrl });
-
- expect(controller.getTime()).toEqual(initialTimestamp);
- expect(controller.getImageUrl()).toEqual(initialUrl);
-
- controller.paused(false);
- expect(controller.paused()).toBeFalsy();
- expect(controller.getTime()).toEqual(prefix + newTimestamp);
- expect(controller.getImageUrl()).toEqual(newUrl);
- });
-
- it("forwards large image view to latest image in history on un-pause", function () {
- $scope.imageHistory = [
- { utc: 1434600258122, url: 'some/url1', selected: false},
- { utc: 1434600258123, url: 'some/url2', selected: false}
- ];
- controller.paused(true);
- controller.paused(false);
-
- expect(controller.getImageUrl()).toEqual(controller.getImageUrl($scope.imageHistory[1]));
- });
-
- it("subscribes to telemetry", function () {
- expect(openmct.telemetry.subscribe).toHaveBeenCalledWith(
- newDomainObject,
- jasmine.any(Function)
- );
- });
-
- it("requests telemetry", function () {
- expect(openmct.telemetry.request).toHaveBeenCalledWith(
- newDomainObject,
- bounds
- );
- });
-
- it("unsubscribes and unlistens when scope is destroyed", function () {
- expect(unsubscribe).not.toHaveBeenCalled();
-
- $scope.$on.calls.all().forEach(function (call) {
- if (call.args[0] === '$destroy') {
- call.args[1]();
- }
- });
- expect(unsubscribe).toHaveBeenCalled();
- expect(openmct.time.off)
- .toHaveBeenCalledWith('bounds', jasmine.any(Function));
- });
-
- it("listens for bounds event and responds to tick and manual change", function () {
- var mockBounds = {start: 1434600000000, end: 1434600500000};
- expect(openmct.time.on).toHaveBeenCalled();
- openmct.telemetry.request.calls.reset();
- boundsListener(mockBounds, true);
- expect(openmct.telemetry.request).not.toHaveBeenCalled();
- boundsListener(mockBounds, false);
- expect(openmct.telemetry.request).toHaveBeenCalledWith(newDomainObject, mockBounds);
- });
-
- it ("doesnt append duplicate datum", function () {
- var mockDatum = {value: 'image/url', timestamp: 1434700000000};
- var mockDatum2 = {value: 'image/url', timestamp: 1434700000000};
- var mockDatum3 = {value: 'image/url', url: 'someval', timestamp: 1434700000000};
- expect(controller.updateHistory(mockDatum)).toBe(true);
- expect(controller.updateHistory(mockDatum)).toBe(false);
- expect(controller.updateHistory(mockDatum)).toBe(false);
- expect(controller.updateHistory(mockDatum2)).toBe(false);
- expect(controller.updateHistory(mockDatum3)).toBe(false);
- });
-
- describe("when user clicks on imagery thumbnail", function () {
- var mockDatum = { utc: 1434600258123, url: 'some/url', selected: false};
-
- it("pauses and adds selected class to imagery thumbnail", function () {
- controller.setSelectedImage(mockDatum);
- expect(controller.paused()).toBeTruthy();
- expect(mockDatum.selected).toBeTruthy();
- });
-
- it("unselects previously selected image", function () {
- $scope.imageHistory = [{ utc: 1434600258123, url: 'some/url', selected: true}];
- controller.unselectAllImages();
- expect($scope.imageHistory[0].selected).toBeFalsy();
- });
-
- it("updates larger image url and time", function () {
- controller.setSelectedImage(mockDatum);
- expect(controller.getImageUrl()).toEqual(controller.getImageUrl(mockDatum));
- expect(controller.getTime()).toEqual(controller.timeFormat.format(mockDatum.utc));
- });
- });
-
- });
-
- it("initially shows an empty string for date/time", function () {
- expect(controller.getTime()).toEqual("");
- expect(controller.getImageUrl()).toEqual("");
- });
- });
- }
-);
-
diff --git a/platform/features/imagery/test/directives/MCTBackgroundImageSpec.js b/platform/features/imagery/test/directives/MCTBackgroundImageSpec.js
deleted file mode 100644
index dd6182be54..0000000000
--- a/platform/features/imagery/test/directives/MCTBackgroundImageSpec.js
+++ /dev/null
@@ -1,126 +0,0 @@
-/*****************************************************************************
- * Open MCT, Copyright (c) 2014-2018, United States Government
- * as represented by the Administrator of the National Aeronautics and Space
- * Administration. All rights reserved.
- *
- * Open MCT is licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0.
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- * Open MCT includes source code licensed under additional open source
- * licenses. See the Open Source Licenses file (LICENSES.md) included with
- * this source code distribution or the Licensing information page available
- * at runtime from the About dialog for additional information.
- *****************************************************************************/
-
-define(
- ["../../src/directives/MCTBackgroundImage"],
- function (MCTBackgroundImage) {
-
- 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',
- '$watchCollection'
- ]);
- mockElement = jasmine.createSpyObj('element', ['css']);
- testImage = {};
-
- mockDocument[0].createElement.and.returnValue(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("=");
- });
-
- describe("once linked", function () {
- beforeEach(function () {
- directive.link(mockScope, mockElement, {});
- });
-
- it("watches for changes to the URL", function () {
- expect(mockScope.$watch).toHaveBeenCalledWith(
- 'mctBackgroundImage',
- jasmine.any(Function)
- );
- });
-
- it("updates images in-order, even when they load out-of-order", function () {
- var firstOnload;
-
- mockScope.$watch.calls.mostRecent().args[1]("some/url/0");
- firstOnload = testImage.onload;
-
- mockScope.$watch.calls.mostRecent().args[1]("some/url/1");
-
- // Resolve in a different order
- testImage.onload();
- firstOnload();
-
- // Should still have taken the more recent value
- expect(mockElement.css.calls.mostRecent().args).toEqual([
- "background-image",
- "url('some/url/1')"
- ]);
- });
-
- it("clears the background image when undefined is passed in", function () {
- mockScope.$watch.calls.mostRecent().args[1]("some/url/0");
- testImage.onload();
- mockScope.$watch.calls.mostRecent().args[1](undefined);
-
- expect(mockElement.css.calls.mostRecent().args).toEqual([
- "background-image",
- "none"
- ]);
- });
-
- it("updates filters on change", function () {
- var filters = { brightness: 123, contrast: 21 };
- mockScope.$watchCollection.calls.all().forEach(function (call) {
- if (call.args[0] === 'filters') {
- call.args[1](filters);
- }
- });
- expect(mockElement.css).toHaveBeenCalledWith(
- 'filter',
- 'brightness(123%) contrast(21%)'
- );
- });
-
- it("clears filters when none are present", function () {
- mockScope.$watchCollection.calls.all().forEach(function (call) {
- if (call.args[0] === 'filters') {
- call.args[1](undefined);
- }
- });
- expect(mockElement.css)
- .toHaveBeenCalledWith('filter', '');
- });
- });
- });
- }
-);
-
diff --git a/platform/features/imagery/test/policies/ImageryViewPolicySpec.js b/platform/features/imagery/test/policies/ImageryViewPolicySpec.js
deleted file mode 100644
index de61a91100..0000000000
--- a/platform/features/imagery/test/policies/ImageryViewPolicySpec.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/*****************************************************************************
- * Open MCT, Copyright (c) 2014-2018, United States Government
- * as represented by the Administrator of the National Aeronautics and Space
- * Administration. All rights reserved.
- *
- * Open MCT is licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0.
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- * Open MCT includes source code licensed under additional open source
- * licenses. See the Open Source Licenses file (LICENSES.md) included with
- * this source code distribution or the Licensing information page available
- * at runtime from the About dialog for additional information.
- *****************************************************************************/
-
-define(
- ["../../src/policies/ImageryViewPolicy"],
- function (ImageryViewPolicy) {
-
- describe("Imagery view policy", function () {
- var testView,
- openmct,
- mockDomainObject,
- mockTelemetry,
- mockMetadata,
- policy;
-
- beforeEach(function () {
- testView = { key: "imagery" };
- mockMetadata = jasmine.createSpyObj('metadata', [
- "valuesForHints"
- ]);
- mockDomainObject = jasmine.createSpyObj(
- 'domainObject',
- ['getId', 'getModel', 'getCapability']
- );
- mockTelemetry = jasmine.createSpyObj(
- 'telemetry',
- ['getMetadata']
- );
- mockDomainObject.getCapability.and.callFake(function (c) {
- return c === 'telemetry' ? mockTelemetry : undefined;
- });
- mockDomainObject.getId.and.returnValue("some-id");
- mockDomainObject.getModel.and.returnValue({ name: "foo" });
- mockTelemetry.getMetadata.and.returnValue(mockMetadata);
- mockMetadata.valuesForHints.and.returnValue(["bar"]);
-
- openmct = { telemetry: mockTelemetry };
-
- policy = new ImageryViewPolicy(openmct);
- });
-
- it("checks for hints indicating image telemetry", function () {
- policy.allow(testView, mockDomainObject);
- expect(mockMetadata.valuesForHints)
- .toHaveBeenCalledWith(["image"]);
- });
-
- it("allows the imagery view for domain objects with image telemetry", function () {
- expect(policy.allow(testView, mockDomainObject)).toBeTruthy();
- });
-
- it("disallows the imagery view for domain objects without image telemetry", function () {
- mockMetadata.valuesForHints.and.returnValue([]);
- expect(policy.allow(testView, mockDomainObject)).toBeFalsy();
- });
-
- it("allows other views", function () {
- testView.key = "somethingElse";
- expect(policy.allow(testView, mockDomainObject)).toBeTruthy();
- });
-
- });
- }
-);
-
diff --git a/src/MCT.js b/src/MCT.js
index 3337afb29b..c07dd39840 100644
--- a/src/MCT.js
+++ b/src/MCT.js
@@ -33,6 +33,7 @@ define([
'./adapter/indicators/legacy-indicators-plugin',
'./plugins/buildInfo/plugin',
'./ui/registries/ViewRegistry',
+ './plugins/imagery/plugin',
'./ui/registries/InspectorViewRegistry',
'./ui/registries/ToolbarRegistry',
'./ui/router/ApplicationRouter',
@@ -59,6 +60,7 @@ define([
LegacyIndicatorsPlugin,
buildInfoPlugin,
ViewRegistry,
+ ImageryPlugin,
InspectorViewRegistry,
ToolbarRegistry,
ApplicationRouter,
@@ -257,6 +259,7 @@ define([
this.install(RemoveActionPlugin.default());
this.install(this.plugins.FolderView());
this.install(this.plugins.Tabs());
+ this.install(ImageryPlugin.default());
this.install(this.plugins.FlexibleLayout());
this.install(this.plugins.GoToOriginalAction());
this.install(this.plugins.ImportExport());
diff --git a/src/installDefaultBundles.js b/src/installDefaultBundles.js
index 6f0e07f02b..a2732cfe1f 100644
--- a/src/installDefaultBundles.js
+++ b/src/installDefaultBundles.js
@@ -38,7 +38,6 @@ const DEFAULTS = [
'platform/exporters',
'platform/telemetry',
'platform/features/clock',
- 'platform/features/imagery',
'platform/features/hyperlink',
'platform/features/timeline',
'platform/forms',
@@ -82,7 +81,6 @@ define([
'../platform/execution/bundle',
'../platform/exporters/bundle',
'../platform/features/clock/bundle',
- '../platform/features/imagery/bundle',
'../platform/features/my-items/bundle',
'../platform/features/hyperlink/bundle',
'../platform/features/static-markup/bundle',
diff --git a/src/plugins/imagery/ImageryViewProvider.js b/src/plugins/imagery/ImageryViewProvider.js
new file mode 100644
index 0000000000..5697030320
--- /dev/null
+++ b/src/plugins/imagery/ImageryViewProvider.js
@@ -0,0 +1,47 @@
+import ImageryViewLayout from './components/ImageryViewLayout.vue';
+import Vue from 'vue';
+
+export default function ImageryViewProvider(openmct) {
+ const type = 'example.imagery';
+
+ const hasImageTelemetry = function (domainObject) {
+ const metadata = openmct.telemetry.getMetadata(domainObject);
+ if (!metadata) {
+ return false;
+ }
+
+ return metadata.valuesForHints(['image']).length > 0;
+ };
+
+ return {
+ key: type,
+ name: 'Imagery Layout',
+ cssClass: 'icon-image',
+ canView: function (domainObject) {
+ return hasImageTelemetry(domainObject);
+ },
+ view: function (domainObject) {
+ let component;
+
+ return {
+ show: function (element) {
+ component = new Vue({
+ components: {
+ ImageryViewLayout
+ },
+ provide: {
+ openmct,
+ domainObject
+ },
+ el: element,
+ template: ''
+ });
+ },
+ destroy: function () {
+ component.$destroy();
+ component = undefined;
+ }
+ };
+ }
+ }
+}
diff --git a/src/plugins/imagery/components/ImageryViewLayout.vue b/src/plugins/imagery/components/ImageryViewLayout.vue
new file mode 100644
index 0000000000..9a08fb91e9
--- /dev/null
+++ b/src/plugins/imagery/components/ImageryViewLayout.vue
@@ -0,0 +1,249 @@
+
+
+
+
+
+
+
+
+
+
+
![]()
+
{{ getTime(imageData) }}
+
+
+
+
+
+
+
+
diff --git a/src/plugins/imagery/components/imagery-view-layout.scss b/src/plugins/imagery/components/imagery-view-layout.scss
new file mode 100644
index 0000000000..0a86127853
--- /dev/null
+++ b/src/plugins/imagery/components/imagery-view-layout.scss
@@ -0,0 +1,32 @@
+.c-imagery-layout {
+ display: flex;
+ flex-direction: column;
+ overflow: auto;
+
+ .main-image-wrapper {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ padding-bottom: 5px;
+ }
+
+ .main-image {
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: contain;
+ height: 100%;
+
+ &.unnsynced{
+ @include sUnsynced();
+ }
+ }
+
+ .l-image-controller {
+ padding: 5px 0 0 0;
+ }
+
+ .thumbs-layout {
+ margin-top: 5px;
+ overflow: auto;
+ }
+}
diff --git a/src/plugins/imagery/plugin.js b/src/plugins/imagery/plugin.js
new file mode 100644
index 0000000000..fdbaeba18c
--- /dev/null
+++ b/src/plugins/imagery/plugin.js
@@ -0,0 +1,8 @@
+import ImageryViewProvider from './ImageryViewProvider';
+
+export default function () {
+ return function install(openmct) {
+ openmct.objectViews.addProvider(new ImageryViewProvider(openmct));
+ };
+}
+
diff --git a/src/plugins/plugins.js b/src/plugins/plugins.js
index e831676939..26a0b7a34c 100644
--- a/src/plugins/plugins.js
+++ b/src/plugins/plugins.js
@@ -28,6 +28,7 @@ define([
'./autoflow/AutoflowTabularPlugin',
'./timeConductor/plugin',
'../../example/imagery/plugin',
+ './imagery/plugin',
'../../platform/import-export/bundle',
'./summaryWidget/plugin',
'./URLIndicatorPlugin/URLIndicatorPlugin',
@@ -57,6 +58,7 @@ define([
AutoflowPlugin,
TimeConductorPlugin,
ExampleImagery,
+ ImageryPlugin,
ImportExport,
SummaryWidget,
URLIndicatorPlugin,
@@ -162,6 +164,7 @@ define([
};
plugins.ExampleImagery = ExampleImagery;
+ plugins.ImageryPlugin = ImageryPlugin;
plugins.Plot = PlotPlugin;
plugins.TelemetryTable = TelemetryTablePlugin;
diff --git a/src/styles/vue-styles.scss b/src/styles/vue-styles.scss
index 0a29abc358..4a9611bd32 100644
--- a/src/styles/vue-styles.scss
+++ b/src/styles/vue-styles.scss
@@ -14,6 +14,7 @@
@import "../plugins/folderView/components/grid-view.scss";
@import "../plugins/folderView/components/list-item.scss";
@import "../plugins/folderView/components/list-view.scss";
+@import "../plugins/imagery/components/imagery-view-layout.scss";
@import "../plugins/telemetryTable/components/table-row.scss";
@import "../plugins/telemetryTable/components/telemetry-filter-indicator.scss";
@import "../plugins/tabs/components/tabs.scss";
diff --git a/webpack.config.js b/webpack.config.js
index c935beafb1..8013a20ded 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -31,6 +31,7 @@ const webpackConfig = {
},
resolve: {
alias: {
+ "@": path.join(__dirname, "src"),
"legacyRegistry": path.join(__dirname, "src/legacyRegistry"),
"saveAs": "file-saver",
"csv": "comma-separated-values",