diff --git a/src/plugins/telemetryTable/TableConfigurationComponent.js b/src/plugins/telemetryTable/TableConfigurationComponent.js deleted file mode 100644 index 9f8f60892f..0000000000 --- a/src/plugins/telemetryTable/TableConfigurationComponent.js +++ /dev/null @@ -1,87 +0,0 @@ -/***************************************************************************** - * 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([ - 'lodash', - 'vue', - './table-configuration.html', - './TelemetryTableConfiguration' -],function ( - _, - Vue, - TableConfigurationTemplate, - TelemetryTableConfiguration -) { - return function TableConfigurationComponent(domainObject, openmct) { - const tableConfiguration = new TelemetryTableConfiguration(domainObject, openmct); - let unlisteners = []; - - return new Vue({ - template: TableConfigurationTemplate, - data() { - return { - headers: {}, - configuration: tableConfiguration.getConfiguration() - } - }, - methods: { - updateHeaders(headers) { - this.headers = headers; - }, - toggleColumn(key) { - let isHidden = this.configuration.hiddenColumns[key] === true; - - this.configuration.hiddenColumns[key] = !isHidden; - tableConfiguration.updateConfiguration(this.configuration); - }, - addObject(domainObject) { - tableConfiguration.addColumnsForObject(domainObject, true); - this.updateHeaders(tableConfiguration.getAllHeaders()); - }, - removeObject(objectIdentifier) { - tableConfiguration.removeColumnsForObject(objectIdentifier, true); - this.updateHeaders(tableConfiguration.getAllHeaders()); - } - - }, - mounted() { - let compositionCollection = openmct.composition.get(domainObject); - - compositionCollection.load() - .then((composition) => { - tableConfiguration.addColumnsForAllObjects(composition); - this.updateHeaders(tableConfiguration.getAllHeaders()); - - compositionCollection.on('add', this.addObject); - unlisteners.push(compositionCollection.off.bind(compositionCollection, 'add', this.addObject)); - - compositionCollection.on('remove', this.removeObject); - unlisteners.push(compositionCollection.off.bind(compositionCollection, 'remove', this.removeObject)); - }); - }, - destroyed() { - tableConfiguration.destroy(); - unlisteners.forEach((unlisten) => unlisten()); - } - }); - } - }); \ No newline at end of file diff --git a/src/plugins/telemetryTable/TableConfigurationViewProvider.js b/src/plugins/telemetryTable/TableConfigurationViewProvider.js index 1203160c6c..fe21c1c262 100644 --- a/src/plugins/telemetryTable/TableConfigurationViewProvider.js +++ b/src/plugins/telemetryTable/TableConfigurationViewProvider.js @@ -22,11 +22,16 @@ define([ '../../api/objects/object-utils', - './TableConfigurationComponent' + './components/table-configuration.vue', + './TelemetryTableConfiguration', + 'vue' ], function ( objectUtils, - TableConfigurationComponent + TableConfigurationComponent, + TelemetryTableConfiguration, + Vue ) { + function TableConfigurationViewProvider(openmct) { let instantiateService; @@ -51,27 +56,38 @@ define([ return instantiateService(model, id); } + return { key: 'table-configuration', name: 'Telemetry Table Configuration', canView: function (selection) { + if (selection.length === 0) { + return false; + } let object = selection[0].context.item; - - return selection.length > 0 && - object.type === 'table' && + return object.type === 'table' && isBeingEdited(object); }, view: function (selection) { let component; let domainObject = selection[0].context.item; + const tableConfiguration = new TelemetryTableConfiguration(domainObject, openmct); return { show: function (element) { - component = TableConfigurationComponent(domainObject, openmct); - element.appendChild(component.$mount().$el); - }, + component = new Vue({ + provide: { + openmct, + tableConfiguration + }, + components: { + TableConfiguration: TableConfigurationComponent.default + }, + template: '', + el: element + }); + }, destroy: function (element) { component.$destroy(); - element.removeChild(component.$el); component = undefined; } } @@ -82,4 +98,4 @@ define([ } } return TableConfigurationViewProvider; -}); \ No newline at end of file +}); diff --git a/src/plugins/telemetryTable/TelemetryTable.js b/src/plugins/telemetryTable/TelemetryTable.js index 92dc238e88..43d48c0d38 100644 --- a/src/plugins/telemetryTable/TelemetryTable.js +++ b/src/plugins/telemetryTable/TelemetryTable.js @@ -36,12 +36,12 @@ define([ TelemetryTableConfiguration ) { class TelemetryTable extends EventEmitter { - constructor(domainObject, rowCount, openmct) { + constructor(domainObject, openmct) { super(); this.domainObject = domainObject; this.openmct = openmct; - this.rowCount = rowCount; + this.rowCount = 100; this.subscriptions = {}; this.tableComposition = undefined; this.telemetryObjects = []; @@ -85,10 +85,10 @@ define([ this.configuration.addColumnsForAllObjects(composition); composition.forEach(this.addTelemetryObject); - + this.tableComposition.on('add', this.addTelemetryObject); this.tableComposition.on('remove', this.removeTelemetryObject); - }); + }); } } @@ -158,7 +158,7 @@ define([ getColumnMapForObject(objectKeyString) { let columns = this.configuration.getColumns(); - + return columns[objectKeyString].reduce((map, column) => { map[column.getKey()] = column; return map; @@ -189,7 +189,7 @@ define([ this.filteredRows.destroy(); Object.keys(this.subscriptions).forEach(this.unsubscribe, this); this.openmct.time.off('bounds', this.refreshData); - + if (this.tableComposition !== undefined) { this.tableComposition.off('add', this.addTelemetryObject); this.tableComposition.off('remove', this.removeTelemetryObject); @@ -198,4 +198,4 @@ define([ } return TelemetryTable; -}); \ No newline at end of file +}); diff --git a/src/plugins/telemetryTable/TelemetryTableComponent.js b/src/plugins/telemetryTable/TelemetryTableComponent.js deleted file mode 100644 index 72ba2bfdea..0000000000 --- a/src/plugins/telemetryTable/TelemetryTableComponent.js +++ /dev/null @@ -1,315 +0,0 @@ -/***************************************************************************** - * 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([ - 'lodash', - 'vue', - './telemetry-table.html', - './TelemetryTable', - './TelemetryTableRowComponent', - '../../exporters/CSVExporter' -],function ( - _, - Vue, - TelemetryTableTemplate, - TelemetryTable, - TelemetryTableRowComponent, - CSVExporter -) { - const VISIBLE_ROW_COUNT = 100; - const ROW_HEIGHT = 17; - const RESIZE_POLL_INTERVAL = 200; - const AUTO_SCROLL_TRIGGER_HEIGHT = 20; - - return function TelemetryTableComponent(domainObject, openmct) { - const csvExporter = new CSVExporter(); - const table = new TelemetryTable(domainObject, VISIBLE_ROW_COUNT, openmct); - let processingScroll = false; - let updatingView = false; - - return new Vue({ - template: TelemetryTableTemplate, - components: { - 'telemetry-table-row': TelemetryTableRowComponent - }, - data() { - return { - headers: {}, - configuration: table.configuration.getConfiguration(), - headersCount: 0, - visibleRows: [], - columnWidths: [], - sizingRows: {}, - rowHeight: ROW_HEIGHT, - scrollOffset: 0, - totalHeight: 0, - totalWidth: 0, - rowOffset: 0, - autoScroll: true, - sortOptions: {}, - filters: {}, - loading: false, - scrollable: undefined, - tableEl: undefined, - headersHolderEl: undefined, - calcTableWidth: '100%' - } - }, - methods: { - updateVisibleRows() { - - let start = 0; - let end = VISIBLE_ROW_COUNT; - let filteredRows = table.filteredRows.getRows(); - let filteredRowsLength = filteredRows.length; - - this.totalHeight = this.rowHeight * filteredRowsLength - 1; - - if (filteredRowsLength < VISIBLE_ROW_COUNT) { - end = filteredRowsLength; - } else { - let firstVisible = this.calculateFirstVisibleRow(); - let lastVisible = this.calculateLastVisibleRow(); - let totalVisible = lastVisible - firstVisible; - - let numberOffscreen = VISIBLE_ROW_COUNT - totalVisible; - start = firstVisible - Math.floor(numberOffscreen / 2); - end = lastVisible + Math.ceil(numberOffscreen / 2); - - if (start < 0) { - start = 0; - end = Math.min(VISIBLE_ROW_COUNT, filteredRowsLength); - } else if (end >= filteredRowsLength) { - end = filteredRowsLength; - start = end - VISIBLE_ROW_COUNT + 1; - } - } - this.rowOffset = start; - this.visibleRows = filteredRows.slice(start, end); - }, - calculateFirstVisibleRow() { - return Math.floor(this.scrollable.scrollTop / this.rowHeight); - }, - calculateLastVisibleRow() { - let bottomScroll = this.scrollable.scrollTop + this.scrollable.offsetHeight; - return Math.floor(bottomScroll / this.rowHeight); - }, - updateHeaders() { - let headers = table.configuration.getVisibleHeaders(); - - this.headers = headers; - this.headersCount = Object.values(headers).length; - Vue.nextTick().then(this.calculateColumnWidths); - }, - setSizingTableWidth() { - let scrollW = this.scrollable.offsetWidth - this.scrollable.clientWidth; - - if (scrollW && scrollW > 0) { - this.calcTableWidth = 'calc(100% - ' + scrollW + 'px)'; - } - }, - calculateColumnWidths() { - let columnWidths = []; - let totalWidth = 0; - let sizingRowEl = this.sizingTable.children[0]; - let sizingCells = Array.from(sizingRowEl.children); - - sizingCells.forEach((cell) => { - let columnWidth = cell.offsetWidth; - columnWidths.push(columnWidth + 'px'); - totalWidth += columnWidth; - }); - - this.columnWidths = columnWidths; - this.totalWidth = totalWidth; - }, - sortBy(columnKey) { - // If sorting by the same column, flip the sort direction. - if (this.sortOptions.key === columnKey) { - if (this.sortOptions.direction === 'asc') { - this.sortOptions.direction = 'desc'; - } else { - this.sortOptions.direction = 'asc'; - } - } else { - this.sortOptions = { - key: columnKey, - direction: 'asc' - } - } - table.filteredRows.sortBy(this.sortOptions); - }, - scroll() { - if (!processingScroll) { - processingScroll = true; - requestAnimationFrame(()=> { - this.updateVisibleRows(); - this.synchronizeScrollX(); - - if (this.shouldSnapToBottom()) { - this.autoScroll = true; - } else { - // If user scrolls away from bottom, disable auto-scroll. - // Auto-scroll will be re-enabled if user scrolls to bottom again. - this.autoScroll = false; - } - processingScroll = false; - }); - } - }, - shouldSnapToBottom() { - return this.scrollable.scrollTop >= (this.scrollable.scrollHeight - this.scrollable.offsetHeight - AUTO_SCROLL_TRIGGER_HEIGHT); - }, - scrollToBottom() { - this.scrollable.scrollTop = this.scrollable.scrollHeight; - }, - synchronizeScrollX() { - this.headersHolderEl.scrollLeft = this.scrollable.scrollLeft; - }, - filterChanged(columnKey) { - table.filteredRows.setColumnFilter(columnKey, this.filters[columnKey]); - }, - clearFilter(columnKey) { - this.filters[columnKey] = ''; - table.filteredRows.setColumnFilter(columnKey, ''); - }, - rowsAdded(rows) { - let sizingRow; - if (Array.isArray(rows)) { - sizingRow = rows[0]; - } else { - sizingRow = rows; - } - if (!this.sizingRows[sizingRow.objectKeyString]) { - this.sizingRows[sizingRow.objectKeyString] = sizingRow; - Vue.nextTick().then(this.calculateColumnWidths); - } - - if (!updatingView) { - updatingView = true; - requestAnimationFrame(()=> { - this.updateVisibleRows(); - if (this.autoScroll) { - Vue.nextTick().then(this.scrollToBottom); - } - updatingView = false; - }); - } - }, - rowsRemoved(rows) { - if (!updatingView) { - updatingView = true; - requestAnimationFrame(()=> { - this.updateVisibleRows(); - updatingView = false; - }); - } - }, - exportAsCSV() { - const justTheData = table.filteredRows.getRows() - .map(row => row.getFormattedDatum()); - const headers = Object.keys(this.headers); - csvExporter.export(justTheData, { - filename: table.domainObject.name + '.csv', - headers: headers - }); - }, - outstandingRequests(loading) { - this.loading = loading; - }, - calculateTableSize() { - this.setSizingTableWidth(); - Vue.nextTick().then(this.calculateColumnWidths); - }, - pollForResize() { - let el = this.$el; - let width = el.clientWidth; - let height = el.clientHeight; - - this.resizePollHandle = setInterval(() => { - if (el.clientWidth !== width || el.clientHeight !== height) { - this.calculateTableSize(); - width = el.clientWidth; - height = el.clientHeight; - } - }, RESIZE_POLL_INTERVAL); - }, - updateConfiguration(configuration) { - this.configuration = configuration; - this.updateHeaders(); - }, - addObject() { - this.updateHeaders(); - }, - removeObject(objectIdentifier) { - let objectKeyString = openmct.objects.makeKeyString(objectIdentifier); - delete this.sizingRows[objectKeyString]; - this.updateHeaders(); - } - }, - created() { - this.filterChanged = _.debounce(this.filterChanged, 500); - }, - mounted() { - table.on('object-added', this.addObject); - table.on('object-removed', this.removeObject); - table.on('outstanding-requests', this.outstandingRequests); - - table.filteredRows.on('add', this.rowsAdded); - table.filteredRows.on('remove', this.rowsRemoved); - table.filteredRows.on('sort', this.updateVisibleRows); - table.filteredRows.on('filter', this.updateVisibleRows); - - //Default sort - this.sortOptions = table.filteredRows.sortBy(); - this.scrollable = this.$el.querySelector('.t-scrolling'); - this.sizingTable = this.$el.querySelector('.js-sizing-table'); - this.headersHolderEl = this.$el.querySelector('.mct-table-headers-w'); - - table.configuration.on('change', this.updateConfiguration); - - this.calculateTableSize(); - this.pollForResize(); - - table.initialize(); - }, - destroyed() { - table.off('object-added', this.addObject); - table.off('object-removed', this.removeObject); - table.off('outstanding-requests', this.outstandingRequests); - - table.filteredRows.off('add', this.rowsAdded); - table.filteredRows.off('remove', this.rowsRemoved); - table.filteredRows.off('sort', this.updateVisibleRows); - table.filteredRows.off('filter', this.updateVisibleRows); - - table.configuration.off('change', this.updateConfiguration); - - clearInterval(this.resizePollHandle); - - table.configuration.destroy(); - - table.destroy(); - } - }); - } - }); \ No newline at end of file diff --git a/src/plugins/telemetryTable/TelemetryTableRowComponent.js b/src/plugins/telemetryTable/TelemetryTableRowComponent.js deleted file mode 100644 index 6fdac03979..0000000000 --- a/src/plugins/telemetryTable/TelemetryTableRowComponent.js +++ /dev/null @@ -1,90 +0,0 @@ -/***************************************************************************** - * 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([ - './telemetry-table-row.html', -],function ( - TelemetryTableRowTemplate -) { - return { - template: TelemetryTableRowTemplate, - data: function () { - return { - rowTop: (this.rowOffset + this.rowIndex) * this.rowHeight + 'px', - formattedRow: this.row.getFormattedDatum(), - rowLimitClass: this.row.getRowLimitClass(), - cellLimitClasses: this.row.getCellLimitClasses() - } - }, - props: { - headers: { - type: Object, - required: true - }, - row: { - type: Object, - required: true - }, - columnWidths: { - type: Array, - required: false, - default: [], - }, - rowIndex: { - type: Number, - required: false, - default: undefined - }, - rowOffset: { - type: Number, - required: false, - default: 0 - }, - rowHeight: { - type: Number, - required: false, - default: 0 - }, - configuration: { - type: Object, - required: true - } - }, - methods: { - calculateRowTop: function (rowOffset) { - this.rowTop = (rowOffset + this.rowIndex) * this.rowHeight + 'px'; - }, - formatRow: function (row) { - this.formattedRow = row.getFormattedDatum(); - this.rowLimitClass = row.getRowLimitClass(); - this.cellLimitClasses = row.getCellLimitClasses(); - } - }, - watch: { - rowOffset: 'calculateRowTop', - row: { - handler: 'formatRow', - deep: false - } - } - }; - }); \ No newline at end of file diff --git a/src/plugins/telemetryTable/TelemetryTableViewProvider.js b/src/plugins/telemetryTable/TelemetryTableViewProvider.js index c162ce4d90..35ef0cd01a 100644 --- a/src/plugins/telemetryTable/TelemetryTableViewProvider.js +++ b/src/plugins/telemetryTable/TelemetryTableViewProvider.js @@ -20,7 +20,17 @@ * at runtime from the About dialog for additional information. *****************************************************************************/ -define(['./TelemetryTableComponent'], function (TelemetryTableComponent) { +define([ + './components/table.vue', + '../../exporters/CSVExporter', + './TelemetryTable', + 'vue' +], function ( + TableComponent, + CSVExporter, + TelemetryTable, + Vue +) { function TelemetryTableViewProvider(openmct) { return { key: 'table', @@ -30,15 +40,26 @@ define(['./TelemetryTableComponent'], function (TelemetryTableComponent) { return domainObject.type === 'table' || domainObject.hasOwnProperty('telemetry'); }, view: function (domainObject) { + let csvExporter = new CSVExporter(); + let table = new TelemetryTable(domainObject, openmct); let component; return { show: function (element) { - component = new TelemetryTableComponent(domainObject, openmct); - element.appendChild(component.$mount().$el); - }, + component = new Vue({ + components: { + TableComponent: TableComponent.default, + }, + provide: { + openmct, + csvExporter, + table + }, + el: element, + template: '' + }); + }, destroy: function (element) { component.$destroy(); - element.removeChild(component.$el); component = undefined; } } @@ -49,4 +70,4 @@ define(['./TelemetryTableComponent'], function (TelemetryTableComponent) { } } return TelemetryTableViewProvider; -}); \ No newline at end of file +}); diff --git a/src/plugins/telemetryTable/components/table-configuration.vue b/src/plugins/telemetryTable/components/table-configuration.vue new file mode 100644 index 0000000000..57f6152e79 --- /dev/null +++ b/src/plugins/telemetryTable/components/table-configuration.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/src/plugins/telemetryTable/components/table-row.vue b/src/plugins/telemetryTable/components/table-row.vue new file mode 100644 index 0000000000..8d39e95481 --- /dev/null +++ b/src/plugins/telemetryTable/components/table-row.vue @@ -0,0 +1,76 @@ + + + + + diff --git a/src/plugins/telemetryTable/components/table.vue b/src/plugins/telemetryTable/components/table.vue new file mode 100644 index 0000000000..cbd8bcbce7 --- /dev/null +++ b/src/plugins/telemetryTable/components/table.vue @@ -0,0 +1,543 @@ + + + + + diff --git a/src/plugins/telemetryTable/table-configuration.html b/src/plugins/telemetryTable/table-configuration.html deleted file mode 100644 index b21e1e7fe1..0000000000 --- a/src/plugins/telemetryTable/table-configuration.html +++ /dev/null @@ -1,11 +0,0 @@ -
- - - -
\ No newline at end of file diff --git a/src/plugins/telemetryTable/telemetry-table-row.html b/src/plugins/telemetryTable/table-row.html similarity index 100% rename from src/plugins/telemetryTable/telemetry-table-row.html rename to src/plugins/telemetryTable/table-row.html diff --git a/src/plugins/telemetryTable/telemetry-table.html b/src/plugins/telemetryTable/telemetry-table.html deleted file mode 100644 index 78fa917a2c..0000000000 --- a/src/plugins/telemetryTable/telemetry-table.html +++ /dev/null @@ -1,64 +0,0 @@ -
-
- - Export As CSV - -
- -
- - - - - - - - - -
{{title}}
-
- - -
-
-
- -
-
- - - - - -
-
- - - - - - - -
{{title}}
-
\ No newline at end of file diff --git a/src/styles-new/_constants.scss b/src/styles-new/_constants.scss index 15e4c98466..ec738401b9 100644 --- a/src/styles-new/_constants.scss +++ b/src/styles-new/_constants.scss @@ -19,7 +19,12 @@ $treeItemIndent: 16px; $treeTypeIconW: 18px; /*************** Items */ +$itemPadLR: 5px; $ueBrowseGridItemLg: 200px; +/*************** Tabular */ +$tabularHeaderH: 22px; +$tabularTdPadLR: $itemPadLR; +$tabularTdPadTB: 2px; /************************** VISUAL */ diff --git a/src/styles-new/_global.scss b/src/styles-new/_global.scss index 86bd7cebed..85e8ce1a34 100644 --- a/src/styles-new/_global.scss +++ b/src/styles-new/_global.scss @@ -146,6 +146,11 @@ ol, ul { padding-left: 0; } +table { + border-spacing: 0; + border-collapse: collapse; +} + /************************** LEGACY */ mct-container { diff --git a/src/styles-new/legacy-styles.scss b/src/styles-new/legacy-styles.scss index bd7804cc91..14c816fa04 100644 --- a/src/styles-new/legacy-styles.scss +++ b/src/styles-new/legacy-styles.scss @@ -56,7 +56,7 @@ // //!********************************* VIEWS *! @import "../styles/fixed-position"; -@import "../styles/lists/tabular"; +//@import "../styles/lists/tabular"; @import "../styles/plots/plots-main"; @import "../styles/plots/legend"; @import "../styles/iframe"; diff --git a/src/styles/_views.scss b/src/styles/_views.scss index 8c45ff2d78..0aa41468fa 100644 --- a/src/styles/_views.scss +++ b/src/styles/_views.scss @@ -30,7 +30,8 @@ .child-frame { .has-control-bar { $btnExportH: $btnFrameH; - .l-control-bar { + .l-control-bar, + .c-control-bar { display: none; } .l-view-section {