Updating features archetype to talk about user-facing features.
[controller.git] / opendaylight / web / devices / src / main / resources / js / page.js
1 /* 
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved. 
3  * 
4  * This program and the accompanying materials are made available under the 
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution, 
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 //PAGE Devices
10 one.f = {};
11
12 // specify dashlets and layouts
13
14 one.f.dashlet = {
15   nodesLearnt : {
16     id : 'nodesLearnt',
17     name : 'Nodes Learned'
18   },
19   staticRouteConfig : {
20     id : 'staticRouteConfig',
21     name : 'Static Route Configuration'
22   },
23   subnetGatewayConfig : {
24     id : 'subnetGatewayConfig',
25     name : 'Subnet Gateway Configuration'
26   },
27   spanPortConfig : {
28     id : 'spanPortConfig',
29     name : 'SPAN Port Configuration'
30   },
31   connection : {
32     id : 'connection',
33     name : 'Connection Manager'
34   }
35 };
36
37 one.f.menu = {
38   left : {
39     top : [
40       one.f.dashlet.nodesLearnt
41       ],
42     bottom : [
43       one.f.dashlet.staticRouteConfig,
44       one.f.dashlet.connection
45       ]
46   },
47   right : {
48     top : [],
49     bottom : [
50       one.f.dashlet.subnetGatewayConfig,
51     one.f.dashlet.spanPortConfig
52       ]
53   }
54 };
55
56 /**Devices Modules */
57 one.f.switchmanager = {
58   rootUrl: "controller/web/devices",
59   createTable: function(columnNames, body) {
60     var tableAttributes = ["table-striped", "table-bordered", "table-condensed"];
61     var $table = one.lib.dashlet.table.table(tableAttributes);
62     var tableHeaders = columnNames;
63     var $thead = one.lib.dashlet.table.header(tableHeaders);
64     var $tbody = one.lib.dashlet.table.body(body, tableHeaders);
65     $table.append($thead)
66       .append($tbody);
67     return $table;
68   },
69   validateName: function(name) {
70     return (name.length < 256);
71   }
72 };
73
74 one.f.switchmanager.nodesLearnt = {
75   id: {
76     dashlet: {
77       popout: "one_f_switchmanager_nodesLearnt_id_dashlet_popout",
78       datagrid: "one_f_switchmanager_nodesLearnt_id_dashlet_datagrid"
79     },
80     modal: {
81       modal: "one_f_switchmanager_nodesLearnt_id_modal_modal",
82       configure: "one_f_switchmanager_nodesLearnt_id_modal_configure",
83       ports: "one_f_switchmanager_nodesLearnt_id_modal_ports",
84       save: "one_f_switchmanager_nodesLearnt_id_modal_save",
85       datagrid: "one_f_switchmanager_nodesLearnt_id_modal_datagrid",
86       portsDatagrid: "one_f_switchmanager_nodesLearnt_id_modal_portsDatagrid",
87       form: {
88         nodeId: "one_f_switchmanager_nodesLearnt_id_modal_form_nodeid",
89         nodeName : "one_f_switchmanager_nodesLearnt_id_modal_form_nodename",
90         portStatus : "one_f_switchmanager_nodesLearnt_id_modal_form_portstatus",
91         tier: "one_f_switchmanager_nodesLearnt_id_modal_form_tier",
92         operationMode: "one_f_switchmanager_nodesLearnt_id_modal_form_opmode"
93       }
94     }
95   },
96   dashlet: function($dashlet) {
97     var url = one.f.switchmanager.rootUrl + "/nodesLearnt";
98     one.lib.dashlet.empty($dashlet);
99     $dashlet.append(one.lib.dashlet.header(one.f.dashlet.nodesLearnt.name));
100
101     one.f.switchmanager.nodesLearnt.ajax.main(url, function(content) {
102       var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.nodesLearnt.id.dashlet.datagrid, {
103         searchable: true,
104           filterable: false,
105           pagination: true,
106           flexibleRowsPerPage: true
107       }, "table-striped table-condensed");
108       $dashlet.append($gridHTML);
109       var dataSource = one.f.switchmanager.nodesLearnt.data.gridDataSource.abridged(content);
110       $("#" + one.f.switchmanager.nodesLearnt.id.dashlet.datagrid).datagrid({dataSource: dataSource}).on("loaded", function() {
111         $(this).find("tbody a").click(one.f.switchmanager.nodesLearnt.modal.initialize.updateNode);
112       });
113
114       $("#" + one.f.switchmanager.nodesLearnt.id.dashlet.datagrid).datagrid({dataSource: dataSource}).on("loaded", function() {
115         $(this).find("tbody span").click(function(){
116           one.f.switchmanager.nodesLearnt.modal.initialize.displayPorts($(this));
117         });
118       });
119
120     });
121   },
122   ajax : {
123     main : function(url, callback) {
124       $.getJSON(url, function(data) {
125         callback(data);
126       });
127     }
128   },
129   modal : {
130     registry : { callback:undefined },
131     initialize: {
132       updateNode: function(evt) {
133         one.f.switchmanager.nodesLearnt.ajax.main(one.f.switchmanager.rootUrl + "/tiers", function(tiers) {
134
135           var nodeId = decodeURIComponent(evt.target.id);
136           var h3;
137           var footer = [];
138           var $body = one.f.switchmanager.nodesLearnt.modal.body.updateNode(nodeId, JSON.parse(decodeURIComponent(evt.target.getAttribute("switchDetails"))), tiers);
139           if (evt.target.getAttribute("privilege") == 'WRITE'){
140             h3 = "Update Node Information";
141             footer = one.f.switchmanager.nodesLearnt.modal.footer.updateNode();
142           } else { //disable node edit
143             $body.find('*').attr('disabled', 'disabled');
144             h3 = 'Node Information';
145           }
146
147           var $modal = one.lib.modal.spawn(one.f.switchmanager.nodesLearnt.id.modal.configure, h3, "", footer);
148           // bind save button
149           $('#' + one.f.switchmanager.nodesLearnt.id.modal.save, $modal).click(function() {
150             one.f.switchmanager.nodesLearnt.modal.save($modal);
151           });
152
153           // inject body (nodePorts)
154           one.lib.modal.inject.body($modal, $body);
155
156           $modal.modal().on("shown",function() {
157               var callback = one.f.switchmanager.nodesLearnt.modal.registry.callback;
158               if( callback !== undefined && $.isFunction(callback)) {
159                  callback();
160               }
161           });
162         });
163       },
164       popout: function() {
165         var h3 = "Nodes Learned";
166         var footer = one.f.switchmanager.nodesLearnt.modal.footer.popout();
167         var $modal = one.lib.modal.spawn(one.f.switchmanager.nodesLearnt.id.modal.modal, h3, "", footer);
168         var $body = one.f.switchmanager.nodesLearnt.modal.body.popout($modal);
169         return $modal;
170       },
171       displayPorts: function(ports) {
172         var content = JSON.parse(decodeURIComponent(ports.attr("ports")));
173
174         var h3 = ((ports.attr("nodeName") == "None")? ports.attr("nodeId") : ports.attr("nodeName"))
175           var footer = [];
176         var $modal = one.lib.modal.spawn(one.f.switchmanager.nodesLearnt.id.modal.ports, h3, "", footer);
177
178         var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.nodesLearnt.id.modal.portsDatagrid, {
179           searchable: true,
180             filterable: false,
181             pagination: true,
182             flexibleRowsPerPage: true,
183             popout: true
184         }, "table-striped table-condensed");
185         one.lib.modal.inject.body($modal, $gridHTML);
186         $modal.on("shown", function() {
187           var dataSource = one.f.switchmanager.nodesLearnt.data.gridDataSource.displayPorts(content);
188           $("#" + one.f.switchmanager.nodesLearnt.id.modal.portsDatagrid).datagrid({
189             dataSource: dataSource,
190             stretchHeight: false
191           });
192         });
193         $modal.modal();
194       }
195     },
196     body: {
197       updateNode: function(nodeId, switchDetails, tiers) {
198         var $form = $(document.createElement('form'));
199         var $fieldset = $(document.createElement('fieldset'));
200         // node ID. not editable.
201         var $label = one.lib.form.label("Node ID");
202         var $input = one.lib.form.input("node id");
203         $input.attr('id', one.f.switchmanager.nodesLearnt.id.modal.form.nodeId);
204         $input.attr("disabled", true);
205         $input.attr("value", nodeId);
206         $fieldset.append($label).append($input);
207         // node name
208         var $label = one.lib.form.label("Node Name");
209         var $input = one.lib.form.input("Node Name");
210         $input.attr('id', one.f.switchmanager.nodesLearnt.id.modal.form.nodeName);
211         if(switchDetails["nodeName"] != null) {
212           $input.attr('value', switchDetails["nodeName"]);
213         }
214         $fieldset.append($label).append($input);
215         // node tier
216         var $label = one.lib.form.label("Tier");
217         var $select = one.lib.form.select.create(tiers);
218         $select.attr('id', one.f.switchmanager.nodesLearnt.id.modal.form.tier);
219         $select.val(switchDetails["tier"]);
220         $fieldset.append($label).append($select);
221         // operation mode
222         var $label = one.lib.form.label("Operation Mode");
223         var $select = one.lib.form.select.create(
224             ["Allow reactive forwarding", "Proactive forwarding only"]);
225         $select.attr('id', one.f.switchmanager.nodesLearnt.id.modal.form.operationMode);
226         if ((one.main.registry != undefined) && (one.main.registry.container != 'default')) {
227           $select.attr("disabled", true);
228         }
229         $select.val(switchDetails["mode"]);
230         $fieldset.append($label).append($select);
231         $form.append($fieldset);
232         return $form;
233       },
234       popout: function($modal) {
235         var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.nodesLearnt.id.modal.datagrid, {
236           searchable: true,
237         filterable: false,
238         pagination: true,
239         flexibleRowsPerPage: true,
240         popout: true
241         }, "table-striped table-condensed");
242         one.lib.modal.inject.body($modal, $gridHTML);
243         // attach to shown event of modal 
244         $modal.on("shown", function() {
245           var url = one.f.switchmanager.rootUrl + "/nodesLearnt";
246           one.f.switchmanager.nodesLearnt.ajax.main(url, function(content) {
247             var dataSource = one.f.switchmanager.nodesLearnt.data.gridDataSource.popout(content);
248             $("#" + one.f.switchmanager.nodesLearnt.id.modal.datagrid).datagrid({
249               dataSource: dataSource,
250               stretchHeight: false
251             })
252             .on("loaded", function() {
253               $("#" + one.f.switchmanager.nodesLearnt.id.modal.datagrid).find("tbody span").click(function(){
254                 one.f.switchmanager.nodesLearnt.modal.initialize.displayPorts($(this));
255               });
256             });
257           });
258         });
259       }
260     },
261     save: function($modal) {
262       var result = {};
263       result['nodeName'] = $('#' + one.f.switchmanager.nodesLearnt.id.modal.form.nodeName, $modal).val();
264       if(!one.f.switchmanager.validateName(result['nodeName'])) {
265         alert("Node name can contain upto 255 characters");
266         return;
267       }
268       result['nodeId'] = $('#' + one.f.switchmanager.nodesLearnt.id.modal.form.nodeId, $modal).val();
269       result['tier'] = $('#' + one.f.switchmanager.nodesLearnt.id.modal.form.tier, $modal).val();
270       result['operationMode'] = $('#' + one.f.switchmanager.nodesLearnt.id.modal.form.operationMode, $modal).val();
271       one.f.switchmanager.nodesLearnt.modal.ajax(result, 
272           function(response) {
273             if(response.status == true) {
274               $modal.modal('hide');
275               one.topology.update(); // refresh visual topology with new name
276               // TODO: Identify dashlet by inserting a nodesLearnt div 
277               // in the dashlet() instead
278               one.f.switchmanager.nodesLearnt.dashlet($("#left-top .dashlet"));
279             } else {
280               alert(response.message);
281             }
282
283           });
284     },
285     ajax: function(requestData, callback) {
286       $.getJSON(one.f.switchmanager.rootUrl + "/nodesLearnt/update", requestData, function(response) {
287         callback(response);
288       });
289     },
290     footer: {
291       updateNode: function() {
292         var footer = [];
293         var saveButton = one.lib.dashlet.button.single("Save", one.f.switchmanager.nodesLearnt.id.modal.save, "btn-primary", "");
294         var $saveButton = one.lib.dashlet.button.button(saveButton);
295         footer.push($saveButton);
296
297         return footer;
298       },
299       popout: function() {
300         // TODO: Maybe put a close button in the footer?
301         return [];
302       }
303     }
304   },
305   // data functions
306   data : {
307     gridDataSource: {
308       abridged: function(data) {
309         var source = new StaticDataSource({
310           columns: [
311         {
312           property: 'nodeName',
313         label: 'Node Name',
314         sortable: true
315         },
316         {
317           property: 'nodeId',
318         label: 'Node ID',
319         sortable: true
320         },
321         {
322           property: 'ports',
323         label: 'Ports',
324         sortable: true
325         }
326         ],
327         data: data.nodeData,
328         formatter: function(items) {
329           $.each(items, function (index, item) {
330             var nodeName = item.nodeName;
331             var nodeNameEntry = item.nodeName ? item.nodeName : "Click to update";
332             item.nodeName = '<a href="#" id="' + item.nodeId + '" switchDetails=' + encodeURIComponent(JSON.stringify(item)) + 
333             ' privilege=' + data.privilege + '>' + nodeNameEntry + '</a>';
334
335           var ports = item.ports;
336           var portsMatch = ports.match(/<\/span>/g);
337           var portsLength = 0;
338           if (portsMatch != null) {
339             portsLength = portsMatch.length;
340           }
341           item.ports = '<span class="nodePorts" style="cursor:pointer;color: #08c" ports='+encodeURIComponent(JSON.stringify(item.ports)) + ' nodeId="' + item.nodeId
342             + '" nodeName="' + nodeName
343             + '">' + portsLength +'</span>';
344           }); 
345         },
346         delay: 0
347         });
348         return source;
349
350       },
351       popout: function(data) {
352         var source = new StaticDataSource({
353           columns: [
354         {
355           property: 'nodeName',
356         label: 'Node Name',
357         sortable: true
358         },
359         {
360           property: 'nodeId',
361         label: 'Node ID',
362         sortable: true
363         },
364         {
365           property: 'tierName',
366         label: 'Tier Name',
367         sortable: true
368         },
369         {
370           property: 'mac',
371         label: 'MAC Address',
372         sortable: true
373         },
374         {
375           property: 'ports',
376           label: 'Ports',
377           sortable: true
378         }
379         ],
380           data: data.nodeData,
381           formatter: function(items) {
382             $.each(items, function (index, item) {
383               var ports = item.ports;
384               var portsMatch = ports.match(/<\/span>/g);
385               var portsLength = 0;
386               if (portsMatch != null) {
387                 portsLength = portsMatch.length;
388               }
389               item.ports = '<span class="nodePorts" style="cursor: pointer;color: #08c" ports='+encodeURIComponent(JSON.stringify(item.ports)) + ' nodeId="' + item.nodeId
390               + '" nodeName="' + item.nodeName
391               + '">' + portsLength +'</span>';
392             }); 
393           },
394           delay: 0
395         });
396         return source;
397       },
398       displayPorts: function(content){
399         var data=[];
400         var start=0;;
401         var finish=content.indexOf("<br>",start);
402         while(finish != -1){
403           data.push({"ports":content.substring(start,finish)});
404           start=finish+4
405             finish=content.indexOf("<br>",start);
406         }
407         var source = new StaticDataSource({
408           columns: [
409         {
410           property: 'ports',
411             label: 'Ports',
412             sortable: true
413         }
414         ],
415             data:data,
416             delay: 0
417         });
418
419         return source;
420       }
421     },
422     abridged : function(data) {
423       var result = [];
424       $.each(data.nodeData, function(key, value) {
425         var tr = {};
426         var entry = [];
427         var nodeNameEntry = value["nodeName"] ? value["nodeName"] : "Click to update";
428
429         // TODO: Move anchor tag creation to one.lib.form.
430         var aTag;
431         aTag = document.createElement("a");
432         aTag.privilege = data.privilege;
433         aTag.addEventListener("click", one.f.switchmanager.nodesLearnt.modal.initialize.updateNode);
434         aTag.addEventListener("mouseover", function(evt) {
435           evt.target.style.cursor = "pointer";
436         }, false);
437         aTag.setAttribute("id", encodeURIComponent(value["nodeId"]));
438         aTag.switchDetails = value;
439         aTag.innerHTML = nodeNameEntry;
440         entry.push(aTag);
441         entry.push(value["nodeId"]);
442         entry.push(value["ports"]);
443         tr.entry = entry;
444         result.push(tr);
445       });
446       return result;
447     },
448     popout : function(data) {
449       var result = [];
450       $.each(data.nodeData, function(key, value) {
451         var tr = {};
452         // fill up all the td's
453         var entry = [];
454         var nodenameentry = value["nodeName"] ? value["nodeName"] : "No name provided";
455         entry.push(nodenameentry);
456         entry.push(value["nodeId"]);
457         entry.push(value["tierName"]);
458         entry.push(value["mac"]);
459         entry.push(value["ports"]);
460         tr.entry = entry;
461         result.push(tr);
462       });
463       return result;
464     }
465   }
466 };
467
468 one.f.switchmanager.subnetGatewayConfig = {
469   id: {
470     dashlet: {
471       addIPAddress: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_addIP",
472       addPorts: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_addPorts",
473       removeIPAddress: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_removeIP",
474       datagrid: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_datagrid",
475       selectAll: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_selectAll"
476     }, 
477     modal: {
478       modal: "one_f_switchmanager_subnetGatewayConfig_id_modal_modal",
479       ports : "one_f_switchmanager_subnetGatewayConfig_id_modal_ports",
480       save: "one_f_switchmanager_subnetGatewayConfig_id_modal_save",
481       remove: "one_f_switchmanager_subnetGatewayConfig_id_modal_remove",
482       cancel: "one_f_switchmanager_subnetGatewayConfig_id_modal_cancel",
483       form: {
484         name : "one_f_switchmanager_subnetGatewayConfig_id_modal_form_gatewayname",
485         gatewayIPAddress : "one_f_switchmanager_subnetGatewayConfig_id_modal_form_gatewayipaddress",
486         nodeId: "one_f_switchmanager_subnetGatewayConfig_id_modal_form_nodeid",
487         ports: "one_f_switchmanager_subnetGatewayConfig_id_modal_form_ports"
488       }
489     }
490   },
491   // device ajax calls
492   dashlet: function($dashlet) {
493     one.lib.dashlet.empty($dashlet);
494     $dashlet.append(one.lib.dashlet.header(one.f.dashlet.subnetGatewayConfig.name));
495     // Add gateway IP Address button
496     var url = one.f.switchmanager.rootUrl + "/subnets";
497     one.f.switchmanager.subnetGatewayConfig.ajax.main(url, {}, function(content) {
498
499       if (content.privilege === 'WRITE') {
500         var button = one.lib.dashlet.button.single("Add Gateway IP Address",
501           one.f.switchmanager.subnetGatewayConfig.id.dashlet.addIPAddress, "btn-primary", "btn-mini");
502         var $button = one.lib.dashlet.button.button(button);
503         $button.click(function() {
504           var $modal = one.f.switchmanager.subnetGatewayConfig.modal.initialize.gateway();
505           $modal.modal();
506         });
507         $dashlet.append($button);
508
509         // Delete gateway ip address button
510         var button = one.lib.dashlet.button.single("Remove Gateway IP Address",
511           one.f.switchmanager.subnetGatewayConfig.id.dashlet.removeIPAddress, "btn-danger", "btn-mini");
512         var $button = one.lib.dashlet.button.button(button);
513         $button.click(function() {
514           var gatewaysToDelete = [];
515           var checkedCheckBoxes = $("#" + one.f.switchmanager.subnetGatewayConfig.id.dashlet.datagrid).find("tbody input:checked")
516           checkedCheckBoxes.each(function(index, value) {
517             gatewaysToDelete.push(checkedCheckBoxes[index].id);
518           });
519         if (checkedCheckBoxes.size() === 0) {
520           return false;
521         }
522         one.f.switchmanager.subnetGatewayConfig.modal.removeMultiple.dialog(gatewaysToDelete)
523         });
524         $dashlet.append($button);
525
526         // Add Ports button
527         var button = one.lib.dashlet.button.single("Add Ports",
528             one.f.switchmanager.subnetGatewayConfig.id.dashlet.addPorts, "btn-primary", "btn-mini");
529         var $button = one.lib.dashlet.button.button(button);
530         $button.click(function() {
531           if (one.f.switchmanager.subnetGatewayConfig.registry.gateways.length === 0) {
532             alert('No Gateways Exist');
533             return false;
534           }
535           var $modal = one.f.switchmanager.subnetGatewayConfig.modal.initialize.ports();
536           $modal.modal();
537         });
538         $dashlet.append($button);
539       }
540       var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.subnetGatewayConfig.id.dashlet.datagrid, {
541         searchable: true,
542           filterable: false,
543           pagination: true,
544           flexibleRowsPerPage: true
545       }, "table-striped table-condensed");
546       $dashlet.append($gridHTML);
547       var dataSource = one.f.switchmanager.subnetGatewayConfig.data.devicesgrid(content);
548       $("#" + one.f.switchmanager.subnetGatewayConfig.id.dashlet.datagrid).datagrid({dataSource: dataSource})
549         .on("loaded", function() {
550           $("#"+one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll).click(function() {
551             $("#" + one.f.switchmanager.subnetGatewayConfig.id.dashlet.datagrid).find(':checkbox').prop('checked',
552               $("#"+one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll).is(':checked'));
553           });
554           $(".subnetGatewayConfig").click(function(e){
555             if (!$('.subnetGatewayConfig[type=checkbox]:not(:checked)').length) {
556               $("#"+one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll)
557             .prop("checked",
558               true);
559             } else {
560               $("#"+one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll)
561             .prop("checked",
562               false);
563             }
564             e.stopPropagation();
565           });
566         });
567     });
568   },
569   ajax : {
570     main : function(url, requestData, callback) {
571       $.getJSON(url, requestData, function(data) {
572         callback(data);
573       });
574     }
575   },
576   registry: {},
577   modal : {
578     initialize: {
579       gateway: function() {
580         var h3 = "Add Gateway IP Address";
581         var footer = one.f.switchmanager.subnetGatewayConfig.modal.footer();
582         var $modal = one.lib.modal.spawn(one.f.switchmanager.subnetGatewayConfig.id.modal.modal, h3, "", footer);
583         // bind save button
584         $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.save, $modal).click(function() {
585           one.f.switchmanager.subnetGatewayConfig.modal.save.gateway($modal);
586         });
587         var $body = one.f.switchmanager.subnetGatewayConfig.modal.body.gateway();
588         one.lib.modal.inject.body($modal, $body);
589         return $modal;
590       },
591       ports: function() {
592         var h3 = "Add Ports";
593         var footer = one.f.switchmanager.subnetGatewayConfig.modal.footer();
594         var $modal = one.lib.modal.spawn(one.f.switchmanager.subnetGatewayConfig.id.modal.ports, h3, "", footer);
595         // bind save button
596         $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.save, $modal).click(function() {
597           one.f.switchmanager.subnetGatewayConfig.modal.save.ports($modal);
598         });
599
600         // TODO: Change to subnetGateway instead.
601         one.f.switchmanager.spanPortConfig.modal.ajax.nodes(function(nodes, nodeports) {
602           var $body = one.f.switchmanager.subnetGatewayConfig.modal.body.ports(nodes, nodeports);
603           one.lib.modal.inject.body($modal, $body);
604         });
605         return $modal;
606       }
607     },
608     save: {
609       gateway: function($modal) {
610         var result = {};
611         result['gatewayName'] = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.name, $modal).val();
612         if(!one.f.switchmanager.validateName(result['gatewayName'])) {
613           alert("Gateway name can contain upto 255 characters");
614           return;
615         }
616         result['gatewayIPAddress'] = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.gatewayIPAddress, $modal).val();
617         one.f.switchmanager.subnetGatewayConfig.modal.ajax.gateway(result, 
618             function(response) {
619               if(response.status == true) {
620                 $modal.modal('hide');
621                 one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
622               } else {
623                 alert(response.message);
624               }
625             });
626       },
627       ports: function($modal) {
628         var result = {};
629         var gatewayRegistryIndex = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.name, $modal).val();
630         result['portsName'] = one.f.switchmanager.subnetGatewayConfig.registry.gateways[gatewayRegistryIndex];
631         result['nodeId'] = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.nodeId, $modal).val();
632         result['ports'] = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.ports, $modal).val();
633         if(!result['portsName'] || result['portsName'] == "") {
634           alert("No gateway chosen. Cannot add port");
635           return;
636         }
637         if(!result['nodeId'] || result['nodeId'] == "") {
638           alert("Please select a node.");
639           return;
640         }
641         if(!result['ports'] || result['ports'] == "") {
642           alert("Please choose a port.");
643           return;
644         }
645         one.f.switchmanager.subnetGatewayConfig.modal.ajax.ports(result, 
646             function(response) {
647               if(response.status == true) {
648                 $modal.modal('hide');
649                 one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
650               } else {
651                 alert(response.message);
652               }
653             });
654       }
655     },
656     body: {
657       gateway: function() {
658         var $form = $(document.createElement('form'));
659         var $fieldset = $(document.createElement('fieldset'));
660         // gateway name
661         var $label = one.lib.form.label("Name");
662         var $input = one.lib.form.input("Name");
663         $input.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.name);
664         $fieldset.append($label).append($input);
665         // gateway IP Mask 
666         var $label = one.lib.form.label("Gateway IP Address/Mask");
667         var $input = one.lib.form.input("Gateway IP Address/Mask");
668         var $help = one.lib.form.help('Example: 192.168.10.254/16');
669         $input.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.gatewayIPAddress);
670         $fieldset.append($label).append($input).append($help);
671
672         $form.append($fieldset);
673         return $form;
674       },
675       ports: function(nodes, nodeports) {
676         var $form = $(document.createElement('form'));
677         var $fieldset = $(document.createElement('fieldset'));
678         // gateways drop down
679         var $label = one.lib.form.label("Gateway Name");
680         var $select = one.lib.form.select.create(one.f.switchmanager.subnetGatewayConfig.registry.gateways);
681         $select.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.name);
682         one.lib.form.select.prepend($select, { '' : 'Please Select a Gateway' });
683         $select.val($select.find("option:first").val());
684         $fieldset.append($label).append($select);
685
686         // node ID
687         var $label = one.lib.form.label("Node ID");
688         var $select = one.lib.form.select.create(nodes);
689         $select.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.nodeId);
690         one.lib.form.select.prepend($select, { '' : 'Please Select a Node' });
691         $select.val($select.find("option:first").val());
692         $fieldset.append($label).append($select);
693
694         // bind onchange
695         $select.change(function() {
696           // retrieve port value
697           var node = $(this).find('option:selected').attr('value');
698           one.f.switchmanager.subnetGatewayConfig.registry['currentNode'] = node;
699           var $ports = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.ports);
700           var ports = nodeports[node];
701           var options = {};
702           $(ports).each(function(idx, val) {
703             options[val.internalPortName] = val.portName+' ('+val.portId+')'; 
704               });
705             one.lib.form.select.inject($ports, options);
706             one.lib.form.select.prepend($ports, { '' : 'Please Select a Port' });
707             $ports.val($ports.find("option:first").val());
708             });
709
710           // ports
711           var $label = one.lib.form.label("Select Port");
712           var $select = one.lib.form.select.create();
713           one.lib.form.select.prepend($select, { '' : 'Please Select a Port' });
714           $select.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.ports);
715           $fieldset.append($label).append($select);
716
717           $form.append($fieldset);
718           return $form;
719       }
720     },
721     ajax: {
722       gateway: function(requestData, callback) {
723         $.getJSON(one.f.switchmanager.rootUrl + "/subnetGateway/add", requestData, function(data) {
724           callback(data);
725         });
726       },
727       ports: function(requestData, callback) {
728         $.getJSON(one.f.switchmanager.rootUrl + "/subnetGateway/ports/add", requestData, function(data) {
729           callback(data);
730         });
731       }
732     },
733     footer : function() {
734       var footer = [];
735       var saveButton = one.lib.dashlet.button.single("Save", one.f.switchmanager.subnetGatewayConfig.id.modal.save, "btn-primary", "");
736       var $saveButton = one.lib.dashlet.button.button(saveButton);
737       footer.push($saveButton);
738       return footer;
739     },
740     removeMultiple: {
741       dialog: function(gatewaysToDelete) {
742         var h3 = 'Remove Gateway IP Address';
743
744         var footer = one.f.switchmanager.subnetGatewayConfig.modal.removeMultiple.footer();
745         var $body = one.f.switchmanager.subnetGatewayConfig.modal.removeMultiple.body(gatewaysToDelete);
746         var $modal = one.lib.modal.spawn(one.f.switchmanager.subnetGatewayConfig.id.modal.modal, h3, $body, footer);
747
748         // bind close button
749         $('#'+one.f.switchmanager.subnetGatewayConfig.id.modal.cancel, $modal).click(function() {
750           $modal.modal('hide');
751         });
752
753         // bind remove rule button
754         $('#'+one.f.switchmanager.subnetGatewayConfig.id.modal.remove, $modal).click(this, function(e) {
755           var requestData = {};
756           if (gatewaysToDelete.length > 0) {
757             requestData["gatewaysToDelete"] = gatewaysToDelete.toString();
758             var url = one.f.switchmanager.rootUrl + "/subnetGateway/delete";
759             one.f.switchmanager.subnetGatewayConfig.ajax.main(url, requestData, function(response) {
760               $modal.modal('hide');
761               if (response.status == true) {
762                 // refresh dashlet by passing dashlet div as param 
763                 one.lib.alert("Gateway IP Address(es) successfully removed");
764               } else {
765                 alert(response.message);
766               }
767               one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
768             });
769           }
770         });
771         $modal.modal();
772       },
773       footer : function() {
774         var footer = [];
775         var remove = one.lib.dashlet.button.single('Remove Gateway IP Address',one.f.switchmanager.subnetGatewayConfig.id.modal.remove, 'btn-danger', '');
776         var $remove = one.lib.dashlet.button.button(remove);
777         footer.push($remove);
778
779         var cancel = one.lib.dashlet.button.single('Cancel', one.f.switchmanager.subnetGatewayConfig.id.modal.cancel, '', '');
780         var $cancel = one.lib.dashlet.button.button(cancel);
781         footer.push($cancel);
782
783         return footer;
784       },
785       body : function (gatewayList) {
786         var $p = $(document.createElement('p'));
787         var p = 'Remove the following Gateway IP Address(es)?';
788         //creata a BS label for each rule and append to list
789         $(gatewayList).each(function(){
790           var $span = $(document.createElement('span'));
791           $span.append(this);
792           p += '<br/>' + $span[0].outerHTML;
793         });
794         $p.append(p);
795         return $p;
796       }
797     }
798   },
799   // data functions
800   data : {
801     devicesgrid: function(data) {
802       one.f.switchmanager.subnetGatewayConfig.registry.gateways = [];
803       var source = new StaticDataSource({
804         columns: [
805       {
806         property: 'selector',
807           label: "<input type='checkbox'  id='"
808         +one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll+"'/>",
809           sortable: false
810       },
811           {
812             property: 'name',
813           label: 'Name',
814           sortable: true
815           },
816           {
817             property: 'subnet',
818           label: 'Gateway IP Address/Mask',
819           sortable: true
820           },
821           {
822             property: 'nodePorts',
823           label: 'Ports',
824           sortable: false
825           }
826       ],
827         data: data.nodeData,
828         formatter: function(items) {
829           $.each(items, function(index, tableRow) {
830             tableRow["selector"] = '<input type="checkbox" class="subnetGatewayConfig" id="'
831             + tableRow["name"] + '"></input>';
832           var json = tableRow["nodePorts"];
833           var nodePorts = JSON.parse(json);
834           var nodePortHtml = "<div>";
835           $.each(nodePorts, function(index, nodePort) {
836             nodePortHtml += nodePort["nodePortName"] + " @ " + nodePort["nodeName"];
837             nodePortHtml += "&nbsp;";
838             nodePortHtml += '<a href="#" id="' + encodeURIComponent(nodePort["nodePortId"]) +
839             '" gatewayName="' + tableRow["name"] +
840             '" onclick="javascript:one.f.switchmanager.subnetGatewayConfig.actions.deleteNodePort(this);">Remove</a>';
841           nodePortHtml += "<br/>";
842           });
843           nodePortHtml += "</div>";
844           tableRow["nodePorts"] = nodePortHtml;
845           });
846
847         },
848         delay: 0
849       });
850       // populate the registry with subnet names
851       one.f.switchmanager.subnetGatewayConfig.registry.gateways = [];
852       $.each(data.nodeData, function(key, value) {
853         one.f.switchmanager.subnetGatewayConfig.registry.gateways.push(value["name"]);
854       });
855       return source;          
856     },
857     devices : function(data) {
858       var result = [];
859       one.f.switchmanager.subnetGatewayConfig.registry.gateways = [];
860       $.each(data.nodeData, function(key, value) {
861         var tr = {};
862         // fill up all the td's
863         var subnetConfigObject = $.parseJSON(value["json"]);
864         var nodePorts = subnetConfigObject.nodePorts;
865         var $nodePortsContainer = $(document.createElement("div"));
866
867         for(var i = 0; i < nodePorts.length; i++) {
868           var nodePort = nodePorts[i];
869           $nodePortsContainer.append(nodePort + " ");
870           // add delete anchor tag to delete ports
871           var aTag = document.createElement("a");
872           aTag.setAttribute("id", encodeURIComponent(nodePort));
873           aTag.gatewayName = value["name"];
874           aTag.addEventListener("click", function(evt) {
875             var htmlPortAnchor = evt.target;
876             var requestData = {};
877             requestData["gatewayName"] = evt.target.gatewayName;
878             requestData["nodePort"] = decodeURIComponent(evt.target.id);
879             // make ajax call to delete port
880             var url = one.f.switchmanager.rootUrl + "/subnetGateway/ports/delete";
881             one.f.switchmanager.subnetGatewayConfig.ajax.main(url, requestData, function(response) {
882               if(response.status == true) {
883                 // refresh dashlet by passing dashlet div as param
884                 one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
885               } else {
886                 alert(response.message);
887               }
888             });
889
890           });
891           aTag.addEventListener("mouseover", function(evt) {
892             evt.target.style.cursor = "pointer";
893           }, false);
894           aTag.innerHTML = "Remove";
895           $nodePortsContainer.append(aTag);
896           $nodePortsContainer.append("<br/>");
897         }
898
899         // store gateways in the registry so that they can be used in the add ports popup
900         one.f.switchmanager.subnetGatewayConfig.registry.gateways.push(value["name"]);
901         var entry = [];
902         var checkbox = document.createElement("input");
903         checkbox.setAttribute("type", "checkbox");
904         checkbox.setAttribute("id", value["name"]);
905         entry.push(checkbox);
906         entry.push(value["name"]);
907         entry.push(value["subnet"]);
908         entry.push($nodePortsContainer);
909         tr.entry = entry;
910         result.push(tr);
911       });
912       return result;
913     }
914   },
915   actions: {
916     deleteNodePort: function(htmlPortAnchor) {
917       var requestData = {};
918       requestData["gatewayName"] = htmlPortAnchor.getAttribute("gatewayName");
919       requestData["nodePort"] = decodeURIComponent(htmlPortAnchor.id);
920       // make ajax call to delete port
921       var url = one.f.switchmanager.rootUrl + "/subnetGateway/ports/delete";
922       one.f.switchmanager.subnetGatewayConfig.ajax.main(url, requestData, function(response) {
923         if(response.status == true) {
924           // refresh dashlet by passing dashlet div as param
925           one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
926         } else {
927           alert(response.message);
928         }
929       });
930     }
931   }
932 }
933
934 one.f.switchmanager.staticRouteConfig = {
935   id: {
936     dashlet: {
937       add: "one_f_switchmanager_staticRouteConfig_id_dashlet_add",
938       remove: "one_f_switchmanager_staticRouteConfig_id_dashlet_remove",
939       datagrid: "one_f_switchmanager_staticRouteConfig_id_dashlet_datagrid",
940       selectAll: "one_f_switchmanager_staticRouteConfig_id_dashlet_selectAll"
941     }, 
942     modal: {
943       modal: "one_f_switchmanager_staticRouteConfig_id_modal_modal",
944       save: "one_f_switchmanager_staticRouteConfig_id_modal_save",
945       cancel: "one_f_switchmanager_staticRouteConfig_id_modal_cancel",
946       remove: "one_f_switchmanager_staticRouteConfig_id_modal_remove",
947       form: {
948         routeName : "one_f_switchmanager_staticRouteConfig_id_modal_form_routename",
949         staticRoute : "one_f_switchmanager_staticRouteConfig_id_modal_form_staticroute",
950         nextHop : "one_f_switchmanager_staticRouteConfig_id_modal_form_nexthop",
951       }
952     }
953   },
954   dashlet: function($dashlet) {
955     one.lib.dashlet.empty($dashlet);
956     var url = one.f.switchmanager.rootUrl + "/staticRoutes";
957     one.f.switchmanager.staticRouteConfig.ajax.main(url, {}, function(content) {
958
959       if (content.privilege === 'WRITE') {
960         // Add static route button
961         var button = one.lib.dashlet.button.single("Add Static Route", one.f.switchmanager.staticRouteConfig.id.dashlet.add, "btn-primary", "btn-mini");
962         var $button = one.lib.dashlet.button.button(button);
963         $button.click(function() {
964           var $modal = one.f.switchmanager.staticRouteConfig.modal.initialize();
965           $modal.modal();
966         });
967         $dashlet.append(one.lib.dashlet.header(one.f.dashlet.staticRouteConfig.name));
968         $dashlet.append($button);
969
970         // Delete static route button
971         var button = one.lib.dashlet.button.single("Remove Static Route", one.f.switchmanager.staticRouteConfig.id.dashlet.remove, "btn-danger", "btn-mini");
972         var $button = one.lib.dashlet.button.button(button);
973         $button.click(function() {
974           var routesToDelete = [];
975           var checkedCheckBoxes = $("#" + one.f.switchmanager.staticRouteConfig.id.dashlet.datagrid).find("tbody input:checked");
976           checkedCheckBoxes.each(function(index, value) {
977             routesToDelete.push(checkedCheckBoxes[index].id);
978           });
979           if (checkedCheckBoxes.size() === 0) {
980             return false;
981           }
982           one.f.switchmanager.staticRouteConfig.modal.removeMultiple.dialog(routesToDelete);
983         });
984         $dashlet.append($button);
985       }
986       var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.staticRouteConfig.id.dashlet.datagrid, {
987         searchable: true,
988           filterable: false,
989           pagination: true,
990           flexibleRowsPerPage: true
991       }, "table-striped table-condensed");
992       $dashlet.append($gridHTML);
993       var dataSource = one.f.switchmanager.staticRouteConfig.data.staticRouteConfigGrid(content);
994       $("#" + one.f.switchmanager.staticRouteConfig.id.dashlet.datagrid).datagrid({dataSource: dataSource})
995         .on("loaded", function() {
996           $("#"+one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll).click(function() {
997             $("#" + one.f.switchmanager.staticRouteConfig.id.dashlet.datagrid).find(':checkbox').prop('checked',
998               $("#"+one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll).is(':checked'));
999           });
1000           $(".staticRoute").click(function(e){
1001             if (!$('.staticRoute[type=checkbox]:not(:checked)').length) {
1002               $("#"+one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll)
1003             .prop("checked",
1004               true);
1005             } else {
1006               $("#"+one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll)
1007             .prop("checked",
1008               false);
1009             }
1010             e.stopPropagation();
1011           });
1012         });
1013     });
1014   },
1015   // device ajax calls
1016   ajax : {
1017     main : function(url, requestData, callback) {
1018       $.getJSON(url, requestData, function(data) {
1019         callback(data);
1020       });
1021     }
1022   },
1023   registry: {},
1024   modal : {
1025     initialize: function() {
1026       var h3 = "Add Static Route";
1027       var footer = one.f.switchmanager.staticRouteConfig.modal.footer();
1028       var $modal = one.lib.modal.spawn(one.f.switchmanager.staticRouteConfig.id.modal.modal, h3, "", footer);
1029       // bind save button
1030       $('#' + one.f.switchmanager.staticRouteConfig.id.modal.save, $modal).click(function() {
1031         one.f.switchmanager.staticRouteConfig.modal.save($modal);
1032       });
1033       var $body = one.f.switchmanager.staticRouteConfig.modal.body();
1034       one.lib.modal.inject.body($modal, $body);
1035       return $modal;
1036     },
1037     save: function($modal) {
1038       var result = {};
1039       result['routeName'] = $('#' + one.f.switchmanager.staticRouteConfig.id.modal.form.routeName, $modal).val();
1040       result['staticRoute'] = $('#' + one.f.switchmanager.staticRouteConfig.id.modal.form.staticRoute, $modal).val();
1041       result['nextHop'] = $('#' + one.f.switchmanager.staticRouteConfig.id.modal.form.nextHop, $modal).val();
1042       one.f.switchmanager.staticRouteConfig.modal.ajax.staticRouteConfig(result, function(response) {
1043         if(response.status == true) {
1044           $modal.modal('hide');
1045           // refresh dashlet by passing dashlet div as param
1046           one.f.switchmanager.staticRouteConfig.dashlet($("#left-bottom .dashlet"));
1047         } else {
1048           // TODO: Show error message in a error message label instead.
1049           alert(response.message);
1050         }
1051       });
1052     },
1053     body: function() {
1054       var $form = $(document.createElement('form'));
1055       var $fieldset = $(document.createElement('fieldset'));
1056       // static route name
1057       var $label = one.lib.form.label("Name");
1058       var $input = one.lib.form.input("Name");
1059       $input.attr('id', one.f.switchmanager.staticRouteConfig.id.modal.form.routeName);
1060       $fieldset.append($label).append($input);
1061       // static route IP Mask 
1062       var $label = one.lib.form.label("Static Route");
1063       var $input = one.lib.form.input("Static Route");
1064       var $help = one.lib.form.help('Example: 53.55.0.0/16');
1065       $input.attr('id', one.f.switchmanager.staticRouteConfig.id.modal.form.staticRoute);
1066       $fieldset.append($label).append($input).append($help);
1067       // static route IP Mask 
1068       var $label = one.lib.form.label("Next Hop");
1069       var $input = one.lib.form.input("Next Hop");
1070       var $help = one.lib.form.help('Example: 192.168.10.254');
1071       $input.attr('id', one.f.switchmanager.staticRouteConfig.id.modal.form.nextHop);
1072       $fieldset.append($label).append($input).append($help);
1073       // return
1074       $form.append($fieldset);
1075       return $form;
1076     },
1077     ajax: {
1078       staticRouteConfig: function(requestData, callback) {
1079         $.getJSON(one.f.switchmanager.rootUrl + "/staticRoute/add", requestData, function(data) {
1080           callback(data);
1081         });
1082       }
1083     },
1084     data : {
1085
1086     },
1087     footer : function() {
1088       var footer = [];
1089       var saveButton = one.lib.dashlet.button.single("Save", one.f.switchmanager.staticRouteConfig.id.modal.save, "btn-primary", "");
1090       var $saveButton = one.lib.dashlet.button.button(saveButton);
1091       footer.push($saveButton);
1092       return footer;
1093     },
1094     removeMultiple: {
1095       dialog: function(routesToDelete) {
1096         var h3 = 'Remove Static Route';
1097
1098         var footer = one.f.switchmanager.staticRouteConfig.modal.removeMultiple.footer();
1099         var $body = one.f.switchmanager.staticRouteConfig.modal.removeMultiple.body(routesToDelete);
1100         var $modal = one.lib.modal.spawn(one.f.switchmanager.staticRouteConfig.id.modal.modal, h3, $body, footer);
1101
1102         // bind close button
1103         $('#'+one.f.switchmanager.staticRouteConfig.id.modal.cancel, $modal).click(function() {
1104           $modal.modal('hide');
1105         });
1106
1107         // bind remove rule button
1108         $('#'+one.f.switchmanager.staticRouteConfig.id.modal.remove, $modal).click(this, function(e) {
1109           if (routesToDelete.length > 0) {
1110             var requestData = {};
1111             requestData["routesToDelete"] = routesToDelete.toString();
1112             var url = one.f.switchmanager.rootUrl + "/staticRoute/delete";
1113             one.f.switchmanager.staticRouteConfig.ajax.main(url, requestData, function(response) {
1114               $modal.modal('hide');
1115               if (response.status == true) {
1116                 // refresh dashlet by passing dashlet div as param 
1117                 one.lib.alert("Static Route(s) successfully removed");
1118               } else {
1119                 alert(response.message);
1120               }
1121               one.f.switchmanager.staticRouteConfig.dashlet($("#left-bottom .dashlet"));
1122             });
1123           }
1124         });
1125         $modal.modal();
1126       },
1127       footer : function() {
1128         var footer = [];
1129         var remove = one.lib.dashlet.button.single('Remove Static Route',one.f.switchmanager.staticRouteConfig.id.modal.remove, 'btn-danger', '');
1130         var $remove = one.lib.dashlet.button.button(remove);
1131         footer.push($remove);
1132
1133         var cancel = one.lib.dashlet.button.single('Cancel', one.f.switchmanager.staticRouteConfig.id.modal.cancel, '', '');
1134         var $cancel = one.lib.dashlet.button.button(cancel);
1135         footer.push($cancel);
1136
1137         return footer;
1138       },
1139       body : function (staticRouteList) {
1140         var $p = $(document.createElement('p'));
1141         var p = 'Remove the following Static Route(s)?';
1142         //creata a BS label for each rule and append to list
1143         $(staticRouteList).each(function(){
1144           var $span = $(document.createElement('span'));
1145           $span.append(this);
1146           p += '<br/>' + $span[0].outerHTML;
1147         });
1148         $p.append(p);
1149         return $p;
1150       }
1151     }
1152   },
1153   // data functions
1154   data : {
1155     staticRouteConfigGrid: function(data) {
1156       var source = new StaticDataSource({
1157         columns: [
1158       {
1159         property: 'selector',
1160       label: "<input type='checkbox'  id='"
1161         +one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll+"'/>",
1162       sortable: false
1163       },
1164       {
1165         property: 'name',
1166       label: 'Name',
1167       sortable: true
1168       },
1169       {
1170         property: 'staticRoute',
1171       label: 'Static Route',
1172       sortable: true
1173       },
1174       {
1175         property: 'nextHop',
1176           label: 'Next Hop Address',
1177           sortable: true
1178       }
1179       ],
1180         data: data.nodeData,
1181         formatter: function(items) {
1182           $.each(items, function(index, item) {
1183             item["selector"] = '<input type="checkbox" class="staticRoute" id="' + item["name"] + '"></input>';
1184           });
1185
1186         },
1187         delay: 0
1188       });
1189       return source;              
1190     },
1191     staticRouteConfig : function(data) {
1192       var result = [];
1193       $.each(data.nodeData, function(key, value) {
1194         var tr = {};
1195         // fill up all the td's
1196         var entry = [];
1197         var checkbox = document.createElement("input");
1198         checkbox.setAttribute("type", "checkbox");
1199         checkbox.setAttribute("id", value["name"]);
1200         entry.push(checkbox);
1201         entry.push(value["name"]);
1202         entry.push(value["staticRoute"]);
1203         entry.push(value["nextHop"]);
1204         tr.entry = entry;
1205         result.push(tr);
1206       });
1207       return result;
1208     }
1209   }
1210 }
1211
1212 one.f.switchmanager.spanPortConfig = {
1213   id: {
1214     dashlet: {
1215       add: "one_f_switchmanager_spanPortConfig_id_dashlet_add",
1216       remove: "one_f_switchmanager_spanPortConfig_id_dashlet_remove",
1217       datagrid: "one_f_switchmanager_spanPortConfig_id_dashlet_datagrid",
1218       selectAllFlows: "one_f_switchmanager_spanPortConfig_id_dashlet_selectAllFlows"
1219     }, 
1220     modal: {
1221       modal: "one_f_switchmanager_spanPortConfig_id_modal_modal",
1222       save: "one_f_switchmanager_spanPortConfig_id_modal_save",
1223       cancel: "one_f_switchmanager_spanPortConfig_id_modal_cancel",
1224       remove: "one_f_switchmanager_spanPortConfig_id_modal_remove",
1225       form: {
1226         name : "one_f_switchmanager_spanPortConfig_id_modal_form_name",
1227         nodes : "one_f_switchmanager_spanPortConfig_id_modal_form_nodes",
1228         port : "one_f_switchmanager_spanPortConfig_id_modal_form_port",
1229       }
1230     }
1231   },
1232   dashlet: function($dashlet) {
1233     one.lib.dashlet.empty($dashlet);
1234
1235     //populate table in dashlet
1236     var url = one.f.switchmanager.rootUrl + "/spanPorts";
1237     one.f.switchmanager.spanPortConfig.ajax.main(url, {}, function(content) {
1238
1239       if (content.privilege === 'WRITE') {
1240
1241         // Add span port button
1242         var button = one.lib.dashlet.button.single("Add SPAN Port", one.f.switchmanager.spanPortConfig.id.dashlet.add, "btn-primary", "btn-mini");
1243         var $button = one.lib.dashlet.button.button(button);
1244
1245         $button.click(function() {
1246           var $modal = one.f.switchmanager.spanPortConfig.modal.initialize();
1247           $modal.modal();
1248         });
1249         $dashlet.append(one.lib.dashlet.header(one.f.dashlet.spanPortConfig.name));
1250         $dashlet.append($button);
1251
1252         // Delete span port button
1253         var button = one.lib.dashlet.button.single("Remove SPAN Port", one.f.switchmanager.spanPortConfig.id.dashlet.remove, "btn-danger", "btn-mini");
1254         var $button = one.lib.dashlet.button.button(button);
1255         $button.click(function() {
1256           var spanPortsToDelete = [];
1257           var checkedCheckBoxes = $("#" + one.f.switchmanager.spanPortConfig.id.dashlet.datagrid).find("tbody input:checked");
1258
1259           if (checkedCheckBoxes.size() === 0) {
1260             return false;
1261           }
1262           checkedCheckBoxes.each(function(index, value) {
1263             var spanPortObj = {};
1264             spanPortObj['spanPortJson'] = decodeURIComponent(checkedCheckBoxes[index].getAttribute("spanPort"));
1265             spanPortObj['spanPortNodeName'] = checkedCheckBoxes[index].getAttribute("spanPortNode");
1266             spanPortObj['spanPortPortName'] = checkedCheckBoxes[index].getAttribute("spanPortPort");
1267
1268             spanPortsToDelete.push(spanPortObj);
1269           });
1270           one.f.switchmanager.spanPortConfig.modal.removeMultiple.dialog(spanPortsToDelete);
1271         });
1272         $dashlet.append($button);
1273       }
1274       var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.spanPortConfig.id.dashlet.datagrid, {
1275         searchable: true,
1276           filterable: false,
1277           pagination: true,
1278           flexibleRowsPerPage: true
1279       }, "table-striped table-condensed");
1280       $dashlet.append($gridHTML);
1281       var dataSource = one.f.switchmanager.spanPortConfig.data.spanPortConfigGrid(content);
1282       $("#" + one.f.switchmanager.spanPortConfig.id.dashlet.datagrid).datagrid({dataSource: dataSource})
1283         .on("loaded", function() {
1284           $("#"+one.f.switchmanager.spanPortConfig.id.dashlet.selectAll).click(function() {
1285             $("#" + one.f.switchmanager.spanPortConfig.id.dashlet.datagrid).find(':checkbox').prop('checked',
1286               $("#"+one.f.switchmanager.spanPortConfig.id.dashlet.selectAll).is(':checked'));
1287           });
1288           $(".spanPortConfig").click(function(e){
1289             if (!$('.spanPortConfig[type=checkbox]:not(:checked)').length) {
1290               $("#"+one.f.switchmanager.spanPortConfig.id.dashlet.selectAll)
1291             .prop("checked",
1292               true);
1293             } else {
1294               $("#"+one.f.switchmanager.spanPortConfig.id.dashlet.selectAll)
1295             .prop("checked",
1296               false);
1297             }
1298             e.stopPropagation();
1299           });
1300         });
1301     });
1302   },
1303   // device ajax calls
1304   ajax : {
1305     main : function(url, requestData, callback) {
1306       $.getJSON(url, requestData, function(data) {
1307         callback(data);
1308       });
1309     }
1310   },
1311   registry: {},
1312   modal : {
1313     initialize: function() {
1314       var h3 = "Add SPAN Port";
1315       var footer = one.f.switchmanager.spanPortConfig.modal.footer();
1316       var $modal = one.lib.modal.spawn(one.f.switchmanager.spanPortConfig.id.modal.modal, h3, "", footer);
1317       // bind save button
1318       $('#' + one.f.switchmanager.spanPortConfig.id.modal.save, $modal).click(function() {
1319         one.f.switchmanager.spanPortConfig.modal.save($modal);
1320       });
1321
1322       one.f.switchmanager.spanPortConfig.modal.ajax.nodes(function(nodes, nodeports) {
1323         var $body = one.f.switchmanager.spanPortConfig.modal.body(nodes, nodeports);
1324         one.lib.modal.inject.body($modal, $body);
1325       });
1326       return $modal;
1327     },
1328     save: function($modal) {
1329       var result = {};
1330       result['nodeId'] = $('#' + one.f.switchmanager.spanPortConfig.id.modal.form.nodes, $modal).val();
1331       result['spanPort'] = $('#' + one.f.switchmanager.spanPortConfig.id.modal.form.port, $modal).val();
1332       one.f.switchmanager.spanPortConfig.modal.ajax.saveSpanPortConfig(result, 
1333           function(response) {
1334             if(response.status == true) {
1335               $modal.modal('hide');
1336               one.f.switchmanager.spanPortConfig.dashlet($("#right-bottom .dashlet"));
1337             } else {
1338               alert(response.message);
1339             }
1340
1341           });
1342     },
1343     body: function(nodes, nodeports) {
1344       var $form = $(document.createElement('form'));
1345       var $fieldset = $(document.createElement('fieldset'));
1346       // node
1347       var $label = one.lib.form.label("Node");
1348       var $select = one.lib.form.select.create(nodes);
1349       one.lib.form.select.prepend($select, { '' : 'Please Select a Node' });
1350       $select.val($select.find("option:first").val());
1351       $select.attr('id', one.f.switchmanager.spanPortConfig.id.modal.form.nodes);
1352
1353       // bind onchange
1354       $select.change(function() {
1355         // retrieve port value
1356         var nodeId = $(this).find('option:selected').attr('value');
1357         one.f.switchmanager.spanPortConfig.registry['currentNode'] = nodeId;
1358         var $ports = $('#'+one.f.switchmanager.spanPortConfig.id.modal.form.port);
1359         var ports = one.f.switchmanager.spanPortConfig.registry['nodePorts'][nodeId]
1360         var options = {};
1361       $(ports).each(function(idx, val) {
1362         options[val.internalPortName] = val.portName+' ('+val.portId+')'; 
1363           });
1364         one.lib.form.select.inject($ports, options); 
1365         one.lib.form.select.prepend($ports, {'':'Please Select a Port'});
1366         $ports.val($ports.find('option:first').val());
1367         });
1368
1369       $fieldset.append($label).append($select);
1370       // input port
1371       var $label = one.lib.form.label("Port");
1372       var $select = one.lib.form.select.create();
1373       one.lib.form.select.prepend($select, {'':'None'});
1374       $select.attr('id', one.f.switchmanager.spanPortConfig.id.modal.form.port);
1375       $select.val($select.find('option:first').val());
1376       $fieldset.append($label).append($select);
1377
1378       // return
1379       $form.append($fieldset);
1380       return $form;
1381     },
1382     ajax: {
1383       nodes: function(callback) {
1384         $.getJSON(one.f.switchmanager.rootUrl + "/nodeports", function(data) {
1385           var nodes = {};
1386           var nodePorts = {};
1387           $(data).each(function(index, node) {
1388             nodes[node.nodeId] = node.nodeName;
1389             nodePorts[node.nodeId] = node.nodePorts;
1390           });
1391           one.f.switchmanager.spanPortConfig.registry['nodePorts'] = nodePorts;
1392           callback(nodes, nodePorts);
1393         });
1394       },
1395       saveSpanPortConfig: function(requestData, callback) {
1396         var resource = {};
1397         resource["jsonData"] = JSON.stringify(requestData);
1398         $.getJSON(one.f.switchmanager.rootUrl + "/spanPorts/add", resource, function(data) {
1399           callback(data);
1400         });
1401       }
1402     },
1403     footer : function() {
1404       var footer = [];
1405       var saveButton = one.lib.dashlet.button.single("Save", one.f.switchmanager.spanPortConfig.id.modal.save, "btn-primary", "");
1406       var $saveButton = one.lib.dashlet.button.button(saveButton);
1407       footer.push($saveButton);
1408       return footer;
1409     },
1410     removeMultiple: {
1411       dialog: function(spanPortsToDelete) {
1412         var h3 = 'Remove SPAN Port';
1413
1414         var footer = one.f.switchmanager.spanPortConfig.modal.removeMultiple.footer();
1415         var $body = one.f.switchmanager.spanPortConfig.modal.removeMultiple.body(spanPortsToDelete);
1416         var $modal = one.lib.modal.spawn(one.f.switchmanager.spanPortConfig.id.modal.modal, h3, $body, footer);
1417
1418         // bind close button
1419         $('#'+one.f.switchmanager.spanPortConfig.id.modal.cancel, $modal).click(function() {
1420           $modal.modal('hide');
1421         });
1422
1423         // bind remove rule button
1424         $('#'+one.f.switchmanager.spanPortConfig.id.modal.remove, $modal).click(this, function(e) {
1425           var requestData = {};
1426           var spanPorts = [];
1427           $(spanPortsToDelete).each(function(index, spanPort) {
1428             spanPorts.push(JSON.parse(spanPort.spanPortJson));
1429           });
1430           requestData["spanPortsToDelete"] = JSON.stringify(spanPorts);
1431
1432           var url = one.f.switchmanager.rootUrl + "/spanPorts/delete";
1433           one.f.switchmanager.spanPortConfig.ajax.main(url, requestData, function(response) {
1434             $modal.modal('hide');
1435             if (response.status == true) {
1436               // refresh dashlet by passing dashlet div as param
1437               one.lib.alert("Span Port(s) successfully removed");
1438             } else {
1439               alert(response.message);
1440             }
1441             one.f.switchmanager.spanPortConfig.dashlet($("#right-bottom .dashlet"));
1442           });
1443         });
1444         $modal.modal();
1445       },
1446       footer : function() {
1447         var footer = [];
1448         var remove = one.lib.dashlet.button.single('Remove SPAN Port',one.f.switchmanager.spanPortConfig.id.modal.remove, 'btn-danger', '');
1449         var $remove = one.lib.dashlet.button.button(remove);
1450         footer.push($remove);
1451
1452         var cancel = one.lib.dashlet.button.single('Cancel', one.f.switchmanager.spanPortConfig.id.modal.cancel, '', '');
1453         var $cancel = one.lib.dashlet.button.button(cancel);
1454         footer.push($cancel);
1455
1456         return footer;
1457       },
1458       body : function (spanPortToDelete) {
1459         var $p = $(document.createElement('p'));
1460         var p = 'Remove the following Span Port(s)?';
1461         //creata a BS label for each rule and append to list
1462
1463         $(spanPortToDelete).each(function(index, spanPortItem) {
1464           var $span = $(document.createElement('span'));
1465           $span.append(this.spanPortNodeName+"-"+this.spanPortPortName);
1466           p += '<br/>' + $span[0].outerHTML;
1467         });
1468         $p.append(p);
1469         return $p;
1470       }
1471     }
1472   },
1473   // data functions
1474   data : {
1475     spanPortConfigGrid: function(data) {
1476       var source = new StaticDataSource({
1477         columns: [
1478       {
1479         property: 'selector',
1480       label: "<input type='checkbox'  id='"
1481         +one.f.switchmanager.spanPortConfig.id.dashlet.selectAll+"'/>",
1482       sortable: false
1483       },
1484       {
1485         property: 'nodeName',
1486       label: 'Node',
1487       sortable: true
1488       },
1489       {
1490         property: 'spanPortName',
1491       label: 'SPAN Port',
1492       sortable: true
1493       },
1494       ],
1495       data: data.nodeData,
1496       formatter: function(items) {
1497         $.each(items, function(index, item) {
1498           item["selector"] = '<input type="checkbox" class="spanPortConfig" spanPort=' + encodeURIComponent(item["json"]) + ' spanPortNode="' + item["nodeName"] + '" spanPortPort="' + item["spanPortName"] + '"></input>';
1499         });
1500       },
1501       delay: 0
1502       });
1503       return source;              
1504     },
1505     devices : function(data) {
1506       var result = [];
1507       $.each(data.nodeData, function(key, value) {
1508         var tr = {};
1509         // fill up all the td's
1510         var entry = [];
1511         var checkbox = document.createElement("input");
1512         checkbox.setAttribute("type", "checkbox");
1513         checkbox.spanPort = value.json;
1514         entry.push(checkbox);
1515         entry.push(value["nodeName"]);
1516         entry.push(value["spanPort"]);
1517         tr.entry = entry;
1518         result.push(tr);
1519       });
1520       return result;
1521     }
1522   }
1523 }
1524
1525 one.f.connection = {
1526   id : { // one.f.connection.id
1527     datagrid : 'one-f-connection-id-datagrid',
1528     add : 'one-f-connection-id-add'
1529   },
1530   dashlet: function($dashlet) {
1531     one.lib.dashlet.empty($dashlet);
1532     // heading
1533     $dashlet.append(one.lib.dashlet.header(one.f.dashlet.connection.name));
1534     // add button
1535     var add = one.lib.dashlet.button.single('Add Node', one.f.connection.id.add, 'btn-primary', 'btn-mini');
1536     var $add = one.lib.dashlet.button.button(add);
1537     $add.click(function() {
1538       one.f.connection.add.initialize();
1539     });
1540     $dashlet.append($add);
1541     // load table
1542     var url = one.f.switchmanager.rootUrl+'/connect/nodes';
1543     $.getJSON(url, function(data) {
1544       var $gridHTML = one.lib.dashlet.datagrid.init(one.f.connection.id.datagrid, {
1545         searchable: true,
1546         filterable: false,
1547         pagination: true,
1548         flexibleRowsPerPage: true
1549       }, 'table-striped table-condensed table-cursor');
1550       $dashlet.append($gridHTML);
1551       var dataSource = one.f.connection.data(data);
1552       $('#'+one.f.connection.id.datagrid, $dashlet).datagrid({dataSource:dataSource})
1553         .on('loaded', function() {
1554           $(this).find('tbody tr').click(function() {
1555             var nodeId = $(this).find('.nodeId').text();
1556             var nodeType = $(this).find('.nodeType').text();
1557             var nodeName = $(this).find('.nodeName').text();
1558             one.f.connection.remove.initialize(nodeId, nodeName, nodeType);
1559           });
1560         });
1561     });
1562   },
1563   data : function(data) {
1564     var source = new StaticDataSource({
1565       columns: [
1566       {
1567         property: 'nodeName',
1568         label: 'Node',
1569         sortable: true
1570       }
1571       ],
1572       data: data,
1573       formatter: function(items) {
1574         $.each(items, function(index, item) {
1575           var $nodeId = $(document.createElement('span'));
1576           $nodeId.css('display', 'none');
1577           var $nodeType = $nodeId.clone();
1578           var $nodeName = $nodeId.clone();
1579           $nodeId.append(item.nodeId).addClass('nodeId');
1580           $nodeType.append(item.nodeType).addClass('nodeType');
1581           $nodeName.append(item.nodeName).addClass('nodeName');
1582           item.nodeName += $nodeId[0].outerHTML+$nodeType[0].outerHTML+$nodeName[0].outerHTML;
1583         });
1584       },
1585       delay: 0
1586     });
1587     return source;              
1588   },
1589   add : {
1590     id : { // one.f.connection.add.id
1591       modal : 'one-f-connection-add-id-modal',
1592       add : 'one-f-connection-add-id-add',
1593       cancel : 'one-f-connection-add-id-cancel',
1594       form : {
1595         nodeId : 'one-f-connection-add-id-form-nodeId',
1596         ipAddress : 'one-f-connection-add-id-form-ipAddress',
1597         port : 'one-f-connection-add-id-form-port',
1598         nodeType : 'one-f-connection-add-id-form-nodeType'
1599       }
1600     },
1601     initialize : function() {
1602       var h3 = 'Add Node';
1603       var footer = one.f.connection.add.footer();
1604       var $body = one.f.connection.add.body();;
1605       var $modal = one.lib.modal.spawn(one.f.connection.add.id.modal, h3, $body, footer);
1606       // bind add buton
1607       $('#'+one.f.connection.add.id.add, $modal).click(function() {
1608         var nodeId = $('#'+one.f.connection.add.id.form.nodeId, $modal).val();
1609         if (nodeId === '') {
1610           alert('Please enter a node ID');
1611           return false;
1612         }
1613         var resources = {};
1614         resources.ipAddress = $('#'+one.f.connection.add.id.form.ipAddress, $modal).val();
1615         if (resources.ipAddress === '') {
1616           alert('Please enter an IP Address');
1617           return false;
1618         }
1619         resources.port = $('#'+one.f.connection.add.id.form.port, $modal).val();
1620         if (resources.port === '') {
1621           alert('Please enter a port');
1622           return false;
1623         }
1624         var nodeType = $('#'+one.f.connection.add.id.form.nodeType, $modal).val();
1625         if (nodeType !== '') {
1626           resources.nodeType = nodeType;
1627         }
1628         var url = one.f.switchmanager.rootUrl+'/connect/'+encodeURI(nodeId);
1629         $.post(url, resources, function(result) {
1630           if (result.success === true) {
1631             $modal.modal('hide');
1632             one.lib.alert(result.description);
1633           } else {
1634             alert(result.code+': '+result.description);
1635           }
1636         });
1637       });
1638       // bind cancel button
1639       $('#'+one.f.connection.add.id.cancel, $modal).click(function() {
1640         $modal.modal('hide');
1641       });
1642       $modal.modal();
1643     },
1644     body : function() {
1645       var $form = $(document.createElement('form'));
1646       var $fieldset = $(document.createElement('fieldset'));
1647       // node id
1648       var $label = one.lib.form.label('Node ID');
1649       var $input = one.lib.form.input('Node ID');
1650       $input.attr('id', one.f.connection.add.id.form.nodeId);
1651       $fieldset.append($label).append($input);
1652       // ip address
1653       $label = one.lib.form.label('IP Address');
1654       $input = one.lib.form.input('IP Address');
1655       $input.attr('id', one.f.connection.add.id.form.ipAddress);
1656       $fieldset.append($label).append($input);
1657       // port
1658       $label = one.lib.form.label('Port');
1659       $input = one.lib.form.input('Port');
1660       $input.attr('id', one.f.connection.add.id.form.port);
1661       var $help = one.lib.form.help('Enter a number');
1662       $fieldset.append($label).append($input).append($help);
1663       // node type
1664       $label = one.lib.form.label('Node Type');
1665       $input = one.lib.form.input('Node Type');
1666       $input.attr('id', one.f.connection.add.id.form.nodeType);
1667       $help = one.lib.form.help('Optional');
1668       $fieldset.append($label).append($input).append($help);
1669       $form.append($fieldset);
1670       return $form;
1671     },
1672     footer : function() {
1673       var footer = [];
1674       var add = one.lib.dashlet.button.single('Submit', one.f.connection.add.id.add, 'btn-primary', '');
1675       var $add = one.lib.dashlet.button.button(add);
1676       footer.push($add);
1677       var cancel = one.lib.dashlet.button.single('Cancel', one.f.connection.add.id.cancel, '', '');
1678       var $cancel = one.lib.dashlet.button.button(cancel);
1679       footer.push($cancel);
1680       return footer;
1681     }
1682   },
1683   remove : {
1684     id : { // one.f.connection.remove.id
1685       modal : 'one-f-connection-remove-id-modal',
1686       remove : 'one-f-connection-remove-id-remove',
1687       cancel : 'one-f-connection-remove-id-cancel'
1688     },
1689     initialize : function(nodeId, nodeName, nodeType) {
1690       var h3 = 'Remove Node';
1691       var footer = one.f.connection.remove.footer();
1692       var $body = one.f.connection.remove.body(nodeName);
1693       var $modal = one.lib.modal.spawn(one.f.connection.remove.id.modal, h3, $body, footer);
1694       // bind remove buton
1695       $('#'+one.f.connection.remove.id.remove, $modal).click(function() {
1696         var resources = {};
1697         resources.nodeType = nodeType;
1698         var url = one.f.switchmanager.rootUrl+'/disconnect/'+encodeURI(nodeId);
1699         $.post(url, resources, function(result) {
1700           if (result.success === true) {
1701             $modal.modal('hide');
1702             one.lib.alert(result.description);
1703           } else {
1704             alert(result.code+': '+result.description);
1705           }
1706         }).fail(function() { debugger; });
1707       });
1708       // bind cancel button
1709       $('#'+one.f.connection.remove.id.cancel, $modal).click(function() {
1710         $modal.modal('hide');
1711       });
1712       $modal.modal();
1713     },
1714     body : function(nodeName) {
1715       var $p = $(document.createElement('p'));
1716       $p.append('Remove the following node? ');
1717       var $span = $(document.createElement('span'));
1718       $span.addClass('label label-info');
1719       $span.append(nodeName);
1720       $p.append($span[0].outerHTML);
1721       return $p;
1722     },
1723     footer : function() {
1724       var footer = [];
1725       var remove = one.lib.dashlet.button.single('Remove', one.f.connection.remove.id.remove, 'btn-danger', '');
1726       var $remove = one.lib.dashlet.button.button(remove);
1727       footer.push($remove);
1728       var cancel = one.lib.dashlet.button.single('Cancel', one.f.connection.remove.id.cancel, '', '');
1729       var $cancel = one.lib.dashlet.button.button(cancel);
1730       footer.push($cancel);
1731       return footer;
1732     }
1733   }
1734 }
1735
1736 /** INIT **/
1737 // populate nav tabs
1738 $(one.f.menu.left.top).each(function(index, value) {
1739   var $nav = $(".nav", "#left-top");
1740   one.main.page.dashlet($nav, value);
1741 });
1742
1743 $(one.f.menu.left.bottom).each(function(index, value) {
1744   var $nav = $(".nav", "#left-bottom");
1745   one.main.page.dashlet($nav, value);
1746 });
1747
1748 $(one.f.menu.right.bottom).each(function(index, value) {
1749   var $nav = $(".nav", "#right-bottom");
1750   one.main.page.dashlet($nav, value);
1751 });
1752
1753 one.f.addPopOut = function() {
1754   $img1 = $(document.createElement("img"));
1755   $img1.attr("src", "/img/Expand16T.png");
1756   $img1.attr("style", "float: right;");
1757   $img1.hover(function() {
1758     $img1.css("cursor", "pointer");
1759   });
1760   $img1.click(function() {
1761     var $modal = one.f.switchmanager.nodesLearnt.modal.initialize.popout();
1762     $modal.css({
1763       'margin-left': '-45%',
1764       'margin-top': '-3%',
1765       'width':$(document).width() * 0.8,
1766       'height':$(document).height() * 0.9
1767     });
1768     $(".modal-body", $modal).css({
1769       "max-height": $(document).height() * 0.75,
1770     });
1771     $modal.modal();
1772   });
1773   $dash1 = $($("#left-top .nav")[0]);
1774   $dash1.append($img1);
1775 };
1776 one.f.addPopOut();
1777
1778 // bind dashlet nav
1779 $('.dash .nav a', '#main').click(function() {
1780   // de/activation
1781   var $li = $(this).parent();
1782   var $ul = $li.parent();
1783   one.lib.nav.unfocus($ul);
1784   $li.addClass('active');
1785   // clear respective dashlet
1786   var $dashlet = $ul.parent().find('.dashlet');
1787   one.lib.dashlet.empty($dashlet);
1788
1789   // callback based on menu
1790   var id = $(this).attr('id');
1791   var menu = one.f.dashlet;
1792   switch (id) {
1793     case menu.nodesLearnt.id:
1794       one.f.switchmanager.nodesLearnt.dashlet($dashlet);
1795       break;
1796     case menu.staticRouteConfig.id:
1797       one.f.switchmanager.staticRouteConfig.dashlet($dashlet);
1798       break;
1799     case menu.subnetGatewayConfig.id:
1800       one.f.switchmanager.subnetGatewayConfig.dashlet($dashlet);
1801       break;
1802     case menu.spanPortConfig.id:
1803       one.f.switchmanager.spanPortConfig.dashlet($dashlet);
1804       break;
1805     case menu.connection.id:
1806       one.f.connection.dashlet($dashlet);
1807       break;
1808   };
1809 });
1810
1811 // activate first tab on each dashlet
1812 $('.dash .nav').each(function(index, value) {
1813   $($(value).find('li')[0]).find('a').click();
1814 });