Bri Prebilic Cole

GUI -- onos-sortable-header will get the controller to use the restService to up…

…date the table data. Query parameters were created based on colId and sort direction.

Change-Id: I27bc6ebab9f8f1ba332b4480171b8afc3a4fd3c4
......@@ -21,8 +21,12 @@
'use strict';
var $log, $window, fs, is,
div,
currCol = {},
prevCol = {},
bottomMargin = 200;
// Render a plain d3 table by giving it the div, a config file, and data
function renderTable(div, config, data) {
......@@ -106,6 +110,50 @@
setTableHeight(th, tb);
}
function updateSortingIcons(thElem, api) {
currCol.colId = thElem.attr('colId');
if (currCol.colId === prevCol.colId) {
(currCol.icon === 'tableColSortDesc') ?
currCol.icon = 'tableColSortAsc' :
currCol.icon = 'tableColSortDesc';
prevCol.icon = currCol.icon;
} else {
currCol.icon = 'tableColSortAsc';
prevCol.icon = 'tableColSortNone';
}
div = thElem.select('div');
div.remove();
div = thElem.append('div');
if (currCol.icon === 'tableColSortAsc') {
api.sortAsc(div);
} else {
api.sortDesc(div);
}
if (prevCol.colId !== undefined &&
prevCol.icon === 'tableColSortNone') {
api.sortNone(prevCol.elem.select('div'));
}
prevCol.colId = currCol.colId;
prevCol.elem = thElem;
}
function generateQueryParams() {
var queryString = '?sortCol=' + currCol.colId + '&sortDir=';
if(currCol.icon === 'tableColSortAsc') {
queryString = queryString + 'asc';
} else {
queryString = queryString + 'desc';
}
return queryString;
}
angular.module('onosWidget')
.factory('TableService', [function () {
return {
......@@ -158,66 +206,31 @@
.directive('onosSortableHeader', ['$log', 'IconService',
function (_$log_, _is_) {
return function (scope, element, attrs) {
$log = _$log_;
is = _is_;
var table = d3.select(element[0]),
currCol = {},
prevCol = {},
sortIconAPI = is.createSortIcon();
// when a header is clicked, change its icon tag and get sorting
// order to send to the server.
table.selectAll('th').on('click', function () {
var thElem = d3.select(this),
div;
currCol.colId = thElem.attr('colId');
if (currCol.colId === prevCol.colId) {
(currCol.icon === 'tableColSortDesc') ?
currCol.icon = 'tableColSortAsc' :
currCol.icon = 'tableColSortDesc';
prevCol.icon = currCol.icon;
} else {
currCol.icon = 'tableColSortAsc';
prevCol.icon = 'tableColSortNone';
}
$log.debug('currCol clicked: ' + currCol.colId +
', with sorting icon: ' + currCol.icon);
$log.debug('prevCol clicked: ' + prevCol.colId +
', with its current sorting icon as ' + prevCol.icon);
div = thElem.select('div');
div.remove();
div = thElem.append('div');
if (currCol.icon === 'tableColSortAsc') {
sortIconAPI.sortAsc(div);
} else {
sortIconAPI.sortDesc(div);
}
if (prevCol.colId !== undefined &&
prevCol.icon === 'tableColSortNone') {
sortIconAPI.sortNone(prevCol.elem.select('div'));
}
prevCol.colId = currCol.colId;
prevCol.elem = thElem;
});
// TODO: send the prev and currCol info to the server to use in sorting table
// TODO: figure out timing of events:
// updating the icon
// sending the column sorting info to the server
// refreshing the table so that the new rows will be sorted
}
return {
scope: {
ctrlCallback: '&sortCallback'
},
link: function (scope, element, attrs) {
$log = _$log_;
is = _is_;
var table = d3.select(element[0]),
sortIconAPI = is.createSortIcon();
// when a header is clicked, change its icon tag
// and get sorting order to send to the server.
table.selectAll('th').on('click', function () {
var thElem = d3.select(this);
if (thElem.attr('sortable') === '') {
updateSortingIcons(thElem, sortIconAPI);
// call the ctrl's rest callback function
scope.ctrlCallback({
urlSuffix: generateQueryParams()
});
}
});
}
};
}]);
}());
......
......@@ -5,7 +5,7 @@
onos-fixed-header
ng-style="setTableHW()"
onos-sortable-header
sort-callback="ctrl.sortCallback()">
sort-callback="sortCallback(urlSuffix)">
<thead>
<tr>
<th colId="available"></th>
......
......@@ -22,8 +22,8 @@
'use strict';
angular.module('ovDevice', [])
.controller('OvDeviceCtrl', ['$log', '$location', 'RestService',
function ($log, $location, rs) {
.controller('OvDeviceCtrl', ['$log', '$scope', '$location', 'RestService',
function ($log, $scope, $location, rs) {
var self = this;
self.deviceData = [];
......@@ -31,9 +31,17 @@
var testCase = $location.search().test;
var url = testCase ? 'test/' + testCase : 'device';
rs.get(url, function (data) {
self.deviceData = data.devices;
});
$scope.sortCallback = function (urlSuffix) {
if (!urlSuffix) {
urlSuffix = '';
}
url = 'device' + urlSuffix;
rs.get(url, function (data) {
self.deviceData = data.devices;
});
};
$scope.sortCallback();
$log.log('OvDeviceCtrl has been created');
}]);
......
......@@ -64,7 +64,7 @@ describe('factory: fw/layer/flash.js', function () {
text = item.select('text');
expect(text.size()).toEqual(1);
expect(text.text()).toEqual('foo');
}, 500);
}, 2000);
});
// TODO: testing these time-sensitive behaviors is hard...
......
......@@ -21,7 +21,7 @@ describe('Controller: OvDeviceCtrl', function () {
// instantiate the Device module
beforeEach(module('ovDevice', 'onosRemote'));
var $log, $controller, ctrl, $mockHttp;
var $log, $scope, $controller, ctrl, $mockHttp;
var fakeData = {
"devices": [{
......@@ -40,17 +40,21 @@ describe('Controller: OvDeviceCtrl', function () {
}]
};
beforeEach(inject(function(_$log_, _$controller_, $httpBackend) {
beforeEach(inject(function(_$log_, $rootScope, _$controller_, $httpBackend) {
$log = _$log_;
$scope = $rootScope.$new();
$controller = _$controller_;
$mockHttp = $httpBackend;
$mockHttp.whenGET(/\/device$/).respond(fakeData);
}));
it('should be an empty array', function () {
ctrl = $controller('OvDeviceCtrl');
it('should be an empty array and then have device data', function () {
ctrl = $controller('OvDeviceCtrl', {
$scope: $scope
});
expect(ctrl.deviceData).toEqual([]);
$scope.sortCallback();
$mockHttp.flush();
expect(ctrl.deviceData).toEqual(fakeData.devices);
});
......