[Kimchi-devel] [V2] UI: List iSCSI Servers & Targets

Aline Manera alinefm at linux.vnet.ibm.com
Thu Aug 28 18:27:30 UTC 2014


The UI looks good but the combo box style differs from others.
Usually the combo box has a blue border and have a green checked in the 
select item.

Some comments below:

On 08/28/2014 07:24 AM, huoyuxin at linux.vnet.ibm.com wrote:
> From: Yu Xin Huo <huoyuxin at linux.vnet.ibm.com>
>
> Signed-off-by: Yu Xin Huo <huoyuxin at linux.vnet.ibm.com>
> ---
>   ui/css/theme-default/storage.css         |   69 +++++++++++++++++++++-
>   ui/js/src/kimchi.api.js                  |   30 ++++++++++
>   ui/js/src/kimchi.storagepool_add_main.js |   94 ++++++++++++++++++++++++++++++
>   ui/pages/storagepool-add.html.tmpl       |   12 +++-
>   4 files changed, 201 insertions(+), 4 deletions(-)
>
> diff --git a/ui/css/theme-default/storage.css b/ui/css/theme-default/storage.css
> index 4f439e8..1b71d82 100644
> --- a/ui/css/theme-default/storage.css
> +++ b/ui/css/theme-default/storage.css
> @@ -315,7 +315,7 @@
>   }
>
>   .hide-content {
> -    display: none;
> +    display: none!important;
>   }
>
>   .volumeslist {
> @@ -593,3 +593,70 @@
>                   center no-repeat;
>       padding: 0 20px 0 26px;
>   }
> +
> +.storage-admin .filter-select {
> +    display: inline-block;
> +    position: relative;
> +}
> +
> +#iscsiportId, .storage-admin .filter-select input {
> +    border: 1px solid #CCCCCC;
> +    border-radius: 1px;
> +    font-size: 14px;
> +    padding: 3px 3px 3px 10px;
> +    height: 30px;
> +}
> +
> +.storage-admin .filter-select input::-ms-clear {
> +    display: none;
> +}
> +
> +.storage-admin .filter-select .arrow {
> +    display: inline-block;
> +    vertical-align: middle;
> +    position: relative;
> +    left: -25px;
> +}
> +
> +.storage-admin .filter-select .option {
> +    border-style: solid;
> +    border-color: #CCCCCC;
> +    border-width: 0px 1px 1px 1px;
> +    border-radius: 1px;
> +    font-size: 14px;
> +    background-color: white;
> +    max-height: 140px;
> +    overflow: auto;
> +    color: #666666;
> +    position: absolute;
> +    z-index: 1000;
> +}
> +
> +.storage-admin .filter-select .option .item {
> +    padding: 5px 10px;
> +    cursor: pointer;
> +}
> +
> +.storage-admin .filter-select .option .item:hover {
> +    background-color: #DDDDDD;
> +}
> +
> +#iSCSIServer input {
> +    width: 410px;
> +}
> +
> +#iSCSIServer .option {
> +    width: 423px;
> +}
> +
> +#iscsiportId {
> +    width: 60px;
> +}
> +
> +#iSCSITarget input {
> +    width: 493px;
> +}
> +
> +#iSCSITarget .option {
> +    width: 506px;
> +}
> diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
> index 4562992..9de1b08 100644
> --- a/ui/js/src/kimchi.api.js
> +++ b/ui/js/src/kimchi.api.js
> @@ -1098,5 +1098,35 @@ var kimchi = {
>                   kimchi.message.error(data.responseJSON.reason);
>               }
>           });
> +    },
> +
> +    getISCSIServers : function(suc, err) {
> +        kimchi.requestJSON({
> +            url : kimchi.url + 'storageservers?_target_type=iscsi',
> +            type : 'GET',
> +            contentType : 'application/json',
> +            dataType : 'json',
> +            resend : true,
> +            success : suc,
> +            error : err ? err : function(data) {
> +                kimchi.message.error(data.responseJSON.reason);
> +            }
> +        });
> +    },
> +


There is a function in kimchi.api.js named getStorageServers():

getStorageServers: function(type, suc, err) {
}

You just need to pass the type, ie, netfs or iscsi

For this case it would be getStorageServers("iscsi", ...)

> +    getISCSITargets : function(server, port, suc, err) {
> +        server = encodeURIComponent(server);
> +        port = encodeURIComponent(port);
> +        kimchi.requestJSON({
> +            url : kimchi.url + 'storageservers/'+server+'/storagetargets?_target_type=iscsi&_server_port='+port,
> +            type : 'GET',
> +            contentType : 'application/json',
> +            dataType : 'json',
> +            resend : true,
> +            success : suc,
> +            error : err ? err : function(data) {
> +                kimchi.message.error(data.responseJSON.reason);
> +            }
> +        });
>       }
>   };
> diff --git a/ui/js/src/kimchi.storagepool_add_main.js b/ui/js/src/kimchi.storagepool_add_main.js
> index ecbc682..affb714 100644
> --- a/ui/js/src/kimchi.storagepool_add_main.js
> +++ b/ui/js/src/kimchi.storagepool_add_main.js
> @@ -34,6 +34,96 @@ kimchi.storagepool_add_main = function() {
>       });
>   };
>
> +kimchi.storageFilterSelect = function(id, isUpdate) {
> +    var input = $('input', '#'+id);
> +    var options = $(".option", '#'+id);
> +    $('.arrow', '#'+id).toggleClass("hide-content", options.children().length==0);
> +    var filter = function(container, key){
> +        container.children().each(function(){
> +            $(this).css("display", $(this).text().indexOf(key)==-1 ? "none" : "");
> +        });
> +    };
> +    if(!isUpdate){
> +        $('.arrow', '#'+id).click(function(){
> +            options.toggleClass("hide-content");
> +        });
> +        input.focus(function(){
> +            options.removeClass("hide-content");
> +        }).on("keyup", function(){
> +            filter(options, input.val());
> +        });
> +    }
> +    options.children().each(function(){
> +        $(this).click(function(){
> +            input.val($(this).text());
> +            $('.option', '#'+id).addClass("hide-content");
> +            filter(options, "");
> +        });
> +    });
> +};
> +
> +kimchi.setupISCSI = function(){
> +    var loadTargets = function(server, port, callback){
> +        var isUpdate = $(".option", "#iSCSITarget").children().length > 0;
> +        $(".option", "#iSCSITarget").empty();
> +        $('input', "#iSCSITarget").attr("placeholder", "loading targets...");
> +        kimchi.getISCSITargets(server, port, function(data){
> +            if(data.length==0){
> +                $('input', "#iSCSITarget").attr("placeholder", "no targets is got, please input one.");
> +            }else{
> +                for(var i=0; i<data.length; i++){
> +                    var itemNode = $.parseHTML("<div class='item'>"+data[i].target+"</div>");
> +                    $(".option", "#iSCSITarget").append(itemNode);
> +                }
> +                $('input', "#iSCSITarget").attr("placeholder", "");
> +            }
> +            kimchi.storageFilterSelect('iSCSITarget', isUpdate);
> +            $('input', "#iSCSITarget").trigger("focus");
> +            callback();
> +        }, function(data){
> +            $('input', "#iSCSITarget").attr("placeholder","failed to load targets.");
> +            callback();
> +            kimchi.message.error(data.responseJSON.reason);
> +        });
> +    };
> +    var triggerLoadTarget = function(){
> +        $('input', "#iSCSITarget").val("");
> +        var server = $("#iscsiserverId").val().trim();
> +        var port = $("#iscsiportId").val().trim();
> +        if(server!="" && port!="" && !$("#iscsiserverId").hasClass("invalid-field") && !$("#iscsiportId").hasClass("invalid-field")){
> +            $("#iscsiserverId").attr("disabled", true);
> +            $("#iscsiportId").attr("disabled", true);
> +            $('.arrow', '#iSCSIServer').addClass("hide-content");
> +            loadTargets(server, port, function(){
> +                $("#iscsiserverId").attr("disabled", false);
> +                $("#iscsiportId").attr("disabled", false);
> +                $('.arrow', '#iSCSIServer').removeClass("hide-content");
> +            });
> +        }
> +    };
> +    $("#iscsiserverId").change(function(){
> +        triggerLoadTarget();
> +    });
> +    $("#iscsiportId").change(function(){
> +        triggerLoadTarget();
> +    });
> +    var initISCSIServers = function(){
> +        kimchi.getISCSIServers(function(data){
> +            for(var i=0;i<data.length;i++){
> +                var itemNode = $.parseHTML("<div class='item'>"+data[i].host+"</div>");
> +                $(".option", "#iSCSIServer").append(itemNode);
> +                $(itemNode).click(function(){
> +                    $("#iscsiportId").val($(this).prop("port"));
> +                    $("#iscsiserverId").val($(this).text());
> +                    triggerLoadTarget();
> +                }).prop("port", data[i].port);
> +            }
> +            kimchi.storageFilterSelect('iSCSIServer', false);
> +         });
> +    };
> +    initISCSIServers();
> +};
> +
>   kimchi.initStorageAddPage = function() {
>       kimchi.listHostPartitions(function(data) {
>           if (data.length > 0) {
> @@ -160,6 +250,10 @@ kimchi.initStorageAddPage = function() {
>       $('#iscsiportId').keyup(function(event) {
>           $(this).toggleClass("invalid-field",!/^[0-9]+$/.test($(this).val()));
>       });
> +    $('#iscsiserverId').keyup(function(event) {
> +        $(this).toggleClass("invalid-field",!kimchi.isServer($(this).val().trim()));
> +    });
> +    kimchi.setupISCSI();
>   };
>
>   /* Returns 'true' if all form fields were filled, 'false' if
> diff --git a/ui/pages/storagepool-add.html.tmpl b/ui/pages/storagepool-add.html.tmpl
> index 1eb2029..6b526a7 100644
> --- a/ui/pages/storagepool-add.html.tmpl
> +++ b/ui/pages/storagepool-add.html.tmpl
> @@ -23,7 +23,7 @@
>   <!DOCTYPE html>
>   <html>
>   <body>
> -    <div class="window storage-window">
> +    <div class="window storage-window storage-admin">
>           <header>
>               <h1 class="title">$_("Define a New Storage Pool")</h1>
>               <div class="close">X</div>
> @@ -111,7 +111,10 @@
>                           <div class="field">
>                               <p class="text-help">
>                                   $_("iSCSI server IP or hostname. It should not be empty.")</p>
> -                            <input id="iscsiserverId" placeholder="$_("Server")" type="text" class="text storage-base-input-width">
> +                            <span class="filter-select" id="iSCSIServer">
> +                            <div><input id="iscsiserverId" type="text" placeholder="$_("Server")"><a class="ui-icon ui-icon-triangle-1-s arrow hide-content"></a></div>
> +                            <div class="option hide-content"></div>
> +                            </span>
>                               <input id="iscsiportId" placeholder="$_("Port")" type="text" class="text storage-port-width" maxlength="4">
>                           </div>
>                       </section>
> @@ -119,7 +122,10 @@
>                           <h2>4. $_("Target")</h2>
>                           <div class="field">
>                               <p class="text-help">$_("The iSCSI target on iSCSI server")</p>
> -                            <input id="iscsiTargetId" type="text" class="text storage-base-input-width">
> +                            <span class="filter-select" id="iSCSITarget">
> +                            <div><input id="iscsiTargetId" type="text"><a class="ui-icon ui-icon-triangle-1-s arrow hide-content"></a></div>
> +                            <div class="option hide-content"></div>
> +                            </span>
>                           </div>
>                       </section>
>                       <section class="form-section">




More information about the Kimchi-devel mailing list