Update telemetry table for multisession (#2686)

* update telemetry table to ingest marked row data, add a new alterntate bar with includes row name, selected rows and show selected rows toggle

* Enhancements for alternate toolbar in telem tables

- .c-control-bar adds style enhancements and `__label` element;
- Added `label` prop, markup and styling to ToggleSwitch;
- ToggleSwitch layout enhanced;
- Unit tested in main view and placed in Display Layout;

* made improvements to row marking

* bug fixes for marking

* fix linting issues

* -Make reviewer requested changes
-Clarify prop for marking
-Include alternateControlBar in the marking prop
- - since it only makes sense for making

Co-authored-by: Charles Hacskaylo <charlesh88@gmail.com>
This commit is contained in:
Deep Tailor 2020-02-27 10:27:58 -08:00 committed by GitHub
parent a0b7999ea2
commit 85902b878e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 184 additions and 53 deletions

View File

@ -47,6 +47,7 @@ define([
this.subscriptions = {};
this.tableComposition = undefined;
this.telemetryObjects = [];
this.datumCache = [];
this.outstandingRequests = 0;
this.configuration = new TelemetryTableConfiguration(domainObject, openmct);
this.paused = false;
@ -155,6 +156,7 @@ define([
processHistoricalData(telemetryData, columnMap, keyString, limitEvaluator) {
let telemetryRows = telemetryData.map(datum => new TelemetryTableRow(datum, columnMap, keyString, limitEvaluator));
this.boundedRows.add(telemetryRows);
this.emit('historical-rows-processed');
}
/**
@ -227,12 +229,28 @@ define([
return;
}
if (!this.paused) {
if (this.paused) {
let realtimeDatum = {
datum,
columnMap,
keyString,
limitEvaluator
};
this.datumCache.push(realtimeDatum);
} else {
this.processRealtimeDatum(datum, columnMap, keyString, limitEvaluator);
}
}, subscribeOptions);
}
processDatumCache() {
this.datumCache.forEach(cachedDatum => {
this.processRealtimeDatum(cachedDatum.datum, cachedDatum.columnMap, cachedDatum.keyString, cachedDatum.limitEvaluator);
});
this.datumCache = [];
}
processRealtimeDatum(datum, columnMap, keyString, limitEvaluator) {
this.boundedRows.add(new TelemetryTableRow(datum, columnMap, keyString, limitEvaluator));
}
@ -272,8 +290,8 @@ define([
unpause() {
this.paused = false;
this.processDatumCache();
this.boundedRows.subscribeToBounds();
this.refreshData();
}
destroy() {

View File

@ -68,7 +68,7 @@ define([
table,
objectPath
},
template: '<table-component :isEditing="isEditing" :enableMarking="true"></table-component>'
template: '<table-component :isEditing="isEditing" :marking="{enable: true}"/>'
});
},
onEditModeChange(editMode) {
@ -86,7 +86,7 @@ define([
priority() {
return 1;
}
}
};
}
return TelemetryTableViewProvider;
});

View File

@ -21,7 +21,10 @@
*****************************************************************************/
<template>
<div class="c-table-wrapper">
<div class="c-table-control-bar c-control-bar">
<!-- main contolbar start-->
<div v-if="!marking.useAlternateControlBar"
class="c-table-control-bar c-control-bar"
>
<button
v-if="allowExport"
class="c-button icon-download labeled"
@ -48,11 +51,11 @@
<span class="c-button__label">Unmark All Rows</span>
</button>
<div
v-if="enableMarking"
v-if="marking.enable"
class="c-separator"
></div>
<button
v-if="enableMarking"
v-if="marking.enable"
class="c-button icon-pause pause-play labeled"
:class=" paused ? 'icon-play is-paused' : 'icon-pause'"
:title="paused ? 'Continue Data Flow' : 'Pause Data Flow'"
@ -62,8 +65,37 @@
{{ paused ? 'Play' : 'Pause' }}
</span>
</button>
<slot name="buttons"></slot>
</div>
<!-- main controlbar end -->
<!-- alternate controlbar start -->
<div v-if="marking.useAlternateControlBar && markedRows.length"
class="c-table-control-bar c-control-bar"
>
<div class="c-control-bar__label">
{{ markedRows.length > 1 ? `${markedRows.length} ${marking.rowNamePlural} selected`: `${markedRows.length} ${marking.rowName} selected` }}
</div>
<toggle-switch
id="show-filtered-rows-toggle"
label="Show selected items only"
:checked="isShowingMarkedRowsOnly"
@change="toggleMarkedRows"
/>
<button
class="c-button icon-x labeled"
title="Deselect All"
@click="unmarkAllRows()"
>
<span class="c-button__label">Deselect All</span>
</button>
<slot name="buttons"></slot>
</div>
<!-- alternate controlbar end -->
<div
class="c-table c-telemetry-table c-table--filterable c-table--sortable has-control-bar"
@ -205,6 +237,7 @@ import TableColumnHeader from './table-column-header.vue';
import TelemetryFilterIndicator from './TelemetryFilterIndicator.vue';
import CSVExporter from '../../../exporters/CSVExporter.js';
import _ from 'lodash';
import ToggleSwitch from '../../../ui/components/ToggleSwitch.vue';
const VISIBLE_ROW_COUNT = 100;
const ROW_HEIGHT = 17;
@ -216,7 +249,8 @@ export default {
TelemetryTableRow,
TableColumnHeader,
search,
TelemetryFilterIndicator
TelemetryFilterIndicator,
ToggleSwitch
},
inject: ['table', 'openmct', 'objectPath'],
props: {
@ -236,9 +270,16 @@ export default {
'type': Boolean,
'default': true
},
enableMarking: {
type: Boolean,
default: false
marking: {
type: Object,
default() {
return {
enable: false,
useAlternateControlBar: false,
rowName: '',
rowNamePlural: ""
}
}
}
},
data() {
@ -270,7 +311,8 @@ export default {
scrollW: 0,
markCounter: 0,
paused: false,
markedRows: []
markedRows: [],
isShowingMarkedRowsOnly: false
}
},
computed: {
@ -317,6 +359,7 @@ export default {
this.table.on('object-removed', this.removeObject);
this.table.on('outstanding-requests', this.outstandingRequests);
this.table.on('refresh', this.clearRowsAndRerender);
this.table.on('historical-rows-processed', this.checkForMarkedRows);
this.table.filteredRows.on('add', this.rowsAdded);
this.table.filteredRows.on('remove', this.rowsRemoved);
@ -631,18 +674,19 @@ export default {
},
unpause(unpausedByButton) {
if (unpausedByButton) {
this.paused = false;
this.undoMarkedRows();
this.table.unpause();
this.markedRows = [];
this.paused = false;
this.pausedByButton = false;
} else {
if (!this.pausedByButton) {
this.paused = false;
this.undoMarkedRows();
this.table.unpause();
this.markedRows = [];
this.paused = false;
}
}
this.isShowingMarkedRowsOnly = false;
},
togglePauseByButton() {
if (this.paused) {
@ -655,24 +699,23 @@ export default {
this.markedRows.forEach(r => r.marked = false);
this.markedRows = [];
},
unmarkRow(rowIndex, ctrlKeyModifier) {
if (ctrlKeyModifier) {
unmarkRow(rowIndex) {
if (this.markedRows.length > 1) {
let row = this.visibleRows[rowIndex],
positionInMarkedArray = this.markedRows.indexOf(row);
row.marked = false;
this.markedRows.splice(positionInMarkedArray, 1);
} else if (this.markedRows.length === 1) {
this.unmarkAllRows();
}
if (this.markedRows.length === 0) {
this.unpause();
}
} else if (this.markedRows.length) {
this.undoMarkedRows();
this.markRow(rowIndex);
}
},
markRow(rowIndex, keyModifier) {
if (!this.enableMarking) {
if (!this.marking.enable) {
return;
}
@ -691,12 +734,13 @@ export default {
this.markedRows[insertMethod](markedRow);
},
unmarkAllRows(skipUnpause) {
this.markedRows.forEach(row => row.marked = false);
this.markedRows = [];
this.undoMarkedRows();
this.isShowingMarkedRowsOnly = false;
this.unpause();
this.restorePreviousRows();
},
markMultipleConcurrentRows(rowIndex) {
if (!this.enableMarking) {
if (!this.marking.enable) {
return;
}
@ -733,6 +777,34 @@ export default {
}
}
}
},
checkForMarkedRows() {
this.markedRows = this.table.filteredRows.getRows().filter(row => row.marked);
},
showRows(rows) {
this.table.filteredRows.rows = rows;
this.table.filteredRows.emit('filter');
},
toggleMarkedRows(flag) {
if (flag) {
this.isShowingMarkedRowsOnly = true;
this.userScroll = this.scrollable.scrollTop;
this.allRows = this.table.filteredRows.getRows();
this.showRows(this.markedRows);
this.setHeight();
} else {
this.isShowingMarkedRowsOnly = false;
this.restorePreviousRows();
}
},
restorePreviousRows() {
if (this.allRows && this.allRows.length) {
this.showRows(this.allRows);
this.allRows = [];
this.setHeight();
this.scrollable.scrollTop = this.userScroll;
}
}
}
}

View File

@ -28,6 +28,16 @@
height: $controlBarH;
}
.c-control-bar {
display: flex;
align-items: center;
&__label {
display: inline-block;
white-space: nowrap;
}
}
.l-view-section {
@include abs();
overflow: auto;

View File

@ -1,5 +1,6 @@
<template>
<label class="c-toggle-switch">
<div class="c-toggle-switch">
<label class="c-toggle-switch__control">
<input
:id="id"
type="checkbox"
@ -7,10 +8,18 @@
@change="onUserSelect($event)"
>
<span class="c-toggle-switch__slider"></span>
</label>
</label>
<div
v-if="label && label.length"
class="c-toggle-switch__label"
>
{{ label }}
</div>
</div>
</template>
<script>
export default {
inject: ['openmct'],
props: {
@ -18,6 +27,11 @@ export default {
type: String,
required: true
},
label: {
type: String,
required: false,
default: ''
},
checked: Boolean
},
methods: {
@ -26,4 +40,5 @@ export default {
}
}
}
</script>

View File

@ -2,15 +2,40 @@
$d: 12px;
$m: 2px;
$br: $d/1.5;
cursor: pointer;
overflow: hidden;
display: inline;
display: inline-flex;
align-items: center;
vertical-align: middle;
&__control,
&__label {
flex: 0 0 auto;
}
&__control {
cursor: pointer;
overflow: hidden;
display: block;
}
input {
opacity: 0;
width: 0;
height: 0;
&:checked {
+ .c-toggle-switch__slider {
background: $colorKey; // TODO: make discrete theme constants for these colors
&:before {
transform: translateX(100%);
}
}
}
}
&__slider {
// Sits within __switch
background: $colorBtnBg; // TODO: make discrete theme constants for these colors
border-radius: $br;
//box-shadow: inset rgba($colorBtnFg, 0.4) 0 0 0 1px;
display: inline-block;
height: $d + ($m*2);
position: relative;
@ -31,18 +56,9 @@
}
}
input {
opacity: 0;
width: 0;
height: 0;
&:checked {
+ .c-toggle-switch__slider {
background: $colorKey; // TODO: make discrete theme constants for these colors
&:before {
transform: translateX(100%);
}
}
}
&__label {
margin-left: $interiorMarginSm;
margin-right: $interiorMargin;
white-space: nowrap;
}
}