blob: d9fdddadc8314cab290cc8bc8c64a1775a125a42 [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 Cole45069382015-04-14 15:21:38 -070028 pdg = 12,
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070029 colWidth = 'col-width',
Bri Prebilic Cole3d4d01c2015-04-30 13:48:36 -070030 tableIcon = 'table-icon',
31 asc = 'asc',
32 desc = 'desc',
33 none = 'none';
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070034
35 // internal state
36 var currCol = {},
Bri Prebilic Cole3d4d01c2015-04-30 13:48:36 -070037 prevCol = {},
38 sortIconAPI;
Bri Prebilic Cole093739a2015-01-23 10:22:50 -080039
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080040 // Functions for creating a fixed header on a table (Angular Directive)
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080041
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070042 function setElemWidth(elem, size) {
43 elem.style('width', size + 'px')
44 }
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080045
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070046 function setColWidth(th, td, size) {
47 setElemWidth(th, size);
48 setElemWidth(td, size);
49 }
Thomas Vachuska0fa583c2015-03-30 23:07:41 -070050
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070051 // count number of headers of
52 // - assigned width,
53 // - icon width,
54 // - and default width
55 // assumes assigned width is not given to icons
Bri Prebilic Cole264c5ec2015-04-07 10:22:26 -070056 // returns the width of all columns that are not icons
57 // or have an assigned width
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070058 function getDefaultWidth(headers) {
59 var winWidth = fs.windowSize().width,
60 iconCols = 0,
61 regCols = 0,
62 cstmColWidth = 0;
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080063
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070064 headers.each(function (d, i) {
65 var thElement = d3.select(this),
66 cstmWidth = thElement.attr(colWidth);
67
68 if (cstmWidth) {
69 cstmColWidth += fs.noPx(cstmWidth);
70 } else if (thElement.classed(tableIcon)) {
71 iconCols += 1;
Thomas Vachuska0fa583c2015-03-30 23:07:41 -070072 } else {
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070073 regCols += 1;
Thomas Vachuska0fa583c2015-03-30 23:07:41 -070074 }
75 });
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080076
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070077 return Math.floor((winWidth - cstmColWidth -
78 (iconCols * tableIconTdSize)) / regCols);
79 }
Thomas Vachuska0fa583c2015-03-30 23:07:41 -070080
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070081 function setTableWidth(t) {
82 var tHeaders = t.selectAll('th'),
83 defaultColWidth = getDefaultWidth(tHeaders);
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080084
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070085 tHeaders.each(function (d, i) {
86 var thElement = d3.select(this),
Bri Prebilic Cole384e8dc2015-04-13 15:51:14 -070087 tr = t.select('tr:nth-of-type(2)'),
88 tdElement = tr.select('td:nth-of-type(' + (i + 1) + ')'),
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070089 custWidth = thElement.attr(colWidth);
90
91 if (custWidth) {
92 setColWidth(thElement, tdElement, fs.noPx(custWidth));
93 } else if (thElement.classed(tableIcon)) {
94 setColWidth(thElement, tdElement, tableIconTdSize);
Bri Prebilic Cole357f7fd2015-02-12 17:03:42 -080095 } else {
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070096 setColWidth(thElement, tdElement, defaultColWidth);
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080097 }
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080098 });
99 }
100
Bri Prebilic Cole264c5ec2015-04-07 10:22:26 -0700101 // get the size of the window and then subtract the extra space at the top
102 // to get the height of the table
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800103 function setTableHeight(thead, tbody) {
Bri Prebilic Cole45069382015-04-14 15:21:38 -0700104 var ttlHgt = fs.noPxStyle(d3.select('.tabular-header'), 'height'),
105 thHgt = fs.noPxStyle(thead, 'height'),
106 totalHgt = ttlHgt + thHgt + pdg,
107 tbleHgt = fs.windowSize(mast.mastHeight() + totalHgt).height;
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800108
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800109 thead.style('display', 'block');
Bri Prebilic Cole384e8dc2015-04-13 15:51:14 -0700110 tbody.style({
111 display: 'block',
Bri Prebilic Cole45069382015-04-14 15:21:38 -0700112 height: tbleHgt + 'px',
Bri Prebilic Cole384e8dc2015-04-13 15:51:14 -0700113 overflow: 'auto'
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800114 });
115 }
116
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800117 function fixTable(t, th, tb) {
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800118 setTableWidth(t);
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800119 setTableHeight(th, tb);
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800120 }
121
Bri Prebilic Cole3d4d01c2015-04-30 13:48:36 -0700122 // Functions for sorting table rows by header
Bri Prebilic Colee1bda3f2015-02-13 17:01:49 -0800123
Bri Prebilic Cole3d4d01c2015-04-30 13:48:36 -0700124 function updateSortDirection(thElem) {
125 sortIconAPI.sortNone(thElem.select('div'));
126 currCol.div = thElem.append('div');
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800127 currCol.colId = thElem.attr('colId');
128
129 if (currCol.colId === prevCol.colId) {
Bri Prebilic Cole3d4d01c2015-04-30 13:48:36 -0700130 (currCol.dir === desc) ? currCol.dir = asc : currCol.dir = desc;
131 prevCol.dir = currCol.dir;
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800132 } else {
Bri Prebilic Cole3d4d01c2015-04-30 13:48:36 -0700133 currCol.dir = asc;
134 prevCol.dir = none;
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800135 }
Bri Prebilic Cole3d4d01c2015-04-30 13:48:36 -0700136 (currCol.dir === asc) ?
137 sortIconAPI.sortAsc(currCol.div) : sortIconAPI.sortDesc(currCol.div);
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800138
Bri Prebilic Cole3d4d01c2015-04-30 13:48:36 -0700139 if (prevCol.colId && prevCol.dir === none) {
140 sortIconAPI.sortNone(prevCol.div);
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800141 }
142
143 prevCol.colId = currCol.colId;
Bri Prebilic Cole3d4d01c2015-04-30 13:48:36 -0700144 prevCol.div = currCol.div;
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800145 }
146
Bri Prebilic Cole19a32dd2015-03-26 18:00:03 -0700147 function sortRequestParams() {
148 return {
149 sortCol: currCol.colId,
Bri Prebilic Cole3d4d01c2015-04-30 13:48:36 -0700150 sortDir: currCol.dir
Bri Prebilic Cole19a32dd2015-03-26 18:00:03 -0700151 };
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800152 }
153
Bri Prebilic Cole3d4d01c2015-04-30 13:48:36 -0700154 function resetSortIcons() {
155 if (currCol.div) {
156 sortIconAPI.sortNone(currCol.div);
157 }
158 if (prevCol.div) {
159 sortIconAPI.sortNone(prevCol.div);
160 }
161 currCol = {};
162 prevCol = {};
163 }
164
Bri Prebilic Cole093739a2015-01-23 10:22:50 -0800165 angular.module('onosWidget')
Bri Prebilic Cole264c5ec2015-04-07 10:22:26 -0700166 .directive('onosFixedHeader', ['$window', 'FnService', 'MastService',
167 function (_$window_, _fs_, _mast_) {
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800168 return function (scope, element) {
169 $window = _$window_;
170 fs = _fs_;
Bri Prebilic Cole264c5ec2015-04-07 10:22:26 -0700171 mast = _mast_;
172
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800173 var w = angular.element($window),
Bri Prebilic Coleb0e66be2015-02-10 10:53:15 -0800174 table = d3.select(element[0]),
Bri Prebilic Cole7c445752015-02-17 14:49:46 -0800175 thead = table.select('thead'),
176 tbody = table.select('tbody'),
177 canAdjust = false;
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800178
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800179 scope.$watch(function () {
180 return {
181 h: window.innerHeight,
182 w: window.innerWidth
183 };
184 }, function (newVal) {
Simon Hunt0c2c4c52015-04-02 17:42:45 -0700185 var wsz = fs.windowSize(0, 30);
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800186 scope.windowHeight = newVal.h;
187 scope.windowWidth = newVal.w;
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800188
Simon Hunt0c2c4c52015-04-02 17:42:45 -0700189 // default table size in case no data elements
190 table.style('width', wsz.width + 'px');
191
Bri Prebilic Cole7c445752015-02-17 14:49:46 -0800192 scope.$on('LastElement', function () {
193 // only adjust the table once it's completely loaded
194 fixTable(table, thead, tbody);
195 canAdjust = true;
196 });
Bri Prebilic Coleb0e66be2015-02-10 10:53:15 -0800197
Bri Prebilic Cole7c445752015-02-17 14:49:46 -0800198 if (canAdjust) {
Bri Prebilic Coleb0e66be2015-02-10 10:53:15 -0800199 fixTable(table, thead, tbody);
200 }
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800201 }, true);
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800202
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800203 w.bind('onos-fixed-header', function () {
204 scope.$apply();
205 });
206 };
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800207 }])
208
209 .directive('onosSortableHeader', ['$log', 'IconService',
210 function (_$log_, _is_) {
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800211 return {
212 scope: {
213 ctrlCallback: '&sortCallback'
214 },
Bri Prebilic Colee1bda3f2015-02-13 17:01:49 -0800215 link: function (scope, element) {
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800216 $log = _$log_;
217 is = _is_;
Bri Prebilic Cole3d4d01c2015-04-30 13:48:36 -0700218 var table = d3.select(element[0]);
219 sortIconAPI = is.sortIcons();
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800220
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800221 // when a header is clicked, change its icon tag
222 // and get sorting order to send to the server.
223 table.selectAll('th').on('click', function () {
224 var thElem = d3.select(this);
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800225
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800226 if (thElem.attr('sortable') === '') {
Bri Prebilic Cole3d4d01c2015-04-30 13:48:36 -0700227 updateSortDirection(thElem);
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800228 scope.ctrlCallback({
Bri Prebilic Cole72eb6db2015-03-30 16:58:53 -0700229 requestParams: sortRequestParams()
230 });
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800231 }
232 });
233 }
234 };
Bri Prebilic Cole3d4d01c2015-04-30 13:48:36 -0700235 }])
236
237 .factory('TableService', ['$log', 'IconService',
238
239 function ($log, is) {
240 sortIconAPI = is.sortIcons();
241
242 return {
243 resetSortIcons: resetSortIcons
244 };
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800245 }]);
Bri Prebilic Cole093739a2015-01-23 10:22:50 -0800246
247}());