Replace exception.printStacktrace with write to log.
[controller.git] / opendaylight / web / flows / 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 flows
10 one.f = {};
11
12 // specify dashlets and layouts
13 one.f.dashlet = {
14     flows : {
15         id : 'flows',
16         name : 'Flow Entries'
17     },
18     nodes : {
19         id : 'nodes',
20         name : 'Nodes'
21     },
22     detail : {
23         id : 'detail',
24         name : 'Flow Detail'
25     }
26 };
27
28 one.f.menu = {
29     left : {
30         top : [
31             one.f.dashlet.flows
32         ],
33         bottom : [
34             one.f.dashlet.nodes
35         ]
36     },
37     right : {
38         top : [],
39         bottom : [
40             one.f.dashlet.detail
41         ]
42     }
43 };
44
45 one.f.address = {
46     root : "/controller/web/flows",
47     flows : {
48         main : "/main",
49         flows : "/node-flows",
50         nodes : "/node-ports",
51         flow : "/flow",
52         deleteFlows:"/flow/deleteFlows"
53     }
54 }
55
56 /** NODES **/
57 one.f.nodes = {
58     id : {
59         dashlet: {
60             datagrid: "one_f_nodes_id_dashlet_datagrid"
61         }
62     },
63     registry : {},
64     dashlet : function($dashlet) {
65         var $h4 = one.lib.dashlet.header("Nodes");
66         $dashlet.append($h4);
67
68         one.f.nodes.ajax.dashlet(function(data) {
69             var $gridHTML = one.lib.dashlet.datagrid.init(one.f.nodes.id.dashlet.datagrid, {
70                 searchable: true,
71                 filterable: false,
72                 pagination: true,
73                 flexibleRowsPerPage: true
74                 }, "table-striped table-condensed");
75             $dashlet.append($gridHTML);
76             var dataSource = one.f.nodes.data.nodesDataGrid(data);
77             $("#" + one.f.nodes.id.dashlet.datagrid).datagrid({dataSource: dataSource});
78         });
79     },
80     ajax : {
81         dashlet : function(callback) {
82             $.getJSON(one.f.address.root+one.f.address.flows.flows, function(data) {
83                 callback(data);
84             });
85         }
86     },
87     data : {
88         nodesDataGrid: function(data) {
89             var gridData = [];
90             $.each(data, function(nodeName, flow) {
91                 var nodeFlowObject = {};
92                 nodeFlowObject["nodeName"] = nodeName;
93                 nodeFlowObject["flows"] = flow;
94                 nodeFlowObject["rowData"] = nodeName + flow + "-foobar";
95                 gridData.push(nodeFlowObject);
96             });
97
98             var source = new StaticDataSource({
99                     columns: [
100                         {
101                             property: 'nodeName',
102                             label: 'Node',
103                             sortable: true
104                         },
105                         {
106                             property: 'flows',
107                             label: 'Flows',
108                             sortable: true
109                         }
110                     ],
111                     data: gridData,
112                     delay: 0
113                 });
114             return source;
115         }
116     },
117     body : {
118         dashlet : function(body, callback) {
119             var attributes = ['table-striped', 'table-bordered', 'table-hover', 'table-condensed'];
120             var $table = one.lib.dashlet.table.table(attributes);
121
122             var headers = ['Node', 'Flows'];
123             var $thead = one.lib.dashlet.table.header(headers);
124             $table.append($thead);
125
126             var $tbody = one.lib.dashlet.table.body(body);
127             $table.append($tbody);
128
129             return $table;
130         }
131     }
132 }
133
134 /** FLOW DETAIL **/
135 one.f.detail = {
136     id : {},
137     registry : {},
138     dashlet : function($dashlet, details) {
139         var $h4 = one.lib.dashlet.header("Flow Details");
140         $dashlet.append($h4);
141
142         // details
143         if (details == undefined) {
144             var $none = $(document.createElement('div'));
145             $none.addClass('none');
146             var $p = $(document.createElement('p'));
147             $p.text('Please select a flow');
148             $p.addClass('text-center').addClass('text-info');
149
150             $dashlet.append($none)
151                 .append($p);
152         }
153     },
154     data : {
155         dashlet : function(data) {
156             var body = [];
157             var tr = {};
158             var entry = [];
159
160             entry.push(data['name']);
161             entry.push(data['node']);
162             entry.push(data['flow']['priority']);
163             entry.push(data['flow']['hardTimeout']);
164             entry.push(data['flow']['idleTimeout']);
165
166             tr.entry = entry;
167             body.push(tr);
168             return body;
169         },
170         description : function(data) {
171             var body = [];
172             var tr = {};
173             var entry = [];
174                         entry.push(data['flow']['ingressPort']);
175             entry.push(data['flow']['etherType']);
176             entry.push(data['flow']['vlanId']);
177             entry.push(data['flow']['vlanPriority']);
178             entry.push(data['flow']['srcMac']);
179             entry.push(data['flow']['dstMac']);
180             entry.push(data['flow']['srcIp']);
181             entry.push(data['flow']['dstIp']);
182             entry.push(data['flow']['tosBits']);
183             entry.push(data['flow']['srcPort']);
184             entry.push(data['flow']['dstPort']);
185             entry.push(data['flow']['protocol']);
186             entry.push(data['flow']['cookie']);
187
188             tr.entry = entry;
189             body.push(tr);
190             return body;
191         },
192         actions : function(data) {
193             var body = [];
194             var tr = {};
195             var entry = [];
196
197             var actions = '';
198             $(data['flow']['actions']).each(function(index, value) {
199                 actions += value + ', ';
200             });
201             actions = actions.slice(0,-2);
202             entry.push(actions);
203
204             tr.entry = entry;
205             body.push(tr);
206             return body;
207         }
208     },
209     body : {
210         dashlet : function(body) {
211             // create table
212             var header = ['Flow Name', 'Node', 'Priority', 'Hard Timeout', 'Idle Timeout'];
213             var $thead = one.lib.dashlet.table.header(header);
214             var attributes = ['table-striped', 'table-bordered', 'table-condensed'];
215             var $table = one.lib.dashlet.table.table(attributes);
216             $table.append($thead);
217
218             var $tbody = one.lib.dashlet.table.body(body);
219             $table.append($tbody);
220
221             return $table;
222         },
223         description : function(body) {
224             var header = ['Input Port', 'Ethernet Type', 'VLAN ID', 'VLAN Priority', 'Source MAC', 'Dest MAC', 'Source IP', 'Dest IP', 'TOS', 'Source Port', 'Dest Port', 'Protocol', 'Cookie'];
225             var $thead = one.lib.dashlet.table.header(header);
226             var attributes = ['table-striped', 'table-bordered', 'table-condensed'];
227             var $table = one.lib.dashlet.table.table(attributes);
228             $table.append($thead);
229
230             var $tbody = one.lib.dashlet.table.body(body);
231             $table.append($tbody);
232
233             return $table;
234         },
235         actions : function(body) {
236             var header = ['Actions'];
237             var $thead = one.lib.dashlet.table.header(header);
238             var attributes = ['table-striped', 'table-bordered', 'table-condensed'];
239             var $table = one.lib.dashlet.table.table(attributes);
240             $table.append($thead);
241
242             var $tbody = one.lib.dashlet.table.body(body);
243             $table.append($tbody);
244
245             return $table;
246         }
247     }
248 }
249
250 /** FLOW ENTRIES **/
251 one.f.flows = {
252     id : {
253         dashlet : {
254             add : "one_f_flows_id_dashlet_add",
255             removeMultiple : "one_f_flows_id_dashlet_removeMultiple",
256             remove : "one_f_flows_id_dashlet_remove",
257             toggle : "one_f_flows_id_dashlet_toggle",
258             datagrid : "one_f_flows_id_dashlet_datagrid",
259             selectAllFlows : "one_f_flows_id_dashlet_selectAllFlows"
260         },
261         modal : {
262             install : "one_f_flows_id_modal_install",
263             add : "one_f_flows_id_modal_add",
264             close : "one_f_flows_id_modal_close",
265             modal : "one_f_flows_id_modal_modal",
266             dialog : {
267                 modal : "one_f_flows_id_modal_dialog_modal",
268                 remove : "one_f_flows_id_modal_dialog_remove",
269                 close : "one_f_flows_id_modal_dialog_close"
270             },
271             action : {
272                 button : "one_f_flows_id_modal_action_button",
273                 modal : "one_f_flows_id_modal_action_modal",
274                 add : "one_f_flows_id_modal_action_add",
275                 close : "one_f_flows_id_modal_action_close",
276                 table : "one_f_flows_id_modal_action_table",
277                 addOutputPorts : "one_f_flows_id_modal_action_addOutputPorts",
278                 setVlanId : "one_f_flows_id_modal_action_setVlanId",
279                 setVlanPriority : "one_f_flows_id_modal_action_setVlanPriority",
280                 modifyDatalayerSourceAddress : "one_f_flows_id_modal_action_modifyDatalayerSourceAddress",
281                 modifyDatalayerDestinationAddress : "one_f_flows_id_modal_action_modifyDatalayerDestinationAddress",
282                 modifyNetworkSourceAddress : "one_f_flows_modal_action_modifyNetworkSourceAddress",
283                 modifyNetworkDestinationAddress : "one_f_flows_modal_action_modifyNetworkDestinationAddress",
284                 modifyTosBits : "one_f_flows_modal_action_modifyTosBits",
285                 modifyTransportSourcePort : "one_f_flows_modal_action_modifyTransportSourcePort",
286                 modifyTransportDestinationPort : "one_f_flows_modal_action_modifyTransportDestinationPort",
287                 modal : {
288                     modal : "one_f_flows_modal_action_modal_modal",
289                     remove : "one_f_flows_modal_action_modal_remove",
290                     cancel : "one_f_flows_modal_action_modal_cancel"
291                 }
292             },
293             form : {
294                 name : "one_f_flows_id_modal_form_name",
295                 nodes : "one_f_flows_id_modal_form_nodes",
296                 port : "one_f_flows_id_modal_form_port",
297                 priority : "one_f_flows_id_modal_form_priority",
298                 hardTimeout : "one_f_flows_id_modal_form_hardTimeout",
299                 idleTimeout : "one_f_flows_id_modal_form_idleTimeout",
300                 cookie : "one_f_flows_id_modal_form_cookie",
301                 etherType : "one_f_flows_id_modal_form_etherType",
302                 vlanId : "one_f_flows_id_modal_form_vlanId",
303                 vlanPriority : "one_f_flows_id_modal_form_vlanPriority",
304                 srcMac : "one_f_flows_id_modal_form_srcMac",
305                 dstMac : "one_f_flows_id_modal_form_dstMac",
306                 srcIp : "one_f_flows_id_modal_form_srcIp",
307                 dstIp : "one_f_flows_id_modal_form_dstIp",
308                 tosBits : "one_f_flows_id_modal_form_tosBits",
309                 srcPort : "one_f_flows_id_modal_form_srcPort",
310                 dstPort : "one_f_flows_id_modal_form_dstPort",
311                 protocol : "one_f_flows_id_modal_form_protocol"
312             }
313         }
314     },
315     registry : {},
316     dashlet : function($dashlet, callback) {
317
318         // load body
319         one.f.flows.ajax.dashlet(function(data) {
320
321             var $h4 = one.lib.dashlet.header("Flow Entries");
322
323             $dashlet.append($h4);
324             if (one.f.flows.registry.privilege === 'WRITE') {
325                 var button = one.lib.dashlet.button.single("Add Flow Entry", one.f.flows.id.dashlet.add, "btn-primary", "btn-mini");
326                 var $button = one.lib.dashlet.button.button(button);
327
328                 $button.click(function() {
329                     var $modal = one.f.flows.modal.initialize();
330                     $modal.modal();
331                 });
332                 $dashlet.append($button);
333                 var button = one.lib.dashlet.button.single("Remove Flow Entry", one.f.flows.id.dashlet.removeMultiple, "btn-danger", "btn-mini");
334                 var $button = one.lib.dashlet.button.button(button);
335
336                 $button.click(function() {
337                     var checkedCheckBoxes = $('.flowEntry[type=checkbox]:checked');
338                     if (checkedCheckBoxes.size() === 0) {
339                         alert('Please select at least one flow');
340                         return false;
341                     }
342                     
343                     var requestData = [];
344                     
345                     var resource = {};
346                     checkedCheckBoxes.each(function(index, value) {
347                         var flowEntry = {};
348                         flowEntry['name'] = checkedCheckBoxes[index].name;
349                         flowEntry['node'] = checkedCheckBoxes[index].getAttribute("node");
350                         requestData.push(flowEntry);  
351                     });
352                     resource['body'] = JSON.stringify(requestData);
353
354                     $.post(one.f.address.root+one.f.address.flows.deleteFlows, resource, function(response) {
355                         if(response == "Success") {
356                             one.lib.alert("Flow(s) successfully removed");                            
357                         } else {
358                             one.lib.alert(response);
359                         }
360                         one.main.dashlet.right.bottom.empty();
361                         one.f.detail.dashlet(one.main.dashlet.right.bottom);
362                         one.main.dashlet.left.top.empty();
363                         one.f.flows.dashlet(one.main.dashlet.left.top);
364                     });                    
365                 });
366                 $dashlet.append($button);
367
368             }
369
370             var $gridHTML = one.lib.dashlet.datagrid.init(one.f.flows.id.dashlet.datagrid, {
371                 searchable: true,
372                 filterable: false,
373                 pagination: true,
374                 flexibleRowsPerPage: true
375                 }, "table-striped table-condensed");
376             $dashlet.append($gridHTML);
377             var dataSource = one.f.flows.data.flowsDataGrid(data);
378             $("#" + one.f.flows.id.dashlet.datagrid).datagrid({dataSource: dataSource}).on("loaded", function() {
379                     $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows).click(function() {
380                                 $("#" + one.f.flows.id.dashlet.datagrid).find(':checkbox').prop('checked',
381                                         $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows).is(':checked'));
382                     });
383                     
384                     $("#" + one.f.flows.id.dashlet.datagrid).find("tbody tr").each(function(index, tr) {
385                     $tr = $(tr);
386                     $span = $("td span", $tr);
387                     var flowstatus = $span.data("flowstatus");
388                     if($span.data("installinhw") != null) {
389                         var installInHw = $span.data("installinhw").toString();
390                         if(installInHw == "true" && flowstatus == "Success") {
391                             $tr.addClass("success");
392                         } else {
393                             $tr.addClass("warning");
394                         }
395                     }
396                     // attach mouseover to show pointer cursor
397                     $tr.mouseover(function() {
398                         $(this).css("cursor", "pointer");
399                     });
400                     // attach click event
401                     $tr.click(function() {
402                         var $td = $($(this).find("td")[1]);
403                         var id = $td.text();
404                         var node = $td.find("span").data("nodeid");
405                         one.f.flows.detail(id, node);
406                     });
407                     $(".flowEntry").click(function(e){
408                                 if (!$('.flowEntry[type=checkbox]:not(:checked)').length) {
409                             $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows)
410                                 .prop("checked",
411                               true);
412                         } else {
413                             $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows)
414                                 .prop("checked",
415                              false);
416                         }
417                         e.stopPropagation();
418                     });
419                 });
420             });
421             
422             // details callback
423             if(callback != undefined) callback();
424         });
425     },
426     detail : function(id, node) {
427         // clear flow details
428         var $detailDashlet = one.main.dashlet.right.bottom;
429         $detailDashlet.empty();
430         var $h4 = one.lib.dashlet.header("Flow Overview");
431         $detailDashlet.append($h4);
432
433         // details
434         var flows = one.f.flows.registry.flows;
435         var flow;
436         $(flows).each(function(index, value) {
437             if (value['name'] == id) {
438                 flow = value;
439             }
440         });
441         if (one.f.flows.registry.privilege === 'WRITE') {
442             // remove button
443             var button = one.lib.dashlet.button.single("Remove Flow", one.f.flows.id.dashlet.remove, "btn-danger", "btn-mini");
444             var $button = one.lib.dashlet.button.button(button);
445             $button.click(function() {
446                 var $modal = one.f.flows.modal.dialog.initialize(id, node);
447                 $modal.modal();
448             });
449             // toggle button
450             var toggle;
451             if (flow['flow']['installInHw'] == 'true' && flow['flow']['status'] == 'Success') {
452                 toggle = one.lib.dashlet.button.single("Uninstall Flow", one.f.flows.id.dashlet.toggle, "btn-warning", "btn-mini");
453             } else {
454                 toggle = one.lib.dashlet.button.single("Install Flow", one.f.flows.id.dashlet.toggle, "btn-success", "btn-mini");
455             }
456             var $toggle = one.lib.dashlet.button.button(toggle);
457             $toggle.click(function() {
458                 one.f.flows.modal.ajax.toggleflow(id, node, function(data) {
459                     if(data == "Success") {
460                         one.main.dashlet.right.bottom.empty();
461                         one.f.detail.dashlet(one.main.dashlet.right.bottom);
462                         one.main.dashlet.left.top.empty();
463                         one.f.flows.dashlet(one.main.dashlet.left.top, function() {
464                            // checks are backwards due to stale registry
465                            if(flow['flow']['installInHw'] == 'true') {
466                                one.lib.alert('Uninstalled Flow');
467                            } else {
468                                one.lib.alert('Installed Flow');
469                            }
470                            one.f.flows.detail(id, node)
471                         });
472                     } else {
473                         one.lib.alert('Cannot toggle flow: '+data);
474                     }
475                 });
476             });
477
478             $detailDashlet.append($button).append($toggle);
479         }
480         // append details
481         var body = one.f.detail.data.dashlet(flow);
482         var $body = one.f.detail.body.dashlet(body);
483         $detailDashlet.append($body);
484         var body = one.f.detail.data.description(flow);
485         var $body = one.f.detail.body.description(body);
486         $detailDashlet.append($body);
487         var body = one.f.detail.data.actions(flow);
488         var $body = one.f.detail.body.actions(body);
489         $detailDashlet.append($body);
490     },
491     modal : {
492         dialog : {
493             initialize : function(id, node) {
494                 var h3 = "Remove Flow?";
495                 var $p = one.f.flows.modal.dialog.body(id);
496                 var footer = one.f.flows.modal.dialog.footer();
497                 var $modal = one.lib.modal.spawn(one.f.flows.id.modal.dialog.modal, h3, $p, footer);
498                 $('#'+one.f.flows.id.modal.dialog.close, $modal).click(function() {
499                     $modal.modal('hide');
500                 });
501                 $('#'+one.f.flows.id.modal.dialog.remove, $modal).click(function() {
502                     one.f.flows.modal.ajax.removeflow(id, node, function(data) {
503                         if (data == "Success") {
504                             $modal.modal('hide');
505                             one.main.dashlet.right.bottom.empty();
506                             one.f.detail.dashlet(one.main.dashlet.right.bottom);
507                             one.main.dashlet.left.top.empty();
508                             one.f.flows.dashlet(one.main.dashlet.left.top);
509                             one.lib.alert('Flow removed');
510                         } else {
511                             one.lib.alert('Cannot remove flow: '+data);
512                         }
513                     });
514                 });
515                 return $modal;
516             },
517             footer : function() {
518                 var footer = [];
519
520                 var removeButton = one.lib.dashlet.button.single("Remove Flow", one.f.flows.id.modal.dialog.remove, "btn-danger", "");
521                 var $removeButton = one.lib.dashlet.button.button(removeButton);
522                 footer.push($removeButton);
523
524                 var closeButton = one.lib.dashlet.button.single("Cancel", one.f.flows.id.modal.dialog.close, "", "");
525                 var $closeButton = one.lib.dashlet.button.button(closeButton);
526                 footer.push($closeButton);
527
528                 return footer;
529             },
530             body : function(id) {
531                 var $p = $(document.createElement('p'));
532                 $p.append('Remove flow '+id+'?');
533                 return $p;
534             }
535         },
536         initialize : function() {
537             var h3 = "Add Flow Entry";
538             var footer = one.f.flows.modal.footer();
539             var $modal = one.lib.modal.spawn(one.f.flows.id.modal.modal, h3, "", footer);
540
541             // bind close button
542             $('#'+one.f.flows.id.modal.close, $modal).click(function() {
543                 $modal.modal('hide');
544             });
545
546             // bind add flow button
547             $('#'+one.f.flows.id.modal.add, $modal).click(function() {
548                 one.f.flows.modal.add($modal, 'false');
549             });
550
551             // bind install flow button
552             $('#'+one.f.flows.id.modal.install, $modal).click(function() {
553                 one.f.flows.modal.add($modal, 'true');
554             });
555
556             // inject body (nodePorts)
557             one.f.flows.modal.ajax.nodes(function(nodes, nodeports) {
558                 var $body = one.f.flows.modal.body(nodes, nodeports);
559                 one.lib.modal.inject.body($modal, $body);
560             });
561
562             return $modal;
563         },
564         add : function($modal, install) {
565             var result = {};
566
567             result['name'] = $('#'+one.f.flows.id.modal.form.name, $modal).val();
568             result['ingressPort'] = $('#'+one.f.flows.id.modal.form.port, $modal).val();
569             result['priority'] = $('#'+one.f.flows.id.modal.form.priority, $modal).val();
570             result['hardTimeout'] = $('#'+one.f.flows.id.modal.form.hardTimeout, $modal).val();
571             result['idleTimeout'] = $('#'+one.f.flows.id.modal.form.idleTimeout, $modal).val();
572             result['cookie'] = $('#'+one.f.flows.id.modal.form.cookie, $modal).val();
573             result['etherType'] = $('#'+one.f.flows.id.modal.form.etherType, $modal).val();
574             result['vlanId'] = $('#'+one.f.flows.id.modal.form.vlanId, $modal).val();
575             result['vlanPriority'] = $('#'+one.f.flows.id.modal.form.vlanPriority, $modal).val();
576             result['dlSrc'] = $('#'+one.f.flows.id.modal.form.srcMac, $modal).val();
577             result['dlDst'] = $('#'+one.f.flows.id.modal.form.dstMac, $modal).val();
578             result['nwSrc'] = $('#'+one.f.flows.id.modal.form.srcIp, $modal).val();
579             result['nwDst'] = $('#'+one.f.flows.id.modal.form.dstIp, $modal).val();
580             result['tosBits'] = $('#'+one.f.flows.id.modal.form.tosBits, $modal).val();
581             result['tpSrc'] = $('#'+one.f.flows.id.modal.form.srcPort, $modal).val();
582             result['tpDst'] = $('#'+one.f.flows.id.modal.form.dstPort, $modal).val();
583             result['protocol'] = $('#'+one.f.flows.id.modal.form.protocol, $modal).val();
584
585             result['installInHw'] = install;
586
587             var nodeId = $('#'+one.f.flows.id.modal.form.nodes, $modal).val();
588
589             $.each(result, function(key, value) {
590                 if (value == "") delete result[key];
591             });
592
593             var action = [];
594             var $table = $('#'+one.f.flows.id.modal.action.table, $modal);
595             $($table.find('tbody').find('tr')).each(function(index, value) {
596                 if (!$(this).find('td').hasClass('empty')) {
597                     action.push($(value).data('action'));
598                 }
599             });
600             result['actions'] = action;
601
602             // frontend validation
603             if (result['name'] == undefined) {
604                 alert('Need flow name');
605                 return;
606             }
607             if (nodeId == '') {
608                 alert('Select node');
609                 return;
610             }
611             if (action.length == 0) {
612                 alert('Please specify an action');
613                 return;
614             }
615
616             // package for ajax call
617             var resource = {};
618             resource['body'] = JSON.stringify(result);
619             resource['action'] = 'add';
620             resource['nodeId'] = nodeId;
621
622             one.f.flows.modal.ajax.saveflow(resource, function(data) {
623                 if (data == "Success") {
624                     $modal.modal('hide');
625                     one.lib.alert('Flow added');
626                     one.main.dashlet.left.top.empty();
627                     one.f.flows.dashlet(one.main.dashlet.left.top);
628                 } else {
629                     alert('Could not add flow: '+data);
630                 }
631             });
632         },
633         ajax : {
634             nodes : function(successCallback) {
635                 $.getJSON(one.f.address.root+one.f.address.flows.nodes, function(data) {
636                     var nodes = one.f.flows.modal.data.nodes(data);
637                     var nodeports = data;
638                     one.f.flows.registry['nodeports'] = nodeports;
639
640                     successCallback(nodes, nodeports);
641                 });
642             },
643             saveflow : function(resource, callback) {
644                 $.post(one.f.address.root+one.f.address.flows.flow, resource, function(data) {
645                     callback(data);
646                 });
647             },
648             removeflow : function(id, node, callback) {
649                 resource = {};
650                 resource['action'] = 'remove';
651                 $.post(one.f.address.root+one.f.address.flows.flow+'/'+node+'/'+id, resource, function(data) {
652                     callback(data);
653                 });
654             },
655             toggleflow : function(id, node, callback) {
656                 resource = {};
657                 resource['action'] = 'toggle';
658                 $.post(one.f.address.root+one.f.address.flows.flow+'/'+node+'/'+id, resource, function(data) {
659                     callback(data);
660                 });
661             }
662         },
663         data : {
664             nodes : function(data) {
665                 result = {};
666                 $.each(data, function(key, value) {
667                     result[key] = value['name'];
668                 });
669                 return result;
670             }
671         },
672         body : function(nodes, nodeports) {
673             var $form = $(document.createElement('form'));
674             var $fieldset = $(document.createElement('fieldset'));
675             // flow description
676             var $legend = one.lib.form.legend("Flow Description");
677             $fieldset.append($legend);
678             // name
679             var $label = one.lib.form.label("Name");
680             var $input = one.lib.form.input("Flow Name");
681             $input.attr('id', one.f.flows.id.modal.form.name);
682             $fieldset.append($label).append($input);
683             // node
684             var $label = one.lib.form.label("Node");
685             var $select = one.lib.form.select.create(nodes);
686             one.lib.form.select.prepend($select, { '' : 'Please Select a Node' });
687             $select.val($select.find("option:first").val());
688             $select.attr('id', one.f.flows.id.modal.form.nodes);
689
690             // bind onchange
691             $select.change(function() {
692                 // retrieve port value
693                 var node = $(this).find('option:selected').attr('value');
694                 var $ports = $('#'+one.f.flows.id.modal.form.port);
695                 if (node == '') {
696                     one.lib.form.select.inject($ports, {});
697                     return;
698                 }
699                 one.f.flows.registry['currentNode'] = node;
700                 var ports = nodeports[node]['ports'];
701                 one.lib.form.select.inject($ports, ports);
702                 one.lib.form.select.prepend($ports, { '' : 'Please Select a Port' });
703                 $ports.val($ports.find("option:first").val());
704             });
705
706             $fieldset.append($label).append($select);
707             // input port
708             var $label = one.lib.form.label("Input Port");
709             var $select = one.lib.form.select.create();
710             $select.attr('id', one.f.flows.id.modal.form.port);
711             $fieldset.append($label).append($select);
712             // priority
713             var $label = one.lib.form.label("Priority");
714             var $input = one.lib.form.input("Priority");
715             $input.attr('id', one.f.flows.id.modal.form.priority);
716             $input.val('500');
717             $fieldset.append($label).append($input);
718             // hardTimeout
719             var $label = one.lib.form.label("Hard Timeout");
720             var $input = one.lib.form.input("Hard Timeout");
721             $input.attr('id', one.f.flows.id.modal.form.hardTimeout);
722             $fieldset.append($label).append($input);
723             // idleTimeout
724             var $label = one.lib.form.label("Idle Timeout");
725             var $input = one.lib.form.input("Idle Timeout");
726             $input.attr('id', one.f.flows.id.modal.form.idleTimeout);
727             $fieldset.append($label).append($input);
728             // cookie
729             var $label = one.lib.form.label("Cookie");
730             var $input = one.lib.form.input("Cookie");
731             $input.attr('id', one.f.flows.id.modal.form.cookie);
732             $fieldset.append($label).append($input);
733             // layer 2
734             var $legend = one.lib.form.legend("Layer 2");
735             $fieldset.append($legend);
736             // etherType
737             var $label = one.lib.form.label("Ethernet Type");
738             var $input = one.lib.form.input("Ethernet Type");
739             $input.attr('id', one.f.flows.id.modal.form.etherType);
740             $input.val('0x800');
741             $fieldset.append($label).append($input);
742             // vlanId
743             var $label = one.lib.form.label("VLAN Identification Number");
744             var $input = one.lib.form.input("VLAN Identification Number");
745             $input.attr('id', one.f.flows.id.modal.form.vlanId);
746             var $help = one.lib.form.help("Range: 0 - 4095");
747             $fieldset.append($label).append($input).append($help);
748             // vlanPriority
749             var $label = one.lib.form.label("VLAN Priority");
750             var $input = one.lib.form.input("VLAN Priority");
751             $input.attr('id', one.f.flows.id.modal.form.vlanPriority);
752             var $help = one.lib.form.help("Range: 0 - 7");
753             $fieldset.append($label).append($input).append($help);
754             // srcMac
755             var $label = one.lib.form.label("Source MAC Address");
756             var $input = one.lib.form.input("Source MAC Address");
757             $input.attr('id', one.f.flows.id.modal.form.srcMac);
758             var $help = one.lib.form.help("Example: 00:11:22:aa:bb:cc");
759             $fieldset.append($label).append($input).append($help);
760             // dstMac
761             var $label = one.lib.form.label("Destination MAC Address");
762             var $input = one.lib.form.input("Destination MAC Address");
763             $input.attr('id', one.f.flows.id.modal.form.dstMac);
764             var $help = one.lib.form.help("Example: 00:11:22:aa:bb:cc");
765             $fieldset.append($label).append($input).append($help);
766             // layer 3
767             var $legend = one.lib.form.legend("Layer 3");
768             $fieldset.append($legend);
769             // srcIp
770             var $label = one.lib.form.label("Source IP Address");
771             var $input = one.lib.form.input("Source IP Address");
772             $input.attr('id', one.f.flows.id.modal.form.srcIp);
773             var $help = one.lib.form.help("Example: 127.0.0.1");
774             $fieldset.append($label).append($input).append($help);
775             // dstIp
776             var $label = one.lib.form.label("Destination IP Address");
777             var $input = one.lib.form.input("Destination IP Address");
778             $input.attr('id', one.f.flows.id.modal.form.dstIp);
779             var $help = one.lib.form.help("Example: 127.0.0.1");
780             $fieldset.append($label).append($input).append($help);
781             // tosBits
782             var $label = one.lib.form.label("TOS Bits");
783             var $input = one.lib.form.input("TOS Bits");
784             $input.attr('id', one.f.flows.id.modal.form.tosBits);
785             var $help = one.lib.form.help("Range: 0 - 63");
786             $fieldset.append($label).append($input).append($help);
787             // layer 4
788             var $legend = one.lib.form.legend("Layer 4");
789             $fieldset.append($legend);
790             // srcPort
791             var $label = one.lib.form.label("Source Port");
792             var $input = one.lib.form.input("Source Port");
793             $input.attr('id', one.f.flows.id.modal.form.srcPort);
794             var $help = one.lib.form.help("Range: 0 - 65535");
795             $fieldset.append($label).append($input).append($help);
796             // dstPort
797             var $label = one.lib.form.label("Destination Port");
798             var $input = one.lib.form.input("Destination Port");
799             $input.attr('id', one.f.flows.id.modal.form.dstPort);
800             var $help = one.lib.form.help("Range: 0 - 65535");
801             $fieldset.append($label).append($input).append($help);
802             // protocol
803             var $label = one.lib.form.label("Protocol");
804             var $input = one.lib.form.input("Protocol");
805             $input.attr('id', one.f.flows.id.modal.form.protocol);
806             $fieldset.append($label).append($input);
807             // actions
808             var $legend = one.lib.form.label("Actions");
809             $fieldset.append($legend);
810             // actions table
811             var tableAttributes = ["table-striped", "table-bordered", "table-condensed", "table-hover", "table-cursor"];
812             var $table = one.lib.dashlet.table.table(tableAttributes);
813             $table.attr('id', one.f.flows.id.modal.action.table);
814             var tableHeaders = ["Action", "Data", "Type"];
815             var $thead = one.lib.dashlet.table.header(tableHeaders);
816             var $tbody = one.lib.dashlet.table.body("", tableHeaders);
817             $table.append($thead).append($tbody);
818             // actions
819             var actions = {
820                 "" : "Please Select an Action",
821                 "drop" : "Drop",
822                 "loopback" : "Loopback",
823                 "flood" : "Flood",
824                 "softwarePath" : "Software Path",
825                 "hardwarePath" : "Hardware Path",
826                 "controller" : "Controller",
827                 "addOutputPorts" : "Add Output Ports",
828                 "setVlanId" : "Set VLAN ID",
829                 "setVlanPriority" : "Set VLAN Priority",
830                 "stripVlanHeader" : "Strip VLAN Header",
831                 "modifyDatalayerSourceAddress" : "Modify Datalayer Source Address",
832                 "modifyDatalayerDestinationAddress" : "Modify Datalayer Destination Address",
833                 "modifyNetworkSourceAddress" : "Modify Network Source Address",
834                 "modifyNetworkDestinationAddress" :"Modify Network Destination Address",
835                 "modifyTosBits" : "Modify TOS Bits",
836                 "modifyTransportSourcePort" : "Modify Transport Source Port",
837                 "modifyTransportDestinationPort" : "Modify Transport Destination Port"
838             };
839             var $select = one.lib.form.select.create(actions);
840             // when selecting an action
841             $select.change(function() {
842                 var action = $(this).find('option:selected');
843                 one.f.flows.modal.action.parse(action.attr('value'));
844                 $select[0].selectedIndex = 0;
845             });
846
847             $fieldset.append($select).append($table);
848
849             // return
850             $form.append($fieldset);
851             return $form;
852         },
853         action : {
854             parse : function(option) {
855                 switch (option) {
856                     case "addOutputPorts" :
857                         var h3 = "Add Output Port";
858                         var $modal = one.f.flows.modal.action.initialize(h3, one.f.flows.modal.action.body.addOutputPorts, one.f.flows.modal.action.add.addOutputPorts);
859                         $modal.modal();
860                         break;
861                     case "setVlanId" :
862                         var h3 = "Set VLAN ID";
863                         var placeholder = "VLAN Identification Number";
864                         var id = one.f.flows.id.modal.action.setVlanId;
865                         var help = "Range: 0 - 4095";
866                         var action = 'SET_VLAN_ID';
867                         var name = "VLAN ID";
868                         var body = function() {
869                             return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
870                         };
871                         var add = function($modal) {
872                             one.f.flows.modal.action.add.set(name, id, action, $modal);
873                         };
874                         var $modal = one.f.flows.modal.action.initialize(h3, body, add);
875                         $modal.modal();
876                         break;
877                     case "setVlanPriority" :
878                         var h3 = "Set VLAN Priority";
879                         var placeholder = "VLAN Priority";
880                         var id = one.f.flows.id.modal.action.setVlanPriority;
881                         var help = "Range: 0 - 7";
882                         var action = 'SET_VLAN_PCP';
883                         var name = "VLAN Priority";
884                         var body = function() {
885                             return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
886                         };
887                         var add = function($modal) {
888                             one.f.flows.modal.action.add.set(name, id, action, $modal);
889                         };
890                         var $modal = one.f.flows.modal.action.initialize(h3, body, add);
891                         $modal.modal();
892                         break;
893                     case "stripVlanHeader" :
894                         var name = "Strip VLAN Header";
895                         var action = 'POP_VLAN';
896                         one.f.flows.modal.action.add.add(name, action);
897                         break;
898                     case "modifyDatalayerSourceAddress" :
899                         var h3 = "Set Source MAC Address";
900                         var placeholder = "Source MAC Address";
901                         var id = one.f.flows.id.modal.action.modifyDatalayerSourceAddress;
902                         var help = "Example: 00:11:22:aa:bb:cc";
903                         var action = 'SET_DL_SRC';
904                         var name = "Source MAC";
905                         var body = function() {
906                             return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
907                         };
908                         var add = function($modal) {
909                             one.f.flows.modal.action.add.set(name, id, action, $modal);
910                         };
911                         var $modal = one.f.flows.modal.action.initialize(h3, body, add);
912                         $modal.modal();
913                         break;
914                     case "modifyDatalayerDestinationAddress" :
915                         var h3 = "Set Destination MAC Address";
916                         var placeholder = "Destination MAC Address";
917                         var id = one.f.flows.id.modal.action.modifyDatalayerDestinationAddress;
918                         var help = "Example: 00:11:22:aa:bb:cc";
919                         var action = 'SET_DL_DST';
920                         var name = "Destination MAC";
921                         var body = function() {
922                             return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
923                         };
924                         var add = function($modal) {
925                             one.f.flows.modal.action.add.set(name, id, action, $modal);
926                         };
927                         var $modal = one.f.flows.modal.action.initialize(h3, body, add);
928                         $modal.modal();
929                         break;
930                     case "modifyNetworkSourceAddress" :
931                         var h3 = "Set IP Source Address";
932                         var placeholder = "Source IP Address";
933                         var id = one.f.flows.id.modal.action.modifyNetworkSourceAddress;
934                         var help = "Example: 127.0.0.1";
935                         var action = 'SET_NW_SRC';
936                         var name = "Source IP";
937                         var body = function() {
938                             return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
939                         };
940                         var add = function($modal) {
941                             one.f.flows.modal.action.add.set(name, id, action, $modal);
942                         };
943                         var $modal = one.f.flows.modal.action.initialize(h3, body, add);
944                         $modal.modal();
945                         break;
946                     case "modifyNetworkDestinationAddress" :
947                         var h3 = "Set IP Destination Address";
948                         var placeholder = "Destination IP Address";
949                         var id = one.f.flows.id.modal.action.modifyNetworkDestinationAddress;
950                         var help = "Example: 127.0.0.1";
951                         var action = 'SET_NW_DST';
952                         var name = "Destination IP";
953                         var body = function() {
954                             return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
955                         };
956                         var add = function($modal) {
957                             one.f.flows.modal.action.add.set(name, id, action, $modal);
958                         };
959                         var $modal = one.f.flows.modal.action.initialize(h3, body, add);
960                         $modal.modal();
961                         break;
962                     case "modifyTosBits" :
963                         var h3 = "Set IPv4 ToS";
964                         var placeholder = "IPv4 ToS";
965                         var id = one.f.flows.id.modal.action.modifyTosBits;
966                         var help = "Range: 0 - 63";
967                         var action = 'SET_NW_TOS';
968                         var name = "TOS Bits";
969                         var body = function() {
970                             return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
971                         };
972                         var add = function($modal) {
973                             one.f.flows.modal.action.add.set(name, id, action, $modal);
974                         };
975                         var $modal = one.f.flows.modal.action.initialize(h3, body, add);
976                         $modal.modal();
977                         break;
978                     case "modifyTransportSourcePort" :
979                         var h3 = "Set Transport Source Port";
980                         var placeholder = "Transport Source Port";
981                         var id = one.f.flows.id.modal.action.modifyTransportSourcePort;
982                         var help = "Range: 1 - 65535";
983                         var action = 'SET_TP_SRC';
984                         var name = "Source Port";
985                         var body = function() {
986                             return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
987                         };
988                         var add = function($modal) {
989                             one.f.flows.modal.action.add.set(name, id, action, $modal);
990                         };
991                         var $modal = one.f.flows.modal.action.initialize(h3, body, add);
992                         $modal.modal();
993                         break;
994                     case "modifyTransportDestinationPort" :
995                         var h3 = "Set Transport Destination Port";
996                         var placeholder = "Transport Destination Port";
997                         var id = one.f.flows.id.modal.action.modifyTransportDestinationPort;
998                         var help = "Range: 1 - 65535";
999                         var action = 'SET_TP_DST';
1000                         var name = "Destination Port";
1001                         var body = function() {
1002                             return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
1003                         };
1004                         var add = function($modal) {
1005                             one.f.flows.modal.action.add.set(name, id, action, $modal);
1006                         };
1007                         var $modal = one.f.flows.modal.action.initialize(h3, body, add);
1008                         $modal.modal();
1009                         break;
1010                     case "drop" :
1011                         var name = "Drop";
1012                         var action = 'DROP';
1013                         one.f.flows.modal.action.add.add(name, action);
1014                         break;
1015                     case "loopback" :
1016                         var name = "Loopback";
1017                         var action = 'LOOPBACK';
1018                         one.f.flows.modal.action.add.add(name, action);
1019                         break;
1020                     case "flood" :
1021                         var name = "Flood";
1022                         var action = 'FLOOD';
1023                         one.f.flows.modal.action.add.add(name, action);
1024                         break;
1025                     case "softwarePath" :
1026                         var name = "Software Path";
1027                         var action = 'SW_PATH';
1028                         one.f.flows.modal.action.add.add(name, action);
1029                         break;
1030                     case "hardwarePath" :
1031                         var name = "Hardware Path";
1032                         var action = 'HW_PATH';
1033                         one.f.flows.modal.action.add.add(name, action);
1034                         break;
1035                     case "controller" :
1036                         var name = "Controller";
1037                         var action = 'CONTROLLER';
1038                         one.f.flows.modal.action.add.add(name, action);
1039                         break;
1040                 }
1041             },
1042             initialize : function(h3, bodyCallback, addCallback) {
1043                 var footer = one.f.flows.modal.action.footer();
1044                 var $body = bodyCallback();
1045                 var $modal = one.lib.modal.spawn(one.f.flows.id.modal.action.modal, h3, $body, footer);
1046                 // bind close button
1047                 $('#'+one.f.flows.id.modal.action.close, $modal).click(function() {
1048                     $modal.modal('hide');
1049                 });
1050                 // bind add flow button
1051                 $('#'+one.f.flows.id.modal.action.add, $modal).click(function() {
1052                     addCallback($modal);
1053                 });
1054                 return $modal;
1055             },
1056             add : {
1057                 addOutputPorts : function($modal) {
1058                     var $options = $('#'+one.f.flows.id.modal.action.addOutputPorts).find('option:selected');
1059                     var ports = '';
1060                     var pid = '';
1061                     $options.each(function(index, value) {
1062                         ports = ports+$(value).text()+", ";
1063                         pid = pid+$(value).attr('value')+",";
1064                     });
1065                     ports = ports.slice(0,-2);
1066                     pid = pid.slice(0,-1);
1067                     var $tr = one.f.flows.modal.action.table.add("Add Output Ports", ports);
1068                     $tr.attr('id', 'addOutputPorts');
1069                     $tr.data('action', 'OUTPUT='+pid);
1070                     $tr.click(function() {
1071                         one.f.flows.modal.action.add.modal.initialize(this);
1072                     });
1073                     one.f.flows.modal.action.table.append($tr);
1074                     $modal.modal('hide');
1075                 },
1076                 add : function(name, action) {
1077                     var $tr = one.f.flows.modal.action.table.add(name);
1078                     $tr.attr('id', action);
1079                     $tr.data('action', action);
1080                     $tr.click(function() {
1081                         one.f.flows.modal.action.add.modal.initialize(this);
1082                     });
1083                     one.f.flows.modal.action.table.append($tr);
1084                 },
1085                 set : function(name, id, action, $modal) {
1086                     var $input = $('#'+id);
1087                     var value = $input.val();
1088                     var $tr = one.f.flows.modal.action.table.add(name, value);
1089                     $tr.attr('id', action);
1090                     $tr.data('action', action+'='+value);
1091                     $tr.click(function() {
1092                         one.f.flows.modal.action.add.modal.initialize(this);
1093                     });
1094                     one.f.flows.modal.action.table.append($tr);
1095                     $modal.modal('hide');
1096                 },
1097                 remove : function(that) {
1098                     $(that).remove();
1099                     var $table = $('#'+one.f.flows.id.modal.action.table);
1100                     if ($table.find('tbody').find('tr').size() == 0) {
1101                         var $tr = $(document.createElement('tr'));
1102                         var $td = $(document.createElement('td'));
1103                         $td.attr('colspan', '3');
1104                         $tr.addClass('empty');
1105                         $td.text('No data available');
1106                         $tr.append($td);
1107                         $table.find('tbody').append($tr);
1108                     }
1109                 },
1110                 modal : {
1111                     initialize : function(that) {
1112                         var h3 = "Remove Action";
1113                         var footer = one.f.flows.modal.action.add.modal.footer();
1114                         var $body = one.f.flows.modal.action.add.modal.body();
1115                         var $modal = one.lib.modal.spawn(one.f.flows.id.modal.action.modal.modal, h3, $body, footer);
1116
1117                         // bind cancel button
1118                         $('#'+one.f.flows.id.modal.action.modal.cancel, $modal).click(function() {
1119                             $modal.modal('hide');
1120                         });
1121
1122                         // bind remove button
1123                         $('#'+one.f.flows.id.modal.action.modal.remove, $modal).click(function() {
1124                             one.f.flows.modal.action.add.remove(that);
1125                             $modal.modal('hide');
1126                         });
1127
1128                         $modal.modal();
1129                     },
1130                     body : function() {
1131                         var $p = $(document.createElement('p'));
1132                         $p.append("Remove this action?");
1133                         return $p;
1134                     },
1135                     footer : function() {
1136                         var footer = [];
1137
1138                         var removeButton = one.lib.dashlet.button.single("Remove Action", one.f.flows.id.modal.action.modal.remove, "btn-danger", "");
1139                         var $removeButton = one.lib.dashlet.button.button(removeButton);
1140                         footer.push($removeButton);
1141
1142                         var cancelButton = one.lib.dashlet.button.single("Cancel", one.f.flows.id.modal.action.modal.cancel, "", "");
1143                         var $cancelButton = one.lib.dashlet.button.button(cancelButton);
1144                         footer.push($cancelButton);
1145
1146                         return footer;
1147                     }
1148                 }
1149             },
1150             table : {
1151                 add : function(action, data, type) {
1152                     var $tr = $(document.createElement('tr'));
1153                     var $td = $(document.createElement('td'));
1154                     $td.append(action);
1155                     $tr.append($td);
1156                     var $td = $(document.createElement('td'));
1157                     if (data != undefined) $td.append(data);
1158                     $tr.append($td);
1159                     var $td = $(document.createElement('td'));
1160                     if (type != undefined) $td.append(type);
1161                     $tr.append($td);
1162                     return $tr;
1163                 },
1164                 append : function($tr) {
1165                     var $table = $('#'+one.f.flows.id.modal.action.table);
1166                     var $empty = $table.find('.empty').parent();
1167                     if ($empty.size() > 0) $empty.remove();
1168                     $table.append($tr);
1169                 }
1170             },
1171             body : {
1172                 common : function() {
1173                     var $form = $(document.createElement('form'));
1174                     var $fieldset = $(document.createElement('fieldset'));
1175                     return [$form, $fieldset];
1176                 },
1177                 addOutputPorts : function() {
1178                     var common = one.f.flows.modal.action.body.common();
1179                     var $form = common[0];
1180                     var $fieldset = common[1];
1181                     // output port
1182                     $label = one.lib.form.label("Select Output Ports");
1183                     var ports = one.f.flows.registry.nodeports[one.f.flows.registry.currentNode]['ports'];
1184                     $select = one.lib.form.select.create(ports, true);
1185                     $select.attr('id', one.f.flows.id.modal.action.addOutputPorts);
1186                     one.lib.form.select.prepend($select, {'':'Select a Port'});
1187                     $fieldset.append($label).append($select);
1188                     $form.append($fieldset);
1189                     return $form;
1190                 },
1191                 set : function(label, placeholder, id, help) {
1192                     var common = one.f.flows.modal.action.body.common();
1193                     var $form = common[0];
1194                     var $fieldset = common[1];
1195                     // input
1196                     $label = one.lib.form.label(label);
1197                     $input = one.lib.form.input(placeholder);
1198                     $input.attr('id', id);
1199                     $help = one.lib.form.help(help);
1200                     // append
1201                     $fieldset.append($label).append($input).append($help);
1202                     $form.append($fieldset);
1203                     return $form;
1204                 }
1205             },
1206             footer : function() {
1207                 var footer = [];
1208                 var addButton = one.lib.dashlet.button.single("Add Action", one.f.flows.id.modal.action.add, "btn-primary", "");
1209                 var $addButton = one.lib.dashlet.button.button(addButton);
1210                 footer.push($addButton);
1211
1212                 var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.action.close, "", "");
1213                 var $closeButton = one.lib.dashlet.button.button(closeButton);
1214                 footer.push($closeButton);
1215
1216                 return footer;
1217             }
1218         },
1219         footer : function() {
1220             var footer = [];
1221
1222             var installButton = one.lib.dashlet.button.single("Install Flow", one.f.flows.id.modal.install, "btn-success", "");
1223             var $installButton = one.lib.dashlet.button.button(installButton);
1224             footer.push($installButton);
1225
1226             var addButton = one.lib.dashlet.button.single("Save Flow", one.f.flows.id.modal.add, "btn-primary", "");
1227             var $addButton = one.lib.dashlet.button.button(addButton);
1228             footer.push($addButton);
1229
1230             var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.close, "", "");
1231             var $closeButton = one.lib.dashlet.button.button(closeButton);
1232             footer.push($closeButton);
1233
1234             return footer;
1235         }
1236     },
1237     ajax : {
1238         dashlet : function(callback) {
1239             $.getJSON(one.f.address.root+one.f.address.flows.main, function(data) {
1240                 one.f.flows.registry['flows'] = data.flows;
1241                 one.f.flows.registry['privilege'] = data.privilege;
1242                 callback(data);
1243             });
1244         }
1245     },
1246     data : {
1247         flowsDataGrid: function(data) {
1248             var source = new StaticDataSource({
1249                     columns: [
1250                         {
1251                             property: 'selector',
1252                             label: "<input type='checkbox' id='"+one.f.flows.id.dashlet.datagrid.selectAllFlows+"'/>",
1253                             sortable: false
1254                         },
1255                         {
1256                             property: 'name',
1257                             label: 'Flow Name',
1258                             sortable: true
1259                         },
1260                         {
1261                             property: 'node',
1262                             label: 'Node',
1263                             sortable: true
1264                         }
1265                     ],
1266                     data: data.flows,
1267                     formatter: function(items) {
1268                         $.each(items, function(index, item) {
1269                                     var $checkbox = document.createElement("input");
1270                             $checkbox.setAttribute("type", "checkbox");
1271                             $checkbox.setAttribute("name", item.name);
1272                             $checkbox.setAttribute("node", item.node);
1273                             $checkbox.setAttribute('class','flowEntry')
1274                             item.selector = $checkbox.outerHTML;
1275                                   item["name"] = '<span data-installInHw=' + item["flow"]["installInHw"] + 
1276                                 ' data-flowstatus=' + item["flow"]["status"] + 
1277                                 ' data-nodeId=' + item["nodeId"] + '>' + item["name"] + '</span>';
1278                         });
1279
1280                     },
1281                     delay: 0
1282                 });
1283             return source;
1284         },
1285         dashlet : function(data) {
1286             var body = [];
1287             $(data).each(function(index, value) {
1288                 var tr = {};
1289                 var entry = [];
1290
1291                 
1292                 entry.push(value['name']);
1293                 entry.push(value['node']);
1294                 if (value['flow']['installInHw'] == 'true' && value['flow']['status'] == 'Success')
1295                     tr['type'] = ['success'];
1296                 else if (value['flow']['installInHw'] == 'false' && value['flow']['status'] == 'Success')
1297                     tr['type'] = ['warning'];
1298                 else 
1299                     tr['type'] = ['warning'];
1300                 tr['entry'] = entry;
1301                 tr['id'] = value['nodeId'];
1302
1303                 body.push(tr);
1304             });
1305             return body;
1306         }
1307     },
1308     body : {
1309         dashlet : function(body, callback) {
1310             var attributes = ['table-striped', 'table-bordered', 'table-hover', 'table-condensed', 'table-cursor'];
1311             var $table = one.lib.dashlet.table.table(attributes);
1312
1313             var headers = ['Flow Name', 'Node'];
1314                 
1315             var $thead = one.lib.dashlet.table.header(headers);
1316             $table.append($thead);
1317
1318             var $tbody = one.lib.dashlet.table.body(body);
1319             $table.append($tbody);
1320             return $table;
1321         }
1322     }
1323 }
1324
1325 /** INIT **/
1326 // populate nav tabs
1327 $(one.f.menu.left.top).each(function(index, value) {
1328     var $nav = $(".nav", "#left-top");
1329     one.main.page.dashlet($nav, value);
1330 });
1331
1332 $(one.f.menu.left.bottom).each(function(index, value) {
1333     var $nav = $(".nav", "#left-bottom");
1334     one.main.page.dashlet($nav, value);
1335 });
1336
1337 $(one.f.menu.right.bottom).each(function(index, value) {
1338     var $nav = $(".nav", "#right-bottom");
1339     one.main.page.dashlet($nav, value);
1340 });
1341
1342 one.f.populate = function($dashlet, header) {
1343     var $h4 = one.lib.dashlet.header(header);
1344     $dashlet.append($h4);
1345 };
1346
1347 // bind dashlet nav
1348 $('.dash .nav a', '#main').click(function() {
1349     // de/activation
1350     var $li = $(this).parent();
1351     var $ul = $li.parent();
1352     one.lib.nav.unfocus($ul);
1353     $li.addClass('active');
1354     // clear respective dashlet
1355     var $dashlet = $ul.parent().find('.dashlet');
1356     one.lib.dashlet.empty($dashlet);
1357     // callback based on menu
1358     var id = $(this).attr('id');
1359     var menu = one.f.dashlet;
1360     switch (id) {
1361         case menu.flows.id:
1362             one.f.flows.dashlet($dashlet);
1363             break;
1364         case menu.nodes.id:
1365             one.f.nodes.dashlet($dashlet);
1366             break;
1367         case menu.detail.id:
1368             one.f.detail.dashlet($dashlet);
1369             break;
1370     };
1371 });
1372
1373 // activate first tab on each dashlet
1374 $('.dash .nav').each(function(index, value) {
1375     $($(value).find('li')[0]).find('a').click();
1376 });