[Kimchi-devel] [V1 1/2] Edit Guest Network Inteface UI
Aline Manera
alinefm at linux.vnet.ibm.com
Mon Apr 14 18:49:17 UTC 2014
On 04/14/2014 06:53 AM, huoyuxin at linux.vnet.ibm.com wrote:
> From: Yu Xin Huo <huoyuxin at linux.vnet.ibm.com>
>
> Add, List, Delete, Update Guest Network Interface.
>
> Signed-off-by: Yu Xin Huo <huoyuxin at linux.vnet.ibm.com>
> ---
> ui/css/theme-default/guest-edit.css | 43 +++++++++++++++
> ui/js/src/kimchi.api.js | 55 +++++++++++++++++++
> ui/js/src/kimchi.guest_edit_main.js | 103 +++++++++++++++++++++++++++++++++++
> ui/pages/guest-edit.html.tmpl | 53 ++++++++++++++++++
> 4 files changed, 254 insertions(+), 0 deletions(-)
>
> diff --git a/ui/css/theme-default/guest-edit.css b/ui/css/theme-default/guest-edit.css
> index 0b7ba21..4b208c1 100644
> --- a/ui/css/theme-default/guest-edit.css
> +++ b/ui/css/theme-default/guest-edit.css
> @@ -156,3 +156,46 @@
> .guest-edit-cdrom-button.detach[disabled] {
> background-position: -54px -108px;
> }
> +
> +.guest-edit-interface .header {
> + margin-bottom: 8px;
> + padding-bottom: 2px;
> + font-weight: bold;
> + border-bottom: 1px solid #999999;
> + overflow: hidden;
> +}
> +
> +.guest-edit-interface .body .item {
> + margin: 5px 0;
> +}
> +
> +.guest-edit-interface .cell {
> + display: inline-block;
> + width: 150px;
> +}
> +
> +.guest-edit-interface .body select {
> + width: 130px;
> + padding: 0px;
> +}
> +
> +.guest-edit-interface .action-area {
> + float: right;
> +}
> +
> +.guest-edit-interface button {
> + width: 20px;
> + height: 20px;
> +}
> +
> +.guest-edit-interface .header button {
> + margin-bottom: 1px;
> +}
> +
> +.guest-edit-interface .body button:not(:last-child) {
> + margin-right: 2px;
> +}
> +
> +.guest-edit-interface .hide {
> + display: none;
> +}
> diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
> index 8c1030c..168e53d 100644
> --- a/ui/js/src/kimchi.api.js
> +++ b/ui/js/src/kimchi.api.js
> @@ -955,5 +955,60 @@ var kimchi = {
> kimchi.message.error(data.responseJSON.reason);
> }
> });
> + },
> +
> + getGuestInterfaces: function(name, suc, err) {
> + var url = kimchi.url+'/vms/'+encodeURIComponent(name)+'/ifaces';
> + kimchi.requestJSON({
> + url : url,
> + type : 'GET',
> + contentType : 'application/json',
> + dataType : 'json',
> + success : suc,
> + error : err || function(data) {
> + kimchi.message.error(data.responseJSON.reason);
> + }
> + });
> + },
> +
> + createGuestInterface : function(name, interface, suc, err) {
> + kimchi.requestJSON({
> + url : kimchi.url+'/vms/'+encodeURIComponent(name)+'/ifaces',
> + type : 'POST',
> + contentType : 'application/json',
> + dataType : 'json',
> + data : JSON.stringify(interface),
> + success : suc,
> + error : err || function(data) {
> + kimchi.message.error(data.responseJSON.reason);
> + }
> + });
> + },
> +
> + deleteGuestInterface : function(vm, mac, suc, err) {
> + kimchi.requestJSON({
> + url : kimchi.url+'/vms/'+encodeURIComponent(vm)+'/ifaces/'+encodeURIComponent(mac),
> + type : 'DELETE',
> + contentType : 'application/json',
> + dataType : 'json',
> + success : suc,
> + error : err ? err : function(data) {
> + kimchi.message.error(data.responseJSON.reason);
> + }
> + });
> + },
> +
> + updateGuestInterface : function(vm, mac, interface, suc, err) {
> + $.ajax({
> + url : kimchi.url+'/vms/'+encodeURIComponent(vm)+'/ifaces/'+encodeURIComponent(mac),
> + type : 'PUT',
> + contentType : 'application/json',
> + data : JSON.stringify(interface),
> + dataType : 'json',
> + success: suc,
> + error: err ? err : function(data) {
> + kimchi.message.error(data.responseJSON.reason);
> + }
> + });
The update API is not implemented on backend yet.
You can remove it.
> }
> };
> diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js
> index 9375c51..b051774 100644
> --- a/ui/js/src/kimchi.guest_edit_main.js
> +++ b/ui/js/src/kimchi.guest_edit_main.js
> @@ -78,6 +78,107 @@ kimchi.guest_edit_main = function() {
> });
> };
>
> + var setupInterface = function() {
> + $(".add", "#form-guest-edit-interface").button({
> + icons: { primary: "ui-icon-plusthick" },
> + text: false
> + }).click(function(){
> + addItem({
> + mac: "",
> + network: "",
> + model: "",
The model will be chosen by Kimchi automatically.
It is a low level information and we should not require it from user.
> + type: "",
> + viewMode: "hide",
> + editMode: ""
> + });
> + });
> + var toggleEdit = function(item, on){
> + $("label", item).toggleClass("hide", on);
> + $("select", item).toggleClass("hide", !on);
> + $(".action-area", item).toggleClass("hide");
> + };
> + var addItem = function(data) {
> + var attrs = ["network", "model", "type"];
> + var attrIndex = 0;
> + var itemNode = $.parseHTML(kimchi.template($('#interface-tmpl').html(),data));
> + $(".body", "#form-guest-edit-interface").append(itemNode);
> + $("select", itemNode).first().append(networkOptions);
> + if(data[attrs[attrIndex]]!=""){
> + $("select", itemNode).each(function(){
> + $(this).val(data[attrs[attrIndex]]);
> + attrIndex++;
> + });
> + attrIndex = 0;
> + }
> + $(".edit", itemNode).button({
> + icons: { primary: "ui-icon-pencil" },
> + text: false
> + }).click(function(){
> + toggleEdit($(this).parent().parent(), true);
> + });
> + $(".delete", itemNode).button({
> + icons: { primary: "ui-icon-trash" },
> + text: false
> + }).click(function(){
> + var item = $(this).parent().parent();
> + kimchi.deleteGuestInterface(kimchi.selectedGuest, item.prop("id"), function(){
> + item.remove();
> + });
> + });
> + $(".save", itemNode).button({
> + icons: { primary: "ui-icon-disk" },
> + text: false
> + }).click(function(){
> + var interface = {};
> + var item = $(this).parent().parent();
> + $("select", item).each(function(){
> + interface[attrs[attrIndex]] = $(this).val();
> + attrIndex++;
> + });
> + attrIndex = 0;
> + var postUpdae = function(){
> + $("label", item).each(function(){
> + $(this).text(interface[attrs[attrIndex]]);
> + attrIndex++;
> + });
> + attrIndex = 0;
> + toggleEdit(item, false);
> + };
> + if(item.prop("id")==""){
> + kimchi.createGuestInterface(kimchi.selectedGuest, interface, function(data){
> + item.prop("id", data.mac);
> + postUpdae();
> + });
> + }else{
> + kimchi.updateGuestInterface(kimchi.selectedGuest, item.prop("id"), interface, function(){
> + postUpdae();
> + });
> + }
> + });
> + $(".cancel", itemNode).button({
> + icons: { primary: "ui-icon-arrowreturnthick-1-w" },
> + text: false
> + }).click(function(){
> + var item = $(this).parent().parent();
> + $("label", item).text()==="" ? item.remove() : toggleEdit(item, false);
> + });
> + };
> + var networkOptions = "";
> + kimchi.listNetworks(function(data){
> + for(var i=0;i<data.length;i++){
> + var isSlected = i==0 ? " selected" : "";
> + networkOptions += "<option"+isSlected+">"+data[i].name+"</option>";
> + }
> + kimchi.getGuestInterfaces(kimchi.selectedGuest, function(data){
> + for(var i=0;i<data.length;i++){
> + data[i].viewMode = "";
> + data[i].editMode = "hide";
> + addItem(data[i]);
> + }
> + });
> + });
> + };
> +
> var initContent = function(guest) {
> guest['icon'] = guest['icon'] || 'images/icon-vm.png';
> for ( var prop in guest) {
> @@ -101,6 +202,8 @@ kimchi.guest_edit_main = function() {
> refreshCDROMs();
> };
>
> + setupInterface();
> +
> kimchi.topic('kimchi/vmCDROMAttached').subscribe(onAttached);
> kimchi.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced);
> kimchi.topic('kimchi/vmCDROMDetached').subscribe(onDetached);
> diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl
> index 804fc39..a2949be 100644
> --- a/ui/pages/guest-edit.html.tmpl
> +++ b/ui/pages/guest-edit.html.tmpl
> @@ -35,6 +35,9 @@
> <li>
> <a href="#form-guest-edit-storage">$_("Storage")</a>
> </li>
> + <li>
> + <a href="#form-guest-edit-interface">$_("Interface")</a>
> + </li>
> </ul>
> <form id="form-guest-edit-general">
> <fieldset class="guest-edit-fieldset">
> @@ -103,6 +106,15 @@
> </div>
> </fieldset>
> </form>
> + <form id="form-guest-edit-interface" class="guest-edit-interface">
> + <div class="header">
> + <span class="cell">$_("Network")</span>
> + <span class="cell">$_("Model")</span>
As I said before we should not require model info
> + <span class="cell">$_("Type")</span>
> + <button class="add action-area"></button>
> + </div>
> + <div class="body"></div>
> + </form>
> </div>
> </div>
> <footer>
> @@ -133,6 +145,47 @@
> </div>
> </div>
> </script>
> +<script id="interface-tmpl" type="text/html">
> + <div class="item" id="{mac}">
> + <span class="cell">
> + <label class="{viewMode}">{network}</label>
> + <select class="{editMode}"></select>
> + </span>
> + <span class="cell">
> + <label class="{viewMode}">{model}</label>
> + <select class="{editMode}">
> + <option>ne2k_pci</option>
> + <option>i82551</option>
> + <option>i82557b</option>
> + <option>i82559er</option>
> + <option selected>rtl8139</option>
> + <option>e1000</option>
> + <option>pcnet</option>
> + <option>virtio</option>
Same here.
> + </select>
> + </span>
> + <span class="cell">
> + <label class="{viewMode}">{type}</label>
> + <select class="{editMode}">
> + <option selected>network</option>
> + <option disabled>bridge</option>
> + <option disabled>user</option>
> + <option disabled>ethernet</option>
> + <option disabled>direct</option>
> + <option disabled>hostdev</option>
> + <option disabled>mcast</option>
> + <option disabled>server</option>
> + <option disabled>client</option>
> + </select>
> + </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 type="text/javascript">
> kimchi.guest_edit_main();
More information about the Kimchi-devel
mailing list