mirror of
https://github.com/nasa/openmct.git
synced 2025-04-23 10:23:43 +00:00
Merged
Resolved merge conflicts Resolved merge conflicts
This commit is contained in:
parent
23a8c305c1
commit
99ba9edb95
platform/features/table
@ -23,16 +23,16 @@
|
||||
|
||||
define([
|
||||
"./src/directives/MCTTable",
|
||||
"./src/controllers/RTTelemetryTableController",
|
||||
"./src/controllers/TelemetryTableController",
|
||||
"./src/controllers/RealtimeTableController",
|
||||
"./src/controllers/HistoricalTableController",
|
||||
"./src/controllers/TableOptionsController",
|
||||
'../../commonUI/regions/src/Region',
|
||||
'../../commonUI/browse/src/InspectorRegion',
|
||||
"legacyRegistry"
|
||||
], function (
|
||||
MCTTable,
|
||||
RTTelemetryTableController,
|
||||
TelemetryTableController,
|
||||
RealtimeTableController,
|
||||
HistoricalTableController,
|
||||
TableOptionsController,
|
||||
Region,
|
||||
InspectorRegion,
|
||||
@ -109,13 +109,13 @@ define([
|
||||
],
|
||||
"controllers": [
|
||||
{
|
||||
"key": "TelemetryTableController",
|
||||
"implementation": TelemetryTableController,
|
||||
"key": "HistoricalTableController",
|
||||
"implementation": HistoricalTableController,
|
||||
"depends": ["$scope", "telemetryHandler", "telemetryFormatter"]
|
||||
},
|
||||
{
|
||||
"key": "RTTelemetryTableController",
|
||||
"implementation": RTTelemetryTableController,
|
||||
"key": "RealtimeTableController",
|
||||
"implementation": RealtimeTableController,
|
||||
"depends": ["$scope", "telemetryHandler", "telemetryFormatter"]
|
||||
},
|
||||
{
|
||||
@ -130,7 +130,7 @@ define([
|
||||
"name": "Historical Table",
|
||||
"key": "table",
|
||||
"glyph": "\ue604",
|
||||
"templateUrl": "templates/table.html",
|
||||
"templateUrl": "templates/historical-table.html",
|
||||
"needs": [
|
||||
"telemetry"
|
||||
],
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div ng-controller="TelemetryTableController">
|
||||
<div ng-controller="HistoricalTableController">
|
||||
<mct-table
|
||||
headers="headers"
|
||||
rows="rows"
|
@ -1,4 +1,4 @@
|
||||
<div ng-controller="RTTelemetryTableController">
|
||||
<div ng-controller="RealtimeTableController">
|
||||
<mct-table
|
||||
headers="headers"
|
||||
rows="rows"
|
||||
|
@ -47,7 +47,7 @@ define(
|
||||
* @param metadata Metadata describing the domains and ranges available
|
||||
* @returns {TableConfiguration} This object
|
||||
*/
|
||||
TableConfiguration.prototype.buildColumns = function (metadata) {
|
||||
TableConfiguration.prototype.populateColumns = function (metadata) {
|
||||
var self = this;
|
||||
|
||||
this.columns = [];
|
||||
@ -141,7 +141,7 @@ define(
|
||||
*/
|
||||
TableConfiguration.prototype.defaultColumnConfiguration = function () {
|
||||
return ((this.domainObject.getModel().configuration || {}).table ||
|
||||
{}).columns || {};
|
||||
{}).columns;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -156,6 +156,16 @@ define(
|
||||
});
|
||||
};
|
||||
|
||||
function configChanged(config1, config2) {
|
||||
var config1Keys = Object.keys(config1),
|
||||
config2Keys = Object.keys(config2);
|
||||
|
||||
return (config1Keys.length !== config2Keys.length) ||
|
||||
config1Keys.some(function(key){
|
||||
return config1[key] !== config2[key];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* As part of the process of building the table definition, extract
|
||||
* configuration from column definitions.
|
||||
@ -163,10 +173,10 @@ define(
|
||||
* pairs where the key is the column title, and the value is a
|
||||
* boolean indicating whether the column should be shown.
|
||||
*/
|
||||
TableConfiguration.prototype.getColumnConfiguration = function () {
|
||||
TableConfiguration.prototype.buildColumnConfiguration = function () {
|
||||
var configuration = {},
|
||||
//Use existing persisted config, or default it
|
||||
defaultConfig = this.defaultColumnConfiguration();
|
||||
defaultConfig = this.defaultColumnConfiguration() || {};
|
||||
|
||||
/**
|
||||
* For each column header, define a configuration value
|
||||
@ -175,10 +185,15 @@ define(
|
||||
*/
|
||||
this.getHeaders().forEach(function (columnTitle) {
|
||||
configuration[columnTitle] =
|
||||
typeof defaultConfig[columnTitle] === 'undefined' ? true :
|
||||
typeof (defaultConfig || {})[columnTitle] === 'undefined' ? true :
|
||||
defaultConfig[columnTitle];
|
||||
});
|
||||
|
||||
//Synchronize column configuration with model
|
||||
if (configChanged(configuration, defaultConfig)) {
|
||||
this.saveColumnConfiguration(configuration);
|
||||
}
|
||||
|
||||
return configuration;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,70 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web 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 Web 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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
[
|
||||
'./TelemetryTableController'
|
||||
],
|
||||
function (TableController) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Extends TelemetryTableController and adds real-time streaming
|
||||
* support.
|
||||
* @memberof platform/features/table
|
||||
* @param $scope
|
||||
* @param telemetryHandler
|
||||
* @param telemetryFormatter
|
||||
* @constructor
|
||||
*/
|
||||
function HistoricalTableController($scope, telemetryHandler, telemetryFormatter) {
|
||||
TableController.call(this, $scope, telemetryHandler, telemetryFormatter);
|
||||
}
|
||||
|
||||
HistoricalTableController.prototype = Object.create(TableController.prototype);
|
||||
|
||||
/**
|
||||
* Populates historical data on scope when it becomes available from
|
||||
* the telemetry API
|
||||
*/
|
||||
HistoricalTableController.prototype.addHistoricalData = function () {
|
||||
var rowData = [],
|
||||
self = this;
|
||||
|
||||
this.handle.getTelemetryObjects().forEach(function (telemetryObject){
|
||||
var series = self.handle.getSeries(telemetryObject) || {},
|
||||
pointCount = series.getPointCount ? series.getPointCount() : 0,
|
||||
i = 0;
|
||||
|
||||
for (; i < pointCount; i++) {
|
||||
rowData.push(self.table.getRowValues(telemetryObject,
|
||||
self.handle.makeDatum(telemetryObject, series, i)));
|
||||
}
|
||||
});
|
||||
|
||||
this.$scope.rows = rowData;
|
||||
};
|
||||
|
||||
return HistoricalTableController;
|
||||
}
|
||||
);
|
@ -61,25 +61,33 @@ define(
|
||||
$scope.sortColumn = undefined;
|
||||
$scope.sortDirection = undefined;
|
||||
}
|
||||
self.updateRows($scope.rows);
|
||||
self.setRows($scope.rows);
|
||||
};
|
||||
|
||||
/*
|
||||
* Define watches to listen for changes to headers and rows.
|
||||
*/
|
||||
$scope.$watchCollection('filters', function () {
|
||||
self.updateRows($scope.rows);
|
||||
self.setRows($scope.rows);
|
||||
});
|
||||
$scope.$watch('headers', this.updateHeaders.bind(this));
|
||||
$scope.$watch('rows', this.updateRows.bind(this));
|
||||
$scope.$watch('headers', this.setHeaders.bind(this));
|
||||
$scope.$watch('rows', this.setRows.bind(this));
|
||||
|
||||
/*
|
||||
* Listen for rows added individually (eg. for real-time tables)
|
||||
*/
|
||||
$scope.$on('add:row', this.newRow.bind(this));
|
||||
$scope.$on('add:row', this.addRow.bind(this));
|
||||
$scope.$on('remove:row', this.removeRow.bind(this));
|
||||
}
|
||||
|
||||
function fastPromise(returnValue) {
|
||||
return {
|
||||
then: function (callback) {
|
||||
return fastPromise(callback(returnValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If auto-scroll is enabled, this function will scroll to the
|
||||
* bottom of the page
|
||||
@ -99,40 +107,28 @@ define(
|
||||
|
||||
/**
|
||||
* Handles a row add event. Rows can be added as needed using the
|
||||
* `addRow` broadcast event.
|
||||
* `add:row` broadcast event.
|
||||
* @private
|
||||
*/
|
||||
MCTTableController.prototype.newRow = function (event, rowIndex) {
|
||||
var self = this,
|
||||
row = this.$scope.rows[rowIndex],
|
||||
largestRow;
|
||||
|
||||
function sizeAndScroll () {
|
||||
self.setElementSizes();
|
||||
self.scrollToBottom();
|
||||
}
|
||||
MCTTableController.prototype.addRow = function (event, rowIndex) {
|
||||
var row = this.$scope.rows[rowIndex];
|
||||
|
||||
//Does the row pass the current filter?
|
||||
if (this.filterRows([row]).length === 1) {
|
||||
//Insert the row into the correct position in the array
|
||||
this.insertSorted(this.$scope.displayRows, row);
|
||||
|
||||
//Calculate largest row
|
||||
largestRow = this.buildLargestRow([this.$scope.sizingRow, row]);
|
||||
|
||||
// Has it changed? If so, set the the 'sizing' row which
|
||||
// determines column widths
|
||||
if (JSON.stringify(largestRow) !== JSON.stringify(this.$scope.sizingRow)){
|
||||
this.$scope.sizingRow = largestRow;
|
||||
this.$timeout(sizeAndScroll);
|
||||
} else {
|
||||
sizeAndScroll();
|
||||
}
|
||||
|
||||
//Resize the columns , then update the rows
|
||||
// visible in the table
|
||||
this.resize([this.$scope.sizingRow, row])
|
||||
.then(this.setVisibleRows.bind(this))
|
||||
.then(this.scrollToBottom.bind(this));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles a row add event. Rows can be added as needed using the
|
||||
* `addRow` broadcast event.
|
||||
* Handles a row remove event. Rows can be removed as needed using the
|
||||
* `remove:row` broadcast event.
|
||||
* @private
|
||||
*/
|
||||
MCTTableController.prototype.removeRow = function (event, rowIndex) {
|
||||
@ -245,7 +241,7 @@ define(
|
||||
* enabled, reset filters. If sorting is enabled, reset
|
||||
* sorting.
|
||||
*/
|
||||
MCTTableController.prototype.updateHeaders = function (newHeaders) {
|
||||
MCTTableController.prototype.setHeaders = function (newHeaders) {
|
||||
if (!newHeaders){
|
||||
return;
|
||||
}
|
||||
@ -261,7 +257,7 @@ define(
|
||||
this.$scope.sortColumn = undefined;
|
||||
this.$scope.sortDirection = undefined;
|
||||
}
|
||||
this.updateRows(this.$scope.rows);
|
||||
this.setRows(this.$scope.rows);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -291,7 +287,6 @@ define(
|
||||
this.$scope.headerHeight = headerHeight;
|
||||
this.$scope.rowHeight = rowHeight;
|
||||
this.$scope.totalHeight = overallHeight;
|
||||
this.setVisibleRows();
|
||||
|
||||
if (tableWidth > 0) {
|
||||
this.$scope.totalWidth = tableWidth + 'px';
|
||||
@ -439,7 +434,6 @@ define(
|
||||
prevLargest[key] = JSON.parse(JSON.stringify(row[key]));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
return prevLargest;
|
||||
}, JSON.parse(JSON.stringify(rows[0] || {})));
|
||||
@ -447,26 +441,30 @@ define(
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates the widest row in the table, pads that row, and adds
|
||||
* it to the table. Allows the table to size itself, then uses this
|
||||
* as basis for column dimensions.
|
||||
* Calculates the widest row in the table, and if necessary, resizes
|
||||
* the table accordingly
|
||||
*
|
||||
* @param rows the rows on which to resize
|
||||
* @returns {Promise} a promise that will resolve when resizing has
|
||||
* occurred.
|
||||
* @private
|
||||
*/
|
||||
MCTTableController.prototype.resize = function (){
|
||||
var self = this;
|
||||
MCTTableController.prototype.resize = function (rows){
|
||||
//Calculate largest row
|
||||
var largestRow = this.buildLargestRow(rows);
|
||||
|
||||
this.$scope.sizingRow = this.buildLargestRow(this.$scope.displayRows);
|
||||
|
||||
//Wait a timeout to allow digest of previous change to visible
|
||||
// rows to happen.
|
||||
this.$timeout(function () {
|
||||
self.$scope.visibleRows = [];
|
||||
self.setElementSizes();
|
||||
});
|
||||
// Has it changed? If so, set the the 'sizing' row which
|
||||
// determines column widths
|
||||
if (JSON.stringify(largestRow) !== JSON.stringify(this.$scope.sizingRow)){
|
||||
this.$scope.sizingRow = largestRow;
|
||||
return this.$timeout(this.setElementSizes.bind(this));
|
||||
} else {
|
||||
return fastPromise(undefined);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @priate
|
||||
* @private
|
||||
*/
|
||||
MCTTableController.prototype.filterAndSort = function (rows) {
|
||||
var displayRows = rows;
|
||||
@ -484,17 +482,14 @@ define(
|
||||
* Update rows with new data. If filtering is enabled, rows
|
||||
* will be sorted before display.
|
||||
*/
|
||||
MCTTableController.prototype.updateRows = function (newRows) {
|
||||
//Reset visible rows because new row data available.
|
||||
this.$scope.visibleRows = [];
|
||||
|
||||
MCTTableController.prototype.setRows = function (newRows) {
|
||||
//Nothing to show because no columns visible
|
||||
if (!this.$scope.displayHeaders) {
|
||||
if (!this.$scope.displayHeaders || !newRows) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.filterAndSort(newRows || []);
|
||||
this.resize();
|
||||
this.resize(newRows).then(this.setVisibleRows.bind(this));
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -37,7 +37,7 @@ define(
|
||||
* @param telemetryFormatter
|
||||
* @constructor
|
||||
*/
|
||||
function RTTelemetryTableController($scope, telemetryHandler, telemetryFormatter) {
|
||||
function RealtimeTableController($scope, telemetryHandler, telemetryFormatter) {
|
||||
TableController.call(this, $scope, telemetryHandler, telemetryFormatter);
|
||||
|
||||
$scope.autoScroll = false;
|
||||
@ -66,58 +66,31 @@ define(
|
||||
});
|
||||
}
|
||||
|
||||
RTTelemetryTableController.prototype = Object.create(TableController.prototype);
|
||||
RealtimeTableController.prototype = Object.create(TableController.prototype);
|
||||
|
||||
/**
|
||||
Override the subscribe function defined on the parent controller in
|
||||
order to handle realtime telemetry instead of historical.
|
||||
*/
|
||||
RTTelemetryTableController.prototype.subscribe = function () {
|
||||
var self = this;
|
||||
self.$scope.rows = undefined;
|
||||
(this.subscriptions || []).forEach(function (unsubscribe){
|
||||
unsubscribe();
|
||||
});
|
||||
RealtimeTableController.prototype.addRealtimeData = function() {
|
||||
var self = this,
|
||||
datum,
|
||||
row;
|
||||
this.handle.getTelemetryObjects().forEach(function (telemetryObject){
|
||||
datum = self.handle.getDatum(telemetryObject);
|
||||
if (datum) {
|
||||
//Populate row values from telemetry datum
|
||||
row = self.table.getRowValues(telemetryObject, datum);
|
||||
self.$scope.rows.push(row);
|
||||
|
||||
if (this.handle) {
|
||||
this.handle.unsubscribe();
|
||||
}
|
||||
|
||||
function updateData(){
|
||||
var datum,
|
||||
row;
|
||||
self.handle.getTelemetryObjects().forEach(function (telemetryObject){
|
||||
datum = self.handle.getDatum(telemetryObject);
|
||||
if (datum) {
|
||||
row = self.table.getRowValues(telemetryObject, datum);
|
||||
if (!self.$scope.rows){
|
||||
self.$scope.rows = [row];
|
||||
self.$scope.$digest();
|
||||
} else {
|
||||
self.$scope.rows.push(row);
|
||||
|
||||
if (self.$scope.rows.length > self.maxRows) {
|
||||
self.$scope.$broadcast('remove:row', 0);
|
||||
self.$scope.rows.shift();
|
||||
}
|
||||
|
||||
self.$scope.$broadcast('add:row',
|
||||
self.$scope.rows.length - 1);
|
||||
}
|
||||
//Inform table that a new row has been added
|
||||
if (self.$scope.rows.length > self.maxRows) {
|
||||
self.$scope.$broadcast('remove:row', 0);
|
||||
self.$scope.rows.shift();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
self.$scope.$broadcast('add:row',
|
||||
self.$scope.rows.length - 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.handle = this.$scope.domainObject && this.telemetryHandler.handle(
|
||||
this.$scope.domainObject,
|
||||
updateData,
|
||||
true // Lossless
|
||||
);
|
||||
|
||||
this.setup();
|
||||
};
|
||||
|
||||
return RTTelemetryTableController;
|
||||
return RealtimeTableController;
|
||||
}
|
||||
);
|
@ -51,13 +51,22 @@ define(
|
||||
|
||||
this.$scope = $scope;
|
||||
this.domainObject = $scope.domainObject;
|
||||
this.listeners = [];
|
||||
|
||||
$scope.columnsForm = {};
|
||||
|
||||
this.domainObject.getCapability('mutation').listen(function (model) {
|
||||
self.populateForm(model);
|
||||
$scope.$watch('domainObject', function(domainObject) {
|
||||
self.populateForm(domainObject.getModel());
|
||||
|
||||
self.listeners.push(self.domainObject.getCapability('mutation').listen(function (model) {
|
||||
self.populateForm(model);
|
||||
}));
|
||||
});
|
||||
|
||||
/**
|
||||
* Maintain a configuration object on scope that stores column
|
||||
* configuration. On change, synchronize with object model.
|
||||
*/
|
||||
$scope.$watchCollection('configuration.table.columns', function (columns){
|
||||
if (columns){
|
||||
self.domainObject.useCapability('mutation', function (model) {
|
||||
@ -67,6 +76,15 @@ define(
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Destroy all mutation listeners
|
||||
*/
|
||||
$scope.$on('$destroy', function () {
|
||||
self.listeners.forEach(function (listener) {
|
||||
listener();
|
||||
});
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
TableOptionsController.prototype.populateForm = function (model) {
|
||||
@ -86,7 +104,7 @@ define(
|
||||
'key': key
|
||||
});
|
||||
});
|
||||
this.$scope.configuration = JSON.parse(JSON.stringify(model.configuration));
|
||||
this.$scope.configuration = JSON.parse(JSON.stringify(model.configuration || {}));
|
||||
};
|
||||
|
||||
return TableOptionsController;
|
||||
|
@ -52,19 +52,15 @@ define(
|
||||
this.$scope = $scope;
|
||||
this.columns = {}; //Range and Domain columns
|
||||
this.handle = undefined;
|
||||
//this.pending = false;
|
||||
this.telemetryHandler = telemetryHandler;
|
||||
this.table = new TableConfiguration($scope.domainObject,
|
||||
telemetryFormatter);
|
||||
this.changeListeners = [];
|
||||
|
||||
$scope.rows = undefined;
|
||||
$scope.rows = [];
|
||||
|
||||
// Subscribe to telemetry when a domain object becomes available
|
||||
this.$scope.$watch('domainObject', function(domainObject){
|
||||
if (!domainObject)
|
||||
return;
|
||||
|
||||
this.$scope.$watch('domainObject', function(){
|
||||
self.subscribe();
|
||||
self.registerChangeListeners();
|
||||
});
|
||||
@ -73,16 +69,24 @@ define(
|
||||
this.$scope.$on("$destroy", this.destroy.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
TelemetryTableController.prototype.unregisterChangeListeners = function () {
|
||||
this.changeListeners.forEach(function (listener) {
|
||||
return listener && listener();
|
||||
});
|
||||
this.changeListeners = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defer registration of change listeners until domain object is
|
||||
* available in order to avoid race conditions
|
||||
* @private
|
||||
*/
|
||||
TelemetryTableController.prototype.registerChangeListeners = function () {
|
||||
this.changeListeners.forEach(function (listener) {
|
||||
return listener && listener();
|
||||
});
|
||||
this.changeListeners = [];
|
||||
this.unregisterChangeListeners();
|
||||
|
||||
// When composition changes, re-subscribe to the various
|
||||
// telemetry subscriptions
|
||||
this.changeListeners.push(this.$scope.$watchCollection(
|
||||
@ -103,25 +107,37 @@ define(
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Function for handling realtime data when it is available. This
|
||||
* will be called by the telemetry framework when new data is
|
||||
* available.
|
||||
*
|
||||
* Method should be overridden by specializing class.
|
||||
*/
|
||||
TelemetryTableController.prototype.addRealtimeData = function () {
|
||||
};
|
||||
|
||||
/**
|
||||
* Function for handling historical data. Will be called by
|
||||
* telemetry framework when requested historical data is available.
|
||||
* Should be overridden by specializing class.
|
||||
*/
|
||||
TelemetryTableController.prototype.addHistoricalData = function () {
|
||||
};
|
||||
|
||||
/**
|
||||
Create a new subscription. This can be overridden by children to
|
||||
change default behaviour (which is to retrieve historical telemetry
|
||||
only).
|
||||
*/
|
||||
TelemetryTableController.prototype.subscribe = function () {
|
||||
var self = this;
|
||||
|
||||
if (this.handle) {
|
||||
this.handle.unsubscribe();
|
||||
}
|
||||
|
||||
//Noop because not supporting realtime data right now
|
||||
function noop(){
|
||||
}
|
||||
|
||||
this.handle = this.$scope.domainObject && this.telemetryHandler.handle(
|
||||
this.$scope.domainObject,
|
||||
noop,
|
||||
this.addRealtimeData.bind(this),
|
||||
true // Lossless
|
||||
);
|
||||
|
||||
@ -130,28 +146,6 @@ define(
|
||||
this.setup();
|
||||
};
|
||||
|
||||
/**
|
||||
* Populates historical data on scope when it becomes available
|
||||
* @private
|
||||
*/
|
||||
TelemetryTableController.prototype.addHistoricalData = function () {
|
||||
var rowData = [],
|
||||
self = this;
|
||||
|
||||
this.handle.getTelemetryObjects().forEach(function (telemetryObject){
|
||||
var series = self.handle.getSeries(telemetryObject) || {},
|
||||
pointCount = series.getPointCount ? series.getPointCount() : 0,
|
||||
i = 0;
|
||||
|
||||
for (; i < pointCount; i++) {
|
||||
rowData.push(self.table.getRowValues(telemetryObject,
|
||||
self.handle.makeDatum(telemetryObject, series, i)));
|
||||
}
|
||||
});
|
||||
|
||||
this.$scope.rows = rowData;
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup table columns based on domain object metadata
|
||||
*/
|
||||
@ -162,7 +156,9 @@ define(
|
||||
|
||||
if (handle) {
|
||||
handle.promiseTelemetryObjects().then(function () {
|
||||
table.buildColumns(handle.getMetadata());
|
||||
self.$scope.headers = []
|
||||
self.$scope.rows = [];
|
||||
table.populateColumns(handle.getMetadata());
|
||||
|
||||
self.filterColumns();
|
||||
|
||||
@ -176,26 +172,14 @@ define(
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param object The object for which data is available (table may
|
||||
* be composed of multiple objects)
|
||||
* @param datum The data received from the telemetry source
|
||||
*/
|
||||
TelemetryTableController.prototype.updateRows = function (object, datum) {
|
||||
this.$scope.rows.push(this.table.getRowValues(object, datum));
|
||||
};
|
||||
|
||||
/**
|
||||
* When column configuration changes, update the visible headers
|
||||
* accordingly.
|
||||
* @private
|
||||
*/
|
||||
TelemetryTableController.prototype.filterColumns = function (columnConfig) {
|
||||
if (!columnConfig){
|
||||
columnConfig = this.table.getColumnConfiguration();
|
||||
this.table.saveColumnConfiguration(columnConfig);
|
||||
}
|
||||
TelemetryTableController.prototype.filterColumns = function () {
|
||||
var columnConfig = this.table.buildColumnConfiguration();
|
||||
|
||||
//Populate headers with visible columns (determined by configuration)
|
||||
this.$scope.headers = Object.keys(columnConfig).filter(function (column) {
|
||||
return columnConfig[column];
|
||||
|
@ -116,10 +116,10 @@ define(
|
||||
}];
|
||||
|
||||
beforeEach(function() {
|
||||
table.buildColumns(metadata);
|
||||
table.populateColumns(metadata);
|
||||
});
|
||||
|
||||
it("populates the columns attribute", function() {
|
||||
it("populates columns", function() {
|
||||
expect(table.columns.length).toBe(5);
|
||||
});
|
||||
|
||||
@ -141,7 +141,7 @@ define(
|
||||
|
||||
it("Provides a default configuration with all columns" +
|
||||
" visible", function() {
|
||||
var configuration = table.getColumnConfiguration();
|
||||
var configuration = table.buildColumnConfiguration();
|
||||
|
||||
expect(configuration).toBeDefined();
|
||||
expect(Object.keys(configuration).every(function(key){
|
||||
@ -160,7 +160,7 @@ define(
|
||||
};
|
||||
mockModel.configuration = modelConfig;
|
||||
|
||||
tableConfig = table.getColumnConfiguration();
|
||||
tableConfig = table.buildColumnConfiguration();
|
||||
|
||||
expect(tableConfig).toBeDefined();
|
||||
expect(tableConfig['Range 1']).toBe(false);
|
||||
@ -191,6 +191,9 @@ define(
|
||||
expect(mockTelemetryFormatter.formatRangeValue).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
/**
|
||||
* TODO: Add test for saving column config
|
||||
*/
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
define(
|
||||
[
|
||||
"../../src/controllers/TelemetryTableController"
|
||||
"../../src/controllers/HistoricalTableController"
|
||||
],
|
||||
function (TableController) {
|
||||
"use strict";
|
||||
@ -73,14 +73,14 @@ define(
|
||||
|
||||
mockTable = jasmine.createSpyObj('table',
|
||||
[
|
||||
'buildColumns',
|
||||
'getColumnConfiguration',
|
||||
'populateColumns',
|
||||
'buildColumnConfiguration',
|
||||
'getRowValues',
|
||||
'saveColumnConfiguration'
|
||||
]
|
||||
);
|
||||
mockTable.columns = [];
|
||||
mockTable.getColumnConfiguration.andReturn(mockConfiguration);
|
||||
mockTable.buildColumnConfiguration.andReturn(mockConfiguration);
|
||||
|
||||
mockDomainObject= jasmine.createSpyObj('domainObject', [
|
||||
'getCapability',
|
||||
@ -126,21 +126,18 @@ define(
|
||||
expect(mockTelemetryHandle.unsubscribe).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('the controller makes use of the table', function () {
|
||||
describe('makes use of the table', function () {
|
||||
|
||||
it('to create column definitions from telemetry' +
|
||||
' metadata', function () {
|
||||
controller.setup();
|
||||
expect(mockTable.buildColumns).toHaveBeenCalled();
|
||||
expect(mockTable.populateColumns).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('to create column configuration, which is written to the' +
|
||||
' object model', function () {
|
||||
var mockModel = {};
|
||||
|
||||
controller.setup();
|
||||
expect(mockTable.getColumnConfiguration).toHaveBeenCalled();
|
||||
expect(mockTable.saveColumnConfiguration).toHaveBeenCalled();
|
||||
expect(mockTable.buildColumnConfiguration).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
@ -118,7 +118,7 @@ define(
|
||||
});
|
||||
|
||||
it('Sets rows on scope when rows change', function() {
|
||||
controller.updateRows(testRows);
|
||||
controller.setRows(testRows);
|
||||
expect(mockScope.displayRows.length).toBe(3);
|
||||
expect(mockScope.displayRows).toEqual(testRows);
|
||||
});
|
||||
@ -130,7 +130,7 @@ define(
|
||||
'col2': {'text': 'ghi'},
|
||||
'col3': {'text': 'row3 col3'}
|
||||
};
|
||||
controller.updateRows(testRows);
|
||||
controller.setRows(testRows);
|
||||
expect(mockScope.displayRows.length).toBe(3);
|
||||
testRows.push(row4);
|
||||
addRowFunc(undefined, 3);
|
||||
@ -139,7 +139,7 @@ define(
|
||||
|
||||
it('Supports removing rows individually', function() {
|
||||
var removeRowFunc = mockScope.$on.calls[mockScope.$on.calls.length-1].args[1];
|
||||
controller.updateRows(testRows);
|
||||
controller.setRows(testRows);
|
||||
expect(mockScope.displayRows.length).toBe(3);
|
||||
removeRowFunc(undefined, 2);
|
||||
expect(mockScope.displayRows.length).toBe(2);
|
||||
@ -211,20 +211,20 @@ define(
|
||||
mockScope.displayRows = controller.sortRows(testRows.slice(0));
|
||||
|
||||
mockScope.rows.push(row4);
|
||||
controller.newRow(undefined, mockScope.rows.length-1);
|
||||
controller.addRow(undefined, mockScope.rows.length-1);
|
||||
expect(mockScope.displayRows[0].col2.text).toEqual('xyz');
|
||||
|
||||
mockScope.rows.push(row5);
|
||||
controller.newRow(undefined, mockScope.rows.length-1);
|
||||
controller.addRow(undefined, mockScope.rows.length-1);
|
||||
expect(mockScope.displayRows[4].col2.text).toEqual('aaa');
|
||||
|
||||
mockScope.rows.push(row6);
|
||||
controller.newRow(undefined, mockScope.rows.length-1);
|
||||
controller.addRow(undefined, mockScope.rows.length-1);
|
||||
expect(mockScope.displayRows[2].col2.text).toEqual('ggg');
|
||||
|
||||
//Add a duplicate row
|
||||
mockScope.rows.push(row6);
|
||||
controller.newRow(undefined, mockScope.rows.length-1);
|
||||
controller.addRow(undefined, mockScope.rows.length-1);
|
||||
expect(mockScope.displayRows[2].col2.text).toEqual('ggg');
|
||||
expect(mockScope.displayRows[3].col2.text).toEqual('ggg');
|
||||
});
|
||||
@ -240,12 +240,12 @@ define(
|
||||
mockScope.displayRows = controller.filterRows(testRows);
|
||||
|
||||
mockScope.rows.push(row5);
|
||||
controller.newRow(undefined, mockScope.rows.length-1);
|
||||
controller.addRow(undefined, mockScope.rows.length-1);
|
||||
expect(mockScope.displayRows.length).toBe(2);
|
||||
expect(mockScope.displayRows[1].col2.text).toEqual('aaa');
|
||||
|
||||
mockScope.rows.push(row6);
|
||||
controller.newRow(undefined, mockScope.rows.length-1);
|
||||
controller.addRow(undefined, mockScope.rows.length-1);
|
||||
expect(mockScope.displayRows.length).toBe(2);
|
||||
//Row was not added because does not match filter
|
||||
});
|
||||
@ -259,11 +259,11 @@ define(
|
||||
mockScope.displayRows = testRows.slice(0);
|
||||
|
||||
mockScope.rows.push(row5);
|
||||
controller.newRow(undefined, mockScope.rows.length-1);
|
||||
controller.addRow(undefined, mockScope.rows.length-1);
|
||||
expect(mockScope.displayRows[3].col2.text).toEqual('aaa');
|
||||
|
||||
mockScope.rows.push(row6);
|
||||
controller.newRow(undefined, mockScope.rows.length-1);
|
||||
controller.addRow(undefined, mockScope.rows.length-1);
|
||||
expect(mockScope.displayRows[4].col2.text).toEqual('ggg');
|
||||
});
|
||||
|
||||
@ -282,7 +282,7 @@ define(
|
||||
mockScope.displayRows = testRows.slice(0);
|
||||
|
||||
mockScope.rows.push(row7);
|
||||
controller.newRow(undefined, mockScope.rows.length-1);
|
||||
controller.addRow(undefined, mockScope.rows.length-1);
|
||||
expect(controller.$scope.sizingRow.col2).toEqual({text: 'some longer string'});
|
||||
});
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
define(
|
||||
[
|
||||
"../../src/controllers/RTTelemetryTableController"
|
||||
"../../src/controllers/RealtimeTableController"
|
||||
],
|
||||
function (TableController) {
|
||||
"use strict";
|
||||
@ -77,14 +77,14 @@ define(
|
||||
|
||||
mockTable = jasmine.createSpyObj('table',
|
||||
[
|
||||
'buildColumns',
|
||||
'getColumnConfiguration',
|
||||
'populateColumns',
|
||||
'buildColumnConfiguration',
|
||||
'getRowValues',
|
||||
'saveColumnConfiguration'
|
||||
]
|
||||
);
|
||||
mockTable.columns = [];
|
||||
mockTable.getColumnConfiguration.andReturn(mockConfiguration);
|
||||
mockTable.buildColumnConfiguration.andReturn(mockConfiguration);
|
||||
mockTable.getRowValues.andReturn(mockTableRow);
|
||||
|
||||
mockDomainObject= jasmine.createSpyObj('domainObject', [
|
||||
@ -107,13 +107,16 @@ define(
|
||||
'unsubscribe',
|
||||
'getDatum',
|
||||
'promiseTelemetryObjects',
|
||||
'getTelemetryObjects'
|
||||
'getTelemetryObjects',
|
||||
'request'
|
||||
]);
|
||||
|
||||
// Arbitrary array with non-zero length, contents are not
|
||||
// used by mocks
|
||||
mockTelemetryHandle.getTelemetryObjects.andReturn([{}]);
|
||||
mockTelemetryHandle.promiseTelemetryObjects.andReturn(promise(undefined));
|
||||
mockTelemetryHandle.getDatum.andReturn({});
|
||||
mockTelemetryHandle.request.andReturn(promise(undefined));
|
||||
|
||||
mockTelemetryHandler = jasmine.createSpyObj('telemetryHandler', [
|
||||
'handle'
|
@ -47,11 +47,16 @@ define(
|
||||
'listen'
|
||||
]);
|
||||
mockDomainObject = jasmine.createSpyObj('domainObject', [
|
||||
'getCapability'
|
||||
'getCapability',
|
||||
'getModel'
|
||||
]);
|
||||
mockDomainObject.getCapability.andReturn(mockCapability);
|
||||
mockDomainObject.getModel.andReturn({});
|
||||
|
||||
mockScope = jasmine.createSpyObj('scope', [
|
||||
'$watchCollection'
|
||||
'$watchCollection',
|
||||
'$watch',
|
||||
'$on'
|
||||
]);
|
||||
mockScope.domainObject = mockDomainObject;
|
||||
|
||||
@ -59,6 +64,7 @@ define(
|
||||
});
|
||||
|
||||
it('Registers a listener for mutation events on the object', function() {
|
||||
mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
|
||||
expect(mockCapability.listen).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user