[Kimchi-devel] [PATCH V3] Edit Template redefined

Aline Manera alinefm at linux.vnet.ibm.com
Mon Nov 17 17:23:35 UTC 2014


On 11/17/2014 01:22 AM, Wen Wang wrote:
> Thanks for the timely reply, just two inline comments:
>
> On 11/15/2014 1:57 AM, Aline Manera wrote:
>>
>> Some issues I found:
>>
>> 1. While trying to add a new network:
>> |{
>> ||   "reason":"KCHTMPL0017E: All networks for the template must be specified in a list.",
>> ||   "code":"400 Bad Request",
>> ||   "call_stack":"Traceback (most recent call last):\n  File \"/usr/lib/python2.7/site-packages/cherrypy||/_cprequest.py\",
>> line 656, in respond\n    response.body = self.handler()\n  File \"/usr/lib/python2||.7/site-packages/cherrypy/lib/encoding.py\",
>> line 188, in __call__\n    self.body = self.oldhandler(||*args, **kwargs)\n  File \"/usr/lib/python2.7/site-packages/cherrypy/_cpdispatch.py\",
>> line 34, in __call__||\n    return self.callable(*self.args, **self.kwargs)\n  File \"/home/alinefm/kimchi/src/kimchi/control||/base.py\", line 162,
>> in index\n    raise cherrypy.HTTPError(400, e.message)\nHTTPError: (400, u'KCHTMPL0017E||: All networks for the template must be specified in a list.')\n"
>> ||}|
> I cannot reproduce this I can successfully update the net work and 
> here is my result of adding the network from Firebug:
>

I can reproduce it as many time as I want.

The steps I did are:

1) Switch to "Network" tab on "Edit Template"
2) Select + icon to add new network
3) Select a network on combo box
4) Select the save icon (in the same network line along with edit icon)
4) Select "Save" button in the dialog footer
5) The PUT request will raise the above error.

> |{"storagepool":"/storagepools/ISO","name":"fedora20.1415180417383","cpus":1,"memory":1024,"disks":[{"index"||:0,"size":10}],"graphics":{"type":"vnc"},"networks":["1","dab","default","6","fsdfsdfs"]}|
>
> Could you please give me an access to one of your testing environment 
> so that I can have a better loot at it?
>
>> 2. The "Save" button on footer must be shown only in the General Tab 
>> as Storage and Network Tabs have different save handlers.
>>
> The template is a little bit different from the guest. What we are 
> using for the api is to have all the data including network and the 
> storage information submitted to the server. without clicking the 
> "Save", network and the storage changes won't be updated. "Save" 
> button will update information from all tabs to the server and share 
> the same handler. I can change it to the one that only show in 
> "General" but then we have to send a post of all the information of 
> three tabs to the server every time we add or delete a network and 
> storage. It is less efficient which I would not recommend.

It is confusing for me have 2 save ways: one in a icon form and other 
the Save button on footer.
Is possible to remove the save icon so?

>
> Best Regards
>
> Wang Wen
>>
>> On 11/13/2014 04:47 AM, Wen Wang wrote:
>>> From: Wen Wang<wenwang at linux.vnet.ibm.com>
>>>
>>> V2 -> V3:
>>> Fix the bug that iscsi and scsi disk size won't change automatically
>>>
>>> V1 -> V2:
>>>
>>> 1) Enable "iSCSI" and "SCSI" for storage.
>>> 2) Changed the storage tab from "storage" to "Storage".
>>> 3) Fix the defect that when editing/adding "Storage" or "Interface" line
>>> went down issue.
>>> 4) "Storage" and "Interface" content can display properly on Remote and
>>> Image created template.
>>> 5) Fix the defect that "Image" didn't show properly when using a Image
>>> created template.
>>>
>>> This patch redesigned "Edit Template" diaguage in "Templates". New "Edit
>>> Template" will display all the related information into tabs of
>>> "General", "Storage" and "Interface". Due to unfinished back-end work,
>>> functions are not fully supported, which will be finished in the future
>>> work.
>>>
>>> Temporary disabled functions:
>>> 1) Multiple disk operation with multiple storage pools edit in template
>>> for which reason the add button in "Storage" tab is disabled.
>>> 2) iSCSI and SCSI storage pool add is removed since we are going to
>>> allow this kind of operation in the process of creating a VM.
>>>
>>> Signed-off-by: Wen Wang<wenwang at linux.vnet.ibm.com>
>>> ---
>>>   ui/css/theme-default/template-edit.css |  116 +++++++----
>>>   ui/js/src/kimchi.template_edit_main.js |  366 +++++++++++++++++++++++---------
>>>   ui/pages/template-edit.html.tmpl       |  168 ++++++++-------
>>>   3 files changed, 434 insertions(+), 216 deletions(-)
>>>
>>> diff --git a/ui/css/theme-default/template-edit.css b/ui/css/theme-default/template-edit.css
>>> index 4975f1b..094e909 100644
>>> --- a/ui/css/theme-default/template-edit.css
>>> +++ b/ui/css/theme-default/template-edit.css
>>> @@ -17,24 +17,33 @@
>>>    */
>>>   #template-edit-window {
>>>       font-size: 13px;
>>> -    height: 600px;
>>> -    width: 1000px;
>>> +    height: 500px;
>>> +    width: 800px;
>>>   }
>>>
>>> -.template-edit-fieldset {
>>> -    float: left;
>>> -    padding: 1em;
>>> +#edit-template-tabs {
>>> +    background: none repeat scroll 0 0 transparent;
>>> +    border: medium none;
>>> +    height: 100%;
>>> +    padding: 0;
>>>   }
>>>
>>> -.template-edit-wrapper-label, .template-edit-wrapper-controls {
>>> +#edit-template-tabs .form-template-inline-wrapper {
>>> +    display: inline-block;
>>>       vertical-align: top;
>>> -    width: 470px;
>>>   }
>>>
>>>   .template-edit-wrapper-label {
>>> -    height: 18px;
>>> -    line-height: 18px;
>>> -    margin-top: 8px;
>>> +    vertical-align: top;
>>> +    min-width: 100px;
>>> +    height: 35px;
>>> +    line-height: 35px;
>>> +    margin: 7px 0 8px;
>>> +}
>>> +
>>> +.template-edit-wrapper-controls {
>>> +    vertical-align: top;
>>> +    width: 400px;
>>>   }
>>>
>>>   .template-edit-wrapper-controls input[type="text"] {
>>> @@ -56,7 +65,7 @@
>>>
>>>   .template-edit-wrapper-controls > .dropdown {
>>>       margin: 5px 0 0 1px;
>>> -    width: 440px;
>>> +    width: 372px;
>>>   }
>>>
>>>   .template-edit-wrapper-controls input[type="text"][disabled] {
>>> @@ -65,41 +74,72 @@
>>>       cursor: not-allowed;
>>>   }
>>>
>>> -.hidden-area {
>>> -    display: none;
>>> +#edit-template-tabs .template-tab-header {
>>> +    margin-bottom: 8px;
>>> +    padding-bottom: 2px;
>>> +    font-weight: bold;
>>> +    border-bottom: 1px solid #999999;
>>> +    overflow: hidden;
>>>   }
>>>
>>> -.template-edit-wrapper-controls .select-list-box {
>>> -    width: 464px;
>>> -    max-height: 168px;
>>> -    overflow: auto;
>>> -    margin-top: 5px;
>>> -    border: 1px solid #ccc;
>>> +#edit-template-tabs .template-tab-header .action-area {
>>> +    float: right;
>>> +    height: 20px;
>>> +    width: 20px;
>>>   }
>>>
>>> -.template-edit-wrapper-controls .select-list-box>li>label {
>>> -    display: block;
>>> +#edit-template-tabs .template-interface-cell {
>>> +    display: inline-block;
>>> +    width: 250px;
>>>   }
>>>
>>> -.template-edit-wrapper-controls .select-list-box>li>label>
>>> -input[type="checkbox"] {
>>> -    display: none;
>>> +#edit-template-tabs .template-storage-cell{
>>> +    display: inline-block;
>>> +    width: 230px;
>>> +}
>>> +
>>> +#edit-template-tabs .template-storage-cell label {
>>> +    height: 25px;
>>> +    padding: 2px;
>>> +    border: 1px;
>>>   }
>>>
>>> -.template-edit-wrapper-controls .select-list-box>li>label>.item {
>>> -    display: block;
>>> -    height: 41px;
>>> -    line-height: 41px;
>>> -    padding: 0 20px 0 40px;
>>> -    border-bottom: 1px solid #ccc;
>>> -    box-shadow: 0px 1px 1px #fff;
>>> -    text-shadow: -1px -1px 1px #ddd, 1px 1px 1px #fff;
>>> -    color: #222;
>>> -    font-size: 12px;
>>> +#form-template-storage .template-tab-body select {
>>> +    width: 140px;
>>>   }
>>>
>>> -.template-edit-wrapper-controls .select-list-box>li>label>
>>> -input[type="checkbox"]:CHECKED+.item {
>>> -    background: #f8f8f8 url(../images/theme-default/check-green.png) no-repeat
>>> -                10px center;
>>> +#form-template-storage .template-tab-body input {
>>> +    width: 56px;
>>> +    height: 17px;
>>>   }
>>> +
>>> +#form-template-storage .template-tab-body .template-storage-name {
>>> +    width: 220px;
>>> +}
>>> +
>>> +#edit-template-tabs .template-tab-body input[readonly] {
>>> +    background: none repeat scroll 0 0 rgba(0, 0, 0, 0);
>>> +    border-color: transparent;
>>> +    text-overflow: ellipsis;
>>> +}
>>> +
>>> +#edit-template-tabs .template-tab-body .item {
>>> +    height: 25px;
>>> +}
>>> +
>>> +#form-template-interface .template-tab-body select {
>>> +    width: 180px;
>>> +}
>>> +
>>> +#edit-template-tabs .template-tab-body .action-area {
>>> +    float: right;
>>> +}
>>> +
>>> +#edit-template-tabs .template-tab-body .action-area button {
>>> +    width: 20px;
>>> +    height: 20px;
>>> +}
>>> +
>>> +#edit-template-tabs .hide {
>>> +    display: none;
>>> +}
>>> \ No newline at end of file
>>> diff --git a/ui/js/src/kimchi.template_edit_main.js b/ui/js/src/kimchi.template_edit_main.js
>>> index 2f4cc9a..5073c62 100644
>>> --- a/ui/js/src/kimchi.template_edit_main.js
>>> +++ b/ui/js/src/kimchi.template_edit_main.js
>>> @@ -16,19 +16,23 @@
>>>    * limitations under the License.
>>>    */
>>>   kimchi.template_edit_main = function() {
>>> -    var templateEditForm = $('#form-template-edit');
>>> +    var templateEditMain = $('#edit-template-tabs');
>>>       var origDisks;
>>>       var origPool;
>>> +    var origNetworks;
>>>       var templateDiskSize;
>>> -    $('#template-name', templateEditForm).val(kimchi.selectedTemplate);
>>> -    kimchi.retrieveTemplate(kimchi.selectedTemplate, function(template) {
>>> +    $('#template-name', templateEditMain).val(kimchi.selectedTemplate);
>>> +    templateEditMain.tabs();
>>> +
>>> +    var initTemplate = function(template) {
>>>           origDisks =  template.disks;
>>>           origPool = template.storagepool;
>>> +        origNetworks = template.networks;
>>>           for(var i=0;i<template.disks.length;i++){
>>>               if(template.disks[i].base){
>>>                   template["vm-image"] = template.disks[i].base;
>>> -                $('#templ-edit-cdrom').addClass('hide-content');
>>> -                $('#templ-edit-vm-image').removeClass('hide-content');
>>> +                $('.templ-edit-cdrom').addClass('hide');
>>> +                $('.templ-edit-vm-image').removeClass('hide');
>>>                   break;
>>>               }
>>>           }
>>> @@ -37,18 +41,12 @@ kimchi.template_edit_main = function() {
>>>               if (prop == 'graphics') {
>>>                  value = value["type"];
>>>               }
>>> -            $('input[name="' + prop + '"]', templateEditForm).val(value);
>>> -        }
>>> -        var disks = template.disks;
>>> -        $('input[name="disks"]').val(disks[0].size);
>>> -        templateDiskSize = $('input[name="disks"]').val();
>>> -        if (disks[0].volume) {
>>> -            var spool_value = $('#form-template-edit [name="storagepool"]').val();
>>> -            $('input[name="storagepool"]', templateEditForm).val(spool_value + '/' + disks[0].volume);
>>> -            $('input[name="disks"]', templateEditForm).attr('disabled','disabled');
>>> +            $('input[name="' + prop + '"]', templateEditMain).val(value);
>>>           }
>>>
>>>           var vncOpt = [{label: 'VNC', value: 'vnc'}];
>>> +        $('#template-edit-graphics').append('<option selected>VNC</option>');
>>> +        $('#template-edit-graphics').append('<option>Spice</option>');
>>>           kimchi.select('template-edit-graphics-list', vncOpt);
>>>           var enableSpice = function() {
>>>               if (kimchi.capabilities == undefined) {
>>> @@ -61,119 +59,283 @@ kimchi.template_edit_main = function() {
>>>               }
>>>           };
>>>           enableSpice();
>>> -
>>> -        var scsipools = {};
>>> -        kimchi.listStoragePools(function(result) {
>>> -            var options = [];
>>> -            if (result && result.length) {
>>> -                $.each(result, function(index, storagePool) {
>>> -                    if ((storagePool.state=="active") && (storagePool.type !== 'kimchi-iso')) {
>>> -                        if ((storagePool.type == 'iscsi') || (storagePool.type == 'scsi')){
>>> -                            scsipools[storagePool.name] = [];
>>> -                            kimchi.listStorageVolumes(storagePool.name, function(result) {
>>> -                                if (result && result.length) {
>>> -                                    $.each(result, function(index, storageVolume) {
>>> -                                        options.push({
>>> -                                            label: storagePool.name + '/' + storageVolume.name,
>>> -                                            value: '/storagepools/' + storagePool.name + '/' + storageVolume.name
>>> -                                        });
>>> -                                        scsipools[storagePool.name].push(storageVolume)
>>> -                                    });
>>> -                                }
>>> -                                kimchi.select('template-edit-storagePool-list', options);
>>> -                            });
>>> -                        }
>>> -                        else {
>>> -                            options.push({
>>> -                                label: storagePool.name,
>>> -                                value: '/storagepools/' + storagePool.name
>>> -                            });
>>> -                        }
>>> +        var initStorage = function(result) {
>>> +            var scsipools = {};
>>> +            var addStorageItem = function(storageData) {
>>> +                var thisName;
>>> +                var thisType;
>>> +                var thisDisk;
>>> +                var nodeStorage = $.parseHTML(kimchi.substitute($('#template-storage-pool-tmpl').html(), storageData));
>>> +                $('.template-tab-body', '#form-template-storage').append(nodeStorage);
>>> +                $('.edit', '#form-template-storage').button({
>>> +                    icons : {primary : 'ui-icon-pencil'},
>>> +                    text : false
>>> +                }).click(function(evt) {
>>> +                    evt.preventDefault();
>>> +                    var storageItem = $(this).parent().parent();
>>> +                    thisName = $('.template-storage-name', storageItem).val();
>>> +                    thisType = $('.template-storage-type', storageItem).val();
>>> +                    thisDisk = $('.template-storage-disk', storageItem).val();
>>> +                    $('.template-storage-name', storageItem).hide();
>>> +                    $('.template-storage-disk', storageItem).attr('readonly', false);
>>> +                    if (thisType === 'iscsi' || thisType === 'scsi') {
>>> +                        $('.template-storage-disk', storageItem).attr('readonly', true);
>>> +                    } else {
>>> +                        $('.template-storage-disk', storageItem).attr('readonly', false);
>>>                       }
>>> +                    $('.save', storageItem).parent().show();
>>> +                    $('.delete', storageItem).parent().hide();
>>> +                    var selectedStorage = $('select', storageItem).val();
>>> +                    $('.template-storage-name', storageItem).val(selectedStorage).hide();
>>> +                    $('select', storageItem).val(thisName).show();
>>>                   });
>>> -            }
>>> -            if ($.isEmptyObject(scsipools)) {
>>> -                kimchi.select('template-edit-storagePool-list', options);
>>> -            }
>>> -        });
>>> -        kimchi.listNetworks(function(result) {
>>> -            if(result && result.length > 0) {
>>> -                var html = '';
>>> -                var tmpl = $('#tmpl-network').html();
>>> -                $.each(result, function(index, network) {
>>> -                    if (result[index].state === 'active')
>>> -                        html += kimchi.substitute(tmpl, network);
>>> +                $('.delete', '#form-template-storage').button({
>>> +                    icons : {primary : 'ui-icon-trash'},
>>> +                    text : false
>>> +                }).click(function(evt) {
>>> +                    evt.preventDefault();
>>> +                    $(this).parent().parent().remove();
>>> +                });
>>> +                $('.cancel', '#form-template-storage').button({
>>> +                    icons : {primary : 'ui-icon-arrowreturnthick-1-w'},
>>> +                    text : false
>>> +                }).click(function(evt) {
>>> +                    evt.preventDefault();
>>> +                    var cancelEntity = $(this).parent().parent();
>>> +                    if ($('.template-storage-name', cancelEntity).val() === 'null') {
>>> +                        cancelEntity.remove();
>>> +                    } else {
>>> +                        $('select', cancelEntity).hide();
>>> +                        $('.template-storage-name', cancelEntity).val(thisName).attr('readonly', true).show();
>>> +                        $('.template-storage-type', cancelEntity).val(thisType).attr('readonly', true);
>>> +                        $('.template-storage-disk', cancelEntity).val(thisDisk).attr('readonly', true);
>>> +                        $('.save', cancelEntity).parent().hide();
>>> +                        $('.edit', cancelEntity).parent().show();
>>> +                    }
>>> +                });
>>> +                $('.save', '#form-template-storage').button({
>>> +                    icons : {primary : 'ui-icon-disk'},
>>> +                    text : false
>>> +                }).click(function(evt) {
>>> +                    evt.preventDefault();
>>> +                    var storageItem = $(this).parent().parent();
>>> +                    $('.save', storageItem).parent().hide();
>>> +                    $('.delete', storageItem).parent().show();
>>> +                    var selectedStorage = $('select', storageItem).val();
>>> +                    $('.template-storage-name', storageItem).val(selectedStorage).attr('readonly', true).show();
>>> +                    $('.template-storage-disk', storageItem).attr('readonly', true);
>>> +                    $('.template-storage-type', storageItem).attr('readonly', true);
>>> +                    $('select', storageItem).hide();
>>>                   });
>>> -                $('#template-edit-network-list').html(html).show();
>>> -                if(template.networks && template.networks.length > 0) {
>>> -                    $('input[name="networks"]', templateEditForm).each(function(index, element) {
>>> -                        var value = $(element).val();
>>> -                        if(template.networks.indexOf(value) >= 0) {
>>> -                            $(element).prop('checked', true);
>>> +                var storageOptions = '';
>>> +                var scsiOptions = '';
>>> +                $('select', '#form-template-storage').find('option').remove();
>>> +                $.each(result, function(index, storageEntities) {
>>> +                    if((storageEntities.state === 'active') && (storageEntities.type != 'kimchi-iso')) {
>>> +                        if(storageEntities.type === 'iscsi' || storageEntities.type === 'scsi') {
>>> +                            kimchi.listStorageVolumes(storageEntities.name, function(currentVolume) {
>>> +                                $.each(currentVolume, function(indexSCSI, scsiEntities) {
>>> +                                    scsiOptions += '<option>' + storageEntities.name + '/' + scsiEntities.name + '</option>';
>>> +                                });
>>> +                                $('select', '#form-template-storage').append(scsiOptions);
>>> +                            }, function() {});
>>> +                        } else {
>>> +                            var isSlected = storageEntities.name === 'default' ? ' selected' : '';
>>> +                            storageOptions += '<option' + isSlected + '>' + storageEntities.name + '</option>';
>>> +                        }
>>> +                    }
>>> +                });
>>> +                $('select', '#form-template-storage').append(storageOptions);
>>> +                $('select', '#form-template-storage').change(function() {
>>> +                    var selectedItem = $(this).parent().parent();
>>> +                    var tempStorageName = $(this).val();
>>> +                    var tempType;
>>> +                    tempStorageName =tempStorageName.split('/')[0];
>>> +                    var scsiCap;
>>> +                    $.each(result, function(index, storageEntities) {
>>> +                        if (tempStorageName === storageEntities.name) {
>>> +                            selectedItem.find('.template-storage-type').val(storageEntities.type);
>>> +                            scsiCap = storageEntities.capacity / Math.pow(1024, 3);
>>> +                            tempType = storageEntities.type;
>>>                           }
>>>                       });
>>> +                    if (tempType === 'iscsi' || tempType === 'scsi') {
>>> +                        $('.template-storage-disk', selectedItem).attr('readonly', true).val(scsiCap);
>>> +                    } else {
>>> +                        $('.template-storage-disk', selectedItem).attr('readonly', false).val('10');
>>> +                    }
>>> +                });
>>> +            };
>>> +
>>> +            if ((origDisks && origDisks.length) && (origPool && origPool.length)) {
>>> +                splitPool = origPool.split('/');
>>> +                var defaultPool;
>>> +                var defaultType;
>>> +                $.each(result, function(index, poolEntities) {
>>> +                    if (poolEntities.name === splitPool[splitPool.length-1]) {
>>> +                        defaultType = poolEntities.type;
>>> +                        defaultPool = splitPool[splitPool.length-1]
>>> +                    }
>>> +                });
>>> +                if (origDisks[0]['volume']) {
>>> +                    defaultPool = defaultPool + '/' + origDisks[0]['volume'];
>>>                   }
>>> -            } else {
>>> -                $('#template-edit-network-list').hide();
>>> +                $.each(origDisks, function(index, diskEntities) {
>>> +                    var storageNodeData = {
>>> +                        viewMode : '',
>>> +                        editMode : 'hide',
>>> +                        storageName : defaultPool,
>>> +                        storageType : defaultType,
>>> +                        storageDisk : diskEntities.size
>>> +                    }
>>> +                    addStorageItem(storageNodeData);
>>> +                });
>>> +                $('.template-storage-disk').attr('readonly', true);
>>>               }
>>> -        });
>>> -    });
>>>
>>> -    $('#template-edit-storagePool').change(function() {
>>> -        storagepool = $(this).val();
>>> -        var storageArray = storagepool.split("/");
>>> -        if (storageArray.length > 3) {
>>> -            volumeName = storageArray.pop();
>>> -            poolName = storageArray.pop();
>>> -            kimchi.getStoragePoolVolume(poolName, volumeName, function(result) {
>>> -                $('input[name="disks"]', templateEditForm).val(result.capacity / Math.pow(1024,3));
>>> -                $('input[name="disks"]', templateEditForm).attr('disabled','disabled');
>>> -                return false;
>>> -            }, function (err) {
>>> -                kimchi.message.error(err.responseJSON.reason);
>>> +            $('#template-edit-storage-add-button').button({
>>> +                icons: {
>>> +                    primary: "ui-icon-plusthick"
>>> +                },
>>> +                text: false,
>>> +                disabled: true
>>> +            }).click(function(event) {
>>> +                event.preventDefault();
>>> +                var storageNodeData = {
>>> +                    viewMode : 'hide',
>>> +                    editMode : '',
>>> +                    storageName : 'null',
>>> +                    storageType : 'dir',
>>> +                    storageDisk : '10'
>>> +                }
>>> +                addStorageItem(storageNodeData);
>>>               });
>>> -        } else {
>>> -            $('input[name="disks"]', templateEditForm).removeAttr('disabled');
>>> -            $('input[name="disks"]', templateEditForm).val(templateDiskSize);
>>> -        }
>>> -    });
>>> -    $('input[name="disks"]', templateEditForm).keyup(function() {
>>> -        templateDiskSize = $('input[name="disks"]', templateEditForm).val();
>>> -    });
>>> +        };
>>> +        var initInterface = function(result) {
>>> +            var addInterfaceItem = function(networkData) {
>>> +                var nodeInterface = $.parseHTML(kimchi.substitute($('#template-interface-tmpl').html(), networkData));
>>> +                $('.template-tab-body', '#form-template-interface').append(nodeInterface);
>>> +                $('.edit', '#form-template-interface').button({
>>> +                    icons : {primary : 'ui-icon-pencil'},
>>> +                    text : false,
>>> +                    disabled : true
>>> +                });
>>> +                $('.delete', '#form-template-interface').button({
>>> +                    icons : {primary : 'ui-icon-trash'},
>>> +                    text : false
>>> +                }).click(function(evt) {
>>> +                    evt.preventDefault();
>>> +                    $(this).parent().parent().remove();
>>> +                });
>>> +                $('.cancel', '#form-template-interface').button({
>>> +                    icons : {primary : 'ui-icon-arrowreturnthick-1-w'},
>>> +                    text : false
>>> +                }).click(function(evt) {
>>> +                    evt.preventDefault();
>>> +                    $(this).parent().parent().remove();
>>> +                });
>>> +                $('.save', '#form-template-interface').button({
>>> +                    icons : {primary : 'ui-icon-disk'},
>>> +                    text : false
>>> +                }).click(function(evt) {
>>> +                    evt.preventDefault();
>>> +                    var interItem = $(this).parent().parent();
>>> +                    $('.save', interItem).parent().hide();
>>> +                    $('.delete', interItem).parent().show();
>>> +                    var selectedInterface = $('select', interItem).val();
>>> +                    $('.template-interface-name', interItem).val(selectedInterface).show();
>>> +                    $('select', interItem).hide();
>>> +                });
>>> +                var networkOptions = '';
>>> +                for(var i=0;i<result.length;i++){
>>> +                    if(result[i].state === "active") {
>>> +                        var isSlected = i==0 ? ' selected' : '';
>>> +                        networkOptions += '<option' + isSlected + '>' + result[i].name + '</option>';
>>> +                    }
>>> +                }
>>> +                $('select', '#form-template-interface').find('option').remove();
>>> +                $('select', '#form-template-interface').append(networkOptions);
>>> +            };
>>> +            if(result && result.length > 0) {
>>> +                $.each(result, function(index, data) {
>>> +                    if($.inArray(data.name, origNetworks) > -1) {
>>> +                        addInterfaceItem({
>>> +                            mac : '',
>>> +                            network : data.name,
>>> +                            type : 'network',
>>> +                            viewMode : '',
>>> +                            editMode : 'hide'
>>> +                        });
>>> +                    }
>>> +                });
>>> +            }
>>> +            $('#template-edit-interface-add-button').button({
>>> +                icons: {
>>> +                    primary: 'ui-icon-plusthick'
>>> +                },
>>> +                text: false
>>> +            }).click(function(evt) {
>>> +                evt.preventDefault();
>>> +                addInterfaceItem({
>>> +                    mac : '',
>>> +                    network : '',
>>> +                    type : 'network',
>>> +                    viewMode : 'hide',
>>> +                    editMode : ''
>>> +                });
>>> +            });
>>> +        };
>>> +        kimchi.listNetworks(initInterface);
>>> +        kimchi.listStoragePools(initStorage);
>>> +    };
>>> +    kimchi.retrieveTemplate(kimchi.selectedTemplate, initTemplate);
>>> +
>>>
>>>       $('#tmpl-edit-button-save').on('click', function() {
>>> -        var editableFields = [ 'name', 'cpus', 'memory', 'storagepool', 'disks', 'graphics'];
>>> +        var editableFields = [ 'name', 'cpus', 'memory', 'disks', 'graphics'];
>>>           var data = {};
>>> +        //Fix me: Only support one storage pool now
>>> +        var storages = $('.template-tab-body .item', '#form-template-storage');
>>> +        var tempName = $('.template-storage-name', storages).val();
>>> +        tempName = tempName.split('/');
>>> +        var tempNameHead =tempName[0];
>>> +        var tempNameTail = tempNameHead;
>>> +        if(tempNameHead === 'iscsi' || tempNameHead =='scsi') {
>>> +            tempNameTail = tempName[tempName.length-1];
>>> +        }
>>> +        tempName = '/storagepools/' + tempNameHead;
>>> +        data['storagepool'] = tempName;
>>>           $.each(editableFields, function(i, field) {
>>>               /* Support only 1 disk at this moment */
>>>               if (field == 'disks') {
>>> -               origDisks[0].size = Number($('#form-template-edit [name="' + field + '"]').val());
>>> +                var tmpItem = $('#form-template-storage .item');
>>> +                origDisks[0].size = Number($('.template-storage-disk', tmpItem).val());
>>> +                if($('.template-storage-type', tmpItem).val() === 'iscsi' || $('.template-storage-type', tmpItem).val() =='scsi') {
>>> +                    origDisks[0]['volume'] = tempNameTail;
>>> +                } else {
>>> +                    origDisks[0]['volume'] && delete origDisks[0]['volume'];
>>> +                }
>>>                  data[field] = origDisks;
>>>               }
>>>               else if (field == 'graphics') {
>>> -               var type = $('#form-template-edit [name="' + field + '"]').val();
>>> +               var type = $('#form-template-general [name="' + field + '"]').val();
>>>                  data[field] = {'type': type};
>>>               }
>>>               else {
>>> -               data[field] = $('#form-template-edit [name="' + field + '"]').val();
>>> +               data[field] = $('#form-template-general [name="' + field + '"]').val();
>>>               }
>>>           });
>>>           data['memory'] = Number(data['memory']);
>>>           data['cpus']   = Number(data['cpus']);
>>> -        storagepool = data['storagepool'];
>>> -        storageArray = storagepool.split("/");
>>> -        if (storageArray.length > 3){
>>> -            /* Support only 1 disk at this moment */
>>> -            data["disks"][0].volume = storageArray.pop();
>>> -            data['storagepool'] = storageArray.join("/");
>>> -        } else if (data["disks"][0].volume) {
>>> -            delete data["disks"][0].volume;
>>> -        }
>>> -        var networks = templateEditForm.serializeObject().networks;
>>> -        if (networks instanceof Array) {
>>> -            data.networks = networks;
>>> -        } else if (networks != null) {
>>> -            data.networks = [networks];
>>> +        var networks = $('.template-tab-body .item', '#form-template-interface');
>>> +        var networkForUpdate = new Array();
>>> +        $.each(networks, function(index, networkEntities) {
>>> +            networkForUpdate.push($('.template-interface-name', networkEntities).val());
>>> +        });
>>> +        if (networkForUpdate instanceof Array) {
>>> +            data.networks = networkForUpdate;
>>> +        } else if (networkForUpdate != null) {
>>> +            data.networks = [networkForUpdate];
>>>           } else {
>>>               data.networks = [];
>>>           }
>>> diff --git a/ui/pages/template-edit.html.tmpl b/ui/pages/template-edit.html.tmpl
>>> index 5a71d91..018ac10 100644
>>> --- a/ui/pages/template-edit.html.tmpl
>>> +++ b/ui/pages/template-edit.html.tmpl
>>> @@ -28,74 +28,67 @@
>>>           <div class="close">X</div>
>>>       </header>
>>>       <div class="content">
>>> -        <form id="form-template-edit">
>>> +        <div id="edit-template-tabs">
>>>               <input type="hidden" id="template-name" name="templateName" />
>>> -            <fieldset class="template-edit-fieldset">
>>> -                <div>
>>> +            <ul>
>>> +                <li>
>>> +                    <a href="#form-template-general">$_("General")</a>
>>> +                </li>
>>> +                <li>
>>> +                    <a href="#form-template-storage">$_("Storage")</a>
>>> +                </li>
>>> +                <li>
>>> +                    <a href="#form-template-interface">$_("Interface")</a>
>>> +                </li>
>>> +            </ul>
>>> +            <form id="form-template-general">
>>> +                <div class="form-template-inline-wrapper">
>>>                       <div class="template-edit-wrapper-label">
>>>                           <label for="template-edit-id-textbox">$_("Name")</label>
>>>                       </div>
>>> -                    <div class="template-edit-wrapper-controls">
>>> -                        <input id="template-edit-id-textbox" name="name" type="text" />
>>> -                    </div>
>>> -                </div>
>>> -                <div>
>>>                       <div class="template-edit-wrapper-label">
>>>                           <label for="template-edit-vendor-textbox">$_("Vendor")</label>
>>>                       </div>
>>> -                    <div class="template-edit-wrapper-controls">
>>> -                        <input id="template-edit-vendor-textbox" name="os_distro" type="text" disabled="disabled" />
>>> -                    </div>
>>> -                </div>
>>> -                <div>
>>>                       <div class="template-edit-wrapper-label">
>>>                           <label for="template-edit-version-textbox">$_("Version")</label>
>>>                       </div>
>>> -                    <div class="template-edit-wrapper-controls">
>>> -                        <input id="template-edit-version-textbox" name="os_version" type="text" disabled="disabled" />
>>> -                    </div>
>>> -                </div>
>>> -                <div>
>>>                       <div class="template-edit-wrapper-label">
>>>                           <label for="template-edit-cpu-textbox">$_("CPU Number")</label>
>>>                       </div>
>>> -                    <div class="template-edit-wrapper-controls">
>>> -                        <input id="template-edit-cpu-textbox" name="cpus" type="text" />
>>> -                    </div>
>>> -                </div>
>>> -                <div>
>>>                       <div class="template-edit-wrapper-label">
>>>                           <label for="template-edit-memory-textbox">$_("Memory (MB)")</label>
>>>                       </div>
>>> -                    <div class="template-edit-wrapper-controls">
>>> -                        <input id="template-edit-memory-textbox" name="memory" type="text" />
>>> +                    <div class="template-edit-wrapper-label templ-edit-cdrom">
>>> +                        <label for="template-edit-cdrom-textbox">$_("CDROM")</label>
>>> +                    </div>
>>> +                    <div class="template-edit-wrapper-label templ-edit-vm-image hide">
>>> +                        <label for="template-edit-vmimage-textbox">$_("Image File")</label>
>>>                       </div>
>>> -                </div>
>>> -                <div>
>>>                       <div class="template-edit-wrapper-label">
>>> -                        <label for="template-edit-disk-textbox">$_("Disk (GB)")</label>
>>> +                        <label>$_("Graphics")</label>
>>>                       </div>
>>> +                </div>
>>> +                <div class="form-template-inline-wrapper">
>>>                       <div class="template-edit-wrapper-controls">
>>> -                        <input id="template-edit-disk-textbox" name="disks" type="text" />
>>> +                        <input id="template-edit-id-textbox" name="name" type="text" />
>>>                       </div>
>>> -                </div>
>>> -            </fieldset>
>>> -            <fieldset class="template-edit-fieldset">
>>> -                <div id="templ-edit-cdrom">
>>> -                    <div class="template-edit-wrapper-label">
>>> -                        <label for="template-edit-cdrom-textbox">$_("CDROM")</label>
>>> +                    <div class="template-edit-wrapper-controls">
>>> +                        <input id="template-edit-vendor-textbox" name="os_distro" type="text" disabled="disabled" />
>>>                       </div>
>>>                       <div class="template-edit-wrapper-controls">
>>> -                        <input id="template-edit-cdrom-textbox" name="cdrom" type="text" disabled="disabled"/>
>>> +                        <input id="template-edit-version-textbox" name="os_version" type="text" disabled="disabled" />
>>>                       </div>
>>> -                </div>
>>> -                <div id="templ-edit-vm-image" class="hide-content">
>>> -                    <div class="template-edit-wrapper-label">$_("Image File")</div>
>>> -                    <div class="template-edit-wrapper-controls"><input name="vm-image" type="text" disabled/></div>
>>> -                </div>
>>> -                <div>
>>> -                    <div class="template-edit-wrapper-label">
>>> -                        <label>$_("Graphics")</label>
>>> +                    <div class="template-edit-wrapper-controls">
>>> +                        <input id="template-edit-cpu-textbox" name="cpus" type="text" />
>>> +                    </div>
>>> +                    <div class="template-edit-wrapper-controls">
>>> +                        <input id="template-edit-memory-textbox" name="memory" type="text" />
>>> +                    </div>
>>> +                    <div class="template-edit-wrapper-controls templ-edit-cdrom">
>>> +                        <input id="template-edit-cdrom-textbox" name="cdrom" type="text" disabled="disabled" />
>>> +                    </div>
>>> +                    <div class="template-edit-wrapper-controls templ-edit-vm-image hide">
>>> +                        <input id="template-edit-vmimage-textbox" name="vm-image" type="text" disabled="disabled" />
>>>                       </div>
>>>                       <div class="template-edit-wrapper-controls">
>>>                           <div class="btn dropdown popable">
>>> @@ -108,40 +101,26 @@
>>>                           </div>
>>>                       </div>
>>>                   </div>
>>> -                <div>
>>> -                    <div class="template-edit-wrapper-label">
>>> -                        <label>$_("Storage Pool")</label>
>>> -                    </div>
>>> -                    <div class="template-edit-wrapper-controls">
>>> -                        <div class="btn dropdown popable">
>>> -                            <input id="template-edit-storagePool" name="storagepool" type="hidden" />
>>> -                            <span class="text" id="template-edit-storage-label"></span><span class="arrow"></span>
>>> -                            <div class="popover" style="width: 100%">
>>> -                                <ul class="select-list" id="template-edit-storagePool-list" data-target="template-edit-storagePool" data-label="template-edit-storage-label">
>>> -                                </ul>
>>> -                            </div>
>>> -                        </div>
>>> -                    </div>
>>> +            </form>
>>> +            <form id="form-template-storage">
>>> +                <div class="template-tab-header">
>>> +                    <span class="template-storage-cell">$_("Storage Pool")</span>
>>> +                    <span class="template-storage-cell">$_("Type")</span>
>>> +                    <span class="template-storage-cell">$_("Disk(GB)")</span>
>>> +                    <button type="button" id="template-edit-storage-add-button" class="action-area"></button>
>>>                   </div>
>>> -                <div>
>>> -                    <div class="template-edit-wrapper-label">
>>> -                        <label>$_("Network")</label>
>>> -                    </div>
>>> -                    <div class="template-edit-wrapper-controls">
>>> -                        <ul class="select-list-box" id="template-edit-network-list">
>>> -                        </ul>
>>> -                        <script id="tmpl-network" type="text/html">
>>> -                            <li>
>>> -                                <label>
>>> -                                    <input name="networks" type="checkbox" value="{name}" />
>>> -                                    <span class="item">{name}</span>
>>> -                                </label>
>>> -                            </li>
>>> -                        </script>
>>> -                    </div>
>>> +                <div class="template-tab-body">
>>>                   </div>
>>> -            </fieldset>
>>> -        </form>
>>> +            </form>
>>> +            <form id="form-template-interface">
>>> +                <div class="template-tab-header">
>>> +                    <span class="template-interface-cell">$_("Network")</span>
>>> +                    <span class="template-interface-cell">$_("Type")</span>
>>> +                    <button type="button" id="template-edit-interface-add-button" class="action-area"></button>
>>> +                </div>
>>> +                <div class="template-tab-body"></div>
>>> +            </form>
>>> +        </div>
>>>       </div>
>>>       <footer>
>>>           <div class="btn-group">
>>> @@ -152,3 +131,40 @@
>>>   <script>
>>>       kimchi.template_edit_main();
>>>   </script>
>>> +<script id="template-storage-pool-tmpl" type="text/html">
>>> +    <div class='item'>
>>> +        <span class="template-storage-cell">
>>> +            <input class="template-storage-name {viewMode}" value={storageName} readonly=true type="text"/>
>>> +            <select class="{editMode}"></select>
>>> +        </span>
>>> +        <span class="template-storage-cell">
>>> +            <input class="template-storage-type" value={storageType} readonly=true type="text" />
>>> +        </span>
>>> +        <span class="template-storage-cell">
>>> +            <input class="template-storage-disk" value={storageDisk} type="text" />
>>> +        </span>
>>> +        <span class="action-area {editMode}">
>>> +            <button class="save"></button><button class="cancel"></button>
>>> +        </span>
>>> +        <span class="action-area {viewMode}">
>>> +            <button class="edit"></button><button class="delete"></button>
>>> +        </span>
>>> +    </div>
>>> +</script>
>>> +<script id="template-interface-tmpl" type="text/html">
>>> +    <div class="item">
>>> +        <span class="template-interface-cell">
>>> +            <input class="template-interface-name {viewMode}" readonly="true" type="text"  value={network} />
>>> +            <select class="{editMode}"></select>
>>> +        </span>
>>> +        <span class="template-interface-cell">
>>> +            <input value={type} readonly=true type="text" />
>>> +        </span>
>>> +        <span class="action-area {editMode}">
>>> +            <button class="save"></button><button class="cancel"></button>
>>> +        </span>
>>> +        <span class="action-area {viewMode}">
>>> +            <button class="edit"></button><button class="delete"></button>
>>> +        </span>
>>> +    </div>
>>> +</script>
>>> \ No newline at end of file
>>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ovirt.org/pipermail/kimchi-devel/attachments/20141117/af48d958/attachment.html>


More information about the Kimchi-devel mailing list