Compare commits

..

1 Commits

Author SHA1 Message Date
Joshi
436c6b531c Prepare for sprint 1.7.7 2021-08-17 15:59:39 -07:00
71 changed files with 342 additions and 2592 deletions

View File

@@ -56,38 +56,14 @@ workflows:
browser: ChromeHeadless
always-pass: false
- test:
name: node12-firefoxESR-build-only
name: node12-firefoxESR
node-version: lts/erbium
browser: FirefoxESR
always-pass: true
- test:
name: node14-chrome-build-only
name: node14-chrome
node-version: lts/fermium
browser: ChromeHeadless
always-pass: true
nightly:
jobs:
- test:
name: node10-chrome-nightly
node-version: lts/dubnium
browser: ChromeHeadless
always-pass: false
- test:
name: node12-firefoxESR-nightly
node-version: lts/erbium
browser: FirefoxESR
always-pass: false
- test:
name: node14-chrome-nightly
node-version: lts/fermium
browser: ChromeHeadless
always-pass: false
triggers:
- schedule:
cron: "0 0 * * *"
filters:
branches:
only:
- master

View File

@@ -1,33 +0,0 @@
name: "CodeQL"
on:
push:
branches: [ master ]
schedule:
- cron: '28 21 * * 3'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: javascript
- name: Autobuild
uses: github/codeql-action/autobuild@v1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

1
.npmrc
View File

@@ -1 +0,0 @@
loglevel=warn

2
API.md
View File

@@ -996,7 +996,7 @@ reveal additional information when the mouse cursor is hovered over it.
A common use case for indicators is to convey the state of some external system such as a
persistence backend or HTTP server. So long as this system is accessible via HTTP request,
Open MCT provides a general purpose indicator to show whether the server is available and
returning a 2xx status code. The URL Status Indicator is made available as a default plugin. See
returing a 2xx status code. The URL Status Indicator is made available as a default plugin. See
the [documentation](./src/plugins/URLIndicatorPlugin) for details on how to install and configure the
URL Status Indicator.

View File

@@ -423,7 +423,7 @@ which can help with this, however.
instead of separate approaches for static and substitutable
dependencies.
* Removes need to understand Angular's DI mechanism.
* Improves usability of documentation (`typeService` is an
* Improves useability of documentation (`typeService` is an
instance of `CompositeService` and implements `TypeService`
so you can easily traverse links in the JSDoc.)
* Can be used more easily from Web Workers, allowing services

View File

@@ -25,7 +25,7 @@
## Legacy Documentation
As we transition to a new API, the following documentation for the old API
(which is supported during the transition) may be useful as well:
(which is supported during the transtion) may be useful as well:
* The [Architecture Overview](architecture/) describes the concepts used
throughout Open MCT, and gives a high level overview of the platform's design.

View File

@@ -28,15 +28,6 @@ define([
domain: 2
}
},
{
key: "cos",
name: "Cosine",
unit: "deg",
formatString: '%0.2f',
hints: {
domain: 3
}
},
// Need to enable "LocalTimeSystem" plugin to make use of this
// {
// key: "local",
@@ -118,100 +109,6 @@ define([
}
}
]
},
'example.spectral-generator': {
values: [
{
key: "name",
name: "Name",
format: "string"
},
{
key: "utc",
name: "Time",
format: "utc",
hints: {
domain: 1
}
},
{
key: "wavelength",
name: "Wavelength",
unit: "Hz",
formatString: '%0.2f',
hints: {
domain: 2,
spectralAttribute: true
}
},
{
key: "cos",
name: "Cosine",
unit: "deg",
formatString: '%0.2f',
hints: {
range: 2,
spectralAttribute: true
}
}
]
},
'example.spectral-aggregate-generator': {
values: [
{
key: "name",
name: "Name",
format: "string"
},
{
key: "utc",
name: "Time",
format: "utc",
hints: {
domain: 1
}
},
{
key: "ch1",
name: "Channel 1",
format: "string",
hints: {
range: 1
}
},
{
key: "ch2",
name: "Channel 2",
format: "string",
hints: {
range: 2
}
},
{
key: "ch3",
name: "Channel 3",
format: "string",
hints: {
range: 3
}
},
{
key: "ch4",
name: "Channel 4",
format: "string",
hints: {
range: 4
}
},
{
key: "ch5",
name: "Channel 5",
format: "string",
hints: {
range: 5
}
}
]
}
};

View File

@@ -1,86 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, 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 (
) {
function SpectralAggregateGeneratorProvider() {
}
function pointForTimestamp(timestamp, count, name) {
return {
name: name,
utc: String(Math.floor(timestamp / count) * count),
ch1: String(Math.floor(timestamp / count) % 1),
ch2: String(Math.floor(timestamp / count) % 2),
ch3: String(Math.floor(timestamp / count) % 3),
ch4: String(Math.floor(timestamp / count) % 4),
ch5: String(Math.floor(timestamp / count) % 5)
};
}
SpectralAggregateGeneratorProvider.prototype.supportsSubscribe = function (domainObject) {
return domainObject.type === 'example.spectral-aggregate-generator';
};
SpectralAggregateGeneratorProvider.prototype.subscribe = function (domainObject, callback) {
var count = 5000;
var interval = setInterval(function () {
var now = Date.now();
var datum = pointForTimestamp(now, count, domainObject.name);
callback(datum);
}, count);
return function () {
clearInterval(interval);
};
};
SpectralAggregateGeneratorProvider.prototype.supportsRequest = function (domainObject, options) {
return domainObject.type === 'example.spectral-aggregate-generator';
};
SpectralAggregateGeneratorProvider.prototype.request = function (domainObject, options) {
var start = options.start;
var end = Math.min(Date.now(), options.end); // no future values
var count = 5000;
if (options.strategy === 'latest' || options.size === 1) {
start = end;
}
var data = [];
while (start <= end && data.length < 5000) {
data.push(pointForTimestamp(start, count, domainObject.name));
start += count;
}
return Promise.resolve(data);
};
return SpectralAggregateGeneratorProvider;
});

View File

@@ -1,104 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, 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([
'./WorkerInterface'
], function (
WorkerInterface
) {
var REQUEST_DEFAULTS = {
amplitude: 1,
wavelength: 1,
period: 10,
offset: 0,
dataRateInHz: 1,
randomness: 0,
phase: 0
};
function SpectralGeneratorProvider() {
this.workerInterface = new WorkerInterface();
}
SpectralGeneratorProvider.prototype.canProvideTelemetry = function (domainObject) {
return domainObject.type === 'example.spectral-generator';
};
SpectralGeneratorProvider.prototype.supportsRequest =
SpectralGeneratorProvider.prototype.supportsSubscribe =
SpectralGeneratorProvider.prototype.canProvideTelemetry;
SpectralGeneratorProvider.prototype.makeWorkerRequest = function (domainObject, request) {
var props = [
'amplitude',
'wavelength',
'period',
'offset',
'dataRateInHz',
'phase',
'randomness'
];
request = request || {};
var workerRequest = {};
props.forEach(function (prop) {
if (domainObject.telemetry && Object.prototype.hasOwnProperty.call(domainObject.telemetry, prop)) {
workerRequest[prop] = domainObject.telemetry[prop];
}
if (request && Object.prototype.hasOwnProperty.call(request, prop)) {
workerRequest[prop] = request[prop];
}
if (!Object.prototype.hasOwnProperty.call(workerRequest, prop)) {
workerRequest[prop] = REQUEST_DEFAULTS[prop];
}
workerRequest[prop] = Number(workerRequest[prop]);
});
workerRequest.name = domainObject.name;
return workerRequest;
};
SpectralGeneratorProvider.prototype.request = function (domainObject, request) {
var workerRequest = this.makeWorkerRequest(domainObject, request);
workerRequest.start = request.start;
workerRequest.end = request.end;
workerRequest.spectra = true;
return this.workerInterface.request(workerRequest);
};
SpectralGeneratorProvider.prototype.subscribe = function (domainObject, callback) {
var workerRequest = this.makeWorkerRequest(domainObject, {});
workerRequest.spectra = true;
return this.workerInterface.subscribe(workerRequest, callback);
};
return SpectralGeneratorProvider;
});

View File

@@ -54,39 +54,23 @@
var start = Date.now();
var step = 1000 / data.dataRateInHz;
var nextStep = start - (start % step) + step;
let work;
console.log('dataRate', data);
if (data.spectra) {
work = function (now) {
while (nextStep < now) {
const messageCopy = Object.create(message);
message.data.start = nextStep - (60 * 1000);
message.data.end = nextStep;
onRequest(messageCopy);
nextStep += step;
}
return nextStep;
};
} else {
work = function (now) {
while (nextStep < now) {
self.postMessage({
id: message.id,
data: {
name: data.name,
utc: nextStep,
yesterday: nextStep - 60 * 60 * 24 * 1000,
sin: sin(nextStep, data.period, data.amplitude, data.offset, data.phase, data.randomness),
wavelength: wavelength(start, nextStep),
cos: cos(nextStep, data.period, data.amplitude, data.offset, data.phase, data.randomness)
}
});
nextStep += step;
}
function work(now) {
while (nextStep < now) {
self.postMessage({
id: message.id,
data: {
name: data.name,
utc: nextStep,
yesterday: nextStep - 60 * 60 * 24 * 1000,
sin: sin(nextStep, data.period, data.amplitude, data.offset, data.phase, data.randomness),
cos: cos(nextStep, data.period, data.amplitude, data.offset, data.phase, data.randomness)
}
});
nextStep += step;
}
return nextStep;
};
return nextStep;
}
subscriptions[message.id] = work;
@@ -127,21 +111,13 @@
utc: nextStep,
yesterday: nextStep - 60 * 60 * 24 * 1000,
sin: sin(nextStep, period, amplitude, offset, phase, randomness),
wavelength: wavelength(start, nextStep),
cos: cos(nextStep, period, amplitude, offset, phase, randomness)
});
}
self.postMessage({
id: message.id,
data: request.spectra ? {
wavelength: data.map((item) => {
return item.wavelength;
}),
cos: data.map((item) => {
return item.cos;
})
} : data
data: data
});
}
@@ -155,10 +131,6 @@
* Math.sin(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
}
function wavelength(start, nextStep) {
return (nextStep - start) / 10;
}
function sendError(error, message) {
self.postMessage({
error: error.name + ': ' + error.message,

View File

@@ -24,15 +24,11 @@ define([
"./GeneratorProvider",
"./SinewaveLimitProvider",
"./StateGeneratorProvider",
"./SpectralGeneratorProvider",
"./SpectralAggregateGeneratorProvider",
"./GeneratorMetadataProvider"
], function (
GeneratorProvider,
SinewaveLimitProvider,
StateGeneratorProvider,
SpectralGeneratorProvider,
SpectralAggregateGeneratorProvider,
GeneratorMetadataProvider
) {
@@ -65,37 +61,6 @@ define([
openmct.telemetry.addProvider(new StateGeneratorProvider());
openmct.types.addType("example.spectral-generator", {
name: "Spectral Generator",
description: "For development use. Generates example streaming telemetry data using a simple sine wave algorithm.",
cssClass: "icon-generator-telemetry",
creatable: true,
initialize: function (object) {
object.telemetry = {
period: 10,
amplitude: 1,
wavelength: 1,
frequency: 1,
offset: 0,
dataRateInHz: 1,
phase: 0,
randomness: 0
};
}
});
openmct.telemetry.addProvider(new SpectralGeneratorProvider());
openmct.types.addType("example.spectral-aggregate-generator", {
name: "Spectral Aggregate Generator",
description: "For development use. Generates example streaming telemetry data using a simple state algorithm.",
cssClass: "icon-generator-telemetry",
creatable: true,
initialize: function (object) {
object.telemetry = {};
}
});
openmct.telemetry.addProvider(new SpectralAggregateGeneratorProvider());
openmct.types.addType("generator", {
name: "Sine Wave Generator",
description: "For development use. Generates example streaming telemetry data using a simple sine wave algorithm.",

View File

@@ -152,7 +152,7 @@
<h2>How to Use Glyphs</h2>
<div class="cols cols1-1">
<div class="col">
<p>The easiest way to use a glyph is to include its CSS class in an element. The CSS adds a pseudo <code>:before</code> HTML element to whatever element it's attached to that makes proper use of the symbols font.</p>
<p>The easiest way to use a glyph is to include its CSS class in an element. The CSS adds a psuedo <code>:before</code> HTML element to whatever element it's attached to that makes proper use of the symbols font.</p>
<p>Alternately, you can use the <code>.ui-symbol</code> class in an object that contains encoded HTML entities. This method is only recommended if you cannot use the aforementioned CSS class approach.</p>
</div>
<mct-example><a class="s-button icon-gear" title="Settings"></a>

View File

@@ -1,7 +1,8 @@
{
"name": "openmct",
"version": "1.7.8-SNAPSHOT",
"version": "1.7.7-SNAPSHOT",
"description": "The Open MCT core platform",
"dependencies": {},
"devDependencies": {
"angular": ">=1.8.0",
"angular-route": "1.4.14",
@@ -40,13 +41,13 @@
"jsdoc": "^3.3.2",
"karma": "6.3.4",
"karma-chrome-launcher": "3.1.0",
"karma-firefox-launcher": "2.1.1",
"karma-cli": "2.0.0",
"karma-coverage": "2.0.3",
"karma-coverage-istanbul-reporter": "3.0.3",
"karma-firefox-launcher": "2.1.1",
"karma-junit-reporter": "2.0.1",
"karma-html-reporter": "0.2.7",
"karma-jasmine": "4.0.1",
"karma-junit-reporter": "2.0.1",
"karma-sourcemap-loader": "0.3.8",
"karma-webpack": "4.0.2",
"location-bar": "^3.0.1",
@@ -61,7 +62,6 @@
"node-bourbon": "^4.2.3",
"node-sass": "^4.14.1",
"painterro": "^1.2.56",
"plotly.js": "^2.5.0",
"printj": "^1.2.1",
"raw-loader": "^0.5.1",
"request": "^2.69.0",

View File

@@ -64,7 +64,7 @@ define(
*
* @param {DomainObject} domainObject the domain object to navigate to
* @param {Boolean} force if true, force navigation to occur.
* @returns {Boolean} true if navigation occurred, otherwise false.
* @returns {Boolean} true if navigation occured, otherwise false.
*/
NavigationService.prototype.setNavigation = function (domainObject, force) {
if (force) {

View File

@@ -379,7 +379,7 @@ define([
{
"name": "Math.uuid.js",
"version": "1.4.7",
"description": "Unique identifier generation (code adapted.)",
"description": "Unique identifer generation (code adapted.)",
"author": "Robert Kieffer",
"website": "https://github.com/broofa/node-uuid",
"copyright": "Copyright (c) 2010-2012 Robert Kieffer",

View File

@@ -30,8 +30,8 @@ define([
return function ImportExportPlugin() {
return function (openmct) {
ExportAsJSONAction.prototype.appliesTo = function (context) {
return this.openmct.$injector.get('policyService')
ExportAsJSONAction.appliesTo = function (context) {
return openmct.$injector.get('policyService')
.allow("creation", context.domainObject.getCapability("type")
);
};

View File

@@ -29,7 +29,7 @@ define(
],
function (ExportAsJSONAction, domainObjectFactory, MCT, AdapterCapability) {
describe("The export JSON action", function () {
xdescribe("The export JSON action", function () {
var context,
action,
@@ -102,7 +102,7 @@ define(
expect(action).toBeDefined();
});
xit("doesn't export non-creatable objects in tree", function () {
it("doesn't export non-creatable objects in tree", function () {
var nonCreatableType = {
hasFeature:
function (feature) {
@@ -149,7 +149,7 @@ define(
});
});
xit("can export self-containing objects", function () {
it("can export self-containing objects", function () {
var parent = domainObjectFactory({
name: 'parent',
model: {
@@ -191,7 +191,7 @@ define(
});
});
xit("exports links to external objects as new objects", function () {
it("exports links to external objects as new objects", function () {
var parent = domainObjectFactory({
name: 'parent',
model: {

View File

@@ -27,7 +27,7 @@ define(
],
function (ImportAsJSONAction, domainObjectFactory) {
describe("The import JSON action", function () {
xdescribe("The import JSON action", function () {
var context = {};
var action,
@@ -146,7 +146,7 @@ define(
});
});
xit("can import self-containing objects", function () {
it("can import self-containing objects", function () {
var compDomainObject = domainObjectFactory({
name: 'compObject',
model: { name: 'compObject'},
@@ -198,7 +198,7 @@ define(
});
});
xit("assigns new ids to each imported object", function () {
it("assigns new ids to each imported object", function () {
dialogService.getUserInput.and.returnValue(Promise.resolve(
{
selectFile: {

View File

@@ -47,7 +47,7 @@ define(
* @param $interval Angular's $interval service
* @param {string} space the name of the persistence space being served
* @param {string} root the root of the path to ElasticSearch
* @param {string} path the path to domain objects within ElasticSearch
* @param {stirng} path the path to domain objects within ElasticSearch
*/
function ElasticPersistenceProvider($http, $q, space, root, path) {
this.spaces = [space];

View File

@@ -60,7 +60,9 @@ class ActionsAPI extends EventEmitter {
}
_getCachedActionCollection(objectPath, view) {
return this._actionCollections.get(view);
let cachedActionCollection = this._actionCollections.get(view);
return cachedActionCollection;
}
_newActionCollection(objectPath, view, skipEnvironmentObservers) {

View File

@@ -42,7 +42,7 @@ import EventEmitter from 'EventEmitter';
*
* @typedef {object} NotificationModel
* @property {string} message The message to be displayed by the notification
* @property {number | 'unknown'} [progress] The progress of some ongoing task. Should be a number between 0 and 100, or
* @property {number | 'unknown'} [progress] The progres of some ongoing task. Should be a number between 0 and 100, or
* with the string literal 'unknown'.
* @property {string} [progressText] A message conveying progress of some ongoing task.
@@ -98,7 +98,7 @@ export default class NotificationAPI extends EventEmitter {
* Present an alert to the user.
* @param {string} message The message to display to the user.
* @param {Object} [options] object with following properties
* autoDismissTimeout: {number} in milliseconds to automatically dismisses notification
* autoDismissTimeout: {number} in miliseconds to automatically dismisses notification
* link: {Object} Add a link to notifications for navigation
* onClick: callback function
* cssClass: css class name to add style on link
@@ -119,7 +119,7 @@ export default class NotificationAPI extends EventEmitter {
* Present an error message to the user
* @param {string} message
* @param {Object} [options] object with following properties
* autoDismissTimeout: {number} in milliseconds to automatically dismisses notification
* autoDismissTimeout: {number} in miliseconds to automatically dismisses notification
* link: {Object} Add a link to notifications for navigation
* onClick: callback function
* cssClass: css class name to add style on link

View File

@@ -60,7 +60,7 @@ class OverlayAPI {
* A description of option properties that can be passed into the overlay
* @typedef options
* @property {object} element DOMElement that is to be inserted/shown on the overlay
* @property {string} size preferred size of the overlay (large, small, fit)
* @property {string} size prefered size of the overlay (large, small, fit)
* @property {array} buttons optional button objects with label and callback properties
* @property {function} onDestroy callback to be called when overlay is destroyed
* @property {boolean} dismissable allow user to dismiss overlay by using esc, and clicking away

View File

@@ -12,7 +12,7 @@
></button>
<div
ref="element"
class="c-overlay__contents js-notebook-snapshot-item-wrapper"
class="c-overlay__contents"
tabindex="0"
></div>
<div

View File

@@ -281,7 +281,7 @@ define([
* (start, end, etc.), sort order, and strategies for retrieving
* telemetry (aggregation, latest available, etc.).
*
* @method requestCollection
* @method requestTelemetryCollection
* @memberof module:openmct.TelemetryAPI~TelemetryProvider#
* @param {module:openmct.DomainObject} domainObject the object
* which has associated telemetry
@@ -289,7 +289,7 @@ define([
* options for this telemetry collection request
* @returns {TelemetryCollection} a TelemetryCollection instance
*/
TelemetryAPI.prototype.requestCollection = function (domainObject, options = {}) {
TelemetryAPI.prototype.requestTelemetryCollection = function (domainObject, options = {}) {
return new TelemetryCollection(
this.openmct,
domainObject,

View File

@@ -603,7 +603,7 @@ describe('Telemetry API', function () {
});
it('when requested, returns an instance of telemetry collection', () => {
const telemetryCollection = telemetryAPI.requestCollection(domainObject);
const telemetryCollection = telemetryAPI.requestTelemetryCollection(domainObject);
expect(telemetryCollection).toBeInstanceOf(TelemetryCollection);
});

View File

@@ -23,11 +23,6 @@
import _ from 'lodash';
import EventEmitter from 'EventEmitter';
const ERRORS = {
TIMESYSTEM_KEY: 'All telemetry metadata must have a telemetry value with a key that matches the key of the active time system.',
LOADED: 'Telemetry Collection has already been loaded.'
};
/** Class representing a Telemetry Collection. */
export class TelemetryCollection extends EventEmitter {
@@ -62,7 +57,7 @@ export class TelemetryCollection extends EventEmitter {
*/
load() {
if (this.loaded) {
this._error(ERRORS.LOADED);
throw new Error('Telemetry Collection has already been loaded.');
}
this._timeSystem(this.openmct.time.timeSystem());
@@ -128,13 +123,13 @@ export class TelemetryCollection extends EventEmitter {
try {
this.requestAbort = new AbortController();
this.options.signal = this.requestAbort.signal;
this.options.abortSignal = this.requestAbort.signal;
historicalData = await this.historicalProvider.request(this.domainObject, this.options);
this.requestAbort = undefined;
} catch (error) {
console.error('Error requesting telemetry data...');
this.requestAbort = undefined;
this._error(error);
throw new Error(error);
}
this._processNewTelemetry(historicalData);
@@ -194,7 +189,7 @@ export class TelemetryCollection extends EventEmitter {
if (endIndex > startIndex) {
let potentialDupes = this.boundedTelemetry.slice(startIndex, endIndex);
isDuplicate = potentialDupes.some(_.isEqual.bind(undefined, datum));
isDuplicate = potentialDupes.some(_.isEqual(undefined, datum));
}
}
@@ -312,16 +307,8 @@ export class TelemetryCollection extends EventEmitter {
* @private
*/
_timeSystem(timeSystem) {
let domains = this.metadata.valuesForHints(['domain']);
let domain = domains.find((d) => d.key === timeSystem.key);
if (domain === undefined) {
this._error(ERRORS.TIMESYSTEM_KEY);
}
// timeKey is used to create a dummy datum used for sorting
this.timeKey = domain.source; // this defaults to key if no source is set
let metadataValue = this.metadata.value(timeSystem.key) || { format: timeSystem.key };
this.timeKey = timeSystem.key;
let metadataValue = this.metadata.value(this.timeKey) || { format: this.timeKey };
let valueFormatter = this.openmct.telemetry.getValueFormatter(metadataValue);
this.parseTime = (datum) => {
@@ -376,13 +363,4 @@ export class TelemetryCollection extends EventEmitter {
_unwatchTimeSystem() {
this.openmct.time.off('timeSystem', this._timeSystem, this);
}
/**
* will throw a new Error, for passed in message
* @param {string} message Message describing the error
* @private
*/
_error(message) {
throw new Error(message);
}
}

View File

@@ -141,7 +141,6 @@ const NON_STYLEABLE_CONTAINER_TYPES = [
const NON_STYLEABLE_LAYOUT_ITEM_TYPES = [
'line-view',
'box-view',
'ellipse-view',
'image-view'
];
@@ -322,7 +321,7 @@ export default {
if (item) {
const type = this.openmct.types.get(item.type);
if (type && type.definition) {
creatable = (type.definition.creatable !== undefined && (type.definition.creatable === 'true' || type.definition.creatable === true));
creatable = (type.definition.creatable === true);
}
}

View File

@@ -230,7 +230,7 @@ describe('the plugin', function () {
};
const staticStyle = {
"style": {
"backgroundColor": "#666666",
"backgroundColor": "#717171",
"border": "1px solid #00ffff"
}
};
@@ -238,7 +238,7 @@ describe('the plugin', function () {
"conditionId": "39584410-cbf9-499e-96dc-76f27e69885d",
"style": {
"isStyleInvisible": "",
"backgroundColor": "#666666",
"backgroundColor": "#717171",
"border": "1px solid #ffff00"
}
};
@@ -250,7 +250,7 @@ describe('the plugin', function () {
"configuration": {
"items": [
{
"fill": "#666666",
"fill": "#717171",
"stroke": "",
"x": 1,
"y": 1,
@@ -259,22 +259,12 @@ describe('the plugin', function () {
"type": "box-view",
"id": "89b88746-d325-487b-aec4-11b79afff9e8"
},
{
"fill": "#666666",
"stroke": "",
"x": 1,
"y": 1,
"width": 10,
"height": 5,
"type": "ellipse-view",
"id": "19b88746-d325-487b-aec4-11b79afff9z8"
},
{
"x": 18,
"y": 9,
"x2": 23,
"y2": 4,
"stroke": "#666666",
"stroke": "#717171",
"type": "line-view",
"id": "57d49a28-7863-43bd-9593-6570758916f0"
},
@@ -309,12 +299,12 @@ describe('the plugin', function () {
"y": 9,
"x2": 23,
"y2": 4,
"stroke": "#666666",
"stroke": "#717171",
"type": "line-view",
"id": "57d49a28-7863-43bd-9593-6570758916f0"
};
boxLayoutItem = {
"fill": "#666666",
"fill": "#717171",
"stroke": "",
"x": 1,
"y": 1,

View File

@@ -29,10 +29,9 @@ const styleProps = {
noneValue: NONE_VALUE,
applicableForType: type => {
return !type ? true : (type === 'text-view'
|| type === 'telemetry-view'
|| type === 'box-view'
|| type === 'ellipse-view'
|| type === 'subobject-view');
|| type === 'telemetry-view'
|| type === 'box-view'
|| type === 'subobject-view');
}
},
border: {
@@ -42,7 +41,6 @@ const styleProps = {
return !type ? true : (type === 'text-view'
|| type === 'telemetry-view'
|| type === 'box-view'
|| type === 'ellipse-view'
|| type === 'image-view'
|| type === 'line-view'
|| type === 'subobject-view');

View File

@@ -149,7 +149,6 @@ define(['lodash'], function (_) {
return type === 'text-view'
|| type === 'telemetry-view'
|| type === 'box-view'
|| type === 'ellipse-view'
|| type === 'image-view'
|| type === 'line-view'
|| type === 'subobject-view';
@@ -181,10 +180,6 @@ define(['lodash'], function (_) {
"name": "Box",
"class": "icon-box-round-corners"
},
{
"name": "Ellipse",
"class": "icon-circle"
},
{
"name": "Line",
"class": "icon-line-horz"
@@ -750,7 +745,7 @@ define(['lodash'], function (_) {
if (toolbar.remove.length === 0) {
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
}
} else if (layoutItem.type === 'box-view' || layoutItem.type === 'ellipse-view') {
} else if (layoutItem.type === 'box-view') {
if (toolbar.position.length === 0) {
toolbar.position = [
getStackOrder(selectedParent, selectionPath),

View File

@@ -43,7 +43,7 @@ import conditionalStylesMixin from '../mixins/objectStyles-mixin';
export default {
makeDefinition() {
return {
fill: '#666666',
fill: '#717171',
stroke: '',
x: 1,
y: 1,

View File

@@ -76,7 +76,6 @@ import uuid from 'uuid';
import SubobjectView from './SubobjectView.vue';
import TelemetryView from './TelemetryView.vue';
import BoxView from './BoxView.vue';
import EllipseView from './EllipseView.vue';
import TextView from './TextView.vue';
import LineView from './LineView.vue';
import ImageView from './ImageView.vue';
@@ -113,7 +112,6 @@ const ITEM_TYPE_VIEW_MAP = {
'subobject-view': SubobjectView,
'telemetry-view': TelemetryView,
'box-view': BoxView,
'ellipse-view': EllipseView,
'line-view': LineView,
'text-view': TextView,
'image-view': ImageView

View File

@@ -28,19 +28,19 @@
>
<div
class="c-frame-edit__handle c-frame-edit__handle--nw"
@mousedown.left="startResize([1,1], [-1,-1], $event)"
@mousedown="startResize([1,1], [-1,-1], $event)"
></div>
<div
class="c-frame-edit__handle c-frame-edit__handle--ne"
@mousedown.left="startResize([0,1], [1,-1], $event)"
@mousedown="startResize([0,1], [1,-1], $event)"
></div>
<div
class="c-frame-edit__handle c-frame-edit__handle--sw"
@mousedown.left="startResize([1,0], [-1,1], $event)"
@mousedown="startResize([1,0], [-1,1], $event)"
></div>
<div
class="c-frame-edit__handle c-frame-edit__handle--se"
@mousedown.left="startResize([0,0], [1,1], $event)"
@mousedown="startResize([0,0], [1,1], $event)"
></div>
</div>
</template>

View File

@@ -1,122 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, 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.
*****************************************************************************/
<template>
<layout-frame
:item="item"
:grid-size="gridSize"
:is-editing="isEditing"
@move="(gridDelta) => $emit('move', gridDelta)"
@endMove="() => $emit('endMove')"
>
<div
class="c-ellipse-view u-style-receiver js-style-receiver"
:class="[styleClass]"
:style="style"
></div>
</layout-frame>
</template>
<script>
import LayoutFrame from './LayoutFrame.vue';
import conditionalStylesMixin from '../mixins/objectStyles-mixin';
export default {
makeDefinition() {
return {
fill: '#666666',
stroke: '',
x: 1,
y: 1,
width: 10,
height: 10
};
},
components: {
LayoutFrame
},
mixins: [conditionalStylesMixin],
inject: ['openmct'],
props: {
item: {
type: Object,
required: true
},
gridSize: {
type: Array,
required: true,
validator: (arr) => arr && arr.length === 2
&& arr.every(el => typeof el === 'number')
},
index: {
type: Number,
required: true
},
initSelect: Boolean,
isEditing: {
type: Boolean,
required: true
}
},
computed: {
style() {
if (this.itemStyle) {
return this.itemStyle;
} else {
return {
backgroundColor: this.item.fill,
border: this.item.stroke ? '1px solid ' + this.item.stroke : ''
};
}
}
},
watch: {
index(newIndex) {
if (!this.context) {
return;
}
this.context.index = newIndex;
},
item(newItem) {
if (!this.context) {
return;
}
this.context.layoutItem = newItem;
}
},
mounted() {
this.context = {
layoutItem: this.item,
index: this.index
};
this.removeSelectable = this.openmct.selection.selectable(
this.$el, this.context, this.initSelect);
},
destroyed() {
if (this.removeSelectable) {
this.removeSelectable();
}
}
};
</script>

View File

@@ -33,7 +33,7 @@
<slot></slot>
<div
class="c-frame__move-bar"
@mousedown.left="startMove($event)"
@mousedown="isEditing ? startMove([1,1], [0,0], $event) : null"
></div>
</div>
</template>
@@ -93,11 +93,7 @@ export default {
return value - this.initialPosition[index];
}.bind(this));
},
startMove(event, posFactor = [1, 1], dimFactor = [0, 0]) {
if (!this.isEditing) {
return;
}
startMove(posFactor, dimFactor, event) {
document.body.addEventListener('mousemove', this.continueMove);
document.body.addEventListener('mouseup', this.endMove);
this.dragPosition = {

View File

@@ -45,7 +45,7 @@
<div
class="c-frame__move-bar"
@mousedown.left="startDrag($event)"
@mousedown="startDrag($event)"
></div>
<div
v-if="showFrameEdit"
@@ -96,7 +96,7 @@ export default {
y: 10,
x2: 10,
y2: 5,
stroke: '#666666'
stroke: '#717171'
};
},
mixins: [conditionalStylesMixin],

View File

@@ -1,5 +1,4 @@
.c-box-view,
.c-ellipse-view {
.c-box-view {
border-width: $drawingObjBorderW !important;
display: flex;
align-items: stretch;
@@ -9,10 +8,6 @@
}
}
.c-ellipse-view {
border-radius: 50%;
}
.c-line-view {
&.c-frame {
box-shadow: none !important;

View File

@@ -186,7 +186,7 @@ describe('the plugin', function () {
'configuration': {
'items': [
{
'fill': '#666666',
'fill': '#717171',
'stroke': '',
'x': 1,
'y': 1,
@@ -195,22 +195,12 @@ describe('the plugin', function () {
'type': 'box-view',
'id': '89b88746-d325-487b-aec4-11b79afff9e8'
},
{
'fill': '#666666',
'stroke': '',
'x': 1,
'y': 1,
'width': 10,
'height': 10,
'type': 'ellipse-view',
'id': '19b88746-d325-487b-aec4-11b79afff9z8'
},
{
'x': 18,
'y': 9,
'x2': 23,
'y2': 4,
'stroke': '#666666',
'stroke': '#717171',
'type': 'line-view',
'id': '57d49a28-7863-43bd-9593-6570758916f0'
},
@@ -351,7 +341,7 @@ describe('the plugin', function () {
it('provides controls including separators', () => {
const displayLayoutToolbar = openmct.toolbars.get(selection);
expect(displayLayoutToolbar.length).toBe(7);
expect(displayLayoutToolbar.length).toBe(9);
});
});
});

View File

@@ -81,7 +81,7 @@ export default {
cssClass: 'icon-notebook',
name: `Save to Notebook ${defaultPath}`,
onItemClicked: () => {
return this.snapshot(NOTEBOOK_DEFAULT, event.target);
return this.snapshot(NOTEBOOK_DEFAULT);
}
});
}
@@ -91,17 +91,16 @@ export default {
cssClass: 'icon-camera',
name: 'Save to Notebook Snapshots',
onItemClicked: () => {
return this.snapshot(NOTEBOOK_SNAPSHOT, event.target);
return this.snapshot(NOTEBOOK_SNAPSHOT);
}
});
this.openmct.menus.showMenu(x, y, notebookTypes);
},
snapshot(notebookType, target) {
snapshot(notebookType) {
this.$nextTick(() => {
const wrapper = target && target.closest('.js-notebook-snapshot-item-wrapper')
|| document;
const element = wrapper.querySelector('.js-notebook-snapshot-item');
const element = document.querySelector('.c-overlay__contents')
|| document.getElementsByClassName('l-shell__main-container')[0];
const bounds = this.openmct.time.bounds();
const link = !this.ignoreLink

View File

@@ -103,13 +103,10 @@ export function validateNotebookStorageObject() {
let valid = false;
if (notebookStorage) {
const oldInvalidKeys = ['notebookMeta', 'page', 'section'];
valid = Object.entries(notebookStorage).every(([key, value]) => {
Object.entries(notebookStorage).forEach(([key, value]) => {
const validKey = key !== undefined && key !== null;
const validValue = value !== undefined && value !== null;
const hasOldInvalidKeys = oldInvalidKeys.includes(key);
return validKey && validValue && !hasOldInvalidKeys;
valid = validKey && validValue;
});
}

View File

@@ -89,4 +89,13 @@ ColorPalette.prototype.getNextColor = function () {
return this.availableColors.shift();
};
/**
* @param {number} index the index of the color to return. An index
* value larger than the size of the index will wrap around.
* @returns {Color}
*/
ColorPalette.prototype.getColor = function (index) {
return this.colors[index % this.colors.length];
};
export default ColorPalette;

View File

@@ -19,17 +19,13 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
import { SPECTRAL_AGGREGATE_KEY } from './spectralAggregatePlot/SpectralAggregateConstants';
import PlotViewProvider from './PlotViewProvider';
import SpectralPlotViewProvider from './spectralPlot/SpectralPlotViewProvider';
import SpectralAggregatePlotViewProvider from './spectralAggregatePlot/SpectralAggregatePlotViewProvider';
import OverlayPlotViewProvider from './overlayPlot/OverlayPlotViewProvider';
import StackedPlotViewProvider from './stackedPlot/StackedPlotViewProvider';
import PlotsInspectorViewProvider from './inspector/PlotsInspectorViewProvider';
import OverlayPlotCompositionPolicy from './overlayPlot/OverlayPlotCompositionPolicy';
import StackedPlotCompositionPolicy from './stackedPlot/StackedPlotCompositionPolicy';
import SpectralPlotCompositionPolicy from './spectralPlot/SpectralPlotCompositionPolicy';
import SpectralAggregatePlotCompositionPolicy from './spectralAggregatePlot/SpectralAggregatePlotCompositionPolicy';
export default function () {
return function install(openmct) {
@@ -63,46 +59,13 @@ export default function () {
},
priority: 890
});
openmct.types.addType('telemetry.plot.spectral', {
key: "telemetry.plot.spectral",
name: "Spectral Plot",
cssClass: "icon-plot-stacked",
description: "View Spectra on Y Axes with non-time domain on the X axis. Can be added to Display Layouts.",
creatable: true,
initialize: function (domainObject) {
domainObject.composition = [];
domainObject.configuration = {};
},
priority: 890
});
openmct.types.addType(SPECTRAL_AGGREGATE_KEY, {
key: SPECTRAL_AGGREGATE_KEY,
name: "Spectral Aggregate Plot",
cssClass: "icon-plot-stacked",
description: "View Spectra on Y Axes with non-time domain on the X axis. Can be added to Display Layouts.",
creatable: true,
initialize: function (domainObject) {
domainObject.composition = [];
domainObject.configuration = {
plotType: 'bar'
};
},
priority: 891
});
openmct.objectViews.addProvider(new StackedPlotViewProvider(openmct));
openmct.objectViews.addProvider(new OverlayPlotViewProvider(openmct));
openmct.objectViews.addProvider(new PlotViewProvider(openmct));
openmct.objectViews.addProvider(new SpectralPlotViewProvider(openmct));
openmct.objectViews.addProvider(new SpectralAggregatePlotViewProvider(openmct));
openmct.inspectorViews.addProvider(new PlotsInspectorViewProvider(openmct));
openmct.composition.addPolicy(new OverlayPlotCompositionPolicy(openmct).allow);
openmct.composition.addPolicy(new StackedPlotCompositionPolicy(openmct).allow);
openmct.composition.addPolicy(new SpectralPlotCompositionPolicy(openmct).allow);
openmct.composition.addPolicy(new SpectralAggregatePlotCompositionPolicy(openmct).allow);
};
}

View File

@@ -24,12 +24,10 @@ import {createMouseEvent, createOpenMct, resetApplicationState, spyOnBuiltins} f
import PlotVuePlugin from "./plugin";
import Vue from "vue";
import StackedPlot from "./stackedPlot/StackedPlot.vue";
// import SpectralPlot from "./spectralPlot/SpectralPlot.vue";
import configStore from "./configuration/configStore";
import EventEmitter from "EventEmitter";
import PlotOptions from "./inspector/PlotOptions.vue";
import PlotConfigurationModel from "./configuration/PlotConfigurationModel";
import { SPECTRAL_AGGREGATE_VIEW, SPECTRAL_AGGREGATE_KEY } from './spectralAggregatePlot/SpectralAggregateConstants';
describe("the plugin", function () {
let element;
@@ -314,38 +312,6 @@ describe("the plugin", function () {
let plotView = applicableViews.find((viewProvider) => viewProvider.key === "plot-stacked");
expect(plotView).toBeDefined();
});
it("provides a spectral plot view for objects with telemetry", () => {
const testTelemetryObject = {
id: "test-object",
type: "telemetry.plot.spectral",
telemetry: {
values: [{
key: "a-very-fine-key"
}]
}
};
const applicableViews = openmct.objectViews.get(testTelemetryObject, mockObjectPath);
let plotView = applicableViews.find((viewProvider) => viewProvider.key === "plot-spectral");
expect(plotView).toBeDefined();
});
it("provides a spectral aggregate plot view for objects with telemetry", () => {
const testTelemetryObject = {
id: "test-object",
type: SPECTRAL_AGGREGATE_KEY,
telemetry: {
values: [{
key: "lots-of-aggregate-telemetry"
}]
}
};
const applicableViews = openmct.objectViews.get(testTelemetryObject, mockObjectPath);
let plotView = applicableViews.find((viewProvider) => viewProvider.key === SPECTRAL_AGGREGATE_VIEW);
expect(plotView).toBeDefined();
});
});
describe("The single plot view", () => {
@@ -496,146 +462,6 @@ describe("the plugin", function () {
});
});
/*
* disabling this until we develop the plot view
describe("The spectral plot view", () => {
let testTelemetryObject;
// eslint-disable-next-line no-unused-vars
let testTelemetryObject2;
// eslint-disable-next-line no-unused-vars
let config;
let spectralPlotObject;
let component;
let mockComposition;
// eslint-disable-next-line no-unused-vars
let plotViewComponentObject;
beforeEach(() => {
const getFunc = openmct.$injector.get;
spyOn(openmct.$injector, "get")
.withArgs("exportImageService").and.returnValue({
exportPNG: () => {},
exportJPG: () => {}
})
.and.callFake(getFunc);
spectralPlotObject = {
identifier: {
namespace: "",
key: "test-spectral-plot"
},
type: "telemetry.plot.spectral",
name: "Test Spectral Plot"
};
testTelemetryObject = {
identifier: {
namespace: "",
key: "test-object"
},
type: "test-object",
name: "Test Object",
telemetry: {
values: [{
key: "utc",
format: "utc",
name: "Time",
hints: {
domain: 1
}
}, {
key: "some-key",
name: "Some attribute",
hints: {
range: 1
}
}, {
key: "some-other-key",
name: "Another attribute",
hints: {
range: 2
}
}]
}
};
testTelemetryObject2 = {
identifier: {
namespace: "",
key: "test-object2"
},
type: "test-object",
name: "Test Object2",
telemetry: {
values: [{
key: "utc",
format: "utc",
name: "Time",
hints: {
domain: 1
}
}, {
key: "wavelength",
name: "Wavelength",
hints: {
range: 1
}
}, {
key: "some-other-key2",
name: "Another attribute2",
hints: {
range: 2
}
}]
}
};
mockComposition = new EventEmitter();
mockComposition.load = () => {
mockComposition.emit('add', testTelemetryObject);
return [testTelemetryObject];
};
spyOn(openmct.composition, 'get').and.returnValue(mockComposition);
let viewContainer = document.createElement("div");
child.append(viewContainer);
component = new Vue({
el: viewContainer,
components: {
SpectralPlot
},
provide: {
openmct: openmct,
domainObject: spectralPlotObject,
composition: openmct.composition.get(spectralPlotObject)
},
template: "<spectral-plot></spectral-plot>"
});
cleanupFirst.push(() => {
component.$destroy();
component = undefined;
});
return telemetryPromise
.then(Vue.nextTick())
.then(() => {
plotViewComponentObject = component.$root.$children[0];
const configId = openmct.objects.makeKeyString(testTelemetryObject.identifier);
config = configStore.get(configId);
});
});
it("Renders a collapsed legend for every telemetry", () => {
let legend = element.querySelectorAll(".plot-wrapper-collapsed-legend .plot-series-name");
expect(legend.length).toBe(1);
expect(legend[0].innerHTML).toEqual("Test Object");
});
}); */
describe("The stacked plot view", () => {
let testTelemetryObject;
let testTelemetryObject2;
@@ -1164,39 +990,4 @@ describe("the plugin", function () {
});
});
describe("the spectral plot", () => {
const mockObject = {
name: 'A Very Nice Spectral Plot',
key: 'telemetry.plot.spectral',
creatable: true
};
it('defines a spectral plot object type with the correct key', () => {
const objectDef = openmct.types.get('telemetry.plot.spectral').definition;
expect(objectDef.key).toEqual(mockObject.key);
});
it('is creatable', () => {
const objectDef = openmct.types.get('telemetry.plot.spectral').definition;
expect(objectDef.creatable).toEqual(mockObject.creatable);
});
});
describe("the aggregate spectral plot", () => {
const mockObject = {
name: 'An Even Nicer Aggregate Spectral Plot',
key: SPECTRAL_AGGREGATE_KEY,
creatable: true
};
it('defines a spectral plot object type with the correct key', () => {
const objectDef = openmct.types.get(SPECTRAL_AGGREGATE_KEY).definition;
expect(objectDef.key).toEqual(mockObject.key);
});
it('is creatable', () => {
const objectDef = openmct.types.get(SPECTRAL_AGGREGATE_KEY).definition;
expect(objectDef.creatable).toEqual(mockObject.creatable);
});
});
});

View File

@@ -1,10 +0,0 @@
export const CONFIGURATION_CHANGED = 'configurationChanged';
export const HOVER_VALUES_CHANGED = 'hoverValuesChanged';
export const HOVER_VALUES_CLEARED = 'hoverValuesCleared';
export const LEGEND_EXPANDED = 'plot-legends-expanded';
export const REALTIME_POLL_INTERVAL_IN_MS = 5000;
export const SPECTRAL_AGGREGATE_VIEW = 'plot.spectral.aggregate.view';
export const SPECTRAL_AGGREGATE_KEY = 'telemetry.plot.spectral.aggregate';
export const SUBSCRIBE = 'subscribe';
export const UNSUBSCRIBE = 'unsubscribe';

View File

@@ -1,289 +0,0 @@
<template>
<div ref="plotWrapper"
class="has-local-controls"
:class="{ 's-unsynced' : isZoomed }"
>
<div v-if="isZoomed"
class="l-state-indicators"
>
<span class="l-state-indicators__alert-no-lad t-object-alert t-alert-unsynced icon-alert-triangle"
title="This plot is not currently displaying the latest data. Reset pan/zoom to view latest data."
></span>
</div>
<div ref="plot"
class="c-spectral-aggregate-plot__plot"
></div>
<div ref="localControl"
class="gl-plot__local-controls h-local-controls h-local-controls--overlay-content c-local-controls--show-on-hover"
>
<button v-if="data.length"
class="c-button icon-reset"
:disabled="!isZoomed"
title="Reset pan/zoom"
@click="reset()"
>
</button>
</div>
</div>
</template>
<script>
import Plotly from 'plotly.js/dist/plotly';
import { HOVER_VALUES_CLEARED, HOVER_VALUES_CHANGED, SUBSCRIBE, UNSUBSCRIBE } from './SpectralAggregateConstants';
const PLOT_PADDING_IN_PERCENT = 1;
const MULTI_AXES_X_PADDING_PERCENT = {
LEFT: 8,
RIGHT: 94
};
export default {
inject: ['openmct', 'domainObject'],
props: [
'data',
'legendExpanded',
'plotAxisTitle'
],
data() {
return {
isZoomed: false,
primaryYAxisRange: {
min: '',
max: ''
},
xAxisRange: {
min: '',
max: ''
}
};
},
watch: {
data: {
immediate: false,
handler: 'updateData'
},
legendExpanded: {
immediate: false,
handler: 'updatePlot'
}
},
mounted() {
Plotly.newPlot(this.$refs.plot, Array.from(this.data), this.getLayout(), {
responsive: true,
displayModeBar: false
});
this.registerListeners();
},
beforeDestroy() {
this.$refs.plot.removeAllListeners();
if (this.plotResizeObserver) {
this.plotResizeObserver.unobserve(this.$refs.plotWrapper);
clearTimeout(this.resizeTimer);
}
},
methods: {
getAxisMinMax(axis) {
const min = axis.autoSize
? ''
: axis.min;
const max = axis.autoSize
? ''
: axis.max;
return {
min,
max
};
},
getAxisPadding(min, max) {
return (Math.abs(max - min) * PLOT_PADDING_IN_PERCENT / 100) || 0;
},
getLayout() {
const yAxesMeta = this.getYAxisMeta();
const primaryYaxis = this.getYaxisLayout(yAxesMeta['1']);
const xAxisDomain = this.getXAxisDomain(yAxesMeta);
return {
// hovermode: 'closest',
// hoverdistance: -1,
autosize: true,
showlegend: false,
font: {
family: 'Helvetica Neue, Helvetica, Arial, sans-serif',
size: '12px',
color: '#666'
},
xaxis: {
domain: xAxisDomain,
// hoverformat: '.2r',
range: [this.xAxisRange.min, this.xAxisRange.max],
title: this.plotAxisTitle.xAxisTitle
// zeroline: false
},
yaxis: primaryYaxis,
margin: {
l: 40,
r: 10,
b: 40,
t: 20
},
paper_bgcolor: 'transparent',
plot_bgcolor: 'transparent'
};
},
getYAxisMeta() {
const yAxisMeta = {};
this.data.forEach(d => {
const yAxisMetadata = d.yAxisMetadata;
const range = '1';
const side = 'left';
const name = '';
const unit = yAxisMetadata.units;
yAxisMeta[range] = {
range,
side,
name,
unit
};
});
return yAxisMeta;
},
getXAxisDomain(yAxisMeta) {
let leftPaddingPerc = 0;
let rightPaddingPerc = 100;
let rightSide = yAxisMeta && Object.values(yAxisMeta).filter((axisMeta => axisMeta.side === 'right'));
let leftSide = yAxisMeta && Object.values(yAxisMeta).filter((axisMeta => axisMeta.side === 'left'));
if (yAxisMeta && rightSide.length > 1) {
rightPaddingPerc = MULTI_AXES_X_PADDING_PERCENT.RIGHT;
}
if (yAxisMeta && leftSide.length > 1) {
leftPaddingPerc = MULTI_AXES_X_PADDING_PERCENT.LEFT;
}
return [leftPaddingPerc / 100, rightPaddingPerc / 100];
},
getYaxisLayout(yAxisMeta) {
if (!yAxisMeta) {
return {};
}
const { name, range, side = 'left', unit } = yAxisMeta;
const title = `${name} ${unit ? '(' + unit + ')' : ''}`;
const yaxis = {
// hoverformat: '.2r',
// showgrid: true,
title
// zeroline: false
};
let yAxistype = this.primaryYAxisRange;
if (range === '1') {
yaxis.range = [yAxistype.min, yAxistype.max];
return yaxis;
}
yaxis.range = [yAxistype.min, yAxistype.max];
yaxis.anchor = side.toLowerCase() === 'left'
? 'free'
: 'x';
yaxis.showline = side.toLowerCase() === 'left';
yaxis.side = side.toLowerCase();
yaxis.overlaying = 'y';
yaxis.position = 0.01;
return yaxis;
},
handleHover(isHovered, itemValues) {
return () => {
this.updateLocalControlPosition(isHovered);
const eventName = isHovered ? HOVER_VALUES_CHANGED : HOVER_VALUES_CLEARED;
this.$emit(eventName, { itemValues });
};
},
registerListeners() {
this.$refs.plot.on('plotly_hover', this.handleHover.bind(this, true));
this.$refs.plot.on('plotly_unhover', this.handleHover.bind(this, false));
this.$refs.plot.on('plotly_relayout', this.zoom);
this.resizeTimer = false;
if (window.ResizeObserver) {
this.plotResizeObserver = new ResizeObserver(() => {
// debounce and trigger window resize so that plotly can resize the plot
clearTimeout(this.resizeTimer);
this.resizeTimer = setTimeout(() => {
window.dispatchEvent(new Event('resize'));
}, 250);
});
this.plotResizeObserver.observe(this.$refs.plotWrapper);
}
},
reset() {
this.updatePlot();
this.isZoomed = false;
this.$emit(SUBSCRIBE);
},
updateData() {
this.updatePlot();
},
updateLocalControlPosition() {
const localControl = this.$refs.localControl;
localControl.style.display = 'none';
const plot = this.$refs.plot;
const bgLayer = this.$el.querySelector('.bglayer');
const plotBoundingRect = plot.getBoundingClientRect();
const bgLayerBoundingRect = bgLayer.getBoundingClientRect();
const top = bgLayerBoundingRect.top - plotBoundingRect.top + 5;
const left = bgLayerBoundingRect.left - plotBoundingRect.left + 5;
localControl.style.top = `${top}px`;
localControl.style.left = `${left}px`;
localControl.style.display = 'block';
},
updatePlot() {
if (!this.$refs || !this.$refs.plot) {
return;
}
Plotly.react(this.$refs.plot, Array.from(this.data), this.getLayout());
},
zoom(eventData) {
const autorange = eventData['xaxis.autorange'];
const { autosize } = eventData;
if (autosize || autorange) {
this.isZoomed = false;
this.reset();
return;
}
this.isZoomed = true;
this.$emit(UNSUBSCRIBE);
}
}
};
</script>
<style lang="scss">
.c-spectral-aggregate-plot__plot {
height: 100%;
}
.c-spectral-aggregate-plot-view .gl-plot__local-controls {
top: 25px;
}
.has-local-controls {
border: 1px solid transparent;
}
</style>

View File

@@ -1,58 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, 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.
*****************************************************************************/
import { SPECTRAL_AGGREGATE_KEY } from './SpectralAggregateConstants';
export default function SpectralAggregatePlotCompositionPolicy(openmct) {
function hasAggregateDomainAndRange(metadata) {
const rangeValues = metadata.valuesForHints(['domain']);
const domainValues = metadata.valuesForHints(['range']);
return rangeValues.length > 0
|| domainValues.length > 0;
}
function hasSpectralAggregateTelemetry(domainObject) {
if (!Object.prototype.hasOwnProperty.call(domainObject, 'telemetry')) {
return false;
}
let metadata = openmct.telemetry.getMetadata(domainObject);
return metadata.values().length > 0 && hasAggregateDomainAndRange(metadata);
}
function hasNoChildren(parentObject) {
return parentObject.composition && parentObject.composition.length < 1;
}
return {
allow: function (parent, child) {
if ((parent.type === SPECTRAL_AGGREGATE_KEY)
&& ((child.type !== 'telemetry.plot.overlay') && (hasSpectralAggregateTelemetry(child) === false) || (hasNoChildren(parent) === false))
) {
return false;
}
return true;
}
};
}

View File

@@ -1,376 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, 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.
*****************************************************************************/
import SpectralAggregatePlotCompositionPolicy from "./SpectralAggregatePlotCompositionPolicy";
import { createOpenMct } from "utils/testing";
describe("The spectral aggregation plot composition policy", () => {
let openmct;
const mockNonSpectralMetaData = {
"period": 10,
"amplitude": 1,
"offset": 0,
"dataRateInHz": 1,
"phase": 0,
"randomness": 0,
valuesForHints: () => {
return [
{
"key": "sin",
"name": "Sine",
"unit": "Hz",
"formatString": "%0.2f",
"hints": {
"range": 1,
"priority": 4
},
"source": "sin"
},
{
"key": "cos",
"name": "Cosine",
"unit": "deg",
"formatString": "%0.2f",
"hints": {
"range": 2,
"priority": 5
},
"source": "cos"
}
];
},
values: [
{
"key": "name",
"name": "Name",
"format": "string",
"source": "name",
"hints": {
"priority": 0
}
},
{
"key": "utc",
"name": "Time",
"format": "utc",
"hints": {
"domain": 1,
"priority": 1
},
"source": "utc"
},
{
"key": "yesterday",
"name": "Yesterday",
"format": "utc",
"hints": {
"domain": 2,
"priority": 2
},
"source": "yesterday"
},
{
"key": "cos",
"name": "Cosine",
"unit": "deg",
"formatString": "%0.2f",
"hints": {
"domain": 3,
"priority": 3
},
"source": "cos"
},
{
"key": "sin",
"name": "Sine",
"unit": "Hz",
"formatString": "%0.2f",
"hints": {
"range": 1,
"priority": 4
},
"source": "sin"
},
{
"key": "cos",
"name": "Cosine",
"unit": "deg",
"formatString": "%0.2f",
"hints": {
"range": 2,
"priority": 5
},
"source": "cos"
}
]
};
const mockGoodSpectralMetaData = {
"period": 10,
"amplitude": 1,
"offset": 0,
"dataRateInHz": 1,
"phase": 0,
"randomness": 0,
"wavelength": 0,
valuesForHints: () => {
return [
{
"key": "sin",
"name": "Sine",
"unit": "Hz",
"formatString": "%0.2f",
"hints": {
"range": 1,
"priority": 4
},
"source": "sin"
},
{
"key": "cos",
"name": "Cosine",
"unit": "deg",
"formatString": "%0.2f",
"hints": {
"range": 2,
"priority": 5
},
"source": "cos"
}
];
},
values: [
{
"key": "name",
"name": "Name",
"format": "string",
"source": "name",
"hints": {
"priority": 0
}
},
{
"key": "utc",
"name": "Time",
"format": "utc",
"hints": {
"domain": 1,
"priority": 1
},
"source": "utc"
},
{
"key": "yesterday",
"name": "Yesterday",
"format": "utc",
"hints": {
"domain": 2,
"priority": 2
},
"source": "yesterday"
},
{
"key": "cos",
"name": "Cosine",
"unit": "deg",
"formatString": "%0.2f",
"hints": {
"domain": 3,
"priority": 3
},
"source": "cos"
},
{
"key": "sin",
"name": "Sine",
"unit": "Hz",
"formatString": "%0.2f",
"hints": {
"range": 1,
"spectralAttribute": true
},
"source": "sin"
},
{
"key": "cos",
"name": "Cosine",
"unit": "deg",
"formatString": "%0.2f",
"hints": {
"range": 2,
"priority": 5
},
"source": "cos"
}
]
};
beforeEach(() => {
openmct = createOpenMct();
const mockTypeDef = {
telemetry: mockGoodSpectralMetaData
};
const mockTypeService = {
getType: () => {
return {
typeDef: mockTypeDef
};
}
};
openmct.$injector = {
get: () => {
return mockTypeService;
}
};
openmct.telemetry.isTelemetryObject = function (domainObject) {
return true;
};
});
it("exists", () => {
expect(SpectralAggregatePlotCompositionPolicy(openmct).allow).toBeDefined();
});
it("allow composition only for telemetry that provides/supports spectral data", () => {
const parent = {
"composition": [],
"configuration": {},
"name": "Some Spectral Aggregate Plot",
"type": "telemetry.plot.spectral.aggregate",
"location": "mine",
"modified": 1631005183584,
"persisted": 1631005183502,
"identifier": {
"namespace": "",
"key": "b78e7e23-f2b8-4776-b1f0-3ff778f5c8a9"
}
};
const child = {
"telemetry": {
"period": 10,
"amplitude": 1,
"offset": 0,
"dataRateInHz": 1,
"phase": 0,
"randomness": 0
},
"name": "Unnamed Sine Wave Generator",
"type": "generator",
"location": "mine",
"modified": 1630399715531,
"persisted": 1630399715531,
"identifier": {
"namespace": "",
"key": "21d61f2d-6d2d-4bea-8b0a-7f59fd504c6c"
}
};
expect(SpectralAggregatePlotCompositionPolicy(openmct).allow(parent, child)).toEqual(true);
});
it("disallows composition for telemetry that contain anything else", () => {
const mockTypeDef = {
telemetry: mockNonSpectralMetaData
};
const mockTypeService = {
getType: () => {
return {
typeDef: mockTypeDef
};
}
};
openmct.$injector = {
get: () => {
return mockTypeService;
}
};
const parent = {
"composition": [],
"configuration": {},
"name": "Some Spectral Aggregate Plot",
"type": "telemetry.plot.spectral.aggregate",
"location": "mine",
"modified": 1631005183584,
"persisted": 1631005183502,
"identifier": {
"namespace": "",
"key": "b78e7e23-f2b8-4776-b1f0-3ff778f5c8a9"
}
};
const child = {
"telemetry": {
"period": 10,
"amplitude": 1,
"offset": 0,
"dataRateInHz": 1,
"phase": 0,
"randomness": 0
},
"name": "Unnamed Sine Wave Generator",
"type": "generator",
"location": "mine",
"modified": 1630399715531,
"persisted": 1630399715531,
"identifier": {
"namespace": "",
"key": "21d61f2d-6d2d-4bea-8b0a-7f59fd504c6c"
}
};
expect(SpectralAggregatePlotCompositionPolicy(openmct).allow(parent, child)).toEqual(false);
});
it("passthrough for composition for non spectral aggregate plots", () => {
const parent = {
"composition": [],
"configuration": {},
"name": "Some Stacked Plot",
"type": "telemetry.plot.stacked",
"location": "mine",
"modified": 1631005183584,
"persisted": 1631005183502,
"identifier": {
"namespace": "",
"key": "b78e7e23-f2b8-4776-b1f0-3ff778f5c8a9"
}
};
const child = {
"telemetry": {
"period": 10,
"amplitude": 1,
"offset": 0,
"dataRateInHz": 1,
"phase": 0,
"randomness": 0
},
"name": "Unnamed Sine Wave Generator",
"type": "generator",
"location": "mine",
"modified": 1630399715531,
"persisted": 1630399715531,
"identifier": {
"namespace": "",
"key": "21d61f2d-6d2d-4bea-8b0a-7f59fd504c6c"
}
};
expect(SpectralAggregatePlotCompositionPolicy(openmct).allow(parent, child)).toEqual(true);
});
});

View File

@@ -1,76 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, 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.
*****************************************************************************/
import SpectralAggregateView from './SpectralAggregateView.vue';
import { SPECTRAL_AGGREGATE_KEY, SPECTRAL_AGGREGATE_VIEW } from './SpectralAggregateConstants';
import Vue from 'vue';
export default function SpectralAggregatePlotViewProvider(openmct) {
function isCompactView(objectPath) {
return objectPath.find(object => object.type === 'time-strip');
}
return {
key: SPECTRAL_AGGREGATE_VIEW,
name: 'Spectral Aggregate Plot',
cssClass: 'icon-telemetry',
canView(domainObject, objectPath) {
return domainObject && domainObject.type === SPECTRAL_AGGREGATE_KEY;
},
canEdit(domainObject, objectPath) {
return domainObject && domainObject.type === SPECTRAL_AGGREGATE_KEY;
},
view: function (domainObject, objectPath) {
let component;
return {
show: function (element) {
let isCompact = isCompactView(objectPath);
component = new Vue({
el: element,
components: {
SpectralAggregateView
},
provide: {
openmct,
domainObject
},
data() {
return {
options: {
compact: isCompact
}
};
},
template: '<spectral-aggregate-view :options="options"></spectral-aggregate-view>'
});
},
destroy: function () {
component.$destroy();
component = undefined;
}
};
}
};
}

View File

@@ -1,332 +0,0 @@
<!--
Open MCT, Copyright (c) 2014-2021, 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.
-->
<template>
<div class="c-spectral-aggregate-plot-view gl-plot plot-legend-bottom"
:class="{'plot-legend-expanded': legendExpanded, 'plot-legend-collapsed': !legendExpanded }"
>
<SpectralAggregatePlot ref="spectralAggregatePlot"
class="c-spectral-aggregate-plot__plot-wrapper"
:data="visibleData"
:plot-axis-title="plotAxisTitle"
:legend-expanded="legendExpanded"
/>
</div>
</template>
<script>
import * as SPECTRAL_AGGREGATE from './SpectralAggregateConstants';
import ColorPalette from '../lib/ColorPalette';
import objectUtils from 'objectUtils';
import SpectralAggregatePlot from './SpectralAggregatePlot.vue';
export default {
components: {
SpectralAggregatePlot
},
inject: ['openmct', 'domainObject'],
data() {
return {
colorMapping: {},
composition: {},
currentDomainObject: this.domainObject,
isRealTime: (this.openmct.time.clock() !== undefined),
spectralAggregateTypes: {},
subscriptions: [],
telemetryObjects: {},
trace: [],
legendExpanded: false
};
},
computed: {
activeClock() {
return this.openmct.time.activeClock;
},
plotAxisTitle() {
const { xAxisMetadata = {}, yAxisMetadata = {} } = this.trace[0] || {};
const xAxisUnit = xAxisMetadata.units ? `(${xAxisMetadata.units})` : '';
const yAxisUnit = yAxisMetadata.units ? `(${yAxisMetadata.units})` : '';
return {
xAxisTitle: `${xAxisMetadata.name || ''} ${xAxisUnit}`,
yAxisTitle: `${yAxisMetadata.name || ''} ${yAxisUnit}`
};
},
visibleData() {
return this.trace.filter((trace) => trace.hidden !== true);
}
},
mounted() {
this.colorPalette = new ColorPalette();
this.loadComposition();
this.openmct.time.on('bounds', this.refreshData);
this.openmct.time.on('clock', this.clockChanged);
this.$refs.spectralAggregatePlot.$on(SPECTRAL_AGGREGATE.SUBSCRIBE, this.subscribeToAll);
this.$refs.spectralAggregatePlot.$on(SPECTRAL_AGGREGATE.UNSUBSCRIBE, this.removeAllSubscriptions);
this.unobserve = this.openmct.objects.observe(this.currentDomainObject, '*', this.updateDomainObject);
},
beforeDestroy() {
this.$refs.spectralAggregatePlot.$off();
this.openmct.time.off('bounds', this.refreshData);
this.openmct.time.off('clock', this.clockChanged);
this.removeAllSubscriptions();
this.unobserve();
if (!this.composition) {
return;
}
this.composition.off('add', this.addTelemetryObject);
this.composition.off('remove', this.removeTelemetryObject);
},
methods: {
addColorForTelemetry(key) {
const color = this.colorPalette.getNextColor().asHexString();
this.colorMapping[key] = color;
return color;
},
addSpectralAggregateType(key, name, timestamp, color) {
this.$set(this.spectralAggregateTypes, key, {
name,
timestamp,
color
});
},
addTelemetryObject(telemetryObject) {
const key = objectUtils.makeKeyString(telemetryObject.identifier);
if (!this.colorMapping[key]) {
this.addColorForTelemetry(key);
}
this.telemetryObjects[key] = telemetryObject;
this.requestDataFor(telemetryObject);
this.subscribeToObject(telemetryObject);
},
addTrace(trace, key) {
if (!this.trace.length) {
this.trace = this.trace.concat([trace]);
return;
}
let isInTrace = false;
const newTrace = this.trace.map((currentTrace, index) => {
if (currentTrace.key !== key) {
return currentTrace;
}
isInTrace = true;
return trace;
});
this.trace = isInTrace ? newTrace : newTrace.concat([trace]);
this.updateTraceVisibility();
},
clockChanged() {
this.isRealTime = this.openmct.time.clock() !== undefined;
this.removeAllSubscriptions();
this.subscribeToAll();
},
getAxisMetadata(telemetryObject) {
const metadata = this.openmct.telemetry.getMetadata(telemetryObject);
const yAxisMetadata = metadata.valuesForHints(['range'])[0];
const xAxisMetadata = metadata.valueMetadatas.filter((valueMetadata => {
return valueMetadata.key !== 'name' && !this.openmct.time.getAllTimeSystems().find((timeSystem) => timeSystem.key === valueMetadata.key);
}));
return {
xAxisMetadata,
yAxisMetadata
};
},
getOptions(telemetryObject) {
const { start, end } = this.openmct.time.bounds();
return {
averages: 0,
end,
start,
startTime: null,
spectra: true
};
},
loadComposition() {
this.composition = this.openmct.composition.get(this.currentDomainObject);
if (!this.composition) {
this.addTelemetryObject(this.currentDomainObject);
return;
}
this.composition.on('add', this.addTelemetryObject);
this.composition.on('remove', this.removeTelemetryObject);
this.composition.load();
},
refreshData(bounds, isTick) {
if (!isTick) {
this.colorPalette.reset();
const telemetryObjects = Object.values(this.telemetryObjects);
telemetryObjects.forEach(this.requestDataFor);
}
},
removeAllSubscriptions() {
this.subscriptions.forEach(subscription => subscription.unsubscribe());
this.subscriptions = [];
},
removeTelemetryObject(identifier) {
const key = objectUtils.makeKeyString(identifier);
delete this.telemetryObjects[key];
this.$delete(this.spectralAggregateTypes, key);
this.subscriptions.forEach(subscription => {
if (subscription.key !== key) {
return;
}
subscription.unsubscribe();
delete this.subscriptions[key];
});
this.trace = this.trace.filter(t => t.key !== key);
},
processData(telemetryObject, data, axisMetadata) {
const key = objectUtils.makeKeyString(telemetryObject.identifier);
const formattedTimestamp = 'N/A';
const color = this.colorMapping[key];
const spectralAggregateValue = this.spectralAggregateTypes[key];
if (!spectralAggregateValue) {
this.addSpectralAggregateType(key, telemetryObject.name, formattedTimestamp, color);
}
if (data.message) {
this.openmct.notifications.alert(data.message);
}
let xValues = [];
let yValues = [];
axisMetadata.xAxisMetadata.forEach((metadata) => {
xValues.push(metadata.name);
if (data[metadata.key]) {
yValues.push(data[metadata.key]);
} else {
yValues.push('');
}
});
const trace = {
key,
name: telemetryObject.name,
x: xValues,
y: yValues,
xAxisMetadata: axisMetadata.xAxisMetadata,
yAxisMetadata: axisMetadata.yAxisMetadata,
type: 'bar'
};
this.addTrace(trace, key);
},
requestDataFor(telemetryObject) {
const axisMetadata = this.getAxisMetadata(telemetryObject);
this.openmct.telemetry.request(telemetryObject, this.getOptions(telemetryObject))
.then(data => {
data.forEach((datum) => {
this.processData(telemetryObject, datum, axisMetadata);
});
});
},
subscribeToObject(telemetryObject) {
const key = objectUtils.makeKeyString(telemetryObject.identifier);
const found = Object.values(this.subscriptions).findIndex(objectKey => objectKey === key);
if (found > -1) {
this.subscriptions[found].unsubscribe();
delete this.subscriptions[found];
}
const options = this.getOptions(telemetryObject);
const axisMetadata = this.getAxisMetadata(telemetryObject);
const unsubscribe = this.openmct.telemetry.subscribe(telemetryObject,
data => this.processData(telemetryObject, data, axisMetadata)
, options);
this.subscriptions.push({
key,
unsubscribe
});
},
subscribeToAll() {
this.colorPalette.reset();
const telemetryObjects = Object.values(this.telemetryObjects);
telemetryObjects.forEach(this.subscribeToObject);
},
updateDomainObject(newDomainObject) {
this.currentDomainObject = newDomainObject;
},
updateTraceVisibility() {
// We create a copy here to improve performance since visibleData - a computed property - is dependent on this.trace.
this.trace = this.trace.map((currentTrace, index) => {
currentTrace.hidden = this.spectralAggregateTypes[currentTrace.key].hidden === true;
return currentTrace;
});
}
}
};
</script>
<style lang="scss">
.c-spectral-aggregate-plot {
> * + * {
margin-top: 5px;
}
&-view {
display: flex;
flex-direction: column;
overflow: hidden;
}
&__plot-wrapper {
flex: 1 1 auto;
min-height: 300px;
min-width: 300px;
}
&__legend-wrapper {
flex: 0 1 auto;
overflow: auto;
padding-right: 5px;
}
}
</style>

View File

@@ -1,36 +0,0 @@
export default function SpectralPlotCompositionPolicy(openmct) {
function hasSpectralDomainAndRange(metadata) {
const rangeValues = metadata.valuesForHints(['range']);
const domainValues = metadata.valuesForHints(['domain']);
const containsSomeSpectralData = domainValues.some(value => {
return ((value.key === 'wavelength') || (value.key === 'frequency'));
});
return rangeValues.length > 0
&& domainValues.length > 0
&& containsSomeSpectralData;
}
function hasSpectralTelemetry(domainObject) {
if (!Object.prototype.hasOwnProperty.call(domainObject, 'telemetry')) {
return false;
}
let metadata = openmct.telemetry.getMetadata(domainObject);
return metadata.values().length > 0 && hasSpectralDomainAndRange(metadata);
}
return {
allow: function (parent, child) {
if ((parent.type === 'telemetry.plot.spectral')
&& ((child.type !== 'telemetry.plot.overlay') && (hasSpectralTelemetry(child) === false))
) {
return false;
}
return true;
}
};
}

View File

@@ -1,75 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, 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.
*****************************************************************************/
import SpectralView from './SpectralView.vue';
import Vue from 'vue';
export default function SpectralPlotViewProvider(openmct) {
function isCompactView(objectPath) {
return objectPath.find(object => object.type === 'time-strip');
}
return {
key: 'plot-spectral',
name: 'Spectral Plot',
cssClass: 'icon-telemetry',
canView(domainObject, objectPath) {
return domainObject && domainObject.type === 'telemetry.plot.spectral';
},
canEdit(domainObject, objectPath) {
return domainObject && domainObject.type === 'telemetry.plot.spectral';
},
view: function (domainObject, objectPath) {
let component;
return {
show: function (element) {
let isCompact = isCompactView(objectPath);
component = new Vue({
el: element,
components: {
SpectralView
},
provide: {
openmct,
domainObject
},
data() {
return {
options: {
compact: isCompact
}
};
},
template: '<spectral-view :options="options"></spectral-view>'
});
},
destroy: function () {
component.$destroy();
component = undefined;
}
};
}
};
}

View File

@@ -1,13 +0,0 @@
<template>
<div>
</div>
</template>
<script>
export default {
inject: ['openmct', 'domainObject']
};
</script>

View File

@@ -36,7 +36,7 @@ define([
}
/**
* Converts all objects in an object make from old format objects to new
* Convets all objects in an object make from old format objects to new
* format objects.
*/
function convertToNewObjects(oldObjectMap) {

View File

@@ -115,7 +115,7 @@ define([
expect(condition.evaluate(telemetryState)).toBe(true);
});
it('can evaluate "if any object matches"', function () {
it('can evalute "if any object matches"', function () {
condition = new SummaryWidgetCondition({
object: 'any',
key: 'raw',

View File

@@ -379,7 +379,7 @@ define(['../src/ConditionManager'], function (ConditionManager) {
telemetryRequests[1].resolve([mockTelemetryValues.mockCompObject2]);
});
it('updates its LAD cache upon receiving telemetry and invokes the appropriate handlers', function () {
it('updates its LAD cache upon recieving telemetry and invokes the appropriate handlers', function () {
mockTelemetryAPI.triggerTelemetryCallback('mockCompObject1');
expect(conditionManager.subscriptionCache.mockCompObject1.property1).toEqual('Its a different string');
mockTelemetryAPI.triggerTelemetryCallback('mockCompObject2');

View File

@@ -48,7 +48,7 @@
display: flex;
flex-flow: column nowrap;
flex: 1 1 auto;
height: 0; // Chrome 73 overflow bug fix
height: 0; // Chrome 73 oveflow bug fix
}
&__empty-message {

View File

@@ -149,7 +149,7 @@ define([
this.removeTelemetryCollection(keyString);
this.telemetryCollections[keyString] = this.openmct.telemetry
.requestCollection(telemetryObject, requestOptions);
.requestTelemetryCollection(telemetryObject, requestOptions);
this.telemetryCollections[keyString].on('remove', telemetryRemover);
this.telemetryCollections[keyString].on('add', telemetryProcessor);

View File

@@ -154,7 +154,6 @@ $glyph-icon-flag: '\e92a';
$glyph-icon-eye-disabled: '\e92b';
$glyph-icon-notebook-page: '\e92c';
$glyph-icon-unlocked: '\e92d';
$glyph-icon-circle: '\e92e';
$glyph-icon-arrows-right-left: '\ea00';
$glyph-icon-arrows-up-down: '\ea01';
$glyph-icon-bullet: '\ea02';
@@ -258,7 +257,6 @@ $glyph-icon-conditional: '\eb27';
$glyph-icon-condition-widget: '\eb28';
$glyph-icon-alphanumeric: '\eb29';
$glyph-icon-image-telemetry: '\eb2a';
$glyph-icon-telemetry-aggregate: '\eb2b';
/************************** GLYPHS AS DATA URI */
// Only objects have been converted, for use in Create menu and folder views

View File

@@ -85,7 +85,6 @@
.icon-eye-disabled { @include glyphBefore($glyph-icon-eye-disabled); }
.icon-notebook-page { @include glyphBefore($glyph-icon-notebook-page); }
.icon-unlocked { @include glyphBefore($glyph-icon-unlocked); }
.icon-circle { @include glyphBefore($glyph-icon-circle); }
.icon-arrows-right-left { @include glyphBefore($glyph-icon-arrows-right-left); }
.icon-arrows-up-down { @include glyphBefore($glyph-icon-arrows-up-down); }
.icon-bullet { @include glyphBefore($glyph-icon-bullet); }
@@ -189,7 +188,6 @@
.icon-condition-widget { @include glyphBefore($glyph-icon-condition-widget); }
.icon-alphanumeric { @include glyphBefore($glyph-icon-alphanumeric); }
.icon-image-telemetry { @include glyphBefore($glyph-icon-image-telemetry); }
.icon-telemetry-aggregate { @include glyphBefore($glyph-icon-telemetry-aggregate); }
/************************** 12 PX CLASSES */
// TODO: sync with 16px redo as of 10/25/18

View File

@@ -2,7 +2,7 @@
"metadata": {
"name": "Open MCT Symbols 16px",
"lastOpened": 0,
"created": 1629996145999
"created": 1621648023886
},
"iconSets": [
{
@@ -375,21 +375,13 @@
"code": 59693,
"tempChar": ""
},
{
"order": 197,
"id": 169,
"name": "icon-circle",
"prevSize": 24,
"code": 59694,
"tempChar": ""
},
{
"order": 27,
"id": 105,
"name": "icon-arrows-right-left",
"prevSize": 24,
"code": 59904,
"tempChar": ""
"tempChar": ""
},
{
"order": 26,
@@ -397,7 +389,7 @@
"name": "icon-arrows-up-down",
"prevSize": 24,
"code": 59905,
"tempChar": ""
"tempChar": ""
},
{
"order": 68,
@@ -405,7 +397,7 @@
"name": "icon-bullet",
"prevSize": 24,
"code": 59906,
"tempChar": ""
"tempChar": ""
},
{
"order": 150,
@@ -413,7 +405,7 @@
"prevSize": 24,
"code": 59907,
"name": "icon-calendar",
"tempChar": ""
"tempChar": ""
},
{
"order": 45,
@@ -421,7 +413,7 @@
"name": "icon-chain-links",
"prevSize": 24,
"code": 59908,
"tempChar": ""
"tempChar": ""
},
{
"order": 73,
@@ -429,7 +421,7 @@
"name": "icon-download",
"prevSize": 24,
"code": 59909,
"tempChar": ""
"tempChar": ""
},
{
"order": 39,
@@ -437,7 +429,7 @@
"name": "icon-duplicate",
"prevSize": 24,
"code": 59910,
"tempChar": ""
"tempChar": ""
},
{
"order": 50,
@@ -445,7 +437,7 @@
"name": "icon-folder-new",
"prevSize": 24,
"code": 59911,
"tempChar": ""
"tempChar": ""
},
{
"order": 138,
@@ -453,7 +445,7 @@
"name": "icon-fullscreen-collapse",
"prevSize": 24,
"code": 59912,
"tempChar": ""
"tempChar": ""
},
{
"order": 139,
@@ -461,7 +453,7 @@
"name": "icon-fullscreen-expand",
"prevSize": 24,
"code": 59913,
"tempChar": ""
"tempChar": ""
},
{
"order": 122,
@@ -469,7 +461,7 @@
"name": "icon-layers",
"prevSize": 24,
"code": 59914,
"tempChar": ""
"tempChar": ""
},
{
"order": 151,
@@ -477,7 +469,7 @@
"name": "icon-line-horz",
"prevSize": 24,
"code": 59915,
"tempChar": ""
"tempChar": ""
},
{
"order": 100,
@@ -485,7 +477,7 @@
"name": "icon-magnify",
"prevSize": 24,
"code": 59916,
"tempChar": ""
"tempChar": ""
},
{
"order": 99,
@@ -493,7 +485,7 @@
"name": "icon-magnify-in",
"prevSize": 24,
"code": 59917,
"tempChar": ""
"tempChar": ""
},
{
"order": 101,
@@ -501,7 +493,7 @@
"name": "icon-magnify-out-v2",
"prevSize": 24,
"code": 59918,
"tempChar": ""
"tempChar": ""
},
{
"order": 103,
@@ -509,7 +501,7 @@
"name": "icon-menu",
"prevSize": 24,
"code": 59919,
"tempChar": ""
"tempChar": ""
},
{
"order": 124,
@@ -517,7 +509,7 @@
"name": "icon-move",
"prevSize": 24,
"code": 59920,
"tempChar": ""
"tempChar": ""
},
{
"order": 7,
@@ -525,7 +517,7 @@
"name": "icon-new-window",
"prevSize": 24,
"code": 59921,
"tempChar": ""
"tempChar": ""
},
{
"order": 63,
@@ -533,7 +525,7 @@
"name": "icon-paint-bucket-v2",
"prevSize": 24,
"code": 59922,
"tempChar": ""
"tempChar": ""
},
{
"order": 15,
@@ -541,7 +533,7 @@
"name": "icon-pencil",
"prevSize": 24,
"code": 59923,
"tempChar": ""
"tempChar": ""
},
{
"order": 54,
@@ -549,7 +541,7 @@
"name": "icon-pencil-edit-in-place",
"prevSize": 24,
"code": 59924,
"tempChar": ""
"tempChar": ""
},
{
"order": 40,
@@ -557,7 +549,7 @@
"name": "icon-play",
"prevSize": 24,
"code": 59925,
"tempChar": ""
"tempChar": ""
},
{
"order": 125,
@@ -565,7 +557,7 @@
"name": "icon-pause",
"prevSize": 24,
"code": 59926,
"tempChar": ""
"tempChar": ""
},
{
"order": 119,
@@ -573,7 +565,7 @@
"name": "icon-plot-resource",
"prevSize": 24,
"code": 59927,
"tempChar": ""
"tempChar": ""
},
{
"order": 48,
@@ -581,7 +573,7 @@
"name": "icon-pointer-left",
"prevSize": 24,
"code": 59928,
"tempChar": ""
"tempChar": ""
},
{
"order": 47,
@@ -589,7 +581,7 @@
"name": "icon-pointer-right",
"prevSize": 24,
"code": 59929,
"tempChar": ""
"tempChar": ""
},
{
"order": 85,
@@ -597,7 +589,7 @@
"name": "icon-refresh",
"prevSize": 24,
"code": 59930,
"tempChar": ""
"tempChar": ""
},
{
"order": 55,
@@ -605,7 +597,7 @@
"name": "icon-save",
"prevSize": 24,
"code": 59931,
"tempChar": ""
"tempChar": ""
},
{
"order": 56,
@@ -613,7 +605,7 @@
"name": "icon-save-as",
"prevSize": 24,
"code": 59932,
"tempChar": ""
"tempChar": ""
},
{
"order": 58,
@@ -621,7 +613,7 @@
"name": "icon-sine",
"prevSize": 24,
"code": 59933,
"tempChar": ""
"tempChar": ""
},
{
"order": 113,
@@ -629,7 +621,7 @@
"name": "icon-font",
"prevSize": 24,
"code": 59934,
"tempChar": ""
"tempChar": ""
},
{
"order": 41,
@@ -637,7 +629,7 @@
"name": "icon-thumbs-strip",
"prevSize": 24,
"code": 59935,
"tempChar": ""
"tempChar": ""
},
{
"order": 146,
@@ -645,7 +637,7 @@
"name": "icon-two-parts-both",
"prevSize": 24,
"code": 59936,
"tempChar": ""
"tempChar": ""
},
{
"order": 145,
@@ -653,7 +645,7 @@
"name": "icon-two-parts-one-only",
"prevSize": 24,
"code": 59937,
"tempChar": ""
"tempChar": ""
},
{
"order": 82,
@@ -661,7 +653,7 @@
"name": "icon-resync",
"prevSize": 24,
"code": 59938,
"tempChar": ""
"tempChar": ""
},
{
"order": 86,
@@ -669,7 +661,7 @@
"name": "icon-reset",
"prevSize": 24,
"code": 59939,
"tempChar": ""
"tempChar": ""
},
{
"order": 61,
@@ -677,7 +669,7 @@
"name": "icon-x-in-circle",
"prevSize": 24,
"code": 59940,
"tempChar": ""
"tempChar": ""
},
{
"order": 84,
@@ -685,7 +677,7 @@
"name": "icon-brightness",
"prevSize": 24,
"code": 59941,
"tempChar": ""
"tempChar": ""
},
{
"order": 83,
@@ -693,7 +685,7 @@
"name": "icon-contrast",
"prevSize": 24,
"code": 59942,
"tempChar": ""
"tempChar": ""
},
{
"order": 87,
@@ -701,7 +693,7 @@
"name": "icon-expand",
"prevSize": 24,
"code": 59943,
"tempChar": ""
"tempChar": ""
},
{
"order": 89,
@@ -709,7 +701,7 @@
"name": "icon-list-view",
"prevSize": 24,
"code": 59944,
"tempChar": ""
"tempChar": ""
},
{
"order": 133,
@@ -717,7 +709,7 @@
"name": "icon-grid-snap-to",
"prevSize": 24,
"code": 59945,
"tempChar": ""
"tempChar": ""
},
{
"order": 132,
@@ -725,7 +717,7 @@
"name": "icon-grid-snap-no",
"prevSize": 24,
"code": 59946,
"tempChar": ""
"tempChar": ""
},
{
"order": 94,
@@ -733,7 +725,7 @@
"name": "icon-frame-show",
"prevSize": 24,
"code": 59947,
"tempChar": ""
"tempChar": ""
},
{
"order": 95,
@@ -741,7 +733,7 @@
"name": "icon-frame-hide",
"prevSize": 24,
"code": 59948,
"tempChar": ""
"tempChar": ""
},
{
"order": 97,
@@ -749,7 +741,7 @@
"name": "icon-import",
"prevSize": 24,
"code": 59949,
"tempChar": ""
"tempChar": ""
},
{
"order": 96,
@@ -757,7 +749,7 @@
"name": "icon-export",
"prevSize": 24,
"code": 59950,
"tempChar": ""
"tempChar": ""
},
{
"order": 194,
@@ -765,7 +757,7 @@
"name": "icon-font-size",
"prevSize": 24,
"code": 59951,
"tempChar": ""
"tempChar": ""
},
{
"order": 163,
@@ -773,7 +765,7 @@
"name": "icon-clear-data",
"prevSize": 24,
"code": 59952,
"tempChar": ""
"tempChar": ""
},
{
"order": 173,
@@ -781,7 +773,7 @@
"name": "icon-history",
"prevSize": 24,
"code": 59953,
"tempChar": ""
"tempChar": ""
},
{
"order": 181,
@@ -789,7 +781,7 @@
"name": "icon-arrow-up-to-parent",
"prevSize": 24,
"code": 59954,
"tempChar": ""
"tempChar": ""
},
{
"order": 184,
@@ -797,7 +789,7 @@
"name": "icon-crosshair-in-circle",
"prevSize": 24,
"code": 59955,
"tempChar": ""
"tempChar": ""
},
{
"order": 185,
@@ -805,7 +797,7 @@
"name": "icon-target",
"prevSize": 24,
"code": 59956,
"tempChar": ""
"tempChar": ""
},
{
"order": 187,
@@ -813,7 +805,7 @@
"name": "icon-items-collapse",
"prevSize": 24,
"code": 59957,
"tempChar": ""
"tempChar": ""
},
{
"order": 188,
@@ -821,7 +813,7 @@
"name": "icon-items-expand",
"prevSize": 24,
"code": 59958,
"tempChar": ""
"tempChar": ""
},
{
"order": 190,
@@ -829,7 +821,7 @@
"name": "icon-3-dots",
"prevSize": 24,
"code": 59959,
"tempChar": ""
"tempChar": ""
},
{
"order": 193,
@@ -837,7 +829,7 @@
"name": "icon-grid-on",
"prevSize": 24,
"code": 59960,
"tempChar": ""
"tempChar": ""
},
{
"order": 192,
@@ -845,7 +837,7 @@
"name": "icon-grid-off",
"prevSize": 24,
"code": 59961,
"tempChar": ""
"tempChar": ""
},
{
"order": 191,
@@ -853,7 +845,7 @@
"name": "icon-camera",
"prevSize": 24,
"code": 59962,
"tempChar": ""
"tempChar": ""
},
{
"order": 196,
@@ -861,7 +853,7 @@
"name": "icon-folders-collapse",
"prevSize": 24,
"code": 59963,
"tempChar": ""
"tempChar": ""
},
{
"order": 144,
@@ -869,7 +861,7 @@
"name": "icon-activity",
"prevSize": 24,
"code": 60160,
"tempChar": ""
"tempChar": ""
},
{
"order": 104,
@@ -877,7 +869,7 @@
"name": "icon-activity-mode",
"prevSize": 24,
"code": 60161,
"tempChar": ""
"tempChar": ""
},
{
"order": 137,
@@ -885,7 +877,7 @@
"name": "icon-autoflow-tabular",
"prevSize": 24,
"code": 60162,
"tempChar": ""
"tempChar": ""
},
{
"order": 115,
@@ -893,7 +885,7 @@
"name": "icon-clock",
"prevSize": 24,
"code": 60163,
"tempChar": ""
"tempChar": ""
},
{
"order": 2,
@@ -901,7 +893,7 @@
"name": "icon-database",
"prevSize": 24,
"code": 60164,
"tempChar": ""
"tempChar": ""
},
{
"order": 3,
@@ -909,7 +901,7 @@
"name": "icon-database-query",
"prevSize": 24,
"code": 60165,
"tempChar": ""
"tempChar": ""
},
{
"order": 67,
@@ -917,7 +909,7 @@
"name": "icon-dataset",
"prevSize": 24,
"code": 60166,
"tempChar": ""
"tempChar": ""
},
{
"order": 59,
@@ -925,7 +917,7 @@
"name": "icon-datatable",
"prevSize": 24,
"code": 60167,
"tempChar": ""
"tempChar": ""
},
{
"order": 136,
@@ -933,7 +925,7 @@
"name": "icon-dictionary",
"prevSize": 24,
"code": 60168,
"tempChar": ""
"tempChar": ""
},
{
"order": 51,
@@ -941,7 +933,7 @@
"name": "icon-folder",
"prevSize": 24,
"code": 60169,
"tempChar": ""
"tempChar": ""
},
{
"order": 147,
@@ -949,7 +941,7 @@
"name": "icon-image",
"prevSize": 24,
"code": 60170,
"tempChar": ""
"tempChar": ""
},
{
"order": 4,
@@ -957,7 +949,7 @@
"name": "icon-layout",
"prevSize": 24,
"code": 60171,
"tempChar": ""
"tempChar": ""
},
{
"order": 24,
@@ -965,7 +957,7 @@
"name": "icon-object",
"prevSize": 24,
"code": 60172,
"tempChar": ""
"tempChar": ""
},
{
"order": 52,
@@ -973,7 +965,7 @@
"name": "icon-object-unknown",
"prevSize": 24,
"code": 60173,
"tempChar": ""
"tempChar": ""
},
{
"order": 105,
@@ -981,7 +973,7 @@
"name": "icon-packet",
"prevSize": 24,
"code": 60174,
"tempChar": ""
"tempChar": ""
},
{
"order": 126,
@@ -989,7 +981,7 @@
"name": "icon-page",
"prevSize": 24,
"code": 60175,
"tempChar": ""
"tempChar": ""
},
{
"order": 130,
@@ -997,7 +989,7 @@
"name": "icon-plot-overlay",
"prevSize": 24,
"code": 60176,
"tempChar": ""
"tempChar": ""
},
{
"order": 80,
@@ -1005,7 +997,7 @@
"name": "icon-plot-stacked",
"prevSize": 24,
"code": 60177,
"tempChar": ""
"tempChar": ""
},
{
"order": 134,
@@ -1013,7 +1005,7 @@
"name": "icon-session",
"prevSize": 24,
"code": 60178,
"tempChar": ""
"tempChar": ""
},
{
"order": 109,
@@ -1021,7 +1013,7 @@
"name": "icon-tabular",
"prevSize": 24,
"code": 60179,
"tempChar": ""
"tempChar": ""
},
{
"order": 107,
@@ -1029,7 +1021,7 @@
"name": "icon-tabular-lad",
"prevSize": 24,
"code": 60180,
"tempChar": ""
"tempChar": ""
},
{
"order": 106,
@@ -1037,7 +1029,7 @@
"name": "icon-tabular-lad-set",
"prevSize": 24,
"code": 60181,
"tempChar": ""
"tempChar": ""
},
{
"order": 70,
@@ -1045,7 +1037,7 @@
"name": "icon-tabular-realtime",
"prevSize": 24,
"code": 60182,
"tempChar": ""
"tempChar": ""
},
{
"order": 60,
@@ -1053,7 +1045,7 @@
"name": "icon-tabular-scrolling",
"prevSize": 24,
"code": 60183,
"tempChar": ""
"tempChar": ""
},
{
"order": 131,
@@ -1061,7 +1053,7 @@
"name": "icon-telemetry",
"prevSize": 24,
"code": 60184,
"tempChar": ""
"tempChar": ""
},
{
"order": 108,
@@ -1069,7 +1061,7 @@
"name": "icon-timeline",
"prevSize": 24,
"code": 60185,
"tempChar": ""
"tempChar": ""
},
{
"order": 81,
@@ -1077,7 +1069,7 @@
"name": "icon-timer",
"prevSize": 24,
"code": 60186,
"tempChar": ""
"tempChar": ""
},
{
"order": 69,
@@ -1085,7 +1077,7 @@
"name": "icon-topic",
"prevSize": 24,
"code": 60187,
"tempChar": ""
"tempChar": ""
},
{
"order": 79,
@@ -1093,7 +1085,7 @@
"name": "icon-box-with-dashed-lines-v2",
"prevSize": 24,
"code": 60188,
"tempChar": ""
"tempChar": ""
},
{
"order": 90,
@@ -1101,7 +1093,7 @@
"name": "icon-summary-widget",
"prevSize": 24,
"code": 60189,
"tempChar": ""
"tempChar": ""
},
{
"order": 92,
@@ -1109,7 +1101,7 @@
"name": "icon-notebook",
"prevSize": 24,
"code": 60190,
"tempChar": ""
"tempChar": ""
},
{
"order": 168,
@@ -1117,7 +1109,7 @@
"name": "icon-tabs-view",
"prevSize": 24,
"code": 60191,
"tempChar": ""
"tempChar": ""
},
{
"order": 117,
@@ -1125,7 +1117,7 @@
"name": "icon-flexible-layout",
"prevSize": 24,
"code": 60192,
"tempChar": ""
"tempChar": ""
},
{
"order": 166,
@@ -1133,7 +1125,7 @@
"name": "icon-generator-sine",
"prevSize": 24,
"code": 60193,
"tempChar": ""
"tempChar": ""
},
{
"order": 167,
@@ -1141,7 +1133,7 @@
"name": "icon-generator-event",
"prevSize": 24,
"code": 60194,
"tempChar": ""
"tempChar": ""
},
{
"order": 165,
@@ -1149,7 +1141,7 @@
"name": "icon-gauge-v2",
"prevSize": 24,
"code": 60195,
"tempChar": ""
"tempChar": ""
},
{
"order": 170,
@@ -1157,7 +1149,7 @@
"name": "icon-spectra",
"prevSize": 24,
"code": 60196,
"tempChar": ""
"tempChar": ""
},
{
"order": 171,
@@ -1165,7 +1157,7 @@
"name": "icon-telemetry-spectra",
"prevSize": 24,
"code": 60197,
"tempChar": ""
"tempChar": ""
},
{
"order": 172,
@@ -1173,7 +1165,7 @@
"name": "icon-pushbutton",
"prevSize": 24,
"code": 60198,
"tempChar": ""
"tempChar": ""
},
{
"order": 174,
@@ -1181,7 +1173,7 @@
"name": "icon-conditional",
"prevSize": 24,
"code": 60199,
"tempChar": ""
"tempChar": ""
},
{
"order": 178,
@@ -1189,7 +1181,7 @@
"name": "icon-condition-widget",
"prevSize": 24,
"code": 60200,
"tempChar": ""
"tempChar": ""
},
{
"order": 180,
@@ -1197,7 +1189,7 @@
"name": "icon-alphanumeric",
"prevSize": 24,
"code": 60201,
"tempChar": ""
"tempChar": ""
},
{
"order": 183,
@@ -1205,15 +1197,7 @@
"name": "icon-image-telemetry",
"prevSize": 24,
"code": 60202,
"tempChar": ""
},
{
"order": 198,
"id": 170,
"name": "icon-telemetry-aggregate",
"prevSize": 24,
"code": 60203,
"tempChar": ""
"tempChar": ""
}
],
"id": 0,
@@ -2016,26 +2000,6 @@
]
}
},
{
"id": 169,
"paths": [
"M1024 512c0 282.77-229.23 512-512 512s-512-229.23-512-512c0-282.77 229.23-512 512-512s512 229.23 512 512z"
],
"attrs": [
{}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 16,
"tags": [
"icon-circle"
],
"colorPermutations": {
"12552552551": [
{}
]
}
},
{
"id": 105,
"paths": [
@@ -3820,32 +3784,6 @@
{}
]
}
},
{
"id": 170,
"paths": [
"M78 395.44c14-41.44 37.48-100.8 69.2-148.36 38.62-57.78 82.38-87.080 130.14-87.080s91.5 29.3 130 87.080c31.72 47.56 55.14 106.92 69.2 148.36 30.88 90.96 63.12 134.98 78 146.54 14.94-11.56 47.2-55.58 78-146.54 14-41.44 37.48-100.8 69.22-148.36q27.8-41.7 59.12-63.5c-75.7-111.377-201.81-183.58-344.783-183.58-0.034 0-0.068 0-0.103 0l0.006-0c-229.76 0-416 186.24-416 416-0 0.071-0 0.156-0 0.24 0 39.119 5.396 76.977 15.484 112.871l-0.704-2.931c16.78-21.74 40.4-63.34 63.22-130.74z",
"M754 436.56c-14 41.44-37.48 100.8-69.2 148.36-38.56 57.78-82.32 87.080-130 87.080s-91.5-29.3-130-87.080c-31.72-47.56-55.14-106.92-69.2-148.36-30.88-90.96-63.14-134.98-78-146.54-14.94 11.56-47.2 55.58-78 146.54-14.38 41.44-37.8 100.8-69.6 148.36q-27.8 41.7-59.12 63.5c75.7 111.378 201.81 183.58 344.783 183.58 0.119 0 0.237-0 0.356-0l-0.019 0c229.76 0 416-186.24 416-416 0-0.071 0-0.156 0-0.24 0-39.119-5.396-76.977-15.484-112.871l0.704 2.931c-16.78 21.74-40.4 63.34-63.22 130.74z",
"M921.56 334.62c4.098 24.449 6.44 52.617 6.44 81.332 0 0.017-0 0.034-0 0.051l0-0.003c0 0.095 0 0.208 0 0.32 0 282.593-229.087 511.68-511.68 511.68-0.113 0-0.225-0-0.338-0l0.018 0c-0.014 0-0.031 0-0.048 0-28.716 0-56.884-2.342-84.325-6.845l2.993 0.405c72.483 63.623 168.109 102.44 272.802 102.44 0.203 0 0.406-0 0.61-0l-0.031 0c229.76 0 416-186.24 416-416 0-0.172 0-0.375 0-0.578 0-104.692-38.817-200.319-102.844-273.271l0.404 0.47z"
],
"attrs": [
{},
{},
{}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 16,
"tags": [
"icon-telemetry-aggregate"
],
"colorPermutations": {
"12552552551": [
{},
{},
{}
]
}
}
],
"invisible": false,

View File

@@ -53,7 +53,6 @@
<glyph unicode="&#xe92b;" glyph-name="icon-eye-disabled" d="M209.46 223.32q-7.46 9.86-14.26 20.28c-14.737 21.984-27.741 47.184-37.759 73.847l-0.841 2.553c11.078 29.259 24.068 54.443 39.51 77.869l-0.91-1.469c23.221 34.963 50.705 64.8 82.207 89.793l0.793 0.607c57.663 45.719 130.179 75.053 209.311 79.947l1.069 0.053 114.48 140.88c-27.366 5.017-58.869 7.898-91.041 7.92h-0.019c-245.8 0-452.2-168-510.8-395.6 21.856-82.93 60.906-154.847 113.325-214.773l-0.525 0.613zM814.76 416.92q7.52-10 14.44-20.52c14.737-21.984 27.741-47.184 37.759-73.847l0.841-2.553c-10.859-29.216-23.863-54.416-39.447-77.748l0.847 1.348c-23.221-34.963-50.705-64.8-82.207-89.793l-0.793-0.607c-57.762-45.834-130.437-75.216-209.743-80.049l-1.057-0.051-114.46-140.86c27.346-4.988 58.817-7.84 90.955-7.84 0.037 0 0.074 0 0.111 0h-0.005c245.8 0 452.2 168 510.8 395.6-21.856 82.93-60.906 154.847-113.325 214.773l0.525-0.613zM832 832l-832-1024h192l832 1024h-192z" />
<glyph unicode="&#xe92c;" glyph-name="icon-notebook-page" d="M830 770h-830l-4-702c0-106.6 87.4-194 194-194h640c106.6 0 194 87.4 194 194v508c0 106.8-87.4 194-194 194zM832 386l-384-384-192 192v256l192-192 384 384v-256z" />
<glyph unicode="&#xe92d;" glyph-name="icon-unlocked" d="M768 832c-141.339-0.114-255.886-114.661-256-255.989v-128.011h-448c-35.301-0.113-63.887-28.699-64-63.989v-512.011c0.113-35.301 28.699-63.887 63.989-64h638.011c35.301 0.113 63.887 28.699 64 63.989v512.011c-0.113 35.301-28.699 63.887-63.989 64h-62.011v128c0 70.692 57.308 128 128 128s128-57.308 128-128v0-128h128v128c-0.114 141.339-114.661 255.886-255.989 256h-0.011z" />
<glyph unicode="&#xe92e;" glyph-name="icon-circle" d="M1024 320c0-282.77-229.23-512-512-512s-512 229.23-512 512c0 282.77 229.23 512 512 512s512-229.23 512-512z" />
<glyph unicode="&#xea00;" glyph-name="icon-arrows-right-left" d="M1024 320l-448-512v1024zM448 832l-448-512 448-512z" />
<glyph unicode="&#xea01;" glyph-name="icon-arrows-up-down" d="M512 832l512-448h-1024zM0 256l512-448 512 448z" />
<glyph unicode="&#xea02;" glyph-name="icon-bullet" d="M832 80c0-44-36-80-80-80h-480c-44 0-80 36-80 80v480c0 44 36 80 80 80h480c44 0 80-36 80-80v-480z" />
@@ -157,5 +156,4 @@
<glyph unicode="&#xeb28;" glyph-name="icon-condition-widget" d="M832 832h-640c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h640c105.6 0 192 86.4 192 192v640c0 105.6-86.4 192-192 192zM512 64l-384 256 384 256 384-256z" />
<glyph unicode="&#xeb29;" glyph-name="icon-alphanumeric" d="M535.6 301.4c-8.4-1.6-17.2-3-26.2-4s-18.2-2.4-27.2-4c-10.196-1.861-18.808-4.010-27.21-6.633l1.61 0.433c-8.609-2.674-16.105-6.348-22.89-10.987l0.29 0.187c-6.693-4.517-12.283-10.107-16.663-16.585l-0.137-0.215c-4.6-6.8-7.4-15.6-8.8-26s-0.4-18.4 2.4-25.2c2.746-6.688 7.224-12.195 12.881-16.122l0.119-0.078c5.967-4.053 13.057-6.94 20.704-8.161l0.296-0.039c7.592-1.527 16.319-2.4 25.25-2.4 0.123 0 0.246 0 0.369 0h-0.019c22.2 0 39.6 3.6 52.6 11s23.2 16.2 30.2 26.4c6.273 8.873 11.271 19.191 14.426 30.285l0.174 0.715c1.853 6.809 3.601 15.41 4.855 24.169l0.145 1.231 5.2 41.6c-5.4-4.217-11.723-7.564-18.583-9.689l-0.417-0.111c-6.489-2.241-14.362-4.255-22.444-5.662l-0.956-0.138zM1024 448v192h-152l24 192h-192l-24-192h-256l24 192h-192l-24-192h-232v-192h208l-32-256h-176v-192h152l-24-192h192l24 192h256l-24-192h192l24 192h232v192h-208l32 256zM702.8 420.2l-26.4-211.8c-2.231-15.809-3.537-34.122-3.6-52.727v-0.073c0-16.8 2.2-29.4 6.4-37.8h-113.4c-1.342 5.556-2.338 12.122-2.781 18.84l-0.019 0.36c-0.261 3.524-0.409 7.634-0.409 11.778 0 2.962 0.076 5.907 0.226 8.832l-0.017-0.41c-18.663-17.401-41.395-30.694-66.597-38.289l-1.203-0.311c-22.627-6.956-48.639-10.974-75.586-11h-0.014c-0.764-0.011-1.666-0.018-2.569-0.018-18.098 0-35.598 2.563-52.156 7.345l1.325-0.328c-15.991 4.512-29.851 12.090-41.545 22.122l0.145-0.122c-11.233 9.982-19.792 22.733-24.624 37.192l-0.176 0.608c-5.2 15.2-6.4 33.4-3.8 54.4s9.4 42.2 19.4 57.2c9.524 14.399 21.535 26.346 35.532 35.512l0.468 0.288c13.387 8.662 28.922 15.533 45.512 19.765l1.088 0.235c13.436 3.792 30.801 7.554 48.47 10.41l2.93 0.39c17 2.6 33.8 4.6 50.4 6.2 16.628 1.527 31.69 4.070 46.349 7.643l-2.149-0.443c13 3 23.6 7.6 31.6 13.6s12.6 15 13.6 26.4 0.8 21.8-2.4 28.8c-2.849 6.902-7.542 12.56-13.468 16.517l-0.132 0.083c-6.217 4.011-13.604 6.78-21.543 7.774l-0.257 0.026c-7.897 1.277-17 2.007-26.274 2.007-0.537 0-1.073-0.002-1.609-0.007l0.082 0.001c-22 0-40-4.6-53.8-14.2s-23-25.2-28-47.2h-111.8c4.8 26.2 14.2 48 27.8 65.4 13.475 16.978 29.89 30.968 48.574 41.377l0.826 0.423c18.192 10.038 39.297 17.806 61.619 22.175l1.381 0.225c20.488 4.162 44.053 6.563 68.171 6.6h0.029c21.8-0.005 43.239-1.532 64.222-4.479l-2.422 0.279c20.641-2.809 39.324-8.783 56.401-17.461l-1.001 0.461c15.909-8.108 28.858-20.031 37.967-34.601l0.233-0.399c9-15 12.2-34.8 9-59.6z" />
<glyph unicode="&#xeb2a;" glyph-name="icon-image-telemetry" d="M512 832c-282.8 0-512-229.2-512-512s229.2-512 512-512 512 229.2 512 512-229.2 512-512 512zM783.6 48.4c-69.581-69.675-165.757-112.776-272-112.776-212.298 0-384.4 172.102-384.4 384.4s172.102 384.4 384.4 384.4c212.298 0 384.4-172.102 384.4-384.4 0-0.008 0-0.017 0-0.025v0.001c0.001-0.264 0.001-0.575 0.001-0.887 0-105.769-42.964-201.503-112.391-270.703l-0.010-0.010zM704 448l-128-128-192 192-192-192c0-176.731 143.269-320 320-320s320 143.269 320 320v0z" />
<glyph unicode="&#xeb2b;" glyph-name="icon-telemetry-aggregate" d="M78 436.56c14 41.44 37.48 100.8 69.2 148.36 38.62 57.78 82.38 87.080 130.14 87.080s91.5-29.3 130-87.080c31.72-47.56 55.14-106.92 69.2-148.36 30.88-90.96 63.12-134.98 78-146.54 14.94 11.56 47.2 55.58 78 146.54 14 41.44 37.48 100.8 69.22 148.36q27.8 41.7 59.12 63.5c-75.7 111.377-201.81 183.58-344.783 183.58-0.034 0-0.068 0-0.103 0h0.006c-229.76 0-416-186.24-416-416 0-0.071 0-0.156 0-0.24 0-39.119 5.396-76.977 15.484-112.871l-0.704 2.931c16.78 21.74 40.4 63.34 63.22 130.74zM754 395.44c-14-41.44-37.48-100.8-69.2-148.36-38.56-57.78-82.32-87.080-130-87.080s-91.5 29.3-130 87.080c-31.72 47.56-55.14 106.92-69.2 148.36-30.88 90.96-63.14 134.98-78 146.54-14.94-11.56-47.2-55.58-78-146.54-14.38-41.44-37.8-100.8-69.6-148.36q-27.8-41.7-59.12-63.5c75.7-111.378 201.81-183.58 344.783-183.58 0.119 0 0.237 0 0.356 0h-0.019c229.76 0 416 186.24 416 416 0 0.071 0 0.156 0 0.24 0 39.119-5.396 76.977-15.484 112.871l0.704-2.931c-16.78-21.74-40.4-63.34-63.22-130.74zM921.56 497.38c4.098-24.449 6.44-52.617 6.44-81.332 0-0.017 0-0.034 0-0.051v0.003c0-0.095 0-0.208 0-0.32 0-282.593-229.087-511.68-511.68-511.68-0.113 0-0.225 0-0.338 0h0.018c-0.014 0-0.031 0-0.048 0-28.716 0-56.884 2.342-84.325 6.845l2.993-0.405c72.483-63.623 168.109-102.44 272.802-102.44 0.203 0 0.406 0 0.61 0h-0.031c229.76 0 416 186.24 416 416 0 0.172 0 0.375 0 0.578 0 104.692-38.817 200.319-102.844 273.271l0.404-0.47z" />
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 59 KiB

View File

@@ -21,7 +21,7 @@
*****************************************************************************/
<template>
<div
class="c-so-view js-notebook-snapshot-item-wrapper"
class="c-so-view"
:class="[
statusClass,
'c-so-view--' + domainObject.type,
@@ -56,11 +56,6 @@
'has-complex-content': complexContent
}"
>
<NotebookMenuSwitcher v-if="notebookEnabled"
:domain-object="domainObject"
:object-path="objectPath"
class="c-notebook-snapshot-menubutton"
/>
<div v-if="statusBarItems.length > 0"
class="c-so-view__frame-controls__btns"
>
@@ -85,7 +80,7 @@
<object-view
ref="objectView"
class="c-so-view__object-view js-object-view js-notebook-snapshot-item"
class="c-so-view__object-view js-object-view"
:show-edit-view="showEditView"
:object-path="objectPath"
:layout-font-size="layoutFontSize"
@@ -97,7 +92,6 @@
<script>
import ObjectView from './ObjectView.vue';
import NotebookMenuSwitcher from '@/plugins/notebook/components/NotebookMenuSwitcher.vue';
const SIMPLE_CONTENT_TYPES = [
'clock',
@@ -109,8 +103,7 @@ const SIMPLE_CONTENT_TYPES = [
export default {
components: {
ObjectView,
NotebookMenuSwitcher
ObjectView
},
inject: ['openmct'],
props: {
@@ -146,7 +139,6 @@ export default {
return {
cssClass,
complexContent,
notebookEnabled: this.openmct.types.get('notebook'),
statusBarItems: [],
status: ''
};

View File

@@ -53,7 +53,7 @@
class="l-shell__pane-tree"
handle="after"
label="Browse"
hide-param="hideTree"
collapsable
@start-resizing="onStartResizing"
@end-resizing="onEndResizing"
>
@@ -90,7 +90,7 @@
/>
<object-view
ref="browseObject"
class="l-shell__main-container js-main-container js-notebook-snapshot-item"
class="l-shell__main-container js-main-container"
data-selectable
:show-edit-view="true"
@change-action-collection="setActionCollection"
@@ -104,7 +104,7 @@
class="l-shell__pane-inspector l-pane--holds-multipane"
handle="before"
label="Inspect"
hide-param="hideInspector"
collapsable
@start-resizing="onStartResizing"
@end-resizing="onEndResizing"
>

View File

@@ -1,171 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, 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.
*****************************************************************************/
import {
createOpenMct,
resetApplicationState
} from 'utils/testing';
import Vue from 'vue';
import Layout from './Layout.vue';
describe('Open MCT Layout:', () => {
let openmct;
let element;
let components;
beforeEach((done) => {
openmct = createOpenMct();
openmct.on('start', done);
// to silence error from BrowseBar.vue
spyOn(openmct.objectViews, 'get')
.and.callFake(() => []);
openmct.startHeadless();
});
afterEach(() => {
return resetApplicationState(openmct);
});
describe('the pane:', () => {
it('is displayed on layout load', async () => {
await createLayout();
await Vue.nextTick();
Object.entries(components).forEach(([name, component]) => {
expect(
component.pane
).toBeTruthy();
expect(
isCollapsed(component.pane)
).toBeFalse();
});
});
it('is collapsed on layout load if specified by a hide param', async () => {
setHideParams();
await createLayout();
await Vue.nextTick();
Object.entries(components).forEach(([name, component]) => {
expect(
isCollapsed(component.pane)
).toBeTrue();
});
});
it('on toggle collapses if expanded', async () => {
await createLayout();
toggleCollapseButtons();
await Vue.nextTick();
Object.entries(components).forEach(([name, component]) => {
expect(
openmct.router.getSearchParam(component.param)
).toEqual('true');
expect(
isCollapsed(component.pane)
).toBeTrue();
});
});
it('on toggle expands if collapsed', async () => {
setHideParams();
await createLayout();
toggleExpandButtons();
await Vue.nextTick();
Object.entries(components).forEach(([name, component]) => {
expect(
openmct.router.getSearchParam(component.param)
).not.toEqual('true');
expect(
isCollapsed(component.pane)
).toBeFalse();
});
});
});
async function createLayout() {
const el = document.createElement('div');
const child = document.createElement('div');
el.appendChild(child);
element = await new Vue({
el,
components: {
Layout
},
provide: {
openmct
},
template: `<Layout ref="layout"/>`
}).$mount().$el;
setComponents();
}
function setComponents() {
components = {
tree: {
param: 'hideTree',
pane: element.querySelector('.l-shell__pane-tree'),
collapseButton: element.querySelector('.l-shell__pane-tree .l-pane__collapse-button'),
expandButton: element.querySelector('.l-shell__pane-tree .l-pane__expand-button')
},
inspector: {
param: 'hideInspector',
pane: element.querySelector('.l-shell__pane-inspector'),
collapseButton: element.querySelector('.l-shell__pane-inspector .l-pane__collapse-button'),
expandButton: element.querySelector('.l-shell__pane-inspector .l-pane__expand-button')
}
};
}
function isCollapsed(el) {
return el.classList.contains('l-pane--collapsed');
}
function setHideParams() {
Object.entries(components).forEach(([name, component]) => {
openmct.router.setSearchParam(component.param, true);
});
}
function toggleCollapseButtons() {
Object.entries(components).forEach(([name, component]) => {
component.collapseButton.click();
});
}
function toggleExpandButtons() {
Object.entries(components).forEach(([name, component]) => {
component.expandButton.click();
});
}
});

View File

@@ -226,21 +226,18 @@ export default {
},
created() {
this.getSearchResults = _.debounce(this.getSearchResults, 400);
this.handleTreeResize = _.debounce(this.handleTreeResize, 300);
this.handleWindowResize = _.debounce(this.handleWindowResize, 500);
this.scrollEndEvent = _.debounce(this.scrollEndEvent, 100);
},
destroyed() {
if (this.treeResizeObserver) {
this.treeResizeObserver.disconnect();
}
window.removeEventListener('resize', this.handleWindowResize);
},
methods: {
async initialize() {
this.isLoading = true;
this.openmct.$injector.get('searchService');
this.getSavedOpenItems();
this.treeResizeObserver = new ResizeObserver(this.handleTreeResize);
this.treeResizeObserver.observe(this.$el);
window.addEventListener('resize', this.handleWindowResize);
await this.calculateHeights();
@@ -522,7 +519,7 @@ export default {
},
searchTree(value) {
// if an abort controller exists, regardless of the value passed in,
// there is an active search that should be canceled
// there is an active search that should be cancled
if (this.abortSearchController) {
this.abortSearchController.abort();
delete this.abortSearchController;
@@ -713,7 +710,7 @@ export default {
setSavedOpenItems() {
localStorage.setItem(LOCAL_STORAGE_KEY__TREE_EXPANDED, JSON.stringify(this.openTreeItems));
},
handleTreeResize() {
handleWindowResize() {
this.calculateHeights();
}
}

View File

@@ -41,6 +41,10 @@
<script>
const COLLAPSE_THRESHOLD_PX = 40;
const HIDE_TREE_PARAM = 'hideTree';
const HIDE_INSPECTOR_PARAM = 'hideInspector';
const PANE_INSPECTOR = 'Inspect';
const PANE_TREE = 'Browse';
export default {
inject: ['openmct'],
@@ -52,11 +56,11 @@ export default {
return ['', 'before', 'after'].indexOf(value) !== -1;
}
},
label: {
type: String,
default: ''
collapsable: {
type: Boolean,
default: false
},
hideParam: {
label: {
type: String,
default: ''
}
@@ -67,11 +71,6 @@ export default {
resizing: false
};
},
computed: {
collapsable() {
return this.hideParam && this.hideParam.length;
}
},
beforeMount() {
this.type = this.$parent.type;
this.styleProp = (this.type === 'horizontal') ? 'width' : 'height';
@@ -79,25 +78,39 @@ export default {
async mounted() {
await this.$nextTick();
// Hide tree and/or inspector pane if specified in URL
if (this.collapsable) {
this.handleHideUrl();
}
this.handleHideUrl();
this.openmct.router.on('change:params', this.handleHideUrl);
},
beforeDestroy() {
this.openmct.router.off('change:params', this.handleHideUrl);
},
methods: {
toggleCollapse: function (e) {
let target = this.label === PANE_TREE ? HIDE_TREE_PARAM : HIDE_INSPECTOR_PARAM;
this.collapsed = !this.collapsed;
if (this.collapsed) {
this.handleExpand();
this.removeHideParam(this.hideParam);
} else {
this.handleCollapse();
this.addHideParam(this.hideParam);
this.addHideParam(target);
} else {
this.handleExpand();
this.removeHideParam(target);
}
},
handleHideUrl: function () {
const hideParam = this.openmct.router.getSearchParam(this.hideParam);
if (!this.collapsable) {
return;
}
if (hideParam === 'true') {
let hideTreeParam = this.openmct.router.getSearchParam(HIDE_TREE_PARAM);
let hideInspectorParam = this.openmct.router.getSearchParam(HIDE_INSPECTOR_PARAM);
let hideTree = hideTreeParam === 'true' && this.label === PANE_TREE;
let hideInspector = hideInspectorParam === 'true' && this.label === PANE_INSPECTOR;
if (hideTree || hideInspector) {
this.collapsed = true;
this.handleCollapse();
} else {
this.collapsed = false;
this.handleExpand();
}
},
addHideParam: function (target) {
@@ -109,13 +122,11 @@ export default {
handleCollapse: function () {
this.currentSize = (this.dragCollapse === true) ? this.initial : this.$el.style[this.styleProp];
this.$el.style[this.styleProp] = '';
this.collapsed = true;
},
handleExpand: function () {
this.$el.style[this.styleProp] = this.currentSize;
delete this.currentSize;
delete this.dragCollapse;
this.collapsed = false;
},
trackSize: function () {
if (!this.dragCollapse === true) {

90
src/ui/layout/paneSpec.js Normal file
View File

@@ -0,0 +1,90 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, 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.
*****************************************************************************/
import {
createOpenMct,
resetApplicationState
} from 'utils/testing';
describe("the pane", () => {
let openmct;
let appHolder;
let element;
let child;
let resolveFunction;
beforeEach((done) => {
openmct = createOpenMct();
appHolder = document.createElement('div');
appHolder.style.width = '640px';
appHolder.style.height = '480px';
openmct = createOpenMct();
openmct.install(openmct.plugins.MyItems());
openmct.install(openmct.plugins.LocalTimeSystem());
openmct.install(openmct.plugins.UTCTimeSystem());
element = document.createElement('div');
child = document.createElement('div');
element.appendChild(child);
openmct.on('start', done);
openmct.start(appHolder);
document.body.append(appHolder);
});
afterEach(() => {
return resetApplicationState(openmct);
});
it('toggling tree will toggle tree hide params', (done) => {
document.querySelector('.l-shell__pane-tree .l-pane__collapse-button').click();
expect(openmct.router.getSearchParam('hideTree')).toBe('true');
done();
});
it('tree pane collapses when adding hide tree param in URL', () => {
openmct.router.setSearchParam('hideTree', 'true');
expect(document.querySelector('.l-shell__pane-tree.l-pane--collapsed')).toBeDefined();
});
it('inspector pane collapses when adding hide inspector param in URL', () => {
openmct.router.setSearchParam('hideInspector', 'true');
expect(document.querySelector('.l-shell__pane-inspector.l-pane--collapsed')).toBeDefined();
});
it('toggle inspector pane will toggle inspector hide param', (done) => {
// There's a short delay on addubg the param.
resolveFunction = () => {
setTimeout(() => {
expect(openmct.router.getSearchParam('hideInspector')).toBe('true');
done();
}, 500);
};
openmct.router.on('change:params', resolveFunction);
document.querySelector('.l-shell__pane-inspector .l-pane__collapse-button').click();
});
});

View File

@@ -27,7 +27,7 @@
:domain-object="domainObject"
:views="views"
/>
<div class="l-preview-window__object-view js-notebook-snapshot-item">
<div class="l-preview-window__object-view">
<div ref="objectView"></div>
</div>
</div>

View File

@@ -69,11 +69,11 @@ xdescribe('Application router utility functions', () => {
openmct.router.on('change:hash', resolveFunction);
});
it('The getSearchParam function returns the value of an individual search parameter in the window location hash', () => {
it('The getSearchParam function returns the value of an individual search paramater in the window location hash', () => {
expect(openmct.router.getSearchParam('testParam')).toBe('testValue');
});
it('The deleteSearchParam function deletes an individual search parameter in the window location hash', (done) => {
it('The deleteSearchParam function deletes an individual search paramater in the window location hash', (done) => {
let success;
openmct.router.deleteSearchParam('testParam');
resolveFunction = () => {
@@ -109,7 +109,7 @@ xdescribe('Application router utility functions', () => {
openmct.router.on('change:hash', resolveFunction);
});
it('The setAllSearchParams function replaces all search parameters in the window location hash', (done) => {
it('The setAllSearchParams function replaces all search paramaters in the window location hash', (done) => {
let success;
openmct.router.setSearchParam('testParam2', 'updatedtestValue2');
@@ -130,7 +130,7 @@ xdescribe('Application router utility functions', () => {
openmct.router.on('change:hash', resolveFunction);
});
it('The getAllSearchParams function returns the values of all search parameters in the window location hash', () => {
it('The getAllSearchParams function returns the values of all search paramaters in the window location hash', () => {
let searchParams = openmct.router.getAllSearchParams();
expect(searchParams.get('testParam1')).toBe('testValue1');
expect(searchParams.get('testParam2')).toBe('updatedtestValue2');