blob: 699aad13f7098836c4630a945ebd7d99935917f6 [file] [log] [blame]
Bri Prebilic Cole093739a2015-01-23 10:22:50 -08001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 ONOS GUI -- Widget -- Table Service
19 */
20(function () {
21 'use strict';
22
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070023 // injected refs
Bri Prebilic Cole264c5ec2015-04-07 10:22:26 -070024 var $log, $window, fs, mast, is;
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070025
26 // constants
27 var tableIconTdSize = 33,
Bri Prebilic Cole264c5ec2015-04-07 10:22:26 -070028 mastPdg = 8,
29 h2Pdg = 40,
30 thPdg = 12,
31 tbodyPdg = 5,
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070032 colWidth = 'col-width',
33 tableIcon = 'table-icon';
34
35 // internal state
36 var currCol = {},
37 prevCol = {};
Bri Prebilic Cole093739a2015-01-23 10:22:50 -080038
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080039 // Functions for creating a fixed header on a table (Angular Directive)
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080040
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070041 function setElemWidth(elem, size) {
42 elem.style('width', size + 'px')
43 }
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080044
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070045 function setColWidth(th, td, size) {
46 setElemWidth(th, size);
47 setElemWidth(td, size);
48 }
Thomas Vachuska0fa583c2015-03-30 23:07:41 -070049
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070050 // count number of headers of
51 // - assigned width,
52 // - icon width,
53 // - and default width
54 // assumes assigned width is not given to icons
Bri Prebilic Cole264c5ec2015-04-07 10:22:26 -070055 // returns the width of all columns that are not icons
56 // or have an assigned width
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070057 function getDefaultWidth(headers) {
58 var winWidth = fs.windowSize().width,
59 iconCols = 0,
60 regCols = 0,
61 cstmColWidth = 0;
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080062
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070063 headers.each(function (d, i) {
64 var thElement = d3.select(this),
65 cstmWidth = thElement.attr(colWidth);
66
67 if (cstmWidth) {
68 cstmColWidth += fs.noPx(cstmWidth);
69 } else if (thElement.classed(tableIcon)) {
70 iconCols += 1;
Thomas Vachuska0fa583c2015-03-30 23:07:41 -070071 } else {
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070072 regCols += 1;
Thomas Vachuska0fa583c2015-03-30 23:07:41 -070073 }
74 });
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080075
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070076 return Math.floor((winWidth - cstmColWidth -
77 (iconCols * tableIconTdSize)) / regCols);
78 }
Thomas Vachuska0fa583c2015-03-30 23:07:41 -070079
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070080 function setTableWidth(t) {
81 var tHeaders = t.selectAll('th'),
82 defaultColWidth = getDefaultWidth(tHeaders);
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080083
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070084 tHeaders.each(function (d, i) {
85 var thElement = d3.select(this),
86 tdElement = t.select('td:nth-of-type(' + (i + 1) + ')'),
87 custWidth = thElement.attr(colWidth);
88
89 if (custWidth) {
90 setColWidth(thElement, tdElement, fs.noPx(custWidth));
91 } else if (thElement.classed(tableIcon)) {
92 setColWidth(thElement, tdElement, tableIconTdSize);
Bri Prebilic Cole357f7fd2015-02-12 17:03:42 -080093 } else {
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070094 setColWidth(thElement, tdElement, defaultColWidth);
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080095 }
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080096 });
97 }
98
Bri Prebilic Cole264c5ec2015-04-07 10:22:26 -070099 // get the size of the window and then subtract the extra space at the top
100 // to get the height of the table
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800101 function setTableHeight(thead, tbody) {
Bri Prebilic Cole264c5ec2015-04-07 10:22:26 -0700102 var titleHeight = h2Pdg + fs.noPxStyle(d3.select('h2'), 'height'),
103 thHeight = thPdg + fs.noPxStyle(d3.select('th'), 'height'),
104 totalHeight = titleHeight + thHeight + tbodyPdg + mastPdg,
105 tableHeight = fs.windowSize(mast.mastHeight() + totalHeight).height;
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800106
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800107 thead.style('display', 'block');
108 tbody.style({'display': 'block',
Bri Prebilic Cole264c5ec2015-04-07 10:22:26 -0700109 'height': (tableHeight + 'px'),
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800110 'overflow': 'auto'
111 });
112 }
113
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800114 function fixTable(t, th, tb) {
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800115 setTableWidth(t);
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800116 setTableHeight(th, tb);
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800117 }
118
Bri Prebilic Colee1bda3f2015-02-13 17:01:49 -0800119 // Functions for sorting table rows by header and choosing appropriate icon
120
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800121 function updateSortingIcons(thElem, api) {
Bri Prebilic Colee1bda3f2015-02-13 17:01:49 -0800122 var div;
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800123 currCol.colId = thElem.attr('colId');
124
125 if (currCol.colId === prevCol.colId) {
126 (currCol.icon === 'tableColSortDesc') ?
127 currCol.icon = 'tableColSortAsc' :
128 currCol.icon = 'tableColSortDesc';
129 prevCol.icon = currCol.icon;
130 } else {
131 currCol.icon = 'tableColSortAsc';
132 prevCol.icon = 'tableColSortNone';
133 }
134
135 div = thElem.select('div');
Bri Prebilic Colee1bda3f2015-02-13 17:01:49 -0800136 api.sortNone(div);
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800137 div = thElem.append('div');
138
139 if (currCol.icon === 'tableColSortAsc') {
140 api.sortAsc(div);
141 } else {
142 api.sortDesc(div);
143 }
144
145 if (prevCol.colId !== undefined &&
146 prevCol.icon === 'tableColSortNone') {
147 api.sortNone(prevCol.elem.select('div'));
148 }
149
150 prevCol.colId = currCol.colId;
151 prevCol.elem = thElem;
152 }
153
Bri Prebilic Cole19a32dd2015-03-26 18:00:03 -0700154 function sortRequestParams() {
155 return {
156 sortCol: currCol.colId,
157 sortDir: (currCol.icon === 'tableColSortAsc' ? 'asc' : 'desc')
158 };
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800159 }
160
Bri Prebilic Cole093739a2015-01-23 10:22:50 -0800161 angular.module('onosWidget')
Bri Prebilic Cole264c5ec2015-04-07 10:22:26 -0700162 .directive('onosFixedHeader', ['$window', 'FnService', 'MastService',
163 function (_$window_, _fs_, _mast_) {
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800164 return function (scope, element) {
165 $window = _$window_;
166 fs = _fs_;
Bri Prebilic Cole264c5ec2015-04-07 10:22:26 -0700167 mast = _mast_;
168
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800169 var w = angular.element($window),
Bri Prebilic Coleb0e66be2015-02-10 10:53:15 -0800170 table = d3.select(element[0]),
Bri Prebilic Cole7c445752015-02-17 14:49:46 -0800171 thead = table.select('thead'),
172 tbody = table.select('tbody'),
173 canAdjust = false;
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800174
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800175 scope.$watch(function () {
176 return {
177 h: window.innerHeight,
178 w: window.innerWidth
179 };
180 }, function (newVal) {
Simon Hunt0c2c4c52015-04-02 17:42:45 -0700181 var wsz = fs.windowSize(0, 30);
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800182 scope.windowHeight = newVal.h;
183 scope.windowWidth = newVal.w;
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800184
Simon Hunt0c2c4c52015-04-02 17:42:45 -0700185 // default table size in case no data elements
186 table.style('width', wsz.width + 'px');
187
Bri Prebilic Cole7c445752015-02-17 14:49:46 -0800188 scope.$on('LastElement', function () {
189 // only adjust the table once it's completely loaded
190 fixTable(table, thead, tbody);
191 canAdjust = true;
192 });
Bri Prebilic Coleb0e66be2015-02-10 10:53:15 -0800193
Bri Prebilic Cole7c445752015-02-17 14:49:46 -0800194 if (canAdjust) {
Bri Prebilic Coleb0e66be2015-02-10 10:53:15 -0800195 fixTable(table, thead, tbody);
196 }
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800197 }, true);
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800198
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800199 w.bind('onos-fixed-header', function () {
200 scope.$apply();
201 });
202 };
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800203 }])
204
205 .directive('onosSortableHeader', ['$log', 'IconService',
206 function (_$log_, _is_) {
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800207 return {
208 scope: {
209 ctrlCallback: '&sortCallback'
210 },
Bri Prebilic Colee1bda3f2015-02-13 17:01:49 -0800211 link: function (scope, element) {
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800212 $log = _$log_;
213 is = _is_;
214 var table = d3.select(element[0]),
215 sortIconAPI = is.createSortIcon();
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800216
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800217 // when a header is clicked, change its icon tag
218 // and get sorting order to send to the server.
219 table.selectAll('th').on('click', function () {
220 var thElem = d3.select(this);
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800221
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800222 if (thElem.attr('sortable') === '') {
223 updateSortingIcons(thElem, sortIconAPI);
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800224 scope.ctrlCallback({
Bri Prebilic Cole72eb6db2015-03-30 16:58:53 -0700225 requestParams: sortRequestParams()
226 });
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800227 }
228 });
229 }
230 };
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800231 }]);
Bri Prebilic Cole093739a2015-01-23 10:22:50 -0800232
233}());