mirror of
https://github.com/nasa/openmct.git
synced 2025-06-23 01:18:57 +00:00
Merge branch 'master' into iso-date-format
This commit is contained in:
@ -31,6 +31,7 @@ define(function () {
|
||||
if (this.knownBundles.hasOwnProperty(path)) {
|
||||
throw new Error('Cannot register bundle with duplicate path', path);
|
||||
}
|
||||
|
||||
this.knownBundles[path] = definition;
|
||||
};
|
||||
|
||||
@ -38,6 +39,7 @@ define(function () {
|
||||
if (!this.knownBundles[path]) {
|
||||
throw new Error('Unknown bundle ' + path);
|
||||
}
|
||||
|
||||
this.bundles[path] = this.knownBundles[path];
|
||||
};
|
||||
|
||||
@ -45,11 +47,12 @@ define(function () {
|
||||
if (!this.bundles[path]) {
|
||||
throw new Error('Tried to disable inactive bundle ' + path);
|
||||
}
|
||||
|
||||
delete this.bundles[path];
|
||||
};
|
||||
|
||||
BundleRegistry.prototype.contains = function (path) {
|
||||
return !!this.bundles[path];
|
||||
return Boolean(this.bundles[path]);
|
||||
};
|
||||
|
||||
BundleRegistry.prototype.get = function (path) {
|
||||
@ -66,6 +69,7 @@ define(function () {
|
||||
if (!this.knownBundles[path]) {
|
||||
throw new Error('Cannot remove Unknown Bundle ' + path);
|
||||
}
|
||||
|
||||
delete this.bundles[path];
|
||||
delete this.knownBundles[path];
|
||||
};
|
||||
|
35
src/MCT.js
35
src/MCT.js
@ -102,19 +102,21 @@ define([
|
||||
};
|
||||
/* eslint-enable no-undef */
|
||||
|
||||
this.legacyBundle = {
|
||||
extensions: {
|
||||
services: [
|
||||
{
|
||||
key: "openmct",
|
||||
implementation: function ($injector) {
|
||||
this.$injector = $injector;
|
||||
|
||||
this.legacyBundle = { extensions: {
|
||||
services: [
|
||||
{
|
||||
key: "openmct",
|
||||
implementation: function ($injector) {
|
||||
this.$injector = $injector;
|
||||
return this;
|
||||
}.bind(this),
|
||||
depends: ['$injector']
|
||||
}
|
||||
]
|
||||
} };
|
||||
return this;
|
||||
}.bind(this),
|
||||
depends: ['$injector']
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Tracks current selection state of the application.
|
||||
@ -292,6 +294,7 @@ define([
|
||||
function instantiate(model, keyString) {
|
||||
var capabilities = capabilityService.getCapabilities(model, keyString);
|
||||
model.id = keyString;
|
||||
|
||||
return new DomainObjectImpl(keyString, model, capabilities);
|
||||
}
|
||||
|
||||
@ -303,6 +306,7 @@ define([
|
||||
.map((o) => {
|
||||
let keyString = objectUtils.makeKeyString(o.identifier);
|
||||
let oldModel = objectUtils.toOldFormat(o);
|
||||
|
||||
return instantiate(oldModel, keyString);
|
||||
})
|
||||
.reverse()
|
||||
@ -313,6 +317,7 @@ define([
|
||||
} else {
|
||||
let keyString = objectUtils.makeKeyString(domainObject.identifier);
|
||||
let oldModel = objectUtils.toOldFormat(domainObject);
|
||||
|
||||
return instantiate(oldModel, keyString);
|
||||
}
|
||||
};
|
||||
@ -391,7 +396,7 @@ define([
|
||||
* @event start
|
||||
* @memberof module:openmct.MCT~
|
||||
*/
|
||||
const startPromise = new Main()
|
||||
const startPromise = new Main();
|
||||
startPromise.run(this)
|
||||
.then(function (angular) {
|
||||
this.$angular = angular;
|
||||
@ -414,6 +419,7 @@ define([
|
||||
this.layout = appLayout.$refs.layout;
|
||||
Browse(this);
|
||||
}
|
||||
|
||||
this.router.start();
|
||||
this.emit('start');
|
||||
}.bind(this));
|
||||
@ -421,8 +427,9 @@ define([
|
||||
|
||||
MCT.prototype.startHeadless = function () {
|
||||
let unreachableNode = document.createElement('div');
|
||||
|
||||
return this.start(unreachableNode, true);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Install a plugin in MCT.
|
||||
|
@ -49,6 +49,7 @@ define([
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return action;
|
||||
});
|
||||
};
|
||||
|
@ -27,7 +27,9 @@ export default function LegacyActionAdapter(openmct, legacyActions) {
|
||||
if (action.category === 'contextual' || (Array.isArray(action.category) && action.category.includes('contextual'))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
console.warn(`DEPRECATION WARNING: Action ${action.definition.key} in bundle ${action.bundle.path} is non-contextual and should be migrated.`);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ export default class LegacyContextMenuAction {
|
||||
let context = {
|
||||
category: 'contextual',
|
||||
domainObject: this.openmct.legacyObject(pathWithRoot)
|
||||
}
|
||||
};
|
||||
let legacyAction = new this.LegacyAction(context);
|
||||
|
||||
if (!legacyAction.getMetadata) {
|
||||
@ -51,6 +51,7 @@ export default class LegacyContextMenuAction {
|
||||
return metadata;
|
||||
}.bind(legacyAction);
|
||||
}
|
||||
|
||||
legacyAction.perform();
|
||||
});
|
||||
}
|
||||
@ -58,9 +59,9 @@ export default class LegacyContextMenuAction {
|
||||
appliesTo(objectPath) {
|
||||
let legacyObject = this.openmct.legacyObject(objectPath);
|
||||
|
||||
return (this.LegacyAction.appliesTo === undefined ||
|
||||
this.LegacyAction.appliesTo({domainObject: legacyObject})) &&
|
||||
!this.isBlacklisted(objectPath);
|
||||
return (this.LegacyAction.appliesTo === undefined
|
||||
|| this.LegacyAction.appliesTo({domainObject: legacyObject}))
|
||||
&& !this.isBlacklisted(objectPath);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -84,6 +85,7 @@ export default class LegacyContextMenuAction {
|
||||
return OUTSIDE_EDIT_PATH_BLACKLIST.some(actionKey => this.LegacyAction.key === actionKey);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -202,5 +202,5 @@ define([
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -48,9 +48,11 @@ define([
|
||||
capabilities.mutation =
|
||||
synchronizeMutationCapability(capabilities.mutation);
|
||||
}
|
||||
|
||||
if (capabilities.view) {
|
||||
capabilities.view = patchViewCapability(capabilities.view);
|
||||
}
|
||||
|
||||
if (AlternateCompositionCapability.appliesTo(model, id)) {
|
||||
capabilities.composition = function (domainObject) {
|
||||
return new AlternateCompositionCapability(this.$injector, domainObject);
|
||||
|
@ -74,6 +74,7 @@ define([
|
||||
var keyString = objectUtils.makeKeyString(child.identifier);
|
||||
var oldModel = objectUtils.toOldFormat(child);
|
||||
var newDO = this.instantiate(oldModel, keyString);
|
||||
|
||||
return new ContextualDomainObject(newDO, this.domainObject);
|
||||
|
||||
};
|
||||
|
@ -47,6 +47,7 @@ define([
|
||||
if (v.provider && v.provider.priority) {
|
||||
vd.priority = v.provider.priority(newDomainObject);
|
||||
}
|
||||
|
||||
return vd;
|
||||
})
|
||||
.sortBy('priority')
|
||||
|
@ -41,6 +41,7 @@ define([
|
||||
listener(newModel);
|
||||
});
|
||||
};
|
||||
|
||||
return capability;
|
||||
};
|
||||
}
|
||||
|
@ -21,11 +21,11 @@
|
||||
*****************************************************************************/
|
||||
define([], function () {
|
||||
var LEGACY_INDICATOR_TEMPLATE =
|
||||
'<mct-include ' +
|
||||
' ng-model="indicator" ' +
|
||||
' class="h-indicator" ' +
|
||||
' key="template">' +
|
||||
' </mct-include>';
|
||||
'<mct-include '
|
||||
+ ' ng-model="indicator" '
|
||||
+ ' class="h-indicator" '
|
||||
+ ' key="template">'
|
||||
+ ' </mct-include>';
|
||||
|
||||
return function () {
|
||||
return function (openmct) {
|
||||
@ -51,6 +51,7 @@ define([], function () {
|
||||
} else {
|
||||
legacyIndicator = LegacyIndicatorDef;
|
||||
}
|
||||
|
||||
return legacyIndicator;
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ define(
|
||||
}
|
||||
|
||||
it("Displays any legacy indicators ", function () {
|
||||
var legacyIndicators = [{},{},{},{}];
|
||||
var legacyIndicators = [{}, {}, {}, {}];
|
||||
|
||||
legacyIndicatorsRunsFunction(legacyIndicators);
|
||||
renderIndicators();
|
||||
|
@ -31,8 +31,10 @@ define([], function () {
|
||||
) {
|
||||
if (view.hasOwnProperty('provider')) {
|
||||
var domainObject = legacyObject.useCapability('adapter');
|
||||
|
||||
return view.provider.canView(domainObject);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
@ -33,7 +33,8 @@ define([
|
||||
function AlternateCompositionInitializer(openmct) {
|
||||
AlternateCompositionCapability.appliesTo = function (model, id) {
|
||||
model = objectUtils.toNewFormat(model, id || '');
|
||||
return !!openmct.composition.get(model);
|
||||
|
||||
return Boolean(openmct.composition.get(model));
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -137,6 +137,7 @@ define([
|
||||
function callbackWrapper(series) {
|
||||
callback(createDatum(domainObject, metadata, series, series.getPointCount() - 1));
|
||||
}
|
||||
|
||||
return capability.subscribe(callbackWrapper, request) || function () {};
|
||||
};
|
||||
|
||||
@ -145,6 +146,7 @@ define([
|
||||
utils.toOldFormat(domainObject),
|
||||
utils.makeKeyString(domainObject.identifier)
|
||||
);
|
||||
|
||||
return oldObject.hasCapability("limit");
|
||||
};
|
||||
|
||||
|
@ -30,10 +30,10 @@ define([
|
||||
function checkForDeprecatedFunctionality(typeDef) {
|
||||
if (typeDef.hasOwnProperty('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
|
||||
'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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ define(
|
||||
var capabilities = capabilityService.getCapabilities(model, id);
|
||||
model.id = old_id;
|
||||
cacheService.put(id, model);
|
||||
|
||||
return new DomainObjectImpl(id, model, capabilities);
|
||||
};
|
||||
}
|
||||
|
@ -77,7 +77,8 @@ define([
|
||||
object.identifier.key,
|
||||
model
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
ObjectServiceProvider.prototype.update = async function (object) {
|
||||
let model = utils.toOldFormat(object);
|
||||
|
||||
@ -86,7 +87,7 @@ define([
|
||||
object.identifier.key,
|
||||
model
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the space in which this domain object is persisted;
|
||||
@ -106,6 +107,7 @@ define([
|
||||
if (this.identifierService === undefined) {
|
||||
this.identifierService = this.$injector.get('identifierService');
|
||||
}
|
||||
|
||||
return this.identifierService;
|
||||
};
|
||||
|
||||
@ -113,8 +115,9 @@ define([
|
||||
if (this.persistenceService === undefined) {
|
||||
this.persistenceService = this.$injector.get('persistenceService');
|
||||
}
|
||||
|
||||
return this.persistenceService;
|
||||
}
|
||||
};
|
||||
|
||||
ObjectServiceProvider.prototype.delete = function (object) {
|
||||
// TODO!
|
||||
@ -122,9 +125,11 @@ define([
|
||||
|
||||
ObjectServiceProvider.prototype.get = function (key) {
|
||||
var keyString = utils.makeKeyString(key);
|
||||
|
||||
return this.objectService.getObjects([keyString])
|
||||
.then(function (results) {
|
||||
var model = results[keyString].getModel();
|
||||
|
||||
return utils.toNewFormat(model, key);
|
||||
});
|
||||
};
|
||||
@ -138,6 +143,7 @@ define([
|
||||
var results = {},
|
||||
promises = keys.map(function (keyString) {
|
||||
var key = utils.parseKeyString(keyString);
|
||||
|
||||
return openmct.objects.get(key)
|
||||
.then(function (object) {
|
||||
object = utils.toOldFormat(object);
|
||||
|
@ -51,6 +51,7 @@ define([
|
||||
if (this.apiFetching[id]) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
this.apiFetching[id] = true;
|
||||
|
||||
return this.api.objects.get(objectUtils.parseKeyString(id))
|
||||
@ -84,6 +85,7 @@ define([
|
||||
Object.keys(apiResults).forEach(function (k) {
|
||||
models[k] = apiResults[k];
|
||||
});
|
||||
|
||||
return models;
|
||||
});
|
||||
}.bind(this));
|
||||
|
@ -16,6 +16,7 @@ define([
|
||||
|
||||
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 {
|
||||
key: legacyView.key,
|
||||
name: legacyView.name,
|
||||
@ -28,9 +29,11 @@ define([
|
||||
if (!domainObject || !domainObject.identifier) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (legacyView.type) {
|
||||
return domainObject.type === legacyView.type;
|
||||
}
|
||||
|
||||
let legacyObject = convertToLegacyObject(domainObject);
|
||||
if (legacyView.needs) {
|
||||
let meetsNeeds = legacyView.needs.every(k => legacyObject.hasCapability(k));
|
||||
@ -38,6 +41,7 @@ define([
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return openmct.$injector.get('policyService').allow(
|
||||
'view', legacyView, legacyObject
|
||||
);
|
||||
@ -79,6 +83,7 @@ define([
|
||||
results[i] = r;
|
||||
}));
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
@ -86,6 +91,7 @@ define([
|
||||
if (isDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
uses.forEach(function (key, i) {
|
||||
scope[key] = results[i];
|
||||
});
|
||||
@ -119,13 +125,14 @@ define([
|
||||
scope = null;
|
||||
unlistenToStatus();
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
priority: function () {
|
||||
let priority = legacyView.priority || DEFAULT_VIEW_PRIORITY;
|
||||
if (typeof priority === 'string') {
|
||||
priority = PRIORITY_LEVELS[priority];
|
||||
}
|
||||
|
||||
return priority;
|
||||
}
|
||||
};
|
||||
|
@ -37,7 +37,6 @@ define([
|
||||
scope.domainObject = legacyObject;
|
||||
scope.model = legacyObject.getModel();
|
||||
|
||||
|
||||
return {
|
||||
show: function (container) {
|
||||
let child = document.createElement('div');
|
||||
@ -52,6 +51,7 @@ define([
|
||||
results[i] = r;
|
||||
}));
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
@ -59,10 +59,11 @@ define([
|
||||
if (isDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
uses.forEach(function (key, i) {
|
||||
scope[key] = results[i];
|
||||
});
|
||||
element = openmct.$angular.element(child)
|
||||
element = openmct.$angular.element(child);
|
||||
templateLinker.link(
|
||||
scope,
|
||||
element,
|
||||
@ -88,7 +89,7 @@ define([
|
||||
element = null;
|
||||
scope = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ define([
|
||||
function convertToLegacyObject(domainObject) {
|
||||
let keyString = objectUtils.makeKeyString(domainObject.identifier);
|
||||
let oldModel = objectUtils.toOldFormat(domainObject);
|
||||
|
||||
return instantiate(oldModel, keyString);
|
||||
}
|
||||
|
||||
|
@ -41,5 +41,6 @@ export default function Branding(options) {
|
||||
if (arguments.length === 1) {
|
||||
brandingOptions = options;
|
||||
}
|
||||
|
||||
return brandingOptions;
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ export default class Editor extends EventEmitter {
|
||||
if (this.editing === true) {
|
||||
throw "Already editing";
|
||||
}
|
||||
|
||||
this.editing = true;
|
||||
this.getTransactionService().startTransaction();
|
||||
this.emit('isEditing', true);
|
||||
@ -59,11 +60,12 @@ export default class Editor extends EventEmitter {
|
||||
* @private
|
||||
*/
|
||||
save() {
|
||||
return this.getTransactionService().commit().then((result)=>{
|
||||
return this.getTransactionService().commit().then((result) => {
|
||||
this.editing = false;
|
||||
this.emit('isEditing', false);
|
||||
return result
|
||||
}).catch((error)=>{
|
||||
|
||||
return result;
|
||||
}).catch((error) => {
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
@ -88,6 +90,7 @@ export default class Editor extends EventEmitter {
|
||||
if (!this.transactionService) {
|
||||
this.transactionService = this.openmct.$injector.get('transactionService');
|
||||
}
|
||||
|
||||
return this.transactionService;
|
||||
}
|
||||
}
|
||||
|
@ -94,7 +94,10 @@ define([
|
||||
return composition.load().then(function () {
|
||||
expect(listener.calls.count()).toBe(3);
|
||||
expect(listener).toHaveBeenCalledWith({
|
||||
identifier: {namespace: 'test', key: 'a'}
|
||||
identifier: {
|
||||
namespace: 'test',
|
||||
key: 'a'
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -129,12 +132,15 @@ define([
|
||||
expect(newComposition[0].key).toEqual('b');
|
||||
expect(newComposition[1].key).toEqual('c');
|
||||
expect(newComposition[2].key).toEqual('a');
|
||||
})
|
||||
});
|
||||
});
|
||||
it('supports adding an object to composition', function () {
|
||||
let addListener = jasmine.createSpy('addListener');
|
||||
let mockChildObject = {
|
||||
identifier: {key: 'mock-key', namespace: ''}
|
||||
identifier: {
|
||||
key: 'mock-key',
|
||||
namespace: ''
|
||||
}
|
||||
};
|
||||
composition.on('add', addListener);
|
||||
composition.add(mockChildObject);
|
||||
@ -191,7 +197,10 @@ define([
|
||||
listenObject = addListener.calls.mostRecent().args[0];
|
||||
expect(listenObject).toEqual(loadedObject);
|
||||
expect(loadedObject).toEqual({
|
||||
identifier: {namespace: 'custom', key: 'thing'}
|
||||
identifier: {
|
||||
namespace: 'custom',
|
||||
key: 'thing'
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -200,7 +209,10 @@ define([
|
||||
|
||||
beforeEach(function () {
|
||||
mockChildObject = {
|
||||
identifier: {key: 'mock-key', namespace: ''}
|
||||
identifier: {
|
||||
key: 'mock-key',
|
||||
namespace: ''
|
||||
}
|
||||
};
|
||||
composition.add(mockChildObject);
|
||||
});
|
||||
@ -277,17 +289,28 @@ define([
|
||||
.then(function () {
|
||||
expect(addListener).not.toHaveBeenCalled();
|
||||
expect(removeListener).not.toHaveBeenCalled();
|
||||
add({namespace: 'custom', key: 'thing'});
|
||||
add({
|
||||
namespace: 'custom',
|
||||
key: 'thing'
|
||||
});
|
||||
|
||||
return addPromise;
|
||||
}).then(function () {
|
||||
expect(addListener).toHaveBeenCalledWith({
|
||||
identifier: {namespace: 'custom', key: 'thing'}
|
||||
identifier: {
|
||||
namespace: 'custom',
|
||||
key: 'thing'
|
||||
}
|
||||
});
|
||||
remove(addListener.calls.mostRecent().args[0]);
|
||||
|
||||
return removePromise;
|
||||
}).then(function () {
|
||||
expect(removeListener).toHaveBeenCalledWith({
|
||||
identifier: {namespace: 'custom', key: 'thing'}
|
||||
identifier: {
|
||||
namespace: 'custom',
|
||||
key: 'thing'
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -74,9 +74,11 @@ define([
|
||||
if (!this.listeners[event]) {
|
||||
throw new Error('Event not supported by composition: ' + event);
|
||||
}
|
||||
|
||||
if (!this.mutationListener) {
|
||||
this._synchronize();
|
||||
}
|
||||
|
||||
if (this.provider.on && this.provider.off) {
|
||||
if (event === 'add') {
|
||||
this.provider.on(
|
||||
@ -85,20 +87,24 @@ define([
|
||||
this.onProviderAdd,
|
||||
this
|
||||
);
|
||||
} if (event === 'remove') {
|
||||
}
|
||||
|
||||
if (event === 'remove') {
|
||||
this.provider.on(
|
||||
this.domainObject,
|
||||
'remove',
|
||||
this.onProviderRemove,
|
||||
this
|
||||
);
|
||||
} if (event === 'reorder') {
|
||||
}
|
||||
|
||||
if (event === 'reorder') {
|
||||
this.provider.on(
|
||||
this.domainObject,
|
||||
'reorder',
|
||||
this.onProviderReorder,
|
||||
this
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,6 +186,7 @@ define([
|
||||
if (!this.publicAPI.composition.checkPolicy(this.domainObject, child)) {
|
||||
throw `Object of type ${child.type} cannot be added to object of type ${this.domainObject.type}`;
|
||||
}
|
||||
|
||||
this.provider.add(this.domainObject, child.identifier);
|
||||
} else {
|
||||
this.emit('add', child);
|
||||
@ -201,10 +208,12 @@ define([
|
||||
}.bind(this))
|
||||
.then(function (childObjects) {
|
||||
childObjects.forEach(c => this.add(c, true));
|
||||
|
||||
return childObjects;
|
||||
}.bind(this))
|
||||
.then(function (children) {
|
||||
this.emit('load');
|
||||
|
||||
return children;
|
||||
}.bind(this));
|
||||
};
|
||||
@ -259,6 +268,7 @@ define([
|
||||
CompositionCollection.prototype.onProviderAdd = function (childId) {
|
||||
return this.publicAPI.objects.get(childId).then(function (child) {
|
||||
this.add(child, true);
|
||||
|
||||
return child;
|
||||
}.bind(this));
|
||||
};
|
||||
|
@ -57,9 +57,9 @@ define([
|
||||
* @private
|
||||
*/
|
||||
DefaultCompositionProvider.prototype.cannotContainItself = function (parent, child) {
|
||||
return !(parent.identifier.namespace === child.identifier.namespace &&
|
||||
parent.identifier.key === child.identifier.key);
|
||||
}
|
||||
return !(parent.identifier.namespace === child.identifier.namespace
|
||||
&& parent.identifier.key === child.identifier.key);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if this provider should be used to load composition for a
|
||||
@ -72,7 +72,7 @@ define([
|
||||
* @method appliesTo
|
||||
*/
|
||||
DefaultCompositionProvider.prototype.appliesTo = function (domainObject) {
|
||||
return !!domainObject.composition;
|
||||
return Boolean(domainObject.composition);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -167,8 +167,8 @@ define([
|
||||
*/
|
||||
DefaultCompositionProvider.prototype.remove = function (domainObject, childId) {
|
||||
let composition = domainObject.composition.filter(function (child) {
|
||||
return !(childId.namespace === child.namespace &&
|
||||
childId.key === child.key);
|
||||
return !(childId.namespace === child.namespace
|
||||
&& childId.key === child.key);
|
||||
});
|
||||
|
||||
this.publicAPI.objects.mutate(domainObject, 'composition', composition);
|
||||
@ -192,6 +192,7 @@ define([
|
||||
this.publicAPI.objects.mutate(parent, 'composition', parent.composition);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
@ -228,6 +229,7 @@ define([
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.publicAPI.objects.mutate(domainObject, 'composition', newComposition);
|
||||
|
||||
let id = objectUtils.makeKeyString(domainObject.identifier);
|
||||
@ -258,9 +260,10 @@ define([
|
||||
if (this.topicListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.publicAPI.objects.eventEmitter.on('mutation', this.onMutation);
|
||||
this.topicListener = () => {
|
||||
this.publicAPI.objects.eventEmitter.off('mutation', this.onMutation)
|
||||
this.publicAPI.objects.eventEmitter.off('mutation', this.onMutation);
|
||||
};
|
||||
};
|
||||
|
||||
@ -304,7 +307,6 @@ define([
|
||||
listeners.remove.forEach(notify(removedChild));
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
return DefaultCompositionProvider;
|
||||
|
@ -20,5 +20,5 @@
|
||||
<script>
|
||||
export default {
|
||||
inject: ['actions', 'objectPath']
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -83,11 +83,13 @@ class ContextMenuAPI {
|
||||
if (action.appliesTo === undefined && actionsToBeIncluded.includes(action.key)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return action.appliesTo(objectPath, actionsToBeIncluded) && actionsToBeIncluded.includes(action.key);
|
||||
} else {
|
||||
if (action.appliesTo === undefined) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return action.appliesTo(objectPath) && !action.hideInDefaultMenu;
|
||||
}
|
||||
});
|
||||
@ -126,7 +128,7 @@ class ContextMenuAPI {
|
||||
return {
|
||||
x: eventPosX,
|
||||
y: eventPosY
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
|
@ -68,9 +68,11 @@ define(['zepto', './res/indicator-template.html'],
|
||||
if (this.iconClassValue) {
|
||||
this.element.classList.remove(this.iconClassValue);
|
||||
}
|
||||
|
||||
if (iconClass) {
|
||||
this.element.classList.add(iconClass);
|
||||
}
|
||||
|
||||
this.iconClassValue = iconClass;
|
||||
}
|
||||
|
||||
@ -82,9 +84,11 @@ define(['zepto', './res/indicator-template.html'],
|
||||
if (this.statusClassValue) {
|
||||
this.element.classList.remove(this.statusClassValue);
|
||||
}
|
||||
|
||||
if (statusClass) {
|
||||
this.element.classList.add(statusClass);
|
||||
}
|
||||
|
||||
this.statusClassValue = statusClass;
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,8 @@ export default class NotificationAPI extends EventEmitter {
|
||||
message: message,
|
||||
autoDismiss: true,
|
||||
severity: "info"
|
||||
}
|
||||
};
|
||||
|
||||
return this._notify(notificationModel);
|
||||
}
|
||||
|
||||
@ -95,7 +96,8 @@ export default class NotificationAPI extends EventEmitter {
|
||||
let notificationModel = {
|
||||
message: message,
|
||||
severity: "alert"
|
||||
}
|
||||
};
|
||||
|
||||
return this._notify(notificationModel);
|
||||
}
|
||||
|
||||
@ -108,7 +110,8 @@ export default class NotificationAPI extends EventEmitter {
|
||||
let notificationModel = {
|
||||
message: message,
|
||||
severity: "error"
|
||||
}
|
||||
};
|
||||
|
||||
return this._notify(notificationModel);
|
||||
}
|
||||
|
||||
@ -124,7 +127,8 @@ export default class NotificationAPI extends EventEmitter {
|
||||
progressPerc: progressPerc,
|
||||
progressText: progressText,
|
||||
severity: "info"
|
||||
}
|
||||
};
|
||||
|
||||
return this._notify(notificationModel);
|
||||
}
|
||||
|
||||
@ -200,6 +204,7 @@ export default class NotificationAPI extends EventEmitter {
|
||||
if (index >= 0) {
|
||||
this.notifications.splice(index, 1);
|
||||
}
|
||||
|
||||
this._setActiveNotification(this._selectNextNotification());
|
||||
this._setHighestSeverity();
|
||||
notification.emit('destroy');
|
||||
@ -299,7 +304,7 @@ export default class NotificationAPI extends EventEmitter {
|
||||
notification.model.progressPerc = progressPerc;
|
||||
notification.model.progressText = progressText;
|
||||
notification.emit('progress', progressPerc, progressText);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return notification;
|
||||
@ -313,8 +318,10 @@ export default class NotificationAPI extends EventEmitter {
|
||||
|
||||
if (!notification) {
|
||||
delete this.activeTimeout;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.emit('notification', notification);
|
||||
|
||||
if (notification.model.autoDismiss || this._selectNextNotification()) {
|
||||
@ -342,8 +349,8 @@ export default class NotificationAPI extends EventEmitter {
|
||||
for (; i < this.notifications.length; i++) {
|
||||
notification = this.notifications[i];
|
||||
|
||||
if (!notification.model.minimized &&
|
||||
notification !== this.activeNotification) {
|
||||
if (!notification.model.minimized
|
||||
&& notification !== this.activeNotification) {
|
||||
return notification;
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,6 @@ define([
|
||||
EventEmitter
|
||||
) {
|
||||
|
||||
|
||||
/**
|
||||
* Utilities for loading, saving, and manipulating domain objects.
|
||||
* @interface ObjectAPI
|
||||
@ -66,6 +65,7 @@ define([
|
||||
if (identifier.key === 'ROOT') {
|
||||
return this.rootProvider;
|
||||
}
|
||||
|
||||
return this.providers[identifier.namespace] || this.fallbackProvider;
|
||||
};
|
||||
|
||||
@ -174,10 +174,11 @@ define([
|
||||
|
||||
ObjectAPI.prototype.isPersistable = function (domainObject) {
|
||||
let provider = this.getProvider(domainObject.identifier);
|
||||
return provider !== undefined &&
|
||||
provider.create !== undefined &&
|
||||
provider.update !== undefined;
|
||||
}
|
||||
|
||||
return provider !== undefined
|
||||
&& provider.create !== undefined
|
||||
&& provider.update !== undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Save this domain object in its current state. EXPERIMENTAL
|
||||
@ -206,6 +207,7 @@ define([
|
||||
result = provider.update(domainObject);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
@ -232,6 +234,7 @@ define([
|
||||
ObjectAPI.prototype.mutate = function (domainObject, path, value) {
|
||||
var mutableObject =
|
||||
new MutableObject(this.eventEmitter, domainObject);
|
||||
|
||||
return mutableObject.set(path, value);
|
||||
};
|
||||
|
||||
@ -248,6 +251,7 @@ define([
|
||||
var mutableObject =
|
||||
new MutableObject(this.eventEmitter, domainObject);
|
||||
mutableObject.on(path, callback);
|
||||
|
||||
return mutableObject.stopListening.bind(mutableObject);
|
||||
};
|
||||
|
||||
@ -266,9 +270,9 @@ define([
|
||||
ObjectAPI.prototype.areIdsEqual = function (...identifiers) {
|
||||
return identifiers.map(utils.parseKeyString)
|
||||
.every(identifier => {
|
||||
return identifier === identifiers[0] ||
|
||||
(identifier.namespace === identifiers[0].namespace &&
|
||||
identifier.key === identifiers[0].key);
|
||||
return identifier === identifiers[0]
|
||||
|| (identifier.namespace === identifiers[0].namespace
|
||||
&& identifier.key === identifiers[0].key);
|
||||
});
|
||||
};
|
||||
|
||||
@ -321,8 +325,9 @@ define([
|
||||
*/
|
||||
|
||||
function hasAlreadyBeenPersisted(domainObject) {
|
||||
return domainObject.persisted !== undefined &&
|
||||
domainObject.persisted === domainObject.modified;
|
||||
return domainObject.persisted !== undefined
|
||||
&& domainObject.persisted === domainObject.modified;
|
||||
}
|
||||
|
||||
return ObjectAPI;
|
||||
});
|
||||
|
@ -16,10 +16,11 @@ describe("The Object API", () => {
|
||||
name: "test object",
|
||||
type: "test-type"
|
||||
};
|
||||
})
|
||||
});
|
||||
describe("The save function", () => {
|
||||
it("Rejects if no provider available", () => {
|
||||
let rejected = false;
|
||||
|
||||
return objectAPI.save(mockDomainObject)
|
||||
.catch(() => rejected = true)
|
||||
.then(() => expect(rejected).toBe(true));
|
||||
@ -32,7 +33,7 @@ describe("The Object API", () => {
|
||||
"update"
|
||||
]);
|
||||
objectAPI.addProvider(TEST_NAMESPACE, mockProvider);
|
||||
})
|
||||
});
|
||||
it("Calls 'create' on provider if object is new", () => {
|
||||
objectAPI.save(mockDomainObject);
|
||||
expect(mockProvider.create).toHaveBeenCalled();
|
||||
@ -56,5 +57,5 @@ describe("The Object API", () => {
|
||||
expect(mockProvider.update).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
});
|
||||
|
@ -34,6 +34,7 @@ define([
|
||||
var promises = this.providers.map(function (provider) {
|
||||
return provider();
|
||||
});
|
||||
|
||||
return Promise.all(promises)
|
||||
.then(_.flatten);
|
||||
};
|
||||
|
@ -31,9 +31,9 @@ define([
|
||||
* @private
|
||||
*/
|
||||
function isIdentifier(thing) {
|
||||
return typeof thing === 'object' &&
|
||||
thing.hasOwnProperty('key') &&
|
||||
thing.hasOwnProperty('namespace');
|
||||
return typeof thing === 'object'
|
||||
&& thing.hasOwnProperty('key')
|
||||
&& thing.hasOwnProperty('namespace');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,6 +57,7 @@ define([
|
||||
if (isIdentifier(keyString)) {
|
||||
return keyString;
|
||||
}
|
||||
|
||||
var namespace = '',
|
||||
key = keyString;
|
||||
for (var i = 0; i < key.length; i++) {
|
||||
@ -66,6 +67,7 @@ define([
|
||||
key = key.slice(i + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
namespace += key[i];
|
||||
}
|
||||
|
||||
@ -79,7 +81,6 @@ define([
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert an Open MCT Identifier into a keyString, ex:
|
||||
* {namespace: 'scratch', key: 'root'} ==> 'scratch:root'
|
||||
@ -93,9 +94,11 @@ define([
|
||||
if (isKeyString(identifier)) {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
if (!identifier.namespace) {
|
||||
return identifier.key;
|
||||
}
|
||||
|
||||
return [
|
||||
identifier.namespace.replace(/:/g, '\\:'),
|
||||
identifier.key
|
||||
@ -116,6 +119,7 @@ define([
|
||||
if (model.composition) {
|
||||
model.composition = model.composition.map(makeKeyString);
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
@ -134,6 +138,7 @@ define([
|
||||
if (model.composition) {
|
||||
model.composition = model.composition.map(parseKeyString);
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
|
@ -31,14 +31,24 @@ define([
|
||||
registry;
|
||||
|
||||
beforeEach(function () {
|
||||
idA = {key: 'keyA', namespace: 'something'};
|
||||
idB = {key: 'keyB', namespace: 'something'};
|
||||
idC = {key: 'keyC', namespace: 'something'};
|
||||
idA = {
|
||||
key: 'keyA',
|
||||
namespace: 'something'
|
||||
};
|
||||
idB = {
|
||||
key: 'keyB',
|
||||
namespace: 'something'
|
||||
};
|
||||
idC = {
|
||||
key: 'keyC',
|
||||
namespace: 'something'
|
||||
};
|
||||
registry = new RootRegistry();
|
||||
});
|
||||
|
||||
it('can register a root by key', function () {
|
||||
registry.addRoot(idA);
|
||||
|
||||
return registry.getRoots()
|
||||
.then(function (roots) {
|
||||
expect(roots).toEqual([idA]);
|
||||
@ -47,6 +57,7 @@ define([
|
||||
|
||||
it('can register multiple roots by key', function () {
|
||||
registry.addRoot([idA, idB]);
|
||||
|
||||
return registry.getRoots()
|
||||
.then(function (roots) {
|
||||
expect(roots).toEqual([idA, idB]);
|
||||
@ -57,6 +68,7 @@ define([
|
||||
registry.addRoot(function () {
|
||||
return Promise.resolve(idA);
|
||||
});
|
||||
|
||||
return registry.getRoots()
|
||||
.then(function (roots) {
|
||||
expect(roots).toEqual([idA]);
|
||||
@ -67,6 +79,7 @@ define([
|
||||
registry.addRoot(function () {
|
||||
return Promise.resolve([idA, idB]);
|
||||
});
|
||||
|
||||
return registry.getRoots()
|
||||
.then(function (roots) {
|
||||
expect(roots).toEqual([idA, idB]);
|
||||
@ -78,6 +91,7 @@ define([
|
||||
registry.addRoot(function () {
|
||||
return Promise.resolve([idC]);
|
||||
});
|
||||
|
||||
return registry.getRoots()
|
||||
.then(function (roots) {
|
||||
expect(roots).toEqual([idA, idB, idC]);
|
||||
|
@ -5,7 +5,6 @@ define([
|
||||
) {
|
||||
describe('objectUtils', function () {
|
||||
|
||||
|
||||
describe('keyString util', function () {
|
||||
var EXPECTATIONS = {
|
||||
'ROOT': {
|
||||
|
@ -13,7 +13,7 @@ class Overlay extends EventEmitter {
|
||||
constructor(options) {
|
||||
super();
|
||||
|
||||
this.dismissable = options.dismissable !== false ? true : false;
|
||||
this.dismissable = options.dismissable !== false;
|
||||
this.container = document.createElement('div');
|
||||
this.container.classList.add('l-overlay-wrapper', cssClasses[options.size]);
|
||||
|
||||
|
@ -101,7 +101,6 @@ class OverlayAPI {
|
||||
return dialog;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Displays a blocking (modal) progress dialog. This dialog can be used for
|
||||
* displaying messages that require the user's attention, and show progress
|
||||
|
@ -23,7 +23,7 @@ class ProgressDialog extends Overlay {
|
||||
progressPerc: progressPerc || 0,
|
||||
progressText
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
template: '<progress-dialog-component :model="model"></progress-dialog-component>'
|
||||
}).$mount();
|
||||
|
@ -35,6 +35,6 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
inject:['iconClass', 'title', 'hint', 'timestamp', 'message']
|
||||
}
|
||||
inject: ['iconClass', 'title', 'hint', 'timestamp', 'message']
|
||||
};
|
||||
</script>
|
||||
|
@ -72,6 +72,7 @@ export default {
|
||||
if (this.buttons[index].emphasis) {
|
||||
this.focusIndex = index;
|
||||
}
|
||||
|
||||
return this.buttons[index].emphasis;
|
||||
});
|
||||
|
||||
@ -82,5 +83,5 @@ export default {
|
||||
return focusButton[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -13,12 +13,12 @@ export default {
|
||||
DialogComponent: DialogComponent,
|
||||
ProgressComponent: ProgressComponent
|
||||
},
|
||||
inject:['iconClass', 'title', 'hint', 'timestamp', 'message'],
|
||||
inject: ['iconClass', 'title', 'hint', 'timestamp', 'message'],
|
||||
props: {
|
||||
model: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -44,7 +44,7 @@ define([
|
||||
* definition has a telemetry property.
|
||||
*/
|
||||
DefaultMetadataProvider.prototype.supportsMetadata = function (domainObject) {
|
||||
return !!domainObject.telemetry || !!this.typeHasTelemetry(domainObject);
|
||||
return Boolean(domainObject.telemetry) || Boolean(this.typeHasTelemetry(domainObject));
|
||||
};
|
||||
|
||||
/**
|
||||
@ -82,7 +82,7 @@ define([
|
||||
_.sortBy(valueMetadata.enumerations.map(function (e) {
|
||||
return {
|
||||
string: e.string,
|
||||
value: +e.value
|
||||
value: Number(e.value)
|
||||
};
|
||||
}), 'e.value');
|
||||
valueMetadata.values = valueMetadata.enumerations.map(e => e.value);
|
||||
@ -119,9 +119,9 @@ define([
|
||||
if (!this.typeService) {
|
||||
this.typeService = this.openmct.$injector.get('typeService');
|
||||
}
|
||||
return !!this.typeService.getType(domainObject.type).typeDef.telemetry;
|
||||
};
|
||||
|
||||
return Boolean(this.typeService.getType(domainObject.type).typeDef.telemetry);
|
||||
};
|
||||
|
||||
return DefaultMetadataProvider;
|
||||
|
||||
|
@ -123,7 +123,6 @@ define([
|
||||
* @memberof module:openmct.TelemetryAPI~
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* An interface for retrieving telemetry data associated with a domain
|
||||
* object.
|
||||
@ -152,7 +151,7 @@ define([
|
||||
* @returns {boolean} true if the object is a telemetry object.
|
||||
*/
|
||||
TelemetryAPI.prototype.isTelemetryObject = function (domainObject) {
|
||||
return !!this.findMetadataProvider(domainObject);
|
||||
return Boolean(this.findMetadataProvider(domainObject));
|
||||
};
|
||||
|
||||
/**
|
||||
@ -167,12 +166,13 @@ define([
|
||||
*/
|
||||
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.'
|
||||
'DEPRECATION WARNING: openmct.telemetry.canProvideTelemetry '
|
||||
+ 'will not be supported in future versions of Open MCT. Please '
|
||||
+ 'use openmct.telemetry.isTelemetryObject instead.'
|
||||
);
|
||||
return !!this.findSubscriptionProvider(domainObject) ||
|
||||
!!this.findRequestProvider(domainObject);
|
||||
|
||||
return Boolean(this.findSubscriptionProvider(domainObject))
|
||||
|| Boolean(this.findRequestProvider(domainObject));
|
||||
};
|
||||
|
||||
/**
|
||||
@ -187,12 +187,15 @@ define([
|
||||
if (provider.supportsRequest) {
|
||||
this.requestProviders.unshift(provider);
|
||||
}
|
||||
|
||||
if (provider.supportsSubscribe) {
|
||||
this.subscriptionProviders.unshift(provider);
|
||||
}
|
||||
|
||||
if (provider.supportsMetadata) {
|
||||
this.metadataProviders.unshift(provider);
|
||||
}
|
||||
|
||||
if (provider.supportsLimits) {
|
||||
this.limitProviders.unshift(provider);
|
||||
}
|
||||
@ -247,9 +250,11 @@ define([
|
||||
if (!options.hasOwnProperty('start')) {
|
||||
options.start = this.openmct.time.bounds().start;
|
||||
}
|
||||
|
||||
if (!options.hasOwnProperty('end')) {
|
||||
options.end = this.openmct.time.bounds().end;
|
||||
}
|
||||
|
||||
if (!options.hasOwnProperty('domain')) {
|
||||
options.domain = this.openmct.time.timeSystem().key;
|
||||
}
|
||||
@ -275,14 +280,17 @@ define([
|
||||
arguments.length = 2;
|
||||
arguments[1] = {};
|
||||
}
|
||||
|
||||
this.standardizeRequestOptions(arguments[1]);
|
||||
var provider = this.findRequestProvider.apply(this, arguments);
|
||||
if (!provider) {
|
||||
return Promise.reject('No provider found');
|
||||
}
|
||||
|
||||
return provider.request.apply(provider, arguments).catch((rejected) => {
|
||||
this.openmct.notifications.error('Error requesting telemetry data, see console for details');
|
||||
console.error(rejected);
|
||||
|
||||
return Promise.reject(rejected);
|
||||
});
|
||||
};
|
||||
@ -307,6 +315,7 @@ define([
|
||||
if (!this.subscribeCache) {
|
||||
this.subscribeCache = {};
|
||||
}
|
||||
|
||||
var keyString = objectUtils.makeKeyString(domainObject.identifier);
|
||||
var subscriber = this.subscribeCache[keyString];
|
||||
|
||||
@ -352,6 +361,7 @@ define([
|
||||
if (!metadataProvider) {
|
||||
return;
|
||||
}
|
||||
|
||||
var metadata = metadataProvider.getMetadata(domainObject);
|
||||
|
||||
this.metadataCache.set(
|
||||
@ -359,6 +369,7 @@ define([
|
||||
new TelemetryMetadataManager(metadata)
|
||||
);
|
||||
}
|
||||
|
||||
return this.metadataCache.get(domainObject);
|
||||
};
|
||||
|
||||
@ -370,6 +381,7 @@ define([
|
||||
TelemetryAPI.prototype.commonValuesForHints = function (metadatas, hints) {
|
||||
var options = metadatas.map(function (metadata) {
|
||||
var values = metadata.valuesForHints(hints);
|
||||
|
||||
return _.keyBy(values, 'key');
|
||||
}).reduce(function (a, b) {
|
||||
var results = {};
|
||||
@ -378,11 +390,13 @@ define([
|
||||
results[key] = a[key];
|
||||
}
|
||||
});
|
||||
|
||||
return results;
|
||||
});
|
||||
var sortKeys = hints.map(function (h) {
|
||||
return 'hints.' + h;
|
||||
});
|
||||
|
||||
return _.sortBy(options, sortKeys);
|
||||
};
|
||||
|
||||
@ -396,11 +410,13 @@ define([
|
||||
if (!this.formatService) {
|
||||
this.formatService = this.openmct.$injector.get('formatService');
|
||||
}
|
||||
|
||||
this.valueFormatterCache.set(
|
||||
valueMetadata,
|
||||
new TelemetryValueFormatter(valueMetadata, this.formatService)
|
||||
);
|
||||
}
|
||||
|
||||
return this.valueFormatterCache.get(valueMetadata);
|
||||
};
|
||||
|
||||
@ -414,10 +430,12 @@ define([
|
||||
if (!this.formatMapCache.has(metadata)) {
|
||||
var formatMap = metadata.values().reduce(function (map, valueMetadata) {
|
||||
map[valueMetadata.key] = this.getValueFormatter(valueMetadata);
|
||||
|
||||
return map;
|
||||
}.bind(this), {});
|
||||
this.formatMapCache.set(metadata, formatMap);
|
||||
}
|
||||
|
||||
return this.formatMapCache.get(metadata);
|
||||
};
|
||||
|
||||
@ -477,6 +495,7 @@ define([
|
||||
evaluate: function () {}
|
||||
};
|
||||
}
|
||||
|
||||
return provider.getLimitEvaluator(domainObject);
|
||||
};
|
||||
|
||||
|
@ -45,7 +45,10 @@ define([
|
||||
]);
|
||||
openmct.$injector.get.and.returnValue(mockTypeService);
|
||||
openmct.time.timeSystem.and.returnValue({key: 'system'});
|
||||
openmct.time.bounds.and.returnValue({start: 0, end: 1});
|
||||
openmct.time.bounds.and.returnValue({
|
||||
start: 0,
|
||||
end: 1
|
||||
});
|
||||
telemetryAPI = new TelemetryAPI(openmct);
|
||||
|
||||
});
|
||||
@ -203,6 +206,7 @@ define([
|
||||
var unsubFunc = jasmine.createSpy('unsubscribe ' + unsubFuncs.length);
|
||||
unsubFuncs.push(unsubFunc);
|
||||
notifiers.push(cb);
|
||||
|
||||
return unsubFunc;
|
||||
});
|
||||
telemetryAPI.addProvider(telemetryProvider);
|
||||
@ -343,7 +347,7 @@ define([
|
||||
}
|
||||
});
|
||||
mockTypeService.getType.and.returnValue(mockObjectType);
|
||||
})
|
||||
});
|
||||
it('respects explicit priority', function () {
|
||||
mockMetadata.values = [
|
||||
{
|
||||
@ -554,6 +558,6 @@ define([
|
||||
expect(values[index].key).toBe(key);
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -33,25 +33,27 @@ define([
|
||||
|
||||
if (valueMetadata.hints.hasOwnProperty('x')) {
|
||||
console.warn(
|
||||
'DEPRECATION WARNING: `x` hints should be replaced with ' +
|
||||
'`domain` hints moving forward. ' +
|
||||
'https://github.com/nasa/openmct/issues/1546'
|
||||
'DEPRECATION WARNING: `x` hints should be replaced with '
|
||||
+ '`domain` hints moving forward. '
|
||||
+ 'https://github.com/nasa/openmct/issues/1546'
|
||||
);
|
||||
if (!valueMetadata.hints.hasOwnProperty('domain')) {
|
||||
valueMetadata.hints.domain = valueMetadata.hints.x;
|
||||
}
|
||||
|
||||
delete valueMetadata.hints.x;
|
||||
}
|
||||
|
||||
if (valueMetadata.hints.hasOwnProperty('y')) {
|
||||
console.warn(
|
||||
'DEPRECATION WARNING: `y` hints should be replaced with ' +
|
||||
'`range` hints moving forward. ' +
|
||||
'https://github.com/nasa/openmct/issues/1546'
|
||||
'DEPRECATION WARNING: `y` hints should be replaced with '
|
||||
+ '`range` hints moving forward. '
|
||||
+ 'https://github.com/nasa/openmct/issues/1546'
|
||||
);
|
||||
if (!valueMetadata.hints.hasOwnProperty('range')) {
|
||||
valueMetadata.hints.range = valueMetadata.hints.y;
|
||||
}
|
||||
|
||||
delete valueMetadata.hints.y;
|
||||
}
|
||||
|
||||
@ -59,9 +61,11 @@ define([
|
||||
if (!valueMetadata.values) {
|
||||
valueMetadata.values = valueMetadata.enumerations.map(e => e.value);
|
||||
}
|
||||
|
||||
if (!valueMetadata.hasOwnProperty('max')) {
|
||||
valueMetadata.max = Math.max(valueMetadata.values) + 1;
|
||||
}
|
||||
|
||||
if (!valueMetadata.hasOwnProperty('min')) {
|
||||
valueMetadata.min = Math.min(valueMetadata.values) - 1;
|
||||
}
|
||||
@ -70,6 +74,7 @@ define([
|
||||
if (!valueMetadata.hints.hasOwnProperty('priority')) {
|
||||
valueMetadata.hints.priority = index;
|
||||
}
|
||||
|
||||
return valueMetadata;
|
||||
}
|
||||
|
||||
@ -112,21 +117,24 @@ define([
|
||||
/*jshint validthis: true */
|
||||
return this.hints.hasOwnProperty(hint);
|
||||
}
|
||||
|
||||
function hasHints(metadata) {
|
||||
return hints.every(hasHint, metadata);
|
||||
}
|
||||
|
||||
var matchingMetadata = this.valueMetadatas.filter(hasHints);
|
||||
let iteratees = hints.map(hint => {
|
||||
return (metadata) => {
|
||||
return metadata.hints[hint];
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
return _.sortBy(matchingMetadata, ...iteratees);
|
||||
};
|
||||
|
||||
TelemetryMetadataManager.prototype.getFilterableValues = function () {
|
||||
return this.valueMetadatas.filter(metadatum => metadatum.filters && metadatum.filters.length > 0);
|
||||
}
|
||||
};
|
||||
|
||||
TelemetryMetadataManager.prototype.getDefaultDisplayValue = function () {
|
||||
let valueMetadata = this.valuesForHints(['range'])[0];
|
||||
@ -144,7 +152,6 @@ define([
|
||||
return valueMetadata.key;
|
||||
};
|
||||
|
||||
|
||||
return TelemetryMetadataManager;
|
||||
|
||||
});
|
||||
|
@ -56,12 +56,17 @@ define([
|
||||
this.enumerations = valueMetadata.enumerations.reduce(function (vm, e) {
|
||||
vm.byValue[e.value] = e.string;
|
||||
vm.byString[e.string] = e.value;
|
||||
|
||||
return vm;
|
||||
}, {byValue: {}, byString: {}});
|
||||
}, {
|
||||
byValue: {},
|
||||
byString: {}
|
||||
});
|
||||
this.formatter.format = function (value) {
|
||||
if (this.enumerations.byValue.hasOwnProperty(value)) {
|
||||
return this.enumerations.byValue[value];
|
||||
}
|
||||
|
||||
return value;
|
||||
}.bind(this);
|
||||
this.formatter.parse = function (string) {
|
||||
@ -70,9 +75,11 @@ define([
|
||||
return this.enumerations.byString[string];
|
||||
}
|
||||
}
|
||||
|
||||
return Number(string);
|
||||
}.bind(this);
|
||||
}
|
||||
|
||||
// Check for formatString support once instead of per format call.
|
||||
if (valueMetadata.formatString) {
|
||||
var baseFormat = this.formatter.format;
|
||||
@ -81,20 +88,24 @@ define([
|
||||
return printj.sprintf(formatString, baseFormat.call(this, value));
|
||||
};
|
||||
}
|
||||
|
||||
if (valueMetadata.format === 'string') {
|
||||
this.formatter.parse = function (value) {
|
||||
if (value === undefined) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
return value;
|
||||
} else {
|
||||
return value.toString();
|
||||
}
|
||||
};
|
||||
|
||||
this.formatter.format = function (value) {
|
||||
return value;
|
||||
};
|
||||
|
||||
this.formatter.validate = function (value) {
|
||||
return typeof value === 'string';
|
||||
};
|
||||
@ -105,6 +116,7 @@ define([
|
||||
if (_.isObject(datum)) {
|
||||
return this.formatter.parse(datum[this.valueMetadata.source]);
|
||||
}
|
||||
|
||||
return this.formatter.parse(datum);
|
||||
};
|
||||
|
||||
@ -112,6 +124,7 @@ define([
|
||||
if (_.isObject(datum)) {
|
||||
return this.formatter.format(datum[this.valueMetadata.source]);
|
||||
}
|
||||
|
||||
return this.formatter.format(datum);
|
||||
};
|
||||
|
||||
|
@ -148,15 +148,16 @@ define(['EventEmitter'], function (EventEmitter) {
|
||||
* @method validateBounds
|
||||
*/
|
||||
TimeAPI.prototype.validateBounds = function (bounds) {
|
||||
if ((bounds.start === undefined) ||
|
||||
(bounds.end === undefined) ||
|
||||
isNaN(bounds.start) ||
|
||||
isNaN(bounds.end)
|
||||
if ((bounds.start === undefined)
|
||||
|| (bounds.end === undefined)
|
||||
|| isNaN(bounds.start)
|
||||
|| isNaN(bounds.end)
|
||||
) {
|
||||
return "Start and end must be specified as integer values";
|
||||
} else if (bounds.start > bounds.end) {
|
||||
return "Specified start date exceeds end bound";
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
@ -169,15 +170,16 @@ define(['EventEmitter'], function (EventEmitter) {
|
||||
* @method validateBounds
|
||||
*/
|
||||
TimeAPI.prototype.validateOffsets = function (offsets) {
|
||||
if ((offsets.start === undefined) ||
|
||||
(offsets.end === undefined) ||
|
||||
isNaN(offsets.start) ||
|
||||
isNaN(offsets.end)
|
||||
if ((offsets.start === undefined)
|
||||
|| (offsets.end === undefined)
|
||||
|| isNaN(offsets.start)
|
||||
|| isNaN(offsets.end)
|
||||
) {
|
||||
return "Start and end offsets must be specified as integer values";
|
||||
} else if (offsets.start >= offsets.end) {
|
||||
return "Specified start offset must be < end offset";
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
@ -207,6 +209,7 @@ define(['EventEmitter'], function (EventEmitter) {
|
||||
if (validationResult !== true) {
|
||||
throw new Error(validationResult);
|
||||
}
|
||||
|
||||
//Create a copy to avoid direct mutation of conductor bounds
|
||||
this.boundsVal = JSON.parse(JSON.stringify(newBounds));
|
||||
/**
|
||||
@ -225,6 +228,7 @@ define(['EventEmitter'], function (EventEmitter) {
|
||||
this.timeOfInterest(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
//Return a copy to prevent direct mutation of time conductor bounds.
|
||||
return JSON.parse(JSON.stringify(this.boundsVal));
|
||||
};
|
||||
@ -242,10 +246,11 @@ define(['EventEmitter'], function (EventEmitter) {
|
||||
if (arguments.length >= 1) {
|
||||
if (arguments.length === 1 && !this.activeClock) {
|
||||
throw new Error(
|
||||
"Must specify bounds when changing time system without " +
|
||||
"an active clock."
|
||||
"Must specify bounds when changing time system without "
|
||||
+ "an active clock."
|
||||
);
|
||||
}
|
||||
|
||||
var timeSystem;
|
||||
|
||||
if (timeSystemOrKey === undefined) {
|
||||
@ -312,6 +317,7 @@ define(['EventEmitter'], function (EventEmitter) {
|
||||
*/
|
||||
this.emit('timeOfInterest', this.toi);
|
||||
}
|
||||
|
||||
return this.toi;
|
||||
};
|
||||
|
||||
@ -440,6 +446,7 @@ define(['EventEmitter'], function (EventEmitter) {
|
||||
*/
|
||||
this.emit("clockOffsets", offsets);
|
||||
}
|
||||
|
||||
return this.offsets;
|
||||
};
|
||||
|
||||
|
@ -43,7 +43,10 @@ define(['./TimeAPI'], function (TimeAPI) {
|
||||
]);
|
||||
clock.currentValue.and.returnValue(100);
|
||||
clock.key = clockKey;
|
||||
bounds = {start: 0, end: 1};
|
||||
bounds = {
|
||||
start: 0,
|
||||
end: 1
|
||||
};
|
||||
eventListener = jasmine.createSpy("eventListener");
|
||||
toi = 111;
|
||||
});
|
||||
@ -55,14 +58,20 @@ define(['./TimeAPI'], function (TimeAPI) {
|
||||
});
|
||||
|
||||
it("Allows setting of valid bounds", function () {
|
||||
bounds = {start: 0, end: 1};
|
||||
bounds = {
|
||||
start: 0,
|
||||
end: 1
|
||||
};
|
||||
expect(api.bounds()).not.toBe(bounds);
|
||||
expect(api.bounds.bind(api, bounds)).not.toThrow();
|
||||
expect(api.bounds()).toEqual(bounds);
|
||||
});
|
||||
|
||||
it("Disallows setting of invalid bounds", function () {
|
||||
bounds = {start: 1, end: 0};
|
||||
bounds = {
|
||||
start: 1,
|
||||
end: 0
|
||||
};
|
||||
expect(api.bounds()).not.toEqual(bounds);
|
||||
expect(api.bounds.bind(api, bounds)).toThrow();
|
||||
expect(api.bounds()).not.toEqual(bounds);
|
||||
@ -94,7 +103,10 @@ define(['./TimeAPI'], function (TimeAPI) {
|
||||
it("allows setting of timesystem without bounds with clock", function () {
|
||||
api.addTimeSystem(timeSystem);
|
||||
api.addClock(clock);
|
||||
api.clock(clockKey, {start: 0, end: 1});
|
||||
api.clock(clockKey, {
|
||||
start: 0,
|
||||
end: 1
|
||||
});
|
||||
expect(api.timeSystem()).not.toBe(timeSystem);
|
||||
expect(function () {
|
||||
api.timeSystem(timeSystemKey);
|
||||
@ -127,20 +139,25 @@ define(['./TimeAPI'], function (TimeAPI) {
|
||||
|
||||
it("If bounds are set and TOI lies inside them, do not change TOI", function () {
|
||||
api.timeOfInterest(6);
|
||||
api.bounds({start: 1, end: 10});
|
||||
api.bounds({
|
||||
start: 1,
|
||||
end: 10
|
||||
});
|
||||
expect(api.timeOfInterest()).toEqual(6);
|
||||
});
|
||||
|
||||
it("If bounds are set and TOI lies outside them, reset TOI", function () {
|
||||
api.timeOfInterest(11);
|
||||
api.bounds({start: 1, end: 10});
|
||||
api.bounds({
|
||||
start: 1,
|
||||
end: 10
|
||||
});
|
||||
expect(api.timeOfInterest()).toBeUndefined();
|
||||
});
|
||||
|
||||
it("Maintains delta during tick", function () {
|
||||
});
|
||||
|
||||
|
||||
it("Allows registered time system to be activated", function () {
|
||||
});
|
||||
|
||||
@ -184,7 +201,10 @@ define(['./TimeAPI'], function (TimeAPI) {
|
||||
|
||||
it("sets bounds based on current value", function () {
|
||||
api.clock("mts", mockOffsets);
|
||||
expect(api.bounds()).toEqual({start: 10, end: 11});
|
||||
expect(api.bounds()).toEqual({
|
||||
start: 10,
|
||||
end: 11
|
||||
});
|
||||
});
|
||||
|
||||
it("a new tick listener is registered", function () {
|
||||
|
@ -87,7 +87,7 @@ define(function () {
|
||||
for (let [k, v] of Object.entries(legacyDefinition.model)) {
|
||||
model[k] = JSON.parse(JSON.stringify(v));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (legacyDefinition.features && legacyDefinition.features.includes("creation")) {
|
||||
|
@ -65,14 +65,15 @@ define(['./Type'], function (Type) {
|
||||
TypeRegistry.prototype.standardizeType = function (typeDef) {
|
||||
if (typeDef.hasOwnProperty('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');
|
||||
'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) {
|
||||
typeDef.name = typeDef.label;
|
||||
}
|
||||
|
||||
delete typeDef.label;
|
||||
}
|
||||
};
|
||||
@ -104,9 +105,8 @@ define(['./Type'], function (Type) {
|
||||
let def = Type.definitionFromLegacyDefinition(type);
|
||||
this.addType(type.key, def);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return TypeRegistry;
|
||||
});
|
||||
|
||||
|
||||
|
@ -25,8 +25,8 @@ import {saveAs} from 'file-saver/FileSaver';
|
||||
|
||||
class CSVExporter {
|
||||
export(rows, options) {
|
||||
let headers = (options && options.headers) ||
|
||||
(Object.keys((rows[0] || {})).sort());
|
||||
let headers = (options && options.headers)
|
||||
|| (Object.keys((rows[0] || {})).sort());
|
||||
let filename = (options && options.filename) || "export.csv";
|
||||
let csvText = new CSV(rows, { header: headers }).encode();
|
||||
let blob = new Blob([csvText], { type: "text/csv" });
|
||||
|
@ -22,11 +22,12 @@
|
||||
|
||||
export default function ladTableCompositionPolicy(openmct) {
|
||||
return function (parent, child) {
|
||||
if(parent.type === 'LadTable') {
|
||||
if (parent.type === 'LadTable') {
|
||||
return openmct.telemetry.isTelemetryObject(child);
|
||||
} else if(parent.type === 'LadTableSet') {
|
||||
} else if (parent.type === 'LadTableSet') {
|
||||
return child.type === 'LadTable';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ export default function LADTableSetViewProvider(openmct) {
|
||||
|
||||
return {
|
||||
show: function (element) {
|
||||
component = new Vue({
|
||||
component = new Vue({
|
||||
el: element,
|
||||
components: {
|
||||
LadTableSet: LadTableSet
|
||||
|
@ -38,7 +38,7 @@ export default function LADTableViewProvider(openmct) {
|
||||
|
||||
return {
|
||||
show: function (element) {
|
||||
component = new Vue({
|
||||
component = new Vue({
|
||||
el: element,
|
||||
components: {
|
||||
LadTableComponent: LadTable
|
||||
|
@ -32,6 +32,12 @@
|
||||
class="js-third-data"
|
||||
:class="valueClass"
|
||||
>{{ value }}</td>
|
||||
<td
|
||||
v-if="hasUnits"
|
||||
class="js-units"
|
||||
>
|
||||
{{ unit }}
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
@ -48,6 +54,10 @@ export default {
|
||||
domainObject: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
hasUnits: {
|
||||
type: Boolean,
|
||||
requred: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@ -59,8 +69,9 @@ export default {
|
||||
timestamp: undefined,
|
||||
value: '---',
|
||||
valueClass: '',
|
||||
currentObjectPath
|
||||
}
|
||||
currentObjectPath,
|
||||
unit: ''
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
formattedTimestamp() {
|
||||
@ -94,13 +105,17 @@ export default {
|
||||
.metadata
|
||||
.valuesForHints(['range'])[0];
|
||||
|
||||
this.valueKey = this.valueMetadata.key
|
||||
this.valueKey = this.valueMetadata.key;
|
||||
|
||||
this.unsubscribe = this.openmct
|
||||
.telemetry
|
||||
.subscribe(this.domainObject, this.updateValues);
|
||||
|
||||
this.requestHistory();
|
||||
|
||||
if (this.hasUnits) {
|
||||
this.setUnit();
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
this.stopWatchingMutation();
|
||||
@ -113,7 +128,7 @@ export default {
|
||||
let newTimestamp = this.getParsedTimestamp(datum),
|
||||
limit;
|
||||
|
||||
if(this.shouldUpdate(newTimestamp)) {
|
||||
if (this.shouldUpdate(newTimestamp)) {
|
||||
this.timestamp = newTimestamp;
|
||||
this.value = this.formats[this.valueKey].format(datum);
|
||||
limit = this.limitEvaluator.evaluate(datum, this.valueMetadata);
|
||||
@ -129,8 +144,8 @@ export default {
|
||||
noExistingTimestamp = this.timestamp === undefined,
|
||||
newTimestampIsLatest = newTimestamp > this.timestamp;
|
||||
|
||||
return newTimestampInBounds &&
|
||||
(noExistingTimestamp || newTimestampIsLatest);
|
||||
return newTimestampInBounds
|
||||
&& (noExistingTimestamp || newTimestampIsLatest);
|
||||
},
|
||||
requestHistory() {
|
||||
this.openmct
|
||||
@ -148,7 +163,7 @@ export default {
|
||||
},
|
||||
updateBounds(bounds, isTick) {
|
||||
this.bounds = bounds;
|
||||
if(!isTick) {
|
||||
if (!isTick) {
|
||||
this.resetValues();
|
||||
this.requestHistory();
|
||||
}
|
||||
@ -169,24 +184,28 @@ export default {
|
||||
this.valueClass = '';
|
||||
},
|
||||
getParsedTimestamp(timestamp) {
|
||||
if(this.timeSystemFormat()) {
|
||||
if (this.timeSystemFormat()) {
|
||||
return this.formats[this.timestampKey].parse(timestamp);
|
||||
}
|
||||
},
|
||||
getFormattedTimestamp(timestamp) {
|
||||
if(this.timeSystemFormat()) {
|
||||
if (this.timeSystemFormat()) {
|
||||
return this.formats[this.timestampKey].format(timestamp);
|
||||
}
|
||||
},
|
||||
timeSystemFormat() {
|
||||
if(this.formats[this.timestampKey]) {
|
||||
if (this.formats[this.timestampKey]) {
|
||||
return true;
|
||||
} else {
|
||||
console.warn(`No formatter for ${this.timestampKey} time system for ${this.domainObject.name}.`);
|
||||
|
||||
return false;
|
||||
}
|
||||
},
|
||||
setUnit() {
|
||||
this.unit = this.valueMetadata.unit || '';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
<th>Name</th>
|
||||
<th>Timestamp</th>
|
||||
<th>Value</th>
|
||||
<th v-if="hasUnits">Unit</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -35,6 +36,7 @@
|
||||
v-for="item in items"
|
||||
:key="item.key"
|
||||
:domain-object="item.domainObject"
|
||||
:has-units="hasUnits"
|
||||
/>
|
||||
</tbody>
|
||||
</table>
|
||||
@ -52,6 +54,18 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
items: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
hasUnits() {
|
||||
let itemsWithUnits = this.items.filter((item) => {
|
||||
let metadata = this.openmct.telemetry.getMetadata(item.domainObject);
|
||||
|
||||
return this.metadataHasUnits(metadata.valueMetadatas);
|
||||
|
||||
});
|
||||
|
||||
return itemsWithUnits.length !== 0;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@ -84,7 +98,12 @@ export default {
|
||||
reorderPlan.forEach((reorderEvent) => {
|
||||
this.$set(this.items, reorderEvent.newIndex, oldItems[reorderEvent.oldIndex]);
|
||||
});
|
||||
},
|
||||
metadataHasUnits(valueMetadatas) {
|
||||
let metadataWithUnits = valueMetadatas.filter(metadatum => metadatum.unit);
|
||||
|
||||
return metadataWithUnits.length > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -27,6 +27,7 @@
|
||||
<th>Name</th>
|
||||
<th>Timestamp</th>
|
||||
<th>Value</th>
|
||||
<th v-if="hasUnits">Unit</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -45,6 +46,7 @@
|
||||
v-for="secondary in secondaryTelemetryObjects[primary.key]"
|
||||
:key="secondary.key"
|
||||
:domain-object="secondary.domainObject"
|
||||
:has-units="hasUnits"
|
||||
/>
|
||||
</template>
|
||||
</tbody>
|
||||
@ -64,6 +66,23 @@ export default {
|
||||
primaryTelemetryObjects: [],
|
||||
secondaryTelemetryObjects: {},
|
||||
compositions: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
hasUnits() {
|
||||
let ladTables = Object.values(this.secondaryTelemetryObjects);
|
||||
for (let ladTable of ladTables) {
|
||||
for (let telemetryObject of ladTable) {
|
||||
let metadata = this.openmct.telemetry.getMetadata(telemetryObject.domainObject);
|
||||
for (let metadatum of metadata.valueMetadatas) {
|
||||
if (metadatum.unit) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@ -99,15 +118,18 @@ export default {
|
||||
composition.on('remove', removeCallback);
|
||||
composition.load();
|
||||
|
||||
this.compositions.push({composition, addCallback, removeCallback});
|
||||
this.compositions.push({
|
||||
composition,
|
||||
addCallback,
|
||||
removeCallback
|
||||
});
|
||||
},
|
||||
removePrimary(identifier) {
|
||||
let index = this.primaryTelemetryObjects.findIndex(primary => this.openmct.objects.makeKeyString(identifier) === primary.key),
|
||||
primary = this.primaryTelemetryObjects[index];
|
||||
|
||||
this.$set(this.secondaryTelemetryObjects, primary.key, undefined);
|
||||
this.primaryTelemetryObjects.splice(index,1);
|
||||
primary = undefined;
|
||||
this.$delete(this.secondaryTelemetryObjects, primary.key);
|
||||
this.primaryTelemetryObjects.splice(index, 1);
|
||||
},
|
||||
reorderPrimary(reorderPlan) {
|
||||
let oldComposition = this.primaryTelemetryObjects.slice();
|
||||
@ -125,7 +147,7 @@ export default {
|
||||
array.push(secondary);
|
||||
|
||||
this.$set(this.secondaryTelemetryObjects, primary.key, array);
|
||||
}
|
||||
};
|
||||
},
|
||||
removeSecondary(primary) {
|
||||
return (identifier) => {
|
||||
@ -135,8 +157,8 @@ export default {
|
||||
array.splice(index, 1);
|
||||
|
||||
this.$set(this.secondaryTelemetryObjects, primary.key, array);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -37,7 +37,7 @@ const TABLE_BODY_FIRST_ROW_THIRD_DATA = TABLE_BODY_FIRST_ROW + ' .js-third-data'
|
||||
const LAD_SET_TABLE_HEADERS = '.js-lad-table-set__table-headers';
|
||||
|
||||
function utcTimeFormat(value) {
|
||||
return new Date(value).toISOString().replace('T', ' ')
|
||||
return new Date(value).toISOString().replace('T', ' ');
|
||||
}
|
||||
|
||||
describe("The LAD Table", () => {
|
||||
@ -49,7 +49,10 @@ describe("The LAD Table", () => {
|
||||
child,
|
||||
telemetryCount = 3,
|
||||
timeFormat = 'utc',
|
||||
mockTelemetry = getMockTelemetry({ count: telemetryCount, format: timeFormat }),
|
||||
mockTelemetry = getMockTelemetry({
|
||||
count: telemetryCount,
|
||||
format: timeFormat
|
||||
}),
|
||||
mockObj = getMockObjects({
|
||||
objectKeyStrings: ['ladTable', 'telemetry'],
|
||||
format: timeFormat
|
||||
@ -81,7 +84,10 @@ describe("The LAD Table", () => {
|
||||
|
||||
spyOn(openmct.objects, 'get').and.returnValue(Promise.resolve({}));
|
||||
|
||||
openmct.time.bounds({ start: bounds.start, end: bounds.end });
|
||||
openmct.time.bounds({
|
||||
start: bounds.start,
|
||||
end: bounds.end
|
||||
});
|
||||
|
||||
openmct.on('start', done);
|
||||
openmct.startHeadless(appHolder);
|
||||
@ -116,7 +122,7 @@ describe("The LAD Table", () => {
|
||||
});
|
||||
|
||||
it("should reject non-telemtry producing objects", () => {
|
||||
expect(()=> {
|
||||
expect(() => {
|
||||
ladTableCompositionCollection.add(mockObj.ladTable);
|
||||
}).toThrow();
|
||||
});
|
||||
@ -131,7 +137,10 @@ describe("The LAD Table", () => {
|
||||
overwrite: {
|
||||
telemetry: {
|
||||
name: "New Telemetry Object",
|
||||
identifier: { namespace: "", key: "another-telemetry-object" }
|
||||
identifier: {
|
||||
namespace: "",
|
||||
key: "another-telemetry-object"
|
||||
}
|
||||
}
|
||||
}
|
||||
}).telemetry;
|
||||
@ -151,22 +160,28 @@ describe("The LAD Table", () => {
|
||||
}),
|
||||
anotherTelemetryObjectPromise = new Promise((resolve) => {
|
||||
anotherTelemetryObjectResolve = resolve;
|
||||
})
|
||||
});
|
||||
openmct.telemetry.request.and.callFake(() => {
|
||||
telemetryRequestResolve(mockTelemetry);
|
||||
|
||||
return telemetryRequestPromise;
|
||||
});
|
||||
openmct.objects.get.and.callFake((obj) => {
|
||||
if(obj.key === 'telemetry-object') {
|
||||
if (obj.key === 'telemetry-object') {
|
||||
telemetryObjectResolve(mockObj.telemetry);
|
||||
|
||||
return telemetryObjectPromise;
|
||||
} else {
|
||||
anotherTelemetryObjectResolve(anotherTelemetryObj);
|
||||
|
||||
return anotherTelemetryObjectPromise;
|
||||
}
|
||||
});
|
||||
|
||||
openmct.time.bounds({ start: bounds.start, end: bounds.end });
|
||||
openmct.time.bounds({
|
||||
start: bounds.start,
|
||||
end: bounds.end
|
||||
});
|
||||
|
||||
applicableViews = openmct.objectViews.get(mockObj.ladTable);
|
||||
ladTableViewProvider = applicableViews.find((viewProvider) => viewProvider.key === ladTableKey);
|
||||
@ -175,6 +190,7 @@ describe("The LAD Table", () => {
|
||||
|
||||
await Promise.all([telemetryRequestPromise, telemetryObjectPromise, anotherTelemetryObjectPromise]);
|
||||
await Vue.nextTick();
|
||||
|
||||
return;
|
||||
});
|
||||
|
||||
@ -225,7 +241,10 @@ describe("The LAD Table Set", () => {
|
||||
child,
|
||||
telemetryCount = 3,
|
||||
timeFormat = 'utc',
|
||||
mockTelemetry = getMockTelemetry({ count: telemetryCount, format: timeFormat }),
|
||||
mockTelemetry = getMockTelemetry({
|
||||
count: telemetryCount,
|
||||
format: timeFormat
|
||||
}),
|
||||
mockObj = getMockObjects({
|
||||
objectKeyStrings: ['ladTable', 'ladTableSet', 'telemetry']
|
||||
}),
|
||||
@ -255,7 +274,10 @@ describe("The LAD Table Set", () => {
|
||||
|
||||
spyOn(openmct.objects, 'get').and.returnValue(Promise.resolve({}));
|
||||
|
||||
openmct.time.bounds({ start: bounds.start, end: bounds.end });
|
||||
openmct.time.bounds({
|
||||
start: bounds.start,
|
||||
end: bounds.end
|
||||
});
|
||||
|
||||
openmct.on('start', done);
|
||||
openmct.start(appHolder);
|
||||
@ -290,7 +312,7 @@ describe("The LAD Table Set", () => {
|
||||
});
|
||||
|
||||
it("should reject non lad table objects", () => {
|
||||
expect(()=> {
|
||||
expect(() => {
|
||||
ladTableSetCompositionCollection.add(mockObj.telemetry);
|
||||
}).toThrow();
|
||||
});
|
||||
@ -305,7 +327,10 @@ describe("The LAD Table Set", () => {
|
||||
overwrite: {
|
||||
ladTable: {
|
||||
name: "New LAD Table Object",
|
||||
identifier: { namespace: "", key: "another-lad-object" }
|
||||
identifier: {
|
||||
namespace: "",
|
||||
key: "another-lad-object"
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -326,24 +351,30 @@ describe("The LAD Table Set", () => {
|
||||
}),
|
||||
anotherLadObjectPromise = new Promise((resolve) => {
|
||||
anotherLadObjectResolve = resolve;
|
||||
})
|
||||
});
|
||||
openmct.telemetry.request.and.callFake(() => {
|
||||
telemetryRequestResolve(mockTelemetry);
|
||||
|
||||
return telemetryRequestPromise;
|
||||
});
|
||||
openmct.objects.get.and.callFake((obj) => {
|
||||
if(obj.key === 'lad-object') {
|
||||
if (obj.key === 'lad-object') {
|
||||
ladObjectResolve(mockObj.ladObject);
|
||||
|
||||
return ladObjectPromise;
|
||||
} else if(obj.key === 'another-lad-object') {
|
||||
} else if (obj.key === 'another-lad-object') {
|
||||
anotherLadObjectResolve(otherObj.ladObject);
|
||||
|
||||
return anotherLadObjectPromise;
|
||||
}
|
||||
|
||||
return Promise.resolve({});
|
||||
});
|
||||
|
||||
openmct.time.bounds({ start: bounds.start, end: bounds.end });
|
||||
openmct.time.bounds({
|
||||
start: bounds.start,
|
||||
end: bounds.end
|
||||
});
|
||||
|
||||
applicableViews = openmct.objectViews.get(mockObj.ladTableSet);
|
||||
ladTableSetViewProvider = applicableViews.find((viewProvider) => viewProvider.key === ladTableSetKey);
|
||||
@ -352,6 +383,7 @@ describe("The LAD Table Set", () => {
|
||||
|
||||
await Promise.all([telemetryRequestPromise, ladObjectPromise, anotherLadObjectPromise]);
|
||||
await Vue.nextTick();
|
||||
|
||||
return;
|
||||
});
|
||||
|
||||
|
@ -57,11 +57,13 @@ define(
|
||||
this.indicator.description(this.label + " is online, checking status every " + this.interval + " milliseconds.");
|
||||
break;
|
||||
}
|
||||
|
||||
case PENDING: {
|
||||
this.indicator.text("Checking status of " + this.label + " please stand by...");
|
||||
this.indicator.description("Checking status of " + this.label + " please stand by...");
|
||||
break;
|
||||
}
|
||||
|
||||
case DISCONNECTED: {
|
||||
this.indicator.text(this.label + " is offline");
|
||||
this.indicator.description(this.label + " is offline, checking status every " + this.interval + " milliseconds");
|
||||
|
@ -122,18 +122,20 @@ export default class URLTimeSettingsSynchronizer {
|
||||
} else if (!this.areStartAndEndEqual(this.openmct.time.bounds(), timeParameters.bounds)) {
|
||||
this.openmct.time.bounds(timeParameters.bounds);
|
||||
}
|
||||
|
||||
if (this.openmct.time.clock()) {
|
||||
this.openmct.time.stopClock();
|
||||
}
|
||||
} else {
|
||||
if (!this.openmct.time.clock() ||
|
||||
this.openmct.time.clock().key !== timeParameters.mode) {
|
||||
if (!this.openmct.time.clock()
|
||||
|| this.openmct.time.clock().key !== timeParameters.mode) {
|
||||
this.openmct.time.clock(timeParameters.mode, timeParameters.clockOffsets);
|
||||
} else if (!this.areStartAndEndEqual(this.openmct.time.clockOffsets(), timeParameters.clockOffsets)) {
|
||||
this.openmct.time.clockOffsets(timeParameters.clockOffsets);
|
||||
}
|
||||
if (!this.openmct.time.timeSystem() ||
|
||||
this.openmct.time.timeSystem().key !== timeParameters.timeSystem) {
|
||||
|
||||
if (!this.openmct.time.timeSystem()
|
||||
|| this.openmct.time.timeSystem().key !== timeParameters.timeSystem) {
|
||||
this.openmct.time.timeSystem(timeParameters.timeSystem);
|
||||
}
|
||||
}
|
||||
@ -168,6 +170,7 @@ export default class URLTimeSettingsSynchronizer {
|
||||
searchParams.delete(SEARCH_START_DELTA);
|
||||
searchParams.delete(SEARCH_END_DELTA);
|
||||
}
|
||||
|
||||
searchParams.delete(SEARCH_START_BOUND);
|
||||
searchParams.delete(SEARCH_END_BOUND);
|
||||
}
|
||||
@ -180,8 +183,8 @@ export default class URLTimeSettingsSynchronizer {
|
||||
areTimeParametersValid(timeParameters) {
|
||||
let isValid = false;
|
||||
|
||||
if (this.isModeValid(timeParameters.mode) &&
|
||||
this.isTimeSystemValid(timeParameters.timeSystem)) {
|
||||
if (this.isModeValid(timeParameters.mode)
|
||||
&& this.isTimeSystemValid(timeParameters.timeSystem)) {
|
||||
|
||||
if (timeParameters.mode === 'fixed') {
|
||||
isValid = this.areStartAndEndValid(timeParameters.bounds);
|
||||
@ -194,13 +197,13 @@ export default class URLTimeSettingsSynchronizer {
|
||||
}
|
||||
|
||||
areStartAndEndValid(bounds) {
|
||||
return bounds !== undefined &&
|
||||
bounds.start !== undefined &&
|
||||
bounds.start !== null &&
|
||||
bounds.end !== undefined &&
|
||||
bounds.start !== null &&
|
||||
!isNaN(bounds.start) &&
|
||||
!isNaN(bounds.end);
|
||||
return bounds !== undefined
|
||||
&& bounds.start !== undefined
|
||||
&& bounds.start !== null
|
||||
&& bounds.end !== undefined
|
||||
&& bounds.start !== null
|
||||
&& !isNaN(bounds.start)
|
||||
&& !isNaN(bounds.end);
|
||||
}
|
||||
|
||||
isTimeSystemValid(timeSystem) {
|
||||
@ -209,14 +212,15 @@ export default class URLTimeSettingsSynchronizer {
|
||||
let timeSystemObject = this.openmct.time.timeSystems.get(timeSystem);
|
||||
isValid = timeSystemObject !== undefined;
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
isModeValid(mode) {
|
||||
let isValid = false;
|
||||
|
||||
if (mode !== undefined &&
|
||||
mode !== null) {
|
||||
if (mode !== undefined
|
||||
&& mode !== null) {
|
||||
isValid = true;
|
||||
}
|
||||
|
||||
@ -227,11 +231,12 @@ export default class URLTimeSettingsSynchronizer {
|
||||
isValid = this.openmct.time.clocks.get(mode) !== undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
areStartAndEndEqual(firstBounds, secondBounds) {
|
||||
return firstBounds.start === secondBounds.start &&
|
||||
firstBounds.end === secondBounds.end;
|
||||
return firstBounds.start === secondBounds.start
|
||||
&& firstBounds.end === secondBounds.end;
|
||||
}
|
||||
}
|
||||
|
@ -24,5 +24,5 @@ import URLTimeSettingsSynchronizer from "./URLTimeSettingsSynchronizer.js";
|
||||
export default function () {
|
||||
return function install(openmct) {
|
||||
return new URLTimeSettingsSynchronizer(openmct);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -49,7 +49,10 @@ describe("The URLTimeSettingsSynchronizer", () => {
|
||||
//Test expected initial conditions
|
||||
expect(window.location.hash.includes('tc.mode=fixed')).toBe(true);
|
||||
|
||||
openmct.time.clock('local', {start: -1000, end: 100});
|
||||
openmct.time.clock('local', {
|
||||
start: -1000,
|
||||
end: 100
|
||||
});
|
||||
|
||||
expect(window.location.hash.includes('tc.mode=local')).toBe(true);
|
||||
|
||||
@ -61,11 +64,17 @@ describe("The URLTimeSettingsSynchronizer", () => {
|
||||
expect(window.location.hash.includes('tc.startDelta')).toBe(false);
|
||||
expect(window.location.hash.includes('tc.endDelta')).toBe(false);
|
||||
|
||||
openmct.time.clock('local', {start: -1000, end: 100});
|
||||
openmct.time.clock('local', {
|
||||
start: -1000,
|
||||
end: 100
|
||||
});
|
||||
expect(window.location.hash.includes('tc.startDelta=1000')).toBe(true);
|
||||
expect(window.location.hash.includes('tc.endDelta=100')).toBe(true);
|
||||
|
||||
openmct.time.clockOffsets({start: -2000, end: 200});
|
||||
openmct.time.clockOffsets({
|
||||
start: -2000,
|
||||
end: 200
|
||||
});
|
||||
expect(window.location.hash.includes('tc.startDelta=2000')).toBe(true);
|
||||
expect(window.location.hash.includes('tc.endDelta=200')).toBe(true);
|
||||
|
||||
@ -75,6 +84,7 @@ describe("The URLTimeSettingsSynchronizer", () => {
|
||||
describe("when set in the url", () => {
|
||||
it("will change from fixed to realtime mode when the mode changes", () => {
|
||||
expectLocationToBeInFixedMode();
|
||||
|
||||
return switchToRealtimeMode().then(() => {
|
||||
let clock = openmct.time.clock();
|
||||
|
||||
@ -85,6 +95,7 @@ describe("The URLTimeSettingsSynchronizer", () => {
|
||||
it("the clock is correctly set in the API from the URL parameters", () => {
|
||||
return switchToRealtimeMode().then(() => {
|
||||
let resolveFunction;
|
||||
|
||||
return new Promise((resolve) => {
|
||||
resolveFunction = resolve;
|
||||
|
||||
@ -105,6 +116,7 @@ describe("The URLTimeSettingsSynchronizer", () => {
|
||||
it("the clock offsets are correctly set in the API from the URL parameters", () => {
|
||||
return switchToRealtimeMode().then(() => {
|
||||
let resolveFunction;
|
||||
|
||||
return new Promise((resolve) => {
|
||||
resolveFunction = resolve;
|
||||
//The 'hashchange' event appears to be asynchronous, so we need to wait until a clock change has been
|
||||
@ -126,6 +138,7 @@ describe("The URLTimeSettingsSynchronizer", () => {
|
||||
it("the time system is correctly set in the API from the URL parameters", () => {
|
||||
return switchToRealtimeMode().then(() => {
|
||||
let resolveFunction;
|
||||
|
||||
return new Promise((resolve) => {
|
||||
resolveFunction = resolve;
|
||||
|
||||
@ -148,15 +161,21 @@ describe("The URLTimeSettingsSynchronizer", () => {
|
||||
describe("fixed timespan mode", () => {
|
||||
beforeEach(() => {
|
||||
openmct.time.stopClock();
|
||||
openmct.time.timeSystem('utc', {start: 0, end: 1});
|
||||
openmct.time.timeSystem('utc', {
|
||||
start: 0,
|
||||
end: 1
|
||||
});
|
||||
});
|
||||
|
||||
it("when bounds are set via the time API, they are immediately reflected in the URL", ()=>{
|
||||
it("when bounds are set via the time API, they are immediately reflected in the URL", () => {
|
||||
//Test expected initial conditions
|
||||
expect(window.location.hash.includes('tc.startBound=0')).toBe(true);
|
||||
expect(window.location.hash.includes('tc.endBound=1')).toBe(true);
|
||||
|
||||
openmct.time.bounds({start: 10, end: 20});
|
||||
openmct.time.bounds({
|
||||
start: 10,
|
||||
end: 20
|
||||
});
|
||||
|
||||
expect(window.location.hash.includes('tc.startBound=10')).toBe(true);
|
||||
expect(window.location.hash.includes('tc.endBound=20')).toBe(true);
|
||||
@ -166,11 +185,14 @@ describe("The URLTimeSettingsSynchronizer", () => {
|
||||
expect(window.location.hash.includes('tc.endBound=1')).toBe(false);
|
||||
});
|
||||
|
||||
it("when time system is set via the time API, it is immediately reflected in the URL", ()=>{
|
||||
it("when time system is set via the time API, it is immediately reflected in the URL", () => {
|
||||
//Test expected initial conditions
|
||||
expect(window.location.hash.includes('tc.timeSystem=utc')).toBe(true);
|
||||
|
||||
openmct.time.timeSystem('local', {start: 20, end: 30});
|
||||
openmct.time.timeSystem('local', {
|
||||
start: 20,
|
||||
end: 30
|
||||
});
|
||||
|
||||
expect(window.location.hash.includes('tc.timeSystem=local')).toBe(true);
|
||||
|
||||
@ -269,6 +291,7 @@ describe("The URLTimeSettingsSynchronizer", () => {
|
||||
|
||||
function switchToRealtimeMode() {
|
||||
let resolveFunction;
|
||||
|
||||
return new Promise((resolve) => {
|
||||
resolveFunction = resolve;
|
||||
openmct.time.on('clock', resolveFunction);
|
||||
@ -280,6 +303,7 @@ describe("The URLTimeSettingsSynchronizer", () => {
|
||||
|
||||
function switchToFixedMode() {
|
||||
let resolveFunction;
|
||||
|
||||
return new Promise((resolve) => {
|
||||
resolveFunction = resolve;
|
||||
//The 'hashchange' event appears to be asynchronous, so we need to wait until a clock change has been
|
||||
|
@ -102,7 +102,10 @@ define([
|
||||
testKeys = ['abc', 'def', 'xyz'];
|
||||
testChildren = testKeys.map(function (key) {
|
||||
return {
|
||||
identifier: { namespace: "test", key: key },
|
||||
identifier: {
|
||||
namespace: "test",
|
||||
key: key
|
||||
},
|
||||
name: "Object " + key
|
||||
};
|
||||
});
|
||||
@ -110,7 +113,12 @@ define([
|
||||
domObserver = new DOMObserver(testContainer);
|
||||
|
||||
testHistories = testKeys.reduce(function (histories, key, index) {
|
||||
histories[key] = { key: key, range: index + 10, domain: key + index };
|
||||
histories[key] = {
|
||||
key: key,
|
||||
range: index + 10,
|
||||
domain: key + index
|
||||
};
|
||||
|
||||
return histories;
|
||||
}, {});
|
||||
|
||||
@ -122,12 +130,14 @@ define([
|
||||
mockEvaluator = jasmine.createSpyObj('evaluator', ['evaluate']);
|
||||
mockUnsubscribes = testKeys.reduce(function (map, key) {
|
||||
map[key] = jasmine.createSpy('unsubscribe-' + key);
|
||||
|
||||
return map;
|
||||
}, {});
|
||||
|
||||
mockmct.composition.get.and.returnValue(mockComposition);
|
||||
mockComposition.load.and.callFake(function () {
|
||||
testChildren.forEach(emitEvent.bind(null, mockComposition, 'add'));
|
||||
|
||||
return Promise.resolve(testChildren);
|
||||
});
|
||||
|
||||
@ -137,16 +147,19 @@ define([
|
||||
mockFormatter.format.and.callFake(function (datum) {
|
||||
return datum[metadatum.hint];
|
||||
});
|
||||
|
||||
return mockFormatter;
|
||||
});
|
||||
mockmct.telemetry.limitEvaluator.and.returnValue(mockEvaluator);
|
||||
mockmct.telemetry.subscribe.and.callFake(function (obj, callback) {
|
||||
var key = obj.identifier.key;
|
||||
callbacks[key] = callback;
|
||||
|
||||
return mockUnsubscribes[key];
|
||||
});
|
||||
mockmct.telemetry.request.and.callFake(function (obj, request) {
|
||||
var key = obj.identifier.key;
|
||||
|
||||
return Promise.resolve([testHistories[key]]);
|
||||
});
|
||||
mockMetadata.valuesForHints.and.callFake(function (hints) {
|
||||
@ -170,6 +183,7 @@ define([
|
||||
describe("when rows have been populated", function () {
|
||||
function rowsMatch() {
|
||||
var rows = $(testContainer).find(".l-autoflow-row").length;
|
||||
|
||||
return rows === testChildren.length;
|
||||
}
|
||||
|
||||
@ -179,17 +193,22 @@ define([
|
||||
|
||||
it("adds rows on composition change", function () {
|
||||
var child = {
|
||||
identifier: { namespace: "test", key: "123" },
|
||||
identifier: {
|
||||
namespace: "test",
|
||||
key: "123"
|
||||
},
|
||||
name: "Object 123"
|
||||
};
|
||||
testChildren.push(child);
|
||||
emitEvent(mockComposition, 'add', child);
|
||||
|
||||
return domObserver.when(rowsMatch);
|
||||
});
|
||||
|
||||
it("removes rows on composition change", function () {
|
||||
var child = testChildren.pop();
|
||||
emitEvent(mockComposition, 'remove', child.identifier);
|
||||
|
||||
return domObserver.when(rowsMatch);
|
||||
});
|
||||
});
|
||||
@ -216,6 +235,7 @@ define([
|
||||
|
||||
function widthHasChanged() {
|
||||
var width = $(testContainer).find('.l-autoflow-col').css('width');
|
||||
|
||||
return width !== initialWidth + 'px';
|
||||
}
|
||||
|
||||
@ -236,6 +256,7 @@ define([
|
||||
function rowTextDefined() {
|
||||
return $(testContainer).find(".l-autoflow-item").filter(".r").text() !== "";
|
||||
}
|
||||
|
||||
return domObserver.when(rowTextDefined).then(function () {
|
||||
testKeys.forEach(function (key, index) {
|
||||
var datum = testHistories[key];
|
||||
@ -247,7 +268,11 @@ define([
|
||||
|
||||
it("displays incoming telemetry", function () {
|
||||
var testData = testKeys.map(function (key, index) {
|
||||
return { key: key, range: index * 100, domain: key + index };
|
||||
return {
|
||||
key: key,
|
||||
range: index * 100,
|
||||
domain: key + index
|
||||
};
|
||||
});
|
||||
|
||||
testData.forEach(function (datum) {
|
||||
@ -266,7 +291,10 @@ define([
|
||||
var testClass = "some-limit-violation";
|
||||
mockEvaluator.evaluate.and.returnValue({ cssClass: testClass });
|
||||
testKeys.forEach(function (key) {
|
||||
callbacks[key]({ range: 'foo', domain: 'bar' });
|
||||
callbacks[key]({
|
||||
range: 'foo',
|
||||
domain: 'bar'
|
||||
});
|
||||
});
|
||||
|
||||
return waitsForChange().then(function () {
|
||||
@ -306,12 +334,14 @@ define([
|
||||
|
||||
function setHeight(height) {
|
||||
$container.css('height', height + 'px');
|
||||
|
||||
return domObserver.when(columnsHaveAutoflowed);
|
||||
}
|
||||
|
||||
for (var height = 0; height < rowHeight * count * 2; height += rowHeight / 2) {
|
||||
promiseChain = promiseChain.then(setHeight.bind(this, height));
|
||||
}
|
||||
|
||||
return promiseChain.then(function () {
|
||||
$container.remove();
|
||||
});
|
||||
|
@ -58,8 +58,8 @@ define([
|
||||
methods: {
|
||||
increaseColumnWidth: function () {
|
||||
data.width += COLUMN_WIDTH_STEP;
|
||||
data.width = data.width > MAX_COLUMN_WIDTH ?
|
||||
INITIAL_COLUMN_WIDTH : data.width;
|
||||
data.width = data.width > MAX_COLUMN_WIDTH
|
||||
? INITIAL_COLUMN_WIDTH : data.width;
|
||||
},
|
||||
reflow: function () {
|
||||
var column = [];
|
||||
|
@ -26,6 +26,7 @@ define(['vue'], function (Vue) {
|
||||
this.show = function (container) {
|
||||
container.appendChild(vm.$mount().$el);
|
||||
};
|
||||
|
||||
this.destroy = vm.$destroy.bind(vm);
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,11 @@ define([], function () {
|
||||
resolve();
|
||||
} else {
|
||||
//Latch condition not true yet, create observer on DOM and test again on change.
|
||||
var config = { attributes: true, childList: true, subtree: true };
|
||||
var config = {
|
||||
attributes: true,
|
||||
childList: true,
|
||||
subtree: true
|
||||
};
|
||||
var observer = new MutationObserver(function () {
|
||||
if (latchFunction()) {
|
||||
resolve();
|
||||
|
@ -29,7 +29,10 @@ define([
|
||||
|
||||
beforeEach(function () {
|
||||
mockmct = jasmine.createSpyObj('openmct', ['legacyExtension']);
|
||||
testInfo = { foo: 123, bar: "baz" };
|
||||
testInfo = {
|
||||
foo: 123,
|
||||
bar: "baz"
|
||||
};
|
||||
plugin(testInfo)(mockmct);
|
||||
});
|
||||
|
||||
|
@ -14,5 +14,5 @@ export default {
|
||||
this.openmct.objectViews.emit('clearData');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -20,7 +20,7 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
import ClearDataActionPlugin from '../plugin.js';
|
||||
import ClearDataActionPlugin from '../plugin.js';
|
||||
import ClearDataAction from '../clearDataAction.js';
|
||||
|
||||
describe('When the Clear Data Plugin is installed,', function () {
|
||||
|
@ -63,6 +63,7 @@ export default class Condition extends EventEmitter {
|
||||
if (conditionConfiguration.configuration.criteria) {
|
||||
this.createCriteria(conditionConfiguration.configuration.criteria);
|
||||
}
|
||||
|
||||
this.trigger = conditionConfiguration.configuration.trigger;
|
||||
this.description = '';
|
||||
}
|
||||
@ -70,6 +71,7 @@ export default class Condition extends EventEmitter {
|
||||
getResult(datum) {
|
||||
if (!datum || !datum.id) {
|
||||
console.log('no data received');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -149,24 +151,27 @@ export default class Condition extends EventEmitter {
|
||||
} else {
|
||||
criterion = new TelemetryCriterion(criterionConfigurationWithId, this.openmct);
|
||||
}
|
||||
|
||||
criterion.on('criterionUpdated', (obj) => this.handleCriterionUpdated(obj));
|
||||
criterion.on('telemetryIsStale', (obj) => this.handleStaleCriterion(obj));
|
||||
if (!this.criteria) {
|
||||
this.criteria = [];
|
||||
}
|
||||
|
||||
this.criteria.push(criterion);
|
||||
|
||||
return criterionConfigurationWithId.id;
|
||||
}
|
||||
|
||||
findCriterion(id) {
|
||||
let criterion;
|
||||
|
||||
for (let i=0, ii=this.criteria.length; i < ii; i ++) {
|
||||
for (let i = 0, ii = this.criteria.length; i < ii; i++) {
|
||||
if (this.criteria[i].id === id) {
|
||||
criterion = {
|
||||
item: this.criteria[i],
|
||||
index: i
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -206,6 +211,7 @@ export default class Condition extends EventEmitter {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -236,6 +242,7 @@ export default class Condition extends EventEmitter {
|
||||
if (!index) {
|
||||
description = `Match if ${triggerDescription.prefix}`;
|
||||
}
|
||||
|
||||
description = `${description} ${criterion.getDescription()} ${(index < this.criteria.length - 1) ? triggerDescription.conjunction : ''}`;
|
||||
});
|
||||
this.description = description;
|
||||
@ -260,8 +267,9 @@ export default class Condition extends EventEmitter {
|
||||
results.forEach(resultObj => {
|
||||
const { id, data, data: { result } } = resultObj;
|
||||
if (this.findCriterion(id)) {
|
||||
criteriaResults[id] = !!result;
|
||||
criteriaResults[id] = Boolean(result);
|
||||
}
|
||||
|
||||
latestTimestamp = getLatestTimestamp(
|
||||
latestTimestamp,
|
||||
data,
|
||||
@ -269,6 +277,7 @@ export default class Condition extends EventEmitter {
|
||||
this.openmct.time.timeSystem()
|
||||
);
|
||||
});
|
||||
|
||||
return {
|
||||
id: this.id,
|
||||
data: Object.assign(
|
||||
@ -287,9 +296,10 @@ export default class Condition extends EventEmitter {
|
||||
destroyCriteria() {
|
||||
let success = true;
|
||||
//looping through the array backwards since destroyCriterion modifies the criteria array
|
||||
for (let i=this.criteria.length-1; i >= 0; i--) {
|
||||
for (let i = this.criteria.length - 1; i >= 0; i--) {
|
||||
success = success && this.destroyCriterion(this.criteria[i].id);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,10 @@ export default class ConditionManager extends EventEmitter {
|
||||
this.compositionLoad = this.composition.load();
|
||||
this.subscriptions = {};
|
||||
this.telemetryObjects = {};
|
||||
this.testData = {conditionTestData: [], applied: false};
|
||||
this.testData = {
|
||||
conditionTestData: [],
|
||||
applied: false
|
||||
};
|
||||
this.initialize();
|
||||
|
||||
this.stopObservingForChanges = this.openmct.objects.observe(this.conditionSetDomainObject, '*', (newDomainObject) => {
|
||||
@ -50,8 +53,10 @@ export default class ConditionManager extends EventEmitter {
|
||||
const id = this.openmct.objects.makeKeyString(endpoint.identifier);
|
||||
if (this.subscriptions[id]) {
|
||||
console.log('subscription already exists');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.telemetryObjects[id] = Object.assign({}, endpoint, {telemetryMetaData: this.openmct.telemetry.getMetadata(endpoint).valueMetadatas});
|
||||
this.subscriptions[id] = this.openmct.telemetry.subscribe(
|
||||
endpoint,
|
||||
@ -64,6 +69,7 @@ export default class ConditionManager extends EventEmitter {
|
||||
const id = this.openmct.objects.makeKeyString(endpointIdentifier);
|
||||
if (!this.subscriptions[id]) {
|
||||
console.log('no subscription to remove');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -189,6 +195,7 @@ export default class ConditionManager extends EventEmitter {
|
||||
} else {
|
||||
this.conditionSetDomainObject.configuration.conditionCollection.unshift(newCondition);
|
||||
}
|
||||
|
||||
this.initCondition(newCondition, index);
|
||||
this.persistConditions();
|
||||
}
|
||||
@ -218,10 +225,10 @@ export default class ConditionManager extends EventEmitter {
|
||||
|
||||
getCurrentCondition() {
|
||||
const conditionCollection = this.conditionSetDomainObject.configuration.conditionCollection;
|
||||
let currentCondition = conditionCollection[conditionCollection.length-1];
|
||||
let currentCondition = conditionCollection[conditionCollection.length - 1];
|
||||
|
||||
for (let i = 0; i < conditionCollection.length - 1; i++) {
|
||||
const condition = this.findConditionById(conditionCollection[i].id)
|
||||
const condition = this.findConditionById(conditionCollection[i].id);
|
||||
if (condition.result) {
|
||||
//first condition to be true wins
|
||||
currentCondition = conditionCollection[i];
|
||||
@ -234,7 +241,7 @@ export default class ConditionManager extends EventEmitter {
|
||||
|
||||
getCurrentConditionLAD(conditionResults) {
|
||||
const conditionCollection = this.conditionSetDomainObject.configuration.conditionCollection;
|
||||
let currentCondition = conditionCollection[conditionCollection.length-1];
|
||||
let currentCondition = conditionCollection[conditionCollection.length - 1];
|
||||
|
||||
for (let i = 0; i < conditionCollection.length - 1; i++) {
|
||||
if (conditionResults[conditionCollection[i].id]) {
|
||||
@ -243,6 +250,7 @@ export default class ConditionManager extends EventEmitter {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return currentCondition;
|
||||
}
|
||||
|
||||
@ -262,8 +270,9 @@ export default class ConditionManager extends EventEmitter {
|
||||
results.forEach(resultObj => {
|
||||
const { id, data, data: { result } } = resultObj;
|
||||
if (this.findConditionById(id)) {
|
||||
conditionResults[id] = !!result;
|
||||
conditionResults[id] = Boolean(result);
|
||||
}
|
||||
|
||||
latestTimestamp = getLatestTimestamp(
|
||||
latestTimestamp,
|
||||
data,
|
||||
@ -294,7 +303,7 @@ export default class ConditionManager extends EventEmitter {
|
||||
isTelemetryUsed(endpoint) {
|
||||
const id = this.openmct.objects.makeKeyString(endpoint.identifier);
|
||||
|
||||
for(const condition of this.conditions) {
|
||||
for (const condition of this.conditions) {
|
||||
if (condition.isTelemetryUsed(id)) {
|
||||
return true;
|
||||
}
|
||||
@ -332,7 +341,7 @@ export default class ConditionManager extends EventEmitter {
|
||||
},
|
||||
timestamp
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
getTestData(metadatum) {
|
||||
@ -343,6 +352,7 @@ export default class ConditionManager extends EventEmitter {
|
||||
data = found.value;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -353,7 +363,8 @@ export default class ConditionManager extends EventEmitter {
|
||||
const normalizedDatum = Object.values(metadata).reduce((datum, metadatum) => {
|
||||
const testValue = this.getTestData(metadatum);
|
||||
const formatter = this.openmct.telemetry.getValueFormatter(metadatum);
|
||||
datum[metadatum.key] = testValue !== undefined ? formatter.parse(testValue) : formatter.parse(telemetryDatum[metadatum.source]);
|
||||
datum[metadatum.key] = testValue !== undefined ? formatter.parse(testValue) : formatter.parse(telemetryDatum[metadatum.source]);
|
||||
|
||||
return datum;
|
||||
}, {});
|
||||
|
||||
@ -377,12 +388,12 @@ export default class ConditionManager extends EventEmitter {
|
||||
Object.values(this.subscriptions).forEach(unsubscribe => unsubscribe());
|
||||
delete this.subscriptions;
|
||||
|
||||
if(this.stopObservingForChanges) {
|
||||
if (this.stopObservingForChanges) {
|
||||
this.stopObservingForChanges();
|
||||
}
|
||||
|
||||
this.conditions.forEach((condition) => {
|
||||
condition.destroy();
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
import ConditionManager from './ConditionManager';
|
||||
import ConditionManager from './ConditionManager';
|
||||
|
||||
describe('ConditionManager', () => {
|
||||
|
||||
@ -93,6 +93,7 @@ describe('ConditionManager', () => {
|
||||
setTimeout(() => {
|
||||
loader.resolve();
|
||||
});
|
||||
|
||||
return loader.promise;
|
||||
});
|
||||
mockComposition.on('add', mockListener);
|
||||
|
@ -29,5 +29,5 @@ export default function ConditionSetCompositionPolicy(openmct) {
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
import ConditionSetCompositionPolicy from './ConditionSetCompositionPolicy';
|
||||
import ConditionSetCompositionPolicy from './ConditionSetCompositionPolicy';
|
||||
|
||||
describe('ConditionSetCompositionPolicy', () => {
|
||||
|
||||
@ -31,7 +31,10 @@ describe('ConditionSetCompositionPolicy', () => {
|
||||
|
||||
beforeAll(function () {
|
||||
testTelemetryObject = {
|
||||
identifier:{ namespace: "", key: "test-object"},
|
||||
identifier: {
|
||||
namespace: "",
|
||||
key: "test-object"
|
||||
},
|
||||
type: "test-object",
|
||||
name: "Test Object",
|
||||
telemetry: {
|
||||
|
@ -20,7 +20,7 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
import ConditionManager from './ConditionManager'
|
||||
import ConditionManager from './ConditionManager';
|
||||
|
||||
export default class ConditionSetTelemetryProvider {
|
||||
constructor(openmct) {
|
||||
|
@ -27,7 +27,8 @@ ConditionSetViewPolicy.prototype.allow = function (view, domainObject) {
|
||||
if (domainObject.getModel().type === 'conditionSet') {
|
||||
return view.key === 'conditionSet.view';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
export default ConditionSetViewPolicy;
|
||||
|
@ -44,6 +44,7 @@ export default class ConditionSetViewProvider {
|
||||
view(domainObject, objectPath) {
|
||||
let component;
|
||||
const openmct = this.openmct;
|
||||
|
||||
return {
|
||||
show: (container, isEditing) => {
|
||||
component = new Vue({
|
||||
@ -59,7 +60,7 @@ export default class ConditionSetViewProvider {
|
||||
data() {
|
||||
return {
|
||||
isEditing
|
||||
}
|
||||
};
|
||||
},
|
||||
template: '<condition-set :isEditing="isEditing"></condition-set>'
|
||||
});
|
||||
|
@ -43,7 +43,10 @@ describe("The condition", function () {
|
||||
conditionManager.updateConditionDescription.and.returnValue(function () {});
|
||||
|
||||
testTelemetryObject = {
|
||||
identifier:{ namespace: "", key: "test-object"},
|
||||
identifier: {
|
||||
namespace: "",
|
||||
key: "test-object"
|
||||
},
|
||||
type: "test-object",
|
||||
name: "Test Object",
|
||||
telemetry: {
|
||||
@ -75,7 +78,7 @@ describe("The condition", function () {
|
||||
openmct.objects = jasmine.createSpyObj('objects', ['get', 'makeKeyString']);
|
||||
openmct.objects.get.and.returnValue(new Promise(function (resolve, reject) {
|
||||
resolve(testTelemetryObject);
|
||||
})); openmct.objects.makeKeyString.and.returnValue(testTelemetryObject.identifier.key);
|
||||
})); openmct.objects.makeKeyString.and.returnValue(testTelemetryObject.identifier.key);
|
||||
openmct.telemetry = jasmine.createSpyObj('telemetry', ['isTelemetryObject', 'subscribe', 'getMetadata']);
|
||||
openmct.telemetry.isTelemetryObject.and.returnValue(true);
|
||||
openmct.telemetry.subscribe.and.returnValue(function () {});
|
||||
|
@ -31,6 +31,7 @@ export default class StyleRuleManager extends EventEmitter {
|
||||
this.openmct.editor.on('isEditing', this.toggleSubscription.bind(this));
|
||||
this.isEditing = this.openmct.editor.editing;
|
||||
}
|
||||
|
||||
if (styleConfiguration) {
|
||||
this.initialize(styleConfiguration);
|
||||
if (styleConfiguration.conditionSetIdentifier) {
|
||||
@ -48,6 +49,7 @@ export default class StyleRuleManager extends EventEmitter {
|
||||
this.stopProvidingTelemetry();
|
||||
delete this.stopProvidingTelemetry;
|
||||
}
|
||||
|
||||
if (this.conditionSetIdentifier) {
|
||||
this.applySelectedConditionStyle();
|
||||
}
|
||||
@ -69,6 +71,7 @@ export default class StyleRuleManager extends EventEmitter {
|
||||
this.stopProvidingTelemetry();
|
||||
delete this.stopProvidingTelemetry;
|
||||
}
|
||||
|
||||
this.openmct.objects.get(this.conditionSetIdentifier).then((conditionSetDomainObject) => {
|
||||
this.openmct.telemetry.request(conditionSetDomainObject)
|
||||
.then(output => {
|
||||
@ -85,8 +88,8 @@ export default class StyleRuleManager extends EventEmitter {
|
||||
this.initialize(styleConfiguration || {});
|
||||
this.destroy();
|
||||
} else {
|
||||
let isNewConditionSet = !this.conditionSetIdentifier ||
|
||||
!this.openmct.objects.areIdsEqual(this.conditionSetIdentifier, styleConfiguration.conditionSetIdentifier);
|
||||
let isNewConditionSet = !this.conditionSetIdentifier
|
||||
|| !this.openmct.objects.areIdsEqual(this.conditionSetIdentifier, styleConfiguration.conditionSetIdentifier);
|
||||
this.initialize(styleConfiguration);
|
||||
if (this.isEditing) {
|
||||
this.applySelectedConditionStyle();
|
||||
@ -117,6 +120,7 @@ export default class StyleRuleManager extends EventEmitter {
|
||||
if (foundStyle !== this.currentStyle) {
|
||||
this.currentStyle = foundStyle;
|
||||
}
|
||||
|
||||
this.updateDomainObjectStyle();
|
||||
} else {
|
||||
this.applyStaticStyle();
|
||||
@ -149,6 +153,7 @@ export default class StyleRuleManager extends EventEmitter {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.updateDomainObjectStyle();
|
||||
}
|
||||
|
||||
@ -158,6 +163,7 @@ export default class StyleRuleManager extends EventEmitter {
|
||||
this.stopProvidingTelemetry();
|
||||
delete this.stopProvidingTelemetry;
|
||||
}
|
||||
|
||||
this.conditionSetIdentifier = undefined;
|
||||
}
|
||||
|
||||
|
@ -253,20 +253,22 @@ export default {
|
||||
label: `when ${TRIGGER_LABEL[TRIGGER[trigger]]}`
|
||||
});
|
||||
});
|
||||
|
||||
return triggerOptions;
|
||||
},
|
||||
canEvaluateCriteria: function () {
|
||||
let criteria = this.condition.configuration.criteria;
|
||||
if (criteria.length) {
|
||||
let lastCriterion = criteria[criteria.length - 1];
|
||||
if (lastCriterion.telemetry &&
|
||||
lastCriterion.operation &&
|
||||
(lastCriterion.input.length ||
|
||||
lastCriterion.operation === 'isDefined' ||
|
||||
lastCriterion.operation === 'isUndefined')) {
|
||||
if (lastCriterion.telemetry
|
||||
&& lastCriterion.operation
|
||||
&& (lastCriterion.input.length
|
||||
|| lastCriterion.operation === 'isDefined'
|
||||
|| lastCriterion.operation === 'isUndefined')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
},
|
||||
@ -293,6 +295,7 @@ export default {
|
||||
} else {
|
||||
this.condition.configuration.output = this.selectedOutputSelection;
|
||||
}
|
||||
|
||||
this.persist();
|
||||
},
|
||||
addCriteria() {
|
||||
@ -317,8 +320,14 @@ export default {
|
||||
this.$emit('dragComplete');
|
||||
},
|
||||
dropCondition(event, targetIndex) {
|
||||
if (!this.isDragging) { return }
|
||||
if (targetIndex > this.moveIndex) { targetIndex-- } // for 'downward' move
|
||||
if (!this.isDragging) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (targetIndex > this.moveIndex) {
|
||||
targetIndex--;
|
||||
} // for 'downward' move
|
||||
|
||||
if (this.isValidTarget(targetIndex)) {
|
||||
this.dragElement = undefined;
|
||||
this.draggingOver = false;
|
||||
@ -326,8 +335,14 @@ export default {
|
||||
}
|
||||
},
|
||||
dragEnter(event, targetIndex) {
|
||||
if (!this.isDragging) { return }
|
||||
if (targetIndex > this.moveIndex) { targetIndex-- } // for 'downward' move
|
||||
if (!this.isDragging) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (targetIndex > this.moveIndex) {
|
||||
targetIndex--;
|
||||
} // for 'downward' move
|
||||
|
||||
if (this.isValidTarget(targetIndex)) {
|
||||
this.dragElement = event.target.parentElement;
|
||||
this.draggingOver = true;
|
||||
@ -370,8 +385,8 @@ export default {
|
||||
});
|
||||
},
|
||||
initCap(str) {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1)
|
||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -94,7 +94,7 @@ export default {
|
||||
return {
|
||||
applied: false,
|
||||
conditionTestInputs: []
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -126,10 +126,11 @@ export default {
|
||||
destroyed() {
|
||||
this.composition.off('add', this.addTelemetryObject);
|
||||
this.composition.off('remove', this.removeTelemetryObject);
|
||||
if(this.conditionManager) {
|
||||
if (this.conditionManager) {
|
||||
this.conditionManager.off('conditionSetResultUpdated', this.handleConditionSetResultUpdated);
|
||||
this.conditionManager.destroy();
|
||||
}
|
||||
|
||||
if (this.stopObservingForChanges) {
|
||||
this.stopObservingForChanges();
|
||||
}
|
||||
@ -148,7 +149,7 @@ export default {
|
||||
methods: {
|
||||
handleConditionSetResultUpdated(data) {
|
||||
this.currentConditionId = data.conditionId;
|
||||
this.$emit('conditionSetResultUpdated', data)
|
||||
this.$emit('conditionSetResultUpdated', data);
|
||||
},
|
||||
observeForChanges() {
|
||||
this.stopObservingForChanges = this.openmct.objects.observe(this.domainObject, 'configuration.conditionCollection', (newConditionCollection) => {
|
||||
@ -172,23 +173,31 @@ export default {
|
||||
while (old_index < 0) {
|
||||
old_index += arr.length;
|
||||
}
|
||||
|
||||
while (new_index < 0) {
|
||||
new_index += arr.length;
|
||||
}
|
||||
|
||||
if (new_index >= arr.length) {
|
||||
var k = new_index - arr.length;
|
||||
while ((k--) + 1) {
|
||||
arr.push(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
|
||||
|
||||
return arr;
|
||||
}
|
||||
};
|
||||
|
||||
const newIndexArr = move(oldIndexArr, this.moveIndex, targetIndex);
|
||||
const reorderPlan = [];
|
||||
|
||||
for (let i = 0; i < oldIndexArr.length; i++) {
|
||||
reorderPlan.push({oldIndex: Number(newIndexArr[i]), newIndex: i});
|
||||
reorderPlan.push({
|
||||
oldIndex: Number(newIndexArr[i]),
|
||||
newIndex: i
|
||||
});
|
||||
}
|
||||
|
||||
this.reorder(reorderPlan);
|
||||
@ -204,6 +213,7 @@ export default {
|
||||
let index = this.telemetryObjs.findIndex(obj => {
|
||||
let objId = this.openmct.objects.makeKeyString(obj.identifier);
|
||||
let id = this.openmct.objects.makeKeyString(identifier);
|
||||
|
||||
return objId === id;
|
||||
});
|
||||
if (index > -1) {
|
||||
@ -229,5 +239,5 @@ export default {
|
||||
this.conditionManager.updateTestData(this.testData);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -64,5 +64,5 @@ export default {
|
||||
return this.condition ? this.condition.summary : '';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -52,7 +52,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
conditionErrors: []
|
||||
}
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.getConditionErrors();
|
||||
@ -76,5 +76,5 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -72,7 +72,7 @@ export default {
|
||||
defaultConditionOutput: '',
|
||||
telemetryObjs: [],
|
||||
testData: {}
|
||||
}
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.conditionSetIdentifier = this.openmct.objects.makeKeyString(this.domainObject.identifier);
|
||||
|
@ -142,11 +142,12 @@ export default {
|
||||
operationFormat: '',
|
||||
enumerations: [],
|
||||
inputTypes: INPUT_TYPES
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
setRowLabel: function () {
|
||||
let operator = TRIGGER_CONJUNCTION[this.trigger];
|
||||
|
||||
return (this.index !== 0 ? operator : '') + ' when';
|
||||
},
|
||||
filteredOps: function () {
|
||||
@ -163,11 +164,13 @@ export default {
|
||||
if (this.filteredOps[i].appliesTo.length) {
|
||||
type = this.inputTypes[this.filteredOps[i].appliesTo[0]];
|
||||
} else {
|
||||
type = 'text'
|
||||
type = 'text';
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
},
|
||||
@ -184,11 +187,11 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
checkTelemetry() {
|
||||
if(this.criterion.telemetry) {
|
||||
if (this.criterion.telemetry) {
|
||||
const isAnyAllTelemetry = this.criterion.telemetry === 'any' || this.criterion.telemetry === 'all';
|
||||
const telemetryForCriterionExists = this.telemetry.find((telemetryObj) => this.openmct.objects.areIdsEqual(this.criterion.telemetry, telemetryObj.identifier));
|
||||
if (!isAnyAllTelemetry &&
|
||||
!telemetryForCriterionExists) {
|
||||
if (!isAnyAllTelemetry
|
||||
&& !telemetryForCriterionExists) {
|
||||
//telemetry being used was removed. So reset this criterion.
|
||||
this.criterion.telemetry = '';
|
||||
this.criterion.metadata = '';
|
||||
@ -223,6 +226,7 @@ export default {
|
||||
} else if (this.criterion.metadata === 'dataReceived') {
|
||||
this.operationFormat = 'number';
|
||||
}
|
||||
|
||||
this.updateInputVisibilityAndValues();
|
||||
},
|
||||
updateMetadataOptions(ev) {
|
||||
@ -230,12 +234,14 @@ export default {
|
||||
this.clearDependentFields(ev.target);
|
||||
this.persist();
|
||||
}
|
||||
|
||||
if (this.criterion.telemetry) {
|
||||
let telemetryObjects = this.telemetry;
|
||||
if (this.criterion.telemetry !== 'all' && this.criterion.telemetry !== 'any') {
|
||||
const found = this.telemetry.find(telemetryObj => (this.openmct.objects.areIdsEqual(telemetryObj.identifier, this.criterion.telemetry)));
|
||||
telemetryObjects = found ? [found] : [];
|
||||
}
|
||||
|
||||
this.telemetryMetadataOptions = [];
|
||||
telemetryObjects.forEach(telemetryObject => {
|
||||
let telemetryMetadata = this.openmct.telemetry.getMetadata(telemetryObject);
|
||||
@ -248,9 +254,10 @@ export default {
|
||||
if (!this.telemetryMetadataOptions) {
|
||||
this.telemetryMetadataOptions = options;
|
||||
}
|
||||
|
||||
options.forEach((option) => {
|
||||
const found = this.telemetryMetadataOptions.find((metadataOption) => {
|
||||
return (metadataOption.key && (metadataOption.key === option.key)) && (metadataOption.name && (metadataOption.name === option.name))
|
||||
return (metadataOption.key && (metadataOption.key === option.key)) && (metadataOption.name && (metadataOption.name === option.name));
|
||||
});
|
||||
if (!found) {
|
||||
this.telemetryMetadataOptions.push(option);
|
||||
@ -275,6 +282,7 @@ export default {
|
||||
this.inputCount = this.filteredOps[i].inputCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.inputCount) {
|
||||
this.criterion.input = [];
|
||||
}
|
||||
@ -292,6 +300,7 @@ export default {
|
||||
if (this.enumerations.length && !this.criterion.input.length) {
|
||||
this.criterion.input = [this.enumerations[0].value.toString()];
|
||||
}
|
||||
|
||||
this.inputCount = 0;
|
||||
}
|
||||
},
|
||||
|
@ -136,7 +136,7 @@ export default {
|
||||
return {
|
||||
applied: false,
|
||||
conditionTestInputs: []
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -183,6 +183,7 @@ export default {
|
||||
if (this.testData && this.testData.conditionTestInputs) {
|
||||
this.testInputs = this.testData.conditionTestInputs;
|
||||
}
|
||||
|
||||
if (!this.testInputs.length) {
|
||||
this.addTestInput();
|
||||
}
|
||||
@ -209,14 +210,16 @@ export default {
|
||||
if (identifier) {
|
||||
return this.openmct.objects.makeKeyString(identifier);
|
||||
}
|
||||
|
||||
return [];
|
||||
},
|
||||
updateMetadata(testInput) {
|
||||
if (testInput.telemetry) {
|
||||
const id = this.openmct.objects.makeKeyString(testInput.telemetry);
|
||||
if(this.telemetryMetadataOptions[id]) {
|
||||
if (this.telemetryMetadataOptions[id]) {
|
||||
return;
|
||||
}
|
||||
|
||||
let telemetryMetadata = this.openmct.telemetry.getMetadata(testInput);
|
||||
this.telemetryMetadataOptions[id] = telemetryMetadata.values().slice();
|
||||
}
|
||||
@ -232,5 +235,5 @@ export default {
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -98,7 +98,7 @@ export default {
|
||||
loaded: false,
|
||||
children: [],
|
||||
expanded: false
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
navigated() {
|
||||
@ -106,8 +106,10 @@ export default {
|
||||
const isSelectedObject = itemId && this.openmct.objects.areIdsEqual(this.node.object.identifier, itemId);
|
||||
if (isSelectedObject && this.node.objectPath && this.node.objectPath.length > 1) {
|
||||
const isParent = this.openmct.objects.areIdsEqual(this.node.objectPath[1].identifier, this.selectedItem.parentId);
|
||||
|
||||
return isSelectedObject && isParent;
|
||||
}
|
||||
|
||||
return isSelectedObject;
|
||||
},
|
||||
isAlias() {
|
||||
@ -115,7 +117,9 @@ export default {
|
||||
if (!parent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let parentKeyString = this.openmct.objects.makeKeyString(parent.identifier);
|
||||
|
||||
return parentKeyString !== this.node.object.location;
|
||||
},
|
||||
typeClass() {
|
||||
@ -123,6 +127,7 @@ export default {
|
||||
if (!type) {
|
||||
return 'icon-object-unknown';
|
||||
}
|
||||
|
||||
return type.definition.cssClass;
|
||||
}
|
||||
},
|
||||
@ -131,6 +136,7 @@ export default {
|
||||
if (!this.hasChildren) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.loaded && !this.isLoading) {
|
||||
this.composition = this.openmct.composition.get(this.domainObject);
|
||||
this.composition.on('add', this.addChild);
|
||||
@ -181,5 +187,5 @@ export default {
|
||||
this.loaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -98,7 +98,7 @@ export default {
|
||||
filteredTreeItems: [],
|
||||
isLoading: false,
|
||||
selectedItem: undefined
|
||||
}
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.searchService = this.openmct.$injector.get('searchService');
|
||||
@ -109,7 +109,7 @@ export default {
|
||||
this.isLoading = true;
|
||||
this.openmct.objects.get('ROOT')
|
||||
.then(root => {
|
||||
return this.openmct.composition.get(root).load()
|
||||
return this.openmct.composition.get(root).load();
|
||||
})
|
||||
.then(children => {
|
||||
this.isLoading = false;
|
||||
@ -146,7 +146,7 @@ export default {
|
||||
object,
|
||||
objectPath,
|
||||
navigateToParent
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
},
|
||||
@ -168,5 +168,5 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -131,7 +131,7 @@ export default {
|
||||
conditionsLoaded: false,
|
||||
navigateToPath: '',
|
||||
selectedConditionId: ''
|
||||
}
|
||||
};
|
||||
},
|
||||
destroyed() {
|
||||
this.removeListeners();
|
||||
@ -150,6 +150,7 @@ export default {
|
||||
} else {
|
||||
this.initializeStaticStyle();
|
||||
}
|
||||
|
||||
this.openmct.editor.on('isEditing', this.setEditState);
|
||||
},
|
||||
methods: {
|
||||
@ -166,8 +167,8 @@ export default {
|
||||
layoutItem = this.selection[0][0].context.layoutItem;
|
||||
const item = this.selection[0][0].context.item;
|
||||
this.canHide = true;
|
||||
if (item &&
|
||||
(!layoutItem || (this.isItemType('subobject-view', layoutItem)))) {
|
||||
if (item
|
||||
&& (!layoutItem || (this.isItemType('subobject-view', layoutItem)))) {
|
||||
domainObject = item;
|
||||
} else {
|
||||
domainObject = this.selection[0][1].context.item;
|
||||
@ -178,6 +179,7 @@ export default {
|
||||
} else {
|
||||
domainObject = this.selection[0][0].context.item;
|
||||
}
|
||||
|
||||
this.domainObject = domainObject;
|
||||
this.initialStyles = getApplicableStylesForItem(domainObject, layoutItem);
|
||||
this.$nextTick(() => {
|
||||
@ -192,9 +194,11 @@ export default {
|
||||
if (this.stopObserving) {
|
||||
this.stopObserving();
|
||||
}
|
||||
|
||||
if (this.stopObservingItems) {
|
||||
this.stopObservingItems();
|
||||
}
|
||||
|
||||
if (this.stopProvidingTelemetry) {
|
||||
this.stopProvidingTelemetry();
|
||||
delete this.stopProvidingTelemetry;
|
||||
@ -224,6 +228,7 @@ export default {
|
||||
conditionSetDomainObject = item;
|
||||
}
|
||||
};
|
||||
|
||||
const dismissDialog = (overlay, initialize) => {
|
||||
overlay.dismiss();
|
||||
if (initialize && conditionSetDomainObject) {
|
||||
@ -232,6 +237,7 @@ export default {
|
||||
this.initializeConditionalStyles();
|
||||
}
|
||||
};
|
||||
|
||||
let vm = new Vue({
|
||||
provide: {
|
||||
openmct: this.openmct
|
||||
@ -240,7 +246,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
handleItemSelection
|
||||
}
|
||||
};
|
||||
},
|
||||
template: '<condition-set-selector-dialog @conditionSetSelected="handleItemSelection"></condition-set-selector-dialog>'
|
||||
}).$mount();
|
||||
@ -283,7 +289,7 @@ export default {
|
||||
removeConditionSet() {
|
||||
this.conditionSetDomainObject = undefined;
|
||||
this.conditionalStyles = [];
|
||||
let domainObjectStyles = (this.domainObject.configuration && this.domainObject.configuration.objectStyles) || {};
|
||||
let domainObjectStyles = (this.domainObject.configuration && this.domainObject.configuration.objectStyles) || {};
|
||||
if (this.itemId) {
|
||||
domainObjectStyles[this.itemId].conditionSetIdentifier = undefined;
|
||||
domainObjectStyles[this.itemId].selectedConditionId = undefined;
|
||||
@ -302,6 +308,7 @@ export default {
|
||||
domainObjectStyles.styles = undefined;
|
||||
delete domainObjectStyles.styles;
|
||||
}
|
||||
|
||||
if (isEmpty(domainObjectStyles)) {
|
||||
domainObjectStyles = undefined;
|
||||
}
|
||||
@ -314,16 +321,16 @@ export default {
|
||||
},
|
||||
updateDomainObjectItemStyles(newItems) {
|
||||
//check that all items that have been styles still exist. Otherwise delete those styles
|
||||
let domainObjectStyles = (this.domainObject.configuration && this.domainObject.configuration.objectStyles) || {};
|
||||
let domainObjectStyles = (this.domainObject.configuration && this.domainObject.configuration.objectStyles) || {};
|
||||
let itemsToRemove = [];
|
||||
let keys = Object.keys(domainObjectStyles);
|
||||
//TODO: Need an easier way to find which properties are itemIds
|
||||
keys.forEach((key) => {
|
||||
const keyIsItemId = (key !== 'styles') &&
|
||||
(key !== 'staticStyle') &&
|
||||
(key !== 'defaultConditionId') &&
|
||||
(key !== 'selectedConditionId') &&
|
||||
(key !== 'conditionSetIdentifier');
|
||||
const keyIsItemId = (key !== 'styles')
|
||||
&& (key !== 'staticStyle')
|
||||
&& (key !== 'defaultConditionId')
|
||||
&& (key !== 'selectedConditionId')
|
||||
&& (key !== 'conditionSetIdentifier');
|
||||
if (keyIsItemId) {
|
||||
if (!(newItems.find(item => item.id === key))) {
|
||||
itemsToRemove.push(key);
|
||||
@ -344,17 +351,20 @@ export default {
|
||||
if (isEmpty(domainObjectStyles)) {
|
||||
domainObjectStyles = undefined;
|
||||
}
|
||||
|
||||
this.persist(domainObjectStyles);
|
||||
},
|
||||
initializeConditionalStyles() {
|
||||
if (!this.conditions) {
|
||||
this.conditions = {};
|
||||
}
|
||||
|
||||
let conditionalStyles = [];
|
||||
this.conditionSetDomainObject.configuration.conditionCollection.forEach((conditionConfiguration, index) => {
|
||||
if (conditionConfiguration.isDefault) {
|
||||
this.selectedConditionId = conditionConfiguration.id;
|
||||
}
|
||||
|
||||
this.conditions[conditionConfiguration.id] = conditionConfiguration;
|
||||
let foundStyle = this.findStyleByConditionId(conditionConfiguration.id);
|
||||
if (foundStyle) {
|
||||
@ -380,6 +390,7 @@ export default {
|
||||
this.stopProvidingTelemetry();
|
||||
delete this.stopProvidingTelemetry;
|
||||
}
|
||||
|
||||
if (this.conditionSetDomainObject) {
|
||||
this.openmct.telemetry.request(this.conditionSetDomainObject)
|
||||
.then(output => {
|
||||
@ -429,11 +440,12 @@ export default {
|
||||
if (defaultConditionId) {
|
||||
objectStyle.defaultConditionId = defaultConditionId;
|
||||
}
|
||||
|
||||
if (this.conditionSetDomainObject) {
|
||||
objectStyle.conditionSetIdentifier = this.conditionSetDomainObject.identifier;
|
||||
}
|
||||
|
||||
let domainObjectStyles = (this.domainObject.configuration && this.domainObject.configuration.objectStyles) || {};
|
||||
let domainObjectStyles = (this.domainObject.configuration && this.domainObject.configuration.objectStyles) || {};
|
||||
|
||||
if (this.itemId) {
|
||||
domainObjectStyles[this.itemId] = objectStyle;
|
||||
@ -442,7 +454,7 @@ export default {
|
||||
domainObjectStyles = {
|
||||
...domainObjectStyles,
|
||||
...objectStyle
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return domainObjectStyles;
|
||||
@ -458,5 +470,5 @@ export default {
|
||||
this.openmct.objects.mutate(this.domainObject, 'configuration.objectStyles', style);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -67,7 +67,7 @@ export default {
|
||||
isEditing: this.openmct.editor.isEditing(),
|
||||
mixedStyles: [],
|
||||
isStaticAndConditionalStyles: false
|
||||
}
|
||||
};
|
||||
},
|
||||
destroyed() {
|
||||
this.removeListeners();
|
||||
@ -113,6 +113,7 @@ export default {
|
||||
this.isStaticAndConditionalStyles = this.hasConditionalStyles(domainObject, layoutItem.id);
|
||||
}
|
||||
}
|
||||
|
||||
itemInitialStyles.push(itemStyle);
|
||||
});
|
||||
const {styles, mixedStyles} = getConsolidatedStyleValues(itemInitialStyles);
|
||||
@ -132,9 +133,9 @@ export default {
|
||||
//check that all items that have been styles still exist. Otherwise delete those styles
|
||||
let keys = Object.keys(this.domainObject.configuration.objectStyles || {});
|
||||
keys.forEach((key) => {
|
||||
if ((key !== 'styles') &&
|
||||
(key !== 'staticStyle') &&
|
||||
(key !== 'conditionSetIdentifier')) {
|
||||
if ((key !== 'styles')
|
||||
&& (key !== 'staticStyle')
|
||||
&& (key !== 'conditionSetIdentifier')) {
|
||||
if (!(newItems.find(item => item.id === key))) {
|
||||
this.removeItemStyles(key);
|
||||
}
|
||||
@ -163,18 +164,21 @@ export default {
|
||||
if (this.stopObserving) {
|
||||
this.stopObserving();
|
||||
}
|
||||
|
||||
if (this.stopObservingItems) {
|
||||
this.stopObservingItems();
|
||||
}
|
||||
|
||||
if (this.unObserveObjects) {
|
||||
this.unObserveObjects.forEach((unObserveObject) => {
|
||||
unObserveObject();
|
||||
});
|
||||
}
|
||||
|
||||
this.unObserveObjects = [];
|
||||
},
|
||||
removeItemStyles(itemId) {
|
||||
let domainObjectStyles = (this.domainObject.configuration && this.domainObject.configuration.objectStyles) || {};
|
||||
let domainObjectStyles = (this.domainObject.configuration && this.domainObject.configuration.objectStyles) || {};
|
||||
if (itemId && domainObjectStyles[itemId]) {
|
||||
domainObjectStyles[itemId] = undefined;
|
||||
delete domainObjectStyles[this.itemId];
|
||||
@ -182,6 +186,7 @@ export default {
|
||||
if (isEmpty(domainObjectStyles)) {
|
||||
domainObjectStyles = undefined;
|
||||
}
|
||||
|
||||
this.persist(this.domainObject, domainObjectStyles);
|
||||
}
|
||||
},
|
||||
@ -217,6 +222,7 @@ export default {
|
||||
this.persist(domainObject, this.getDomainObjectStyle(domainObject, property));
|
||||
});
|
||||
}
|
||||
|
||||
this.isStaticAndConditionalStyles = false;
|
||||
let foundIndex = this.mixedStyles.indexOf(property);
|
||||
if (foundIndex > -1) {
|
||||
@ -224,7 +230,7 @@ export default {
|
||||
}
|
||||
},
|
||||
getDomainObjectStyle(domainObject, property, items) {
|
||||
let domainObjectStyles = (domainObject.configuration && domainObject.configuration.objectStyles) || {};
|
||||
let domainObjectStyles = (domainObject.configuration && domainObject.configuration.objectStyles) || {};
|
||||
|
||||
if (items) {
|
||||
items.forEach(item => {
|
||||
@ -232,6 +238,7 @@ export default {
|
||||
if (domainObjectStyles[item.id] && domainObjectStyles[item.id].staticStyle) {
|
||||
itemStaticStyle = domainObjectStyles[item.id].staticStyle.style;
|
||||
}
|
||||
|
||||
Object.keys(item.applicableStyles).forEach(key => {
|
||||
if (property === key) {
|
||||
itemStaticStyle[key] = this.staticStyle.style[key];
|
||||
@ -240,6 +247,7 @@ export default {
|
||||
if (this.isStaticAndConditionalStyles) {
|
||||
this.removeConditionalStyles(domainObjectStyles, item.id);
|
||||
}
|
||||
|
||||
if (isEmpty(itemStaticStyle)) {
|
||||
itemStaticStyle = undefined;
|
||||
domainObjectStyles[item.id] = undefined;
|
||||
@ -251,11 +259,13 @@ export default {
|
||||
if (!domainObjectStyles.staticStyle) {
|
||||
domainObjectStyles.staticStyle = {
|
||||
style: {}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (this.isStaticAndConditionalStyles) {
|
||||
this.removeConditionalStyles(domainObjectStyles);
|
||||
}
|
||||
|
||||
domainObjectStyles.staticStyle.style[property] = this.staticStyle.style[property];
|
||||
}
|
||||
|
||||
@ -266,5 +276,5 @@ export default {
|
||||
this.openmct.objects.mutate(domainObject, 'configuration.objectStyles', style);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -104,6 +104,7 @@ export default {
|
||||
},
|
||||
borderColorOption() {
|
||||
let value = this.styleItem.style.border.replace('1px solid ', '');
|
||||
|
||||
return {
|
||||
icon: 'icon-line-horz',
|
||||
title: STYLE_CONSTANTS.borderColorTitle,
|
||||
@ -111,10 +112,11 @@ export default {
|
||||
property: 'border',
|
||||
isEditing: this.isEditing,
|
||||
nonSpecific: this.mixedStyles.indexOf('border') > -1
|
||||
}
|
||||
};
|
||||
},
|
||||
backgroundColorOption() {
|
||||
let value = this.styleItem.style.backgroundColor;
|
||||
|
||||
return {
|
||||
icon: 'icon-paint-bucket',
|
||||
title: STYLE_CONSTANTS.backgroundColorTitle,
|
||||
@ -122,10 +124,11 @@ export default {
|
||||
property: 'backgroundColor',
|
||||
isEditing: this.isEditing,
|
||||
nonSpecific: this.mixedStyles.indexOf('backgroundColor') > -1
|
||||
}
|
||||
};
|
||||
},
|
||||
colorOption() {
|
||||
let value = this.styleItem.style.color;
|
||||
|
||||
return {
|
||||
icon: 'icon-font',
|
||||
title: STYLE_CONSTANTS.textColorTitle,
|
||||
@ -133,7 +136,7 @@ export default {
|
||||
property: 'color',
|
||||
isEditing: this.isEditing,
|
||||
nonSpecific: this.mixedStyles.indexOf('color') > -1
|
||||
}
|
||||
};
|
||||
},
|
||||
imageUrlOption() {
|
||||
return {
|
||||
@ -159,7 +162,7 @@ export default {
|
||||
value: {url: this.styleItem.style.imageUrl},
|
||||
isEditing: this.isEditing,
|
||||
nonSpecific: this.mixedStyles.indexOf('imageUrl') > -1
|
||||
}
|
||||
};
|
||||
},
|
||||
isStyleInvisibleOption() {
|
||||
return {
|
||||
@ -178,7 +181,7 @@ export default {
|
||||
title: STYLE_CONSTANTS.visibilityVisible
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
},
|
||||
@ -190,12 +193,14 @@ export default {
|
||||
if (value && value.indexOf('__no_value') > -1) {
|
||||
return value.replace('__no_value', 'transparent');
|
||||
}
|
||||
|
||||
return value;
|
||||
},
|
||||
normalizeValueForStyle(value) {
|
||||
if (value && value === 'transparent') {
|
||||
return '__no_value';
|
||||
}
|
||||
|
||||
return value;
|
||||
},
|
||||
updateStyleValue(value, item) {
|
||||
@ -203,13 +208,15 @@ export default {
|
||||
if (item.property === 'border') {
|
||||
value = '1px solid ' + value;
|
||||
}
|
||||
|
||||
if (value && (value.url !== undefined)) {
|
||||
this.styleItem.style[item.property] = value.url;
|
||||
} else {
|
||||
this.styleItem.style[item.property] = value;
|
||||
}
|
||||
|
||||
this.$emit('persist', this.styleItem, item.property);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -140,7 +140,7 @@ export default {
|
||||
navigateToPath: '',
|
||||
selectedConditionId: '',
|
||||
locked: false
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
allowEditing() {
|
||||
@ -165,6 +165,7 @@ export default {
|
||||
} else {
|
||||
this.initializeStaticStyle();
|
||||
}
|
||||
|
||||
this.openmct.editor.on('isEditing', this.setEditState);
|
||||
},
|
||||
methods: {
|
||||
@ -183,6 +184,7 @@ export default {
|
||||
} else if (this.domainObject.configuration && this.domainObject.configuration.objectStyles) {
|
||||
objectStyles = this.domainObject.configuration.objectStyles;
|
||||
}
|
||||
|
||||
return objectStyles;
|
||||
},
|
||||
setEditState(isEditing) {
|
||||
@ -219,6 +221,7 @@ export default {
|
||||
},
|
||||
hasConditionalStyle(domainObject, layoutItem) {
|
||||
const id = layoutItem ? layoutItem.id : undefined;
|
||||
|
||||
return getConditionSetIdentifierForItem(domainObject, id) !== undefined;
|
||||
},
|
||||
getObjectsAndItemsFromSelection() {
|
||||
@ -265,6 +268,7 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
itemInitialStyles.push(itemStyle);
|
||||
});
|
||||
this.isStaticAndConditionalStyles = this.isMultipleSelection && itemsWithConditionalStyles;
|
||||
@ -292,11 +296,11 @@ export default {
|
||||
});
|
||||
},
|
||||
isKeyItemId(key) {
|
||||
return (key !== 'styles') &&
|
||||
(key !== 'staticStyle') &&
|
||||
(key !== 'defaultConditionId') &&
|
||||
(key !== 'selectedConditionId') &&
|
||||
(key !== 'conditionSetIdentifier');
|
||||
return (key !== 'styles')
|
||||
&& (key !== 'staticStyle')
|
||||
&& (key !== 'defaultConditionId')
|
||||
&& (key !== 'selectedConditionId')
|
||||
&& (key !== 'conditionSetIdentifier');
|
||||
},
|
||||
registerListener(domainObject) {
|
||||
let id = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
@ -320,6 +324,7 @@ export default {
|
||||
if (this.stopObserving) {
|
||||
this.stopObserving();
|
||||
}
|
||||
|
||||
if (this.stopObservingItems) {
|
||||
this.stopObservingItems();
|
||||
}
|
||||
@ -334,6 +339,7 @@ export default {
|
||||
unObserveObject();
|
||||
});
|
||||
}
|
||||
|
||||
this.unObserveObjects = [];
|
||||
},
|
||||
subscribeToConditionSet() {
|
||||
@ -341,6 +347,7 @@ export default {
|
||||
this.stopProvidingTelemetry();
|
||||
delete this.stopProvidingTelemetry;
|
||||
}
|
||||
|
||||
if (this.conditionSetDomainObject) {
|
||||
this.openmct.telemetry.request(this.conditionSetDomainObject)
|
||||
.then(output => {
|
||||
@ -364,11 +371,13 @@ export default {
|
||||
if (!this.conditions) {
|
||||
this.conditions = {};
|
||||
}
|
||||
|
||||
let conditionalStyles = [];
|
||||
this.conditionSetDomainObject.configuration.conditionCollection.forEach((conditionConfiguration, index) => {
|
||||
if (conditionConfiguration.isDefault) {
|
||||
this.selectedConditionId = conditionConfiguration.id;
|
||||
}
|
||||
|
||||
this.conditions[conditionConfiguration.id] = conditionConfiguration;
|
||||
let foundStyle = this.findStyleByConditionId(conditionConfiguration.id);
|
||||
if (foundStyle) {
|
||||
@ -403,13 +412,14 @@ export default {
|
||||
}
|
||||
},
|
||||
removeItemStyles(itemId) {
|
||||
let domainObjectStyles = (this.domainObject.configuration && this.domainObject.configuration.objectStyles) || {};
|
||||
let domainObjectStyles = (this.domainObject.configuration && this.domainObject.configuration.objectStyles) || {};
|
||||
if (itemId && domainObjectStyles[itemId]) {
|
||||
delete domainObjectStyles[itemId];
|
||||
|
||||
if (Object.keys(domainObjectStyles).length <= 0) {
|
||||
domainObjectStyles = undefined;
|
||||
}
|
||||
|
||||
this.persist(this.domainObject, domainObjectStyles);
|
||||
}
|
||||
},
|
||||
@ -426,6 +436,7 @@ export default {
|
||||
conditionSetDomainObject = item;
|
||||
}
|
||||
};
|
||||
|
||||
const dismissDialog = (overlay, initialize) => {
|
||||
overlay.dismiss();
|
||||
if (initialize && conditionSetDomainObject) {
|
||||
@ -434,6 +445,7 @@ export default {
|
||||
this.initializeConditionalStyles();
|
||||
}
|
||||
};
|
||||
|
||||
let vm = new Vue({
|
||||
provide: {
|
||||
openmct: this.openmct
|
||||
@ -442,7 +454,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
handleItemSelection
|
||||
}
|
||||
};
|
||||
},
|
||||
template: '<condition-set-selector-dialog @conditionSetSelected="handleItemSelection"></condition-set-selector-dialog>'
|
||||
}).$mount();
|
||||
@ -467,18 +479,20 @@ export default {
|
||||
removeConditionSet() {
|
||||
this.conditionSetDomainObject = undefined;
|
||||
this.conditionalStyles = [];
|
||||
let domainObjectStyles = (this.domainObject.configuration && this.domainObject.configuration.objectStyles) || {};
|
||||
let domainObjectStyles = (this.domainObject.configuration && this.domainObject.configuration.objectStyles) || {};
|
||||
if (this.domainObjectsById) {
|
||||
const domainObjects = Object.values(this.domainObjectsById);
|
||||
domainObjects.forEach(domainObject => {
|
||||
let objectStyles = (domainObject.configuration && domainObject.configuration.objectStyles) || {};
|
||||
let objectStyles = (domainObject.configuration && domainObject.configuration.objectStyles) || {};
|
||||
this.removeConditionalStyles(objectStyles);
|
||||
if (objectStyles && Object.keys(objectStyles).length <= 0) {
|
||||
objectStyles = undefined;
|
||||
}
|
||||
|
||||
this.persist(domainObject, objectStyles);
|
||||
});
|
||||
}
|
||||
|
||||
if (this.items.length) {
|
||||
this.items.forEach((item) => {
|
||||
const itemId = item.id;
|
||||
@ -487,12 +501,14 @@ export default {
|
||||
delete domainObjectStyles[itemId];
|
||||
}
|
||||
});
|
||||
} else {
|
||||
} else {
|
||||
this.removeConditionalStyles(domainObjectStyles);
|
||||
}
|
||||
|
||||
if (domainObjectStyles && Object.keys(domainObjectStyles).length <= 0) {
|
||||
domainObjectStyles = undefined;
|
||||
}
|
||||
|
||||
this.persist(this.domainObject, domainObjectStyles);
|
||||
|
||||
if (this.stopProvidingTelemetry) {
|
||||
@ -539,9 +555,11 @@ export default {
|
||||
this.persist(domainObject, this.getDomainObjectStyle(domainObject, property, null, defaultConditionId));
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.items.length && !this.domainObjectsById) {
|
||||
this.persist(this.domainObject, this.getDomainObjectStyle(this.domainObject, property, null, defaultConditionId));
|
||||
}
|
||||
|
||||
this.isStaticAndConditionalStyles = false;
|
||||
if (property) {
|
||||
let foundIndex = this.mixedStyles.indexOf(property);
|
||||
@ -559,10 +577,12 @@ export default {
|
||||
if (defaultConditionId) {
|
||||
objectStyle.defaultConditionId = defaultConditionId;
|
||||
}
|
||||
|
||||
if (this.conditionSetDomainObject) {
|
||||
objectStyle.conditionSetIdentifier = this.conditionSetDomainObject.identifier;
|
||||
}
|
||||
let domainObjectStyles = (domainObject.configuration && domainObject.configuration.objectStyles) || {};
|
||||
|
||||
let domainObjectStyles = (domainObject.configuration && domainObject.configuration.objectStyles) || {};
|
||||
|
||||
if (items) {
|
||||
items.forEach(item => {
|
||||
@ -572,12 +592,15 @@ export default {
|
||||
if (domainObjectStyles[item.id] && domainObjectStyles[item.id].staticStyle) {
|
||||
itemStaticStyle = Object.assign({}, domainObjectStyles[item.id].staticStyle.style);
|
||||
}
|
||||
|
||||
if (item.applicableStyles[property] !== undefined) {
|
||||
itemStaticStyle[property] = this.staticStyle.style[property];
|
||||
}
|
||||
|
||||
if (Object.keys(itemStaticStyle).length <= 0) {
|
||||
itemStaticStyle = undefined;
|
||||
}
|
||||
|
||||
domainObjectStyles[item.id] = { staticStyle: { style: itemStaticStyle } };
|
||||
} else {
|
||||
objectStyle.styles.forEach((conditionalStyle, index) => {
|
||||
@ -614,5 +637,5 @@ export default {
|
||||
this.openmct.objects.mutate(domainObject, 'configuration.objectStyles', style);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -51,14 +51,15 @@ export default class AllTelemetryCriterion extends TelemetryCriterion {
|
||||
if (!this.stalenessSubscription) {
|
||||
this.stalenessSubscription = {};
|
||||
}
|
||||
|
||||
Object.values(telemetryObjects).forEach((telemetryObject) => {
|
||||
const id = this.openmct.objects.makeKeyString(telemetryObject.identifier);
|
||||
if (!this.stalenessSubscription[id]) {
|
||||
this.stalenessSubscription[id] = subscribeForStaleness((data) => {
|
||||
this.handleStaleTelemetry(id, data);
|
||||
}, this.input[0]*1000);
|
||||
}, this.input[0] * 1000);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
handleStaleTelemetry(id, data) {
|
||||
@ -66,6 +67,7 @@ export default class AllTelemetryCriterion extends TelemetryCriterion {
|
||||
this.telemetryDataCache[id] = true;
|
||||
this.result = evaluateResults(Object.values(this.telemetryDataCache), this.telemetry);
|
||||
}
|
||||
|
||||
this.emitEvent('telemetryIsStale', data);
|
||||
}
|
||||
|
||||
@ -116,9 +118,10 @@ export default class AllTelemetryCriterion extends TelemetryCriterion {
|
||||
|
||||
if (data) {
|
||||
this.openmct.time.getAllTimeSystems().forEach(timeSystem => {
|
||||
datum[timeSystem.key] = data[timeSystem.key]
|
||||
datum[timeSystem.key] = data[timeSystem.key];
|
||||
});
|
||||
}
|
||||
|
||||
return datum;
|
||||
}
|
||||
|
||||
@ -130,6 +133,7 @@ export default class AllTelemetryCriterion extends TelemetryCriterion {
|
||||
if (this.stalenessSubscription && this.stalenessSubscription[validatedData.id]) {
|
||||
this.stalenessSubscription[validatedData.id].update(validatedData);
|
||||
}
|
||||
|
||||
this.telemetryDataCache[validatedData.id] = false;
|
||||
} else {
|
||||
this.telemetryDataCache[validatedData.id] = this.computeResult(validatedData);
|
||||
@ -164,6 +168,7 @@ export default class AllTelemetryCriterion extends TelemetryCriterion {
|
||||
));
|
||||
|
||||
let telemetryDataCache = {};
|
||||
|
||||
return Promise.all(telemetryRequests)
|
||||
.then(telemetryRequestsResults => {
|
||||
let latestTimestamp;
|
||||
@ -203,7 +208,7 @@ export default class AllTelemetryCriterion extends TelemetryCriterion {
|
||||
let inputValue = this.input;
|
||||
if (this.metadata) {
|
||||
const telemetryObjects = Object.values(this.telemetryObjects);
|
||||
for (let i=0; i < telemetryObjects.length; i++) {
|
||||
for (let i = 0; i < telemetryObjects.length; i++) {
|
||||
const telemetryObject = telemetryObjects[i];
|
||||
const metadataObject = this.getMetaDataObject(telemetryObject, this.metadata);
|
||||
if (metadataObject) {
|
||||
@ -213,6 +218,7 @@ export default class AllTelemetryCriterion extends TelemetryCriterion {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return `${telemetryDescription} ${metadataValue} ${getOperatorText(this.operation, inputValue)}`;
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ export default class TelemetryCriterion extends EventEmitter {
|
||||
this.telemetryObjectIdAsString = this.openmct.objects.makeKeyString(this.telemetryDomainObjectDefinition.telemetry);
|
||||
this.updateTelemetryObjects(this.telemetryDomainObjectDefinition.telemetryObjects);
|
||||
if (this.isValid() && this.isStalenessCheck() && this.isValidInput()) {
|
||||
this.subscribeForStaleData()
|
||||
this.subscribeForStaleData();
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,7 +62,8 @@ export default class TelemetryCriterion extends EventEmitter {
|
||||
if (this.stalenessSubscription) {
|
||||
this.stalenessSubscription.clear();
|
||||
}
|
||||
this.stalenessSubscription = subscribeForStaleness(this.handleStaleTelemetry.bind(this), this.input[0]*1000);
|
||||
|
||||
this.stalenessSubscription = subscribeForStaleness(this.handleStaleTelemetry.bind(this), this.input[0] * 1000);
|
||||
}
|
||||
|
||||
handleStaleTelemetry(data) {
|
||||
@ -85,7 +86,7 @@ export default class TelemetryCriterion extends EventEmitter {
|
||||
updateTelemetryObjects(telemetryObjects) {
|
||||
this.telemetryObject = telemetryObjects[this.telemetryObjectIdAsString];
|
||||
if (this.isValid() && this.isStalenessCheck() && this.isValidInput()) {
|
||||
this.subscribeForStaleData()
|
||||
this.subscribeForStaleData();
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,6 +97,7 @@ export default class TelemetryCriterion extends EventEmitter {
|
||||
const normalizedDatum = Object.values(metadata).reduce((datum, metadatum) => {
|
||||
const formatter = this.openmct.telemetry.getValueFormatter(metadatum);
|
||||
datum[metadatum.key] = formatter.parse(telemetryDatum[metadatum.source]);
|
||||
|
||||
return datum;
|
||||
}, {});
|
||||
|
||||
@ -111,9 +113,10 @@ export default class TelemetryCriterion extends EventEmitter {
|
||||
|
||||
if (data) {
|
||||
this.openmct.time.getAllTimeSystems().forEach(timeSystem => {
|
||||
datum[timeSystem.key] = data[timeSystem.key]
|
||||
datum[timeSystem.key] = data[timeSystem.key];
|
||||
});
|
||||
}
|
||||
|
||||
return datum;
|
||||
}
|
||||
|
||||
@ -123,6 +126,7 @@ export default class TelemetryCriterion extends EventEmitter {
|
||||
if (this.stalenessSubscription) {
|
||||
this.stalenessSubscription.update(validatedData);
|
||||
}
|
||||
|
||||
this.result = false;
|
||||
} else {
|
||||
this.result = this.computeResult(validatedData);
|
||||
@ -159,11 +163,12 @@ export default class TelemetryCriterion extends EventEmitter {
|
||||
}
|
||||
|
||||
findOperation(operation) {
|
||||
for (let i=0, ii=OPERATIONS.length; i < ii; i++) {
|
||||
for (let i = 0, ii = OPERATIONS.length; i < ii; i++) {
|
||||
if (operation === OPERATIONS[i].name) {
|
||||
return OPERATIONS[i].operation;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -176,10 +181,12 @@ export default class TelemetryCriterion extends EventEmitter {
|
||||
if (this.isValidInput()) {
|
||||
this.input.forEach(input => params.push(input));
|
||||
}
|
||||
|
||||
if (typeof comparator === 'function') {
|
||||
result = !!comparator(params);
|
||||
result = Boolean(comparator(params));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -196,19 +203,21 @@ export default class TelemetryCriterion extends EventEmitter {
|
||||
const telemetryMetadata = this.openmct.telemetry.getMetadata(telemetryObject);
|
||||
metadataObject = telemetryMetadata.valueMetadatas.find((valueMetadata) => valueMetadata.key === metadata);
|
||||
}
|
||||
|
||||
return metadataObject;
|
||||
}
|
||||
|
||||
getInputValueFromMetaData(metadataObject, input) {
|
||||
let inputValue;
|
||||
if (metadataObject) {
|
||||
if(metadataObject.enumerations && input.length) {
|
||||
if (metadataObject.enumerations && input.length) {
|
||||
const enumeration = metadataObject.enumerations[input[0]];
|
||||
if (enumeration !== undefined && enumeration.string) {
|
||||
inputValue = [enumeration.string];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return inputValue;
|
||||
}
|
||||
|
||||
@ -219,6 +228,7 @@ export default class TelemetryCriterion extends EventEmitter {
|
||||
metadataValue = metadataObject.name;
|
||||
}
|
||||
}
|
||||
|
||||
return metadataValue;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,10 @@ describe("The telemetry criterion", function () {
|
||||
|
||||
beforeEach (() => {
|
||||
testTelemetryObject = {
|
||||
identifier:{ namespace: "", key: "test-object"},
|
||||
identifier: {
|
||||
namespace: "",
|
||||
key: "test-object"
|
||||
},
|
||||
type: "test-object",
|
||||
name: "Test Object",
|
||||
telemetry: {
|
||||
@ -76,7 +79,10 @@ describe("The telemetry criterion", function () {
|
||||
['timeSystem', 'bounds', 'getAllTimeSystems']
|
||||
);
|
||||
openmct.time.timeSystem.and.returnValue({key: 'system'});
|
||||
openmct.time.bounds.and.returnValue({start: 0, end: 1});
|
||||
openmct.time.bounds.and.returnValue({
|
||||
start: 0,
|
||||
end: 1
|
||||
});
|
||||
openmct.time.getAllTimeSystems.and.returnValue([{key: 'system'}]);
|
||||
|
||||
testCriterionDefinition = {
|
||||
@ -122,6 +128,7 @@ describe("The telemetry criterion", function () {
|
||||
setTimeout(() => {
|
||||
telemetryRequestResolve(mockTelemetry);
|
||||
}, 100);
|
||||
|
||||
return telemetryRequestPromise;
|
||||
});
|
||||
});
|
||||
|
@ -64,5 +64,5 @@ export default function ConditionPlugin() {
|
||||
openmct.telemetry.addProvider(new ConditionSetTelemetryProvider(openmct));
|
||||
openmct.objectViews.addProvider(new ConditionSetViewProvider(openmct));
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -42,7 +42,10 @@ describe('the plugin', function () {
|
||||
|
||||
beforeEach((done) => {
|
||||
testTelemetryObject = {
|
||||
identifier:{ namespace: "", key: "test-object"},
|
||||
identifier: {
|
||||
namespace: "",
|
||||
key: "test-object"
|
||||
},
|
||||
type: "test-object",
|
||||
name: "Test Object",
|
||||
telemetry: {
|
||||
@ -121,7 +124,7 @@ describe('the plugin', function () {
|
||||
|
||||
it('provides a view', () => {
|
||||
const testViewObject = {
|
||||
id:"test-object",
|
||||
id: "test-object",
|
||||
type: "conditionSet",
|
||||
configuration: {
|
||||
conditionCollection: []
|
||||
@ -143,142 +146,142 @@ describe('the plugin', function () {
|
||||
let component;
|
||||
let styleViewComponentObject;
|
||||
const conditionSetDomainObject = {
|
||||
"configuration":{
|
||||
"conditionTestData":[
|
||||
"configuration": {
|
||||
"conditionTestData": [
|
||||
{
|
||||
"telemetry":"",
|
||||
"metadata":"",
|
||||
"input":""
|
||||
"telemetry": "",
|
||||
"metadata": "",
|
||||
"input": ""
|
||||
}
|
||||
],
|
||||
"conditionCollection":[
|
||||
"conditionCollection": [
|
||||
{
|
||||
"id":"39584410-cbf9-499e-96dc-76f27e69885d",
|
||||
"configuration":{
|
||||
"name":"Unnamed Condition",
|
||||
"output":"Sine > 0",
|
||||
"trigger":"all",
|
||||
"criteria":[
|
||||
"id": "39584410-cbf9-499e-96dc-76f27e69885d",
|
||||
"configuration": {
|
||||
"name": "Unnamed Condition",
|
||||
"output": "Sine > 0",
|
||||
"trigger": "all",
|
||||
"criteria": [
|
||||
{
|
||||
"id":"85fbb2f7-7595-42bd-9767-a932266c5225",
|
||||
"telemetry":{
|
||||
"namespace":"",
|
||||
"key":"be0ba97f-b510-4f40-a18d-4ff121d5ea1a"
|
||||
"id": "85fbb2f7-7595-42bd-9767-a932266c5225",
|
||||
"telemetry": {
|
||||
"namespace": "",
|
||||
"key": "be0ba97f-b510-4f40-a18d-4ff121d5ea1a"
|
||||
},
|
||||
"operation":"greaterThan",
|
||||
"input":[
|
||||
"operation": "greaterThan",
|
||||
"input": [
|
||||
"0"
|
||||
],
|
||||
"metadata":"sin"
|
||||
"metadata": "sin"
|
||||
},
|
||||
{
|
||||
"id":"35400132-63b0-425c-ac30-8197df7d5862",
|
||||
"telemetry":"any",
|
||||
"operation":"enumValueIs",
|
||||
"input":[
|
||||
"id": "35400132-63b0-425c-ac30-8197df7d5862",
|
||||
"telemetry": "any",
|
||||
"operation": "enumValueIs",
|
||||
"input": [
|
||||
"0"
|
||||
],
|
||||
"metadata":"state"
|
||||
"metadata": "state"
|
||||
}
|
||||
]
|
||||
},
|
||||
"summary":"Match if all criteria are met: Sine Wave Generator Sine > 0 and any telemetry State is OFF "
|
||||
"summary": "Match if all criteria are met: Sine Wave Generator Sine > 0 and any telemetry State is OFF "
|
||||
},
|
||||
{
|
||||
"isDefault":true,
|
||||
"id":"2532d90a-e0d6-4935-b546-3123522da2de",
|
||||
"configuration":{
|
||||
"name":"Default",
|
||||
"output":"Default",
|
||||
"trigger":"all",
|
||||
"criteria":[
|
||||
"isDefault": true,
|
||||
"id": "2532d90a-e0d6-4935-b546-3123522da2de",
|
||||
"configuration": {
|
||||
"name": "Default",
|
||||
"output": "Default",
|
||||
"trigger": "all",
|
||||
"criteria": [
|
||||
]
|
||||
},
|
||||
"summary":""
|
||||
"summary": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"composition":[
|
||||
"composition": [
|
||||
{
|
||||
"namespace":"",
|
||||
"key":"be0ba97f-b510-4f40-a18d-4ff121d5ea1a"
|
||||
"namespace": "",
|
||||
"key": "be0ba97f-b510-4f40-a18d-4ff121d5ea1a"
|
||||
},
|
||||
{
|
||||
"namespace":"",
|
||||
"key":"077ffa67-e78f-4e99-80e0-522ac33a3888"
|
||||
"namespace": "",
|
||||
"key": "077ffa67-e78f-4e99-80e0-522ac33a3888"
|
||||
}
|
||||
],
|
||||
"telemetry":{
|
||||
"telemetry": {
|
||||
},
|
||||
"name":"Condition Set",
|
||||
"type":"conditionSet",
|
||||
"identifier":{
|
||||
"namespace":"",
|
||||
"key":"863012c1-f6ca-4ab0-aed7-fd43d5e4cd12"
|
||||
"name": "Condition Set",
|
||||
"type": "conditionSet",
|
||||
"identifier": {
|
||||
"namespace": "",
|
||||
"key": "863012c1-f6ca-4ab0-aed7-fd43d5e4cd12"
|
||||
}
|
||||
|
||||
};
|
||||
const staticStyle = {
|
||||
"style":{
|
||||
"backgroundColor":"#717171",
|
||||
"border":"1px solid #00ffff"
|
||||
"style": {
|
||||
"backgroundColor": "#717171",
|
||||
"border": "1px solid #00ffff"
|
||||
}
|
||||
};
|
||||
const conditionalStyle = {
|
||||
"conditionId":"39584410-cbf9-499e-96dc-76f27e69885d",
|
||||
"style":{
|
||||
"isStyleInvisible":"",
|
||||
"backgroundColor":"#717171",
|
||||
"border":"1px solid #ffff00"
|
||||
"conditionId": "39584410-cbf9-499e-96dc-76f27e69885d",
|
||||
"style": {
|
||||
"isStyleInvisible": "",
|
||||
"backgroundColor": "#717171",
|
||||
"border": "1px solid #ffff00"
|
||||
}
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
displayLayoutItem = {
|
||||
"composition":[
|
||||
"composition": [
|
||||
],
|
||||
"configuration":{
|
||||
"items":[
|
||||
"configuration": {
|
||||
"items": [
|
||||
{
|
||||
"fill":"#717171",
|
||||
"stroke":"",
|
||||
"x":1,
|
||||
"y":1,
|
||||
"width":10,
|
||||
"height":5,
|
||||
"type":"box-view",
|
||||
"id":"89b88746-d325-487b-aec4-11b79afff9e8"
|
||||
"fill": "#717171",
|
||||
"stroke": "",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"width": 10,
|
||||
"height": 5,
|
||||
"type": "box-view",
|
||||
"id": "89b88746-d325-487b-aec4-11b79afff9e8"
|
||||
},
|
||||
{
|
||||
"x":18,
|
||||
"y":9,
|
||||
"x2":23,
|
||||
"y2":4,
|
||||
"stroke":"#717171",
|
||||
"type":"line-view",
|
||||
"id":"57d49a28-7863-43bd-9593-6570758916f0"
|
||||
"x": 18,
|
||||
"y": 9,
|
||||
"x2": 23,
|
||||
"y2": 4,
|
||||
"stroke": "#717171",
|
||||
"type": "line-view",
|
||||
"id": "57d49a28-7863-43bd-9593-6570758916f0"
|
||||
}
|
||||
],
|
||||
"layoutGrid":[
|
||||
"layoutGrid": [
|
||||
10,
|
||||
10
|
||||
]
|
||||
},
|
||||
"name":"Display Layout",
|
||||
"type":"layout",
|
||||
"identifier":{
|
||||
"namespace":"",
|
||||
"key":"c5e636c1-6771-4c9c-b933-8665cab189b3"
|
||||
"name": "Display Layout",
|
||||
"type": "layout",
|
||||
"identifier": {
|
||||
"namespace": "",
|
||||
"key": "c5e636c1-6771-4c9c-b933-8665cab189b3"
|
||||
}
|
||||
};
|
||||
lineLayoutItem = {
|
||||
"x":18,
|
||||
"y":9,
|
||||
"x2":23,
|
||||
"y2":4,
|
||||
"stroke":"#717171",
|
||||
"type":"line-view",
|
||||
"id":"57d49a28-7863-43bd-9593-6570758916f0"
|
||||
"x": 18,
|
||||
"y": 9,
|
||||
"x2": 23,
|
||||
"y2": 4,
|
||||
"stroke": "#717171",
|
||||
"type": "line-view",
|
||||
"id": "57d49a28-7863-43bd-9593-6570758916f0"
|
||||
};
|
||||
boxLayoutItem = {
|
||||
"fill": "#717171",
|
||||
@ -294,13 +297,13 @@ describe('the plugin', function () {
|
||||
[{
|
||||
context: {
|
||||
"layoutItem": lineLayoutItem,
|
||||
"index":1
|
||||
"index": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
context: {
|
||||
"item": displayLayoutItem,
|
||||
"supportsMultiSelect":true
|
||||
"supportsMultiSelect": true
|
||||
}
|
||||
}],
|
||||
[{
|
||||
@ -312,7 +315,7 @@ describe('the plugin', function () {
|
||||
{
|
||||
context: {
|
||||
item: displayLayoutItem,
|
||||
"supportsMultiSelect":true
|
||||
"supportsMultiSelect": true
|
||||
}
|
||||
}]
|
||||
];
|
||||
@ -329,6 +332,7 @@ describe('the plugin', function () {
|
||||
},
|
||||
template: '<styles-view/>'
|
||||
});
|
||||
|
||||
return Vue.nextTick().then(() => {
|
||||
styleViewComponentObject = component.$root.$children[0];
|
||||
styleViewComponentObject.setEditState(true);
|
||||
@ -352,6 +356,7 @@ describe('the plugin', function () {
|
||||
styleViewComponentObject.initializeConditionalStyles();
|
||||
expect(styleViewComponentObject.conditionalStyles.length).toBe(2);
|
||||
styleViewComponentObject.updateConditionalStyle(conditionalStyle, 'border');
|
||||
|
||||
return Vue.nextTick().then(() => {
|
||||
expect(styleViewComponentObject.domainObject.configuration.objectStyles).toBeDefined();
|
||||
[boxLayoutItem, lineLayoutItem].forEach((item) => {
|
||||
@ -373,6 +378,7 @@ describe('the plugin', function () {
|
||||
|
||||
it('updates applicable static styles', () => {
|
||||
styleViewComponentObject.updateStaticStyle(staticStyle, 'border');
|
||||
|
||||
return Vue.nextTick().then(() => {
|
||||
expect(styleViewComponentObject.domainObject.configuration.objectStyles).toBeDefined();
|
||||
[boxLayoutItem, lineLayoutItem].forEach((item) => {
|
||||
@ -393,64 +399,64 @@ describe('the plugin', function () {
|
||||
describe('the condition check for staleness', () => {
|
||||
let conditionSetDomainObject;
|
||||
|
||||
beforeEach(()=>{
|
||||
beforeEach(() => {
|
||||
conditionSetDomainObject = {
|
||||
"configuration":{
|
||||
"conditionTestData":[
|
||||
"configuration": {
|
||||
"conditionTestData": [
|
||||
{
|
||||
"telemetry":"",
|
||||
"metadata":"",
|
||||
"input":""
|
||||
"telemetry": "",
|
||||
"metadata": "",
|
||||
"input": ""
|
||||
}
|
||||
],
|
||||
"conditionCollection":[
|
||||
"conditionCollection": [
|
||||
{
|
||||
"id":"39584410-cbf9-499e-96dc-76f27e69885d",
|
||||
"configuration":{
|
||||
"name":"Unnamed Condition",
|
||||
"output":"Any stale telemetry",
|
||||
"trigger":"all",
|
||||
"criteria":[
|
||||
"id": "39584410-cbf9-499e-96dc-76f27e69885d",
|
||||
"configuration": {
|
||||
"name": "Unnamed Condition",
|
||||
"output": "Any stale telemetry",
|
||||
"trigger": "all",
|
||||
"criteria": [
|
||||
{
|
||||
"id":"35400132-63b0-425c-ac30-8197df7d5862",
|
||||
"telemetry":"any",
|
||||
"operation":"isStale",
|
||||
"input":[
|
||||
"1"
|
||||
"id": "35400132-63b0-425c-ac30-8197df7d5862",
|
||||
"telemetry": "any",
|
||||
"operation": "isStale",
|
||||
"input": [
|
||||
"0.2"
|
||||
],
|
||||
"metadata":"dataReceived"
|
||||
"metadata": "dataReceived"
|
||||
}
|
||||
]
|
||||
},
|
||||
"summary":"Match if all criteria are met: Any telemetry is stale after 5 seconds"
|
||||
"summary": "Match if all criteria are met: Any telemetry is stale after 5 seconds"
|
||||
},
|
||||
{
|
||||
"isDefault":true,
|
||||
"id":"2532d90a-e0d6-4935-b546-3123522da2de",
|
||||
"configuration":{
|
||||
"name":"Default",
|
||||
"output":"Default",
|
||||
"trigger":"all",
|
||||
"criteria":[
|
||||
"isDefault": true,
|
||||
"id": "2532d90a-e0d6-4935-b546-3123522da2de",
|
||||
"configuration": {
|
||||
"name": "Default",
|
||||
"output": "Default",
|
||||
"trigger": "all",
|
||||
"criteria": [
|
||||
]
|
||||
},
|
||||
"summary":""
|
||||
"summary": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"composition":[
|
||||
"composition": [
|
||||
{
|
||||
"namespace":"",
|
||||
"key":"test-object"
|
||||
"namespace": "",
|
||||
"key": "test-object"
|
||||
}
|
||||
],
|
||||
"telemetry":{
|
||||
"telemetry": {
|
||||
},
|
||||
"name":"Condition Set",
|
||||
"type":"conditionSet",
|
||||
"identifier":{
|
||||
"namespace":"",
|
||||
"key":"cf4456a9-296a-4e6b-b182-62ed29cd15b9"
|
||||
"name": "Condition Set",
|
||||
"type": "conditionSet",
|
||||
"identifier": {
|
||||
"namespace": "",
|
||||
"key": "cf4456a9-296a-4e6b-b182-62ed29cd15b9"
|
||||
}
|
||||
|
||||
};
|
||||
@ -467,17 +473,20 @@ describe('the plugin', function () {
|
||||
setTimeout(() => {
|
||||
expect(mockListener).toHaveBeenCalledWith({
|
||||
output: 'Any stale telemetry',
|
||||
id: { namespace: '', key: 'cf4456a9-296a-4e6b-b182-62ed29cd15b9' },
|
||||
id: {
|
||||
namespace: '',
|
||||
key: 'cf4456a9-296a-4e6b-b182-62ed29cd15b9'
|
||||
},
|
||||
conditionId: '39584410-cbf9-499e-96dc-76f27e69885d',
|
||||
utc: undefined
|
||||
});
|
||||
done();
|
||||
}, 1500);
|
||||
}, 300);
|
||||
});
|
||||
|
||||
it('should not evaluate as stale when telemetry is received in the allotted time', (done) => {
|
||||
const date = Date.now();
|
||||
conditionSetDomainObject.configuration.conditionCollection[0].configuration.criteria[0].input = ["2"];
|
||||
conditionSetDomainObject.configuration.conditionCollection[0].configuration.criteria[0].input = ["0.4"];
|
||||
let conditionMgr = new ConditionManager(conditionSetDomainObject, openmct);
|
||||
conditionMgr.on('conditionSetResultUpdated', mockListener);
|
||||
conditionMgr.telemetryObjects = {
|
||||
@ -490,12 +499,15 @@ describe('the plugin', function () {
|
||||
setTimeout(() => {
|
||||
expect(mockListener).toHaveBeenCalledWith({
|
||||
output: 'Default',
|
||||
id: { namespace: '', key: 'cf4456a9-296a-4e6b-b182-62ed29cd15b9' },
|
||||
id: {
|
||||
namespace: '',
|
||||
key: 'cf4456a9-296a-4e6b-b182-62ed29cd15b9'
|
||||
},
|
||||
conditionId: '2532d90a-e0d6-4935-b546-3123522da2de',
|
||||
utc: undefined
|
||||
});
|
||||
done();
|
||||
}, 1500);
|
||||
}, 300);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -31,7 +31,7 @@ export const evaluateResults = (results, trigger) => {
|
||||
} else {
|
||||
return matchAny(results);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function matchAll(results) {
|
||||
for (const result of results) {
|
||||
@ -59,6 +59,7 @@ function matchExact(results, target) {
|
||||
if (result === true) {
|
||||
matches++;
|
||||
}
|
||||
|
||||
if (matches > target) {
|
||||
return false;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user