Merge pull request #2747 from nasa/conditions-do-refactor

Conditions refactor - not domain objects anymore
This commit is contained in:
David Tsay 2020-03-16 10:59:31 -07:00 committed by GitHub
commit 55e5c49f6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 212 additions and 287 deletions

View File

@ -28,10 +28,7 @@ import {computeCondition} from "./utils/evaluator";
/*
* conditionConfiguration = {
* identifier: {
* key: '',
* namespace: ''
* },
* id: uuid,
* trigger: 'any'/'all',
* criteria: [
* {
@ -48,14 +45,14 @@ export default class ConditionClass extends EventEmitter {
/**
* Manages criteria and emits the result of - true or false - based on criteria evaluated.
* @constructor
* @param conditionConfiguration: {identifier: {domainObject.identifier},trigger: enum, criteria: Array of {id: uuid, operation: enum, input: Array, metaDataKey: string, key: {domainObject.identifier} }
* @param conditionConfiguration: {id: uuid,trigger: enum, criteria: Array of {id: uuid, operation: enum, input: Array, metaDataKey: string, key: {domainObject.identifier} }
* @param openmct
*/
constructor(conditionConfiguration, openmct) {
super();
this.openmct = openmct;
this.id = this.openmct.objects.makeKeyString(conditionConfiguration.identifier);
this.id = conditionConfiguration.id;
this.criteria = [];
this.criteriaResults = {};
this.result = undefined;
@ -63,16 +60,11 @@ export default class ConditionClass extends EventEmitter {
this.createCriteria(conditionConfiguration.configuration.criteria);
}
this.trigger = conditionConfiguration.configuration.trigger;
this.openmct.objects.get(this.id).then(obj => this.observeForChanges(obj));
}
observeForChanges(conditionDO) {
this.stopObservingForChanges = this.openmct.objects.observe(conditionDO, '*', this.update.bind(this));
}
update(newDomainObject) {
this.updateTrigger(newDomainObject.configuration.trigger);
this.updateCriteria(newDomainObject.configuration.criteria);
update(conditionConfiguration) {
this.updateTrigger(conditionConfiguration.configuration.trigger);
this.updateCriteria(conditionConfiguration.configuration.criteria);
}
updateTrigger(trigger) {

View File

@ -25,71 +25,52 @@ import uuid from "uuid";
import EventEmitter from 'EventEmitter';
export default class ConditionManager extends EventEmitter {
constructor(domainObject, openmct) {
constructor(conditionSetDomainObject, openmct) {
super();
this.openmct = openmct;
this.domainObject = domainObject;
this.conditionSetDomainObject = conditionSetDomainObject;
this.timeAPI = this.openmct.time;
this.latestTimestamp = {};
this.instantiate = this.openmct.$injector.get('instantiate');
this.initialize();
this.stopObservingForChanges = this.openmct.objects.observe(this.conditionSetDomainObject, '*', (newDomainObject) => {
this.update(newDomainObject);
});
}
initialize() {
this.conditionResults = {};
this.observeForChanges(this.domainObject);
this.conditionCollection = [];
if (this.domainObject.configuration.conditionCollection.length) {
this.domainObject.configuration.conditionCollection.forEach((conditionConfigurationId, index) => {
this.openmct.objects.get(conditionConfigurationId).then((conditionConfiguration) => {
this.initCondition(conditionConfiguration, index)
});
this.conditionClassCollection = [];
if (this.conditionSetDomainObject.configuration.conditionCollection.length) {
this.conditionSetDomainObject.configuration.conditionCollection.forEach((conditionConfiguration, index) => {
this.initCondition(conditionConfiguration, index);
});
} else {
this.addCondition(true);
}
}
observeForChanges(domainObject) {
//TODO: Observe only the conditionCollection property instead of the whole domainObject
this.stopObservingForChanges = this.openmct.objects.observe(domainObject, '*', this.handleConditionCollectionUpdated.bind(this));
update(newDomainObject) {
this.destroy();
this.conditionSetDomainObject = newDomainObject;
this.stopObservingForChanges = this.openmct.objects.observe(this.conditionSetDomainObject, '*', (newDO) => {
this.update(newDO);
});
this.initialize();
}
handleConditionCollectionUpdated(newDomainObject) {
let oldConditionIdentifiers = this.domainObject.configuration.conditionCollection.map((conditionConfigurationId) => {
return this.openmct.objects.makeKeyString(conditionConfigurationId);
});
let newConditionIdentifiers = newDomainObject.configuration.conditionCollection.map((conditionConfigurationId) => {
return this.openmct.objects.makeKeyString(conditionConfigurationId);
});
this.domainObject = newDomainObject;
//check for removed conditions
oldConditionIdentifiers.forEach((identifier, index) => {
if (newConditionIdentifiers.indexOf(identifier) < 0) {
this.removeCondition(identifier);
}
});
let newConditionCount = this.domainObject.configuration.conditionCollection.length - this.conditionCollection.length;
for (let i = 0; i < newConditionCount; i++) {
let conditionConfigurationId = this.domainObject.configuration.conditionCollection[i];
this.openmct.objects.get(conditionConfigurationId).then((conditionConfiguration) => {
this.initCondition(conditionConfiguration, i);
});
}
updateCondition(conditionConfiguration, index) {
let condition = this.conditionClassCollection[index];
condition.update(conditionConfiguration);
this.conditionSetDomainObject.configuration.conditionCollection[index] = conditionConfiguration;
this.persistConditions();
}
initCondition(conditionConfiguration, index) {
let condition = new Condition(conditionConfiguration, this.openmct);
condition.on('conditionResultUpdated', this.handleConditionResult.bind(this));
if (index !== undefined) {
this.conditionCollection.splice(index + 1, 0, condition);
this.conditionClassCollection.splice(index + 1, 0, condition);
} else {
this.conditionCollection.unshift(condition);
this.conditionClassCollection.unshift(condition);
}
//There are no criteria for a default condition and hence no subscriptions.
//Hence the conditionResult must be manually triggered for it.
@ -98,30 +79,25 @@ export default class ConditionManager extends EventEmitter {
}
}
createConditionDomainObject(isDefault, conditionConfiguration) {
createCondition(conditionConfiguration) {
let conditionObj;
if (conditionConfiguration) {
conditionObj = {
...conditionConfiguration,
name: `Copy of ${conditionConfiguration.name}`,
identifier: {
...this.domainObject.identifier,
key: uuid()
id: uuid(),
configuration: {
...conditionConfiguration.configuration,
name: `Copy of ${conditionConfiguration.configuration.name}`
}
};
} else {
conditionObj = {
isDefault: isDefault,
type: 'condition',
identifier: {
...this.domainObject.identifier,
key: uuid()
},
id: uuid(),
configuration: {
name: isDefault ? 'Default' : 'Unnamed Condition',
name: 'Unnamed Condition',
output: 'false',
trigger: 'all',
criteria: isDefault ? [] : [{
criteria: [{
telemetry: '',
operation: '',
input: [],
@ -131,58 +107,48 @@ export default class ConditionManager extends EventEmitter {
summary: ''
};
}
let conditionDomainObjectKeyString = this.openmct.objects.makeKeyString(conditionObj.identifier);
let newDomainObject = this.instantiate(conditionObj, conditionDomainObjectKeyString);
return newDomainObject.useCapability('adapter');
return conditionObj;
}
addCondition(isDefault, index) {
this.createAndSaveConditionDomainObject(!!isDefault, index);
addCondition() {
this.createAndSaveCondition();
}
cloneCondition(conditionConfigurationId, index) {
this.openmct.objects.get(conditionConfigurationId).then((conditionConfiguration) => {
this.createAndSaveConditionDomainObject(false, index, conditionConfiguration);
});
cloneCondition(conditionConfiguration, index) {
this.createAndSaveCondition(index, conditionConfiguration);
}
createAndSaveConditionDomainObject(isDefault, index, conditionConfiguration) {
let newConditionDomainObject = this.createConditionDomainObject(isDefault, conditionConfiguration);
//persist the condition domain object so that we can do an openmct.objects.get on it and only persist the identifier in the conditionCollection of conditionSet
this.openmct.objects.mutate(newConditionDomainObject, 'created', new Date());
createAndSaveCondition(index, conditionConfiguration) {
let newCondition = this.createCondition(conditionConfiguration);
if (index !== undefined) {
this.domainObject.configuration.conditionCollection.splice(index + 1, 0, newConditionDomainObject.identifier);
this.conditionSetDomainObject.configuration.conditionCollection.splice(index + 1, 0, newCondition);
} else {
this.domainObject.configuration.conditionCollection.unshift(newConditionDomainObject.identifier);
this.conditionSetDomainObject.configuration.conditionCollection.unshift(newCondition);
}
this.persist();
this.initCondition(newCondition, index);
this.persistConditions();
}
removeCondition(identifier) {
let found = this.findConditionById(identifier);
if (found) {
let index = found.index;
let condition = this.conditionCollection[index];
let conditionIdAsString = condition.id;
condition.destroyCriteria();
condition.off('conditionResultUpdated', this.handleConditionResult.bind(this));
this.conditionCollection.splice(index, 1);
this.domainObject.configuration.conditionCollection.splice(index, 1);
if (this.conditionResults[conditionIdAsString] !== undefined) {
delete this.conditionResults[conditionIdAsString];
}
this.persist();
this.handleConditionResult();
removeCondition(index) {
let condition = this.conditionClassCollection[index];
condition.destroyCriteria();
condition.off('conditionResultUpdated', this.handleConditionResult.bind(this));
this.conditionClassCollection.splice(index, 1);
this.conditionSetDomainObject.configuration.conditionCollection.splice(index, 1);
if (this.conditionResults[condition.id] !== undefined) {
delete this.conditionResults[condition.id];
}
this.persistConditions();
this.handleConditionResult();
}
findConditionById(identifier) {
findConditionById(id) {
let found;
for (let i=0, ii=this.conditionCollection.length; i < ii; i++) {
if (this.conditionCollection[i].id === this.openmct.objects.makeKeyString(identifier)) {
for (let i=0, ii=this.conditionClassCollection.length; i < ii; i++) {
if (this.conditionClassCollection[i].id === id) {
found = {
item: this.conditionCollection[i],
item: this.conditionClassCollection[i],
index: i
};
break;
@ -192,51 +158,48 @@ export default class ConditionManager extends EventEmitter {
return found;
}
//this.$set(this.conditionCollection, reorderEvent.newIndex, oldConditions[reorderEvent.oldIndex]);
//this.$set(this.conditionClassCollection, reorderEvent.newIndex, oldConditions[reorderEvent.oldIndex]);
reorderConditions(reorderPlan) {
let oldConditions = Array.from(this.domainObject.configuration.conditionCollection);
let oldConditions = Array.from(this.conditionSetDomainObject.configuration.conditionCollection);
let newCollection = [];
reorderPlan.forEach((reorderEvent) => {
let item = oldConditions[reorderEvent.oldIndex];
newCollection.push(item);
this.domainObject.configuration.conditionCollection = newCollection;
this.conditionSetDomainObject.configuration.conditionCollection = newCollection;
});
this.persist();
this.persistConditions();
}
handleConditionResult(resultObj) {
let conditionCollection = this.domainObject.configuration.conditionCollection;
let currentConditionIdentifier = conditionCollection[conditionCollection.length-1];
const conditionCollection = this.conditionSetDomainObject.configuration.conditionCollection;
let currentCondition = conditionCollection[conditionCollection.length-1];
if (resultObj) {
let idAsString = this.openmct.objects.makeKeyString(resultObj.id);
if (this.findConditionById(idAsString)) {
this.conditionResults[idAsString] = resultObj.data.result;
const id = resultObj.id;
if (this.findConditionById(id)) {
this.conditionResults[id] = resultObj.data.result;
}
this.updateTimestamp(resultObj.data);
}
for (let i = 0; i < conditionCollection.length - 1; i++) {
let conditionIdAsString = this.openmct.objects.makeKeyString(conditionCollection[i]);
if (this.conditionResults[conditionIdAsString]) {
if (this.conditionResults[conditionCollection[i].id]) {
//first condition to be true wins
currentConditionIdentifier = conditionCollection[i];
currentCondition = conditionCollection[i];
break;
}
}
this.openmct.objects.get(currentConditionIdentifier).then((obj) => {
this.emit('conditionSetResultUpdated',
Object.assign(
{
output: obj.configuration.output,
id: this.domainObject.identifier,
conditionId: currentConditionIdentifier
},
this.latestTimestamp
)
this.emit('conditionSetResultUpdated',
Object.assign(
{
output: currentCondition.configuration.output,
id: this.conditionSetDomainObject.identifier,
conditionId: currentCondition.id
},
this.latestTimestamp
)
});
)
}
updateTimestamp(timestamp) {
@ -249,15 +212,15 @@ export default class ConditionManager extends EventEmitter {
});
}
persist() {
this.openmct.objects.mutate(this.domainObject, 'configuration.conditionCollection', this.domainObject.configuration.conditionCollection);
persistConditions() {
this.openmct.objects.mutate(this.conditionSetDomainObject, 'configuration.conditionCollection', this.conditionSetDomainObject.configuration.conditionCollection);
}
destroy() {
if (typeof this.stopObservingForChanges === 'function') {
if(this.stopObservingForChanges) {
this.stopObservingForChanges();
}
this.conditionCollection.forEach((condition) => {
this.conditionClassCollection.forEach((condition) => {
condition.off('conditionResultUpdated', this.handleConditionResult);
condition.destroy();
})

View File

@ -27,6 +27,13 @@ describe('ConditionManager', () => {
let conditionMgr;
let mockListener;
let openmct = {};
let mockCondition = {
isDefault: true,
id: '1234-5678',
configuration: {
criteria: []
}
};
let conditionSetDomainObject = {
identifier: {
namespace: "",
@ -35,15 +42,9 @@ describe('ConditionManager', () => {
type: "conditionSet",
location: "mine",
configuration: {
conditionCollection: []
}
};
let mockConditionDomainObject = {
isDefault: true,
type: 'condition',
identifier: {
namespace: '',
key: '1234-5678'
conditionCollection: [
mockCondition
]
}
};
@ -55,7 +56,7 @@ describe('ConditionManager', () => {
let mockDomainObject = {
useCapability: function () {
return mockConditionDomainObject;
return mockCondition;
}
};
mockInstantiate.and.callFake(function () {
@ -78,7 +79,7 @@ describe('ConditionManager', () => {
openmct.objects.get.and.returnValues(new Promise(function (resolve, reject) {
resolve(conditionSetDomainObject);
}), new Promise(function (resolve, reject) {
resolve(mockConditionDomainObject);
resolve(mockCondition);
}));
openmct.objects.makeKeyString.and.returnValue(conditionSetDomainObject.identifier.key);
openmct.objects.observe.and.returnValue(function () {});
@ -90,9 +91,9 @@ describe('ConditionManager', () => {
});
it('creates a conditionCollection with a default condition', function () {
expect(conditionMgr.domainObject.configuration.conditionCollection.length).toEqual(1);
let defaultConditionIdentifier = conditionMgr.domainObject.configuration.conditionCollection[0];
expect(defaultConditionIdentifier).toEqual(mockConditionDomainObject.identifier);
expect(conditionMgr.conditionSetDomainObject.configuration.conditionCollection.length).toEqual(1);
let defaultConditionId = conditionMgr.conditionClassCollection[0].id;
expect(defaultConditionId).toEqual(mockCondition.id);
});
});

View File

@ -1,3 +1,25 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2020, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
import ConditionManager from './ConditionManager'
export default class ConditionSetTelemetryProvider {

View File

@ -64,6 +64,7 @@ describe("The condition", function () {
openmct.telemetry.getMetadata.and.returnValue(testTelemetryObject.telemetry.values);
testConditionDefinition = {
id: '123-456',
configuration: {
trigger: TRIGGER.ANY,
criteria: [

View File

@ -64,15 +64,13 @@ export default class StyleRuleManager extends EventEmitter {
updateConditionStylesMap(conditionStyles) {
let conditionStyleMap = {};
conditionStyles.forEach((conditionStyle) => {
const identifier = this.openmct.objects.makeKeyString(conditionStyle.conditionIdentifier);
conditionStyleMap[identifier] = conditionStyle.style;
conditionStyleMap[conditionStyle.conditionId] = conditionStyle.style;
});
this.conditionalStyleMap = conditionStyleMap;
}
handleConditionSetResultUpdated(resultData) {
let identifier = this.openmct.objects.makeKeyString(resultData.conditionId);
let foundStyle = this.conditionalStyleMap[identifier];
let foundStyle = this.conditionalStyleMap[resultData.conditionId];
if (foundStyle) {
if (foundStyle !== this.currentStyle) {
this.currentStyle = foundStyle;

View File

@ -23,14 +23,13 @@
<template>
<div v-if="isEditing"
class="c-condition c-condition--edit js-condition-drag-wrapper"
:class="{ 'c-condition--current-match': currentConditionIdentifier && (currentConditionIdentifier.key === conditionIdentifier.key) }"
>
<!-- Edit view -->
<div class="c-condition__header">
<span class="c-condition__drag-grippy c-grippy c-grippy--vertical-drag"
title="Drag to reorder conditions"
:class="[{ 'is-enabled': !domainObject.isDefault }, { 'hide-nice': domainObject.isDefault }]"
:draggable="!domainObject.isDefault"
:class="[{ 'is-enabled': !condition.isDefault }, { 'hide-nice': condition.isDefault }]"
:draggable="!condition.isDefault"
@dragstart="dragStart"
@dragstop="dragStop"
@dragover.stop
@ -41,20 +40,20 @@
@click="expanded = !expanded"
></span>
<span class="c-condition__name">{{ domainObject.configuration.name }}</span>
<span class="c-condition__name">{{ condition.configuration.name }}</span>
<!-- TODO: description should be derived from criteria -->
<span class="c-condition__summary">
Description/summary goes here {{ domainObject.configuration.description }}
Description/summary goes here {{ condition.configuration.description }}
</span>
<div class="c-condition__buttons">
<button v-if="!domainObject.isDefault"
<button v-if="!condition.isDefault"
class="c-click-icon c-condition__duplicate-button icon-duplicate"
title="Duplicate this condition"
@click="cloneCondition"
></button>
<button v-if="!domainObject.isDefault"
<button v-if="!condition.isDefault"
class="c-click-icon c-condition__delete-button icon-trash"
title="Delete this condition"
@click="removeCondition"
@ -67,7 +66,7 @@
<span class="c-cdef__separator c-row-separator"></span>
<span class="c-cdef__label">Condition Name</span>
<span class="c-cdef__controls">
<input v-model="domainObject.configuration.name"
<input v-model="condition.configuration.name"
class="t-condition-input__name"
type="text"
@blur="persist"
@ -88,20 +87,20 @@
</option>
</select>
<input v-if="selectedOutputSelection === outputOptions[2]"
v-model="domainObject.configuration.output"
v-model="condition.configuration.output"
class="t-condition-name-input"
type="text"
@blur="persist"
>
</span>
<div v-if="!domainObject.isDefault"
<div v-if="!condition.isDefault"
class="c-cdef__match-and-criteria"
>
<span class="c-cdef__separator c-row-separator"></span>
<span class="c-cdef__label">Match</span>
<span class="c-cdef__controls">
<select v-model="domainObject.configuration.trigger"
<select v-model="condition.configuration.trigger"
@change="persist"
>
<option value="all">when all criteria are met</option>
@ -110,15 +109,15 @@
</span>
<template v-if="telemetry.length">
<div v-for="(criterion, index) in domainObject.configuration.criteria"
<div v-for="(criterion, index) in condition.configuration.criteria"
:key="index"
class="c-cdef__criteria"
>
<Criterion :telemetry="telemetry"
:criterion="criterion"
:index="index"
:trigger="domainObject.configuration.trigger"
:is-default="domainObject.configuration.criteria.length === 1"
:trigger="condition.configuration.trigger"
:is-default="condition.configuration.criteria.length === 1"
@persist="persist"
/>
<div class="c-cdef__criteria__buttons">
@ -126,7 +125,7 @@
title="Duplicate this criteria"
@click="cloneCriterion(index)"
></button>
<button v-if="!(domainObject.configuration.criteria.length === 1)"
<button v-if="!(condition.configuration.criteria.length === 1)"
class="c-click-icon c-cdef__criteria-duplicate-button icon-trash"
title="Delete this criteria"
@click="removeCriterion(index)"
@ -150,19 +149,18 @@
</div>
<div v-else
class="c-condition c-condition--browse"
:class="{ 'c-condition--current': currentConditionIdentifier && (currentConditionIdentifier.key === conditionIdentifier.key) }"
>
<!-- Browse view -->
<div class="c-condition__header">
<span class="c-condition__name">
{{ domainObject.configuration.name }}
{{ condition.configuration.name }}
</span>
<span class="c-condition__output">
Output: {{ domainObject.configuration.output }}
Output: {{ condition.configuration.output }}
</span>
</div>
<div class="c-condition__summary">
Description/summary goes here {{ domainObject.configuration.description }}
Description/summary goes here {{ condition.configuration.description }}
</div>
</div>
</template>
@ -176,11 +174,7 @@ export default {
Criterion
},
props: {
conditionIdentifier: {
type: Object,
required: true
},
currentConditionIdentifier: {
condition: {
type: Object,
required: true
},
@ -200,9 +194,6 @@ export default {
},
data() {
return {
domainObject: {
configuration: {}
},
currentCriteria: this.currentCriteria,
expanded: true,
trigger: 'all',
@ -215,17 +206,11 @@ export default {
this.destroy();
},
mounted() {
this.openmct.objects.get(this.conditionIdentifier).then((domainObject => {
this.domainObject = domainObject;
this.initialize();
}));
this.setOutputSelection();
},
methods: {
initialize() {
this.setOutputSelection();
},
setOutputSelection() {
let conditionOutput = this.domainObject.configuration.output;
let conditionOutput = this.condition.configuration.output;
if (conditionOutput) {
if (conditionOutput !== 'false' && conditionOutput !== 'true') {
this.selectedOutputSelection = 'string';
@ -236,9 +221,9 @@ export default {
},
setOutputValue() {
if (this.selectedOutputSelection === 'string') {
this.domainObject.configuration.output = '';
this.condition.configuration.output = '';
} else {
this.domainObject.configuration.output = this.selectedOutputSelection;
this.condition.configuration.output = this.selectedOutputSelection;
}
this.persist();
},
@ -249,7 +234,7 @@ export default {
input: '',
metadata: ''
};
this.domainObject.configuration.criteria.push(criteriaObject);
this.condition.configuration.criteria.push(criteriaObject);
},
dragStart(e) {
e.dataTransfer.setData('dragging', e.target); // required for FF to initiate drag
@ -263,32 +248,35 @@ export default {
destroy() {
},
removeCondition(ev) {
this.$emit('removeCondition', this.conditionIdentifier);
this.$emit('removeCondition', this.conditionIndex);
},
cloneCondition(ev) {
this.$emit('cloneCondition', {
identifier: this.conditionIdentifier,
index: Number(ev.target.closest('.widget-condition').getAttribute('data-condition-index'))
condition: this.condition,
index: this.conditionIndex
});
},
removeCriterion(index) {
this.domainObject.configuration.criteria.splice(index, 1);
this.condition.configuration.criteria.splice(index, 1);
this.persist()
},
cloneCriterion(index) {
const clonedCriterion = {...this.domainObject.configuration.criteria[index]};
this.domainObject.configuration.criteria.splice(index + 1, 0, clonedCriterion);
const clonedCriterion = {...this.condition.configuration.criteria[index]};
this.condition.configuration.criteria.splice(index + 1, 0, clonedCriterion);
this.persist()
},
hasTelemetry(identifier) {
// TODO: check parent domainObject.composition.hasTelemetry
// TODO: check parent condition.composition.hasTelemetry
return this.currentCriteria && identifier;
},
persist() {
this.openmct.objects.mutate(this.domainObject, 'configuration', this.domainObject.configuration);
this.$emit('updateCondition', {
condition: this.condition,
index: this.conditionIndex
});
},
initCap: function (string) {
return string.charAt(0).toUpperCase() + string.slice(1)
initCap: function (str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
}
}

View File

@ -54,8 +54,8 @@
</button>
<div class="c-cs__conditions-h">
<div v-for="(conditionIdentifier, index) in conditionCollection"
:key="conditionIdentifier.key"
<div v-for="(condition, index) in conditionCollection"
:key="condition.id"
class="c-condition-h"
>
<div v-if="isEditing"
@ -65,11 +65,11 @@
@dragleave="dragLeave"
@dragover.prevent
></div>
<Condition :condition-identifier="conditionIdentifier"
:current-condition-identifier="currentConditionIdentifier"
<Condition :condition="condition"
:condition-index="index"
:telemetry="telemetryObjs"
:is-editing="isEditing"
@updateCondition="updateCondition"
@removeCondition="removeCondition"
@cloneCondition="cloneCondition"
@setMoveIndex="setMoveIndex"
@ -95,11 +95,9 @@ export default {
data() {
return {
expanded: true,
parentKeyString: this.openmct.objects.makeKeyString(this.domainObject.identifier),
conditionCollection: [],
conditionResults: {},
conditions: [],
currentConditionIdentifier: this.currentConditionIdentifier || {},
telemetryObjs: [],
moveIndex: Number,
isDragging: false
@ -111,7 +109,7 @@ export default {
if(this.conditionManager) {
this.conditionManager.destroy();
}
if (typeof this.stopObservingForChanges === 'function') {
if (this.stopObservingForChanges) {
this.stopObservingForChanges();
}
},
@ -121,13 +119,13 @@ export default {
this.composition.on('remove', this.removeTelemetryObject);
this.composition.load();
this.conditionCollection = this.domainObject.configuration.conditionCollection;
this.conditionManager = new ConditionManager(this.domainObject, this.openmct);
this.observeForChanges();
this.conditionManager = new ConditionManager(this.domainObject, this.openmct);
},
methods: {
observeForChanges() {
this.stopObservingForChanges = this.openmct.objects.observe(this.domainObject, '*', (newDomainObject) => {
this.conditionCollection = newDomainObject.configuration.conditionCollection;
this.stopObservingForChanges = this.openmct.objects.observe(this.domainObject, 'configuration.conditionCollection', (newConditionCollection) => {
this.conditionCollection = newConditionCollection;
});
},
setMoveIndex(index) {
@ -189,20 +187,20 @@ export default {
this.telemetryObjs.splice(index, 1);
}
},
addCondition(event, isDefault, index) {
this.conditionManager.addCondition(!!isDefault, index);
addCondition() {
this.conditionManager.addCondition();
},
updateCurrentCondition(identifier) {
this.currentConditionIdentifier = identifier;
updateCondition(data) {
this.conditionManager.updateCondition(data.condition, data.index);
},
removeCondition(identifier) {
this.conditionManager.removeCondition(identifier);
removeCondition(index) {
this.conditionManager.removeCondition(index);
},
reorder(reorderPlan) {
this.conditionManager.reorderConditions(reorderPlan);
},
cloneCondition(condition) {
this.conditionManager.cloneCondition(condition.identifier, condition.index);
cloneCondition(data) {
this.conditionManager.cloneCondition(data.condition, data.index);
}
}
}

View File

@ -70,6 +70,9 @@ export default {
this.currentConditionOutput = currentConditionResult.output;
},
provideTelemetry() {
if (this.stopProvidingTelemetry) {
this.stopProvidingTelemetry();
}
this.stopProvidingTelemetry = this.openmct.telemetry
.subscribe(this.domainObject, output => { this.updateCurrentOutput(output); });
}

View File

@ -52,7 +52,7 @@
<input v-model="criterion.input[inputIndex]"
class="c-cdef__control__input"
type="text"
@blur="persist"
@change="persist"
>
<span v-if="inputIndex < inputCount-1">and</span>
</span>

View File

@ -1,9 +1,9 @@
<template>
<div>
<div v-if="condition"
<div v-if="conditionName"
class="holder c-c-button-wrapper align-left"
>
<div>{{ condition.configuration.name }}</div>
<div>{{ conditionName }}</div>
</div>
</div>
</template>
@ -17,22 +17,12 @@ export default {
'openmct'
],
props: {
conditionIdentifier: {
type: Object,
conditionName: {
type: String,
required: true
}
},
data() {
return {
condition: null
}
},
destroyed() {
},
mounted() {
this.openmct.objects.get(this.conditionIdentifier).then((conditionDomainObject) => {
this.condition = conditionDomainObject;
});
}
}
</script>

View File

@ -21,9 +21,9 @@
</div>
<ul>
<li v-for="conditionStyle in conditionalStyles"
:key="conditionStyle.conditionIdentifier.key"
:key="conditionStyle.conditionId"
>
<conditional-style :condition-identifier="conditionStyle.conditionIdentifier"
<conditional-style :condition-name="conditionStyle.conditionName"
:condition-style="conditionStyle.style"
/>
</li>
@ -77,9 +77,10 @@ export default {
initializeConditionalStyles() {
const backgroundColors = [{backgroundColor: 'red'},{backgroundColor: 'orange'}, {backgroundColor: 'blue'}];
this.openmct.objects.get(this.conditionSetIdentifier).then((conditionSetDomainObject) => {
conditionSetDomainObject.configuration.conditionCollection.forEach((identifier, index) => {
conditionSetDomainObject.configuration.conditionCollection.forEach((conditionConfiguration, index) => {
this.conditionalStyles.push({
conditionIdentifier: identifier,
conditionId: conditionConfiguration.id,
conditionName: conditionConfiguration.name,
style: backgroundColors[index]
});
});
@ -92,7 +93,7 @@ export default {
},
findStyleByConditionId(id) {
for(let i=0, ii=this.conditionalStyles.length; i < ii; i++) {
if (this.openmct.objects.makeKeyString(this.conditionalStyles[i].conditionIdentifier) === this.openmct.objects.makeKeyString(id)) {
if (this.conditionalStyles[i].conditionId === id) {
return {
index: i,
item: this.conditionalStyles[i]
@ -100,8 +101,8 @@ export default {
}
}
},
updateConditionalStyle(conditionIdentifier, style) {
let found = this.findStyleByConditionId(conditionIdentifier);
updateConditionalStyle(conditionId, style) {
let found = this.findStyleByConditionId(conditionId);
if (found) {
this.conditionalStyles[found.index].style = style;
}

View File

@ -23,19 +23,11 @@ import ConditionSetViewProvider from './ConditionSetViewProvider.js';
import ConditionSetCompositionPolicy from "./ConditionSetCompositionPolicy";
import ConditionSetMetadataProvider from './ConditionSetMetadataProvider';
import ConditionSetTelemetryProvider from './ConditionSetTelemetryProvider';
import uuid from "uuid";
export default function ConditionPlugin() {
return function install(openmct) {
openmct.types.addType('condition', {
name: 'Condition',
key: 'condition',
description: 'A list of criteria which will be evaluated based on a trigger',
creatable: false,
initialize: function (domainObject) {
domainObject.composition = [];
}
});
openmct.types.addType('conditionSet', {
name: 'Condition Set',
@ -45,7 +37,17 @@ export default function ConditionPlugin() {
cssClass: 'icon-conditional', // TODO: replace with class for new icon
initialize: function (domainObject) {
domainObject.configuration = {
conditionCollection: []
conditionCollection: [{
isDefault: true,
id: uuid(),
configuration: {
name: 'Default',
output: 'false',
trigger: 'all',
criteria: []
},
summary: 'Default condition'
}]
};
domainObject.composition = [];
domainObject.telemetry = {};

View File

@ -26,26 +26,14 @@ import ConditionPlugin from "./plugin";
let openmct = createOpenMct();
openmct.install(new ConditionPlugin());
let conditionDefinition;
let conditionSetDefinition;
let mockDomainObject;
let mockDomainObject2;
let mockConditionSetDomainObject;
let element;
let child;
describe('the plugin', function () {
beforeAll((done) => {
conditionDefinition = openmct.types.get('condition').definition;
mockDomainObject = {
identifier: {
key: 'testConditionKey',
namespace: ''
},
type: 'condition'
};
conditionDefinition.initialize(mockDomainObject);
conditionSetDefinition = openmct.types.get('conditionSet').definition;
const appHolder = document.createElement('div');
@ -56,7 +44,7 @@ describe('the plugin', function () {
child = document.createElement('div');
element.appendChild(child);
mockDomainObject2 = {
mockConditionSetDomainObject = {
identifier: {
key: 'testConditionSetKey',
namespace: ''
@ -64,22 +52,12 @@ describe('the plugin', function () {
type: 'conditionSet'
};
conditionSetDefinition.initialize(mockDomainObject2);
conditionSetDefinition.initialize(mockConditionSetDomainObject);
openmct.on('start', done);
openmct.start(appHolder);
});
let mockConditionObject = {
name: 'Condition',
key: 'condition',
creatable: false
};
it('defines a condition object type with the correct key', () => {
expect(conditionDefinition.key).toEqual(mockConditionObject.key);
});
let mockConditionSetObject = {
name: 'Condition Set',
key: 'conditionSet',
@ -90,18 +68,6 @@ describe('the plugin', function () {
expect(conditionSetDefinition.key).toEqual(mockConditionSetObject.key);
});
describe('the condition object', () => {
it('is not creatable', () => {
expect(conditionDefinition.creatable).toEqual(mockConditionObject.creatable);
});
it('initializes with an empty composition list', () => {
expect(mockDomainObject.composition instanceof Array).toBeTrue();
expect(mockDomainObject.composition.length).toEqual(0);
});
});
describe('the conditionSet object', () => {
it('is creatable', () => {
@ -109,8 +75,8 @@ describe('the plugin', function () {
});
it('initializes with an empty composition list', () => {
expect(mockDomainObject2.composition instanceof Array).toBeTrue();
expect(mockDomainObject2.composition.length).toEqual(0);
expect(mockConditionSetDomainObject.composition instanceof Array).toBeTrue();
expect(mockConditionSetDomainObject.composition.length).toEqual(0);
});
it('provides a view', () => {