Add felix webconsole and link it off the admin web ui
[controller.git] / opendaylight / web / root / src / main / resources / js / open.js
1 one.main = {};
2
3 one.main.constants = {
4   address : {
5     menu : "/web.json",
6     prefix : "/controller/web",
7     save : "/save"
8   }
9 }
10
11 one.main.menu = {
12   registry : {
13     load : false
14   },
15   load : function() {
16     one.main.menu.ajax(function(data) {
17       // reparse the ajax data
18       var result = one.main.menu.data.menu(data);
19       // transform into list to append to menu
20       var $div = one.main.menu.menu(result);
21       // append to menu
22       $("#menu .nav").append($div.children());
23       // binding all menu items
24       var $menu = $("#menu .nav a");
25       $menu.click(function() {
26         if (one.main.menu.registry.load === true) {
27           return false;
28         }
29         one.main.menu.registry.load = true;
30         var href = $(this).attr('href').substring(1);
31         one.main.page.load(href);
32         var $li = $(this).parent();
33         // reset all other active
34         $menu.each(function(index, value) {
35           $(value).parent().removeClass('active');
36         });
37         $li.addClass('active');
38       });
39       // reset or go to first menu item by default
40       var currentLocation = location.hash;
41       if (data[currentLocation.substring(1)] == undefined) {
42         $($menu[0]).click();
43       } else {
44         $menu.each(function(index, value) {
45           var menuLocation = $(value).attr('href');
46           if (currentLocation == menuLocation) {
47             $($menu[index]).click();
48             return;
49           }
50         });
51       }
52     });
53   },
54   menu : function(result) {
55     var $div = $(document.createElement('div'));
56     $(result).each(function(index, value) {
57       if (value != undefined) {
58         var $li = $(document.createElement('li'));
59         var $a = $(document.createElement('a'));
60         $a.text(value['name']);
61         $a.attr('href', '#' + value['id']);
62         $li.append($a);
63         $div.append($li);
64       }
65     });
66     return $div;
67   },
68   ajax : function(successCallback) {
69     $.getJSON(one.main.constants.address.menu, function(data) {
70       successCallback(data);
71     });
72   },
73   data : {
74     menu : function(data) {
75       var result = [];
76       $.each(data, function(key, value) {
77         var order = value['order'];
78         if (order >= 0) {
79           var name = value['name'];
80           var entry = {
81             'name' : name,
82         'id' : key
83           };
84           result[order] = entry;
85         }
86       });
87       return result;
88     }
89   }
90 }
91
92 one.main.page = {
93   load : function(page) {
94     if (one.f !== undefined && one.f.cleanUp !== undefined) {
95       one.f.cleanUp();
96     }
97     // clear page related
98     delete one.f;
99     $('.dashlet', '#main').empty();
100     $('.nav', '#main').empty();
101     // fetch page's js
102     $.getScript(one.main.constants.address.prefix+"/"+page+"/js/page.js")
103       .success(function() {
104         one.main.menu.registry.load = false;
105       });
106
107     $.ajaxSetup({
108       data : {
109         'x-page-url' : page
110       }
111     });
112   },
113   dashlet : function($nav, dashlet) {
114     var $li = $(document.createElement('li'));
115     var $a = $(document.createElement('a'));
116     $a.text(dashlet.name);
117     $a.attr('id', dashlet.id);
118     $a.attr('href', '#');
119     $li.append($a);
120     $nav.append($li);
121   }
122 }
123
124 one.main.admin = {
125   id : {
126     modal : {
127       main : "one_main_admin_id_modal_main",
128       close : "one_main_admin_id_modal_close",
129       user : "one_main_admin_id_modal_user",
130       add : {
131         user : "one_main_admin_id_modal_add_user",
132         close : "one_main_admin_id_modal_add_close",
133         form : {
134           name : "one_main_admin_id_modal_add_form_name",
135           role : "one_main_admin_id_modal_add_form_role",
136           password : "one_main_admin_id_modal_add_form_password",
137           verify : "one_main_admin_id_modal_add_form_verify"
138         }
139       },
140       remove : {
141         user : "one_main_admin_id_modal_remove_user",
142         close : "one_main_admin_id_modal_remove_close",
143         password : 'one_main_admin_id_modal_remove_password'
144       },
145       password : {
146         modal : 'one_main_admin_id_modal_password_modal',
147         submit : 'one_main_admin_id_modal_password_submit',
148         cancel : 'one_main_admin_id_modal_password_cancel',
149         form : {
150           old : 'one_main_admin_id_modal_password_form_old',
151           set : 'one_main_admin_id_modal_password_form_new',
152           verify : 'one_main_admin_id_modal_password_form_verify'
153         }
154       }
155     },
156     add : {
157       user : "one_main_admin_id_add_user"
158     }
159   },
160   address : {
161     root : "/admin",
162     users : "/users",
163     password : '/admin/users/password/'
164   },
165   modal : {
166     initialize : function(callback) {
167       var h3 = "Welcome " + $('#admin').text();
168       var footer = one.main.admin.modal.footer();
169       var $modal = one.lib.modal.spawn(one.main.admin.id.modal.main, h3,
170           '', footer);
171
172       // close binding
173       $('#' + one.main.admin.id.modal.close, $modal).click(function() {
174         $modal.modal('hide');
175       });
176
177       // body inject
178       one.main.admin.ajax.users(function($body) {
179         one.lib.modal.inject.body($modal, $body);
180       });
181
182       // modal show callback
183       callback($modal);
184     },
185     footer : function() {
186       var footer = [];
187       var closeButton = one.lib.dashlet.button.single('Close', one.main.admin.id.modal.close, '', '');
188       var $closeButton = one.lib.dashlet.button.button(closeButton);
189       footer.push($closeButton);
190       return footer;
191     }
192   },
193   ajax : {
194     users : function(callback) {
195       $.getJSON(one.main.admin.address.root
196           + one.main.admin.address.users, function(data) {
197             var body = one.main.admin.data.users(data);
198             var $body = one.main.admin.body.users(body);
199             callback($body);
200           });
201     }
202   },
203   data : {
204     users : function(data) {
205       var body = [];
206       $(data).each(function(index, value) {
207         var tr = {};
208         var entry = [];
209         entry.push(value['user']);
210         entry.push(value['roles']);
211         tr['entry'] = entry;
212         tr['id'] = value['user'];
213         body.push(tr);
214       });
215       return body;
216     }
217   },
218   body : {
219     users : function(body) {
220       var $div = $(document.createElement('div'));
221       var $h5 = $(document.createElement('h5'));
222       $h5.append("Manage Users");
223       var attributes = [ "table-striped", "table-bordered",
224           "table-hover", "table-cursor" ];
225       var $table = one.lib.dashlet.table.table(attributes);
226       var headers = [ "User", "Role" ];
227       var $thead = one.lib.dashlet.table.header(headers);
228       var $tbody = one.lib.dashlet.table.body(body);
229       $table.append($thead).append($tbody);
230
231       // bind table
232       if (one.role < 2) {
233         $table.find('tr').click(function() {
234           var id = $(this).data('id');
235           one.main.admin.remove.modal.initialize(id);
236         });
237       }
238
239       // append to div
240       $div.append($h5).append($table);
241
242       if (one.role < 2) {
243         var addUserButton = one.lib.dashlet.button.single("Add User",
244             one.main.admin.id.add.user, "btn-primary", "btn-mini");
245         var $addUserButton = one.lib.dashlet.button
246           .button(addUserButton);
247         $div.append($addUserButton);
248
249         // add user binding
250         $addUserButton.click(function() {
251           one.main.admin.add.modal.initialize();
252         });
253       }
254
255       return $div;
256     }
257   },
258   remove : {
259     modal : {
260       initialize : function(id) {
261         var h3 = "Edit User";
262         var footer = one.main.admin.remove.footer();
263         var $body = one.main.admin.remove.body();
264         var $modal = one.lib.modal.spawn(one.main.admin.id.modal.user,
265             h3, $body, footer);
266         // close binding
267         $('#'+one.main.admin.id.modal.remove.close, $modal).click(function() {
268           $modal.modal('hide');
269         });
270         // remove binding
271         $('#' + one.main.admin.id.modal.remove.user, $modal).click(function() {
272           one.main.admin.remove.modal.ajax(id, function(result) {
273             if (result == 'Success') {
274               $modal.modal('hide');
275               // body inject
276               var $admin = $('#'+one.main.admin.id.modal.main);
277               one.main.admin.ajax.users(function($body) {
278                 one.lib.modal.inject.body($admin, $body);
279               });
280             } else {
281               alert("Failed to remove user: " + result);
282             }
283           });
284         });
285         // change password binding
286         $('#' + one.main.admin.id.modal.remove.password, $modal).click(function() {
287           one.main.admin.password.initialize(id, function() {
288             $modal.modal('hide');
289           });
290         });
291         $modal.modal();
292       },
293       ajax : function(id, callback) {
294         $.post(one.main.admin.address.root + one.main.admin.address.users + '/' + id, function(data) {
295           callback(data);
296         });
297       },
298     },
299     footer : function() {
300       var footer = [];
301       var removeButton = one.lib.dashlet.button.single("Remove User",
302           one.main.admin.id.modal.remove.user, "btn-danger", "");
303       var $removeButton = one.lib.dashlet.button.button(removeButton);
304       footer.push($removeButton);
305       var change = one.lib.dashlet.button.single('Change Password',
306           one.main.admin.id.modal.remove.password, 'btn-success', '');
307       var $change = one.lib.dashlet.button.button(change);
308       footer.push($change);
309       var closeButton = one.lib.dashlet.button.single("Close",
310           one.main.admin.id.modal.remove.close, "", "");
311       var $closeButton = one.lib.dashlet.button.button(closeButton);
312       footer.push($closeButton);
313       return footer;
314     },
315     body : function() {
316       var $p = $(document.createElement('p'));
317       $p.append('Select an action');
318       return $p;
319     },
320   },
321   add : {
322     modal : {
323       initialize : function() {
324         var h3 = "Add User";
325         var footer = one.main.admin.add.footer();
326         var $body = one.main.admin.add.body();
327         var $modal = one.lib.modal.spawn(one.main.admin.id.modal.user,
328             h3, $body, footer);
329         // close binding
330         $('#' + one.main.admin.id.modal.add.close, $modal).click(function() {
331           $modal.modal('hide');
332         });
333         // add binding
334         $('#' + one.main.admin.id.modal.add.user, $modal).click(function() {
335           one.main.admin.add.modal.add($modal, function(result) {
336             if (result == 'Success') {
337               $modal.modal('hide');
338               // body inject
339               var $admin = $('#'+one.main.admin.id.modal.main);
340               one.main.admin.ajax.users(function($body) {
341                 one.lib.modal.inject.body($admin, $body);
342               });
343             } else {
344               alert("Failed to add user: "+result);
345             }
346           });
347         });
348         $modal.modal();
349       },
350       add : function($modal, callback) {
351         var user = {};
352         user['user'] = $modal.find(
353             '#' + one.main.admin.id.modal.add.form.name).val();
354         user['password'] = $modal.find(
355             '#' + one.main.admin.id.modal.add.form.password).val();
356         roles = new Array();
357         roles[0] = $modal.find(
358             '#' + one.main.admin.id.modal.add.form.role).find(
359               'option:selected').attr('value');
360         user['roles'] = roles;
361
362         // password check
363         var verify = $('#'+one.main.admin.id.modal.add.form.verify).val();
364         if (user.password != verify) {
365           alert('Passwords do not match');
366           return false;
367         }
368
369         var resource = {};
370         resource['json'] = JSON.stringify(user);
371         resource['action'] = 'add'
372
373           one.main.admin.add.modal.ajax(resource, callback);
374       },
375       ajax : function(data, callback) {
376         $.post(one.main.admin.address.root
377             + one.main.admin.address.users, data, function(data) {
378               callback(data);
379             });
380       }
381     },
382     body : function() {
383       var $form = $(document.createElement('form'));
384       var $fieldset = $(document.createElement('fieldset'));
385       // user
386       var $label = one.lib.form.label('Username');
387       var $input = one.lib.form.input('Username');
388       $input.attr('id', one.main.admin.id.modal.add.form.name);
389       $fieldset.append($label).append($input);
390       // password
391       var $label = one.lib.form.label('Password');
392       var $input = one.lib.form.input('Password');
393       $input.attr('id', one.main.admin.id.modal.add.form.password);
394       $input.attr('type', 'password');
395       $fieldset.append($label).append($input);
396       // password verify
397       var $label = one.lib.form.label('Verify Password');
398       var $input = one.lib.form.input('Verify Password');
399       $input.attr('id', one.main.admin.id.modal.add.form.verify);
400       $input.attr('type', 'password');
401       $fieldset.append($label).append($input);
402       // roles
403       var $label = one.lib.form.label('Roles');
404       var options = {
405         "Network-Admin" : "Network Administrator",
406         "Network-Operator" : "Network Operator"
407       };
408       var $select = one.lib.form.select.create(options);
409       $select.attr('id', one.main.admin.id.modal.add.form.role);
410       $fieldset.append($label).append($select);
411       $form.append($fieldset);
412       return $form;
413     },
414     footer : function() {
415       var footer = [];
416
417       var addButton = one.lib.dashlet.button.single("Add User",
418           one.main.admin.id.modal.add.user, "btn-primary", "");
419       var $addButton = one.lib.dashlet.button.button(addButton);
420       footer.push($addButton);
421
422       var closeButton = one.lib.dashlet.button.single("Close",
423           one.main.admin.id.modal.add.close, "", "");
424       var $closeButton = one.lib.dashlet.button.button(closeButton);
425       footer.push($closeButton);
426
427       return footer;
428     }
429   },
430   password : {
431     initialize : function(id, successCallback) {
432       var h3 = 'Change Password';
433       var footer = one.main.admin.password.footer();
434       var $body = one.main.admin.password.body(id);;
435       var $modal = one.lib.modal.spawn(one.main.admin.id.modal.password.modal,
436           h3, $body, footer);
437
438       // cancel binding
439       $('#'+one.main.admin.id.modal.password.cancel, $modal).click(function() {
440         $modal.modal('hide');
441       });
442
443       // change password binding
444       $('#'+one.main.admin.id.modal.password.submit, $modal).click(function() {
445         one.main.admin.password.submit(id, $modal, function(result) {
446           if (result.success) {
447             //if changed own password, enforce relogin
448             if (id.trim() == $('#currentuser').val().trim()) {
449                 alert("Password changed successfully. Please re-login with your new password.");
450                 window.location = '/';
451             }
452           } else {
453             alert(result.code+': '+result.description);
454           }
455         });
456       });
457
458       $modal.modal();
459     },
460     submit : function(id, $modal, callback) {
461       var resource = {};
462       resource.newPassword = $('#'+one.main.admin.id.modal.password.form.set, $modal).val();
463
464       // verify password
465       var verify = $('#'+one.main.admin.id.modal.password.form.verify, $modal).val();
466       if (verify != resource.newPassword) {
467         alert('Passwords do not match');
468         return false;
469       }
470
471       resource.currentPassword = $('#'+one.main.admin.id.modal.password.form.old, $modal).val();
472
473       $.post(one.main.admin.address.password+id, resource, function(data) {
474         callback(data);
475       });
476     },
477     body : function(id) {
478       var $form = $(document.createElement('form'));
479       var $fieldset = $(document.createElement('fieldset'));
480       // user
481       var $label = one.lib.form.label('Username');
482       var $input = one.lib.form.input('');
483       $input.attr('disabled', 'disabled');
484       $input.val(id);
485       $fieldset.append($label)
486         .append($input);
487       // old password
488       var $label = one.lib.form.label('Old Password');
489       var $input = one.lib.form.input('Old Password');
490       $input.attr('id', one.main.admin.id.modal.password.form.old);
491       $input.attr('type', 'password');
492       $fieldset.append($label).append($input);
493       // new password
494       var $label = one.lib.form.label('New Password');
495       var $input = one.lib.form.input('New Password');
496       $input.attr('id', one.main.admin.id.modal.password.form.set);
497       $input.attr('type', 'password');
498       $fieldset.append($label).append($input);
499       // verify new password
500       var $label = one.lib.form.label('Verify Password');
501       var $input = one.lib.form.input('Verify Password');
502       $input.attr('id', one.main.admin.id.modal.password.form.verify);
503       $input.attr('type', 'password');
504       $fieldset.append($label).append($input);
505       // return
506       $form.append($fieldset);
507       return $form;
508     },
509     footer : function() {
510       var footer = [];
511       var submit = one.lib.dashlet.button.single('Submit',
512           one.main.admin.id.modal.password.submit, 'btn-primary', '');
513       var $submit = one.lib.dashlet.button.button(submit);
514       footer.push($submit);
515       var cancel = one.lib.dashlet.button.single('Cancel',
516           one.main.admin.id.modal.password.cancel, '', '');
517       var $cancel = one.lib.dashlet.button.button(cancel);
518       footer.push($cancel);
519       return footer;
520     }
521   }
522 }
523
524 one.main.cluster = {
525   id : { // one.main.cluster.id
526     modal : 'one-main-cluster-id-modal',
527     close : 'one-main-cluster-id-close',
528     datagrid : 'one-main-cluster-id-datagrid'
529   },
530   initialize : function() {
531     var h3 = 'Cluster Management';
532     var footer = one.main.cluster.footer();
533     var $body = '';
534     var $modal = one.lib.modal.spawn(one.main.cluster.id.modal, h3, $body, footer); 
535
536     // close
537     $('#'+one.main.cluster.id.close, $modal).click(function() {
538       $modal.modal('hide');
539     });
540
541     // body
542     $.getJSON('/admin/cluster', function(data) {
543       var $gridHTML = one.lib.dashlet.datagrid.init(one.main.cluster.id.datagrid, {
544         searchable: true,
545           filterable: false,
546           pagination: true,
547           flexibleRowsPerPage: true
548       }, 'table-striped table-condensed table-cursor');
549       var source = one.main.cluster.data(data);
550       $gridHTML.datagrid({dataSource : source}).on('loaded', function() {
551         $(this).find('tbody tr').click(function() {
552           var $tr = $(this);
553           if ($tr.find('td:nth-child(1)').attr('colspan') === '1') {
554             return false;
555           }
556           var address = $tr.find('.ux-id').text();
557           one.main.cluster.nodes.initialize(address);
558         });
559       });
560       one.lib.modal.inject.body($modal, $gridHTML);
561     });
562
563     $modal.modal();
564   },
565   data : function(data) {
566     var tdata = [];
567     var registry = [];
568     $(data).each(function(idx, controller) {
569       var name = controller.name;
570       var address = controller.address;
571       var $registry = $(document.createElement('span'));
572       $registry
573       .append(JSON.stringify(address))
574       .css('display', 'none')
575       .addClass('ux-id');
576     name = one.lib.dashlet.label(name, null)[0].outerHTML;
577     name += $registry[0].outerHTML;
578     if (controller.me === true) {
579       var me = one.lib.dashlet.label('*', 'label-inverse')[0].outerHTML;
580       name += '&nbsp;'+me;
581     }
582     if (controller.coordinator === true) {
583       var coord = one.lib.dashlet.label('C')[0].outerHTML;
584       name += '&nbsp;'+coord;
585     }
586     tdata.push({
587       'controller' : name,
588       'numNodes'   : controller.numConnectedNodes
589     });
590     });
591     var source = new StaticDataSource({
592         columns : [
593             {
594               property : 'controller',
595                 label : 'Controller',
596                 sortable : true
597             },
598             {
599                 property : 'numNodes',
600                 label    : 'Nodes',
601                 sortable : true
602             }
603         ],
604         data : tdata,
605         delay : 0
606     });
607     return source;
608   },
609   footer : function() {
610     var footer = [];
611     var close = one.lib.dashlet.button.single('Close', one.main.cluster.id.close, '', '');
612     var $close = one.lib.dashlet.button.button(close);
613     footer.push($close);
614     return footer;
615   }
616 }
617
618 one.main.cluster.nodes = {
619   id : { // one.main.cluster.nodes.id
620     modal : 'one-main-cluster-nodes-id-modal',
621     close : 'one-main-cluster-nodes-id-close',
622     datagrid : 'one-main-cluser-nodes-id-datagrid'
623   },
624   initialize : function(address) { // one.main.cluster.nodes.initialize
625     var h3 = 'Connected Nodes';
626     var footer = one.main.cluster.nodes.footer();
627     var $body = '';
628     var $modal = one.lib.modal.spawn(one.main.cluster.nodes.id.modal, h3, $body, footer);
629
630     // close
631     $('#'+one.main.cluster.nodes.id.close, $modal).click(function() {
632       $modal.modal('hide');
633     });
634
635     // body
636     $.getJSON('/admin/cluster/controller/'+address, function(data) {
637       var $gridHTML = one.lib.dashlet.datagrid.init(one.main.cluster.nodes.id.datagrid, {
638         searchable: true,
639           filterable: false,
640           pagination: true,
641           flexibleRowsPerPage: true
642       }, 'table-striped table-condensed');
643       var source = one.main.cluster.nodes.data(data);
644       $gridHTML.datagrid({dataSource : source});
645       one.lib.modal.inject.body($modal, $gridHTML);
646     });
647
648     $modal.modal();
649   },
650   data : function(data) {
651     var tdata = [];
652     $(data).each(function(idx, val) {
653       tdata.push({
654         'node' : val.description
655       });
656     });
657     var source = new StaticDataSource({
658       columns : [
659     {
660       property : 'node',
661         label : 'Node',
662         sortable : true
663     }
664     ],
665         data : tdata,
666         delay : 0
667     });
668     return source;
669   },
670   footer : function() { // one.main.cluster.nodes.footer
671     var footer = [];
672     var close = one.lib.dashlet.button.single('Close', one.main.cluster.nodes.id.close, '', '');
673     var $close = one.lib.dashlet.button.button(close);
674     footer.push($close);
675     return footer;
676   }
677 }
678
679 one.main.dashlet = {
680   left : {
681     top : $("#left-top .dashlet"),
682     bottom : $("#left-bottom .dashlet")
683   },
684   right : {
685     bottom : $("#right-bottom .dashlet")
686   }
687 }
688
689 /** BOOTSTRAP */
690 $(".modal").on('hidden', function() {
691   $(this).remove();
692 });
693
694 $("#alert .close").click(function() {
695   $("#alert").hide();
696 });
697
698 /** INIT */
699
700 // parse role
701 one.role = $('#admin').data('role');
702
703 // user admin
704 $("#admin").click(function() {
705   one.main.admin.modal.initialize(function($modal) {
706     $modal.modal();
707   });
708 });
709
710 // cluster
711 $('#cluster').click(function() {
712   one.main.cluster.initialize();
713 });
714
715 // save
716 $("#save").click(function() {
717   $.post(one.main.constants.address.save, function(data) {
718     if (data == "Success") {
719       one.lib.alert("Configuration Saved");
720     } else {
721       one.lib.alert("Unable to save configuration: " + data);
722     }
723   });
724 });
725
726 // logout
727 $("#logout").click(function() {
728   location.href = "/logout";
729 });
730
731 // felix osgi runtime
732 $("#osgi").click(function() {
733   window.open("/controller/osgi/system/console", '_newtab');
734 });
735
736 $.ajaxSetup({
737   complete : function(xhr, textStatus) {
738     var mime = xhr.getResponseHeader('Content-Type');
739     if (mime.substring(0, 9) == 'text/html') {
740       location.href = '/';
741     }
742   }
743 });
744
745 /** MAIN PAGE LOAD */
746 one.main.menu.load();