[PATCH 0/7] [WIP] Updates to Manage Repositories

This series updates HLWs original set to work with the new repo management API set posted by Aline. There are some puts that the backend currently rejects that I think should be accepted. I will work with Aline to determine if its the PUT content or the backend that needs additional work. Adam King (2): Update form.serializeObject method to handle deep object serialization Update grid widget to populate fields from deeply nested objects Hongliang Wang (5): Repository Management - Add i18n Strings Repository Management - Add API Support Repository Management - Add Repository Support Repository Management - Edit Repository Support Repository Management - Integrate into Host Tab po/POTFILES.in | 2 + ui/css/theme-default/host.css | 8 ++ ui/css/theme-default/repository-add.css | 39 +++++++ ui/css/theme-default/repository-edit.css | 128 +++++++++++++++++++++ ui/js/src/kimchi.api.js | 76 ++++++++++++- ui/js/src/kimchi.form.js | 66 +++++++++-- ui/js/src/kimchi.grid.js | 17 ++- ui/js/src/kimchi.host.js | 185 +++++++++++++++++++++++++++++++ ui/js/src/kimchi.repository_add_main.js | 84 ++++++++++++++ ui/js/src/kimchi.repository_edit_main.js | 94 ++++++++++++++++ ui/pages/i18n.html.tmpl | 19 ++++ ui/pages/repository-add.html.tmpl | 115 +++++++++++++++++++ ui/pages/repository-edit.html.tmpl | 115 +++++++++++++++++++ ui/pages/tabs/host.html.tmpl | 13 +++ 14 files changed, 946 insertions(+), 15 deletions(-) create mode 100644 ui/css/theme-default/repository-add.css create mode 100644 ui/css/theme-default/repository-edit.css create mode 100644 ui/js/src/kimchi.repository_add_main.js create mode 100644 ui/js/src/kimchi.repository_edit_main.js create mode 100644 ui/pages/repository-add.html.tmpl create mode 100644 ui/pages/repository-edit.html.tmpl -- 1.8.1.4

Previous form.serializeObject only handled single depth objects. Updates accomodate arbitrary object depth. Signed-off-by: Adam King <rak@linux.vnet.ibm.com> --- ui/js/src/kimchi.form.js | 66 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 12 deletions(-) diff --git a/ui/js/src/kimchi.form.js b/ui/js/src/kimchi.form.js index 7174b35..cdcb1e7 100644 --- a/ui/js/src/kimchi.form.js +++ b/ui/js/src/kimchi.form.js @@ -20,19 +20,61 @@ var formDataArray = $(this).serializeArray(); var formData = {}; $.each(formDataArray, function(index, data) { - if (formData[data.name] === undefined) { - formData[data.name] = data.value; - } else { - if (formData[data.name] instanceof Array) { - formData[data.name].push(data.value); - } else { - var oldValue = formData[data.name]; - formData[data.name] = []; - formData[data.name].push(oldValue); - formData[data.name].push(data.value); - } - } + var names=kimchi.form.parseFormName(data.name); + kimchi.form.assignValue(names,data.value,formData); }); return formData; }; }(jQuery)); + +kimchi.form = {}; +kimchi.form.assignValue = function(names, value, obj) { + var result=value; + + if(names.length!=0) { + result=obj; + var name=names.shift(); + if(!result) { + result={}; + } + if(!result[name]) { + result[name]=kimchi.form.assignValue(names,value); + } + else if(names.length==0) { + if(Array.isArray(result[name])){ + result[name].push(value); + } + else { + result[name]=[result[name],value]; + } + } + else { + result[name]=kimchi.form.assignValue(names,value,result[name]); + } + } + return(result); +} + +kimchi.form.parseFormName = function(name, parsedName) { + if (!parsedName) { + parsedName=[]; + } + if(!name || name=="") { + return(parsedName); + } + var openBracket=name.indexOf("["); + if (openBracket!=-1) { + var id=name.slice(0, openBracket); + parsedName.push(id); + var closeBracket=name.lastIndexOf("]"); + if (closeBracket==-1) { + closeBracket=name.length; + } + var tmpName=name.slice(openBracket+1,closeBracket); + kimchi.form.parseFormName(tmpName,parsedName); + } + else { + parsedName.push(name); + } + return(parsedName); +} -- 1.8.1.4

Prior implementation of grid assumed all fields were defined as properties of the top object with no nesting. The update facilitates use of nested objects. Signed-off-by: Adam King <rak@linux.vnet.ibm.com> --- ui/js/src/kimchi.grid.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/ui/js/src/kimchi.grid.js b/ui/js/src/kimchi.grid.js index e5892ff..340ff7a 100644 --- a/ui/js/src/kimchi.grid.js +++ b/ui/js/src/kimchi.grid.js @@ -166,8 +166,21 @@ kimchi.widget.Grid = function(params) { $.each(data, function(i, row) { var rowNode = $('<tr></tr>').appendTo(tbody); $.each(fields, function(fi, field) { - var fieldName = field['name']; - var value = (row[fieldName]==null) ? '' : row[fieldName]; + var fieldName = field['name'].split('.'); + var tmpRow=row; + for(var i=0;tmpRow && i<fieldName.length;i++) { + tmpRow=tmpRow[fieldName[i]]; + } + var value; + if (tmpRow==undefined) { + value=''; + } + else if (Array.isArray(tmpRow)) { + value=tmpRow.toString(); + } + else { + value=tmpRow; + } $('<td><div class="cell-text-wrapper"' + (field['makeTitle'] === true ? ' title="' + value + '"' -- 1.8.1.4

From: Hongliang Wang <hlwang@linux.vnet.ibm.com> Add i18n translation strings for repository management. Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/pages/i18n.html.tmpl | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ui/pages/i18n.html.tmpl b/ui/pages/i18n.html.tmpl index 2f47e50..e1ebd47 100644 --- a/ui/pages/i18n.html.tmpl +++ b/ui/pages/i18n.html.tmpl @@ -80,6 +80,25 @@ var i18n = { 'KCHHOST6008M': "$_("Shutting down or restarting host will cause unsaved work lost. Continue to shut down/restarting?")", + 'KCHREPO6001M': "$_("Confirm")", + 'KCHREPO6002M': "$_("Repository will be removed permanently and can't be recovered. Do you want to continue?")", + 'KCHREPO6003M': "$_("Repositories")", + 'KCHREPO6004M': "$_("ID")", + 'KCHREPO6005M': "$_("Name")", + 'KCHREPO6006M': "$_("Base URL")", + 'KCHREPO6007M': "$_("Is Mirror")", + 'KCHREPO6008M': "$_("URL Args")", + 'KCHREPO6009M': "$_("Enabled")", + 'KCHREPO6010M': "$_("GPG Check")", + 'KCHREPO6011M': "$_("GPG Key")", + 'KCHREPO6012M': "$_("Add")", + 'KCHREPO6013M': "$_("Edit")", + 'KCHREPO6014M': "$_("Remove")", + 'KCHREPO6015M': "$_("Failed.")", + 'KCHREPO6016M': "$_("Enable")", + 'KCHREPO6017M': "$_("Disable")", + + 'KCHUPD6001M': "$_("Software Updates")", 'KCHUPD6002M': "$_("Package Name")", 'KCHUPD6003M': "$_("Version")", -- 1.8.1.4

From: Hongliang Wang <hlwang@linux.vnet.ibm.com> Add API calling in kimchi.api.js. Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/js/src/kimchi.api.js | 76 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index 4310435..9ceed0b 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -856,5 +856,79 @@ var kimchi = { success : onResponse, error : err }); - } + }, + + createRepository : function(settings, suc, err) { + kimchi.requestJSON({ + url : "host/repositories", + type : "POST", + contentType : "application/json", + data : JSON.stringify(settings), + dataType : "json", + success: suc, + error: err + }); + }, + + retrieveRepository : function(repository, suc, err) { + var reposID = encodeURIComponent(repository); + kimchi.requestJSON({ + url : kimchi.url + "host/repositories/" + reposID, + type : 'GET', + contentType : 'application/json', + dataType : 'json', + success : suc, + error : err + }); + }, + + updateRepository : function(name, settings, suc, err) { + var reposID = encodeURIComponent(name); + $.ajax({ + url : kimchi.url + "host/repositories/" + reposID, + type : 'PUT', + contentType : 'application/json', + data : JSON.stringify(settings), + dataType : 'json', + success : suc, + error : err + }); + }, + + enableRepository : function(name, enable, suc, err) { + var reposID = encodeURIComponent(name); + $.ajax({ + url : kimchi.url + "host/repositories/" + reposID + + '/' + (enable === true ? 'enable' : 'disable'), + type : 'POST', + contentType : 'application/json', + dataType : 'json', + success : suc, + error : err + }); + }, + + deleteRepository : function(repository, suc, err) { + var reposID = encodeURIComponent(repository); + kimchi.requestJSON({ + url : kimchi.url + 'host/repositories/' + reposID, + type : 'DELETE', + contentType : 'application/json', + dataType : 'json', + success : suc, + error : err + }); + }, + + listRepositories : function(suc, err) { + kimchi.requestJSON({ + url : kimchi.url + 'host/repositories', + type : 'GET', + contentType : 'application/json', + dataType : 'json', + resend: true, + success : suc, + error : err + }); + } }; -- 1.8.1.4

From: Hongliang Wang <hlwang@linux.vnet.ibm.com> Add repository. Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> Signed-off-by: Adam King <rak@linux.vnet.ibm.com> --- ui/css/theme-default/repository-add.css | 39 +++++++++++ ui/js/src/kimchi.repository_add_main.js | 84 +++++++++++++++++++++++ ui/pages/repository-add.html.tmpl | 115 ++++++++++++++++++++++++++++++++ 3 files changed, 238 insertions(+) create mode 100644 ui/css/theme-default/repository-add.css create mode 100644 ui/js/src/kimchi.repository_add_main.js create mode 100644 ui/pages/repository-add.html.tmpl diff --git a/ui/css/theme-default/repository-add.css b/ui/css/theme-default/repository-add.css new file mode 100644 index 0000000..2434efd --- /dev/null +++ b/ui/css/theme-default/repository-add.css @@ -0,0 +1,39 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Authors: + * Hongliang Wang <hlwang@linux.vnet.ibm.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#repository-add-window { + height: 680px; + width: 1000px; +} + +#repository-add-window .required { + color: red; + padding-left: 5px; + vertical-align: top; +} + +#repository-add-window .textbox-wrapper input[type="text"] { + box-sizing: border-box; + width: 100%; +} + +#repository-add-window .textbox-wrapper label { + vertical-align: middle; +} diff --git a/ui/js/src/kimchi.repository_add_main.js b/ui/js/src/kimchi.repository_add_main.js new file mode 100644 index 0000000..f08c209 --- /dev/null +++ b/ui/js/src/kimchi.repository_add_main.js @@ -0,0 +1,84 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Authors: + * Hongliang Wang <hlwang@linux.vnet.ibm.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +kimchi.repository_add_main = function() { + + var addForm = $('#form-repository-add'); + var addButton = $('#button-repository-add'); + + var validateField = function(event) { + var valid=($(this).val()!==''); + $(addButton).prop('disabled', !valid); + return(valid); + }; + + var validateForm = function(event) { + var valid=false; + addForm.find('input.required').each( function() { + valid=($(this).val()!==''); + return(!valid); + }); + return(valid); + } + + addForm.find('input.required').on('input propertychange', validateField); + + var weedObject = function(obj) { + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + if((typeof(obj[key])==="object") && !Array.isArray(obj[key])) { + weedObject(obj[key]); + } + else if(obj[key] == '') { + delete obj[key]; + } + } + } + } + + var addRepository = function(event) { + var valid = validateForm(); + if(!valid) { + return false; + } + + var formData = $(addForm).serializeObject(); + if (formData && formData.config) { + formData.config.gpgcheck=(String(formData.config.gpgcheck).toLowerCase() === 'true'); + } + weedObject(formData); + + + kimchi.createRepository(formData, function() { + kimchi.topic('kimchi/repositoryAdded').publish(); + kimchi.window.close(); + }, function(jqXHR, textStatus, errorThrown) { + var reason = jqXHR && + jqXHR['responseJSON'] && + jqXHR['responseJSON']['reason']; + reason = reason ? ': ' + reason : ''; + kimchi.message.error(i18n['KCHREPO6015M'] + reason); + }); + + return false; + }; + + $(addForm).on('submit', addRepository); +}; diff --git a/ui/pages/repository-add.html.tmpl b/ui/pages/repository-add.html.tmpl new file mode 100644 index 0000000..991278e --- /dev/null +++ b/ui/pages/repository-add.html.tmpl @@ -0,0 +1,115 @@ +#* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Authors: + * Hongliang Wang <hlwang@linux.vnet.ibm.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *# +#unicode UTF-8 +#import gettext +#from kimchi.cachebust import href +#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang) +#silent _ = t.gettext +#silent _t = t.gettext +<div id="repository-add-window" class="window"> + <form id="form-repository-add"> + <header class="window-header"> + <h1 class="title">$_("Add a Repository")</h1> + <div class="close">X</div> + <fieldset class="repository-edit-fieldset"> + <div class="repository-id"> + <div class="repository-edit-wrapper-label"> + <label for="repository-edit-id-textbox">$_("ID")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-id-textbox" name="repo_id" type="text"/> + </div> + </div> + <div class="repository-name"> + <div class="repository-edit-wrapper-label"> + <label for="repository-edit-name-textbox">$_("Name")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-name-textbox" class="yum" name="config[repo_name]" type="text" /> + </div> + </div> + <div class="repository-dist"> + <div class="repository-edit-wrapper-label"> + <label for="repository-edit-urlargs-textbox">$_("Distribution")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-urlargs-textbox" class="deb" name="config[dist]" type="text" /> + </div> + </div> + <div class="repository-gpgcheck"> + <div class="repository-edit-wrapper-label"> + <label>$_("GPG Check")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-gpgcheck-radio-true" class="yum" name="config[gpgcheck]" type="radio" value="true" /> + <label for="repository-edit-gpgcheck-radio-true">$_("Yes")</label> + <input id="repository-edit-gpgcheck-radio-false" class="yum" name="config[gpgcheck]" type="radio" value="false" checked="checked"/> + <label for="repository-edit-gpgcheck-radio-false">$_("No")</label> + </div> + </div> + </fieldset> + <fieldset class="repository-edit-fieldset"> + <div class="repository-url"> + <div class="repository-edit-wrapper-label"> + <label for="repository-edit-baseurl-textbox">$_("URL")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-baseurl-textbox" class="required" name="baseurl" type="text" /> + </div> + </div> + <div class="repository-mirrorlist"> + <div class="repository-edit-wrapper-label"> + <label for="repository-edit-urlargs-textbox">$_("Mirror List URL")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-urlargs-textbox" class="yum required" name="config[mirrorlist]" type="text" /> + </div> + </div> + <div class="repository-comps"> + <div class="repository-edit-wrapper-label"> + <label for="repository-edit-urlargs-textbox">$_("Components")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-urlargs-textbox" class="deb" name="config[comps]" type="text" /> + </div> + </div> + <div class="repository-gpgkey"> + <div class="repository-edit-wrapper-label"> + <label for="repository-edit-gpgkey-textbox">$_("GPG Key")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-gpgkey-textbox" class="yum" name="config[gpgkey]" type="text" /> + </div> + </div> + </fieldset> + </header> + <footer> + <div class="btn-group"> + <button type="submit" id="button-repository-add" class="btn-normal" disabled="disabled"> + <span class="text">$_("Add")</span> + </button> + </div> + </footer> + </form> +</div> +<script> + kimchi.repository_add_main(); +</script> -- 1.8.1.4

From: Hongliang Wang <hlwang@linux.vnet.ibm.com> Edit repository support. Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> Signed-off-by: Adam King <rak@linux.vnet.ibm.com> --- ui/css/theme-default/repository-edit.css | 128 +++++++++++++++++++++++++++++++ ui/js/src/kimchi.repository_edit_main.js | 94 +++++++++++++++++++++++ ui/pages/repository-edit.html.tmpl | 115 +++++++++++++++++++++++++++ 3 files changed, 337 insertions(+) create mode 100644 ui/css/theme-default/repository-edit.css create mode 100644 ui/js/src/kimchi.repository_edit_main.js create mode 100644 ui/pages/repository-edit.html.tmpl diff --git a/ui/css/theme-default/repository-edit.css b/ui/css/theme-default/repository-edit.css new file mode 100644 index 0000000..df6bbdb --- /dev/null +++ b/ui/css/theme-default/repository-edit.css @@ -0,0 +1,128 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Authors: + * Hongliang Wang <hlwang@linux.vnet.ibm.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#repository-edit-window { + height: 420px; + width: 1000px; +} + +.repository-edit-fieldset { + float: left; + padding: 1em; + width: 450px; +} + +.repository-edit-wrapper-label, .repository-edit-wrapper-controls { + display: inline-block; + height: 38px; + line-height: 38px; + margin-top: 5px; + vertical-align: top; +} + +.repository-edit-wrapper-label { + width: 150px; +} + +.repository-edit-wrapper-controls label { + vertical-align: middle; +} + +.repository-edit-wrapper-controls { + width: 300px; +} + +.repository-edit-wrapper-controls input[type="text"] { + font-size: 16px; + height: 38px; + line-height: 38px; + background: #fff; + -webkit-border-radius: 5px; + border-radius: 5px; + box-shadow: 2px 2px 2px #eee inset; + border-top: 1px solid #bbb; + border-left: 1px solid #bbb; + padding: 0 10px; + width: 400px; +} + + +.repository-edit-wrapper-controls input[type="text"][readonly] { + color: #bbb; + background-color: #fafafa; +} + + +.repository-edit-wrapper-controls input[type="text"][disabled] { + color: #bbb; + background-color: #fafafa; + cursor: not-allowed; +} + +/* +.repository-gpgcheck { + width: 60px; +} + +.yum .repository-id{ + width: 70px; +} + +.yum .repository-gpgkey { + width: 400px; +} + +.yum .repository-mirrorlist { + width: 400px; +} +*/ + +.yum .repository-dist { + display: none; +} + +.yum .repository-comps { + display: none; +} + +.deb .repository-id{ + display: none; +} + +.deb .repository-name { + display: none; +} + +.deb .repository-gpgkey { + display: none; +} + +.deb .repository-mirrorlist { + display: none; +} +/* +.deb .repository-dist { + width: 300px; +} + +.deb .repository-comps { + width: 400px; +} +*/ diff --git a/ui/js/src/kimchi.repository_edit_main.js b/ui/js/src/kimchi.repository_edit_main.js new file mode 100644 index 0000000..13af36c --- /dev/null +++ b/ui/js/src/kimchi.repository_edit_main.js @@ -0,0 +1,94 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +kimchi.repository_fillForm = function(form, name, values) { + var name= (name=="" || !name) ? "%s" : name; + for(var prop in values) { + if ((typeof(values[prop])==="object") && !Array.isArray(values[prop])) { + tmpName=name.replace("%s", prop+"[%s]" ); + kimchi.repository_fillForm(form, tmpName, values[prop]); + } + else { + tmpName=name.replace("%s", prop ); + var control = $('input[name="' + tmpName + '"]', form); + switch($(control).attr('type')) { + case 'text': + $(control).val(values[prop]); + break; + case 'radio': + case 'checkbox': + $(control).each(function(i, c) { + var matched = ('' + values[prop]) == $(c).val(); + $(c).prop('checked', matched); + }); + break; + default: + break; + } + } + } +} + +kimchi.repository_edit_main = function() { + + var editForm = $('#form-repository-edit'); + + var saveButton = $('#repository-edit-button-save'); + + if(kimchi.host.capabilities['repo_mngt_tool']=="yum") { + editForm.find('input.deb').prop('disabled', true); + } + else if(kimchi.host.capabilities['repo_mngt_tool']=="deb") { + editForm.find('input.yum').prop('disabled', true); + } + + kimchi.retrieveRepository(kimchi.selectedRepository, function(repository) { + kimchi.repository_fillForm(editForm,"",repository); + + $('input', editForm).on('input propertychange', function(event) { + if($(this).val() !== '') { + $(saveButton).prop('disabled', false); + } + }); + }); + + + var editRepository = function(event) { + var formData = $(editForm).serializeObject(); + + if (formData && formData.config) { + formData.config.gpgcheck=(String(formData.config.gpgcheck).toLowerCase() === 'true'); + } + + kimchi.updateRepository(kimchi.selectedRepository, formData, function() { + kimchi.topic('kimchi/repositoryUpdated').publish(); + kimchi.window.close(); + }, function(jqXHR, textStatus, errorThrown) { + var reason = jqXHR && + jqXHR['responseJSON'] && + jqXHR['responseJSON']['reason']; + reason = reason ? ': ' + reason : ''; + kimchi.message.error(i18n['KCHREPO6015M'] + reason); + }); + + return false; + }; + + $(editForm).on('submit', editRepository); + $(saveButton).on('click', editRepository); +}; diff --git a/ui/pages/repository-edit.html.tmpl b/ui/pages/repository-edit.html.tmpl new file mode 100644 index 0000000..b13cba3 --- /dev/null +++ b/ui/pages/repository-edit.html.tmpl @@ -0,0 +1,115 @@ +#* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *# +#unicode UTF-8 +#import gettext +#from kimchi.cachebust import href +#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang) +#silent _ = t.gettext +#silent _t = t.gettext + +<div id="repository-edit-window" class="window"> + <header> + <h1 class="title">$_("Edit Repository")</h1> + <div class="close">X</div> + </header> + <div class="content"> + <form id="form-repository-edit"> + <fieldset class="repository-edit-fieldset"> + <div class="repository-id"> + <div class="repository-edit-wrapper-label"> + <label for="repository-edit-id-textbox">$_("ID")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-id-textbox" name="repo_id" type="text" disabled="disabled" readonly="readonly"/> + </div> + </div> + <div class="repository-name"> + <div class="repository-edit-wrapper-label"> + <label for="repository-edit-name-textbox">$_("Name")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-name-textbox" class="yum" name="config[repo_name]" type="text" /> + </div> + </div> + <div class="repository-dist"> + <div class="repository-edit-wrapper-label"> + <label for="repository-edit-urlargs-textbox">$_("Distribution")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-urlargs-textbox" class="deb" name="config[dist]" type="text" /> + </div> + </div> + <div class="repository-gpgcheck"> + <div class="repository-edit-wrapper-label"> + <label>$_("GPG Check")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-gpgcheck-radio-true" class="yum" name="config[gpgcheck]" type="radio" value="true" /> + <label for="repository-edit-gpgcheck-radio-true">$_("Yes")</label> + <input id="repository-edit-gpgcheck-radio-false" class="yum" name="config[gpgcheck]" type="radio" value="false" /> + <label for="repository-edit-gpgcheck-radio-false">$_("No")</label> + </div> + </div> + </fieldset> + <fieldset class="repository-edit-fieldset"> + <div class="repository-url"> + <div class="repository-edit-wrapper-label"> + <label for="repository-edit-baseurl-textbox">$_("URL")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-baseurl-textbox" name="baseurl" type="text" /> + </div> + </div> + <div class="repository-mirrorlist"> + <div class="repository-edit-wrapper-label"> + <label for="repository-edit-urlargs-textbox">$_("Mirror List URL")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-urlargs-textbox" class="yum" name="config[mirrorlist]" type="text" /> + </div> + </div> + <div class="repository-comps"> + <div class="repository-edit-wrapper-label"> + <label for="repository-edit-urlargs-textbox">$_("Components")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-urlargs-textbox" class="deb" name="config[comps]" type="text" /> + </div> + </div> + <div class="repository-gpgkey"> + <div class="repository-edit-wrapper-label"> + <label for="repository-edit-gpgkey-textbox">$_("GPG Key")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-gpgkey-textbox" class="yum" name="config[gpgkey]" type="text" /> + </div> + </div> + </fieldset> + </form> + </div> + <footer> + <div class="btn-group"> + <button id="repository-edit-button-save" class="btn-normal"> + <span class="text">$_("Save")</span> + </button> + </div> + </footer> +</div> +<script type="text/javascript"> + kimchi.repository_edit_main(); +</script> -- 1.8.1.4

From: Hongliang Wang <hlwang@linux.vnet.ibm.com> Integrate add/enable/disalbe/edit/remove a repository feature into host tab. Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> Signed-off-by: Adam King <rak@linux.vnet.ibm.com> --- po/POTFILES.in | 2 + ui/css/theme-default/host.css | 8 ++ ui/js/src/kimchi.host.js | 185 ++++++++++++++++++++++++++++++++++++++++++ ui/pages/tabs/host.html.tmpl | 13 +++ 4 files changed, 208 insertions(+) diff --git a/po/POTFILES.in b/po/POTFILES.in index 4ff7eaa..955a675 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -7,6 +7,8 @@ ui/pages/i18n.html.tmpl ui/pages/kimchi-ui.html.tmpl ui/pages/login-window.html.tmpl ui/pages/report-add.html.tmpl +ui/pages/repository-add.html.tmpl +ui/pages/repository-edit.html.tmpl ui/pages/storagepool-add.html.tmpl ui/pages/tabs/guests.html.tmpl ui/pages/tabs/host.html.tmpl diff --git a/ui/css/theme-default/host.css b/ui/css/theme-default/host.css index 0f8b941..0ca6684 100644 --- a/ui/css/theme-default/host.css +++ b/ui/css/theme-default/host.css @@ -253,3 +253,11 @@ width: 846px; } /* End of Software Updates */ + +/* Repository */ +.host-panel #repositories-grid { + border-color: #ddd; + height: 200px; + width: 850px; +} +/* End of Repository */ diff --git a/ui/js/src/kimchi.host.js b/ui/js/src/kimchi.host.js index 6300f37..bd07561 100644 --- a/ui/js/src/kimchi.host.js +++ b/ui/js/src/kimchi.host.js @@ -15,6 +15,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +kimchi.host={}; + kimchi.host_main = function() { var expand = function(header, toExpand) { var controlledNode = $(header).attr('aria-controls'); @@ -22,6 +24,169 @@ kimchi.host_main = function() { $(header).attr('aria-expanded', toExpand ? 'true' : 'false'); }; + var repositoriesGrid = null; + var initRepositoriesGrid = function(repo_type) { + var gridFields=[]; + if (repo_type == "yum") { + gridFields=[{ + name: 'repo_id', + label: i18n['KCHREPO6004M'], + 'class': 'repository-id' + }, { + name: 'config.repo_name', + label: i18n['KCHREPO6005M'], + 'class': 'repository-name' + }, { + name: 'enabled', + label: i18n['KCHREPO6009M'], + 'class': 'repository-enabled' + }]; + } + else if (repo_type == "deb") { + gridFields=[{ + name: 'baseurl', + label: i18n['KCHREPO6006M'], + makeTitle: true, + 'class': 'repository-baseurl' + }, { + name: 'enabled', + label: i18n['KCHREPO6009M'], + 'class': 'repository-enabled' + }, { + name: 'config.dist', + label: "dist", + 'class': 'repository-gpgcheck' + }, { + name: 'config.comps', + label: "comps", + 'class': 'repository-gpgcheck' + }]; + } + else { + gridFields=[{ + name: 'repo_id', + label: i18n['KCHREPO6004M'], + 'class': 'repository-id' + }, { + name: 'enabled', + label: i18n['KCHREPO6009M'], + 'class': 'repository-enabled' + }, { + name: 'baseurl', + label: i18n['KCHREPO6006M'], + makeTitle: true, + 'class': 'repository-baseurl' + }, { + name: 'gpgcheck', + label: i18n['KCHREPO6010M'], + 'class': 'repository-gpgcheck' + }]; + } + repositoriesGrid = new kimchi.widget.Grid({ + container: 'repositories-grid-container', + id: 'repositories-grid', + title: i18n['KCHREPO6003M'], + toolbarButtons: [{ + id: 'repositories-grid-add-button', + label: i18n['KCHREPO6012M'], + onClick: function(event) { + kimchi.window.open({url:'repository-add.html', class: repo_type}); + } + }, { + id: 'repositories-grid-enable-button', + label: i18n['KCHREPO6016M'], + disabled: true, + onClick: function(event) { + var repository = repositoriesGrid.getSelected(); + if(!repository) { + return; + } + var name = repository['repo_id']; + var enable = !repository['enabled']; + $(this).prop('disabled', true); + kimchi.enableRepository(name, enable, function() { + kimchi.topic('kimchi/repositoryUpdated').publish(); + }); + } + }, { + id: 'repositories-grid-edit-button', + label: i18n['KCHREPO6013M'], + disabled: true, + onClick: function(event) { + var repository = repositoriesGrid.getSelected(); + if(!repository) { + return; + } + kimchi.selectedRepository = repository['repo_id']; + kimchi.window.open({url:'repository-edit.html', class: repo_type}); + } + }, { + id: 'repositories-grid-remove-button', + label: i18n['KCHREPO6014M'], + disabled: true, + onClick: function(event) { + var repository = repositoriesGrid.getSelected(); + if(!repository) { + return; + } + + var settings = { + title : i18n['KCHREPO6001M'], + content : i18n['KCHREPO6002M'], + confirm : i18n['KCHAPI6004M'], + cancel : i18n['KCHAPI6003M'] + }; + + kimchi.confirm(settings, function() { + kimchi.deleteRepository( + repository['repo_id'], + function(result) { + kimchi.topic('kimchi/repositoryDeleted').publish(result); + }, function(error) { + } + ); + }); + } + }], + onRowSelected: function(row) { + var repository = repositoriesGrid.getSelected(); + if(!repository) { + return; + } + $('#repositories-grid-remove-button').prop('disabled', false); + $('#repositories-grid-edit-button').prop('disabled', false); + var enabled = repository['enabled']; + $('#repositories-grid-enable-button') + .text(i18n[enabled ? 'KCHREPO6017M' : 'KCHREPO6016M']) + .prop('disabled', false); + }, + frozenFields: [], + fields: gridFields, + data: listRepositories + }); + }; + + var listRepositories = function(gridCallback) { + kimchi.listRepositories(function(repositories) { + if($.isFunction(gridCallback)) { + gridCallback(repositories); + } + else { + if(repositoriesGrid) { + repositoriesGrid.setData(repositories); + } + else { + initRepositoriesGrid(); + repositoriesGrid.setData(repositories); + } + } + }); + + $('#repositories-grid-remove-button').prop('disabled', true); + $('#repositories-grid-edit-button').prop('disabled', true); + $('#repositories-grid-enable-button').prop('disabled', true); + }; + var softwareUpdatesGridID = 'software-updates-grid'; var softwareUpdatesGrid = null; var progressAreaID = 'software-updates-progress-textarea'; @@ -271,6 +436,18 @@ kimchi.host_main = function() { }); kimchi.getCapabilities(function(capabilities) { + kimchi.host.capabilities=capabilities; + if((capabilities['repo_mngt_tool']) && (capabilities['repo_mngt_tool']!="None")) { + initRepositoriesGrid(capabilities['repo_mngt_tool']); + $('#repositories-section').switchClass('hidden', capabilities['repo_mngt_tool']); + kimchi.topic('kimchi/repositoryAdded') + .subscribe(listRepositories); + kimchi.topic('kimchi/repositoryUpdated') + .subscribe(listRepositories); + kimchi.topic('kimchi/repositoryDeleted') + .subscribe(listRepositories); + } + if(capabilities['update_tool']) { $('#software-update-section').removeClass('hidden'); initSoftwareUpdatesGrid(); @@ -552,6 +729,14 @@ kimchi.host_main = function() { delete kimchi.hostTimer; } + repositoriesGrid && repositoriesGrid.destroy(); + kimchi.topic('kimchi/repositoryAdded') + .unsubscribe(listRepositories); + kimchi.topic('kimchi/repositoryUpdated') + .unsubscribe(listRepositories); + kimchi.topic('kimchi/repositoryDeleted') + .unsubscribe(listRepositories); + softwareUpdatesGrid && softwareUpdatesGrid.destroy(); kimchi.topic('kimchi/softwareUpdated').unsubscribe(listSoftwareUpdates); diff --git a/ui/pages/tabs/host.html.tmpl b/ui/pages/tabs/host.html.tmpl index 179deba..eaab451 100644 --- a/ui/pages/tabs/host.html.tmpl +++ b/ui/pages/tabs/host.html.tmpl @@ -120,6 +120,19 @@ </div> </div> </div> + <div id="repositories-section" class="host-section hidden"> + <h3 class="section-header" + aria-controls="content-repositories"> + $_("Repositories") + </h3> + <div id="content-repositories" class="section-content"> + <div class="section-row"> + <div class="section-value"> + <div id="repositories-grid-container"></div> + </div> + </div> + </div> + </div> <div id="software-update-section" class="host-section hidden"> <h3 class="section-header" aria-controls="content-software-update"> -- 1.8.1.4
participants (1)
-
Adam King