From f30cdb500194d9b7dad95dada5cdbd36ddbcd79a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 24 Oct 2014 12:12:43 +0200 Subject: [PATCH] Bug #3251: Use generic sunstone.js Host table for Clusters --- .../public/js/plugins/clusters-tab.js | 253 ++++-------------- src/sunstone/public/js/sunstone.js | 75 +++++- 2 files changed, 121 insertions(+), 207 deletions(-) diff --git a/src/sunstone/public/js/plugins/clusters-tab.js b/src/sunstone/public/js/plugins/clusters-tab.js index 9413e16fad..f25710fa2c 100644 --- a/src/sunstone/public/js/plugins/clusters-tab.js +++ b/src/sunstone/public/js/plugins/clusters-tab.js @@ -18,26 +18,6 @@ /* ------------ Cluster creation dialog ------------ */ -var host_datatable_table_tmpl='\ - \ - \ - ' + tr("ID") + '\ - ' + tr("Name") + '\ - ' + tr("Cluster") + '\ - ' + tr("RVMs") + '\ - ' + tr("Real CPU") + '\ - ' + tr("Allocated CPU") + '\ - ' + tr("Real MEM") + '\ - ' + tr("Allocated MEM") + '\ - ' + tr("Status") + '\ - ' + tr("IM MAD") + '\ - ' + tr("VM MAD") + '\ - ' + tr("Last monitored on") + '\ - \ - \ - \ - ' - var vnet_datatable_table_tmpl='\ \ \ @@ -97,25 +77,7 @@ var create_cluster_tmpl ='
\
\
\
\ -
\ -
\ - \ -
\ -
\ - \ -
\ -
\ -
\ -
\ - ' + host_datatable_table_tmpl + '
\ -
\ -
\ -
\ -
\ - '+tr("Please select one or more hosts from the list")+'\ - \ -
\ -
\ + '+generateHostTableSelect("cluster_wizard_hosts")+'\
\
\
\ @@ -173,11 +135,9 @@ var create_cluster_tmpl ='
\ // Common utils for datatatables // Holds the selected items -selected_hosts_list = {}; selected_vnets_list = {}; selected_datastore_list = {}; -host_row_hash = {}; vnet_row_hash = {}; datastore_row_hash = {}; @@ -197,24 +157,11 @@ function setupCreateClusterDialog(){ dialog.addClass("reveal-modal large max-height").attr("data-reveal", ""); - // ------- Create the dialog datatables ------------ - dataTable_cluster_hosts = $("#datatable_cluster_hosts", dialog).dataTable({ - "sDom" : '<"H">t<"F"p>', - "oColVis": { //exclude checkbox column - "aiExclude": [ 0 ] - }, - "aoColumnDefs": [ - { "sWidth": "35px", "aTargets": [1] }, - { "bVisible": false, "aTargets": [0,5,7,10,11,12]} // 3 = cluster - ], - "bSortClasses" : false, - "bDeferRender": true - }); - - $('#cluster_hosts_search', dialog).keyup(function(){ - dataTable_cluster_hosts.fnFilter( $(this).val() ); - }) + var opts = { + multiple_choice: true + }; + setupHostTableSelect(dialog, "cluster_wizard_hosts", opts); dataTable_cluster_vnets = $("#datatable_cluster_vnets", dialog).dataTable({ @@ -256,46 +203,6 @@ function setupCreateClusterDialog(){ // ------- End of create the dialog datatables ------------ - // Add listener to row select action - // Marks it in another background color - // Adds or removes the element from the list - $('#datatable_cluster_hosts tbody', dialog).delegate("tr", "click", function(e){ - if ($(e.target).is('input') || - $(e.target).is('select') || - $(e.target).is('option')) return true; - - var aData = dataTable_cluster_hosts.fnGetData(this); - var host_id = aData[1]; - var name = aData[2]; - - if ($.isEmptyObject(selected_hosts_list)) { - $('#cluster_hosts_selected', dialog).show(); - $('#select_cluster_hosts', dialog).hide(); - } - - if(!$("td:first", this).hasClass('markrowchecked')) - { - selected_hosts_list[host_id]=1; - host_row_hash[host_id]=this; - $(this).children().each(function(){$(this).addClass('markrowchecked');}); - $('div#selected_hosts_div', dialog).append(''+name+' '); - } - else - { - delete selected_hosts_list[host_id]; - $(this).children().each(function(){$(this).removeClass('markrowchecked');}); - $('div#selected_hosts_div span#tag_hosts_'+host_id, dialog).remove(); - } - - if ($.isEmptyObject(selected_hosts_list)) { - $('#cluster_hosts_selected', dialog).hide(); - $('#select_cluster_hosts', dialog).show(); - } - - return false; - }); - - $('#datatable_cluster_vnets tbody', dialog).delegate("tr", "click", function(e){ if ($(e.target).is('input') || $(e.target).is('select') || @@ -378,18 +285,7 @@ function setupCreateClusterDialog(){ // Unselect row var id = $(this).parent().attr("ID"); - if (id.match(/host/g)) - { - var host_id=id.substring(10,id.length); - delete selected_hosts_list[host_id]; - $("td:first", host_row_hash[host_id]).parent().children().each(function(){$(this).removeClass('markrowchecked');}); - - if ($.isEmptyObject(selected_hosts_list)) { - $('#cluster_hosts_selected', dialog).hide(); - $('#select_cluster_hosts', dialog).show(); - } - } - else if (id.match(/vnet/g)) + if (id.match(/vnet/g)) { var vnet_id=id.substring(10,id.length); delete selected_vnets_list[vnet_id]; @@ -414,12 +310,6 @@ function setupCreateClusterDialog(){ } }); - $("#refresh_host_table_button_class", dialog).click( function(){ - Sunstone.runAction("ClusterHost.list"); - return false; - } - ); - $("#refresh_vnet_table_button_class", dialog).click( function(){ Sunstone.runAction("ClusterVN.list"); return false; @@ -441,6 +331,14 @@ function setupCreateClusterDialog(){ return false; } + var selected_hosts_arr = retrieveHostTableSelect(dialog, "cluster_wizard_hosts"); + + var selected_hosts_list = {}; + + $.each(selected_hosts_arr, function(i,e){ + selected_hosts_list[e] = 1; + }); + var cluster_json = { "cluster": { "name": $('#name',dialog).val(), @@ -457,15 +355,12 @@ function setupCreateClusterDialog(){ } function reset_counters(){ - selected_hosts_list = {}; selected_vnets_list = {}; selected_datastore_list = {}; - original_hosts_list = {}; original_vnets_list = {}; original_datastores_list = {}; - host_row_hash = {}; vnet_row_hash = {}; datastore_row_hash = {}; } @@ -484,7 +379,7 @@ function popUpCreateClusterDialog(){ $('#create_cluster_header',$create_cluster_dialog).show(); $('#update_cluster_header',$create_cluster_dialog).hide(); - Sunstone.runAction("ClusterHost.list"); + refreshHostTableSelect($create_cluster_dialog, "cluster_wizard_hosts"); Sunstone.runAction("ClusterVN.list"); Sunstone.runAction("ClusterDS.list"); @@ -562,9 +457,19 @@ function fillPopPup(request,response){ $('#name',dialog).val(name); $('#name',dialog).attr("disabled", "disabled"); + var original_hosts_list = []; + // Select hosts belonging to the cluster if (host_ids) { + original_hosts_list = host_ids; + var opts = { + ids : host_ids + } + + selectHostTableSelect(dialog, "cluster_wizard_hosts", opts); + +/* dataTable_cluster_hosts.on('draw', function(){ dataTable_cluster_hosts.unbind('draw'); var rows = dataTable_cluster_hosts.fnGetNodes(); @@ -588,6 +493,7 @@ function fillPopPup(request,response){ original_hosts_list = $.extend({}, selected_hosts_list); }); +//*/ } if (vnet_ids) @@ -649,7 +555,7 @@ function fillPopPup(request,response){ // Clone already existing resources (to keep track) cluster_to_update_id = response.CLUSTER.ID; - Sunstone.runAction("ClusterHost.list"); + refreshHostTableSelect(dialog, "cluster_wizard_hosts"); Sunstone.runAction("ClusterVN.list"); Sunstone.runAction("ClusterDS.list"); @@ -657,21 +563,21 @@ function fillPopPup(request,response){ $('#update_cluster_submit').click(function(){ // find out which ones are in and out - for (var host_id in selected_hosts_list) - { - if (!original_hosts_list[host_id]) + var selected_hosts_list = retrieveHostTableSelect(dialog, "cluster_wizard_hosts"); + + $.each(selected_hosts_list, function(i,host_id){ + if (original_hosts_list.indexOf(host_id) == -1) { Sunstone.runAction("Cluster.addhost",cluster_to_update_id,host_id); - } - } + } + }); - for (var host_id in original_hosts_list) - { - if (!selected_hosts_list[host_id]) + $.each(original_hosts_list, function(i,host_id){ + if (selected_hosts_list.indexOf(host_id) == -1) { Sunstone.runAction("Cluster.delhost",cluster_to_update_id,host_id); } - } + }); for (var vnet_id in selected_vnets_list) { @@ -713,58 +619,6 @@ function fillPopPup(request,response){ }); } - -/* -------- Host datatable -------- */ - -//Setup actions -var cluster_host_actions = { - - "ClusterHost.list" : { - type: "list", - call: OpenNebula.Host.list, - callback: function(request,host_list){ - updateClusterHostsView(request,host_list); - dataTable_cluster_hosts.fnSort( [ [1,config['user_config']['table_order']] ] ); - }, - error: onError - }, - - "ClusterHostInfo.list" : { - type: "list", - call: OpenNebula.Host.list, - callback: function(request,host_list){ - updateClusterHostsInfoView(request,host_list); - dataTable_cluster_hosts_panel.fnSort( [ [1,config['user_config']['table_order']] ] ); - }, - error: onError - } -} - -//callback to update the list of hosts for Create dialog -function updateClusterHostsView (request,host_list){ - var host_list_array = []; - - $.each(host_list,function(){ - //Grab table data from the host_list - host_list_array.push(hostElementArray(this)); - }); - - updateView(host_list_array,dataTable_cluster_hosts); -} - -//callback to update the list of hosts for info panel -function updateClusterHostsInfoView (request,host_list){ - var host_list_array = []; - - $.each(host_list,function(){ - if(this.HOST.CLUSTER_ID == cluster_info.ID) - host_list_array.push(hostElementArray(this)); - }); - - updateView(host_list_array,dataTable_cluster_hosts_panel); -} - - /* -------- Virtual Networks datatable -------- */ //Setup actions @@ -1123,7 +977,6 @@ var cluster_info_panel = { }; -Sunstone.addActions(cluster_host_actions); Sunstone.addActions(cluster_vnet_actions); Sunstone.addActions(cluster_datastore_actions); Sunstone.addActions(cluster_actions); @@ -1248,9 +1101,7 @@ function updateClusterInfo(request,cluster){ icon: "fa-hdd-o", content : '
\
\ - ' + - host_datatable_table_tmpl + - '
\ + '+generateHostTableSelect("cluster_info_hosts")+'\
\
' } @@ -1289,21 +1140,22 @@ function updateClusterInfo(request,cluster){ // Hosts datatable - dataTable_cluster_hosts_panel = $("#datatable_cluster_hosts_info_panel").dataTable({ - "sDom" : "<'H'>t<'row'<'large-6 columns'i><'large-6 columns'p>>", - "oColVis": { //exclude checkbox column - "aiExclude": [ 0 ] - }, - "bSortClasses" : false, - "bDeferRender": true, - "aoColumnDefs": [ - { "sWidth": "35px", "aTargets": [1] }, - { "sWidth": "35px", "aTargets": [9] }, - { "bVisible": false, "aTargets": [0,5,7,10,11,12]} - ] - }); + var host_ids = cluster_info.HOSTS.ID; - infoListener(dataTable_cluster_hosts_panel,'Host.show','hosts-tab'); + if (typeof host_ids == 'string'){ + host_ids = [host_ids]; + } else if (host_ids == undefined){ + host_ids = []; + } + + var opts = { + read_only: true, + fixed_ids: host_ids + } + + setupHostTableSelect($("#cluster_info_panel"), "cluster_info_hosts", opts); + + refreshHostTableSelect($("#cluster_info_panel"), "cluster_info_hosts"); // Virtual networks datatable @@ -1340,7 +1192,6 @@ function updateClusterInfo(request,cluster){ infoListener(dataTable_cluster_datastores_panel,'Datastore.show','datastores-tab'); // initialize datatables values - Sunstone.runAction("ClusterHostInfo.list"); Sunstone.runAction("ClusterVNInfo.list"); Sunstone.runAction("ClusterDSInfo.list"); } diff --git a/src/sunstone/public/js/sunstone.js b/src/sunstone/public/js/sunstone.js index 27523dc115..5e924368cd 100644 --- a/src/sunstone/public/js/sunstone.js +++ b/src/sunstone/public/js/sunstone.js @@ -1402,7 +1402,9 @@ function updateView(item_list,dataTable){ } }); - if (dataTable) { + // dataTable.fnSettings is undefined when the table has been detached from + // the DOM + if (dataTable && dataTable.fnSettings()) { var dTable_settings = dataTable.fnSettings(); var prev_start = dTable_settings._iDisplayStart; @@ -5781,7 +5783,9 @@ function generateHostTableSelect(context_id){ "id_index": 1, "name_index": 2, "select_resource": tr("Please select a Host from the list"), - "you_selected": tr("You selected the following Host:") + "you_selected": tr("You selected the following Host:"), + "select_resource_multiple": tr("Please select one or more hosts from the list"), + "you_selected_multiple": tr("You selected the following hosts:") }; return generateResourceTableSelect(context_id, columns, options); @@ -5790,6 +5794,11 @@ function generateHostTableSelect(context_id){ // opts.bVisible: dataTable bVisible option. If not set, the .yaml visibility will be used // opts.filter_fn: boolean function to filter which elements to show // opts.select_callback(aData, options): function called after a row is selected +// opts.multiple_choice: boolean true to enable multiple element selection +// opts.read_only: boolean true so user is not asked to select elements +// opts.fixed_ids: Array of IDs to show. Any other ID will be filtered out. If +// an ID is not returned by the pool, it will be included as a +// blank row function setupHostTableSelect(section, context_id, opts){ if(opts == undefined){ @@ -5808,6 +5817,18 @@ function setupHostTableSelect(section, context_id, opts){ opts.bVisible = config; } + if(opts.multiple_choice == undefined){ + opts.multiple_choice = false; + } + + var fixed_ids_map_orig = {}; + + if(opts.fixed_ids != undefined){ + $.each(opts.fixed_ids,function(){ + fixed_ids_map_orig[this] = true; + }); + } + var options = { "dataTable_options": { "bAutoWidth":false, @@ -5823,6 +5844,10 @@ function setupHostTableSelect(section, context_id, opts){ ] }, + "multiple_choice": opts.multiple_choice, + "read_only": opts.read_only, + "fixed_ids": opts.fixed_ids, + "id_index": 1, "name_index": 2, @@ -5832,6 +5857,8 @@ function setupHostTableSelect(section, context_id, opts){ success: function (request, resource_list){ var list_array = []; + var fixed_ids_map = $.extend({}, fixed_ids_map_orig); + $.each(resource_list,function(){ var add = true; @@ -5839,11 +5866,31 @@ function setupHostTableSelect(section, context_id, opts){ add = opts.filter_fn(this.HOST); } + if(opts.fixed_ids != undefined){ + add = (add && fixed_ids_map[this.HOST.ID]); + } + if(add){ list_array.push(hostElementArray(this)); + + delete fixed_ids_map[this.HOST.ID]; } }); + var n_columns = 13; // SET FOR EACH RESOURCE + + $.each(fixed_ids_map, function(id,v){ + var empty = []; + + for(var i=0; i<=n_columns; i++){ + empty.push(""); + } + + empty[1] = id; // SET FOR EACH RESOURCE, id_index + + list_array.push(empty); + }); + updateView(list_array, datatable); }, error: onError @@ -5856,6 +5903,22 @@ function setupHostTableSelect(section, context_id, opts){ return setupResourceTableSelect(section, context_id, options); } +// Clicks the refresh button +function refreshHostTableSelect(section, context_id){ + return refreshResourceTableSelect(section, context_id); +} + +// Returns an ID, or an array of IDs for opts.multiple_choice +function retrieveHostTableSelect(section, context_id){ + return retrieveResourceTableSelect(section, context_id); +} + +// Clears the current selection, and selects the given IDs +// opts.ids must be a single ID, or an array of IDs for options.multiple_choice +// opts.names must be an array of {name, uname} +function selectHostTableSelect(section, context_id, opts){ + return selectResourceTableSelect(section, context_id, opts); +} function generateDatastoreTableSelect(context_id){ @@ -6212,9 +6275,8 @@ function setupResourceTableSelect(section, context_id, options) { } else if(options.multiple_choice){ $('#selected_ids_row_'+context_id, section).data("ids", {}); - function row_click(row){ + function row_click(row, aData){ dataTable_select.unbind("draw"); - var aData = dataTable_select.fnGetData(row); var row_id = aData[options.id_index]; var row_name = aData[options.name_index]; @@ -6253,7 +6315,8 @@ function setupResourceTableSelect(section, context_id, options) { }; $('#datatable_'+context_id+' tbody', section).on("click", "tr", function(e){ - row_click(this); + var aData = dataTable_select.fnGetData(this); + row_click(this, aData); }); $(section).on("click", '#selected_ids_row_'+context_id+' span.fa.fa-times', function() { @@ -6262,7 +6325,7 @@ function setupResourceTableSelect(section, context_id, options) { // TODO: improve preformance, linear search $.each(dataTable_select.fnGetData(), function(index, row){ if(row[options.id_index] == row_id){ - row_click(dataTable_select.fnGetNodes(index)); + row_click(dataTable_select.fnGetNodes(index), row); return false; } });