[PATCHv2 0/2] UI for LDAP support

From: Royce Lv <lvroyce@linux.vnet.ibm.com> v1>v2, Change according to backend API change. Royce Lv (2): UI: support ldap vm permission tag Change guest edit permission logic ui/css/theme-default/guest-edit.css | 79 +++++++--- ui/js/src/kimchi.api.js | 15 +- ui/js/src/kimchi.guest_edit_main.js | 300 ++++++++++++++++++++++++------------ ui/pages/guest-edit.html.tmpl | 28 +++- 4 files changed, 299 insertions(+), 123 deletions(-) -- 1.8.3.2

From: Royce Lv <lvroyce@linux.vnet.ibm.com> Add corresponding html and css to support vm permission. Signed-off-by: Royce Lv <lvroyce@linux.vnet.ibm.com> --- ui/css/theme-default/guest-edit.css | 79 ++++++++++++++++++++++++++++--------- ui/pages/guest-edit.html.tmpl | 28 ++++++++++++- 2 files changed, 87 insertions(+), 20 deletions(-) diff --git a/ui/css/theme-default/guest-edit.css b/ui/css/theme-default/guest-edit.css index b1d3931..11d0ff7 100644 --- a/ui/css/theme-default/guest-edit.css +++ b/ui/css/theme-default/guest-edit.css @@ -168,22 +168,26 @@ padding: 5px 10px!important; } -.guest-edit-permission .column { +.guest-edit-permission .hide { + display: none; +} + +.guest-edit-permission .pam .column { display: inline-block; vertical-align: top; } -.guest-edit-permission .title { +.guest-edit-permission .pam .title { margin-bottom: 3px; } -.guest-edit-permission input[type="text"] { +.guest-edit-permission .pam input[type="text"] { margin-bottom: 3px; font-size: 12px; width: 97%; } -.guest-edit-permission .body { +.guest-edit-permission .pam .body { border: 1px solid #999999; font-size: 12px; padding: 1px; @@ -191,77 +195,114 @@ overflow: auto; } -.guest-edit-permission .body .head { +.guest-edit-permission .pam .body .head { margin-bottom: 3px; font-weight: bold; background: linear-gradient(to bottom, #E5E5E5 0%, #C4C4C4 100%) repeat scroll 0 0 transparent; } -.guest-edit-permission .body .item { +.guest-edit-permission .pam .body .item { padding: 2px 3px; margin-bottom: 1px; cursor: pointer; } -.guest-edit-permission .body .item:hover { +.guest-edit-permission .pam .body .item:hover { background-color: #AAAAAA; } -.guest-edit-permission .body .item-picked { +.guest-edit-permission .pam .body .item-picked { background-color: #BBBBBB; } -.guest-edit-permission .body .item .icon { +.guest-edit-permission .pam .body .item .icon { display: inline-block; height: 15px; width: 15px; vertical-align: bottom; } -.guest-edit-permission .body .item .user-icon { +.guest-edit-permission .pam .body .item .user-icon { background: url('/images/theme-default/user.png') no-repeat scroll; background-size: 15px 15px; } -.guest-edit-permission .body .item .group-icon { +.guest-edit-permission .pam .body .item .group-icon { background: url('/images/theme-default/group.png') no-repeat scroll; background-size: 15px 15px; } -.guest-edit-permission .body .column-user { +.guest-edit-permission .pam .body .column-user { width: 48%; } -.guest-edit-permission .body .column-group { +.guest-edit-permission .pam .body .column-group { width: 50%; } -.guest-edit-permission .control { +.guest-edit-permission .pam .control { width: 5%; } -.guest-edit-permission .control button { +.guest-edit-permission .pam .control button { width: 26px; margin-left: 7px; } -.guest-edit-permission .control button:first-child { +.guest-edit-permission .pam .control button:first-child { margin-top: 110px; margin-bottom: 2px; } -.guest-edit-permission .control .ui-button-text-only .ui-button-text { +.guest-edit-permission .pam .control .ui-button-text-only .ui-button-text { padding: 2px 8px; } -.guest-edit-permission .avail { +.guest-edit-permission .pam .avail { width: 46%; } -.guest-edit-permission .selected { +.guest-edit-permission .pam .selected { width: 46%; float: right; } +#form-guest-edit-permission .ldap .header { + font-weight: bold; + padding-bottom: 2px; + margin-bottom: 8px; + border-bottom: 1px solid #999; +} + +#form-guest-edit-permission .ldap .body .item { + margin: 8px 0; +} + +#form-guest-edit-permission .ldap .cell { + width: 250px; +} + +#form-guest-edit-permission .ldap .action-area { + float: right; + line-height: 24px; +} + +#form-guest-edit-permission .ldap button { + width: 20px; + height: 20px; +} + +#form-guest-edit-permission .ldap .header button { + margin-bottom: 1px; +} + +#form-guest-edit-permission .ldap .checked { + display: inline-block; +} + +#form-guest-edit-permission .ldap .checked.hide { + display: none; +} + .guest-edit-pci { height: 79%; overflow: auto; diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl index 512909a..1be7ed4 100644 --- a/ui/pages/guest-edit.html.tmpl +++ b/ui/pages/guest-edit.html.tmpl @@ -112,6 +112,7 @@ <div class="body"></div> </form> <form id="form-guest-edit-permission" class="guest-edit-permission"> + <div class="pam"> <div class="column avail"> <div class="title">$_("Available system users and groups")</div> <input type="text" id="permission-avail-searchBox"> @@ -140,6 +141,14 @@ <div id="permission-sel-groups" class="column column-group"></div> </div> </div> + </div> + <div class="ldap"> + <div class="header"> + <span class="cell">$_("User")</span> + <button type="button" id="guest-edit-add-user-button" class="action-area add"></button> + </div> + <div class="body"></div> + </div> </form> <form id="form-guest-edit-pci" class="guest-edit-pci"> <div class="guest-scroll-indent"> @@ -218,6 +227,23 @@ </span> <div> </script> +<script id="ldap-user-tmpl" type="text/html"> + <div class="item" id="{user}"> + <span class="cell"> + <label class="{viewMode}">{user}</label> + <input type="text" class="{editMode}"/> + </span> + <span class="checked ui-icon ui-icon-notice"> + </span> + <span class="action-area {editMode}"> + <button class="cancel"></button> + </span> + <span class="action-area {viewMode}"> + <button class="edit"></button> + <button class="delete"></button> + </span> + <div> +</script> <script id="disk-row-tmpl" type="text/html"> <div class="item" id="cdrom-{dev}"> <span class="cell dev"> @@ -237,7 +263,7 @@ </span> </div> </script> -<script id="permission-item" type="text/html"> +<script id="permission-item-pam" type="text/html"> <div class="item"> <span class="icon {class}"></span> <label>{val}</label> -- 1.8.3.2

From: Royce Lv <lvroyce@linux.vnet.ibm.com> Update api for ldap user query, also adopt guest edit permission, validate user when change permission, add notice icon to indicate invalid user input. Signed-off-by: Royce Lv <lvroyce@linux.vnet.ibm.com> --- ui/js/src/kimchi.api.js | 15 +- ui/js/src/kimchi.guest_edit_main.js | 300 ++++++++++++++++++++++++------------ 2 files changed, 212 insertions(+), 103 deletions(-) diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index 78c6d66..d868a4a 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -1087,14 +1087,21 @@ var kimchi = { }); }, - getHostUsers : function(suc, err) { + getHostUsers : function(usr_data, suc, err) { + var usr = usr_data ? '?_user_id='+usr_data.user_id : ''; + var handler = function(data) { + if (usr_data) { + data['_kimchi_user'] = usr_data.user_id; + } + suc(data); + } kimchi.requestJSON({ - url : kimchi.url + 'host/users', + url : kimchi.url + '/users' + usr, type : 'GET', contentType : 'application/json', dataType : 'json', resend : true, - success : suc, + success : handler, error : err ? err : function(data) { kimchi.message.error(data.responseJSON.reason); } @@ -1103,7 +1110,7 @@ var kimchi = { getHostGroups : function(suc, err) { kimchi.requestJSON({ - url : kimchi.url + 'host/groups', + url : kimchi.url + '/groups', type : 'GET', contentType : 'application/json', dataType : 'json', diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js index 9d87a73..bb621d2 100644 --- a/ui/js/src/kimchi.guest_edit_main.js +++ b/ui/js/src/kimchi.guest_edit_main.js @@ -35,6 +35,7 @@ kimchi.guest_edit_main = function() { var guestEditForm = $('#form-guest-edit-general'); var saveButton = $('#guest-edit-button-save'); + var authType; var refreshCDROMs = function() { kimchi.listVMStorages({ @@ -42,7 +43,6 @@ kimchi.guest_edit_main = function() { }, function(storages) { var container = $('#form-guest-edit-storage .body'); $(container).empty(); - $.each(storages, function(index, storage) { storage['vm'] = kimchi.selectedGuest; rowHTML = $('#' + storage['type'] + '-row-tmpl').html(); @@ -256,107 +256,193 @@ kimchi.guest_edit_main = function() { }; var setupPermission = function() { - var userNodes = {}, groupNodes = {}; - kimchi.retrieveVM(kimchi.selectedGuest, function(vm){ - kimchi.getHostUsers(function(users){ - kimchi.getHostGroups(function(groups){ - var subArray = function(a1, a2){ //a1-a2 - for(var i=0; i<a2.length; i++){ - for(var j=0; j<a1.length; j++){ - if(a2[i] == a1[j]){ - a1.splice(j, 1); - break; - } - } - } - }; - subArray(users, vm.users); subArray(groups, vm.groups); - init(users, groups, vm.users, vm.groups); - }); + //set up for LDAP + $(".add", "#form-guest-edit-permission").button({ + icons: { primary: "ui-icon-plusthick" }, + text: false + }).click(function(evt){ + evt.preventDefault(); + addItem({ + user: "", + freeze: false, + viewMode: "hide", + editMode: "", + checked: true }); }); - var sortNodes = function(container, isUser){ - nodes = container.children(); - var keys = []; - nodes.each(function(){ - keys.push($("label", this).text()); + var addItem = function(data) { + var itemNode = $.parseHTML(kimchi.substitute($('#ldap-user-tmpl').html(),data)); + $(".body", "#form-guest-edit-permission .ldap").append(itemNode); + $(".edit", itemNode).button({ + disabled: data.freeze, + icons: { primary: "ui-icon-pencil" }, + text: false + }).click(function(evt){ + evt.preventDefault(); + toggleEdit($(this).parent().parent(), true); }); - keys.sort(); - container.empty(); - for(var i=0; i<keys.length; i++){ - var itemNode = isUser ? userNodes[keys[i]] : groupNodes[keys[i]]; - $(itemNode).click(function(){ - $(this).toggleClass("item-picked"); - }); - container.append(itemNode); + $(".delete", itemNode).button({ + icons: { primary: "ui-icon-trash" }, + text: false + }).click(function(evt){ + evt.preventDefault(); + var item = $(this).parent().parent(); + item.remove(); + }); + $("input").focusout(function() { + var item = $(this).parent().parent(); + var user= $(this).val(); + item.prop("id", user); + $("label", item).text(user); + toggleEdit(item, false); + }); + if (data.checked == true) { + $(".checked", itemNode).addClass("hide"); } + $(".cancel", itemNode).button({ + icons: { primary: "ui-icon-arrowreturnthick-1-w" }, + text: false + }).click(function(evt){ + evt.preventDefault(); + var item = $(this).parent().parent(); + $("label", item).text()==="" ? item.remove() : toggleEdit(item, false); + }); }; - var init = function(availUsers, availGroups, selUsers, selGroups){ - var initNode = function(key, isUserNode){ - var nodeGroups = isUserNode ? userNodes : groupNodes; - nodeGroups[key] = $.parseHTML(kimchi.substitute($('#permission-item').html(), { - val: key, - class: isUserNode? "user-icon" : "group-icon" - })); - }; - for(var i=0; i<availUsers.length; i++){ - initNode(availUsers[i], true); - $("#permission-avail-users").append(userNodes[availUsers[i]]); - sortNodes($("#permission-avail-users"), true); + var toggleEdit = function(item, on){ + $("label", item).toggleClass("hide", on); + $("input", item).toggleClass("hide", !on); + $(".action-area", item).toggleClass("hide"); + }; + //set up for PAM + var userNodes = {}, groupNodes = {}; + kimchi.getCapabilities(function(result) { + authType = result.auth; + if (authType == 'pam') { + $("#form-guest-edit-permission .ldap").hide(); + kimchi.retrieveVM(kimchi.selectedGuest, function(vm){ + kimchi.getHostUsers(undefined, function(users){ + kimchi.getHostGroups(function(groups){ + var subArray = function(a1, a2){ //a1-a2 + for(var i=0; i<a2.length; i++){ + for(var j=0; j<a1.length; j++){ + if(a2[i] == a1[j]){ + a1.splice(j, 1); + break; + } + } + } + }; + subArray(users, vm.users); subArray(groups, vm.groups); + init(users, groups, vm.users, vm.groups); + }); + }); + }); } - for(var i=0; i<selUsers.length; i++){ - initNode(selUsers[i], true); - $("#permission-sel-users").append(userNodes[selUsers[i]]); - sortNodes($("#permission-sel-users"), true); + else if (authType == 'ldap') { + $("#form-guest-edit-permission .pam").hide(); + kimchi.retrieveVM(kimchi.selectedGuest, function(vm){ + for (var i=0; i<vm.users.length; i++) { + var user = {'user_id' :vm.users[i]}; + kimchi.getHostUsers(user, function(data) { + addItem({ + user: data._kimchi_user, + viewMode: "", + freeze: true, + editMode: "hide", + checked: true}); + }, function (data) { + addItem({ + user: data._kimchi_user, + viewMode: "", + freeze: true, + editMode: "hide", + checked: false}); + }); + } + }); } - for(var i=0; i<availGroups.length; i++){ - initNode(availGroups[i], false); - $("#permission-avail-groups").append(groupNodes[availGroups[i]]); - sortNodes($("#permission-avail-groups"), false); + var sortNodes = function(container, isUser){ + nodes = container.children(); + var keys = []; + nodes.each(function(){ + keys.push($("label", this).text()); + }); + keys.sort(); + container.empty(); + for(var i=0; i<keys.length; i++){ + var itemNode = isUser ? userNodes[keys[i]] : groupNodes[keys[i]]; + $(itemNode).click(function(){ + $(this).toggleClass("item-picked"); + }); + container.append(itemNode); + } + }; + var init = function(availUsers, availGroups, selUsers, selGroups){ + var initNode = function(key, isUserNode){ + var nodeGroups = isUserNode ? userNodes : groupNodes; + nodeGroups[key] = $.parseHTML(kimchi.substitute($('#permission-item-pam').html(), { + val: key, + class: isUserNode? "user-icon" : "group-icon" + })); + }; + for(var i=0; i<availUsers.length; i++){ + initNode(availUsers[i], true); + $("#permission-avail-users").append(userNodes[availUsers[i]]); + sortNodes($("#permission-avail-users"), true); + } + for(var i=0; i<selUsers.length; i++){ + initNode(selUsers[i], true); + $("#permission-sel-users").append(userNodes[selUsers[i]]); + sortNodes($("#permission-sel-users"), true); + } + for(var i=0; i<availGroups.length; i++){ + initNode(availGroups[i], false); + $("#permission-avail-groups").append(groupNodes[availGroups[i]]); + sortNodes($("#permission-avail-groups"), false); + } + for(var i=0; i<selGroups.length; i++){ + initNode(selGroups[i], false); + $("#permission-sel-groups").append(groupNodes[selGroups[i]]); + sortNodes($("#permission-sel-groups"), false); + } + }; + var filterNodes = function(key, container){ + container.children().each(function(){ + $(this).css("display", $("label", this).text().indexOf(key)==-1 ? "none" : ""); + }); } - for(var i=0; i<selGroups.length; i++){ - initNode(selGroups[i], false); - $("#permission-sel-groups").append(groupNodes[selGroups[i]]); + $("#permission-avail-searchBox").on("keyup", function() { + var key = $(this).val(); + filterNodes(key, $("#permission-avail-users")); + filterNodes(key, $("#permission-avail-groups")); + }); + $("#permission-sel-searchBox").on("keyup", function() { + var key = $(this).val(); + filterNodes(key, $("#permission-sel-users")); + filterNodes(key, $("#permission-sel-groups")); + }); + $('#permissionGo').button().click(function(evt) { + evt.preventDefault(); + $("#permission-avail-users").children(".item-picked").appendTo("#permission-sel-users").removeClass("item-picked"); + sortNodes($("#permission-sel-users"), true); + $("#permission-avail-groups").children(".item-picked").appendTo("#permission-sel-groups").removeClass("item-picked"); sortNodes($("#permission-sel-groups"), false); - } - }; - var filterNodes = function(key, container){ - container.children().each(function(){ - $(this).css("display", $("label", this).text().indexOf(key)==-1 ? "none" : ""); + $("#permission-sel-searchBox").val(""); + filterNodes("", $("#permission-sel-users")); + filterNodes("", $("#permission-sel-groups")); + }); + $('#permissionBack').button().click(function(evt) { + evt.preventDefault(); + $("#permission-sel-users").children(".item-picked").appendTo("#permission-avail-users").removeClass("item-picked"); + sortNodes($("#permission-avail-users"), true); + $("#permission-sel-groups").children(".item-picked").appendTo("#permission-avail-groups").removeClass("item-picked"); + sortNodes($("#permission-avail-groups"), false); + $("#permission-avail-searchBox").val(""); + filterNodes("", $("#permission-avail-users")); + filterNodes("", $("#permission-avail-groups")); }); - } - $("#permission-avail-searchBox").on("keyup", function() { - var key = $(this).val(); - filterNodes(key, $("#permission-avail-users")); - filterNodes(key, $("#permission-avail-groups")); - }); - $("#permission-sel-searchBox").on("keyup", function() { - var key = $(this).val(); - filterNodes(key, $("#permission-sel-users")); - filterNodes(key, $("#permission-sel-groups")); - }); - $('#permissionGo').button().click(function(evt) { - evt.preventDefault(); - $("#permission-avail-users").children(".item-picked").appendTo("#permission-sel-users").removeClass("item-picked"); - sortNodes($("#permission-sel-users"), true); - $("#permission-avail-groups").children(".item-picked").appendTo("#permission-sel-groups").removeClass("item-picked"); - sortNodes($("#permission-sel-groups"), false); - $("#permission-sel-searchBox").val(""); - filterNodes("", $("#permission-sel-users")); - filterNodes("", $("#permission-sel-groups")); - }); - $('#permissionBack').button().click(function(evt) { - evt.preventDefault(); - $("#permission-sel-users").children(".item-picked").appendTo("#permission-avail-users").removeClass("item-picked"); - sortNodes($("#permission-avail-users"), true); - $("#permission-sel-groups").children(".item-picked").appendTo("#permission-avail-groups").removeClass("item-picked"); - sortNodes($("#permission-avail-groups"), false); - $("#permission-avail-searchBox").val(""); - filterNodes("", $("#permission-avail-users")); - filterNodes("", $("#permission-avail-groups")); }); - }; - + } var setupPCIDevice = function(){ kimchi.getHostPCIDevices(function(hostPCIs){ kimchi.getVMPCIDevices(kimchi.selectedGuest, function(vmPCIs){ @@ -531,14 +617,30 @@ kimchi.guest_edit_main = function() { var permissionSubmit = function(event) { var content = { users: [], groups: [] }; - $("#permission-sel-users").children().each(function(){ - content.users.push($("label", this).text()); - }); - $("#permission-sel-groups").children().each(function(){ - content.groups.push($("label", this).text()); - }); - kimchi.updateVM(kimchi.selectedGuest, content, function(){ - kimchi.window.close(); + kimchi.getCapabilities(function(result) { + authType = result.auth; + if (authType == 'pam') { + $("#permission-sel-users").children().each(function(){ + content.users.push($("label", this).text()); + }); + $("#permission-sel-groups").children().each(function(){ + content.groups.push($("label", this).text()); + }); + } + else if (authType == 'ldap') { + $(".body","#form-guest-edit-permission .ldap").children().each(function () { + var user = {'user_id': $(this).attr("id")}; + var tmp = $(this); + kimchi.getHostUsers(user, function(data) { + }, function (data) { + $(".checked", tmp).removeClass("hide"); + }); + content.users.push($(this).attr("id")); + }); + } + kimchi.updateVM(kimchi.selectedGuest, content, function(){ + kimchi.window.close(); + }); }); } -- 1.8.3.2

On 11/20/2014 08:22 AM, lvroyce@linux.vnet.ibm.com wrote:
From: Royce Lv <lvroyce@linux.vnet.ibm.com>
Update api for ldap user query, also adopt guest edit permission, validate user when change permission, add notice icon to indicate invalid user input.
Signed-off-by: Royce Lv <lvroyce@linux.vnet.ibm.com> --- ui/js/src/kimchi.api.js | 15 +- ui/js/src/kimchi.guest_edit_main.js | 300 ++++++++++++++++++++++++------------ 2 files changed, 212 insertions(+), 103 deletions(-)
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index 78c6d66..d868a4a 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -1087,14 +1087,21 @@ var kimchi = { }); },
- getHostUsers : function(suc, err) { + getHostUsers : function(usr_data, suc, err) {
Let's rename it to "GetUsers" or if you want to differ from PAM, use "GetUserById"
+ var usr = usr_data ? '?_user_id='+usr_data.user_id : ''; + var handler = function(data) { + if (usr_data) { + data['_kimchi_user'] = usr_data.user_id; + } + suc(data); + } kimchi.requestJSON({ - url : kimchi.url + 'host/users', + url : kimchi.url + '/users' + usr, type : 'GET', contentType : 'application/json', dataType : 'json', resend : true, - success : suc, + success : handler, error : err ? err : function(data) { kimchi.message.error(data.responseJSON.reason); } @@ -1103,7 +1110,7 @@ var kimchi = {
getHostGroups : function(suc, err) {
Same here.
kimchi.requestJSON({ - url : kimchi.url + 'host/groups', + url : kimchi.url + '/groups', type : 'GET', contentType : 'application/json', dataType : 'json', diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js index 9d87a73..bb621d2 100644 --- a/ui/js/src/kimchi.guest_edit_main.js +++ b/ui/js/src/kimchi.guest_edit_main.js @@ -35,6 +35,7 @@ kimchi.guest_edit_main = function() {
var guestEditForm = $('#form-guest-edit-general'); var saveButton = $('#guest-edit-button-save'); + var authType;
var refreshCDROMs = function() { kimchi.listVMStorages({ @@ -42,7 +43,6 @@ kimchi.guest_edit_main = function() { }, function(storages) { var container = $('#form-guest-edit-storage .body'); $(container).empty(); - $.each(storages, function(index, storage) { storage['vm'] = kimchi.selectedGuest; rowHTML = $('#' + storage['type'] + '-row-tmpl').html(); @@ -256,107 +256,193 @@ kimchi.guest_edit_main = function() { };
var setupPermission = function() { - var userNodes = {}, groupNodes = {}; - kimchi.retrieveVM(kimchi.selectedGuest, function(vm){ - kimchi.getHostUsers(function(users){ - kimchi.getHostGroups(function(groups){ - var subArray = function(a1, a2){ //a1-a2 - for(var i=0; i<a2.length; i++){ - for(var j=0; j<a1.length; j++){ - if(a2[i] == a1[j]){ - a1.splice(j, 1); - break; - } - } - } - }; - subArray(users, vm.users); subArray(groups, vm.groups); - init(users, groups, vm.users, vm.groups); - }); + //set up for LDAP + $(".add", "#form-guest-edit-permission").button({ + icons: { primary: "ui-icon-plusthick" }, + text: false + }).click(function(evt){ + evt.preventDefault(); + addItem({ + user: "", + freeze: false, + viewMode: "hide", + editMode: "", + checked: true }); }); - var sortNodes = function(container, isUser){ - nodes = container.children(); - var keys = []; - nodes.each(function(){ - keys.push($("label", this).text()); + var addItem = function(data) { + var itemNode = $.parseHTML(kimchi.substitute($('#ldap-user-tmpl').html(),data)); + $(".body", "#form-guest-edit-permission .ldap").append(itemNode); + $(".edit", itemNode).button({ + disabled: data.freeze, + icons: { primary: "ui-icon-pencil" }, + text: false + }).click(function(evt){ + evt.preventDefault(); + toggleEdit($(this).parent().parent(), true); }); - keys.sort(); - container.empty(); - for(var i=0; i<keys.length; i++){ - var itemNode = isUser ? userNodes[keys[i]] : groupNodes[keys[i]]; - $(itemNode).click(function(){ - $(this).toggleClass("item-picked"); - }); - container.append(itemNode); + $(".delete", itemNode).button({ + icons: { primary: "ui-icon-trash" }, + text: false + }).click(function(evt){ + evt.preventDefault(); + var item = $(this).parent().parent(); + item.remove(); + }); + $("input").focusout(function() { + var item = $(this).parent().parent(); + var user= $(this).val(); + item.prop("id", user); + $("label", item).text(user); + toggleEdit(item, false); + }); + if (data.checked == true) { + $(".checked", itemNode).addClass("hide"); } + $(".cancel", itemNode).button({ + icons: { primary: "ui-icon-arrowreturnthick-1-w" }, + text: false + }).click(function(evt){ + evt.preventDefault(); + var item = $(this).parent().parent(); + $("label", item).text()==="" ? item.remove() : toggleEdit(item, false); + }); }; - var init = function(availUsers, availGroups, selUsers, selGroups){ - var initNode = function(key, isUserNode){ - var nodeGroups = isUserNode ? userNodes : groupNodes; - nodeGroups[key] = $.parseHTML(kimchi.substitute($('#permission-item').html(), { - val: key, - class: isUserNode? "user-icon" : "group-icon" - })); - }; - for(var i=0; i<availUsers.length; i++){ - initNode(availUsers[i], true); - $("#permission-avail-users").append(userNodes[availUsers[i]]); - sortNodes($("#permission-avail-users"), true); + var toggleEdit = function(item, on){ + $("label", item).toggleClass("hide", on); + $("input", item).toggleClass("hide", !on); + $(".action-area", item).toggleClass("hide"); + };
+ //set up for PAM + var userNodes = {}, groupNodes = {}; + kimchi.getCapabilities(function(result) {
The capabilities values are cached on kimchi.capabilities variable so you don't need to request it again. You can check kimchi.host.js for details on how use the kimchi.capabilities variable.
+ authType = result.auth; + if (authType == 'pam') { + $("#form-guest-edit-permission .ldap").hide(); + kimchi.retrieveVM(kimchi.selectedGuest, function(vm){ + kimchi.getHostUsers(undefined, function(users){ + kimchi.getHostGroups(function(groups){ + var subArray = function(a1, a2){ //a1-a2 + for(var i=0; i<a2.length; i++){ + for(var j=0; j<a1.length; j++){ + if(a2[i] == a1[j]){ + a1.splice(j, 1); + break; + } + } + } + }; + subArray(users, vm.users); subArray(groups, vm.groups); + init(users, groups, vm.users, vm.groups); + }); + }); + }); } - for(var i=0; i<selUsers.length; i++){ - initNode(selUsers[i], true); - $("#permission-sel-users").append(userNodes[selUsers[i]]); - sortNodes($("#permission-sel-users"), true); + else if (authType == 'ldap') { + $("#form-guest-edit-permission .pam").hide(); + kimchi.retrieveVM(kimchi.selectedGuest, function(vm){ + for (var i=0; i<vm.users.length; i++) { + var user = {'user_id' :vm.users[i]}; + kimchi.getHostUsers(user, function(data) { + addItem({ + user: data._kimchi_user, + viewMode: "", + freeze: true, + editMode: "hide", + checked: true}); + }, function (data) { + addItem({ + user: data._kimchi_user, + viewMode: "", + freeze: true, + editMode: "hide", + checked: false}); + }); + } + }); } - for(var i=0; i<availGroups.length; i++){ - initNode(availGroups[i], false); - $("#permission-avail-groups").append(groupNodes[availGroups[i]]); - sortNodes($("#permission-avail-groups"), false); + var sortNodes = function(container, isUser){ + nodes = container.children(); + var keys = []; + nodes.each(function(){ + keys.push($("label", this).text()); + }); + keys.sort(); + container.empty(); + for(var i=0; i<keys.length; i++){ + var itemNode = isUser ? userNodes[keys[i]] : groupNodes[keys[i]]; + $(itemNode).click(function(){ + $(this).toggleClass("item-picked"); + }); + container.append(itemNode); + } + }; + var init = function(availUsers, availGroups, selUsers, selGroups){ + var initNode = function(key, isUserNode){ + var nodeGroups = isUserNode ? userNodes : groupNodes; + nodeGroups[key] = $.parseHTML(kimchi.substitute($('#permission-item-pam').html(), { + val: key, + class: isUserNode? "user-icon" : "group-icon" + })); + }; + for(var i=0; i<availUsers.length; i++){ + initNode(availUsers[i], true); + $("#permission-avail-users").append(userNodes[availUsers[i]]); + sortNodes($("#permission-avail-users"), true); + } + for(var i=0; i<selUsers.length; i++){ + initNode(selUsers[i], true); + $("#permission-sel-users").append(userNodes[selUsers[i]]); + sortNodes($("#permission-sel-users"), true); + } + for(var i=0; i<availGroups.length; i++){ + initNode(availGroups[i], false); + $("#permission-avail-groups").append(groupNodes[availGroups[i]]); + sortNodes($("#permission-avail-groups"), false); + } + for(var i=0; i<selGroups.length; i++){ + initNode(selGroups[i], false); + $("#permission-sel-groups").append(groupNodes[selGroups[i]]); + sortNodes($("#permission-sel-groups"), false); + } + }; + var filterNodes = function(key, container){ + container.children().each(function(){ + $(this).css("display", $("label", this).text().indexOf(key)==-1 ? "none" : ""); + }); } - for(var i=0; i<selGroups.length; i++){ - initNode(selGroups[i], false); - $("#permission-sel-groups").append(groupNodes[selGroups[i]]); + $("#permission-avail-searchBox").on("keyup", function() { + var key = $(this).val(); + filterNodes(key, $("#permission-avail-users")); + filterNodes(key, $("#permission-avail-groups")); + }); + $("#permission-sel-searchBox").on("keyup", function() { + var key = $(this).val(); + filterNodes(key, $("#permission-sel-users")); + filterNodes(key, $("#permission-sel-groups")); + }); + $('#permissionGo').button().click(function(evt) { + evt.preventDefault(); + $("#permission-avail-users").children(".item-picked").appendTo("#permission-sel-users").removeClass("item-picked"); + sortNodes($("#permission-sel-users"), true); + $("#permission-avail-groups").children(".item-picked").appendTo("#permission-sel-groups").removeClass("item-picked"); sortNodes($("#permission-sel-groups"), false); - } - }; - var filterNodes = function(key, container){ - container.children().each(function(){ - $(this).css("display", $("label", this).text().indexOf(key)==-1 ? "none" : ""); + $("#permission-sel-searchBox").val(""); + filterNodes("", $("#permission-sel-users")); + filterNodes("", $("#permission-sel-groups")); + }); + $('#permissionBack').button().click(function(evt) { + evt.preventDefault(); + $("#permission-sel-users").children(".item-picked").appendTo("#permission-avail-users").removeClass("item-picked"); + sortNodes($("#permission-avail-users"), true); + $("#permission-sel-groups").children(".item-picked").appendTo("#permission-avail-groups").removeClass("item-picked"); + sortNodes($("#permission-avail-groups"), false); + $("#permission-avail-searchBox").val(""); + filterNodes("", $("#permission-avail-users")); + filterNodes("", $("#permission-avail-groups")); }); - } - $("#permission-avail-searchBox").on("keyup", function() { - var key = $(this).val(); - filterNodes(key, $("#permission-avail-users")); - filterNodes(key, $("#permission-avail-groups")); - }); - $("#permission-sel-searchBox").on("keyup", function() { - var key = $(this).val(); - filterNodes(key, $("#permission-sel-users")); - filterNodes(key, $("#permission-sel-groups")); - }); - $('#permissionGo').button().click(function(evt) { - evt.preventDefault(); - $("#permission-avail-users").children(".item-picked").appendTo("#permission-sel-users").removeClass("item-picked"); - sortNodes($("#permission-sel-users"), true); - $("#permission-avail-groups").children(".item-picked").appendTo("#permission-sel-groups").removeClass("item-picked"); - sortNodes($("#permission-sel-groups"), false); - $("#permission-sel-searchBox").val(""); - filterNodes("", $("#permission-sel-users")); - filterNodes("", $("#permission-sel-groups")); - }); - $('#permissionBack').button().click(function(evt) { - evt.preventDefault(); - $("#permission-sel-users").children(".item-picked").appendTo("#permission-avail-users").removeClass("item-picked"); - sortNodes($("#permission-avail-users"), true); - $("#permission-sel-groups").children(".item-picked").appendTo("#permission-avail-groups").removeClass("item-picked"); - sortNodes($("#permission-avail-groups"), false); - $("#permission-avail-searchBox").val(""); - filterNodes("", $("#permission-avail-users")); - filterNodes("", $("#permission-avail-groups")); }); - }; - + } var setupPCIDevice = function(){ kimchi.getHostPCIDevices(function(hostPCIs){ kimchi.getVMPCIDevices(kimchi.selectedGuest, function(vmPCIs){ @@ -531,14 +617,30 @@ kimchi.guest_edit_main = function() {
var permissionSubmit = function(event) { var content = { users: [], groups: [] }; - $("#permission-sel-users").children().each(function(){ - content.users.push($("label", this).text()); - }); - $("#permission-sel-groups").children().each(function(){ - content.groups.push($("label", this).text()); - }); - kimchi.updateVM(kimchi.selectedGuest, content, function(){ - kimchi.window.close(); + kimchi.getCapabilities(function(result) { + authType = result.auth; + if (authType == 'pam') { + $("#permission-sel-users").children().each(function(){ + content.users.push($("label", this).text()); + }); + $("#permission-sel-groups").children().each(function(){ + content.groups.push($("label", this).text()); + }); + } + else if (authType == 'ldap') { + $(".body","#form-guest-edit-permission .ldap").children().each(function () { + var user = {'user_id': $(this).attr("id")}; + var tmp = $(this); + kimchi.getHostUsers(user, function(data) { + }, function (data) { + $(".checked", tmp).removeClass("hide"); + }); + content.users.push($(this).attr("id")); + }); + } + kimchi.updateVM(kimchi.selectedGuest, content, function(){ + kimchi.window.close(); + }); }); }

Some style comments: 1. Storage, Network and Permission (when ldap) tabs will have a similar layout so all those 3 tabs should share the same margin and alignment values. Network and Storage differs on margins values. The Permission tab differs on margin and alignment from the other 2. Also the plus icon is over the line. So I'd suggest to have those margin and alignment values shared in all those 3 tabs. 2. I think the user input box (when I select the plus icon on Permission tab) should be bigger, like 2x the current width On 11/20/2014 08:22 AM, lvroyce@linux.vnet.ibm.com wrote:
From: Royce Lv <lvroyce@linux.vnet.ibm.com>
v1>v2, Change according to backend API change.
Royce Lv (2): UI: support ldap vm permission tag Change guest edit permission logic
ui/css/theme-default/guest-edit.css | 79 +++++++--- ui/js/src/kimchi.api.js | 15 +- ui/js/src/kimchi.guest_edit_main.js | 300 ++++++++++++++++++++++++------------ ui/pages/guest-edit.html.tmpl | 28 +++- 4 files changed, 299 insertions(+), 123 deletions(-)

On 11/24/2014 01:27 PM, Aline Manera wrote:
Some style comments:
1. Storage, Network and Permission (when ldap) tabs will have a similar layout so all those 3 tabs should share the same margin and alignment values.
Network and Storage differs on margins values.
The Permission tab differs on margin and alignment from the other 2. Also the plus icon is over the line.
So I'd suggest to have those margin and alignment values shared in all those 3 tabs.
2. I think the user input box (when I select the plus icon on Permission tab) should be bigger, like 2x the current width
Also a label for each input box would guide user to which value he/she must enter there. Something like below: User ID: [_____________________________] User ID: [_____________________________] User ID: [_____________________________]
On 11/20/2014 08:22 AM, lvroyce@linux.vnet.ibm.com wrote:
From: Royce Lv<lvroyce@linux.vnet.ibm.com>
v1>v2, Change according to backend API change.
Royce Lv (2): UI: support ldap vm permission tag Change guest edit permission logic
ui/css/theme-default/guest-edit.css | 79 +++++++--- ui/js/src/kimchi.api.js | 15 +- ui/js/src/kimchi.guest_edit_main.js | 300 ++++++++++++++++++++++++------------ ui/pages/guest-edit.html.tmpl | 28 +++- 4 files changed, 299 insertions(+), 123 deletions(-)
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel

The Kimchi 1.4 code freeze starts tomorrow. So we need to have the LDAP support UI merged ASAP. On 11/20/2014 08:22 AM, lvroyce@linux.vnet.ibm.com wrote:
From: Royce Lv <lvroyce@linux.vnet.ibm.com>
v1>v2, Change according to backend API change.
Royce Lv (2): UI: support ldap vm permission tag Change guest edit permission logic
ui/css/theme-default/guest-edit.css | 79 +++++++--- ui/js/src/kimchi.api.js | 15 +- ui/js/src/kimchi.guest_edit_main.js | 300 ++++++++++++++++++++++++------------ ui/pages/guest-edit.html.tmpl | 28 +++- 4 files changed, 299 insertions(+), 123 deletions(-)
participants (2)
-
Aline Manera
-
lvroyce@linux.vnet.ibm.com