diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index 21c45e5e0d..477b0d8e64 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -200,7 +200,6 @@ var host_actions = { type: "create", call : OpenNebula.Cluster.create, callback : function(){ - //OpenNebula.Cluster.list({success: updateClustersView, error: onError}); Sunstone.runAction("Cluster.list"); }, error : onError @@ -336,39 +335,44 @@ Sunstone.addMainTab('hosts_tab',hosts_tab); Sunstone.addInfoPanel("host_info_panel",host_info_panel); + +//Creates an array to be added to the dataTable from the JSON of a host. function hostElementArray(host_json){ - host = host_json.HOST; - acpu = parseInt(host.HOST_SHARE.MAX_CPU); + + var host = host_json.HOST; + + //Calculate some values + var acpu = parseInt(host.HOST_SHARE.MAX_CPU); if (!acpu) {acpu=100}; acpu = acpu - parseInt(host.HOST_SHARE.CPU_USAGE); - total_mem = parseInt(host.HOST_SHARE.MAX_MEM); - free_mem = parseInt(host.HOST_SHARE.FREE_MEM); + var total_mem = parseInt(host.HOST_SHARE.MAX_MEM); + var free_mem = parseInt(host.HOST_SHARE.FREE_MEM); - if (total_mem == 0) { - ratio_mem = 0; - } else { + var ratio_mem = 0; + if (total_mem) { ratio_mem = Math.round(((total_mem - free_mem) / total_mem) * 100); } - total_cpu = parseInt(host.HOST_SHARE.MAX_CPU); - used_cpu = Math.max(total_cpu - parseInt(host.HOST_SHARE.USED_CPU),acpu); + var total_cpu = parseInt(host.HOST_SHARE.MAX_CPU); + var used_cpu = Math.max(total_cpu - parseInt(host.HOST_SHARE.USED_CPU),acpu); - if (total_cpu == 0) { - ratio_cpu = 0; - } else { + var ratio_cpu = 0; + if (total_cpu){ ratio_cpu = Math.round(((total_cpu - used_cpu) / total_cpu) * 100); } - pb_mem = + + //progressbars html code - hardcoded jquery html result + var pb_mem = '
\
\ '+ratio_mem+'%\
\
'; - pb_cpu = + var pb_cpu = '
\
\ '+ratio_cpu+'%\ @@ -387,7 +391,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){ @@ -395,14 +399,14 @@ function hostInfoListener(){ if ($(e.target).is('input')) {return true;} popDialogLoading(); - aData = dataTable_hosts.fnGetData(this); - id = $(aData[0]).val(); + var aData = dataTable_hosts.fnGetData(this); + var id = $(aData[0]).val(); Sunstone.runAction("Host.showinfo",id); - //OpenNebula.Host.show({data:{id:id},success: updateHostInfo,error: onError}); return false; }); } +//updates the host select by refreshing the options in it function updateHostSelect(host_list){ //update select helper @@ -412,11 +416,9 @@ function updateHostSelect(host_list){ hosts_select += ""; }); - //update static selectors - $('#vm_host').html(hosts_select); } - +//updates the cluster select by refreshing the options in it function updateClusterSelect(cluster_list){ //update select helper @@ -425,31 +427,32 @@ function updateClusterSelect(cluster_list){ $.each(cluster_list, function(){ clusters_select += ""; }); - - //update static selectors - //$('#host_cluster').html(clusters_select); - } +//callback for an action affecting a host element function updateHostElement(request, host_json){ - id = host_json.HOST.ID; - element = hostElementArray(host_json); + var id = host_json.HOST.ID; + var element = hostElementArray(host_json); updateSingleElement(element,dataTable_hosts,'#host_'+id); } +//callback for actions deleting a host element function deleteHostElement(req){ deleteElement(dataTable_hosts,'#host_'+req.request.data); } +//call back for actions creating a host element function addHostElement(request,host_json){ - id = host_json.HOST.ID; - element = hostElementArray(host_json); + var id = host_json.HOST.ID; + var element = hostElementArray(host_json); + hosts_select += ""; addElement(element,dataTable_hosts); } +//callback to update the list of hosts. function updateHostsView (request,host_list){ host_list_json = host_list; - host_list_array = [] + var host_list_array = [] $.each(host_list,function(){ //Grab table data from the host_list @@ -458,24 +461,22 @@ function updateHostsView (request,host_list){ updateView(host_list_array,dataTable_hosts); updateHostSelect(host_list); + //dependency with the dashboard plugin updateDashboard("hosts",host_list_json); } +//updates the list of clusters function updateClustersView(request, cluster_list){ cluster_list_json = cluster_list; - //~ cluster_list_array = []; - - //~ $.each(cluster_list, function(){ - //~ cluster_list_array.push(clusterElementArray(this)); - //~ }); - //~ updateView(cluster_list_array,dataTable_clusters); updateClusterSelect(cluster_list); updateDashboard("clusters",cluster_list); } - +//Updates the host info panel tab's content and pops it up function updateHostInfo(request,host){ var host_info = host.HOST; + + //Information tab var info_tab = { title : "Host information", content : @@ -539,6 +540,7 @@ function updateHostInfo(request,host){ ' } + //Template tab var template_tab = { title : "Host template", content : @@ -548,12 +550,14 @@ function updateHostInfo(request,host){ '' } + //Sunstone.updateInfoPanelTab(info_panel_name,tab_name, new tab object); Sunstone.updateInfoPanelTab("host_info_panel","host_info_tab",info_tab); Sunstone.updateInfoPanelTab("host_info_panel","host_template_tab",template_tab); Sunstone.popUpInfoPanel("host_info_panel"); } +//Prepares the host creation dialog function setupCreateHostDialog(){ $('div#dialogs').append('
'); $('div#create_host_dialog').html(create_host_tmpl); @@ -571,7 +575,7 @@ function setupCreateHostDialog(){ notifyError("Host name missing!"); return false; } - host_json = { "host": { "name": $('#name',this).val(), + var host_json = { "host": { "name": $('#name',this).val(), "tm_mad": $('#tm_mad :selected',this).val(), "vm_mad": $('#vmm_mad :selected',this).val(), "im_mad": $('#im_mad :selected',this).val()}} @@ -586,6 +590,7 @@ function setupCreateHostDialog(){ } +//Prepares the dialog to create a cluster function setupCreateClusterDialog(){ $('div#dialogs').append('
'); $('#create_cluster_dialog').html(create_cluster_tmpl); @@ -599,8 +604,8 @@ function setupCreateClusterDialog(){ $('#create_cluster_dialog button').button(); $('#create_cluster_form').submit(function(){ - name=$('#name',this).val(); - cluster_json = { "cluster" : { "name" : name }}; + var name=$('#name',this).val(); + var cluster_json = { "cluster" : { "name" : name }}; Sunstone.runAction("Cluster.create",cluster_json); $('#create_cluster_dialog').dialog('close'); return false; @@ -609,7 +614,7 @@ function setupCreateClusterDialog(){ } - +//Open creation dialogs function popUpCreateHostDialog(){ $('#create_host_dialog').dialog('open'); return false; @@ -620,6 +625,7 @@ function popUpCreateClusterDialog(){ return false; } +//Prepares the autorefresh for hosts function setHostAutorefresh() { setInterval(function(){ var checked = $('input:checked',dataTable_hosts.fnGetNodes()); @@ -630,13 +636,16 @@ function setHostAutorefresh() { },INTERVAL+someTime()); } +//Prepares the autorefresh for clusters function setClusterAutorefresh(){ setInterval(function(){ Sunstone.runAction("Cluster.autorefresh"); },INTERVAL+someTime()); } -//Document ready +//This is executed after the sunstone.js ready() is run. +//Here we can basicly init the host datatable, preload it +//and add specific listeners $(document).ready(function(){ //prepare host datatable @@ -663,13 +672,12 @@ $(document).ready(function(){ setupCreateHostDialog(); setupCreateClusterDialog(); + setHostAutorefresh(); setClusterAutorefresh(); - initCheckAllBoxes(dataTable_hosts); tableCheckboxesListener(dataTable_hosts); hostInfoListener(); - }); diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index 3fd1622da0..04666e6de0 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -817,6 +817,11 @@ Sunstone.addMainTab('vms_tab',vms_tab); Sunstone.addInfoPanel('vm_info_panel',vm_info_panel); +// Returns a human readable running time for a VM +function str_start_time(vm){ + return pretty_time(vm.STIME); +} + function vMachineElementArray(vm_json){ var vm = vm_json.VM; var state = OpenNebula.Helper.resource_state("vm",vm.STATE); diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index 030202981c..44f24859b0 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -270,18 +270,23 @@ Sunstone.addActions(vnet_actions); Sunstone.addMainTab('vnets_tab',vnets_tab); Sunstone.addInfoPanel('vnet_info_panel',vnet_info_panel); - +//returns an array with the VNET information fetched from the JSON object function vNetworkElementArray(vn_json){ - network = vn_json.VNET; + var network = vn_json.VNET; + var total_leases = "0"; + if (network.TOTAL_LEASES){ total_leases = network.TOTAL_LEASES; - }else if (network.LEASES && network.LEASES.LEASE){ + } else if (network.LEASES && network.LEASES.LEASE){ total_leases = network.LEASES.LEASE.length ? network.LEASES.LEASE.length : "1"; - } else{ - total_leases = "0"; } - username = network.USERNAME? network.USERNAME : getUserName(network.UID) - return ['', + + //Does the JSON bring a username field? Otherwise try + //to get it from the users dataTable + var username = network.USERNAME? network.USERNAME : getUserName(network.UID) + + + return ['', network.ID, username, network.NAME, @@ -297,15 +302,15 @@ function vNetworkInfoListener(){ $('#tbodyvnetworks tr').live("click", function(e){ if ($(e.target).is('input')) {return true;} - aData = dataTable_vNetworks.fnGetData(this); - id = $(aData[0]).val(); + var aData = dataTable_vNetworks.fnGetData(this); + var id = $(aData[0]).val(); Sunstone.runAction("Network.showinfo",id); return false; }); } +//updates the vnet select different options function updateNetworkSelect(network_list){ - //update select helper vnetworks_select=""; vnetworks_select += ""; $.each(network_list, function(){ @@ -313,31 +318,38 @@ function updateNetworkSelect(network_list){ }); - //update static selectors + //update static selectors: + //in the VM creation dialog $('div.vm_section#networks select#NETWORK').html(vnetworks_select); } +//Callback to update a vnet element after an action on it function updateVNetworkElement(request, vn_json){ id = vn_json.VNET.ID; element = vNetworkElementArray(vn_json); updateSingleElement(element,dataTable_vNetworks,'#vnetwork_'+id); } +//Callback to delete a vnet element from the table function deleteVNetworkElement(req){ deleteElement(dataTable_vNetworks,'#vnetwork_'+req.request.data); - //How to delete vNetwork select option here? + //TODO: Delete vNetwork select option here? } +//Callback to add a new element function addVNetworkElement(request,vn_json){ - element = vNetworkElementArray(vn_json); + var element = vNetworkElementArray(vn_json); addElement(element,dataTable_vNetworks); + + //update select variable and vnetworks_select += ""; $('div.vm_section#networks select#NETWORK').html(vnetworks_select); } +//updates the list of virtual networks function updateVNetworksView(request, network_list){ network_list_json = network_list; - network_list_array = []; + var network_list_array = []; $.each(network_list,function(){ network_list_array.push(vNetworkElementArray(this)); @@ -345,11 +357,12 @@ function updateVNetworksView(request, network_list){ updateView(network_list_array,dataTable_vNetworks); updateNetworkSelect(network_list); + //dependency with dashboard updateDashboard("vnets",network_list_json); } - +//updates the information panel tabs and pops the panel up function updateVNetworkInfo(request,vn){ var vn_info = vn.VNET; var info_tab_content = @@ -370,7 +383,8 @@ function updateVNetworkInfo(request,vn){ '+(parseInt(vn_info.PUBLIC) ? "yes" : "no" )+'\ \ '; - + + //if it is a fixed VNET we can add leases information if (vn_info.TEMPLATE.TYPE == "FIXED"){ info_tab_content += '\ \ @@ -402,6 +416,7 @@ function updateVNetworkInfo(request,vn){ } +//Prepares the vnet creation dialog function setupCreateVNetDialog() { $('div#dialogs').append('
'); @@ -477,7 +492,7 @@ function setupCreateVNetDialog() { var bridge = $('#bridge',this).val(); var type = $('input:checked',this).val(); - //TBD: Name and bridge provided?! + //TODO: Name and bridge provided?! var network_json = null; if (type == "fixed") { @@ -569,6 +584,7 @@ $(document).ready(function(){ '','','','','','',''],dataTable_vNetworks); Sunstone.runAction("Network.list"); + setupCreateVNetDialog(); setVNetAutorefresh(); diff --git a/src/sunstone/public/js/sunstone-util.js b/src/sunstone/public/js/sunstone-util.js index aeb8ca63a7..5f64176755 100644 --- a/src/sunstone/public/js/sunstone-util.js +++ b/src/sunstone/public/js/sunstone-util.js @@ -22,6 +22,7 @@ function someTime(){ return Math.floor(Math.random()*30000); } +//introduces 0s before a number until in reaches 'length'. function pad(number,length) { var str = '' + number; while (str.length < length) @@ -29,6 +30,7 @@ function pad(number,length) { return str; } +//turns a Unix-formatted time into a human readable string function pretty_time(time_seconds) { var d = new Date(); @@ -44,6 +46,7 @@ function pretty_time(time_seconds) return hour + ":" + mins +":" + secs + " " + month + "/" + day + "/" + year; } +//returns a human readable size in Kilo, Mega, Giga or Tera bytes function humanize_size(value) { if (typeof(value) === "undefined") { value = 0; @@ -64,21 +67,27 @@ function humanize_size(value) { return st; } +//Wrapper to add an element to a dataTable function addElement(element,data_table){ data_table.fnAddData(element); } - +//deletes an element with id 'tag' from a dataTable function deleteElement(data_table,tag){ - tr = $(tag).parents('tr')[0]; + var tr = $(tag).parents('tr')[0]; data_table.fnDeleteRow(tr); $('input',data_table).trigger("change"); } +//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){ - context = dataTable.parents('form'); - last_action_b = $('.last_action_button',context); + //Initialization - disable all buttons + var context = dataTable.parents('form'); + 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){ last_action_b.button("disable"); @@ -87,35 +96,40 @@ function tableCheckboxesListener(dataTable){ //listen to changes $('input',dataTable).live("change",function(){ - dataTable = $(this).parents('table').dataTable(); - context = dataTable.parents('form'); - last_action_b = $('.last_action_button',context); - nodes = dataTable.fnGetNodes(); - total_length = nodes.length; - checked_length = $('input:checked',nodes).length; - + var dataTable = $(this).parents('table').dataTable(); + var context = dataTable.parents('form'); + var last_action_b = $('.last_action_button',context); + var nodes = dataTable.fnGetNodes(); + var total_length = nodes.length; + var checked_length = $('input:checked',nodes).length; + + //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"); }; - $('.create_dialog_button',context).button("enable"); } else { $('.top_button, .list_button',context).button("disable"); last_action_b.button("disable"); - $('.create_dialog_button',context).button("enable"); } + + //any case the create dialog buttons should always be enabled. + $('.create_dialog_button',context).button("enable"); }); } -// Updates a data_table, with a 2D array containing +// 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) { @@ -125,9 +139,10 @@ function updateView(item_list,data_table){ }; } +//replaces an element with id 'tag' in a dataTable with a new one function updateSingleElement(element,data_table,tag){ - tr = $(tag).parents('tr')[0]; - position = data_table.fnGetPosition(tr); + var tr = $(tag).parents('tr')[0]; + var position = data_table.fnGetPosition(tr); data_table.fnUpdate(element,position,0); $('input',data_table).trigger("change"); @@ -136,20 +151,15 @@ function updateSingleElement(element,data_table,tag){ // Returns an string in the form key=value key=value ... // Does not explore objects in depth. function stringJSON(json){ - str = "" + var str = "" for (field in json) { str+= field + '=' + json[field] + ' '; } return str; } -// Returns the running time data -function str_start_time(vm){ - return pretty_time(vm.STIME); -} - - //Notifications +//Notification of submission of action function notifySubmit(action, args, extra_param){ var action_text = action.replace(/OpenNebula\./,'').replace(/\./,' '); @@ -161,6 +171,7 @@ function notifySubmit(action, args, extra_param){ $.jGrowl(msg, {theme: "jGrowl-notify-submit"}); } +//Notification on error function notifyError(msg){ msg = "

Error

" + msg; @@ -172,7 +183,7 @@ function notifyError(msg){ // It recursively explores objects, and flattens their contents in // the result. function prettyPrintJSON(template_json){ - str = "" + var str = "" for (field in template_json) { if (typeof template_json[field] == 'object'){ str += prettyPrintJSON(template_json[field]) + ''; @@ -183,11 +194,14 @@ function prettyPrintJSON(template_json){ return str; } -//Adds a listener to checks all the elements of a table +//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")) { @@ -204,6 +218,8 @@ function initCheckAllBoxes(datatable){ }); } +//standard handling for the server errors on ajax requests. +//Pops up a message with the information. function onError(request,error_json) { var method; var action; @@ -266,19 +282,26 @@ function onError(request,error_json) { return true; } +//Replaces the checkboxes of a datatable with a ajax-loading spinner. +//Used when refreshing elements of a datatable. function waitingNodes(dataTable){ - nodes = dataTable.fnGetData(); + var nodes = dataTable.fnGetData(); for (var i=0;i'); $(this).append(''); $(this).append(''); - + //add the text to .tipspan $('span.tipspan',this).html(tip); + //make sure it is not floating in the wrong place $(this).parent().append('
'); + //hide the text $('span.tipspan',this).hide(); + + //When the mouse is hovering on the icon we fadein/out + //the tip text $('span.info_icon',this).hover(function(e){ var top, left; top = e.pageY - 15;// - $(this).parents('#create_vm_dialog').offset().top - 15; @@ -319,7 +351,7 @@ function setupTips(context){ }); } - +//functions that used as true and false conditions for testing mainly function True(){ return true; } diff --git a/src/sunstone/public/js/sunstone.js b/src/sunstone/public/js/sunstone.js index e425a3a308..04ea79e363 100644 --- a/src/sunstone/public/js/sunstone.js +++ b/src/sunstone/public/js/sunstone.js @@ -190,7 +190,8 @@ var Sunstone = { // function with an extraparam if defined. switch (action_cfg.type){ - case "create","register": + case "create": + case "register": call({data:data_arg, success: callback, error:err}); break; case "single":