Compare commits
	
		
			19 Commits
		
	
	
		
			eventemitt
			...
			select-tab
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					b74507bd1b | ||
| 
						 | 
					1461a209d9 | ||
| 
						 | 
					bfb89c7ece | ||
| 
						 | 
					f45e1623a1 | ||
| 
						 | 
					09c4ee48b2 | ||
| 
						 | 
					e8997917b2 | ||
| 
						 | 
					faa1d01499 | ||
| 
						 | 
					a9c245a7db | ||
| 
						 | 
					85dd5ce00c | ||
| 
						 | 
					ec86ebd692 | ||
| 
						 | 
					6c69694dca | ||
| 
						 | 
					0b8bf682a4 | ||
| 
						 | 
					e72ba5e8bf | ||
| 
						 | 
					3caba5efac | ||
| 
						 | 
					efdd80bd57 | ||
| 
						 | 
					832c4d9816 | ||
| 
						 | 
					3a5024d38d | ||
| 
						 | 
					dcd6334036 | ||
| 
						 | 
					728b39164e | 
@@ -49,6 +49,7 @@ define([
 | 
			
		||||
            this.telemetryObjects = [];
 | 
			
		||||
            this.outstandingRequests = 0;
 | 
			
		||||
            this.configuration = new TelemetryTableConfiguration(domainObject, openmct);
 | 
			
		||||
            this.paused = false;
 | 
			
		||||
            this.keyString = this.openmct.objects.makeKeyString(this.domainObject.identifier);
 | 
			
		||||
 | 
			
		||||
            this.addTelemetryObject = this.addTelemetryObject.bind(this);
 | 
			
		||||
@@ -219,7 +220,10 @@ define([
 | 
			
		||||
                if (!this.telemetryObjects.includes(telemetryObject)) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                this.processRealtimeDatum(datum, columnMap, keyString, limitEvaluator);
 | 
			
		||||
 | 
			
		||||
                if (!this.paused) {
 | 
			
		||||
                    this.processRealtimeDatum(datum, columnMap, keyString, limitEvaluator);
 | 
			
		||||
                }
 | 
			
		||||
            }, subscribeOptions);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -255,6 +259,17 @@ define([
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pause() {
 | 
			
		||||
            this.paused = true;
 | 
			
		||||
            this.boundedRows.unsubscribeFromBounds();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        unpause() {
 | 
			
		||||
            this.paused = false;
 | 
			
		||||
            this.boundedRows.subscribeToBounds();
 | 
			
		||||
            this.refreshData();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        destroy() {
 | 
			
		||||
            this.boundedRows.destroy();
 | 
			
		||||
            this.filteredRows.destroy();
 | 
			
		||||
 
 | 
			
		||||
@@ -21,10 +21,11 @@
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
define(function () {
 | 
			
		||||
    class TelemetryTableColumn {
 | 
			
		||||
        constructor (openmct, metadatum) {
 | 
			
		||||
        constructor (openmct, metadatum, options = {selectable: false}) {
 | 
			
		||||
            this.metadatum = metadatum;
 | 
			
		||||
            this.formatter = openmct.telemetry.getValueFormatter(metadatum);
 | 
			
		||||
            this.titleValue = this.metadatum.name;
 | 
			
		||||
            this.selectable = options.selectable;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        getKey() {
 | 
			
		||||
@@ -55,8 +56,7 @@ define(function () {
 | 
			
		||||
                return formattedValue;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return TelemetryTableColumn;
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -67,7 +67,7 @@ define([
 | 
			
		||||
                                table
 | 
			
		||||
                            },
 | 
			
		||||
                            el: element,
 | 
			
		||||
                            template: '<table-component :isEditing="isEditing"></table-component>'
 | 
			
		||||
                            template: '<table-component :isEditing="isEditing" :enableMarking="true"></table-component>'
 | 
			
		||||
                        });
 | 
			
		||||
                    },
 | 
			
		||||
                    onEditModeChange(isEditing) {
 | 
			
		||||
 
 | 
			
		||||
@@ -43,7 +43,8 @@ define(
 | 
			
		||||
                this.sortByTimeSystem(openmct.time.timeSystem());
 | 
			
		||||
 | 
			
		||||
                this.lastBounds = openmct.time.bounds();
 | 
			
		||||
                openmct.time.on('bounds', this.bounds);
 | 
			
		||||
 | 
			
		||||
                this.subscribeToBounds();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            addOne(item) {
 | 
			
		||||
@@ -140,9 +141,17 @@ define(
 | 
			
		||||
                return this.parseTime(row.datum[this.sortOptions.key]);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            destroy() {
 | 
			
		||||
            unsubscribeFromBounds() {
 | 
			
		||||
                this.openmct.time.off('bounds', this.bounds);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            subscribeToBounds() {
 | 
			
		||||
                this.openmct.time.on('bounds', this.bounds);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            destroy() {
 | 
			
		||||
                this.unsubscribeFromBounds();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return BoundedTableRowCollection;
 | 
			
		||||
    });
 | 
			
		||||
 
 | 
			
		||||
@@ -20,22 +20,36 @@
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
<template>
 | 
			
		||||
<tr :style="{ top: rowTop }" :class="rowClass">
 | 
			
		||||
    <component
 | 
			
		||||
        v-for="(title, key) in headers"
 | 
			
		||||
<tr :style="{ top: rowTop }"
 | 
			
		||||
    class="noselect"
 | 
			
		||||
    :class="[
 | 
			
		||||
        rowClass,
 | 
			
		||||
        {'is-selected': marked}
 | 
			
		||||
    ]"
 | 
			
		||||
    @click="markRow">
 | 
			
		||||
    <component v-for="(title, key) in headers" 
 | 
			
		||||
        :key="key"
 | 
			
		||||
        :is="componentList[key]"
 | 
			
		||||
        :columnKey="key"
 | 
			
		||||
        :style="columnWidths[key] === undefined ? {} : { width: columnWidths[key] + 'px', 'max-width': columnWidths[key] + 'px'}"
 | 
			
		||||
        :title="formattedRow[key]"
 | 
			
		||||
        :class="cellLimitClasses[key]"
 | 
			
		||||
        class="is-selectable"
 | 
			
		||||
        :class="[cellLimitClasses[key], selectableColumns[key] ? 'is-selectable' : '']"
 | 
			
		||||
        @click="selectCell($event.currentTarget, key)"
 | 
			
		||||
        :row="row"></component>
 | 
			
		||||
        :row="row">
 | 
			
		||||
    </component>
 | 
			
		||||
</tr>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
    .noselect {
 | 
			
		||||
    -webkit-touch-callout: none; /* iOS Safari */
 | 
			
		||||
        -webkit-user-select: none; /* Safari */
 | 
			
		||||
        -khtml-user-select: none; /* Konqueror HTML */
 | 
			
		||||
        -moz-user-select: none; /* Firefox */
 | 
			
		||||
            -ms-user-select: none; /* Internet Explorer/Edge */
 | 
			
		||||
                user-select: none; /* Non-prefixed version, currently
 | 
			
		||||
                                    supported by Chrome and Opera */
 | 
			
		||||
    }
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
@@ -51,6 +65,10 @@ export default {
 | 
			
		||||
            componentList: Object.keys(this.headers).reduce((components, header) => {
 | 
			
		||||
                components[header] = this.row.getCellComponentName(header) || 'table-cell';
 | 
			
		||||
                return components
 | 
			
		||||
            }, {}),
 | 
			
		||||
            selectableColumns : Object.keys(this.row.columns).reduce((selectable, columnKeys) => {
 | 
			
		||||
                selectable[columnKeys] = this.row.columns[columnKeys].selectable;
 | 
			
		||||
                return selectable;
 | 
			
		||||
            }, {})
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
@@ -81,6 +99,11 @@ export default {
 | 
			
		||||
            type: Number,
 | 
			
		||||
            required: false,
 | 
			
		||||
            default: 0
 | 
			
		||||
        },
 | 
			
		||||
        marked: {
 | 
			
		||||
            type: Boolean,
 | 
			
		||||
            required: false,
 | 
			
		||||
            default: false
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    methods: {
 | 
			
		||||
@@ -92,22 +115,41 @@ export default {
 | 
			
		||||
            this.rowClass = row.getRowClass();
 | 
			
		||||
            this.cellLimitClasses = row.getCellLimitClasses();
 | 
			
		||||
        },
 | 
			
		||||
        markRow: function (event) {
 | 
			
		||||
            let keyCtrlModifier = false;
 | 
			
		||||
 | 
			
		||||
            if (event.ctrlKey || event.metaKey) {
 | 
			
		||||
                keyCtrlModifier = true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (event.shiftKey) {
 | 
			
		||||
                this.$emit('markMultipleConcurrent', this.rowIndex);
 | 
			
		||||
            } else {
 | 
			
		||||
                if (this.marked) {
 | 
			
		||||
                    this.$emit('unmark', this.rowIndex, keyCtrlModifier);
 | 
			
		||||
                } else {
 | 
			
		||||
                    this.$emit('mark', this.rowIndex, keyCtrlModifier);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        selectCell(element, columnKey) {
 | 
			
		||||
            //TODO: This is a hack. Cannot get parent this way.
 | 
			
		||||
            this.openmct.selection.select([{
 | 
			
		||||
                element: element,
 | 
			
		||||
                context: {
 | 
			
		||||
                    type: 'table-cell',
 | 
			
		||||
                    row: this.row.objectKeyString,
 | 
			
		||||
                    column: columnKey
 | 
			
		||||
                }
 | 
			
		||||
            },{
 | 
			
		||||
                element: this.openmct.layout.$refs.browseObject.$el,
 | 
			
		||||
                context: {
 | 
			
		||||
                    item: this.openmct.router.path[0]
 | 
			
		||||
                }
 | 
			
		||||
            }], false);
 | 
			
		||||
            event.stopPropagation();
 | 
			
		||||
            if (this.selectableColumns[columnKey]) {
 | 
			
		||||
                 //TODO: This is a hack. Cannot get parent this way.
 | 
			
		||||
                this.openmct.selection.select([{
 | 
			
		||||
                    element: element,
 | 
			
		||||
                    context: {
 | 
			
		||||
                        type: 'table-cell',
 | 
			
		||||
                        row: this.row.objectKeyString,
 | 
			
		||||
                        column: columnKey
 | 
			
		||||
                    }
 | 
			
		||||
                },{
 | 
			
		||||
                    element: this.openmct.layout.$refs.browseObject.$el,
 | 
			
		||||
                    context: {
 | 
			
		||||
                        item: this.openmct.router.path[0]
 | 
			
		||||
                    }
 | 
			
		||||
                }], false);
 | 
			
		||||
                event.stopPropagation();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    // TODO: use computed properties
 | 
			
		||||
 
 | 
			
		||||
@@ -20,95 +20,134 @@
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
<template>
 | 
			
		||||
<div class="c-table c-telemetry-table c-table--filterable c-table--sortable has-control-bar"
 | 
			
		||||
     :class="{'loading': loading}">
 | 
			
		||||
    <div :style="{ 'max-width': widthWithScroll, 'min-width': '150px'}"><slot></slot></div>
 | 
			
		||||
    <div v-if="allowExport" class="c-table__control-bar c-control-bar">
 | 
			
		||||
<div class="c-table-wrapper">
 | 
			
		||||
    <div class="c-table-control-bar c-control-bar">
 | 
			
		||||
        <button class="c-button icon-download labeled"
 | 
			
		||||
           v-on:click="exportAsCSV()"
 | 
			
		||||
           title="Export This View's Data">
 | 
			
		||||
            <span class="c-button__label">Export As CSV</span>
 | 
			
		||||
                v-if="allowExport"
 | 
			
		||||
                v-on:click="exportAllDataAsCSV()"
 | 
			
		||||
                title="Export This View's Data">
 | 
			
		||||
            <span class="c-button__label">Export Table Data</span>
 | 
			
		||||
        </button>
 | 
			
		||||
        <button class="c-button icon-download labeled"
 | 
			
		||||
                v-if="allowExport"
 | 
			
		||||
                v-show="markedRows.length"
 | 
			
		||||
                v-on:click="exportMarkedDataAsCSV()"
 | 
			
		||||
                title="Export Marked Rows As CSV">
 | 
			
		||||
            <span class="c-button__label">Export Marked Rows</span>
 | 
			
		||||
        </button>
 | 
			
		||||
        <button class="c-button icon-x labeled"
 | 
			
		||||
                v-show="markedRows.length"
 | 
			
		||||
                v-on:click="unmarkAllRows()"
 | 
			
		||||
                title="Unmark All Rows">
 | 
			
		||||
            <span class="c-button__label">Unmark All Rows</span>
 | 
			
		||||
        </button>
 | 
			
		||||
        <div v-if="enableMarking"
 | 
			
		||||
            class="c-separator">
 | 
			
		||||
        </div>
 | 
			
		||||
        <button v-if="enableMarking"
 | 
			
		||||
                class="c-button icon-pause pause-play labeled"
 | 
			
		||||
                :class=" paused ? 'icon-play is-paused' : 'icon-pause'"
 | 
			
		||||
                v-on:click="togglePauseByButton()"
 | 
			
		||||
                :title="paused ? 'Continue Data Flow' : 'Pause Data Flow'">
 | 
			
		||||
                <span class="c-button__label">
 | 
			
		||||
                    {{paused ? 'Play' : 'Pause'}}
 | 
			
		||||
                </span>
 | 
			
		||||
        </button>
 | 
			
		||||
        <slot name="buttons"></slot>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div v-if="isDropTargetActive" class="c-telemetry-table__drop-target" :style="dropTargetStyle"></div>
 | 
			
		||||
    <!-- Headers table -->
 | 
			
		||||
    <div class="c-telemetry-table__headers-w js-table__headers-w" ref="headersTable" :style="{ 'max-width': widthWithScroll}">
 | 
			
		||||
        <table class="c-table__headers c-telemetry-table__headers">
 | 
			
		||||
            <thead>
 | 
			
		||||
                <tr class="c-telemetry-table__headers__labels">
 | 
			
		||||
                    <table-column-header
 | 
			
		||||
                        v-for="(title, key, headerIndex) in headers"
 | 
			
		||||
                        :key="key"
 | 
			
		||||
                        :headerKey="key"
 | 
			
		||||
                        :headerIndex="headerIndex"
 | 
			
		||||
                        @sort="allowSorting && sortBy(key)"
 | 
			
		||||
                        @resizeColumn="resizeColumn"
 | 
			
		||||
                        @dropTargetOffsetChanged="setDropTargetOffset"
 | 
			
		||||
                        @dropTargetActive="dropTargetActive"
 | 
			
		||||
                        @reorderColumn="reorderColumn"
 | 
			
		||||
                        @resizeColumnEnd="updateConfiguredColumnWidths"
 | 
			
		||||
                        :columnWidth="columnWidths[key]"
 | 
			
		||||
                        :sortOptions="sortOptions"
 | 
			
		||||
                        :isEditing="isEditing"
 | 
			
		||||
                    ><span class="c-telemetry-table__headers__label">{{title}}</span>
 | 
			
		||||
                    </table-column-header>
 | 
			
		||||
                </tr>
 | 
			
		||||
                <tr class="c-telemetry-table__headers__filter">
 | 
			
		||||
                    <table-column-header
 | 
			
		||||
                        v-for="(title, key, headerIndex) in headers"
 | 
			
		||||
                        :key="key"
 | 
			
		||||
                        :headerKey="key"
 | 
			
		||||
                        :headerIndex="headerIndex"
 | 
			
		||||
                        @resizeColumn="resizeColumn"
 | 
			
		||||
                        @dropTargetOffsetChanged="setDropTargetOffset"
 | 
			
		||||
                        @dropTargetActive="dropTargetActive"
 | 
			
		||||
                        @reorderColumn="reorderColumn"
 | 
			
		||||
                        @resizeColumnEnd="updateConfiguredColumnWidths"
 | 
			
		||||
                        :columnWidth="columnWidths[key]"
 | 
			
		||||
                        :isEditing="isEditing"
 | 
			
		||||
                        >
 | 
			
		||||
                        <search class="c-table__search"
 | 
			
		||||
                            v-model="filters[key]"
 | 
			
		||||
                            v-on:input="filterChanged(key)"
 | 
			
		||||
                            v-on:clear="clearFilter(key)" />
 | 
			
		||||
                    </table-column-header>
 | 
			
		||||
                </tr>
 | 
			
		||||
            </thead>
 | 
			
		||||
 | 
			
		||||
    <div class="c-table c-telemetry-table c-table--filterable c-table--sortable has-control-bar"
 | 
			
		||||
         :class="{
 | 
			
		||||
         'loading': loading,
 | 
			
		||||
         'paused' : paused
 | 
			
		||||
        }">
 | 
			
		||||
 | 
			
		||||
        <div :style="{ 'max-width': widthWithScroll, 'min-width': '150px'}"><slot></slot></div>
 | 
			
		||||
 | 
			
		||||
        <div v-if="isDropTargetActive" class="c-telemetry-table__drop-target" :style="dropTargetStyle"></div>
 | 
			
		||||
        <!-- Headers table -->
 | 
			
		||||
        <div class="c-telemetry-table__headers-w js-table__headers-w" ref="headersTable" :style="{ 'max-width': widthWithScroll}">
 | 
			
		||||
            <table class="c-table__headers c-telemetry-table__headers">
 | 
			
		||||
                <thead>
 | 
			
		||||
                    <tr class="c-telemetry-table__headers__labels">
 | 
			
		||||
                        <table-column-header
 | 
			
		||||
                            v-for="(title, key, headerIndex) in headers"
 | 
			
		||||
                            :key="key"
 | 
			
		||||
                            :headerKey="key"
 | 
			
		||||
                            :headerIndex="headerIndex"
 | 
			
		||||
                            @sort="allowSorting && sortBy(key)"
 | 
			
		||||
                            @resizeColumn="resizeColumn"
 | 
			
		||||
                            @dropTargetOffsetChanged="setDropTargetOffset"
 | 
			
		||||
                            @dropTargetActive="dropTargetActive"
 | 
			
		||||
                            @reorderColumn="reorderColumn"
 | 
			
		||||
                            @resizeColumnEnd="updateConfiguredColumnWidths"
 | 
			
		||||
                            :columnWidth="columnWidths[key]"
 | 
			
		||||
                            :sortOptions="sortOptions"
 | 
			
		||||
                            :isEditing="isEditing"
 | 
			
		||||
                        ><span class="c-telemetry-table__headers__label">{{title}}</span>
 | 
			
		||||
                        </table-column-header>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr class="c-telemetry-table__headers__filter">
 | 
			
		||||
                        <table-column-header
 | 
			
		||||
                            v-for="(title, key, headerIndex) in headers"
 | 
			
		||||
                            :key="key"
 | 
			
		||||
                            :headerKey="key"
 | 
			
		||||
                            :headerIndex="headerIndex"
 | 
			
		||||
                            @resizeColumn="resizeColumn"
 | 
			
		||||
                            @dropTargetOffsetChanged="setDropTargetOffset"
 | 
			
		||||
                            @dropTargetActive="dropTargetActive"
 | 
			
		||||
                            @reorderColumn="reorderColumn"
 | 
			
		||||
                            @resizeColumnEnd="updateConfiguredColumnWidths"
 | 
			
		||||
                            :columnWidth="columnWidths[key]"
 | 
			
		||||
                            :isEditing="isEditing"
 | 
			
		||||
                            >
 | 
			
		||||
                            <search class="c-table__search"
 | 
			
		||||
                                v-model="filters[key]"
 | 
			
		||||
                                v-on:input="filterChanged(key)"
 | 
			
		||||
                                v-on:clear="clearFilter(key)" />
 | 
			
		||||
                        </table-column-header>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                </thead>
 | 
			
		||||
            </table>
 | 
			
		||||
        </div>
 | 
			
		||||
        <!-- Content table -->
 | 
			
		||||
        <div class="c-table__body-w c-telemetry-table__body-w js-telemetry-table__body-w" @scroll="scroll" :style="{ 'max-width': widthWithScroll}">
 | 
			
		||||
            <div class="c-telemetry-table__scroll-forcer" :style="{ width: totalWidth + 'px' }"></div>
 | 
			
		||||
            <table class="c-table__body c-telemetry-table__body js-telemetry-table__content"
 | 
			
		||||
                   :style="{ height: totalHeight + 'px'}">
 | 
			
		||||
                <tbody>
 | 
			
		||||
                    <telemetry-table-row v-for="(row, rowIndex) in visibleRows"
 | 
			
		||||
                        :headers="headers"
 | 
			
		||||
                        :columnWidths="columnWidths"
 | 
			
		||||
                        :rowIndex="rowIndex"
 | 
			
		||||
                        :rowOffset="rowOffset"
 | 
			
		||||
                        :rowHeight="rowHeight"
 | 
			
		||||
                        :row="row"
 | 
			
		||||
                        :marked="row.marked"
 | 
			
		||||
                        @mark="markRow"
 | 
			
		||||
                        @unmark="unmarkRow"
 | 
			
		||||
                        @markMultipleConcurrent="markMultipleConcurrentRows">
 | 
			
		||||
                    </telemetry-table-row>
 | 
			
		||||
                </tbody>
 | 
			
		||||
            </table>
 | 
			
		||||
        </div>
 | 
			
		||||
        <!-- Sizing table -->
 | 
			
		||||
        <table class="c-telemetry-table__sizing js-telemetry-table__sizing" :style="sizingTableWidth">
 | 
			
		||||
            <tr>
 | 
			
		||||
                <template v-for="(title, key) in headers">
 | 
			
		||||
                <th :key="key" :style="{ width: configuredColumnWidths[key] + 'px', 'max-width': configuredColumnWidths[key] + 'px'}">{{title}}</th>
 | 
			
		||||
                </template>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <telemetry-table-row v-for="(sizingRowData, objectKeyString) in sizingRows"
 | 
			
		||||
                :key="objectKeyString"
 | 
			
		||||
                :headers="headers"
 | 
			
		||||
                :columnWidths="configuredColumnWidths"
 | 
			
		||||
                :row="sizingRowData">
 | 
			
		||||
            </telemetry-table-row>
 | 
			
		||||
        </table>
 | 
			
		||||
        <telemetry-filter-indicator></telemetry-filter-indicator>
 | 
			
		||||
    </div>
 | 
			
		||||
    <!-- Content table -->
 | 
			
		||||
    <div class="c-table__body-w c-telemetry-table__body-w js-telemetry-table__body-w" @scroll="scroll" :style="{ 'max-width': widthWithScroll}">
 | 
			
		||||
        <div class="c-telemetry-table__scroll-forcer" :style="{ width: totalWidth + 'px' }"></div>
 | 
			
		||||
        <table class="c-table__body c-telemetry-table__body js-telemetry-table__content"
 | 
			
		||||
               :style="{ height: totalHeight + 'px'}">
 | 
			
		||||
            <tbody>
 | 
			
		||||
                <telemetry-table-row v-for="(row, rowIndex) in visibleRows"
 | 
			
		||||
                    :headers="headers"
 | 
			
		||||
                    :columnWidths="columnWidths"
 | 
			
		||||
                    :rowIndex="rowIndex"
 | 
			
		||||
                    :rowOffset="rowOffset"
 | 
			
		||||
                    :rowHeight="rowHeight"
 | 
			
		||||
                    :row="row">
 | 
			
		||||
                </telemetry-table-row>
 | 
			
		||||
            </tbody>
 | 
			
		||||
        </table>
 | 
			
		||||
    </div>
 | 
			
		||||
    <!-- Sizing table -->
 | 
			
		||||
    <table class="c-telemetry-table__sizing js-telemetry-table__sizing" :style="sizingTableWidth">
 | 
			
		||||
        <tr>
 | 
			
		||||
            <template v-for="(title, key) in headers">
 | 
			
		||||
            <th :key="key" :style="{ width: configuredColumnWidths[key] + 'px', 'max-width': configuredColumnWidths[key] + 'px'}">{{title}}</th>
 | 
			
		||||
            </template>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <telemetry-table-row v-for="(sizingRowData, objectKeyString) in sizingRows"
 | 
			
		||||
            :headers="headers"
 | 
			
		||||
            :columnWidths="configuredColumnWidths"
 | 
			
		||||
            :row="sizingRowData">
 | 
			
		||||
        </telemetry-table-row>
 | 
			
		||||
    </table>
 | 
			
		||||
    <telemetry-filter-indicator></telemetry-filter-indicator>
 | 
			
		||||
</div>
 | 
			
		||||
</div><!-- closes c-table-wrapper -->
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<style lang="scss">
 | 
			
		||||
@@ -134,7 +173,7 @@
 | 
			
		||||
            display: block;
 | 
			
		||||
            flex: 1 0 auto;
 | 
			
		||||
            width: 100px;
 | 
			
		||||
            vertical-align: middle; // This is crucial to hiding f**king 4px height injected by browser by default
 | 
			
		||||
            vertical-align: middle; // This is crucial to hiding 4px height injected by browser by default
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        td {
 | 
			
		||||
@@ -219,6 +258,10 @@
 | 
			
		||||
                align-items: stretch;
 | 
			
		||||
                position: absolute;
 | 
			
		||||
                height: 18px; // Needed when a row has empty values in its cells
 | 
			
		||||
 | 
			
		||||
                &.is-selected {
 | 
			
		||||
                    background-color: $colorSelectedBg;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            td {
 | 
			
		||||
@@ -269,6 +312,10 @@
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .paused {
 | 
			
		||||
        border: 1px solid #ff9900;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /******************************* LEGACY */
 | 
			
		||||
    .s-status-taking-snapshot,
 | 
			
		||||
    .overlay.snapshot {
 | 
			
		||||
@@ -318,6 +365,10 @@ export default {
 | 
			
		||||
        allowSorting: {
 | 
			
		||||
            'type': Boolean,
 | 
			
		||||
            'default': true
 | 
			
		||||
        },
 | 
			
		||||
        enableMarking: {
 | 
			
		||||
            type: Boolean,
 | 
			
		||||
            default: false
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    data() {
 | 
			
		||||
@@ -346,7 +397,10 @@ export default {
 | 
			
		||||
            dropOffsetLeft: undefined,
 | 
			
		||||
            isDropTargetActive: false,
 | 
			
		||||
            isAutosizeEnabled: configuration.autosize,
 | 
			
		||||
            scrollW: 0
 | 
			
		||||
            scrollW: 0,
 | 
			
		||||
            markCounter: 0,
 | 
			
		||||
            paused: false,
 | 
			
		||||
            markedRows: []
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    computed: {
 | 
			
		||||
@@ -532,15 +586,27 @@ export default {
 | 
			
		||||
            // which causes subsequent scroll to use an out of date height.
 | 
			
		||||
            this.contentTable.style.height = this.totalHeight + 'px'; 
 | 
			
		||||
        },
 | 
			
		||||
        exportAsCSV() {
 | 
			
		||||
        exportAsCSV(data) {
 | 
			
		||||
            const headerKeys = Object.keys(this.headers);
 | 
			
		||||
            const justTheData = this.table.filteredRows.getRows()
 | 
			
		||||
                .map(row => row.getFormattedDatum(this.headers));
 | 
			
		||||
            this.csvExporter.export(justTheData, {
 | 
			
		||||
 | 
			
		||||
            this.csvExporter.export(data, {
 | 
			
		||||
                filename: this.table.domainObject.name + '.csv',
 | 
			
		||||
                headers: headerKeys
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
        exportAllDataAsCSV() {
 | 
			
		||||
            const justTheData = this.table.filteredRows.getRows()
 | 
			
		||||
                .map(row => row.getFormattedDatum(this.headers));
 | 
			
		||||
 | 
			
		||||
            this.exportAsCSV(justTheData);
 | 
			
		||||
        },
 | 
			
		||||
        exportMarkedDataAsCSV() {
 | 
			
		||||
            const data = this.table.filteredRows.getRows()
 | 
			
		||||
                .filter(row => row.marked === true)
 | 
			
		||||
                .map(row => row.getFormattedDatum(this.headers));
 | 
			
		||||
 | 
			
		||||
            this.exportAsCSV(data);
 | 
			
		||||
        },
 | 
			
		||||
        outstandingRequests(loading) {
 | 
			
		||||
            this.loading = loading;
 | 
			
		||||
        },
 | 
			
		||||
@@ -632,8 +698,105 @@ export default {
 | 
			
		||||
        clearRowsAndRerender() {
 | 
			
		||||
            this.visibleRows = [];
 | 
			
		||||
            this.$nextTick().then(this.updateVisibleRows);
 | 
			
		||||
        }
 | 
			
		||||
        },
 | 
			
		||||
        pause(pausedByButton) {
 | 
			
		||||
            if (pausedByButton) {
 | 
			
		||||
                this.pausedByButton = true;
 | 
			
		||||
            }
 | 
			
		||||
            this.paused = true;
 | 
			
		||||
            this.table.pause();
 | 
			
		||||
        },
 | 
			
		||||
        unpause(unpausedByButton) {
 | 
			
		||||
            if (unpausedByButton) {
 | 
			
		||||
                this.paused = false;
 | 
			
		||||
                this.table.unpause();
 | 
			
		||||
                this.markedRows = [];
 | 
			
		||||
                this.pausedByButton = false;
 | 
			
		||||
            } else {
 | 
			
		||||
                if (!this.pausedByButton) {
 | 
			
		||||
                    this.paused = false;
 | 
			
		||||
                    this.table.unpause();
 | 
			
		||||
                    this.markedRows = [];
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
        },
 | 
			
		||||
        togglePauseByButton() {
 | 
			
		||||
            if (this.paused) {
 | 
			
		||||
                this.unpause(true);
 | 
			
		||||
            } else {
 | 
			
		||||
                this.pause(true);
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        undoMarkedRows(unpause) {
 | 
			
		||||
            this.markedRows.forEach(r => r.marked = false);
 | 
			
		||||
            this.markedRows = [];
 | 
			
		||||
        },
 | 
			
		||||
        unmarkRow(rowIndex) {
 | 
			
		||||
            this.undoMarkedRows();
 | 
			
		||||
            this.unpause();
 | 
			
		||||
        },
 | 
			
		||||
        markRow(rowIndex, keyModifier) {
 | 
			
		||||
            if (!this.enableMarking) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let insertMethod = 'unshift';
 | 
			
		||||
 | 
			
		||||
            if (this.markedRows.length && !keyModifier) {
 | 
			
		||||
                this.undoMarkedRows();
 | 
			
		||||
                insertMethod = 'push';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let markedRow = this.visibleRows[rowIndex];
 | 
			
		||||
 | 
			
		||||
            this.$set(markedRow, 'marked', true);
 | 
			
		||||
            this.pause();
 | 
			
		||||
 | 
			
		||||
            this.markedRows[insertMethod](markedRow);
 | 
			
		||||
        },
 | 
			
		||||
        unmarkAllRows(skipUnpause) {
 | 
			
		||||
            this.markedRows.forEach(row => row.marked = false);
 | 
			
		||||
            this.markedRows = [];
 | 
			
		||||
            this.unpause();
 | 
			
		||||
        },
 | 
			
		||||
        markMultipleConcurrentRows(rowIndex) {
 | 
			
		||||
            if (!this.enableMarking) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!this.markedRows.length) {
 | 
			
		||||
                this.markRow(rowIndex);
 | 
			
		||||
            } else {
 | 
			
		||||
                if (this.markedRows.length > 1) {
 | 
			
		||||
                    this.markedRows.forEach((r,i) => {
 | 
			
		||||
                        if (i !== 0) {
 | 
			
		||||
                            r.marked = false;
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                    this.markedRows.splice(1);
 | 
			
		||||
                }
 | 
			
		||||
                let lastRowToBeMarked = this.visibleRows[rowIndex];
 | 
			
		||||
 | 
			
		||||
                let allRows = this.table.filteredRows.getRows(),
 | 
			
		||||
                    firstRowIndex = allRows.indexOf(this.markedRows[0]),
 | 
			
		||||
                    lastRowIndex = allRows.indexOf(lastRowToBeMarked);
 | 
			
		||||
 | 
			
		||||
                //supports backward selection
 | 
			
		||||
                if (lastRowIndex < firstRowIndex) {
 | 
			
		||||
                    let temp = lastRowIndex;
 | 
			
		||||
                
 | 
			
		||||
                    lastRowIndex = firstRowIndex;
 | 
			
		||||
                    firstRowIndex = temp - 1;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                for (var i = firstRowIndex + 1; i <= lastRowIndex; i++) {
 | 
			
		||||
                    let row = allRows[i];
 | 
			
		||||
                    row.marked = true;
 | 
			
		||||
                    this.markedRows.push(row);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    created() {
 | 
			
		||||
        this.filterChanged = _.debounce(this.filterChanged, 500);
 | 
			
		||||
 
 | 
			
		||||
@@ -600,15 +600,15 @@ select {
 | 
			
		||||
    margin-right: $m;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.c-separator {
 | 
			
		||||
    @include cToolbarSeparator();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.c-toolbar {
 | 
			
		||||
    > * + * {
 | 
			
		||||
        margin-left: 2px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &__button {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &__separator {
 | 
			
		||||
        @include cToolbarSeparator();
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -76,23 +76,43 @@ div.c-table {
 | 
			
		||||
    height: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.c-table-wrapper {
 | 
			
		||||
    // Wraps .c-control-bar and .c-table
 | 
			
		||||
    @include abs();
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
 | 
			
		||||
    > .c-table {
 | 
			
		||||
        height: auto;
 | 
			
		||||
        flex: 1 1 auto;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    > * + * {
 | 
			
		||||
        margin-top: $interiorMarginSm;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.c-table-control-bar {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex: 0 0 auto;
 | 
			
		||||
 | 
			
		||||
    > * + * {
 | 
			
		||||
        margin-left: $interiorMarginSm;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.c-table {
 | 
			
		||||
    // Can be used by any type of table, scrolling, LAD, etc.
 | 
			
		||||
    $min-w: 50px;
 | 
			
		||||
 | 
			
		||||
    width: 100%;
 | 
			
		||||
 | 
			
		||||
    &__control-bar,
 | 
			
		||||
    &__headers-w {
 | 
			
		||||
        flex: 0 0 auto;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /******************************* ELEMENTS */
 | 
			
		||||
 | 
			
		||||
    &__control-bar {
 | 
			
		||||
        margin-bottom: $interiorMarginSm;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    thead tr,
 | 
			
		||||
    &.c-table__headers {
 | 
			
		||||
        background: $colorTabHeaderBg;
 | 
			
		||||
 
 | 
			
		||||
@@ -123,7 +123,12 @@
 | 
			
		||||
        .c-click-icon,
 | 
			
		||||
        .c-button {
 | 
			
		||||
            // Shrink buttons a bit when they appear in a frame
 | 
			
		||||
            font-size: 0.8em;
 | 
			
		||||
            align-items: baseline;
 | 
			
		||||
            font-size: 0.85em;
 | 
			
		||||
            padding: 3px 5px;
 | 
			
		||||
            &:before {
 | 
			
		||||
                font-size: 0.8em;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
</style>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user