[PATCH] [Kimchi 0/3] Vitualization UI multiple changes

From: Rajat Gupta <rajggupta@linux.vnet.ibm.com> 1. Added UI validation for s390x Virtualization Guest Edit Add Storage module 2. Added UI validation for s390x Virtualization Template Edit Add Storage module 3. For s390x Virtualization under Edit Template display "Storage" as header instead of "Storage Pool" Rajat Gupta (3): Added UI validation for s390x Virtualization Guest Edit Add Storage module Added UI validation for s390x Virtualization Template Edit Add Storage module For s390x virtualization edit template display "Storage" as header ui/css/kimchi.css | 23 ++--- ui/css/src/modules/_templates.scss | 3 + ui/js/src/kimchi.guest_storage_add.main.js | 130 +++++++++++++++++++---------- ui/js/src/kimchi.template_edit_main.js | 59 +++++++++---- ui/pages/i18n.json.tmpl | 4 + ui/pages/template-edit.html.tmpl | 1 + 6 files changed, 147 insertions(+), 73 deletions(-) -- 2.1.0

From: Rajat Gupta <rajggupta@linux.vnet.ibm.com> Added UI validation for s390x Virtualization Guest Edit Add Storage module Signed-off-by: Rajat Gupta <rajggupta@linux.vnet.ibm.com> --- ui/js/src/kimchi.guest_storage_add.main.js | 130 +++++++++++++++++++---------- ui/pages/i18n.json.tmpl | 3 + 2 files changed, 87 insertions(+), 46 deletions(-) diff --git a/ui/js/src/kimchi.guest_storage_add.main.js b/ui/js/src/kimchi.guest_storage_add.main.js index bebcff7..9fa9175 100644 --- a/ui/js/src/kimchi.guest_storage_add.main.js +++ b/ui/js/src/kimchi.guest_storage_add.main.js @@ -272,12 +272,14 @@ kimchi.guest_storage_add_main = function() { case 'path': $('#new-disk-box div.pool').hide(); $('#new-disk-box div.directorypath').show(); + $(directorypathTextbox).val(""); break; default: $('#new-disk-box div.pool').show(); $('#new-disk-box div.directorypath').hide(); } + $(capacityTextbox).val("").trigger('change'); }); sourceTextbox.on('change', function() { @@ -285,11 +287,14 @@ kimchi.guest_storage_add_main = function() { case 'path': $('#existing-disk-box div.pool,div.volume').hide(); $('#existing-disk-box div.diskpath').show(); + $(diskpathTextbox).val("").trigger('change'); + $(submitButton).prop('disabled', true); break; default: $('#existing-disk-box div.pool,div.volume').show(); $('#existing-disk-box div.diskpath').hide(); + $(submitButton).prop('disabled', false); } }); } @@ -322,6 +327,7 @@ kimchi.guest_storage_add_main = function() { getStoragePools('existing'); if(kimchi.hostarch === s390xArch){ getStorageSource('pool'); + $(diskpathTextbox).val("").trigger('change'); } $(pathTextbox).val(""); $(newPoolTextbox).val(""); @@ -349,6 +355,7 @@ kimchi.guest_storage_add_main = function() { $('#guest-storage-add-window .modal-body .template-pager').animate({ height: "400px" }, 400); + $(capacityTextbox).val("").trigger('change'); }else{ $('#guest-storage-add-window .modal-body .template-pager').animate({ height: "300px" @@ -449,48 +456,66 @@ kimchi.guest_storage_add_main = function() { var bNewDisk = 'false'; var validateDisk = function(settings) { + bNewDisk = 'false'; // Determine whether it's existing disk or new disk if($(capacityTextbox).is(":visible") === true ) { bNewDisk = 'true'; } - if (bNewDisk === 'true') { - if (settings['newpool'] && settings['capacity'] && settings['format']){ - //Change settings['newpool'] to settings['pool'] - settings['pool']=settings['newpool']; - var vmname = settings['vm']; - vmname = vmname + new Date().getTime(); - //Unique vol name to be created - settings['vol']=vmname + ".img"; - //This is all that is needed for attaching newly created volume to VM - var addVolSettings = { - vm: settings['vm'], - type: settings['type'], - vol: settings['vol'], - pool: settings['pool'] - }; - var sizeInBytes = parseInt(settings['capacity']) * 1024 * 1024 * 1024; - settings['capacity'] = sizeInBytes; - //These need to be deleted so they don't get passed to backend - delete settings['path']; - delete settings['newpool']; - //Create an empty storage volume and attach to VM if successful - createVol(settings, addVolSettings); - return true; - } else { - wok.message.error(i18n['KCHVMSTOR0002E'],'#alert-modal-container2'); - return false; - } - } else { - if (settings['pool'] && settings['vol']){ - // Delete path property since it's not needed for disk - delete settings['path']; - return true; - } - else { - wok.message.error(i18n['KCHVMSTOR0002E'],'#alert-modal-container2'); - return false; + if (kimchi.hostarch === s390xArch && ((sourceTextbox.val() === 'path' || sourcenewTextbox.val() === 'path'))) { + if (bNewDisk === 'true') { + if ((/^((https|http|ftp|ftps|tftp|\/).*)+$/.test(settings['dir_path'])) && settings['size'] && settings['format']){ + return true; + }else{ + wok.message.error(i18n['KCHVMSTOR0003E'],'#alert-modal-container2'); + return false; + } + }else{ + if (/^((https|http|ftp|ftps|tftp|\/).*)+$/.test(settings['path'])){ + return true; + }else{ + wok.message.error(i18n['KCHVMSTOR0004E'],'#alert-modal-container2'); + return false; + } } - } + }else{ + if (bNewDisk === 'true') { + if (settings['newpool'] && settings['capacity'] && settings['format']){ + //Change settings['newpool'] to settings['pool'] + settings['pool']=settings['newpool']; + var vmname = settings['vm']; + vmname = vmname + new Date().getTime(); + //Unique vol name to be created + settings['vol']=vmname + ".img"; + //This is all that is needed for attaching newly created volume to VM + var addVolSettings = { + vm: settings['vm'], + type: settings['type'], + vol: settings['vol'], + pool: settings['pool'] + }; + var sizeInMB = parseInt(settings['capacity']) * 1024; + settings['capacity'] = sizeInMB; + //These need to be deleted so they don't get passed to backend + delete settings['path']; + delete settings['newpool']; + //Create an empty storage volume and attach to VM if successful + createVol(settings, addVolSettings); + return true; + } else { + wok.message.error(i18n['KCHVMSTOR0005E'],'#alert-modal-container2'); + return false; + } + } else { + if (settings['pool'] && settings['vol']){ + // Delete path property since it's not needed for disk + delete settings['path']; + return true; + } else { + wok.message.error(i18n['KCHVMSTOR0002E'],'#alert-modal-container2'); + return false; + } + } + } }; validator = {cdrom: validateCDROM, disk: validateDisk}; @@ -505,7 +530,7 @@ kimchi.guest_storage_add_main = function() { } var formData = storageAddForm.serializeObject(); - if (kimchi.hostarch === s390xArch && ((sourceTextbox.val() === 'path') || sourcenewTextbox.val() === 'path')) { + if (kimchi.hostarch === s390xArch && ((sourceTextbox.val() === 'path' || sourcenewTextbox.val() === 'path'))) { if ($('#new-disk').prop('checked')) { var settings = { vm: kimchi.selectedGuest, @@ -541,7 +566,6 @@ kimchi.guest_storage_add_main = function() { $(c).prop('disabled', true); }); - if (kimchi.hostarch != s390xArch) { // Validate form for cdrom and disk validateSpecifiedForm = validator[settings['type']]; if (!validateSpecifiedForm(settings)) { @@ -551,12 +575,11 @@ kimchi.guest_storage_add_main = function() { }); return false; } - if(bNewDisk === 'false'){ + + if((bNewDisk === 'false' || ((kimchi.hostarch === s390xArch && ((sourceTextbox.val() === 'path' || sourcenewTextbox.val() === 'path')))))){ addStorage(settings); } - } else { - addStorage(settings); - } + $(submitButton).addClass('loading').text(i18n['KCHVMCD6003M']); event.preventDefault(); }; @@ -569,8 +592,23 @@ kimchi.guest_storage_add_main = function() { volTextbox.on('change propertychange', function (event) { $(submitButton).prop('disabled', $(this).val() === ''); }); - capacityTextbox.on('change input propertychange', function(event) { - $(submitButton).prop('disabled', $(this).val() === ''); - }); + + if(kimchi.hostarch === s390xArch){ + $(capacityTextbox).add(directorypathTextbox).on('change input propertychange', function(event){ + if(sourcenewTextbox.val() === 'path'){ + $(submitButton).prop('disabled', $(capacityTextbox).val() === '' || $(directorypathTextbox).val() === ''); + }else{ + $(submitButton).prop('disabled', $(capacityTextbox).val() === ''); + } + }); + + diskpathTextbox.on('change input propertychange', function(event) { + $(submitButton).prop('disabled', $(this).val() === ''); + }); + }else{ + capacityTextbox.on('change input propertychange', function(event) { + $(submitButton).prop('disabled', $(this).val() === ''); + }); + } }; diff --git a/ui/pages/i18n.json.tmpl b/ui/pages/i18n.json.tmpl index c67e9e8..399c58f 100644 --- a/ui/pages/i18n.json.tmpl +++ b/ui/pages/i18n.json.tmpl @@ -119,6 +119,9 @@ "KCHVMSTOR0001E": "$_("CDROM path needs to be a valid local/remote path and cannot be blank.")", "KCHVMSTOR0002E": "$_("Disk pool or volume cannot be blank.")", + "KCHVMSTOR0003E": "$_("Disk size or Format or Directory path cannot be blank and Directory path needs to be a valid local/remote path.")", + "KCHVMSTOR0004E": "$_("Disk path needs to be a valid local/remote path and cannot be blank.")", + "KCHVMSTOR0005E": "$_("Storage pool or Disk size or Format cannot be blank.")", "KCHPEERS0001M": "$_("Peers")" } -- 2.1.0

From: Rajat Gupta <rajggupta@linux.vnet.ibm.com> Added UI validation for s390x Virtualization Template Edit Add Storage module Signed-off-by: Rajat Gupta <rajggupta@linux.vnet.ibm.com> --- ui/js/src/kimchi.template_edit_main.js | 57 ++++++++++++++++++++++++---------- ui/pages/i18n.json.tmpl | 1 + 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/ui/js/src/kimchi.template_edit_main.js b/ui/js/src/kimchi.template_edit_main.js index b1f5123..3e4ae29 100644 --- a/ui/js/src/kimchi.template_edit_main.js +++ b/ui/js/src/kimchi.template_edit_main.js @@ -317,9 +317,30 @@ kimchi.template_edit_main = function() { if (source == 'path') { $(storageRow + ' span.storage-pool').hide(); $(storageRow + ' span.storage-path').show(); + $(storageRow + ' span.storage-pool').removeClass('has-error'); + + if($(storageRow + ' input.storage-path').val()){ + $(storageRow + ' span.storage-path').removeClass('has-error'); + }else{ + $(storageRow + ' span.storage-path').addClass('has-error'); + } } else { + if($(storageRow + ' select.selectStorageName').val()){ + $(storageRow + ' span.storage-pool').removeClass('has-error'); + }else{ + $(storageRow + ' span.storage-pool').addClass('has-error'); + } $(storageRow + ' span.storage-pool').show(); $(storageRow + ' span.storage-path').hide(); + $(storageRow + ' span.storage-path').removeClass('has-error'); + } + }); + + $(storageRow + ' input.storage-path').on('change',function(){ + if($(storageRow + ' input.storage-path').val()){ + $(storageRow + ' span.storage-path').removeClass('has-error'); + }else{ + $(storageRow + ' span.storage-path').addClass('has-error'); } }); @@ -835,23 +856,23 @@ kimchi.template_edit_main = function() { interfacceForUpdate.push(thisdata); break; } + }); - if (networkForUpdate instanceof Array) { - data.networks = networkForUpdate; - } else if (networkForUpdate != null) { - data.networks = [networkForUpdate]; - } else { - data.networks = []; - } + if (networkForUpdate instanceof Array) { + data.networks = networkForUpdate; + } else if (networkForUpdate != null) { + data.networks = [networkForUpdate]; + } else { + data.networks = []; + } - if (networkForUpdate instanceof Array) { - data.interfaces = interfacceForUpdate; - } else if (interfacceForUpdate != null) { - data.interfaces = [interfacceForUpdate]; - } else { - data.interfaces = []; - } - }); + if (interfacceForUpdate instanceof Array) { + data.interfaces = interfacceForUpdate; + } else if (interfacceForUpdate != null) { + data.interfaces = [interfacceForUpdate]; + } else { + data.interfaces = []; + } }else { var networks = $('.template-tab-body .item', '#form-template-interface'); var networkForUpdate = new Array(); @@ -879,7 +900,11 @@ kimchi.template_edit_main = function() { $('.modal input[type="checkbox"]').prop('disabled', false); $('.modal select').prop('disabled', false); $('.modal .selectpicker').removeClass('disabled'); - wok.message.error(i18n['KCHTMPL6007M'], '#alert-modal-container'); + if(kimchi.hostarch === s390xArch){ + wok.message.error(i18n['KCHTMPL6008M'], '#alert-modal-container'); + }else{ + wok.message.error(i18n['KCHTMPL6007M'], '#alert-modal-container'); + } } else { kimchi.updateTemplate($('#template-name').val(), data, function() { kimchi.doListTemplates(); diff --git a/ui/pages/i18n.json.tmpl b/ui/pages/i18n.json.tmpl index 399c58f..ba5812f 100644 --- a/ui/pages/i18n.json.tmpl +++ b/ui/pages/i18n.json.tmpl @@ -52,6 +52,7 @@ "KCHTMPL6005M": "$_("View Gallery")", "KCHTMPL6006M": "$_("Not Available")", "KCHTMPL6007M": "$_("Please check the invalid Storage Pools")", + "KCHTMPL6008M": "$_("Please check the invalid Storage Pools or Paths")", "KCHVM6001M": "$_("This will delete the %1 virtual machine and its virtual disks. This operation cannot be undone. Would you like to continue?")", "KCHVM6002M": "$_("Power off Confirmation")", -- 2.1.0

From: Rajat Gupta <rajggupta@linux.vnet.ibm.com> For s390x Virtualization under Edit Template display "Storage" as header instead of "Storage Pool" Signed-off-by: Rajat Gupta <rajggupta@linux.vnet.ibm.com> --- ui/css/kimchi.css | 23 ++++++++++++----------- ui/css/src/modules/_templates.scss | 3 +++ ui/js/src/kimchi.template_edit_main.js | 2 ++ ui/pages/template-edit.html.tmpl | 1 + 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/ui/css/kimchi.css b/ui/css/kimchi.css index ba66785..de23053 100644 --- a/ui/css/kimchi.css +++ b/ui/css/kimchi.css @@ -96,7 +96,7 @@ #guest-add-window.modal-content label.box-iso-outer span.box-iso-border { display: block; border: 3px solid transparent; - transition: all 0.1s ease-in-out; + transition: all .1s ease-in-out; } #template-add-window.modal-content label.box-iso-outer .iso-radio-hidden:checked + span.box-iso-border, @@ -118,7 +118,7 @@ display: block; border: 1px solid transparent; background: #fff; - transition: all 0.1s ease-in-out; + transition: all .1s ease-in-out; } #template-add-window.modal-content label.box-iso-outer span.box-iso-inner .tooltip-inner, @@ -1456,7 +1456,7 @@ body.wok-gallery { border: 1px solid #eee !important; margin-bottom: 3px; display: block; - padding: 0.2em 0.6em 0.3em; + padding: .2em .6em .3em; font-weight: 700; line-height: 1; text-align: left; @@ -1687,6 +1687,10 @@ body.wok-gallery { width: 180px !important; } +#template-edit-window .template-storage-cell.storage { + width: 180px !important; +} + #template-edit-window .template-storage-cell.storage-path { width: 180px !important; } @@ -1750,7 +1754,7 @@ body.wok-gallery { height: 664px; width: 2164px; left: 0; - transition: left 0.2s ease-in-out; + transition: left .2s ease-in-out; } #template-add-window.modal-content p { @@ -2137,9 +2141,7 @@ body.wok-gallery { font-size: 32px; } -#templates-root-container .wok-vm-gallery .item-hidden.column-type, -#templates-root-container .wok-vm-gallery .item-hidden.column-version, -#templates-root-container .wok-vm-gallery .item-hidden.column-processors { +#templates-root-container .wok-vm-gallery .item-hidden.column-type, #templates-root-container .wok-vm-gallery .item-hidden.column-version, #templates-root-container .wok-vm-gallery .item-hidden.column-processors { padding-bottom: 11px; } @@ -2565,7 +2567,7 @@ body.wok-gallery { border-style: solid; border-color: transparent; border-color: rgba(255, 255, 255, 0); - transition: border-color 0.1s ease-in-out; + transition: border-color .1s ease-in-out; } #storage-root-container .volumes .wok-gallery .volume-box-inner { @@ -2579,7 +2581,7 @@ body.wok-gallery { border-style: solid; border-color: #fff; background: #fff; - transition: border-color 0.1s ease-in-out; + transition: border-color .1s ease-in-out; } #storage-root-container .volumes .wok-gallery span.column-name, @@ -3060,8 +3062,7 @@ body.wok-gallery { white-space: nowrap; } -.storage-modal .filter-select.popable .popover ul li:hover, -.storage-modal .filter-select.popable .popover ul li:focus, +.storage-modal .filter-select.popable .popover ul li:hover, .storage-modal .filter-select.popable .popover ul li:focus, .storage-modal .storage-target-input .popover ul li:hover, .storage-modal .storage-target-input .popover ul li:focus, .storage-modal .storage-add-input .popover ul li:hover, diff --git a/ui/css/src/modules/_templates.scss b/ui/css/src/modules/_templates.scss index be7e5bc..eec5878 100644 --- a/ui/css/src/modules/_templates.scss +++ b/ui/css/src/modules/_templates.scss @@ -160,6 +160,9 @@ $kimchi-icon-path: '../images'; .template-storage-cell.storage-pool { width: 180px !important; } + .template-storage-cell.storage { + width: 180px !important; + } .template-storage-cell.storage-path { width: 180px !important; } diff --git a/ui/js/src/kimchi.template_edit_main.js b/ui/js/src/kimchi.template_edit_main.js index 3e4ae29..31cb8d9 100644 --- a/ui/js/src/kimchi.template_edit_main.js +++ b/ui/js/src/kimchi.template_edit_main.js @@ -307,6 +307,8 @@ kimchi.template_edit_main = function() { $(storageRow + ' #diskFormat').val('raw'); $(storageRow + ' #diskFormat').prop('disabled', true).change(); } + $('#form-template-storage .template-tab-header span.storage-pool').hide(); + $('#form-template-storage .template-tab-header span.storage').show(); //set source $('#form-template-storage span.source').show(); diff --git a/ui/pages/template-edit.html.tmpl b/ui/pages/template-edit.html.tmpl index 10532be..88454dc 100644 --- a/ui/pages/template-edit.html.tmpl +++ b/ui/pages/template-edit.html.tmpl @@ -122,6 +122,7 @@ <div class="template-tab-header"> <span class="template-storage-cell source" style="display:none">$_("Source")</span> <span class="template-storage-cell storage-pool">$_("Storage Pool")</span> + <span class="template-storage-cell storage" style="display:none">$_("Storage")</span> <span class="template-storage-cell type">$_("Type")</span> <span class="template-storage-cell disk">$_("Disk(GB)")</span> <span class="template-storage-cell format">$_("Disk Format")</span> -- 2.1.0
participants (2)
-
Aline Manera
-
rajgupta@linux.vnet.ibm.com