From 027770a7b4ff5dcd7d4ffaa93159a605de58a803 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Fri, 5 Aug 2011 18:14:33 +0200 Subject: [PATCH] Feature #746: Complete review of Sunstone client code and plugins. This revision contains many changes in the Sunstone client side. Most of them are motivated by the wish of gaining efficience by watching and delimiting calls to jQuery as much as possible. There are also bugfixes and small improvements regarding ACLs, drop down selects... oZones client javascript files have been fixed to work with the new version as well. Feature #765: Included here, at it affects only 2 lines in the acl plugins. --- .../public/js/plugins/aggregated-tab.js | 6 - .../Server/public/js/plugins/dashboard-tab.js | 3 +- .../Server/public/js/plugins/vdcs-tab.js | 1 - .../Server/public/js/plugins/zones-tab.js | 1 - src/sunstone/etc/sunstone-plugins.yaml | 5 + src/sunstone/public/js/plugins/acls-tab.js | 104 ++++-- .../public/js/plugins/dashboard-tab.js | 32 +- .../public/js/plugins/dashboard-users-tab.js | 21 +- src/sunstone/public/js/plugins/groups-tab.js | 75 ++-- src/sunstone/public/js/plugins/hosts-tab.js | 83 ++--- src/sunstone/public/js/plugins/images-tab.js | 207 +++++------ .../public/js/plugins/templates-tab.js | 327 ++++++++--------- src/sunstone/public/js/plugins/users-tab.js | 66 ++-- src/sunstone/public/js/plugins/vms-tab.js | 304 +++++++-------- src/sunstone/public/js/plugins/vnets-tab.js | 128 +++---- src/sunstone/public/js/sunstone-util.js | 346 ++++++++++-------- src/sunstone/public/js/sunstone.js | 128 ++++--- 17 files changed, 935 insertions(+), 902 deletions(-) diff --git a/src/ozones/Server/public/js/plugins/aggregated-tab.js b/src/ozones/Server/public/js/plugins/aggregated-tab.js index 3f7f83db4c..710e5fa53b 100644 --- a/src/ozones/Server/public/js/plugins/aggregated-tab.js +++ b/src/ozones/Server/public/js/plugins/aggregated-tab.js @@ -186,7 +186,6 @@ var agg_actions = { waitingNodes(dataTable_agg_hosts); Sunstone.runAction("ZoneHosts.list"); }, - callback: Empty, error: onError, notify: false }, @@ -207,7 +206,6 @@ var agg_actions = { waitingNodes(dataTable_agg_vms); Sunstone.runAction("ZoneVMs.list"); }, - callback: Empty, error: onError, notify: false }, @@ -228,7 +226,6 @@ var agg_actions = { waitingNodes(dataTable_agg_vns); Sunstone.runAction("ZoneVNs.list"); }, - callback: Empty, error: onError, notify: false }, @@ -249,7 +246,6 @@ var agg_actions = { waitingNodes(dataTable_agg_images); Sunstone.runAction("ZoneImages.list"); }, - callback: Empty, error: onError, notify: false }, @@ -270,7 +266,6 @@ var agg_actions = { waitingNodes(dataTable_agg_users); Sunstone.runAction("ZoneUsers.list"); }, - callback: Empty, error: onError, notify: false }, @@ -291,7 +286,6 @@ var agg_actions = { waitingNodes(dataTable_agg_templates); Sunstone.runAction("ZoneTemplates.list"); }, - callback: Empty, error: onError, notify: false }, diff --git a/src/ozones/Server/public/js/plugins/dashboard-tab.js b/src/ozones/Server/public/js/plugins/dashboard-tab.js index 20761d59b3..34553f45ab 100644 --- a/src/ozones/Server/public/js/plugins/dashboard-tab.js +++ b/src/ozones/Server/public/js/plugins/dashboard-tab.js @@ -177,8 +177,7 @@ var dashboard_tab_content = var dashboard_tab = { title: 'Dashboard', - content: dashboard_tab_content, - condition : True + content: dashboard_tab_content } Sunstone.addMainTab('dashboard_tab',dashboard_tab); diff --git a/src/ozones/Server/public/js/plugins/vdcs-tab.js b/src/ozones/Server/public/js/plugins/vdcs-tab.js index 9c113c1da7..c995495f43 100644 --- a/src/ozones/Server/public/js/plugins/vdcs-tab.js +++ b/src/ozones/Server/public/js/plugins/vdcs-tab.js @@ -94,7 +94,6 @@ var vdc_actions = { waitingNodes(dataTable_vdcs); Sunstone.runAction("Zone.list"); }, - callback: Empty, error: onError }, diff --git a/src/ozones/Server/public/js/plugins/zones-tab.js b/src/ozones/Server/public/js/plugins/zones-tab.js index 1006d523b8..920d024609 100644 --- a/src/ozones/Server/public/js/plugins/zones-tab.js +++ b/src/ozones/Server/public/js/plugins/zones-tab.js @@ -91,7 +91,6 @@ var zone_actions = { waitingNodes(dataTable_zones); Sunstone.runAction("Zone.list"); }, - callback: Empty, error: onError, notify: false }, diff --git a/src/sunstone/etc/sunstone-plugins.yaml b/src/sunstone/etc/sunstone-plugins.yaml index 3b4c997c4d..38228d404e 100644 --- a/src/sunstone/etc/sunstone-plugins.yaml +++ b/src/sunstone/etc/sunstone-plugins.yaml @@ -40,3 +40,8 @@ :user: :group: oneadmin: true +- plugins/acls-tab.js: + :ALL: false + :user: + :group: + oneadmin: true diff --git a/src/sunstone/public/js/plugins/acls-tab.js b/src/sunstone/public/js/plugins/acls-tab.js index 8f2a4ab7b0..d25e45dc49 100644 --- a/src/sunstone/public/js/plugins/acls-tab.js +++ b/src/sunstone/public/js/plugins/acls-tab.js @@ -16,6 +16,7 @@ /*ACLs tab plugin*/ var dataTable_acls; +var $create_acl_dialog; var acls_tab_content = '
\ @@ -64,7 +65,7 @@ var create_acl_tmpl = \ \
\ - \ + \ Create
\ Delete
\ Use
\ @@ -73,6 +74,7 @@ var create_acl_tmpl = Get Pool of resources
\ Get Pool of my/group\'s resources
\ Change owner
\ + Deploy
\
\ \ \ @@ -114,7 +116,7 @@ var acl_actions = { call: function () { waitingNodes(dataTable_acls); Sunstone.runAction("Acl.list"); - }, + } }, "Acl.autorefresh" : { @@ -125,16 +127,14 @@ var acl_actions = { success: updateAclsView, error: onError }); - }, - condition: True, - notify: false + } }, "Acl.delete" : { type: "multiple", call: OpenNebula.Acl.delete, callback: deleteAclElement, - elements: function() { return getSelectedNodes(dataTable_acls); }, + elements: aclElements, error: onError, notify: true }, @@ -144,31 +144,38 @@ var acl_buttons = { "Acl.refresh" : { type: "image", text: "Refresh list", - img: "images/Refresh-icon.png", - condition: True + img: "images/Refresh-icon.png" }, "Acl.create_dialog" : { type: "create_dialog", - text: "+ New", - condition: True + text: "+ New" }, "Acl.delete" : { type: "action", - text: "Delete", - condition: True + text: "Delete" } } var acls_tab = { title: "ACLs", content: acls_tab_content, - buttons: acl_buttons, - condition: True + buttons: acl_buttons } Sunstone.addActions(acl_actions); Sunstone.addMainTab('acls_tab',acls_tab); +//Returns selected elements on the acl datatable +function aclElements(){ + return getSelectedNodes(dataTable_acls); +} + +//Receives a segment of an ACL and translates: +// * -> All +// @1 -> Group 1 (tries to translate "1" into group name) +// #1 -> User 1 (tries to translate "1" into username) +//Translation of usernames and groupnames depends on +//group and user plugins tables. function parseUserAcl(user){ var user_str=""; if (user[0] == '*'){ @@ -186,6 +193,7 @@ function parseUserAcl(user){ return user_str; } +//Similar to above, but #1 means resource with "ID 1" function parseResourceAcl(user){ var user_str=""; if (user[0] == '*'){ @@ -203,7 +211,9 @@ function parseResourceAcl(user){ return user_str; } -//Parses the string, returns a legible array +//Parses a full ACL string, and translates it into +//a legible array +//to be put in the datatable fields. function parseAclString(string) { var space_split = string.split(' '); var user = space_split[0]; @@ -258,7 +268,8 @@ function parseAclString(string) { return [user_str,resources_str,belonging_to,ops_str]; } - +//forms the array of data to be inserted from +//the raw json function aclElementArray(acl_json){ var acl = acl_json.ACL; var acl_string = acl.STRING; @@ -277,37 +288,41 @@ function aclElementArray(acl_json){ // Callback to delete a single element from the dataTable -function deleteAclElement(req){ - deleteElement(dataTable_acls,'#acl_'+req.request.data); +function deleteAclElement(request){ + deleteElement(dataTable_acls,'#acl_'+request.request.data); } +//update the datatable with new data function updateAclsView(request,list){ var list_array = []; - $.each(list,function(){ list_array.push(aclElementArray(this)); }); updateView(list_array,dataTable_acls); + updateDashboard("acls",list); } function setupCreateAclDialog(){ - $('div#dialogs').append('
'); - $('#create_acl_dialog').html(create_acl_tmpl); - + dialogs_context.append('
'); + $create_acl_dialog = $('#create_acl_dialog',dialogs_context); + var dialog = $create_acl_dialog; + dialog.html(create_acl_tmpl); + var height = Math.floor($(window).height()*0.8); //set height to a percentage of the window //Prepare jquery dialog - $('#create_acl_dialog').dialog({ + dialog.dialog({ autoOpen: false, modal:true, - width: 600 + width: 600, + height: height }); - $('#create_acl_dialog #res_subgroup_all').attr("checked","checked"); - $('#create_acl_dialog #res_id').attr("disabled","disabled"); - $('#create_acl_dialog #belonging_to').attr("disabled","disabled"); + $('#res_subgroup_all',dialog).attr("checked","checked"); + $('#res_id',dialog).attr("disabled","disabled"); + $('#belonging_to',dialog).attr("disabled","disabled"); - $('#create_acl_dialog button').button(); + $('button',dialog).button(); - $('.res_subgroup').click(function(){ + $('.res_subgroup',dialog).click(function(){ var value = $(this).val(); var context = $(this).parent(); switch (value) { @@ -326,8 +341,13 @@ function setupCreateAclDialog(){ }; }); - $('input,select',$('#create_acl_form')).live("change",function(){ - var context = $('#create_acl_form'); + $('input#res_id',dialog).keyup(function(){ + $(this).trigger("change"); + }); + + //update the rule preview every time some field changes + $('input,select',dialog).change(function(){ + var context = $('#create_acl_form',$create_acl_dialog); var user = $('#applies',context).val(); if ($('#applies :selected',context).hasClass("user")){ @@ -343,7 +363,7 @@ function setupCreateAclDialog(){ if (resources.length) { resources = resources.substring(0,resources.length-1) }; var belonging=""; - var mode = $('.res_subgroup:checked').val(); + var mode = $('.res_subgroup:checked',context).val(); switch (mode) { case "*": belonging="*"; @@ -368,7 +388,7 @@ function setupCreateAclDialog(){ }); - $('#create_acl_form').submit(function(){ + $('#create_acl_form',dialog).submit(function(){ var user = $('#applies',this).val(); if (!user.length) { notifyError("Please specify to who this ACL applies"); @@ -409,11 +429,14 @@ function setupCreateAclDialog(){ var acl_json = { "acl" : acl_string }; Sunstone.runAction("Acl.create",acl_json); - $('#create_acl_dialog').dialog('close'); + $create_acl_dialog.dialog('close'); return false; }); } +// Before popping up the dialog, some prepartions are +// required: we have to put the right options in the +// selects. function popUpCreateAclDialog(){ var users = $(''); $('.empty_value',users).remove(); @@ -425,19 +448,20 @@ function popUpCreateAclDialog(){ $('option',groups).addClass("group"); groups.prepend(''); - - $('#create_acl_dialog #applies').html(''+ + var dialog = $create_acl_dialog; + $('#applies',dialog).html(''+ users.html()+groups.html()); - $('#create_acl_dialog #belonging_to').html(groups_select); + $('#belonging_to',dialog).html(groups_select); - $('#create_acl_dialog').dialog('open'); + $('#applies',dialog).trigger("change"); + dialog.dialog('open'); } // Prepare the autorefresh of the list function setAclAutorefresh(){ setInterval(function(){ var checked = $('input:checked',dataTable_acls.fnGetNodes()); - var filter = $("#datatable_acls_filter input").attr("value"); + var filter = $("#datatable_acls_filter input",dataTable_acls.parents("#datatable_acls_wrapper")).attr("value"); if (!checked.length && !filter.length){ Sunstone.runAction("Acl.autorefresh"); } @@ -446,7 +470,7 @@ function setAclAutorefresh(){ $(document).ready(function(){ //if we are not oneadmin, our tab will not even be in the DOM. - dataTable_acls = $("#datatable_acls").dataTable({ + dataTable_acls = $("#datatable_acls",main_tabs_context).dataTable({ "bJQueryUI": true, "bSortClasses": false, "sPaginationType": "full_numbers", diff --git a/src/sunstone/public/js/plugins/dashboard-tab.js b/src/sunstone/public/js/plugins/dashboard-tab.js index 48e31f6a9f..56b2b475e8 100644 --- a/src/sunstone/public/js/plugins/dashboard-tab.js +++ b/src/sunstone/public/js/plugins/dashboard-tab.js @@ -14,6 +14,7 @@ /* limitations under the License. */ /* -------------------------------------------------------------------------- */ +/** HISTORY_LENGTH currently ignored on server, but it doesn't harm to have it**/ var HISTORY_LENGTH=40; var GRAPH_AUTOREFRESH_INTERVAL=60000; //60 secs @@ -81,6 +82,10 @@ var dashboard_tab_content = Users\ \ \ + \ + ACL Rules\ + \ + \ \ \ \ @@ -93,14 +98,15 @@ var dashboard_tab_content =

Quickstart

\
\
\ - \ + \ Host
\ - Group
\ - VM Template
\ VM Instance
\ + VM Template
\ Virtual Network
\ Image
\ User
\ + Group
\ + Acl
\
\ \ \ @@ -138,13 +144,13 @@ var dashboard_tab_content = var dashboard_tab = { title: 'Dashboard', - content: dashboard_tab_content, - condition : True + content: dashboard_tab_content } Sunstone.addMainTab('dashboard_tab',dashboard_tab); function plot_global_graph(data,info){ + var context = $('#historical_table',main_tabs_context); var id = info.title; var monitoring = data.monitoring; var serie; @@ -153,7 +159,7 @@ function plot_global_graph(data,info){ var mon_count = 0; var labels_array = info.monitor_resources.split(','); - $('#'+id).html('
'); + $('#'+id,context).html('
'); for (var i=0; i
'); + $('#'+id,context).html('
'); for (var i=0; i\ @@ -93,9 +92,7 @@ var group_actions = { waitingNodes(dataTable_groups); Sunstone.runAction("Group.list"); }, - callback: function(){}, - error: onError, - notify: false + error: onError }, "Group.delete" : { @@ -103,7 +100,7 @@ var group_actions = { call : OpenNebula.Group.delete, callback : deleteGroupElement, error : onError, - elements: function() { return getSelectedNodes(dataTable_groups); }, + elements: groupElements, notify:true }, @@ -122,13 +119,11 @@ var group_buttons = { "Group.refresh" : { type: "image", text: "Refresh list", - img: "images/Refresh-icon.png", - condition: True + img: "images/Refresh-icon.png" }, "Group.create_dialog" : { type: "create_dialog", - text: "+ New Group", - condition : True + text: "+ New Group" }, // "Group.chown" : { // type: "confirm_with_select", @@ -140,21 +135,23 @@ var group_buttons = { "Group.delete" : { type: "action", - text: "Delete", - condition : True + text: "Delete" } }; var groups_tab = { title: 'Groups', content: groups_tab_content, - buttons: group_buttons, - condition: True + buttons: group_buttons } Sunstone.addActions(group_actions); Sunstone.addMainTab('groups_tab',groups_tab); +function groupElements(){ + return getSelectedNodes(dataTable_groups); +} + function groupElementArray(group_json){ var group = group_json.GROUP; @@ -176,19 +173,24 @@ function groupElementArray(group_json){ users_str ]; } -function groupInfoListener(){ - $('#tbodygroups tr').live("click",function(e){ - //do nothing if we are clicking a checkbox! - if ($(e.target).is('input')) {return true;} - var aData = dataTable_groups.fnGetData(this); - var id = $(aData[0]).val(); - Sunstone.runAction("Group.showinfo",id); - return false; - }); -} +// function groupInfoListener(){ +// $('#groups_tab #tbodygroups tr',main_tabs_context).live("click",function(e){ +// //do nothing if we are clicking a checkbox! +// if ($(e.target).is('input')) {return true;} +// var aData = dataTable_groups.fnGetData(this); +// var id = $(aData[0]).val(); +// Sunstone.runAction("Group.showinfo",id); +// return false; +// }); +// } function updateGroupSelect(){ - groups_select = makeSelectOptions(dataTable_groups,1,2,-1,"",-1); + groups_select = makeSelectOptions(dataTable_groups, + 1,//id_col + 2,//name_col + [],//status_cols + []//bad_status_cols + ); } function updateGroupElement(request, group_json){ @@ -199,7 +201,7 @@ function updateGroupElement(request, group_json){ } function deleteGroupElement(request){ - deleteElement(dataTable_groups,'#group_'+req.request.data); + deleteElement(dataTable_groups,'#group_'+request.request.data); updateGroupSelect(); } @@ -226,27 +228,30 @@ function updateGroupsView(request, group_list){ //Prepares the dialog to create function setupCreateGroupDialog(){ - $('div#dialogs').append('
'); - $('#create_group_dialog').html(create_group_tmpl); - $('#create_group_dialog').dialog({ + dialogs_context.append('
'); + $create_group_dialog = $('#create_group_dialog',dialogs_context); + var dialog = $create_group_dialog; + + dialog.html(create_group_tmpl); + dialog.dialog({ autoOpen: false, modal: true, width: 400 }); - $('#create_group_dialog button').button(); + $('button',dialog).button(); - $('#create_group_form').submit(function(){ + $('#create_group_form',dialog).submit(function(){ var name=$('#name',this).val(); var group_json = { "group" : { "name" : name }}; Sunstone.runAction("Group.create",group_json); - $('#create_group_dialog').dialog('close'); + $create_group_dialog.dialog('close'); return false; }); } function popUpCreateGroupDialog(){ - $('#create_group_dialog').dialog('open'); + $create_group_dialog.dialog('open'); return false; } @@ -254,7 +259,7 @@ function popUpCreateGroupDialog(){ function setGroupAutorefresh(){ setInterval(function(){ var checked = $('input:checked',dataTable_groups.fnGetNodes()); - var filter = $("#datatable_groups_filter input").attr("value"); + var filter = $("#datatable_groups_filter input",dataTable_groups.parents("#datatable_groups_wrapper")).attr("value"); if (!checked.length && !filter.length){ Sunstone.runAction("Group.autorefresh"); } @@ -262,7 +267,7 @@ function setGroupAutorefresh(){ } $(document).ready(function(){ - dataTable_groups = $("#datatable_groups").dataTable({ + dataTable_groups = $("#datatable_groups",main_tabs_context).dataTable({ "bJQueryUI": true, "bSortClasses": false, "sPaginationType": "full_numbers", diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index 333388c144..655fe75d07 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -15,7 +15,7 @@ /* -------------------------------------------------------------------------- */ /*Host tab plugin*/ - +/* HOST_HISTORY_LENGTH is ignored by server */ var HOST_HISTORY_LENGTH = 40; var host_graphs = [ { @@ -98,8 +98,8 @@ var create_host_tmpl =
'; var hosts_select=""; -var host_list_json = {}; var dataTable_hosts; +var $create_host_dialog; //Setup actions var host_actions = { @@ -121,8 +121,7 @@ var host_actions = { type: "list", call: OpenNebula.Host.list, callback: updateHostsView, - error: onError, - notify: false + error: onError }, "Host.show" : { @@ -145,9 +144,7 @@ var host_actions = { waitingNodes(dataTable_hosts); Sunstone.runAction("Host.list"); }, - callback: function(){}, - error: onError, - notify:false + error: onError }, "Host.autorefresh" : { @@ -163,7 +160,7 @@ var host_actions = { callback : function (req) { Sunstone.runAction("Host.show",req.request.data[0]); }, - elements: function() { return getSelectedNodes(dataTable_hosts); }, + elements: hostElements, error : onError, notify: true }, @@ -174,7 +171,7 @@ var host_actions = { callback : function (req) { Sunstone.runAction("Host.show",req.request.data[0]); }, - elements: function() { return getSelectedNodes(dataTable_hosts); }, + elements: hostElements, error : onError, notify:true }, @@ -183,7 +180,7 @@ var host_actions = { type: "multiple", call : OpenNebula.Host.delete, callback : deleteHostElement, - elements: function() { return getSelectedNodes(dataTable_hosts); }, + elements: hostElements, error : onError, notify:true }, @@ -215,8 +212,7 @@ var host_actions = { callback: function (request,response) { $('#template_update_dialog #template_update_textarea').val(response.template); }, - error: onError, - notify: false + error: onError }, "Host.update_dialog" : { @@ -232,8 +228,7 @@ var host_actions = { callback: function() { notifyMessage("Template updated correctly"); }, - error: onError, - notify: false + error: onError } }; @@ -241,34 +236,28 @@ var host_buttons = { "Host.refresh" : { type: "image", text: "Refresh list", - img: "images/Refresh-icon.png", - condition: True + img: "images/Refresh-icon.png" }, "Host.create_dialog" : { type: "create_dialog", - text: "+ New", - condition :True + text: "+ New" }, "Host.update_dialog" : { type: "action", text: "Update a template", - condition: True, alwaysActive: true }, "Host.enable" : { type: "action", - text: "Enable", - condition : True + text: "Enable" }, "Host.disable" : { type: "action", - text: "Disable", - condition : True + text: "Disable" }, "Host.delete" : { type: "action", - text: "Delete host", - condition : True + text: "Delete host" } }; @@ -292,8 +281,7 @@ var host_info_panel = { var hosts_tab = { title: 'Hosts', content: hosts_tab_content, - buttons: host_buttons, - condition: True + buttons: host_buttons } Sunstone.addActions(host_actions); @@ -301,6 +289,10 @@ Sunstone.addMainTab('hosts_tab',hosts_tab); Sunstone.addInfoPanel("host_info_panel",host_info_panel); +function hostElements(){ + return getSelectedNodes(dataTable_hosts); +} + //Creates an array to be added to the dataTable from the JSON of a host. function hostElementArray(host_json){ @@ -357,8 +349,7 @@ function hostElementArray(host_json){ //Listen to clicks on the tds of the tables and shows the info dialogs. function hostInfoListener(){ - $('#tbodyhosts tr').live("click",function(e){ - + $('#tbodyhosts tr',dataTable_hosts).live("click",function(e){ //do nothing if we are clicking a checkbox! if ($(e.target).is('input')) {return true;} popDialogLoading(); @@ -371,7 +362,12 @@ function hostInfoListener(){ //updates the host select by refreshing the options in it function updateHostSelect(){ - hosts_select = makeSelectOptions(dataTable_hosts,1,2,7,"DISABLED",-1); + hosts_select = makeSelectOptions(dataTable_hosts, + 1,//id_col + 2,//name_col + [6,6],//status_cols + ["ERROR","OFF"]//bad_st + ); } //callback for an action affecting a host element @@ -398,7 +394,6 @@ function addHostElement(request,host_json){ //callback to update the list of hosts. function updateHostsView (request,host_list){ - host_list_json = host_list; var host_list_array = []; $.each(host_list,function(){ @@ -409,7 +404,7 @@ function updateHostsView (request,host_list){ updateView(host_list_array,dataTable_hosts); updateHostSelect(); //dependency with the dashboard plugin - updateDashboard("hosts",host_list_json); + updateDashboard("hosts",host_list); } //Updates the host info panel tab's content and pops it up @@ -511,18 +506,21 @@ function updateHostInfo(request,host){ //Prepares the host creation dialog function setupCreateHostDialog(){ - $('div#dialogs').append('
'); - $('div#create_host_dialog').html(create_host_tmpl); - $('#create_host_dialog').dialog({ + dialogs_context.append('
'); + $create_host_dialog = $('div#create_host_dialog'); + var dialog = $create_host_dialog; + + dialog.html(create_host_tmpl); + dialog.dialog({ autoOpen: false, modal: true, width: 500 }); - $('#create_host_dialog button').button(); + $('button',dialog).button(); //Handle the form submission - $('#create_host_form').submit(function(){ + $('#create_host_form',dialog).submit(function(){ if (!($('#name',this).val().length)){ notifyError("Host name missing!"); return false; @@ -539,14 +537,14 @@ function setupCreateHostDialog(){ //Create the OpenNebula.Host. //If it's successfull we refresh the list. Sunstone.runAction("Host.create",host_json); - $('#create_host_dialog').dialog('close'); + $create_host_dialog.dialog('close'); return false; }); } //Open creation dialogs function popUpCreateHostDialog(){ - $('#create_host_dialog').dialog('open'); + $create_host_dialog.dialog('open'); return false; } @@ -554,7 +552,7 @@ function popUpCreateHostDialog(){ function setHostAutorefresh() { setInterval(function(){ var checked = $('input:checked',dataTable_hosts.fnGetNodes()); - var filter = $("#datatable_hosts_filter input").attr("value"); + var filter = $("#datatable_hosts_filter input",dataTable_hosts.parents('#datatable_hosts_wrapper')).attr("value"); if (!checked.length && !filter.length){ Sunstone.runAction("Host.autorefresh"); } @@ -570,6 +568,9 @@ function hostMonitorError(req,error_json){ $('#host_monitoring_tab '+id).html('
'+message+'
'); } +function hosts_sel() { + return hosts_select; +} //This is executed after the sunstone.js ready() is run. //Here we can basicly init the host datatable, preload it @@ -577,7 +578,7 @@ function hostMonitorError(req,error_json){ $(document).ready(function(){ //prepare host datatable - dataTable_hosts = $("#datatable_hosts").dataTable({ + dataTable_hosts = $("#datatable_hosts",main_tabs_context).dataTable({ "bJQueryUI": true, "bSortClasses": false, "bAutoWidth":false, diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js index e0a675456a..b1ed59e5cb 100644 --- a/src/sunstone/public/js/plugins/images-tab.js +++ b/src/sunstone/public/js/plugins/images-tab.js @@ -156,8 +156,8 @@ var create_image_tmpl =
'; var images_select = ""; -var image_list_json = {}; var dataTable_images; +var $create_image_dialog; var image_actions = { @@ -216,8 +216,7 @@ var image_actions = { callback: function (request,response) { $('#template_update_dialog #template_update_textarea').val(response.template); }, - error: onError, - notify: false + error: onError }, "Image.update_dialog" : { @@ -233,8 +232,7 @@ var image_actions = { callback: function() { notifyMessage("Template updated correctly"); }, - error: onError, - notify: false + error: onError }, "Image.enable" : { @@ -243,7 +241,7 @@ var image_actions = { callback: function (req) { Sunstone.runAction("Image.show",req.request.data[0]); }, - elements: function() { return getSelectedNodes(dataTable_images); }, + elements: imageElements, error: onError, notify: true }, @@ -254,7 +252,7 @@ var image_actions = { callback: function (req) { Sunstone.runAction("Image.show",req.request.data[0]); }, - elements: function() { return getSelectedNodes(dataTable_images); }, + elements: imageElements, error: onError, notify: true }, @@ -265,7 +263,7 @@ var image_actions = { callback: function (req) { Sunstone.runAction("Image.show",req.request.data[0]); }, - elements: function() { return getSelectedNodes(dataTable_images); }, + elements: imageElements, error: onError, notify: true }, @@ -276,7 +274,7 @@ var image_actions = { callback: function (req) { Sunstone.runAction("Image.show",req.request.data[0]); }, - elements: function() { return getSelectedNodes(dataTable_images); }, + elements: imageElements, error: onError, notify: true }, @@ -287,7 +285,7 @@ var image_actions = { callback: function (req) { Sunstone.runAction("Image.show",req.request.data[0]); }, - elements: function() { return getSelectedNodes(dataTable_images); }, + elements: imageElements, error: onError, notify: true }, @@ -298,7 +296,7 @@ var image_actions = { callback: function (req) { Sunstone.runAction("Image.show",req.request.data[0]); }, - elements: function() { return getSelectedNodes(dataTable_images); }, + elements: imageElements, error: onError, notify: true }, @@ -307,7 +305,7 @@ var image_actions = { type: "multiple", call: OpenNebula.Image.delete, callback: deleteImageElement, - elements: function() { return getSelectedNodes(dataTable_images); }, + elements: imageElements, error: onError, notify: true }, @@ -318,7 +316,7 @@ var image_actions = { callback: function (req) { Sunstone.runAction("Image.show",req.request.data[0]); }, - elements: function() { return getSelectedNodes(dataTable_images); }, + elements: imageElements, error: onError, notify: true }, @@ -329,7 +327,7 @@ var image_actions = { callback: function (req) { Sunstone.runAction("Image.show",req.request.data[0]); }, - elements: function() { return getSelectedNodes(dataTable_images); }, + elements: imageElements, error: onError, notify: true } @@ -340,74 +338,63 @@ var image_buttons = { "Image.refresh" : { type: "image", text: "Refresh list", - img: "images/Refresh-icon.png", - condition: True + img: "images/Refresh-icon.png" }, "Image.create_dialog" : { type: "create_dialog", - text: "+ New", - condition: True + text: "+ New" }, "Image.update_dialog" : { type: "action", text: "Update a template", - condition: True, alwaysActive: true }, "Image.chown" : { type: "confirm_with_select", text: "Change owner", - select: function() {return users_select;}, + select: users_sel, tip: "Select the new owner:", - condition: function() { return gid == 0; } + condition: mustBeAdmin }, "Image.chgrp" : { type: "confirm_with_select", text: "Change group", - select: function() {return groups_select;}, + select: groups_sel, tip: "Select the new group:", - condition: function() { return gid == 0; } + condition: mustBeAdmin }, "action_list" : { type: "select", - condition: True, actions: { "Image.enable" : { type: "action", - text: "Enable", - condition: True + text: "Enable" }, "Image.disable" : { type: "action", - text: "Disable", - condition: True + text: "Disable" }, "Image.publish" : { type: "action", - text: "Publish", - condition: True + text: "Publish" }, "Image.unpublish" : { type: "action", - text: "Unpublish", - condition: True + text: "Unpublish" }, "Image.persistent" : { type: "action", - text: "Make persistent", - condition: True + text: "Make persistent" }, "Image.nonpersistent" : { type: "action", - text: "Make non persistent", - condition: True + text: "Make non persistent" } } }, "Image.delete" : { type: "action", - text: "Delete", - condition: True + text: "Delete" } } @@ -427,14 +414,18 @@ var image_info_panel = { var images_tab = { title: "Images", content: images_tab_content, - buttons: image_buttons, - condition: True + buttons: image_buttons } Sunstone.addActions(image_actions); Sunstone.addMainTab('images_tab',images_tab); Sunstone.addInfoPanel('image_info_panel',image_info_panel); + +function imageElements() { + return getSelectedNodes(dataTable_images); +} + // Returns an array containing the values of the image_json and ready // to be inserted in the dataTable function imageElementArray(image_json){ @@ -456,8 +447,7 @@ function imageElementArray(image_json){ // Set up the listener on the table TDs to show the info panel function imageInfoListener(){ - - $('#tbodyimages tr').live("click",function(e){ + $('#tbodyimages tr',dataTable_images).live("click",function(e){ if ($(e.target).is('input')) {return true;} popDialogLoading(); var aData = dataTable_images.fnGetData(this); @@ -470,11 +460,16 @@ function imageInfoListener(){ //Updates the select input field with an option for each image function updateImageSelect(){ images_select = - makeSelectOptions(dataTable_images,1,4,9,"DISABLED",2); + makeSelectOptions(dataTable_images, + 1, + 4, + [9,9,9], + ["DISABLED","LOCKED","ERROR"] + ); //update static selectors: //in the VM section - $('div.vm_section#disks select#IMAGE_ID').html(images_select); + $('div.vm_section#disks select#IMAGE_ID', $create_template_dialog).html(images_select); } // Callback to update an element in the dataTable @@ -500,16 +495,15 @@ function addImageElement(request, image_json){ // Callback to refresh the list of images function updateImagesView(request, images_list){ - image_list_json = images_list; var image_list_array = []; - $.each(image_list_json,function(){ + + $.each(images_list,function(){ image_list_array.push(imageElementArray(this)); }); updateView(image_list_array,dataTable_images); updateImageSelect(); - updateDashboard("images",image_list_json); - + updateDashboard("images",images_list); } // Callback to update the information panel tabs and pop it up @@ -582,85 +576,82 @@ function updateImageInfo(request,img){ // Prepare the image creation dialog function setupCreateImageDialog(){ - $('div#dialogs').append('
'); - - //Insert HTML in place - $('#create_image_dialog').html(create_image_tmpl); + dialogs_context.append('
'); + $create_image_dialog = $('#create_image_dialog',dialogs_context); + var dialog = $create_image_dialog; + dialog.html(create_image_tmpl); var height = Math.floor($(window).height()*0.8); //set height to a percentage of the window //Prepare jquery dialog - $('#create_image_dialog').dialog({ + dialog.dialog({ autoOpen: false, modal:true, width: 520, height: height }); - $('#img_tabs').tabs(); - $('#create_image_dialog button').button(); - $('#img_type option').first().attr("selected","selected"); - $('#datablock_img').attr("disabled","disabled"); + $('#img_tabs',dialog).tabs(); + $('button',dialog).button(); + $('#img_type option',dialog).first().attr("selected","selected"); + $('#datablock_img',dialog).attr("disabled","disabled"); - //Chrome workaround - $('select#img_type').change(function(){ - $(this).trigger("click"); - }); - - $('select#img_type').click(function(){ + $('select#img_type',dialog).change(function(){ var value = $(this).val(); + var context = $create_image_dialog; switch (value){ case "DATABLOCK": - $('#datablock_img').removeAttr("disabled"); + $('#datablock_img',context).removeAttr("disabled"); break; default: - $('#datablock_img').attr("disabled","disabled"); - $('#path_img').attr("checked","checked"); - $('#img_source,#img_fstype,#img_size').parent().hide(); - $('#img_path').parent().show(); + $('#datablock_img',context).attr("disabled","disabled"); + $('#path_img',context).attr("checked","checked"); + $('#img_source,#img_fstype,#img_size',context).parent().hide(); + $('#img_path',context).parent().show(); } }); - $('#img_source,#img_fstype,#img_size').parent().hide(); - $('#path_img').attr("checked","checked"); - $('#img_path').parent().addClass("img_man"); + $('#img_source,#img_fstype,#img_size',dialog).parent().hide(); + $('#path_img',dialog).attr("checked","checked"); + $('#img_path',dialog).parent().addClass("img_man"); - $('#img_public').click(function(){ - $('#img_persistent').removeAttr("checked"); + $('#img_public',dialog).click(function(){ + $('#img_persistent',$create_image_dialog).removeAttr("checked"); }); - $('#img_persistent').click(function(){ - $('#img_public').removeAttr("checked"); + $('#img_persistent',dialog).click(function(){ + $('#img_public',$create_image_dialog).removeAttr("checked"); }); $('#src_path_select input').click(function(){ + var context = $create_image_dialog; var value = $(this).val(); switch (value){ case "path": - $('#img_source,#img_fstype,#img_size').parent().hide(); - $('#img_source,#img_fstype,#img_size').parent().removeClass("img_man"); - $('#img_path').parent().show(); - $('#img_path').parent().addClass("img_man"); + $('#img_source,#img_fstype,#img_size',context).parent().hide(); + $('#img_source,#img_fstype,#img_size',context).parent().removeClass("img_man"); + $('#img_path',context).parent().show(); + $('#img_path',context).parent().addClass("img_man"); break; case "source": - $('#img_path,#img_fstype,#img_size').parent().hide(); - $('#img_path,#img_fstype,#img_size').parent().removeClass("img_man"); - $('#img_source').parent().show(); - $('#img_source').parent().addClass("img_man"); + $('#img_path,#img_fstype,#img_size',context).parent().hide(); + $('#img_path,#img_fstype,#img_size',context).parent().removeClass("img_man"); + $('#img_source',context).parent().show(); + $('#img_source',context).parent().addClass("img_man"); break; case "datablock": - $('#img_source,#img_path').parent().hide(); - $('#img_source,#img_path').parent().removeClass("img_man"); - $('#img_fstype,#img_size').parent().show(); - $('#img_fstype,#img_size').parent().addClass("img_man"); + $('#img_source,#img_path',context).parent().hide(); + $('#img_source,#img_path',context).parent().removeClass("img_man"); + $('#img_fstype,#img_size',context).parent().show(); + $('#img_fstype,#img_size',context).parent().addClass("img_man"); break; } }); - $('#create_image_form_easy').submit(function(){ + $('#create_image_form_easy',dialog).submit(function(){ var exit = false; $('.img_man',this).each(function(){ if (!$('input',this).val().length){ @@ -672,41 +663,41 @@ function setupCreateImageDialog(){ if (exit) { return false; } var img_json = {}; - var name = $('#img_name').val(); + var name = $('#img_name',this).val(); img_json["NAME"] = name; - var desc = $('#img_desc').val(); + var desc = $('#img_desc',this).val(); if (desc.length){ img_json["DESCRIPTION"] = desc; } - var type = $('#img_type').val(); + var type = $('#img_type',this).val(); img_json["TYPE"]= type; - img_json["PUBLIC"] = $('#img_public:checked').length ? "YES" : "NO"; + img_json["PUBLIC"] = $('#img_public:checked',this).length ? "YES" : "NO"; - img_json["PERSISTENT"] = $('#img_persistent:checked').length ? "YES" : "NO"; + img_json["PERSISTENT"] = $('#img_persistent:checked',this).length ? "YES" : "NO"; - var dev_prefix = $('#img_dev_prefix').val(); + var dev_prefix = $('#img_dev_prefix',this).val(); if (dev_prefix.length){ img_json["DEV_PREFIX"] = dev_prefix; } - var bus = $('#img_bus').val(); + var bus = $('#img_bus',this).val(); img_json["BUS"] = bus; - switch ($('#src_path_select input:checked').val()){ + switch ($('#src_path_select input:checked',this).val()){ case "path": - path = $('#img_path').val(); + path = $('#img_path',this).val(); img_json["PATH"] = path; break; case "source": - source = $('#img_source').val(); + source = $('#img_source',this).val(); img_json["SOURCE"] = source; break; case "datablock": - size = $('#img_size').val(); - fstype = $('#img_fstype').val(); + size = $('#img_size',this).val(); + fstype = $('#img_fstype',this).val(); img_json["SIZE"] = size; img_json["FSTYPE"] = fstype; break; @@ -714,28 +705,28 @@ function setupCreateImageDialog(){ var obj = { "image" : img_json }; Sunstone.runAction("Image.register", obj); - $('#create_image_dialog').dialog('close'); + $create_image_dialog.dialog('close'); return false; }); - $('#create_image_form_manual').submit(function(){ + $('#create_image_form_manual',dialog).submit(function(){ var template=$('#template',this).val(); Sunstone.runAction("Image.register",template); - $('#create_image_dialog').dialog('close'); + $create_image_dialog.dialog('close'); return false; }); - } function popUpCreateImageDialog(){ - $('#create_image_dialog').dialog('open'); + $create_image_dialog.dialog('open'); } // Set the autorefresh interval for the datatable function setImageAutorefresh() { setInterval(function(){ var checked = $('input:checked',dataTable_images.fnGetNodes()); - var filter = $("#datatable_images_filter input").attr("value"); + var filter = $("#datatable_images_filter input", + dataTable_images.parents("#datatable_images_wrapper")).attr("value"); if (!checked.length && !filter.length){ Sunstone.runAction("Image.autorefresh"); } @@ -745,7 +736,7 @@ function setImageAutorefresh() { //The DOM is ready at this point $(document).ready(function(){ - dataTable_images = $("#datatable_images").dataTable({ + dataTable_images = $("#datatable_images",main_tabs_context).dataTable({ "bJQueryUI": true, "bSortClasses": false, "bAutoWidth":false, @@ -765,7 +756,7 @@ $(document).ready(function(){ Sunstone.runAction("Image.list"); setupCreateImageDialog(); - setupTips($('#create_image_dialog')); + setupTips($create_image_dialog); setImageAutorefresh(); initCheckAllBoxes(dataTable_images); diff --git a/src/sunstone/public/js/plugins/templates-tab.js b/src/sunstone/public/js/plugins/templates-tab.js index 61853318c3..cd89b8856b 100644 --- a/src/sunstone/public/js/plugins/templates-tab.js +++ b/src/sunstone/public/js/plugins/templates-tab.js @@ -581,8 +581,8 @@ var create_template_tmpl = '
\
'; var templates_select = ""; -var template_list_json = {}; var dataTable_templates; +var $create_template_dialog; var template_actions = { @@ -648,8 +648,7 @@ var template_actions = { callback: function() { notifyMessage("Template updated correctly"); }, - error: onError, - notify: false + error: onError }, "Template.fetch_template" : { @@ -658,45 +657,39 @@ var template_actions = { callback: function (request,response) { $('#template_update_dialog #template_update_textarea').val(response.template); }, - error: onError, - notify: false + error: onError }, "Template.publish" : { type: "multiple", call: OpenNebula.Template.publish, - callback: function (req) { - Sunstone.runAction("Template.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_templates); }, + callback: templateShow, + elements: templateElements, error: onError, notify: true }, "Template.unpublish" : { - type: "multiple", - call: OpenNebula.Template.unpublish, - callback: function (req) { - Sunstone.runAction("Template.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_templates); }, - error: onError, - notify: true + type: "multiple", + call: OpenNebula.Template.unpublish, + callback: templateShow, + elements: templateElements, + error: onError, + notify: true }, "Template.delete" : { - type: "multiple", - call: OpenNebula.Template.delete, - callback: deleteTemplateElement, - elements: function() { return getSelectedNodes(dataTable_templates); }, - error: onError, - notify: true + type: "multiple", + call: OpenNebula.Template.delete, + callback: deleteTemplateElement, + elements: templateElements, + error: onError, + notify: true }, "Template.instantiate" : { type: "single", call: OpenNebula.Template.instantiate, - callback: function(){}, error: onError, notify: true }, @@ -709,89 +702,75 @@ var template_actions = { Sunstone.runAction("Template.instantiate",this,""); }); Sunstone.runAction("VM.refresh"); - }, - notify: false + } }, "Template.chown" : { type: "multiple", call: OpenNebula.Template.chown, - callback: function (req) { - Sunstone.runAction("Template.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_templates); }, + callback: templateShow, + elements: templateElements, error:onError, notify: true }, "Template.chgrp" : { type: "multiple", call: OpenNebula.Template.chgrp, - callback: function (req) { - Sunstone.runAction("Template.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_templates); }, + callback: templateShow, + elements: templateElements, error:onError, notify: true } } - var template_buttons = { "Template.refresh" : { type: "image", text: "Refresh list", - img: "images/Refresh-icon.png", - condition: True + img: "images/Refresh-icon.png" }, "Template.create_dialog" : { type: "create_dialog", - text: "+ New", - condition: True + text: "+ New" }, "Template.update_dialog" : { type: "action", text: "Update a template", - condition: True, alwaysActive: true }, "Template.instantiate_vms" : { type: "action", - text: "Instantiate", - condition: True + text: "Instantiate" }, "Template.chown" : { type: "confirm_with_select", text: "Change owner", - select: function() {return users_select;}, + select: users_sel, tip: "Select the new owner:", - condition: function(){return gid==0;} + condition: mustBeAdmin }, "Template.chgrp" : { type: "confirm_with_select", text: "Change group", - select: function() {return groups_select;}, + select: groups_sel, tip: "Select the new group:", - condition: function(){return gid==0;} + condition: mustBeAdmin }, "action_list" : { type: "select", - condition: True, actions: { "Template.publish" : { type: "action", - text: "Publish", - condition: True + text: "Publish" }, "Template.unpublish" : { type: "action", - text: "Unpublish", - condition: True + text: "Unpublish" }, } }, "Template.delete" : { type: "action", - text: "Delete", - condition: True + text: "Delete" } } @@ -805,14 +784,23 @@ var template_info_panel = { var templates_tab = { title: "Templates", content: templates_tab_content, - buttons: template_buttons, - condition: True + buttons: template_buttons } Sunstone.addActions(template_actions); Sunstone.addMainTab('templates_tab',templates_tab); Sunstone.addInfoPanel('template_info_panel',template_info_panel); +//Returns selected elements in the template table +function templateElements(){ + return getSelectedNodes(dataTable_templates); +} + +//Runs a show action on the template with from a prev request +function templateShow(req){ + Sunstone.runAction("Template.show",req.request.data[0]); +} + // Returns an array containing the values of the template_json and ready // to be inserted in the dataTable function templateElementArray(template_json){ @@ -830,8 +818,7 @@ function templateElementArray(template_json){ // Set up the listener on the table TDs to show the info panel function templateInfoListener(){ - - $('#tbodytemplates tr').live("click",function(e){ + $('#tbodytemplates tr',dataTable_templates).live("click",function(e){ if ($(e.target).is('input')) {return true;} popDialogLoading(); var aData = dataTable_templates.fnGetData(this); @@ -844,11 +831,15 @@ function templateInfoListener(){ //Updates the select input field with an option for each template function updateTemplateSelect(){ templates_select = - makeSelectOptions(dataTable_templates,1,4,7,"no",2); + makeSelectOptions(dataTable_templates, + 1,//id_col + 4,//name_col + [7],//published_col + ["no"]//bad status col + ); //update static selectors: - $('#create_vm_dialog #template_id').html(templates_select); - $('#speed_virt').html(templates_select); + $('#template_id', $create_vm_dialog).html(templates_select); } // Callback to update an element in the dataTable @@ -874,15 +865,15 @@ function addTemplateElement(request, template_json){ // Callback to refresh the list of templates function updateTemplatesView(request, templates_list){ - template_list_json = templates_list; var template_list_array = []; - $.each(template_list_json,function(){ + + $.each(templates_list,function(){ template_list_array.push(templateElementArray(this)); }); updateView(template_list_array,dataTable_templates); updateTemplateSelect(); - updateDashboard("templates",template_list_json); + updateDashboard("templates",templates_list); } @@ -935,7 +926,6 @@ function updateTemplateInfo(request,template){ Sunstone.updateInfoPanelTab("template_info_panel","template_template_tab",template_tab); Sunstone.popUpInfoPanel("template_info_panel"); - } // Prepare the template creation dialog @@ -950,30 +940,30 @@ function setupCreateTemplateDialog(){ // ui.index // zero-based index of the selected (clicked) tab //disable all items - $(items).attr("disabled","disabled"); + $(items,dialog).attr("disabled","disabled"); //hide all mandatory icons - $('.vm_param .man_icon').css("display","none"); + $('.vm_param .man_icon',dialog).css("display","none"); //empty selects - $('div#os_boot_opts select#BOOT').empty(); - $('div#disks select#TYPE').empty(); - $('div#disks select#BUS').empty(); + $('select#BOOT',section_os_boot).empty(); + $('select#TYPE',section_disks).empty(); + $('select#BUS',section_disks).empty(); //hide options about boot method $('div#kernel_bootloader',section_os_boot).show(); - $('.kernel, .bootloader', $('div#os_boot_opts')).hide(); - $('div#os_boot_opts select#BOOT').parent().hide(); + $('.kernel, .bootloader', section_os_boot).hide(); + $('select#BOOT',section_os_boot).parent().hide(); //unselect boot method - $('select#boot_method option').removeAttr("selected"); + $('select#boot_method option',section_os_boot).removeAttr("selected"); //hide non common sections $(section_inputs).hide(); $(section_graphics).hide(); //Repopulate images select - $('div.vm_section#disks select#IMAGE_ID').html(images_select); + $('select#IMAGE_ID',section_disks).html(images_select); //Repopulate network select - $('div.vm_section#networks select#NETWORK_ID').html(vnetworks_select); + $('select#NETWORK_ID',section_networks).html(vnetworks_select); switch(ui.index){ @@ -1020,8 +1010,8 @@ function setupCreateTemplateDialog(){ var enable_kvm = function(){ man_class="kvm"; opt_class="kvm_opt"; - $(kvm_items).removeAttr("disabled"); - $('.kvm .man_icon').css("display","inline-block"); + $(kvm_items,dialog).removeAttr("disabled"); + $('.kvm .man_icon',dialog).css("display","inline-block"); //KVM particularities: // * Add custom disk types @@ -1040,7 +1030,7 @@ function setupCreateTemplateDialog(){ \ '; - $('div#disks select#TYPE').html(type_opts); + $('select#TYPE',section_disks).html(type_opts); var boot_opts = '\ @@ -1048,16 +1038,16 @@ function setupCreateTemplateDialog(){ \ '; - $('div#os_boot_opts select#BOOT').html(boot_opts); - $('div#os_boot_opts select#BOOT').parent().show(); - $('select#boot_method option#no_boot').html("Driver default"); + $('select#BOOT',section_os_boot).html(boot_opts); + $('select#BOOT',section_os_boot).parent().show(); + $('select#boot_method option#no_boot',section_os_boot).html("Driver default"); var bus_opts = '\ \ '; - $('div#disks select#BUS').html(bus_opts); + $('select#BUS',section_disks).html(bus_opts); $('input#TYPE', section_raw).val("kvm"); @@ -1069,8 +1059,8 @@ function setupCreateTemplateDialog(){ var enable_xen = function(){ man_class="xen"; opt_class="xen_opt"; - $(xen_items).removeAttr("disabled"); - $('.xen .man_icon').css("display","inline-block"); + $(xen_items,dialog).removeAttr("disabled"); + $('.xen .man_icon',dialog).css("display","inline-block"); // XEN particularities: // * Add custom disk types @@ -1087,15 +1077,15 @@ function setupCreateTemplateDialog(){ \ '; - $('div#disks select#TYPE').html(type_opts); + $('select#TYPE',section_disks).html(type_opts); - $('select#boot_method option#no_boot').html("Please choose"); + $('select#boot_method option#no_boot',section_os_boot).html("Please choose"); var bus_opts = '\ '; - $('div#disks select#BUS').html(bus_opts); + $('select#BUS',section_disks).html(bus_opts); $('input#TYPE', section_raw).val("xen"); $(section_graphics).show(); @@ -1105,8 +1095,8 @@ function setupCreateTemplateDialog(){ var enable_vmware = function() { man_class="vmware"; opt_class="vmware_opt"; - $(vmware_items).removeAttr("disabled"); - $('.vmware .man_icon').css("display","inline-block"); + $(vmware_items,dialog).removeAttr("disabled"); + $('.vmware .man_icon',dialog).css("display","inline-block"); //VMWARE particularities // * Add custom disk types @@ -1119,7 +1109,7 @@ function setupCreateTemplateDialog(){ \ '; - $('div#disks select#TYPE').html(type_opts); + $('select#TYPE',section_disks).html(type_opts); $('div#kernel_bootloader',section_os_boot).hide(); @@ -1127,10 +1117,9 @@ function setupCreateTemplateDialog(){ '\ '; - $('div#disks select#BUS').html(bus_opts); - + $('select#BUS',section_disks).html(bus_opts); $('input#TYPE', section_raw).val("vmware"); - } + }; //This function checks that all mandatory items within a section //have some value. Returns true if so, false if not. @@ -1143,14 +1132,14 @@ function setupCreateTemplateDialog(){ //we fail it the item is enabled and has no value $.each(man_items,function(){ - if ($(this).parents(".vm_param").attr("disabled") || - !($(this).val().length)) { + var item = $(this); + if (item.parents(".vm_param").attr("disabled") || + !(item.val().length)) { r = false; return false; }; }); return r; - }; //Adds an option element to a multiple select box. Before doing so, @@ -1174,12 +1163,13 @@ function setupCreateTemplateDialog(){ //With each enabled field we form a JSON object var id = null; $.each(fields,function(){ - if (!($(this).parents(".vm_param").attr("disabled")) && - $(this).val().length){ + var field = $(this); + if (!(field.parents(".vm_param").attr("disabled")) && + field.val().length){ //Pick up parent's ID if we do not have one - id = $(this).attr('id').length ? $(this).attr('id') : $(this).parent().attr('id'); - value[id] = $(this).val(); - } + id = field.attr('id').length ? field.attr('id') : field.parent().attr('id'); + value[id] = field.val(); + }; }); var value_string = JSON.stringify(value); var option= @@ -1192,7 +1182,7 @@ function setupCreateTemplateDialog(){ //Removes selected elements from a multiple select box var box_remove_element = function(section_tag,box_tag){ - var context = $(section_tag); + var context = $(section_tag,dialog); $('select'+box_tag+' :selected',context).remove(); return false; }; @@ -1207,22 +1197,25 @@ function setupCreateTemplateDialog(){ var fields = $.merge(inputs,selects); fields.each(function(){ - if (!($(this).parents(".vm_param").attr("disabled"))){ //if ! disabled - if ($(this).val().length){ //if has a length - template_json[$(this).attr('id')]=$(this).val(); - } - } + var field=$(this); + if (!(field.parents(".vm_param").attr("disabled"))){ //if ! disabled + if (field.val().length){ //if has a length + template_json[field.attr('id')]=field.val(); + }; + }; }); - } + }; - // Given an array (usually empty), a section (context) and a tag for - // a multiple select in that section, it adds the contents of the - // box as objects in the array. - // TODO: Make it return a new array? - var addBoxJSON = function(array,context,box_tag){ + // Given a section (context) and a tag for + // a multiple select in that section, it adds the + // JSON values to an array parsed as objects. + // Returns the array + var addBoxJSON = function(context,box_tag){ + var array = []; $('select'+box_tag+' option',context).each(function(){ array.push( JSON.parse($(this).val()) ); }); + return array; } //Given an object, removes those elements which are empty @@ -1259,7 +1252,7 @@ function setupCreateTemplateDialog(){ //Toggles the icon when a section is folded/unfolded var iconToggle = function(){ - $('.icon_right').toggle( + $('.icon_right',dialog).toggle( function(e){ $('span',e.currentTarget).removeClass("ui-icon-plusthick"); $('span',e.currentTarget).addClass("ui-icon-minusthick"); @@ -1293,13 +1286,8 @@ function setupCreateTemplateDialog(){ return false; }); - //Chrome workaround - $('#boot_method').change(function(){ - $(this).trigger("click"); - }); - //Depending on the boot method we enable/disable some options - $('#boot_method',section_os_boot).click(function(){ + $('#boot_method',section_os_boot).change(function(){ select = $(this).val(); switch (select) { @@ -1378,14 +1366,9 @@ function setupCreateTemplateDialog(){ //hide_disabled(section_disks); }); - //Chrome workaround - $('select#TYPE',section_disks).change(function(){ - $(this).trigger('click'); - }); - //Depending on the type of disk we need to show/hide //different options and make then mandatory or not - $('select#TYPE',section_disks).click(function(){ + $('select#TYPE',section_disks).change(function(){ var select = $(this).val(); switch (select) { //size,format,target @@ -1475,8 +1458,8 @@ function setupCreateTemplateDialog(){ //hide_disabled(section_disks); }); - //Our filter for the disks section fields is the mandatory - //filter for this section + //Our filter for the disks section fields is the standard + //mandatory filter applied for this section var diskFilter = function(){ return mandatory_filter(section_disks); }; @@ -1495,7 +1478,7 @@ function setupCreateTemplateDialog(){ var networks_setup = function(){ $('.vm_param',section_networks).hide(); - $('.firewall_select').hide(); + $('.firewall_select',section_networks).hide(); $('fieldset',section_networks).hide(); $('#add_networks',section_networks).click(function(){ @@ -1531,7 +1514,7 @@ function setupCreateTemplateDialog(){ //hide_disabled(section_networks); }); - $('#black_white_tcp',section_networks).live("change",function(){ + $('#black_white_tcp',section_networks).change(function(){ switch ($(this).val()) { case "whitelist": $('#BLACK_PORTS_TCP',section_networks).parent().attr("disabled","disabled"); @@ -1553,7 +1536,7 @@ function setupCreateTemplateDialog(){ }; }); - $('#black_white_udp',section_networks).live("change",function(){ + $('#black_white_udp',section_networks).change(function(){ switch ($(this).val()) { case "whitelist": $('#BLACK_PORTS_UDP',section_networks).parent().attr("disabled","disabled"); @@ -1604,7 +1587,7 @@ function setupCreateTemplateDialog(){ $('#add_input_button',section_inputs).click(function(){ //no filter - box_add_element(section_inputs,'#inputs_box',True); + box_add_element(section_inputs,'#inputs_box',function(){return true}); return false; }); $('#remove_input_button',section_inputs).click(function(){ @@ -1654,11 +1637,10 @@ function setupCreateTemplateDialog(){ $('#PORT',section_graphics).parent().hide(); $('#PASSWD',section_graphics).parent().hide(); $('#KEYMAP',section_graphics).parent().hide(); - } }); - } + }; //Set up the context section - TODO: Apply improvements here... var context_setup = function(){ @@ -1687,8 +1669,6 @@ function setupCreateTemplateDialog(){ box_remove_element(section_context,'#context_box'); return false; }); - - }; // Set up the placement section @@ -1746,17 +1726,21 @@ filled in"); //***CREATE VM DIALOG MAIN BODY*** - $('div#dialogs').append('
'); + dialogs_context.append('
'); + $create_template_dialog = $('#create_template_dialog',dialogs_context) + var dialog = $create_template_dialog; + //Insert HTML in place - $('#create_template_dialog').html(create_template_tmpl); + dialog.html(create_template_tmpl); + //Enable tabs - $('#template_create_tabs').tabs({ + $('#template_create_tabs',dialog).tabs({ select:vmTabChange }); //Prepare jquery dialog var height = Math.floor($(window).height()*0.8); //set height to a percentage of the window - $('#create_template_dialog').dialog({ + dialog.dialog({ autoOpen: false, modal: true, width: 600, @@ -1764,26 +1748,26 @@ filled in"); }); // Enhace buttons - $('#create_template_dialog button').button(); + $('button',dialog).button(); // Re-Setup tips - setupTips($('#create_template_dialog')); + setupTips(dialog); //Enable different icon for folded/unfolded categories iconToggle(); //toogle +/- buttons //Sections, used to stay within their scope - var section_capacity = $('#capacity'); - var section_os_boot = $('#os_boot_opts'); - var section_features = $('#features'); - var section_disks = $('#disks'); - var section_networks = $('#networks'); - var section_inputs = $('#inputs'); - var section_graphics = $('#graphics'); - var section_context = $('#context'); - var section_placement = $('#placement'); - var section_raw = $('#raw'); - var section_custom_var = $('#custom_var'); + var section_capacity = $('div#capacity',dialog); + var section_os_boot = $('div#os_boot_opts',dialog); + var section_features = $('div#features',dialog); + var section_disks = $('div#disks',dialog); + var section_networks = $('div#networks',dialog); + var section_inputs = $('div#inputs',dialog); + var section_graphics = $('div#graphics',dialog); + var section_context = $('div#context',dialog); + var section_placement = $('div#placement',dialog); + var section_raw = $('div#raw',dialog); + var section_custom_var = $('div#custom_var',dialog); //Different selector for items of kvm and xen (mandatory and optional) var items = '.vm_param input,.vm_param select'; @@ -1805,14 +1789,15 @@ filled in"); vmTabChange(0,{index : 0}); //enable kvm //Fold/unfold all sections button - $('#fold_unfold_vm_params').toggle( + $('#fold_unfold_vm_params',dialog).toggle( function(){ - $('.vm_section fieldset').show(); + $('.vm_section fieldset',$create_template_dialog).show(); return false; }, function(){ - $('.vm_section fieldset').hide(); - $('.vm_section fieldset').first().show(); //Show capacity opts + $('.vm_section fieldset',$create_template_dialog).hide(); + //Show capacity opts + $('.vm_section fieldset',$create_template_dialog).first().show(); return false; }); @@ -1830,7 +1815,7 @@ filled in"); custom_variables_setup(); //Process form - $('button#create_template_form_easy').click(function(){ + $('button#create_template_form_easy',dialog).click(function(){ //validate form var vm_json = {}; @@ -1869,18 +1854,15 @@ filled in"); //process disks -> fetch from box scope = section_disks; - vm_json["DISK"] = []; - addBoxJSON(vm_json["DISK"],scope,'#disks_box'); + vm_json["DISK"] = addBoxJSON(scope,'#disks_box'); //process nics -> fetch from box scope = section_networks; - vm_json["NIC"] = []; - addBoxJSON(vm_json["NIC"],scope,'#nics_box'); + vm_json["NIC"] = addBoxJSON(scope,'#nics_box'); //process inputs -> fetch from box scope = section_inputs; - vm_json["INPUT"] = []; - addBoxJSON(vm_json["INPUT"],scope,'#inputs_box'); + vm_json["INPUT"] = addBoxJSON(scope,'#inputs_box'); //process graphics -> fetch fields with value scope = section_graphics; @@ -1928,41 +1910,42 @@ filled in"); Sunstone.runAction("Template.create",vm_json); - $('#create_template_dialog').dialog('close'); + $create_template_dialog.dialog('close'); return false; }); //Handle manual forms - $('button#create_template_form_manual').click(function(){ - var template = $('#textarea_vm_template').val(); + $('button#create_template_form_manual',$create_template_dialog).click(function(){ + var template = $('textarea#textarea_vm_template',$create_template_dialog).val(); //wrap it in the "vm" object template = {"vmtemplate": {"template_raw": template}}; Sunstone.runAction("Template.create",template); - $('#create_template_dialog').dialog('close'); + $create_template_dialog.dialog('close'); return false; }); //Reset form - empty boxes - $('button#reset_vm_form').click(function(){ + $('button#reset_vm_form',dialog).click(function(){ $('select#disks_box option',section_disks).remove(); $('select#nics_box option',section_networks).remove(); $('select#inputs_box option',section_inputs).remove(); + $('select#custom_var_box option',section_custom_var).remove(); return true; }); - } function popUpCreateTemplateDialog(){ - $('#create_template_dialog').dialog('open'); + $create_template_dialog.dialog('open'); } // Set the autorefresh interval for the datatable function setTemplateAutorefresh() { setInterval(function(){ var checked = $('input:checked',dataTable_templates.fnGetNodes()); - var filter = $("#datatable_templates_filter input").attr("value"); + var filter = $("#datatable_templates_filter input", + dataTable_templates.parents('#datatable_templates_wrapper')).attr("value"); if (!checked.length && !filter.length){ Sunstone.runAction("Template.autorefresh"); } @@ -1972,7 +1955,7 @@ function setTemplateAutorefresh() { //The DOM is ready at this point $(document).ready(function(){ - dataTable_templates = $("#datatable_templates").dataTable({ + dataTable_templates = $("#datatable_templates",main_tabs_context).dataTable({ "bJQueryUI": true, "bSortClasses": false, "bAutoWidth":false, diff --git a/src/sunstone/public/js/plugins/users-tab.js b/src/sunstone/public/js/plugins/users-tab.js index d36105e279..0c48249ef8 100644 --- a/src/sunstone/public/js/plugins/users-tab.js +++ b/src/sunstone/public/js/plugins/users-tab.js @@ -15,9 +15,9 @@ /* -------------------------------------------------------------------------- */ /*Users tab plugin*/ -var user_list_json = {}; var dataTable_users; var users_select=""; +var $create_user_dialog; var users_tab_content = '
\ @@ -92,9 +92,7 @@ var user_actions = { success: updateUsersView, error: onError }); - }, - condition: True, - notify: false + } }, "User.chgrp" : { @@ -103,7 +101,7 @@ var user_actions = { callback : function(req){ Sunstone.runAction("User.show",req.request.data[0]); }, - elements : function() {return getSelectedNodes(dataTable_users);}, + elements : userElements, error: onError, notify: true }, @@ -141,7 +139,7 @@ var user_actions = { type: "multiple", call: OpenNebula.User.delete, callback: deleteUserElement, - elements: function() { return getSelectedNodes(dataTable_users); }, + elements: userElements, error: onError, notify: true }, @@ -151,20 +149,17 @@ var user_buttons = { "User.refresh" : { type: "image", text: "Refresh list", - img: "images/Refresh-icon.png", - condition: True + img: "images/Refresh-icon.png" }, "User.create_dialog" : { type: "create_dialog", - text: "+ New", - condition: True + text: "+ New" }, "User.chgrp" : { type: "confirm_with_select", text: "Change group", - select: function(){ return groups_select; }, - tip: "This will change the main group of the selected users. Select the new group:", - condition: True + select: groups_sel, + tip: "This will change the main group of the selected users. Select the new group:" }, // "User.addgroup" : { // type: "confirm_with_select", @@ -182,21 +177,23 @@ var user_buttons = { // }, "User.delete" : { type: "action", - text: "Delete", - condition: True + text: "Delete" } } var users_tab = { title: "Users", content: users_tab_content, - buttons: user_buttons, - condition: True + buttons: user_buttons } Sunstone.addActions(user_actions); Sunstone.addMainTab('users_tab',users_tab); +function userElements(){ + return getSelectedNodes(dataTable_users); +} + // Returns an array with the values from the user_json ready to be // added to the dataTable function userElementArray(user_json){ @@ -212,7 +209,12 @@ function userElementArray(user_json){ function updateUserSelect(){ - users_select = makeSelectOptions(dataTable_users,1,2,-1,"",-1); + users_select = makeSelectOptions(dataTable_users, + 1,//id_col + 2,//name_col + [],//status_cols + []//bad status values + ); } // Callback to refresh a single element from the dataTable @@ -237,32 +239,33 @@ function addUserElement(request,user_json){ // Callback to update the list of users function updateUsersView(request,users_list){ - user_list_json = users_list; var user_list_array = []; - $.each(user_list_json,function(){ + $.each(users_list,function(){ user_list_array.push(userElementArray(this)); }); updateView(user_list_array,dataTable_users); - updateDashboard("users",user_list_json); + updateDashboard("users",users_list); updateUserSelect(); } // Prepare the user creation dialog function setupCreateUserDialog(){ - $('div#dialogs').append('
'); - $('#create_user_dialog').html(create_user_tmpl); + dialogs_context.append('
'); + $create_user_dialog = $('#create_user_dialog',dialogs_context); + var dialog = $create_user_dialog; + dialog.html(create_user_tmpl); //Prepare jquery dialog - $('#create_user_dialog').dialog({ + dialog.dialog({ autoOpen: false, modal:true, width: 400 }); - $('#create_user_dialog button').button(); + $('button',dialog).button(); - $('#create_user_form').submit(function(){ + $('#create_user_form',dialog).submit(function(){ var user_name=$('#username',this).val(); var user_password=$('#pass',this).val(); if (!user_name.length || !user_password.length){ @@ -275,20 +278,21 @@ function setupCreateUserDialog(){ "password" : user_password } }; Sunstone.runAction("User.create",user_json); - $('#create_user_dialog').dialog('close'); + $create_user_dialog.dialog('close'); return false; }); } function popUpCreateUserDialog(){ - $('#create_user_dialog').dialog('open'); + $create_user_dialog.dialog('open'); } // Prepare the autorefresh of the list function setUserAutorefresh(){ setInterval(function(){ var checked = $('input:checked',dataTable_users.fnGetNodes()); - var filter = $("#datatable_users_filter input").attr("value"); + var filter = $("#datatable_users_filter input", + dataTable_users.parents("#datatable_users_wrapper")).attr("value"); if (!checked.length && !filter.length){ Sunstone.runAction("User.autorefresh"); } @@ -297,7 +301,7 @@ function setUserAutorefresh(){ $(document).ready(function(){ //if we are not oneadmin, our tab will not even be in the DOM. - dataTable_users = $("#datatable_users").dataTable({ + dataTable_users = $("#datatable_users",main_tabs_context).dataTable({ "bJQueryUI": true, "bSortClasses": false, "sPaginationType": "full_numbers", @@ -320,6 +324,6 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_users); tableCheckboxesListener(dataTable_users); - shortenedInfoFields('#datatable_users'); + //shortenedInfoFields('#datatable_users'); }) diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index fc318bd398..ba33ae67a1 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -94,6 +94,9 @@ var create_vm_tmpl ='\ var vmachine_list_json = {}; var dataTable_vMachines; +var $create_vm_dialog; +var $saveas_vm_dialog; +var $vnc_dialog; var rfb; var vm_actions = { @@ -151,10 +154,8 @@ var vm_actions = { "VM.deploy" : { type: "multiple", call: OpenNebula.VM.deploy, - callback: function (req) { - Sunstone.runAction("VM.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_vMachines); }, + callback: vmShow, + elements: vmElements, error: onError, notify: true }, @@ -162,9 +163,7 @@ var vm_actions = { "VM.migrate" : { type: "multiple", call: OpenNebula.VM.migrate, - callback: function (req) { - Sunstone.runAction("VM.show",req.request.data[0]); - }, + callback: vmShow, elements: function() { return getSelectedNodes(dataTable_vMachines); }, error: onError, notify: true @@ -173,10 +172,8 @@ var vm_actions = { "VM.livemigrate" : { type: "multiple", call: OpenNebula.VM.livemigrate, - callback: function (req) { - Sunstone.runAction("VM.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_vMachines); }, + callback: vmShow, + elements: vmElements, error: onError, notify: true }, @@ -184,10 +181,8 @@ var vm_actions = { "VM.hold" : { type: "multiple", call: OpenNebula.VM.hold, - callback: function (req) { - Sunstone.runAction("VM.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_vMachines); }, + callback: vmShow, + elements: vmElements, error: onError, notify: true }, @@ -195,10 +190,8 @@ var vm_actions = { "VM.release" : { type: "multiple", call: OpenNebula.VM.release, - callback: function (req) { - Sunstone.runAction("VM.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_vMachines); }, + callback: vmShow, + elements: vmElements, error: onError, notify: true }, @@ -206,10 +199,8 @@ var vm_actions = { "VM.suspend" : { type: "multiple", call: OpenNebula.VM.suspend, - callback: function (req) { - Sunstone.runAction("VM.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_vMachines); }, + callback: vmShow, + elements: vmElements, error: onError, notify: true }, @@ -217,10 +208,8 @@ var vm_actions = { "VM.resume" : { type: "multiple", call: OpenNebula.VM.resume, - callback: function (req) { - Sunstone.runAction("VM.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_vMachines); }, + callback: vmShow, + elements: vmElements, error: onError, notify: true }, @@ -228,10 +217,8 @@ var vm_actions = { "VM.stop" : { type: "multiple", call: OpenNebula.VM.stop, - callback: function (req) { - Sunstone.runAction("VM.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_vMachines); }, + callback: vmShow, + elements: vmElements, error: onError, notify: true }, @@ -239,10 +226,8 @@ var vm_actions = { "VM.restart" : { type: "multiple", call: OpenNebula.VM.restart, - callback: function (req) { - Sunstone.runAction("VM.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_vMachines); }, + callback: vmShow, + elements: vmElements, error: onError, notify: true }, @@ -250,10 +235,8 @@ var vm_actions = { "VM.resubmit" : { type: "multiple", call: OpenNebula.VM.resubmit, - callback: function (req) { - Sunstone.runAction("VM.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_vMachines); }, + callback: vmShow, + elements: vmElements, error: onError, notify: true }, @@ -261,10 +244,9 @@ var vm_actions = { "VM.saveasmultiple" : { type: "custom", call: function(){ - var elems = vm_actions["VM.saveasmultiple"].elements(); + var elems = vmElements(); popUpSaveasDialog(elems); - }, - elements: function() { return getSelectedNodes(dataTable_vMachines); } + } }, "VM.saveas" : { @@ -272,10 +254,7 @@ var vm_actions = { call: function(obj) { OpenNebula.VM.saveas( {data:obj, - success: function (req) { - Sunstone.runAction("VM.show", - req.request.data[0][0]); - }, + success: vmShow, error: onError }); } }, @@ -284,17 +263,14 @@ var vm_actions = { type: "single", call: OpenNebula.VM.show, callback: saveasDisksCallback, - error: onError, - notify: false + error: onError }, "VM.shutdown" : { type: "multiple", call: OpenNebula.VM.shutdown, - callback: function (req) { - Sunstone.runAction("VM.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_vMachines); }, + callback: vmShow, + elements: vmElements, error: onError, notify: true }, @@ -302,10 +278,8 @@ var vm_actions = { "VM.cancel" : { type: "multiple", call: OpenNebula.VM.cancel, - callback: function (req) { - Sunstone.runAction("VM.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_vMachines); }, + callback: vmShow, + elements: vmElements, error: onError, notify: true }, @@ -314,7 +288,7 @@ var vm_actions = { type: "multiple", call: OpenNebula.VM.delete, callback: deleteVMachineElement, - elements: function() { return getSelectedNodes(dataTable_vMachines); }, + elements: vmElements, error: onError, notify: true }, @@ -354,7 +328,6 @@ var vm_actions = { "VM.stopvnc" : { type: "single", call: OpenNebula.VM.stopvnc, - callback: null, error: onError, notify: true }, @@ -381,20 +354,16 @@ var vm_actions = { "VM.chown" : { type: "multiple", call: OpenNebula.VM.chown, - callback: function (req) { - Sunstone.runAction("VM.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_vMachines); }, + callback: vmShow, + elements: vmElements, error: onError, notify: true }, "VM.chgrp" : { type: "multiple", call: OpenNebula.VM.chgrp, - callback: function (req) { - Sunstone.runAction("VM.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_vMachines); }, + callback: vmShow, + elements: vmElements, error: onError, notify: true } @@ -406,39 +375,35 @@ var vm_buttons = { "VM.refresh" : { type: "image", text: "Refresh list", - img: "images/Refresh-icon.png", - condition: True + img: "images/Refresh-icon.png" }, "VM.create_dialog" : { type: "action", text: "+ New", - condition: True, - alwaysActive: true, - + alwaysActive: true }, "VM.chown" : { type: "confirm_with_select", text: "Change owner", - select: function() {return users_select;}, + select: users_sel, tip: "Select the new owner:", - condition: function() { return gid == 0; } + condition: mustBeAdmin }, "VM.chgrp" : { type: "confirm_with_select", text: "Change group", - select: function() {return groups_select;}, + select: groups_sel, tip: "Select the new group:", - condition: function() { return gid == 0; } + condition: mustBeAdmin }, "VM.shutdown" : { type: "confirm", text: "Shutdown", - tip: "This will initiate the shutdown process in the selected VMs", - condition: True + tip: "This will initiate the shutdown process in the selected VMs" }, "action_list" : { @@ -448,95 +413,75 @@ var vm_buttons = { type: "confirm_with_select", text: "Deploy", tip: "This will deploy the selected VMs on the chosen host", - select: function(){ - if (hosts_select){return hosts_select} - else {return ""} - }, - condition: function() { return gid == 0; } + select: hosts_sel, + condition: mustBeAdmin }, "VM.migrate" : { type: "confirm_with_select", text: "Migrate", tip: "This will migrate the selected VMs to the chosen host", - select: function(){ - if (hosts_select){return hosts_select} - else {return ""} - }, - condition: function() { return gid == 0; } + select: hosts_sel, + condition: mustBeAdmin }, "VM.livemigrate" : { type: "confirm_with_select", text: "Live migrate", tip: "This will live-migrate the selected VMs to the chosen host", - select: function(){ - if (hosts_select){return hosts_select} - else {return ""} - }, - condition: function() { return gid == 0; } + select: hosts_sel, + condition: mustBeAdmin }, "VM.hold" : { type: "confirm", text: "Hold", - tip: "This will hold selected pending VMs from being deployed", - condition: True + tip: "This will hold selected pending VMs from being deployed" }, "VM.release" : { type: "confirm", text: "Release", - tip: "This will release held machines", - condition: True + tip: "This will release held machines" }, "VM.suspend" : { type: "confirm", text: "Suspend", - tip: "This will suspend selected machines", - condition: True + tip: "This will suspend selected machines" }, "VM.resume" : { type: "confirm", text: "Resume", - tip: "This will resume selected stopped or suspended VMs", - condition: True + tip: "This will resume selected stopped or suspended VMs" }, "VM.stop" : { type: "confirm", text: "Stop", - tip: "This will stop selected VMs", - condition: True + tip: "This will stop selected VMs" }, "VM.restart" : { type: "confirm", text: "Restart", - tip: "This will redeploy selected VMs (in UNKNOWN or BOOT state)", - condition: True + tip: "This will redeploy selected VMs (in UNKNOWN or BOOT state)" }, "VM.resubmit" : { type: "confirm", text: "Resubmit", - tip: "This will resubmits VMs to PENDING state", - condition: True + tip: "This will resubmits VMs to PENDING state" }, "VM.saveasmultiple" : { type: "action", - text: "Save as", - condition: True + text: "Save as" }, "VM.cancel" : { type: "confirm", text: "Cancel", - tip: "This will cancel selected VMs", - condition: True + tip: "This will cancel selected VMs" } - }, - condition: True + } }, "VM.delete" : { type: "confirm", text: "Delete", - tip: "This will delete the selected VMs from the database", - condition: True + tip: "This will delete the selected VMs from the database" } } @@ -558,8 +503,7 @@ var vm_info_panel = { var vms_tab = { title: "Virtual Machines", content: vms_tab_content, - buttons: vm_buttons, - condition: True + buttons: vm_buttons } Sunstone.addActions(vm_actions); @@ -567,6 +511,14 @@ Sunstone.addMainTab('vms_tab',vms_tab); Sunstone.addInfoPanel('vm_info_panel',vm_info_panel); +function vmElements() { + return getSelectedNodes(dataTable_vMachines); +} + +function vmShow(req) { + Sunstone.runAction("VM.show",req.request.data[0]); +} + // Returns a human readable running time for a VM function str_start_time(vm){ return pretty_time(vm.STIME); @@ -610,7 +562,7 @@ function vMachineElementArray(vm_json){ //Creates a listener for the TDs of the VM table function vMachineInfoListener(){ - $('#tbodyvmachines tr').live("click", function(e){ + $('#tbodyvmachines tr',dataTable_vMachines).live("click", function(e){ if ($(e.target).is('input') || $(e.target).is('a img')) {return true;} popDialogLoading(); var aData = dataTable_vMachines.fnGetData(this); @@ -628,8 +580,8 @@ function updateVMachineElement(request, vm_json){ } // Callback to delete a single element from the list -function deleteVMachineElement(req){ - deleteElement(dataTable_vMachines,'#vm_'+req.request.data); +function deleteVMachineElement(request){ + deleteElement(dataTable_vMachines,'#vm_'+request.request.data); } // Callback to add an element to the list @@ -642,7 +594,6 @@ function addVMachineElement(request,vm_json){ // Callback to refresh the list of Virtual Machines function updateVMachinesView(request, vmachine_list){ - vmachine_list_json = vmachine_list; var vmachine_list_array = []; $.each(vmachine_list,function(){ @@ -650,7 +601,7 @@ function updateVMachinesView(request, vmachine_list){ }); updateView(vmachine_list_array,dataTable_vMachines); - updateDashboard("vms",vmachine_list_json); + updateDashboard("vms",vmachine_list); } @@ -777,29 +728,40 @@ function updateVMInfo(request,vm){ // which is a lot. function setupCreateVMDialog(){ - $('div#dialogs').append('
'); + dialogs_context.append('
'); //Insert HTML in place - $('#create_vm_dialog').html(create_vm_tmpl); + $create_vm_dialog = $('#create_vm_dialog') + var dialog = $create_vm_dialog; + dialog.html(create_vm_tmpl); //Prepare jquery dialog - $('#create_vm_dialog').dialog({ + dialog.dialog({ autoOpen: false, modal: true, width: 400 }); - $('#create_vm_dialog button').button(); + $('button',dialog).button(); - $('#create_vm_dialog #create_vm_proceed').click(function(){ - var vm_name = $('#create_vm_form #vm_name').val(); - var template_id = $('#create_vm_form #template_id').val(); - var n_times = $('#create_vm_form #vm_n_times').val(); + $('#create_vm_form',dialog).submit(function(){ + var vm_name = $('#vm_name',this).val(); + var template_id = $('#template_id',this).val(); + var n_times = $('#vm_n_times',this).val(); var n_times_int=1; + + if (!template_id.length){ + notifyError("You have not selected a template"); + return false; + } + if (n_times.length){ n_times_int=parseInt(n_times,10); } if (n_times_int>1){ + if (!vm_name.length){ + vm_name = $('#template_id option:selected',this).text(); + } for (var i=0; i< n_times_int; i++){ Sunstone.runAction("Template.instantiate",template_id,vm_name+"_"+i); }; @@ -808,28 +770,26 @@ function setupCreateVMDialog(){ }; Sunstone.runAction("VM.list"); - $('#create_vm_dialog').dialog('close'); + $create_vm_dialog.dialog('close'); return false; }); - - $('#create_vm_dialog #create_vm_cancel').click(function(){ - - }); } // Open creation dialog function popUpCreateVMDialog(){ - $('#create_vm_dialog').dialog('open'); + $create_vm_dialog.dialog('open'); } //Prepares a dialog to saveas a VM function setupSaveasDialog(){ //Append to DOM - $('div#dialogs').append('
'); + dialogs_context.append('
'); + $saveas_vm_dialog = $('#saveas_vm_dialog',dialogs_context); + var dialog = $saveas_vm_dialog; //Put HTML in place - $('#saveas_vm_dialog').html('\ - \ + dialog.html('\ + \
\
\
\ @@ -839,7 +799,7 @@ function setupSaveasDialog(){
\ '); - $('#saveas_vm_dialog').dialog({ + dialog.dialog({ autoOpen:false, width:600, modal:true, @@ -847,8 +807,8 @@ function setupSaveasDialog(){ resizable:true, }); - $('#saveas_vm_dialog #vm_saveas_proceed').click(function(){ - var elems = $('#saveas_vm_dialog #saveas_tabs div.saveas_tab'); + $('#saveas_vm_form',dialog).submit(function(){ + var elems = $('#saveas_tabs div.saveas_tab',this); var args = []; $.each(elems,function(){ var id = $('#vm_id',this).text(); @@ -875,25 +835,26 @@ function setupSaveasDialog(){ notifySubmit("VM.saveas",args); } - $('#saveas_vm_dialog').dialog('close'); + $saveas_vm_dialog.dialog('close'); return false; }); - $('#saveas_vm_dialog #vm_saveas_cancel').click(function(){ - $('#saveas_vm_dialog').dialog('close'); + $('#vm_saveas_cancel',dialog).click(function(){ + $saveas_vm_dialog.dialog('close'); return false; }); } function popUpSaveasDialog(elems){ - $('#saveas_vm_dialog #saveas_tabs').tabs('destroy'); - $('#saveas_vm_dialog #saveas_tabs').empty(); - $('#saveas_vm_dialog #saveas_tabs').html(''); + var dialog = $saveas_vm_dialog; + $('#saveas_tabs',dialog).tabs('destroy'); + $('#saveas_tabs',dialog).empty(); + $('#saveas_tabs',dialog).html(''); $.each(elems,function(){ var li = '
  • VM '+this+'
  • ' - $('#saveas_vm_dialog #saveas_tabs ul').append(li); + $('#saveas_tabs ul',dialog).append(li); var tab = '
    \
    Saveas for VM with ID '+this+'
    \
    \ @@ -923,12 +884,12 @@ function popUpSaveasDialog(elems){ -->\
    \
    '; - $('#saveas_vm_dialog #saveas_tabs').append(tab); + $('#saveas_tabs',dialog).append(tab); Sunstone.runAction("VM.saveas_disks",this); }); - $('#saveas_vm_dialog #saveas_tabs').tabs(); - $('#saveas_vm_dialog button').button(); - $('#saveas_vm_dialog').dialog('open'); + $('#saveas_tabs',dialog).tabs(); + $('button',dialog).button(); + dialog.dialog('open'); } function saveasDisksCallback(req,response){ @@ -956,7 +917,7 @@ function saveasDisksCallback(req,response){ select+= gen_option(disks.DISK_ID,disks.IMAGE,disks.SOURCE); } //introduce options in the right tab - $('#saveas_tabs #saveas_tab_'+id+' #vm_disk_id').html(select); + $('#saveas_tabs #saveas_tab_'+id+' #vm_disk_id',$saveas_vm_dialog).html(select); } @@ -964,10 +925,11 @@ function saveasDisksCallback(req,response){ function setVMAutorefresh(){ setInterval(function(){ var checked = $('input:checked',dataTable_vMachines.fnGetNodes()); - var filter = $("#datatable_vmachines_filter input").attr("value"); + var filter = $("#datatable_vmachines_filter input", + dataTable_vMachines.parents('#datatable_vmachines_wrapper')).attr("value"); if (!checked.length && !filter.length){ Sunstone.runAction("VM.autorefresh"); - } + }; },INTERVAL+someTime()); } @@ -1009,9 +971,11 @@ function updateVNCState(rfb, state, oldstate, msg) { function setupVNC(){ //Append to DOM - $('div#dialogs').append('
    '); + dialogs_context.append('
    '); + $vnc_dialog = $('#vnc_dialog',dialogs_context); + var dialog = $vnc_dialog; - $('#vnc_dialog').html('\ + dialog.html('\
    \ \ \ @@ -1026,12 +990,7 @@ function setupVNC(){ \ '); - $('#sendCtrlAltDelButton').click(function(){ - rfb.sendCtrlAltDel(); - return false; - }); - - $('#vnc_dialog').dialog({ + dialog.dialog({ autoOpen:false, width:700, modal:true, @@ -1039,22 +998,26 @@ function setupVNC(){ resizable:true, }); - $( "#vnc_dialog" ).bind( "dialogclose", function(event, ui) { - var id = $("#vnc_dialog").attr("vm_id"); + $('#sendCtrlAltDelButton',dialog).click(function(){ + rfb.sendCtrlAltDel(); + return false; + }); + + dialog.bind( "dialogclose", function(event, ui) { + var id = $vnc_dialog.attr("vm_id"); rfb.disconnect(); Sunstone.runAction("VM.stopvnc",id); }); - $('.vnc').live("click",function(){ + $('.vnc',main_tabs_context).live("click",function(){ //Which VM is it? var id = $(this).attr("vm_id"); //Set attribute to dialog - $('#vnc_dialog').attr("vm_id",id); + $vnc_dialog.attr("vm_id",id); //Request proxy server start Sunstone.runAction("VM.startvnc",id); return false; }); - } function vncCallback(request,response){ @@ -1074,7 +1037,7 @@ function vncCallback(request,response){ setTimeout(function(){ rfb.connect(vnc_host, vnc_port, vnc_pw); - $('#vnc_dialog').dialog('open'); + $vnc_dialog.dialog('open'); },4000); } @@ -1091,7 +1054,6 @@ function vncIcon(vm){ gr_icon = 'VNC Disabled'; } return gr_icon; - } function vmMonitorError(req,error_json){ @@ -1106,7 +1068,7 @@ function vmMonitorError(req,error_json){ // At this point the DOM is ready and the sunstone.js ready() has been run. $(document).ready(function(){ - dataTable_vMachines = $("#datatable_vmachines").dataTable({ + dataTable_vMachines = $("#datatable_vmachines",main_tabs_context).dataTable({ "bJQueryUI": true, "bSortClasses": false, "sPaginationType": "full_numbers", diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index 09c88afc80..7d6f6de516 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -122,8 +122,8 @@ var create_vn_tmpl = '; var vnetworks_select=""; -var network_list_json = {}; var dataTable_vNetworks; +var $create_vn_dialog; //Setup actions @@ -181,10 +181,8 @@ var vnet_actions = { "Network.publish" : { type: "multiple", call: OpenNebula.Network.publish, - callback: function (req) { - Sunstone.runAction("Network.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_vNetworks); }, + callback: vnShow, + elements: vnElements, error: onError, notify: true }, @@ -192,10 +190,8 @@ var vnet_actions = { "Network.unpublish" : { type: "multiple", call: OpenNebula.Network.unpublish, - callback: function (req) { - Sunstone.runAction("Network.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_vNetworks); }, + callback: vnShow, + elements: vnElements, error: onError, notify: true }, @@ -204,7 +200,7 @@ var vnet_actions = { type: "multiple", call: OpenNebula.Network.delete, callback: deleteVNetworkElement, - elements: function() { return getSelectedNodes(dataTable_vNetworks); }, + elements: vnElements, error: onError, notify: true }, @@ -212,10 +208,8 @@ var vnet_actions = { "Network.chown" : { type: "multiple", call: OpenNebula.Network.chown, - callback: function (req) { - Sunstone.runAction("Network.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_vNetworks); }, + callback: vnShow, + elements: vnElements, error:onError, notify: true }, @@ -223,10 +217,8 @@ var vnet_actions = { "Network.chgrp" : { type: "multiple", call: OpenNebula.Network.chgrp, - callback: function (req) { - Sunstone.runAction("Network.show",req.request.data[0]); - }, - elements: function() { return getSelectedNodes(dataTable_vNetworks); }, + callback: vnShow, + elements: vnElements, error:onError, notify: true } @@ -237,48 +229,43 @@ var vnet_buttons = { "Network.refresh" : { type: "image", text: "Refresh list", - img: "images/Refresh-icon.png", - condition: True + img: "images/Refresh-icon.png" }, "Network.create_dialog" : { type: "create_dialog", - text: "+ New", - condition: True + text: "+ New" }, "Network.publish" : { type: "action", - text: "Publish", - condition: True + text: "Publish" }, "Network.unpublish" : { type: "action", - text: "Unpublish", - condition: True + text: "Unpublish" }, "Network.chown" : { type: "confirm_with_select", text: "Change owner", - select: function() {return users_select;}, + select: users_sel, tip: "Select the new owner:", - condition: function() { return gid == 0; } + condition: mustBeAdmin }, "Network.chgrp" : { type: "confirm_with_select", text: "Change group", - select: function() {return groups_select;}, + select: groups_sel, tip: "Select the new group:", - condition: function() { return gid == 0; } + condition: mustBeAdmin, }, "Network.delete" : { type: "action", - text: "Delete", - condition: True + text: "Delete" } } @@ -296,14 +283,22 @@ var vnet_info_panel = { var vnets_tab = { title: "Virtual Networks", content: vnets_tab_content, - buttons: vnet_buttons, - condition: True + buttons: vnet_buttons } Sunstone.addActions(vnet_actions); Sunstone.addMainTab('vnets_tab',vnets_tab); Sunstone.addInfoPanel('vnet_info_panel',vnet_info_panel); + +function vnElements(){ + return getSelectedNodes(dataTable_vNetworks); +} + +function vnShow(req){ + Sunstone.runAction("Network.show",req.request.data[0]); +} + //returns an array with the VNET information fetched from the JSON object function vNetworkElementArray(vn_json){ var network = vn_json.VNET; @@ -331,7 +326,7 @@ function vNetworkElementArray(vn_json){ //Adds a listener to show the extended info when clicking on a row function vNetworkInfoListener(){ - $('#tbodyvnetworks tr').live("click", function(e){ + $('#tbodyvnetworks tr',dataTable_vNetworks).live("click", function(e){ if ($(e.target).is('input')) {return true;} popDialogLoading(); var aData = dataTable_vNetworks.fnGetData(this); @@ -344,11 +339,16 @@ function vNetworkInfoListener(){ //updates the vnet select different options function updateNetworkSelect(){ vnetworks_select= - makeSelectOptions(dataTable_vNetworks,1,4,7,"no",2); + makeSelectOptions(dataTable_vNetworks, + 1, + 4, + [], + [] + ); //update static selectors: //in the VM creation dialog - $('div.vm_section#networks select#NETWORK_ID').html(vnetworks_select); + $('div.vm_section#networks select#NETWORK_ID',$create_template_dialog).html(vnetworks_select); } //Callback to update a vnet element after an action on it @@ -374,7 +374,6 @@ function addVNetworkElement(request,vn_json){ //updates the list of virtual networks function updateVNetworksView(request, network_list){ - network_list_json = network_list; var network_list_array = []; $.each(network_list,function(){ @@ -384,7 +383,7 @@ function updateVNetworksView(request, network_list){ updateView(network_list_array,dataTable_vNetworks); updateNetworkSelect(); //dependency with dashboard - updateDashboard("vnets",network_list_json); + updateDashboard("vnets",network_list); } @@ -449,11 +448,13 @@ function updateVNetworkInfo(request,vn){ //Prepares the vnet creation dialog function setupCreateVNetDialog() { - $('div#dialogs').append('
    '); - $('#create_vn_dialog').html(create_vn_tmpl); + dialogs_context.append('
    '); + $create_vn_dialog = $('#create_vn_dialog',dialogs_context) + var dialog = $create_vn_dialog; + dialog.html(create_vn_tmpl); //Prepare the jquery-ui dialog. Set style options here. - $('#create_vn_dialog').dialog({ + dialog.dialog({ autoOpen: false, modal: true, width: 475, @@ -461,22 +462,22 @@ function setupCreateVNetDialog() { }); //Make the tabs look nice for the creation mode - $('#vn_tabs').tabs(); - $('div#ranged').hide(); - $('#fixed_check').click(function(){ - $('div#fixed').show(); - $('div#ranged').hide(); + $('#vn_tabs',dialog).tabs(); + $('div#ranged',dialog).hide(); + $('#fixed_check',dialog).click(function(){ + $('div#fixed',$create_vn_dialog).show(); + $('div#ranged',$create_vn_dialog).hide(); }); - $('#ranged_check').click(function(){ - $('div#fixed').hide(); - $('div#ranged').show(); + $('#ranged_check',dialog).click(function(){ + $('div#fixed',$create_vn_dialog).hide(); + $('div#ranged',$create_vn_dialog).show(); }); - $('#create_vn_dialog button').button(); + $('button',dialog).button(); //When we hit the add lease button... - $('#add_lease').click(function(){ - var create_form = $('#create_vn_form_easy'); //this is our scope + $('#add_lease',dialog).click(function(){ + var create_form = $('#create_vn_form_easy',$create_vn_dialog); //this is our scope //Fetch the interesting values var lease_ip = $('#leaseip',create_form).val(); @@ -500,17 +501,17 @@ function setupCreateVNetDialog() { }; //We append the HTML into the select box. - $('select#leases').append(lease); + $('select#leases',$create_vn_dialog).append(lease); return false; }); - $('#remove_lease').click(function(){ - $('select#leases :selected').remove(); + $('#remove_lease', dialog).click(function(){ + $('select#leases :selected',$create_vn_dialog).remove(); return false; }); //Handle submission of the easy mode - $('#create_vn_form_easy').submit(function(){ + $('#create_vn_form_easy',dialog).submit(function(){ //Fetch values var name = $('#name',this).val(); if (!name.length){ @@ -563,27 +564,28 @@ function setupCreateVNetDialog() { //Create the VNetwork. Sunstone.runAction("Network.create",network_json); - $('#create_vn_dialog').dialog('close'); + $create_vn_dialog.dialog('close'); return false; }); - $('#create_vn_form_manual').submit(function(){ + $('#create_vn_form_manual',dialog).submit(function(){ var template=$('#template',this).val(); var vnet_json = {vnet: {vnet_raw: template}}; Sunstone.runAction("Network.create",vnet_json); - $('#create_vn_dialog').dialog('close'); + $create_vn_dialog.dialog('close'); return false; }); } function popUpCreateVnetDialog() { - $('#create_vn_dialog').dialog('open'); + $create_vn_dialog.dialog('open'); } function setVNetAutorefresh() { setInterval(function(){ var checked = $('input:checked',dataTable_vNetworks.fnGetNodes()); - var filter = $("#datatable_vnetworks_filter input").attr("value"); + var filter = $("#datatable_vnetworks_filter input", + dataTable_vNetworks.parents("#datatable_vnetworks_wrapper")).attr("value"); if (!checked.length && !filter.length){ Sunstone.runAction("Network.autorefresh"); } @@ -594,7 +596,7 @@ function setVNetAutorefresh() { //has been executed at this point. $(document).ready(function(){ - dataTable_vNetworks = $("#datatable_vnetworks").dataTable({ + dataTable_vNetworks = $("#datatable_vnetworks",main_tabs_context).dataTable({ "bJQueryUI": true, "bSortClasses": false, "bAutoWidth":false, diff --git a/src/sunstone/public/js/sunstone-util.js b/src/sunstone/public/js/sunstone-util.js index e2c570c792..94bbdccd67 100644 --- a/src/sunstone/public/js/sunstone-util.js +++ b/src/sunstone/public/js/sunstone-util.js @@ -82,98 +82,94 @@ function humanize_size(value) { } //Wrapper to add an element to a dataTable -function addElement(element,data_table){ - data_table.fnAddData(element); +function addElement(element,dataTable){ + dataTable.fnAddData(element); } //deletes an element with id 'tag' from a dataTable -function deleteElement(data_table,tag){ - var tr = $(tag).parents('tr')[0]; - data_table.fnDeleteRow(tr); - $('input',data_table).trigger("change"); +function deleteElement(dataTable,tag){ + var tr = $(tag,dataTable).parents('tr')[0]; + dataTable.fnDeleteRow(tr); + recountCheckboxes(dataTable); } -//Listens to the checkboxes of the datatable. This function is used -//by standard sunstone plugins to enable/disable certain action buttons -//according to the number of elements checked in the dataTables. -//It also checks the "check-all" box when all elements are checked -function tableCheckboxesListener(dataTable){ - - //Initialization - disable all buttons - var context = dataTable.parents('form'); +//Handle the activation of action buttons and the check_all box +//when elements in a datatable are modified. +function recountCheckboxes(dataTable){ + var table = $('tbody',dataTable); + var context = table.parents('form'); + var nodes = $('tr',table); //visible nodes + var total_length = nodes.length; + var checked_length = $('input:checked',nodes).length; var last_action_b = $('.last_action_button',context); - $('.top_button, .list_button',context).button("disable"); - if (last_action_b.length && last_action_b.val().length){ + + if (checked_length) { //at least 1 element checked + //enable action buttons + $('.top_button, .list_button',context).button("enable"); + //check if the last_action_button should be enabled + if (last_action_b.length && last_action_b.val().length){ + last_action_b.button("enable"); + }; + //enable checkall box + if (total_length == checked_length){ + $('.check_all',dataTable).attr("checked","checked"); + }; + } else { //no elements cheked + //disable action buttons, uncheck checkAll + $('.check_all',dataTable).removeAttr("checked"); + $('.top_button, .list_button',context).button("disable"); last_action_b.button("disable"); }; + + //any case the create dialog buttons should always be enabled. + $('.create_dialog_button',context).button("enable"); + $('.alwaysActive',context).button("enable"); +} + +//Init action buttons and checkboxes listeners +function tableCheckboxesListener(dataTable){ + //Initialization - disable all buttons + var context = dataTable.parents('form'); + + $('.last_action_button',context).button("disable"); + $('.top_button, .list_button',context).button("disable"); + //These are always enabled $('.create_dialog_button',context).button("enable"); $('.alwaysActive',context).button("enable"); //listen to changes in the visible inputs $('tbody input',dataTable).live("change",function(){ - var table = $(this).parents('tbody'); - var context = table.parents('form'); - var nodes = $('tr',table); - var total_length = nodes.length; - var checked_length = $('input:checked',nodes).length; - - var last_action_b = $('.last_action_button',context); - - - //if all elements are checked we check the check-all box - if (total_length == checked_length && total_length != 0){ - $('.check_all',dataTable).attr("checked","checked"); - } else { - $('.check_all',dataTable).removeAttr("checked"); - } - - //if some element is checked, we enable buttons, otherwise - //we disable them. - if (checked_length){ - $('.top_button, .list_button',context).button("enable"); - //check if the last_action_button should be enabled - if (last_action_b.length && last_action_b.val().length){ - last_action_b.button("enable"); - }; - } else { - $('.top_button, .list_button',context).button("disable"); - last_action_b.button("disable"); - } - - //any case the create dialog buttons should always be enabled. - $('.create_dialog_button',context).button("enable"); - $('.alwaysActive',context).button("enable"); + var datatable = $(this).parents('table'); + recountCheckboxes(dataTable); }); - } // Updates a data_table, with a 2D array containing the new values // Does a partial redraw, so the filter and pagination are kept -function updateView(item_list,data_table){ - if (data_table!=null) { - data_table.fnClearTable(); - data_table.fnAddData(item_list); - data_table.fnDraw(false); +function updateView(item_list,dataTable){ + if (dataTable) { + dataTable.fnClearTable(); + dataTable.fnAddData(item_list); + dataTable.fnDraw(false); }; } //replaces an element with id 'tag' in a dataTable with a new one -function updateSingleElement(element,data_table,tag){ - var nodes = data_table.fnGetNodes(); +function updateSingleElement(element,dataTable,tag){ + var nodes = dataTable.fnGetNodes(); var tr = $(tag,nodes).parents('tr')[0]; - var position = data_table.fnGetPosition(tr); - data_table.fnUpdate(element,position,0,false); - $('input',data_table).trigger("change"); - + var position = dataTable.fnGetPosition(tr); + dataTable.fnUpdate(element,position,0,false); + recountCheckboxes(dataTable); } // Returns an string in the form key=value key=value ... // Does not explore objects in depth. function stringJSON(json){ - var str = "" + var str = ""; for (field in json) { str+= field + '=' + json[field] + ' '; - } + }; return str; } @@ -187,9 +183,10 @@ function notifySubmit(action, args, extra_param){ msg += action_text; } else { msg += action_text + ": " + args; - } - if (extra_param != null) + }; + if (extra_param) { msg += " >> " + extra_param; + }; $.jGrowl(msg, {theme: "jGrowl-notify-submit"}); } @@ -197,19 +194,19 @@ function notifySubmit(action, args, extra_param){ //Notification on error function notifyError(msg){ msg = "

    Error

    " + msg; - $.jGrowl(msg, {theme: "jGrowl-notify-error", sticky: true }); } +//Standard notification function notifyMessage(msg){ msg = "

    Info

    " + msg; - $.jGrowl(msg, {theme: "jGrowl-notify-submit"}); } -// Returns an HTML string with the json keys and values in the form -// key: value
    -// It recursively explores objects +// Returns an HTML string with the json keys and values +// Attempts to css format output, giving different values to +// margins etc. according to depth level etc. +// See exapmle of use in plugins. function prettyPrintJSON(template_json,padding,weight, border_bottom,padding_top_bottom){ var str = "" if (!template_json){ return "Not defined";} @@ -287,26 +284,18 @@ function prettyPrintRowJSON(field,value,padding,weight, border_bottom,padding_to //Add a listener to the check-all box of a datatable, enabling it to //check and uncheck all the checkboxes of its elements. function initCheckAllBoxes(datatable){ - //not showing nice in that position - //$('.check_all').button({ icons: {primary : "ui-icon-check" }, - // text : true}); //small css hack $('.check_all',datatable).css({"border":"2px"}); - $('.check_all',datatable).click(function(){ - if ($(this).attr("checked")) { - $('tbody input:checkbox', - $(this).parents("table")).each(function(){ - $(this).attr("checked","checked"); - }); - - } else { - $('tbody input:checkbox', - $(this).parents("table")).each(function(){ - $(this).removeAttr("checked"); - }); - } - $('tbody input:checkbox',$(this).parents("table")).trigger("change"); + $('.check_all',datatable).change(function(){ + var table = $(this).parents('table'); + var checked = $(this).attr("checked"); + if (checked) { //check all + $('tbody input:checkbox',table).attr("checked","checked"); + } else { //uncheck all + $('tbody input:checkbox',table).removeAttr("checked"); + }; + recountCheckboxes(table); }); } @@ -323,7 +312,7 @@ function onError(request,error_json) { if ( typeof onError.disabled == 'undefined' ) { onError.disabled=false; - } + }; //redirect to login if unauthenticated if (error_json.error.http_status=="401") { @@ -332,15 +321,25 @@ function onError(request,error_json) { return false; }; + if (!message){ if (!onError.disabled){ notifyError("Cannot contact server: is it running and reachable?"); onError.disabled=true; } return false; + }; + + if (message.match(/^Network is unreachable .+$/)){ + if (!onError.disabled){ + notifyError("Network is unreachable: is OpenNebula running?"); + onError.disabled=true; + }; + return false; } else { onError.disabled=false; - } + }; + //Parse known errors: var get_error = /^\[(\w+)\] Error getting ([\w ]+) \[(\d+)\]\.$/; @@ -355,7 +354,7 @@ function onError(request,error_json) { method = m[1]; object = m[3]; reason = "Unauthorized"; - } + }; if (m) { var rows; @@ -370,7 +369,7 @@ function onError(request,error_json) { message += ""; } message = "
    Loading
    "+key+""+value+"
    " + message + "
    "; - } + }; notifyError(message); return true; @@ -382,8 +381,8 @@ function waitingNodes(dataTable){ var nodes = dataTable.fnGetData(); for (var i=0;i'); - $(this).append(''); + obj.html(''); + obj.append(''); - $(this).append(''); + obj.append(''); //add the text to .tipspan - $('span.tipspan',this).html(tip); + $('span.tipspan',obj).html(tip); //make sure it is not floating in the wrong place - $(this).parent().append('
    '); + obj.parent().append('
    '); //hide the text - $('span.tipspan',this).hide(); + $('span.tipspan',obj).hide(); //When the mouse is hovering on the icon we fadein/out //the tip text - $('span.info_icon',this).hover(function(e){ + $('span.info_icon',obj).hover(function(e){ + var icon = $(this); var top, left; top = e.pageY - 15;// - $(this).parents('#create_vm_dialog').offset().top - 15; left = e.pageX + 15;// - $(this).parents('#create_vm_dialog').offset().left; - $(this).next().css( + icon.next().css( {"top":top+"px", "left":left+"px"}); - $(this).next().fadeIn(); + icon.next().fadeIn(); },function(){ $(this).next().fadeOut(); }); @@ -456,41 +457,45 @@ function setupTips(context){ //returns an array of ids of selected elements in a dataTable function getSelectedNodes(dataTable){ var selected_nodes = []; - if (dataTable != null){ + if (dataTable){ //Which rows of the datatable are checked? - var nodes = $('input:checked',$('tbody',dataTable)); + var nodes = $('tbody input:checked',dataTable); $.each(nodes,function(){ selected_nodes.push($(this).val()); }); - } + }; return selected_nodes; } //returns a HTML string with a select input code generated from -//a dataTable +//a dataTable. Allows filtering elements. function makeSelectOptions(dataTable, id_col,name_col, - status_col, - status_bad, - user_col){ + status_cols, + bad_status_values){ var nodes = dataTable.fnGetData(); var select = ''; var array; - $.each(nodes,function(){ - var id = this[id_col]; - var name = this[name_col]; - var status; - if (status_col >= 0) { - status = this[status_col]; - } - var user = user_col > 0 ? this[user_col] : false; - var isMine = user ? (username == user) || (uid == user) : true; - - - if (status_col < 0 || (status != status_bad) || isMine ){ + for (var j=0; j'+name+''; - } - }); + }; + }; return select; } @@ -500,13 +505,18 @@ function escapeDoubleQuotes(string){ return string.replace(/"/g,'\\"'); } +//Generate the div elements in which the monitoring graphs +//will be contained. They have some elements which ids are +//determined by the graphs configuration, so when the time +//of plotting comes, we can put the data in the right place. function generateMonitoringDivs(graphs, id_prefix){ var str = ""; - //40% of the width of the screen minus + //42% of the width of the screen minus //129px (left menu size) var width = ($(window).width()-129)*42/100; var id_suffix=""; var label=""; + var id=""; $.each(graphs,function(){ label = this.monitor_resources; @@ -525,6 +535,10 @@ function generateMonitoringDivs(graphs, id_prefix){ return str; } +//Draws data for plotting. It will find the correct +//div for doing it in the context with an id +//formed by a prefix (i.e. "hosts") and a suffix +//determined by the graph configuration: "info". function plot_graph(data,context,id_prefix,info){ var labels = info.monitor_resources; var humanize = info.humanize_figures ? @@ -536,6 +550,8 @@ function plot_graph(data,context,id_prefix,info){ var serie; var mon_count = 0; + //make sure series are painted in the order of the + //labels array. for (var i=0; i
    '); + dialogs_context.append('
    '); + var dialog = $('#template_update_dialog',dialogs_context); //Put HTML in place - $('#template_update_dialog').html( + dialog.html( '
    \

    Update the template here:

    \
    \ @@ -607,7 +630,8 @@ function setupTemplateUpdateDialog(){
    \
    '); - $('#template_update_dialog').dialog({ + //Convert into jQuery + dialog.dialog({ autoOpen:false, width:700, modal:true, @@ -615,33 +639,40 @@ function setupTemplateUpdateDialog(){ resizable:false, }); - $('#template_update_dialog button').button(); + $('button',dialog).button(); - $('#template_update_dialog #template_update_select').live("change",function(){ + $('#template_update_select',dialog).change(function(){ var id = $(this).val(); + var dialog = $('#template_update_dialog'); if (id.length){ - var resource = $('#template_update_dialog #template_update_button').val(); - $('#template_update_dialog #template_update_textarea').val("Loading..."); + var resource = $('#template_update_button',dialog).val(); + $('#template_update_textarea',dialog).val("Loading..."); Sunstone.runAction(resource+".fetch_template",id); } else { - $('#template_update_dialog #template_update_textarea').val(""); - } + $('#template_update_textarea',dialog).val(""); + }; }); - $('#template_update_dialog #template_update_button').click(function(){ - var new_template = $('#template_update_dialog #template_update_textarea').val(); - var id = $('#template_update_dialog #template_update_select').val(); + $('#template_update_button',dialog).click(function(){ + var dialog = $('#template_update_dialog'); + var new_template = $('#template_update_textarea',dialog).val(); + var id = $('#template_update_select',dialog).val(); var resource = $(this).val(); Sunstone.runAction(resource+".update",id,new_template); - $('#template_update_dialog').dialog('close'); + dialog.dialog('close'); return false; }); } +//Pops up a dialog to update a template. +//If 1 element is selected, then this the only one shown. +//If no elements are selected, then all elements are included in the select box. +//If several elements are selected, only those are included in the select box. function popUpTemplateUpdateDialog(elem_str,select_items,sel_elems){ - $('#template_update_dialog #template_update_button').val(elem_str); - $('#template_update_dialog #template_update_select').html(select_items); - $('#template_update_dialog #template_update_textarea').val(""); + var dialog = $('#template_update_dialog'); + $('#template_update_button',dialog).val(elem_str); + $('#template_update_select',dialog).html(select_items); + $('#template_update_textarea',dialog).val(""); if (sel_elems.length >= 1){ //several items in the list are selected //grep them @@ -651,24 +682,29 @@ function popUpTemplateUpdateDialog(elem_str,select_items,sel_elems){ new_select+=''; }; }); - $('#template_update_dialog #template_update_select').html(new_select); + $('#template_update_select',dialog).html(new_select); if (sel_elems.length == 1) { - $('#template_update_dialog #template_update_select option').attr("selected","selected"); - $('#template_update_dialog #template_update_select').trigger("change"); + $('#template_update_select option',dialog).attr("selected","selected"); + $('#template_update_select',dialog).trigger("change"); } }; - $('#template_update_dialog').dialog('open'); + dialog.dialog('open'); return false; } -//functions that used as true and false conditions for testing mainly -function True(){ - return true; -} -function False(){ - return false; +function mustBeAdmin(){ + return gid == 0; } -function Empty(){ -}; +function users_sel(){ + return users_select; +} + +function groups_sel(){ + return groups_select; +} + +function hosts_sel(){ + return hosts_select; +} diff --git a/src/sunstone/public/js/sunstone.js b/src/sunstone/public/js/sunstone.js index c642261d6f..cbc3d4553e 100644 --- a/src/sunstone/public/js/sunstone.js +++ b/src/sunstone/public/js/sunstone.js @@ -17,8 +17,14 @@ var cookie = {}; var username = ''; var uid = ''; +var gid = ''; var spinner = 'retrieving'; +var main_tabs_context; +var dialogs_context; +var plots_context; +var info_panels_context; + //Sunstone configuration is formed by predifined "actions", main tabs //and "info_panels". Each tab has "content" and "buttons". Each @@ -67,7 +73,7 @@ var Sunstone = { "updateMainTabContent" : function(tab_id,content_arg,refresh){ SunstoneCfg["tabs"][tab_id]["content"]=content_arg; if (refresh){ //if not present it won't be updated - $('div#'+tab_id).html(content_arg); + $('div#'+tab_id, main_tabs_context).html(content_arg); } }, @@ -75,7 +81,7 @@ var Sunstone = { "updateMainTabButtons" : function(tab_id,buttons_arg,refresh){ SunstoneCfg["tabs"][tab_id]["buttons"]=buttons_arg; if (refresh){ - $('div#'+tab_id+' .action_blocks').empty(); + $('div#'+tab_id+' .action_blocks', main_tabs_context).empty(); insertButtonsInTab(tab_id); } }, @@ -84,7 +90,7 @@ var Sunstone = { "removeMainTab" : function(tab_id,refresh) { delete SunstoneCfg["tabs"][tab_id]; if (refresh) { - $('div#'+tab_id).remove(); + $('div#'+tab_id, main_tabs_context).remove(); $('ul#navigation li#li_'+tab_id).remove(); } }, @@ -138,7 +144,7 @@ var Sunstone = { SunstoneCfg["info_panels"][panel_name][panel_tab_id] = panel_tab_obj; if (refresh){ var tab_content = panel_tab_obj.content; - $('div#'+panel_name+' div#'+panel_tab_id).html(tab_content); + $('div#'+panel_name+' div#'+panel_tab_id,info_panel_context).html(tab_content); } }, @@ -278,6 +284,13 @@ var Sunstone = { //Plugins have done their pre-ready jobs when we execute this. That means //all startup configuration is in place regarding tabs, info panels etc. $(document).ready(function(){ + + //Contexts - make everything more efficient + main_tabs_context = $('div.inner-center'); + dialogs_context = $('div#dialogs'); + plots_context = $('div#plots'); + info_panels_context = $('div#info_panels'); + readCookie(); setLogin(); @@ -299,7 +312,6 @@ $(document).ready(function(){ //An action buttons runs a predefined action. If it has type //"multiple" it runs that action on the elements of a datatable. $('.action_button').live("click",function(){ - var error = 0; var table = null; var value = $(this).attr("value"); @@ -329,14 +341,14 @@ $(document).ready(function(){ //Listen .confirm_buttons. These buttons show a confirmation dialog //before running the action. - $('.confirm_button').live("click",function(){ + $('.confirm_button',main_tabs_context).live("click",function(){ popUpConfirmDialog(this); return false; }); //Listen .confirm_buttons. These buttons show a confirmation dialog //with a select box before running the action. - $('.confirm_with_select_button').live("click",function(){ + $('.confirm_with_select_button',main_tabs_context).live("click",function(){ popUpConfirmWithSelectDialog(this); return false; }); @@ -351,7 +363,7 @@ $(document).ready(function(){ //Close select lists when clicking somewhere else. $('*:not(.action_list,.list_button)').click(function(){ - $('.action_list:visible').hide(); + $('.action_blocks .action_list:visible',main_tabs_context).hide(); }); //Start with the dashboard (supposing we have one). @@ -380,8 +392,8 @@ function setLogin(){ uid = cookie["one-user_id"]; gid = cookie["one-user_gid"]; - $("#user").html(username); - $("#logout").click(function(){ + $("div#header span#user").html(username); + $("div#header a#logout").click(function(){ //todo, this is ugly var f_logout = typeof(OpenNebula)!="undefined"? OpenNebula.Auth.logout : oZones.Auth.logout; @@ -420,10 +432,12 @@ function insertTab(tab_name){ //skip this tab if we do not meet the condition if (condition && !condition()) {return;} - $("div.inner-center").append('
    '); - $('div#'+tab_name).html(tab_info.content); - $('ul#navigation').append('
  • '+tab_info.title+'
  • '); + main_tabs_context.append('
    '); + + $('div#'+tab_name,main_tabs_context).html(tab_info.content); + + $('div#menu ul#navigation').append('
  • '+tab_info.title+'
  • '); } function hideSubTabs(){ @@ -431,7 +445,7 @@ function hideSubTabs(){ var tab_info = SunstoneCfg["tabs"][tab]; var tabClass = tab_info["tabClass"]; if (tabClass=="subTab"){ - $('#li_'+tab).hide(); + $('div#menu ul#navigation #li_'+tab).hide(); }; }; } @@ -440,7 +454,7 @@ function hideSubTabs(){ //Inserts the buttons of all tabs. function insertButtons(){ - for (tab in SunstoneCfg["tabs"]){ + for (tab in SunstoneCfg["tabs"]){ insertButtonsInTab(tab) } } @@ -455,7 +469,9 @@ function insertButtonsInTab(tab_name){ //Check if we have included an appropiate space our tab to //insert them (an .action_blocks div) - if ($('div#'+tab_name+' div.action_blocks').length){ + var action_block = $('div#'+tab_name+' div.action_blocks',main_tabs_context) + + if (action_block.length){ //for every button defined for this tab... for (button_name in buttons){ @@ -501,10 +517,10 @@ function insertButtonsInTab(tab_name){ button_code = $(button_code).addClass("alwaysActive"); } - $('div#'+tab_name+' .action_blocks').append(button_code); + action_block.append(button_code); }//for each button in tab - $('.top_button').button(); + $('.top_button',action_block).button(); }//if tab exists } @@ -514,7 +530,7 @@ function insertButtonsInTab(tab_name){ function initListButtons(){ //for each multi_action select - $('.multi_action_slct').each(function(){ + $('.multi_action_slct',main_tabs_context).each(function(){ //prepare replacement buttons var buttonset = $('
    Previous action').button(); @@ -551,7 +567,7 @@ function initListButtons(){ //below the listeners for events on these buttons and list //enable run the last action button - $('.action_list li a').click(function(){ + $('.action_list li a',main_tabs_context).click(function(){ //enable run last action button var prev_action_button = $('.last_action_button',$(this).parents('.action_blocks')); prev_action_button.val($(this).val()); @@ -565,28 +581,26 @@ function initListButtons(){ //return false; }); - //Show the list of actions in place - $('.list_button').click(function(){ - $('.action_list',$(this).parents('.action_blocks')).css({ - "left": $(this).prev().position().left, - "top": $(this).prev().position().top+13, - "width": $(this).parent().outerWidth()-11 - }); - $('.action_list',$(this).parents('.action_blocks')).toggle("blind",100); - return false; + //Show the list of actions in place + $('.list_button',main_tabs_context).click(function(){ + $('.action_list',$(this).parents('.action_blocks')).css({ + "left": $(this).prev().position().left, + "top": $(this).prev().position().top+13, + "width": $(this).parent().outerWidth()-11 }); + //100ms animation time + $('.action_list',$(this).parents('.action_blocks')).toggle("blind",100); + return false; + }); } //Prepares the standard confirm dialogs function setupConfirmDialogs(){ - - //add div to the main body if it isn't present. - if (!($('div#confirm_dialog').length)){ - $('div#dialogs').append('
    '); - }; + dialogs_context.append('
    '); + var dialog = $('div#confirm_dialog',dialogs_context); //add the HTML with the standard question and buttons. - $('div#confirm_dialog').html( + dialog.html( '
    \
    You have to confirm this action.
    \
    \ @@ -599,7 +613,7 @@ function setupConfirmDialogs(){
    '); //prepare the jquery dialog - $('div#confirm_dialog').dialog({ + dialog.dialog({ resizable:false, modal:true, width:300, @@ -608,14 +622,12 @@ function setupConfirmDialogs(){ }); //enhace the button look - $('div#confirm_dialog button').button(); + $('button',dialog).button(); - //same for the confirm with select dialog. - if (!($('div#confirm_with_select_dialog').length)){ - $('div#dialogs').append('
    '); - }; + dialogs_context.append('
    '); + dialog = $('div#confirm_with_select_dialog',dialogs_context); - $('div#confirm_with_select_dialog').html( + dialog.html( '
    \
    You need to select something.
    \