mirror of
https://github.com/nasa/openmct.git
synced 2025-06-17 22:58:14 +00:00
feat: AMD -> ES6 (#7029)
* feat: full amd -> es6 conversion * fix: move MCT to ES6 class * fix: default drop, correct imports * fix: correct all imports * fix: property typo * fix: avoid anonymous functions * fix: correct typo scarily small - can see why this e2e coverage issue is high priority * fix: use proper uuid format * style: fmt * fix: import vue correctly, get correct layout * fix: createApp without JSON fixes template issues * fix: don't use default on InspectorDataVisualization * fix: remove more .default calls * Update src/api/api.js Co-authored-by: Jesse Mazzella <ozyx@users.noreply.github.com> * Update src/plugins/plugins.js Co-authored-by: Jesse Mazzella <ozyx@users.noreply.github.com> * Update src/plugins/plugins.js Co-authored-by: Jesse Mazzella <ozyx@users.noreply.github.com> * fix: suggestions * fix: drop unnecessary this.annotation initialization * fix: move all initialization calls to constructor * refactor: move vue dist import to webpack alias --------- Co-authored-by: Jesse Mazzella <ozyx@users.noreply.github.com>
This commit is contained in:
@ -20,24 +20,24 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
'./actions/ActionsAPI',
|
||||
'./composition/CompositionAPI',
|
||||
'./Editor',
|
||||
'./faultmanagement/FaultManagementAPI',
|
||||
'./forms/FormsAPI',
|
||||
'./indicators/IndicatorAPI',
|
||||
'./menu/MenuAPI',
|
||||
'./notifications/NotificationAPI',
|
||||
'./objects/ObjectAPI',
|
||||
'./priority/PriorityAPI',
|
||||
'./status/StatusAPI',
|
||||
'./telemetry/TelemetryAPI',
|
||||
'./time/TimeAPI',
|
||||
'./types/TypeRegistry',
|
||||
'./user/UserAPI',
|
||||
'./annotation/AnnotationAPI'
|
||||
], function (
|
||||
import ActionsAPI from './actions/ActionsAPI';
|
||||
import AnnotationAPI from './annotation/AnnotationAPI';
|
||||
import CompositionAPI from './composition/CompositionAPI';
|
||||
import EditorAPI from './Editor';
|
||||
import FaultManagementAPI from './faultmanagement/FaultManagementAPI';
|
||||
import FormsAPI from './forms/FormsAPI';
|
||||
import IndicatorAPI from './indicators/IndicatorAPI';
|
||||
import MenuAPI from './menu/MenuAPI';
|
||||
import NotificationAPI from './notifications/NotificationAPI';
|
||||
import ObjectAPI from './objects/ObjectAPI';
|
||||
import PriorityAPI from './priority/PriorityAPI';
|
||||
import StatusAPI from './status/StatusAPI';
|
||||
import TelemetryAPI from './telemetry/TelemetryAPI';
|
||||
import TimeAPI from './time/TimeAPI';
|
||||
import TypeRegistry from './types/TypeRegistry';
|
||||
import UserAPI from './user/UserAPI';
|
||||
|
||||
export default {
|
||||
ActionsAPI,
|
||||
CompositionAPI,
|
||||
EditorAPI,
|
||||
@ -54,23 +54,4 @@ define([
|
||||
TypeRegistry,
|
||||
UserAPI,
|
||||
AnnotationAPI
|
||||
) {
|
||||
return {
|
||||
ActionsAPI: ActionsAPI.default,
|
||||
CompositionAPI: CompositionAPI,
|
||||
EditorAPI: EditorAPI,
|
||||
FaultManagementAPI: FaultManagementAPI,
|
||||
FormsAPI: FormsAPI,
|
||||
IndicatorAPI: IndicatorAPI.default,
|
||||
MenuAPI: MenuAPI.default,
|
||||
NotificationAPI: NotificationAPI.default,
|
||||
ObjectAPI: ObjectAPI,
|
||||
PriorityAPI: PriorityAPI.default,
|
||||
StatusAPI: StatusAPI.default,
|
||||
TelemetryAPI: TelemetryAPI,
|
||||
TimeAPI: TimeAPI.default,
|
||||
TypeRegistry: TypeRegistry.default,
|
||||
UserAPI: UserAPI.default,
|
||||
AnnotationAPI: AnnotationAPI.default
|
||||
};
|
||||
});
|
||||
};
|
||||
|
@ -20,163 +20,161 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define([], function () {
|
||||
/**
|
||||
* Utility for checking if a thing is an Open MCT Identifier.
|
||||
* @private
|
||||
*/
|
||||
function isIdentifier(thing) {
|
||||
return (
|
||||
typeof thing === 'object' &&
|
||||
Object.prototype.hasOwnProperty.call(thing, 'key') &&
|
||||
Object.prototype.hasOwnProperty.call(thing, 'namespace')
|
||||
);
|
||||
/**
|
||||
* Utility for checking if a thing is an Open MCT Identifier.
|
||||
* @private
|
||||
*/
|
||||
function isIdentifier(thing) {
|
||||
return (
|
||||
typeof thing === 'object' &&
|
||||
Object.prototype.hasOwnProperty.call(thing, 'key') &&
|
||||
Object.prototype.hasOwnProperty.call(thing, 'namespace')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for checking if a thing is a key string. Not perfect.
|
||||
* @private
|
||||
*/
|
||||
function isKeyString(thing) {
|
||||
return typeof thing === 'string';
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a keyString into an Open MCT Identifier, ex:
|
||||
* 'scratch:root' ==> {namespace: 'scratch', key: 'root'}
|
||||
*
|
||||
* Idempotent.
|
||||
*
|
||||
* @param keyString
|
||||
* @returns identifier
|
||||
*/
|
||||
function parseKeyString(keyString) {
|
||||
if (isIdentifier(keyString)) {
|
||||
return keyString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for checking if a thing is a key string. Not perfect.
|
||||
* @private
|
||||
*/
|
||||
function isKeyString(thing) {
|
||||
return typeof thing === 'string';
|
||||
let namespace = '';
|
||||
let key = keyString;
|
||||
for (let i = 0; i < key.length; i++) {
|
||||
if (key[i] === '\\' && key[i + 1] === ':') {
|
||||
i++; // skip escape character.
|
||||
} else if (key[i] === ':') {
|
||||
key = key.slice(i + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
namespace += key[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a keyString into an Open MCT Identifier, ex:
|
||||
* 'scratch:root' ==> {namespace: 'scratch', key: 'root'}
|
||||
*
|
||||
* Idempotent.
|
||||
*
|
||||
* @param keyString
|
||||
* @returns identifier
|
||||
*/
|
||||
function parseKeyString(keyString) {
|
||||
if (isIdentifier(keyString)) {
|
||||
return keyString;
|
||||
}
|
||||
|
||||
let namespace = '';
|
||||
let key = keyString;
|
||||
for (let i = 0; i < key.length; i++) {
|
||||
if (key[i] === '\\' && key[i + 1] === ':') {
|
||||
i++; // skip escape character.
|
||||
} else if (key[i] === ':') {
|
||||
key = key.slice(i + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
namespace += key[i];
|
||||
}
|
||||
|
||||
if (keyString === namespace) {
|
||||
namespace = '';
|
||||
}
|
||||
|
||||
return {
|
||||
namespace: namespace,
|
||||
key: key
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an Open MCT Identifier into a keyString, ex:
|
||||
* {namespace: 'scratch', key: 'root'} ==> 'scratch:root'
|
||||
*
|
||||
* Idempotent
|
||||
*
|
||||
* @param identifier
|
||||
* @returns keyString
|
||||
*/
|
||||
function makeKeyString(identifier) {
|
||||
if (!identifier) {
|
||||
throw new Error('Cannot make key string from null identifier');
|
||||
}
|
||||
|
||||
if (isKeyString(identifier)) {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
if (!identifier.namespace) {
|
||||
return identifier.key;
|
||||
}
|
||||
|
||||
return [identifier.namespace.replace(/:/g, '\\:'), identifier.key].join(':');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a new domain object into an old format model, removing the
|
||||
* identifier and converting the composition array from Open MCT Identifiers
|
||||
* to old format keyStrings.
|
||||
*
|
||||
* @param domainObject
|
||||
* @returns oldFormatModel
|
||||
*/
|
||||
function toOldFormat(model) {
|
||||
model = JSON.parse(JSON.stringify(model));
|
||||
delete model.identifier;
|
||||
if (model.composition) {
|
||||
model.composition = model.composition.map(makeKeyString);
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an old format domain object model into a new format domain
|
||||
* object. Adds an identifier using the provided keyString, and converts
|
||||
* the composition array to utilize Open MCT Identifiers.
|
||||
*
|
||||
* @param model
|
||||
* @param keyString
|
||||
* @returns domainObject
|
||||
*/
|
||||
function toNewFormat(model, keyString) {
|
||||
model = JSON.parse(JSON.stringify(model));
|
||||
model.identifier = parseKeyString(keyString);
|
||||
if (model.composition) {
|
||||
model.composition = model.composition.map(parseKeyString);
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two Open MCT Identifiers, returning true if they are equal.
|
||||
*
|
||||
* @param identifier
|
||||
* @param otherIdentifier
|
||||
* @returns Boolean true if identifiers are equal.
|
||||
*/
|
||||
function identifierEquals(a, b) {
|
||||
return a.key === b.key && a.namespace === b.namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two domain objects, return true if they're the same object.
|
||||
* Equality is determined by identifier.
|
||||
*
|
||||
* @param domainObject
|
||||
* @param otherDomainOBject
|
||||
* @returns Boolean true if objects are equal.
|
||||
*/
|
||||
function objectEquals(a, b) {
|
||||
return identifierEquals(a.identifier, b.identifier);
|
||||
}
|
||||
|
||||
function refresh(oldObject, newObject) {
|
||||
let deleted = _.difference(Object.keys(oldObject), Object.keys(newObject));
|
||||
deleted.forEach((propertyName) => delete oldObject[propertyName]);
|
||||
Object.assign(oldObject, newObject);
|
||||
if (keyString === namespace) {
|
||||
namespace = '';
|
||||
}
|
||||
|
||||
return {
|
||||
isIdentifier: isIdentifier,
|
||||
toOldFormat: toOldFormat,
|
||||
toNewFormat: toNewFormat,
|
||||
makeKeyString: makeKeyString,
|
||||
parseKeyString: parseKeyString,
|
||||
equals: objectEquals,
|
||||
identifierEquals: identifierEquals,
|
||||
refresh: refresh
|
||||
namespace: namespace,
|
||||
key: key
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an Open MCT Identifier into a keyString, ex:
|
||||
* {namespace: 'scratch', key: 'root'} ==> 'scratch:root'
|
||||
*
|
||||
* Idempotent
|
||||
*
|
||||
* @param identifier
|
||||
* @returns keyString
|
||||
*/
|
||||
function makeKeyString(identifier) {
|
||||
if (!identifier) {
|
||||
throw new Error('Cannot make key string from null identifier');
|
||||
}
|
||||
|
||||
if (isKeyString(identifier)) {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
if (!identifier.namespace) {
|
||||
return identifier.key;
|
||||
}
|
||||
|
||||
return [identifier.namespace.replace(/:/g, '\\:'), identifier.key].join(':');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a new domain object into an old format model, removing the
|
||||
* identifier and converting the composition array from Open MCT Identifiers
|
||||
* to old format keyStrings.
|
||||
*
|
||||
* @param domainObject
|
||||
* @returns oldFormatModel
|
||||
*/
|
||||
function toOldFormat(model) {
|
||||
model = JSON.parse(JSON.stringify(model));
|
||||
delete model.identifier;
|
||||
if (model.composition) {
|
||||
model.composition = model.composition.map(makeKeyString);
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an old format domain object model into a new format domain
|
||||
* object. Adds an identifier using the provided keyString, and converts
|
||||
* the composition array to utilize Open MCT Identifiers.
|
||||
*
|
||||
* @param model
|
||||
* @param keyString
|
||||
* @returns domainObject
|
||||
*/
|
||||
function toNewFormat(model, keyString) {
|
||||
model = JSON.parse(JSON.stringify(model));
|
||||
model.identifier = parseKeyString(keyString);
|
||||
if (model.composition) {
|
||||
model.composition = model.composition.map(parseKeyString);
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two Open MCT Identifiers, returning true if they are equal.
|
||||
*
|
||||
* @param identifier
|
||||
* @param otherIdentifier
|
||||
* @returns Boolean true if identifiers are equal.
|
||||
*/
|
||||
function identifierEquals(a, b) {
|
||||
return a.key === b.key && a.namespace === b.namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two domain objects, return true if they're the same object.
|
||||
* Equality is determined by identifier.
|
||||
*
|
||||
* @param domainObject
|
||||
* @param otherDomainOBject
|
||||
* @returns Boolean true if objects are equal.
|
||||
*/
|
||||
function objectEquals(a, b) {
|
||||
return identifierEquals(a.identifier, b.identifier);
|
||||
}
|
||||
|
||||
function refresh(oldObject, newObject) {
|
||||
let deleted = _.difference(Object.keys(oldObject), Object.keys(newObject));
|
||||
deleted.forEach((propertyName) => delete oldObject[propertyName]);
|
||||
Object.assign(oldObject, newObject);
|
||||
}
|
||||
|
||||
export default {
|
||||
isIdentifier: isIdentifier,
|
||||
toOldFormat: toOldFormat,
|
||||
toNewFormat: toNewFormat,
|
||||
makeKeyString: makeKeyString,
|
||||
parseKeyString: parseKeyString,
|
||||
equals: objectEquals,
|
||||
identifierEquals: identifierEquals,
|
||||
refresh: refresh
|
||||
};
|
||||
|
@ -1,89 +1,127 @@
|
||||
define(['objectUtils'], function (objectUtils) {
|
||||
describe('objectUtils', function () {
|
||||
describe('keyString util', function () {
|
||||
const EXPECTATIONS = {
|
||||
ROOT: {
|
||||
import objectUtils from 'objectUtils';
|
||||
|
||||
describe('objectUtils', function () {
|
||||
describe('keyString util', function () {
|
||||
const EXPECTATIONS = {
|
||||
ROOT: {
|
||||
namespace: '',
|
||||
key: 'ROOT'
|
||||
},
|
||||
mine: {
|
||||
namespace: '',
|
||||
key: 'mine'
|
||||
},
|
||||
'extended:something:with:colons': {
|
||||
key: 'something:with:colons',
|
||||
namespace: 'extended'
|
||||
},
|
||||
'https\\://some/url:resourceId': {
|
||||
key: 'resourceId',
|
||||
namespace: 'https://some/url'
|
||||
},
|
||||
'scratch:root': {
|
||||
namespace: 'scratch',
|
||||
key: 'root'
|
||||
},
|
||||
'thingy\\:thing:abc123': {
|
||||
namespace: 'thingy:thing',
|
||||
key: 'abc123'
|
||||
}
|
||||
};
|
||||
|
||||
Object.keys(EXPECTATIONS).forEach(function (keyString) {
|
||||
it('parses "' + keyString + '".', function () {
|
||||
expect(objectUtils.parseKeyString(keyString)).toEqual(EXPECTATIONS[keyString]);
|
||||
});
|
||||
|
||||
it('parses and re-encodes "' + keyString + '"', function () {
|
||||
const identifier = objectUtils.parseKeyString(keyString);
|
||||
expect(objectUtils.makeKeyString(identifier)).toEqual(keyString);
|
||||
});
|
||||
|
||||
it('is idempotent for "' + keyString + '".', function () {
|
||||
const identifier = objectUtils.parseKeyString(keyString);
|
||||
let again = objectUtils.parseKeyString(identifier);
|
||||
expect(identifier).toEqual(again);
|
||||
again = objectUtils.parseKeyString(again);
|
||||
again = objectUtils.parseKeyString(again);
|
||||
expect(identifier).toEqual(again);
|
||||
|
||||
let againKeyString = objectUtils.makeKeyString(again);
|
||||
expect(againKeyString).toEqual(keyString);
|
||||
againKeyString = objectUtils.makeKeyString(againKeyString);
|
||||
againKeyString = objectUtils.makeKeyString(againKeyString);
|
||||
againKeyString = objectUtils.makeKeyString(againKeyString);
|
||||
expect(againKeyString).toEqual(keyString);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('old object conversions', function () {
|
||||
it('translate ids', function () {
|
||||
expect(
|
||||
objectUtils.toNewFormat(
|
||||
{
|
||||
prop: 'someValue'
|
||||
},
|
||||
'objId'
|
||||
)
|
||||
).toEqual({
|
||||
prop: 'someValue',
|
||||
identifier: {
|
||||
namespace: '',
|
||||
key: 'ROOT'
|
||||
},
|
||||
mine: {
|
||||
namespace: '',
|
||||
key: 'mine'
|
||||
},
|
||||
'extended:something:with:colons': {
|
||||
key: 'something:with:colons',
|
||||
namespace: 'extended'
|
||||
},
|
||||
'https\\://some/url:resourceId': {
|
||||
key: 'resourceId',
|
||||
namespace: 'https://some/url'
|
||||
},
|
||||
'scratch:root': {
|
||||
namespace: 'scratch',
|
||||
key: 'root'
|
||||
},
|
||||
'thingy\\:thing:abc123': {
|
||||
namespace: 'thingy:thing',
|
||||
key: 'abc123'
|
||||
key: 'objId'
|
||||
}
|
||||
};
|
||||
|
||||
Object.keys(EXPECTATIONS).forEach(function (keyString) {
|
||||
it('parses "' + keyString + '".', function () {
|
||||
expect(objectUtils.parseKeyString(keyString)).toEqual(EXPECTATIONS[keyString]);
|
||||
});
|
||||
|
||||
it('parses and re-encodes "' + keyString + '"', function () {
|
||||
const identifier = objectUtils.parseKeyString(keyString);
|
||||
expect(objectUtils.makeKeyString(identifier)).toEqual(keyString);
|
||||
});
|
||||
|
||||
it('is idempotent for "' + keyString + '".', function () {
|
||||
const identifier = objectUtils.parseKeyString(keyString);
|
||||
let again = objectUtils.parseKeyString(identifier);
|
||||
expect(identifier).toEqual(again);
|
||||
again = objectUtils.parseKeyString(again);
|
||||
again = objectUtils.parseKeyString(again);
|
||||
expect(identifier).toEqual(again);
|
||||
|
||||
let againKeyString = objectUtils.makeKeyString(again);
|
||||
expect(againKeyString).toEqual(keyString);
|
||||
againKeyString = objectUtils.makeKeyString(againKeyString);
|
||||
againKeyString = objectUtils.makeKeyString(againKeyString);
|
||||
againKeyString = objectUtils.makeKeyString(againKeyString);
|
||||
expect(againKeyString).toEqual(keyString);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('old object conversions', function () {
|
||||
it('translate ids', function () {
|
||||
expect(
|
||||
objectUtils.toNewFormat(
|
||||
{
|
||||
prop: 'someValue'
|
||||
},
|
||||
'objId'
|
||||
)
|
||||
).toEqual({
|
||||
it('translates composition', function () {
|
||||
expect(
|
||||
objectUtils.toNewFormat(
|
||||
{
|
||||
prop: 'someValue',
|
||||
composition: ['anotherObjectId', 'scratch:anotherObjectId']
|
||||
},
|
||||
'objId'
|
||||
)
|
||||
).toEqual({
|
||||
prop: 'someValue',
|
||||
composition: [
|
||||
{
|
||||
namespace: '',
|
||||
key: 'anotherObjectId'
|
||||
},
|
||||
{
|
||||
namespace: 'scratch',
|
||||
key: 'anotherObjectId'
|
||||
}
|
||||
],
|
||||
identifier: {
|
||||
namespace: '',
|
||||
key: 'objId'
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('new object conversions', function () {
|
||||
it('removes ids', function () {
|
||||
expect(
|
||||
objectUtils.toOldFormat({
|
||||
prop: 'someValue',
|
||||
identifier: {
|
||||
namespace: '',
|
||||
key: 'objId'
|
||||
}
|
||||
});
|
||||
})
|
||||
).toEqual({
|
||||
prop: 'someValue'
|
||||
});
|
||||
});
|
||||
|
||||
it('translates composition', function () {
|
||||
expect(
|
||||
objectUtils.toNewFormat(
|
||||
{
|
||||
prop: 'someValue',
|
||||
composition: ['anotherObjectId', 'scratch:anotherObjectId']
|
||||
},
|
||||
'objId'
|
||||
)
|
||||
).toEqual({
|
||||
it('translates composition', function () {
|
||||
expect(
|
||||
objectUtils.toOldFormat({
|
||||
prop: 'someValue',
|
||||
composition: [
|
||||
{
|
||||
@ -99,48 +137,10 @@ define(['objectUtils'], function (objectUtils) {
|
||||
namespace: '',
|
||||
key: 'objId'
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('new object conversions', function () {
|
||||
it('removes ids', function () {
|
||||
expect(
|
||||
objectUtils.toOldFormat({
|
||||
prop: 'someValue',
|
||||
identifier: {
|
||||
namespace: '',
|
||||
key: 'objId'
|
||||
}
|
||||
})
|
||||
).toEqual({
|
||||
prop: 'someValue'
|
||||
});
|
||||
});
|
||||
|
||||
it('translates composition', function () {
|
||||
expect(
|
||||
objectUtils.toOldFormat({
|
||||
prop: 'someValue',
|
||||
composition: [
|
||||
{
|
||||
namespace: '',
|
||||
key: 'anotherObjectId'
|
||||
},
|
||||
{
|
||||
namespace: 'scratch',
|
||||
key: 'anotherObjectId'
|
||||
}
|
||||
],
|
||||
identifier: {
|
||||
namespace: '',
|
||||
key: 'objId'
|
||||
}
|
||||
})
|
||||
).toEqual({
|
||||
prop: 'someValue',
|
||||
composition: ['anotherObjectId', 'scratch:anotherObjectId']
|
||||
});
|
||||
})
|
||||
).toEqual({
|
||||
prop: 'someValue',
|
||||
composition: ['anotherObjectId', 'scratch:anotherObjectId']
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -20,17 +20,19 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(['lodash'], function (_) {
|
||||
/**
|
||||
* This is the default metadata provider; for any object with a "telemetry"
|
||||
* property, this provider will return the value of that property as the
|
||||
* telemetry metadata.
|
||||
*
|
||||
* This provider also implements legacy support for telemetry metadata
|
||||
* defined on the type. Telemetry metadata definitions on type will be
|
||||
* depreciated in the future.
|
||||
*/
|
||||
function DefaultMetadataProvider(openmct) {
|
||||
import _ from 'lodash';
|
||||
|
||||
/**
|
||||
* This is the default metadata provider; for any object with a "telemetry"
|
||||
* property, this provider will return the value of that property as the
|
||||
* telemetry metadata.
|
||||
*
|
||||
* This provider also implements legacy support for telemetry metadata
|
||||
* defined on the type. Telemetry metadata definitions on type will be
|
||||
* depreciated in the future.
|
||||
*/
|
||||
export default class DefaultMetadataProvider {
|
||||
constructor(openmct) {
|
||||
this.openmct = openmct;
|
||||
}
|
||||
|
||||
@ -38,65 +40,14 @@ define(['lodash'], function (_) {
|
||||
* Applies to any domain object with a telemetry property, or whose type
|
||||
* definition has a telemetry property.
|
||||
*/
|
||||
DefaultMetadataProvider.prototype.supportsMetadata = function (domainObject) {
|
||||
supportsMetadata(domainObject) {
|
||||
return Boolean(domainObject.telemetry) || Boolean(this.typeHasTelemetry(domainObject));
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves valueMetadata from legacy metadata.
|
||||
* @private
|
||||
*/
|
||||
function valueMetadatasFromOldFormat(metadata) {
|
||||
const valueMetadatas = [];
|
||||
|
||||
valueMetadatas.push({
|
||||
key: 'name',
|
||||
name: 'Name'
|
||||
});
|
||||
|
||||
metadata.domains.forEach(function (domain, index) {
|
||||
const valueMetadata = _.clone(domain);
|
||||
valueMetadata.hints = {
|
||||
domain: index + 1
|
||||
};
|
||||
valueMetadatas.push(valueMetadata);
|
||||
});
|
||||
|
||||
metadata.ranges.forEach(function (range, index) {
|
||||
const valueMetadata = _.clone(range);
|
||||
valueMetadata.hints = {
|
||||
range: index,
|
||||
priority: index + metadata.domains.length + 1
|
||||
};
|
||||
|
||||
if (valueMetadata.type === 'enum') {
|
||||
valueMetadata.key = 'enum';
|
||||
valueMetadata.hints.y -= 10;
|
||||
valueMetadata.hints.range -= 10;
|
||||
valueMetadata.enumerations = _.sortBy(
|
||||
valueMetadata.enumerations.map(function (e) {
|
||||
return {
|
||||
string: e.string,
|
||||
value: Number(e.value)
|
||||
};
|
||||
}),
|
||||
'e.value'
|
||||
);
|
||||
valueMetadata.values = valueMetadata.enumerations.map((e) => e.value);
|
||||
valueMetadata.max = Math.max(valueMetadata.values);
|
||||
valueMetadata.min = Math.min(valueMetadata.values);
|
||||
}
|
||||
|
||||
valueMetadatas.push(valueMetadata);
|
||||
});
|
||||
|
||||
return valueMetadatas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns telemetry metadata for a given domain object.
|
||||
*/
|
||||
DefaultMetadataProvider.prototype.getMetadata = function (domainObject) {
|
||||
getMetadata(domainObject) {
|
||||
const metadata = domainObject.telemetry || {};
|
||||
if (this.typeHasTelemetry(domainObject)) {
|
||||
const typeMetadata = this.openmct.types.get(domainObject.type).definition.telemetry;
|
||||
@ -109,16 +60,65 @@ define(['lodash'], function (_) {
|
||||
}
|
||||
|
||||
return metadata;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
DefaultMetadataProvider.prototype.typeHasTelemetry = function (domainObject) {
|
||||
typeHasTelemetry(domainObject) {
|
||||
const type = this.openmct.types.get(domainObject.type);
|
||||
|
||||
return Boolean(type.definition.telemetry);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return DefaultMetadataProvider;
|
||||
});
|
||||
/**
|
||||
* Retrieves valueMetadata from legacy metadata.
|
||||
* @private
|
||||
*/
|
||||
function valueMetadatasFromOldFormat(metadata) {
|
||||
const valueMetadatas = [];
|
||||
|
||||
valueMetadatas.push({
|
||||
key: 'name',
|
||||
name: 'Name'
|
||||
});
|
||||
|
||||
metadata.domains.forEach(function (domain, index) {
|
||||
const valueMetadata = _.clone(domain);
|
||||
valueMetadata.hints = {
|
||||
domain: index + 1
|
||||
};
|
||||
valueMetadatas.push(valueMetadata);
|
||||
});
|
||||
|
||||
metadata.ranges.forEach(function (range, index) {
|
||||
const valueMetadata = _.clone(range);
|
||||
valueMetadata.hints = {
|
||||
range: index,
|
||||
priority: index + metadata.domains.length + 1
|
||||
};
|
||||
|
||||
if (valueMetadata.type === 'enum') {
|
||||
valueMetadata.key = 'enum';
|
||||
valueMetadata.hints.y -= 10;
|
||||
valueMetadata.hints.range -= 10;
|
||||
valueMetadata.enumerations = _.sortBy(
|
||||
valueMetadata.enumerations.map(function (e) {
|
||||
return {
|
||||
string: e.string,
|
||||
value: Number(e.value)
|
||||
};
|
||||
}),
|
||||
'e.value'
|
||||
);
|
||||
valueMetadata.values = valueMetadata.enumerations.map((e) => e.value);
|
||||
valueMetadata.max = Math.max(valueMetadata.values);
|
||||
valueMetadata.min = Math.min(valueMetadata.values);
|
||||
}
|
||||
|
||||
valueMetadatas.push(valueMetadata);
|
||||
});
|
||||
|
||||
return valueMetadatas;
|
||||
}
|
||||
|
@ -20,143 +20,141 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(['lodash'], function (_) {
|
||||
function applyReasonableDefaults(valueMetadata, index) {
|
||||
valueMetadata.source = valueMetadata.source || valueMetadata.key;
|
||||
valueMetadata.hints = valueMetadata.hints || {};
|
||||
import _ from 'lodash';
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(valueMetadata.hints, 'x')) {
|
||||
if (!Object.prototype.hasOwnProperty.call(valueMetadata.hints, 'domain')) {
|
||||
valueMetadata.hints.domain = valueMetadata.hints.x;
|
||||
}
|
||||
function applyReasonableDefaults(valueMetadata, index) {
|
||||
valueMetadata.source = valueMetadata.source || valueMetadata.key;
|
||||
valueMetadata.hints = valueMetadata.hints || {};
|
||||
|
||||
delete valueMetadata.hints.x;
|
||||
if (Object.prototype.hasOwnProperty.call(valueMetadata.hints, 'x')) {
|
||||
if (!Object.prototype.hasOwnProperty.call(valueMetadata.hints, 'domain')) {
|
||||
valueMetadata.hints.domain = valueMetadata.hints.x;
|
||||
}
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(valueMetadata.hints, 'y')) {
|
||||
if (!Object.prototype.hasOwnProperty.call(valueMetadata.hints, 'range')) {
|
||||
valueMetadata.hints.range = valueMetadata.hints.y;
|
||||
}
|
||||
|
||||
delete valueMetadata.hints.y;
|
||||
}
|
||||
|
||||
if (valueMetadata.format === 'enum') {
|
||||
if (!valueMetadata.values) {
|
||||
valueMetadata.values = valueMetadata.enumerations.map((e) => e.value);
|
||||
}
|
||||
|
||||
if (!Object.prototype.hasOwnProperty.call(valueMetadata, 'max')) {
|
||||
valueMetadata.max = Math.max(valueMetadata.values) + 1;
|
||||
}
|
||||
|
||||
if (!Object.prototype.hasOwnProperty.call(valueMetadata, 'min')) {
|
||||
valueMetadata.min = Math.min(valueMetadata.values) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Object.prototype.hasOwnProperty.call(valueMetadata.hints, 'priority')) {
|
||||
valueMetadata.hints.priority = index;
|
||||
}
|
||||
|
||||
return valueMetadata;
|
||||
delete valueMetadata.hints.x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility class for handling and inspecting telemetry metadata. Applies
|
||||
* reasonable defaults to simplify the task of providing metadata, while
|
||||
* also providing methods for interrogating telemetry metadata.
|
||||
*/
|
||||
function TelemetryMetadataManager(metadata) {
|
||||
this.metadata = metadata;
|
||||
if (Object.prototype.hasOwnProperty.call(valueMetadata.hints, 'y')) {
|
||||
if (!Object.prototype.hasOwnProperty.call(valueMetadata.hints, 'range')) {
|
||||
valueMetadata.hints.range = valueMetadata.hints.y;
|
||||
}
|
||||
|
||||
this.valueMetadatas = this.metadata.values
|
||||
? this.metadata.values.map(applyReasonableDefaults)
|
||||
: [];
|
||||
delete valueMetadata.hints.y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value metadata for a single key.
|
||||
*/
|
||||
TelemetryMetadataManager.prototype.value = function (key) {
|
||||
return this.valueMetadatas.filter(function (metadata) {
|
||||
return metadata.key === key;
|
||||
if (valueMetadata.format === 'enum') {
|
||||
if (!valueMetadata.values) {
|
||||
valueMetadata.values = valueMetadata.enumerations.map((e) => e.value);
|
||||
}
|
||||
|
||||
if (!Object.prototype.hasOwnProperty.call(valueMetadata, 'max')) {
|
||||
valueMetadata.max = Math.max(valueMetadata.values) + 1;
|
||||
}
|
||||
|
||||
if (!Object.prototype.hasOwnProperty.call(valueMetadata, 'min')) {
|
||||
valueMetadata.min = Math.min(valueMetadata.values) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Object.prototype.hasOwnProperty.call(valueMetadata.hints, 'priority')) {
|
||||
valueMetadata.hints.priority = index;
|
||||
}
|
||||
|
||||
return valueMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility class for handling and inspecting telemetry metadata. Applies
|
||||
* reasonable defaults to simplify the task of providing metadata, while
|
||||
* also providing methods for interrogating telemetry metadata.
|
||||
*/
|
||||
export default function TelemetryMetadataManager(metadata) {
|
||||
this.metadata = metadata;
|
||||
|
||||
this.valueMetadatas = this.metadata.values
|
||||
? this.metadata.values.map(applyReasonableDefaults)
|
||||
: [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value metadata for a single key.
|
||||
*/
|
||||
TelemetryMetadataManager.prototype.value = function (key) {
|
||||
return this.valueMetadatas.filter(function (metadata) {
|
||||
return metadata.key === key;
|
||||
})[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns all value metadatas, sorted by priority.
|
||||
*/
|
||||
TelemetryMetadataManager.prototype.values = function () {
|
||||
return this.valuesForHints(['priority']);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an array of valueMetadatas that possess all hints requested.
|
||||
* Array is sorted based on hint priority.
|
||||
*
|
||||
*/
|
||||
TelemetryMetadataManager.prototype.valuesForHints = function (hints) {
|
||||
function hasHint(hint) {
|
||||
// eslint-disable-next-line no-invalid-this
|
||||
return Object.prototype.hasOwnProperty.call(this.hints, hint);
|
||||
}
|
||||
|
||||
function hasHints(metadata) {
|
||||
return hints.every(hasHint, metadata);
|
||||
}
|
||||
|
||||
const matchingMetadata = this.valueMetadatas.filter(hasHints);
|
||||
let iteratees = hints.map((hint) => {
|
||||
return (metadata) => {
|
||||
return metadata.hints[hint];
|
||||
};
|
||||
});
|
||||
|
||||
return _.sortBy(matchingMetadata, ...iteratees);
|
||||
};
|
||||
|
||||
/**
|
||||
* check out of a given metadata has array values
|
||||
*/
|
||||
TelemetryMetadataManager.prototype.isArrayValue = function (metadata) {
|
||||
const regex = /\[\]$/g;
|
||||
if (!metadata.format && !metadata.formatString) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (metadata.format || metadata.formatString).match(regex) !== null;
|
||||
};
|
||||
|
||||
TelemetryMetadataManager.prototype.getFilterableValues = function () {
|
||||
return this.valueMetadatas.filter(
|
||||
(metadatum) => metadatum.filters && metadatum.filters.length > 0
|
||||
);
|
||||
};
|
||||
|
||||
TelemetryMetadataManager.prototype.getUseToUpdateInPlaceValue = function () {
|
||||
return this.valueMetadatas.find(this.isInPlaceUpdateValue);
|
||||
};
|
||||
|
||||
TelemetryMetadataManager.prototype.isInPlaceUpdateValue = function (metadatum) {
|
||||
return metadatum.useToUpdateInPlace === true;
|
||||
};
|
||||
|
||||
TelemetryMetadataManager.prototype.getDefaultDisplayValue = function () {
|
||||
let valueMetadata = this.valuesForHints(['range'])[0];
|
||||
|
||||
if (valueMetadata === undefined) {
|
||||
valueMetadata = this.values().filter((values) => {
|
||||
return !values.hints.domain;
|
||||
})[0];
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all value metadatas, sorted by priority.
|
||||
*/
|
||||
TelemetryMetadataManager.prototype.values = function () {
|
||||
return this.valuesForHints(['priority']);
|
||||
};
|
||||
if (valueMetadata === undefined) {
|
||||
valueMetadata = this.values()[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of valueMetadatas that possess all hints requested.
|
||||
* Array is sorted based on hint priority.
|
||||
*
|
||||
*/
|
||||
TelemetryMetadataManager.prototype.valuesForHints = function (hints) {
|
||||
function hasHint(hint) {
|
||||
// eslint-disable-next-line no-invalid-this
|
||||
return Object.prototype.hasOwnProperty.call(this.hints, hint);
|
||||
}
|
||||
|
||||
function hasHints(metadata) {
|
||||
return hints.every(hasHint, metadata);
|
||||
}
|
||||
|
||||
const matchingMetadata = this.valueMetadatas.filter(hasHints);
|
||||
let iteratees = hints.map((hint) => {
|
||||
return (metadata) => {
|
||||
return metadata.hints[hint];
|
||||
};
|
||||
});
|
||||
|
||||
return _.sortBy(matchingMetadata, ...iteratees);
|
||||
};
|
||||
|
||||
/**
|
||||
* check out of a given metadata has array values
|
||||
*/
|
||||
TelemetryMetadataManager.prototype.isArrayValue = function (metadata) {
|
||||
const regex = /\[\]$/g;
|
||||
if (!metadata.format && !metadata.formatString) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (metadata.format || metadata.formatString).match(regex) !== null;
|
||||
};
|
||||
|
||||
TelemetryMetadataManager.prototype.getFilterableValues = function () {
|
||||
return this.valueMetadatas.filter(
|
||||
(metadatum) => metadatum.filters && metadatum.filters.length > 0
|
||||
);
|
||||
};
|
||||
|
||||
TelemetryMetadataManager.prototype.getUseToUpdateInPlaceValue = function () {
|
||||
return this.valueMetadatas.find(this.isInPlaceUpdateValue);
|
||||
};
|
||||
|
||||
TelemetryMetadataManager.prototype.isInPlaceUpdateValue = function (metadatum) {
|
||||
return metadatum.useToUpdateInPlace === true;
|
||||
};
|
||||
|
||||
TelemetryMetadataManager.prototype.getDefaultDisplayValue = function () {
|
||||
let valueMetadata = this.valuesForHints(['range'])[0];
|
||||
|
||||
if (valueMetadata === undefined) {
|
||||
valueMetadata = this.values().filter((values) => {
|
||||
return !values.hints.domain;
|
||||
})[0];
|
||||
}
|
||||
|
||||
if (valueMetadata === undefined) {
|
||||
valueMetadata = this.values()[0];
|
||||
}
|
||||
|
||||
return valueMetadata;
|
||||
};
|
||||
|
||||
return TelemetryMetadataManager;
|
||||
});
|
||||
return valueMetadata;
|
||||
};
|
||||
|
Reference in New Issue
Block a user