Compare commits
217 Commits
notebook-p
...
hide-show-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a1bf4a92e5 | ||
|
|
a7fc9b3caa | ||
|
|
53b785269b | ||
|
|
007b14b5c9 | ||
|
|
50b331c451 | ||
|
|
44fc62e0ba | ||
|
|
2635f085f0 | ||
|
|
d425bd564c | ||
|
|
93e3065b3e | ||
|
|
0ad2d59924 | ||
|
|
f4468a8233 | ||
|
|
dc08877bbb | ||
|
|
f08caa6135 | ||
|
|
ad7d029ce8 | ||
|
|
387912b4d3 | ||
|
|
53e0ed4d4a | ||
|
|
11c205b5c4 | ||
|
|
4ede6351ec | ||
|
|
24bbcb466f | ||
|
|
b6b5cfe403 | ||
|
|
b6ce9c6ed7 | ||
|
|
6e5e8f0ce8 | ||
|
|
2415d785cc | ||
|
|
2b5d6beb84 | ||
|
|
86316d8940 | ||
|
|
1f2b5ec5c8 | ||
|
|
8db6f8f633 | ||
|
|
79557165a3 | ||
|
|
ec1d4abde9 | ||
|
|
07c5e2800a | ||
|
|
79811d6662 | ||
|
|
67919ece16 | ||
|
|
7029dcf09e | ||
|
|
fc03b3a79d | ||
|
|
096d6371f1 | ||
|
|
e580734c95 | ||
|
|
2690156a9d | ||
|
|
7ac7a40b1b | ||
|
|
dc9e572052 | ||
|
|
b15ebfd492 | ||
|
|
8baee7a0c9 | ||
|
|
dc85063467 | ||
|
|
be428b326e | ||
|
|
dd0e360709 | ||
|
|
04da88e3b4 | ||
|
|
9bcab02e35 | ||
|
|
1ff4d41b7c | ||
|
|
04a5c8f69f | ||
|
|
8886a94a01 | ||
|
|
f25eebdf3f | ||
|
|
f9ba46fe85 | ||
|
|
6f6fb859d6 | ||
|
|
1e3389b427 | ||
|
|
c977c64139 | ||
|
|
e419149378 | ||
|
|
a5a3e41d21 | ||
|
|
ecef8eaf86 | ||
|
|
de03cfbe64 | ||
|
|
03a6de55d6 | ||
|
|
3c5047df5e | ||
|
|
3cc630d4c2 | ||
|
|
b3488c54cd | ||
|
|
01b1d66bea | ||
|
|
bc9cadaa77 | ||
|
|
f42ec7e2c5 | ||
|
|
d6a422fbdb | ||
|
|
d98b54bea7 | ||
|
|
0beda1d053 | ||
|
|
e912ab8f4e | ||
|
|
5055a18ca1 | ||
|
|
96746f4042 | ||
|
|
b22ad3ded9 | ||
|
|
7e0f475c63 | ||
|
|
efb3c2b71e | ||
|
|
862ea6986f | ||
|
|
cfa5dcb02e | ||
|
|
23aaada79d | ||
|
|
9e4458db10 | ||
|
|
a8da06033c | ||
|
|
0bf3597147 | ||
|
|
cfd9730055 | ||
|
|
e88ead30dc | ||
|
|
67b24ce846 | ||
|
|
709c3fff65 | ||
|
|
ab6e87ae6b | ||
|
|
cdb7066bed | ||
|
|
73d0507f1f | ||
|
|
4d263bcf32 | ||
|
|
2d8f61172d | ||
|
|
621c1dc11e | ||
|
|
dd136a5ff4 | ||
|
|
8fc785bbd6 | ||
|
|
82be503f4f | ||
|
|
7feb933519 | ||
|
|
e806e5a293 | ||
|
|
770951c6da | ||
|
|
7b7c7b528a | ||
|
|
a554aa20f8 | ||
|
|
ff1ef1f184 | ||
|
|
bf1efaf912 | ||
|
|
ff2bc41317 | ||
|
|
bdaf8aff15 | ||
|
|
1dc4f9f6bb | ||
|
|
d6320f5da1 | ||
|
|
276be5e857 | ||
|
|
3101e77ecc | ||
|
|
ab6dae16f1 | ||
|
|
36222d79c6 | ||
|
|
08656a6674 | ||
|
|
8034317796 | ||
|
|
a59f3a550e | ||
|
|
415b967c0b | ||
|
|
642499d519 | ||
|
|
fa0a54eee7 | ||
|
|
82f175f6c7 | ||
|
|
8df549e8d9 | ||
|
|
9fd720777b | ||
|
|
4c68c725b1 | ||
|
|
06a5207c6d | ||
|
|
78b885c508 | ||
|
|
a18a3b6099 | ||
|
|
68949e070c | ||
|
|
654333dabe | ||
|
|
81b8a76f1b | ||
|
|
31736fa194 | ||
|
|
33632ef1dc | ||
|
|
94305ed82c | ||
|
|
c8abc45e25 | ||
|
|
cd25459ac9 | ||
|
|
aaf1eb8059 | ||
|
|
1589e4236a | ||
|
|
8ca202d0a9 | ||
|
|
d2f7904118 | ||
|
|
2d059fb856 | ||
|
|
8bbd7898bb | ||
|
|
ea6f8c9a50 | ||
|
|
d152440436 | ||
|
|
1ffe76a525 | ||
|
|
a6825f530c | ||
|
|
7cf6dc386f | ||
|
|
5d8252bb07 | ||
|
|
e1e1e0fb2f | ||
|
|
4f7345563f | ||
|
|
68a2b9f3a8 | ||
|
|
d79402c568 | ||
|
|
d0e8f650be | ||
|
|
d819c6efe2 | ||
|
|
91c877f234 | ||
|
|
55a674ba7b | ||
|
|
36055b7c04 | ||
|
|
fe3cc661d3 | ||
|
|
eb7efae1cc | ||
|
|
63f8fb54d4 | ||
|
|
097fa2e655 | ||
|
|
3d0b4d51c2 | ||
|
|
37650487f7 | ||
|
|
6ccc0b4fbf | ||
|
|
79fe95372d | ||
|
|
6adb190d0e | ||
|
|
c094e6c6f4 | ||
|
|
8c796b4e57 | ||
|
|
c08e9a89ff | ||
|
|
cc8ba18ccc | ||
|
|
57c671a42e | ||
|
|
1ee6ecf3ae | ||
|
|
5f80b3773b | ||
|
|
8452455050 | ||
|
|
e5d8f60cdb | ||
|
|
de466000a0 | ||
|
|
49664c011c | ||
|
|
cf34d6b127 | ||
|
|
e52f6ce099 | ||
|
|
1ecdc4c487 | ||
|
|
d38e2c49cb | ||
|
|
f8464fa76f | ||
|
|
308ae2cb2e | ||
|
|
88219659fb | ||
|
|
c34c2df061 | ||
|
|
99c7bd4c10 | ||
|
|
f93d5a6fbf | ||
|
|
cd116667be | ||
|
|
2f2de3952d | ||
|
|
45e56798c5 | ||
|
|
0664d480e6 | ||
|
|
283599ddf5 | ||
|
|
09e3ceefa0 | ||
|
|
87f76ebfe4 | ||
|
|
55a195b841 | ||
|
|
c7946fd7b3 | ||
|
|
5d3ba3199c | ||
|
|
f0d10306fc | ||
|
|
161943b5b8 | ||
|
|
e545043a26 | ||
|
|
40fb58b5b7 | ||
|
|
1f9d4708b3 | ||
|
|
162809e081 | ||
|
|
482c871ac2 | ||
|
|
f0b3311630 | ||
|
|
656d6d6c3f | ||
|
|
ea45f0f4aa | ||
|
|
6a25cb0a58 | ||
|
|
4a1901420d | ||
|
|
ad64f00608 | ||
|
|
65aea29cb9 | ||
|
|
7981424e9a | ||
|
|
10c4340475 | ||
|
|
0a95db1a51 | ||
|
|
ace77dce65 | ||
|
|
c1d58bb25f | ||
|
|
fbcafe0f62 | ||
|
|
9a9d9222a9 | ||
|
|
221e5b4f6c | ||
|
|
5df74aee68 | ||
|
|
17838d8040 | ||
|
|
f82ca91a61 | ||
|
|
b06c234b59 | ||
|
|
31a7ebd4f1 |
80
coverage/HeadlessChrome 0.0.0 (Mac OS X 10.14.6)/index.html
Normal file
80
coverage/HeadlessChrome 0.0.0 (Mac OS X 10.14.6)/index.html
Normal file
@@ -0,0 +1,80 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Code coverage report for All files</title>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" href="prettify.css" />
|
||||
<link rel="stylesheet" href="base.css" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style type='text/css'>
|
||||
.coverage-summary .sorter {
|
||||
background-image: url(sort-arrow-sprite.png);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class='wrapper'>
|
||||
<div class='pad1'>
|
||||
<h1>
|
||||
/
|
||||
</h1>
|
||||
<div class='clearfix'>
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">100% </span>
|
||||
<span class="quiet">Statements</span>
|
||||
<span class='fraction'>0/0</span>
|
||||
</div>
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">100% </span>
|
||||
<span class="quiet">Branches</span>
|
||||
<span class='fraction'>0/0</span>
|
||||
</div>
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">100% </span>
|
||||
<span class="quiet">Functions</span>
|
||||
<span class='fraction'>0/0</span>
|
||||
</div>
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">100% </span>
|
||||
<span class="quiet">Lines</span>
|
||||
<span class='fraction'>0/0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='status-line high'></div>
|
||||
<div class="pad1">
|
||||
<table class="coverage-summary">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-col="file" data-fmt="html" data-html="true" class="file">File</th>
|
||||
<th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>
|
||||
<th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>
|
||||
<th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>
|
||||
<th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th>
|
||||
<th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th>
|
||||
<th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th>
|
||||
<th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th>
|
||||
<th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th>
|
||||
<th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div><div class='push'></div><!-- for sticky footer -->
|
||||
</div><!-- /wrapper -->
|
||||
<div class='footer quiet pad2 space-top1 center small'>
|
||||
Code coverage
|
||||
generated by <a href="http://istanbul-js.org/" target="_blank">istanbul</a> at Wed Dec 11 2019 13:15:10 GMT-0800 (Pacific Standard Time)
|
||||
</div>
|
||||
</div>
|
||||
<script src="prettify.js"></script>
|
||||
<script>
|
||||
window.onload = function () {
|
||||
if (typeof prettyPrint === 'function') {
|
||||
prettyPrint();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<script src="sorter.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 209 B |
158
coverage/HeadlessChrome 0.0.0 (Mac OS X 10.14.6)/sorter.js
Normal file
158
coverage/HeadlessChrome 0.0.0 (Mac OS X 10.14.6)/sorter.js
Normal file
@@ -0,0 +1,158 @@
|
||||
var addSorting = (function () {
|
||||
"use strict";
|
||||
var cols,
|
||||
currentSort = {
|
||||
index: 0,
|
||||
desc: false
|
||||
};
|
||||
|
||||
// returns the summary table element
|
||||
function getTable() { return document.querySelector('.coverage-summary'); }
|
||||
// returns the thead element of the summary table
|
||||
function getTableHeader() { return getTable().querySelector('thead tr'); }
|
||||
// returns the tbody element of the summary table
|
||||
function getTableBody() { return getTable().querySelector('tbody'); }
|
||||
// returns the th element for nth column
|
||||
function getNthColumn(n) { return getTableHeader().querySelectorAll('th')[n]; }
|
||||
|
||||
// loads all columns
|
||||
function loadColumns() {
|
||||
var colNodes = getTableHeader().querySelectorAll('th'),
|
||||
colNode,
|
||||
cols = [],
|
||||
col,
|
||||
i;
|
||||
|
||||
for (i = 0; i < colNodes.length; i += 1) {
|
||||
colNode = colNodes[i];
|
||||
col = {
|
||||
key: colNode.getAttribute('data-col'),
|
||||
sortable: !colNode.getAttribute('data-nosort'),
|
||||
type: colNode.getAttribute('data-type') || 'string'
|
||||
};
|
||||
cols.push(col);
|
||||
if (col.sortable) {
|
||||
col.defaultDescSort = col.type === 'number';
|
||||
colNode.innerHTML = colNode.innerHTML + '<span class="sorter"></span>';
|
||||
}
|
||||
}
|
||||
return cols;
|
||||
}
|
||||
// attaches a data attribute to every tr element with an object
|
||||
// of data values keyed by column name
|
||||
function loadRowData(tableRow) {
|
||||
var tableCols = tableRow.querySelectorAll('td'),
|
||||
colNode,
|
||||
col,
|
||||
data = {},
|
||||
i,
|
||||
val;
|
||||
for (i = 0; i < tableCols.length; i += 1) {
|
||||
colNode = tableCols[i];
|
||||
col = cols[i];
|
||||
val = colNode.getAttribute('data-value');
|
||||
if (col.type === 'number') {
|
||||
val = Number(val);
|
||||
}
|
||||
data[col.key] = val;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
// loads all row data
|
||||
function loadData() {
|
||||
var rows = getTableBody().querySelectorAll('tr'),
|
||||
i;
|
||||
|
||||
for (i = 0; i < rows.length; i += 1) {
|
||||
rows[i].data = loadRowData(rows[i]);
|
||||
}
|
||||
}
|
||||
// sorts the table using the data for the ith column
|
||||
function sortByIndex(index, desc) {
|
||||
var key = cols[index].key,
|
||||
sorter = function (a, b) {
|
||||
a = a.data[key];
|
||||
b = b.data[key];
|
||||
return a < b ? -1 : a > b ? 1 : 0;
|
||||
},
|
||||
finalSorter = sorter,
|
||||
tableBody = document.querySelector('.coverage-summary tbody'),
|
||||
rowNodes = tableBody.querySelectorAll('tr'),
|
||||
rows = [],
|
||||
i;
|
||||
|
||||
if (desc) {
|
||||
finalSorter = function (a, b) {
|
||||
return -1 * sorter(a, b);
|
||||
};
|
||||
}
|
||||
|
||||
for (i = 0; i < rowNodes.length; i += 1) {
|
||||
rows.push(rowNodes[i]);
|
||||
tableBody.removeChild(rowNodes[i]);
|
||||
}
|
||||
|
||||
rows.sort(finalSorter);
|
||||
|
||||
for (i = 0; i < rows.length; i += 1) {
|
||||
tableBody.appendChild(rows[i]);
|
||||
}
|
||||
}
|
||||
// removes sort indicators for current column being sorted
|
||||
function removeSortIndicators() {
|
||||
var col = getNthColumn(currentSort.index),
|
||||
cls = col.className;
|
||||
|
||||
cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, '');
|
||||
col.className = cls;
|
||||
}
|
||||
// adds sort indicators for current column being sorted
|
||||
function addSortIndicators() {
|
||||
getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted';
|
||||
}
|
||||
// adds event listeners for all sorter widgets
|
||||
function enableUI() {
|
||||
var i,
|
||||
el,
|
||||
ithSorter = function ithSorter(i) {
|
||||
var col = cols[i];
|
||||
|
||||
return function () {
|
||||
var desc = col.defaultDescSort;
|
||||
|
||||
if (currentSort.index === i) {
|
||||
desc = !currentSort.desc;
|
||||
}
|
||||
sortByIndex(i, desc);
|
||||
removeSortIndicators();
|
||||
currentSort.index = i;
|
||||
currentSort.desc = desc;
|
||||
addSortIndicators();
|
||||
};
|
||||
};
|
||||
for (i =0 ; i < cols.length; i += 1) {
|
||||
if (cols[i].sortable) {
|
||||
// add the click event handler on the th so users
|
||||
// dont have to click on those tiny arrows
|
||||
el = getNthColumn(i).querySelector('.sorter').parentElement;
|
||||
if (el.addEventListener) {
|
||||
el.addEventListener('click', ithSorter(i));
|
||||
} else {
|
||||
el.attachEvent('onclick', ithSorter(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// adds sorting functionality to the UI
|
||||
return function () {
|
||||
if (!getTable()) {
|
||||
return;
|
||||
}
|
||||
cols = loadColumns();
|
||||
loadData(cols);
|
||||
addSortIndicators();
|
||||
enableUI();
|
||||
};
|
||||
})();
|
||||
|
||||
window.addEventListener('load', addSorting);
|
||||
@@ -43,7 +43,7 @@
|
||||
openmct.legacyRegistry.enable.bind(openmct.legacyRegistry)
|
||||
);
|
||||
|
||||
openmct.install(openmct.plugins.Espresso());
|
||||
openmct.install(openmct.plugins.Snow());
|
||||
openmct.install(openmct.plugins.MyItems());
|
||||
openmct.install(openmct.plugins.LocalStorage());
|
||||
openmct.install(openmct.plugins.Generator());
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
"request": "^2.69.0",
|
||||
"split": "^1.0.0",
|
||||
"style-loader": "^1.0.1",
|
||||
"uuid": "^3.3.3",
|
||||
"v8-compile-cache": "^1.1.0",
|
||||
"vue": "2.5.6",
|
||||
"vue-loader": "^15.2.6",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* Open MCT, Copyright (c) 2014-2019, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
@@ -264,6 +264,7 @@ define([
|
||||
this.install(this.plugins.GoToOriginalAction());
|
||||
this.install(this.plugins.ImportExport());
|
||||
this.install(this.plugins.WebPage());
|
||||
this.install(this.plugins.Condition());
|
||||
}
|
||||
|
||||
MCT.prototype = Object.create(EventEmitter.prototype);
|
||||
|
||||
244
src/plugins/condition/Condition.js
Normal file
244
src/plugins/condition/Condition.js
Normal file
@@ -0,0 +1,244 @@
|
||||
/*****************************************************************************
|
||||
* 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 * as EventEmitter from 'eventemitter3';
|
||||
import uuid from 'uuid';
|
||||
import TelemetryCriterion from "@/plugins/condition/criterion/TelemetryCriterion";
|
||||
import { TRIGGER } from "@/plugins/condition/utils/constants";
|
||||
import {computeCondition} from "@/plugins/condition/utils/evaluator";
|
||||
|
||||
/*
|
||||
* conditionConfiguration = {
|
||||
* identifier: {
|
||||
* key: '',
|
||||
* namespace: ''
|
||||
* },
|
||||
* trigger: 'any'/'all',
|
||||
* criteria: [
|
||||
* {
|
||||
* telemetry: '',
|
||||
* operation: '',
|
||||
* input: [],
|
||||
* metadata: ''
|
||||
* }
|
||||
* ]
|
||||
* }
|
||||
*/
|
||||
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 openmct
|
||||
*/
|
||||
constructor(conditionConfiguration, openmct) {
|
||||
super();
|
||||
|
||||
this.openmct = openmct;
|
||||
this.id = this.openmct.objects.makeKeyString(conditionConfiguration.identifier);
|
||||
this.criteria = [];
|
||||
this.criteriaResults = {};
|
||||
if (conditionConfiguration.configuration.criteria) {
|
||||
this.createCriteria(conditionConfiguration.configuration.criteria);
|
||||
}
|
||||
this.trigger = conditionConfiguration.configuration.trigger;
|
||||
this.result = null;
|
||||
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);
|
||||
}
|
||||
|
||||
updateTrigger(trigger) {
|
||||
if (this.trigger !== trigger) {
|
||||
this.trigger = trigger;
|
||||
this.handleConditionUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
generateCriterion(criterionConfiguration) {
|
||||
return {
|
||||
id: uuid(),
|
||||
telemetry: criterionConfiguration.telemetry || '',
|
||||
operation: criterionConfiguration.operation || '',
|
||||
input: criterionConfiguration.input === undefined ? [] : criterionConfiguration.input,
|
||||
metadata: criterionConfiguration.metadata || ''
|
||||
};
|
||||
}
|
||||
|
||||
createCriteria(criterionConfigurations) {
|
||||
criterionConfigurations.forEach((criterionConfiguration) => {
|
||||
this.addCriterion(criterionConfiguration);
|
||||
});
|
||||
}
|
||||
|
||||
updateCriteria(criterionConfigurations) {
|
||||
this.destroyCriteria();
|
||||
this.createCriteria(criterionConfigurations);
|
||||
}
|
||||
|
||||
/**
|
||||
* adds criterion to the condition.
|
||||
*/
|
||||
addCriterion(criterionConfiguration) {
|
||||
let criterionConfigurationWithId = this.generateCriterion(criterionConfiguration || null);
|
||||
let criterion = new TelemetryCriterion(criterionConfigurationWithId, this.openmct);
|
||||
criterion.on('criterionUpdated', (obj) => this.handleCriterionUpdated(obj));
|
||||
criterion.on('criterionResultUpdated', (obj) => this.handleCriterionResult(obj));
|
||||
if (!this.criteria) {
|
||||
this.criteria = [];
|
||||
}
|
||||
this.criteria.push(criterion);
|
||||
return criterionConfigurationWithId.id;
|
||||
}
|
||||
|
||||
findCriterion(id) {
|
||||
let criterion;
|
||||
|
||||
for (let i=0, ii=this.criteria.length; i < ii; i ++) {
|
||||
if (this.criteria[i].id === id) {
|
||||
criterion = {
|
||||
item: this.criteria[i],
|
||||
index: i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return criterion;
|
||||
}
|
||||
|
||||
updateCriterion(id, criterionConfiguration) {
|
||||
let found = this.findCriterion(id);
|
||||
if (found) {
|
||||
const newCriterionConfiguration = this.generateCriterion(criterionConfiguration);
|
||||
let newCriterion = new TelemetryCriterion(newCriterionConfiguration, this.openmct);
|
||||
newCriterion.on('criterionUpdated', (obj) => this.handleCriterionUpdated(obj));
|
||||
newCriterion.on('criterionResultUpdated', (obj) => this.handleCriterionResult(obj));
|
||||
|
||||
let criterion = found.item;
|
||||
criterion.unsubscribe();
|
||||
criterion.off('criterionUpdated', (obj) => this.handleCriterionUpdated(obj));
|
||||
criterion.off('criterionResultUpdated', (obj) => this.handleCriterionResult(obj));
|
||||
this.criteria.splice(found.index, 1, newCriterion);
|
||||
if (this.criteriaResults[criterion.id] !== undefined) {
|
||||
delete this.criteriaResults[criterion.id];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
removeCriterion(id) {
|
||||
if (this.destroyCriterion(id)) {
|
||||
this.handleConditionUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
destroyCriterion(id) {
|
||||
let found = this.findCriterion(id);
|
||||
if (found) {
|
||||
let criterion = found.item;
|
||||
criterion.destroy();
|
||||
criterion.off('criterionUpdated', (result) => {
|
||||
this.handleCriterionUpdated(id, result);
|
||||
});
|
||||
this.criteria.splice(found.index, 1);
|
||||
if (this.criteriaResults[criterion.id] !== undefined) {
|
||||
delete this.criteriaResults[criterion.id];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
handleCriterionUpdated(criterion) {
|
||||
let found = this.findCriterion(criterion.id);
|
||||
if (found) {
|
||||
this.criteria[found.index] = criterion.data;
|
||||
this.subscribe();
|
||||
this.emitEvent('conditionUpdated', {
|
||||
trigger: this.trigger,
|
||||
criteria: this.criteria
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handleCriterionResult(eventData) {
|
||||
let id = eventData.id;
|
||||
let result = eventData.data.result;
|
||||
let found = this.findCriterion(id);
|
||||
if (found) {
|
||||
this.criteriaResults[id] = result;
|
||||
}
|
||||
this.handleConditionUpdated();
|
||||
}
|
||||
|
||||
subscribe() {
|
||||
this.criteria.forEach((criterion) => {
|
||||
if (criterion.isValid()) {
|
||||
criterion.subscribe();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
handleConditionUpdated() {
|
||||
// trigger an updated event so that consumers can react accordingly
|
||||
this.evaluate();
|
||||
this.emitEvent('conditionResultUpdated', {result: this.result});
|
||||
}
|
||||
|
||||
getCriteria() {
|
||||
return this.criteria;
|
||||
}
|
||||
|
||||
destroyCriteria() {
|
||||
let success = true;
|
||||
//looping through the array backwards since destroyCriterion modifies the criteria array
|
||||
for (let i=this.criteria.length-1; i >= 0; i--) {
|
||||
success = success && this.destroyCriterion(this.criteria[i].id);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
evaluate() {
|
||||
this.result = computeCondition(this.criteriaResults, this.trigger === TRIGGER.ALL);
|
||||
}
|
||||
|
||||
emitEvent(eventName, data) {
|
||||
this.emit(eventName, {
|
||||
id: this.id,
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
destroy() {
|
||||
if (typeof this.stopObservingForChanges === 'function') {
|
||||
this.stopObservingForChanges();
|
||||
}
|
||||
this.destroyCriteria();
|
||||
}
|
||||
}
|
||||
33
src/plugins/condition/ConditionSetCompositionPolicy.js
Normal file
33
src/plugins/condition/ConditionSetCompositionPolicy.js
Normal file
@@ -0,0 +1,33 @@
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
export default function ConditionSetCompositionPolicy(openmct) {
|
||||
return {
|
||||
allow: function (parent, child) {
|
||||
if (parent.type === 'conditionSet' && !openmct.telemetry.isTelemetryObject(child)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
87
src/plugins/condition/ConditionSetCompositionPolicySpec.js
Normal file
87
src/plugins/condition/ConditionSetCompositionPolicySpec.js
Normal file
@@ -0,0 +1,87 @@
|
||||
/*****************************************************************************
|
||||
* 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 ConditionSetCompositionPolicy from './ConditionSetCompositionPolicy';
|
||||
|
||||
describe('ConditionSetCompositionPolicy', () => {
|
||||
|
||||
let policy;
|
||||
let testTelemetryObject;
|
||||
let openmct = {};
|
||||
let parentDomainObject;
|
||||
let composition;
|
||||
|
||||
beforeAll(function () {
|
||||
testTelemetryObject = {
|
||||
identifier:{ namespace: "", key: "test-object"},
|
||||
type: "test-object",
|
||||
name: "Test Object",
|
||||
telemetry: {
|
||||
values: [{
|
||||
key: "some-key",
|
||||
name: "Some attribute",
|
||||
hints: {
|
||||
domain: 1
|
||||
}
|
||||
}, {
|
||||
key: "some-other-key",
|
||||
name: "Another attribute",
|
||||
hints: {
|
||||
range: 1
|
||||
}
|
||||
}]
|
||||
}
|
||||
};
|
||||
openmct.objects = jasmine.createSpyObj('objects', ['get', 'makeKeyString']);
|
||||
openmct.objects.get.and.returnValue(testTelemetryObject);
|
||||
openmct.objects.makeKeyString.and.returnValue(testTelemetryObject.identifier.key);
|
||||
openmct.telemetry = jasmine.createSpyObj('telemetry', ['isTelemetryObject']);
|
||||
policy = new ConditionSetCompositionPolicy(openmct);
|
||||
parentDomainObject = {};
|
||||
composition = {};
|
||||
});
|
||||
|
||||
it('returns true for object types that are not conditionSets', function () {
|
||||
parentDomainObject.type = 'random';
|
||||
openmct.telemetry.isTelemetryObject.and.returnValue(false);
|
||||
expect(policy.allow(parentDomainObject, {})).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false for object types that are not telemetry objects when parent is a conditionSet', function () {
|
||||
parentDomainObject.type = 'conditionSet';
|
||||
openmct.telemetry.isTelemetryObject.and.returnValue(false);
|
||||
expect(policy.allow(parentDomainObject, {})).toBe(false);
|
||||
});
|
||||
|
||||
it('returns true for object types that are telemetry objects when parent is a conditionSet', function () {
|
||||
parentDomainObject.type = 'conditionSet';
|
||||
openmct.telemetry.isTelemetryObject.and.returnValue(true);
|
||||
expect(policy.allow(parentDomainObject, testTelemetryObject)).toBe(true);
|
||||
});
|
||||
|
||||
it('returns true for object types that are telemetry objects when parent is not a conditionSet', function () {
|
||||
parentDomainObject.type = 'random';
|
||||
openmct.telemetry.isTelemetryObject.and.returnValue(true);
|
||||
expect(policy.allow(parentDomainObject, testTelemetryObject)).toBe(true);
|
||||
});
|
||||
|
||||
});
|
||||
73
src/plugins/condition/ConditionSetViewProvider.js
Normal file
73
src/plugins/condition/ConditionSetViewProvider.js
Normal file
@@ -0,0 +1,73 @@
|
||||
/*****************************************************************************
|
||||
* 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 ConditionSet from './components/ConditionSet.vue';
|
||||
import Vue from 'vue';
|
||||
|
||||
export default class ConditionSetViewProvider {
|
||||
constructor(openmct) {
|
||||
this.openmct = openmct;
|
||||
this.key = 'conditionSet.view';
|
||||
this.cssClass = 'icon-conditional'; // TODO: replace with class for new icon
|
||||
}
|
||||
|
||||
canView(domainObject) {
|
||||
return domainObject.type === 'conditionSet';
|
||||
}
|
||||
|
||||
canEdit(domainObject) {
|
||||
return domainObject.type === 'conditionSet';
|
||||
}
|
||||
|
||||
view(domainObject, objectPath) {
|
||||
let component;
|
||||
const openmct = this.openmct;
|
||||
return {
|
||||
show: (container, isEditing) => {
|
||||
component = new Vue({
|
||||
el: container,
|
||||
components: {
|
||||
ConditionSet
|
||||
},
|
||||
provide: {
|
||||
openmct,
|
||||
domainObject,
|
||||
objectPath
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isEditing
|
||||
}
|
||||
},
|
||||
template: '<condition-set :isEditing="isEditing"></condition-set>'
|
||||
});
|
||||
},
|
||||
onEditModeChange: (isEditing) => {
|
||||
component.isEditing = isEditing;
|
||||
},
|
||||
destroy: () => {
|
||||
component.$destroy();
|
||||
component = undefined;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
121
src/plugins/condition/ConditionSpec.js
Normal file
121
src/plugins/condition/ConditionSpec.js
Normal file
@@ -0,0 +1,121 @@
|
||||
/*****************************************************************************
|
||||
* 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 Condition from "./Condition";
|
||||
import {TRIGGER} from "./utils/constants";
|
||||
import TelemetryCriterion from "./criterion/TelemetryCriterion";
|
||||
|
||||
let openmct = {},
|
||||
mockListener,
|
||||
testConditionDefinition,
|
||||
testTelemetryObject,
|
||||
conditionObj;
|
||||
|
||||
describe("The condition", function () {
|
||||
|
||||
beforeEach (() => {
|
||||
mockListener = jasmine.createSpy('listener');
|
||||
testTelemetryObject = {
|
||||
identifier:{ namespace: "", key: "test-object"},
|
||||
type: "test-object",
|
||||
name: "Test Object",
|
||||
telemetry: {
|
||||
values: [{
|
||||
key: "some-key",
|
||||
name: "Some attribute",
|
||||
hints: {
|
||||
domain: 1
|
||||
}
|
||||
}, {
|
||||
key: "some-other-key",
|
||||
name: "Another attribute",
|
||||
hints: {
|
||||
range: 1
|
||||
}
|
||||
}]
|
||||
}
|
||||
};
|
||||
openmct.objects = jasmine.createSpyObj('objects', ['get', 'makeKeyString']);
|
||||
openmct.objects.get.and.returnValue(new Promise(function (resolve, reject) {
|
||||
resolve(testTelemetryObject);
|
||||
})); openmct.objects.makeKeyString.and.returnValue(testTelemetryObject.identifier.key);
|
||||
openmct.telemetry = jasmine.createSpyObj('telemetry', ['isTelemetryObject', 'subscribe', 'getMetadata']);
|
||||
openmct.telemetry.isTelemetryObject.and.returnValue(true);
|
||||
openmct.telemetry.subscribe.and.returnValue(function () {});
|
||||
openmct.telemetry.getMetadata.and.returnValue(testTelemetryObject.telemetry.values);
|
||||
|
||||
testConditionDefinition = {
|
||||
configuration: {
|
||||
trigger: TRIGGER.ANY,
|
||||
criteria: [
|
||||
{
|
||||
operation: 'equalTo',
|
||||
input: false,
|
||||
metadata: 'value',
|
||||
telemetry: testTelemetryObject.identifier
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
conditionObj = new Condition(
|
||||
testConditionDefinition,
|
||||
openmct
|
||||
);
|
||||
|
||||
conditionObj.on('conditionUpdated', mockListener);
|
||||
|
||||
});
|
||||
|
||||
it("generates criteria with an id", function () {
|
||||
const testCriterion = testConditionDefinition.configuration.criteria[0];
|
||||
let criterion = conditionObj.generateCriterion(testCriterion);
|
||||
expect(criterion.id).toBeDefined();
|
||||
expect(criterion.operation).toEqual(testCriterion.operation);
|
||||
expect(criterion.input).toEqual(testCriterion.input);
|
||||
expect(criterion.metadata).toEqual(testCriterion.metadata);
|
||||
expect(criterion.telemetry).toEqual(testCriterion.telemetry);
|
||||
});
|
||||
|
||||
it("initializes with an id", function () {
|
||||
expect(conditionObj.id).toBeDefined();
|
||||
});
|
||||
|
||||
it("initializes with criteria from the condition definition", function () {
|
||||
expect(conditionObj.criteria.length).toEqual(1);
|
||||
let criterion = conditionObj.criteria[0];
|
||||
expect(criterion instanceof TelemetryCriterion).toBeTrue();
|
||||
expect(criterion.operator).toEqual(testConditionDefinition.configuration.criteria[0].operator);
|
||||
expect(criterion.input).toEqual(testConditionDefinition.configuration.criteria[0].input);
|
||||
expect(criterion.metadata).toEqual(testConditionDefinition.configuration.criteria[0].metadata);
|
||||
});
|
||||
|
||||
it("initializes with the trigger from the condition definition", function () {
|
||||
expect(conditionObj.trigger).toEqual(testConditionDefinition.configuration.trigger);
|
||||
});
|
||||
|
||||
it("destroys all criteria for a condition", function () {
|
||||
const result = conditionObj.destroyCriteria();
|
||||
expect(result).toBeTrue();
|
||||
expect(conditionObj.criteria.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
0
src/plugins/condition/StyleRuleManager.js
Normal file
0
src/plugins/condition/StyleRuleManager.js
Normal file
272
src/plugins/condition/components/Condition.vue
Normal file
272
src/plugins/condition/components/Condition.vue
Normal file
@@ -0,0 +1,272 @@
|
||||
<template>
|
||||
<div v-if="isEditing">
|
||||
<div v-if="domainObject"
|
||||
class="c-c-editui__conditions c-c-container__container c-c__drag-wrapper"
|
||||
:class="['widget-condition', { 'widget-condition--current': currentConditionIdentifier && (currentConditionIdentifier.key === conditionIdentifier.key) }]"
|
||||
:data-condition-index="conditionIndex"
|
||||
:draggable="!domainObject.isDefault"
|
||||
@dragstart="dragStart"
|
||||
@dragover.stop
|
||||
>
|
||||
<div class="title-bar">
|
||||
<span
|
||||
class="c-c__menu-hamburger"
|
||||
:class="{ 'is-enabled': !domainObject.isDefault }"
|
||||
></span>
|
||||
<span
|
||||
class="is-enabled flex-elem"
|
||||
:class="['c-c__disclosure-triangle', { 'c-c__disclosure-triangle--expanded': expanded }]"
|
||||
@click="expanded = !expanded"
|
||||
></span>
|
||||
<div class="condition-summary">
|
||||
<span class="condition-name">{{ domainObject.configuration.name }}</span>
|
||||
<span class="condition-description">{{ domainObject.configuration.name }}</span>
|
||||
</div>
|
||||
<span v-if="!domainObject.isDefault"
|
||||
class="is-enabled c-c__duplicate"
|
||||
@click="cloneCondition"
|
||||
></span>
|
||||
<span v-if="!domainObject.isDefault"
|
||||
class="is-enabled c-c__trash"
|
||||
@click="removeCondition"
|
||||
></span>
|
||||
</div>
|
||||
<div v-if="expanded"
|
||||
class="condition-config-edit widget-condition-content c-sw-editui__conditions-wrapper holder widget-conditions-wrapper flex-elem expanded"
|
||||
>
|
||||
<div id="conditionArea"
|
||||
class="c-c-editui__condition widget-conditions"
|
||||
>
|
||||
<div class="c-c-condition">
|
||||
<div class="c-c-condition__ui l-compact-form l-widget-condition has-local-controls">
|
||||
<div>
|
||||
<ul class="t-widget-condition-config">
|
||||
<li>
|
||||
<label>Condition Name</label>
|
||||
<span class="controls">
|
||||
<input v-model="domainObject.configuration.name"
|
||||
class="t-condition-input__name"
|
||||
type="text"
|
||||
>
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<label>Output</label>
|
||||
<span class="controls">
|
||||
<select v-model="selectedOutputKey"
|
||||
@change="checkInputValue"
|
||||
>
|
||||
<option value="">- Select Output -</option>
|
||||
<option v-for="option in outputOptions"
|
||||
:key="option"
|
||||
:value="option"
|
||||
>
|
||||
{{ initCap(option) }}
|
||||
</option>
|
||||
</select>
|
||||
<input v-if="selectedOutputKey === outputOptions[2]"
|
||||
v-model="domainObject.configuration.output"
|
||||
class="t-condition-name-input"
|
||||
type="text"
|
||||
@blur="persist"
|
||||
>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div v-if="!domainObject.isDefault"
|
||||
class="widget-condition-content expanded"
|
||||
>
|
||||
<ul class="t-widget-condition-config">
|
||||
<li class="has-local-controls t-condition">
|
||||
<label>Match when</label>
|
||||
<span class="controls">
|
||||
<select v-model="trigger">
|
||||
<option value="all">all criteria are met</option>
|
||||
<option value="any">any criteria are met</option>
|
||||
</select>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<ul v-if="telemetry.length"
|
||||
class="t-widget-condition-config"
|
||||
>
|
||||
<Criterion v-for="(criterion, index) in domainObject.configuration.criteria"
|
||||
:key="index"
|
||||
:telemetry="telemetry"
|
||||
:criterion="criterion"
|
||||
:index="index"
|
||||
:trigger="trigger"
|
||||
@persist="persist"
|
||||
/>
|
||||
</ul>
|
||||
<div class="holder c-c-button-wrapper align-left">
|
||||
<span class="c-c-label-spacer"></span>
|
||||
<button
|
||||
class="c-c-button c-c-button--minor add-criteria-button"
|
||||
@click="addCriteria"
|
||||
>
|
||||
<span class="c-c-button__label">Add Criteria</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div v-if="domainObject"
|
||||
id="conditionArea"
|
||||
class="c-cs-ui__conditions"
|
||||
:class="['widget-condition', { 'widget-condition--current': currentConditionIdentifier && (currentConditionIdentifier.key === conditionIdentifier.key) }]"
|
||||
>
|
||||
<div class="title-bar">
|
||||
<span class="condition-name">
|
||||
{{ domainObject.configuration.name }}
|
||||
</span>
|
||||
<span class="condition-output">
|
||||
Output: {{ domainObject.configuration.output }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="condition-config">
|
||||
<span class="condition-description">
|
||||
{{ domainObject.configuration.description }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ConditionClass from "@/plugins/condition/Condition";
|
||||
import Criterion from '../../condition/components/Criterion.vue';
|
||||
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
components: {
|
||||
Criterion
|
||||
},
|
||||
props: {
|
||||
conditionIdentifier: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
currentConditionIdentifier: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
conditionIndex: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
telemetry: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
domainObject: this.domainObject,
|
||||
currentCriteria: this.currentCriteria,
|
||||
expanded: true,
|
||||
trigger: 'all',
|
||||
selectedOutputKey: '',
|
||||
stringOutputField: false,
|
||||
outputOptions: ['false', 'true', 'string']
|
||||
};
|
||||
},
|
||||
destroyed() {
|
||||
this.destroy();
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.objects.get(this.conditionIdentifier).then((domainObject => {
|
||||
this.domainObject = domainObject;
|
||||
this.initialize();
|
||||
}));
|
||||
},
|
||||
methods: {
|
||||
initialize() {
|
||||
this.setOutput();
|
||||
if (!this.domainObject.isDefault) {
|
||||
this.conditionClass = new ConditionClass(this.domainObject, this.openmct);
|
||||
this.conditionClass.on('conditionResultUpdated', this.handleConditionResult.bind(this));
|
||||
}
|
||||
},
|
||||
addCriteria() {
|
||||
const criteriaObject = {
|
||||
telemetry: '',
|
||||
operation: '',
|
||||
input: '',
|
||||
metadata: ''
|
||||
};
|
||||
this.domainObject.configuration.criteria.push(criteriaObject);
|
||||
},
|
||||
dragStart(e) {
|
||||
this.$emit('setMoveIndex', Number(e.target.getAttribute('data-condition-index')));
|
||||
},
|
||||
destroy() {
|
||||
if (this.conditionClass) {
|
||||
this.conditionClass.off('conditionResultUpdated', this.handleConditionResult.bind(this));
|
||||
if (typeof this.conditionClass.destroy === 'function') {
|
||||
this.conditionClass.destroy();
|
||||
}
|
||||
delete this.conditionClass;
|
||||
}
|
||||
},
|
||||
handleConditionResult(args) {
|
||||
this.$emit('conditionResultUpdated', {
|
||||
id: this.conditionIdentifier,
|
||||
result: args.data.result
|
||||
})
|
||||
},
|
||||
removeCondition(ev) {
|
||||
this.$emit('removeCondition', this.conditionIdentifier);
|
||||
},
|
||||
cloneCondition(ev) {
|
||||
this.$emit('cloneCondition', {
|
||||
identifier: this.conditionIdentifier,
|
||||
index: Number(ev.target.closest('.widget-condition').getAttribute('data-condition-index'))
|
||||
});
|
||||
},
|
||||
setOutput() {
|
||||
let conditionOutput = this.domainObject.configuration.output;
|
||||
if (conditionOutput) {
|
||||
if (conditionOutput !== 'false' && conditionOutput !== 'true') {
|
||||
this.selectedOutputKey = 'string';
|
||||
} else {
|
||||
this.selectedOutputKey = conditionOutput;
|
||||
}
|
||||
}
|
||||
},
|
||||
persist() {
|
||||
this.openmct.objects.mutate(this.domainObject, 'configuration', this.domainObject.configuration);
|
||||
},
|
||||
checkInputValue() {
|
||||
if (this.selectedOutputKey === 'string') {
|
||||
this.domainObject.configuration.output = '';
|
||||
} else {
|
||||
this.domainObject.configuration.output = this.selectedOutputKey;
|
||||
}
|
||||
},
|
||||
updateCurrentCondition() {
|
||||
this.$emit('updateCurrentCondition', this.currentConditionIdentifier);
|
||||
},
|
||||
hasTelemetry(identifier) {
|
||||
// TODO: check parent domainObject.composition.hasTelemetry
|
||||
return this.currentCriteria && identifier;
|
||||
},
|
||||
initCap: function (string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
299
src/plugins/condition/components/ConditionCollection.vue
Normal file
299
src/plugins/condition/components/ConditionCollection.vue
Normal file
@@ -0,0 +1,299 @@
|
||||
/*****************************************************************************
|
||||
* 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>
|
||||
<section id="conditionCollection"
|
||||
class="c-cs__ui_section"
|
||||
>
|
||||
<div class="c-cs__ui__header">
|
||||
<span class="c-cs__ui__header-label">Conditions</span>
|
||||
<span
|
||||
class="is-enabled flex-elem"
|
||||
:class="['c-cs__disclosure-triangle', { 'c-cs__disclosure-triangle--expanded': expanded }]"
|
||||
@click="expanded = !expanded"
|
||||
></span>
|
||||
</div>
|
||||
<div v-if="expanded"
|
||||
class="c-cs__ui_content"
|
||||
>
|
||||
<div v-show="isEditing"
|
||||
class="help"
|
||||
>
|
||||
<span>The first condition to match is the one that wins. Drag conditions to rearrange.</span>
|
||||
</div>
|
||||
<div class="holder add-condition-button-wrapper align-left">
|
||||
<button
|
||||
v-show="isEditing"
|
||||
id="addCondition"
|
||||
class="c-cs-button c-cs-button--major add-condition-button"
|
||||
@click="addCondition"
|
||||
>
|
||||
<span class="c-cs-button__label">Add Condition</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="c-c condition-collection">
|
||||
<ul class="c-c__container-holder">
|
||||
<li v-for="(conditionIdentifier, index) in conditionCollection"
|
||||
:key="conditionIdentifier.key"
|
||||
>
|
||||
<div v-if="isEditing"
|
||||
class="c-c__drag-ghost"
|
||||
@drop.prevent="dropCondition"
|
||||
@dragenter="dragEnter"
|
||||
@dragleave="dragLeave"
|
||||
@dragover.prevent
|
||||
></div>
|
||||
<Condition :condition-identifier="conditionIdentifier"
|
||||
:current-condition-identifier="currentConditionIdentifier"
|
||||
:condition-index="index"
|
||||
:telemetry="telemetryObjs"
|
||||
:is-editing="isEditing"
|
||||
@updateCurrentCondition="updateCurrentCondition"
|
||||
@removeCondition="removeCondition"
|
||||
@cloneCondition="cloneCondition"
|
||||
@conditionResultUpdated="handleConditionResult"
|
||||
@setMoveIndex="setMoveIndex"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Condition from '../../condition/components/Condition.vue';
|
||||
import uuid from 'uuid';
|
||||
|
||||
|
||||
export default {
|
||||
inject: ['openmct', 'domainObject'],
|
||||
components: {
|
||||
Condition
|
||||
},
|
||||
props: {
|
||||
isEditing: Boolean
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
expanded: true,
|
||||
parentKeyString: this.openmct.objects.makeKeyString(this.domainObject.identifier),
|
||||
conditionCollection: [],
|
||||
conditionResults: {},
|
||||
conditions: [],
|
||||
currentConditionIdentifier: this.currentConditionIdentifier || {},
|
||||
telemetryObjs: [],
|
||||
moveIndex: Number,
|
||||
isDragging: false
|
||||
};
|
||||
},
|
||||
destroyed() {
|
||||
this.composition.off('add', this.addTelemetryObject);
|
||||
this.composition.off('remove', this.removeTelemetryObject);
|
||||
},
|
||||
mounted() {
|
||||
this.instantiate = this.openmct.$injector.get('instantiate');
|
||||
this.composition = this.openmct.composition.get(this.domainObject);
|
||||
this.composition.on('add', this.addTelemetryObject);
|
||||
this.composition.on('remove', this.removeTelemetryObject);
|
||||
this.composition.load();
|
||||
this.conditionCollection = this.domainObject.configuration ? this.domainObject.configuration.conditionCollection : [];
|
||||
if (!this.conditionCollection.length) {
|
||||
this.addCondition(null, true);
|
||||
} else {
|
||||
this.updateCurrentCondition(this.conditionCollection[0]);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setMoveIndex(index) {
|
||||
this.moveIndex = index;
|
||||
this.isDragging = true;
|
||||
},
|
||||
dropCondition(e) {
|
||||
let targetIndex = Array.from(document.querySelectorAll('.c-c__drag-ghost')).indexOf(e.target);
|
||||
if (targetIndex > this.moveIndex) { targetIndex-- } // for 'downward' move
|
||||
const oldIndexArr = Object.keys(this.conditionCollection);
|
||||
const move = function (arr, old_index, new_index) {
|
||||
while (old_index < 0) {
|
||||
old_index += arr.length;
|
||||
}
|
||||
while (new_index < 0) {
|
||||
new_index += arr.length;
|
||||
}
|
||||
if (new_index >= arr.length) {
|
||||
var k = new_index - arr.length;
|
||||
while ((k--) + 1) {
|
||||
arr.push(undefined);
|
||||
}
|
||||
}
|
||||
arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
|
||||
return arr;
|
||||
}
|
||||
const newIndexArr = move(oldIndexArr, this.moveIndex, targetIndex);
|
||||
const reorderPlan = [];
|
||||
|
||||
for (let i = 0; i < oldIndexArr.length; i++) {
|
||||
reorderPlan.push({oldIndex: Number(newIndexArr[i]), newIndex: i});
|
||||
}
|
||||
|
||||
this.reorder(reorderPlan);
|
||||
|
||||
e.target.classList.remove("dragging");
|
||||
this.isDragging = false;
|
||||
},
|
||||
dragEnter(e) {
|
||||
if (!this.isDragging) { return }
|
||||
let targetIndex = Array.from(document.querySelectorAll('.c-c__drag-ghost')).indexOf(e.target);
|
||||
if (targetIndex > this.moveIndex) { targetIndex-- } // for 'downward' move
|
||||
if (this.moveIndex === targetIndex) { return }
|
||||
e.target.classList.add("dragging");
|
||||
},
|
||||
dragLeave(e) {
|
||||
e.target.classList.remove("dragging");
|
||||
},
|
||||
handleConditionResult(args) {
|
||||
let idAsString = this.openmct.objects.makeKeyString(args.id);
|
||||
this.conditionResults[idAsString] = args.result;
|
||||
this.updateCurrentConditionId();
|
||||
},
|
||||
updateCurrentConditionId() {
|
||||
let currentConditionIdentifier = this.conditionCollection[this.conditionCollection.length-1];
|
||||
for (let i = 0; i < this.conditionCollection.length - 1; i++) {
|
||||
let conditionIdAsString = this.openmct.objects.makeKeyString(this.conditionCollection[i]);
|
||||
if (this.conditionResults[conditionIdAsString]) {
|
||||
//first condition to be true wins
|
||||
currentConditionIdentifier = this.conditionCollection[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.$emit('currentConditionUpdated', currentConditionIdentifier);
|
||||
},
|
||||
addTelemetryObject(domainObject) {
|
||||
this.telemetryObjs.push(domainObject);
|
||||
},
|
||||
removeTelemetryObject(identifier) {
|
||||
let index = _.findIndex(this.telemetryObjs, (obj) => {
|
||||
let objId = this.openmct.objects.makeKeyString(obj.identifier);
|
||||
let id = this.openmct.objects.makeKeyString(identifier);
|
||||
return objId === id;
|
||||
});
|
||||
if (index > -1) {
|
||||
this.telemetryObjs.splice(index, 1);
|
||||
}
|
||||
},
|
||||
removeTelemetry(telemetryDomainObjectIdentifier) {
|
||||
let index = _.findIndex(this.telemetryObjs, (obj) => {
|
||||
let objId = this.openmct.objects.makeKeyString(obj.identifier);
|
||||
let id = this.openmct.objects.makeKeyString(telemetryDomainObjectIdentifier);
|
||||
return objId === id;
|
||||
});
|
||||
if (index > -1) {
|
||||
this.telemetryObjs.splice(index, 1);
|
||||
}
|
||||
},
|
||||
/*
|
||||
Adds a condition to list via programatic creation of default for initial list, manual
|
||||
creation via Add Condition button, or duplication via button in title bar of condition.
|
||||
Params:
|
||||
event: always null,
|
||||
isDefault (boolean): true if conditionList is empty
|
||||
isClone (boolean): true if duplicating a condition
|
||||
definition (string): definition property of condition being duplicated with new name
|
||||
index (number): index of condition being duplicated
|
||||
*/
|
||||
addCondition(event, isDefault, isClone, configuration, index) {
|
||||
let conditionDomainObject = this.createConditionDomainObject(!!isDefault, isClone, configuration);
|
||||
//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(conditionDomainObject, 'created', new Date());
|
||||
if (!isClone) {
|
||||
this.conditionCollection.unshift(conditionDomainObject.identifier);
|
||||
} else {
|
||||
this.conditionCollection.splice(index + 1, 0, conditionDomainObject.identifier);
|
||||
}
|
||||
this.persist();
|
||||
},
|
||||
updateCurrentCondition(identifier) {
|
||||
this.currentConditionIdentifier = identifier;
|
||||
},
|
||||
createConditionDomainObject(isDefault, isClone, configuration) {
|
||||
const configurationTemplate = {
|
||||
name: isDefault ? 'Default' : (isClone ? 'Copy of ' : '') + 'Unnamed Condition',
|
||||
output: 'false',
|
||||
trigger: 'any',
|
||||
criteria: isDefault ? [] : [{
|
||||
telemetry: '',
|
||||
operation: '',
|
||||
input: [],
|
||||
metadata: '',
|
||||
key: ''
|
||||
}]
|
||||
};
|
||||
let conditionObj = {
|
||||
isDefault: isDefault,
|
||||
type: 'condition',
|
||||
name: isDefault ? 'Default' : (isClone ? 'Copy of ' : '') + 'Unnamed Condition',
|
||||
identifier: {
|
||||
namespace: this.domainObject.identifier.namespace,
|
||||
key: uuid()
|
||||
},
|
||||
configuration: isClone ? configuration: configurationTemplate,
|
||||
summary: 'summary description',
|
||||
created: new Date()
|
||||
};
|
||||
let conditionDomainObjectKeyString = this.openmct.objects.makeKeyString(conditionObj.identifier);
|
||||
let newDomainObject = this.instantiate(conditionObj, conditionDomainObjectKeyString);
|
||||
|
||||
return newDomainObject.useCapability('adapter');
|
||||
},
|
||||
updateCondition(updatedCondition) {
|
||||
let index = _.findIndex(this.conditions, (condition) => condition.id === updatedCondition.id);
|
||||
this.conditions[index] = updatedCondition;
|
||||
},
|
||||
removeCondition(identifier) {
|
||||
let index = _.findIndex(this.conditionCollection, (condition) => {
|
||||
let conditionId = this.openmct.objects.makeKeyString(condition);
|
||||
let id = this.openmct.objects.makeKeyString(identifier);
|
||||
return conditionId === id;
|
||||
});
|
||||
this.conditionCollection.splice(index, 1);
|
||||
this.persist();
|
||||
this.updateCurrentConditionId();
|
||||
},
|
||||
reorder(reorderPlan) {
|
||||
let oldConditions = Array.from(this.conditionCollection);
|
||||
reorderPlan.forEach((reorderEvent) => {
|
||||
this.$set(this.conditionCollection, reorderEvent.newIndex, oldConditions[reorderEvent.oldIndex]);
|
||||
});
|
||||
this.persist();
|
||||
},
|
||||
cloneCondition(condition) {
|
||||
this.openmct.objects.get(condition.identifier).then((obj) => {
|
||||
obj.configuration.name = 'Copy of ' + obj.configuration.name;
|
||||
this.addCondition(null, false, true, obj.configuration, condition.index);
|
||||
});
|
||||
},
|
||||
persist() {
|
||||
this.openmct.objects.mutate(this.domainObject, 'configuration.conditionCollection', this.conditionCollection);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
74
src/plugins/condition/components/ConditionSet.vue
Normal file
74
src/plugins/condition/components/ConditionSet.vue
Normal file
@@ -0,0 +1,74 @@
|
||||
/*****************************************************************************
|
||||
* 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 class="c-cs-edit w-condition-set">
|
||||
<div class="c-sw-edit__ui holder">
|
||||
<CurrentOutput :condition="currentCondition" />
|
||||
<TestData :is-editing="isEditing" />
|
||||
<ConditionCollection :is-editing="isEditing"
|
||||
@currentConditionUpdated="updateCurrentCondition"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CurrentOutput from './CurrentOutput.vue';
|
||||
import TestData from './TestData.vue';
|
||||
import ConditionCollection from './ConditionCollection.vue';
|
||||
|
||||
export default {
|
||||
inject: ["openmct", "domainObject"],
|
||||
components: {
|
||||
CurrentOutput,
|
||||
TestData,
|
||||
ConditionCollection
|
||||
},
|
||||
props: {
|
||||
isEditing: Boolean
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentCondition: this.currentCondition
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let conditionCollection = this.domainObject.configuration.conditionCollection;
|
||||
this.currentConditionIdentifier = conditionCollection.length ? this.updateCurrentCondition(conditionCollection[0]) : null;
|
||||
},
|
||||
methods: {
|
||||
setCurrentCondition() {
|
||||
if (this.currentConditionIdentifier) {
|
||||
this.openmct.objects.get(this.currentConditionIdentifier).then((obj) => {
|
||||
this.currentCondition = obj;
|
||||
});
|
||||
}
|
||||
},
|
||||
updateCurrentCondition(conditionIdentifier) {
|
||||
this.currentConditionIdentifier = conditionIdentifier;
|
||||
this.setCurrentCondition();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
167
src/plugins/condition/components/Criterion.vue
Normal file
167
src/plugins/condition/components/Criterion.vue
Normal file
@@ -0,0 +1,167 @@
|
||||
<template>
|
||||
<li class="has-local-controls t-condition">
|
||||
<label>{{ setRowLabel }}</label>
|
||||
<span class="t-configuration">
|
||||
<span class="controls">
|
||||
<select v-model="criterion.telemetry"
|
||||
@change="updateMetadataOptions"
|
||||
>
|
||||
<option value="">- Select Telemetry -</option>
|
||||
<option v-for="telemetryOption in telemetry"
|
||||
:key="telemetryOption.identifier.key"
|
||||
:value="telemetryOption.identifier"
|
||||
>
|
||||
{{ telemetryOption.name }}
|
||||
</option>
|
||||
</select>
|
||||
</span>
|
||||
<span v-if="criterion.telemetry"
|
||||
class="controls"
|
||||
>
|
||||
<select v-model="criterion.metadata"
|
||||
@change="updateOperations"
|
||||
>
|
||||
<option value="">- Select Field -</option>
|
||||
<option v-for="option in telemetryMetadataOptions"
|
||||
:key="option.key"
|
||||
:value="option.key"
|
||||
>
|
||||
{{ option.name }}
|
||||
</option>
|
||||
</select>
|
||||
</span>
|
||||
<span v-if="criterion.telemetry && criterion.metadata"
|
||||
class="controls"
|
||||
>
|
||||
<select v-model="criterion.operation"
|
||||
@change="updateOperationInputVisibility"
|
||||
>
|
||||
<option value="">- Select Comparison -</option>
|
||||
<option v-for="option in filteredOps"
|
||||
:key="option.name"
|
||||
:value="option.name"
|
||||
>
|
||||
{{ option.text }}
|
||||
</option>
|
||||
</select>
|
||||
<input v-if="isInputOperation"
|
||||
v-model="criterion.input"
|
||||
class="t-condition-name-input"
|
||||
type="text"
|
||||
@blur="persist"
|
||||
>
|
||||
</span>
|
||||
</span>
|
||||
</li>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { OPERATIONS } from '../utils/operations';
|
||||
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
criterion: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
telemetry: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => []
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
trigger: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
telemetryMetadata: {},
|
||||
telemetryMetadataOptions: {},
|
||||
operations: OPERATIONS,
|
||||
filteredOps: [],
|
||||
isInputOperation: false,
|
||||
rowLabel: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
setRowLabel: function () {
|
||||
let operator = this.trigger === 'all' ? 'and ': 'or ';
|
||||
return (this.index !== 0 ? operator : '') + 'when';
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.updateMetadataOptions();
|
||||
},
|
||||
methods: {
|
||||
updateMetadataOptions(ev) {
|
||||
if (ev) {
|
||||
this.criterion.metadata = '';
|
||||
this.criterion.operation = '';
|
||||
this.criterion.input = [];
|
||||
}
|
||||
if (this.criterion.telemetry) {
|
||||
this.openmct.objects.get(this.criterion.telemetry).then((telemetryObject) => {
|
||||
this.telemetryMetadata = this.openmct.telemetry.getMetadata(telemetryObject);
|
||||
this.telemetryMetadataOptions = this.telemetryMetadata.values();
|
||||
this.updateOperations();
|
||||
this.updateOperationInputVisibility();
|
||||
});
|
||||
} else {
|
||||
this.criterion.metadata = '';
|
||||
}
|
||||
this.persist();
|
||||
},
|
||||
updateOperations(ev) {
|
||||
if (ev) {
|
||||
this.criterion.operation = '';
|
||||
this.criterion.input = [];
|
||||
}
|
||||
let operationFormat = 'string';
|
||||
this.telemetryMetadata.valueMetadatas.forEach((value, index) => {
|
||||
if (value.key === this.criterion.metadata) {
|
||||
let valueMetadata = this.telemetryMetadataOptions[index];
|
||||
if (valueMetadata.formatString) {
|
||||
operationFormat = 'number';
|
||||
} else if (valueMetadata.format) {
|
||||
if (valueMetadata.format === 'utc') {
|
||||
operationFormat = 'number';
|
||||
} else if (valueMetadata.format === 'enum') {
|
||||
operationFormat = 'enum';
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
this.filteredOps = [...this.operations.filter(op => op.appliesTo.indexOf(operationFormat) !== -1)];
|
||||
},
|
||||
updateOperationInputVisibility(ev) {
|
||||
if (ev) {
|
||||
this.criterion.input = [];
|
||||
}
|
||||
if (this.criterion.operation === '') {
|
||||
this.isInputOperation = false;
|
||||
} else {
|
||||
for (let i = 0; i < this.filteredOps.length; i++) {
|
||||
if (this.criterion.operation === this.filteredOps[i].name) {
|
||||
this.isInputOperation = this.filteredOps[i].inputCount > 0;
|
||||
if (!this.isInputOperation) {this.criterion.input = ''}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.persist();
|
||||
},
|
||||
updateMetadataSelection() {
|
||||
this.updateOperationInputVisibility();
|
||||
},
|
||||
persist() {
|
||||
this.$emit('persist', this.criterion);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
69
src/plugins/condition/components/CurrentOutput.vue
Normal file
69
src/plugins/condition/components/CurrentOutput.vue
Normal file
@@ -0,0 +1,69 @@
|
||||
/*****************************************************************************
|
||||
* 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>
|
||||
<section id="current-output">
|
||||
<div v-if="condition"
|
||||
class="c-cs__ui__header"
|
||||
>
|
||||
<span class="c-cs__ui__header-label">Current Output</span>
|
||||
<span
|
||||
class="is-enabled flex-elem"
|
||||
:class="['c-cs__disclosure-triangle', { 'c-cs__disclosure-triangle--expanded': expanded }]"
|
||||
@click="expanded = !expanded"
|
||||
></span>
|
||||
</div>
|
||||
<div v-if="expanded && condition"
|
||||
class="c-cs__ui_content"
|
||||
>
|
||||
<div>
|
||||
<span class="current-output">{{ condition.configuration.output }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
inject: ['openmct', 'domainObject'],
|
||||
props: {
|
||||
isEditing: Boolean,
|
||||
condition: {
|
||||
default: () => {return null;},
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
expanded: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
updated() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
96
src/plugins/condition/components/TestData.vue
Normal file
96
src/plugins/condition/components/TestData.vue
Normal file
@@ -0,0 +1,96 @@
|
||||
/*****************************************************************************
|
||||
* 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>
|
||||
<section v-show="isEditing"
|
||||
id="test-data"
|
||||
class="test-data"
|
||||
>
|
||||
<div class="c-cs__ui__header">
|
||||
<span class="c-cs__ui__header-label">Test Data</span>
|
||||
<span
|
||||
class="is-enabled flex-elem"
|
||||
:class="['c-cs__disclosure-triangle', { 'c-cs__disclosure-triangle--expanded': expanded }]"
|
||||
@click="expanded = !expanded"
|
||||
></span>
|
||||
</div>
|
||||
<div v-if="expanded"
|
||||
class="c-cs__ui_content"
|
||||
>
|
||||
<label class="c-toggle-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="isApplied"
|
||||
@change="applyTestData"
|
||||
>
|
||||
<span class="c-toggle-switch__slider"></span>
|
||||
<span>Apply Test Data</span>
|
||||
</label>
|
||||
<div class="t-test-data-config">
|
||||
<div class="c-cs-editui__conditions widget-condition">
|
||||
<form>
|
||||
<label>
|
||||
<span>Set</span>
|
||||
<select>
|
||||
<option>- Select Input -</option>
|
||||
</select>
|
||||
</label>
|
||||
<span class="is-enabled flex-elem c-cs__duplicate"></span>
|
||||
<span class="is-enabled flex-elem c-cs__trash"></span>
|
||||
</form>
|
||||
</div>
|
||||
<div class="c-cs-editui__conditions widget-condition">
|
||||
<form>
|
||||
<label>
|
||||
<span>Set</span>
|
||||
<select>
|
||||
<option>- Select Input -</option>
|
||||
</select>
|
||||
</label>
|
||||
<span class="is-enabled c-cs__duplicate"></span>
|
||||
<span class="is-enabled c-cs__trash"></span>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
isEditing: Boolean
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
expanded: true,
|
||||
isApplied: true
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
applyTestData(ev) {
|
||||
this.$emit('change', ev.target.checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
147
src/plugins/condition/components/condition-set.scss
Normal file
147
src/plugins/condition/components/condition-set.scss
Normal file
@@ -0,0 +1,147 @@
|
||||
.c-cs-edit {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
section {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.c-cs__ui__header {
|
||||
background-color: #D0D1D3;
|
||||
padding: 0.4em 0.6em;
|
||||
text-transform: uppercase;
|
||||
font-size: 0.8em;
|
||||
font-weight: bold;
|
||||
color: #7C7D80;
|
||||
display: flex;
|
||||
justify-content: stretch;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.c-cs__ui__header-label {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.c-cs__ui_content {
|
||||
padding: 0.4em;
|
||||
}
|
||||
|
||||
.c-cs-ui__label {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.c-cs__ui_content .help {
|
||||
font-style: italic;
|
||||
padding: 0.4em 0;
|
||||
}
|
||||
|
||||
.current-output {
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
margin: 0.4em 0.6em;
|
||||
}
|
||||
|
||||
.condition-output {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.condition-description {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.checkbox.custom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 0.6em;
|
||||
}
|
||||
.checkbox.custom span {
|
||||
display: inline-block;
|
||||
margin-left: 0.6em;
|
||||
}
|
||||
|
||||
.t-test-data-config {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.widget-condition form {
|
||||
padding: 0.5em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: stretch;
|
||||
}
|
||||
|
||||
.widget-condition form label {
|
||||
flex-grow: 1;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.widget-condition form input {
|
||||
min-height: 24px;
|
||||
}
|
||||
|
||||
.c-cs-button[class*="--major"],
|
||||
.c-cs-button[class*='is-active'],
|
||||
.c-cs-button--menu[class*="--major"],
|
||||
.c-cs-button--menu[class*='is-active'] {
|
||||
border: solid 1px #0B427C;
|
||||
background-color: #4778A3;
|
||||
padding: 0.2em 0.6em;
|
||||
margin: 0.4em;
|
||||
font-weight: bold;
|
||||
color: #eee;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.c-cs__disclosure-triangle,
|
||||
.c-cs__menu-hamburger,
|
||||
.c-cs__duplicate,
|
||||
.c-cs__trash {
|
||||
$d: 8px;
|
||||
color: $colorDisclosureCtrl;
|
||||
width: $d;
|
||||
visibility: hidden;
|
||||
|
||||
&.is-enabled {
|
||||
cursor: pointer;
|
||||
visibility: visible;
|
||||
|
||||
&:hover {
|
||||
color: $colorDisclosureCtrlHov;
|
||||
}
|
||||
|
||||
&:before {
|
||||
$s: .5;
|
||||
display: block;
|
||||
font-family: symbolsfont;
|
||||
font-size: 1rem * $s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.c-cs__disclosure-triangle {
|
||||
&:before {
|
||||
content: $glyph-icon-arrow-right;
|
||||
}
|
||||
|
||||
&--expanded {
|
||||
&:before {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.c-cs__duplicate {
|
||||
margin-right: 0.3em;
|
||||
&:before {
|
||||
content: $glyph-icon-duplicate;
|
||||
}
|
||||
}
|
||||
|
||||
.c-cs__trash {
|
||||
&:before {
|
||||
content: $glyph-icon-trash;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
199
src/plugins/condition/components/condition.scss
Normal file
199
src/plugins/condition/components/condition.scss
Normal file
@@ -0,0 +1,199 @@
|
||||
.widget-condition {
|
||||
background-color: #eee;
|
||||
margin: 0 0 0.33em;
|
||||
border-radius: 3px;
|
||||
|
||||
&--current {
|
||||
background-color: #DEECFA;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.c-c-editui__conditions.widget-condition {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.c-c-button-wrapper {
|
||||
border-top: solid 1px #ccc;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.c-c-label-spacer {
|
||||
display: inline-block;
|
||||
width: 90px;
|
||||
}
|
||||
|
||||
.c-c-button[class*="--minor"],
|
||||
.c-c-button[class*='is-active'],
|
||||
.c-c-button--menu[class*="--minor"],
|
||||
.c-c-button--menu[class*='is-active'] {
|
||||
border: solid 1px #666;
|
||||
background-color: #fff;
|
||||
padding: 0.1em 0.4em;
|
||||
margin: 0.4em;
|
||||
font-weight: normal;
|
||||
color: #666;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.title-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: stretch;
|
||||
padding: 0.4em 0;
|
||||
}
|
||||
|
||||
.title-bar span {
|
||||
margin-right: 0.6em;
|
||||
}
|
||||
|
||||
.title-bar span.c-c__duplicate,
|
||||
.title-bar span.c-c__trash{
|
||||
margin-right: 0;
|
||||
margin-left: 0.3em;
|
||||
}
|
||||
|
||||
.widget-condition > div {
|
||||
margin: 0 0.4em;
|
||||
}
|
||||
|
||||
.condition-name {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.condition-summary .condition-description {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.condition-summary {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.condition-config {
|
||||
padding: 0.3em 0;
|
||||
}
|
||||
|
||||
.widget-condition form label {
|
||||
flex-grow: 1;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.l-widget-condition {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.l-compact-form ul li {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.widget-condition-content.expanded {
|
||||
margin: 0 3px;
|
||||
}
|
||||
|
||||
.widget-condition-content.expanded ul li {
|
||||
border-top: solid 1px #ccc;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.l-compact-form ul li .controls {
|
||||
display: inline-flex;
|
||||
flex-grow: inherit;
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.l-compact-form ul li > label {
|
||||
display: block;
|
||||
width: 90px;
|
||||
min-width: 90px;
|
||||
text-align: right;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.l-compact-form ul li .controls input[type="text"],
|
||||
.l-compact-form ul li .controls input[type="search"],
|
||||
.l-compact-form ul li .controls input[type="number"],
|
||||
.l-compact-form ul li .controls button,
|
||||
.l-compact-form ul li .controls select {
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
.condition-config-edit {
|
||||
padding: 3px 0;
|
||||
}
|
||||
|
||||
|
||||
.c-c__disclosure-triangle,
|
||||
.c-c__menu-hamburger,
|
||||
.c-c__duplicate,
|
||||
.c-c__trash {
|
||||
$d: 8px;
|
||||
color: $colorDisclosureCtrl;
|
||||
width: $d;
|
||||
visibility: hidden;
|
||||
|
||||
&.is-enabled {
|
||||
cursor: pointer;
|
||||
visibility: visible;
|
||||
|
||||
&:hover {
|
||||
color: $colorDisclosureCtrlHov;
|
||||
}
|
||||
|
||||
&:before {
|
||||
$s: .5;
|
||||
display: block;
|
||||
font-family: symbolsfont;
|
||||
font-size: 1rem * $s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.c-c__disclosure-triangle {
|
||||
&:before {
|
||||
content: $glyph-icon-arrow-right;
|
||||
}
|
||||
|
||||
&--expanded {
|
||||
&:before {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.c-c__menu-hamburger {
|
||||
&:active {
|
||||
cursor: grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
cursor: -webkit-grabbing;
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: $glyph-icon-menu-hamburger;
|
||||
}
|
||||
}
|
||||
|
||||
.c-c__duplicate {
|
||||
&:before {
|
||||
content: $glyph-icon-duplicate;
|
||||
}
|
||||
}
|
||||
|
||||
.c-c__trash {
|
||||
&:before {
|
||||
content: $glyph-icon-trash;
|
||||
}
|
||||
}
|
||||
|
||||
.c-c__drag-ghost {
|
||||
width: 100%;
|
||||
min-height: 0.33em;
|
||||
&.dragging {
|
||||
min-height: 2em;
|
||||
border: solid 1px blue;
|
||||
background-color: lightblue;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
128
src/plugins/condition/criterion/TelemetryCriterion.js
Normal file
128
src/plugins/condition/criterion/TelemetryCriterion.js
Normal file
@@ -0,0 +1,128 @@
|
||||
/*****************************************************************************
|
||||
* 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 * as EventEmitter from 'eventemitter3';
|
||||
import {OPERATIONS} from '../utils/operations';
|
||||
|
||||
export default class TelemetryCriterion extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Subscribes/Unsubscribes to telemetry and emits the result
|
||||
* of operations performed on the telemetry data returned and a given input value.
|
||||
* @constructor
|
||||
* @param telemetryDomainObjectDefinition {id: uuid, operation: enum, input: Array, metadata: string, key: {domainObject.identifier} }
|
||||
* @param openmct
|
||||
*/
|
||||
constructor(telemetryDomainObjectDefinition, openmct) {
|
||||
super();
|
||||
|
||||
this.openmct = openmct;
|
||||
this.objectAPI = this.openmct.objects;
|
||||
this.telemetryAPI = this.openmct.telemetry;
|
||||
this.id = telemetryDomainObjectDefinition.id;
|
||||
this.telemetry = telemetryDomainObjectDefinition.telemetry;
|
||||
this.operation = telemetryDomainObjectDefinition.operation;
|
||||
this.input = telemetryDomainObjectDefinition.input;
|
||||
this.metadata = telemetryDomainObjectDefinition.metadata;
|
||||
this.subscription = null;
|
||||
this.telemetryObjectIdAsString = null;
|
||||
this.objectAPI.get(this.objectAPI.makeKeyString(this.telemetry)).then((obj) => this.initialize(obj));
|
||||
}
|
||||
|
||||
initialize(obj) {
|
||||
this.telemetryObject = obj;
|
||||
this.telemetryObjectIdAsString = this.objectAPI.makeKeyString(this.telemetryObject.identifier);
|
||||
this.emitEvent('criterionUpdated', this);
|
||||
}
|
||||
|
||||
handleSubscription(data) {
|
||||
let result = this.computeResult(data);
|
||||
this.emitEvent('criterionResultUpdated', {
|
||||
result: result,
|
||||
error: null
|
||||
})
|
||||
}
|
||||
|
||||
findOperation(operation) {
|
||||
for (let i=0, ii=OPERATIONS.length; i < ii; i++) {
|
||||
if (operation === OPERATIONS[i].name) {
|
||||
return OPERATIONS[i].operation;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
computeResult(data) {
|
||||
let comparator = this.findOperation(this.operation);
|
||||
let params = [];
|
||||
let result = false;
|
||||
params.push(data[this.metadata]);
|
||||
if (this.input instanceof Array && this.input.length) {
|
||||
params.push(this.input[0]);
|
||||
} else if (this.input) {
|
||||
params.push(this.input);
|
||||
}
|
||||
if (typeof comparator === 'function') {
|
||||
result = comparator(params);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
emitEvent(eventName, data) {
|
||||
this.emit(eventName, {
|
||||
id: this.id,
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
isValid() {
|
||||
return this.telemetryObject && this.metadata && this.operation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribes to the telemetry object and returns an unsubscribe function
|
||||
*/
|
||||
subscribe() {
|
||||
this.unsubscribe();
|
||||
this.subscription = this.telemetryAPI.subscribe(this.telemetryObject, (datum) => {
|
||||
this.handleSubscription(datum);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls an unsubscribe function returned by subscribe() and deletes any initialized data
|
||||
*/
|
||||
unsubscribe() {
|
||||
//unsubscribe from telemetry source
|
||||
if (typeof this.subscription === 'function') {
|
||||
this.subscription();
|
||||
}
|
||||
delete this.subscription;
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.unsubscribe();
|
||||
this.emitEvent('criterionRemoved');
|
||||
delete this.telemetryObjectIdAsString;
|
||||
delete this.telemetryObject;
|
||||
}
|
||||
}
|
||||
116
src/plugins/condition/criterion/TelemetryCriterionSpec.js
Normal file
116
src/plugins/condition/criterion/TelemetryCriterionSpec.js
Normal file
@@ -0,0 +1,116 @@
|
||||
/*****************************************************************************
|
||||
* 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 TelemetryCriterion from "./TelemetryCriterion";
|
||||
|
||||
let openmct = {},
|
||||
mockListener,
|
||||
mockListener2,
|
||||
testCriterionDefinition,
|
||||
testTelemetryObject,
|
||||
telemetryCriterion;
|
||||
|
||||
describe("The telemetry criterion", function () {
|
||||
|
||||
beforeEach (() => {
|
||||
testTelemetryObject = {
|
||||
identifier:{ namespace: "", key: "test-object"},
|
||||
type: "test-object",
|
||||
name: "Test Object",
|
||||
telemetry: {
|
||||
values: [{
|
||||
key: "some-key",
|
||||
name: "Some attribute",
|
||||
hints: {
|
||||
domain: 1
|
||||
}
|
||||
}, {
|
||||
key: "some-other-key",
|
||||
name: "Another attribute",
|
||||
hints: {
|
||||
range: 1
|
||||
}
|
||||
}]
|
||||
}
|
||||
};
|
||||
openmct.objects = jasmine.createSpyObj('objects', ['get', 'makeKeyString']);
|
||||
openmct.objects.get.and.returnValue(new Promise(function (resolve, reject) {
|
||||
resolve(testTelemetryObject);
|
||||
}));
|
||||
openmct.objects.makeKeyString.and.returnValue(testTelemetryObject.identifier.key);
|
||||
openmct.telemetry = jasmine.createSpyObj('telemetry', ['isTelemetryObject', "subscribe", "getMetadata"]);
|
||||
openmct.telemetry.isTelemetryObject.and.returnValue(true);
|
||||
openmct.telemetry.subscribe.and.returnValue(function () {});
|
||||
openmct.telemetry.getMetadata.and.returnValue(testTelemetryObject.telemetry.values);
|
||||
|
||||
testCriterionDefinition = {
|
||||
id: 'test-criterion-id',
|
||||
telemetry: openmct.objects.makeKeyString(testTelemetryObject.identifier)
|
||||
};
|
||||
|
||||
mockListener = jasmine.createSpy('listener');
|
||||
mockListener2 = jasmine.createSpy('updatedListener', (data) => {
|
||||
console.log(data);
|
||||
});
|
||||
|
||||
telemetryCriterion = new TelemetryCriterion(
|
||||
testCriterionDefinition,
|
||||
openmct
|
||||
);
|
||||
|
||||
telemetryCriterion.on('criterionResultUpdated', mockListener);
|
||||
telemetryCriterion.on('criterionUpdated', mockListener2);
|
||||
|
||||
});
|
||||
|
||||
it("initializes with a telemetry objectId as string", function () {
|
||||
telemetryCriterion.initialize(testTelemetryObject);
|
||||
expect(telemetryCriterion.telemetryObjectIdAsString).toEqual(testTelemetryObject.identifier.key);
|
||||
expect(mockListener2).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("subscribes to telemetry providers", function () {
|
||||
telemetryCriterion.subscribe();
|
||||
expect(telemetryCriterion.subscription).toBeDefined();
|
||||
});
|
||||
|
||||
it("emits update event on new data from telemetry providers", function () {
|
||||
spyOn(telemetryCriterion, 'emitEvent').and.callThrough();
|
||||
telemetryCriterion.handleSubscription({
|
||||
key: 'some-key',
|
||||
source: 'testSource',
|
||||
testSource: 'Hello'
|
||||
});
|
||||
expect(telemetryCriterion.emitEvent).toHaveBeenCalled();
|
||||
expect(mockListener).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("un-subscribes from telemetry providers", function () {
|
||||
telemetryCriterion.subscribe();
|
||||
expect(telemetryCriterion.subscription).toBeDefined();
|
||||
telemetryCriterion.destroy();
|
||||
expect(telemetryCriterion.subscription).toBeUndefined();
|
||||
expect(telemetryCriterion.telemetryObjectIdAsString).toBeUndefined();
|
||||
expect(telemetryCriterion.telemetryObject).toBeUndefined();
|
||||
});
|
||||
|
||||
});
|
||||
0
src/plugins/condition/event
Normal file
0
src/plugins/condition/event
Normal file
57
src/plugins/condition/plugin.js
Normal file
57
src/plugins/condition/plugin.js
Normal file
@@ -0,0 +1,57 @@
|
||||
/*****************************************************************************
|
||||
* 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 ConditionSetViewProvider from './ConditionSetViewProvider.js';
|
||||
import ConditionSetCompositionPolicy from "./ConditionSetCompositionPolicy";
|
||||
|
||||
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',
|
||||
key: 'conditionSet',
|
||||
description: 'A set of one or more conditions based on user-specified criteria.',
|
||||
creatable: true,
|
||||
cssClass: 'icon-conditional', // TODO: replace with class for new icon
|
||||
initialize: function (domainObject) {
|
||||
domainObject.configuration = {
|
||||
conditionCollection: []
|
||||
};
|
||||
domainObject.composition = [];
|
||||
}
|
||||
});
|
||||
|
||||
openmct.composition.addPolicy(new ConditionSetCompositionPolicy(openmct).allow);
|
||||
|
||||
openmct.objectViews.addProvider(new ConditionSetViewProvider(openmct));
|
||||
|
||||
}
|
||||
}
|
||||
128
src/plugins/condition/pluginSpec.js
Normal file
128
src/plugins/condition/pluginSpec.js
Normal file
@@ -0,0 +1,128 @@
|
||||
/*****************************************************************************
|
||||
* 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 { createOpenMct } from "testTools";
|
||||
import ConditionPlugin from "./plugin";
|
||||
|
||||
let openmct = createOpenMct();
|
||||
openmct.install(new ConditionPlugin());
|
||||
|
||||
let conditionDefinition;
|
||||
let conditionSetDefinition;
|
||||
let mockDomainObject;
|
||||
let mockDomainObject2;
|
||||
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');
|
||||
appHolder.style.width = '640px';
|
||||
appHolder.style.height = '480px';
|
||||
|
||||
element = document.createElement('div');
|
||||
child = document.createElement('div');
|
||||
element.appendChild(child);
|
||||
|
||||
mockDomainObject2 = {
|
||||
identifier: {
|
||||
key: 'testConditionSetKey',
|
||||
namespace: ''
|
||||
},
|
||||
type: 'conditionSet'
|
||||
};
|
||||
|
||||
conditionSetDefinition.initialize(mockDomainObject2);
|
||||
|
||||
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',
|
||||
creatable: true
|
||||
};
|
||||
|
||||
it('defines a conditionSet object type with the correct key', () => {
|
||||
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', () => {
|
||||
expect(conditionSetDefinition.creatable).toEqual(mockConditionSetObject.creatable);
|
||||
});
|
||||
|
||||
it('initializes with an empty composition list', () => {
|
||||
expect(mockDomainObject2.composition instanceof Array).toBeTrue();
|
||||
expect(mockDomainObject2.composition.length).toEqual(0);
|
||||
});
|
||||
|
||||
it('provides a view', () => {
|
||||
const testViewObject = {
|
||||
id:"test-object",
|
||||
type: "conditionSet"
|
||||
};
|
||||
|
||||
const applicableViews = openmct.objectViews.get(testViewObject);
|
||||
let conditionSetView = applicableViews.find((viewProvider) => viewProvider.key === 'conditionSet.view');
|
||||
expect(conditionSetView).toBeDefined();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
4
src/plugins/condition/utils/constants.js
Normal file
4
src/plugins/condition/utils/constants.js
Normal file
@@ -0,0 +1,4 @@
|
||||
export const TRIGGER = {
|
||||
ANY: 'any',
|
||||
ALL: 'all'
|
||||
};
|
||||
16
src/plugins/condition/utils/evaluator.js
Normal file
16
src/plugins/condition/utils/evaluator.js
Normal file
@@ -0,0 +1,16 @@
|
||||
export const computeCondition = (resultMap, allMustBeTrue) => {
|
||||
let result = false;
|
||||
for (let key in resultMap) {
|
||||
if (resultMap.hasOwnProperty(key)) {
|
||||
result = resultMap[key];
|
||||
if (allMustBeTrue && !result) {
|
||||
//If we want all conditions to be true, then even one negative result should break.
|
||||
break;
|
||||
} else if (!allMustBeTrue && result) {
|
||||
//If we want at least one condition to be true, then even one positive result should break.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
206
src/plugins/condition/utils/operations.js
Normal file
206
src/plugins/condition/utils/operations.js
Normal file
@@ -0,0 +1,206 @@
|
||||
export const OPERATIONS = [
|
||||
{
|
||||
name: 'equalTo',
|
||||
operation: function (input) {
|
||||
return input[0] === input[1];
|
||||
},
|
||||
text: 'is equal to',
|
||||
appliesTo: ['number'],
|
||||
inputCount: 1,
|
||||
getDescription: function (values) {
|
||||
return ' == ' + values[0];
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'notEqualTo',
|
||||
operation: function (input) {
|
||||
return input[0] !== input[1];
|
||||
},
|
||||
text: 'is not equal to',
|
||||
appliesTo: ['number'],
|
||||
inputCount: 1,
|
||||
getDescription: function (values) {
|
||||
return ' != ' + values[0];
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'greaterThan',
|
||||
operation: function (input) {
|
||||
return input[0] > input[1];
|
||||
},
|
||||
text: 'is greater than',
|
||||
appliesTo: ['number'],
|
||||
inputCount: 1,
|
||||
getDescription: function (values) {
|
||||
return ' > ' + values[0];
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'lessThan',
|
||||
operation: function (input) {
|
||||
return input[0] < input[1];
|
||||
},
|
||||
text: 'is less than',
|
||||
appliesTo: ['number'],
|
||||
inputCount: 1,
|
||||
getDescription: function (values) {
|
||||
return ' < ' + values[0];
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'greaterThanOrEq',
|
||||
operation: function (input) {
|
||||
return input[0] >= input[1];
|
||||
},
|
||||
text: 'is greater than or equal to',
|
||||
appliesTo: ['number'],
|
||||
inputCount: 1,
|
||||
getDescription: function (values) {
|
||||
return ' >= ' + values[0];
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'lessThanOrEq',
|
||||
operation: function (input) {
|
||||
return input[0] <= input[1];
|
||||
},
|
||||
text: 'is less than or equal to',
|
||||
appliesTo: ['number'],
|
||||
inputCount: 1,
|
||||
getDescription: function (values) {
|
||||
return ' <= ' + values[0];
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'between',
|
||||
operation: function (input) {
|
||||
return input[0] > input[1] && input[0] < input[2];
|
||||
},
|
||||
text: 'is between',
|
||||
appliesTo: ['number'],
|
||||
inputCount: 2,
|
||||
getDescription: function (values) {
|
||||
return ' between ' + values[0] + ' and ' + values[1];
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'notBetween',
|
||||
operation: function (input) {
|
||||
return input[0] < input[1] || input[0] > input[2];
|
||||
},
|
||||
text: 'is not between',
|
||||
appliesTo: ['number'],
|
||||
inputCount: 2,
|
||||
getDescription: function (values) {
|
||||
return ' not between ' + values[0] + ' and ' + values[1];
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'textContains',
|
||||
operation: function (input) {
|
||||
return input[0] && input[1] && input[0].includes(input[1]);
|
||||
},
|
||||
text: 'text contains',
|
||||
appliesTo: ['string'],
|
||||
inputCount: 1,
|
||||
getDescription: function (values) {
|
||||
return ' contains ' + values[0];
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'textDoesNotContain',
|
||||
operation: function (input) {
|
||||
return input[0] && input[1] && !input[0].includes(input[1]);
|
||||
},
|
||||
text: 'text does not contain',
|
||||
appliesTo: ['string'],
|
||||
inputCount: 1,
|
||||
getDescription: function (values) {
|
||||
return ' does not contain ' + values[0];
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'textStartsWith',
|
||||
operation: function (input) {
|
||||
return input[0].startsWith(input[1]);
|
||||
},
|
||||
text: 'text starts with',
|
||||
appliesTo: ['string'],
|
||||
inputCount: 1,
|
||||
getDescription: function (values) {
|
||||
return ' starts with ' + values[0];
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'textEndsWith',
|
||||
operation: function (input) {
|
||||
return input[0].endsWith(input[1]);
|
||||
},
|
||||
text: 'text ends with',
|
||||
appliesTo: ['string'],
|
||||
inputCount: 1,
|
||||
getDescription: function (values) {
|
||||
return ' ends with ' + values[0];
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'textIsExactly',
|
||||
operation: function (input) {
|
||||
return input[0] === input[1];
|
||||
},
|
||||
text: 'text is exactly',
|
||||
appliesTo: ['string'],
|
||||
inputCount: 1,
|
||||
getDescription: function (values) {
|
||||
return ' is exactly ' + values[0];
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'isUndefined',
|
||||
operation: function (input) {
|
||||
return typeof input[0] === 'undefined';
|
||||
},
|
||||
text: 'is undefined',
|
||||
appliesTo: ['string', 'number', 'enum'],
|
||||
inputCount: 0,
|
||||
getDescription: function () {
|
||||
return ' is undefined';
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'isDefined',
|
||||
operation: function (input) {
|
||||
return typeof input[0] !== 'undefined';
|
||||
},
|
||||
text: 'is defined',
|
||||
appliesTo: ['string', 'number', 'enum'],
|
||||
inputCount: 0,
|
||||
getDescription: function () {
|
||||
return ' is defined';
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'enumValueIs',
|
||||
operation: function (input) {
|
||||
return input[0] === input[1];
|
||||
},
|
||||
text: 'is',
|
||||
appliesTo: ['enum'],
|
||||
inputCount: 1,
|
||||
getDescription: function (values) {
|
||||
return ' == ' + values[0];
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'enumValueIsNot',
|
||||
operation: function (input) {
|
||||
return input[0] !== input[1];
|
||||
},
|
||||
text: 'is not',
|
||||
appliesTo: ['enum'],
|
||||
inputCount: 1,
|
||||
getDescription: function (values) {
|
||||
return ' != ' + values[0];
|
||||
}
|
||||
}
|
||||
];
|
||||
@@ -1,5 +1,5 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* Open MCT, Copyright (c) 2014-2019, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
@@ -47,6 +47,7 @@ define([
|
||||
'./goToOriginalAction/plugin',
|
||||
'./clearData/plugin',
|
||||
'./webPage/plugin',
|
||||
'./condition/plugin',
|
||||
'./themes/espresso',
|
||||
'./themes/maelstrom',
|
||||
'./themes/snow'
|
||||
@@ -77,6 +78,7 @@ define([
|
||||
GoToOriginalAction,
|
||||
ClearData,
|
||||
WebPagePlugin,
|
||||
ConditionPlugin,
|
||||
Espresso,
|
||||
Maelstrom,
|
||||
Snow
|
||||
@@ -185,6 +187,7 @@ define([
|
||||
plugins.Espresso = Espresso.default;
|
||||
plugins.Maelstrom = Maelstrom.default;
|
||||
plugins.Snow = Snow.default;
|
||||
plugins.Condition = ConditionPlugin.default;
|
||||
|
||||
return plugins;
|
||||
});
|
||||
|
||||
3
src/styles/_constants.scss
Normal file → Executable file
3
src/styles/_constants.scss
Normal file → Executable file
@@ -147,6 +147,7 @@ $glyph-icon-filter: '\e926';
|
||||
$glyph-icon-filter-outline: '\e927';
|
||||
$glyph-icon-suitcase: '\e928';
|
||||
$glyph-icon-cursor-lock: '\e929';
|
||||
$glyph-icon-flag: '\e92a';
|
||||
$glyph-icon-arrows-right-left: '\ea00';
|
||||
$glyph-icon-arrows-up-down: '\ea01';
|
||||
$glyph-icon-bullet: '\ea02';
|
||||
@@ -236,6 +237,7 @@ $glyph-icon-gauge: '\eb23';
|
||||
$glyph-icon-spectra: '\eb24';
|
||||
$glyph-icon-spectra-telemetry: '\eb25';
|
||||
$glyph-icon-command: '\eb26';
|
||||
$glyph-icon-conditional: '\eb27';
|
||||
|
||||
/************************** GLYPHS AS DATA URI */
|
||||
// Only objects have been converted, for use in Create menu and folder views
|
||||
@@ -285,3 +287,4 @@ $bg-icon-gauge: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w
|
||||
$bg-icon-spectra: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M384 352H128l51.2-89.6L0 288v127c0 53.3 43.7 97 97 97h318c53.4 0 97-43.7 97-97v-31l-162.9-93.1zM415 0H97C43.7 0 0 43.6 0 97v159l200-30.1 56-97.9 54.9 96H512V97a97.2 97.2 0 00-97-97zM512 320v-32l-192-32 192 64z'/%3e%3c/svg%3e");
|
||||
$bg-icon-spectra-telemetry: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M256 128l54.9 96H510C494.3 97.7 386.5 0 256 0 114.6 0 0 114.6 0 256l200-30.1zM384 352H128l51.2-89.6L2 287.7C17.6 414.1 125.4 512 256 512c100.8 0 188-58.3 229.8-143l-136.7-78.1zM320 256l192 64v-32l-192-32z'/%3e%3c/svg%3e");
|
||||
$bg-icon-command: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M185.1 229.7a96.5 96.5 0 0015.8 11.7A68.5 68.5 0 01192 208c0-19.8 8.9-38.8 25.1-53.7 18.5-17 43.7-26.3 70.9-26.3 20.1 0 39.1 5.1 55.1 14.6a81.3 81.3 0 00-16.2-20.3C308.4 105.3 283.2 96 256 96s-52.4 9.3-70.9 26.3C168.9 137.2 160 156.2 160 176s8.9 38.8 25.1 53.7z'/%3e%3cpath d='M442.7 134.8C422.4 57.5 346.5 0 256 0S89.6 57.5 69.3 134.8C26.3 174.8 0 228.7 0 288c0 123.7 114.6 224 256 224s256-100.3 256-224c0-59.3-26.3-113.2-69.3-153.2zM256 64c70.6 0 128 50.2 128 112s-57.4 112-128 112-128-50.2-128-112S185.4 64 256 64zm0 352c-87.7 0-159.2-63.9-160-142.7 34.4 47.4 93.2 78.7 160 78.7s125.6-31.3 160-78.7c-.8 78.8-72.3 142.7-160 142.7z'/%3e%3c/svg%3e");
|
||||
$bg-icon-conditional: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath d='M256 0C114.62 0 0 114.62 0 256s114.62 256 256 256 256-114.62 256-256S397.38 0 256 0zm0 384L64 256l192-128 192 128z' fill='%23000000'/%3e%3c/svg%3e");
|
||||
|
||||
3
src/styles/_glyphs.scss
Normal file → Executable file
3
src/styles/_glyphs.scss
Normal file → Executable file
@@ -81,6 +81,7 @@
|
||||
.icon-filter-outline { @include glyphBefore($glyph-icon-filter-outline); }
|
||||
.icon-suitcase { @include glyphBefore($glyph-icon-suitcase); }
|
||||
.icon-cursor-lock { @include glyphBefore($glyph-icon-cursor-lock); }
|
||||
.icon-flag { @include glyphBefore($glyph-icon-flag); }
|
||||
.icon-arrows-right-left { @include glyphBefore($glyph-icon-arrows-right-left); }
|
||||
.icon-arrows-up-down { @include glyphBefore($glyph-icon-arrows-up-down); }
|
||||
.icon-bullet { @include glyphBefore($glyph-icon-bullet); }
|
||||
@@ -170,6 +171,7 @@
|
||||
.icon-spectra { @include glyphBefore($glyph-icon-spectra); }
|
||||
.icon-spectra-telemetry { @include glyphBefore($glyph-icon-spectra-telemetry); }
|
||||
.icon-command { @include glyphBefore($glyph-icon-command); }
|
||||
.icon-conditional { @include glyphBefore($glyph-icon-conditional); }
|
||||
|
||||
/************************** 12 PX CLASSES */
|
||||
// TODO: sync with 16px redo as of 10/25/18
|
||||
@@ -227,3 +229,4 @@
|
||||
.bg-icon-spectra { @include glyphBg($bg-icon-spectra); }
|
||||
.bg-icon-spectra-telemetry { @include glyphBg($bg-icon-spectra-telemetry); }
|
||||
.bg-icon-command { @include glyphBg($bg-icon-command); }
|
||||
.bg-icon-conditional { @include glyphBg($bg-icon-conditional); }
|
||||
|
||||
0
src/styles/fonts/Open MCT Symbols 12px.json
Normal file → Executable file
0
src/styles/fonts/Open MCT Symbols 12px.json
Normal file → Executable file
226
src/styles/fonts/Open MCT Symbols 16px.json
Normal file → Executable file
226
src/styles/fonts/Open MCT Symbols 16px.json
Normal file → Executable file
@@ -2,7 +2,7 @@
|
||||
"metadata": {
|
||||
"name": "Open MCT Symbols 16px",
|
||||
"lastOpened": 0,
|
||||
"created": 1574106570211
|
||||
"created": 1581619121103
|
||||
},
|
||||
"iconSets": [
|
||||
{
|
||||
@@ -343,13 +343,21 @@
|
||||
"code": 59689,
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 176,
|
||||
"id": 150,
|
||||
"name": "icon-flag",
|
||||
"prevSize": 24,
|
||||
"code": 59690,
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 27,
|
||||
"id": 105,
|
||||
"name": "icon-arrows-right-left",
|
||||
"prevSize": 24,
|
||||
"code": 59904,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 26,
|
||||
@@ -357,7 +365,7 @@
|
||||
"name": "icon-arrows-up-down",
|
||||
"prevSize": 24,
|
||||
"code": 59905,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 68,
|
||||
@@ -365,7 +373,7 @@
|
||||
"name": "icon-bullet",
|
||||
"prevSize": 24,
|
||||
"code": 59906,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 150,
|
||||
@@ -373,7 +381,7 @@
|
||||
"prevSize": 24,
|
||||
"code": 59907,
|
||||
"name": "icon-calendar",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 45,
|
||||
@@ -381,7 +389,7 @@
|
||||
"name": "icon-chain-links",
|
||||
"prevSize": 24,
|
||||
"code": 59908,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 73,
|
||||
@@ -389,7 +397,7 @@
|
||||
"name": "icon-download",
|
||||
"prevSize": 24,
|
||||
"code": 59909,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 39,
|
||||
@@ -397,7 +405,7 @@
|
||||
"name": "icon-duplicate",
|
||||
"prevSize": 24,
|
||||
"code": 59910,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 50,
|
||||
@@ -405,7 +413,7 @@
|
||||
"name": "icon-folder-new",
|
||||
"prevSize": 24,
|
||||
"code": 59911,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 138,
|
||||
@@ -413,7 +421,7 @@
|
||||
"name": "icon-fullscreen-collapse",
|
||||
"prevSize": 24,
|
||||
"code": 59912,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 139,
|
||||
@@ -421,7 +429,7 @@
|
||||
"name": "icon-fullscreen-expand",
|
||||
"prevSize": 24,
|
||||
"code": 59913,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 122,
|
||||
@@ -429,7 +437,7 @@
|
||||
"name": "icon-layers",
|
||||
"prevSize": 24,
|
||||
"code": 59914,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 151,
|
||||
@@ -437,7 +445,7 @@
|
||||
"name": "icon-line-horz",
|
||||
"prevSize": 24,
|
||||
"code": 59915,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 100,
|
||||
@@ -445,7 +453,7 @@
|
||||
"name": "icon-magnify",
|
||||
"prevSize": 24,
|
||||
"code": 59916,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 99,
|
||||
@@ -453,7 +461,7 @@
|
||||
"name": "icon-magnify-in",
|
||||
"prevSize": 24,
|
||||
"code": 59917,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 101,
|
||||
@@ -461,7 +469,7 @@
|
||||
"name": "icon-magnify-out-v2",
|
||||
"prevSize": 24,
|
||||
"code": 59918,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 103,
|
||||
@@ -469,7 +477,7 @@
|
||||
"name": "icon-menu",
|
||||
"prevSize": 24,
|
||||
"code": 59919,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 124,
|
||||
@@ -477,7 +485,7 @@
|
||||
"name": "icon-move",
|
||||
"prevSize": 24,
|
||||
"code": 59920,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 7,
|
||||
@@ -485,7 +493,7 @@
|
||||
"name": "icon-new-window",
|
||||
"prevSize": 24,
|
||||
"code": 59921,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 63,
|
||||
@@ -493,7 +501,7 @@
|
||||
"name": "icon-paint-bucket-v2",
|
||||
"prevSize": 24,
|
||||
"code": 59922,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 15,
|
||||
@@ -501,7 +509,7 @@
|
||||
"name": "icon-pencil",
|
||||
"prevSize": 24,
|
||||
"code": 59923,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 54,
|
||||
@@ -509,7 +517,7 @@
|
||||
"name": "icon-pencil-edit-in-place",
|
||||
"prevSize": 24,
|
||||
"code": 59924,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 40,
|
||||
@@ -517,7 +525,7 @@
|
||||
"name": "icon-play",
|
||||
"prevSize": 24,
|
||||
"code": 59925,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 125,
|
||||
@@ -525,7 +533,7 @@
|
||||
"name": "icon-pause",
|
||||
"prevSize": 24,
|
||||
"code": 59926,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 119,
|
||||
@@ -533,7 +541,7 @@
|
||||
"name": "icon-plot-resource",
|
||||
"prevSize": 24,
|
||||
"code": 59927,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 48,
|
||||
@@ -541,7 +549,7 @@
|
||||
"name": "icon-pointer-left",
|
||||
"prevSize": 24,
|
||||
"code": 59928,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 47,
|
||||
@@ -549,7 +557,7 @@
|
||||
"name": "icon-pointer-right",
|
||||
"prevSize": 24,
|
||||
"code": 59929,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 85,
|
||||
@@ -557,7 +565,7 @@
|
||||
"name": "icon-refresh",
|
||||
"prevSize": 24,
|
||||
"code": 59930,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 55,
|
||||
@@ -565,7 +573,7 @@
|
||||
"name": "icon-save",
|
||||
"prevSize": 24,
|
||||
"code": 59931,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 56,
|
||||
@@ -573,7 +581,7 @@
|
||||
"name": "icon-save-as",
|
||||
"prevSize": 24,
|
||||
"code": 59932,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 58,
|
||||
@@ -581,7 +589,7 @@
|
||||
"name": "icon-sine",
|
||||
"prevSize": 24,
|
||||
"code": 59933,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 113,
|
||||
@@ -589,7 +597,7 @@
|
||||
"name": "icon-font",
|
||||
"prevSize": 24,
|
||||
"code": 59934,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 41,
|
||||
@@ -597,7 +605,7 @@
|
||||
"name": "icon-thumbs-strip",
|
||||
"prevSize": 24,
|
||||
"code": 59935,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 146,
|
||||
@@ -605,7 +613,7 @@
|
||||
"name": "icon-two-parts-both",
|
||||
"prevSize": 24,
|
||||
"code": 59936,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 145,
|
||||
@@ -613,7 +621,7 @@
|
||||
"name": "icon-two-parts-one-only",
|
||||
"prevSize": 24,
|
||||
"code": 59937,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 82,
|
||||
@@ -621,7 +629,7 @@
|
||||
"name": "icon-resync",
|
||||
"prevSize": 24,
|
||||
"code": 59938,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 86,
|
||||
@@ -629,7 +637,7 @@
|
||||
"name": "icon-reset",
|
||||
"prevSize": 24,
|
||||
"code": 59939,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 61,
|
||||
@@ -637,7 +645,7 @@
|
||||
"name": "icon-x-in-circle",
|
||||
"prevSize": 24,
|
||||
"code": 59940,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 84,
|
||||
@@ -645,7 +653,7 @@
|
||||
"name": "icon-brightness",
|
||||
"prevSize": 24,
|
||||
"code": 59941,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 83,
|
||||
@@ -653,7 +661,7 @@
|
||||
"name": "icon-contrast",
|
||||
"prevSize": 24,
|
||||
"code": 59942,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 87,
|
||||
@@ -661,7 +669,7 @@
|
||||
"name": "icon-expand",
|
||||
"prevSize": 24,
|
||||
"code": 59943,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 89,
|
||||
@@ -669,7 +677,7 @@
|
||||
"name": "icon-list-view",
|
||||
"prevSize": 24,
|
||||
"code": 59944,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 133,
|
||||
@@ -677,7 +685,7 @@
|
||||
"name": "icon-grid-snap-to",
|
||||
"prevSize": 24,
|
||||
"code": 59945,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 132,
|
||||
@@ -685,7 +693,7 @@
|
||||
"name": "icon-grid-snap-no",
|
||||
"prevSize": 24,
|
||||
"code": 59946,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 94,
|
||||
@@ -693,7 +701,7 @@
|
||||
"name": "icon-frame-show",
|
||||
"prevSize": 24,
|
||||
"code": 59947,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 95,
|
||||
@@ -701,7 +709,7 @@
|
||||
"name": "icon-frame-hide",
|
||||
"prevSize": 24,
|
||||
"code": 59948,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 97,
|
||||
@@ -709,7 +717,7 @@
|
||||
"name": "icon-import",
|
||||
"prevSize": 24,
|
||||
"code": 59949,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 96,
|
||||
@@ -717,7 +725,7 @@
|
||||
"name": "icon-export",
|
||||
"prevSize": 24,
|
||||
"code": 59950,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 114,
|
||||
@@ -725,7 +733,7 @@
|
||||
"name": "icon-font-size",
|
||||
"prevSize": 24,
|
||||
"code": 59951,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 163,
|
||||
@@ -733,7 +741,7 @@
|
||||
"name": "icon-clear-data",
|
||||
"prevSize": 24,
|
||||
"code": 59952,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 173,
|
||||
@@ -741,7 +749,7 @@
|
||||
"name": "icon-history",
|
||||
"prevSize": 24,
|
||||
"code": 59953,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 144,
|
||||
@@ -749,7 +757,7 @@
|
||||
"name": "icon-activity",
|
||||
"prevSize": 24,
|
||||
"code": 60160,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 104,
|
||||
@@ -757,7 +765,7 @@
|
||||
"name": "icon-activity-mode",
|
||||
"prevSize": 24,
|
||||
"code": 60161,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 137,
|
||||
@@ -765,7 +773,7 @@
|
||||
"name": "icon-autoflow-tabular",
|
||||
"prevSize": 24,
|
||||
"code": 60162,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 115,
|
||||
@@ -773,7 +781,7 @@
|
||||
"name": "icon-clock",
|
||||
"prevSize": 24,
|
||||
"code": 60163,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 2,
|
||||
@@ -781,7 +789,7 @@
|
||||
"name": "icon-database",
|
||||
"prevSize": 24,
|
||||
"code": 60164,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 3,
|
||||
@@ -789,7 +797,7 @@
|
||||
"name": "icon-database-query",
|
||||
"prevSize": 24,
|
||||
"code": 60165,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 67,
|
||||
@@ -797,7 +805,7 @@
|
||||
"name": "icon-dataset",
|
||||
"prevSize": 24,
|
||||
"code": 60166,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 59,
|
||||
@@ -805,7 +813,7 @@
|
||||
"name": "icon-datatable",
|
||||
"prevSize": 24,
|
||||
"code": 60167,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 136,
|
||||
@@ -813,7 +821,7 @@
|
||||
"name": "icon-dictionary",
|
||||
"prevSize": 24,
|
||||
"code": 60168,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 51,
|
||||
@@ -821,7 +829,7 @@
|
||||
"name": "icon-folder",
|
||||
"prevSize": 24,
|
||||
"code": 60169,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 147,
|
||||
@@ -829,7 +837,7 @@
|
||||
"name": "icon-image",
|
||||
"prevSize": 24,
|
||||
"code": 60170,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 4,
|
||||
@@ -837,7 +845,7 @@
|
||||
"name": "icon-layout",
|
||||
"prevSize": 24,
|
||||
"code": 60171,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 24,
|
||||
@@ -845,7 +853,7 @@
|
||||
"name": "icon-object",
|
||||
"prevSize": 24,
|
||||
"code": 60172,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 52,
|
||||
@@ -853,7 +861,7 @@
|
||||
"name": "icon-object-unknown",
|
||||
"prevSize": 24,
|
||||
"code": 60173,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 105,
|
||||
@@ -861,7 +869,7 @@
|
||||
"name": "icon-packet",
|
||||
"prevSize": 24,
|
||||
"code": 60174,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 126,
|
||||
@@ -869,7 +877,7 @@
|
||||
"name": "icon-page",
|
||||
"prevSize": 24,
|
||||
"code": 60175,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 130,
|
||||
@@ -877,7 +885,7 @@
|
||||
"name": "icon-plot-overlay",
|
||||
"prevSize": 24,
|
||||
"code": 60176,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 80,
|
||||
@@ -885,7 +893,7 @@
|
||||
"name": "icon-plot-stacked",
|
||||
"prevSize": 24,
|
||||
"code": 60177,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 134,
|
||||
@@ -893,7 +901,7 @@
|
||||
"name": "icon-session",
|
||||
"prevSize": 24,
|
||||
"code": 60178,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 109,
|
||||
@@ -901,7 +909,7 @@
|
||||
"name": "icon-tabular",
|
||||
"prevSize": 24,
|
||||
"code": 60179,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 107,
|
||||
@@ -909,7 +917,7 @@
|
||||
"name": "icon-tabular-lad",
|
||||
"prevSize": 24,
|
||||
"code": 60180,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 106,
|
||||
@@ -917,7 +925,7 @@
|
||||
"name": "icon-tabular-lad-set",
|
||||
"prevSize": 24,
|
||||
"code": 60181,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 70,
|
||||
@@ -925,7 +933,7 @@
|
||||
"name": "icon-tabular-realtime",
|
||||
"prevSize": 24,
|
||||
"code": 60182,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 60,
|
||||
@@ -933,7 +941,7 @@
|
||||
"name": "icon-tabular-scrolling",
|
||||
"prevSize": 24,
|
||||
"code": 60183,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 131,
|
||||
@@ -941,7 +949,7 @@
|
||||
"name": "icon-telemetry",
|
||||
"prevSize": 24,
|
||||
"code": 60184,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 108,
|
||||
@@ -949,7 +957,7 @@
|
||||
"name": "icon-timeline",
|
||||
"prevSize": 24,
|
||||
"code": 60185,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 81,
|
||||
@@ -957,7 +965,7 @@
|
||||
"name": "icon-timer",
|
||||
"prevSize": 24,
|
||||
"code": 60186,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 69,
|
||||
@@ -965,7 +973,7 @@
|
||||
"name": "icon-topic",
|
||||
"prevSize": 24,
|
||||
"code": 60187,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 79,
|
||||
@@ -973,7 +981,7 @@
|
||||
"name": "icon-box-with-dashed-lines-v2",
|
||||
"prevSize": 24,
|
||||
"code": 60188,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 90,
|
||||
@@ -981,7 +989,7 @@
|
||||
"name": "icon-summary-widget",
|
||||
"prevSize": 24,
|
||||
"code": 60189,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 92,
|
||||
@@ -989,7 +997,7 @@
|
||||
"name": "icon-notebook",
|
||||
"prevSize": 24,
|
||||
"code": 60190,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 168,
|
||||
@@ -997,7 +1005,7 @@
|
||||
"name": "icon-tabs-view",
|
||||
"prevSize": 24,
|
||||
"code": 60191,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 117,
|
||||
@@ -1005,7 +1013,7 @@
|
||||
"name": "icon-flexible-layout",
|
||||
"prevSize": 24,
|
||||
"code": 60192,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 166,
|
||||
@@ -1013,7 +1021,7 @@
|
||||
"name": "icon-generator-sine",
|
||||
"prevSize": 24,
|
||||
"code": 60193,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 167,
|
||||
@@ -1021,7 +1029,7 @@
|
||||
"name": "icon-generator-event",
|
||||
"prevSize": 24,
|
||||
"code": 60194,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 165,
|
||||
@@ -1029,7 +1037,7 @@
|
||||
"name": "icon-gauge-v2",
|
||||
"prevSize": 24,
|
||||
"code": 60195,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 170,
|
||||
@@ -1037,7 +1045,7 @@
|
||||
"name": "icon-spectra",
|
||||
"prevSize": 24,
|
||||
"code": 60196,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 171,
|
||||
@@ -1045,7 +1053,7 @@
|
||||
"name": "icon-telemetry-spectra",
|
||||
"prevSize": 24,
|
||||
"code": 60197,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 172,
|
||||
@@ -1053,7 +1061,15 @@
|
||||
"name": "icon-pushbutton",
|
||||
"prevSize": 24,
|
||||
"code": 60198,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 174,
|
||||
"id": 151,
|
||||
"name": "icon-conditional",
|
||||
"prevSize": 24,
|
||||
"code": 60199,
|
||||
"tempChar": ""
|
||||
}
|
||||
],
|
||||
"id": 0,
|
||||
@@ -1613,6 +1629,21 @@
|
||||
"icon-cursor-locked"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 150,
|
||||
"paths": [
|
||||
"M192 640h832l-192-320 192-320h-896c-70.606 0.215-127.785 57.394-128 127.979l-0 0.021v896h192z"
|
||||
],
|
||||
"attrs": [
|
||||
{}
|
||||
],
|
||||
"grid": 16,
|
||||
"tags": [
|
||||
"icon-flag"
|
||||
],
|
||||
"isMulticolor": false,
|
||||
"isMulticolor2": false
|
||||
},
|
||||
{
|
||||
"id": 105,
|
||||
"paths": [
|
||||
@@ -2771,6 +2802,21 @@
|
||||
"tags": [
|
||||
"icon-pushbutton"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 151,
|
||||
"paths": [
|
||||
"M512 0c-282.76 0-512 229.24-512 512s229.24 512 512 512 512-229.24 512-512-229.24-512-512-512zM512 768l-384-256 384-256 384 256z"
|
||||
],
|
||||
"attrs": [
|
||||
{}
|
||||
],
|
||||
"isMulticolor": false,
|
||||
"isMulticolor2": false,
|
||||
"grid": 16,
|
||||
"tags": [
|
||||
"icon-conditional"
|
||||
]
|
||||
}
|
||||
],
|
||||
"invisible": false,
|
||||
|
||||
0
src/styles/fonts/Open-MCT-Symbols-12px.ttf
Normal file → Executable file
0
src/styles/fonts/Open-MCT-Symbols-12px.ttf
Normal file → Executable file
0
src/styles/fonts/Open-MCT-Symbols-12px.woff
Normal file → Executable file
0
src/styles/fonts/Open-MCT-Symbols-12px.woff
Normal file → Executable file
@@ -49,6 +49,7 @@
|
||||
<glyph unicode="" glyph-name="icon-filter-outline" d="M896 832h-768c-70.601-0.227-127.773-57.399-128-127.978v-768.022c0.227-70.601 57.399-127.773 127.978-128h768.022c70.601 0.227 127.773 57.399 128 127.978v768.022c-0.227 70.601-57.399 127.773-127.978 128h-0.022zM896-63.8h-256v383.8l192 192h-640l192-192v-384h-256v767.8h768z" />
|
||||
<glyph unicode="" glyph-name="icon-suitcase" d="M768 704c-0.080 70.66-57.34 127.92-127.993 128h-256.007c-70.66-0.080-127.92-57.34-128-127.993v-128.007h-64v-768h640v768h-64zM384 703.88l0.12 0.12 255.88-0.12v-127.88h-256zM0 512v-640c0.102-35.305 28.695-63.898 63.99-64h64.010v768h-64c-35.305-0.102-63.898-28.695-64-63.99v-0.010zM960 576h-64v-768h64c35.305 0.102 63.898 28.695 64 63.99v640.010c-0.102 35.305-28.695 63.898-63.99 64h-0.010z" />
|
||||
<glyph unicode="" glyph-name="icon-cursor-locked" horiz-adv-x="768" d="M704 512h-64v64c0 141.385-114.615 256-256 256s-256-114.615-256-256v0-64h-64c-35.301-0.113-63.887-28.699-64-63.989v-576.011c0.113-35.301 28.699-63.887 63.989-64h640.011c35.301 0.113 63.887 28.699 64 63.989v576.011c-0.113 35.301-28.699 63.887-63.989 64h-0.011zM256 576c0 70.692 57.308 128 128 128s128-57.308 128-128v0-64h-256zM533.4-64l-128 128-43-85-170.4 383.6 383.6-170.2-85-43 128-128z" />
|
||||
<glyph unicode="" glyph-name="icon-flag" d="M192 192h832l-192 320 192 320h-896c-70.606-0.215-127.785-57.394-128-127.979v-896.021h192z" />
|
||||
<glyph unicode="" glyph-name="icon-arrows-right-left" d="M1024 320l-448-512v1024zM448 832l-448-512 448-512z" />
|
||||
<glyph unicode="" glyph-name="icon-arrows-up-down" d="M512 832l512-448h-1024zM0 256l512-448 512 448z" />
|
||||
<glyph unicode="" glyph-name="icon-bullet" d="M832 80c0-44-36-80-80-80h-480c-44 0-80 36-80 80v480c0 44 36 80 80 80h480c44 0 80-36 80-80v-480z" />
|
||||
@@ -138,4 +139,5 @@
|
||||
<glyph unicode="" glyph-name="icon-spectra" d="M768 128h-512l102.4 179.2-358.4-51.2v-254c0-106.6 87.4-194 194-194h636c106.8 0 194 87.4 194 194v62l-325.8 186.2zM830 832h-636c-106.6 0-194-87.2-194-194v-318l400 60.2 112 195.8 109.8-192h402.2v254c-0.227 107.052-86.948 193.773-193.978 194h-0.022zM1024 192v64l-384 64 384-128z" />
|
||||
<glyph unicode="" glyph-name="icon-telemetry-spectra" d="M512 576l109.8-192h398.2c-31.4 252.6-247 448-508 448-282.8 0-512-229.2-512-512l400 60.2zM768 128h-512l102.4 179.2-354.4-50.6c31.2-252.8 246.8-448.6 508-448.6 201.6 0 376 116.6 459.6 286l-273.4 156.2zM640 320l384-128v64l-384 64z" />
|
||||
<glyph unicode="" glyph-name="icon-pushbutton" d="M370.2 372.6c9.326-8.53 19.666-16.261 30.729-22.914l0.871-0.486c-11.077 19.209-17.664 42.221-17.8 66.76v0.040c0 39.6 17.8 77.6 50.2 107.4 37 34 87.4 52.6 141.8 52.6 40.2 0 78.2-10.2 110.2-29.2-8.918 15.653-19.693 29.040-32.268 40.482l-0.132 0.118c-37 34-87.4 52.6-141.8 52.6s-104.8-18.6-141.8-52.6c-32.4-29.8-50.2-67.8-50.2-107.4s17.8-77.6 50.2-107.4zM885.4 562.4c-40.6 154.6-192.4 269.6-373.4 269.6s-332.8-115-373.4-269.6c-86-80-138.6-187.8-138.6-306.4 0-247.4 229.2-448 512-448s512 200.6 512 448c0 118.6-52.6 226.4-138.6 306.4zM512 704c141.2 0 256-100.4 256-224s-114.8-224-256-224-256 100.4-256 224 114.8 224 256 224zM512 0c-175.4 0-318.4 127.8-320 285.4 68.8-94.8 186.4-157.4 320-157.4s251.2 62.6 320 157.4c-1.6-157.6-144.6-285.4-320-285.4z" />
|
||||
<glyph unicode="" glyph-name="icon-conditional" d="M512 832c-282.76 0-512-229.24-512-512s229.24-512 512-512 512 229.24 512 512-229.24 512-512 512zM512 64l-384 256 384 256 384-256z" />
|
||||
</font></defs></svg>
|
||||
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 51 KiB |
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,7 @@
|
||||
@import "../api/overlays/components/dialog-component.scss";
|
||||
@import "../api/overlays/components/overlay-component.scss";
|
||||
@import "../plugins/condition/components/condition.scss";
|
||||
@import "../plugins/condition/components/condition-set.scss";
|
||||
@import "../plugins/displayLayout/components/box-view.scss";
|
||||
@import "../plugins/displayLayout/components/display-layout.scss";
|
||||
@import "../plugins/displayLayout/components/edit-marquee.scss";
|
||||
|
||||
Reference in New Issue
Block a user