mirror of
https://github.com/nasa/openmct.git
synced 2025-06-02 07:30:49 +00:00
[Summary Widget] support enum fields (#2406)
* Display a drop down menu if the selected key is of type enum. * Create normalized dataum when persisting telemerty datum using metadatum source as key.: * * Clear config values before creating new inputs. * Emit ‘change' event with the value of the first option after creating the select element. * If a value is a number, pass it as a number when emitting ‘change’. Similarly, if the cashed telemetry value is a number, convert it to number before applying the operation and validation. * Update description. * Update description in operations.js also.
This commit is contained in:
parent
35d0c02bc5
commit
72ea7b80fd
@ -70,16 +70,14 @@ define([
|
|||||||
*/
|
*/
|
||||||
function onValueInput(event) {
|
function onValueInput(event) {
|
||||||
var elem = event.target,
|
var elem = event.target,
|
||||||
value = (isNaN(elem.valueAsNumber) ? elem.value : elem.valueAsNumber),
|
value = isNaN(Number(elem.value)) ? elem.value : Number(elem.value),
|
||||||
inputIndex = self.valueInputs.indexOf(elem);
|
inputIndex = self.valueInputs.indexOf(elem);
|
||||||
|
|
||||||
if (elem.tagName.toUpperCase() === 'INPUT') {
|
self.eventEmitter.emit('change', {
|
||||||
self.eventEmitter.emit('change', {
|
value: value,
|
||||||
value: value,
|
property: 'values[' + inputIndex + ']',
|
||||||
property: 'values[' + inputIndex + ']',
|
index: self.index
|
||||||
index: self.index
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.listenTo(this.deleteButton, 'click', this.remove, this);
|
this.listenTo(this.deleteButton, 'click', this.remove, this);
|
||||||
@ -108,8 +106,7 @@ define([
|
|||||||
Object.values(this.selects).forEach(function (select) {
|
Object.values(this.selects).forEach(function (select) {
|
||||||
$('.t-configuration', self.domElement).append(select.getDOM());
|
$('.t-configuration', self.domElement).append(select.getDOM());
|
||||||
});
|
});
|
||||||
|
this.listenTo($('.t-value-inputs', this.domElement), 'input', onValueInput);
|
||||||
this.listenTo($(this.domElement), 'input', onValueInput);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Condition.prototype.getDOM = function (container) {
|
Condition.prototype.getDOM = function (container) {
|
||||||
@ -167,7 +164,9 @@ define([
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* When an operation is selected, create the appropriate value inputs
|
* When an operation is selected, create the appropriate value inputs
|
||||||
* and add them to the view
|
* and add them to the view. If an operation is of type enum, create
|
||||||
|
* a drop-down menu instead.
|
||||||
|
*
|
||||||
* @param {string} operation The key of currently selected operation
|
* @param {string} operation The key of currently selected operation
|
||||||
*/
|
*/
|
||||||
Condition.prototype.generateValueInputs = function (operation) {
|
Condition.prototype.generateValueInputs = function (operation) {
|
||||||
@ -176,25 +175,49 @@ define([
|
|||||||
inputCount,
|
inputCount,
|
||||||
inputType,
|
inputType,
|
||||||
newInput,
|
newInput,
|
||||||
index = 0;
|
index = 0,
|
||||||
|
emitChange = false;
|
||||||
|
|
||||||
inputArea.html('');
|
inputArea.html('');
|
||||||
this.valueInputs = [];
|
this.valueInputs = [];
|
||||||
|
this.config.values = [];
|
||||||
|
|
||||||
if (evaluator.getInputCount(operation)) {
|
if (evaluator.getInputCount(operation)) {
|
||||||
inputCount = evaluator.getInputCount(operation);
|
inputCount = evaluator.getInputCount(operation);
|
||||||
inputType = evaluator.getInputType(operation);
|
inputType = evaluator.getInputType(operation);
|
||||||
|
|
||||||
while (index < inputCount) {
|
while (index < inputCount) {
|
||||||
if (!this.config.values[index]) {
|
if (inputType === 'select') {
|
||||||
this.config.values[index] = (inputType === 'number' ? 0 : '');
|
newInput = $('<select>' + this.generateSelectOptions() + '</select>');
|
||||||
|
emitChange = true;
|
||||||
|
} else {
|
||||||
|
this.config.values[index] = inputType === 'number' ? 0 : '';
|
||||||
|
newInput = $('<input type = "' + inputType + '" value = "' + this.config.values[index] + '"> </input>');
|
||||||
}
|
}
|
||||||
newInput = $('<input type = "' + inputType + '" value = "' + this.config.values[index] + '"> </input>');
|
|
||||||
this.valueInputs.push(newInput.get(0));
|
this.valueInputs.push(newInput.get(0));
|
||||||
inputArea.append(newInput);
|
inputArea.append(newInput);
|
||||||
index += 1;
|
index += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (emitChange) {
|
||||||
|
this.eventEmitter.emit('change', {
|
||||||
|
value: Number(newInput[0].options[0].value),
|
||||||
|
property: 'values[0]',
|
||||||
|
index: this.index
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Condition.prototype.generateSelectOptions = function () {
|
||||||
|
let telemetryMetadata = this.conditionManager.getTelemetryMetadata(this.config.object);
|
||||||
|
let options = '';
|
||||||
|
telemetryMetadata[this.config.key].enumerations.forEach(enumeration => {
|
||||||
|
options += '<option value="' + enumeration.value + '">'+ enumeration.string + '</option>';
|
||||||
|
});
|
||||||
|
return options;
|
||||||
|
};
|
||||||
|
|
||||||
return Condition;
|
return Condition;
|
||||||
});
|
});
|
||||||
|
@ -24,7 +24,8 @@ define([], function () {
|
|||||||
*/
|
*/
|
||||||
this.inputTypes = {
|
this.inputTypes = {
|
||||||
number: 'number',
|
number: 'number',
|
||||||
string: 'text'
|
string: 'text',
|
||||||
|
enum: 'select'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,7 +35,8 @@ define([], function () {
|
|||||||
*/
|
*/
|
||||||
this.inputValidators = {
|
this.inputValidators = {
|
||||||
number: this.validateNumberInput,
|
number: this.validateNumberInput,
|
||||||
string: this.validateStringInput
|
string: this.validateStringInput,
|
||||||
|
enum: this.validateNumberInput
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -201,7 +203,7 @@ define([], function () {
|
|||||||
return typeof input[0] === 'undefined';
|
return typeof input[0] === 'undefined';
|
||||||
},
|
},
|
||||||
text: 'is undefined',
|
text: 'is undefined',
|
||||||
appliesTo: ['string', 'number'],
|
appliesTo: ['string', 'number', 'enum'],
|
||||||
inputCount: 0,
|
inputCount: 0,
|
||||||
getDescription: function () {
|
getDescription: function () {
|
||||||
return ' is undefined';
|
return ' is undefined';
|
||||||
@ -212,11 +214,33 @@ define([], function () {
|
|||||||
return typeof input[0] !== 'undefined';
|
return typeof input[0] !== 'undefined';
|
||||||
},
|
},
|
||||||
text: 'is defined',
|
text: 'is defined',
|
||||||
appliesTo: ['string', 'number'],
|
appliesTo: ['string', 'number', 'enum'],
|
||||||
inputCount: 0,
|
inputCount: 0,
|
||||||
getDescription: function () {
|
getDescription: function () {
|
||||||
return ' is defined';
|
return ' is defined';
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
enumValueIs: {
|
||||||
|
operation: function (input) {
|
||||||
|
return input[0] === input[1];
|
||||||
|
},
|
||||||
|
text: 'is',
|
||||||
|
appliesTo: ['enum'],
|
||||||
|
inputCount: 1,
|
||||||
|
getDescription: function (values) {
|
||||||
|
return ' == ' + values[0];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enumValueIsNot: {
|
||||||
|
operation: function (input) {
|
||||||
|
return input[0] !== input[1];
|
||||||
|
},
|
||||||
|
text: 'is not',
|
||||||
|
appliesTo: ['enum'],
|
||||||
|
inputCount: 1,
|
||||||
|
getDescription: function (values) {
|
||||||
|
return ' != ' + values[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -310,13 +334,16 @@ define([], function () {
|
|||||||
validator;
|
validator;
|
||||||
|
|
||||||
if (cache[object] && typeof cache[object][key] !== 'undefined') {
|
if (cache[object] && typeof cache[object][key] !== 'undefined') {
|
||||||
telemetryValue = [cache[object][key]];
|
let value = cache[object][key];
|
||||||
|
telemetryValue = [isNaN(Number(value)) ? value : Number(value)];
|
||||||
}
|
}
|
||||||
|
|
||||||
op = this.operations[operation] && this.operations[operation].operation;
|
op = this.operations[operation] && this.operations[operation].operation;
|
||||||
input = telemetryValue && telemetryValue.concat(values);
|
input = telemetryValue && telemetryValue.concat(values);
|
||||||
validator = op && this.inputValidators[this.operations[operation].appliesTo[0]];
|
validator = op && this.inputValidators[this.operations[operation].appliesTo[0]];
|
||||||
|
|
||||||
if (op && input && validator) {
|
if (op && input && validator) {
|
||||||
if (this.operations[operation].appliesTo.length === 2) {
|
if (this.operations[operation].appliesTo.length > 1) {
|
||||||
return (this.validateNumberInput(input) || this.validateStringInput(input)) && op(input);
|
return (this.validateNumberInput(input) || this.validateStringInput(input)) && op(input);
|
||||||
} else {
|
} else {
|
||||||
return validator(input) && op(input);
|
return validator(input) && op(input);
|
||||||
@ -372,7 +399,7 @@ define([], function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true only of the given operation applies to a given type
|
* Returns true only if the given operation applies to a given type
|
||||||
* @param {string} key The key of the operation
|
* @param {string} key The key of the operation
|
||||||
* @param {string} type The value type to query
|
* @param {string} type The value type to query
|
||||||
* @returns {boolean} True if the condition applies, false otherwise
|
* @returns {boolean} True if the condition applies, false otherwise
|
||||||
|
@ -130,7 +130,9 @@ define ([
|
|||||||
this.telemetryTypesById[objectId] = {};
|
this.telemetryTypesById[objectId] = {};
|
||||||
Object.values(this.telemetryMetadataById[objectId]).forEach(function (valueMetadata) {
|
Object.values(this.telemetryMetadataById[objectId]).forEach(function (valueMetadata) {
|
||||||
var type;
|
var type;
|
||||||
if (valueMetadata.hints.hasOwnProperty('range')) {
|
if (valueMetadata.enumerations !== undefined) {
|
||||||
|
type = 'enum';
|
||||||
|
} else if (valueMetadata.hints.hasOwnProperty('range')) {
|
||||||
type = 'number';
|
type = 'number';
|
||||||
} else if (valueMetadata.hints.hasOwnProperty('domain')) {
|
} else if (valueMetadata.hints.hasOwnProperty('domain')) {
|
||||||
type = 'number';
|
type = 'number';
|
||||||
@ -163,11 +165,18 @@ define ([
|
|||||||
* @param {datum} datum The new data from the telemetry source
|
* @param {datum} datum The new data from the telemetry source
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ConditionManager.prototype.handleSubscriptionCallback = function (objId, datum) {
|
ConditionManager.prototype.handleSubscriptionCallback = function (objId, telemetryDatum) {
|
||||||
this.subscriptionCache[objId] = datum;
|
this.subscriptionCache[objId] = this.createNormalizedDatum(objId, telemetryDatum);
|
||||||
this.eventEmitter.emit('receiveTelemetry');
|
this.eventEmitter.emit('receiveTelemetry');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ConditionManager.prototype.createNormalizedDatum = function (objId, telemetryDatum) {
|
||||||
|
return Object.values(this.telemetryMetadataById[objId]).reduce((normalizedDatum, metadatum) => {
|
||||||
|
normalizedDatum[metadatum.key] = telemetryDatum[metadatum.source];
|
||||||
|
return normalizedDatum;
|
||||||
|
}, {});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event handler for an add event in this Summary Widget's composition.
|
* Event handler for an add event in this Summary Widget's composition.
|
||||||
* Sets up subscription handlers and parses its property types.
|
* Sets up subscription handlers and parses its property types.
|
||||||
@ -236,6 +245,7 @@ define ([
|
|||||||
id.namespace === identifier.namespace;
|
id.namespace === identifier.namespace;
|
||||||
});
|
});
|
||||||
delete this.compositionObjs[objectId];
|
delete this.compositionObjs[objectId];
|
||||||
|
delete this.subscriptionCache[objectId];
|
||||||
this.subscriptions[objectId](); //unsubscribe from telemetry source
|
this.subscriptions[objectId](); //unsubscribe from telemetry source
|
||||||
delete this.subscriptions[objectId];
|
delete this.subscriptions[objectId];
|
||||||
this.eventEmitter.emit('remove', identifier);
|
this.eventEmitter.emit('remove', identifier);
|
||||||
|
@ -110,9 +110,11 @@ define([
|
|||||||
|
|
||||||
type = self.manager.getTelemetryPropertyType(self.config.object, key);
|
type = self.manager.getTelemetryPropertyType(self.config.object, key);
|
||||||
|
|
||||||
self.operationKeys = operations.filter(function (operation) {
|
if (type !== undefined) {
|
||||||
return self.evaluator.operationAppliesTo(operation, type);
|
self.operationKeys = operations.filter(function (operation) {
|
||||||
});
|
return self.evaluator.operationAppliesTo(operation, type);
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
OperationSelect.prototype.destroy = function () {
|
OperationSelect.prototype.destroy = function () {
|
||||||
|
@ -174,7 +174,7 @@ define([
|
|||||||
return typeof input[0] === 'undefined';
|
return typeof input[0] === 'undefined';
|
||||||
},
|
},
|
||||||
text: 'is undefined',
|
text: 'is undefined',
|
||||||
appliesTo: ['string', 'number'],
|
appliesTo: ['string', 'number', 'enum'],
|
||||||
inputCount: 0,
|
inputCount: 0,
|
||||||
getDescription: function () {
|
getDescription: function () {
|
||||||
return ' is undefined';
|
return ' is undefined';
|
||||||
@ -185,11 +185,33 @@ define([
|
|||||||
return typeof input[0] !== 'undefined';
|
return typeof input[0] !== 'undefined';
|
||||||
},
|
},
|
||||||
text: 'is defined',
|
text: 'is defined',
|
||||||
appliesTo: ['string', 'number'],
|
appliesTo: ['string', 'number', 'enum'],
|
||||||
inputCount: 0,
|
inputCount: 0,
|
||||||
getDescription: function () {
|
getDescription: function () {
|
||||||
return ' is defined';
|
return ' is defined';
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
enumValueIs: {
|
||||||
|
operation: function (input) {
|
||||||
|
return input[0] === input[1];
|
||||||
|
},
|
||||||
|
text: 'is',
|
||||||
|
appliesTo: ['enum'],
|
||||||
|
inputCount: 1,
|
||||||
|
getDescription: function (values) {
|
||||||
|
return ' == ' + values[0];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enumValueIsNot: {
|
||||||
|
operation: function (input) {
|
||||||
|
return input[0] !== input[1];
|
||||||
|
},
|
||||||
|
text: 'is not',
|
||||||
|
appliesTo: ['enum'],
|
||||||
|
inputCount: 1,
|
||||||
|
getDescription: function (values) {
|
||||||
|
return ' != ' + values[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user