blob: 26e282832c76457a12070b46f3e10814084e6251 [file] [log] [blame]
Simon Huntcc035c52017-02-22 21:12:51 -08001/*
2 * Copyright 2017-present 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 -- YANG Model table view
19 */
20
21(function () {
22 'use strict';
23
24 // injected refs
Simon Hunt7d5e9842017-02-23 11:37:02 -080025 var $log, $scope, fs, mast, ps, wss, is;
26
27 // constants
28 var topPdg = 28,
Thomas Vachuskacde197c2017-03-23 17:51:08 -070029 ctnrPdg = 24,
30 pWidth = 800,
31 scrollSize = 17,
32 tblPdg = 50;
Simon Huntcc035c52017-02-22 21:12:51 -080033
34 // internal state
35 var detailsPanel,
Simon Hunt7d5e9842017-02-23 11:37:02 -080036 ymodel,
37 pStartY,
38 pHeight,
39 wSize,
40 top,
Thomas Vachuskacde197c2017-03-23 17:51:08 -070041 topTable,
42 bottom,
Simon Hunt7d5e9842017-02-23 11:37:02 -080043 iconDiv;
Simon Huntcc035c52017-02-22 21:12:51 -080044
45 // constants
46 var pName = 'yang-model-details-panel',
47 detailsReq = 'yangModelDetailsRequest',
Thomas Vachuskacde197c2017-03-23 17:51:08 -070048 detailsResp = 'yangModelDetailsResponse',
Simon Huntcc035c52017-02-22 21:12:51 -080049
Thomas Vachuskacde197c2017-03-23 17:51:08 -070050 propOrder = [
51 ],
52 friendlyProps = [
Thomas Vachuskacde197c2017-03-23 17:51:08 -070053 ];
Simon Hunt7d5e9842017-02-23 11:37:02 -080054
Simon Hunt7d5e9842017-02-23 11:37:02 -080055 function createDetailsPanel() {
56 detailsPanel = ps.createPanel(pName, {
57 width: pWidth,
58 margin: 0,
59 hideMargin: 0
60 });
61 $scope.hidePanel = function () { detailsPanel.hide(); };
62 detailsPanel.hide();
63 }
64
65 function populateDetails(details) {
Simon Hunt7d5e9842017-02-23 11:37:02 -080066 setUpPanel();
Thomas Vachuskacde197c2017-03-23 17:51:08 -070067 populateTop(details);
Thomas Vachuskae0792f12017-03-31 00:15:06 -070068 populateBottom(details.source);
Simon Hunt7d5e9842017-02-23 11:37:02 -080069 }
70
71 function setUpPanel() {
72 var container, closeBtn, dataDiv;
73 detailsPanel.empty();
74
75 container = detailsPanel.append('div').classed('container', true);
76
77 top = container.append('div').classed('top', true);
78 closeBtn = top.append('div').classed('close-btn', true);
79 addCloseBtn(closeBtn);
80 iconDiv = top.append('div').classed('dev-icon', true);
81 top.append('h2');
Thomas Vachuskacde197c2017-03-23 17:51:08 -070082 topTable = top.append('div').classed('top-content', true)
83 .append('table');
84 top.append('hr');
Simon Hunt7d5e9842017-02-23 11:37:02 -080085
Thomas Vachuskacde197c2017-03-23 17:51:08 -070086 bottom = container.append('div').classed('bottom', true);
Thomas Vachuskae0792f12017-03-31 00:15:06 -070087 bottom.append('h2').classed('modules-title', true).html('YANG Source');
88 bottom.append('div').classed('module-source');
89 bottom.select('div').append('pre');
Simon Hunt7d5e9842017-02-23 11:37:02 -080090 }
91
Thomas Vachuskacde197c2017-03-23 17:51:08 -070092 function addProp(tbody, index, value) {
93 var tr = tbody.append('tr');
Simon Hunt7d5e9842017-02-23 11:37:02 -080094
Thomas Vachuskacde197c2017-03-23 17:51:08 -070095 function addCell(cls, txt) {
96 tr.append('td').attr('class', cls).html(txt);
97 }
98 addCell('label', friendlyProps[index] + ' :');
99 addCell('value', value);
100 }
101
102 function populateTop(details) {
103 is.loadEmbeddedIcon(iconDiv, 'nav_yang', 40);
Thomas Vachuskae0792f12017-03-31 00:15:06 -0700104 top.select('h2').html('Module ' + details.module + " (" + details.revision + ")");
Thomas Vachuskacde197c2017-03-23 17:51:08 -0700105
106 var tbody = topTable.append('tbody');
107
108 propOrder.forEach(function (prop, i) {
109 addProp(tbody, i, details[prop]);
110 });
111 }
112
Thomas Vachuskae0792f12017-03-31 00:15:06 -0700113 function populateBottom(source) {
114 var src = bottom.select('pre');
115 src.html(source.join('\n'));
Simon Hunt7d5e9842017-02-23 11:37:02 -0800116 }
117
118 function closePanel() {
119 if (detailsPanel.isVisible()) {
120 $scope.selId = null;
121 detailsPanel.hide();
122 return true;
123 }
124 return false;
125 }
126
127 function addCloseBtn(div) {
128 is.loadEmbeddedIcon(div, 'close', 20);
129 div.on('click', closePanel);
130 }
131
132
Simon Huntcc035c52017-02-22 21:12:51 -0800133 // callback invoked when data from a details request returns from server
134 function respDetailsCb(data) {
135 $scope.panelData = data.details;
136 ymodel = data.yangModel;
137 $scope.$apply();
138 // TODO: complete the detail panel directive.
139 $log.debug('YANG_MODEL>', detailsResp, data);
140 }
141
Simon Hunt7d5e9842017-02-23 11:37:02 -0800142 function handleEscape() {
143 return closePanel();
144 }
145
146
147 // defines view controller
Simon Huntcc035c52017-02-22 21:12:51 -0800148 angular.module('ovYangModel', [])
Simon Hunt7d5e9842017-02-23 11:37:02 -0800149 .controller('OvYangModelCtrl', [
150 '$log', '$scope', 'TableBuilderService', 'TableDetailService',
151 'FnService', 'MastService', 'PanelService', 'WebSocketService',
152 'IconService',
Simon Huntcc035c52017-02-22 21:12:51 -0800153
Simon Hunt7d5e9842017-02-23 11:37:02 -0800154 function (_$log_, _$scope_, tbs, tds, _fs_, _mast_, _ps_, _wss_, _is_) {
155 var handlers = {};
Simon Huntcc035c52017-02-22 21:12:51 -0800156
Simon Hunt7d5e9842017-02-23 11:37:02 -0800157 $log = _$log_;
158 $scope = _$scope_;
159 fs = _fs_;
160 mast = _mast_;
161 ps = _ps_;
162 wss = _wss_;
163 is = _is_;
Simon Huntcc035c52017-02-22 21:12:51 -0800164
Simon Hunt7d5e9842017-02-23 11:37:02 -0800165 $scope.panelData = {};
Simon Huntcc035c52017-02-22 21:12:51 -0800166
Simon Hunt7d5e9842017-02-23 11:37:02 -0800167 // register response handler
168 handlers[detailsResp] = respDetailsCb;
169 wss.bindHandlers(handlers);
Simon Huntcc035c52017-02-22 21:12:51 -0800170
Simon Hunt7d5e9842017-02-23 11:37:02 -0800171 // row selection callback
172 function selCb($event, row) {
173 if ($scope.selId) {
Thomas Vachuska401a1d32017-03-31 09:58:11 -0700174 wss.sendEvent(detailsReq, { modelId: row.modelId, id: row.id });
Simon Hunt7d5e9842017-02-23 11:37:02 -0800175 } else {
176 $scope.hidePanel();
Simon Huntcc035c52017-02-22 21:12:51 -0800177 }
Simon Hunt7d5e9842017-02-23 11:37:02 -0800178 $log.debug('Got a click on:', row);
Simon Huntcc035c52017-02-22 21:12:51 -0800179 }
Simon Huntcc035c52017-02-22 21:12:51 -0800180
Simon Hunt7d5e9842017-02-23 11:37:02 -0800181 tbs.buildTable({
182 scope: $scope,
183 tag: 'yangModel',
184 selCb: selCb
185 });
186
187 $scope.$on('$destroy', function () {
188 wss.unbindHandlers(handlers);
189 });
190
191 $log.log('OvYangModelCtrl has been created');
192 }
193 ])
194
195 .directive('yangModelDetailsPanel', [
196 '$rootScope', '$window', '$timeout', 'KeyService',
197
198 function ($rootScope, $window, $timeout, ks) {
199 return function (scope) {
200 var unbindWatch;
201
202 function heightCalc() {
203 pStartY = fs.noPxStyle(d3.select('.tabular-header'), 'height')
204 + mast.mastHeight() + topPdg;
205 wSize = fs.windowSize(pStartY);
206 pHeight = wSize.height;
207 }
208
209 function initPanel() {
210 heightCalc();
211 createDetailsPanel();
212 }
213
214 // Safari has a bug where it renders the fixed-layout table wrong
215 // if you ask for the window's size too early
216 if (scope.onos.browser === 'safari') {
217 $timeout(initPanel);
218 } else {
219 initPanel();
220 }
221
222 // create key bindings to handle panel
223 ks.keyBindings({
224 esc: [handleEscape, 'Close the details panel'],
225 _helpFormat: ['esc']
226 });
227 ks.gestureNotes([
228 ['click', 'Select a row to show YANG model details'],
229 ['scroll down', 'See more models']
230 ]);
231
232 // if the panelData changes
233 scope.$watch('panelData', function () {
234 if (!fs.isEmptyObject(scope.panelData)) {
235 populateDetails(scope.panelData);
236 detailsPanel.show();
237 }
238 });
239
240 // if the window size changes
241 unbindWatch = $rootScope.$watchCollection(
242 function () {
243 return {
244 h: $window.innerHeight,
245 w: $window.innerWidth
246 };
247 }, function () {
248 if (!fs.isEmptyObject(scope.panelData)) {
249 heightCalc();
250 populateDetails(scope.panelData);
251 }
252 }
253 );
254
255 scope.$on('$destroy', function () {
256 unbindWatch();
257 ks.unbindKeys();
258 ps.destroyPanel(pName);
259 });
260 };
261 }]);
Simon Huntcc035c52017-02-22 21:12:51 -0800262
263}());