Lad table vue (#2231)

* working telemetry subs

* Styling for LAD table

- Fixed markup;
- Corrected icon, added description;
- Expand c-table styles slightly, moved some definitions into
c-telemetry-table;

* add LADTableSummary

* change function names

* make reviewer requested changes

* add lad table headers in sets

* make column widths fixed

* handle composition remove in sets and tables

* finish updateTimeSystem

* add correct support for limits

* LAD Table and Table Set styling

- Removed fixed table layout;
- Col widths set to 33% for now;
- New c-lad-table class and styling;
- New __group-header class added;
- All themes updated with __group-header style colors;

* make reviewer requested changes

* use lodash findIndex
This commit is contained in:
Deep Tailor 2018-12-20 13:18:22 -08:00 committed by Pete Richards
parent 30a4888363
commit ce6c1f173e
14 changed files with 582 additions and 6 deletions

View File

@ -79,6 +79,7 @@
openmct.install(openmct.plugins.FolderView()); openmct.install(openmct.plugins.FolderView());
openmct.install(openmct.plugins.Tabs()); openmct.install(openmct.plugins.Tabs());
openmct.install(openmct.plugins.FlexibleLayout()); openmct.install(openmct.plugins.FlexibleLayout());
openmct.install(openmct.plugins.LADTable());
openmct.time.clock('local', {start: -THIRTY_MINUTES, end: 0}); openmct.time.clock('local', {start: -THIRTY_MINUTES, end: 0});
openmct.time.timeSystem('utc'); openmct.time.timeSystem('utc');
openmct.start(); openmct.start();

View File

@ -0,0 +1,67 @@
/*****************************************************************************
* 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([
'./components/LadTableSet.vue',
'vue'
], function (
LadTableSet,
Vue
) {
function LADTableSetViewProvider(openmct) {
return {
key: 'LadTableSet',
name: 'LAD Table Set',
cssClass: 'icon-tabular-lad-set',
canView: function (domainObject) {
return domainObject.type === 'LadTableSet';
},
view: function (domainObject) {
let component;
return {
show: function (element) {
component = new Vue({
components: {
LadTableSet: LadTableSet.default
},
provide: {
openmct,
domainObject
},
el: element,
template: '<lad-table-set></lad-table-set>'
});
},
destroy: function (element) {
component.$destroy();
component = undefined;
}
};
},
priority: function () {
return 1;
}
};
}
return LADTableSetViewProvider;
});

View File

@ -0,0 +1,67 @@
/*****************************************************************************
* 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([
'./components/LadTable.vue',
'vue'
], function (
LadTableComponent,
Vue
) {
function LADTableViewProvider(openmct) {
return {
key: 'LadTable',
name: 'LAD Table',
cssClass: 'icon-tabular-lad',
canView: function (domainObject) {
return domainObject.type === 'LadTable';
},
view: function (domainObject) {
let component;
return {
show: function (element) {
component = new Vue({
components: {
LadTableComponent: LadTableComponent.default
},
provide: {
openmct,
domainObject
},
el: element,
template: '<lad-table-component></lad-table-component>'
});
},
destroy: function (element) {
component.$destroy();
component = undefined;
}
};
},
priority: function () {
return 1;
}
};
}
return LADTableViewProvider;
});

View File

@ -0,0 +1,120 @@
/*****************************************************************************
* 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.
*****************************************************************************/
<template>
<tr>
<td>{{name}}</td>
<td>{{timestamp}}</td>
<td :class="valueClass">
{{value}}
</td>
</tr>
</template>
<style lang="scss">
</style>
<script>
export default {
inject: ['openmct'],
props: ['domainObject'],
data() {
return {
name: this.domainObject.name,
timestamp: '---',
value: '---',
valueClass: ''
}
},
methods: {
updateValues(datum) {
this.timestamp = this.formats[this.timestampKey].format(datum);
this.value = this.formats[this.valueKey].format(datum);
var limit = this.limitEvaluator.evaluate(datum, this.valueMetadata);
if (limit) {
this.valueClass = limit.cssClass;
} else {
this.valueClass = '';
}
},
updateName(name){
this.name = name;
},
updateTimeSystem(timeSystem) {
this.value = '---';
this.timestamp = '---';
this.valueClass = '';
this.timestampKey = timeSystem.key;
this.openmct
.telemetry
.request(this.domainObject, {strategy: 'latest'})
.then((array) => this.updateValues(array[array.length - 1]));
}
},
mounted() {
this.metadata = this.openmct.telemetry.getMetadata(this.domainObject);
this.formats = this.openmct.telemetry.getFormatMap(this.metadata);
this.limitEvaluator = openmct
.telemetry
.limitEvaluator(this.domainObject);
this.stopWatchingMutation = openmct
.objects
.observe(
this.domainObject,
'*',
this.updateName
);
this.openmct.time.on('timeSystem', this.updateTimeSystem);
this.timestampKey = this.openmct.time.timeSystem().key;
this.valueMetadata = this
.metadata
.valuesForHints(['range'])[0];
this.valueKey = this.valueMetadata.key
this.unsubscribe = this.openmct
.telemetry
.subscribe(this.domainObject, this.updateValues);
this.openmct
.telemetry
.request(this.domainObject, {strategy: 'latest'})
.then((array) => this.updateValues(array[array.length - 1]));
},
destroyed() {
this.stopWatchingMutation();
this.unsubscribe();
this.openmct.off('timeSystem', this.updateTimeSystem);
}
}
</script>

View File

@ -0,0 +1,82 @@
/*****************************************************************************
* 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.
*****************************************************************************/
<template>
<table class="c-table c-lad-table">
<thead>
<tr>
<th>Name</th>
<th>Timestamp</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<lad-row
v-for="item in items"
:key="item.key"
:domainObject="item.domainObject">
</lad-row>
</tbody>
</table>
</template>
<script>
import lodash from 'lodash';
import LadRow from './LadRow.vue';
export default {
inject: ['openmct', 'domainObject'],
components: {
LadRow
},
data() {
return {
items: []
}
},
methods: {
addItem(domainObject) {
let item = {};
item.domainObject = domainObject;
item.key = this.openmct.objects.makeKeyString(domainObject.identifier);
this.items.push(item);
},
removeItem(identifier) {
let index = _.findIndex(this.items, (item) => this.openmct.objects.makeKeyString(identifier) === item.key);
this.items.splice(index, 1);
}
},
mounted() {
this.composition = this.openmct.composition.get(this.domainObject);
this.composition.on('add', this.addItem);
this.composition.on('remove', this.removeItem);
this.composition.load();
},
destroyed() {
this.composition.off('add', this.addItem);
this.composition.off('remove', this.removeItem);
}
}
</script>

View File

@ -0,0 +1,135 @@
/*****************************************************************************
* 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.
*****************************************************************************/
<template>
<table class="c-table c-lad-table">
<thead>
<tr>
<th>Name</th>
<th>Timestamp</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<template
v-for="primary in primaryTelemetryObjects">
<tr class="c-table__group-header"
:key="primary.key">
<td colspan="10">{{primary.domainObject.name}}</td>
</tr>
<lad-row
v-for="secondary in secondaryTelemetryObjects[primary.key]"
:key="secondary.key"
:domainObject="secondary.domainObject">
</lad-row>
</template>
</tbody>
</table>
</template>
<style lang="scss">
</style>
<script>
import lodash from 'lodash';
import LadRow from './LadRow.vue';
export default {
inject: ['openmct', 'domainObject'],
components: {
LadRow
},
data() {
return {
primaryTelemetryObjects: [],
secondaryTelemetryObjects: {},
compositions: []
}
},
methods: {
addPrimary(domainObject) {
let primary = {};
primary.domainObject = domainObject;
primary.key = this.openmct.objects.makeKeyString(domainObject.identifier);
this.$set(this.secondaryTelemetryObjects, primary.key, []);
this.primaryTelemetryObjects.push(primary);
let composition = openmct.composition.get(primary.domainObject),
addCallback = this.addSecondary(primary),
removeCallback = this.removeSecondary(primary);
composition.on('add', addCallback);
composition.on('remove', removeCallback);
composition.load();
this.compositions.push({composition, addCallback, removeCallback});
},
removePrimary(identifier) {
let index = _.findIndex(this.primaryTelemetryObjects, (primary) => this.openmct.objects.makeKeyString(identifier) === primary.key),
primary = this.primaryTelemetryObjects[index];
this.$set(this.secondaryTelemetryObjects, primary.key, undefined);
this.primaryTelemetryObjects.splice(index,1);
primary = undefined;
},
addSecondary(primary) {
return (domainObject) => {
let secondary = {};
secondary.key = this.openmct.objects.makeKeyString(domainObject.identifier);
secondary.domainObject = domainObject;
let array = this.secondaryTelemetryObjects[primary.key];
array.push(secondary);
this.$set(this.secondaryTelemetryObjects, primary.key, array);
}
},
removeSecondary(primary) {
return (identifier) => {
let array = this.secondaryTelemetryObjects[primary.key],
index = _.findIndex(array, (secondary) => this.openmct.objects.makeKeyString(identifier) === secondary.key);
array.splice(index, 1);
this.$set(this.secondaryTelemetryObjects, primary.key, array);
}
}
},
mounted() {
this.composition = this.openmct.composition.get(this.domainObject);
this.composition.on('add', this.addPrimary);
this.composition.on('remove', this.removePrimary);
this.composition.load();
},
destroyed() {
this.composition.off('add', this.addPrimary);
this.composition.off('remove', this.removePrimary);
this.compositions.forEach(c => {
c.composition.off('add', c.addCallback);
c.composition.off('remove', c.removeCallback);
});
}
}
</script>

View File

@ -0,0 +1,56 @@
/*****************************************************************************
* 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([
'./LADTableViewProvider',
'./LADTableSetViewProvider'
], function (
LADTableViewProvider,
LADTableSetViewProvider
) {
return function plugin() {
return function install(openmct) {
openmct.objectViews.addProvider(new LADTableViewProvider(openmct));
openmct.objectViews.addProvider(new LADTableSetViewProvider(openmct));
openmct.types.addType('LadTable', {
name: "LAD Table",
creatable: true,
description: "A Latest Available Data tabular view in which each row displays the values for one or more contained telemetry objects.",
cssClass: 'icon-tabular-lad',
initialize(domainObject) {
domainObject.composition = [];
}
});
openmct.types.addType('LadTableSet', {
name: "LAD Table Set",
creatable: true,
description: "A Latest Available Data tabular view in which each row displays the values for one or more contained telemetry objects.",
cssClass: 'icon-tabular-lad-set',
initialize(domainObject) {
domainObject.composition = [];
}
});
};
};
});

View File

@ -40,6 +40,7 @@ define([
'./flexibleLayout/plugin', './flexibleLayout/plugin',
'./tabs/plugin', './tabs/plugin',
'../../platform/features/fixed/plugin', '../../platform/features/fixed/plugin',
'./LADTable/plugin',
'./preview/plugin' './preview/plugin'
], function ( ], function (
_, _,
@ -61,6 +62,7 @@ define([
FlexibleLayout, FlexibleLayout,
Tabs, Tabs,
FixedView, FixedView,
LADTable,
PreviewPlugin PreviewPlugin
) { ) {
var bundleMap = { var bundleMap = {
@ -176,6 +178,7 @@ define([
plugins.Tabs = Tabs; plugins.Tabs = Tabs;
plugins.FixedView = FixedView; plugins.FixedView = FixedView;
plugins.FlexibleLayout = FlexibleLayout; plugins.FlexibleLayout = FlexibleLayout;
plugins.LADTable = LADTable;
plugins.Preview = PreviewPlugin.default; plugins.Preview = PreviewPlugin.default;
return plugins; return plugins;

View File

@ -118,6 +118,9 @@
.c-telemetry-table { .c-telemetry-table {
// Table that displays telemetry in a scrolling body area // Table that displays telemetry in a scrolling body area
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
overflow: hidden; overflow: hidden;
th, td { th, td {

View File

@ -267,8 +267,10 @@ $colorTabBorder: lighten($colorBodyBg, 10%);
$colorTabBodyBg: $colorBodyBg; $colorTabBodyBg: $colorBodyBg;
$colorTabBodyFg: lighten($colorBodyFg, 20%); $colorTabBodyFg: lighten($colorBodyFg, 20%);
$colorTabHeaderBg: lighten($colorBodyBg, 10%); $colorTabHeaderBg: lighten($colorBodyBg, 10%);
$colorTabHeaderFg: lighten($colorBodyFg, 20%); $colorTabHeaderFg: $colorBodyFg;
$colorTabHeaderBorder: $colorBodyBg; $colorTabHeaderBorder: $colorBodyBg;
$colorTabGroupHeaderBg: lighten($colorBodyBg, 5%);
$colorTabGroupHeaderFg: darken($colorTabHeaderFg, 10%);
// Plot // Plot
$colorPlotBg: rgba(black, 0.05); $colorPlotBg: rgba(black, 0.05);

View File

@ -20,7 +20,7 @@
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/************************************************** MAELSTROM2 THEME CONSTANTS */ /************************************************** MAELSTROM THEME CONSTANTS */
// Fonts // Fonts
@import url('https://fonts.googleapis.com/css?family=Chakra+Petch:400,600,700|Michroma|Teko:400,700'); @import url('https://fonts.googleapis.com/css?family=Chakra+Petch:400,600,700|Michroma|Teko:400,700');
@ -271,8 +271,10 @@ $colorTabBorder: lighten($colorBodyBg, 10%);
$colorTabBodyBg: $colorBodyBg; $colorTabBodyBg: $colorBodyBg;
$colorTabBodyFg: lighten($colorBodyFg, 20%); $colorTabBodyFg: lighten($colorBodyFg, 20%);
$colorTabHeaderBg: lighten($colorBodyBg, 10%); $colorTabHeaderBg: lighten($colorBodyBg, 10%);
$colorTabHeaderFg: lighten($colorBodyFg, 20%); $colorTabHeaderFg: $colorBodyFg;
$colorTabHeaderBorder: $colorBodyBg; $colorTabHeaderBorder: $colorBodyBg;
$colorTabGroupHeaderBg: lighten($colorBodyBg, 5%);
$colorTabGroupHeaderFg: darken($colorTabHeaderFg, 10%);
// Plot // Plot
$colorPlotBg: rgba(black, 0.05); $colorPlotBg: rgba(black, 0.05);

View File

@ -269,6 +269,8 @@ $colorTabBodyFg: darken($colorBodyFg, 20%);
$colorTabHeaderBg: darken($colorBodyBg, 10%); $colorTabHeaderBg: darken($colorBodyBg, 10%);
$colorTabHeaderFg: darken($colorBodyFg, 20%); $colorTabHeaderFg: darken($colorBodyFg, 20%);
$colorTabHeaderBorder: $colorBodyBg; $colorTabHeaderBorder: $colorBodyBg;
$colorTabGroupHeaderBg: darken($colorBodyBg, 5%);
$colorTabGroupHeaderFg: darken($colorTabGroupHeaderBg, 40%);
// Plot // Plot
$colorPlotBg: rgba(black, 0.05); $colorPlotBg: rgba(black, 0.05);

View File

@ -51,11 +51,11 @@ table {
.c-table { .c-table {
// Can be used by any type of table, scrolling, LAD, etc. // Can be used by any type of table, scrolling, LAD, etc.
display: flex; $min-w: 50px;
flex-flow: column nowrap;
justify-content: flex-start;
position: absolute; position: absolute;
top: 0; right: 0; bottom: 0; left: 0; top: 0; right: 0; bottom: 0; left: 0;
width: 100%;
&__control-bar, &__control-bar,
&__headers-w { &__headers-w {
@ -68,6 +68,31 @@ table {
margin-bottom: $interiorMarginSm; margin-bottom: $interiorMarginSm;
} }
thead tr,
[class*="__header"] {
background: $colorTabHeaderBg;
th {
&:not(:first-child) {
border-left: 1px solid $colorTabHeaderBorder;
}
}
}
tbody,
&__body {
tr:not(.c-table__group-header) + tr:not(.c-table__group-header) {
border-top: 1px solid $colorTabBorder;
}
}
&__group-header {
// tr element found in LAD Table Sets
border-top: 1px solid $colorTabHeaderBorder;
background: $colorTabGroupHeaderBg;
td { color: $colorTabGroupHeaderFg; }
}
&--sortable { &--sortable {
.is-sorting { .is-sorting {
&:after { &:after {
@ -87,3 +112,9 @@ table {
} }
} }
} }
.c-lad-table {
th, td {
width: 33%; // Needed to prevent size jumping as values dynamically update
}
}

View File

@ -35,6 +35,11 @@
display: block; display: block;
} }
} }
input[type='text'],
input[type='search'] {
text-align: left;
}
} }
</style> </style>