mirror of
https://github.com/nasa/openmct.git
synced 2024-12-19 05:07:52 +00:00
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:
parent
a0b7999ea2
commit
85902b878e
@ -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() {
|
||||
|
@ -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;
|
||||
});
|
||||
|
@ -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);
|
||||
if (this.markedRows.length === 0) {
|
||||
this.unpause();
|
||||
}
|
||||
},
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -1,16 +1,25 @@
|
||||
<template>
|
||||
<label class="c-toggle-switch">
|
||||
<input
|
||||
:id="id"
|
||||
type="checkbox"
|
||||
:checked="checked"
|
||||
@change="onUserSelect($event)"
|
||||
<div class="c-toggle-switch">
|
||||
<label class="c-toggle-switch__control">
|
||||
<input
|
||||
:id="id"
|
||||
type="checkbox"
|
||||
:checked="checked"
|
||||
@change="onUserSelect($event)"
|
||||
>
|
||||
<span class="c-toggle-switch__slider"></span>
|
||||
</label>
|
||||
<div
|
||||
v-if="label && label.length"
|
||||
class="c-toggle-switch__label"
|
||||
>
|
||||
<span class="c-toggle-switch__slider"></span>
|
||||
</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>
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user