blob: b3b0476b5e767ef24a9d670a7ac32665d6591b7b [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
24 var $log, $window, fs, is;
25
26 // constants
27 var tableIconTdSize = 33,
28 bottomMargin = 200,
29 colWidth = 'col-width',
30 tableIcon = 'table-icon';
31
32 // internal state
33 var currCol = {},
34 prevCol = {};
Bri Prebilic Cole093739a2015-01-23 10:22:50 -080035
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080036 // Functions for creating a fixed header on a table (Angular Directive)
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080037
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070038 function setElemWidth(elem, size) {
39 elem.style('width', size + 'px')
40 }
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080041
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070042 function setColWidth(th, td, size) {
43 setElemWidth(th, size);
44 setElemWidth(td, size);
45 }
Thomas Vachuska0fa583c2015-03-30 23:07:41 -070046
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070047 // count number of headers of
48 // - assigned width,
49 // - icon width,
50 // - and default width
51 // assumes assigned width is not given to icons
52 // returns the width of all columns that are not icons have an assigned width
53 function getDefaultWidth(headers) {
54 var winWidth = fs.windowSize().width,
55 iconCols = 0,
56 regCols = 0,
57 cstmColWidth = 0;
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080058
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070059 headers.each(function (d, i) {
60 var thElement = d3.select(this),
61 cstmWidth = thElement.attr(colWidth);
62
63 if (cstmWidth) {
64 cstmColWidth += fs.noPx(cstmWidth);
65 } else if (thElement.classed(tableIcon)) {
66 iconCols += 1;
Thomas Vachuska0fa583c2015-03-30 23:07:41 -070067 } else {
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070068 regCols += 1;
Thomas Vachuska0fa583c2015-03-30 23:07:41 -070069 }
70 });
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080071
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070072 return Math.floor((winWidth - cstmColWidth -
73 (iconCols * tableIconTdSize)) / regCols);
74 }
Thomas Vachuska0fa583c2015-03-30 23:07:41 -070075
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070076 function setTableWidth(t) {
77 var tHeaders = t.selectAll('th'),
78 defaultColWidth = getDefaultWidth(tHeaders);
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080079
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070080 tHeaders.each(function (d, i) {
81 var thElement = d3.select(this),
82 tdElement = t.select('td:nth-of-type(' + (i + 1) + ')'),
83 custWidth = thElement.attr(colWidth);
84
85 if (custWidth) {
86 setColWidth(thElement, tdElement, fs.noPx(custWidth));
87 } else if (thElement.classed(tableIcon)) {
88 setColWidth(thElement, tdElement, tableIconTdSize);
Bri Prebilic Cole357f7fd2015-02-12 17:03:42 -080089 } else {
Bri Prebilic Cole08d08d42015-04-01 14:37:02 -070090 setColWidth(thElement, tdElement, defaultColWidth);
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080091 }
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080092 });
93 }
94
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080095 function setTableHeight(thead, tbody) {
96 var winHeight = fs.windowSize().height;
97
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080098 thead.style('display', 'block');
99 tbody.style({'display': 'block',
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800100 'height': ((winHeight - bottomMargin) + 'px'),
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800101 'overflow': 'auto'
102 });
103 }
104
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800105 function fixTable(t, th, tb) {
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800106 setTableWidth(t);
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800107 setTableHeight(th, tb);
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800108 }
109
Bri Prebilic Colee1bda3f2015-02-13 17:01:49 -0800110 // Functions for sorting table rows by header and choosing appropriate icon
111
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800112 function updateSortingIcons(thElem, api) {
Bri Prebilic Colee1bda3f2015-02-13 17:01:49 -0800113 var div;
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800114 currCol.colId = thElem.attr('colId');
115
116 if (currCol.colId === prevCol.colId) {
117 (currCol.icon === 'tableColSortDesc') ?
118 currCol.icon = 'tableColSortAsc' :
119 currCol.icon = 'tableColSortDesc';
120 prevCol.icon = currCol.icon;
121 } else {
122 currCol.icon = 'tableColSortAsc';
123 prevCol.icon = 'tableColSortNone';
124 }
125
126 div = thElem.select('div');
Bri Prebilic Colee1bda3f2015-02-13 17:01:49 -0800127 api.sortNone(div);
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800128 div = thElem.append('div');
129
130 if (currCol.icon === 'tableColSortAsc') {
131 api.sortAsc(div);
132 } else {
133 api.sortDesc(div);
134 }
135
136 if (prevCol.colId !== undefined &&
137 prevCol.icon === 'tableColSortNone') {
138 api.sortNone(prevCol.elem.select('div'));
139 }
140
141 prevCol.colId = currCol.colId;
142 prevCol.elem = thElem;
143 }
144
Bri Prebilic Cole19a32dd2015-03-26 18:00:03 -0700145 function sortRequestParams() {
146 return {
147 sortCol: currCol.colId,
148 sortDir: (currCol.icon === 'tableColSortAsc' ? 'asc' : 'desc')
149 };
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800150 }
151
Bri Prebilic Cole093739a2015-01-23 10:22:50 -0800152 angular.module('onosWidget')
Bri Prebilic Colee1bda3f2015-02-13 17:01:49 -0800153 .directive('onosFixedHeader', ['$window', 'FnService',
154 function (_$window_, _fs_) {
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800155 return function (scope, element) {
156 $window = _$window_;
157 fs = _fs_;
158 var w = angular.element($window),
Bri Prebilic Coleb0e66be2015-02-10 10:53:15 -0800159 table = d3.select(element[0]),
Bri Prebilic Cole7c445752015-02-17 14:49:46 -0800160 thead = table.select('thead'),
161 tbody = table.select('tbody'),
162 canAdjust = false;
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800163
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800164 scope.$watch(function () {
165 return {
166 h: window.innerHeight,
167 w: window.innerWidth
168 };
169 }, function (newVal) {
Simon Hunt0c2c4c52015-04-02 17:42:45 -0700170 var wsz = fs.windowSize(0, 30);
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800171 scope.windowHeight = newVal.h;
172 scope.windowWidth = newVal.w;
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800173
Simon Hunt0c2c4c52015-04-02 17:42:45 -0700174 // default table size in case no data elements
175 table.style('width', wsz.width + 'px');
176
Bri Prebilic Cole7c445752015-02-17 14:49:46 -0800177 scope.$on('LastElement', function () {
178 // only adjust the table once it's completely loaded
179 fixTable(table, thead, tbody);
180 canAdjust = true;
181 });
Bri Prebilic Coleb0e66be2015-02-10 10:53:15 -0800182
Bri Prebilic Cole7c445752015-02-17 14:49:46 -0800183 if (canAdjust) {
Bri Prebilic Coleb0e66be2015-02-10 10:53:15 -0800184 fixTable(table, thead, tbody);
185 }
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800186 }, true);
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800187
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800188 w.bind('onos-fixed-header', function () {
189 scope.$apply();
190 });
191 };
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800192 }])
193
194 .directive('onosSortableHeader', ['$log', 'IconService',
195 function (_$log_, _is_) {
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800196 return {
197 scope: {
198 ctrlCallback: '&sortCallback'
199 },
Bri Prebilic Colee1bda3f2015-02-13 17:01:49 -0800200 link: function (scope, element) {
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800201 $log = _$log_;
202 is = _is_;
203 var table = d3.select(element[0]),
204 sortIconAPI = is.createSortIcon();
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800205
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800206 // when a header is clicked, change its icon tag
207 // and get sorting order to send to the server.
208 table.selectAll('th').on('click', function () {
209 var thElem = d3.select(this);
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800210
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800211 if (thElem.attr('sortable') === '') {
212 updateSortingIcons(thElem, sortIconAPI);
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800213 scope.ctrlCallback({
Bri Prebilic Cole72eb6db2015-03-30 16:58:53 -0700214 requestParams: sortRequestParams()
215 });
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800216 }
217 });
218 }
219 };
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800220 }]);
Bri Prebilic Cole093739a2015-01-23 10:22:50 -0800221
222}());