diff --git a/ui/new/jsp/instance.jsp b/ui/new/jsp/instance.jsp index b81431769bc..18163f88c36 100644 --- a/ui/new/jsp/instance.jsp +++ b/ui/new/jsp/instance.jsp @@ -779,8 +779,10 @@ - - +
diff --git a/ui/new/scripts/cloud.core2.instance.js b/ui/new/scripts/cloud.core2.instance.js index 91c1aa74e7b..3fb30e04822 100644 --- a/ui/new/scripts/cloud.core2.instance.js +++ b/ui/new/scripts/cloud.core2.instance.js @@ -332,7 +332,7 @@ function clickInstanceGroupHeader($arrowIcon) { function vmJsonToMidmenu(json, $midmenuItem) { $midmenuItem.data("jsonObj", json); $midmenuItem.data("toRightPanelFn", vmMidmenuToRightPanel); - $midmenuItem.attr("id", ("midmenuItemVm_"+json.id)); + $midmenuItem.attr("id", ("midmenuItem_"+json.id)); $midmenuItem.data("id", json.id); $midmenuItem.find("#icon").attr("src", "images/status_gray.png"); @@ -425,7 +425,8 @@ function clickInstanceGroupHeader($arrowIcon) { } function vmVolumeJSONToTemplate(json, template) { - template.attr("id","vm_volume_"+json.id); + template.attr("id","vm_volume_"+json.id); + template.data("id", json.id); template.find("#id").text(json.id); template.find("#name").text(json.name); if (json.storagetype == "shared") @@ -438,10 +439,10 @@ function clickInstanceGroupHeader($arrowIcon) { if(json.type=="ROOT") { //"create template" is allowed(when stopped), "detach disk" is disallowed. if (json.vmstate == "Stopped") - buildActionLink("Create Template", volumeActionMap, template.find("#volume_action_menu"), volumeListAPIMap); + buildActionLinkForSingleObject("Create Template", volumeActionMap, template.find("#volume_action_menu"), volumeListAPIMap, template); } else { //json.type=="DATADISK": "detach disk" is allowed, "create template" is disallowed. - buildActionLink("Detach Disk", volumeActionMap, template.find("#volume_action_menu"), volumeListAPIMap); + buildActionLinkForSingleObject("Detach Disk", volumeActionMap, template.find("#volume_action_menu"), volumeListAPIMap, template); } } @@ -508,7 +509,7 @@ function clickInstanceGroupHeader($arrowIcon) { $("#action_link").show(); $("#action_menu #action_list").empty(); for(var label in vmActionMap) - buildActionLink(label, vmActionMap, $("#action_menu"), vmListAPIMap); + buildActionLinkForMidMenu(label, vmActionMap, $("#action_menu"), vmListAPIMap); } }); } @@ -1191,14 +1192,30 @@ function clickInstanceGroupHeader($arrowIcon) { //***** VM Wizard (end) ******************************************************************************** //***** Volume tab (begin) ***************************************************************************** - $("#volume_action_link").bind("mouseover", function(event) { + $("#volume_action_link").live("mouseover", function(event) { $(this).find("#volume_action_menu").show(); return false; }); - $("#volume_action_link").bind("mouseout", function(event) { + $("#volume_action_link").live("mouseout", function(event) { $(this).find("#volume_action_menu").hide(); return false; }); + + + $.ajax({ + data: createURL("command=listOsTypes&response=json"), + dataType: "json", + success: function(json) { + types = json.listostypesresponse.ostype; + if (types != null && types.length > 0) { + var select = $("#dialog_create_template #create_template_os_type").empty(); + for (var i = 0; i < types.length; i++) { + select.append(""); + } + } + } + }); + //***** Volume tab (end) ******************************************************************************* diff --git a/ui/new/scripts/cloud.core2.js b/ui/new/scripts/cloud.core2.js index c0de80bc91d..fbef2d78a43 100644 --- a/ui/new/scripts/cloud.core2.js +++ b/ui/new/scripts/cloud.core2.js @@ -20,9 +20,10 @@ // Version: @VERSION@ +//***** actions for middle menu (begin) ************************************************************************ var selectedItemsInMidMenu = {}; -function buildActionLink(label, actionMap, $actionMenu, listAPIMap) { +function buildActionLinkForMidMenu(label, actionMap, $actionMenu, listAPIMap) { var apiInfo = actionMap[label]; var $listItem = $("#action_list_item").clone(); $actionMenu.find("#action_list").append($listItem.show()); @@ -49,8 +50,7 @@ function buildActionLink(label, actionMap, $actionMenu, listAPIMap) { selectedItemsInMidMenu = {}; //clear selected items for action return false; }); -} - +} function doActionForMidMenu(id, $actionLink, apiCommand, listAPIMap) { var label = $actionLink.data("label"); @@ -61,7 +61,7 @@ function doActionForMidMenu(id, $actionLink, apiCommand, listAPIMap) { var listAPIResponse = listAPIMap["listAPIResponse"]; var listAPIResponseObj = listAPIMap["listAPIResponseObj"]; - var $midmenuItem = $("#midmenuItemVm_"+id); + var $midmenuItem = $("#midmenuItem_"+id); $midmenuItem.find("#content").removeClass("selected").addClass("inaction"); $midmenuItem.find("#spinning_wheel").addClass("midmenu_addingloader").show(); $midmenuItem.find("#info_icon").hide(); @@ -177,7 +177,176 @@ function handleErrorInMidMenu(XMLHttpResponse, $midmenuItem) { $midmenuItem.data("afterActionInfo", ((label + " action failed. Reason: " + sanitizeXSS(unescape(errorMsg))))); else $midmenuItem.data("afterActionInfo", (label + " action failed.")); -} +} +//***** actions for middle menu (end) ************************************************************************** + +//***** actions for right panel (begin) ************************************************************************ +//var selectedItemsInSingleObject = {}; + +function buildActionLinkForSingleObject(label, actionMap, $actionMenu, listAPIMap, $singleObject) { + //debugger; + var apiInfo = actionMap[label]; + var $listItem = $("#action_list_item").clone(); + $actionMenu.find("#action_list").append($listItem.show()); + var $link = $listItem.find("#link").text(label); + $link.data("label", label); + $link.data("api", apiInfo.api); + $link.data("isAsyncJob", apiInfo.isAsyncJob); + $link.data("asyncJobResponse", apiInfo.asyncJobResponse); + $link.data("afterActionSeccessFn", apiInfo.afterActionSeccessFn); + $link.data("dialogBeforeActionFn", apiInfo.dialogBeforeActionFn); + + var id = $singleObject.data("id"); + + $link.bind("click", function(event) { + //debugger; + $actionMenu.hide(); + var $actionLink = $(this); + var dialogBeforeActionFn = $actionLink.data("dialogBeforeActionFn"); + if(dialogBeforeActionFn == null) { + //for(var id in selectedItemsInSingleObject) { + var apiCommand = "command="+$actionLink.data("api")+"&id="+id; + doActionToSingleObject(id, $actionLink, apiCommand, listAPIMap, $singleObject); + //} + } + else { + dialogBeforeActionFn($actionLink, listAPIMap, $singleObject); + } + //selectedItemsInSingleObject = {}; //clear selected items for action + return false; + }); +} + +function doActionToSingleObject(id, $actionLink, apiCommand, listAPIMap, $singleObject) { + //debugger; + var label = $actionLink.data("label"); + var isAsyncJob = $actionLink.data("isAsyncJob"); + var asyncJobResponse = $actionLink.data("asyncJobResponse"); + var afterActionSeccessFn = $actionLink.data("afterActionSeccessFn"); + var listAPI = listAPIMap["listAPI"]; + var listAPIResponse = listAPIMap["listAPIResponse"]; + var listAPIResponseObj = listAPIMap["listAPIResponseObj"]; + + var $spinningWheel = $singleObject.find("#spinning_wheel"); + $spinningWheel.find("#description").text(label + "...."); + $spinningWheel.show(); + + //Async job (begin) ***** + if(isAsyncJob == true) { + $.ajax({ + data: createURL(apiCommand), + dataType: "json", + success: function(json) { + //debugger; + var jobId = json[asyncJobResponse].jobid; + var timerKey = "asyncJob_" + jobId; + $("body").everyTime( + 10000, + timerKey, + function() { + $.ajax({ + data: createURL("command=queryAsyncJobResult&jobId="+jobId), + dataType: "json", + success: function(json) { + //debugger; + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } else { + $("body").stopTime(timerKey); + $spinningWheel.hide(); + if (result.jobstatus == 1) { // Succeeded + $singleObject.data("afterActionInfo", (label + " action succeeded.")); + + //DestroyVirtualMachine API doesn't return an embedded object on success (Bug 6041) + //Before Bug 6041 get fixed, use the temporary solution below. + $.ajax({ + cache: false, + data: createURL("command="+listAPI+"&id="+id), + dataType: "json", + success: function(json) { + afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0], $singleObject); + } + }); + //After Bug 6037 is fixed, remove temporary solution above and uncomment the line below + //afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0], $singleObject); + + } else if (result.jobstatus == 2) { // Failed + $singleObject.data("afterActionInfo", (label + " action failed. Reason: " + sanitizeXSS(result.jobresult))); + } + } + }, + error: function(XMLHttpResponse) { + //debugger; + $("body").stopTime(timerKey); + handleErrorInSingleObject(XMLHttpResponse, $singleObject); + } + }); + }, + 0 + ); + }, + error: function(XMLHttpResponse) { + //debugger; + handleErrorInSingleObject(XMLHttpResponse, $singleObject); + } + }); + } + //Async job (end) ***** + + //Sync job (begin) ***** + else { + //debugger; + $.ajax({ + data: createURL(apiCommand), + dataType: "json", + async: false, + success: function(json) { + //debugger; + $spinningWheel.hide(); + + //RecoverVirtualMachine API doesn't return an embedded object on success (Bug 6037) + //Before Bug 6037 get fixed, use the temporary solution below. + $.ajax({ + cache: false, + data: createURL("command="+listAPI+"&id="+id), + dataType: "json", + async: false, + success: function(json) { + $singleObject.data("afterActionInfo", (label + " action succeeded.")); + afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0], $singleObject); + } + }); + //After Bug 6037 is fixed, remove temporary solution above and uncomment the line below + //afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0], $singleObject); + }, + error: function(XMLHttpResponse) { + //debugger; + handleErrorInSingleObject(XMLHttpResponse, $singleObject); + } + }); + } + //Sync job (end) ***** +} + +function handleErrorInSingleObject(XMLHttpResponse, $singleObject) { + //debugger; + $spinningWheel.hide(); + + var errorMsg = ""; + if(XMLHttpResponse.responseText != null & XMLHttpResponse.responseText.length > 0) { + var start = XMLHttpResponse.responseText.indexOf("h1") + 3; + var end = XMLHttpResponse.responseText.indexOf(" 0) + $singleObject.data("afterActionInfo", ((label + " action failed. Reason: " + sanitizeXSS(unescape(errorMsg))))); + else + $singleObject.data("afterActionInfo", (label + " action failed.")); +} +//***** actions for right panel (end) ************************************************************************** + + function createURL(url) { diff --git a/ui/new/scripts/cloud.core2.volume.js b/ui/new/scripts/cloud.core2.volume.js index 9fc6271ba1c..a69945a5bb5 100644 --- a/ui/new/scripts/cloud.core2.volume.js +++ b/ui/new/scripts/cloud.core2.volume.js @@ -58,12 +58,13 @@ var volumeActionMap = { -function doCreateTemplate($t, selectedItemIds, listAPIMap) { +function doCreateTemplate($actionLink, listAPIMap, $singleObject) { + //debugger; //$("#dialog_create_template").find("#volume_name").text(volumeName); $("#dialog_create_template") .dialog('option', 'buttons', { "Create": function() { - debugger; + //debugger; var thisDialog = $(this); // validate values @@ -78,10 +79,11 @@ function doCreateTemplate($t, selectedItemIds, listAPIMap) { var isPublic = thisDialog.find("#create_template_public").val(); var password = thisDialog.find("#create_template_password").val(); - for(var id in selectedItemIds) { + var id = $singleObject.data("id"); + //for(var id in selectedItemIds) { var apiCommand = "command=createTemplate&volumeId="+id+"&name="+encodeURIComponent(name)+"&displayText="+encodeURIComponent(desc)+"&osTypeId="+osType+"&isPublic="+isPublic+"&passwordEnabled="+password; - doAction(id, $t, apiCommand, listAPIMap); - } + doActionToSingleObject(id, $actionLink, apiCommand, listAPIMap, $singleObject); + //} }, "Cancel": function() { $(this).dialog("close");