diff --git a/platform/features/table/src/controllers/MCTTableController.js b/platform/features/table/src/controllers/MCTTableController.js index ef797a42a5..ad13647766 100644 --- a/platform/features/table/src/controllers/MCTTableController.js +++ b/platform/features/table/src/controllers/MCTTableController.js @@ -74,6 +74,7 @@ define( * Listen for rows added individually (eg. for real-time tables) */ $scope.$on('add:row', this.newRow.bind(this)); + $scope.$on('remove:row', this.removeRow.bind(this)); } /** @@ -109,6 +110,22 @@ define( .then(this.scrollToBottom.bind(this)); }; + /** + * Handles a row add event. Rows can be added as needed using the + * `addRow` broadcast event. + * @private + */ + MCTTableController.prototype.removeRow = function (event, rowIndex) { + var row = this.$scope.rows[rowIndex], + // Do a sequential search here. Only way of finding row is by + // object equality, so array is in effect unsorted. + indexInDisplayRows = this.$scope.displayRows.indexOf(row); + if (indexInDisplayRows != -1) { + this.$scope.displayRows.splice(indexInDisplayRows, 1); + this.setVisibleRows(); + } + }; + /** * @private */ @@ -287,7 +304,7 @@ define( parseFloat(searchElement[sortKey].text); valB = isNaN(searchArray[sampleAt][sortKey].text) ? searchArray[sampleAt][sortKey].text : - searchArray[sampleAt][sortKey].text; + parseFloat(searchArray[sampleAt][sortKey].text); switch(self.sortComparator(valA, valB)) { case -1: diff --git a/platform/features/table/src/controllers/RTTelemetryTableController.js b/platform/features/table/src/controllers/RTTelemetryTableController.js index 10bd62db28..8a61d61b5e 100644 --- a/platform/features/table/src/controllers/RTTelemetryTableController.js +++ b/platform/features/table/src/controllers/RTTelemetryTableController.js @@ -41,6 +41,7 @@ define( TableController.call(this, $scope, telemetryHandler, telemetryFormatter); $scope.autoScroll = false; + this.maxRows = 100000; /* * Determine if auto-scroll should be enabled. Is enabled @@ -94,6 +95,12 @@ define( 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); } diff --git a/platform/features/table/test/controllers/MCTTableControllerSpec.js b/platform/features/table/test/controllers/MCTTableControllerSpec.js index 44cb5f1f8f..5e38c7e651 100644 --- a/platform/features/table/test/controllers/MCTTableControllerSpec.js +++ b/platform/features/table/test/controllers/MCTTableControllerSpec.js @@ -121,7 +121,7 @@ define( }); it('Supports adding rows individually', function() { - var addRowFunc = mockScope.$on.mostRecentCall.args[1], + var addRowFunc = mockScope.$on.calls[mockScope.$on.calls.length-2].args[1], row4 = { 'col1': {'text': 'row3 col1'}, 'col2': {'text': 'ghi'}, @@ -130,10 +130,21 @@ define( controller.updateRows(testRows); expect(mockScope.displayRows.length).toBe(3); testRows.push(row4); - addRowFunc(3); + addRowFunc(undefined, 3); expect(mockScope.displayRows.length).toBe(4); }); + it('Supports removing rows individually', function() { + var removeRowFunc = mockScope.$on.calls[mockScope.$on.calls.length-1].args[1]; + controller.updateRows(testRows); + expect(mockScope.displayRows.length).toBe(3); + spyOn(controller, 'setVisibleRows'); + //controller.setVisibleRows.andReturn(undefined); + removeRowFunc(undefined, 2); + expect(mockScope.displayRows.length).toBe(2); + expect(controller.setVisibleRows).toHaveBeenCalled(); + }); + describe('sorting', function() { var sortedRows; diff --git a/platform/features/table/test/controllers/RTTelemetryTableControllerSpec.js b/platform/features/table/test/controllers/RTTelemetryTableControllerSpec.js index d9823797fb..0900dfdfb2 100644 --- a/platform/features/table/test/controllers/RTTelemetryTableControllerSpec.js +++ b/platform/features/table/test/controllers/RTTelemetryTableControllerSpec.js @@ -130,11 +130,29 @@ define( expect(mockTelemetryHandler.handle).toHaveBeenCalledWith(jasmine.any(Object), jasmine.any(Function), true); }); - it('updates table with new streaming telemetry', function () { - controller.subscribe(); - mockScope.rows = []; - mockTelemetryHandler.handle.mostRecentCall.args[1](); - expect(mockScope.$broadcast).toHaveBeenCalledWith('add:row', 0); + describe('receives new telemetry', function() { + beforeEach(function() { + controller.subscribe(); + mockScope.rows = []; + }); + + it('updates table with new streaming telemetry', function () { + mockTelemetryHandler.handle.mostRecentCall.args[1](); + expect(mockScope.$broadcast).toHaveBeenCalledWith('add:row', 0); + }); + it('observes the row limit', function () { + var i=0; + controller.maxRows = 10; + + //Fill rows array with elements + for (; i < 10; i++) { + mockScope.rows.push({row: i}); + } + mockTelemetryHandler.handle.mostRecentCall.args[1](); + expect(mockScope.rows.length).toBe(controller.maxRows); + expect(mockScope.rows[mockScope.rows.length-1]).toBe(mockTableRow); + expect(mockScope.rows[0].row).toBe(1); + }); }); it('enables autoscroll for event telemetry', function () {