mirror of
https://github.com/nasa/openmct.git
synced 2025-07-01 12:58:56 +00:00
Compare commits
11 Commits
stackplots
...
vue-hack
Author | SHA1 | Date | |
---|---|---|---|
62ff404bb3 | |||
8243cf5d7b | |||
c4c1fea17f | |||
5e920e90ce | |||
886db23eb6 | |||
0ccb546a2e | |||
271f8ed38f | |||
650f84e95c | |||
b70af5a1bb | |||
0af21632db | |||
e2f1ff5442 |
@ -42,7 +42,6 @@ jobs:
|
|||||||
- ~/.npm
|
- ~/.npm
|
||||||
- ~/.cache
|
- ~/.cache
|
||||||
- node_modules
|
- node_modules
|
||||||
- run: npm run lint
|
|
||||||
- run: npm run test:coverage -- --browsers=<<parameters.browser>> || <<parameters.always-pass>>
|
- run: npm run test:coverage -- --browsers=<<parameters.browser>> || <<parameters.always-pass>>
|
||||||
- store_test_results:
|
- store_test_results:
|
||||||
path: dist/reports/tests/
|
path: dist/reports/tests/
|
||||||
|
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
* [ ] Have you followed the guidelines in our [Contributing document](https://github.com/nasa/openmct/blob/master/CONTRIBUTING.md)?
|
* [ ] Have you followed the guidelines in our [Contributing document](https://github.com/nasa/openmct/blob/master/CONTRIBUTING.md)?
|
||||||
* [ ] Have you checked to ensure there aren't other open [Pull Requests](https://github.com/nasa/openmct/pulls) for the same update/change?
|
* [ ] Have you checked to ensure there aren't other open [Pull Requests](https://github.com/nasa/openmct/pulls) for the same update/change?
|
||||||
* [ ] Is this change backwards compatible? For example, developers won't need to change how they are calling the API or how they've extended core plugins such as Tables or Plots.
|
|
||||||
|
|
||||||
### Author Checklist
|
### Author Checklist
|
||||||
|
|
||||||
|
@ -317,7 +317,6 @@ checklist).
|
|||||||
### Reviewer Checklist
|
### Reviewer Checklist
|
||||||
|
|
||||||
* [ ] Changes appear to address issue?
|
* [ ] Changes appear to address issue?
|
||||||
* [ ] Changes appear not to be breaking changes?
|
|
||||||
* [ ] Appropriate unit tests included?
|
* [ ] Appropriate unit tests included?
|
||||||
* [ ] Code style and in-line documentation are appropriate?
|
* [ ] Code style and in-line documentation are appropriate?
|
||||||
* [ ] Commit messages meet standards?
|
* [ ] Commit messages meet standards?
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
const devMode = process.env.NODE_ENV !== 'production';
|
const devMode = process.env.NODE_ENV !== 'production';
|
||||||
const browsers = [process.env.NODE_ENV === 'debug' ? 'ChromeDebugging' : 'ChromeHeadless'];
|
const browsers = [process.env.NODE_ENV === 'debug' ? 'ChromeDebugging' : 'ChromeHeadless'];
|
||||||
const coverageEnabled = process.env.COVERAGE === 'true';
|
const coverageEnabled = process.env.COVERAGE === 'true';
|
||||||
const reporters = ['spec', 'html', 'junit'];
|
const reporters = ['progress', 'html', 'junit'];
|
||||||
|
|
||||||
if (coverageEnabled) {
|
if (coverageEnabled) {
|
||||||
reporters.push('coverage-istanbul');
|
reporters.push('coverage-istanbul');
|
||||||
@ -60,7 +60,7 @@ module.exports = (config) => {
|
|||||||
client: {
|
client: {
|
||||||
jasmine: {
|
jasmine: {
|
||||||
random: false,
|
random: false,
|
||||||
timeoutInterval: 5000
|
timeoutInterval: 30000
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
customLaunchers: {
|
customLaunchers: {
|
||||||
@ -88,6 +88,11 @@ module.exports = (config) => {
|
|||||||
outputFile: "test-results.xml",
|
outputFile: "test-results.xml",
|
||||||
useBrowserName: false
|
useBrowserName: false
|
||||||
},
|
},
|
||||||
|
browserConsoleLogOptions: {
|
||||||
|
level: "error",
|
||||||
|
format: "%b %T: %m",
|
||||||
|
terminal: true
|
||||||
|
},
|
||||||
coverageIstanbulReporter: {
|
coverageIstanbulReporter: {
|
||||||
fixWebpackSourcePaths: true,
|
fixWebpackSourcePaths: true,
|
||||||
dir: process.env.CIRCLE_ARTIFACTS
|
dir: process.env.CIRCLE_ARTIFACTS
|
||||||
@ -100,15 +105,6 @@ module.exports = (config) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
specReporter: {
|
|
||||||
maxLogLines: 5,
|
|
||||||
suppressErrorSummary: true,
|
|
||||||
suppressFailed: false,
|
|
||||||
suppressPassed: false,
|
|
||||||
suppressSkipped: true,
|
|
||||||
showSpecTiming: true,
|
|
||||||
failFast: false
|
|
||||||
},
|
|
||||||
preprocessors: {
|
preprocessors: {
|
||||||
'indexTest.js': ['webpack', 'sourcemap']
|
'indexTest.js': ['webpack', 'sourcemap']
|
||||||
},
|
},
|
||||||
|
@ -41,7 +41,6 @@
|
|||||||
"karma-jasmine": "4.0.1",
|
"karma-jasmine": "4.0.1",
|
||||||
"karma-junit-reporter": "2.0.1",
|
"karma-junit-reporter": "2.0.1",
|
||||||
"karma-sourcemap-loader": "0.3.8",
|
"karma-sourcemap-loader": "0.3.8",
|
||||||
"karma-spec-reporter": "0.0.32",
|
|
||||||
"karma-webpack": "4.0.2",
|
"karma-webpack": "4.0.2",
|
||||||
"location-bar": "^3.0.1",
|
"location-bar": "^3.0.1",
|
||||||
"lodash": "^4.17.12",
|
"lodash": "^4.17.12",
|
||||||
@ -65,7 +64,6 @@
|
|||||||
"uuid": "^3.3.3",
|
"uuid": "^3.3.3",
|
||||||
"v8-compile-cache": "^1.1.0",
|
"v8-compile-cache": "^1.1.0",
|
||||||
"vue": "2.5.6",
|
"vue": "2.5.6",
|
||||||
"vue-eslint-parser": "7.11.0",
|
|
||||||
"vue-loader": "^15.2.6",
|
"vue-loader": "^15.2.6",
|
||||||
"vue-template-compiler": "2.5.6",
|
"vue-template-compiler": "2.5.6",
|
||||||
"webpack": "^4.16.2",
|
"webpack": "^4.16.2",
|
||||||
|
@ -50,6 +50,8 @@ define(
|
|||||||
* or finish() are called.
|
* or finish() are called.
|
||||||
*/
|
*/
|
||||||
EditorCapability.prototype.edit = function () {
|
EditorCapability.prototype.edit = function () {
|
||||||
|
console.warn('DEPRECATED: cannot edit via edit capability, use openmct.editor instead.');
|
||||||
|
|
||||||
if (!this.openmct.editor.isEditing()) {
|
if (!this.openmct.editor.isEditing()) {
|
||||||
this.openmct.editor.edit();
|
this.openmct.editor.edit();
|
||||||
this.domainObject.getCapability('status').set('editing', true);
|
this.domainObject.getCapability('status').set('editing', true);
|
||||||
@ -80,6 +82,8 @@ define(
|
|||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
EditorCapability.prototype.save = function () {
|
EditorCapability.prototype.save = function () {
|
||||||
|
console.warn('DEPRECATED: cannot save via edit capability, use openmct.editor instead.');
|
||||||
|
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -91,6 +95,8 @@ define(
|
|||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
EditorCapability.prototype.finish = function () {
|
EditorCapability.prototype.finish = function () {
|
||||||
|
console.warn('DEPRECATED: cannot finish via edit capability, use openmct.editor instead.');
|
||||||
|
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,14 +25,15 @@ define([
|
|||||||
], function (
|
], function (
|
||||||
moment
|
moment
|
||||||
) {
|
) {
|
||||||
const DATE_FORMAT = "YYYY-MM-DD HH:mm:ss.SSS";
|
|
||||||
const DATE_FORMATS = [
|
var DATE_FORMAT = "YYYY-MM-DD HH:mm:ss.SSS",
|
||||||
DATE_FORMAT,
|
DATE_FORMATS = [
|
||||||
DATE_FORMAT + "Z",
|
DATE_FORMAT,
|
||||||
"YYYY-MM-DD HH:mm:ss",
|
DATE_FORMAT + "Z",
|
||||||
"YYYY-MM-DD HH:mm",
|
"YYYY-MM-DD HH:mm:ss",
|
||||||
"YYYY-MM-DD"
|
"YYYY-MM-DD HH:mm",
|
||||||
];
|
"YYYY-MM-DD"
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef Scale
|
* @typedef Scale
|
||||||
@ -52,27 +53,15 @@ define([
|
|||||||
this.key = "utc";
|
this.key = "utc";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} formatString
|
|
||||||
* @returns the value of formatString if the value is a string type and exists in the DATE_FORMATS array; otherwise the DATE_FORMAT value.
|
|
||||||
*/
|
|
||||||
function validateFormatString(formatString) {
|
|
||||||
return typeof formatString === 'string' && DATE_FORMATS.includes(formatString) ? formatString : DATE_FORMAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} value The value to format.
|
* @param {number} value The value to format.
|
||||||
* @param {string} formatString The string format to format. Default "YYYY-MM-DD HH:mm:ss.SSS" + "Z"
|
* @returns {string} the formatted date(s). If multiple values were requested, then an array of
|
||||||
* @returns {string} the formatted date(s) according to the proper parameter of formatString or the default value of "YYYY-MM-DD HH:mm:ss.SSS" + "Z".
|
|
||||||
* If multiple values were requested, then an array of
|
|
||||||
* formatted values will be returned. Where a value could not be formatted, `undefined` will be returned at its position
|
* formatted values will be returned. Where a value could not be formatted, `undefined` will be returned at its position
|
||||||
* in the array.
|
* in the array.
|
||||||
*/
|
*/
|
||||||
UTCTimeFormat.prototype.format = function (value, formatString) {
|
UTCTimeFormat.prototype.format = function (value) {
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
const format = validateFormatString(formatString);
|
return moment.utc(value).format(DATE_FORMAT) + "Z";
|
||||||
|
|
||||||
return moment.utc(value).format(format) + (formatString ? '' : 'Z');
|
|
||||||
} else {
|
} else {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -44,9 +44,11 @@ define(
|
|||||||
setText(result.name);
|
setText(result.name);
|
||||||
scope.ngModel[scope.field] = result;
|
scope.ngModel[scope.field] = result;
|
||||||
control.$setValidity("file-input", true);
|
control.$setValidity("file-input", true);
|
||||||
|
scope.$digest();
|
||||||
}, function () {
|
}, function () {
|
||||||
setText('Select File');
|
setText('Select File');
|
||||||
control.$setValidity("file-input", false);
|
control.$setValidity("file-input", false);
|
||||||
|
scope.$digest();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,6 +288,8 @@ define([
|
|||||||
this.install(this.plugins.ObjectInterceptors());
|
this.install(this.plugins.ObjectInterceptors());
|
||||||
this.install(this.plugins.NonEditableFolder());
|
this.install(this.plugins.NonEditableFolder());
|
||||||
this.install(this.plugins.DeviceClassifier());
|
this.install(this.plugins.DeviceClassifier());
|
||||||
|
|
||||||
|
this._isVue = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
MCT.prototype = Object.create(EventEmitter.prototype);
|
MCT.prototype = Object.create(EventEmitter.prototype);
|
||||||
|
@ -28,6 +28,8 @@ export default function LegacyActionAdapter(openmct, legacyActions) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.warn(`DEPRECATION WARNING: Action ${action.definition.key} in bundle ${action.bundle.path} is non-contextual and should be migrated.`);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ define([
|
|||||||
'./capabilities/APICapabilityDecorator',
|
'./capabilities/APICapabilityDecorator',
|
||||||
'./policies/AdaptedViewPolicy',
|
'./policies/AdaptedViewPolicy',
|
||||||
'./runs/AlternateCompositionInitializer',
|
'./runs/AlternateCompositionInitializer',
|
||||||
|
'./runs/TypeDeprecationChecker',
|
||||||
'./runs/LegacyTelemetryProvider',
|
'./runs/LegacyTelemetryProvider',
|
||||||
'./runs/RegisterLegacyTypes',
|
'./runs/RegisterLegacyTypes',
|
||||||
'./services/LegacyObjectAPIInterceptor',
|
'./services/LegacyObjectAPIInterceptor',
|
||||||
@ -45,6 +46,7 @@ define([
|
|||||||
APICapabilityDecorator,
|
APICapabilityDecorator,
|
||||||
AdaptedViewPolicy,
|
AdaptedViewPolicy,
|
||||||
AlternateCompositionInitializer,
|
AlternateCompositionInitializer,
|
||||||
|
TypeDeprecationChecker,
|
||||||
LegacyTelemetryProvider,
|
LegacyTelemetryProvider,
|
||||||
RegisterLegacyTypes,
|
RegisterLegacyTypes,
|
||||||
LegacyObjectAPIInterceptor,
|
LegacyObjectAPIInterceptor,
|
||||||
@ -133,6 +135,10 @@ define([
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
runs: [
|
runs: [
|
||||||
|
{
|
||||||
|
implementation: TypeDeprecationChecker,
|
||||||
|
depends: ["types[]"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
implementation: AlternateCompositionInitializer,
|
implementation: AlternateCompositionInitializer,
|
||||||
depends: ["openmct"]
|
depends: ["openmct"]
|
||||||
|
@ -4,6 +4,12 @@ define([
|
|||||||
|
|
||||||
) {
|
) {
|
||||||
function RegisterLegacyTypes(types, openmct) {
|
function RegisterLegacyTypes(types, openmct) {
|
||||||
|
types.forEach(function (legacyDefinition) {
|
||||||
|
if (!openmct.types.get(legacyDefinition.key)) {
|
||||||
|
console.warn(`DEPRECATION WARNING: Migrate type ${legacyDefinition.key} from ${legacyDefinition.bundle.path} to use the new Types API. Legacy type support will be removed soon.`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
openmct.types.importLegacyTypes(types);
|
openmct.types.importLegacyTypes(types);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
46
src/adapter/runs/TypeDeprecationChecker.js
Normal file
46
src/adapter/runs/TypeDeprecationChecker.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open openmct, Copyright (c) 2014-2021, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open openmct 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 openmct 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 checkForDeprecatedFunctionality(typeDef) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(typeDef, 'telemetry')) {
|
||||||
|
console.warn(
|
||||||
|
'DEPRECATION WARNING: Telemetry data on type '
|
||||||
|
+ 'registrations will be deprecated in a future version, '
|
||||||
|
+ 'please convert to a custom telemetry metadata provider '
|
||||||
|
+ 'for type: ' + typeDef.key
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function TypeDeprecationChecker(types) {
|
||||||
|
types.forEach(checkForDeprecatedFunctionality);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TypeDeprecationChecker;
|
||||||
|
|
||||||
|
});
|
@ -81,14 +81,8 @@ define([
|
|||||||
return models;
|
return models;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.apiFetch(missingIds)
|
//Temporary fix for missing models - don't retry using this.apiFetch
|
||||||
.then(function (apiResults) {
|
return models;
|
||||||
Object.keys(apiResults).forEach(function (k) {
|
|
||||||
models[k] = apiResults[k];
|
|
||||||
});
|
|
||||||
|
|
||||||
return models;
|
|
||||||
});
|
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,6 +15,8 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
function LegacyViewProvider(legacyView, openmct, convertToLegacyObject) {
|
function LegacyViewProvider(legacyView, openmct, convertToLegacyObject) {
|
||||||
|
console.warn(`DEPRECATION WARNING: Migrate ${legacyView.key} from ${legacyView.bundle.path} to use the new View APIs. Legacy view support will be removed soon.`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
key: legacyView.key,
|
key: legacyView.key,
|
||||||
name: legacyView.name,
|
name: legacyView.name,
|
||||||
|
@ -4,6 +4,7 @@ define([
|
|||||||
|
|
||||||
) {
|
) {
|
||||||
function TypeInspectorViewProvider(typeDefinition, openmct, convertToLegacyObject) {
|
function TypeInspectorViewProvider(typeDefinition, openmct, convertToLegacyObject) {
|
||||||
|
console.warn(`DEPRECATION WARNING: Migrate ${typeDefinition.key} from ${typeDefinition.bundle.path} to use the new Inspector View APIs. Legacy Inspector view support will be removed soon.`);
|
||||||
let representation = openmct.$injector.get('representations[]')
|
let representation = openmct.$injector.get('representations[]')
|
||||||
.filter((r) => r.key === typeDefinition.inspector)[0];
|
.filter((r) => r.key === typeDefinition.inspector)[0];
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ class ActionsAPI extends EventEmitter {
|
|||||||
return actionsObject;
|
return actionsObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
_groupAndSortActions(actionsArray) {
|
_groupAndSortActions(actionsArray = []) {
|
||||||
if (!Array.isArray(actionsArray) && typeof actionsArray === 'object') {
|
if (!Array.isArray(actionsArray) && typeof actionsArray === 'object') {
|
||||||
actionsArray = Object.keys(actionsArray).map(key => actionsArray[key]);
|
actionsArray = Object.keys(actionsArray).map(key => actionsArray[key]);
|
||||||
}
|
}
|
||||||
|
2
src/api/objects/ConflictError.js
Normal file
2
src/api/objects/ConflictError.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export default class ConflictError extends Error {
|
||||||
|
}
|
@ -26,6 +26,7 @@ import RootRegistry from './RootRegistry';
|
|||||||
import RootObjectProvider from './RootObjectProvider';
|
import RootObjectProvider from './RootObjectProvider';
|
||||||
import EventEmitter from 'EventEmitter';
|
import EventEmitter from 'EventEmitter';
|
||||||
import InterceptorRegistry from './InterceptorRegistry';
|
import InterceptorRegistry from './InterceptorRegistry';
|
||||||
|
import ConflictError from './ConflictError';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utilities for loading, saving, and manipulating domain objects.
|
* Utilities for loading, saving, and manipulating domain objects.
|
||||||
@ -34,6 +35,7 @@ import InterceptorRegistry from './InterceptorRegistry';
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function ObjectAPI(typeRegistry, openmct) {
|
function ObjectAPI(typeRegistry, openmct) {
|
||||||
|
this.openmct = openmct;
|
||||||
this.typeRegistry = typeRegistry;
|
this.typeRegistry = typeRegistry;
|
||||||
this.eventEmitter = new EventEmitter();
|
this.eventEmitter = new EventEmitter();
|
||||||
this.providers = {};
|
this.providers = {};
|
||||||
@ -47,6 +49,10 @@ function ObjectAPI(typeRegistry, openmct) {
|
|||||||
this.interceptorRegistry = new InterceptorRegistry();
|
this.interceptorRegistry = new InterceptorRegistry();
|
||||||
|
|
||||||
this.SYNCHRONIZED_OBJECT_TYPES = ['notebook', 'plan'];
|
this.SYNCHRONIZED_OBJECT_TYPES = ['notebook', 'plan'];
|
||||||
|
|
||||||
|
this.errors = {
|
||||||
|
Conflict: ConflictError
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -181,13 +187,16 @@ ObjectAPI.prototype.get = function (identifier, abortSignal) {
|
|||||||
|
|
||||||
let objectPromise = provider.get(identifier, abortSignal).then(result => {
|
let objectPromise = provider.get(identifier, abortSignal).then(result => {
|
||||||
delete this.cache[keystring];
|
delete this.cache[keystring];
|
||||||
|
|
||||||
result = this.applyGetInterceptors(identifier, result);
|
result = this.applyGetInterceptors(identifier, result);
|
||||||
if (result.isMutable) {
|
|
||||||
result.$refresh(result);
|
return result;
|
||||||
} else {
|
}).catch((result) => {
|
||||||
let mutableDomainObject = this._toMutable(result);
|
console.warn(`Failed to retrieve ${keystring}:`, result);
|
||||||
mutableDomainObject.$refresh(result);
|
|
||||||
}
|
delete this.cache[keystring];
|
||||||
|
|
||||||
|
result = this.applyGetInterceptors(identifier);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
@ -291,6 +300,7 @@ ObjectAPI.prototype.isPersistable = function (idOrKeyString) {
|
|||||||
ObjectAPI.prototype.save = function (domainObject) {
|
ObjectAPI.prototype.save = function (domainObject) {
|
||||||
let provider = this.getProvider(domainObject.identifier);
|
let provider = this.getProvider(domainObject.identifier);
|
||||||
let savedResolve;
|
let savedResolve;
|
||||||
|
let savedReject;
|
||||||
let result;
|
let result;
|
||||||
|
|
||||||
if (!this.isPersistable(domainObject.identifier)) {
|
if (!this.isPersistable(domainObject.identifier)) {
|
||||||
@ -300,19 +310,18 @@ ObjectAPI.prototype.save = function (domainObject) {
|
|||||||
} else {
|
} else {
|
||||||
const persistedTime = Date.now();
|
const persistedTime = Date.now();
|
||||||
if (domainObject.persisted === undefined) {
|
if (domainObject.persisted === undefined) {
|
||||||
result = new Promise((resolve) => {
|
result = new Promise((resolve, reject) => {
|
||||||
savedResolve = resolve;
|
savedResolve = resolve;
|
||||||
|
savedReject = reject;
|
||||||
});
|
});
|
||||||
domainObject.persisted = persistedTime;
|
domainObject.persisted = persistedTime;
|
||||||
const newObjectPromise = provider.create(domainObject);
|
provider.create(domainObject)
|
||||||
if (newObjectPromise) {
|
.then((response) => {
|
||||||
newObjectPromise.then(response => {
|
|
||||||
this.mutate(domainObject, 'persisted', persistedTime);
|
this.mutate(domainObject, 'persisted', persistedTime);
|
||||||
savedResolve(response);
|
savedResolve(response);
|
||||||
|
}).catch((error) => {
|
||||||
|
savedReject(error);
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
result = Promise.reject(`[ObjectAPI][save] Object provider returned ${newObjectPromise} when creating new object.`);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
domainObject.persisted = persistedTime;
|
domainObject.persisted = persistedTime;
|
||||||
this.mutate(domainObject, 'persisted', persistedTime);
|
this.mutate(domainObject, 'persisted', persistedTime);
|
||||||
|
@ -180,6 +180,12 @@ define([
|
|||||||
* @memberof module:openmct.TelemetryAPI~TelemetryProvider#
|
* @memberof module:openmct.TelemetryAPI~TelemetryProvider#
|
||||||
*/
|
*/
|
||||||
TelemetryAPI.prototype.canProvideTelemetry = function (domainObject) {
|
TelemetryAPI.prototype.canProvideTelemetry = function (domainObject) {
|
||||||
|
console.warn(
|
||||||
|
'DEPRECATION WARNING: openmct.telemetry.canProvideTelemetry '
|
||||||
|
+ 'will not be supported in future versions of Open MCT. Please '
|
||||||
|
+ 'use openmct.telemetry.isTelemetryObject instead.'
|
||||||
|
);
|
||||||
|
|
||||||
return Boolean(this.findSubscriptionProvider(domainObject))
|
return Boolean(this.findSubscriptionProvider(domainObject))
|
||||||
|| Boolean(this.findRequestProvider(domainObject));
|
|| Boolean(this.findRequestProvider(domainObject));
|
||||||
};
|
};
|
||||||
@ -477,6 +483,10 @@ define([
|
|||||||
* @returns {Object<String, {TelemetryValueFormatter}>}
|
* @returns {Object<String, {TelemetryValueFormatter}>}
|
||||||
*/
|
*/
|
||||||
TelemetryAPI.prototype.getFormatMap = function (metadata) {
|
TelemetryAPI.prototype.getFormatMap = function (metadata) {
|
||||||
|
if (!metadata) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.formatMapCache.has(metadata)) {
|
if (!this.formatMapCache.has(metadata)) {
|
||||||
const formatMap = metadata.values().reduce(function (map, valueMetadata) {
|
const formatMap = metadata.values().reduce(function (map, valueMetadata) {
|
||||||
map[valueMetadata.key] = this.getValueFormatter(valueMetadata);
|
map[valueMetadata.key] = this.getValueFormatter(valueMetadata);
|
||||||
|
@ -130,8 +130,13 @@ export class TelemetryCollection extends EventEmitter {
|
|||||||
this.options.onPartialResponse = this._processNewTelemetry.bind(this);
|
this.options.onPartialResponse = this._processNewTelemetry.bind(this);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (this.requestAbort) {
|
||||||
|
this.requestAbort.abort();
|
||||||
|
}
|
||||||
|
|
||||||
this.requestAbort = new AbortController();
|
this.requestAbort = new AbortController();
|
||||||
this.options.signal = this.requestAbort.signal;
|
this.options.signal = this.requestAbort.signal;
|
||||||
|
this.emit('requestStarted');
|
||||||
historicalData = await this.historicalProvider.request(this.domainObject, this.options);
|
historicalData = await this.historicalProvider.request(this.domainObject, this.options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.name !== 'AbortError') {
|
if (error.name !== 'AbortError') {
|
||||||
@ -140,6 +145,7 @@ export class TelemetryCollection extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.emit('requestEnded');
|
||||||
this.requestAbort = undefined;
|
this.requestAbort = undefined;
|
||||||
|
|
||||||
this._processNewTelemetry(historicalData);
|
this._processNewTelemetry(historicalData);
|
||||||
|
@ -31,6 +31,11 @@ define([
|
|||||||
valueMetadata.hints = valueMetadata.hints || {};
|
valueMetadata.hints = valueMetadata.hints || {};
|
||||||
|
|
||||||
if (Object.prototype.hasOwnProperty.call(valueMetadata.hints, 'x')) {
|
if (Object.prototype.hasOwnProperty.call(valueMetadata.hints, 'x')) {
|
||||||
|
console.warn(
|
||||||
|
'DEPRECATION WARNING: `x` hints should be replaced with '
|
||||||
|
+ '`domain` hints moving forward. '
|
||||||
|
+ 'https://github.com/nasa/openmct/issues/1546'
|
||||||
|
);
|
||||||
if (!Object.prototype.hasOwnProperty.call(valueMetadata.hints, 'domain')) {
|
if (!Object.prototype.hasOwnProperty.call(valueMetadata.hints, 'domain')) {
|
||||||
valueMetadata.hints.domain = valueMetadata.hints.x;
|
valueMetadata.hints.domain = valueMetadata.hints.x;
|
||||||
}
|
}
|
||||||
@ -39,6 +44,11 @@ define([
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Object.prototype.hasOwnProperty.call(valueMetadata.hints, 'y')) {
|
if (Object.prototype.hasOwnProperty.call(valueMetadata.hints, 'y')) {
|
||||||
|
console.warn(
|
||||||
|
'DEPRECATION WARNING: `y` hints should be replaced with '
|
||||||
|
+ '`range` hints moving forward. '
|
||||||
|
+ 'https://github.com/nasa/openmct/issues/1546'
|
||||||
|
);
|
||||||
if (!Object.prototype.hasOwnProperty.call(valueMetadata.hints, 'range')) {
|
if (!Object.prototype.hasOwnProperty.call(valueMetadata.hints, 'range')) {
|
||||||
valueMetadata.hints.range = valueMetadata.hints.y;
|
valueMetadata.hints.range = valueMetadata.hints.y;
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,12 @@ define(['./Type'], function (Type) {
|
|||||||
*/
|
*/
|
||||||
TypeRegistry.prototype.standardizeType = function (typeDef) {
|
TypeRegistry.prototype.standardizeType = function (typeDef) {
|
||||||
if (Object.prototype.hasOwnProperty.call(typeDef, 'label')) {
|
if (Object.prototype.hasOwnProperty.call(typeDef, 'label')) {
|
||||||
|
console.warn(
|
||||||
|
'DEPRECATION WARNING typeDef: ' + typeDef.label + '. '
|
||||||
|
+ '`label` is deprecated in type definitions. Please use '
|
||||||
|
+ '`name` instead. This will cause errors in a future version '
|
||||||
|
+ 'of Open MCT. For more information, see '
|
||||||
|
+ 'https://github.com/nasa/openmct/issues/1568');
|
||||||
if (!typeDef.name) {
|
if (!typeDef.name) {
|
||||||
typeDef.name = typeDef.label;
|
typeDef.name = typeDef.label;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,6 @@ const DEFAULTS = [
|
|||||||
'platform/forms',
|
'platform/forms',
|
||||||
'platform/identity',
|
'platform/identity',
|
||||||
'platform/persistence/aggregator',
|
'platform/persistence/aggregator',
|
||||||
'platform/persistence/queue',
|
|
||||||
'platform/policy',
|
'platform/policy',
|
||||||
'platform/entanglement',
|
'platform/entanglement',
|
||||||
'platform/search',
|
'platform/search',
|
||||||
|
@ -32,7 +32,7 @@ describe('the plugin', function () {
|
|||||||
let openmct;
|
let openmct;
|
||||||
let composition;
|
let composition;
|
||||||
|
|
||||||
beforeEach((done) => {
|
beforeEach(() => {
|
||||||
|
|
||||||
openmct = createOpenMct();
|
openmct = createOpenMct();
|
||||||
|
|
||||||
@ -47,11 +47,6 @@ describe('the plugin', function () {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
openmct.on('start', done);
|
|
||||||
openmct.startHeadless();
|
|
||||||
|
|
||||||
composition = openmct.composition.get({identifier});
|
|
||||||
|
|
||||||
spyOn(couchPlugin.couchProvider, 'getObjectsByFilter').and.returnValue(Promise.resolve([
|
spyOn(couchPlugin.couchProvider, 'getObjectsByFilter').and.returnValue(Promise.resolve([
|
||||||
{
|
{
|
||||||
identifier: {
|
identifier: {
|
||||||
@ -66,6 +61,19 @@ describe('the plugin', function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]));
|
]));
|
||||||
|
|
||||||
|
spyOn(couchPlugin.couchProvider, "get").and.callFake((id) => {
|
||||||
|
return Promise.resolve({
|
||||||
|
identifier: id
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
openmct.once('start', resolve);
|
||||||
|
openmct.startHeadless();
|
||||||
|
}).then(() => {
|
||||||
|
composition = openmct.composition.get({identifier});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
@ -96,11 +96,11 @@ export default {
|
|||||||
|
|
||||||
this.timestampKey = this.openmct.time.timeSystem().key;
|
this.timestampKey = this.openmct.time.timeSystem().key;
|
||||||
|
|
||||||
this.valueMetadata = this
|
this.valueMetadata = this.metadata ? this
|
||||||
.metadata
|
.metadata
|
||||||
.valuesForHints(['range'])[0];
|
.valuesForHints(['range'])[0] : undefined;
|
||||||
|
|
||||||
this.valueKey = this.valueMetadata.key;
|
this.valueKey = this.valueMetadata ? this.valueMetadata.key : undefined;
|
||||||
|
|
||||||
this.unsubscribe = this.openmct
|
this.unsubscribe = this.openmct
|
||||||
.telemetry
|
.telemetry
|
||||||
@ -151,7 +151,10 @@ export default {
|
|||||||
size: 1,
|
size: 1,
|
||||||
strategy: 'latest'
|
strategy: 'latest'
|
||||||
})
|
})
|
||||||
.then((array) => this.updateValues(array[array.length - 1]));
|
.then((array) => this.updateValues(array[array.length - 1]))
|
||||||
|
.catch((error) => {
|
||||||
|
console.warn('Error fetching data', error);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
updateBounds(bounds, isTick) {
|
updateBounds(bounds, isTick) {
|
||||||
this.bounds = bounds;
|
this.bounds = bounds;
|
||||||
|
@ -73,8 +73,9 @@ export default {
|
|||||||
hasUnits() {
|
hasUnits() {
|
||||||
let itemsWithUnits = this.items.filter((item) => {
|
let itemsWithUnits = this.items.filter((item) => {
|
||||||
let metadata = this.openmct.telemetry.getMetadata(item.domainObject);
|
let metadata = this.openmct.telemetry.getMetadata(item.domainObject);
|
||||||
|
const valueMetadatas = metadata ? metadata.valueMetadatas : [];
|
||||||
|
|
||||||
return this.metadataHasUnits(metadata.valueMetadatas);
|
return this.metadataHasUnits(valueMetadatas);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -30,10 +30,10 @@
|
|||||||
<div v-if="staticStyle"
|
<div v-if="staticStyle"
|
||||||
class="c-inspect-styles__style"
|
class="c-inspect-styles__style"
|
||||||
>
|
>
|
||||||
<StyleEditor class="c-inspect-styles__editor"
|
<style-editor class="c-inspect-styles__editor"
|
||||||
:style-item="staticStyle"
|
:style-item="staticStyle"
|
||||||
:is-editing="isEditing"
|
:is-editing="isEditing"
|
||||||
@persist="updateStaticStyle"
|
@persist="updateStaticStyle"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
@ -87,10 +87,10 @@
|
|||||||
<condition-description :show-label="true"
|
<condition-description :show-label="true"
|
||||||
:condition="getCondition(conditionStyle.conditionId)"
|
:condition="getCondition(conditionStyle.conditionId)"
|
||||||
/>
|
/>
|
||||||
<StyleEditor class="c-inspect-styles__editor"
|
<style-editor class="c-inspect-styles__editor"
|
||||||
:style-item="conditionStyle"
|
:style-item="conditionStyle"
|
||||||
:is-editing="isEditing"
|
:is-editing="isEditing"
|
||||||
@persist="updateConditionalStyle"
|
@persist="updateConditionalStyle"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -240,10 +240,10 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let vm = new Vue({
|
let vm = new Vue({
|
||||||
components: {ConditionSetSelectorDialog},
|
|
||||||
provide: {
|
provide: {
|
||||||
openmct: this.openmct
|
openmct: this.openmct
|
||||||
},
|
},
|
||||||
|
components: {ConditionSetSelectorDialog},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
handleItemSelection
|
handleItemSelection
|
||||||
|
@ -40,13 +40,13 @@
|
|||||||
<div v-if="staticStyle"
|
<div v-if="staticStyle"
|
||||||
class="c-inspect-styles__style"
|
class="c-inspect-styles__style"
|
||||||
>
|
>
|
||||||
<StyleEditor class="c-inspect-styles__editor"
|
<style-editor class="c-inspect-styles__editor"
|
||||||
:style-item="staticStyle"
|
:style-item="staticStyle"
|
||||||
:is-editing="allowEditing"
|
:is-editing="allowEditing"
|
||||||
:mixed-styles="mixedStyles"
|
:mixed-styles="mixedStyles"
|
||||||
:non-specific-font-properties="nonSpecificFontProperties"
|
:non-specific-font-properties="nonSpecificFontProperties"
|
||||||
@persist="updateStaticStyle"
|
@persist="updateStaticStyle"
|
||||||
@save-style="saveStyle"
|
@save-style="saveStyle"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
@ -108,12 +108,12 @@
|
|||||||
<condition-description :show-label="true"
|
<condition-description :show-label="true"
|
||||||
:condition="getCondition(conditionStyle.conditionId)"
|
:condition="getCondition(conditionStyle.conditionId)"
|
||||||
/>
|
/>
|
||||||
<StyleEditor class="c-inspect-styles__editor"
|
<style-editor class="c-inspect-styles__editor"
|
||||||
:style-item="conditionStyle"
|
:style-item="conditionStyle"
|
||||||
:non-specific-font-properties="nonSpecificFontProperties"
|
:non-specific-font-properties="nonSpecificFontProperties"
|
||||||
:is-editing="allowEditing"
|
:is-editing="allowEditing"
|
||||||
@persist="updateConditionalStyle"
|
@persist="updateConditionalStyle"
|
||||||
@save-style="saveStyle"
|
@save-style="saveStyle"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -556,10 +556,10 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let vm = new Vue({
|
let vm = new Vue({
|
||||||
components: {ConditionSetSelectorDialog},
|
|
||||||
provide: {
|
provide: {
|
||||||
openmct: this.openmct
|
openmct: this.openmct
|
||||||
},
|
},
|
||||||
|
components: {ConditionSetSelectorDialog},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
handleItemSelection
|
handleItemSelection
|
||||||
|
@ -98,6 +98,8 @@ describe('the plugin', function () {
|
|||||||
|
|
||||||
conditionSetDefinition.initialize(mockConditionSetDomainObject);
|
conditionSetDefinition.initialize(mockConditionSetDomainObject);
|
||||||
|
|
||||||
|
spyOn(openmct.objects, "save").and.returnValue(Promise.resolve(true));
|
||||||
|
|
||||||
openmct.on('start', done);
|
openmct.on('start', done);
|
||||||
openmct.startHeadless();
|
openmct.startHeadless();
|
||||||
});
|
});
|
||||||
|
@ -38,16 +38,12 @@ a.c-condition-widget {
|
|||||||
|
|
||||||
// Make Condition Widget expand when in a hidden frame Layout context
|
// Make Condition Widget expand when in a hidden frame Layout context
|
||||||
// For both static and Flexible Layouts
|
// For both static and Flexible Layouts
|
||||||
.c-so-view--conditionWidget.c-so-view--no-frame {
|
.c-so-view--no-frame > .c-so-view__object-view > .c-condition-widget {
|
||||||
.c-condition-widget {
|
@include abs();
|
||||||
@include abs();
|
display: flex;
|
||||||
display: flex;
|
align-items: center;
|
||||||
align-items: center;
|
justify-content: center;
|
||||||
justify-content: center;
|
padding: 0;
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.c-so-view__frame-controls { display: none; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add some margin when a Condition Widget is in a Flexible Layout
|
// Add some margin when a Condition Widget is in a Flexible Layout
|
||||||
|
@ -47,8 +47,8 @@
|
|||||||
|
|
||||||
.is-editing {
|
.is-editing {
|
||||||
.l-shell__main-container {
|
.l-shell__main-container {
|
||||||
[s-selected],
|
&[s-selected],
|
||||||
[s-selected-parent] {
|
&[s-selected-parent] {
|
||||||
// Display grid and allow edit marquee to display in main layout holder when editing
|
// Display grid and allow edit marquee to display in main layout holder when editing
|
||||||
> .l-layout {
|
> .l-layout {
|
||||||
background: $editUIGridColorBg;
|
background: $editUIGridColorBg;
|
||||||
|
@ -101,7 +101,7 @@ export default {
|
|||||||
addChildren(domainObject) {
|
addChildren(domainObject) {
|
||||||
let keyString = this.openmct.objects.makeKeyString(domainObject.identifier);
|
let keyString = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||||
let metadata = this.openmct.telemetry.getMetadata(domainObject);
|
let metadata = this.openmct.telemetry.getMetadata(domainObject);
|
||||||
let metadataWithFilters = metadata.valueMetadatas.filter(value => value.filters);
|
let metadataWithFilters = metadata ? metadata.valueMetadatas.filter(value => value.filters) : [];
|
||||||
let hasFiltersWithKeyString = this.persistedFilters[keyString] !== undefined;
|
let hasFiltersWithKeyString = this.persistedFilters[keyString] !== undefined;
|
||||||
let mutateFilters = false;
|
let mutateFilters = false;
|
||||||
let childObject = {
|
let childObject = {
|
||||||
|
@ -39,13 +39,10 @@ describe("The Compass component", () => {
|
|||||||
sunAngle: 30
|
sunAngle: 30
|
||||||
};
|
};
|
||||||
let propsData = {
|
let propsData = {
|
||||||
|
containerWidth: 600,
|
||||||
|
containerHeight: 600,
|
||||||
naturalAspectRatio: 0.9,
|
naturalAspectRatio: 0.9,
|
||||||
image: imageDatum,
|
image: imageDatum
|
||||||
sizedImageDimensions: {
|
|
||||||
width: 100,
|
|
||||||
height: 100
|
|
||||||
},
|
|
||||||
compassRoseSizingClasses: '--rose-small --rose-min'
|
|
||||||
};
|
};
|
||||||
|
|
||||||
app = new Vue({
|
app = new Vue({
|
||||||
@ -54,13 +51,13 @@ describe("The Compass component", () => {
|
|||||||
return propsData;
|
return propsData;
|
||||||
},
|
},
|
||||||
template: `<Compass
|
template: `<Compass
|
||||||
:compass-rose-sizing-classes="compassRoseSizingClasses"
|
:container-width="containerWidth"
|
||||||
:image="image"
|
:container-height="containerHeight"
|
||||||
:natural-aspect-ratio="naturalAspectRatio"
|
:natural-aspect-ratio="naturalAspectRatio"
|
||||||
:sized-image-dimensions="sizedImageDimensions"
|
:image="image" />`
|
||||||
/>`
|
|
||||||
});
|
});
|
||||||
instance = app.$mount();
|
instance = app.$mount();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
|
@ -84,18 +84,18 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="c-local-controls c-local-controls--show-on-hover c-imagery__prev-next-buttons">
|
||||||
<button class="c-local-controls c-local-controls--show-on-hover c-imagery__prev-next-button c-nav c-nav--prev"
|
<button class="c-nav c-nav--prev"
|
||||||
title="Previous image"
|
title="Previous image"
|
||||||
:disabled="isPrevDisabled"
|
:disabled="isPrevDisabled"
|
||||||
@click="prevImage()"
|
@click="prevImage()"
|
||||||
></button>
|
></button>
|
||||||
|
<button class="c-nav c-nav--next"
|
||||||
<button class="c-local-controls c-local-controls--show-on-hover c-imagery__prev-next-button c-nav c-nav--next"
|
title="Next image"
|
||||||
title="Next image"
|
:disabled="isNextDisabled"
|
||||||
:disabled="isNextDisabled"
|
@click="nextImage()"
|
||||||
@click="nextImage()"
|
></button>
|
||||||
></button>
|
</div>
|
||||||
|
|
||||||
<div class="c-imagery__control-bar">
|
<div class="c-imagery__control-bar">
|
||||||
<div class="c-imagery__time">
|
<div class="c-imagery__time">
|
||||||
|
@ -285,17 +285,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.c-imagery__prev-next-button {
|
.c-imagery__prev-next-buttons {
|
||||||
pointer-events: all;
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: space-between;
|
||||||
|
pointer-events: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-75%); // 75% due to transform: rotation approach to the button
|
transform: translateY(-75%);
|
||||||
|
|
||||||
&.c-nav {
|
.c-nav {
|
||||||
position: absolute;
|
pointer-events: all;
|
||||||
|
|
||||||
&--prev { left: 0; }
|
|
||||||
&--next { right: 0; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.s-status-taking-snapshot & {
|
.s-status-taking-snapshot & {
|
||||||
|
@ -159,7 +159,7 @@ export default {
|
|||||||
let image = { ...datum };
|
let image = { ...datum };
|
||||||
image.formattedTime = this.formatTime(datum);
|
image.formattedTime = this.formatTime(datum);
|
||||||
image.url = this.formatImageUrl(datum);
|
image.url = this.formatImageUrl(datum);
|
||||||
image.time = datum[this.timeKey];
|
image.time = this.parseTime(image.formattedTime);
|
||||||
image.imageDownloadName = this.getImageDownloadName(datum);
|
image.imageDownloadName = this.getImageDownloadName(datum);
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
|
@ -220,7 +220,7 @@ describe("The Imagery View Layouts", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
spyOn(openmct.telemetry, 'request').and.returnValue(Promise.resolve([]));
|
spyOn(openmct.telemetry, 'request').and.returnValue(Promise.resolve([]));
|
||||||
spyOn(openmct.objects, 'get').and.returnValue(Promise.resolve(imageryObject));
|
spyOn(openmct.objects, 'get').and.returnValue(Promise.resolve({}));
|
||||||
|
|
||||||
originalRouterPath = openmct.router.path;
|
originalRouterPath = openmct.router.path;
|
||||||
|
|
||||||
@ -370,15 +370,18 @@ describe("The Imagery View Layouts", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should show that an image is not new", (done) => {
|
xit("should show that an image is not new", (done) => {
|
||||||
const target = imageTelemetry[2].url;
|
const target = imageTelemetry[2].url;
|
||||||
parent.querySelectorAll(`img[src='${target}']`)[0].click();
|
parent.querySelectorAll(`img[src='${target}']`)[0].click();
|
||||||
|
|
||||||
Vue.nextTick(() => {
|
Vue.nextTick(() => {
|
||||||
const imageIsNew = isNew(parent);
|
// used in code, need to wait to the 500ms here too
|
||||||
|
setTimeout(() => {
|
||||||
|
const imageIsNew = isNew(parent);
|
||||||
|
|
||||||
expect(imageIsNew).toBeFalse();
|
expect(imageIsNew).toBeFalse();
|
||||||
done();
|
done();
|
||||||
|
}, REFRESH_CSS_MS);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -45,7 +45,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<style lang="sass">
|
||||||
|
</style>
|
||||||
<script>
|
<script>
|
||||||
import packages from './third-party-licenses.json';
|
import packages from './third-party-licenses.json';
|
||||||
|
|
||||||
|
@ -180,9 +180,13 @@ export default {
|
|||||||
this.openmct.notifications.alert(message);
|
this.openmct.notifications.alert(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
const relativeHash = hash.slice(hash.indexOf('#'));
|
if (this.openmct.editor.isEditing()) {
|
||||||
const url = new URL(relativeHash, `${location.protocol}//${location.host}${location.pathname}`);
|
this.previewEmbed();
|
||||||
this.openmct.router.navigate(url.hash);
|
} else {
|
||||||
|
const relativeHash = hash.slice(hash.indexOf('#'));
|
||||||
|
const url = new URL(relativeHash, `${location.protocol}//${location.host}${location.pathname}`);
|
||||||
|
this.openmct.router.navigate(url.hash);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
formatTime(unixTime, timeFormat) {
|
formatTime(unixTime, timeFormat) {
|
||||||
return Moment.utc(unixTime).format(timeFormat);
|
return Moment.utc(unixTime).format(timeFormat);
|
||||||
|
72
src/plugins/notebook/monkeyPatchObjectAPIForNotebooks.js
Normal file
72
src/plugins/notebook/monkeyPatchObjectAPIForNotebooks.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import {NOTEBOOK_TYPE} from './notebook-constants';
|
||||||
|
|
||||||
|
export default function (openmct) {
|
||||||
|
const apiSave = openmct.objects.save.bind(openmct.objects);
|
||||||
|
|
||||||
|
openmct.objects.save = async (domainObject) => {
|
||||||
|
if (domainObject.type !== NOTEBOOK_TYPE) {
|
||||||
|
return apiSave(domainObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
const localMutable = openmct.objects._toMutable(domainObject);
|
||||||
|
let result;
|
||||||
|
|
||||||
|
try {
|
||||||
|
result = await apiSave(localMutable);
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof openmct.objects.errors.Conflict) {
|
||||||
|
result = resolveConflicts(localMutable, openmct);
|
||||||
|
} else {
|
||||||
|
result = Promise.reject(error);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
openmct.objects.destroyMutable(localMutable);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveConflicts(localMutable, openmct) {
|
||||||
|
return openmct.objects.getMutable(localMutable.identifier).then((remoteMutable) => {
|
||||||
|
const localEntries = localMutable.configuration.entries;
|
||||||
|
remoteMutable.$refresh(remoteMutable);
|
||||||
|
applyLocalEntries(remoteMutable, localEntries);
|
||||||
|
|
||||||
|
openmct.objects.destroyMutable(remoteMutable);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyLocalEntries(mutable, entries) {
|
||||||
|
Object.entries(entries).forEach(([sectionKey, pagesInSection]) => {
|
||||||
|
Object.entries(pagesInSection).forEach(([pageKey, localEntries]) => {
|
||||||
|
const remoteEntries = mutable.configuration.entries[sectionKey][pageKey];
|
||||||
|
const mergedEntries = [].concat(remoteEntries);
|
||||||
|
let shouldMutate = false;
|
||||||
|
|
||||||
|
const locallyAddedEntries = _.differenceBy(localEntries, remoteEntries, 'id');
|
||||||
|
const locallyModifiedEntries = _.differenceWith(localEntries, remoteEntries, (localEntry, remoteEntry) => {
|
||||||
|
return localEntry.id === remoteEntry.id && localEntry.text === remoteEntry.text;
|
||||||
|
});
|
||||||
|
|
||||||
|
locallyAddedEntries.forEach((localEntry) => {
|
||||||
|
mergedEntries.push(localEntry);
|
||||||
|
shouldMutate = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
locallyModifiedEntries.forEach((locallyModifiedEntry) => {
|
||||||
|
let mergedEntry = mergedEntries.find(entry => entry.id === locallyModifiedEntry.id);
|
||||||
|
if (mergedEntry !== undefined) {
|
||||||
|
mergedEntry.text = locallyModifiedEntry.text;
|
||||||
|
shouldMutate = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (shouldMutate) {
|
||||||
|
mutable.$set(`configuration.entries.${sectionKey}.${pageKey}`, mergedEntries);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -2,6 +2,7 @@ import CopyToNotebookAction from './actions/CopyToNotebookAction';
|
|||||||
import Notebook from './components/Notebook.vue';
|
import Notebook from './components/Notebook.vue';
|
||||||
import NotebookSnapshotIndicator from './components/NotebookSnapshotIndicator.vue';
|
import NotebookSnapshotIndicator from './components/NotebookSnapshotIndicator.vue';
|
||||||
import SnapshotContainer from './snapshot-container';
|
import SnapshotContainer from './snapshot-container';
|
||||||
|
import monkeyPatchObjectAPIForNotebooks from './monkeyPatchObjectAPIForNotebooks.js';
|
||||||
|
|
||||||
import { notebookImageMigration } from '../notebook/utils/notebook-migration';
|
import { notebookImageMigration } from '../notebook/utils/notebook-migration';
|
||||||
import { NOTEBOOK_TYPE } from './notebook-constants';
|
import { NOTEBOOK_TYPE } from './notebook-constants';
|
||||||
@ -165,5 +166,7 @@ export default function NotebookPlugin() {
|
|||||||
return domainObject;
|
return domainObject;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
monkeyPatchObjectAPIForNotebooks(openmct);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -154,6 +154,8 @@ describe("Notebook plugin:", () => {
|
|||||||
testObjectProvider.get.and.returnValue(Promise.resolve(notebookViewObject));
|
testObjectProvider.get.and.returnValue(Promise.resolve(notebookViewObject));
|
||||||
openmct.objects.addProvider('test-namespace', testObjectProvider);
|
openmct.objects.addProvider('test-namespace', testObjectProvider);
|
||||||
testObjectProvider.observe.and.returnValue(() => {});
|
testObjectProvider.observe.and.returnValue(() => {});
|
||||||
|
testObjectProvider.create.and.returnValue(Promise.resolve(true));
|
||||||
|
testObjectProvider.update.and.returnValue(Promise.resolve(true));
|
||||||
|
|
||||||
return openmct.objects.getMutable(notebookViewObject.identifier).then((mutableObject) => {
|
return openmct.objects.getMutable(notebookViewObject.identifier).then((mutableObject) => {
|
||||||
mutableNotebookObject = mutableObject;
|
mutableNotebookObject = mutableObject;
|
||||||
|
@ -125,7 +125,7 @@ export function addNotebookEntry(openmct, domainObject, notebookStorage, embed =
|
|||||||
const newEntries = addEntryIntoPage(notebookStorage, entries, entry);
|
const newEntries = addEntryIntoPage(notebookStorage, entries, entry);
|
||||||
|
|
||||||
addDefaultClass(domainObject, openmct);
|
addDefaultClass(domainObject, openmct);
|
||||||
openmct.objects.mutate(domainObject, 'configuration.entries', newEntries);
|
domainObject.configuration.entries = newEntries;
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
@ -96,9 +96,6 @@ export function setDefaultNotebookPageId(pageId) {
|
|||||||
|
|
||||||
export function validateNotebookStorageObject() {
|
export function validateNotebookStorageObject() {
|
||||||
const notebookStorage = getDefaultNotebook();
|
const notebookStorage = getDefaultNotebook();
|
||||||
if (!notebookStorage) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
let valid = false;
|
let valid = false;
|
||||||
if (notebookStorage) {
|
if (notebookStorage) {
|
||||||
|
@ -34,7 +34,7 @@ describe('the plugin', () => {
|
|||||||
let countFramesPromise;
|
let countFramesPromise;
|
||||||
|
|
||||||
beforeEach((done) => {
|
beforeEach((done) => {
|
||||||
openmct = createOpenMct();
|
openmct = createOpenMct(false);
|
||||||
|
|
||||||
element = document.createElement('div');
|
element = document.createElement('div');
|
||||||
child = document.createElement('div');
|
child = document.createElement('div');
|
||||||
|
@ -15,12 +15,16 @@
|
|||||||
|
|
||||||
port.onmessage = async function (event) {
|
port.onmessage = async function (event) {
|
||||||
if (event.data.request === 'close') {
|
if (event.data.request === 'close') {
|
||||||
|
console.log('Closing connection');
|
||||||
connections.splice(event.data.connectionId - 1, 1);
|
connections.splice(event.data.connectionId - 1, 1);
|
||||||
if (connections.length <= 0) {
|
if (connections.length <= 0) {
|
||||||
// abort any outstanding requests if there's nobody listening to it.
|
// abort any outstanding requests if there's nobody listening to it.
|
||||||
controller.abort();
|
controller.abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('Closed.');
|
||||||
|
connected = false;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,68 +33,9 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
connected = true;
|
do {
|
||||||
|
await self.listenForChanges(event.data.url, event.data.body, port);
|
||||||
let url = event.data.url;
|
} while (connected);
|
||||||
let body = event.data.body;
|
|
||||||
let error = false;
|
|
||||||
// feed=continuous maintains an indefinitely open connection with a keep-alive of HEARTBEAT milliseconds until this client closes the connection
|
|
||||||
// style=main_only returns only the current winning revision of the document
|
|
||||||
|
|
||||||
const response = await fetch(url, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
"Content-Type": 'application/json'
|
|
||||||
},
|
|
||||||
signal,
|
|
||||||
body
|
|
||||||
});
|
|
||||||
|
|
||||||
let reader;
|
|
||||||
|
|
||||||
if (response.body === undefined) {
|
|
||||||
error = true;
|
|
||||||
} else {
|
|
||||||
reader = response.body.getReader();
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!error) {
|
|
||||||
const {done, value} = await reader.read();
|
|
||||||
//done is true when we lose connection with the provider
|
|
||||||
if (done) {
|
|
||||||
error = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value) {
|
|
||||||
let chunk = new Uint8Array(value.length);
|
|
||||||
chunk.set(value, 0);
|
|
||||||
const decodedChunk = new TextDecoder("utf-8").decode(chunk).split('\n');
|
|
||||||
if (decodedChunk.length && decodedChunk[decodedChunk.length - 1] === '') {
|
|
||||||
decodedChunk.forEach((doc, index) => {
|
|
||||||
try {
|
|
||||||
if (doc) {
|
|
||||||
const objectChanges = JSON.parse(doc);
|
|
||||||
connections.forEach(function (connection) {
|
|
||||||
connection.postMessage({
|
|
||||||
objectChanges
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (decodeError) {
|
|
||||||
//do nothing;
|
|
||||||
console.log(decodeError);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
port.postMessage({
|
|
||||||
error
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -103,4 +48,64 @@
|
|||||||
console.log('Error on feed');
|
console.log('Error on feed');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.listenForChanges = async function (url, body, port) {
|
||||||
|
connected = true;
|
||||||
|
let error = false;
|
||||||
|
// feed=continuous maintains an indefinitely open connection with a keep-alive of HEARTBEAT milliseconds until this client closes the connection
|
||||||
|
// style=main_only returns only the current winning revision of the document
|
||||||
|
|
||||||
|
console.log('Opening changes feed connection.');
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
"Content-Type": 'application/json'
|
||||||
|
},
|
||||||
|
signal,
|
||||||
|
body
|
||||||
|
});
|
||||||
|
|
||||||
|
let reader;
|
||||||
|
|
||||||
|
if (response.body === undefined) {
|
||||||
|
error = true;
|
||||||
|
} else {
|
||||||
|
reader = response.body.getReader();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!error) {
|
||||||
|
const {done, value} = await reader.read();
|
||||||
|
//done is true when we lose connection with the provider
|
||||||
|
if (done) {
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
let chunk = new Uint8Array(value.length);
|
||||||
|
chunk.set(value, 0);
|
||||||
|
const decodedChunk = new TextDecoder("utf-8").decode(chunk).split('\n');
|
||||||
|
console.log('Received chunk');
|
||||||
|
if (decodedChunk.length && decodedChunk[decodedChunk.length - 1] === '') {
|
||||||
|
decodedChunk.forEach((doc, index) => {
|
||||||
|
try {
|
||||||
|
if (doc) {
|
||||||
|
const objectChanges = JSON.parse(doc);
|
||||||
|
connections.forEach(function (connection) {
|
||||||
|
connection.postMessage({
|
||||||
|
objectChanges
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (decodeError) {
|
||||||
|
//do nothing;
|
||||||
|
console.log(decodeError);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Done reading changes feed');
|
||||||
|
};
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
@ -29,7 +29,7 @@ const ID = "_id";
|
|||||||
const HEARTBEAT = 50000;
|
const HEARTBEAT = 50000;
|
||||||
const ALL_DOCS = "_all_docs?include_docs=true";
|
const ALL_DOCS = "_all_docs?include_docs=true";
|
||||||
|
|
||||||
export default class CouchObjectProvider {
|
class CouchObjectProvider {
|
||||||
constructor(openmct, options, namespace) {
|
constructor(openmct, options, namespace) {
|
||||||
options = this._normalize(options);
|
options = this._normalize(options);
|
||||||
this.openmct = openmct;
|
this.openmct = openmct;
|
||||||
@ -74,13 +74,6 @@ export default class CouchObjectProvider {
|
|||||||
if (event.data.type === 'connection') {
|
if (event.data.type === 'connection') {
|
||||||
this.changesFeedSharedWorkerConnectionId = event.data.connectionId;
|
this.changesFeedSharedWorkerConnectionId = event.data.connectionId;
|
||||||
} else {
|
} else {
|
||||||
const error = event.data.error;
|
|
||||||
if (error && Object.keys(this.observers).length > 0) {
|
|
||||||
this.observeObjectChanges();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let objectChanges = event.data.objectChanges;
|
let objectChanges = event.data.objectChanges;
|
||||||
objectChanges.identifier = {
|
objectChanges.identifier = {
|
||||||
namespace: this.namespace,
|
namespace: this.namespace,
|
||||||
@ -126,11 +119,12 @@ export default class CouchObjectProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return fetch(this.url + '/' + subPath, fetchOptions)
|
return fetch(this.url + '/' + subPath, fetchOptions)
|
||||||
.then(response => response.json())
|
.then((response) => {
|
||||||
.then(function (response) {
|
if (response.status === CouchObjectProvider.HTTP_CONFLICT) {
|
||||||
return response;
|
throw new this.openmct.objects.errors.Conflict(`Conflict persisting ${fetchOptions.body.name}`);
|
||||||
}, function () {
|
}
|
||||||
return undefined;
|
|
||||||
|
return response.json();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -561,12 +555,18 @@ export default class CouchObjectProvider {
|
|||||||
let intermediateResponse = this.getIntermediateResponse();
|
let intermediateResponse = this.getIntermediateResponse();
|
||||||
const key = model.identifier.key;
|
const key = model.identifier.key;
|
||||||
this.enqueueObject(key, model, intermediateResponse);
|
this.enqueueObject(key, model, intermediateResponse);
|
||||||
this.objectQueue[key].pending = true;
|
if (!this.objectQueue[key].pending) {
|
||||||
const queued = this.objectQueue[key].dequeue();
|
this.objectQueue[key].pending = true;
|
||||||
let document = new CouchDocument(key, queued.model);
|
const queued = this.objectQueue[key].dequeue();
|
||||||
this.request(key, "PUT", document).then((response) => {
|
let document = new CouchDocument(key, queued.model);
|
||||||
this.checkResponse(response, queued.intermediateResponse, key);
|
this.request(key, "PUT", document).then((response) => {
|
||||||
});
|
console.log('create check response', key);
|
||||||
|
this.checkResponse(response, queued.intermediateResponse, key);
|
||||||
|
}).catch(error => {
|
||||||
|
queued.intermediateResponse.reject(error);
|
||||||
|
this.objectQueue[key].pending = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return intermediateResponse.promise;
|
return intermediateResponse.promise;
|
||||||
}
|
}
|
||||||
@ -581,6 +581,9 @@ export default class CouchObjectProvider {
|
|||||||
let document = new CouchDocument(key, queued.model, this.objectQueue[key].rev);
|
let document = new CouchDocument(key, queued.model, this.objectQueue[key].rev);
|
||||||
this.request(key, "PUT", document).then((response) => {
|
this.request(key, "PUT", document).then((response) => {
|
||||||
this.checkResponse(response, queued.intermediateResponse, key);
|
this.checkResponse(response, queued.intermediateResponse, key);
|
||||||
|
}).catch((error) => {
|
||||||
|
queued.intermediateResponse.reject(error);
|
||||||
|
this.objectQueue[key].pending = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -594,3 +597,7 @@ export default class CouchObjectProvider {
|
|||||||
return intermediateResponse.promise;
|
return intermediateResponse.promise;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CouchObjectProvider.HTTP_CONFLICT = 409;
|
||||||
|
|
||||||
|
export default CouchObjectProvider;
|
||||||
|
@ -49,7 +49,7 @@ describe('the plugin', () => {
|
|||||||
filter: {},
|
filter: {},
|
||||||
disableObserve: true
|
disableObserve: true
|
||||||
};
|
};
|
||||||
openmct = createOpenMct();
|
openmct = createOpenMct(false);
|
||||||
|
|
||||||
openmct.$injector = jasmine.createSpyObj('$injector', ['get']);
|
openmct.$injector = jasmine.createSpyObj('$injector', ['get']);
|
||||||
mockIdentifierService = jasmine.createSpyObj(
|
mockIdentifierService = jasmine.createSpyObj(
|
||||||
|
@ -36,15 +36,7 @@ describe('the plugin', function () {
|
|||||||
appHolder.style.width = '640px';
|
appHolder.style.width = '640px';
|
||||||
appHolder.style.height = '480px';
|
appHolder.style.height = '480px';
|
||||||
|
|
||||||
const timeSystemOptions = {
|
openmct = createOpenMct();
|
||||||
timeSystemKey: 'utc',
|
|
||||||
bounds: {
|
|
||||||
start: 1597160002854,
|
|
||||||
end: 1597181232854
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
openmct = createOpenMct(timeSystemOptions);
|
|
||||||
openmct.install(new PlanPlugin());
|
openmct.install(new PlanPlugin());
|
||||||
|
|
||||||
planDefinition = openmct.types.get('plan').definition;
|
planDefinition = openmct.types.get('plan').definition;
|
||||||
@ -56,6 +48,7 @@ describe('the plugin', function () {
|
|||||||
child.style.width = '640px';
|
child.style.width = '640px';
|
||||||
child.style.height = '480px';
|
child.style.height = '480px';
|
||||||
element.appendChild(child);
|
element.appendChild(child);
|
||||||
|
|
||||||
openmct.on('start', done);
|
openmct.on('start', done);
|
||||||
openmct.start(appHolder);
|
openmct.start(appHolder);
|
||||||
});
|
});
|
||||||
@ -79,6 +72,7 @@ describe('the plugin', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('the plan view', () => {
|
describe('the plan view', () => {
|
||||||
|
|
||||||
it('provides a plan view', () => {
|
it('provides a plan view', () => {
|
||||||
const testViewObject = {
|
const testViewObject = {
|
||||||
id: "test-object",
|
id: "test-object",
|
||||||
@ -89,6 +83,7 @@ describe('the plugin', function () {
|
|||||||
let planView = applicableViews.find((viewProvider) => viewProvider.key === 'plan.view');
|
let planView = applicableViews.find((viewProvider) => viewProvider.key === 'plan.view');
|
||||||
expect(planView).toBeDefined();
|
expect(planView).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('the plan view displays activities', () => {
|
describe('the plan view displays activities', () => {
|
||||||
@ -160,22 +155,12 @@ describe('the plugin', function () {
|
|||||||
expect(labelEl.innerHTML).toEqual('TEST-GROUP');
|
expect(labelEl.innerHTML).toEqual('TEST-GROUP');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays the activities and their labels', (done) => {
|
it('displays the activities and their labels', () => {
|
||||||
const bounds = {
|
const rectEls = element.querySelectorAll('.c-plan__contents rect');
|
||||||
start: 1597160002854,
|
expect(rectEls.length).toEqual(2);
|
||||||
end: 1597181232854
|
const textEls = element.querySelectorAll('.c-plan__contents text');
|
||||||
};
|
expect(textEls.length).toEqual(3);
|
||||||
|
|
||||||
openmct.time.bounds(bounds);
|
|
||||||
|
|
||||||
Vue.nextTick(() => {
|
|
||||||
const rectEls = element.querySelectorAll('.c-plan__contents rect');
|
|
||||||
expect(rectEls.length).toEqual(2);
|
|
||||||
const textEls = element.querySelectorAll('.c-plan__contents text');
|
|
||||||
expect(textEls.length).toEqual(3);
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -21,67 +21,57 @@
|
|||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div class="u-contents">
|
<div class="u-contents">
|
||||||
<ul v-if="canEdit"
|
<div v-if="canEdit"
|
||||||
class="l-inspector-part"
|
class="grid-row"
|
||||||
>
|
>
|
||||||
<h2 v-if="heading"
|
<div class="grid-cell label"
|
||||||
:title="heading"
|
:title="editTitle"
|
||||||
>{{ heading }}</h2>
|
>{{ shortLabel }}</div>
|
||||||
<li class="grid-row">
|
<div class="grid-cell value">
|
||||||
<div class="grid-cell label"
|
<div class="c-click-swatch c-click-swatch--menu"
|
||||||
:title="editTitle"
|
@click="toggleSwatch()"
|
||||||
>{{ shortLabel }}</div>
|
>
|
||||||
<div class="grid-cell value">
|
<span class="c-color-swatch"
|
||||||
<div class="c-click-swatch c-click-swatch--menu"
|
:style="{ background: currentColor }"
|
||||||
@click="toggleSwatch()"
|
|
||||||
>
|
>
|
||||||
<span class="c-color-swatch"
|
</span>
|
||||||
:style="{ background: currentColor }"
|
</div>
|
||||||
|
<div class="c-palette c-palette--color">
|
||||||
|
<div v-show="swatchActive"
|
||||||
|
class="c-palette__items"
|
||||||
|
>
|
||||||
|
<div v-for="group in colorPaletteGroups"
|
||||||
|
:key="group.id"
|
||||||
|
class="u-contents"
|
||||||
>
|
>
|
||||||
</span>
|
<div v-for="color in group"
|
||||||
</div>
|
:key="color.id"
|
||||||
<div class="c-palette c-palette--color">
|
class="c-palette__item"
|
||||||
<div v-show="swatchActive"
|
:class="{ 'selected': currentColor === color.hexString }"
|
||||||
class="c-palette__items"
|
:style="{ background: color.hexString }"
|
||||||
>
|
@click="setColor(color)"
|
||||||
<div v-for="group in colorPaletteGroups"
|
|
||||||
:key="group.id"
|
|
||||||
class="u-contents"
|
|
||||||
>
|
>
|
||||||
<div v-for="color in group"
|
|
||||||
:key="color.id"
|
|
||||||
class="c-palette__item"
|
|
||||||
:class="{ 'selected': currentColor === color.hexString }"
|
|
||||||
:style="{ background: color.hexString }"
|
|
||||||
@click="setColor(color)"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</div>
|
||||||
</ul>
|
</div>
|
||||||
<ul v-else
|
<div v-else
|
||||||
class="l-inspector-part"
|
class="grid-row"
|
||||||
>
|
>
|
||||||
<h2 v-if="heading"
|
<div class="grid-cell label"
|
||||||
:title="heading"
|
:title="viewTitle"
|
||||||
>{{ heading }}</h2>
|
>{{ shortLabel }}</div>
|
||||||
<li class="grid-row">
|
<div class="grid-cell value">
|
||||||
<div class="grid-cell label"
|
<span class="c-color-swatch"
|
||||||
:title="viewTitle"
|
:style="{
|
||||||
>{{ shortLabel }}</div>
|
'background': currentColor
|
||||||
<div class="grid-cell value">
|
}"
|
||||||
<span class="c-color-swatch"
|
>
|
||||||
:style="{
|
</span>
|
||||||
'background': currentColor
|
</div>
|
||||||
}"
|
</div>
|
||||||
>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -114,12 +104,6 @@ export default {
|
|||||||
default() {
|
default() {
|
||||||
return 'Color';
|
return 'Color';
|
||||||
}
|
}
|
||||||
},
|
|
||||||
heading: {
|
|
||||||
type: String,
|
|
||||||
default() {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -39,6 +39,10 @@ export default function BarGraphCompositionPolicy(openmct) {
|
|||||||
return metadata.values().length > 0 && hasAggregateDomainAndRange(metadata);
|
return metadata.values().length > 0 && hasAggregateDomainAndRange(metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasNoChildren(parentObject) {
|
||||||
|
return parentObject.composition && parentObject.composition.length < 1;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
allow: function (parent, child) {
|
allow: function (parent, child) {
|
||||||
if ((parent.type === BAR_GRAPH_KEY)
|
if ((parent.type === BAR_GRAPH_KEY)
|
||||||
|
@ -107,7 +107,7 @@ export default {
|
|||||||
};
|
};
|
||||||
this.openmct.objects.mutate(
|
this.openmct.objects.mutate(
|
||||||
this.domainObject,
|
this.domainObject,
|
||||||
`configuration.barStyles[${this.key}]`,
|
`configuration.barStyles[${key}]`,
|
||||||
this.domainObject.configuration.barStyles[key]
|
this.domainObject.configuration.barStyles[key]
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -150,6 +150,10 @@ export default {
|
|||||||
},
|
},
|
||||||
getAxisMetadata(telemetryObject) {
|
getAxisMetadata(telemetryObject) {
|
||||||
const metadata = this.openmct.telemetry.getMetadata(telemetryObject);
|
const metadata = this.openmct.telemetry.getMetadata(telemetryObject);
|
||||||
|
if (!metadata) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
const yAxisMetadata = metadata.valuesForHints(['range'])[0];
|
const yAxisMetadata = metadata.valuesForHints(['range'])[0];
|
||||||
//Exclude 'name' and 'time' based metadata specifically, from the x-Axis values by using range hints only
|
//Exclude 'name' and 'time' based metadata specifically, from the x-Axis values by using range hints only
|
||||||
const xAxisMetadata = metadata.valuesForHints(['range']);
|
const xAxisMetadata = metadata.valuesForHints(['range']);
|
||||||
@ -255,6 +259,9 @@ export default {
|
|||||||
data.forEach((datum) => {
|
data.forEach((datum) => {
|
||||||
this.processData(telemetryObject, datum, axisMetadata);
|
this.processData(telemetryObject, datum, axisMetadata);
|
||||||
});
|
});
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.warn(`Error fetching data`, error);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
subscribeToObject(telemetryObject) {
|
subscribeToObject(telemetryObject) {
|
||||||
|
@ -33,9 +33,9 @@
|
|||||||
</li>
|
</li>
|
||||||
<ColorSwatch v-if="expanded"
|
<ColorSwatch v-if="expanded"
|
||||||
:current-color="currentColor"
|
:current-color="currentColor"
|
||||||
title="Manually set the color for this bar graph."
|
title="Manually set the color for this bar graph series."
|
||||||
edit-title="Manually set the color for this bar graph"
|
edit-title="Manually set the color for this bar graph series"
|
||||||
view-title="The color for this bar graph."
|
view-title="The color for this bar graph series."
|
||||||
short-label="Color"
|
short-label="Color"
|
||||||
class="grid-properties"
|
class="grid-properties"
|
||||||
@colorSet="setColor"
|
@colorSet="setColor"
|
||||||
|
@ -20,15 +20,13 @@
|
|||||||
at runtime from the About dialog for additional information.
|
at runtime from the About dialog for additional information.
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<ul class="c-tree">
|
||||||
<ul class="c-tree">
|
<h2 title="Display properties for this object">Bar Graph Series</h2>
|
||||||
<li v-for="series in domainObject.composition"
|
<bar-graph-options v-for="series in domainObject.composition"
|
||||||
:key="series.key"
|
:key="series.key"
|
||||||
>
|
:item="series"
|
||||||
<bar-graph-options :item="series" />
|
/>
|
||||||
</li>
|
</ul>
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -19,9 +19,6 @@
|
|||||||
this source code distribution or the Licensing information page available
|
this source code distribution or the Licensing information page available
|
||||||
at runtime from the About dialog for additional information.
|
at runtime from the About dialog for additional information.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- eslint-disable vue/no-v-html -->
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="gl-plot-chart-area">
|
<div class="gl-plot-chart-area">
|
||||||
<span v-html="canvasTemplate"></span>
|
<span v-html="canvasTemplate"></span>
|
||||||
|
@ -82,12 +82,17 @@ export default class PlotSeries extends Model {
|
|||||||
.openmct
|
.openmct
|
||||||
.telemetry
|
.telemetry
|
||||||
.getMetadata(options.domainObject);
|
.getMetadata(options.domainObject);
|
||||||
|
|
||||||
this.formats = options
|
this.formats = options
|
||||||
.openmct
|
.openmct
|
||||||
.telemetry
|
.telemetry
|
||||||
.getFormatMap(this.metadata);
|
.getFormatMap(this.metadata);
|
||||||
|
|
||||||
const range = this.metadata.valuesForHints(['range'])[0];
|
//if the object is missing or doesn't have metadata for some reason
|
||||||
|
let range = {};
|
||||||
|
if (this.metadata) {
|
||||||
|
range = this.metadata.valuesForHints(['range'])[0];
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: options.domainObject.name,
|
name: options.domainObject.name,
|
||||||
@ -191,7 +196,10 @@ export default class PlotSeries extends Model {
|
|||||||
.uniq(true, point => [this.getXVal(point), this.getYVal(point)].join())
|
.uniq(true, point => [this.getXVal(point), this.getYVal(point)].join())
|
||||||
.value();
|
.value();
|
||||||
this.reset(newPoints);
|
this.reset(newPoints);
|
||||||
}.bind(this));
|
}.bind(this))
|
||||||
|
.catch((error) => {
|
||||||
|
console.warn('Error fetching data', error);
|
||||||
|
});
|
||||||
/* eslint-enable you-dont-need-lodash-underscore/concat */
|
/* eslint-enable you-dont-need-lodash-underscore/concat */
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -199,7 +207,9 @@ export default class PlotSeries extends Model {
|
|||||||
*/
|
*/
|
||||||
onXKeyChange(xKey) {
|
onXKeyChange(xKey) {
|
||||||
const format = this.formats[xKey];
|
const format = this.formats[xKey];
|
||||||
this.getXVal = format.parse.bind(format);
|
if (format) {
|
||||||
|
this.getXVal = format.parse.bind(format);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Update y formatter on change, default to stepAfter interpolation if
|
* Update y formatter on change, default to stepAfter interpolation if
|
||||||
|
@ -184,7 +184,7 @@ export default class YAxisModel extends Model {
|
|||||||
this.set('values', yMetadata.values);
|
this.set('values', yMetadata.values);
|
||||||
if (!label) {
|
if (!label) {
|
||||||
const labelName = series.map(function (s) {
|
const labelName = series.map(function (s) {
|
||||||
return s.metadata.value(s.get('yKey')).name;
|
return s.metadata ? s.metadata.value(s.get('yKey')).name : '';
|
||||||
}).reduce(function (a, b) {
|
}).reduce(function (a, b) {
|
||||||
if (a === undefined) {
|
if (a === undefined) {
|
||||||
return b;
|
return b;
|
||||||
@ -204,7 +204,7 @@ export default class YAxisModel extends Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const labelUnits = series.map(function (s) {
|
const labelUnits = series.map(function (s) {
|
||||||
return s.metadata.value(s.get('yKey')).units;
|
return s.metadata ? s.metadata.value(s.get('yKey')).units : '';
|
||||||
}).reduce(function (a, b) {
|
}).reduce(function (a, b) {
|
||||||
if (a === undefined) {
|
if (a === undefined) {
|
||||||
return b;
|
return b;
|
||||||
|
@ -37,6 +37,7 @@ describe("the plugin", function () {
|
|||||||
let openmct;
|
let openmct;
|
||||||
let telemetryPromise;
|
let telemetryPromise;
|
||||||
let telemetryPromiseResolve;
|
let telemetryPromiseResolve;
|
||||||
|
let cleanupFirst;
|
||||||
let mockObjectPath;
|
let mockObjectPath;
|
||||||
let telemetrylimitProvider;
|
let telemetrylimitProvider;
|
||||||
|
|
||||||
@ -76,16 +77,9 @@ describe("the plugin", function () {
|
|||||||
'some-other-key': 'some-other-value 3'
|
'some-other-key': 'some-other-value 3'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
cleanupFirst = [];
|
||||||
|
|
||||||
const timeSystem = {
|
openmct = createOpenMct();
|
||||||
timeSystemKey: 'utc',
|
|
||||||
bounds: {
|
|
||||||
start: 0,
|
|
||||||
end: 4
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
openmct = createOpenMct(timeSystem);
|
|
||||||
|
|
||||||
telemetryPromise = new Promise((resolve) => {
|
telemetryPromise = new Promise((resolve) => {
|
||||||
telemetryPromiseResolve = resolve;
|
telemetryPromiseResolve = resolve;
|
||||||
@ -152,6 +146,11 @@ describe("the plugin", function () {
|
|||||||
disconnect() {}
|
disconnect() {}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
openmct.time.timeSystem("utc", {
|
||||||
|
start: 0,
|
||||||
|
end: 4
|
||||||
|
});
|
||||||
|
|
||||||
openmct.types.addType("test-object", {
|
openmct.types.addType("test-object", {
|
||||||
creatable: true
|
creatable: true
|
||||||
});
|
});
|
||||||
@ -171,8 +170,19 @@ describe("the plugin", function () {
|
|||||||
end: 1
|
end: 1
|
||||||
});
|
});
|
||||||
|
|
||||||
configStore.deleteAll();
|
// Needs to be in a timeout because plots use a bunch of setTimeouts, some of which can resolve during or after
|
||||||
resetApplicationState(openmct).then(done).catch(done);
|
// teardown, which causes problems
|
||||||
|
// This is hacky, we should find a better approach here.
|
||||||
|
setTimeout(() => {
|
||||||
|
//Cleanup code that needs to happen before dom elements start being destroyed
|
||||||
|
cleanupFirst.forEach(cleanup => cleanup());
|
||||||
|
cleanupFirst = [];
|
||||||
|
document.body.removeChild(element);
|
||||||
|
|
||||||
|
configStore.deleteAll();
|
||||||
|
|
||||||
|
resetApplicationState(openmct).then(done).catch(done);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("the plot views", () => {
|
describe("the plot views", () => {
|
||||||
@ -385,6 +395,10 @@ describe("the plugin", function () {
|
|||||||
plotView = plotViewProvider.view(testTelemetryObject, [testTelemetryObject]);
|
plotView = plotViewProvider.view(testTelemetryObject, [testTelemetryObject]);
|
||||||
plotView.show(child, true);
|
plotView.show(child, true);
|
||||||
|
|
||||||
|
cleanupFirst.push(() => {
|
||||||
|
plotView.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
return Vue.nextTick();
|
return Vue.nextTick();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -404,23 +418,12 @@ describe("the plugin", function () {
|
|||||||
expect(legend.length).toBe(6);
|
expect(legend.length).toBe(6);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Renders X-axis ticks for the telemetry object", (done) => {
|
it("Renders X-axis ticks for the telemetry object", () => {
|
||||||
const configId = openmct.objects.makeKeyString(testTelemetryObject.identifier);
|
let xAxisElement = element.querySelectorAll(".gl-plot-axis-area.gl-plot-x .gl-plot-tick-wrapper");
|
||||||
const config = configStore.get(configId);
|
expect(xAxisElement.length).toBe(1);
|
||||||
config.xAxis.set('displayRange', {
|
|
||||||
min: 0,
|
|
||||||
max: 4
|
|
||||||
});
|
|
||||||
|
|
||||||
Vue.nextTick(() => {
|
let ticks = xAxisElement[0].querySelectorAll(".gl-plot-tick");
|
||||||
let xAxisElement = element.querySelectorAll(".gl-plot-axis-area.gl-plot-x .gl-plot-tick-wrapper");
|
expect(ticks.length).toBe(5);
|
||||||
expect(xAxisElement.length).toBe(1);
|
|
||||||
|
|
||||||
let ticks = xAxisElement[0].querySelectorAll(".gl-plot-tick");
|
|
||||||
expect(ticks.length).toBe(5);
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Renders Y-axis options for the telemetry object", () => {
|
it("Renders Y-axis options for the telemetry object", () => {
|
||||||
@ -747,6 +750,11 @@ describe("the plugin", function () {
|
|||||||
template: "<stacked-plot></stacked-plot>"
|
template: "<stacked-plot></stacked-plot>"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cleanupFirst.push(() => {
|
||||||
|
component.$destroy();
|
||||||
|
component = undefined;
|
||||||
|
});
|
||||||
|
|
||||||
return telemetryPromise
|
return telemetryPromise
|
||||||
.then(Vue.nextTick())
|
.then(Vue.nextTick())
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -772,21 +780,12 @@ describe("the plugin", function () {
|
|||||||
expect(legend.length).toBe(6);
|
expect(legend.length).toBe(6);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Renders X-axis ticks for the telemetry object", (done) => {
|
xit("Renders X-axis ticks for the telemetry object", () => {
|
||||||
let xAxisElement = element.querySelectorAll(".gl-plot-axis-area.gl-plot-x .gl-plot-tick-wrapper");
|
let xAxisElement = element.querySelectorAll(".gl-plot-axis-area.gl-plot-x .gl-plot-tick-wrapper");
|
||||||
expect(xAxisElement.length).toBe(1);
|
expect(xAxisElement.length).toBe(1);
|
||||||
|
|
||||||
config.xAxis.set('displayRange', {
|
let ticks = xAxisElement[0].querySelectorAll(".gl-plot-tick");
|
||||||
min: 0,
|
expect(ticks.length).toBe(5);
|
||||||
max: 4
|
|
||||||
});
|
|
||||||
|
|
||||||
Vue.nextTick(() => {
|
|
||||||
let ticks = xAxisElement[0].querySelectorAll(".gl-plot-tick");
|
|
||||||
expect(ticks.length).toBe(5);
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Renders Y-axis ticks for the telemetry object", (done) => {
|
it("Renders Y-axis ticks for the telemetry object", (done) => {
|
||||||
|
@ -52,24 +52,22 @@
|
|||||||
>
|
>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="l-view-section">
|
<stacked-plot-item v-for="object in compositionObjects"
|
||||||
<stacked-plot-item v-for="object in compositionObjects"
|
:key="object.id"
|
||||||
:key="object.id"
|
class="c-plot--stacked-container"
|
||||||
class="c-plot--stacked-container"
|
:object="object"
|
||||||
:object="object"
|
:options="options"
|
||||||
:options="options"
|
:grid-lines="gridLines"
|
||||||
:grid-lines="gridLines"
|
:cursor-guide="cursorGuide"
|
||||||
:cursor-guide="cursorGuide"
|
:plot-tick-width="maxTickWidth"
|
||||||
:plot-tick-width="maxTickWidth"
|
@plotTickWidth="onTickWidthChange"
|
||||||
@plotTickWidth="onTickWidthChange"
|
@loadingUpdated="loadingUpdated"
|
||||||
@loadingUpdated="loadingUpdated"
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import eventHelpers from '../lib/eventHelpers';
|
||||||
import StackedPlotItem from './StackedPlotItem.vue';
|
import StackedPlotItem from './StackedPlotItem.vue';
|
||||||
import ImageExporter from '../../../exporters/ImageExporter';
|
import ImageExporter from '../../../exporters/ImageExporter';
|
||||||
|
|
||||||
@ -104,6 +102,8 @@ export default {
|
|||||||
this.destroy();
|
this.destroy();
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
eventHelpers.extend(this);
|
||||||
|
|
||||||
this.imageExporter = new ImageExporter(this.openmct);
|
this.imageExporter = new ImageExporter(this.openmct);
|
||||||
|
|
||||||
this.tickWidthMap = {};
|
this.tickWidthMap = {};
|
||||||
@ -118,6 +118,7 @@ export default {
|
|||||||
this.loading = loaded;
|
this.loading = loaded;
|
||||||
},
|
},
|
||||||
destroy() {
|
destroy() {
|
||||||
|
this.stopListening();
|
||||||
this.composition.off('add', this.addChild);
|
this.composition.off('add', this.addChild);
|
||||||
this.composition.off('remove', this.removeChild);
|
this.composition.off('remove', this.removeChild);
|
||||||
this.composition.off('reorder', this.compositionReorder);
|
this.composition.off('reorder', this.compositionReorder);
|
||||||
|
@ -75,11 +75,6 @@ export default {
|
|||||||
mounted() {
|
mounted() {
|
||||||
this.updateView();
|
this.updateView();
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
|
||||||
if (this.component) {
|
|
||||||
this.component.$destroy();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
updateComponentProp(prop, value) {
|
updateComponentProp(prop, value) {
|
||||||
if (this.component) {
|
if (this.component) {
|
||||||
|
@ -48,17 +48,17 @@ define([
|
|||||||
components: {
|
components: {
|
||||||
TabsComponent: TabsComponent.default
|
TabsComponent: TabsComponent.default
|
||||||
},
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isEditing: editMode
|
||||||
|
};
|
||||||
|
},
|
||||||
provide: {
|
provide: {
|
||||||
openmct,
|
openmct,
|
||||||
domainObject,
|
domainObject,
|
||||||
objectPath,
|
objectPath,
|
||||||
composition: openmct.composition.get(domainObject)
|
composition: openmct.composition.get(domainObject)
|
||||||
},
|
},
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
isEditing: editMode
|
|
||||||
};
|
|
||||||
},
|
|
||||||
template: '<tabs-component :isEditing="isEditing"></tabs-component>'
|
template: '<tabs-component :isEditing="isEditing"></tabs-component>'
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -60,18 +60,17 @@ define([
|
|||||||
this.addTelemetryObject = this.addTelemetryObject.bind(this);
|
this.addTelemetryObject = this.addTelemetryObject.bind(this);
|
||||||
this.removeTelemetryObject = this.removeTelemetryObject.bind(this);
|
this.removeTelemetryObject = this.removeTelemetryObject.bind(this);
|
||||||
this.removeTelemetryCollection = this.removeTelemetryCollection.bind(this);
|
this.removeTelemetryCollection = this.removeTelemetryCollection.bind(this);
|
||||||
|
this.incrementOutstandingRequests = this.incrementOutstandingRequests.bind(this);
|
||||||
|
this.decrementOutstandingRequests = this.decrementOutstandingRequests.bind(this);
|
||||||
this.resetRowsFromAllData = this.resetRowsFromAllData.bind(this);
|
this.resetRowsFromAllData = this.resetRowsFromAllData.bind(this);
|
||||||
this.isTelemetryObject = this.isTelemetryObject.bind(this);
|
this.isTelemetryObject = this.isTelemetryObject.bind(this);
|
||||||
this.refreshData = this.refreshData.bind(this);
|
|
||||||
this.updateFilters = this.updateFilters.bind(this);
|
this.updateFilters = this.updateFilters.bind(this);
|
||||||
|
this.clearData = this.clearData.bind(this);
|
||||||
this.buildOptionsFromConfiguration = this.buildOptionsFromConfiguration.bind(this);
|
this.buildOptionsFromConfiguration = this.buildOptionsFromConfiguration.bind(this);
|
||||||
|
|
||||||
this.filterObserver = undefined;
|
this.filterObserver = undefined;
|
||||||
|
|
||||||
this.createTableRowCollections();
|
this.createTableRowCollections();
|
||||||
|
|
||||||
openmct.time.on('bounds', this.refreshData);
|
|
||||||
openmct.time.on('timeSystem', this.refreshData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -141,8 +140,6 @@ define([
|
|||||||
let columnMap = this.getColumnMapForObject(keyString);
|
let columnMap = this.getColumnMapForObject(keyString);
|
||||||
let limitEvaluator = this.openmct.telemetry.limitEvaluator(telemetryObject);
|
let limitEvaluator = this.openmct.telemetry.limitEvaluator(telemetryObject);
|
||||||
|
|
||||||
this.incrementOutstandingRequests();
|
|
||||||
|
|
||||||
const telemetryProcessor = this.getTelemetryProcessor(keyString, columnMap, limitEvaluator);
|
const telemetryProcessor = this.getTelemetryProcessor(keyString, columnMap, limitEvaluator);
|
||||||
const telemetryRemover = this.getTelemetryRemover();
|
const telemetryRemover = this.getTelemetryRemover();
|
||||||
|
|
||||||
@ -151,13 +148,13 @@ define([
|
|||||||
this.telemetryCollections[keyString] = this.openmct.telemetry
|
this.telemetryCollections[keyString] = this.openmct.telemetry
|
||||||
.requestCollection(telemetryObject, requestOptions);
|
.requestCollection(telemetryObject, requestOptions);
|
||||||
|
|
||||||
|
this.telemetryCollections[keyString].on('requestStarted', this.incrementOutstandingRequests);
|
||||||
|
this.telemetryCollections[keyString].on('requestEnded', this.decrementOutstandingRequests);
|
||||||
this.telemetryCollections[keyString].on('remove', telemetryRemover);
|
this.telemetryCollections[keyString].on('remove', telemetryRemover);
|
||||||
this.telemetryCollections[keyString].on('add', telemetryProcessor);
|
this.telemetryCollections[keyString].on('add', telemetryProcessor);
|
||||||
this.telemetryCollections[keyString].on('clear', this.tableRows.clear);
|
this.telemetryCollections[keyString].on('clear', this.clearData);
|
||||||
this.telemetryCollections[keyString].load();
|
this.telemetryCollections[keyString].load();
|
||||||
|
|
||||||
this.decrementOutstandingRequests();
|
|
||||||
|
|
||||||
this.telemetryObjects[keyString] = {
|
this.telemetryObjects[keyString] = {
|
||||||
telemetryObject,
|
telemetryObject,
|
||||||
keyString,
|
keyString,
|
||||||
@ -268,17 +265,6 @@ define([
|
|||||||
this.emit('object-removed', objectIdentifier);
|
this.emit('object-removed', objectIdentifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshData(bounds, isTick) {
|
|
||||||
if (!isTick && this.tableRows.outstandingRequests === 0) {
|
|
||||||
this.tableRows.clear();
|
|
||||||
this.tableRows.sortBy({
|
|
||||||
key: this.openmct.time.timeSystem().key,
|
|
||||||
direction: 'asc'
|
|
||||||
});
|
|
||||||
this.tableRows.resubscribe();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clearData() {
|
clearData() {
|
||||||
this.tableRows.clear();
|
this.tableRows.clear();
|
||||||
this.emit('refresh');
|
this.emit('refresh');
|
||||||
@ -378,9 +364,6 @@ define([
|
|||||||
let keystrings = Object.keys(this.telemetryCollections);
|
let keystrings = Object.keys(this.telemetryCollections);
|
||||||
keystrings.forEach(this.removeTelemetryCollection);
|
keystrings.forEach(this.removeTelemetryCollection);
|
||||||
|
|
||||||
this.openmct.time.off('bounds', this.refreshData);
|
|
||||||
this.openmct.time.off('timeSystem', this.refreshData);
|
|
||||||
|
|
||||||
if (this.filterObserver) {
|
if (this.filterObserver) {
|
||||||
this.filterObserver();
|
this.filterObserver();
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,8 @@ export default {
|
|||||||
objects.forEach(object => this.addColumnsForObject(object, false));
|
objects.forEach(object => this.addColumnsForObject(object, false));
|
||||||
},
|
},
|
||||||
addColumnsForObject(telemetryObject) {
|
addColumnsForObject(telemetryObject) {
|
||||||
let metadataValues = this.openmct.telemetry.getMetadata(telemetryObject).values();
|
const metadata = this.openmct.telemetry.getMetadata(telemetryObject);
|
||||||
|
let metadataValues = metadata ? metadata.values() : [];
|
||||||
metadataValues.forEach(metadatum => {
|
metadataValues.forEach(metadatum => {
|
||||||
let column = new TelemetryTableColumn(this.openmct, metadatum);
|
let column = new TelemetryTableColumn(this.openmct, metadatum);
|
||||||
this.tableConfiguration.addSingleColumnForObject(telemetryObject, column);
|
this.tableConfiguration.addSingleColumnForObject(telemetryObject, column);
|
||||||
|
@ -105,7 +105,8 @@ export default {
|
|||||||
composition.load().then((domainObjects) => {
|
composition.load().then((domainObjects) => {
|
||||||
domainObjects.forEach(telemetryObject => {
|
domainObjects.forEach(telemetryObject => {
|
||||||
let keyString = this.openmct.objects.makeKeyString(telemetryObject.identifier);
|
let keyString = this.openmct.objects.makeKeyString(telemetryObject.identifier);
|
||||||
let metadataValues = this.openmct.telemetry.getMetadata(telemetryObject).values();
|
const metadata = this.openmct.telemetry.getMetadata(telemetryObject);
|
||||||
|
let metadataValues = metadata ? metadata.values() : [];
|
||||||
let filters = this.filteredTelemetry[keyString];
|
let filters = this.filteredTelemetry[keyString];
|
||||||
|
|
||||||
if (filters !== undefined) {
|
if (filters !== undefined) {
|
||||||
|
@ -125,7 +125,6 @@
|
|||||||
<div
|
<div
|
||||||
class="c-table c-telemetry-table c-table--filterable c-table--sortable has-control-bar u-style-receiver js-style-receiver"
|
class="c-table c-telemetry-table c-table--filterable c-table--sortable has-control-bar u-style-receiver js-style-receiver"
|
||||||
:class="{
|
:class="{
|
||||||
'loading': loading,
|
|
||||||
'is-paused' : paused
|
'is-paused' : paused
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
@ -362,7 +361,7 @@ export default {
|
|||||||
autoScroll: true,
|
autoScroll: true,
|
||||||
sortOptions: {},
|
sortOptions: {},
|
||||||
filters: {},
|
filters: {},
|
||||||
loading: true,
|
loading: false,
|
||||||
scrollable: undefined,
|
scrollable: undefined,
|
||||||
tableEl: undefined,
|
tableEl: undefined,
|
||||||
headersHolderEl: undefined,
|
headersHolderEl: undefined,
|
||||||
@ -422,6 +421,14 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
loading: {
|
||||||
|
handler(isLoading) {
|
||||||
|
if (this.viewActionsCollection) {
|
||||||
|
let action = isLoading ? 'disable' : 'enable';
|
||||||
|
this.viewActionsCollection[action](['export-csv-all']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
markedRows: {
|
markedRows: {
|
||||||
handler(newVal, oldVal) {
|
handler(newVal, oldVal) {
|
||||||
this.$emit('marked-rows-updated', newVal, oldVal);
|
this.$emit('marked-rows-updated', newVal, oldVal);
|
||||||
@ -528,6 +535,7 @@ export default {
|
|||||||
if (!this.updatingView) {
|
if (!this.updatingView) {
|
||||||
this.updatingView = true;
|
this.updatingView = true;
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
|
|
||||||
let start = 0;
|
let start = 0;
|
||||||
let end = VISIBLE_ROW_COUNT;
|
let end = VISIBLE_ROW_COUNT;
|
||||||
let tableRows = this.table.tableRows.getRows();
|
let tableRows = this.table.tableRows.getRows();
|
||||||
@ -1019,6 +1027,12 @@ export default {
|
|||||||
this.viewActionsCollection.disable(['export-csv-marked', 'unmark-all-rows']);
|
this.viewActionsCollection.disable(['export-csv-marked', 'unmark-all-rows']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.loading) {
|
||||||
|
this.viewActionsCollection.disable(['export-csv-all']);
|
||||||
|
} else {
|
||||||
|
this.viewActionsCollection.enable(['export-csv-all']);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.paused) {
|
if (this.paused) {
|
||||||
this.viewActionsCollection.hide(['pause-data']);
|
this.viewActionsCollection.hide(['pause-data']);
|
||||||
this.viewActionsCollection.show(['play-data']);
|
this.viewActionsCollection.show(['play-data']);
|
||||||
|
@ -222,13 +222,9 @@ describe("the plugin", () => {
|
|||||||
openmct.router.path = originalRouterPath;
|
openmct.router.path = originalRouterPath;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Renders a row for every telemetry datum returned", (done) => {
|
it("Renders a row for every telemetry datum returned", () => {
|
||||||
let rows = element.querySelectorAll('table.c-telemetry-table__body tr');
|
let rows = element.querySelectorAll('table.c-telemetry-table__body tr');
|
||||||
Vue.nextTick(() => {
|
expect(rows.length).toBe(3);
|
||||||
expect(rows.length).toBe(3);
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Renders a column for every item in telemetry metadata", () => {
|
it("Renders a column for every item in telemetry metadata", () => {
|
||||||
|
@ -168,16 +168,13 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
zoom(bounds) {
|
zoom(bounds) {
|
||||||
if (isNaN(bounds.start) || isNaN(bounds.end)) {
|
this.isZooming = true;
|
||||||
this.isZooming = false;
|
this.formattedBounds.start = this.timeFormatter.format(bounds.start);
|
||||||
} else {
|
this.formattedBounds.end = this.timeFormatter.format(bounds.end);
|
||||||
this.isZooming = true;
|
|
||||||
this.formattedBounds.start = this.timeFormatter.format(bounds.start);
|
|
||||||
this.formattedBounds.end = this.timeFormatter.format(bounds.end);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
endZoom(bounds) {
|
endZoom(bounds) {
|
||||||
this.isZooming = false;
|
this.isZooming = false;
|
||||||
|
|
||||||
if (bounds) {
|
if (bounds) {
|
||||||
this.openmct.time.bounds(bounds);
|
this.openmct.time.bounds(bounds);
|
||||||
} else {
|
} else {
|
||||||
|
@ -40,7 +40,7 @@ const LOCAL_STORAGE_HISTORY_KEY_FIXED = 'tcHistory';
|
|||||||
const LOCAL_STORAGE_HISTORY_KEY_REALTIME = 'tcHistoryRealtime';
|
const LOCAL_STORAGE_HISTORY_KEY_REALTIME = 'tcHistoryRealtime';
|
||||||
const DEFAULT_RECORDS = 10;
|
const DEFAULT_RECORDS = 10;
|
||||||
|
|
||||||
import { millisecondsToDHMS } from "utils/duration";
|
import { getDuration } from "utils/duration";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inject: ['openmct', 'configuration'],
|
inject: ['openmct', 'configuration'],
|
||||||
@ -142,7 +142,7 @@ export default {
|
|||||||
let description = `${startTime} - ${this.formatTime(timespan.end)}`;
|
let description = `${startTime} - ${this.formatTime(timespan.end)}`;
|
||||||
|
|
||||||
if (this.timeSystem.isUTCBased && !this.openmct.time.clock()) {
|
if (this.timeSystem.isUTCBased && !this.openmct.time.clock()) {
|
||||||
name = `${startTime} ${millisecondsToDHMS(timespan.end - timespan.start)}`;
|
name = `${startTime} ${getDuration(timespan.end - timespan.start)}`;
|
||||||
} else {
|
} else {
|
||||||
name = description;
|
name = description;
|
||||||
}
|
}
|
||||||
@ -263,7 +263,7 @@ export default {
|
|||||||
format: format
|
format: format
|
||||||
}).formatter;
|
}).formatter;
|
||||||
|
|
||||||
return (isNegativeOffset ? '-' : '') + formatter.format(time, 'YYYY-MM-DD HH:mm:ss');
|
return (isNegativeOffset ? '-' : '') + formatter.format(time);
|
||||||
},
|
},
|
||||||
showHistoryMenu() {
|
showHistoryMenu() {
|
||||||
const elementBoundingClientRect = this.$refs.historyButton.getBoundingClientRect();
|
const elementBoundingClientRect = this.$refs.historyButton.getBoundingClientRect();
|
||||||
|
@ -151,29 +151,22 @@ export default {
|
|||||||
this.stopFollowingTimeContext();
|
this.stopFollowingTimeContext();
|
||||||
this.timeContext = this.openmct.time.getContextForView([this.domainObject]);
|
this.timeContext = this.openmct.time.getContextForView([this.domainObject]);
|
||||||
this.timeContext.on('timeContext', this.setTimeContext);
|
this.timeContext.on('timeContext', this.setTimeContext);
|
||||||
this.timeContext.on('clock', this.setViewFromClock);
|
this.timeContext.on('clock', this.setTimeOptions);
|
||||||
},
|
},
|
||||||
stopFollowingTimeContext() {
|
stopFollowingTimeContext() {
|
||||||
if (this.timeContext) {
|
if (this.timeContext) {
|
||||||
this.timeContext.off('timeContext', this.setTimeContext);
|
this.timeContext.off('timeContext', this.setTimeContext);
|
||||||
this.timeContext.off('clock', this.setViewFromClock);
|
this.timeContext.off('clock', this.setTimeOptions);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setViewFromClock(clock) {
|
setTimeOptions(clock) {
|
||||||
if (!this.timeOptions.mode) {
|
this.timeOptions.clockOffsets = this.timeOptions.clockOffsets || this.timeContext.clockOffsets();
|
||||||
this.setTimeOptions(clock);
|
this.timeOptions.fixedOffsets = this.timeOptions.fixedOffsets || this.timeContext.bounds();
|
||||||
}
|
|
||||||
},
|
|
||||||
setTimeOptions() {
|
|
||||||
if (!this.timeOptions || !this.timeOptions.mode) {
|
|
||||||
this.mode = this.timeContext.clock() === undefined ? { key: 'fixed' } : { key: Object.create(this.timeContext.clock()).key};
|
|
||||||
this.timeOptions = {
|
|
||||||
clockOffsets: this.timeContext.clockOffsets(),
|
|
||||||
fixedOffsets: this.timeContext.bounds()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
this.registerIndependentTimeOffsets();
|
if (!this.timeOptions.mode) {
|
||||||
|
this.mode = this.timeContext.clock() === undefined ? {key: 'fixed'} : {key: Object.create(this.timeContext.clock()).key};
|
||||||
|
this.registerIndependentTimeOffsets();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
saveFixedOffsets(offsets) {
|
saveFixedOffsets(offsets) {
|
||||||
const newOptions = Object.assign({}, this.timeOptions, {
|
const newOptions = Object.assign({}, this.timeOptions, {
|
||||||
|
@ -20,7 +20,8 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
<template>
|
<template>
|
||||||
<div ref="modeMenuButton"
|
<div v-if="modes.length > 1"
|
||||||
|
ref="modeMenuButton"
|
||||||
class="c-ctrl-wrapper c-ctrl-wrapper--menus-up"
|
class="c-ctrl-wrapper c-ctrl-wrapper--menus-up"
|
||||||
>
|
>
|
||||||
<div class="c-menu-button c-ctrl-wrapper c-ctrl-wrapper--menus-left">
|
<div class="c-menu-button c-ctrl-wrapper c-ctrl-wrapper--menus-left">
|
||||||
|
@ -88,7 +88,7 @@ export default {
|
|||||||
this.mutablePromise.then(() => {
|
this.mutablePromise.then(() => {
|
||||||
this.openmct.objects.destroyMutable(this.domainObject);
|
this.openmct.objects.destroyMutable(this.domainObject);
|
||||||
});
|
});
|
||||||
} else {
|
} else if (this.domainObject.isMutable) {
|
||||||
this.openmct.objects.destroyMutable(this.domainObject);
|
this.openmct.objects.destroyMutable(this.domainObject);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -51,15 +51,7 @@ describe('the plugin', function () {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const timeSystem = {
|
openmct = createOpenMct();
|
||||||
timeSystemKey: 'utc',
|
|
||||||
bounds: {
|
|
||||||
start: 1597160002854,
|
|
||||||
end: 1597181232854
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
openmct = createOpenMct(timeSystem);
|
|
||||||
openmct.install(new TimelinePlugin());
|
openmct.install(new TimelinePlugin());
|
||||||
|
|
||||||
objectDef = openmct.types.get('time-strip').definition;
|
objectDef = openmct.types.get('time-strip').definition;
|
||||||
@ -72,6 +64,11 @@ describe('the plugin', function () {
|
|||||||
child.style.height = '480px';
|
child.style.height = '480px';
|
||||||
element.appendChild(child);
|
element.appendChild(child);
|
||||||
|
|
||||||
|
openmct.time.timeSystem('utc', {
|
||||||
|
start: 1597160002854,
|
||||||
|
end: 1597181232854
|
||||||
|
});
|
||||||
|
|
||||||
openmct.on('start', done);
|
openmct.on('start', done);
|
||||||
openmct.startHeadless();
|
openmct.startHeadless();
|
||||||
});
|
});
|
||||||
@ -91,6 +88,7 @@ describe('the plugin', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('the time-strip object', () => {
|
describe('the time-strip object', () => {
|
||||||
|
|
||||||
it('is creatable', () => {
|
it('is creatable', () => {
|
||||||
expect(objectDef.creatable).toEqual(mockObject.creatable);
|
expect(objectDef.creatable).toEqual(mockObject.creatable);
|
||||||
});
|
});
|
||||||
|
@ -453,16 +453,12 @@ select {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.c-so-view--hyperlink.c-so-view--no-frame {
|
.c-so-view--no-frame > .c-so-view__object-view > .c-hyperlink--button {
|
||||||
.c-hyperlink--button {
|
|
||||||
@include abs();
|
@include abs();
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
|
||||||
|
|
||||||
.c-so-view__frame-controls { display: none; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************** MENUS */
|
/******************************************************** MENUS */
|
||||||
@ -1010,9 +1006,6 @@ input[type="range"] {
|
|||||||
transition: $transIn;
|
transition: $transIn;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
pointer-events: inherit;
|
pointer-events: inherit;
|
||||||
|
|
||||||
&[disabled] { opacity: $controlDisabledOpacity; }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +46,9 @@ mct-plot {
|
|||||||
|
|
||||||
.c-plot,
|
.c-plot,
|
||||||
.gl-plot {
|
.gl-plot {
|
||||||
|
overflow: hidden;
|
||||||
|
min-height: 100px;
|
||||||
|
|
||||||
.s-status-taking-snapshot & {
|
.s-status-taking-snapshot & {
|
||||||
.c-control-bar {
|
.c-control-bar {
|
||||||
display: none;
|
display: none;
|
||||||
@ -64,17 +67,16 @@ mct-plot {
|
|||||||
|
|
||||||
.c-plot {
|
.c-plot {
|
||||||
@include abs($mainViewPad);
|
@include abs($mainViewPad);
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: hidden;
|
|
||||||
min-height: $plotMinH;
|
|
||||||
|
|
||||||
.c-control-bar {
|
.c-control-bar {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
margin-bottom: $interiorMargin;
|
margin-bottom: $interiorMargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
.l-view-section {
|
.l-view-section, .c-plot--stacked-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -82,18 +84,7 @@ mct-plot {
|
|||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.c-plot--stacked-container {
|
|
||||||
display: flex;
|
|
||||||
flex: 1 1 auto;
|
|
||||||
flex-direction: column;
|
|
||||||
min-height: $plotMinH;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
&--stacked {
|
&--stacked {
|
||||||
min-height: auto !important;
|
|
||||||
|
|
||||||
.child-frame {
|
.child-frame {
|
||||||
.has-control-bar {
|
.has-control-bar {
|
||||||
.c-control-bar {
|
.c-control-bar {
|
||||||
@ -133,7 +124,7 @@ mct-plot {
|
|||||||
.plot-wrapper-axis-and-display-area {
|
.plot-wrapper-axis-and-display-area {
|
||||||
position: relative;
|
position: relative;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
//min-height: $plotMinH;
|
min-height: $plotMinH;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gl-plot-wrapper-display-area-and-x-axis {
|
.gl-plot-wrapper-display-area-and-x-axis {
|
||||||
@ -474,7 +465,6 @@ mct-plot {
|
|||||||
.gl-plot-legend,
|
.gl-plot-legend,
|
||||||
.c-plot-legend {
|
.c-plot-legend {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
flex: 0 0 auto; // Prevents clipping for all legend placements (top, bottom, etc.)
|
|
||||||
|
|
||||||
&__wrapper {
|
&__wrapper {
|
||||||
// Holds view-control and both collapsed and expanded legends
|
// Holds view-control and both collapsed and expanded legends
|
||||||
|
@ -599,6 +599,8 @@
|
|||||||
@mixin cArrowButtonBase($colorBg: transparent, $colorFg: $colorBtnFg, $filterHov: $filterHov) {
|
@mixin cArrowButtonBase($colorBg: transparent, $colorFg: $colorBtnFg, $filterHov: $filterHov) {
|
||||||
// Copied from branch new-tree-refactor
|
// Copied from branch new-tree-refactor
|
||||||
|
|
||||||
|
flex: 0 0 auto;
|
||||||
|
position: relative;
|
||||||
background: $colorBg;
|
background: $colorBg;
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
|
@ -160,7 +160,9 @@ export default {
|
|||||||
this.status = this.openmct.status.get(this.domainObject.identifier);
|
this.status = this.openmct.status.get(this.domainObject.identifier);
|
||||||
this.removeStatusListener = this.openmct.status.observe(this.domainObject.identifier, this.setStatus);
|
this.removeStatusListener = this.openmct.status.observe(this.domainObject.identifier, this.setStatus);
|
||||||
const provider = this.openmct.objectViews.get(this.domainObject, this.objectPath)[0];
|
const provider = this.openmct.objectViews.get(this.domainObject, this.objectPath)[0];
|
||||||
this.$refs.objectView.show(this.domainObject, provider.key, false, this.objectPath);
|
if (provider) {
|
||||||
|
this.$refs.objectView.show(this.domainObject, provider.key, false, this.objectPath);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.removeStatusListener();
|
this.removeStatusListener();
|
||||||
@ -193,8 +195,10 @@ export default {
|
|||||||
},
|
},
|
||||||
showMenuItems(event) {
|
showMenuItems(event) {
|
||||||
const sortedActions = this.openmct.actions._groupAndSortActions(this.menuActionItems);
|
const sortedActions = this.openmct.actions._groupAndSortActions(this.menuActionItems);
|
||||||
const menuItems = this.openmct.menus.actionsToMenuItems(sortedActions, this.actionCollection.objectPath, this.actionCollection.view);
|
if (sortedActions.length) {
|
||||||
this.openmct.menus.showMenu(event.x, event.y, menuItems);
|
const menuItems = this.openmct.menus.actionsToMenuItems(sortedActions, this.actionCollection.objectPath, this.actionCollection.view);
|
||||||
|
this.openmct.menus.showMenu(event.x, event.y, menuItems);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
setStatus(status) {
|
setStatus(status) {
|
||||||
this.status = status;
|
this.status = status;
|
||||||
|
@ -49,6 +49,7 @@ describe("the inspector", () => {
|
|||||||
|
|
||||||
beforeEach((done) => {
|
beforeEach((done) => {
|
||||||
openmct = createOpenMct();
|
openmct = createOpenMct();
|
||||||
|
spyOn(openmct.objects, 'save').and.returnValue(Promise.resolve(true));
|
||||||
openmct.on('start', done);
|
openmct.on('start', done);
|
||||||
openmct.startHeadless();
|
openmct.startHeadless();
|
||||||
});
|
});
|
||||||
@ -77,12 +78,12 @@ describe("the inspector", () => {
|
|||||||
expect(savedStylesViewComponent.$children[0].$children.length).toBe(0);
|
expect(savedStylesViewComponent.$children[0].$children.length).toBe(0);
|
||||||
stylesViewComponent.$children[0].saveStyle(mockStyle);
|
stylesViewComponent.$children[0].saveStyle(mockStyle);
|
||||||
|
|
||||||
stylesViewComponent.$nextTick().then(() => {
|
return stylesViewComponent.$nextTick().then(() => {
|
||||||
expect(savedStylesViewComponent.$children[0].$children.length).toBe(1);
|
expect(savedStylesViewComponent.$children[0].$children.length).toBe(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should allow a saved style to be applied", () => {
|
xit("should allow a saved style to be applied", () => {
|
||||||
spyOn(openmct.editor, 'isEditing').and.returnValue(true);
|
spyOn(openmct.editor, 'isEditing').and.returnValue(true);
|
||||||
|
|
||||||
selection = mockTelemetryTableSelection;
|
selection = mockTelemetryTableSelection;
|
||||||
@ -91,12 +92,12 @@ describe("the inspector", () => {
|
|||||||
|
|
||||||
stylesViewComponent.$children[0].saveStyle(mockStyle);
|
stylesViewComponent.$children[0].saveStyle(mockStyle);
|
||||||
|
|
||||||
stylesViewComponent.$nextTick().then(() => {
|
return stylesViewComponent.$nextTick().then(() => {
|
||||||
const styleSelectorComponent = savedStylesViewComponent.$children[0].$children[0];
|
const styleSelectorComponent = savedStylesViewComponent.$children[0].$children[0];
|
||||||
|
|
||||||
styleSelectorComponent.selectStyle();
|
styleSelectorComponent.selectStyle();
|
||||||
|
|
||||||
savedStylesViewComponent.$nextTick().then(() => {
|
return savedStylesViewComponent.$nextTick().then(() => {
|
||||||
const styleEditorComponentIndex = stylesViewComponent.$children[0].$children.length - 1;
|
const styleEditorComponentIndex = stylesViewComponent.$children[0].$children.length - 1;
|
||||||
const styleEditorComponent = stylesViewComponent.$children[0].$children[styleEditorComponentIndex];
|
const styleEditorComponent = stylesViewComponent.$children[0].$children[styleEditorComponentIndex];
|
||||||
const styles = styleEditorComponent.$children.filter(component => component.options.value === mockStyle.color);
|
const styles = styleEditorComponent.$children.filter(component => component.options.value === mockStyle.color);
|
||||||
@ -147,7 +148,7 @@ describe("the inspector", () => {
|
|||||||
stylesViewComponent = createViewComponent(StylesView, selection, openmct);
|
stylesViewComponent = createViewComponent(StylesView, selection, openmct);
|
||||||
savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct);
|
savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct);
|
||||||
|
|
||||||
stylesViewComponent.$nextTick().then(() => {
|
return stylesViewComponent.$nextTick().then(() => {
|
||||||
const styleEditorComponentIndex = stylesViewComponent.$children[0].$children.length - 1;
|
const styleEditorComponentIndex = stylesViewComponent.$children[0].$children.length - 1;
|
||||||
const styleEditorComponent = stylesViewComponent.$children[0].$children[styleEditorComponentIndex];
|
const styleEditorComponent = stylesViewComponent.$children[0].$children[styleEditorComponentIndex];
|
||||||
const saveStyleButtonIndex = styleEditorComponent.$children.length - 1;
|
const saveStyleButtonIndex = styleEditorComponent.$children.length - 1;
|
||||||
@ -168,7 +169,7 @@ describe("the inspector", () => {
|
|||||||
stylesViewComponent = createViewComponent(StylesView, selection, openmct);
|
stylesViewComponent = createViewComponent(StylesView, selection, openmct);
|
||||||
savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct);
|
savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct);
|
||||||
|
|
||||||
stylesViewComponent.$nextTick().then(() => {
|
return stylesViewComponent.$nextTick().then(() => {
|
||||||
const styleEditorComponentIndex = stylesViewComponent.$children[0].$children.length - 1;
|
const styleEditorComponentIndex = stylesViewComponent.$children[0].$children.length - 1;
|
||||||
const styleEditorComponent = stylesViewComponent.$children[0].$children[styleEditorComponentIndex];
|
const styleEditorComponent = stylesViewComponent.$children[0].$children[styleEditorComponentIndex];
|
||||||
const saveStyleButtonIndex = styleEditorComponent.$children.length - 1;
|
const saveStyleButtonIndex = styleEditorComponent.$children.length - 1;
|
||||||
@ -185,7 +186,7 @@ describe("the inspector", () => {
|
|||||||
stylesViewComponent = createViewComponent(StylesView, selection, openmct);
|
stylesViewComponent = createViewComponent(StylesView, selection, openmct);
|
||||||
savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct);
|
savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct);
|
||||||
|
|
||||||
stylesViewComponent.$nextTick().then(() => {
|
return stylesViewComponent.$nextTick().then(() => {
|
||||||
const styleEditorComponentIndex = stylesViewComponent.$children[0].$children.length - 1;
|
const styleEditorComponentIndex = stylesViewComponent.$children[0].$children.length - 1;
|
||||||
const styleEditorComponent = stylesViewComponent.$children[0].$children[styleEditorComponentIndex];
|
const styleEditorComponent = stylesViewComponent.$children[0].$children[styleEditorComponentIndex];
|
||||||
const saveStyleButtonIndex = styleEditorComponent.$children.length - 1;
|
const saveStyleButtonIndex = styleEditorComponent.$children.length - 1;
|
||||||
|
@ -54,15 +54,15 @@ export default {
|
|||||||
let viewContainer = document.createElement('div');
|
let viewContainer = document.createElement('div');
|
||||||
this.$el.append(viewContainer);
|
this.$el.append(viewContainer);
|
||||||
this.component = new Vue({
|
this.component = new Vue({
|
||||||
el: viewContainer,
|
|
||||||
components: {
|
|
||||||
StylesView
|
|
||||||
},
|
|
||||||
provide: {
|
provide: {
|
||||||
openmct: this.openmct,
|
openmct: this.openmct,
|
||||||
selection: selection,
|
selection: selection,
|
||||||
stylesManager: this.stylesManager
|
stylesManager: this.stylesManager
|
||||||
},
|
},
|
||||||
|
el: viewContainer,
|
||||||
|
components: {
|
||||||
|
StylesView
|
||||||
|
},
|
||||||
template: '<styles-view/>'
|
template: '<styles-view/>'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -42,10 +42,10 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
launchAbout() {
|
launchAbout() {
|
||||||
let vm = new Vue({
|
let vm = new Vue({
|
||||||
components: {AboutDialog},
|
|
||||||
provide: {
|
provide: {
|
||||||
openmct: this.openmct
|
openmct: this.openmct
|
||||||
},
|
},
|
||||||
|
components: {AboutDialog},
|
||||||
template: '<about-dialog></about-dialog>'
|
template: '<about-dialog></about-dialog>'
|
||||||
}).$mount();
|
}).$mount();
|
||||||
|
|
||||||
|
@ -6,74 +6,133 @@ let child;
|
|||||||
let appHolder;
|
let appHolder;
|
||||||
let resolveFunction;
|
let resolveFunction;
|
||||||
|
|
||||||
describe('Application router utility functions', () => {
|
let initialHash = '';
|
||||||
beforeEach(done => {
|
|
||||||
|
xdescribe('Application router utility functions', () => {
|
||||||
|
beforeAll(done => {
|
||||||
appHolder = document.createElement('div');
|
appHolder = document.createElement('div');
|
||||||
appHolder.style.width = '640px';
|
appHolder.style.width = '640px';
|
||||||
appHolder.style.height = '480px';
|
appHolder.style.height = '480px';
|
||||||
|
|
||||||
openmct = createOpenMct();
|
openmct = createOpenMct();
|
||||||
openmct.install(openmct.plugins.MyItems());
|
openmct.install(openmct.plugins.MyItems());
|
||||||
|
openmct.install(openmct.plugins.LocalTimeSystem());
|
||||||
|
openmct.install(openmct.plugins.UTCTimeSystem());
|
||||||
|
|
||||||
element = document.createElement('div');
|
element = document.createElement('div');
|
||||||
child = document.createElement('div');
|
child = document.createElement('div');
|
||||||
element.appendChild(child);
|
element.appendChild(child);
|
||||||
|
|
||||||
openmct.on('start', () => {
|
openmct.on('start', done);
|
||||||
resolveFunction = () => {
|
|
||||||
const success = window.location.hash !== null && window.location.hash !== '';
|
|
||||||
if (success) {
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
openmct.router.on('change:hash', resolveFunction);
|
|
||||||
openmct.router.setLocationFromUrl();
|
|
||||||
});
|
|
||||||
|
|
||||||
openmct.start(appHolder);
|
openmct.start(appHolder);
|
||||||
|
|
||||||
document.body.append(appHolder);
|
document.body.append(appHolder);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterAll(() => {
|
||||||
openmct.router.removeListener('change:hash', resolveFunction);
|
openmct.router.setHash(initialHash);
|
||||||
appHolder.remove();
|
appHolder.remove();
|
||||||
|
|
||||||
return resetApplicationState(openmct);
|
return resetApplicationState(openmct);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has initial hash when loaded', () => {
|
it('has initial hash when loaded', (done) => {
|
||||||
const success = window.location.hash !== null;
|
let success;
|
||||||
expect(success).toBe(true);
|
resolveFunction = () => {
|
||||||
|
openmct.router.setLocationFromUrl();
|
||||||
|
success = window.location.hash !== null;
|
||||||
|
if (success) {
|
||||||
|
initialHash = window.location.hash;
|
||||||
|
expect(success).toBe(true);
|
||||||
|
|
||||||
|
openmct.router.removeListener('change:hash', resolveFunction);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
openmct.router.on('change:hash', resolveFunction);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('The setSearchParam function sets an individual search parameter in the window location hash', () => {
|
it('The setSearchParam function sets an individual search parameter in the window location hash', (done) => {
|
||||||
|
let success;
|
||||||
openmct.router.setSearchParam('testParam', 'testValue');
|
openmct.router.setSearchParam('testParam', 'testValue');
|
||||||
const searchParams = openmct.router.getAllSearchParams();
|
resolveFunction = () => {
|
||||||
expect(searchParams.get('testParam')).toBe('testValue');
|
success = window.location.hash.includes('testParam=testValue');
|
||||||
|
if (success) {
|
||||||
|
expect(success).toBe(true);
|
||||||
|
|
||||||
|
openmct.router.removeListener('change:hash', resolveFunction);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
openmct.router.on('change:hash', resolveFunction);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('The deleteSearchParam function deletes an individual search paramater in the window location hash', () => {
|
it('The getSearchParam function returns the value of an individual search parameter 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) => {
|
||||||
|
let success;
|
||||||
openmct.router.deleteSearchParam('testParam');
|
openmct.router.deleteSearchParam('testParam');
|
||||||
const searchParams = openmct.router.getAllSearchParams();
|
resolveFunction = () => {
|
||||||
expect(searchParams.get('testParam')).toBe(null);
|
success = window.location.hash.includes('testParam=testValue') === false;
|
||||||
|
if (success) {
|
||||||
|
expect(success).toBe(true);
|
||||||
|
|
||||||
|
openmct.router.removeListener('change:hash', resolveFunction);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
openmct.router.on('change:hash', resolveFunction);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('The setSearchParam function sets a multiple individual search parameters in the window location hash', () => {
|
it('The setSearchParam function sets an individual search parameters in the window location hash', (done) => {
|
||||||
|
let success;
|
||||||
openmct.router.setSearchParam('testParam1', 'testValue1');
|
openmct.router.setSearchParam('testParam1', 'testValue1');
|
||||||
openmct.router.setSearchParam('testParam2', 'testValue2');
|
openmct.router.setSearchParam('testParam2', 'testValue2');
|
||||||
|
|
||||||
const searchParams = openmct.router.getAllSearchParams();
|
resolveFunction = () => {
|
||||||
expect(searchParams.get('testParam1')).toBe('testValue1');
|
const hasTestParam1 = window.location.hash.includes('testParam1=testValue1');
|
||||||
expect(searchParams.get('testParam2')).toBe('testValue2');
|
const hasTestParam2 = window.location.hash.includes('testParam2=testValue2');
|
||||||
|
success = hasTestParam1 && hasTestParam2;
|
||||||
|
if (success) {
|
||||||
|
expect(success).toBe(true);
|
||||||
|
|
||||||
|
openmct.router.removeListener('change:hash', resolveFunction);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
openmct.router.on('change:hash', resolveFunction);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('The setAllSearchParams function replaces all search paramaters in the window location hash', () => {
|
it('The setAllSearchParams function replaces all search parameters in the window location hash', (done) => {
|
||||||
|
let success;
|
||||||
|
|
||||||
openmct.router.setSearchParam('testParam2', 'updatedtestValue2');
|
openmct.router.setSearchParam('testParam2', 'updatedtestValue2');
|
||||||
openmct.router.setSearchParam('newTestParam3', 'newTestValue3');
|
openmct.router.setSearchParam('newTestParam3', 'newTestValue3');
|
||||||
|
|
||||||
const searchParams = openmct.router.getAllSearchParams();
|
resolveFunction = () => {
|
||||||
|
const hasupdatedValueForTestParam2 = window.location.hash.includes('testParam2=updatedtestValue2');
|
||||||
|
const hasNewTestParam3 = window.location.hash.includes('newTestParam3=newTestValue3');
|
||||||
|
success = hasupdatedValueForTestParam2 && hasNewTestParam3;
|
||||||
|
if (success) {
|
||||||
|
expect(success).toBe(true);
|
||||||
|
|
||||||
|
openmct.router.removeListener('change:hash', resolveFunction);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
openmct.router.on('change:hash', resolveFunction);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('The getAllSearchParams function returns the values of all search parameters in the window location hash', () => {
|
||||||
|
let searchParams = openmct.router.getAllSearchParams();
|
||||||
|
expect(searchParams.get('testParam1')).toBe('testValue1');
|
||||||
expect(searchParams.get('testParam2')).toBe('updatedtestValue2');
|
expect(searchParams.get('testParam2')).toBe('updatedtestValue2');
|
||||||
expect(searchParams.get('newTestParam3')).toBe('newTestValue3');
|
expect(searchParams.get('newTestParam3')).toBe('newTestValue3');
|
||||||
});
|
});
|
||||||
|
@ -119,16 +119,11 @@ define([
|
|||||||
function navigateToFirstChildOfRoot() {
|
function navigateToFirstChildOfRoot() {
|
||||||
openmct.objects.get('ROOT')
|
openmct.objects.get('ROOT')
|
||||||
.then(rootObject => {
|
.then(rootObject => {
|
||||||
const composition = openmct.composition.get(rootObject);
|
openmct.composition.get(rootObject).load()
|
||||||
if (!composition) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
composition.load()
|
|
||||||
.then(children => {
|
.then(children => {
|
||||||
let lastChild = children[children.length - 1];
|
let lastChild = children[children.length - 1];
|
||||||
if (!lastChild) {
|
if (!lastChild) {
|
||||||
console.debug('Unable to navigate to anything. No root objects found.');
|
console.error('Unable to navigate to anything. No root objects found.');
|
||||||
} else {
|
} else {
|
||||||
let lastChildId = openmct.objects.makeKeyString(lastChild.identifier);
|
let lastChildId = openmct.objects.makeKeyString(lastChild.identifier);
|
||||||
openmct.router.setPath(`#/browse/${lastChildId}`);
|
openmct.router.setPath(`#/browse/${lastChildId}`);
|
||||||
|
@ -20,8 +20,7 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
const ONE_SECOND = 1000;
|
const ONE_MINUTE = 60 * 1000;
|
||||||
const ONE_MINUTE = 60 * ONE_SECOND;
|
|
||||||
const ONE_HOUR = ONE_MINUTE * 60;
|
const ONE_HOUR = ONE_MINUTE * 60;
|
||||||
const ONE_DAY = ONE_HOUR * 24;
|
const ONE_DAY = ONE_HOUR * 24;
|
||||||
|
|
||||||
@ -40,20 +39,34 @@ function toDoubleDigits(num) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addTimeSuffix(value, suffix) {
|
export function getDuration(numericDuration) {
|
||||||
return typeof value === 'number' && value > 0 ? `${value + suffix}` : '';
|
let result;
|
||||||
}
|
let age;
|
||||||
|
|
||||||
export function millisecondsToDHMS(numericDuration) {
|
if (numericDuration > ONE_DAY - 1) {
|
||||||
const ms = numericDuration || 0;
|
age = normalizeAge((numericDuration / ONE_DAY)).toFixed(2);
|
||||||
const dhms = [
|
result = `+ ${age} day`;
|
||||||
addTimeSuffix(Math.floor(normalizeAge(ms / ONE_DAY)), 'd'),
|
|
||||||
addTimeSuffix(Math.floor(normalizeAge((ms % ONE_DAY) / ONE_HOUR)), 'h'),
|
|
||||||
addTimeSuffix(Math.floor(normalizeAge((ms % ONE_HOUR) / ONE_MINUTE)), 'm'),
|
|
||||||
addTimeSuffix(Math.floor(normalizeAge((ms % ONE_MINUTE) / ONE_SECOND)), 's')
|
|
||||||
].filter(Boolean).join(' ');
|
|
||||||
|
|
||||||
return `${ dhms ? '+' : ''} ${dhms}`;
|
if (age !== 1) {
|
||||||
|
result += 's';
|
||||||
|
}
|
||||||
|
} else if (numericDuration > ONE_HOUR - 1) {
|
||||||
|
age = normalizeAge((numericDuration / ONE_HOUR).toFixed(2));
|
||||||
|
result = `+ ${age} hour`;
|
||||||
|
|
||||||
|
if (age !== 1) {
|
||||||
|
result += 's';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
age = normalizeAge((numericDuration / ONE_MINUTE).toFixed(2));
|
||||||
|
result = `+ ${age} min`;
|
||||||
|
|
||||||
|
if (age !== 1) {
|
||||||
|
result += 's';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPreciseDuration(numericDuration) {
|
export function getPreciseDuration(numericDuration) {
|
||||||
|
@ -25,26 +25,13 @@ import MCT from 'MCT';
|
|||||||
let nativeFunctions = [];
|
let nativeFunctions = [];
|
||||||
let mockObjects = setMockObjects();
|
let mockObjects = setMockObjects();
|
||||||
|
|
||||||
const DEFAULT_TIME_OPTIONS = {
|
export function createOpenMct() {
|
||||||
timeSystemKey: 'utc',
|
|
||||||
bounds: {
|
|
||||||
start: 0,
|
|
||||||
end: 1
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export function createOpenMct(timeSystemOptions = DEFAULT_TIME_OPTIONS) {
|
|
||||||
const openmct = new MCT();
|
const openmct = new MCT();
|
||||||
openmct.install(openmct.plugins.LocalStorage());
|
openmct.install(openmct.plugins.LocalStorage());
|
||||||
openmct.install(openmct.plugins.UTCTimeSystem());
|
openmct.install(openmct.plugins.UTCTimeSystem());
|
||||||
|
openmct.time.timeSystem('utc', {
|
||||||
const timeSystemKey = timeSystemOptions.timeSystemKey;
|
start: 0,
|
||||||
const start = timeSystemOptions.bounds.start;
|
end: 1
|
||||||
const end = timeSystemOptions.bounds.end;
|
|
||||||
|
|
||||||
openmct.time.timeSystem(timeSystemKey, {
|
|
||||||
start,
|
|
||||||
end
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return openmct;
|
return openmct;
|
||||||
|
Reference in New Issue
Block a user