mirror of
https://github.com/nasa/openmct.git
synced 2025-06-29 12:13:03 +00:00
Compare commits
19 Commits
cs-fix
...
omm-large-
Author | SHA1 | Date | |
---|---|---|---|
fe9f740611 | |||
798eb4444d | |||
59ae7cddc5 | |||
321c7a3af5 | |||
609cf72bd1 | |||
a447b0ada8 | |||
5788f4cc69 | |||
f94b4e53c7 | |||
faf71f1e67 | |||
23310f85ae | |||
d80819634b | |||
483b62c152 | |||
1254279635 | |||
c768a71656 | |||
678a92bd29 | |||
34b488944a | |||
4d1dd2f51d | |||
080f7b8f4b | |||
483f2feac8 |
@ -1,37 +1,32 @@
|
|||||||
define([
|
define(['lodash'], function (_) {
|
||||||
'lodash'
|
|
||||||
], function (
|
|
||||||
_
|
|
||||||
) {
|
|
||||||
|
|
||||||
var METADATA_BY_TYPE = {
|
var METADATA_BY_TYPE = {
|
||||||
'generator': {
|
generator: {
|
||||||
values: [
|
values: [
|
||||||
{
|
{
|
||||||
key: "name",
|
key: 'name',
|
||||||
name: "Name",
|
name: 'Name',
|
||||||
format: "string"
|
format: 'string'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "utc",
|
key: 'utc',
|
||||||
name: "Time",
|
name: 'Time',
|
||||||
format: "utc",
|
format: 'utc',
|
||||||
hints: {
|
hints: {
|
||||||
domain: 1
|
domain: 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "yesterday",
|
key: 'yesterday',
|
||||||
name: "Yesterday",
|
name: 'Yesterday',
|
||||||
format: "utc",
|
format: 'utc',
|
||||||
hints: {
|
hints: {
|
||||||
domain: 2
|
domain: 2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "wavelengths",
|
key: 'wavelengths',
|
||||||
name: "Wavelength",
|
name: 'Wavelength',
|
||||||
unit: "nm",
|
unit: 'nm',
|
||||||
format: 'string[]',
|
format: 'string[]',
|
||||||
hints: {
|
hints: {
|
||||||
range: 4
|
range: 4
|
||||||
@ -48,26 +43,26 @@ define([
|
|||||||
// }
|
// }
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
key: "sin",
|
key: 'sin',
|
||||||
name: "Sine",
|
name: 'Sine',
|
||||||
unit: "Hz",
|
unit: 'Hz',
|
||||||
formatString: '%0.2f',
|
formatString: '%0.2f',
|
||||||
hints: {
|
hints: {
|
||||||
range: 1
|
range: 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "cos",
|
key: 'cos',
|
||||||
name: "Cosine",
|
name: 'Cosine',
|
||||||
unit: "deg",
|
unit: 'deg',
|
||||||
formatString: '%0.2f',
|
formatString: '%0.2f',
|
||||||
hints: {
|
hints: {
|
||||||
range: 2
|
range: 2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "intensities",
|
key: 'intensities',
|
||||||
name: "Intensities",
|
name: 'Intensities',
|
||||||
format: 'number[]',
|
format: 'number[]',
|
||||||
hints: {
|
hints: {
|
||||||
range: 3
|
range: 3
|
||||||
@ -78,40 +73,40 @@ define([
|
|||||||
'example.state-generator': {
|
'example.state-generator': {
|
||||||
values: [
|
values: [
|
||||||
{
|
{
|
||||||
key: "name",
|
key: 'name',
|
||||||
name: "Name",
|
name: 'Name',
|
||||||
format: "string"
|
format: 'string'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "utc",
|
key: 'utc',
|
||||||
name: "Time",
|
name: 'Time',
|
||||||
format: "utc",
|
format: 'utc',
|
||||||
hints: {
|
hints: {
|
||||||
domain: 1
|
domain: 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "local",
|
key: 'local',
|
||||||
name: "Time",
|
name: 'Time',
|
||||||
format: "utc",
|
format: 'utc',
|
||||||
source: "utc",
|
source: 'utc',
|
||||||
hints: {
|
hints: {
|
||||||
domain: 2
|
domain: 2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "state",
|
key: 'state',
|
||||||
source: "value",
|
source: 'value',
|
||||||
name: "State",
|
name: 'State',
|
||||||
format: "enum",
|
format: 'enum',
|
||||||
enumerations: [
|
enumerations: [
|
||||||
{
|
{
|
||||||
value: 0,
|
value: 0,
|
||||||
string: "OFF"
|
string: 'OFF'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 1,
|
value: 1,
|
||||||
string: "ON"
|
string: 'ON'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
hints: {
|
hints: {
|
||||||
@ -119,8 +114,8 @@ define([
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "value",
|
key: 'value',
|
||||||
name: "Value",
|
name: 'Value',
|
||||||
hints: {
|
hints: {
|
||||||
range: 2
|
range: 2
|
||||||
}
|
}
|
||||||
@ -129,22 +124,15 @@ define([
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function GeneratorMetadataProvider() {
|
function GeneratorMetadataProvider() {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GeneratorMetadataProvider.prototype.supportsMetadata = function (domainObject) {
|
GeneratorMetadataProvider.prototype.supportsMetadata = function (domainObject) {
|
||||||
return Object.prototype.hasOwnProperty.call(METADATA_BY_TYPE, domainObject.type);
|
return Object.prototype.hasOwnProperty.call(METADATA_BY_TYPE, domainObject.type);
|
||||||
};
|
};
|
||||||
|
|
||||||
GeneratorMetadataProvider.prototype.getMetadata = function (domainObject) {
|
GeneratorMetadataProvider.prototype.getMetadata = function (domainObject) {
|
||||||
return Object.assign(
|
return Object.assign({}, domainObject.telemetry, METADATA_BY_TYPE[domainObject.type]);
|
||||||
{},
|
|
||||||
domainObject.telemetry,
|
|
||||||
METADATA_BY_TYPE[domainObject.type]
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return GeneratorMetadataProvider;
|
return GeneratorMetadataProvider;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -20,12 +20,7 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
define([
|
define(['./WorkerInterface'], function (WorkerInterface) {
|
||||||
'./WorkerInterface'
|
|
||||||
], function (
|
|
||||||
WorkerInterface
|
|
||||||
) {
|
|
||||||
|
|
||||||
var REQUEST_DEFAULTS = {
|
var REQUEST_DEFAULTS = {
|
||||||
amplitude: 1,
|
amplitude: 1,
|
||||||
period: 10,
|
period: 10,
|
||||||
@ -34,7 +29,8 @@ define([
|
|||||||
randomness: 0,
|
randomness: 0,
|
||||||
phase: 0,
|
phase: 0,
|
||||||
loadDelay: 0,
|
loadDelay: 0,
|
||||||
infinityValues: false
|
infinityValues: false,
|
||||||
|
veryLargeValues: false
|
||||||
};
|
};
|
||||||
|
|
||||||
function GeneratorProvider(openmct, StalenessProvider) {
|
function GeneratorProvider(openmct, StalenessProvider) {
|
||||||
@ -46,8 +42,7 @@ define([
|
|||||||
return domainObject.type === 'generator';
|
return domainObject.type === 'generator';
|
||||||
};
|
};
|
||||||
|
|
||||||
GeneratorProvider.prototype.supportsRequest =
|
GeneratorProvider.prototype.supportsRequest = GeneratorProvider.prototype.supportsSubscribe =
|
||||||
GeneratorProvider.prototype.supportsSubscribe =
|
|
||||||
GeneratorProvider.prototype.canProvideTelemetry;
|
GeneratorProvider.prototype.canProvideTelemetry;
|
||||||
|
|
||||||
GeneratorProvider.prototype.makeWorkerRequest = function (domainObject, request) {
|
GeneratorProvider.prototype.makeWorkerRequest = function (domainObject, request) {
|
||||||
@ -59,7 +54,8 @@ define([
|
|||||||
'randomness',
|
'randomness',
|
||||||
'phase',
|
'phase',
|
||||||
'loadDelay',
|
'loadDelay',
|
||||||
'infinityValues'
|
'infinityValues',
|
||||||
|
'veryLargeValues'
|
||||||
];
|
];
|
||||||
|
|
||||||
request = request || {};
|
request = request || {};
|
||||||
@ -67,7 +63,10 @@ define([
|
|||||||
var workerRequest = {};
|
var workerRequest = {};
|
||||||
|
|
||||||
props.forEach(function (prop) {
|
props.forEach(function (prop) {
|
||||||
if (domainObject.telemetry && Object.prototype.hasOwnProperty.call(domainObject.telemetry, prop)) {
|
if (
|
||||||
|
domainObject.telemetry &&
|
||||||
|
Object.prototype.hasOwnProperty.call(domainObject.telemetry, prop)
|
||||||
|
) {
|
||||||
workerRequest[prop] = domainObject.telemetry[prop];
|
workerRequest[prop] = domainObject.telemetry[prop];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,12 +20,7 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
define([
|
define([], function () {
|
||||||
|
|
||||||
], function (
|
|
||||||
|
|
||||||
) {
|
|
||||||
|
|
||||||
var PURPLE = {
|
var PURPLE = {
|
||||||
sin: 2.2,
|
sin: 2.2,
|
||||||
cos: 2.2
|
cos: 2.2
|
||||||
@ -48,34 +43,32 @@ define([
|
|||||||
},
|
},
|
||||||
LIMITS = {
|
LIMITS = {
|
||||||
rh: {
|
rh: {
|
||||||
cssClass: "is-limit--upr is-limit--red",
|
cssClass: 'is-limit--upr is-limit--red',
|
||||||
low: RED,
|
low: RED,
|
||||||
high: Number.POSITIVE_INFINITY,
|
high: Number.POSITIVE_INFINITY,
|
||||||
name: "Red High"
|
name: 'Red High'
|
||||||
},
|
},
|
||||||
rl: {
|
rl: {
|
||||||
cssClass: "is-limit--lwr is-limit--red",
|
cssClass: 'is-limit--lwr is-limit--red',
|
||||||
high: -RED,
|
high: -RED,
|
||||||
low: Number.NEGATIVE_INFINITY,
|
low: Number.NEGATIVE_INFINITY,
|
||||||
name: "Red Low"
|
name: 'Red Low'
|
||||||
},
|
},
|
||||||
yh: {
|
yh: {
|
||||||
cssClass: "is-limit--upr is-limit--yellow",
|
cssClass: 'is-limit--upr is-limit--yellow',
|
||||||
low: YELLOW,
|
low: YELLOW,
|
||||||
high: RED,
|
high: RED,
|
||||||
name: "Yellow High"
|
name: 'Yellow High'
|
||||||
},
|
},
|
||||||
yl: {
|
yl: {
|
||||||
cssClass: "is-limit--lwr is-limit--yellow",
|
cssClass: 'is-limit--lwr is-limit--yellow',
|
||||||
low: -RED,
|
low: -RED,
|
||||||
high: -YELLOW,
|
high: -YELLOW,
|
||||||
name: "Yellow Low"
|
name: 'Yellow Low'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function SinewaveLimitProvider() {
|
function SinewaveLimitProvider() {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
SinewaveLimitProvider.prototype.supportsLimits = function (domainObject) {
|
SinewaveLimitProvider.prototype.supportsLimits = function (domainObject) {
|
||||||
return domainObject.type === 'generator';
|
return domainObject.type === 'generator';
|
||||||
@ -106,62 +99,61 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
SinewaveLimitProvider.prototype.getLimits = function (domainObject) {
|
SinewaveLimitProvider.prototype.getLimits = function (domainObject) {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
limits: function () {
|
limits: function () {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
WATCH: {
|
WATCH: {
|
||||||
low: {
|
low: {
|
||||||
color: "cyan",
|
color: 'cyan',
|
||||||
sin: -CYAN.sin,
|
sin: -CYAN.sin,
|
||||||
cos: -CYAN.cos
|
cos: -CYAN.cos
|
||||||
},
|
},
|
||||||
high: {
|
high: {
|
||||||
color: "cyan",
|
color: 'cyan',
|
||||||
...CYAN
|
...CYAN
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
WARNING: {
|
WARNING: {
|
||||||
low: {
|
low: {
|
||||||
color: "yellow",
|
color: 'yellow',
|
||||||
sin: -YELLOW.sin,
|
sin: -YELLOW.sin,
|
||||||
cos: -YELLOW.cos
|
cos: -YELLOW.cos
|
||||||
},
|
},
|
||||||
high: {
|
high: {
|
||||||
color: "yellow",
|
color: 'yellow',
|
||||||
...YELLOW
|
...YELLOW
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DISTRESS: {
|
DISTRESS: {
|
||||||
low: {
|
low: {
|
||||||
color: "orange",
|
color: 'orange',
|
||||||
sin: -ORANGE.sin,
|
sin: -ORANGE.sin,
|
||||||
cos: -ORANGE.cos
|
cos: -ORANGE.cos
|
||||||
},
|
},
|
||||||
high: {
|
high: {
|
||||||
color: "orange",
|
color: 'orange',
|
||||||
...ORANGE
|
...ORANGE
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CRITICAL: {
|
CRITICAL: {
|
||||||
low: {
|
low: {
|
||||||
color: "red",
|
color: 'red',
|
||||||
sin: -RED.sin,
|
sin: -RED.sin,
|
||||||
cos: -RED.cos
|
cos: -RED.cos
|
||||||
},
|
},
|
||||||
high: {
|
high: {
|
||||||
color: "red",
|
color: 'red',
|
||||||
...RED
|
...RED
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
SEVERE: {
|
SEVERE: {
|
||||||
low: {
|
low: {
|
||||||
color: "purple",
|
color: 'purple',
|
||||||
sin: -PURPLE.sin,
|
sin: -PURPLE.sin,
|
||||||
cos: -PURPLE.cos
|
cos: -PURPLE.cos
|
||||||
},
|
},
|
||||||
high: {
|
high: {
|
||||||
color: "purple",
|
color: 'purple',
|
||||||
...PURPLE
|
...PURPLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ export default class SinewaveLimitProvider extends EventEmitter {
|
|||||||
const id = this.#getObjectKeyString(domainObject);
|
const id = this.#getObjectKeyString(domainObject);
|
||||||
|
|
||||||
if (this.#isRealTime === undefined) {
|
if (this.#isRealTime === undefined) {
|
||||||
this.#updateRealTime(this.#openmct.time.clock());
|
this.#updateRealTime(this.#openmct.time.getMode());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#handleClockUpdate();
|
this.#handleClockUpdate();
|
||||||
@ -92,15 +92,15 @@ export default class SinewaveLimitProvider extends EventEmitter {
|
|||||||
|
|
||||||
if (observers && !this.#watchingTheClock) {
|
if (observers && !this.#watchingTheClock) {
|
||||||
this.#watchingTheClock = true;
|
this.#watchingTheClock = true;
|
||||||
this.#openmct.time.on('clock', this.#updateRealTime, this);
|
this.#openmct.time.on('modeChanged', this.#updateRealTime, this);
|
||||||
} else if (!observers && this.#watchingTheClock) {
|
} else if (!observers && this.#watchingTheClock) {
|
||||||
this.#watchingTheClock = false;
|
this.#watchingTheClock = false;
|
||||||
this.#openmct.time.off('clock', this.#updateRealTime, this);
|
this.#openmct.time.off('modeChanged', this.#updateRealTime, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#updateRealTime(clock) {
|
#updateRealTime(mode) {
|
||||||
this.#isRealTime = clock !== undefined;
|
this.#isRealTime = mode !== 'fixed';
|
||||||
|
|
||||||
if (!this.#isRealTime) {
|
if (!this.#isRealTime) {
|
||||||
Object.keys(this.#observingStaleness).forEach((id) => {
|
Object.keys(this.#observingStaleness).forEach((id) => {
|
||||||
|
@ -20,15 +20,8 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
define([
|
define([], function () {
|
||||||
|
function StateGeneratorProvider() {}
|
||||||
], function (
|
|
||||||
|
|
||||||
) {
|
|
||||||
|
|
||||||
function StateGeneratorProvider() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function pointForTimestamp(timestamp, duration, name) {
|
function pointForTimestamp(timestamp, duration, name) {
|
||||||
return {
|
return {
|
||||||
@ -79,5 +72,4 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
return StateGeneratorProvider;
|
return StateGeneratorProvider;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -20,11 +20,7 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
define([
|
define(['uuid'], function ({ v4: uuid }) {
|
||||||
'uuid'
|
|
||||||
], function (
|
|
||||||
{ v4: uuid }
|
|
||||||
) {
|
|
||||||
function WorkerInterface(openmct, StalenessProvider) {
|
function WorkerInterface(openmct, StalenessProvider) {
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
const workerUrl = `${openmct.getAssetPath()}${__OPENMCT_ROOT_RELATIVE__}generatorWorker.js`;
|
const workerUrl = `${openmct.getAssetPath()}${__OPENMCT_ROOT_RELATIVE__}generatorWorker.js`;
|
||||||
@ -38,7 +34,7 @@ define([
|
|||||||
}
|
}
|
||||||
|
|
||||||
WorkerInterface.prototype.watchStaleness = function () {
|
WorkerInterface.prototype.watchStaleness = function () {
|
||||||
this.StalenessProvider.on('stalenessEvent', ({ id, isStale}) => {
|
this.StalenessProvider.on('stalenessEvent', ({ id, isStale }) => {
|
||||||
this.staleTelemetryIds[id] = isStale;
|
this.staleTelemetryIds[id] = isStale;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -84,7 +80,6 @@ define([
|
|||||||
}
|
}
|
||||||
|
|
||||||
delete self.callbacks[messageId];
|
delete self.callbacks[messageId];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
messageId = this.dispatch('request', request, callback.bind(this));
|
messageId = this.dispatch('request', request, callback.bind(this));
|
||||||
@ -93,10 +88,10 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
WorkerInterface.prototype.subscribe = function (request, cb) {
|
WorkerInterface.prototype.subscribe = function (request, cb) {
|
||||||
const id = request.id;
|
const { id, loadDelay } = request;
|
||||||
const messageId = this.dispatch('subscribe', request, (message) => {
|
const messageId = this.dispatch('subscribe', request, (message) => {
|
||||||
if (!this.staleTelemetryIds[id]) {
|
if (!this.staleTelemetryIds[id]) {
|
||||||
cb(message.data);
|
setTimeout(() => cb(message.data), Math.max(loadDelay, 0));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
|
|
||||||
var FIFTEEN_MINUTES = 15 * 60 * 1000;
|
var FIFTEEN_MINUTES = 15 * 60 * 1000;
|
||||||
|
|
||||||
var handlers = {
|
var handlers = {
|
||||||
@ -34,9 +33,12 @@
|
|||||||
|
|
||||||
function workSubscriptions(timestamp) {
|
function workSubscriptions(timestamp) {
|
||||||
var now = Date.now();
|
var now = Date.now();
|
||||||
var nextWork = Math.min.apply(Math, Object.values(subscriptions).map(function (subscription) {
|
var nextWork = Math.min.apply(
|
||||||
|
Math,
|
||||||
|
Object.values(subscriptions).map(function (subscription) {
|
||||||
return subscription(now);
|
return subscription(now);
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
var wait = nextWork - now;
|
var wait = nextWork - now;
|
||||||
if (wait < 0) {
|
if (wait < 0) {
|
||||||
wait = 0;
|
wait = 0;
|
||||||
@ -59,7 +61,7 @@
|
|||||||
work = function (now) {
|
work = function (now) {
|
||||||
while (nextStep < now) {
|
while (nextStep < now) {
|
||||||
const messageCopy = Object.create(message);
|
const messageCopy = Object.create(message);
|
||||||
message.data.start = nextStep - (60 * 1000);
|
message.data.start = nextStep - 60 * 1000;
|
||||||
message.data.end = nextStep;
|
message.data.end = nextStep;
|
||||||
onRequest(messageCopy);
|
onRequest(messageCopy);
|
||||||
nextStep += step;
|
nextStep += step;
|
||||||
@ -76,10 +78,28 @@
|
|||||||
name: data.name,
|
name: data.name,
|
||||||
utc: nextStep,
|
utc: nextStep,
|
||||||
yesterday: nextStep - 60 * 60 * 24 * 1000,
|
yesterday: nextStep - 60 * 60 * 24 * 1000,
|
||||||
sin: sin(nextStep, data.period, data.amplitude, data.offset, data.phase, data.randomness, data.infinityValues),
|
sin: sin(
|
||||||
|
nextStep,
|
||||||
|
data.period,
|
||||||
|
data.amplitude,
|
||||||
|
data.offset,
|
||||||
|
data.phase,
|
||||||
|
data.randomness,
|
||||||
|
data.infinityValues,
|
||||||
|
data.veryLargeValues
|
||||||
|
),
|
||||||
wavelengths: wavelengths(),
|
wavelengths: wavelengths(),
|
||||||
intensities: intensities(),
|
intensities: intensities(),
|
||||||
cos: cos(nextStep, data.period, data.amplitude, data.offset, data.phase, data.randomness, data.infinityValues)
|
cos: cos(
|
||||||
|
nextStep,
|
||||||
|
data.period,
|
||||||
|
data.amplitude,
|
||||||
|
data.offset,
|
||||||
|
data.phase,
|
||||||
|
data.randomness,
|
||||||
|
data.infinityValues,
|
||||||
|
data.veryLargeValues
|
||||||
|
)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
nextStep += step;
|
nextStep += step;
|
||||||
@ -118,6 +138,7 @@
|
|||||||
var randomness = request.randomness;
|
var randomness = request.randomness;
|
||||||
var loadDelay = Math.max(request.loadDelay, 0);
|
var loadDelay = Math.max(request.loadDelay, 0);
|
||||||
var infinityValues = request.infinityValues;
|
var infinityValues = request.infinityValues;
|
||||||
|
var veryLargeValues = request.veryLargeValues;
|
||||||
|
|
||||||
var step = 1000 / dataRateInHz;
|
var step = 1000 / dataRateInHz;
|
||||||
var nextStep = start - (start % step) + step;
|
var nextStep = start - (start % step) + step;
|
||||||
@ -128,10 +149,10 @@
|
|||||||
data.push({
|
data.push({
|
||||||
utc: nextStep,
|
utc: nextStep,
|
||||||
yesterday: nextStep - 60 * 60 * 24 * 1000,
|
yesterday: nextStep - 60 * 60 * 24 * 1000,
|
||||||
sin: sin(nextStep, period, amplitude, offset, phase, randomness, infinityValues),
|
sin: sin(nextStep, period, amplitude, offset, phase, randomness, infinityValues, veryLargeValues),
|
||||||
wavelengths: wavelengths(),
|
wavelengths: wavelengths(),
|
||||||
intensities: intensities(),
|
intensities: intensities(),
|
||||||
cos: cos(nextStep, period, amplitude, offset, phase, randomness, infinityValues)
|
cos: cos(nextStep, period, amplitude, offset, phase, randomness, infinityValues, veryLargeValues)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,33 +166,63 @@
|
|||||||
function postOnRequest(message, request, data) {
|
function postOnRequest(message, request, data) {
|
||||||
self.postMessage({
|
self.postMessage({
|
||||||
id: message.id,
|
id: message.id,
|
||||||
data: request.spectra ? {
|
data: request.spectra
|
||||||
|
? {
|
||||||
wavelength: data.map((item) => {
|
wavelength: data.map((item) => {
|
||||||
return item.wavelength;
|
return item.wavelength;
|
||||||
}),
|
}),
|
||||||
cos: data.map((item) => {
|
cos: data.map((item) => {
|
||||||
return item.cos;
|
return item.cos;
|
||||||
})
|
})
|
||||||
} : data
|
}
|
||||||
|
: data
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function cos(timestamp, period, amplitude, offset, phase, randomness, infinityValues) {
|
function cos(timestamp, period, amplitude, offset, phase, randomness, infinityValues, veryLargeValues) {
|
||||||
if (infinityValues && Math.random() > 0.5) {
|
const randomValue = Math.random();
|
||||||
|
|
||||||
|
if (infinityValues && veryLargeValues) {
|
||||||
|
if (randomValue < 0.33) return Number.POSITIVE_INFINITY;
|
||||||
|
if (randomValue < 0.66) return (randomValue > 0.5 ? -1 : 1) * 1e+177;
|
||||||
|
// if neither condition is met, it just proceeds to the normal return value
|
||||||
|
} else {
|
||||||
|
if (infinityValues && randomValue > 0.5) {
|
||||||
return Number.POSITIVE_INFINITY;
|
return Number.POSITIVE_INFINITY;
|
||||||
}
|
}
|
||||||
|
if (veryLargeValues && randomValue > 0.5) {
|
||||||
return amplitude
|
return (randomValue > 0.5 ? -1 : 1) * 1e+177;
|
||||||
* Math.cos(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function sin(timestamp, period, amplitude, offset, phase, randomness, infinityValues) {
|
return (
|
||||||
if (infinityValues && Math.random() > 0.5) {
|
amplitude * Math.cos(phase + (timestamp / period / 1000) * Math.PI * 2) +
|
||||||
|
amplitude * Math.random() * randomness +
|
||||||
|
offset
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sin(timestamp, period, amplitude, offset, phase, randomness, infinityValues, veryLargeValues) {
|
||||||
|
const randomValue = Math.random();
|
||||||
|
|
||||||
|
if (infinityValues && veryLargeValues) {
|
||||||
|
if (randomValue < 0.33) return Number.POSITIVE_INFINITY;
|
||||||
|
if (randomValue < 0.66) return (randomValue > 0.5 ? -1 : 1) * 1e+177;
|
||||||
|
// if neither condition is met, it just proceeds to the normal return value
|
||||||
|
} else {
|
||||||
|
if (infinityValues && randomValue > 0.5) {
|
||||||
return Number.POSITIVE_INFINITY;
|
return Number.POSITIVE_INFINITY;
|
||||||
}
|
}
|
||||||
|
if (veryLargeValues && randomValue > 0.5) {
|
||||||
|
return (randomValue > 0.5 ? -1 : 1) * 1e+177;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return amplitude
|
return (
|
||||||
* Math.sin(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
|
amplitude * Math.sin(phase + (timestamp / period / 1000) * Math.PI * 2) +
|
||||||
|
amplitude * Math.random() * randomness +
|
||||||
|
offset
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function wavelengths() {
|
function wavelengths() {
|
||||||
@ -220,5 +271,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
})();
|
||||||
}());
|
|
||||||
|
@ -20,30 +20,27 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
import GeneratorProvider from "./GeneratorProvider";
|
import GeneratorMetadataProvider from './GeneratorMetadataProvider';
|
||||||
import SinewaveLimitProvider from "./SinewaveLimitProvider";
|
import GeneratorProvider from './GeneratorProvider';
|
||||||
import SinewaveStalenessProvider from "./SinewaveStalenessProvider";
|
import SinewaveLimitProvider from './SinewaveLimitProvider';
|
||||||
import StateGeneratorProvider from "./StateGeneratorProvider";
|
import SinewaveStalenessProvider from './SinewaveStalenessProvider';
|
||||||
import GeneratorMetadataProvider from "./GeneratorMetadataProvider";
|
import StateGeneratorProvider from './StateGeneratorProvider';
|
||||||
|
|
||||||
export default function (openmct) {
|
export default function (openmct) {
|
||||||
|
openmct.types.addType('example.state-generator', {
|
||||||
openmct.types.addType("example.state-generator", {
|
name: 'State Generator',
|
||||||
name: "State Generator",
|
description:
|
||||||
description: "For development use. Generates example enumerated telemetry by cycling through a given set of states.",
|
'For development use. Generates example enumerated telemetry by cycling through a given set of states.',
|
||||||
cssClass: "icon-generator-telemetry",
|
cssClass: 'icon-generator-telemetry',
|
||||||
creatable: true,
|
creatable: true,
|
||||||
form: [
|
form: [
|
||||||
{
|
{
|
||||||
name: "State Duration (seconds)",
|
name: 'State Duration (seconds)',
|
||||||
control: "numberfield",
|
control: 'numberfield',
|
||||||
cssClass: "l-input-sm l-numeric",
|
cssClass: 'l-input-sm l-numeric',
|
||||||
key: "duration",
|
key: 'duration',
|
||||||
required: true,
|
required: true,
|
||||||
property: [
|
property: ['telemetry', 'duration']
|
||||||
"telemetry",
|
|
||||||
"duration"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
initialize: function (object) {
|
initialize: function (object) {
|
||||||
@ -55,108 +52,89 @@ export default function (openmct) {
|
|||||||
|
|
||||||
openmct.telemetry.addProvider(new StateGeneratorProvider());
|
openmct.telemetry.addProvider(new StateGeneratorProvider());
|
||||||
|
|
||||||
openmct.types.addType("generator", {
|
openmct.types.addType('generator', {
|
||||||
name: "Sine Wave Generator",
|
name: 'Sine Wave Generator',
|
||||||
description: "For development use. Generates example streaming telemetry data using a simple sine wave algorithm.",
|
description:
|
||||||
cssClass: "icon-generator-telemetry",
|
'For development use. Generates example streaming telemetry data using a simple sine wave algorithm.',
|
||||||
|
cssClass: 'icon-generator-telemetry',
|
||||||
creatable: true,
|
creatable: true,
|
||||||
form: [
|
form: [
|
||||||
{
|
{
|
||||||
name: "Period",
|
name: 'Period',
|
||||||
control: "numberfield",
|
control: 'numberfield',
|
||||||
cssClass: "l-input-sm l-numeric",
|
cssClass: 'l-input-sm l-numeric',
|
||||||
key: "period",
|
key: 'period',
|
||||||
required: true,
|
required: true,
|
||||||
property: [
|
property: ['telemetry', 'period']
|
||||||
"telemetry",
|
|
||||||
"period"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Amplitude",
|
name: 'Amplitude',
|
||||||
control: "numberfield",
|
control: 'numberfield',
|
||||||
cssClass: "l-numeric",
|
cssClass: 'l-numeric',
|
||||||
key: "amplitude",
|
key: 'amplitude',
|
||||||
required: true,
|
required: true,
|
||||||
property: [
|
property: ['telemetry', 'amplitude']
|
||||||
"telemetry",
|
|
||||||
"amplitude"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Offset",
|
name: 'Offset',
|
||||||
control: "numberfield",
|
control: 'numberfield',
|
||||||
cssClass: "l-numeric",
|
cssClass: 'l-numeric',
|
||||||
key: "offset",
|
key: 'offset',
|
||||||
required: true,
|
required: true,
|
||||||
property: [
|
property: ['telemetry', 'offset']
|
||||||
"telemetry",
|
|
||||||
"offset"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Data Rate (hz)",
|
name: 'Data Rate (hz)',
|
||||||
control: "numberfield",
|
control: 'numberfield',
|
||||||
cssClass: "l-input-sm l-numeric",
|
cssClass: 'l-input-sm l-numeric',
|
||||||
key: "dataRateInHz",
|
key: 'dataRateInHz',
|
||||||
required: true,
|
required: true,
|
||||||
property: [
|
property: ['telemetry', 'dataRateInHz']
|
||||||
"telemetry",
|
|
||||||
"dataRateInHz"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Phase (radians)",
|
name: 'Phase (radians)',
|
||||||
control: "numberfield",
|
control: 'numberfield',
|
||||||
cssClass: "l-input-sm l-numeric",
|
cssClass: 'l-input-sm l-numeric',
|
||||||
key: "phase",
|
key: 'phase',
|
||||||
required: true,
|
required: true,
|
||||||
property: [
|
property: ['telemetry', 'phase']
|
||||||
"telemetry",
|
|
||||||
"phase"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Randomness",
|
name: 'Randomness',
|
||||||
control: "numberfield",
|
control: 'numberfield',
|
||||||
cssClass: "l-input-sm l-numeric",
|
cssClass: 'l-input-sm l-numeric',
|
||||||
key: "randomness",
|
key: 'randomness',
|
||||||
required: true,
|
required: true,
|
||||||
property: [
|
property: ['telemetry', 'randomness']
|
||||||
"telemetry",
|
|
||||||
"randomness"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Loading Delay (ms)",
|
name: 'Loading Delay (ms)',
|
||||||
control: "numberfield",
|
control: 'numberfield',
|
||||||
cssClass: "l-input-sm l-numeric",
|
cssClass: 'l-input-sm l-numeric',
|
||||||
key: "loadDelay",
|
key: 'loadDelay',
|
||||||
required: true,
|
required: true,
|
||||||
property: [
|
property: ['telemetry', 'loadDelay']
|
||||||
"telemetry",
|
|
||||||
"loadDelay"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Include Infinity Values",
|
name: 'Include Infinity Values',
|
||||||
control: "toggleSwitch",
|
control: 'toggleSwitch',
|
||||||
cssClass: "l-input",
|
cssClass: 'l-input',
|
||||||
key: "infinityValues",
|
key: 'infinityValues',
|
||||||
property: [
|
property: ['telemetry', 'infinityValues']
|
||||||
"telemetry",
|
|
||||||
"infinityValues"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Provide Staleness Updates",
|
name: 'Include Very Large Values',
|
||||||
control: "toggleSwitch",
|
control: 'toggleSwitch',
|
||||||
cssClass: "l-input",
|
cssClass: 'l-input',
|
||||||
key: "staleness",
|
key: 'veryLargeValues',
|
||||||
property: [
|
property: ['telemetry', 'veryLargeValues']
|
||||||
"telemetry",
|
},
|
||||||
"staleness"
|
{
|
||||||
]
|
name: 'Provide Staleness Updates',
|
||||||
|
control: 'toggleSwitch',
|
||||||
|
cssClass: 'l-input',
|
||||||
|
key: 'staleness',
|
||||||
|
property: ['telemetry', 'staleness']
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
initialize: function (object) {
|
initialize: function (object) {
|
||||||
@ -169,6 +147,7 @@ export default function (openmct) {
|
|||||||
randomness: 0,
|
randomness: 0,
|
||||||
loadDelay: 0,
|
loadDelay: 0,
|
||||||
infinityValues: false,
|
infinityValues: false,
|
||||||
|
veryLargeValues: false,
|
||||||
staleness: false
|
staleness: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -239,9 +239,15 @@ export default class ObjectAPI {
|
|||||||
|
|
||||||
return domainObject;
|
return domainObject;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
console.warn(`Failed to retrieve ${keystring}:`, error);
|
let result;
|
||||||
|
|
||||||
delete this.cache[keystring];
|
delete this.cache[keystring];
|
||||||
const result = this.applyGetInterceptors(identifier);
|
|
||||||
|
// suppress abort errors
|
||||||
|
if (error.name !== 'AbortError') {
|
||||||
|
console.warn(`Failed to retrieve ${keystring}:`, error);
|
||||||
|
result = this.applyGetInterceptors(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
@ -55,6 +55,13 @@ define([
|
|||||||
*/
|
*/
|
||||||
function parseKeyString(keyString) {
|
function parseKeyString(keyString) {
|
||||||
if (isIdentifier(keyString)) {
|
if (isIdentifier(keyString)) {
|
||||||
|
// TODO REMOVE FOR OMM-RELEASE-5.0
|
||||||
|
if (!keyString.namespace && keyString.key.includes(':')) {
|
||||||
|
console.warn(`smushed key: ${keyString.key}`);
|
||||||
|
|
||||||
|
return parseKeyString(keyString.key);
|
||||||
|
}
|
||||||
|
|
||||||
return keyString;
|
return keyString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ export default class TelemetryAPI {
|
|||||||
* @memberof module:openmct.TelemetryAPI~TelemetryProvider#
|
* @memberof module:openmct.TelemetryAPI~TelemetryProvider#
|
||||||
*/
|
*/
|
||||||
canProvideTelemetry(domainObject) {
|
canProvideTelemetry(domainObject) {
|
||||||
return Boolean(this.#findSubscriptionProvider(domainObject))
|
return Boolean(this.findSubscriptionProvider(domainObject))
|
||||||
|| Boolean(this.findRequestProvider(domainObject));
|
|| Boolean(this.findRequestProvider(domainObject));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,9 +123,10 @@ export default class TelemetryAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* Returns a telemetry subscription provider that supports
|
||||||
|
* a given domain object and options.
|
||||||
*/
|
*/
|
||||||
#findSubscriptionProvider() {
|
findSubscriptionProvider() {
|
||||||
const args = Array.prototype.slice.apply(arguments);
|
const args = Array.prototype.slice.apply(arguments);
|
||||||
function supportsDomainObject(provider) {
|
function supportsDomainObject(provider) {
|
||||||
return provider.supportsSubscribe.apply(provider, args);
|
return provider.supportsSubscribe.apply(provider, args);
|
||||||
@ -348,7 +349,7 @@ export default class TelemetryAPI {
|
|||||||
return () => {};
|
return () => {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const provider = this.#findSubscriptionProvider(domainObject);
|
const provider = this.findSubscriptionProvider(domainObject);
|
||||||
|
|
||||||
if (!this.subscribeCache) {
|
if (!this.subscribeCache) {
|
||||||
this.subscribeCache = {};
|
this.subscribeCache = {};
|
||||||
|
@ -21,16 +21,18 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<component
|
<div
|
||||||
:is="urlDefined ? 'a' : 'span'"
|
ref="conditionWidgetElement"
|
||||||
class="c-condition-widget u-style-receiver js-style-receiver"
|
class="c-condition-widget u-style-receiver js-style-receiver"
|
||||||
:href="url"
|
|
||||||
:target="url ? '_BLANK' : ''"
|
|
||||||
>
|
>
|
||||||
<div class="c-condition-widget__label">
|
<component
|
||||||
{{ label }}
|
:is="urlDefined ? 'a' : 'div'"
|
||||||
</div>
|
class="c-condition-widget__label-wrapper"
|
||||||
</component>
|
:href="url"
|
||||||
|
>
|
||||||
|
<div class="c-condition-widget__label">{{ label }}</div>
|
||||||
|
</component>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -40,19 +42,26 @@ export default {
|
|||||||
inject: ['openmct', 'domainObject'],
|
inject: ['openmct', 'domainObject'],
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
conditionalLabel: '',
|
conditionalLabel: ''
|
||||||
conditionSetIdentifier: null,
|
|
||||||
domainObjectLabel: '',
|
|
||||||
url: null,
|
|
||||||
urlDefined: false,
|
|
||||||
useConditionSetOutputAsLabel: false
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
urlDefined() {
|
||||||
|
return this.domainObject.url?.length > 0;
|
||||||
|
},
|
||||||
|
url() {
|
||||||
|
return this.urlDefined ? sanitizeUrl(this.domainObject.url) : null;
|
||||||
|
},
|
||||||
|
useConditionSetOutputAsLabel() {
|
||||||
|
return this.conditionSetIdentifier && this.domainObject.configuration.useConditionSetOutputAsLabel;
|
||||||
|
},
|
||||||
|
conditionSetIdentifier() {
|
||||||
|
return this.domainObject.configuration?.objectStyles?.conditionSetIdentifier;
|
||||||
|
},
|
||||||
label() {
|
label() {
|
||||||
return this.useConditionSetOutputAsLabel
|
return this.useConditionSetOutputAsLabel
|
||||||
? this.conditionalLabel
|
? this.conditionalLabel
|
||||||
: this.domainObjectLabel
|
: this.domainObject.label
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -69,20 +78,11 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.unlisten = this.openmct.objects.observe(this.domainObject, '*', this.updateDomainObject);
|
|
||||||
|
|
||||||
if (this.domainObject) {
|
if (this.domainObject) {
|
||||||
this.updateDomainObject(this.domainObject);
|
|
||||||
this.listenToConditionSetChanges();
|
this.listenToConditionSetChanges();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.conditionSetIdentifier = null;
|
|
||||||
|
|
||||||
if (this.unlisten) {
|
|
||||||
this.unlisten();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.stopListeningToConditionSetChanges();
|
this.stopListeningToConditionSetChanges();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -121,31 +121,6 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.conditionalLabel = latestDatum.output || '';
|
this.conditionalLabel = latestDatum.output || '';
|
||||||
},
|
|
||||||
updateDomainObject(domainObject) {
|
|
||||||
if (this.domainObjectLabel !== domainObject.label) {
|
|
||||||
this.domainObjectLabel = domainObject.label;
|
|
||||||
}
|
|
||||||
|
|
||||||
const urlDefined = domainObject.url && domainObject.url.length > 0;
|
|
||||||
if (this.urlDefined !== urlDefined) {
|
|
||||||
this.urlDefined = urlDefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const url = this.urlDefined ? sanitizeUrl(domainObject.url) : null;
|
|
||||||
if (this.url !== url) {
|
|
||||||
this.url = url;
|
|
||||||
}
|
|
||||||
|
|
||||||
const conditionSetIdentifier = domainObject.configuration?.objectStyles?.conditionSetIdentifier;
|
|
||||||
if (conditionSetIdentifier && this.conditionSetIdentifier !== conditionSetIdentifier) {
|
|
||||||
this.conditionSetIdentifier = conditionSetIdentifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
const useConditionSetOutputAsLabel = this.conditionSetIdentifier && domainObject.configuration.useConditionSetOutputAsLabel;
|
|
||||||
if (this.useConditionSetOutputAsLabel !== useConditionSetOutputAsLabel) {
|
|
||||||
this.useConditionSetOutputAsLabel = useConditionSetOutputAsLabel;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -26,31 +26,35 @@
|
|||||||
background-color: rgba($colorBodyFg, 0.1); // Give a little presence if the user hasn't defined a fill color
|
background-color: rgba($colorBodyFg, 0.1); // Give a little presence if the user hasn't defined a fill color
|
||||||
border-radius: $basicCr;
|
border-radius: $basicCr;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
display: inline-block;
|
display: block;
|
||||||
padding: $interiorMarginLg $interiorMarginLg * 2;
|
max-width: max-content;
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.c-condition-widget__label {
|
.c-condition-widget__label {
|
||||||
padding: $interiorMargin;
|
// Either a <div> or an <a> tag
|
||||||
|
padding: $interiorMargin $interiorMargin * 1.5;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
a.c-condition-widget {
|
|
||||||
// Widget is conditionally made into a <a> when URL property has been defined
|
|
||||||
cursor: pointer !important;
|
|
||||||
pointer-events: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make Condition Widget expand when in a hidden frame Layout context
|
// Make Condition Widget expand when in a hidden frame Layout context
|
||||||
// For both static and Flexible Layouts
|
// For both static and Flexible Layouts
|
||||||
.c-so-view--conditionWidget.c-so-view--no-frame {
|
.c-so-view--conditionWidget.c-so-view--no-frame {
|
||||||
.c-condition-widget {
|
.c-condition-widget {
|
||||||
|
@include abs();
|
||||||
|
max-width: unset;
|
||||||
|
|
||||||
|
&__label-wrapper {
|
||||||
@include abs();
|
@include abs();
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 0;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.c-so-view__frame-controls { display: none; }
|
.c-so-view__frame-controls { display: none; }
|
||||||
|
@ -36,6 +36,7 @@ export default function plugin() {
|
|||||||
domainObject.configuration = {};
|
domainObject.configuration = {};
|
||||||
domainObject.label = 'Condition Widget';
|
domainObject.label = 'Condition Widget';
|
||||||
domainObject.conditionalLabel = '';
|
domainObject.conditionalLabel = '';
|
||||||
|
domainObject.url = '';
|
||||||
},
|
},
|
||||||
form: [
|
form: [
|
||||||
{
|
{
|
||||||
|
@ -20,8 +20,6 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
import JSONExporter from '/src/exporters/JSONExporter.js';
|
import JSONExporter from '/src/exporters/JSONExporter.js';
|
||||||
|
|
||||||
import _ from 'lodash';
|
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
|
|
||||||
export default class ExportAsJSONAction {
|
export default class ExportAsJSONAction {
|
||||||
@ -35,10 +33,9 @@ export default class ExportAsJSONAction {
|
|||||||
this.group = "json";
|
this.group = "json";
|
||||||
this.priority = 1;
|
this.priority = 1;
|
||||||
|
|
||||||
this.externalIdentifiers = [];
|
this.tree = null;
|
||||||
this.tree = {};
|
this.calls = null;
|
||||||
this.calls = 0;
|
this.idMap = null;
|
||||||
this.idMap = {};
|
|
||||||
|
|
||||||
this.JSONExportService = new JSONExporter();
|
this.JSONExportService = new JSONExporter();
|
||||||
}
|
}
|
||||||
@ -60,21 +57,164 @@ export default class ExportAsJSONAction {
|
|||||||
*/
|
*/
|
||||||
invoke(objectpath) {
|
invoke(objectpath) {
|
||||||
this.tree = {};
|
this.tree = {};
|
||||||
|
this.calls = 0;
|
||||||
|
this.idMap = {};
|
||||||
|
|
||||||
const root = objectpath[0];
|
const root = objectpath[0];
|
||||||
this.root = JSON.parse(JSON.stringify(root));
|
this.root = this._copy(root);
|
||||||
const rootId = this._getId(this.root);
|
|
||||||
|
const rootId = this._getKeystring(this.root);
|
||||||
this.tree[rootId] = this.root;
|
this.tree[rootId] = this.root;
|
||||||
|
|
||||||
this._write(this.root);
|
this._write(this.root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @param {object} parent
|
||||||
|
*/
|
||||||
|
async _write(parent) {
|
||||||
|
this.calls++;
|
||||||
|
|
||||||
|
//conditional object styles are not saved on the composition, so we need to check for them
|
||||||
|
const conditionSetIdentifier = this._getConditionSetIdentifier(parent);
|
||||||
|
const hasItemConditionSetIdentifiers = this._hasItemConditionSetIdentifiers(parent);
|
||||||
|
const composition = this.openmct.composition.get(parent);
|
||||||
|
|
||||||
|
if (composition) {
|
||||||
|
const children = await composition.load();
|
||||||
|
|
||||||
|
children.forEach((child) => {
|
||||||
|
this._exportObject(child, parent);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!conditionSetIdentifier && !hasItemConditionSetIdentifiers) {
|
||||||
|
this._decrementCallsAndSave();
|
||||||
|
} else {
|
||||||
|
const conditionSetObjects = [];
|
||||||
|
|
||||||
|
// conditionSetIdentifiers directly in objectStyles object
|
||||||
|
if (conditionSetIdentifier) {
|
||||||
|
conditionSetObjects.push(await this.openmct.objects.get(conditionSetIdentifier));
|
||||||
|
}
|
||||||
|
|
||||||
|
// conditionSetIdentifiers stored on item ids in the objectStyles object
|
||||||
|
if (hasItemConditionSetIdentifiers) {
|
||||||
|
const itemConditionSetIdentifiers = this._getItemConditionSetIdentifiers(parent);
|
||||||
|
|
||||||
|
for (const itemConditionSetIdentifier of itemConditionSetIdentifiers) {
|
||||||
|
conditionSetObjects.push(await this.openmct.objects.get(itemConditionSetIdentifier));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const conditionSetObject of conditionSetObjects) {
|
||||||
|
this._exportObject(conditionSetObject, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._decrementCallsAndSave();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_exportObject(child, parent) {
|
||||||
|
const originalKeyString = this._getKeystring(child);
|
||||||
|
const createable = this._isCreatableAndPersistable(child);
|
||||||
|
const isNotInfinite = !Object.prototype.hasOwnProperty.call(this.tree, originalKeyString);
|
||||||
|
|
||||||
|
if (createable && isNotInfinite) {
|
||||||
|
// for external or linked objects we generate new keys, if they don't exist already
|
||||||
|
if (this._isLinkedObject(child, parent)) {
|
||||||
|
child = this._rewriteLink(child, parent);
|
||||||
|
} else {
|
||||||
|
this.tree[originalKeyString] = child;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._write(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @param {object} child
|
||||||
|
* @param {object} parent
|
||||||
|
* @returns {object}
|
||||||
|
*/
|
||||||
|
_rewriteLink(child, parent) {
|
||||||
|
const originalKeyString = this._getKeystring(child);
|
||||||
|
const parentKeyString = this._getKeystring(parent);
|
||||||
|
const conditionSetIdentifier = this._getConditionSetIdentifier(parent);
|
||||||
|
const hasItemConditionSetIdentifiers = this._hasItemConditionSetIdentifiers(parent);
|
||||||
|
const existingMappedKeyString = this.idMap[originalKeyString];
|
||||||
|
let copy;
|
||||||
|
|
||||||
|
if (!existingMappedKeyString) {
|
||||||
|
copy = this._copy(child);
|
||||||
|
copy.identifier.key = uuid();
|
||||||
|
|
||||||
|
if (!conditionSetIdentifier && !hasItemConditionSetIdentifiers) {
|
||||||
|
copy.location = parentKeyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
let newKeyString = this._getKeystring(copy);
|
||||||
|
this.idMap[originalKeyString] = newKeyString;
|
||||||
|
this.tree[newKeyString] = copy;
|
||||||
|
} else {
|
||||||
|
copy = this.tree[existingMappedKeyString];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conditionSetIdentifier || hasItemConditionSetIdentifiers) {
|
||||||
|
|
||||||
|
// update objectStyle object
|
||||||
|
if (conditionSetIdentifier) {
|
||||||
|
const directObjectStylesIdentifier = this.openmct.objects.areIdsEqual(
|
||||||
|
parent.configuration.objectStyles.conditionSetIdentifier,
|
||||||
|
child.identifier
|
||||||
|
);
|
||||||
|
|
||||||
|
if (directObjectStylesIdentifier) {
|
||||||
|
parent.configuration.objectStyles.conditionSetIdentifier = copy.identifier;
|
||||||
|
this.tree[parentKeyString].configuration.objectStyles.conditionSetIdentifier = copy.identifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update per item id on objectStyle object
|
||||||
|
if (hasItemConditionSetIdentifiers) {
|
||||||
|
for (const itemId in parent.configuration.objectStyles) {
|
||||||
|
if (parent.configuration.objectStyles[itemId]) {
|
||||||
|
const itemConditionSetIdentifier = parent.configuration.objectStyles[itemId].conditionSetIdentifier;
|
||||||
|
|
||||||
|
if (
|
||||||
|
itemConditionSetIdentifier
|
||||||
|
&& this.openmct.objects.areIdsEqual(itemConditionSetIdentifier, child.identifier)
|
||||||
|
) {
|
||||||
|
parent.configuration.objectStyles[itemId].conditionSetIdentifier = copy.identifier;
|
||||||
|
this.tree[parentKeyString].configuration.objectStyles[itemId].conditionSetIdentifier = copy.identifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// just update parent
|
||||||
|
const index = parent.composition.findIndex(identifier => {
|
||||||
|
return this.openmct.objects.areIdsEqual(child.identifier, identifier);
|
||||||
|
});
|
||||||
|
|
||||||
|
parent.composition[index] = copy.identifier;
|
||||||
|
this.tree[parentKeyString].composition[index] = copy.identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {object} domainObject
|
* @param {object} domainObject
|
||||||
* @returns {string} A string representation of the given identifier, including namespace and key
|
* @returns {string} A string representation of the given identifier, including namespace and key
|
||||||
*/
|
*/
|
||||||
_getId(domainObject) {
|
_getKeystring(domainObject) {
|
||||||
return this.openmct.objects.makeKeyString(domainObject.identifier);
|
return this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {object} domainObject
|
* @param {object} domainObject
|
||||||
@ -86,6 +226,7 @@ export default class ExportAsJSONAction {
|
|||||||
|
|
||||||
return type && type.definition.creatable && isPersistable;
|
return type && type.definition.creatable && isPersistable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {object} child
|
* @param {object} child
|
||||||
@ -93,74 +234,80 @@ export default class ExportAsJSONAction {
|
|||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
_isLinkedObject(child, parent) {
|
_isLinkedObject(child, parent) {
|
||||||
if (child.location !== this._getId(parent)
|
const rootKeyString = this._getKeystring(this.root);
|
||||||
&& !Object.keys(this.tree).includes(child.location)
|
const childKeyString = this._getKeystring(child);
|
||||||
&& this._getId(child) !== this._getId(this.root)
|
const parentKeyString = this._getKeystring(parent);
|
||||||
|| this.externalIdentifiers.includes(this._getId(child))) {
|
|
||||||
|
|
||||||
|
return (child.location !== parentKeyString
|
||||||
|
&& !Object.keys(this.tree).includes(child.location)
|
||||||
|
&& childKeyString !== rootKeyString)
|
||||||
|
|| this.idMap[childKeyString] !== undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
_getConditionSetIdentifier(object) {
|
||||||
|
return object.configuration?.objectStyles?.conditionSetIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
_hasItemConditionSetIdentifiers(parent) {
|
||||||
|
const objectStyles = parent.configuration?.objectStyles;
|
||||||
|
|
||||||
|
for (const itemId in objectStyles) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(objectStyles[itemId], 'conditionSetIdentifier')) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* @private
|
_getItemConditionSetIdentifiers(parent) {
|
||||||
* @param {object} child
|
const objectStyles = parent.configuration?.objectStyles;
|
||||||
* @param {object} parent
|
let identifiers = new Set();
|
||||||
* @returns {object}
|
|
||||||
*/
|
if (objectStyles) {
|
||||||
_rewriteLink(child, parent) {
|
Object.keys(objectStyles).forEach(itemId => {
|
||||||
this.externalIdentifiers.push(this._getId(child));
|
if (objectStyles[itemId].conditionSetIdentifier) {
|
||||||
const index = parent.composition.findIndex(id => {
|
identifiers.add(objectStyles[itemId].conditionSetIdentifier);
|
||||||
return _.isEqual(child.identifier, id);
|
}
|
||||||
});
|
});
|
||||||
const copyOfChild = JSON.parse(JSON.stringify(child));
|
|
||||||
|
|
||||||
copyOfChild.identifier.key = uuid();
|
|
||||||
const newIdString = this._getId(copyOfChild);
|
|
||||||
const parentId = this._getId(parent);
|
|
||||||
|
|
||||||
this.idMap[this._getId(child)] = newIdString;
|
|
||||||
copyOfChild.location = parentId;
|
|
||||||
parent.composition[index] = copyOfChild.identifier;
|
|
||||||
this.tree[newIdString] = copyOfChild;
|
|
||||||
this.tree[parentId].composition[index] = copyOfChild.identifier;
|
|
||||||
|
|
||||||
return copyOfChild;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
return Array.from(identifiers);
|
||||||
* @private
|
|
||||||
* @param {object} child
|
|
||||||
* @param {object} parent
|
|
||||||
* @returns {object}
|
|
||||||
*/
|
|
||||||
_rewriteLinkForReference(child, parent) {
|
|
||||||
const childId = this._getId(child);
|
|
||||||
this.externalIdentifiers.push(childId);
|
|
||||||
const copyOfChild = JSON.parse(JSON.stringify(child));
|
|
||||||
|
|
||||||
copyOfChild.identifier.key = uuid();
|
|
||||||
const newIdString = this._getId(copyOfChild);
|
|
||||||
const parentId = this._getId(parent);
|
|
||||||
|
|
||||||
this.idMap[childId] = newIdString;
|
|
||||||
copyOfChild.location = null;
|
|
||||||
parent.configuration.objectStyles.conditionSetIdentifier = copyOfChild.identifier;
|
|
||||||
this.tree[newIdString] = copyOfChild;
|
|
||||||
this.tree[parentId].configuration.objectStyles.conditionSetIdentifier = copyOfChild.identifier;
|
|
||||||
|
|
||||||
return copyOfChild;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_rewriteReferences() {
|
_rewriteReferences() {
|
||||||
|
const oldKeyStrings = Object.keys(this.idMap);
|
||||||
let treeString = JSON.stringify(this.tree);
|
let treeString = JSON.stringify(this.tree);
|
||||||
Object.keys(this.idMap).forEach(function (oldId) {
|
|
||||||
const newId = this.idMap[oldId];
|
oldKeyStrings.forEach((oldKeyString) => {
|
||||||
treeString = treeString.split(oldId).join(newId);
|
// this will cover keyStrings, identifiers and identifiers created
|
||||||
}.bind(this));
|
// by hand that may be structured differently from those created with 'makeKeyString'
|
||||||
|
const newKeyString = this.idMap[oldKeyString];
|
||||||
|
const newIdentifier = JSON.stringify(this.openmct.objects.parseKeyString(newKeyString));
|
||||||
|
const oldIdentifier = this.openmct.objects.parseKeyString(oldKeyString);
|
||||||
|
const oldIdentifierNamespaceFirst = JSON.stringify(oldIdentifier);
|
||||||
|
const oldIdentifierKeyFirst = JSON.stringify({
|
||||||
|
key: oldIdentifier.key,
|
||||||
|
namespace: oldIdentifier.namespace
|
||||||
|
});
|
||||||
|
|
||||||
|
// replace keyStrings
|
||||||
|
treeString = treeString.split(oldKeyString).join(newKeyString);
|
||||||
|
|
||||||
|
// check for namespace first identifiers, replace if necessary
|
||||||
|
if (treeString.includes(oldIdentifierNamespaceFirst)) {
|
||||||
|
treeString = treeString.split(oldIdentifierNamespaceFirst).join(newIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for key first identifiers, replace if necessary
|
||||||
|
if (treeString.includes(oldIdentifierKeyFirst)) {
|
||||||
|
treeString = treeString.split(oldIdentifierKeyFirst).join(newIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
this.tree = JSON.parse(treeString);
|
this.tree = JSON.parse(treeString);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -180,70 +327,10 @@ export default class ExportAsJSONAction {
|
|||||||
_wrapTree() {
|
_wrapTree() {
|
||||||
return {
|
return {
|
||||||
"openmct": this.tree,
|
"openmct": this.tree,
|
||||||
"rootId": this._getId(this.root)
|
"rootId": this._getKeystring(this.root)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @param {object} parent
|
|
||||||
*/
|
|
||||||
_write(parent) {
|
|
||||||
this.calls++;
|
|
||||||
//conditional object styles are not saved on the composition, so we need to check for them
|
|
||||||
let childObjectReferenceId = parent.configuration?.objectStyles?.conditionSetIdentifier;
|
|
||||||
|
|
||||||
const composition = this.openmct.composition.get(parent);
|
|
||||||
if (composition !== undefined) {
|
|
||||||
composition.load()
|
|
||||||
.then((children) => {
|
|
||||||
children.forEach((child, index) => {
|
|
||||||
// Only export if object is creatable
|
|
||||||
if (this._isCreatableAndPersistable(child)) {
|
|
||||||
// Prevents infinite export of self-contained objs
|
|
||||||
if (!Object.prototype.hasOwnProperty.call(this.tree, this._getId(child))) {
|
|
||||||
// If object is a link to something absent from
|
|
||||||
// tree, generate new id and treat as new object
|
|
||||||
if (this._isLinkedObject(child, parent)) {
|
|
||||||
child = this._rewriteLink(child, parent);
|
|
||||||
} else {
|
|
||||||
this.tree[this._getId(child)] = child;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._write(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this._decrementCallsAndSave();
|
|
||||||
});
|
|
||||||
} else if (!childObjectReferenceId) {
|
|
||||||
this._decrementCallsAndSave();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (childObjectReferenceId) {
|
|
||||||
this.openmct.objects.get(childObjectReferenceId)
|
|
||||||
.then((child) => {
|
|
||||||
// Only export if object is creatable
|
|
||||||
if (this._isCreatableAndPersistable(child)) {
|
|
||||||
// Prevents infinite export of self-contained objs
|
|
||||||
if (!Object.prototype.hasOwnProperty.call(this.tree, this._getId(child))) {
|
|
||||||
// If object is a link to something absent from
|
|
||||||
// tree, generate new id and treat as new object
|
|
||||||
if (this._isLinkedObject(child, parent)) {
|
|
||||||
child = this._rewriteLinkForReference(child, parent);
|
|
||||||
} else {
|
|
||||||
this.tree[this._getId(child)] = child;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._write(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this._decrementCallsAndSave();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_decrementCallsAndSave() {
|
_decrementCallsAndSave() {
|
||||||
this.calls--;
|
this.calls--;
|
||||||
if (this.calls === 0) {
|
if (this.calls === 0) {
|
||||||
@ -251,4 +338,8 @@ export default class ExportAsJSONAction {
|
|||||||
this._saveAs(this._wrapTree());
|
this._saveAs(this._wrapTree());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_copy(object) {
|
||||||
|
return JSON.parse(JSON.stringify(object));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,10 @@ define([
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
showTab: function (isEditing) {
|
showTab: function (isEditing) {
|
||||||
|
if (isEditing) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const hasPersistedFilters = Boolean(domainObject?.configuration?.filters);
|
const hasPersistedFilters = Boolean(domainObject?.configuration?.filters);
|
||||||
const hasGlobalFilters = Boolean(domainObject?.configuration?.globalFilters);
|
const hasGlobalFilters = Boolean(domainObject?.configuration?.globalFilters);
|
||||||
|
|
||||||
|
@ -64,6 +64,11 @@ export default class CreateAction extends PropertiesAction {
|
|||||||
|
|
||||||
const parentDomainObject = this.openmct.objects.toMutable(parentDomainObjectPath[0]);
|
const parentDomainObject = this.openmct.objects.toMutable(parentDomainObjectPath[0]);
|
||||||
|
|
||||||
|
// TODO REMOVE FOR OMM-RELEASE-5.0
|
||||||
|
if (!parentDomainObject.identifier.namespace && parentDomainObject.key) {
|
||||||
|
console.error(`parent namespace in key: ${parentDomainObject.key}`);
|
||||||
|
}
|
||||||
|
|
||||||
this.domainObject.modified = Date.now();
|
this.domainObject.modified = Date.now();
|
||||||
this.domainObject.location = this.openmct.objects.makeKeyString(parentDomainObject.identifier);
|
this.domainObject.location = this.openmct.objects.makeKeyString(parentDomainObject.identifier);
|
||||||
this.domainObject.identifier.namespace = parentDomainObject.identifier.namespace;
|
this.domainObject.identifier.namespace = parentDomainObject.identifier.namespace;
|
||||||
|
@ -31,6 +31,7 @@ export default class ImportAsJSONAction {
|
|||||||
this.cssClass = "icon-import";
|
this.cssClass = "icon-import";
|
||||||
this.group = "json";
|
this.group = "json";
|
||||||
this.priority = 2;
|
this.priority = 2;
|
||||||
|
this.newObjects = [];
|
||||||
|
|
||||||
this.openmct = openmct;
|
this.openmct = openmct;
|
||||||
}
|
}
|
||||||
@ -85,22 +86,25 @@ export default class ImportAsJSONAction {
|
|||||||
let objectIdentifiers = this._getObjectReferenceIds(parent);
|
let objectIdentifiers = this._getObjectReferenceIds(parent);
|
||||||
|
|
||||||
if (objectIdentifiers.length) {
|
if (objectIdentifiers.length) {
|
||||||
let newObj;
|
const parentId = this.openmct.objects.makeKeyString(parent.identifier);
|
||||||
|
seen.push(parentId);
|
||||||
|
|
||||||
seen.push(parent.id);
|
for (const childId of objectIdentifiers) {
|
||||||
|
|
||||||
objectIdentifiers.forEach(async (childId) => {
|
|
||||||
const keystring = this.openmct.objects.makeKeyString(childId);
|
const keystring = this.openmct.objects.makeKeyString(childId);
|
||||||
if (!tree[keystring] || seen.includes(keystring)) {
|
if (!tree[keystring] || seen.includes(keystring)) {
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newModel = tree[keystring];
|
const newModel = tree[keystring];
|
||||||
delete newModel.persisted;
|
delete newModel.persisted;
|
||||||
|
|
||||||
newObj = await this._instantiate(newModel);
|
this.newObjects.push(newModel);
|
||||||
this._deepInstantiate(newObj, tree, seen);
|
|
||||||
}, this);
|
// make sure there weren't any errors saving
|
||||||
|
if (newModel) {
|
||||||
|
this._deepInstantiate(newModel, tree, seen);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -110,19 +114,32 @@ export default class ImportAsJSONAction {
|
|||||||
*/
|
*/
|
||||||
_getObjectReferenceIds(parent) {
|
_getObjectReferenceIds(parent) {
|
||||||
let objectIdentifiers = [];
|
let objectIdentifiers = [];
|
||||||
|
let itemObjectReferences = [];
|
||||||
|
const objectStyles = parent?.configuration?.objectStyles;
|
||||||
|
const parentComposition = this.openmct.composition.get(parent);
|
||||||
|
|
||||||
let parentComposition = this.openmct.composition.get(parent);
|
|
||||||
if (parentComposition) {
|
if (parentComposition) {
|
||||||
objectIdentifiers = Array.from(parentComposition.domainObject.composition);
|
objectIdentifiers = Array.from(parent.composition);
|
||||||
}
|
}
|
||||||
|
|
||||||
//conditional object styles are not saved on the composition, so we need to check for them
|
//conditional object styles are not saved on the composition, so we need to check for them
|
||||||
let parentObjectReference = parent.configuration?.objectStyles?.conditionSetIdentifier;
|
if (objectStyles) {
|
||||||
|
const parentObjectReference = objectStyles.conditionSetIdentifier;
|
||||||
|
|
||||||
if (parentObjectReference) {
|
if (parentObjectReference) {
|
||||||
objectIdentifiers.push(parentObjectReference);
|
objectIdentifiers.push(parentObjectReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
return objectIdentifiers;
|
function hasConditionSetIdentifier(item) {
|
||||||
|
return Boolean(item.conditionSetIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
itemObjectReferences = Object.values(objectStyles)
|
||||||
|
.filter(hasConditionSetIdentifier)
|
||||||
|
.map(item => item.conditionSetIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.from(new Set([...objectIdentifiers, ...itemObjectReferences]));
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
@ -155,13 +172,21 @@ export default class ImportAsJSONAction {
|
|||||||
const tree = this._generateNewIdentifiers(objTree, namespace);
|
const tree = this._generateNewIdentifiers(objTree, namespace);
|
||||||
const rootId = tree.rootId;
|
const rootId = tree.rootId;
|
||||||
|
|
||||||
const rootModel = tree.openmct[rootId];
|
const rootObj = tree.openmct[rootId];
|
||||||
delete rootModel.persisted;
|
delete rootObj.persisted;
|
||||||
|
this.newObjects.push(rootObj);
|
||||||
|
|
||||||
const rootObj = await this._instantiate(rootModel);
|
|
||||||
if (this.openmct.composition.checkPolicy(domainObject, rootObj)) {
|
if (this.openmct.composition.checkPolicy(domainObject, rootObj)) {
|
||||||
this._deepInstantiate(rootObj, tree.openmct, []);
|
this._deepInstantiate(rootObj, tree.openmct, []);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await Promise.all(this.newObjects.map(this._instantiate, this));
|
||||||
|
} catch (error) {
|
||||||
|
this.openmct.notifications.error('Error saving objects');
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
const compositionCollection = this.openmct.composition.get(domainObject);
|
const compositionCollection = this.openmct.composition.get(domainObject);
|
||||||
let domainObjectKeyString = this.openmct.objects.makeKeyString(domainObject.identifier);
|
let domainObjectKeyString = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||||
this.openmct.objects.mutate(rootObj, 'location', domainObjectKeyString);
|
this.openmct.objects.mutate(rootObj, 'location', domainObjectKeyString);
|
||||||
@ -184,16 +209,11 @@ export default class ImportAsJSONAction {
|
|||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {object} rootModel
|
* @param {object} model
|
||||||
* @returns {object}
|
* @returns {object}
|
||||||
*/
|
*/
|
||||||
async _instantiate(rootModel) {
|
_instantiate(model) {
|
||||||
const success = await this.openmct.objects.save(rootModel);
|
return this.openmct.objects.save(model);
|
||||||
if (success) {
|
|
||||||
return rootModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.openmct.notifications.error('Error saving objects');
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
class="c-icon-button c-button--menu icon-font"
|
class="c-icon-button c-button--menu icon-font"
|
||||||
@click.prevent.stop="showFontMenu"
|
@click.prevent.stop="showFontMenu"
|
||||||
>
|
>
|
||||||
<span class="c-button__label">{{ fontTypeLable }}</span>
|
<span class="c-button__label">{{ fontTypeLabel }}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -43,7 +43,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
fontTypeLable() {
|
fontTypeLabel() {
|
||||||
const fontType = FONTS.find(f => f.value === this.fontStyle.font);
|
const fontType = FONTS.find(f => f.value === this.fontStyle.font);
|
||||||
if (!fontType) {
|
if (!fontType) {
|
||||||
return '??';
|
return '??';
|
||||||
|
@ -88,7 +88,7 @@ define([], function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getContextMenuActions() {
|
getContextMenuActions() {
|
||||||
return ['viewDatumAction'];
|
return ['viewDatumAction', 'viewHistoricalData'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,14 +175,22 @@ export default {
|
|||||||
getDatum() {
|
getDatum() {
|
||||||
return this.row.fullDatum;
|
return this.row.fullDatum;
|
||||||
},
|
},
|
||||||
showContextMenu: function (event) {
|
showContextMenu: async function (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
this.updateViewContext();
|
this.updateViewContext();
|
||||||
this.markRow(event);
|
this.markRow(event);
|
||||||
|
|
||||||
|
const contextualDomainObject = await this.row.getContextualDomainObject?.(this.openmct, this.row.objectKeyString);
|
||||||
|
|
||||||
|
let objectPath = this.objectPath;
|
||||||
|
if (contextualDomainObject) {
|
||||||
|
objectPath = objectPath.slice();
|
||||||
|
objectPath.unshift(contextualDomainObject);
|
||||||
|
}
|
||||||
|
|
||||||
const actions = this.row.getContextMenuActions().map(key => this.openmct.actions.getAction(key));
|
const actions = this.row.getContextMenuActions().map(key => this.openmct.actions.getAction(key));
|
||||||
const menuItems = this.openmct.menus.actionsToMenuItems(actions, this.objectPath, this.currentView);
|
const menuItems = this.openmct.menus.actionsToMenuItems(actions, objectPath, this.currentView);
|
||||||
if (menuItems.length) {
|
if (menuItems.length) {
|
||||||
this.openmct.menus.showMenu(event.x, event.y, menuItems);
|
this.openmct.menus.showMenu(event.x, event.y, menuItems);
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ export default {
|
|||||||
return this.domainObject && (this.currentObjectPath || this.objectPath);
|
return this.domainObject && (this.currentObjectPath || this.objectPath);
|
||||||
},
|
},
|
||||||
objectFontStyle() {
|
objectFontStyle() {
|
||||||
return this.domainObject && this.domainObject.configuration && this.domainObject.configuration.fontStyle;
|
return this.domainObject?.configuration?.fontStyle;
|
||||||
},
|
},
|
||||||
fontSize() {
|
fontSize() {
|
||||||
return this.objectFontStyle ? this.objectFontStyle.fontSize : this.layoutFontSize;
|
return this.objectFontStyle ? this.objectFontStyle.fontSize : this.layoutFontSize;
|
||||||
@ -287,6 +287,8 @@ export default {
|
|||||||
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.updateStyle(this.styleRuleManager?.currentStyle);
|
this.updateStyle(this.styleRuleManager?.currentStyle);
|
||||||
|
this.setFontSize(this.fontSize);
|
||||||
|
this.setFont(this.font);
|
||||||
this.getActionCollection();
|
this.getActionCollection();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -329,9 +331,9 @@ export default {
|
|||||||
},
|
},
|
||||||
initObjectStyles() {
|
initObjectStyles() {
|
||||||
if (!this.styleRuleManager) {
|
if (!this.styleRuleManager) {
|
||||||
this.styleRuleManager = new StyleRuleManager((this.domainObject.configuration && this.domainObject.configuration.objectStyles), this.openmct, this.updateStyle.bind(this), true);
|
this.styleRuleManager = new StyleRuleManager((this.domainObject.configuration?.objectStyles), this.openmct, this.updateStyle.bind(this), true);
|
||||||
} else {
|
} else {
|
||||||
this.styleRuleManager.updateObjectStyleConfig(this.domainObject.configuration && this.domainObject.configuration.objectStyles);
|
this.styleRuleManager.updateObjectStyleConfig(this.domainObject.configuration?.objectStyles);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.stopListeningStyles) {
|
if (this.stopListeningStyles) {
|
||||||
@ -343,9 +345,6 @@ export default {
|
|||||||
this.styleRuleManager.updateObjectStyleConfig(newObjectStyle);
|
this.styleRuleManager.updateObjectStyleConfig(newObjectStyle);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setFontSize(this.fontSize);
|
|
||||||
this.setFont(this.font);
|
|
||||||
|
|
||||||
this.stopListeningFontStyles = this.openmct.objects.observe(this.domainObject, 'configuration.fontStyle', (newFontStyle) => {
|
this.stopListeningFontStyles = this.openmct.objects.observe(this.domainObject, 'configuration.fontStyle', (newFontStyle) => {
|
||||||
this.setFontSize(newFontStyle.fontSize);
|
this.setFontSize(newFontStyle.fontSize);
|
||||||
this.setFont(newFontStyle.font);
|
this.setFont(newFontStyle.font);
|
||||||
|
@ -322,10 +322,14 @@ export default {
|
|||||||
},
|
},
|
||||||
async openTreeItem(parentItem) {
|
async openTreeItem(parentItem) {
|
||||||
const parentPath = parentItem.navigationPath;
|
const parentPath = parentItem.navigationPath;
|
||||||
|
const abortSignal = this.startItemLoad(parentPath);
|
||||||
|
|
||||||
this.startItemLoad(parentPath);
|
|
||||||
// pass in abort signal when functional
|
// pass in abort signal when functional
|
||||||
const childrenItems = await this.loadAndBuildTreeItemsFor(parentItem.object.identifier, parentItem.objectPath);
|
const childrenItems = await this.loadAndBuildTreeItemsFor(
|
||||||
|
parentItem.object.identifier,
|
||||||
|
parentItem.objectPath,
|
||||||
|
abortSignal
|
||||||
|
);
|
||||||
const parentIndex = this.treeItems.indexOf(parentItem);
|
const parentIndex = this.treeItems.indexOf(parentItem);
|
||||||
|
|
||||||
// if it's not loading, it was aborted
|
// if it's not loading, it was aborted
|
||||||
|
Reference in New Issue
Block a user