326 lines
12 KiB
Vue
326 lines
12 KiB
Vue
/*****************************************************************************
|
|
* 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.
|
|
*****************************************************************************/
|
|
|
|
<template>
|
|
<div v-if="isEditing"
|
|
class="c-condition c-condition--edit js-condition-drag-wrapper"
|
|
>
|
|
<!-- 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': !condition.isDefault }, { 'hide-nice': condition.isDefault }]"
|
|
:draggable="!condition.isDefault"
|
|
@dragstart="dragStart"
|
|
@dragstop="dragStop"
|
|
@dragover.stop
|
|
></span>
|
|
|
|
<span class="c-condition__disclosure c-disclosure-triangle c-tree__item__view-control is-enabled"
|
|
:class="{ 'c-disclosure-triangle--expanded': expanded }"
|
|
@click="expanded = !expanded"
|
|
></span>
|
|
|
|
<span class="c-condition__name">{{ condition.configuration.name }}</span>
|
|
<!-- TODO: description should be derived from criteria -->
|
|
<span class="c-condition__summary">
|
|
<template v-if="!canEvaluateCriteria">
|
|
Define criteria
|
|
</template>
|
|
<span v-else>
|
|
<condition-description :show-label="false"
|
|
:condition="condition"
|
|
/>
|
|
</span>
|
|
</span>
|
|
|
|
<div class="c-condition__buttons">
|
|
<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="!condition.isDefault"
|
|
class="c-click-icon c-condition__delete-button icon-trash"
|
|
title="Delete this condition"
|
|
@click="removeCondition"
|
|
></button>
|
|
</div>
|
|
</div>
|
|
<div v-if="expanded"
|
|
class="c-condition__definition c-cdef"
|
|
>
|
|
<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="condition.configuration.name"
|
|
class="t-condition-input__name"
|
|
type="text"
|
|
@blur="persist"
|
|
>
|
|
</span>
|
|
|
|
<span class="c-cdef__label">Output</span>
|
|
<span class="c-cdef__controls">
|
|
<span class="c-cdef__control">
|
|
<select v-model="selectedOutputSelection"
|
|
@change="setOutputValue"
|
|
>
|
|
<option v-for="option in outputOptions"
|
|
:key="option"
|
|
:value="option"
|
|
>
|
|
{{ initCap(option) }}
|
|
</option>
|
|
</select>
|
|
</span>
|
|
<span class="c-cdef__control">
|
|
<input v-if="selectedOutputSelection === outputOptions[2]"
|
|
v-model="condition.configuration.output"
|
|
class="t-condition-name-input"
|
|
type="text"
|
|
@blur="persist"
|
|
>
|
|
</span>
|
|
</span>
|
|
|
|
<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="condition.configuration.trigger"
|
|
@change="persist"
|
|
>
|
|
<option v-for="option in triggers"
|
|
:key="option.value"
|
|
:value="option.value"
|
|
> {{ option.label }}</option>
|
|
</select>
|
|
</span>
|
|
|
|
<template v-if="telemetry.length || condition.configuration.criteria.length">
|
|
<div v-for="(criterion, index) in condition.configuration.criteria"
|
|
:key="index"
|
|
class="c-cdef__criteria"
|
|
>
|
|
<Criterion :telemetry="telemetry"
|
|
:criterion="criterion"
|
|
:index="index"
|
|
:trigger="condition.configuration.trigger"
|
|
:is-default="condition.configuration.criteria.length === 1"
|
|
@persist="persist"
|
|
/>
|
|
<div class="c-cdef__criteria__buttons">
|
|
<button class="c-click-icon c-cdef__criteria-duplicate-button icon-duplicate"
|
|
title="Duplicate this criteria"
|
|
@click="cloneCriterion(index)"
|
|
></button>
|
|
<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)"
|
|
></button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<div class="c-cdef__separator c-row-separator"></div>
|
|
<div class="c-cdef__controls"
|
|
:disabled="!telemetry.length"
|
|
>
|
|
<button
|
|
class="c-cdef__add-criteria-button c-button c-button--labeled icon-plus"
|
|
@click="addCriteria"
|
|
>
|
|
<span class="c-button__label">Add Criteria</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div v-else
|
|
class="c-condition c-condition--browse"
|
|
>
|
|
<!-- Browse view -->
|
|
<div class="c-condition__header">
|
|
<span class="c-condition__name">
|
|
{{ condition.configuration.name }}
|
|
</span>
|
|
<span class="c-condition__output">
|
|
Output: {{ condition.configuration.output }}
|
|
</span>
|
|
</div>
|
|
<div class="c-condition__summary">
|
|
<condition-description :show-label="false"
|
|
:condition="condition"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import Criterion from './Criterion.vue';
|
|
import ConditionDescription from "./ConditionDescription.vue";
|
|
import { TRIGGER, TRIGGER_LABEL } from "@/plugins/condition/utils/constants";
|
|
|
|
export default {
|
|
inject: ['openmct'],
|
|
components: {
|
|
Criterion,
|
|
ConditionDescription
|
|
},
|
|
props: {
|
|
condition: {
|
|
type: Object,
|
|
required: true
|
|
},
|
|
conditionIndex: {
|
|
type: Number,
|
|
required: true
|
|
},
|
|
isEditing: {
|
|
type: Boolean,
|
|
required: true
|
|
},
|
|
telemetry: {
|
|
type: Array,
|
|
required: true,
|
|
default: () => []
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
currentCriteria: this.currentCriteria,
|
|
expanded: true,
|
|
trigger: 'all',
|
|
selectedOutputSelection: '',
|
|
outputOptions: ['false', 'true', 'string'],
|
|
criterionIndex: 0,
|
|
selectedTelemetryName: '',
|
|
selectedFieldName: ''
|
|
};
|
|
},
|
|
computed: {
|
|
triggers() {
|
|
const keys = Object.keys(TRIGGER);
|
|
const triggerOptions = [];
|
|
keys.forEach((trigger) => {
|
|
triggerOptions.push({
|
|
value: TRIGGER[trigger],
|
|
label: TRIGGER_LABEL[TRIGGER[trigger]]
|
|
});
|
|
});
|
|
return triggerOptions;
|
|
},
|
|
canEvaluateCriteria: function () {
|
|
let criteria = this.condition.configuration.criteria;
|
|
if (criteria.length) {
|
|
let lastCriterion = criteria[criteria.length - 1];
|
|
if (lastCriterion.telemetry &&
|
|
lastCriterion.operation &&
|
|
(lastCriterion.input.length ||
|
|
lastCriterion.operation === 'isDefined' ||
|
|
lastCriterion.operation === 'isUndefined')) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
},
|
|
destroyed() {
|
|
this.destroy();
|
|
},
|
|
mounted() {
|
|
this.setOutputSelection();
|
|
},
|
|
methods: {
|
|
setOutputSelection() {
|
|
let conditionOutput = this.condition.configuration.output;
|
|
if (conditionOutput) {
|
|
if (conditionOutput !== 'false' && conditionOutput !== 'true') {
|
|
this.selectedOutputSelection = 'string';
|
|
} else {
|
|
this.selectedOutputSelection = conditionOutput;
|
|
}
|
|
}
|
|
},
|
|
setOutputValue() {
|
|
if (this.selectedOutputSelection === 'string') {
|
|
this.condition.configuration.output = '';
|
|
} else {
|
|
this.condition.configuration.output = this.selectedOutputSelection;
|
|
}
|
|
this.persist();
|
|
},
|
|
addCriteria() {
|
|
const criteriaObject = {
|
|
telemetry: '',
|
|
operation: '',
|
|
input: '',
|
|
metadata: ''
|
|
};
|
|
this.condition.configuration.criteria.push(criteriaObject);
|
|
},
|
|
dragStart(e) {
|
|
e.dataTransfer.setData('dragging', e.target); // required for FF to initiate drag
|
|
e.dataTransfer.effectAllowed = "copyMove";
|
|
e.dataTransfer.setDragImage(e.target.closest('.js-condition-drag-wrapper'), 0, 0);
|
|
this.$emit('setMoveIndex', this.conditionIndex);
|
|
},
|
|
dragStop(e) {
|
|
e.dataTransfer.clearData();
|
|
},
|
|
destroy() {
|
|
},
|
|
removeCondition(ev) {
|
|
this.$emit('removeCondition', this.conditionIndex);
|
|
},
|
|
cloneCondition(ev) {
|
|
this.$emit('cloneCondition', {
|
|
condition: this.condition,
|
|
index: this.conditionIndex
|
|
});
|
|
},
|
|
removeCriterion(index) {
|
|
this.condition.configuration.criteria.splice(index, 1);
|
|
this.persist();
|
|
},
|
|
cloneCriterion(index) {
|
|
const clonedCriterion = JSON.parse(JSON.stringify(this.condition.configuration.criteria[index]));
|
|
this.condition.configuration.criteria.splice(index + 1, 0, clonedCriterion);
|
|
this.persist();
|
|
},
|
|
persist() {
|
|
this.$emit('updateCondition', {
|
|
condition: this.condition,
|
|
index: this.conditionIndex
|
|
});
|
|
},
|
|
initCap: function (str) {
|
|
return str.charAt(0).toUpperCase() + str.slice(1)
|
|
}
|
|
}
|
|
}
|
|
</script>
|