Compare commits

...

8 Commits

Author SHA1 Message Date
501bdf8f5d [NIRVSS] [Types] Create button to display creatable types dynamically #3273 2020-08-05 12:04:16 -07:00
e32f465f7a Display layout plugin test coverage to 20% or more (#3158)
* Display layout plugin test coverage to 20% or more
Resolves #3157

* Changes address original issue? Yes
* Unit tests included and/or updated with changes? Yes
* Command line build passes? Yes
* Changes have been smoke-tested? Yes
* Testing instructions included? Yes

* Add disable-dev-shm-usage flag to ChromeHeadless launcher config in karma

* Adding disable dev shm usage flag to chromeheadless launcher and setting log level to debug

* Adding np activity timeout to 60000

* Adding no-sandbox flag for headless chrome

* Run tests without headless chrome to see if that fixes the fonts issue

* Fix typo

* Trying chrome headless with increased memory

* Reset karma.conf back to master

* Trying karma chrome launcher 3.1.0

* Revert to master code for package.json and karma.conf.js

* Trying node 12 browsers

* Revert back to node:13 browsers

* Revert to 10.2.1-browsers circle ci node browsers variant image for docker

* Rebuild node-sass for node 10.x

* Upgrading to 13.14.0 node

* Remove node options

* Don't restore cache before npm install

* Comment out tests with setTimeout

* Trying node 8-browsers

* Try firefox headless

* Firefox version typo

* Revert focused tests

* Exclude setTimeout tests

* Increase browser connectivity timeout

* Trying large timeout with Chromeheadless

* Going back to Firefox and setting browser timeout to 1.5 mins

* Fixes linting issues

* Fix broken tests and add some null checks in the code

* Change double quotes to single quotes
2020-08-03 13:41:57 -07:00
abc458cef4 [Time conductor] Better persistence handling for history (#3246) 2020-08-03 11:56:29 -07:00
b76d4b76cb Merge pull request #3228 from nasa/telemetry-table-config-updates
Update TelemetryTable config to allow disable multiselect
2020-07-31 14:41:49 -07:00
5a4cba0226 Merge branch 'master' into telemetry-table-config-updates 2020-07-31 14:23:12 -07:00
f03bfdebb4 [Telemetry Tables][Plots] Display units where applicable (#3198)
* added unit columns in telemetry tables

* added unit column hiding in telemetry tables, added units to lad tables and sets

* added units to plots and plot legends
2020-07-31 13:13:58 -07:00
13ff0c368d Merge branch 'master' into telemetry-table-config-updates 2020-07-24 10:46:02 -07:00
b7d2402434 Update TelemetryTable config to allow disable multiselect. 2020-07-23 14:11:44 -07:00
24 changed files with 681 additions and 74 deletions

View File

@ -41,6 +41,7 @@ define([
{
key: "sin",
name: "Sine",
unit: "Hz",
formatString: '%0.2f',
hints: {
range: 1
@ -49,6 +50,7 @@ define([
{
key: "cos",
name: "Cosine",
unit: "deg",
formatString: '%0.2f',
hints: {
range: 2

View File

@ -32,6 +32,12 @@
class="js-third-data"
:class="valueClass"
>{{ value }}</td>
<td
v-if="hasUnits"
class="js-units"
>
{{ unit }}
</td>
</tr>
</template>
@ -48,6 +54,10 @@ export default {
domainObject: {
type: Object,
required: true
},
hasUnits: {
type: Boolean,
requred: true
}
},
data() {
@ -59,7 +69,8 @@ export default {
timestamp: undefined,
value: '---',
valueClass: '',
currentObjectPath
currentObjectPath,
unit: ''
};
},
computed: {
@ -101,6 +112,10 @@ export default {
.subscribe(this.domainObject, this.updateValues);
this.requestHistory();
if (this.hasUnits) {
this.setUnit();
}
},
destroyed() {
this.stopWatchingMutation();
@ -186,6 +201,9 @@ export default {
return false;
}
},
setUnit() {
this.unit = this.valueMetadata.unit || '';
}
}
};

View File

@ -28,6 +28,7 @@
<th>Name</th>
<th>Timestamp</th>
<th>Value</th>
<th v-if="hasUnits">Unit</th>
</tr>
</thead>
<tbody>
@ -35,6 +36,7 @@
v-for="item in items"
:key="item.key"
:domain-object="item.domainObject"
:has-units="hasUnits"
/>
</tbody>
</table>
@ -54,6 +56,18 @@ export default {
items: []
};
},
computed: {
hasUnits() {
let itemsWithUnits = this.items.filter((item) => {
let metadata = this.openmct.telemetry.getMetadata(item.domainObject);
return this.metadataHasUnits(metadata.valueMetadatas);
});
return itemsWithUnits.length !== 0;
}
},
mounted() {
this.composition = this.openmct.composition.get(this.domainObject);
this.composition.on('add', this.addItem);
@ -84,6 +98,11 @@ export default {
reorderPlan.forEach((reorderEvent) => {
this.$set(this.items, reorderEvent.newIndex, oldItems[reorderEvent.oldIndex]);
});
},
metadataHasUnits(valueMetadatas) {
let metadataWithUnits = valueMetadatas.filter(metadatum => metadatum.unit);
return metadataWithUnits.length > 0;
}
}
};

View File

@ -27,6 +27,7 @@
<th>Name</th>
<th>Timestamp</th>
<th>Value</th>
<th v-if="hasUnits">Unit</th>
</tr>
</thead>
<tbody>
@ -45,6 +46,7 @@
v-for="secondary in secondaryTelemetryObjects[primary.key]"
:key="secondary.key"
:domain-object="secondary.domainObject"
:has-units="hasUnits"
/>
</template>
</tbody>
@ -66,6 +68,23 @@ export default {
compositions: []
};
},
computed: {
hasUnits() {
let ladTables = Object.values(this.secondaryTelemetryObjects);
for (let ladTable of ladTables) {
for (let telemetryObject of ladTable) {
let metadata = this.openmct.telemetry.getMetadata(telemetryObject.domainObject);
for (let metadatum of metadata.valueMetadatas) {
if (metadatum.unit) {
return true;
}
}
}
}
return false;
}
},
mounted() {
this.composition = this.openmct.composition.get(this.domainObject);
this.composition.on('add', this.addPrimary);
@ -109,9 +128,8 @@ export default {
let index = this.primaryTelemetryObjects.findIndex(primary => this.openmct.objects.makeKeyString(identifier) === primary.key),
primary = this.primaryTelemetryObjects[index];
this.$set(this.secondaryTelemetryObjects, primary.key, undefined);
this.$delete(this.secondaryTelemetryObjects, primary.key);
this.primaryTelemetryObjects.splice(index, 1);
primary = undefined;
},
reorderPrimary(reorderPlan) {
let oldComposition = this.primaryTelemetryObjects.slice();

View File

@ -422,7 +422,7 @@ describe('the plugin', function () {
"telemetry": "any",
"operation": "isStale",
"input": [
"1"
"0.2"
],
"metadata": "dataReceived"
}
@ -481,12 +481,12 @@ describe('the plugin', function () {
utc: undefined
});
done();
}, 1500);
}, 300);
});
it('should not evaluate as stale when telemetry is received in the allotted time', (done) => {
const date = Date.now();
conditionSetDomainObject.configuration.conditionCollection[0].configuration.criteria[0].input = ["2"];
conditionSetDomainObject.configuration.conditionCollection[0].configuration.criteria[0].input = ["0.4"];
let conditionMgr = new ConditionManager(conditionSetDomainObject, openmct);
conditionMgr.on('conditionSetResultUpdated', mockListener);
conditionMgr.telemetryObjects = {
@ -507,7 +507,7 @@ describe('the plugin', function () {
utc: undefined
});
done();
}, 1500);
}, 300);
});
});
});

View File

@ -134,6 +134,14 @@ define(['lodash'], function (_) {
return `configuration.items[${selectionPath[0].context.index}]`;
}
function getAllOfType(selection, specificType) {
return selection.filter(selectionPath => {
let type = selectionPath[0].context.layoutItem.type;
return type === specificType;
});
}
function getAllTypes(selection) {
return selection.filter(selectionPath => {
let type = selectionPath[0].context.layoutItem.type;
@ -510,6 +518,54 @@ define(['lodash'], function (_) {
return allTelemetry;
}
function getToggleUnitsButton(selectedParent, selection) {
let applicableItems = getAllOfType(selection, 'telemetry-view');
applicableItems = unitsOnly(applicableItems);
if (!applicableItems.length) {
return;
}
return {
control: "toggle-button",
domainObject: selectedParent,
applicableSelectedItems: applicableItems,
property: function (selectionPath) {
return getPath(selectionPath) + '.showUnits';
},
options: [
{
value: true,
icon: 'icon-eye-open',
title: "Show units"
},
{
value: false,
icon: 'icon-eye-disabled',
title: "Hide units"
}
]
};
}
function unitsOnly(items) {
let results = items.filter((item) => {
let currentItem = item[0];
let metadata = openmct.telemetry.getMetadata(currentItem.context.item);
if (!metadata) {
return false;
}
let hasUnits = metadata
.valueMetadatas
.filter((metadatum) => metadatum.unit)
.length;
return hasUnits > 0;
});
return results;
}
function getViewSwitcherMenu(selectedParent, selectionPath, selection) {
if (selection.length === 1) {
let displayLayoutContext = selectionPath[1].context,
@ -594,6 +650,7 @@ define(['lodash'], function (_) {
'text-style': [],
'position': [],
'duplicate': [],
'unit-toggle': [],
'remove': []
};
@ -663,6 +720,13 @@ define(['lodash'], function (_) {
if (toolbar.viewSwitcher.length === 0) {
toolbar.viewSwitcher = [getViewSwitcherMenu(selectedParent, selectionPath, selectedObjects)];
}
if (toolbar['unit-toggle'].length === 0) {
let toggleUnitsButton = getToggleUnitsButton(selectedParent, selectedObjects);
if (toggleUnitsButton) {
toolbar['unit-toggle'] = [toggleUnitsButton];
}
}
} else if (layoutItem.type === 'text-view') {
if (toolbar['text-style'].length === 0) {
toolbar['text-style'] = [

View File

@ -58,6 +58,12 @@
>
<div class="c-telemetry-view__value-text">
{{ telemetryValue }}
<span
v-if="unit && item.showUnits"
class="c-telemetry-view__value-text__unit"
>
{{ unit }}
</span>
</div>
</div>
</div>
@ -137,6 +143,12 @@ export default {
return displayMode === 'all' || displayMode === 'value';
},
unit() {
let value = this.item.value,
unit = this.metadata.value(value).unit;
return unit;
},
styleObject() {
return Object.assign({}, {
fontSize: this.item.size
@ -257,7 +269,9 @@ export default {
item: domainObject,
layoutItem: this.item,
index: this.index,
updateTelemetryFormat: this.updateTelemetryFormat
updateTelemetryFormat: this.updateTelemetryFormat,
toggleUnits: this.toggleUnits,
showUnits: this.showUnits
};
this.removeSelectable = this.openmct.selection.selectable(
this.$el, this.context, this.immediatelySelect || this.initSelect);

View File

@ -0,0 +1,350 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2020, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* 'License'); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
import { createOpenMct, resetApplicationState } from 'utils/testing';
import DisplayLayoutPlugin from './plugin';
describe('the plugin', function () {
let element;
let child;
let openmct;
let displayLayoutDefinition;
beforeAll(() => {
resetApplicationState(openmct);
});
beforeEach((done) => {
openmct = createOpenMct();
openmct.install(new DisplayLayoutPlugin({
showAsView: []
}));
displayLayoutDefinition = openmct.types.get('layout');
element = document.createElement('div');
child = document.createElement('div');
element.appendChild(child);
openmct.on('start', done);
openmct.startHeadless();
});
afterEach(() => {
resetApplicationState(openmct);
});
it('defines a display layout object type with the correct key', () => {
expect(displayLayoutDefinition.definition.name).toEqual('Display Layout');
});
it('provides a view', () => {
const testViewObject = {
id: 'test-object',
type: 'layout',
configuration: {
items: [
{
'identifier': {
'namespace': '',
'key': '55122607-e65e-44d5-9c9d-9c31a914ca89'
},
'x': 8,
'y': 3,
'width': 10,
'height': 5,
'displayMode': 'all',
'value': 'sin',
'stroke': '',
'fill': '',
'color': '',
'size': '13px',
'type': 'telemetry-view',
'id': 'deb9f839-80ad-4ccf-a152-5c763ceb7d7e'
}
],
layoutGrid: [10, 10]
}
};
const applicableViews = openmct.objectViews.get(testViewObject);
let displayLayoutViewProvider = applicableViews.find((viewProvider) => viewProvider.key === 'layout.view');
expect(displayLayoutViewProvider).toBeDefined();
});
describe('the alpha numeric format view', () => {
let displayLayoutItem;
let telemetryItem;
let selection;
beforeEach(() => {
displayLayoutItem = {
'composition': [
],
'configuration': {
'items': [
{
'identifier': {
'namespace': '',
'key': '55122607-e65e-44d5-9c9d-9c31a914ca89'
},
'x': 8,
'y': 3,
'width': 10,
'height': 5,
'displayMode': 'all',
'value': 'sin',
'stroke': '',
'fill': '',
'color': '',
'size': '13px',
'type': 'telemetry-view',
'id': 'deb9f839-80ad-4ccf-a152-5c763ceb7d7e'
}
],
'layoutGrid': [
10,
10
]
},
'name': 'Display Layout',
'type': 'layout',
'identifier': {
'namespace': '',
'key': 'c5e636c1-6771-4c9c-b933-8665cab189b3'
}
};
telemetryItem = {
'telemetry': {
'period': 5,
'amplitude': 5,
'offset': 5,
'dataRateInHz': 5,
'phase': 5,
'randomness': 0
},
'name': 'Sine Wave Generator',
'type': 'generator',
'modified': 1592851063871,
'location': 'mine',
'persisted': 1592851063871,
'id': '55122607-e65e-44d5-9c9d-9c31a914ca89',
'identifier': {
'namespace': '',
'key': '55122607-e65e-44d5-9c9d-9c31a914ca89'
}
};
selection = [
[{
context: {
'layoutItem': displayLayoutItem.configuration.items[0],
'item': telemetryItem,
'index': 1
}
},
{
context: {
'item': displayLayoutItem,
'supportsMultiSelect': true
}
}]
];
});
it('provides an alphanumeric format view', () => {
const displayLayoutAlphaNumFormatView = openmct.inspectorViews.get(selection);
expect(displayLayoutAlphaNumFormatView.length).toBeDefined();
});
});
describe('the toolbar', () => {
let displayLayoutItem;
let selection;
beforeEach(() => {
displayLayoutItem = {
'composition': [
],
'configuration': {
'items': [
{
'fill': '#717171',
'stroke': '',
'x': 1,
'y': 1,
'width': 10,
'height': 5,
'type': 'box-view',
'id': '89b88746-d325-487b-aec4-11b79afff9e8'
},
{
'x': 18,
'y': 9,
'x2': 23,
'y2': 4,
'stroke': '#717171',
'type': 'line-view',
'id': '57d49a28-7863-43bd-9593-6570758916f0'
},
{
'identifier': {
'namespace': '',
'key': '55122607-e65e-44d5-9c9d-9c31a914ca89'
},
'x': 8,
'y': 3,
'width': 10,
'height': 5,
'displayMode': 'all',
'value': 'sin',
'stroke': '',
'fill': '',
'color': '',
'size': '13px',
'type': 'telemetry-view',
'id': 'deb9f839-80ad-4ccf-a152-5c763ceb7d7e'
},
{
'width': 32,
'height': 18,
'x': 78,
'y': 8,
'identifier': {
'namespace': '',
'key': 'bdeb91ab-3a7e-4a71-9dd2-39d73644e136'
},
'hasFrame': true,
'type': 'subobject-view',
'id': 'c0ff485a-344c-4e70-8d83-a9d9998a69fc'
}
],
'layoutGrid': [
10,
10
]
},
'name': 'Display Layout',
'type': 'layout',
'identifier': {
'namespace': '',
'key': 'c5e636c1-6771-4c9c-b933-8665cab189b3'
}
};
selection = [
[{
context: {
'layoutItem': displayLayoutItem.configuration.items[1],
'index': 1
}
},
{
context: {
'item': displayLayoutItem,
'supportsMultiSelect': true
}
}],
[{
context: {
'layoutItem': displayLayoutItem.configuration.items[0],
'index': 0
}
},
{
context: {
item: displayLayoutItem,
'supportsMultiSelect': true
}
}],
[{
context: {
'layoutItem': displayLayoutItem.configuration.items[2],
'item': displayLayoutItem.configuration.items[2],
'index': 2
}
},
{
context: {
item: displayLayoutItem,
'supportsMultiSelect': true
}
}],
[{
context: {
'item': {
'composition': [
{
'namespace': '',
'key': '55122607-e65e-44d5-9c9d-9c31a914ca89'
}
],
'configuration': {
'series': [
{
'identifier': {
'namespace': '',
'key': '55122607-e65e-44d5-9c9d-9c31a914ca89'
}
}
],
'yAxis': {
},
'xAxis': {
}
},
'name': 'Unnamed Overlay Plot',
'type': 'telemetry.plot.overlay',
'modified': 1594142141929,
'location': 'mine',
'identifier': {
'namespace': '',
'key': 'bdeb91ab-3a7e-4a71-9dd2-39d73644e136'
},
'persisted': 1594142141929
},
'layoutItem': displayLayoutItem.configuration.items[3],
'index': 3
}
},
{
context: {
item: displayLayoutItem,
'supportsMultiSelect': true
}
}]
];
});
it('provides controls including separators', () => {
const displayLayoutToolbar = openmct.toolbars.get(selection);
expect(displayLayoutToolbar.length).toBe(9);
});
});
});

View File

@ -49,7 +49,7 @@
ng-style="{ 'background-color': series.get('color').asHexString() }">
</span>
<span class="is-missing__indicator" title="This item is missing"></span>
<span class="plot-series-name">{{ series.get('name') }}</span>
<span class="plot-series-name">{{ series.nameWithUnit() }}</span>
</div>
<div class="plot-series-value hover-value-enabled value-to-display-{{ legend.get('valueToShowWhenCollapsed') }} {{ series.closest.mctLimitState.cssClass }}"
ng-class="{ 'cursor-hover': (legend.get('valueToShowWhenCollapsed').indexOf('nearest') != -1) }"
@ -79,6 +79,9 @@
<th ng-if="legend.get('showValueWhenExpanded')">
Value
</th>
<th ng-if="legend.get('showUnitsWhenExpanded')">
Unit
</th>
<th ng-if="legend.get('showMinimumWhenExpanded')"
class="mobile-hide">
Min
@ -114,6 +117,11 @@
{{ series.formatY(series.closest) }}
</span>
</td>
<td ng-if="legend.get('showUnitsWhenExpanded')">
<span class="plot-series-value cursor-hover hover-value-enabled">
{{ series.get('unit') }}
</span>
</td>
<td ng-if="legend.get('showMinimumWhenExpanded')"
class="mobile-hide">
<span class="plot-series-value">

View File

@ -140,6 +140,7 @@
<span ng-if="config.legend.get('showValueWhenExpanded')">Value</span>
<span ng-if="config.legend.get('showMinimumWhenExpanded')">Min</span>
<span ng-if="config.legend.get('showMaximumWhenExpanded')">Max</span>
<span ng-if="config.legend.get('showUnitsWhenExpanded')">Units</span>
</div>
</li>
</ul>

View File

@ -201,6 +201,7 @@
<option value="nearestValue">Nearest value</option>
<option value="min">Minimum value</option>
<option value="max">Maximum value</option>
<option value="units">showUnitsWhenExpanded</option>
</select>
</div>
</li>
@ -217,6 +218,8 @@
ng-model="form.showMinimumWhenExpanded"/> Minimum value</li>
<li><input type="checkbox"
ng-model="form.showMaximumWhenExpanded"/> Maximum value</li>
<li><input type="checkbox"
ng-model="form.showUnitsWhenExpanded"/> Units</li>
</ul>
</div>

View File

@ -53,7 +53,8 @@ define([
showTimestampWhenExpanded: true,
showValueWhenExpanded: true,
showMaximumWhenExpanded: true,
showMinimumWhenExpanded: true
showMinimumWhenExpanded: true,
showUnitsWhenExpanded: true
};
}
});

View File

@ -102,6 +102,7 @@ define([
return {
name: options.domainObject.name,
unit: range.unit,
xKey: options.collection.plot.xAxis.get('key'),
yKey: range.key,
markers: true,
@ -439,6 +440,11 @@ define([
const markerSize = this.get('markerSize');
return `${markerShape}: ${markerSize}px`;
},
nameWithUnit: function () {
let unit = this.get('unit');
return this.get('name') + (unit ? ' ' + unit : '');
}
});

View File

@ -65,6 +65,11 @@ define([
modelProp: 'showMinimumWhenExpanded',
coerce: Boolean,
objectPath: 'configuration.legend.showMinimumWhenExpanded'
},
{
modelProp: 'showUnitsWhenExpanded',
coerce: Boolean,
objectPath: 'configuration.legend.showUnitsWhenExpanded'
}
]
});

View File

@ -27,6 +27,7 @@ define([
'./collections/FilteredTableRowCollection',
'./TelemetryTableRow',
'./TelemetryTableColumn',
'./TelemetryTableUnitColumn',
'./TelemetryTableConfiguration'
], function (
EventEmitter,
@ -35,6 +36,7 @@ define([
FilteredTableRowCollection,
TelemetryTableRow,
TelemetryTableColumn,
TelemetryTableUnitColumn,
TelemetryTableConfiguration
) {
class TelemetryTable extends EventEmitter {
@ -210,10 +212,14 @@ define([
addColumnsForObject(telemetryObject) {
let metadataValues = this.openmct.telemetry.getMetadata(telemetryObject).values();
metadataValues.forEach(metadatum => {
let column = this.createColumn(metadatum);
this.configuration.addSingleColumnForObject(telemetryObject, column);
// add units column if available
if (metadatum.unit !== undefined) {
let unitColumn = this.createUnitColumn(metadatum);
this.configuration.addSingleColumnForObject(telemetryObject, unitColumn);
}
});
}
@ -221,6 +227,10 @@ define([
return new TelemetryTableColumn(this.openmct, metadatum);
}
createUnitColumn(metadatum) {
return new TelemetryTableUnitColumn(this.openmct, metadatum);
}
subscribeTo(telemetryObject) {
let subscribeOptions = this.buildOptionsFromConfiguration(telemetryObject);
let keyString = this.openmct.objects.makeKeyString(telemetryObject.identifier);

View File

@ -70,8 +70,10 @@ define([], function () {
getCellLimitClasses() {
if (!this.cellLimitClasses) {
this.cellLimitClasses = Object.values(this.columns).reduce((alarmStateMap, column) => {
let limitEvaluation = this.limitEvaluator.evaluate(this.datum, column.getMetadatum());
alarmStateMap[column.getKey()] = limitEvaluation && limitEvaluation.cssClass;
if (!column.isUnit) {
let limitEvaluation = this.limitEvaluator.evaluate(this.datum, column.getMetadatum());
alarmStateMap[column.getKey()] = limitEvaluation && limitEvaluation.cssClass;
}
return alarmStateMap;
}, {});

View File

@ -0,0 +1,60 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, 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.
*****************************************************************************/
define([
'./TelemetryTableColumn.js'
], function (
TelemetryTableColumn
) {
class TelemetryTableUnitColumn extends TelemetryTableColumn {
constructor(openmct, metadatum) {
super(openmct, metadatum);
this.isUnit = true;
this.titleValue += ' Unit';
this.formatter = {
format: (datum) => {
return this.metadatum.unit;
},
parse: (datum) => {
return this.metadatum.unit;
}
};
}
getKey() {
return this.metadatum.key + '-unit';
}
getTitle() {
return this.metadatum.name + ' Unit';
}
getRawValue(telemetryDatum) {
return this.metadatum.unit;
}
getFormattedValue(telemetryDatum) {
return this.formatter.format(telemetryDatum);
}
}
return TelemetryTableUnitColumn;
});

View File

@ -69,6 +69,7 @@
<script>
import TelemetryTableColumn from '../TelemetryTableColumn';
import TelemetryTableUnitColumn from '../TelemetryTableUnitColumn';
export default {
inject: ['tableConfiguration', 'openmct'],
@ -131,10 +132,14 @@ export default {
},
addColumnsForObject(telemetryObject) {
let metadataValues = this.openmct.telemetry.getMetadata(telemetryObject).values();
metadataValues.forEach(metadatum => {
let column = new TelemetryTableColumn(this.openmct, metadatum);
this.tableConfiguration.addSingleColumnForObject(telemetryObject, column);
// if units are available, need to add columns to be hidden
if (metadatum.unit !== undefined) {
let unitColumn = new TelemetryTableUnitColumn(this.openmct, metadatum);
this.tableConfiguration.addSingleColumnForObject(telemetryObject, unitColumn);
}
});
},
toggleHeaderVisibility() {

View File

@ -117,7 +117,7 @@
title="Deselect All"
@click="unmarkAllRows()"
>
<span class="c-button__label">Deselect All</span>
<span class="c-button__label">{{ `Deselect ${marking.disableMultiSelect ? '' : 'All'}` }} </span>
</button>
<slot name="buttons"></slot>
@ -303,6 +303,7 @@ export default {
default() {
return {
enable: false,
disableMultiSelect: false,
useAlternateControlBar: false,
rowName: '',
rowNamePlural: ""
@ -787,6 +788,11 @@ export default {
this.$set(markedRow, 'marked', true);
this.pause();
if (this.marking.disableMultiSelect) {
this.unmarkAllRows();
insertMethod = 'push';
}
this.markedRows[insertMethod](markedRow);
},
unmarkAllRows(skipUnpause) {
@ -800,7 +806,7 @@ export default {
return;
}
if (!this.markedRows.length) {
if (!this.markedRows.length || this.marking.disableMultiSelect) {
this.markRow(rowIndex);
} else {
if (this.markedRows.length > 1) {

View File

@ -143,7 +143,7 @@
<ConductorHistory
v-if="isFixed"
class="c-conductor__history-select"
:bounds="openmct.time.bounds()"
:bounds="bounds"
:time-system="timeSystem"
/>
</div>
@ -190,6 +190,10 @@ export default {
start: offsets && durationFormatter.format(Math.abs(offsets.start)),
end: offsets && durationFormatter.format(Math.abs(offsets.end))
},
bounds: {
start: bounds.start,
end: bounds.end
},
formattedBounds: {
start: timeFormatter.format(bounds.start),
end: timeFormatter.format(bounds.end)
@ -210,7 +214,7 @@ export default {
document.addEventListener('keydown', this.handleKeyDown);
document.addEventListener('keyup', this.handleKeyUp);
this.setTimeSystem(JSON.parse(JSON.stringify(this.openmct.time.timeSystem())));
this.openmct.time.on('bounds', this.setViewFromBounds);
this.openmct.time.on('bounds', this.handleNewBounds);
this.openmct.time.on('timeSystem', this.setTimeSystem);
this.openmct.time.on('clock', this.setViewFromClock);
this.openmct.time.on('clockOffsets', this.setViewFromOffsets);
@ -220,6 +224,13 @@ export default {
document.removeEventListener('keyup', this.handleKeyUp);
},
methods: {
handleNewBounds(bounds) {
this.setBounds(bounds);
this.setViewFromBounds(bounds);
},
setBounds(bounds) {
this.bounds = bounds;
},
handleKeyDown(event) {
if (event.key === 'Alt') {
this.altPressed = true;
@ -246,10 +257,13 @@ export default {
this.formattedBounds.end = this.timeFormatter.format(bounds.end);
},
endZoom(bounds) {
const _bounds = bounds ? bounds : this.openmct.time.bounds();
this.isZooming = false;
this.openmct.time.bounds(_bounds);
if (bounds) {
this.handleNewBounds(bounds);
} else {
this.setViewFromBounds(this.bounds);
}
},
setTimeSystem(timeSystem) {
this.timeSystem = timeSystem;

View File

@ -207,7 +207,7 @@ export default {
this.$emit('panAxis', panBounds);
},
endPan() {
const panBounds = this.dragStartX && this.dragX && this.dragStartX !== this.dragX
const panBounds = this.isChangingViewBounds()
? this.getPanBounds()
: undefined;
this.$emit('endPan', panBounds);
@ -251,16 +251,14 @@ export default {
});
},
endZoom() {
const zoomRange = this.dragStartX && this.dragX && this.dragStartX !== this.dragX
? this.getZoomRange()
: undefined;
const zoomBounds = zoomRange
? {
let zoomBounds;
if (this.isChangingViewBounds()) {
const zoomRange = this.getZoomRange();
zoomBounds = {
start: this.scaleToBounds(zoomRange.start),
end: this.scaleToBounds(zoomRange.end)
}
: this.openmct.time.bounds();
};
}
this.zoomStyle = {};
this.$emit('endZoom', zoomBounds);
@ -290,6 +288,9 @@ export default {
return bounds.start + offset;
},
isChangingViewBounds() {
return this.dragStartX && this.dragX && this.dragStartX !== this.dragX;
},
resize() {
if (this.$refs.axisHolder.clientWidth !== this.width) {
this.setAxisDimensions();

View File

@ -84,7 +84,12 @@ export default {
},
data() {
return {
history: {}, // contains arrays of timespans {start, end}, array key is time system key
/**
* previous bounds entries available for easy re-use
* @history array of timespans
* @timespans {start, end} number representing timestamp
*/
history: this.getHistoryFromLocalStorage(),
presets: []
};
},
@ -111,22 +116,20 @@ export default {
this.addTimespan();
},
deep: true
},
history: {
handler() {
this.persistHistoryToLocalStorage();
},
deep: true
}
},
mounted() {
this.getHistoryFromLocalStorage();
this.initializeHistoryIfNoHistory();
},
methods: {
getHistoryFromLocalStorage() {
if (localStorage.getItem(LOCAL_STORAGE_HISTORY_KEY)) {
this.history = JSON.parse(localStorage.getItem(LOCAL_STORAGE_HISTORY_KEY));
} else {
const localStorageHistory = localStorage.getItem(LOCAL_STORAGE_HISTORY_KEY);
const history = localStorageHistory ? JSON.parse(localStorageHistory) : undefined;
return history;
},
initializeHistoryIfNoHistory() {
if (!this.history) {
this.history = {};
this.persistHistoryToLocalStorage();
}
@ -157,6 +160,8 @@ export default {
currentHistory.unshift(timespan);
this.history[key] = currentHistory;
this.persistHistoryToLocalStorage();
},
selectTimespan(timespan) {
this.openmct.time.bounds(timespan);

View File

@ -13,7 +13,7 @@
<div class="c-super-menu__menu">
<ul>
<li
v-for="(item, index) in sortedItems"
v-for="(item, index) in sortedItems()"
:key="index"
:class="item.class"
:title="item.title"
@ -44,42 +44,11 @@ import objectUtils from 'objectUtils';
export default {
inject: ['openmct'],
data: function () {
let items = [];
this.openmct.types.listKeys().forEach(key => {
let menuItem = this.openmct.types.get(key).definition;
if (menuItem.creatable) {
let menuItemTemplate = {
key: key,
name: menuItem.name,
class: menuItem.cssClass,
title: menuItem.description
};
items.push(menuItemTemplate);
}
});
return {
items: items,
selectedMenuItem: {},
opened: false
};
},
computed: {
sortedItems() {
return this.items.slice().sort((a, b) => {
if (a.name < b.name) {
return -1;
} else if (a.name > b.name) {
return 1;
} else {
return 0;
}
});
}
},
destroyed() {
document.removeEventListener('click', this.close);
},
@ -132,6 +101,34 @@ export default {
let oldModel = objectUtils.toOldFormat(domainObject);
return this.openmct.$injector.get('instantiate')(oldModel, keyString);
},
sortedItems() {
// TODO: optimize to add event on change 'this.openmct.types'
let items = [];
this.openmct.types.listKeys().forEach(key => {
let menuItem = this.openmct.types.get(key).definition;
if (menuItem.creatable) {
let menuItemTemplate = {
key: key,
name: menuItem.name,
class: menuItem.cssClass,
title: menuItem.description
};
items.push(menuItemTemplate);
}
});
return items.slice().sort((a, b) => {
if (a.name < b.name) {
return -1;
} else if (a.name > b.name) {
return 1;
} else {
return 0;
}
});
}
}
};

View File

@ -135,7 +135,6 @@ export default {
value = this.getFormValue(domainObject, toolbarItem);
} else {
let values = [];
if (applicableSelectedItems) {
applicableSelectedItems.forEach(selectionPath => {
values.push(this.getPropertyValue(domainObject, toolbarItem, selectionPath));
@ -207,7 +206,6 @@ export default {
},
updateObjectValue(value, item) {
let changedItemId = this.openmct.objects.makeKeyString(item.domainObject.identifier);
this.structure = this.structure.map(toolbarItem => {
if (toolbarItem.domainObject) {
let id = this.openmct.objects.makeKeyString(toolbarItem.domainObject.identifier);