mirror of
https://github.com/nasa/openmct.git
synced 2025-02-24 10:45:02 +00:00
resolved merge conflicts
This commit is contained in:
commit
829eecf1ae
@ -31,6 +31,7 @@ define([
|
|||||||
period: 10,
|
period: 10,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
dataRateInHz: 1,
|
dataRateInHz: 1,
|
||||||
|
randomness: 0,
|
||||||
phase: 0
|
phase: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -52,7 +53,8 @@ define([
|
|||||||
'period',
|
'period',
|
||||||
'offset',
|
'offset',
|
||||||
'dataRateInHz',
|
'dataRateInHz',
|
||||||
'phase'
|
'phase',
|
||||||
|
'randomness'
|
||||||
];
|
];
|
||||||
|
|
||||||
request = request || {};
|
request = request || {};
|
||||||
|
@ -65,8 +65,8 @@
|
|||||||
name: data.name,
|
name: data.name,
|
||||||
utc: nextStep,
|
utc: nextStep,
|
||||||
yesterday: nextStep - 60*60*24*1000,
|
yesterday: nextStep - 60*60*24*1000,
|
||||||
sin: sin(nextStep, data.period, data.amplitude, data.offset, data.phase),
|
sin: sin(nextStep, data.period, data.amplitude, data.offset, data.phase, data.randomness),
|
||||||
cos: cos(nextStep, data.period, data.amplitude, data.offset, data.phase)
|
cos: cos(nextStep, data.period, data.amplitude, data.offset, data.phase, data.randomness)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
nextStep += step;
|
nextStep += step;
|
||||||
@ -99,6 +99,7 @@
|
|||||||
var offset = request.offset;
|
var offset = request.offset;
|
||||||
var dataRateInHz = request.dataRateInHz;
|
var dataRateInHz = request.dataRateInHz;
|
||||||
var phase = request.phase;
|
var phase = request.phase;
|
||||||
|
var randomness = request.randomness;
|
||||||
|
|
||||||
var step = 1000 / dataRateInHz;
|
var step = 1000 / dataRateInHz;
|
||||||
var nextStep = start - (start % step) + step;
|
var nextStep = start - (start % step) + step;
|
||||||
@ -110,8 +111,8 @@
|
|||||||
name: request.name,
|
name: request.name,
|
||||||
utc: nextStep,
|
utc: nextStep,
|
||||||
yesterday: nextStep - 60*60*24*1000,
|
yesterday: nextStep - 60*60*24*1000,
|
||||||
sin: sin(nextStep, period, amplitude, offset, phase),
|
sin: sin(nextStep, period, amplitude, offset, phase, randomness),
|
||||||
cos: cos(nextStep, period, amplitude, offset, phase)
|
cos: cos(nextStep, period, amplitude, offset, phase, randomness)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
self.postMessage({
|
self.postMessage({
|
||||||
@ -120,14 +121,14 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function cos(timestamp, period, amplitude, offset, phase) {
|
function cos(timestamp, period, amplitude, offset, phase, randomness) {
|
||||||
return amplitude *
|
return amplitude *
|
||||||
Math.cos(phase + (timestamp / period / 1000 * Math.PI * 2)) + offset;
|
Math.cos(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sin(timestamp, period, amplitude, offset, phase) {
|
function sin(timestamp, period, amplitude, offset, phase, randomness) {
|
||||||
return amplitude *
|
return amplitude *
|
||||||
Math.sin(phase + (timestamp / period / 1000 * Math.PI * 2)) + offset;
|
Math.sin(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendError(error, message) {
|
function sendError(error, message) {
|
||||||
|
@ -122,6 +122,17 @@ define([
|
|||||||
"telemetry",
|
"telemetry",
|
||||||
"phase"
|
"phase"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Randomness",
|
||||||
|
control: "numberfield",
|
||||||
|
cssClass: "l-input-sm l-numeric",
|
||||||
|
key: "randomness",
|
||||||
|
required: true,
|
||||||
|
property: [
|
||||||
|
"telemetry",
|
||||||
|
"randomness"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
initialize: function (object) {
|
initialize: function (object) {
|
||||||
@ -130,7 +141,8 @@ define([
|
|||||||
amplitude: 1,
|
amplitude: 1,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
dataRateInHz: 1,
|
dataRateInHz: 1,
|
||||||
phase: 0
|
phase: 0,
|
||||||
|
randomness: 0
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -48,18 +48,32 @@ export default class ConditionClass extends EventEmitter {
|
|||||||
* @param conditionConfiguration: {id: uuid,trigger: enum, criteria: Array of {id: uuid, operation: enum, input: Array, metaDataKey: string, key: {domainObject.identifier} }
|
* @param conditionConfiguration: {id: uuid,trigger: enum, criteria: Array of {id: uuid, operation: enum, input: Array, metaDataKey: string, key: {domainObject.identifier} }
|
||||||
* @param openmct
|
* @param openmct
|
||||||
*/
|
*/
|
||||||
constructor(conditionConfiguration, openmct) {
|
constructor(conditionConfiguration, openmct, conditionManager) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.openmct = openmct;
|
this.openmct = openmct;
|
||||||
|
this.conditionManager = conditionManager;
|
||||||
this.id = conditionConfiguration.id;
|
this.id = conditionConfiguration.id;
|
||||||
this.criteria = [];
|
this.criteria = [];
|
||||||
this.criteriaResults = {};
|
this.criteriaResults = {};
|
||||||
this.result = undefined;
|
this.result = undefined;
|
||||||
|
this.latestTimestamp = {};
|
||||||
|
|
||||||
if (conditionConfiguration.configuration.criteria) {
|
if (conditionConfiguration.configuration.criteria) {
|
||||||
this.createCriteria(conditionConfiguration.configuration.criteria);
|
this.createCriteria(conditionConfiguration.configuration.criteria);
|
||||||
}
|
}
|
||||||
this.trigger = conditionConfiguration.configuration.trigger;
|
this.trigger = conditionConfiguration.configuration.trigger;
|
||||||
|
this.conditionManager.on('broadcastTelemetry', this.handleBroadcastTelemetry, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleBroadcastTelemetry(datum) {
|
||||||
|
if (!datum || !datum.id) {
|
||||||
|
console.log('no data received');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.criteria.forEach(criterion => {
|
||||||
|
criterion.emit(`subscription:${datum.id}`, datum);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
update(conditionConfiguration) {
|
update(conditionConfiguration) {
|
||||||
@ -172,7 +186,6 @@ export default class ConditionClass extends EventEmitter {
|
|||||||
let found = this.findCriterion(criterion.id);
|
let found = this.findCriterion(criterion.id);
|
||||||
if (found) {
|
if (found) {
|
||||||
this.criteria[found.index] = criterion.data;
|
this.criteria[found.index] = criterion.data;
|
||||||
this.subscribe();
|
|
||||||
// TODO nothing is listening to this
|
// TODO nothing is listening to this
|
||||||
this.emitEvent('conditionUpdated', {
|
this.emitEvent('conditionUpdated', {
|
||||||
trigger: this.trigger,
|
trigger: this.trigger,
|
||||||
@ -181,21 +194,40 @@ export default class ConditionClass extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleCriterionResult(eventData) {
|
updateCriteriaResults(eventData) {
|
||||||
const id = eventData.id;
|
const id = eventData.id;
|
||||||
|
|
||||||
if (this.findCriterion(id)) {
|
if (this.findCriterion(id)) {
|
||||||
this.criteriaResults[id] = eventData.data.result;
|
this.criteriaResults[id] = eventData.data.result;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCriterionResult(eventData) {
|
||||||
|
this.updateCriteriaResults(eventData);
|
||||||
this.handleConditionUpdated(eventData.data);
|
this.handleConditionUpdated(eventData.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
subscribe() {
|
requestLADConditionResult() {
|
||||||
// TODO it looks like on any single criterion update subscriptions fire for all criteria
|
const criteriaResults = this.criteria
|
||||||
this.criteria.forEach((criterion) => {
|
.map(criterion => criterion.requestLAD());
|
||||||
criterion.subscribe();
|
|
||||||
})
|
return Promise.all(criteriaResults)
|
||||||
|
.then(results => {
|
||||||
|
results.forEach(result => {
|
||||||
|
this.updateCriteriaResults(result);
|
||||||
|
this.latestTimestamp = this.getLatestTimestamp(this.latestTimestamp, result.data)
|
||||||
|
});
|
||||||
|
this.evaluate();
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: this.id,
|
||||||
|
data: Object.assign({}, this.latestTimestamp, { result: this.result })
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getTelemetrySubscriptions() {
|
||||||
|
return this.criteria.map(criterion => criterion.telemetryObjectIdAsString);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleConditionUpdated(datum) {
|
handleConditionUpdated(datum) {
|
||||||
@ -223,6 +255,19 @@ export default class ConditionClass extends EventEmitter {
|
|||||||
this.result = computeCondition(this.criteriaResults, this.trigger === TRIGGER.ALL);
|
this.result = computeCondition(this.criteriaResults, this.trigger === TRIGGER.ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getLatestTimestamp(current, compare) {
|
||||||
|
const timestamp = Object.assign({}, current);
|
||||||
|
|
||||||
|
this.openmct.time.getAllTimeSystems().forEach(timeSystem => {
|
||||||
|
if (!timestamp[timeSystem.key]
|
||||||
|
|| compare[timeSystem.key] > timestamp[timeSystem.key]
|
||||||
|
) {
|
||||||
|
timestamp[timeSystem.key] = compare[timeSystem.key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
emitEvent(eventName, data) {
|
emitEvent(eventName, data) {
|
||||||
this.emit(eventName, {
|
this.emit(eventName, {
|
||||||
id: this.id,
|
id: this.id,
|
||||||
@ -231,6 +276,7 @@ export default class ConditionClass extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
|
this.conditionManager.off('broadcastTelemetry', this.handleBroadcastTelemetry, this);
|
||||||
if (typeof this.stopObservingForChanges === 'function') {
|
if (typeof this.stopObservingForChanges === 'function') {
|
||||||
this.stopObservingForChanges();
|
this.stopObservingForChanges();
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,11 @@ export default class ConditionManager extends EventEmitter {
|
|||||||
this.conditionSetDomainObject = conditionSetDomainObject;
|
this.conditionSetDomainObject = conditionSetDomainObject;
|
||||||
this.timeAPI = this.openmct.time;
|
this.timeAPI = this.openmct.time;
|
||||||
this.latestTimestamp = {};
|
this.latestTimestamp = {};
|
||||||
|
this.composition = this.openmct.composition.get(conditionSetDomainObject);
|
||||||
|
this.composition.on('add', this.subscribeToTelemetry, this);
|
||||||
|
this.composition.on('remove', this.unsubscribeFromTelemetry, this);
|
||||||
|
this.compositionLoad = this.composition.load();
|
||||||
|
this.subscriptions = {};
|
||||||
this.initialize();
|
this.initialize();
|
||||||
|
|
||||||
this.stopObservingForChanges = this.openmct.objects.observe(this.conditionSetDomainObject, '*', (newDomainObject) => {
|
this.stopObservingForChanges = this.openmct.objects.observe(this.conditionSetDomainObject, '*', (newDomainObject) => {
|
||||||
@ -38,6 +43,30 @@ export default class ConditionManager extends EventEmitter {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
subscribeToTelemetry(endpoint) {
|
||||||
|
const id = this.openmct.objects.makeKeyString(endpoint.identifier);
|
||||||
|
if (this.subscriptions[id]) {
|
||||||
|
console.log('subscription already exists');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.subscriptions[id] = this.openmct.telemetry.subscribe(
|
||||||
|
endpoint,
|
||||||
|
this.broadcastTelemetry.bind(this, id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsubscribeFromTelemetry(endpointIdentifier) {
|
||||||
|
const id = this.openmct.objects.makeKeyString(endpointIdentifier);
|
||||||
|
if (!this.subscriptions[id]) {
|
||||||
|
console.log('no subscription to remove');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.subscriptions[id]();
|
||||||
|
delete this.subscriptions[id];
|
||||||
|
}
|
||||||
|
|
||||||
initialize() {
|
initialize() {
|
||||||
this.conditionResults = {};
|
this.conditionResults = {};
|
||||||
this.conditionClassCollection = [];
|
this.conditionClassCollection = [];
|
||||||
@ -56,18 +85,13 @@ export default class ConditionManager extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
initCondition(conditionConfiguration, index) {
|
initCondition(conditionConfiguration, index) {
|
||||||
let condition = new Condition(conditionConfiguration, this.openmct);
|
let condition = new Condition(conditionConfiguration, this.openmct, this);
|
||||||
condition.on('conditionResultUpdated', this.handleConditionResult.bind(this));
|
condition.on('conditionResultUpdated', this.handleConditionResult.bind(this));
|
||||||
if (index !== undefined) {
|
if (index !== undefined) {
|
||||||
this.conditionClassCollection.splice(index + 1, 0, condition);
|
this.conditionClassCollection.splice(index + 1, 0, condition);
|
||||||
} else {
|
} else {
|
||||||
this.conditionClassCollection.unshift(condition);
|
this.conditionClassCollection.unshift(condition);
|
||||||
}
|
}
|
||||||
//There are no criteria for a default condition and hence no subscriptions.
|
|
||||||
//Hence the conditionResult must be manually triggered for it.
|
|
||||||
if (conditionConfiguration.isDefault) {
|
|
||||||
this.handleConditionResult();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createCondition(conditionConfiguration) {
|
createCondition(conditionConfiguration) {
|
||||||
@ -150,18 +174,10 @@ export default class ConditionManager extends EventEmitter {
|
|||||||
this.persistConditions();
|
this.persistConditions();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleConditionResult(resultObj) {
|
getCurrentCondition() {
|
||||||
const conditionCollection = this.conditionSetDomainObject.configuration.conditionCollection;
|
const conditionCollection = this.conditionSetDomainObject.configuration.conditionCollection;
|
||||||
let currentCondition = conditionCollection[conditionCollection.length-1];
|
let currentCondition = conditionCollection[conditionCollection.length-1];
|
||||||
|
|
||||||
if (resultObj) {
|
|
||||||
const id = resultObj.id;
|
|
||||||
if (this.findConditionById(id)) {
|
|
||||||
this.conditionResults[id] = resultObj.data.result;
|
|
||||||
}
|
|
||||||
this.updateTimestamp(resultObj.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < conditionCollection.length - 1; i++) {
|
for (let i = 0; i < conditionCollection.length - 1; i++) {
|
||||||
if (this.conditionResults[conditionCollection[i].id]) {
|
if (this.conditionResults[conditionCollection[i].id]) {
|
||||||
//first condition to be true wins
|
//first condition to be true wins
|
||||||
@ -169,7 +185,27 @@ export default class ConditionManager extends EventEmitter {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return currentCondition;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateConditionResults(resultObj) {
|
||||||
|
if (!resultObj) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const id = resultObj.id;
|
||||||
|
|
||||||
|
if (this.findConditionById(id)) {
|
||||||
|
this.conditionResults[id] = resultObj.data.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateTimestamp(resultObj.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleConditionResult(resultObj) {
|
||||||
|
// update conditions results and then calculate the current condition
|
||||||
|
this.updateConditionResults(resultObj);
|
||||||
|
const currentCondition = this.getCurrentCondition();
|
||||||
this.emit('conditionSetResultUpdated',
|
this.emit('conditionSetResultUpdated',
|
||||||
Object.assign(
|
Object.assign(
|
||||||
{
|
{
|
||||||
@ -192,14 +228,50 @@ export default class ConditionManager extends EventEmitter {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
requestLADConditionSetOutput() {
|
||||||
|
if (!this.conditionClassCollection.length || this.conditionClassCollection.length === 1) {
|
||||||
|
return Promise.resolve([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.compositionLoad.then(() => {
|
||||||
|
const ladConditionResults = this.conditionClassCollection
|
||||||
|
.map(condition => condition.requestLADConditionResult());
|
||||||
|
|
||||||
|
return Promise.all(ladConditionResults)
|
||||||
|
.then((results) => {
|
||||||
|
results.forEach(resultObj => { this.updateConditionResults(resultObj); });
|
||||||
|
const currentCondition = this.getCurrentCondition();
|
||||||
|
|
||||||
|
return Object.assign(
|
||||||
|
{
|
||||||
|
output: currentCondition.configuration.output,
|
||||||
|
id: this.conditionSetDomainObject.identifier,
|
||||||
|
conditionId: currentCondition.id
|
||||||
|
},
|
||||||
|
this.latestTimestamp
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
broadcastTelemetry(id, datum) {
|
||||||
|
this.emit(`broadcastTelemetry`, Object.assign({}, datum, {id: id}));
|
||||||
|
}
|
||||||
|
|
||||||
persistConditions() {
|
persistConditions() {
|
||||||
this.openmct.objects.mutate(this.conditionSetDomainObject, 'configuration.conditionCollection', this.conditionSetDomainObject.configuration.conditionCollection);
|
this.openmct.objects.mutate(this.conditionSetDomainObject, 'configuration.conditionCollection', this.conditionSetDomainObject.configuration.conditionCollection);
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
|
this.composition.off('add', this.subscribeToTelemetry, this);
|
||||||
|
this.composition.off('remove', this.unsubscribeFromTelemetry, this);
|
||||||
|
Object.values(this.subscriptions).forEach(unsubscribe => unsubscribe());
|
||||||
|
this.subscriptions = undefined;
|
||||||
|
|
||||||
if(this.stopObservingForChanges) {
|
if(this.stopObservingForChanges) {
|
||||||
this.stopObservingForChanges();
|
this.stopObservingForChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.conditionClassCollection.forEach((condition) => {
|
this.conditionClassCollection.forEach((condition) => {
|
||||||
condition.off('conditionResultUpdated', this.handleConditionResult);
|
condition.off('conditionResultUpdated', this.handleConditionResult);
|
||||||
condition.destroy();
|
condition.destroy();
|
||||||
|
@ -47,6 +47,8 @@ describe('ConditionManager', () => {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let mockComposition;
|
||||||
|
let loader;
|
||||||
|
|
||||||
function mockAngularComponents() {
|
function mockAngularComponents() {
|
||||||
let mockInjector = jasmine.createSpyObj('$injector', ['get']);
|
let mockInjector = jasmine.createSpyObj('$injector', ['get']);
|
||||||
@ -71,9 +73,33 @@ describe('ConditionManager', () => {
|
|||||||
openmct.$injector = mockInjector;
|
openmct.$injector = mockInjector;
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeAll(function () {
|
beforeEach(function () {
|
||||||
|
|
||||||
mockAngularComponents();
|
mockAngularComponents();
|
||||||
|
mockListener = jasmine.createSpy('mockListener');
|
||||||
|
loader = {};
|
||||||
|
loader.promise = new Promise(function (resolve, reject) {
|
||||||
|
loader.resolve = resolve;
|
||||||
|
loader.reject = reject;
|
||||||
|
});
|
||||||
|
|
||||||
|
mockComposition = jasmine.createSpyObj('compositionCollection', [
|
||||||
|
'load',
|
||||||
|
'on',
|
||||||
|
'off'
|
||||||
|
]);
|
||||||
|
mockComposition.load.and.callFake(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
loader.resolve();
|
||||||
|
});
|
||||||
|
return loader.promise;
|
||||||
|
});
|
||||||
|
mockComposition.on('add', mockListener);
|
||||||
|
mockComposition.on('remove', mockListener);
|
||||||
|
openmct.composition = jasmine.createSpyObj('compositionAPI', [
|
||||||
|
'get'
|
||||||
|
]);
|
||||||
|
openmct.composition.get.and.returnValue(mockComposition);
|
||||||
|
|
||||||
openmct.objects = jasmine.createSpyObj('objects', ['get', 'makeKeyString', 'observe', 'mutate']);
|
openmct.objects = jasmine.createSpyObj('objects', ['get', 'makeKeyString', 'observe', 'mutate']);
|
||||||
openmct.objects.get.and.returnValues(new Promise(function (resolve, reject) {
|
openmct.objects.get.and.returnValues(new Promise(function (resolve, reject) {
|
||||||
@ -84,10 +110,11 @@ describe('ConditionManager', () => {
|
|||||||
openmct.objects.makeKeyString.and.returnValue(conditionSetDomainObject.identifier.key);
|
openmct.objects.makeKeyString.and.returnValue(conditionSetDomainObject.identifier.key);
|
||||||
openmct.objects.observe.and.returnValue(function () {});
|
openmct.objects.observe.and.returnValue(function () {});
|
||||||
openmct.objects.mutate.and.returnValue(function () {});
|
openmct.objects.mutate.and.returnValue(function () {});
|
||||||
|
|
||||||
conditionMgr = new ConditionManager(conditionSetDomainObject, openmct);
|
conditionMgr = new ConditionManager(conditionSetDomainObject, openmct);
|
||||||
mockListener = jasmine.createSpy('mockListener');
|
|
||||||
|
|
||||||
conditionMgr.on('conditionSetResultUpdated', mockListener);
|
conditionMgr.on('conditionSetResultUpdated', mockListener);
|
||||||
|
conditionMgr.on('broadcastTelemetry', mockListener);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('creates a conditionCollection with a default condition', function () {
|
it('creates a conditionCollection with a default condition', function () {
|
||||||
|
@ -1,3 +1,25 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2020, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
export default class ConditionSetMetadataProvider {
|
export default class ConditionSetMetadataProvider {
|
||||||
constructor(openmct) {
|
constructor(openmct) {
|
||||||
this.openmct = openmct;
|
this.openmct = openmct;
|
||||||
@ -21,12 +43,21 @@ export default class ConditionSetMetadataProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getMetadata(domainObject) {
|
getMetadata(domainObject) {
|
||||||
|
const enumerations = domainObject.configuration.conditionCollection
|
||||||
|
.map((condition, index) => {
|
||||||
|
return {
|
||||||
|
string: condition.configuration.output,
|
||||||
|
value: index
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
values: this.getDomains().concat([
|
values: this.getDomains().concat([
|
||||||
{
|
{
|
||||||
name: 'Output',
|
name: 'Output',
|
||||||
key: 'output',
|
key: 'output',
|
||||||
format: 'string',
|
format: 'enum',
|
||||||
|
enumerations: enumerations,
|
||||||
hints: {
|
hints: {
|
||||||
range: 1
|
range: 1
|
||||||
}
|
}
|
||||||
|
@ -25,27 +25,60 @@ import ConditionManager from './ConditionManager'
|
|||||||
export default class ConditionSetTelemetryProvider {
|
export default class ConditionSetTelemetryProvider {
|
||||||
constructor(openmct) {
|
constructor(openmct) {
|
||||||
this.openmct = openmct;
|
this.openmct = openmct;
|
||||||
|
this.conditionManagerPool = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
isTelemetryObject(domainObject) {
|
isTelemetryObject(domainObject) {
|
||||||
return domainObject.type === 'conditionSet';
|
return domainObject.type === 'conditionSet';
|
||||||
}
|
}
|
||||||
|
|
||||||
supportsRequest(domainObject, options) {
|
supportsRequest(domainObject) {
|
||||||
return false;
|
return domainObject.type === 'conditionSet';
|
||||||
}
|
}
|
||||||
|
|
||||||
supportsSubscribe(domainObject) {
|
supportsSubscribe(domainObject) {
|
||||||
return domainObject.type === 'conditionSet';
|
return domainObject.type === 'conditionSet';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
request(domainObject) {
|
||||||
|
let conditionManager = this.getConditionManager(domainObject);
|
||||||
|
|
||||||
|
return conditionManager.requestLADConditionSetOutput()
|
||||||
|
.then(latestOutput => {
|
||||||
|
return latestOutput ? [latestOutput] : [];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
subscribe(domainObject, callback) {
|
subscribe(domainObject, callback) {
|
||||||
let conditionManager = new ConditionManager(domainObject, this.openmct);
|
let conditionManager = this.getConditionManager(domainObject);
|
||||||
|
|
||||||
conditionManager.on('conditionSetResultUpdated', callback);
|
conditionManager.on('conditionSetResultUpdated', callback);
|
||||||
|
|
||||||
return function unsubscribe() {
|
return this.destroyConditionManager.bind(this, this.openmct.objects.makeKeyString(domainObject.identifier));
|
||||||
conditionManager.off('conditionSetResultUpdated');
|
}
|
||||||
conditionManager.destroy();
|
|
||||||
|
/**
|
||||||
|
* returns conditionManager instance for corresponding domain object
|
||||||
|
* creates the instance if it is not yet created
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
getConditionManager(domainObject) {
|
||||||
|
const id = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||||
|
|
||||||
|
if (!this.conditionManagerPool[id]) {
|
||||||
|
this.conditionManagerPool[id] = new ConditionManager(domainObject, this.openmct);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this.conditionManagerPool[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cleans up and destroys conditionManager instance for corresponding domain object id
|
||||||
|
* can be called manually for views that only request but do not subscribe to data
|
||||||
|
*/
|
||||||
|
destroyConditionManager(id) {
|
||||||
|
this.conditionManagerPool[id].off('conditionSetResultUpdated');
|
||||||
|
this.conditionManagerPool[id].destroy();
|
||||||
|
delete this.conditionManagerPool[id];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
33
src/plugins/condition/ConditionSetViewPolicy.js
Normal file
33
src/plugins/condition/ConditionSetViewPolicy.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.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
function ConditionSetViewPolicy() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ConditionSetViewPolicy.prototype.allow = function (view, domainObject) {
|
||||||
|
if (domainObject.getModel().type === 'conditionSet') {
|
||||||
|
return view.key === 'conditionSet.view';
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ConditionSetViewPolicy;
|
@ -30,7 +30,7 @@ export default class ConditionSetViewProvider {
|
|||||||
this.openmct = openmct;
|
this.openmct = openmct;
|
||||||
this.name = 'Conditions View';
|
this.name = 'Conditions View';
|
||||||
this.key = 'conditionSet.view';
|
this.key = 'conditionSet.view';
|
||||||
this.cssClass = 'icon-conditional'; // TODO: replace with class for new icon
|
this.cssClass = 'icon-conditional';
|
||||||
}
|
}
|
||||||
|
|
||||||
canView(domainObject) {
|
canView(domainObject) {
|
||||||
|
@ -28,11 +28,19 @@ let openmct = {},
|
|||||||
mockListener,
|
mockListener,
|
||||||
testConditionDefinition,
|
testConditionDefinition,
|
||||||
testTelemetryObject,
|
testTelemetryObject,
|
||||||
conditionObj;
|
conditionObj,
|
||||||
|
conditionManager,
|
||||||
|
mockBroadcastTelemetry;
|
||||||
|
|
||||||
describe("The condition", function () {
|
describe("The condition", function () {
|
||||||
|
|
||||||
beforeEach (() => {
|
beforeEach (() => {
|
||||||
|
conditionManager = jasmine.createSpyObj('conditionManager',
|
||||||
|
['on']
|
||||||
|
);
|
||||||
|
mockBroadcastTelemetry = jasmine.createSpy('listener');
|
||||||
|
conditionManager.on('broadcastTelemetry', mockBroadcastTelemetry);
|
||||||
|
|
||||||
mockListener = jasmine.createSpy('listener');
|
mockListener = jasmine.createSpy('listener');
|
||||||
testTelemetryObject = {
|
testTelemetryObject = {
|
||||||
identifier:{ namespace: "", key: "test-object"},
|
identifier:{ namespace: "", key: "test-object"},
|
||||||
@ -66,11 +74,14 @@ describe("The condition", function () {
|
|||||||
testConditionDefinition = {
|
testConditionDefinition = {
|
||||||
id: '123-456',
|
id: '123-456',
|
||||||
configuration: {
|
configuration: {
|
||||||
|
name: 'mock condition',
|
||||||
|
output: 'mock output',
|
||||||
trigger: TRIGGER.ANY,
|
trigger: TRIGGER.ANY,
|
||||||
criteria: [
|
criteria: [
|
||||||
{
|
{
|
||||||
|
id: '1234-5678-9999-0000',
|
||||||
operation: 'equalTo',
|
operation: 'equalTo',
|
||||||
input: false,
|
input: ['0'],
|
||||||
metadata: 'value',
|
metadata: 'value',
|
||||||
telemetry: testTelemetryObject.identifier
|
telemetry: testTelemetryObject.identifier
|
||||||
}
|
}
|
||||||
@ -80,14 +91,14 @@ describe("The condition", function () {
|
|||||||
|
|
||||||
conditionObj = new Condition(
|
conditionObj = new Condition(
|
||||||
testConditionDefinition,
|
testConditionDefinition,
|
||||||
openmct
|
openmct,
|
||||||
|
conditionManager
|
||||||
);
|
);
|
||||||
|
|
||||||
conditionObj.on('conditionUpdated', mockListener);
|
conditionObj.on('conditionUpdated', mockListener);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("generates criteria with an id", function () {
|
it("generates criteria with the correct properties", function () {
|
||||||
const testCriterion = testConditionDefinition.configuration.criteria[0];
|
const testCriterion = testConditionDefinition.configuration.criteria[0];
|
||||||
let criterion = conditionObj.generateCriterion(testCriterion);
|
let criterion = conditionObj.generateCriterion(testCriterion);
|
||||||
expect(criterion.id).toBeDefined();
|
expect(criterion.id).toBeDefined();
|
||||||
@ -98,6 +109,7 @@ describe("The condition", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("initializes with an id", function () {
|
it("initializes with an id", function () {
|
||||||
|
console.log(conditionObj);
|
||||||
expect(conditionObj.id).toBeDefined();
|
expect(conditionObj.id).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -23,18 +23,24 @@
|
|||||||
import EventEmitter from 'EventEmitter';
|
import EventEmitter from 'EventEmitter';
|
||||||
|
|
||||||
export default class StyleRuleManager extends EventEmitter {
|
export default class StyleRuleManager extends EventEmitter {
|
||||||
constructor(conditionalStyleConfiguration, openmct) {
|
constructor(styleConfiguration, openmct, callback) {
|
||||||
super();
|
super();
|
||||||
this.openmct = openmct;
|
this.openmct = openmct;
|
||||||
if (conditionalStyleConfiguration && conditionalStyleConfiguration.conditionSetIdentifier) {
|
this.callback = callback;
|
||||||
this.initialize(conditionalStyleConfiguration);
|
if (styleConfiguration) {
|
||||||
this.subscribeToConditionSet();
|
this.initialize(styleConfiguration);
|
||||||
|
if (styleConfiguration.conditionSetIdentifier) {
|
||||||
|
this.subscribeToConditionSet();
|
||||||
|
} else {
|
||||||
|
this.applyStaticStyle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize(conditionalStyleConfiguration) {
|
initialize(styleConfiguration) {
|
||||||
this.conditionSetIdentifier = conditionalStyleConfiguration.conditionSetIdentifier;
|
this.conditionSetIdentifier = styleConfiguration.conditionSetIdentifier;
|
||||||
this.updateConditionStylesMap(conditionalStyleConfiguration.styles || []);
|
this.staticStyle = styleConfiguration.staticStyle;
|
||||||
|
this.updateConditionStylesMap(styleConfiguration.styles || []);
|
||||||
}
|
}
|
||||||
|
|
||||||
subscribeToConditionSet() {
|
subscribeToConditionSet() {
|
||||||
@ -46,13 +52,14 @@ export default class StyleRuleManager extends EventEmitter {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateConditionalStyleConfig(conditionalStyleConfiguration) {
|
updateObjectStyleConfig(styleConfiguration) {
|
||||||
if (!conditionalStyleConfiguration || !conditionalStyleConfiguration.conditionSetIdentifier) {
|
if (!styleConfiguration || !styleConfiguration.conditionSetIdentifier) {
|
||||||
|
this.initialize(styleConfiguration || {});
|
||||||
this.destroy();
|
this.destroy();
|
||||||
} else {
|
} else {
|
||||||
let isNewConditionSet = !this.conditionSetIdentifier ||
|
let isNewConditionSet = !this.conditionSetIdentifier ||
|
||||||
this.openmct.objects.areIdsEqual(this.conditionSetIdentifier, conditionalStyleConfiguration.conditionSetIdentifier);
|
this.openmct.objects.areIdsEqual(this.conditionSetIdentifier, styleConfiguration.conditionSetIdentifier);
|
||||||
this.initialize(conditionalStyleConfiguration);
|
this.initialize(styleConfiguration);
|
||||||
//Only resubscribe if the conditionSet has changed.
|
//Only resubscribe if the conditionSet has changed.
|
||||||
if (isNewConditionSet) {
|
if (isNewConditionSet) {
|
||||||
this.subscribeToConditionSet();
|
this.subscribeToConditionSet();
|
||||||
@ -63,7 +70,11 @@ export default class StyleRuleManager extends EventEmitter {
|
|||||||
updateConditionStylesMap(conditionStyles) {
|
updateConditionStylesMap(conditionStyles) {
|
||||||
let conditionStyleMap = {};
|
let conditionStyleMap = {};
|
||||||
conditionStyles.forEach((conditionStyle) => {
|
conditionStyles.forEach((conditionStyle) => {
|
||||||
conditionStyleMap[conditionStyle.conditionId] = conditionStyle.style;
|
if (conditionStyle.conditionId) {
|
||||||
|
conditionStyleMap[conditionStyle.conditionId] = conditionStyle.style;
|
||||||
|
} else {
|
||||||
|
conditionStyleMap.static = conditionStyle.style;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this.conditionalStyleMap = conditionStyleMap;
|
this.conditionalStyleMap = conditionStyleMap;
|
||||||
}
|
}
|
||||||
@ -74,26 +85,33 @@ export default class StyleRuleManager extends EventEmitter {
|
|||||||
if (foundStyle !== this.currentStyle) {
|
if (foundStyle !== this.currentStyle) {
|
||||||
this.currentStyle = foundStyle;
|
this.currentStyle = foundStyle;
|
||||||
}
|
}
|
||||||
|
this.updateDomainObjectStyle();
|
||||||
} else {
|
} else {
|
||||||
if (this.currentStyle !== this.defaultStyle) {
|
this.applyStaticStyle();
|
||||||
this.currentStyle = this.defaultStyle;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateDomainObjectStyle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDomainObjectStyle() {
|
updateDomainObjectStyle() {
|
||||||
this.emit('conditionalStyleUpdated', this.currentStyle)
|
if (this.callback) {
|
||||||
|
this.callback(Object.assign({}, this.currentStyle));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
applyStaticStyle() {
|
||||||
|
if (this.staticStyle) {
|
||||||
|
this.currentStyle = this.staticStyle.style;
|
||||||
|
} else {
|
||||||
|
if (this.currentStyle) {
|
||||||
|
Object.keys(this.currentStyle).forEach(key => {
|
||||||
|
this.currentStyle[key] = 'transparent';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.updateDomainObjectStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
if (this.currentStyle) {
|
this.applyStaticStyle();
|
||||||
Object.keys(this.currentStyle).forEach(key => {
|
|
||||||
this.currentStyle[key] = 'inherit';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.updateDomainObjectStyle();
|
|
||||||
if (this.stopProvidingTelemetry) {
|
if (this.stopProvidingTelemetry) {
|
||||||
this.stopProvidingTelemetry();
|
this.stopProvidingTelemetry();
|
||||||
}
|
}
|
||||||
|
@ -41,28 +41,16 @@
|
|||||||
></span>
|
></span>
|
||||||
|
|
||||||
<span class="c-condition__name">{{ condition.configuration.name }}</span>
|
<span class="c-condition__name">{{ condition.configuration.name }}</span>
|
||||||
<span v-if="condition.isDefault"
|
<!-- TODO: description should be derived from criteria -->
|
||||||
class="c-condition__summary"
|
<span class="c-condition__summary">
|
||||||
>
|
|
||||||
When all else fails
|
|
||||||
</span>
|
|
||||||
<span v-else
|
|
||||||
class="c-condition__summary"
|
|
||||||
>
|
|
||||||
<template v-if="!canEvaluateCriteria">
|
<template v-if="!canEvaluateCriteria">
|
||||||
Define criteria
|
Define criteria
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<span v-else>
|
||||||
When
|
<condition-description :show-label="false"
|
||||||
<span v-for="(criterion, index) in condition.configuration.criteria"
|
:condition="condition"
|
||||||
:key="index"
|
/>
|
||||||
>
|
</span>
|
||||||
{{ getRule(criterion, index) }}
|
|
||||||
<template v-if="!isLastCriterion(index)">
|
|
||||||
{{ getConjunction }}
|
|
||||||
</template>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div class="c-condition__buttons">
|
<div class="c-condition__buttons">
|
||||||
@ -180,40 +168,23 @@
|
|||||||
Output: {{ condition.configuration.output }}
|
Output: {{ condition.configuration.output }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="condition.isDefault"
|
<div class="c-condition__summary">
|
||||||
class="c-condition__summary"
|
<condition-description :show-label="false"
|
||||||
>
|
:condition="condition"
|
||||||
When all else fails
|
/>
|
||||||
</div>
|
|
||||||
<div v-else
|
|
||||||
class="c-condition__summary"
|
|
||||||
>
|
|
||||||
<template v-if="!canEvaluateCriteria">
|
|
||||||
Define criteria
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
When
|
|
||||||
<span v-for="(criterion, index) in condition.configuration.criteria"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
{{ getRule(criterion, index) }}
|
|
||||||
<template v-if="!isLastCriterion(index)">
|
|
||||||
{{ getConjunction }}
|
|
||||||
</template>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Criterion from './Criterion.vue';
|
import Criterion from './Criterion.vue';
|
||||||
import { OPERATIONS } from '../utils/operations';
|
import ConditionDescription from "./ConditionDescription.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inject: ['openmct'],
|
inject: ['openmct'],
|
||||||
components: {
|
components: {
|
||||||
Criterion
|
Criterion,
|
||||||
|
ConditionDescription
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
condition: {
|
condition: {
|
||||||
@ -249,19 +220,17 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
canEvaluateCriteria: function () {
|
canEvaluateCriteria: function () {
|
||||||
let criteria = this.condition.configuration.criteria;
|
let criteria = this.condition.configuration.criteria;
|
||||||
let lastCriterion = criteria[criteria.length - 1];
|
if (criteria.length) {
|
||||||
if (lastCriterion.telemetry &&
|
let lastCriterion = criteria[criteria.length - 1];
|
||||||
lastCriterion.operation &&
|
if (lastCriterion.telemetry &&
|
||||||
(lastCriterion.input.length ||
|
lastCriterion.operation &&
|
||||||
lastCriterion.operation === 'isDefined' ||
|
(lastCriterion.input.length ||
|
||||||
lastCriterion.operation === 'isUndefined')) {
|
lastCriterion.operation === 'isDefined' ||
|
||||||
return true;
|
lastCriterion.operation === 'isUndefined')) {
|
||||||
} else {
|
return true;
|
||||||
return false;
|
}
|
||||||
}
|
}
|
||||||
},
|
return false;
|
||||||
getConjunction: function () {
|
|
||||||
return this.condition.configuration.trigger === 'all' ? 'and' : 'or';
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
destroyed() {
|
destroyed() {
|
||||||
@ -271,26 +240,6 @@ export default {
|
|||||||
this.setOutputSelection();
|
this.setOutputSelection();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setTelemetryName(name) {
|
|
||||||
this.selectedTelemetryName = name;
|
|
||||||
},
|
|
||||||
setFieldName(name) {
|
|
||||||
this.selectedFieldName = name;
|
|
||||||
},
|
|
||||||
getRule(criterion, index) {
|
|
||||||
return `${this.selectedTelemetryName} ${this.selectedFieldName} ${this.findDescription(criterion.operation, criterion.input)}`;
|
|
||||||
},
|
|
||||||
isLastCriterion(index) {
|
|
||||||
return index === this.condition.configuration.criteria.length - 1;
|
|
||||||
},
|
|
||||||
findDescription(operation, values) {
|
|
||||||
for (let i=0, ii= OPERATIONS.length; i < ii; i++) {
|
|
||||||
if (operation === OPERATIONS[i].name) {
|
|
||||||
return OPERATIONS[i].getDescription(values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
setOutputSelection() {
|
setOutputSelection() {
|
||||||
let conditionOutput = this.condition.configuration.output;
|
let conditionOutput = this.condition.configuration.output;
|
||||||
if (conditionOutput) {
|
if (conditionOutput) {
|
||||||
|
@ -107,6 +107,7 @@ export default {
|
|||||||
this.composition.off('add', this.addTelemetryObject);
|
this.composition.off('add', this.addTelemetryObject);
|
||||||
this.composition.off('remove', this.removeTelemetryObject);
|
this.composition.off('remove', this.removeTelemetryObject);
|
||||||
if(this.conditionManager) {
|
if(this.conditionManager) {
|
||||||
|
this.conditionManager.off('conditionSetResultUpdated', this.handleConditionSetResultUpdated);
|
||||||
this.conditionManager.destroy();
|
this.conditionManager.destroy();
|
||||||
}
|
}
|
||||||
if (this.stopObservingForChanges) {
|
if (this.stopObservingForChanges) {
|
||||||
@ -121,11 +122,12 @@ export default {
|
|||||||
this.conditionCollection = this.domainObject.configuration.conditionCollection;
|
this.conditionCollection = this.domainObject.configuration.conditionCollection;
|
||||||
this.observeForChanges();
|
this.observeForChanges();
|
||||||
this.conditionManager = new ConditionManager(this.domainObject, this.openmct);
|
this.conditionManager = new ConditionManager(this.domainObject, this.openmct);
|
||||||
this.conditionManager.on('conditionSetResultUpdated', (data) => {
|
this.conditionManager.on('conditionSetResultUpdated', this.handleConditionSetResultUpdated);
|
||||||
this.$emit('conditionSetResultUpdated', data);
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
handleConditionSetResultUpdated(data) {
|
||||||
|
this.$emit('conditionSetResultUpdated', data)
|
||||||
|
},
|
||||||
observeForChanges() {
|
observeForChanges() {
|
||||||
this.stopObservingForChanges = this.openmct.objects.observe(this.domainObject, 'configuration.conditionCollection', (newConditionCollection) => {
|
this.stopObservingForChanges = this.openmct.objects.observe(this.domainObject, 'configuration.conditionCollection', (newConditionCollection) => {
|
||||||
this.conditionCollection = newConditionCollection;
|
this.conditionCollection = newConditionCollection;
|
||||||
|
123
src/plugins/condition/components/ConditionDescription.vue
Normal file
123
src/plugins/condition/components/ConditionDescription.vue
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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-style__condition-desc">
|
||||||
|
<span v-if="showLabel && condition"
|
||||||
|
class="c-style__condition-desc__name c-condition__name"
|
||||||
|
>
|
||||||
|
{{ condition.configuration.name }}
|
||||||
|
</span>
|
||||||
|
<span v-for="(criterionDescription, index) in criterionDescriptions"
|
||||||
|
:key="criterionDescription"
|
||||||
|
class="c-style__condition-desc__text"
|
||||||
|
>
|
||||||
|
<template v-if="!index">When</template>
|
||||||
|
{{ criterionDescription }}
|
||||||
|
<template v-if="index < (criterionDescriptions.length-1)">{{ triggerDescription }}</template>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { TRIGGER } from "@/plugins/condition/utils/constants";
|
||||||
|
import { OPERATIONS } from "@/plugins/condition/utils/operations";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ConditionDescription',
|
||||||
|
inject: [
|
||||||
|
'openmct'
|
||||||
|
],
|
||||||
|
props: {
|
||||||
|
showLabel: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
condition: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
criterionDescriptions: [],
|
||||||
|
triggerDescription: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
condition: {
|
||||||
|
handler(val) {
|
||||||
|
this.getConditionDescription();
|
||||||
|
},
|
||||||
|
deep: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getConditionDescription();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getConditionDescription() {
|
||||||
|
if (this.condition) {
|
||||||
|
this.triggerDescription = this.condition.configuration.trigger === TRIGGER.ANY ? ' or ' : ' and ';
|
||||||
|
this.criterionDescriptions = [];
|
||||||
|
this.condition.configuration.criteria.forEach((criterion, index) => {
|
||||||
|
this.getCriterionDescription(criterion, index);
|
||||||
|
});
|
||||||
|
if (this.condition.isDefault) {
|
||||||
|
this.criterionDescriptions.splice(0, 0, 'all else fails');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.criterionDescriptions = [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getCriterionDescription(criterion, index) {
|
||||||
|
this.openmct.objects.get(criterion.telemetry).then((telemetryObject) => {
|
||||||
|
if (telemetryObject.type === 'unknown') {
|
||||||
|
let description = `Unknown ${criterion.metadata} ${this.getOperatorText(criterion.operation, criterion.input)}`;
|
||||||
|
this.criterionDescriptions.splice(index, 0, description);
|
||||||
|
} else {
|
||||||
|
let metadataValue = criterion.metadata;
|
||||||
|
if (criterion.metadata) {
|
||||||
|
this.telemetryMetadata = this.openmct.telemetry.getMetadata(telemetryObject);
|
||||||
|
const metadataObj = this.telemetryMetadata.valueMetadatas.find((metadata) => metadata.key === criterion.metadata);
|
||||||
|
if (metadataObj && metadataObj.name) {
|
||||||
|
metadataValue = metadataObj.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let description = `${telemetryObject.name} ${metadataValue} ${this.getOperatorText(criterion.operation, criterion.input)}`;
|
||||||
|
if (this.criterionDescriptions[index]) {
|
||||||
|
this.criterionDescriptions[index] = description;
|
||||||
|
} else {
|
||||||
|
this.criterionDescriptions.splice(index, 0, description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getOperatorText(operationName, values) {
|
||||||
|
const found = OPERATIONS.find((operation) => operation.name === operationName);
|
||||||
|
return found ? found.getDescription(values) : '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
80
src/plugins/condition/components/ConditionError.vue
Normal file
80
src/plugins/condition/components/ConditionError.vue
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2020, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div v-if="conditionErrors.length"
|
||||||
|
class="c-condition__errors"
|
||||||
|
>
|
||||||
|
<div v-for="(error, index) in conditionErrors"
|
||||||
|
:key="index"
|
||||||
|
class="u-alert u-alert--block u-alert--with-icon"
|
||||||
|
>{{ error.message.errorText }} {{ error.additionalInfo }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import { ERROR } from "@/plugins/condition/utils/constants";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ConditionError',
|
||||||
|
inject: [
|
||||||
|
'openmct'
|
||||||
|
],
|
||||||
|
props: {
|
||||||
|
condition: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
conditionErrors: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getConditionErrors();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getConditionErrors() {
|
||||||
|
if (this.condition) {
|
||||||
|
this.condition.configuration.criteria.forEach((criterion, index) => {
|
||||||
|
this.getCriterionErrors(criterion, index);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getCriterionErrors(criterion, index) {
|
||||||
|
this.openmct.objects.get(criterion.telemetry).then((telemetryObject) => {
|
||||||
|
if (telemetryObject.type === 'unknown') {
|
||||||
|
this.conditionErrors.push({
|
||||||
|
message: ERROR.TELEMETRY_NOT_FOUND,
|
||||||
|
additionalInfo: criterion.telemetry ? `Key: ${this.openmct.objects.makeKeyString(criterion.telemetry)}` : ''
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
.c-condition {
|
.c-condition {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
min-width: 400px;
|
||||||
|
|
||||||
> * + * {
|
> * + * {
|
||||||
margin-top: $interiorMarginSm;
|
margin-top: $interiorMarginSm;
|
||||||
@ -24,10 +25,13 @@
|
|||||||
|
|
||||||
/***************************** HEADER */
|
/***************************** HEADER */
|
||||||
&__header {
|
&__header {
|
||||||
|
$h: 22px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: start;
|
||||||
align-content: stretch;
|
align-content: stretch;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
min-height: $h;
|
||||||
|
line-height: $h;
|
||||||
|
|
||||||
> * {
|
> * {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
@ -36,6 +40,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__drag-grippy {
|
||||||
|
transform: translateY(50%);
|
||||||
|
}
|
||||||
|
|
||||||
&__name {
|
&__name {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
align-self: baseline; // Fixes bold line-height offset problem
|
align-self: baseline; // Fixes bold line-height offset problem
|
||||||
|
@ -0,0 +1,163 @@
|
|||||||
|
<template>
|
||||||
|
<li class="c-tree__item-h">
|
||||||
|
<div
|
||||||
|
class="c-tree__item"
|
||||||
|
:class="{ 'is-alias': isAlias, 'is-navigated-object': navigated }"
|
||||||
|
@click="handleItemSelected(node.object, node)"
|
||||||
|
>
|
||||||
|
<view-control
|
||||||
|
v-model="expanded"
|
||||||
|
class="c-tree__item__view-control"
|
||||||
|
:enabled="hasChildren"
|
||||||
|
:propagate="false"
|
||||||
|
/>
|
||||||
|
<div class="c-tree__item__label c-object-label">
|
||||||
|
<div
|
||||||
|
class="c-tree__item__type-icon c-object-label__type-icon"
|
||||||
|
:class="typeClass"
|
||||||
|
></div>
|
||||||
|
<div class="c-tree__item__name c-object-label__name">{{ node.object.name }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul
|
||||||
|
v-if="expanded"
|
||||||
|
class="c-tree"
|
||||||
|
>
|
||||||
|
<li
|
||||||
|
v-if="isLoading && !loaded"
|
||||||
|
class="c-tree__item-h"
|
||||||
|
>
|
||||||
|
<div class="c-tree__item loading">
|
||||||
|
<span class="c-tree__item__label">Loading...</span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<condition-set-dialog-tree-item
|
||||||
|
v-for="child in children"
|
||||||
|
:key="child.id"
|
||||||
|
:node="child"
|
||||||
|
:selected-item="selectedItem"
|
||||||
|
:handle-item-selected="handleItemSelected"
|
||||||
|
/>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import viewControl from '@/ui/components/viewControl.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ConditionSetDialogTreeItem',
|
||||||
|
inject: ['openmct'],
|
||||||
|
components: {
|
||||||
|
viewControl
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
node: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
selectedItem: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleItemSelected: {
|
||||||
|
type: Function,
|
||||||
|
default() {
|
||||||
|
return (item) => {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
hasChildren: false,
|
||||||
|
isLoading: false,
|
||||||
|
loaded: false,
|
||||||
|
children: [],
|
||||||
|
expanded: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
navigated() {
|
||||||
|
const itemId = this.selectedItem && this.selectedItem.itemId;
|
||||||
|
const isSelectedObject = itemId && this.openmct.objects.areIdsEqual(this.node.object.identifier, itemId);
|
||||||
|
if (isSelectedObject && this.node.objectPath && this.node.objectPath.length > 1) {
|
||||||
|
const isParent = this.openmct.objects.areIdsEqual(this.node.objectPath[1].identifier, this.selectedItem.parentId);
|
||||||
|
return isSelectedObject && isParent;
|
||||||
|
}
|
||||||
|
return isSelectedObject;
|
||||||
|
},
|
||||||
|
isAlias() {
|
||||||
|
let parent = this.node.objectPath[1];
|
||||||
|
if (!parent) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let parentKeyString = this.openmct.objects.makeKeyString(parent.identifier);
|
||||||
|
return parentKeyString !== this.node.object.location;
|
||||||
|
},
|
||||||
|
typeClass() {
|
||||||
|
let type = this.openmct.types.get(this.node.object.type);
|
||||||
|
if (!type) {
|
||||||
|
return 'icon-object-unknown';
|
||||||
|
}
|
||||||
|
return type.definition.cssClass;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
expanded() {
|
||||||
|
if (!this.hasChildren) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this.loaded && !this.isLoading) {
|
||||||
|
this.composition = this.openmct.composition.get(this.domainObject);
|
||||||
|
this.composition.on('add', this.addChild);
|
||||||
|
this.composition.on('remove', this.removeChild);
|
||||||
|
this.composition.load().then(this.finishLoading);
|
||||||
|
this.isLoading = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.domainObject = this.node.object;
|
||||||
|
let removeListener = this.openmct.objects.observe(this.domainObject, '*', (newObject) => {
|
||||||
|
this.domainObject = newObject;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$once('hook:destroyed', removeListener);
|
||||||
|
if (this.openmct.composition.get(this.node.object)) {
|
||||||
|
this.hasChildren = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.expanded = false;
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
if (this.composition) {
|
||||||
|
this.composition.off('add', this.addChild);
|
||||||
|
this.composition.off('remove', this.removeChild);
|
||||||
|
delete this.composition;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
addChild(child) {
|
||||||
|
this.children.push({
|
||||||
|
id: this.openmct.objects.makeKeyString(child.identifier),
|
||||||
|
object: child,
|
||||||
|
objectPath: [child].concat(this.node.objectPath),
|
||||||
|
navigateToParent: this.navigateToPath
|
||||||
|
});
|
||||||
|
},
|
||||||
|
removeChild(identifier) {
|
||||||
|
let removeId = this.openmct.objects.makeKeyString(identifier);
|
||||||
|
this.children = this.children
|
||||||
|
.filter(c => c.id !== removeId);
|
||||||
|
},
|
||||||
|
finishLoading() {
|
||||||
|
this.isLoading = false;
|
||||||
|
this.loaded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -0,0 +1,150 @@
|
|||||||
|
<template>
|
||||||
|
<div class="u-contents">
|
||||||
|
<div class="c-overlay__top-bar">
|
||||||
|
<div class="c-overlay__dialog-title">Select Condition Set</div>
|
||||||
|
</div>
|
||||||
|
<div class="c-overlay__contents-main c-selector c-tree-and-search">
|
||||||
|
<div class="c-tree-and-search__search">
|
||||||
|
<search ref="shell-search"
|
||||||
|
class="c-search"
|
||||||
|
:value="searchValue"
|
||||||
|
@input="searchTree"
|
||||||
|
@clear="searchTree"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- loading -->
|
||||||
|
<div v-if="isLoading"
|
||||||
|
class="c-tree-and-search__loading loading"
|
||||||
|
></div>
|
||||||
|
<!-- end loading -->
|
||||||
|
|
||||||
|
<div v-if="(allTreeItems.length === 0) || (searchValue && filteredTreeItems.length === 0)"
|
||||||
|
class="c-tree-and-search__no-results"
|
||||||
|
>
|
||||||
|
No results found
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- main tree -->
|
||||||
|
<ul v-if="!isLoading"
|
||||||
|
v-show="!searchValue"
|
||||||
|
class="c-tree-and-search__tree c-tree"
|
||||||
|
>
|
||||||
|
<condition-set-dialog-tree-item
|
||||||
|
v-for="treeItem in allTreeItems"
|
||||||
|
:key="treeItem.id"
|
||||||
|
:node="treeItem"
|
||||||
|
:selected-item="selectedItem"
|
||||||
|
:handle-item-selected="handleItemSelection"
|
||||||
|
/>
|
||||||
|
</ul>
|
||||||
|
<!-- end main tree -->
|
||||||
|
|
||||||
|
<!-- search tree -->
|
||||||
|
<ul v-if="searchValue"
|
||||||
|
class="c-tree-and-search__tree c-tree"
|
||||||
|
>
|
||||||
|
<condition-set-dialog-tree-item
|
||||||
|
v-for="treeItem in filteredTreeItems"
|
||||||
|
:key="treeItem.id"
|
||||||
|
:node="treeItem"
|
||||||
|
:selected-item="selectedItem"
|
||||||
|
:handle-item-selected="handleItemSelection"
|
||||||
|
/>
|
||||||
|
</ul>
|
||||||
|
<!-- end search tree -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import search from '@/ui/components/search.vue';
|
||||||
|
import ConditionSetDialogTreeItem from './ConditionSetDialogTreeItem.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
inject: ['openmct'],
|
||||||
|
name: 'ConditionSetSelectorDialog',
|
||||||
|
components: {
|
||||||
|
search,
|
||||||
|
ConditionSetDialogTreeItem
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
expanded: false,
|
||||||
|
searchValue: '',
|
||||||
|
allTreeItems: [],
|
||||||
|
filteredTreeItems: [],
|
||||||
|
isLoading: false,
|
||||||
|
selectedItem: undefined
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.searchService = this.openmct.$injector.get('searchService');
|
||||||
|
this.getAllChildren();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getAllChildren() {
|
||||||
|
this.isLoading = true;
|
||||||
|
this.openmct.objects.get('ROOT')
|
||||||
|
.then(root => {
|
||||||
|
return this.openmct.composition.get(root).load()
|
||||||
|
})
|
||||||
|
.then(children => {
|
||||||
|
this.isLoading = false;
|
||||||
|
this.allTreeItems = children.map(c => {
|
||||||
|
return {
|
||||||
|
id: this.openmct.objects.makeKeyString(c.identifier),
|
||||||
|
object: c,
|
||||||
|
objectPath: [c],
|
||||||
|
navigateToParent: '/browse'
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getFilteredChildren() {
|
||||||
|
this.searchService.query(this.searchValue).then(children => {
|
||||||
|
this.filteredTreeItems = children.hits.map(child => {
|
||||||
|
|
||||||
|
let context = child.object.getCapability('context'),
|
||||||
|
object = child.object.useCapability('adapter'),
|
||||||
|
objectPath = [],
|
||||||
|
navigateToParent;
|
||||||
|
|
||||||
|
if (context) {
|
||||||
|
objectPath = context.getPath().slice(1)
|
||||||
|
.map(oldObject => oldObject.useCapability('adapter'))
|
||||||
|
.reverse();
|
||||||
|
navigateToParent = '/browse/' + objectPath.slice(1)
|
||||||
|
.map((parent) => this.openmct.objects.makeKeyString(parent.identifier))
|
||||||
|
.join('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: this.openmct.objects.makeKeyString(object.identifier),
|
||||||
|
object,
|
||||||
|
objectPath,
|
||||||
|
navigateToParent
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
searchTree(value) {
|
||||||
|
this.searchValue = value;
|
||||||
|
|
||||||
|
if (this.searchValue !== '') {
|
||||||
|
this.getFilteredChildren();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleItemSelection(item, node) {
|
||||||
|
if (item && item.type === 'conditionSet') {
|
||||||
|
const parentId = (node.objectPath && node.objectPath.length > 1) ? node.objectPath[1].identifier : undefined;
|
||||||
|
this.selectedItem = {
|
||||||
|
itemId: item.identifier,
|
||||||
|
parentId
|
||||||
|
};
|
||||||
|
this.$emit('conditionSetSelected', item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -1,69 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<div v-if="conditionStyle"
|
|
||||||
class="holder c-c-button-wrapper align-left"
|
|
||||||
>
|
|
||||||
<div>{{ conditionStyle.conditionName }}</div>
|
|
||||||
<span :style="conditionStyle.style">ABC</span>
|
|
||||||
<toolbar-color-picker v-if="conditionStyle.style.border"
|
|
||||||
:options="borderColorOption"
|
|
||||||
@change="updateStyleValue"
|
|
||||||
/>
|
|
||||||
<toolbar-color-picker v-if="conditionStyle.style.backgroundColor"
|
|
||||||
:options="backgroundColorOption"
|
|
||||||
@change="updateStyleValue"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
import ToolbarColorPicker from "@/ui/toolbar/components/toolbar-color-picker.vue";
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
ToolbarColorPicker
|
|
||||||
},
|
|
||||||
inject: [
|
|
||||||
'openmct'
|
|
||||||
],
|
|
||||||
props: {
|
|
||||||
conditionStyle: {
|
|
||||||
type: Object,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
condition: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
borderColorOption() {
|
|
||||||
return {
|
|
||||||
icon: 'icon-line-horz',
|
|
||||||
title: 'Set border color',
|
|
||||||
value: this.conditionStyle.style.border.replace('1px solid ', ''),
|
|
||||||
property: 'border'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
backgroundColorOption() {
|
|
||||||
return {
|
|
||||||
icon: 'icon-paint-bucket',
|
|
||||||
title: 'Set background color',
|
|
||||||
value: this.conditionStyle.style.backgroundColor,
|
|
||||||
property: 'backgroundColor'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
updateStyleValue(value, item) {
|
|
||||||
if (item.property === 'border') {
|
|
||||||
value = '1px solid ' + value;
|
|
||||||
}
|
|
||||||
this.conditionStyle.style[item.property] = value;
|
|
||||||
this.$emit('persist', this.conditionStyle)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
@ -1,43 +1,117 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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>
|
<template>
|
||||||
<div>
|
<div class="c-inspector__styles c-inspect-styles">
|
||||||
<div v-if="!conditionalStyles.length"
|
<template v-if="!conditionSetDomainObject">
|
||||||
class="holder c-c-button-wrapper align-left"
|
<div class="c-inspect-styles__header">
|
||||||
>
|
Object Style
|
||||||
<button
|
</div>
|
||||||
class="c-c-button c-c-button--minor add-criteria-button"
|
<div class="c-inspect-styles__content">
|
||||||
@click="addConditionSet"
|
<div v-if="staticStyle"
|
||||||
>
|
class="c-inspect-styles__style"
|
||||||
<span class="c-c-button__label">Use conditional styling</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div v-else>
|
|
||||||
<div class="holder c-c-button-wrapper align-left">
|
|
||||||
<button
|
|
||||||
class="c-c-button c-c-button--minor add-criteria-button"
|
|
||||||
@click="removeConditionSet"
|
|
||||||
>
|
>
|
||||||
<span class="c-c-button__label">Remove conditional styling</span>
|
<style-editor class="c-inspect-styles__editor"
|
||||||
|
:style-item="staticStyle"
|
||||||
|
:is-editing="isEditing"
|
||||||
|
@persist="updateStaticStyle"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
id="addConditionSet"
|
||||||
|
class="c-button c-button--major c-toggle-styling-button labeled"
|
||||||
|
@click="addConditionSet"
|
||||||
|
>
|
||||||
|
<span class="c-cs-button__label">Use Conditional Styling...</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<ul>
|
</template>
|
||||||
<li v-for="conditionStyle in conditionalStyles"
|
<template v-else>
|
||||||
:key="conditionStyle.conditionId"
|
<div class="c-inspect-styles__header">
|
||||||
|
Conditional Object Styles
|
||||||
|
</div>
|
||||||
|
<div class="c-inspect-styles__content c-inspect-styles__condition-set">
|
||||||
|
<a v-if="conditionSetDomainObject"
|
||||||
|
class="c-object-label icon-conditional"
|
||||||
|
:href="navigateToPath"
|
||||||
|
@click="navigateOrPreview"
|
||||||
>
|
>
|
||||||
<conditional-style :condition-style="conditionStyle"
|
<span class="c-object-label__name">{{ conditionSetDomainObject.name }}</span>
|
||||||
@persist="updateConditionalStyle"
|
</a>
|
||||||
|
<template v-if="isEditing">
|
||||||
|
<button
|
||||||
|
id="changeConditionSet"
|
||||||
|
class="c-button labeled"
|
||||||
|
@click="addConditionSet"
|
||||||
|
>
|
||||||
|
<span class="c-button__label">Change...</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button class="c-click-icon icon-x"
|
||||||
|
title="Remove conditional styles"
|
||||||
|
@click="removeConditionSet"
|
||||||
|
></button>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="conditionsLoaded"
|
||||||
|
class="c-inspect-styles__conditions"
|
||||||
|
>
|
||||||
|
<div v-for="(conditionStyle, index) in conditionalStyles"
|
||||||
|
:key="index"
|
||||||
|
class="c-inspect-styles__condition"
|
||||||
|
>
|
||||||
|
<condition-error :show-label="true"
|
||||||
|
:condition="getCondition(conditionStyle.conditionId)"
|
||||||
/>
|
/>
|
||||||
</li>
|
<condition-description :show-label="true"
|
||||||
</ul>
|
:condition="getCondition(conditionStyle.conditionId)"
|
||||||
</div>
|
/>
|
||||||
|
<style-editor class="c-inspect-styles__editor"
|
||||||
|
:style-item="conditionStyle"
|
||||||
|
:is-editing="isEditing"
|
||||||
|
@persist="updateConditionalStyle"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import ConditionalStyle from "./ConditionalStyle.vue";
|
import StyleEditor from "./StyleEditor.vue";
|
||||||
|
import ConditionSetSelectorDialog from "./ConditionSetSelectorDialog.vue";
|
||||||
|
import ConditionDescription from "@/plugins/condition/components/ConditionDescription.vue";
|
||||||
|
import ConditionError from "@/plugins/condition/components/ConditionError.vue";
|
||||||
|
import Vue from 'vue';
|
||||||
|
import PreviewAction from "@/ui/preview/PreviewAction.js";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
name: 'ConditionalStylesView',
|
||||||
components: {
|
components: {
|
||||||
ConditionalStyle
|
ConditionDescription,
|
||||||
|
ConditionError,
|
||||||
|
StyleEditor
|
||||||
},
|
},
|
||||||
inject: [
|
inject: [
|
||||||
'openmct',
|
'openmct',
|
||||||
@ -53,112 +127,204 @@ export default {
|
|||||||
default() {
|
default() {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
canHide: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
conditionalStyles: []
|
conditionalStyles: [],
|
||||||
|
staticStyle: undefined,
|
||||||
|
conditionSetDomainObject: undefined,
|
||||||
|
isEditing: this.openmct.editor.isEditing(),
|
||||||
|
conditions: undefined,
|
||||||
|
conditionsLoaded: false,
|
||||||
|
navigateToPath: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
destroyed() {
|
||||||
|
this.openmct.editor.off('isEditing', this.setEditState);
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
if (this.domainObject.configuration && this.domainObject.configuration.conditionalStyle) {
|
this.previewAction = new PreviewAction(this.openmct);
|
||||||
if (this.itemId) {
|
if (this.domainObject.configuration && this.domainObject.configuration.objectStyles) {
|
||||||
let conditionalStyle = this.domainObject.configuration.conditionalStyle[this.itemId];
|
let objectStyles = this.itemId ? this.domainObject.configuration.objectStyles[this.itemId] : this.domainObject.configuration.objectStyles;
|
||||||
if (conditionalStyle) {
|
this.initializeStaticStyle(objectStyles);
|
||||||
this.conditionalStyles = conditionalStyle.styles || [];
|
if (objectStyles && objectStyles.conditionSetIdentifier) {
|
||||||
}
|
this.openmct.objects.get(objectStyles.conditionSetIdentifier).then(this.initialize);
|
||||||
} else {
|
this.conditionalStyles = objectStyles.styles;
|
||||||
this.conditionalStyles = this.domainObject.configuration.conditionalStyle.styles || [];
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
this.initializeStaticStyle();
|
||||||
}
|
}
|
||||||
|
this.openmct.editor.on('isEditing', this.setEditState);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
addConditionSet() {
|
initialize(conditionSetDomainObject) {
|
||||||
//TODO: this.conditionSetIdentifier will be set by the UI before calling this
|
//If there are new conditions in the conditionSet we need to set those styles to default
|
||||||
this.conditionSetIdentifier = {
|
this.conditionSetDomainObject = conditionSetDomainObject;
|
||||||
namespace: '',
|
this.enableConditionSetNav();
|
||||||
key: "81088c8a-4b80-41fe-9d07-fda8b22d6f5f"
|
|
||||||
};
|
|
||||||
this.initializeConditionalStyles();
|
this.initializeConditionalStyles();
|
||||||
},
|
},
|
||||||
|
setEditState(isEditing) {
|
||||||
|
this.isEditing = isEditing;
|
||||||
|
},
|
||||||
|
addConditionSet() {
|
||||||
|
let conditionSetDomainObject;
|
||||||
|
const handleItemSelection = (item) => {
|
||||||
|
if (item) {
|
||||||
|
conditionSetDomainObject = item;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const dismissDialog = (overlay, initialize) => {
|
||||||
|
overlay.dismiss();
|
||||||
|
if (initialize && conditionSetDomainObject) {
|
||||||
|
this.conditionSetDomainObject = conditionSetDomainObject;
|
||||||
|
this.conditionalStyles = [];
|
||||||
|
this.initializeConditionalStyles();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let vm = new Vue({
|
||||||
|
provide: {
|
||||||
|
openmct: this.openmct
|
||||||
|
},
|
||||||
|
components: {ConditionSetSelectorDialog},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
handleItemSelection
|
||||||
|
}
|
||||||
|
},
|
||||||
|
template: '<condition-set-selector-dialog @conditionSetSelected="handleItemSelection"></condition-set-selector-dialog>'
|
||||||
|
}).$mount();
|
||||||
|
|
||||||
|
let overlay = this.openmct.overlays.overlay({
|
||||||
|
element: vm.$el,
|
||||||
|
size: 'small',
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
label: 'OK',
|
||||||
|
emphasis: 'true',
|
||||||
|
callback: () => dismissDialog(overlay, true)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Cancel',
|
||||||
|
callback: () => dismissDialog(overlay, false)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
onDestroy: () => vm.$destroy()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
enableConditionSetNav() {
|
||||||
|
this.openmct.objects.getOriginalPath(this.conditionSetDomainObject.identifier).then(
|
||||||
|
(objectPath) => {
|
||||||
|
this.objectPath = objectPath;
|
||||||
|
this.navigateToPath = '#/browse/' + this.objectPath
|
||||||
|
.map(o => o && this.openmct.objects.makeKeyString(o.identifier))
|
||||||
|
.reverse()
|
||||||
|
.join('/');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
navigateOrPreview(event) {
|
||||||
|
// If editing, display condition set in Preview overlay; otherwise nav to it while browsing
|
||||||
|
if (this.openmct.editor.isEditing()) {
|
||||||
|
event.preventDefault();
|
||||||
|
this.previewAction.invoke(this.objectPath);
|
||||||
|
}
|
||||||
|
},
|
||||||
removeConditionSet() {
|
removeConditionSet() {
|
||||||
//TODO: Handle the case where domainObject has items with styles but we're trying to remove the styles on the domainObject itself
|
this.conditionSetDomainObject = undefined;
|
||||||
this.conditionSetIdentifier = '';
|
|
||||||
this.conditionalStyles = [];
|
this.conditionalStyles = [];
|
||||||
let domainObjectConditionalStyle = (this.domainObject.configuration && this.domainObject.configuration.conditionalStyle) || {};
|
let domainObjectStyles = (this.domainObject.configuration && this.domainObject.configuration.objectStyles) || {};
|
||||||
if (domainObjectConditionalStyle) {
|
if (this.itemId) {
|
||||||
if (this.itemId) {
|
domainObjectStyles[this.itemId].conditionSetIdentifier = undefined;
|
||||||
domainObjectConditionalStyle[this.itemId] = undefined;
|
delete domainObjectStyles[this.itemId].conditionSetIdentifier;
|
||||||
delete domainObjectConditionalStyle[this.itemId];
|
domainObjectStyles[this.itemId].styles = undefined;
|
||||||
} else {
|
delete domainObjectStyles[this.itemId].styles;
|
||||||
domainObjectConditionalStyle.conditionSetIdentifier = undefined;
|
if (_.isEmpty(domainObjectStyles[this.itemId])) {
|
||||||
delete domainObjectConditionalStyle.conditionSetIdentifier;
|
delete domainObjectStyles[this.itemId];
|
||||||
domainObjectConditionalStyle.styles = undefined;
|
|
||||||
delete domainObjectConditionalStyle.styles;
|
|
||||||
}
|
|
||||||
if (_.isEmpty(domainObjectConditionalStyle)) {
|
|
||||||
domainObjectConditionalStyle = undefined;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
domainObjectStyles.conditionSetIdentifier = undefined;
|
||||||
|
delete domainObjectStyles.conditionSetIdentifier;
|
||||||
|
domainObjectStyles.styles = undefined;
|
||||||
|
delete domainObjectStyles.styles;
|
||||||
|
}
|
||||||
|
if (_.isEmpty(domainObjectStyles)) {
|
||||||
|
domainObjectStyles = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.persist(domainObjectConditionalStyle);
|
this.persist(domainObjectStyles);
|
||||||
|
|
||||||
},
|
},
|
||||||
initializeConditionalStyles() {
|
initializeConditionalStyles() {
|
||||||
this.openmct.objects.get(this.conditionSetIdentifier).then((conditionSetDomainObject) => {
|
if (!this.conditions) {
|
||||||
conditionSetDomainObject.configuration.conditionCollection.forEach((conditionConfiguration, index) => {
|
this.conditions = {};
|
||||||
this.conditionalStyles.push({
|
}
|
||||||
conditionId: conditionConfiguration.id,
|
this.conditionSetDomainObject.configuration.conditionCollection.forEach((conditionConfiguration, index) => {
|
||||||
conditionName: conditionConfiguration.name,
|
this.conditions[conditionConfiguration.id] = conditionConfiguration;
|
||||||
style: Object.assign({}, this.initialStyles)
|
let foundStyle = this.findStyleByConditionId(conditionConfiguration.id);
|
||||||
});
|
if (foundStyle) {
|
||||||
});
|
foundStyle.style = Object.assign((this.canHide ? { isStyleInvisible: '' } : {}), this.initialStyles, foundStyle.style);
|
||||||
let domainObjectConditionalStyle = (this.domainObject.configuration && this.domainObject.configuration.conditionalStyle) || {};
|
|
||||||
let conditionalStyle = {
|
|
||||||
conditionSetIdentifier: this.conditionSetIdentifier,
|
|
||||||
styles: this.conditionalStyles
|
|
||||||
};
|
|
||||||
if (this.itemId) {
|
|
||||||
this.persist({
|
|
||||||
...domainObjectConditionalStyle,
|
|
||||||
[this.itemId]: conditionalStyle
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
this.persist({
|
this.conditionalStyles.splice(index, 0, {
|
||||||
...domainObjectConditionalStyle,
|
conditionId: conditionConfiguration.id,
|
||||||
...conditionalStyle
|
style: Object.assign((this.canHide ? { isStyleInvisible: '' } : {}), this.initialStyles)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.conditionsLoaded = true;
|
||||||
|
this.persist(this.getDomainObjectConditionalStyle());
|
||||||
|
},
|
||||||
|
initializeStaticStyle(objectStyles) {
|
||||||
|
let staticStyle = objectStyles && objectStyles.staticStyle;
|
||||||
|
this.staticStyle = staticStyle || {
|
||||||
|
style: Object.assign({}, this.initialStyles)
|
||||||
|
};
|
||||||
},
|
},
|
||||||
findStyleByConditionId(id) {
|
findStyleByConditionId(id) {
|
||||||
return this.conditionalStyles.find(conditionalStyle => conditionalStyle.conditionId === id);
|
return this.conditionalStyles.find(conditionalStyle => conditionalStyle.conditionId === id);
|
||||||
},
|
},
|
||||||
|
updateStaticStyle(staticStyle) {
|
||||||
|
this.staticStyle = staticStyle;
|
||||||
|
this.persist(this.getDomainObjectConditionalStyle());
|
||||||
|
},
|
||||||
updateConditionalStyle(conditionStyle) {
|
updateConditionalStyle(conditionStyle) {
|
||||||
let found = this.findStyleByConditionId(conditionStyle.conditionId);
|
let found = this.findStyleByConditionId(conditionStyle.conditionId);
|
||||||
if (found) {
|
if (found) {
|
||||||
found.style = conditionStyle.style;
|
found.style = conditionStyle.style;
|
||||||
let domainObjectConditionalStyle = this.domainObject.configuration.conditionalStyle || {};
|
this.persist(this.getDomainObjectConditionalStyle());
|
||||||
|
|
||||||
if (this.itemId) {
|
|
||||||
let itemConditionalStyle = domainObjectConditionalStyle[this.itemId];
|
|
||||||
if (itemConditionalStyle) {
|
|
||||||
this.persist({
|
|
||||||
...domainObjectConditionalStyle,
|
|
||||||
[this.itemId]: {
|
|
||||||
...itemConditionalStyle,
|
|
||||||
styles: this.conditionalStyles
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
domainObjectConditionalStyle.styles = this.conditionalStyles;
|
|
||||||
this.persist(domainObjectConditionalStyle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
persist(conditionalStyle) {
|
getDomainObjectConditionalStyle() {
|
||||||
this.openmct.objects.mutate(this.domainObject, 'configuration.conditionalStyle', conditionalStyle);
|
let objectStyle = {
|
||||||
|
styles: this.conditionalStyles,
|
||||||
|
staticStyle: this.staticStyle
|
||||||
|
};
|
||||||
|
if (this.conditionSetDomainObject) {
|
||||||
|
objectStyle.conditionSetIdentifier = this.conditionSetDomainObject.identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
let domainObjectStyles = (this.domainObject.configuration && this.domainObject.configuration.objectStyles) || {};
|
||||||
|
|
||||||
|
if (this.itemId) {
|
||||||
|
domainObjectStyles[this.itemId] = objectStyle;
|
||||||
|
} else {
|
||||||
|
//we're deconstructing here to ensure that if an item within a domainObject already had a style we don't lose it
|
||||||
|
domainObjectStyles = {
|
||||||
|
...domainObjectStyles,
|
||||||
|
...objectStyle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return domainObjectStyles;
|
||||||
|
},
|
||||||
|
getCondition(id) {
|
||||||
|
return this.conditions ? this.conditions[id] : {};
|
||||||
|
},
|
||||||
|
persist(style) {
|
||||||
|
this.openmct.objects.mutate(this.domainObject, 'configuration.objectStyles', style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
179
src/plugins/condition/components/inspector/StyleEditor.vue
Normal file
179
src/plugins/condition/components/inspector/StyleEditor.vue
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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-style">
|
||||||
|
<span class="c-style-thumb"
|
||||||
|
:class="{ 'is-style-invisible': styleItem.style.isStyleInvisible }"
|
||||||
|
:style="[styleItem.style.imageUrl ? { backgroundImage:'url(' + styleItem.style.imageUrl + ')'} : styleItem.style ]"
|
||||||
|
>
|
||||||
|
<span class="c-style-thumb__text"
|
||||||
|
:class="{ 'hide-nice': !styleItem.style.color }"
|
||||||
|
>
|
||||||
|
ABC
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span class="c-toolbar">
|
||||||
|
<toolbar-color-picker v-if="styleItem.style.border"
|
||||||
|
class="c-style__toolbar-button--border-color u-menu-to--center"
|
||||||
|
:options="borderColorOption"
|
||||||
|
@change="updateStyleValue"
|
||||||
|
/>
|
||||||
|
<toolbar-color-picker v-if="styleItem.style.backgroundColor"
|
||||||
|
class="c-style__toolbar-button--background-color u-menu-to--center"
|
||||||
|
:options="backgroundColorOption"
|
||||||
|
@change="updateStyleValue"
|
||||||
|
/>
|
||||||
|
<toolbar-color-picker v-if="styleItem.style.color"
|
||||||
|
class="c-style__toolbar-button--color u-menu-to--center"
|
||||||
|
:options="colorOption"
|
||||||
|
@change="updateStyleValue"
|
||||||
|
/>
|
||||||
|
<toolbar-button v-if="styleItem.style.imageUrl !== undefined"
|
||||||
|
class="c-style__toolbar-button--image-url"
|
||||||
|
:options="imageUrlOption"
|
||||||
|
@change="updateStyleValue"
|
||||||
|
/>
|
||||||
|
<toolbar-toggle-button v-if="styleItem.style.isStyleInvisible !== undefined"
|
||||||
|
class="c-style__toolbar-button--toggle-visible"
|
||||||
|
:options="isStyleInvisibleOption"
|
||||||
|
@change="updateStyleValue"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import ToolbarColorPicker from "@/ui/toolbar/components/toolbar-color-picker.vue";
|
||||||
|
import ToolbarButton from "@/ui/toolbar/components/toolbar-button.vue";
|
||||||
|
import ToolbarToggleButton from "@/ui/toolbar/components/toolbar-toggle-button.vue";
|
||||||
|
import {STYLE_CONSTANTS} from "@/plugins/condition/utils/constants";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'StyleEditor',
|
||||||
|
components: {
|
||||||
|
ToolbarButton,
|
||||||
|
ToolbarColorPicker,
|
||||||
|
ToolbarToggleButton
|
||||||
|
},
|
||||||
|
inject: [
|
||||||
|
'openmct'
|
||||||
|
],
|
||||||
|
props: {
|
||||||
|
isEditing: {
|
||||||
|
type: Boolean
|
||||||
|
},
|
||||||
|
styleItem: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
borderColorOption() {
|
||||||
|
return {
|
||||||
|
icon: 'icon-line-horz',
|
||||||
|
title: STYLE_CONSTANTS.borderColorTitle,
|
||||||
|
value: this.styleItem.style.border.replace('1px solid ', ''),
|
||||||
|
property: 'border',
|
||||||
|
isEditing: this.isEditing
|
||||||
|
}
|
||||||
|
},
|
||||||
|
backgroundColorOption() {
|
||||||
|
return {
|
||||||
|
icon: 'icon-paint-bucket',
|
||||||
|
title: STYLE_CONSTANTS.backgroundColorTitle,
|
||||||
|
value: this.styleItem.style.backgroundColor,
|
||||||
|
property: 'backgroundColor',
|
||||||
|
isEditing: this.isEditing
|
||||||
|
}
|
||||||
|
},
|
||||||
|
colorOption() {
|
||||||
|
return {
|
||||||
|
icon: 'icon-font',
|
||||||
|
title: STYLE_CONSTANTS.textColorTitle,
|
||||||
|
value: this.styleItem.style.color,
|
||||||
|
property: 'color',
|
||||||
|
isEditing: this.isEditing
|
||||||
|
}
|
||||||
|
},
|
||||||
|
imageUrlOption() {
|
||||||
|
return {
|
||||||
|
icon: 'icon-image',
|
||||||
|
title: STYLE_CONSTANTS.imagePropertiesTitle,
|
||||||
|
dialog: {
|
||||||
|
name: "Image Properties",
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
rows: [
|
||||||
|
{
|
||||||
|
key: "url",
|
||||||
|
control: "textfield",
|
||||||
|
name: "Image URL",
|
||||||
|
"cssClass": "l-input-lg"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
property: 'imageUrl',
|
||||||
|
formKeys: ['url'],
|
||||||
|
value: {url: this.styleItem.style.imageUrl},
|
||||||
|
isEditing: this.isEditing
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isStyleInvisibleOption() {
|
||||||
|
return {
|
||||||
|
value: this.styleItem.style.isStyleInvisible,
|
||||||
|
property: 'isStyleInvisible',
|
||||||
|
isEditing: this.isEditing,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: '',
|
||||||
|
icon: 'icon-eye-disabled',
|
||||||
|
title: STYLE_CONSTANTS.visibilityHidden
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: STYLE_CONSTANTS.isStyleInvisible,
|
||||||
|
icon: 'icon-eye-open',
|
||||||
|
title: STYLE_CONSTANTS.visibilityVisible
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
updateStyleValue(value, item) {
|
||||||
|
if (item.property === 'border') {
|
||||||
|
value = '1px solid ' + value;
|
||||||
|
}
|
||||||
|
if (value && (value.url !== undefined)) {
|
||||||
|
this.styleItem.style[item.property] = value.url;
|
||||||
|
} else {
|
||||||
|
this.styleItem.style[item.property] = value;
|
||||||
|
}
|
||||||
|
this.$emit('persist', this.styleItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -0,0 +1,100 @@
|
|||||||
|
/********************************************* INSPECTOR STYLES TAB */
|
||||||
|
.c-inspect-styles {
|
||||||
|
> * + * {
|
||||||
|
margin-top: $interiorMargin;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content,
|
||||||
|
&__conditions,
|
||||||
|
&__condition {
|
||||||
|
> * + * {
|
||||||
|
margin-top: $interiorMargin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__condition-set {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.c-object-label {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-button {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__style,
|
||||||
|
&__condition {
|
||||||
|
padding: $interiorMargin;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__condition {
|
||||||
|
@include discreteItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-style {
|
||||||
|
padding: 2px; // Allow a bit of room for thumb box-shadow
|
||||||
|
|
||||||
|
&__condition-desc {
|
||||||
|
@include ellipsize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-inspect-styles__style {
|
||||||
|
.is-editing & {
|
||||||
|
border-bottom: 1px solid $colorInteriorBorder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.l-shell:not(.is-editing) .c-inspect-styles {
|
||||||
|
.c-toolbar {
|
||||||
|
// Disabled-look toolbar when not editing
|
||||||
|
pointer-events: none;
|
||||||
|
cursor: inherit;
|
||||||
|
|
||||||
|
// Hide control buttons, like image URL
|
||||||
|
[class*='--image-url'] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make buttons look disabled by knocking back icon, not swatch element
|
||||||
|
.c-icon-button {
|
||||||
|
&:before {
|
||||||
|
opacity: $controlDisabledOpacity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-toggle-styling-button {
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
.is-editing & {
|
||||||
|
display: block;
|
||||||
|
align-self: flex-end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-style-invisible {
|
||||||
|
display: none !important;
|
||||||
|
|
||||||
|
.is-editing & {
|
||||||
|
display: block !important;
|
||||||
|
opacity: 0.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.c-style-thumb {
|
||||||
|
display: block !important;
|
||||||
|
@include bgCheckerboard($size: 10px, $imp: true);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
@ -44,33 +44,37 @@ export default class TelemetryCriterion extends EventEmitter {
|
|||||||
this.operation = telemetryDomainObjectDefinition.operation;
|
this.operation = telemetryDomainObjectDefinition.operation;
|
||||||
this.input = telemetryDomainObjectDefinition.input;
|
this.input = telemetryDomainObjectDefinition.input;
|
||||||
this.metadata = telemetryDomainObjectDefinition.metadata;
|
this.metadata = telemetryDomainObjectDefinition.metadata;
|
||||||
this.subscription = null;
|
this.telemetryObjectIdAsString = undefined;
|
||||||
this.telemetryObjectIdAsString = null;
|
|
||||||
this.objectAPI.get(this.objectAPI.makeKeyString(this.telemetry)).then((obj) => this.initialize(obj));
|
this.objectAPI.get(this.objectAPI.makeKeyString(this.telemetry)).then((obj) => this.initialize(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize(obj) {
|
initialize(obj) {
|
||||||
this.telemetryObject = obj;
|
this.telemetryObject = obj;
|
||||||
this.telemetryMetaData = this.openmct.telemetry.getMetadata(obj).valueMetadatas;
|
this.telemetryMetaData = this.openmct.telemetry.getMetadata(obj).valueMetadatas;
|
||||||
this.telemetryObjectIdAsString = this.objectAPI.makeKeyString(this.telemetryObject.identifier);
|
this.telemetryObjectIdAsString = this.objectAPI.makeKeyString(this.telemetry);
|
||||||
|
this.on(`subscription:${this.telemetryObjectIdAsString}`, this.handleSubscription);
|
||||||
this.emitEvent('criterionUpdated', this);
|
this.emitEvent('criterionUpdated', this);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSubscription(data) {
|
formatData(data) {
|
||||||
if (data) {
|
const normalizedDatum = this.createNormalizedDatum(data);
|
||||||
data = this.createNormalizedDatum(data);
|
|
||||||
}
|
|
||||||
const datum = {
|
const datum = {
|
||||||
result: this.computeResult(data)
|
result: this.computeResult(normalizedDatum)
|
||||||
};
|
|
||||||
if (data) {
|
|
||||||
// TODO check back to see if we should format times here
|
|
||||||
this.timeAPI.getAllTimeSystems().forEach(timeSystem => {
|
|
||||||
datum[timeSystem.key] = data[timeSystem.key]
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.emitEvent('criterionResultUpdated', datum);
|
if (normalizedDatum) {
|
||||||
|
// TODO check back to see if we should format times here
|
||||||
|
this.timeAPI.getAllTimeSystems().forEach(timeSystem => {
|
||||||
|
datum[timeSystem.key] = normalizedDatum[timeSystem.key]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return datum;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSubscription(data) {
|
||||||
|
if(this.isValid()) {
|
||||||
|
this.emitEvent('criterionResultUpdated', this.formatData(data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createNormalizedDatum(telemetryDatum) {
|
createNormalizedDatum(telemetryDatum) {
|
||||||
@ -116,34 +120,33 @@ export default class TelemetryCriterion extends EventEmitter {
|
|||||||
return this.telemetryObject && this.metadata && this.operation;
|
return this.telemetryObject && this.metadata && this.operation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
requestLAD(options) {
|
||||||
* Subscribes to the telemetry object and returns an unsubscribe function
|
options = Object.assign({},
|
||||||
* If the telemetry is not valid, returns nothing
|
options,
|
||||||
*/
|
{
|
||||||
subscribe() {
|
strategy: 'latest',
|
||||||
if (this.isValid()) {
|
size: 1
|
||||||
this.unsubscribe();
|
}
|
||||||
this.subscription = this.telemetryAPI.subscribe(this.telemetryObject, (datum) => {
|
);
|
||||||
this.handleSubscription(datum);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.handleSubscription();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
if (!this.isValid()) {
|
||||||
* Calls an unsubscribe function returned by subscribe() and deletes any initialized data
|
return this.formatData({});
|
||||||
*/
|
|
||||||
unsubscribe() {
|
|
||||||
//unsubscribe from telemetry source
|
|
||||||
if (typeof this.subscription === 'function') {
|
|
||||||
this.subscription();
|
|
||||||
}
|
}
|
||||||
delete this.subscription;
|
|
||||||
|
return this.telemetryAPI.request(
|
||||||
|
this.telemetryObject,
|
||||||
|
options
|
||||||
|
).then(results => {
|
||||||
|
const latestDatum = results.length ? results[results.length - 1] : {};
|
||||||
|
return {
|
||||||
|
id: this.id,
|
||||||
|
data: this.formatData(latestDatum)
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
this.unsubscribe();
|
this.off(`subscription:${this.telemetryObjectIdAsString}`, this.handleSubscription);
|
||||||
this.emitEvent('criterionRemoved');
|
this.emitEvent('criterionRemoved');
|
||||||
delete this.telemetryObjectIdAsString;
|
delete this.telemetryObjectIdAsString;
|
||||||
delete this.telemetryObject;
|
delete this.telemetryObject;
|
||||||
|
@ -78,7 +78,9 @@ describe("The telemetry criterion", function () {
|
|||||||
|
|
||||||
testCriterionDefinition = {
|
testCriterionDefinition = {
|
||||||
id: 'test-criterion-id',
|
id: 'test-criterion-id',
|
||||||
telemetry: openmct.objects.makeKeyString(testTelemetryObject.identifier)
|
telemetry: openmct.objects.makeKeyString(testTelemetryObject.identifier),
|
||||||
|
operation: 'lessThan',
|
||||||
|
metadata: 'sin'
|
||||||
};
|
};
|
||||||
|
|
||||||
mockListener = jasmine.createSpy('listener');
|
mockListener = jasmine.createSpy('listener');
|
||||||
@ -102,12 +104,7 @@ describe("The telemetry criterion", function () {
|
|||||||
expect(mockListener2).toHaveBeenCalled();
|
expect(mockListener2).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("subscribes to telemetry providers", function () {
|
it("updates and emits event on new data from telemetry providers", function () {
|
||||||
telemetryCriterion.subscribe();
|
|
||||||
expect(telemetryCriterion.subscription).toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("emits update event on new data from telemetry providers", function () {
|
|
||||||
telemetryCriterion.initialize(testTelemetryObject);
|
telemetryCriterion.initialize(testTelemetryObject);
|
||||||
spyOn(telemetryCriterion, 'emitEvent').and.callThrough();
|
spyOn(telemetryCriterion, 'emitEvent').and.callThrough();
|
||||||
telemetryCriterion.handleSubscription({
|
telemetryCriterion.handleSubscription({
|
||||||
@ -115,16 +112,5 @@ describe("The telemetry criterion", function () {
|
|||||||
utc: 'Hi'
|
utc: 'Hi'
|
||||||
});
|
});
|
||||||
expect(telemetryCriterion.emitEvent).toHaveBeenCalled();
|
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();
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -23,6 +23,7 @@ import ConditionSetViewProvider from './ConditionSetViewProvider.js';
|
|||||||
import ConditionSetCompositionPolicy from "./ConditionSetCompositionPolicy";
|
import ConditionSetCompositionPolicy from "./ConditionSetCompositionPolicy";
|
||||||
import ConditionSetMetadataProvider from './ConditionSetMetadataProvider';
|
import ConditionSetMetadataProvider from './ConditionSetMetadataProvider';
|
||||||
import ConditionSetTelemetryProvider from './ConditionSetTelemetryProvider';
|
import ConditionSetTelemetryProvider from './ConditionSetTelemetryProvider';
|
||||||
|
import ConditionSetViewPolicy from './ConditionSetViewPolicy';
|
||||||
import uuid from "uuid";
|
import uuid from "uuid";
|
||||||
|
|
||||||
export default function ConditionPlugin() {
|
export default function ConditionPlugin() {
|
||||||
@ -34,7 +35,7 @@ export default function ConditionPlugin() {
|
|||||||
key: 'conditionSet',
|
key: 'conditionSet',
|
||||||
description: 'A set of one or more conditions based on user-specified criteria.',
|
description: 'A set of one or more conditions based on user-specified criteria.',
|
||||||
creatable: true,
|
creatable: true,
|
||||||
cssClass: 'icon-conditional', // TODO: replace with class for new icon
|
cssClass: 'icon-conditional',
|
||||||
initialize: function (domainObject) {
|
initialize: function (domainObject) {
|
||||||
domainObject.configuration = {
|
domainObject.configuration = {
|
||||||
conditionCollection: [{
|
conditionCollection: [{
|
||||||
@ -53,7 +54,10 @@ export default function ConditionPlugin() {
|
|||||||
domainObject.telemetry = {};
|
domainObject.telemetry = {};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
openmct.legacyExtension('policies', {
|
||||||
|
category: 'view',
|
||||||
|
implementation: ConditionSetViewPolicy
|
||||||
|
});
|
||||||
openmct.composition.addPolicy(new ConditionSetCompositionPolicy(openmct).allow);
|
openmct.composition.addPolicy(new ConditionSetCompositionPolicy(openmct).allow);
|
||||||
openmct.telemetry.addProvider(new ConditionSetMetadataProvider(openmct));
|
openmct.telemetry.addProvider(new ConditionSetMetadataProvider(openmct));
|
||||||
openmct.telemetry.addProvider(new ConditionSetTelemetryProvider(openmct));
|
openmct.telemetry.addProvider(new ConditionSetTelemetryProvider(openmct));
|
||||||
|
@ -82,7 +82,10 @@ describe('the plugin', function () {
|
|||||||
it('provides a view', () => {
|
it('provides a view', () => {
|
||||||
const testViewObject = {
|
const testViewObject = {
|
||||||
id:"test-object",
|
id:"test-object",
|
||||||
type: "conditionSet"
|
type: "conditionSet",
|
||||||
|
configuration: {
|
||||||
|
conditionCollection: []
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const applicableViews = openmct.objectViews.get(testViewObject);
|
const applicableViews = openmct.objectViews.get(testViewObject);
|
||||||
|
@ -2,3 +2,22 @@ export const TRIGGER = {
|
|||||||
ANY: 'any',
|
ANY: 'any',
|
||||||
ALL: 'all'
|
ALL: 'all'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const STYLE_CONSTANTS = {
|
||||||
|
isStyleInvisible: 'is-style-invisible',
|
||||||
|
borderColorTitle: 'Set border color',
|
||||||
|
textColorTitle: 'Set text color',
|
||||||
|
backgroundColorTitle: 'Set background color',
|
||||||
|
imagePropertiesTitle: 'Edit image properties',
|
||||||
|
visibilityHidden: 'Hidden',
|
||||||
|
visibilityVisible: 'Visible'
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ERROR = {
|
||||||
|
'TELEMETRY_NOT_FOUND': {
|
||||||
|
errorText: 'Telemetry not found for criterion'
|
||||||
|
},
|
||||||
|
'CONDITION_NOT_FOUND': {
|
||||||
|
errorText: 'Condition not found'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -8,7 +8,7 @@ export const OPERATIONS = [
|
|||||||
appliesTo: ['number'],
|
appliesTo: ['number'],
|
||||||
inputCount: 1,
|
inputCount: 1,
|
||||||
getDescription: function (values) {
|
getDescription: function (values) {
|
||||||
return ' is ' + values[0];
|
return ' is ' + values.join(', ');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -20,7 +20,7 @@ export const OPERATIONS = [
|
|||||||
appliesTo: ['number'],
|
appliesTo: ['number'],
|
||||||
inputCount: 1,
|
inputCount: 1,
|
||||||
getDescription: function (values) {
|
getDescription: function (values) {
|
||||||
return ' is not ' + values[0];
|
return ' is not ' + values.join(', ');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -32,7 +32,7 @@ export const OPERATIONS = [
|
|||||||
appliesTo: ['number'],
|
appliesTo: ['number'],
|
||||||
inputCount: 1,
|
inputCount: 1,
|
||||||
getDescription: function (values) {
|
getDescription: function (values) {
|
||||||
return ' > ' + values[0];
|
return ' > ' + values.join(', ');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -44,7 +44,7 @@ export const OPERATIONS = [
|
|||||||
appliesTo: ['number'],
|
appliesTo: ['number'],
|
||||||
inputCount: 1,
|
inputCount: 1,
|
||||||
getDescription: function (values) {
|
getDescription: function (values) {
|
||||||
return ' < ' + values[0];
|
return ' < ' + values.join(', ');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -56,7 +56,7 @@ export const OPERATIONS = [
|
|||||||
appliesTo: ['number'],
|
appliesTo: ['number'],
|
||||||
inputCount: 1,
|
inputCount: 1,
|
||||||
getDescription: function (values) {
|
getDescription: function (values) {
|
||||||
return ' >= ' + values[0];
|
return ' >= ' + values.join(', ');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -68,7 +68,7 @@ export const OPERATIONS = [
|
|||||||
appliesTo: ['number'],
|
appliesTo: ['number'],
|
||||||
inputCount: 1,
|
inputCount: 1,
|
||||||
getDescription: function (values) {
|
getDescription: function (values) {
|
||||||
return ' <= ' + values[0];
|
return ' <= ' + values.join(', ');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -80,7 +80,7 @@ export const OPERATIONS = [
|
|||||||
appliesTo: ['number'],
|
appliesTo: ['number'],
|
||||||
inputCount: 2,
|
inputCount: 2,
|
||||||
getDescription: function (values) {
|
getDescription: function (values) {
|
||||||
return ' is between ' + values[0] + ' and ' + values[1];
|
return ' is between ' + values.join(', ') + ' and ' + values[1];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -92,7 +92,7 @@ export const OPERATIONS = [
|
|||||||
appliesTo: ['number'],
|
appliesTo: ['number'],
|
||||||
inputCount: 2,
|
inputCount: 2,
|
||||||
getDescription: function (values) {
|
getDescription: function (values) {
|
||||||
return ' is not between ' + values[0] + ' and ' + values[1];
|
return ' is not between ' + values.join(', ') + ' and ' + values[1];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -104,7 +104,7 @@ export const OPERATIONS = [
|
|||||||
appliesTo: ['string'],
|
appliesTo: ['string'],
|
||||||
inputCount: 1,
|
inputCount: 1,
|
||||||
getDescription: function (values) {
|
getDescription: function (values) {
|
||||||
return ' contains ' + values[0];
|
return ' contains ' + values.join(', ');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -116,7 +116,7 @@ export const OPERATIONS = [
|
|||||||
appliesTo: ['string'],
|
appliesTo: ['string'],
|
||||||
inputCount: 1,
|
inputCount: 1,
|
||||||
getDescription: function (values) {
|
getDescription: function (values) {
|
||||||
return ' does not contain ' + values[0];
|
return ' does not contain ' + values.join(', ');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -128,7 +128,7 @@ export const OPERATIONS = [
|
|||||||
appliesTo: ['string'],
|
appliesTo: ['string'],
|
||||||
inputCount: 1,
|
inputCount: 1,
|
||||||
getDescription: function (values) {
|
getDescription: function (values) {
|
||||||
return ' starts with ' + values[0];
|
return ' starts with ' + values.join(', ');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -140,7 +140,7 @@ export const OPERATIONS = [
|
|||||||
appliesTo: ['string'],
|
appliesTo: ['string'],
|
||||||
inputCount: 1,
|
inputCount: 1,
|
||||||
getDescription: function (values) {
|
getDescription: function (values) {
|
||||||
return ' ends with ' + values[0];
|
return ' ends with ' + values.join(', ');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -152,7 +152,7 @@ export const OPERATIONS = [
|
|||||||
appliesTo: ['string'],
|
appliesTo: ['string'],
|
||||||
inputCount: 1,
|
inputCount: 1,
|
||||||
getDescription: function (values) {
|
getDescription: function (values) {
|
||||||
return ' is exactly ' + values[0];
|
return ' is exactly ' + values.join(', ');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -188,7 +188,7 @@ export const OPERATIONS = [
|
|||||||
appliesTo: ['enum'],
|
appliesTo: ['enum'],
|
||||||
inputCount: 1,
|
inputCount: 1,
|
||||||
getDescription: function (values) {
|
getDescription: function (values) {
|
||||||
return ' is ' + values[0];
|
return ' is ' + values.join(', ');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -200,7 +200,7 @@ export const OPERATIONS = [
|
|||||||
appliesTo: ['enum'],
|
appliesTo: ['enum'],
|
||||||
inputCount: 1,
|
inputCount: 1,
|
||||||
getDescription: function (values) {
|
getDescription: function (values) {
|
||||||
return ' is not ' + values[0];
|
return ' is not ' + values.join(', ');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -2,15 +2,19 @@ export const getStyleProp = (key, defaultValue) => {
|
|||||||
let styleProp = undefined;
|
let styleProp = undefined;
|
||||||
switch(key) {
|
switch(key) {
|
||||||
case 'fill': styleProp = {
|
case 'fill': styleProp = {
|
||||||
backgroundColor: defaultValue || 'none'
|
backgroundColor: defaultValue || 'transparent'
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case 'stroke': styleProp = {
|
case 'stroke': styleProp = {
|
||||||
border: '1px solid ' + defaultValue || 'none'
|
border: '1px solid ' + (defaultValue || 'transparent')
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case 'color': styleProp = {
|
case 'color': styleProp = {
|
||||||
color: defaultValue || 'inherit'
|
color: defaultValue || 'transparent'
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case 'url': styleProp = {
|
||||||
|
imageUrl: defaultValue || 'transparent'
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -23,20 +23,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
v-if="isEditing"
|
v-if="isEditing"
|
||||||
class="c-properties"
|
class="c-inspect-properties"
|
||||||
>
|
>
|
||||||
<div class="c-properties__header">
|
<div class="c-inspect-properties__header">
|
||||||
Alphanumeric Format
|
Alphanumeric Format
|
||||||
</div>
|
</div>
|
||||||
<ul class="c-properties__section">
|
<ul class="c-inspect-properties__section">
|
||||||
<li class="c-properties__row">
|
<li class="c-inspect-properties__row">
|
||||||
<div
|
<div
|
||||||
class="c-properties__label"
|
class="c-inspect-properties__label"
|
||||||
title="Printf formatting for the selected telemetry"
|
title="Printf formatting for the selected telemetry"
|
||||||
>
|
>
|
||||||
<label for="telemetryPrintfFormat">Format</label>
|
<label for="telemetryPrintfFormat">Format</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="c-properties__value">
|
<div class="c-inspect-properties__value">
|
||||||
<input
|
<input
|
||||||
id="telemetryPrintfFormat"
|
id="telemetryPrintfFormat"
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="c-box-view"
|
class="c-box-view"
|
||||||
|
:class="[styleClass]"
|
||||||
:style="style"
|
:style="style"
|
||||||
></div>
|
></div>
|
||||||
</layout-frame>
|
</layout-frame>
|
||||||
@ -36,7 +37,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import LayoutFrame from './LayoutFrame.vue'
|
import LayoutFrame from './LayoutFrame.vue'
|
||||||
import conditionalStylesMixin from '../mixins/conditionalStyles-mixin';
|
import conditionalStylesMixin from '../mixins/objectlStyles-mixin';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
makeDefinition() {
|
makeDefinition() {
|
||||||
@ -73,14 +74,13 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
style() {
|
style() {
|
||||||
if (this.itemStyle) {
|
return Object.assign({
|
||||||
return this.itemStyle;
|
backgroundColor: this.item.fill,
|
||||||
} else {
|
border: '1px solid ' + this.item.stroke
|
||||||
return {
|
}, this.itemStyle);
|
||||||
backgroundColor: this.item.fill,
|
},
|
||||||
border: '1px solid ' + this.item.stroke
|
styleClass() {
|
||||||
};
|
return this.itemStyle && this.itemStyle.isStyleInvisible;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="c-image-view"
|
class="c-image-view"
|
||||||
|
:class="[styleClass]"
|
||||||
:style="style"
|
:style="style"
|
||||||
></div>
|
></div>
|
||||||
</layout-frame>
|
</layout-frame>
|
||||||
@ -36,7 +37,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import LayoutFrame from './LayoutFrame.vue'
|
import LayoutFrame from './LayoutFrame.vue'
|
||||||
import conditionalStylesMixin from "../mixins/conditionalStyles-mixin";
|
import conditionalStylesMixin from "../mixins/objectlStyles-mixin";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
makeDefinition(openmct, gridSize, element) {
|
makeDefinition(openmct, gridSize, element) {
|
||||||
@ -74,9 +75,12 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
style() {
|
style() {
|
||||||
return {
|
return {
|
||||||
backgroundImage: 'url(' + this.item.url + ')',
|
backgroundImage: this.itemStyle ? ('url(' + this.itemStyle.imageUrl + ')') : 'url(' + this.item.url + ')',
|
||||||
border: this.itemStyle ? this.itemStyle.border : '1px solid ' + this.item.stroke
|
border: (this.itemStyle && this.itemStyle.border) ? this.itemStyle.border : ('1px solid ' + this.item.stroke)
|
||||||
}
|
};
|
||||||
|
},
|
||||||
|
styleClass() {
|
||||||
|
return this.itemStyle && this.itemStyle.isStyleInvisible;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="l-layout__frame c-frame no-frame"
|
class="l-layout__frame c-frame no-frame"
|
||||||
|
:class="[styleClass]"
|
||||||
:style="style"
|
:style="style"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@ -60,7 +61,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import conditionalStylesMixin from "../mixins/conditionalStyles-mixin";
|
import conditionalStylesMixin from "../mixins/objectlStyles-mixin";
|
||||||
|
|
||||||
const START_HANDLE_QUADRANTS = {
|
const START_HANDLE_QUADRANTS = {
|
||||||
1: 'c-frame-edit__handle--sw',
|
1: 'c-frame-edit__handle--sw',
|
||||||
@ -145,6 +146,9 @@ export default {
|
|||||||
height: `${height}px`
|
height: `${height}px`
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
styleClass() {
|
||||||
|
return this.itemStyle && this.itemStyle.isStyleInvisible;
|
||||||
|
},
|
||||||
startHandleClass() {
|
startHandleClass() {
|
||||||
return START_HANDLE_QUADRANTS[this.vectorQuadrant];
|
return START_HANDLE_QUADRANTS[this.vectorQuadrant];
|
||||||
},
|
},
|
||||||
|
@ -36,7 +36,8 @@
|
|||||||
<div
|
<div
|
||||||
v-if="showLabel"
|
v-if="showLabel"
|
||||||
class="c-telemetry-view__label"
|
class="c-telemetry-view__label"
|
||||||
:style="conditionalStyle"
|
:class="[styleClass]"
|
||||||
|
:style="objectStyle"
|
||||||
>
|
>
|
||||||
<div class="c-telemetry-view__label-text">
|
<div class="c-telemetry-view__label-text">
|
||||||
{{ domainObject.name }}
|
{{ domainObject.name }}
|
||||||
@ -47,8 +48,8 @@
|
|||||||
v-if="showValue"
|
v-if="showValue"
|
||||||
:title="fieldName"
|
:title="fieldName"
|
||||||
class="c-telemetry-view__value"
|
class="c-telemetry-view__value"
|
||||||
:class="[telemetryClass]"
|
:class="[telemetryClass, !telemetryClass && styleClass]"
|
||||||
:style="!telemetryClass && conditionalStyle"
|
:style="!telemetryClass && objectStyle"
|
||||||
>
|
>
|
||||||
<div class="c-telemetry-view__value-text">
|
<div class="c-telemetry-view__value-text">
|
||||||
{{ telemetryValue }}
|
{{ telemetryValue }}
|
||||||
@ -113,7 +114,7 @@ export default {
|
|||||||
formats: undefined,
|
formats: undefined,
|
||||||
domainObject: undefined,
|
domainObject: undefined,
|
||||||
currentObjectPath: undefined,
|
currentObjectPath: undefined,
|
||||||
conditionalStyle: ''
|
objectStyle: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -133,6 +134,9 @@ export default {
|
|||||||
fontSize: this.item.size
|
fontSize: this.item.size
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
styleClass() {
|
||||||
|
return this.objectStyle && this.objectStyle.isStyleInvisible;
|
||||||
|
},
|
||||||
fieldName() {
|
fieldName() {
|
||||||
return this.valueMetadata && this.valueMetadata.name;
|
return this.valueMetadata && this.valueMetadata.name;
|
||||||
},
|
},
|
||||||
@ -192,7 +196,6 @@ export default {
|
|||||||
|
|
||||||
if (this.styleRuleManager) {
|
if (this.styleRuleManager) {
|
||||||
this.styleRuleManager.destroy();
|
this.styleRuleManager.destroy();
|
||||||
this.styleRuleManager.off('conditionalStyleUpdated', this.updateStyle.bind(this));
|
|
||||||
delete this.styleRuleManager;
|
delete this.styleRuleManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,7 +241,7 @@ export default {
|
|||||||
},
|
},
|
||||||
setObject(domainObject) {
|
setObject(domainObject) {
|
||||||
this.domainObject = domainObject;
|
this.domainObject = domainObject;
|
||||||
this.initConditionalStyles();
|
this.initObjectStyles();
|
||||||
this.keyString = this.openmct.objects.makeKeyString(domainObject.identifier);
|
this.keyString = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||||
this.metadata = this.openmct.telemetry.getMetadata(this.domainObject);
|
this.metadata = this.openmct.telemetry.getMetadata(this.domainObject);
|
||||||
this.limitEvaluator = this.openmct.telemetry.limitEvaluator(this.domainObject);
|
this.limitEvaluator = this.openmct.telemetry.limitEvaluator(this.domainObject);
|
||||||
@ -264,20 +267,27 @@ export default {
|
|||||||
showContextMenu(event) {
|
showContextMenu(event) {
|
||||||
this.openmct.contextMenu._showContextMenuForObjectPath(this.currentObjectPath, event.x, event.y, CONTEXT_MENU_ACTIONS);
|
this.openmct.contextMenu._showContextMenuForObjectPath(this.currentObjectPath, event.x, event.y, CONTEXT_MENU_ACTIONS);
|
||||||
},
|
},
|
||||||
initConditionalStyles() {
|
initObjectStyles() {
|
||||||
this.styleRuleManager = new StyleRuleManager(this.domainObject.configuration.conditionalStyle, this.openmct);
|
this.styleRuleManager = new StyleRuleManager(this.domainObject.configuration.objectStyles, this.openmct, this.updateStyle.bind(this));
|
||||||
this.styleRuleManager.on('conditionalStyleUpdated', this.updateStyle.bind(this));
|
|
||||||
|
|
||||||
if (this.unlistenStyles) {
|
if (this.unlistenStyles) {
|
||||||
this.unlistenStyles();
|
this.unlistenStyles();
|
||||||
}
|
}
|
||||||
this.unlistenStyles = this.openmct.objects.observe(this.domainObject, 'configuration.conditionalStyle', (newConditionalStyle) => {
|
this.unlistenStyles = this.openmct.objects.observe(this.domainObject, 'configuration.objectStyles', (newObjectStyle) => {
|
||||||
//Updating conditional styles in the inspector view will trigger this so that the changes are reflected immediately
|
//Updating object styles in the inspector view will trigger this so that the changes are reflected immediately
|
||||||
this.styleRuleManager.updateConditionalStyleConfig(newConditionalStyle);
|
this.styleRuleManager.updateObjectStyleConfig(newObjectStyle);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
updateStyle(styleObj) {
|
updateStyle(styleObj) {
|
||||||
this.conditionalStyle = styleObj;
|
let keys = Object.keys(styleObj);
|
||||||
|
keys.forEach(key => {
|
||||||
|
if ((typeof styleObj[key] === 'string') && (styleObj[key].indexOf('transparent') > -1)) {
|
||||||
|
if (styleObj[key]) {
|
||||||
|
styleObj[key] = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.objectStyle = styleObj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="c-text-view"
|
class="c-text-view"
|
||||||
|
:class="[styleClass]"
|
||||||
:style="style"
|
:style="style"
|
||||||
>
|
>
|
||||||
{{ item.text }}
|
{{ item.text }}
|
||||||
@ -38,7 +39,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import LayoutFrame from './LayoutFrame.vue'
|
import LayoutFrame from './LayoutFrame.vue'
|
||||||
import conditionalStylesMixin from "../mixins/conditionalStyles-mixin";
|
import conditionalStylesMixin from "../mixins/objectlStyles-mixin";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
makeDefinition(openmct, gridSize, element) {
|
makeDefinition(openmct, gridSize, element) {
|
||||||
@ -78,16 +79,15 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
style() {
|
style() {
|
||||||
if (this.itemStyle) {
|
return Object.assign({
|
||||||
return this.itemStyle;
|
backgroundColor: this.item.fill,
|
||||||
} else {
|
border: '1px solid ' + this.item.stroke,
|
||||||
return {
|
color: this.item.color,
|
||||||
backgroundColor: this.item.fill,
|
fontSize: this.item.size
|
||||||
borderColor: this.item.stroke,
|
}, this.itemStyle);
|
||||||
color: this.item.color,
|
},
|
||||||
fontSize: this.item.size
|
styleClass() {
|
||||||
};
|
return this.itemStyle && this.itemStyle.isStyleInvisible;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -1,54 +0,0 @@
|
|||||||
import StyleRuleManager from "@/plugins/condition/StyleRuleManager";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
inject: ['openmct'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
itemStyle: this.itemStyle
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.domainObject = this.$parent.domainObject;
|
|
||||||
this.itemId = this.item.id;
|
|
||||||
this.conditionalStyle = this.getConditionalStyleForItem(this.domainObject.configuration.conditionalStyle);
|
|
||||||
this.initConditionalStyles();
|
|
||||||
},
|
|
||||||
destroyed() {
|
|
||||||
if (this.stopListeningConditionalStyles) {
|
|
||||||
this.stopListeningConditionalStyles();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getConditionalStyleForItem(conditionalStyle) {
|
|
||||||
if (conditionalStyle) {
|
|
||||||
return conditionalStyle[this.itemId];
|
|
||||||
} else {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
initConditionalStyles() {
|
|
||||||
if (!this.styleRuleManager) {
|
|
||||||
this.styleRuleManager = new StyleRuleManager(this.conditionalStyle, this.openmct);
|
|
||||||
this.styleRuleManager.on('conditionalStyleUpdated', this.updateStyle.bind(this));
|
|
||||||
} else {
|
|
||||||
this.styleRuleManager.updateConditionalStyleConfig(this.conditionalStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.stopListeningConditionalStyles) {
|
|
||||||
this.stopListeningConditionalStyles();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.stopListeningConditionalStyles = this.openmct.objects.observe(this.domainObject, 'configuration.conditionalStyle', (newConditionalStyle) => {
|
|
||||||
//Updating conditional styles in the inspector view will trigger this so that the changes are reflected immediately
|
|
||||||
let newItemConditionalStyle = this.getConditionalStyleForItem(newConditionalStyle);
|
|
||||||
if (this.conditionalStyle !== newItemConditionalStyle) {
|
|
||||||
this.conditionalStyle = newItemConditionalStyle;
|
|
||||||
this.styleRuleManager.updateConditionalStyleConfig(this.conditionalStyle);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
updateStyle(style) {
|
|
||||||
this.itemStyle = style;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
59
src/plugins/displayLayout/mixins/objectlStyles-mixin.js
Normal file
59
src/plugins/displayLayout/mixins/objectlStyles-mixin.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import StyleRuleManager from "@/plugins/condition/StyleRuleManager";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
inject: ['openmct'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
itemStyle: this.itemStyle
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.domainObject = this.$parent.domainObject;
|
||||||
|
this.itemId = this.item.id;
|
||||||
|
this.objectStyle = this.getObjectStyleForItem(this.domainObject.configuration.objectStyles);
|
||||||
|
this.initObjectStyles();
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
if (this.stopListeningObjectStyles) {
|
||||||
|
this.stopListeningObjectStyles();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getObjectStyleForItem(objectStyle) {
|
||||||
|
if (objectStyle) {
|
||||||
|
return objectStyle[this.itemId] ? Object.assign({}, objectStyle[this.itemId]) : undefined;
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
initObjectStyles() {
|
||||||
|
if (!this.styleRuleManager) {
|
||||||
|
this.styleRuleManager = new StyleRuleManager(this.objectStyle, this.openmct, this.updateStyle.bind(this));
|
||||||
|
} else {
|
||||||
|
this.styleRuleManager.updateObjectStyleConfig(this.objectStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.stopListeningObjectStyles) {
|
||||||
|
this.stopListeningObjectStyles();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.stopListeningObjectStyles = this.openmct.objects.observe(this.domainObject, 'configuration.objectStyles', (newObjectStyle) => {
|
||||||
|
//Updating object styles in the inspector view will trigger this so that the changes are reflected immediately
|
||||||
|
let newItemObjectStyle = this.getObjectStyleForItem(newObjectStyle);
|
||||||
|
if (this.objectStyle !== newItemObjectStyle) {
|
||||||
|
this.objectStyle = newItemObjectStyle;
|
||||||
|
this.styleRuleManager.updateObjectStyleConfig(this.objectStyle);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateStyle(style) {
|
||||||
|
this.itemStyle = style;
|
||||||
|
let keys = Object.keys(this.itemStyle);
|
||||||
|
keys.forEach((key) => {
|
||||||
|
if ((typeof this.itemStyle[key] === 'string') && (this.itemStyle[key].indexOf('transparent') > -1)) {
|
||||||
|
delete this.itemStyle[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
@ -1,17 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="c-properties__section c-filter-settings">
|
<div class="c-inspect-properties__section c-filter-settings">
|
||||||
<li
|
<li
|
||||||
v-for="(filter, index) in filterField.filters"
|
v-for="(filter, index) in filterField.filters"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="c-properties__row c-filter-settings__setting"
|
class="c-inspect-properties__row c-filter-settings__setting"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="c-properties__label label"
|
class="c-inspect-properties__label label"
|
||||||
:disabled="useGlobal"
|
:disabled="useGlobal"
|
||||||
>
|
>
|
||||||
{{ filterField.name }} =
|
{{ filterField.name }} =
|
||||||
</div>
|
</div>
|
||||||
<div class="c-properties__value value">
|
<div class="c-inspect-properties__value value">
|
||||||
<!-- EDITING -->
|
<!-- EDITING -->
|
||||||
<!-- String input, editing -->
|
<!-- String input, editing -->
|
||||||
<template v-if="!filter.possibleValues && isEditing">
|
<template v-if="!filter.possibleValues && isEditing">
|
||||||
|
@ -26,17 +26,17 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="expanded">
|
<div v-if="expanded">
|
||||||
<ul class="c-properties">
|
<ul class="c-inspect-properties">
|
||||||
<div
|
<div
|
||||||
v-if="!isEditing && persistedFilters.useGlobal"
|
v-if="!isEditing && persistedFilters.useGlobal"
|
||||||
class="c-properties__label span-all"
|
class="c-inspect-properties__label span-all"
|
||||||
>
|
>
|
||||||
Uses global filter
|
Uses global filter
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="isEditing"
|
v-if="isEditing"
|
||||||
class="c-properties__label span-all"
|
class="c-inspect-properties__label span-all"
|
||||||
>
|
>
|
||||||
<toggle-switch
|
<toggle-switch
|
||||||
:id="keyString"
|
:id="keyString"
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<ul
|
<ul
|
||||||
v-if="expanded"
|
v-if="expanded"
|
||||||
class="c-properties"
|
class="c-inspect-properties"
|
||||||
>
|
>
|
||||||
<filter-field
|
<filter-field
|
||||||
v-for="metadatum in globalMetadata"
|
v-for="metadatum in globalMetadata"
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
}
|
}
|
||||||
.c-filter-tree {
|
.c-filter-tree {
|
||||||
// Filters UI uses a tree-based structure
|
// Filters UI uses a tree-based structure
|
||||||
.c-properties {
|
.c-inspect-properties {
|
||||||
// Add extra margin to account for filter-indicator
|
// Add extra margin to account for filter-indicator
|
||||||
margin-left: 38px;
|
margin-left: 38px;
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="c-properties">
|
<div class="c-inspect-properties">
|
||||||
<template v-if="isEditing">
|
<template v-if="isEditing">
|
||||||
<div class="c-properties__header">
|
<div class="c-inspect-properties__header">
|
||||||
Table Column Size
|
Table Column Size
|
||||||
</div>
|
</div>
|
||||||
<ul class="c-properties__section">
|
<ul class="c-inspect-properties__section">
|
||||||
<li class="c-properties__row">
|
<li class="c-inspect-properties__row">
|
||||||
<div
|
<div
|
||||||
class="c-properties__label"
|
class="c-inspect-properties__label"
|
||||||
title="Auto-size table"
|
title="Auto-size table"
|
||||||
>
|
>
|
||||||
<label for="AutoSizeControl">Auto-size</label>
|
<label for="AutoSizeControl">Auto-size</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="c-properties__value">
|
<div class="c-inspect-properties__value">
|
||||||
<input
|
<input
|
||||||
id="AutoSizeControl"
|
id="AutoSizeControl"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
@ -22,22 +22,22 @@
|
|||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="c-properties__header">
|
<div class="c-inspect-properties__header">
|
||||||
Table Column Visibility
|
Table Column Visibility
|
||||||
</div>
|
</div>
|
||||||
<ul class="c-properties__section">
|
<ul class="c-inspect-properties__section">
|
||||||
<li
|
<li
|
||||||
v-for="(title, key) in headers"
|
v-for="(title, key) in headers"
|
||||||
:key="key"
|
:key="key"
|
||||||
class="c-properties__row"
|
class="c-inspect-properties__row"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="c-properties__label"
|
class="c-inspect-properties__label"
|
||||||
title="Show or hide column"
|
title="Show or hide column"
|
||||||
>
|
>
|
||||||
<label :for="key + 'ColumnControl'">{{ title }}</label>
|
<label :for="key + 'ColumnControl'">{{ title }}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="c-properties__value">
|
<div class="c-inspect-properties__value">
|
||||||
<input
|
<input
|
||||||
:id="key + 'ColumnControl'"
|
:id="key + 'ColumnControl'"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
@ -100,10 +100,12 @@ $colorStatusErrorFilter: invert(10%) sepia(96%) saturate(4360%) hue-rotate(351de
|
|||||||
$colorStatusBtnBg: #666; // Where is this used?
|
$colorStatusBtnBg: #666; // Where is this used?
|
||||||
$colorStatusPartialBg: #3f5e8b;
|
$colorStatusPartialBg: #3f5e8b;
|
||||||
$colorStatusCompleteBg: #457638;
|
$colorStatusCompleteBg: #457638;
|
||||||
$colorAlert: #ff3c00;
|
$colorAlert: #ff8a0d;
|
||||||
$colorAlertFg: #fff;
|
$colorAlertFg: #fff;
|
||||||
$colorWarningHi: #ff0000;
|
$colorError: #ff3c00;
|
||||||
$colorWarningHiFg: #ffdad0;
|
$colorErrorFg: #fff;
|
||||||
|
$colorWarningHi: #990000;
|
||||||
|
$colorWarningHiFg: #FF9594;
|
||||||
$colorWarningLo: #ff9900;
|
$colorWarningLo: #ff9900;
|
||||||
$colorWarningLoFg: #523400;
|
$colorWarningLoFg: #523400;
|
||||||
$colorDiagnostic: #a4b442;
|
$colorDiagnostic: #a4b442;
|
||||||
@ -215,6 +217,7 @@ $colorSelectBg: $colorBtnBg; // This must be a solid color, not a gradient, due
|
|||||||
$colorSelectFg: $colorBtnFg;
|
$colorSelectFg: $colorBtnFg;
|
||||||
$colorSelectArw: lighten($colorBtnBg, 20%);
|
$colorSelectArw: lighten($colorBtnBg, 20%);
|
||||||
$shdwSelect: rgba(black, 0.5) 0 0.5px 3px;
|
$shdwSelect: rgba(black, 0.5) 0 0.5px 3px;
|
||||||
|
$controlDisabledOpacity: 0.2;
|
||||||
|
|
||||||
// Menus
|
// Menus
|
||||||
$colorMenuBg: pullForward($colorBodyBg, 15%);
|
$colorMenuBg: pullForward($colorBodyBg, 15%);
|
||||||
@ -320,7 +323,7 @@ $shdwItemText: none;
|
|||||||
$colorTabBorder: pullForward($colorBodyBg, 10%);
|
$colorTabBorder: pullForward($colorBodyBg, 10%);
|
||||||
$colorTabBodyBg: $colorBodyBg;
|
$colorTabBodyBg: $colorBodyBg;
|
||||||
$colorTabBodyFg: pullForward($colorBodyFg, 20%);
|
$colorTabBodyFg: pullForward($colorBodyFg, 20%);
|
||||||
$colorTabHeaderBg: pullForward($colorBodyBg, 10%);
|
$colorTabHeaderBg: rgba($colorBodyFg, 0.2);
|
||||||
$colorTabHeaderFg: $colorBodyFg;
|
$colorTabHeaderFg: $colorBodyFg;
|
||||||
$colorTabHeaderBorder: $colorBodyBg;
|
$colorTabHeaderBorder: $colorBodyBg;
|
||||||
$colorTabGroupHeaderBg: pullForward($colorBodyBg, 5%);
|
$colorTabGroupHeaderBg: pullForward($colorBodyBg, 5%);
|
||||||
|
@ -104,10 +104,12 @@ $colorStatusErrorFilter: invert(10%) sepia(96%) saturate(4360%) hue-rotate(351de
|
|||||||
$colorStatusBtnBg: #666; // Where is this used?
|
$colorStatusBtnBg: #666; // Where is this used?
|
||||||
$colorStatusPartialBg: #3f5e8b;
|
$colorStatusPartialBg: #3f5e8b;
|
||||||
$colorStatusCompleteBg: #457638;
|
$colorStatusCompleteBg: #457638;
|
||||||
$colorAlert: #ff3c00;
|
$colorAlert: #ff8a0d;
|
||||||
$colorAlertFg: #fff;
|
$colorAlertFg: #fff;
|
||||||
$colorWarningHi: #ff0000;
|
$colorError: #ff3c00;
|
||||||
$colorWarningHiFg: #ffdad0;
|
$colorErrorFg: #fff;
|
||||||
|
$colorWarningHi: #990000;
|
||||||
|
$colorWarningHiFg: #FF9594;
|
||||||
$colorWarningLo: #ff9900;
|
$colorWarningLo: #ff9900;
|
||||||
$colorWarningLoFg: #523400;
|
$colorWarningLoFg: #523400;
|
||||||
$colorDiagnostic: #a4b442;
|
$colorDiagnostic: #a4b442;
|
||||||
@ -219,6 +221,7 @@ $colorSelectBg: $colorBtnBg; // This must be a solid color, not a gradient, due
|
|||||||
$colorSelectFg: $colorBtnFg;
|
$colorSelectFg: $colorBtnFg;
|
||||||
$colorSelectArw: lighten($colorBtnBg, 20%);
|
$colorSelectArw: lighten($colorBtnBg, 20%);
|
||||||
$shdwSelect: rgba(black, 0.5) 0 0.5px 3px;
|
$shdwSelect: rgba(black, 0.5) 0 0.5px 3px;
|
||||||
|
$controlDisabledOpacity: 0.2;
|
||||||
|
|
||||||
// Menus
|
// Menus
|
||||||
$colorMenuBg: pullForward($colorBodyBg, 15%);
|
$colorMenuBg: pullForward($colorBodyBg, 15%);
|
||||||
@ -324,7 +327,7 @@ $shdwItemText: none;
|
|||||||
$colorTabBorder: pullForward($colorBodyBg, 10%);
|
$colorTabBorder: pullForward($colorBodyBg, 10%);
|
||||||
$colorTabBodyBg: $colorBodyBg;
|
$colorTabBodyBg: $colorBodyBg;
|
||||||
$colorTabBodyFg: pullForward($colorBodyFg, 20%);
|
$colorTabBodyFg: pullForward($colorBodyFg, 20%);
|
||||||
$colorTabHeaderBg: pullForward($colorBodyBg, 10%);
|
$colorTabHeaderBg: rgba($colorBodyFg, 0.2);
|
||||||
$colorTabHeaderFg: $colorBodyFg;
|
$colorTabHeaderFg: $colorBodyFg;
|
||||||
$colorTabHeaderBorder: $colorBodyBg;
|
$colorTabHeaderBorder: $colorBodyBg;
|
||||||
$colorTabGroupHeaderBg: pullForward($colorBodyBg, 5%);
|
$colorTabGroupHeaderBg: pullForward($colorBodyBg, 5%);
|
||||||
|
@ -100,8 +100,10 @@ $colorStatusErrorFilter: invert(8%) sepia(96%) saturate(4511%) hue-rotate(352deg
|
|||||||
$colorStatusBtnBg: #666; // Where is this used?
|
$colorStatusBtnBg: #666; // Where is this used?
|
||||||
$colorStatusPartialBg: #c9d6ff;
|
$colorStatusPartialBg: #c9d6ff;
|
||||||
$colorStatusCompleteBg: #a4e4b4;
|
$colorStatusCompleteBg: #a4e4b4;
|
||||||
$colorAlert: #ff3c00;
|
$colorAlert: #ff8a0d;
|
||||||
$colorAlertFg: #fff;
|
$colorAlertFg: #fff;
|
||||||
|
$colorError: #ff3c00;
|
||||||
|
$colorErrorFg: #fff;
|
||||||
$colorWarningHi: #990000;
|
$colorWarningHi: #990000;
|
||||||
$colorWarningHiFg: #FF9594;
|
$colorWarningHiFg: #FF9594;
|
||||||
$colorWarningLo: #ff9900;
|
$colorWarningLo: #ff9900;
|
||||||
@ -215,6 +217,7 @@ $colorSelectBg: $colorBtnBg; // This must be a solid color, not a gradient, due
|
|||||||
$colorSelectFg: $colorBtnFg;
|
$colorSelectFg: $colorBtnFg;
|
||||||
$colorSelectArw: lighten($colorBtnBg, 20%);
|
$colorSelectArw: lighten($colorBtnBg, 20%);
|
||||||
$shdwSelect: none;
|
$shdwSelect: none;
|
||||||
|
$controlDisabledOpacity: 0.3;
|
||||||
|
|
||||||
// Menus
|
// Menus
|
||||||
$colorMenuBg: pushBack($colorBodyBg, 10%);
|
$colorMenuBg: pushBack($colorBodyBg, 10%);
|
||||||
@ -320,8 +323,8 @@ $shdwItemText: none;
|
|||||||
$colorTabBorder: pullForward($colorBodyBg, 10%);
|
$colorTabBorder: pullForward($colorBodyBg, 10%);
|
||||||
$colorTabBodyBg: $colorBodyBg;
|
$colorTabBodyBg: $colorBodyBg;
|
||||||
$colorTabBodyFg: pullForward($colorBodyFg, 20%);
|
$colorTabBodyFg: pullForward($colorBodyFg, 20%);
|
||||||
$colorTabHeaderBg: pullForward($colorBodyBg, 10%);
|
$colorTabHeaderBg: rgba($colorBodyFg, 0.2);
|
||||||
$colorTabHeaderFg: pullForward($colorBodyFg, 20%);
|
$colorTabHeaderFg: $colorBodyFg;
|
||||||
$colorTabHeaderBorder: $colorBodyBg;
|
$colorTabHeaderBorder: $colorBodyBg;
|
||||||
$colorTabGroupHeaderBg: pullForward($colorBodyBg, 5%);
|
$colorTabGroupHeaderBg: pullForward($colorBodyBg, 5%);
|
||||||
$colorTabGroupHeaderFg: pullForward($colorTabGroupHeaderBg, 40%);
|
$colorTabGroupHeaderFg: pullForward($colorTabGroupHeaderBg, 40%);
|
||||||
|
@ -94,9 +94,6 @@ $tableResizeColHitareaD: 6px;
|
|||||||
$mobileMenuIconD: 24px; // Used
|
$mobileMenuIconD: 24px; // Used
|
||||||
$mobileTreeItemH: 35px; // Used
|
$mobileTreeItemH: 35px; // Used
|
||||||
|
|
||||||
/************************** VISUAL */
|
|
||||||
$controlDisabledOpacity: 0.5;
|
|
||||||
|
|
||||||
/************************** UI ELEMENTS */
|
/************************** UI ELEMENTS */
|
||||||
/*************** Progress Bar */
|
/*************** Progress Bar */
|
||||||
$colorProgressBarHolder: rgba(black, 0.1);
|
$colorProgressBarHolder: rgba(black, 0.1);
|
||||||
@ -148,6 +145,7 @@ $glyph-icon-filter-outline: '\e927';
|
|||||||
$glyph-icon-suitcase: '\e928';
|
$glyph-icon-suitcase: '\e928';
|
||||||
$glyph-icon-cursor-lock: '\e929';
|
$glyph-icon-cursor-lock: '\e929';
|
||||||
$glyph-icon-flag: '\e92a';
|
$glyph-icon-flag: '\e92a';
|
||||||
|
$glyph-icon-eye-disabled: '\e92b';
|
||||||
$glyph-icon-arrows-right-left: '\ea00';
|
$glyph-icon-arrows-right-left: '\ea00';
|
||||||
$glyph-icon-arrows-up-down: '\ea01';
|
$glyph-icon-arrows-up-down: '\ea01';
|
||||||
$glyph-icon-bullet: '\ea02';
|
$glyph-icon-bullet: '\ea02';
|
||||||
|
@ -229,6 +229,7 @@ section {
|
|||||||
|
|
||||||
&.is-expanded {
|
&.is-expanded {
|
||||||
flex: 1 1 100%;
|
flex: 1 1 100%;
|
||||||
|
max-height: max-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.c-section__header {
|
.c-section__header {
|
||||||
@ -785,7 +786,25 @@ select {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************** SLIDERS */
|
/******************************************************** STYLE EDITING */
|
||||||
|
.c-style {
|
||||||
|
display: flex;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
> * + * { margin-left: $interiorMargin; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-style-thumb {
|
||||||
|
background-size: cover;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: $basicCr;
|
||||||
|
box-shadow: rgba($colorBodyFg, 0.4) 0 0 3px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
padding: $interiorMargin $interiorMarginLg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************** SLIDERS */
|
||||||
.c-slider {
|
.c-slider {
|
||||||
@include cControl();
|
@include cControl();
|
||||||
> * + * { margin-left: $interiorMargin; }
|
> * + * { margin-left: $interiorMargin; }
|
||||||
|
@ -35,6 +35,22 @@ div {
|
|||||||
display: contents;
|
display: contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.u-menu-to {
|
||||||
|
&--left {
|
||||||
|
.c-menu {
|
||||||
|
left: auto !important;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--center {
|
||||||
|
.c-menu {
|
||||||
|
left: 50% !important;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.u-space {
|
.u-space {
|
||||||
// Provides a separator space between elements
|
// Provides a separator space between elements
|
||||||
&--right {
|
&--right {
|
||||||
|
@ -82,6 +82,7 @@
|
|||||||
.icon-suitcase { @include glyphBefore($glyph-icon-suitcase); }
|
.icon-suitcase { @include glyphBefore($glyph-icon-suitcase); }
|
||||||
.icon-cursor-lock { @include glyphBefore($glyph-icon-cursor-lock); }
|
.icon-cursor-lock { @include glyphBefore($glyph-icon-cursor-lock); }
|
||||||
.icon-flag { @include glyphBefore($glyph-icon-flag); }
|
.icon-flag { @include glyphBefore($glyph-icon-flag); }
|
||||||
|
.icon-eye-disabled { @include glyphBefore($glyph-icon-eye-disabled); }
|
||||||
.icon-arrows-right-left { @include glyphBefore($glyph-icon-arrows-right-left); }
|
.icon-arrows-right-left { @include glyphBefore($glyph-icon-arrows-right-left); }
|
||||||
.icon-arrows-up-down { @include glyphBefore($glyph-icon-arrows-up-down); }
|
.icon-arrows-up-down { @include glyphBefore($glyph-icon-arrows-up-down); }
|
||||||
.icon-bullet { @include glyphBefore($glyph-icon-bullet); }
|
.icon-bullet { @include glyphBefore($glyph-icon-bullet); }
|
||||||
|
@ -67,15 +67,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&__object-name--w {
|
&__object-name--w {
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
flex: 0 1 auto;
|
flex: 0 1 auto;
|
||||||
@include headerFont(1.4em);
|
@include headerFont(1.4em);
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
// Icon
|
// Icon
|
||||||
opacity: 0.5;
|
|
||||||
margin-right: $interiorMargin;
|
margin-right: $interiorMargin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,6 +127,24 @@
|
|||||||
background-size: $bgSize;
|
background-size: $bgSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin bgCheckerboard($c: $colorBodyFg, $opacity: 0.3, $size: 32px, $imp: false) {
|
||||||
|
$color: rgba($c, $opacity);
|
||||||
|
$bgPos: floor($size / 2);
|
||||||
|
|
||||||
|
$impStr: null;
|
||||||
|
@if $imp {
|
||||||
|
$impStr: !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
background-image:
|
||||||
|
linear-gradient(45deg, $color 25%, transparent 25%),
|
||||||
|
linear-gradient(45deg, transparent 75%, $color 75%),
|
||||||
|
linear-gradient(45deg, transparent 75%, $color 75%),
|
||||||
|
linear-gradient(45deg, $color 25%, transparent 25%) $impStr;
|
||||||
|
background-size: $size $size;
|
||||||
|
background-position:0 0, 0 0, -1*$bgPos -1*$bgPos, $bgPos $bgPos;
|
||||||
|
}
|
||||||
|
|
||||||
@mixin disabled() {
|
@mixin disabled() {
|
||||||
opacity: $controlDisabledOpacity;
|
opacity: $controlDisabledOpacity;
|
||||||
pointer-events: none !important;
|
pointer-events: none !important;
|
||||||
@ -403,9 +421,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@mixin cClickIcon() {
|
@mixin cClickIcon() {
|
||||||
@include cControl();
|
@include cControl();
|
||||||
|
color: $colorBodyFg;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 4px; // Bigger hit area
|
padding: 4px; // Bigger hit area
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-family: symbolsfont;
|
font-family: symbolsfont;
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
margin-right: $interiorMargin;
|
margin-right: $interiorMarginSm;
|
||||||
@if $glyph != null {
|
@if $glyph != null {
|
||||||
content: $glyph $impStr;
|
content: $glyph $impStr;
|
||||||
}
|
}
|
||||||
@ -71,6 +71,30 @@
|
|||||||
&.is-limit--lwr:before { content: $glyph-icon-arrow-down !important; }
|
&.is-limit--lwr:before { content: $glyph-icon-arrow-down !important; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin uIndicator($bg, $fg, $glyph) {
|
||||||
|
background: $bg;
|
||||||
|
color: $fg;
|
||||||
|
|
||||||
|
&[class*='--with-icon'] {
|
||||||
|
&:before {
|
||||||
|
color: $fg;
|
||||||
|
display: inline-block;
|
||||||
|
font-family: symbolsfont;
|
||||||
|
margin-right: $interiorMarginSm;
|
||||||
|
@if $glyph != null {
|
||||||
|
content: $glyph;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&[class*='--block'] {
|
||||||
|
border-radius: $controlCr;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 2px $interiorMargin;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************** STYLES */
|
/*************************************************** STYLES */
|
||||||
*:not(tr) {
|
*:not(tr) {
|
||||||
&.is-limit--yellow {
|
&.is-limit--yellow {
|
||||||
@ -173,3 +197,5 @@ tr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.u-alert { @include uIndicator($colorAlert, $colorAlertFg, $glyph-icon-alert-triangle); }
|
||||||
|
.u-error { @include uIndicator($colorError, $colorErrorFg, $glyph-icon-alert-triangle); }
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"name": "Open MCT Symbols 16px",
|
"name": "Open MCT Symbols 16px",
|
||||||
"lastOpened": 0,
|
"lastOpened": 0,
|
||||||
"created": 1581619121103
|
"created": 1585006719465
|
||||||
},
|
},
|
||||||
"iconSets": [
|
"iconSets": [
|
||||||
{
|
{
|
||||||
@ -351,13 +351,21 @@
|
|||||||
"code": 59690,
|
"code": 59690,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"order": 177,
|
||||||
|
"id": 152,
|
||||||
|
"name": "icon-eye-disabled",
|
||||||
|
"prevSize": 24,
|
||||||
|
"code": 59691,
|
||||||
|
"tempChar": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"order": 27,
|
"order": 27,
|
||||||
"id": 105,
|
"id": 105,
|
||||||
"name": "icon-arrows-right-left",
|
"name": "icon-arrows-right-left",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59904,
|
"code": 59904,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 26,
|
"order": 26,
|
||||||
@ -365,7 +373,7 @@
|
|||||||
"name": "icon-arrows-up-down",
|
"name": "icon-arrows-up-down",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59905,
|
"code": 59905,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 68,
|
"order": 68,
|
||||||
@ -373,7 +381,7 @@
|
|||||||
"name": "icon-bullet",
|
"name": "icon-bullet",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59906,
|
"code": 59906,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 150,
|
"order": 150,
|
||||||
@ -381,7 +389,7 @@
|
|||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59907,
|
"code": 59907,
|
||||||
"name": "icon-calendar",
|
"name": "icon-calendar",
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 45,
|
"order": 45,
|
||||||
@ -389,7 +397,7 @@
|
|||||||
"name": "icon-chain-links",
|
"name": "icon-chain-links",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59908,
|
"code": 59908,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 73,
|
"order": 73,
|
||||||
@ -397,7 +405,7 @@
|
|||||||
"name": "icon-download",
|
"name": "icon-download",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59909,
|
"code": 59909,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 39,
|
"order": 39,
|
||||||
@ -405,7 +413,7 @@
|
|||||||
"name": "icon-duplicate",
|
"name": "icon-duplicate",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59910,
|
"code": 59910,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 50,
|
"order": 50,
|
||||||
@ -413,7 +421,7 @@
|
|||||||
"name": "icon-folder-new",
|
"name": "icon-folder-new",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59911,
|
"code": 59911,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 138,
|
"order": 138,
|
||||||
@ -421,7 +429,7 @@
|
|||||||
"name": "icon-fullscreen-collapse",
|
"name": "icon-fullscreen-collapse",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59912,
|
"code": 59912,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 139,
|
"order": 139,
|
||||||
@ -429,7 +437,7 @@
|
|||||||
"name": "icon-fullscreen-expand",
|
"name": "icon-fullscreen-expand",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59913,
|
"code": 59913,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 122,
|
"order": 122,
|
||||||
@ -437,7 +445,7 @@
|
|||||||
"name": "icon-layers",
|
"name": "icon-layers",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59914,
|
"code": 59914,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 151,
|
"order": 151,
|
||||||
@ -445,7 +453,7 @@
|
|||||||
"name": "icon-line-horz",
|
"name": "icon-line-horz",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59915,
|
"code": 59915,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 100,
|
"order": 100,
|
||||||
@ -453,7 +461,7 @@
|
|||||||
"name": "icon-magnify",
|
"name": "icon-magnify",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59916,
|
"code": 59916,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 99,
|
"order": 99,
|
||||||
@ -461,7 +469,7 @@
|
|||||||
"name": "icon-magnify-in",
|
"name": "icon-magnify-in",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59917,
|
"code": 59917,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 101,
|
"order": 101,
|
||||||
@ -469,7 +477,7 @@
|
|||||||
"name": "icon-magnify-out-v2",
|
"name": "icon-magnify-out-v2",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59918,
|
"code": 59918,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 103,
|
"order": 103,
|
||||||
@ -477,7 +485,7 @@
|
|||||||
"name": "icon-menu",
|
"name": "icon-menu",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59919,
|
"code": 59919,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 124,
|
"order": 124,
|
||||||
@ -485,7 +493,7 @@
|
|||||||
"name": "icon-move",
|
"name": "icon-move",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59920,
|
"code": 59920,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 7,
|
"order": 7,
|
||||||
@ -493,7 +501,7 @@
|
|||||||
"name": "icon-new-window",
|
"name": "icon-new-window",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59921,
|
"code": 59921,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 63,
|
"order": 63,
|
||||||
@ -501,7 +509,7 @@
|
|||||||
"name": "icon-paint-bucket-v2",
|
"name": "icon-paint-bucket-v2",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59922,
|
"code": 59922,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 15,
|
"order": 15,
|
||||||
@ -509,7 +517,7 @@
|
|||||||
"name": "icon-pencil",
|
"name": "icon-pencil",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59923,
|
"code": 59923,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 54,
|
"order": 54,
|
||||||
@ -517,7 +525,7 @@
|
|||||||
"name": "icon-pencil-edit-in-place",
|
"name": "icon-pencil-edit-in-place",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59924,
|
"code": 59924,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 40,
|
"order": 40,
|
||||||
@ -525,7 +533,7 @@
|
|||||||
"name": "icon-play",
|
"name": "icon-play",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59925,
|
"code": 59925,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 125,
|
"order": 125,
|
||||||
@ -533,7 +541,7 @@
|
|||||||
"name": "icon-pause",
|
"name": "icon-pause",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59926,
|
"code": 59926,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 119,
|
"order": 119,
|
||||||
@ -541,7 +549,7 @@
|
|||||||
"name": "icon-plot-resource",
|
"name": "icon-plot-resource",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59927,
|
"code": 59927,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 48,
|
"order": 48,
|
||||||
@ -549,7 +557,7 @@
|
|||||||
"name": "icon-pointer-left",
|
"name": "icon-pointer-left",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59928,
|
"code": 59928,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 47,
|
"order": 47,
|
||||||
@ -557,7 +565,7 @@
|
|||||||
"name": "icon-pointer-right",
|
"name": "icon-pointer-right",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59929,
|
"code": 59929,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 85,
|
"order": 85,
|
||||||
@ -565,7 +573,7 @@
|
|||||||
"name": "icon-refresh",
|
"name": "icon-refresh",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59930,
|
"code": 59930,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 55,
|
"order": 55,
|
||||||
@ -573,7 +581,7 @@
|
|||||||
"name": "icon-save",
|
"name": "icon-save",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59931,
|
"code": 59931,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 56,
|
"order": 56,
|
||||||
@ -581,7 +589,7 @@
|
|||||||
"name": "icon-save-as",
|
"name": "icon-save-as",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59932,
|
"code": 59932,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 58,
|
"order": 58,
|
||||||
@ -589,7 +597,7 @@
|
|||||||
"name": "icon-sine",
|
"name": "icon-sine",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59933,
|
"code": 59933,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 113,
|
"order": 113,
|
||||||
@ -597,7 +605,7 @@
|
|||||||
"name": "icon-font",
|
"name": "icon-font",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59934,
|
"code": 59934,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 41,
|
"order": 41,
|
||||||
@ -605,7 +613,7 @@
|
|||||||
"name": "icon-thumbs-strip",
|
"name": "icon-thumbs-strip",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59935,
|
"code": 59935,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 146,
|
"order": 146,
|
||||||
@ -613,7 +621,7 @@
|
|||||||
"name": "icon-two-parts-both",
|
"name": "icon-two-parts-both",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59936,
|
"code": 59936,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 145,
|
"order": 145,
|
||||||
@ -621,7 +629,7 @@
|
|||||||
"name": "icon-two-parts-one-only",
|
"name": "icon-two-parts-one-only",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59937,
|
"code": 59937,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 82,
|
"order": 82,
|
||||||
@ -629,7 +637,7 @@
|
|||||||
"name": "icon-resync",
|
"name": "icon-resync",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59938,
|
"code": 59938,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 86,
|
"order": 86,
|
||||||
@ -637,7 +645,7 @@
|
|||||||
"name": "icon-reset",
|
"name": "icon-reset",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59939,
|
"code": 59939,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 61,
|
"order": 61,
|
||||||
@ -645,7 +653,7 @@
|
|||||||
"name": "icon-x-in-circle",
|
"name": "icon-x-in-circle",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59940,
|
"code": 59940,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 84,
|
"order": 84,
|
||||||
@ -653,7 +661,7 @@
|
|||||||
"name": "icon-brightness",
|
"name": "icon-brightness",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59941,
|
"code": 59941,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 83,
|
"order": 83,
|
||||||
@ -661,7 +669,7 @@
|
|||||||
"name": "icon-contrast",
|
"name": "icon-contrast",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59942,
|
"code": 59942,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 87,
|
"order": 87,
|
||||||
@ -669,7 +677,7 @@
|
|||||||
"name": "icon-expand",
|
"name": "icon-expand",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59943,
|
"code": 59943,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 89,
|
"order": 89,
|
||||||
@ -677,7 +685,7 @@
|
|||||||
"name": "icon-list-view",
|
"name": "icon-list-view",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59944,
|
"code": 59944,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 133,
|
"order": 133,
|
||||||
@ -685,7 +693,7 @@
|
|||||||
"name": "icon-grid-snap-to",
|
"name": "icon-grid-snap-to",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59945,
|
"code": 59945,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 132,
|
"order": 132,
|
||||||
@ -693,7 +701,7 @@
|
|||||||
"name": "icon-grid-snap-no",
|
"name": "icon-grid-snap-no",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59946,
|
"code": 59946,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 94,
|
"order": 94,
|
||||||
@ -701,7 +709,7 @@
|
|||||||
"name": "icon-frame-show",
|
"name": "icon-frame-show",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59947,
|
"code": 59947,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 95,
|
"order": 95,
|
||||||
@ -709,7 +717,7 @@
|
|||||||
"name": "icon-frame-hide",
|
"name": "icon-frame-hide",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59948,
|
"code": 59948,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 97,
|
"order": 97,
|
||||||
@ -717,7 +725,7 @@
|
|||||||
"name": "icon-import",
|
"name": "icon-import",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59949,
|
"code": 59949,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 96,
|
"order": 96,
|
||||||
@ -725,7 +733,7 @@
|
|||||||
"name": "icon-export",
|
"name": "icon-export",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59950,
|
"code": 59950,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 114,
|
"order": 114,
|
||||||
@ -733,7 +741,7 @@
|
|||||||
"name": "icon-font-size",
|
"name": "icon-font-size",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59951,
|
"code": 59951,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 163,
|
"order": 163,
|
||||||
@ -741,7 +749,7 @@
|
|||||||
"name": "icon-clear-data",
|
"name": "icon-clear-data",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59952,
|
"code": 59952,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 173,
|
"order": 173,
|
||||||
@ -749,7 +757,7 @@
|
|||||||
"name": "icon-history",
|
"name": "icon-history",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 59953,
|
"code": 59953,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 144,
|
"order": 144,
|
||||||
@ -757,7 +765,7 @@
|
|||||||
"name": "icon-activity",
|
"name": "icon-activity",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60160,
|
"code": 60160,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 104,
|
"order": 104,
|
||||||
@ -765,7 +773,7 @@
|
|||||||
"name": "icon-activity-mode",
|
"name": "icon-activity-mode",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60161,
|
"code": 60161,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 137,
|
"order": 137,
|
||||||
@ -773,7 +781,7 @@
|
|||||||
"name": "icon-autoflow-tabular",
|
"name": "icon-autoflow-tabular",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60162,
|
"code": 60162,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 115,
|
"order": 115,
|
||||||
@ -781,7 +789,7 @@
|
|||||||
"name": "icon-clock",
|
"name": "icon-clock",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60163,
|
"code": 60163,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 2,
|
"order": 2,
|
||||||
@ -789,7 +797,7 @@
|
|||||||
"name": "icon-database",
|
"name": "icon-database",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60164,
|
"code": 60164,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 3,
|
"order": 3,
|
||||||
@ -797,7 +805,7 @@
|
|||||||
"name": "icon-database-query",
|
"name": "icon-database-query",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60165,
|
"code": 60165,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 67,
|
"order": 67,
|
||||||
@ -805,7 +813,7 @@
|
|||||||
"name": "icon-dataset",
|
"name": "icon-dataset",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60166,
|
"code": 60166,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 59,
|
"order": 59,
|
||||||
@ -813,7 +821,7 @@
|
|||||||
"name": "icon-datatable",
|
"name": "icon-datatable",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60167,
|
"code": 60167,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 136,
|
"order": 136,
|
||||||
@ -821,7 +829,7 @@
|
|||||||
"name": "icon-dictionary",
|
"name": "icon-dictionary",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60168,
|
"code": 60168,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 51,
|
"order": 51,
|
||||||
@ -829,7 +837,7 @@
|
|||||||
"name": "icon-folder",
|
"name": "icon-folder",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60169,
|
"code": 60169,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 147,
|
"order": 147,
|
||||||
@ -837,7 +845,7 @@
|
|||||||
"name": "icon-image",
|
"name": "icon-image",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60170,
|
"code": 60170,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 4,
|
"order": 4,
|
||||||
@ -845,7 +853,7 @@
|
|||||||
"name": "icon-layout",
|
"name": "icon-layout",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60171,
|
"code": 60171,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 24,
|
"order": 24,
|
||||||
@ -853,7 +861,7 @@
|
|||||||
"name": "icon-object",
|
"name": "icon-object",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60172,
|
"code": 60172,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 52,
|
"order": 52,
|
||||||
@ -861,7 +869,7 @@
|
|||||||
"name": "icon-object-unknown",
|
"name": "icon-object-unknown",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60173,
|
"code": 60173,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 105,
|
"order": 105,
|
||||||
@ -869,7 +877,7 @@
|
|||||||
"name": "icon-packet",
|
"name": "icon-packet",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60174,
|
"code": 60174,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 126,
|
"order": 126,
|
||||||
@ -877,7 +885,7 @@
|
|||||||
"name": "icon-page",
|
"name": "icon-page",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60175,
|
"code": 60175,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 130,
|
"order": 130,
|
||||||
@ -885,7 +893,7 @@
|
|||||||
"name": "icon-plot-overlay",
|
"name": "icon-plot-overlay",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60176,
|
"code": 60176,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 80,
|
"order": 80,
|
||||||
@ -893,7 +901,7 @@
|
|||||||
"name": "icon-plot-stacked",
|
"name": "icon-plot-stacked",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60177,
|
"code": 60177,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 134,
|
"order": 134,
|
||||||
@ -901,7 +909,7 @@
|
|||||||
"name": "icon-session",
|
"name": "icon-session",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60178,
|
"code": 60178,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 109,
|
"order": 109,
|
||||||
@ -909,7 +917,7 @@
|
|||||||
"name": "icon-tabular",
|
"name": "icon-tabular",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60179,
|
"code": 60179,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 107,
|
"order": 107,
|
||||||
@ -917,7 +925,7 @@
|
|||||||
"name": "icon-tabular-lad",
|
"name": "icon-tabular-lad",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60180,
|
"code": 60180,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 106,
|
"order": 106,
|
||||||
@ -925,7 +933,7 @@
|
|||||||
"name": "icon-tabular-lad-set",
|
"name": "icon-tabular-lad-set",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60181,
|
"code": 60181,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 70,
|
"order": 70,
|
||||||
@ -933,7 +941,7 @@
|
|||||||
"name": "icon-tabular-realtime",
|
"name": "icon-tabular-realtime",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60182,
|
"code": 60182,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 60,
|
"order": 60,
|
||||||
@ -941,7 +949,7 @@
|
|||||||
"name": "icon-tabular-scrolling",
|
"name": "icon-tabular-scrolling",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60183,
|
"code": 60183,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 131,
|
"order": 131,
|
||||||
@ -949,7 +957,7 @@
|
|||||||
"name": "icon-telemetry",
|
"name": "icon-telemetry",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60184,
|
"code": 60184,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 108,
|
"order": 108,
|
||||||
@ -957,7 +965,7 @@
|
|||||||
"name": "icon-timeline",
|
"name": "icon-timeline",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60185,
|
"code": 60185,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 81,
|
"order": 81,
|
||||||
@ -965,7 +973,7 @@
|
|||||||
"name": "icon-timer",
|
"name": "icon-timer",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60186,
|
"code": 60186,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 69,
|
"order": 69,
|
||||||
@ -973,7 +981,7 @@
|
|||||||
"name": "icon-topic",
|
"name": "icon-topic",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60187,
|
"code": 60187,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 79,
|
"order": 79,
|
||||||
@ -981,7 +989,7 @@
|
|||||||
"name": "icon-box-with-dashed-lines-v2",
|
"name": "icon-box-with-dashed-lines-v2",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60188,
|
"code": 60188,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 90,
|
"order": 90,
|
||||||
@ -989,7 +997,7 @@
|
|||||||
"name": "icon-summary-widget",
|
"name": "icon-summary-widget",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60189,
|
"code": 60189,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 92,
|
"order": 92,
|
||||||
@ -997,7 +1005,7 @@
|
|||||||
"name": "icon-notebook",
|
"name": "icon-notebook",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60190,
|
"code": 60190,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 168,
|
"order": 168,
|
||||||
@ -1005,7 +1013,7 @@
|
|||||||
"name": "icon-tabs-view",
|
"name": "icon-tabs-view",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60191,
|
"code": 60191,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 117,
|
"order": 117,
|
||||||
@ -1013,7 +1021,7 @@
|
|||||||
"name": "icon-flexible-layout",
|
"name": "icon-flexible-layout",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60192,
|
"code": 60192,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 166,
|
"order": 166,
|
||||||
@ -1021,7 +1029,7 @@
|
|||||||
"name": "icon-generator-sine",
|
"name": "icon-generator-sine",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60193,
|
"code": 60193,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 167,
|
"order": 167,
|
||||||
@ -1029,7 +1037,7 @@
|
|||||||
"name": "icon-generator-event",
|
"name": "icon-generator-event",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60194,
|
"code": 60194,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 165,
|
"order": 165,
|
||||||
@ -1037,7 +1045,7 @@
|
|||||||
"name": "icon-gauge-v2",
|
"name": "icon-gauge-v2",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60195,
|
"code": 60195,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 170,
|
"order": 170,
|
||||||
@ -1045,7 +1053,7 @@
|
|||||||
"name": "icon-spectra",
|
"name": "icon-spectra",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60196,
|
"code": 60196,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 171,
|
"order": 171,
|
||||||
@ -1053,7 +1061,7 @@
|
|||||||
"name": "icon-telemetry-spectra",
|
"name": "icon-telemetry-spectra",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60197,
|
"code": 60197,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 172,
|
"order": 172,
|
||||||
@ -1061,7 +1069,7 @@
|
|||||||
"name": "icon-pushbutton",
|
"name": "icon-pushbutton",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60198,
|
"code": 60198,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 174,
|
"order": 174,
|
||||||
@ -1069,7 +1077,7 @@
|
|||||||
"name": "icon-conditional",
|
"name": "icon-conditional",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 60199,
|
"code": 60199,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"id": 0,
|
"id": 0,
|
||||||
@ -1644,6 +1652,25 @@
|
|||||||
"isMulticolor": false,
|
"isMulticolor": false,
|
||||||
"isMulticolor2": false
|
"isMulticolor2": false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": 152,
|
||||||
|
"paths": [
|
||||||
|
"M209.46 608.68q-7.46-9.86-14.26-20.28c-14.737-21.984-27.741-47.184-37.759-73.847l-0.841-2.553c11.078-29.259 24.068-54.443 39.51-77.869l-0.91 1.469c23.221-34.963 50.705-64.8 82.207-89.793l0.793-0.607c57.663-45.719 130.179-75.053 209.311-79.947l1.069-0.053 114.48-140.88c-27.366-5.017-58.869-7.898-91.041-7.92l-0.019-0c-245.8 0-452.2 168-510.8 395.6 21.856 82.93 60.906 154.847 113.325 214.773l-0.525-0.613z",
|
||||||
|
"M814.76 415.080q7.52 10 14.44 20.52c14.737 21.984 27.741 47.184 37.759 73.847l0.841 2.553c-10.859 29.216-23.863 54.416-39.447 77.748l0.847-1.348c-23.221 34.963-50.705 64.8-82.207 89.793l-0.793 0.607c-57.762 45.834-130.437 75.216-209.743 80.049l-1.057 0.051-114.46 140.86c27.346 4.988 58.817 7.84 90.955 7.84 0.037 0 0.074-0 0.111-0l-0.005 0c245.8 0 452.2-168 510.8-395.6-21.856-82.93-60.906-154.847-113.325-214.773l0.525 0.613z",
|
||||||
|
"M832 0l-832 1024h192l832-1024h-192z"
|
||||||
|
],
|
||||||
|
"attrs": [
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{}
|
||||||
|
],
|
||||||
|
"isMulticolor": false,
|
||||||
|
"isMulticolor2": false,
|
||||||
|
"grid": 16,
|
||||||
|
"tags": [
|
||||||
|
"icon-eye-disabled"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": 105,
|
"id": 105,
|
||||||
"paths": [
|
"paths": [
|
||||||
|
1
src/styles/fonts/Open-MCT-Symbols-16px.svg
Executable file → Normal file
1
src/styles/fonts/Open-MCT-Symbols-16px.svg
Executable file → Normal file
@ -50,6 +50,7 @@
|
|||||||
<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-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-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-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-eye-disabled" d="M209.46 223.32q-7.46 9.86-14.26 20.28c-14.737 21.984-27.741 47.184-37.759 73.847l-0.841 2.553c11.078 29.259 24.068 54.443 39.51 77.869l-0.91-1.469c23.221 34.963 50.705 64.8 82.207 89.793l0.793 0.607c57.663 45.719 130.179 75.053 209.311 79.947l1.069 0.053 114.48 140.88c-27.366 5.017-58.869 7.898-91.041 7.92h-0.019c-245.8 0-452.2-168-510.8-395.6 21.856-82.93 60.906-154.847 113.325-214.773l-0.525 0.613zM814.76 416.92q7.52-10 14.44-20.52c14.737-21.984 27.741-47.184 37.759-73.847l0.841-2.553c-10.859-29.216-23.863-54.416-39.447-77.748l0.847 1.348c-23.221-34.963-50.705-64.8-82.207-89.793l-0.793-0.607c-57.762-45.834-130.437-75.216-209.743-80.049l-1.057-0.051-114.46-140.86c27.346-4.988 58.817-7.84 90.955-7.84 0.037 0 0.074 0 0.111 0h-0.005c245.8 0 452.2 168 510.8 395.6-21.856 82.93-60.906 154.847-113.325 214.773l0.525-0.613zM832 832l-832-1024h192l832 1024h-192z" />
|
||||||
<glyph unicode="" glyph-name="icon-arrows-right-left" d="M1024 320l-448-512v1024zM448 832l-448-512 448-512z" />
|
<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-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" />
|
<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" />
|
||||||
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 52 KiB |
BIN
src/styles/fonts/Open-MCT-Symbols-16px.ttf
Executable file → Normal file
BIN
src/styles/fonts/Open-MCT-Symbols-16px.ttf
Executable file → Normal file
Binary file not shown.
BIN
src/styles/fonts/Open-MCT-Symbols-16px.woff
Executable file → Normal file
BIN
src/styles/fonts/Open-MCT-Symbols-16px.woff
Executable file → Normal file
Binary file not shown.
@ -2,6 +2,7 @@
|
|||||||
@import "../api/overlays/components/overlay-component.scss";
|
@import "../api/overlays/components/overlay-component.scss";
|
||||||
@import "../plugins/condition/components/condition.scss";
|
@import "../plugins/condition/components/condition.scss";
|
||||||
@import "../plugins/condition/components/condition-set.scss";
|
@import "../plugins/condition/components/condition-set.scss";
|
||||||
|
@import "../plugins/condition/components/inspector/conditional-styles.scss";
|
||||||
@import "../plugins/displayLayout/components/box-view.scss";
|
@import "../plugins/displayLayout/components/box-view.scss";
|
||||||
@import "../plugins/displayLayout/components/display-layout.scss";
|
@import "../plugins/displayLayout/components/display-layout.scss";
|
||||||
@import "../plugins/displayLayout/components/edit-marquee.scss";
|
@import "../plugins/displayLayout/components/edit-marquee.scss";
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import _ from "lodash"
|
import _ from "lodash"
|
||||||
import StyleRuleManager from "@/plugins/condition/StyleRuleManager";
|
import StyleRuleManager from "@/plugins/condition/StyleRuleManager";
|
||||||
|
import {STYLE_CONSTANTS} from "@/plugins/condition/utils/constants";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inject: ["openmct"],
|
inject: ["openmct"],
|
||||||
@ -37,13 +38,12 @@ export default {
|
|||||||
this.unlisten();
|
this.unlisten();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.stopListeningConditionalStyles) {
|
if (this.stopListeningStyles) {
|
||||||
this.stopListeningConditionalStyles();
|
this.stopListeningStyles();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.styleRuleManager) {
|
if (this.styleRuleManager) {
|
||||||
this.styleRuleManager.destroy();
|
this.styleRuleManager.destroy();
|
||||||
this.styleRuleManager.off('conditionalStyleUpdated', this.updateStyle.bind(this));
|
|
||||||
delete this.styleRuleManager;
|
delete this.styleRuleManager;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -60,7 +60,7 @@ export default {
|
|||||||
this.$el.addEventListener('drop', this.addObjectToParent);
|
this.$el.addEventListener('drop', this.addObjectToParent);
|
||||||
if (this.currentObject) {
|
if (this.currentObject) {
|
||||||
//This is to apply styles to subobjects in a layout
|
//This is to apply styles to subobjects in a layout
|
||||||
this.initConditionalStyles();
|
this.initObjectStyles();
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
@ -102,8 +102,19 @@ export default {
|
|||||||
}
|
}
|
||||||
let keys = Object.keys(styleObj);
|
let keys = Object.keys(styleObj);
|
||||||
keys.forEach(key => {
|
keys.forEach(key => {
|
||||||
this.$el.style[key] = styleObj[key];
|
if ((typeof styleObj[key] === 'string') && (styleObj[key].indexOf('transparent') > -1)) {
|
||||||
})
|
if (this.$el.style[key]) {
|
||||||
|
this.$el.style[key] = '';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!styleObj.isStyleInvisible && this.$el.classList.contains(STYLE_CONSTANTS.isStyleInvisible)) {
|
||||||
|
this.$el.classList.remove(STYLE_CONSTANTS.isStyleInvisible);
|
||||||
|
} else if (styleObj.isStyleInvisible && !this.$el.classList.contains(styleObj.isStyleInvisible)) {
|
||||||
|
this.$el.classList.add(styleObj.isStyleInvisible);
|
||||||
|
}
|
||||||
|
this.$el.style[key] = styleObj[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
updateView(immediatelySelect) {
|
updateView(immediatelySelect) {
|
||||||
this.clear();
|
this.clear();
|
||||||
@ -181,25 +192,24 @@ export default {
|
|||||||
|
|
||||||
this.viewKey = viewKey;
|
this.viewKey = viewKey;
|
||||||
|
|
||||||
this.initConditionalStyles();
|
this.initObjectStyles();
|
||||||
|
|
||||||
this.updateView(immediatelySelect);
|
this.updateView(immediatelySelect);
|
||||||
},
|
},
|
||||||
initConditionalStyles() {
|
initObjectStyles() {
|
||||||
if (!this.styleRuleManager) {
|
if (!this.styleRuleManager) {
|
||||||
this.styleRuleManager = new StyleRuleManager((this.currentObject.configuration && this.currentObject.configuration.conditionalStyle), this.openmct);
|
this.styleRuleManager = new StyleRuleManager((this.currentObject.configuration && this.currentObject.configuration.objectStyles), this.openmct, this.updateStyle.bind(this));
|
||||||
this.styleRuleManager.on('conditionalStyleUpdated', this.updateStyle.bind(this));
|
|
||||||
} else {
|
} else {
|
||||||
this.styleRuleManager.updateConditionalStyleConfig(this.currentObject.configuration && this.currentObject.configuration.conditionalStyle);
|
this.styleRuleManager.updateObjectStyleConfig(this.currentObject.configuration && this.currentObject.configuration.objectStyles);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.stopListeningConditionalStyles) {
|
if (this.stopListeningStyles) {
|
||||||
this.stopListeningConditionalStyles();
|
this.stopListeningStyles();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.stopListeningConditionalStyles = this.openmct.objects.observe(this.currentObject, 'configuration.conditionalStyle', (newConditionalStyle) => {
|
this.stopListeningStyles = this.openmct.objects.observe(this.currentObject, 'configuration.objectStyles', (newObjectStyle) => {
|
||||||
//Updating conditional styles in the inspector view will trigger this so that the changes are reflected immediately
|
//Updating styles in the inspector view will trigger this so that the changes are reflected immediately
|
||||||
this.styleRuleManager.updateConditionalStyleConfig(newConditionalStyle);
|
this.styleRuleManager.updateObjectStyleConfig(newObjectStyle);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
loadComposition() {
|
loadComposition() {
|
||||||
|
@ -1,28 +1,42 @@
|
|||||||
.c-object-label {
|
.c-object-label {
|
||||||
// <a> tag and draggable element that holds type icon and name.
|
// <a> tag and draggable element that holds type icon and name.
|
||||||
// Used mostly in trees and lists
|
// Used mostly in trees and lists
|
||||||
border-radius: $controlCr;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex: 1 1 auto;
|
flex: 0 1 auto;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: $interiorMarginSm 1px;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
&__name {
|
&__name {
|
||||||
@include ellipsize();
|
@include ellipsize();
|
||||||
display: inline;
|
display: inline;
|
||||||
color: $colorItemTreeFg;
|
}
|
||||||
|
|
||||||
|
&__type-icon,
|
||||||
|
&:before {
|
||||||
|
// Type icon. Must be an HTML entity to allow inclusion of alias indicator.
|
||||||
|
display: block;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
font-size: 1.1em;
|
||||||
|
opacity: 0.6;
|
||||||
|
margin-right: $interiorMargin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-tree .c-object-label {
|
||||||
|
border-radius: $controlCr;
|
||||||
|
padding: $interiorMarginSm 1px;
|
||||||
|
|
||||||
|
&__name {
|
||||||
|
display: inline;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__type-icon {
|
&__type-icon {
|
||||||
// Type icon. Must be an HTML entity to allow inclusion of alias indicator.
|
|
||||||
display: block;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
font-size: 1.3em;
|
|
||||||
margin-right: $interiorMarginSm;
|
|
||||||
color: $colorItemTreeIcon;
|
color: $colorItemTreeIcon;
|
||||||
|
font-size: 1.25em;
|
||||||
|
margin-right: $interiorMarginSm;
|
||||||
|
opacity: 1;
|
||||||
width: $treeTypeIconW;
|
width: $treeTypeIconW;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
'c-disclosure-triangle--expanded' : value,
|
'c-disclosure-triangle--expanded' : value,
|
||||||
'is-enabled' : enabled
|
'is-enabled' : enabled
|
||||||
}"
|
}"
|
||||||
@click="$emit('input', !value)"
|
@click="handleClick"
|
||||||
></span>
|
></span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -21,6 +21,18 @@ export default {
|
|||||||
// Used as such in the tree - when a node doesn't have children, set disabled to true.
|
// Used as such in the tree - when a node doesn't have children, set disabled to true.
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
propagate: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleClick(event) {
|
||||||
|
this.$emit('input', !this.value);
|
||||||
|
if (!this.propagate) {
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,44 +1,40 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="c-inspector">
|
<div class="c-inspector">
|
||||||
<div class="c-inspector__tabs">
|
<object-name />
|
||||||
<div v-if="showStyles"
|
<div v-if="showStyles"
|
||||||
class="c-inspector__tabs__holder"
|
class="c-inspector__tabs c-tabs"
|
||||||
|
>
|
||||||
|
<div v-for="tabbedView in tabbedViews"
|
||||||
|
:key="tabbedView.key"
|
||||||
|
class="c-inspector__tab c-tab"
|
||||||
|
:class="{'is-current': isCurrent(tabbedView)}"
|
||||||
|
@click="updateCurrentTab(tabbedView)"
|
||||||
>
|
>
|
||||||
<div v-for="tabbedView in tabbedViews"
|
{{ tabbedView.name }}
|
||||||
:key="tabbedView.key"
|
|
||||||
class="c-inspector__tabs__header"
|
|
||||||
@click="updateCurrentTab(tabbedView)"
|
|
||||||
>
|
|
||||||
<span class="c-inspector__tabs__label c-tab"
|
|
||||||
:class="{'is-current': isCurrent(tabbedView)}"
|
|
||||||
>{{ tabbedView.name }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="c-inspector__tabs__contents">
|
|
||||||
<multipane v-if="currentTabbedView.key === '__properties'"
|
</div>
|
||||||
class="c-inspector"
|
<div class="c-inspector__content">
|
||||||
type="vertical"
|
<multipane v-if="currentTabbedView.key === '__properties'"
|
||||||
>
|
type="vertical"
|
||||||
<pane class="c-inspector__properties">
|
>
|
||||||
<properties />
|
<pane class="c-inspector__properties">
|
||||||
<location />
|
<properties />
|
||||||
<inspector-views />
|
<location />
|
||||||
</pane>
|
<inspector-views />
|
||||||
<pane
|
|
||||||
v-if="isEditing && hasComposition"
|
|
||||||
class="c-inspector__elements"
|
|
||||||
handle="before"
|
|
||||||
label="Elements"
|
|
||||||
>
|
|
||||||
<elements />
|
|
||||||
</pane>
|
|
||||||
</multipane>
|
|
||||||
<pane v-else
|
|
||||||
class="c-inspector__styles"
|
|
||||||
>
|
|
||||||
<styles-inspector-view />
|
|
||||||
</pane>
|
</pane>
|
||||||
</div>
|
<pane
|
||||||
|
v-if="isEditing && hasComposition"
|
||||||
|
class="c-inspector__elements"
|
||||||
|
handle="before"
|
||||||
|
label="Elements"
|
||||||
|
>
|
||||||
|
<elements />
|
||||||
|
</pane>
|
||||||
|
</multipane>
|
||||||
|
<template v-else>
|
||||||
|
<styles-inspector-view />
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -49,6 +45,7 @@ import pane from '../layout/pane.vue';
|
|||||||
import Elements from './Elements.vue';
|
import Elements from './Elements.vue';
|
||||||
import Location from './Location.vue';
|
import Location from './Location.vue';
|
||||||
import Properties from './Properties.vue';
|
import Properties from './Properties.vue';
|
||||||
|
import ObjectName from './ObjectName.vue';
|
||||||
import InspectorViews from './InspectorViews.vue';
|
import InspectorViews from './InspectorViews.vue';
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import StylesInspectorView from "./StylesInspectorView.vue";
|
import StylesInspectorView from "./StylesInspectorView.vue";
|
||||||
@ -62,6 +59,7 @@ export default {
|
|||||||
pane,
|
pane,
|
||||||
Elements,
|
Elements,
|
||||||
Properties,
|
Properties,
|
||||||
|
ObjectName,
|
||||||
Location,
|
Location,
|
||||||
InspectorViews
|
InspectorViews
|
||||||
},
|
},
|
||||||
@ -112,7 +110,10 @@ export default {
|
|||||||
let type = this.openmct.types.get(object.type);
|
let type = this.openmct.types.get(object.type);
|
||||||
this.showStyles = (this.excludeObjectTypes.indexOf(object.type) < 0) && type.definition.creatable;
|
this.showStyles = (this.excludeObjectTypes.indexOf(object.type) < 0) && type.definition.creatable;
|
||||||
}
|
}
|
||||||
this.updateCurrentTab(this.tabbedViews[0]);
|
if (!this.currentTabbedView.key || (!this.showStyles && this.currentTabbedView.key === this.tabbedViews[1].key))
|
||||||
|
{
|
||||||
|
this.updateCurrentTab(this.tabbedViews[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updateCurrentTab(view) {
|
updateCurrentTab(view) {
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="c-properties c-properties--location">
|
<div class="c-inspect-properties c-inspect-properties--location">
|
||||||
<div
|
<div
|
||||||
class="c-properties__header"
|
class="c-inspect-properties__header"
|
||||||
title="The location of this linked object."
|
title="The location of this linked object."
|
||||||
>
|
>
|
||||||
Original Location
|
Original Location
|
||||||
</div>
|
</div>
|
||||||
<ul
|
<ul
|
||||||
v-if="!multiSelect"
|
v-if="!multiSelect"
|
||||||
class="c-properties__section"
|
class="c-inspect-properties__section"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
v-if="originalPath.length"
|
v-if="originalPath.length"
|
||||||
class="c-properties__row"
|
class="c-inspect-properties__row"
|
||||||
>
|
>
|
||||||
<ul class="c-properties__value c-location">
|
<ul class="c-inspect-properties__value c-location">
|
||||||
<li
|
<li
|
||||||
v-for="pathObject in orderedOriginalPath"
|
v-for="pathObject in orderedOriginalPath"
|
||||||
:key="pathObject.key"
|
:key="pathObject.key"
|
||||||
@ -30,7 +30,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
<div
|
<div
|
||||||
v-if="multiSelect"
|
v-if="multiSelect"
|
||||||
class="c-properties__row--span-all"
|
class="c-inspect-properties__row--span-all"
|
||||||
>
|
>
|
||||||
No location to display for multiple items
|
No location to display for multiple items
|
||||||
</div>
|
</div>
|
||||||
|
76
src/ui/inspector/ObjectName.vue
Normal file
76
src/ui/inspector/ObjectName.vue
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<template>
|
||||||
|
<div class="c-inspector__header">
|
||||||
|
<div v-if="!multiSelect && !singleSelectNonObject"
|
||||||
|
class="c-inspector__selected-w c-object-label"
|
||||||
|
:class="typeCssClass"
|
||||||
|
>
|
||||||
|
<span class="c-inspector__selected c-object-label__name">{{ item.name }}</span>
|
||||||
|
</div>
|
||||||
|
<div v-if="singleSelectNonObject"
|
||||||
|
class="c-inspector__selected-w c-object-label"
|
||||||
|
:class="typeCssClass"
|
||||||
|
>
|
||||||
|
<span class="c-inspector__selected c-object-label__name c-inspector__selected--non-domain-object">Layout Object</span>
|
||||||
|
</div>
|
||||||
|
<div v-if="multiSelect"
|
||||||
|
class="c-inspector__multiple-selected-w"
|
||||||
|
>
|
||||||
|
{{ itemsSelected }} items selected
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
inject: ['openmct'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
domainObject: {},
|
||||||
|
multiSelect: false,
|
||||||
|
itemsSelected: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
item() {
|
||||||
|
return this.domainObject || {};
|
||||||
|
},
|
||||||
|
type() {
|
||||||
|
return this.openmct.types.get(this.item.type);
|
||||||
|
},
|
||||||
|
typeCssClass() {
|
||||||
|
if (this.type.definition.cssClass === undefined) {
|
||||||
|
return 'icon-object';
|
||||||
|
}
|
||||||
|
return this.type.definition.cssClass;
|
||||||
|
},
|
||||||
|
singleSelectNonObject() {
|
||||||
|
return !this.item.identifier && !this.multiSelect;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.openmct.selection.on('change', this.updateSelection);
|
||||||
|
this.updateSelection(this.openmct.selection.get());
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.openmct.selection.off('change', this.updateSelection);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
updateSelection(selection) {
|
||||||
|
if (selection.length === 0 || selection[0].length === 0) {
|
||||||
|
this.domainObject = {};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selection.length > 1) {
|
||||||
|
this.multiSelect = true;
|
||||||
|
this.domainObject = {};
|
||||||
|
this.itemsSelected = selection.length;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
this.multiSelect = false;
|
||||||
|
this.domainObject = selection[0][0].context.item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -1,72 +1,72 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="c-properties c-properties--properties">
|
<div class="c-inspector__properties c-inspect-properties">
|
||||||
<div class="c-properties__header">
|
<div class="c-inspect-properties__header">
|
||||||
Properties
|
Details
|
||||||
</div>
|
</div>
|
||||||
<ul
|
<ul
|
||||||
v-if="!multiSelect && !singleSelectNonObject"
|
v-if="!multiSelect && !singleSelectNonObject"
|
||||||
class="c-properties__section"
|
class="c-inspect-properties__section"
|
||||||
>
|
>
|
||||||
<li class="c-properties__row">
|
<li class="c-inspect-properties__row">
|
||||||
<div class="c-properties__label">
|
<div class="c-inspect-properties__label">
|
||||||
Title
|
Title
|
||||||
</div>
|
</div>
|
||||||
<div class="c-properties__value">
|
<div class="c-inspect-properties__value">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="c-properties__row">
|
<li class="c-inspect-properties__row">
|
||||||
<div class="c-properties__label">
|
<div class="c-inspect-properties__label">
|
||||||
Type
|
Type
|
||||||
</div>
|
</div>
|
||||||
<div class="c-properties__value">
|
<div class="c-inspect-properties__value">
|
||||||
{{ typeName }}
|
{{ typeName }}
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
v-if="item.created"
|
v-if="item.created"
|
||||||
class="c-properties__row"
|
class="c-inspect-properties__row"
|
||||||
>
|
>
|
||||||
<div class="c-properties__label">
|
<div class="c-inspect-properties__label">
|
||||||
Created
|
Created
|
||||||
</div>
|
</div>
|
||||||
<div class="c-properties__value">
|
<div class="c-inspect-properties__value">
|
||||||
{{ formatTime(item.created) }}
|
{{ formatTime(item.created) }}
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
v-if="item.modified"
|
v-if="item.modified"
|
||||||
class="c-properties__row"
|
class="c-inspect-properties__row"
|
||||||
>
|
>
|
||||||
<div class="c-properties__label">
|
<div class="c-inspect-properties__label">
|
||||||
Modified
|
Modified
|
||||||
</div>
|
</div>
|
||||||
<div class="c-properties__value">
|
<div class="c-inspect-properties__value">
|
||||||
{{ formatTime(item.modified) }}
|
{{ formatTime(item.modified) }}
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
v-for="prop in typeProperties"
|
v-for="prop in typeProperties"
|
||||||
:key="prop.name"
|
:key="prop.name"
|
||||||
class="c-properties__row"
|
class="c-inspect-properties__row"
|
||||||
>
|
>
|
||||||
<div class="c-properties__label">
|
<div class="c-inspect-properties__label">
|
||||||
{{ prop.name }}
|
{{ prop.name }}
|
||||||
</div>
|
</div>
|
||||||
<div class="c-properties__value">
|
<div class="c-inspect-properties__value">
|
||||||
{{ prop.value }}
|
{{ prop.value }}
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div
|
<div
|
||||||
v-if="multiSelect"
|
v-if="multiSelect"
|
||||||
class="c-properties__row--span-all"
|
class="c-inspect-properties__row--span-all"
|
||||||
>
|
>
|
||||||
No properties to display for multiple items
|
No properties to display for multiple items
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="singleSelectNonObject"
|
v-if="singleSelectNonObject"
|
||||||
class="c-properties__row--span-all"
|
class="c-inspect-properties__row--span-all"
|
||||||
>
|
>
|
||||||
No properties to display for this item
|
No properties to display for this item
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div></div>
|
<div class="u-contents"></div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ConditionalStylesView from '../../plugins/condition/components/inspector/ConditionalStylesView.vue';
|
import ConditionalStylesView from '../../plugins/condition/components/inspector/ConditionalStylesView.vue';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
@ -34,17 +31,18 @@ export default {
|
|||||||
},
|
},
|
||||||
updateSelection(selection) {
|
updateSelection(selection) {
|
||||||
if (selection.length > 0 && selection[0].length > 0) {
|
if (selection.length > 0 && selection[0].length > 0) {
|
||||||
|
let isChildItem = false;
|
||||||
let domainObject = selection[0][0].context.item;
|
let domainObject = selection[0][0].context.item;
|
||||||
let layoutItem = {};
|
let layoutItem = {};
|
||||||
let styleProps = this.getStyleProperties({
|
let styleProps = this.getStyleProperties({
|
||||||
fill: 'inherit',
|
fill: 'transparent',
|
||||||
stroke: 'inherit',
|
stroke: 'transparent',
|
||||||
color: 'inherit'
|
color: 'transparent'
|
||||||
});
|
});
|
||||||
if (selection[0].length > 1) {
|
if (selection[0].length > 1) {
|
||||||
|
isChildItem = true;
|
||||||
//If there are more than 1 items in the selection[0] list, the first one could either be a sub domain object OR a layout drawing control.
|
//If there are more than 1 items in the selection[0] list, the first one could either be a sub domain object OR a layout drawing control.
|
||||||
//The second item in the selection[0] list is the container object (usually a layout)
|
//The second item in the selection[0] list is the container object (usually a layout)
|
||||||
domainObject = selection[0][0].context.item;
|
|
||||||
if (!domainObject) {
|
if (!domainObject) {
|
||||||
styleProps = {};
|
styleProps = {};
|
||||||
layoutItem = selection[0][0].context.layoutItem;
|
layoutItem = selection[0][0].context.layoutItem;
|
||||||
@ -58,7 +56,6 @@ export default {
|
|||||||
this.component = undefined;
|
this.component = undefined;
|
||||||
this.$el.innerHTML = '';
|
this.$el.innerHTML = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
let viewContainer = document.createElement('div');
|
let viewContainer = document.createElement('div');
|
||||||
this.$el.append(viewContainer);
|
this.$el.append(viewContainer);
|
||||||
this.component = new Vue({
|
this.component = new Vue({
|
||||||
@ -73,10 +70,11 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
layoutItem,
|
layoutItem,
|
||||||
styleProps
|
styleProps,
|
||||||
|
isChildItem
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
template: '<conditional-styles-view :item-id="layoutItem.id" :initial-styles="styleProps"></conditional-styles-view>'
|
template: '<conditional-styles-view :can-hide="isChildItem" :item-id="layoutItem.id" :initial-styles="styleProps"></conditional-styles-view>'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,46 @@
|
|||||||
.c-inspector {
|
.c-inspector {
|
||||||
height: 100%;
|
display: flex;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
> [class*="__"] {
|
> * {
|
||||||
min-height: 50px;
|
// Thi is on purpose: want extra margin on top object-name element
|
||||||
|
margin-top: $interiorMargin;
|
||||||
|
}
|
||||||
|
|
||||||
+ [class*="__"] {
|
&__selected-w,
|
||||||
margin-top: $interiorMargin;
|
&__multiple-selected-w {
|
||||||
|
@include headerFont(1.1em);
|
||||||
|
padding: $interiorMarginSm 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__multiple-selected-w {
|
||||||
|
$p: $interiorMarginLg;
|
||||||
|
background: rgba($colorWarningLo, 0.3);
|
||||||
|
border-radius: $basicCr;
|
||||||
|
display: inline-block;
|
||||||
|
font-style: italic;
|
||||||
|
padding-left: $p;
|
||||||
|
padding-right: $p;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__selected {
|
||||||
|
@include ellipsize();
|
||||||
|
flex: 1 1 auto;
|
||||||
|
|
||||||
|
&--non-domain-object {
|
||||||
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
> .l-pane__contents {
|
&__tabs {
|
||||||
overflow: auto;
|
flex: 0 0 auto;
|
||||||
|
font-size: 0.8em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
> * {
|
&__content {
|
||||||
// Fend off scrollbar
|
flex: 1 1 auto;
|
||||||
margin-right: $interiorMarginSm;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__elements {
|
&__elements {
|
||||||
@ -58,67 +83,41 @@
|
|||||||
margin-left: $treeItemIndent;
|
margin-left: $treeItemIndent;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__tabs {
|
.l-multipane {
|
||||||
$h: 20px;
|
.l-pane {
|
||||||
@include abs();
|
min-height: 50px;
|
||||||
display: flex;
|
|
||||||
flex-flow: column nowrap;
|
|
||||||
|
|
||||||
> * + * {
|
|
||||||
margin-top: $interiorMargin;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__holder {
|
|
||||||
display: flex;
|
|
||||||
min-height: $h;
|
|
||||||
|
|
||||||
&__header {
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
margin-right: $interiorMarginSm;
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__contents {
|
|
||||||
flex: 1 1 auto;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
&--hidden {
|
|
||||||
height: 1000px;
|
|
||||||
width: 1000px;
|
|
||||||
position: absolute;
|
|
||||||
left: -9999px;
|
|
||||||
top: -9999px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.c-properties {
|
.c-inspect-properties,
|
||||||
display: grid;
|
.c-inspect-styles {
|
||||||
grid-row-gap: 0;
|
|
||||||
grid-template-columns: 1fr 2fr;
|
|
||||||
align-items: start;
|
|
||||||
min-width: 150px;
|
|
||||||
|
|
||||||
[class*="header"] {
|
[class*="header"] {
|
||||||
@include propertiesHeader();
|
@include propertiesHeader();
|
||||||
|
flex: 0 0 auto;
|
||||||
|
font-size: .85em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
|
||||||
&:not(:first-child) {
|
&:not(:first-child) {
|
||||||
// Allow multiple headers within a component
|
// Allow multiple headers within a component
|
||||||
margin-top: $interiorMarginLg;
|
margin-top: $interiorMarginLg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
/********************************************* INSPECTOR PROPERTIES TAB */
|
||||||
|
.c-inspect-properties {
|
||||||
|
display: grid;
|
||||||
|
grid-row-gap: $interiorMarginSm;
|
||||||
|
grid-template-columns: 1fr 2fr;
|
||||||
|
align-items: start;
|
||||||
|
min-width: 150px;
|
||||||
|
|
||||||
[class*="span-all"],
|
[class*="span-all"],
|
||||||
[class*="header"] {
|
[class*="header"] {
|
||||||
grid-column: 1 / 3;
|
grid-column: 1 / 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ .c-properties {
|
+ .c-inspect-properties {
|
||||||
margin-top: $interiorMarginLg;
|
margin-top: $interiorMarginLg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,11 +135,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__header {
|
|
||||||
font-size: .85em;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__label,
|
&__label,
|
||||||
&__value {
|
&__value {
|
||||||
padding: 3px $interiorMarginLg 3px 0;
|
padding: 3px $interiorMarginLg 3px 0;
|
||||||
@ -164,6 +158,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************* LEGACY SUPPORT */
|
/********************************************* LEGACY SUPPORT */
|
||||||
.c-inspector {
|
.c-inspector {
|
||||||
// FilterField.vue
|
// FilterField.vue
|
||||||
|
@ -7,11 +7,11 @@
|
|||||||
@click="goToParent"
|
@click="goToParent"
|
||||||
></button>
|
></button>
|
||||||
<div
|
<div
|
||||||
class="l-browse-bar__object-name--w"
|
class="l-browse-bar__object-name--w c-object-label"
|
||||||
:class="type.cssClass"
|
:class="type.cssClass"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="l-browse-bar__object-name c-input-inline"
|
class="l-browse-bar__object-name c-object-label__name c-input-inline"
|
||||||
contenteditable
|
contenteditable
|
||||||
@blur="updateName"
|
@blur="updateName"
|
||||||
@keydown.enter.prevent
|
@keydown.enter.prevent
|
||||||
|
@ -35,9 +35,15 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column nowrap;
|
flex-flow: column nowrap;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__pane-tree,
|
||||||
|
&__pane-main {
|
||||||
|
.l-pane__contents {
|
||||||
> * {
|
> * {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
|
|
||||||
+ * {
|
+ * {
|
||||||
margin-top: $interiorMarginLg;
|
margin-top: $interiorMarginLg;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
.c-tree-and-search {
|
.c-tree-and-search {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
flex: 1 1 auto;
|
||||||
padding-right: $interiorMarginSm;
|
padding-right: $interiorMarginSm;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
@ -136,3 +137,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.c-selector {
|
||||||
|
.c-tree-and-search__tree.c-tree {
|
||||||
|
border: 1px solid $colorInteriorBorder;
|
||||||
|
border-radius: $controlCr;
|
||||||
|
padding: $interiorMargin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -15,6 +15,9 @@
|
|||||||
|
|
||||||
&--vertical {
|
&--vertical {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
> .l-pane .l-pane__contents {
|
||||||
|
padding-right: $interiorMarginSm; // Fend off scrollbar
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,9 +93,6 @@
|
|||||||
// Don't pad all nested __contents
|
// Don't pad all nested __contents
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
> [class*="__"] + [class*="__"] {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************ DESKTOP STYLES */
|
/************************************************ DESKTOP STYLES */
|
||||||
@ -263,6 +263,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&[class*="--vertical"] {
|
&[class*="--vertical"] {
|
||||||
|
// l-pane--vertical
|
||||||
|
|
||||||
> .l-pane__handle {
|
> .l-pane__handle {
|
||||||
cursor: row-resize;
|
cursor: row-resize;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
@ -36,7 +36,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onClick(event) {
|
onClick(event) {
|
||||||
if (this.options.dialog) {
|
if ((this.options.isEditing === undefined || this.options.isEditing) && this.options.dialog) {
|
||||||
this.openmct.$injector.get('dialogService')
|
this.openmct.$injector.get('dialogService')
|
||||||
.getUserInput(this.options.dialog, this.options.value)
|
.getUserInput(this.options.dialog, this.options.value)
|
||||||
.then(value => {
|
.then(value => {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
class="c-icon-button c-icon-button--swatched"
|
class="c-icon-button c-icon-button--swatched"
|
||||||
:class="[options.icon, {'c-icon-button--mixed': nonSpecific}]"
|
:class="[options.icon, {'c-icon-button--mixed': nonSpecific}]"
|
||||||
:title="options.title"
|
:title="options.title"
|
||||||
@click="toggle"
|
@click="handleClick"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="c-swatch"
|
class="c-swatch"
|
||||||
@ -146,6 +146,11 @@ export default {
|
|||||||
if (color.value !== this.options.value) {
|
if (color.value !== this.options.value) {
|
||||||
this.$emit('change', color.value, this.options);
|
this.$emit('change', color.value, this.options);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
handleClick(event) {
|
||||||
|
if ((this.options.isEditing === undefined) || this.options.isEditing) {
|
||||||
|
this.toggle(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,9 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
cycle() {
|
cycle() {
|
||||||
this.$emit('change', this.nextValue.value, this.options);
|
if (this.options.isEditing === undefined || this.options.isEditing) {
|
||||||
|
this.$emit('change', this.nextValue.value, this.options);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user