blob: 9673600d0b7821a39dd74eacf1da90683c2f3ab9 [file] [log] [blame]
Steven Burrows1c5c8612016-10-05 13:45:13 -05001/*
2 * Copyright 2016-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 -- Topology View Module.
19 Module that displays the details panel for selected nodes
20 */
21
22(function () {
23 'use strict';
24
25 // Injected Services
26 var Panel, gs, wss, flash, bs, fs, ns;
27
28 // Internal State
29 var detailsPanel;
30
31 // configuration
32 var id = 'topo2-p-detail',
33 className = 'topo-p',
34 panelOpts = {
35 width: 260 // summary and detail panel width
36 },
37 handlerMap = {
38 'showDetails': showDetails
39 };
40
41 var coreButtons = {
42 showDeviceView: {
43 gid: 'switch',
44 tt: 'Show Device View',
45 path: 'device'
46 },
47 showFlowView: {
48 gid: 'flowTable',
49 tt: 'Show Flow View for this Device',
50 path: 'flow'
51 },
52 showPortView: {
53 gid: 'portTable',
54 tt: 'Show Port View for this Device',
55 path: 'port'
56 },
57 showGroupView: {
58 gid: 'groupTable',
59 tt: 'Show Group View for this Device',
60 path: 'group'
61 },
62 showMeterView: {
63 gid: 'meterTable',
64 tt: 'Show Meter View for this Device',
65 path: 'meter'
66 }
67 };
68
69 function init() {
70
71 bindHandlers();
72
73 var options = angular.extend({}, panelOpts, {
74 class: className
75 });
76
77 detailsPanel = new Panel(id, options);
78 detailsPanel.p.classed(className, true);
79 }
80
81 function addProp(tbody, label, value) {
82 var tr = tbody.append('tr'),
83 lab;
84 if (typeof label === 'string') {
85 lab = label.replace(/_/g, ' ');
86 } else {
87 lab = label;
88 }
89
90 function addCell(cls, txt) {
91 tr.append('td').attr('class', cls).html(txt);
92 }
93 addCell('label', lab + ' :');
94 addCell('value', value);
95 }
96
97 function addSep(tbody) {
98 tbody.append('tr').append('td').attr('colspan', 2).append('hr');
99 }
100
101 function listProps(tbody, data) {
102 data.propOrder.forEach(function (p) {
103 if (p === '-') {
104 addSep(tbody);
105 } else {
106 addProp(tbody, p, data.props[p]);
107 }
108 });
109 }
110
111 function addBtnFooter() {
112 detailsPanel.appendToFooter('hr');
113 detailsPanel.appendToFooter('div').classed('actionBtns', true);
114 }
115
116 function addAction(o) {
117 var btnDiv = d3.select('#' + id)
118 .select('.actionBtns')
119 .append('div')
120 .classed('actionBtn', true);
121 bs.button(btnDiv, id + '-' + o.id, o.gid, o.cb, o.tt);
122 }
123
124 function installButtons(buttons, data, devId) {
125 buttons.forEach(function (id) {
126 var btn = coreButtons[id],
127 gid = btn && btn.gid,
128 tt = btn && btn.tt,
129 path = btn && btn.path;
130
131 if (btn) {
132 addAction({
133 id: 'core-' + id,
134 gid: gid,
135 tt: tt,
136 cb: function () { ns.navTo(path, { devId: devId }); }
137 });
138 }
139 // else if (btn = _getButtonDef(id, data)) {
140 // addAction(btn);
141 // }
142 });
143 }
144
145 function renderSingle(data) {
146
147 detailsPanel.emptyRegions();
148
149 var svg = detailsPanel.appendToHeader('div')
150 .classed('icon clickable', true)
151 .append('svg'),
152 title = detailsPanel.appendToHeader('h2')
153 .classed('clickable', true),
154 table = detailsPanel.appendToBody('table'),
155 tbody = table.append('tbody'),
156 navFn;
157
158 gs.addGlyph(svg, (data.type || 'unknown'), 26);
159 title.text(data.title);
160
161 // // only add navigation when displaying a device
162 // if (isDevice[data.type]) {
163 // navFn = function () {
164 // ns.navTo(devPath, { devId: data.id });
165 // };
166 //
167 // svg.on('click', navFn);
168 // title.on('click', navFn);
169 // }
170
171 listProps(tbody, data);
172 addBtnFooter();
173 }
174
175
176 function bindHandlers() {
177 wss.bindHandlers(handlerMap);
178 }
179
180 function updateDetails(id, nodeType) {
181 wss.sendEvent('requestDetails', {
182 id: id,
183 class: nodeType
184 });
185 }
186
187 function showDetails(data) {
188 var buttons = fs.isA(data.buttons) || [];
189 renderSingle(data);
190 installButtons(buttons, data, data.id);
191 }
192
193 function toggle() {
194 var on = detailsPanel.p.toggle(),
195 verb = on ? 'Show' : 'Hide';
196 flash.flash(verb + ' Summary Panel');
197 }
198
199 function show() {
200 detailsPanel.p.show();
201 }
202
203 function hide() {
204 detailsPanel.p.hide();
205 }
206
207 function destroy() {
208 wss.unbindHandlers(handlerMap);
209 detailsPanel.destroy();
210 }
211
212 angular.module('ovTopo2')
213 .factory('Topo2DeviceDetailsPanel',
214 ['Topo2PanelService', 'GlyphService', 'WebSocketService', 'FlashService',
215 'ButtonService', 'FnService', 'NavService',
216 function (_ps_, _gs_, _wss_, _flash_, _bs_, _fs_, _ns_) {
217
218 Panel = _ps_;
219 gs = _gs_;
220 wss = _wss_;
221 flash = _flash_;
222 bs = _bs_;
223 fs = _fs_;
224 ns = _ns_;
225
226 return {
227 init: init,
228 updateDetails: updateDetails,
229
230 toggle: toggle,
231 show: show,
232 hide: hide,
233 destroy: destroy
234 };
235 }
236 ]);
237})();