blob: caacab408263d98b6ad1273dfead0ed0b0e1a18f [file] [log] [blame]
/*
* Copyright 2015 Open Networking Laboratory
*
* 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.
*/
/*
ONOS GUI -- Widget -- Table Service
*/
(function () {
'use strict';
// injected refs
var $log, $window, fs, mast, is;
// constants
var tableIconTdSize = 33,
pdg = 12,
colWidth = 'col-width',
tableIcon = 'table-icon',
asc = 'asc',
desc = 'desc',
none = 'none';
// internal state
var currCol = {},
prevCol = {},
sortIconAPI;
// Functions for creating a scrolling table body with fixed table header
function _width(elem, width) {
elem.style('width', width);
}
function defaultSize(table, width) {
var thead = table.select('.table-header').select('table'),
tbody = table.select('.table-body').select('table'),
wpx = width + 'px';
_width(thead, wpx);
_width(tbody, wpx);
}
function adjustTable(table, width, height) {
var thead = table.select('.table-header').select('table'),
tbodyDiv = table.select('.table-body'),
tbody = tbodyDiv.select('table'),
cstmWidths = {};
function findCstmWidths() {
var headers = thead.selectAll('td');
headers.each(function (d, i) {
var h = d3.select(this),
index = i.toString();
if (h.classed(tableIcon)) {
cstmWidths[index] = tableIconTdSize + 'px';
}
if (h.attr(colWidth)) {
cstmWidths[index] = h.attr(colWidth);
}
});
$log.debug('Headers with custom widths: ', cstmWidths);
}
function setTdWidths(elem) {
var tds = elem.selectAll('tr:not(.ignore-width)').selectAll('td');
_width(elem, width + 'px');
tds.each(function (d, i) {
var td = d3.select(this),
index = i.toString();
if (cstmWidths.hasOwnProperty(index)) {
_width(td, cstmWidths[index]);
}
});
}
function setHeight(body) {
var h = height - (mast.mastHeight() +
fs.noPxStyle(d3.select('.tabular-header'), 'height') +
fs.noPxStyle(thead, 'height') + pdg);
body.style('height', h + 'px');
}
findCstmWidths();
setTdWidths(thead);
setTdWidths(tbody);
setHeight(tbodyDiv);
cstmWidths = {};
}
// Functions for sorting table rows by header
function updateSortDirection(thElem) {
sortIconAPI.sortNone(thElem.select('div'));
currCol.div = thElem.append('div');
currCol.colId = thElem.attr('colId');
if (currCol.colId === prevCol.colId) {
(currCol.dir === desc) ? currCol.dir = asc : currCol.dir = desc;
prevCol.dir = currCol.dir;
} else {
currCol.dir = asc;
prevCol.dir = none;
}
(currCol.dir === asc) ?
sortIconAPI.sortAsc(currCol.div) : sortIconAPI.sortDesc(currCol.div);
if (prevCol.colId && prevCol.dir === none) {
sortIconAPI.sortNone(prevCol.div);
}
prevCol.colId = currCol.colId;
prevCol.div = currCol.div;
}
function sortRequestParams() {
return {
sortCol: currCol.colId,
sortDir: currCol.dir
};
}
function resetSortIcons() {
if (currCol.div) {
sortIconAPI.sortNone(currCol.div);
}
if (prevCol.div) {
sortIconAPI.sortNone(prevCol.div);
}
currCol = {};
prevCol = {};
}
angular.module('onosWidget')
.directive('onosFixedHeader', ['$log','$window',
'FnService', 'MastService',
function (_$log_, _$window_, _fs_, _mast_) {
return function (scope, element) {
$log = _$log_;
$window = _$window_;
fs = _fs_;
mast = _mast_;
var w = angular.element($window),
table = d3.select(element[0]),
canAdjust = false;
scope.$watch(function () {
return {
h: $window.innerHeight,
w: $window.innerWidth
};
}, function () {
var wsz = fs.windowSize(0, 30),
wWidth = wsz.width,
wHeight = wsz.height;
if (!scope.tableData.length) {
defaultSize(table, wWidth);
}
scope.$on('LastElement', function () {
// only adjust the table once it's completely loaded
adjustTable(table, wWidth, wHeight);
canAdjust = true;
});
if (canAdjust) {
adjustTable(table, wWidth, wHeight);
}
}, true);
w.bind('onos-fixed-header', function () {
scope.$apply();
});
};
}])
.directive('onosSortableHeader', ['$log', 'IconService',
function (_$log_, _is_) {
return {
scope: {
ctrlCallback: '&sortCallback'
},
link: function (scope, element) {
$log = _$log_;
is = _is_;
var header = d3.select(element[0]);
sortIconAPI = is.sortIcons();
// when a header is clicked, change its sort direction
// and get sorting order to send to the server.
header.selectAll('td').on('click', function () {
var col = d3.select(this);
if (col.attr('sortable') === '') {
updateSortDirection(col);
scope.ctrlCallback({
requestParams: sortRequestParams()
});
}
});
}
};
}])
.factory('TableService', ['IconService',
function (is) {
sortIconAPI = is.sortIcons();
return {
resetSortIcons: resetSortIcons
};
}]);
}());