blob: d79994628171d9cbf3e958c8878d9a87e42459ae [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 Cole1f93be22015-02-10 17:16:46 -080023 var $log, $window, fs, is,
Bri Prebilic Cole902cb042015-02-11 14:04:15 -080024 div,
25 currCol = {},
26 prevCol = {},
Bri Prebilic Cole357f7fd2015-02-12 17:03:42 -080027 tableIconTdSize = 30,
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080028 bottomMargin = 200;
Bri Prebilic Cole093739a2015-01-23 10:22:50 -080029
Bri Prebilic Cole902cb042015-02-11 14:04:15 -080030
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080031 // Render a plain d3 table by giving it the div, a config file, and data
32
Bri Prebilic Cole4c891772015-01-27 11:38:51 -080033 function renderTable(div, config, data) {
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080034 var table = div.append('table'),
Bri Prebilic Cole4c891772015-01-27 11:38:51 -080035 colIds = config.colIds,
36 colText = config.colText,
37 dataObjects = data[Object.keys(data)[0]],
38 thead, tbody, tRows;
Bri Prebilic Coleaa8d2ed2015-01-23 16:53:29 -080039
Bri Prebilic Cole4c891772015-01-27 11:38:51 -080040 thead = table.append('thead');
41 tbody = table.append('tbody');
Bri Prebilic Coleaa8d2ed2015-01-23 16:53:29 -080042
Bri Prebilic Cole4c891772015-01-27 11:38:51 -080043 thead.append('tr').selectAll('th')
44 .data(colText)
45 .enter()
46 .append('th')
47 .text(function(d) { return d });
Bri Prebilic Coleaa8d2ed2015-01-23 16:53:29 -080048
Bri Prebilic Cole4c891772015-01-27 11:38:51 -080049 tRows = tbody.selectAll('tr')
50 .data(dataObjects)
51 .enter()
52 .append('tr');
Bri Prebilic Coleaa8d2ed2015-01-23 16:53:29 -080053
Bri Prebilic Cole4c891772015-01-27 11:38:51 -080054 tRows.selectAll('td')
55 .data(function(row) {
56 return colIds.map(function(headerId) {
57 return {
58 column: headerId, value: row[headerId]
59 };
60 });
61 })
62 .enter()
63 .append('td')
64 .html(function(d) { return d.value });
Bri Prebilic Coleaa8d2ed2015-01-23 16:53:29 -080065
Bri Prebilic Cole4c891772015-01-27 11:38:51 -080066 return table;
Bri Prebilic Coleaa8d2ed2015-01-23 16:53:29 -080067 }
68
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080069 // Functions for creating a fixed header on a table (Angular Directive)
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080070
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080071 function setTableWidth(t) {
72 var tHeaders, tdElement, colWidth, numCols,
73 winWidth = fs.windowSize().width;
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080074
75 tHeaders = t.selectAll('th');
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080076 numCols = tHeaders[0].length;
77 colWidth = Math.floor(winWidth/numCols);
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080078
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080079 tHeaders.each(function(thElement, index) {
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080080 thElement = d3.select(this);
81
82 tdElement = t.select('td:nth-of-type(' + (index + 1) + ')');
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080083
Bri Prebilic Cole357f7fd2015-02-12 17:03:42 -080084 if (tdElement.classed('table-icon')) {
85 thElement.style('width', tableIconTdSize + 'px');
86 tdElement.style('width', tableIconTdSize + 'px');
87 } else {
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080088 thElement.style('width', colWidth + 'px');
89 tdElement.style('width', colWidth + 'px');
90 }
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080091 });
92 }
93
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080094 function setTableHeight(thead, tbody) {
95 var winHeight = fs.windowSize().height;
96
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080097 thead.style('display', 'block');
98 tbody.style({'display': 'block',
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080099 'height': ((winHeight - bottomMargin) + 'px'),
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800100 'overflow': 'auto'
101 });
102 }
103
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800104 function fixTable(t, th, tb) {
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800105 setTableWidth(t);
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800106 setTableHeight(th, tb);
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800107 }
108
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800109 function updateSortingIcons(thElem, api) {
110 currCol.colId = thElem.attr('colId');
111
112 if (currCol.colId === prevCol.colId) {
113 (currCol.icon === 'tableColSortDesc') ?
114 currCol.icon = 'tableColSortAsc' :
115 currCol.icon = 'tableColSortDesc';
116 prevCol.icon = currCol.icon;
117 } else {
118 currCol.icon = 'tableColSortAsc';
119 prevCol.icon = 'tableColSortNone';
120 }
121
122 div = thElem.select('div');
123 div.remove();
124 div = thElem.append('div');
125
126 if (currCol.icon === 'tableColSortAsc') {
127 api.sortAsc(div);
128 } else {
129 api.sortDesc(div);
130 }
131
132 if (prevCol.colId !== undefined &&
133 prevCol.icon === 'tableColSortNone') {
134 api.sortNone(prevCol.elem.select('div'));
135 }
136
137 prevCol.colId = currCol.colId;
138 prevCol.elem = thElem;
139 }
140
141 function generateQueryParams() {
142 var queryString = '?sortCol=' + currCol.colId + '&sortDir=';
143
144 if(currCol.icon === 'tableColSortAsc') {
145 queryString = queryString + 'asc';
146 } else {
147 queryString = queryString + 'desc';
148 }
149
150 return queryString;
151 }
152
Bri Prebilic Cole093739a2015-01-23 10:22:50 -0800153 angular.module('onosWidget')
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800154 .factory('TableService', [function () {
Bri Prebilic Cole093739a2015-01-23 10:22:50 -0800155 return {
Bri Prebilic Cole4c891772015-01-27 11:38:51 -0800156 renderTable: renderTable
Bri Prebilic Cole093739a2015-01-23 10:22:50 -0800157 };
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800158 }])
159
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800160 .directive('onosFixedHeader', ['$window', '$timeout',
161 'MastService', 'FnService',
162 function (_$window_, $timeout, mast, _fs_) {
163 return function (scope, element) {
164 $window = _$window_;
165 fs = _fs_;
166 var w = angular.element($window),
Bri Prebilic Coleb0e66be2015-02-10 10:53:15 -0800167 table = d3.select(element[0]),
168 shouldResize = false;
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800169
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800170 scope.$watch(function () {
171 return {
172 h: window.innerHeight,
173 w: window.innerWidth
174 };
175 }, function (newVal) {
176 var thead = table.select('thead'),
177 tbody = table.select('tbody');
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800178
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800179 scope.windowHeight = newVal.h;
180 scope.windowWidth = newVal.w;
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800181
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800182 scope.setTableHW = function () {
Bri Prebilic Coleb0e66be2015-02-10 10:53:15 -0800183 scope.$on('LastElement', function (event) {
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800184 // only adjust the table once it's completely loaded
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800185 fixTable(table, thead, tbody);
Bri Prebilic Coleb0e66be2015-02-10 10:53:15 -0800186 shouldResize = true;
187 });
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800188 };
Bri Prebilic Coleb0e66be2015-02-10 10:53:15 -0800189
190 if (shouldResize) {
191 fixTable(table, thead, tbody);
192 }
193
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800194 }, true);
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800195
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800196 w.bind('onos-fixed-header', function () {
197 scope.$apply();
198 });
199 };
200
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800201 }])
202
203 .directive('onosSortableHeader', ['$log', 'IconService',
204 function (_$log_, _is_) {
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800205 return {
206 scope: {
207 ctrlCallback: '&sortCallback'
208 },
209 link: function (scope, element, attrs) {
210 $log = _$log_;
211 is = _is_;
212 var table = d3.select(element[0]),
213 sortIconAPI = is.createSortIcon();
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800214
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800215 // when a header is clicked, change its icon tag
216 // and get sorting order to send to the server.
217 table.selectAll('th').on('click', function () {
218 var thElem = d3.select(this);
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800219
Bri Prebilic Cole902cb042015-02-11 14:04:15 -0800220 if (thElem.attr('sortable') === '') {
221 updateSortingIcons(thElem, sortIconAPI);
222 // call the ctrl's rest callback function
223 scope.ctrlCallback({
224 urlSuffix: generateQueryParams()
225 });
226 }
227 });
228 }
229 };
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800230 }]);
Bri Prebilic Cole093739a2015-01-23 10:22:50 -0800231
232}());