[PATCH 0/4] UI: Download Remote Image Feature

Implemented download remote image feature. Seems something wrong with /tasks response. The "message" is always "OK" and I can't retrieve the progress information. Dependancies: * [PATCH] storagevolume: Use default value for param 'name' when appropriate Hongliang Wang (4): Download Remote Image UI: Add Common API to kimchi.api.js Download Remote Image UI: Add Corresponding Window Download Remote Image UI: Updated i18n Strings Download Remote Image UI: Implemented the Feature ui/css/theme-default/storage.css | 31 ++++++- ui/css/theme-default/storagepool-add-volume.css | 36 ++++++++ ui/js/src/kimchi.api.js | 49 +++++++++++ ui/js/src/kimchi.storage_main.js | 77 +++++++++++++++-- ui/js/src/kimchi.storagepool_add_volume_main.js | 110 ++++++++++++++++++++++++ ui/pages/i18n.json.tmpl | 3 + ui/pages/storagepool-add-volume.html.tmpl | 80 +++++++++++++++++ ui/pages/tabs/storage.html.tmpl | 12 ++- 8 files changed, 388 insertions(+), 10 deletions(-) create mode 100644 ui/css/theme-default/storagepool-add-volume.css create mode 100644 ui/js/src/kimchi.storagepool_add_volume_main.js create mode 100644 ui/pages/storagepool-add-volume.html.tmpl -- 1.8.1.4

Added APIs to kimchi.api.js. Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/js/src/kimchi.api.js | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index 5fc456d..393962b 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -1130,5 +1130,54 @@ var kimchi = { kimchi.message.error(data.responseJSON.reason); } }); + }, + + /** + * Add a volume to a given storage pool by URL. + */ + downloadVolumeToSP: function(settings, suc, err) { + var url = settings['url']; + var name = settings['name']; + var sp = encodeURIComponent(settings['sp']); + kimchi.requestJSON({ + url : kimchi.url + 'storagepools/' + sp + '/storagevolumes', + type : 'POST', + data : JSON.stringify({ + name: name, + url: url + }), + contentType : 'application/json', + dataType : 'json', + success : suc, + error : err + }); + }, + + makeTaskTrackFunc: function(task) { + return function(suc, err, progress) { + var onTaskResponse = function(result) { + var taskStatus = result['status']; + switch(taskStatus) { + case 'running': + progress && progress(result); + setTimeout(trackTask, 200); + break; + case 'finished': + suc(result); + break; + case 'failed': + err(result); + break; + default: + break; + } + }; + + var trackTask = function() { + kimchi.getTask(task, onTaskResponse, err); + }; + + trackTask(); + }; } }; -- 1.8.1.4

On 09/10/2014 09:02 AM, Hongliang Wang wrote:
Added APIs to kimchi.api.js.
Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/js/src/kimchi.api.js | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+)
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index 5fc456d..393962b 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -1130,5 +1130,54 @@ var kimchi = { kimchi.message.error(data.responseJSON.reason); } }); + }, + + /** + * Add a volume to a given storage pool by URL. + */ + downloadVolumeToSP: function(settings, suc, err) { + var url = settings['url']; + var name = settings['name']; + var sp = encodeURIComponent(settings['sp']); + kimchi.requestJSON({ + url : kimchi.url + 'storagepools/' + sp + '/storagevolumes', + type : 'POST', + data : JSON.stringify({ + name: name, + url: url + }), + contentType : 'application/json', + dataType : 'json', + success : suc, + error : err + }); + }, +
+ makeTaskTrackFunc: function(task) { + return function(suc, err, progress) { + var onTaskResponse = function(result) { + var taskStatus = result['status']; + switch(taskStatus) { + case 'running': + progress && progress(result); + setTimeout(trackTask, 200); + break; + case 'finished': + suc(result); + break; + case 'failed': + err(result); + break; + default: + break; + } + }; + + var trackTask = function() { + kimchi.getTask(task, onTaskResponse, err); + }; + + trackTask(); + };
A recently code merged already created a function like above (trackTask) - you can use it.
} };

On 09/11/2014 04:23 AM, Aline Manera wrote:
On 09/10/2014 09:02 AM, Hongliang Wang wrote:
Added APIs to kimchi.api.js.
Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/js/src/kimchi.api.js | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+)
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index 5fc456d..393962b 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -1130,5 +1130,54 @@ var kimchi = { kimchi.message.error(data.responseJSON.reason); } }); + }, + + /** + * Add a volume to a given storage pool by URL. + */ + downloadVolumeToSP: function(settings, suc, err) { + var url = settings['url']; + var name = settings['name']; + var sp = encodeURIComponent(settings['sp']); + kimchi.requestJSON({ + url : kimchi.url + 'storagepools/' + sp + '/storagevolumes', + type : 'POST', + data : JSON.stringify({ + name: name, + url: url + }), + contentType : 'application/json', + dataType : 'json', + success : suc, + error : err + }); + }, +
+ makeTaskTrackFunc: function(task) { + return function(suc, err, progress) { + var onTaskResponse = function(result) { + var taskStatus = result['status']; + switch(taskStatus) { + case 'running': + progress && progress(result); + setTimeout(trackTask, 200); + break; + case 'finished': + suc(result); + break; + case 'failed': + err(result); + break; + default: + break; + } + }; + + var trackTask = function() { + kimchi.getTask(task, onTaskResponse, err); + }; + + trackTask(); + };
A recently code merged already created a function like above (trackTask) - you can use it.
ACK.
} };

On 09/10/2014 09:02 AM, Hongliang Wang wrote:
Added APIs to kimchi.api.js.
Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/js/src/kimchi.api.js | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+)
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index 5fc456d..393962b 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -1130,5 +1130,54 @@ var kimchi = { kimchi.message.error(data.responseJSON.reason); } }); + }, + + /** + * Add a volume to a given storage pool by URL. + */ + downloadVolumeToSP: function(settings, suc, err) {
+ var url = settings['url']; + var name = settings['name'];
Why don't you pass settings direct to data? Seems a duplicated work here.
+ var sp = encodeURIComponent(settings['sp']); + kimchi.requestJSON({ + url : kimchi.url + 'storagepools/' + sp + '/storagevolumes', + type : 'POST', + data : JSON.stringify({ + name: name, + url: url + }),
+ contentType : 'application/json', + dataType : 'json', + success : suc, + error : err + }); + }, + + makeTaskTrackFunc: function(task) { + return function(suc, err, progress) { + var onTaskResponse = function(result) { + var taskStatus = result['status']; + switch(taskStatus) { + case 'running': + progress && progress(result); + setTimeout(trackTask, 200); + break; + case 'finished': + suc(result); + break; + case 'failed': + err(result); + break; + default: + break; + } + }; + + var trackTask = function() { + kimchi.getTask(task, onTaskResponse, err); + }; + + trackTask(); + }; } };

On 09/11/2014 09:12 AM, Aline Manera wrote:
On 09/10/2014 09:02 AM, Hongliang Wang wrote:
Added APIs to kimchi.api.js.
Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/js/src/kimchi.api.js | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+)
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index 5fc456d..393962b 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -1130,5 +1130,54 @@ var kimchi = { kimchi.message.error(data.responseJSON.reason); } }); + }, + + /** + * Add a volume to a given storage pool by URL. + */ + downloadVolumeToSP: function(settings, suc, err) {
+ var url = settings['url']; + var name = settings['name'];
Why don't you pass settings direct to data? Seems a duplicated work here.
There is another property "sp" in settings which is not needed for POST /.../storagevolumes API so a little more work was did here. I'll reduce lines in next patch by deleting "sp" property.
+ var sp = encodeURIComponent(settings['sp']); + kimchi.requestJSON({ + url : kimchi.url + 'storagepools/' + sp + '/storagevolumes', + type : 'POST', + data : JSON.stringify({ + name: name, + url: url + }),
+ contentType : 'application/json', + dataType : 'json', + success : suc, + error : err + }); + }, + + makeTaskTrackFunc: function(task) { + return function(suc, err, progress) { + var onTaskResponse = function(result) { + var taskStatus = result['status']; + switch(taskStatus) { + case 'running': + progress && progress(result); + setTimeout(trackTask, 200); + break; + case 'finished': + suc(result); + break; + case 'failed': + err(result); + break; + default: + break; + } + }; + + var trackTask = function() { + kimchi.getTask(task, onTaskResponse, err); + }; + + trackTask(); + }; } };

Implemented add volume window. Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/css/theme-default/storagepool-add-volume.css | 36 ++++++++ ui/js/src/kimchi.storagepool_add_volume_main.js | 110 ++++++++++++++++++++++++ ui/pages/storagepool-add-volume.html.tmpl | 80 +++++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 ui/css/theme-default/storagepool-add-volume.css create mode 100644 ui/js/src/kimchi.storagepool_add_volume_main.js create mode 100644 ui/pages/storagepool-add-volume.html.tmpl diff --git a/ui/css/theme-default/storagepool-add-volume.css b/ui/css/theme-default/storagepool-add-volume.css new file mode 100644 index 0000000..6e8a551 --- /dev/null +++ b/ui/css/theme-default/storagepool-add-volume.css @@ -0,0 +1,36 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2014 + * + * 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. + */ +#sp-add-volume-window { + height: 400px; + width: 500px; +} + +#sp-add-volume-window .textbox-wrapper input[type="text"] { + box-sizing: border-box; + width: 100%; +} + +#sp-add-volume-window .textbox-wrapper label { + vertical-align: middle; +} + +#sp-add-volume-window input[type="text"][disabled] { + color: #bbb; + background-color: #fafafa; + cursor: not-allowed; +} diff --git a/ui/js/src/kimchi.storagepool_add_volume_main.js b/ui/js/src/kimchi.storagepool_add_volume_main.js new file mode 100644 index 0000000..52d08a2 --- /dev/null +++ b/ui/js/src/kimchi.storagepool_add_volume_main.js @@ -0,0 +1,110 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2014 + * + * 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.sp_add_volume_main = function() { + // download from remote server or upload from local file + var type = 'download'; + + var addButton = $('#sp-add-volume-button'); + + $('input.volume-type').change(function(e) { + $('.volume-input').prop('disabled', true); + $('.volume-input.' + this.value).prop('disabled', false); + type = this.value; + }); + + var onError = function(result) { + if (result['message']) { + var errText = result['message']; + } + else { + var errText = result['responseJSON']['reason']; + } + result && kimchi.message.error(errText); + var volumeName = result['target_uri'].split('/').pop(); + kimchi.topic('kimchi/volumeDownloadError').publish({ + sp: kimchi.selectedSP, + volume: volumeName + }); + }; + + var extractProgressData = function(data) { + var sizeArray = data.split('/'); + var downloaded = sizeArray[0]; + var percent = 0; + if(isNaN(downloaded)) { + downloaded = 0; + } + else { + var total = sizeArray[1]; + percent = downloaded / total * 100; + } + var formatted = kimchi.formatMeasurement(downloaded); + var size = formatted['v'].toFixed(1) + formatted['s']; + return { + size: size, + percent: percent + }; + }; + + var fetchRemoteFile = function() { + var volumeURL = $('#volume-remote-url').val(); + var volumeName = volumeURL.split(/(\\|\/)/g).pop(); + kimchi.downloadVolumeToSP({ + sp: kimchi.selectedSP, + name: volumeName, + url: volumeURL + }, function(resp) { + var taskID = resp['id']; + kimchi.window.close(); + kimchi.topic('kimchi/volumeDownloadStarted').publish({ + sp: kimchi.selectedSP, + volume: volumeName + }); + + kimchi.makeTaskTrackFunc(taskID)(function(result) { + var progress = extractProgressData(resp['message']); + var volumeName = result['target_uri'].split('/').pop(); + kimchi.topic('kimchi/volumeDownloadFinished').publish($.extend(progress, { + sp: kimchi.selectedSP, + volume: volumeName + })); + }, onError, onProgress); + }, onError); + }; + + var onProgress = function(resp) { + var progress = extractProgressData(resp['message']); + var volumeName = resp['target_uri'].split('/').pop(); + kimchi.topic('kimchi/volumeDownloadProgress').publish($.extend(progress, { + sp: kimchi.selectedSP, + volume: volumeName + })); + + }; + + $(addButton).on('click', function(event) { + $(this).prop('disabled', true); + if(type === 'download') { + fetchRemoteFile(); + } + else { + // uploadFile(); + } + event.preventDefault(); + }); +}; diff --git a/ui/pages/storagepool-add-volume.html.tmpl b/ui/pages/storagepool-add-volume.html.tmpl new file mode 100644 index 0000000..148a17b --- /dev/null +++ b/ui/pages/storagepool-add-volume.html.tmpl @@ -0,0 +1,80 @@ +#* + * Project Kimchi + * + * Copyright IBM, Corp. 2014 + * + * 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="sp-add-volume-window" class="window"> + <form id="form-sp-add-volume"> + <header class="window-header"> + <h1 class="title">$_("Add a Volume to Storage Pool")</h1> + <div class="close">X</div> + </header> + <section> + <div class="content"> + <div class="form-section"> + <h2> + <input type="radio" id="volume-type-download" class="volume-type" name="volumeType" value="download" checked="checked" /> + <label for="volume-type-download"> + $_("Fetch from remote URL") + </label> + </h2> + <div class="field"> + <p class="text-help"> + $_("Enter the remote URL here.") + </p> + <div class="textbox-wrapper"> + <input type="text" id="volume-remote-url" class="text volume-input download" name="volumeRemoteURL" /> + </div> + </div> + </div> + <div class="form-section"> + <h2> + <input type="radio" id="volume-type-upload" class="volume-type" name="volumeType" value="upload"/> + <label for="volume-type-upload"> + $_("Upload an file") + </label> + </h2> + <div class="field"> + <p class="text-help"> + $_("Choose the file you want to upload.") + </p> + <div class="textbox-wrapper"> + <input type="file" class="volume-input upload" id="volume-input-file" name="volumeLocalFile" disabled="disabled" /> + </div> + </div> + </div> + </div> + </section> + <footer> + <div class="btn-group"> + <button type="submit" id="sp-add-volume-button" class="btn-normal"> + <span class="text">$_("OK")</span> + </button> + </div> + </footer> + </form> +</div> +<script type="text/javascript"> + kimchi.sp_add_volume_main(); +</script> -- 1.8.1.4

On 09/10/2014 09:02 AM, Hongliang Wang wrote:
Implemented add volume window.
Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/css/theme-default/storagepool-add-volume.css | 36 ++++++++ ui/js/src/kimchi.storagepool_add_volume_main.js | 110 ++++++++++++++++++++++++ ui/pages/storagepool-add-volume.html.tmpl | 80 +++++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 ui/css/theme-default/storagepool-add-volume.css create mode 100644 ui/js/src/kimchi.storagepool_add_volume_main.js create mode 100644 ui/pages/storagepool-add-volume.html.tmpl
diff --git a/ui/css/theme-default/storagepool-add-volume.css b/ui/css/theme-default/storagepool-add-volume.css new file mode 100644 index 0000000..6e8a551 --- /dev/null +++ b/ui/css/theme-default/storagepool-add-volume.css @@ -0,0 +1,36 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2014 + * + * 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. + */ +#sp-add-volume-window { + height: 400px; + width: 500px; +} + +#sp-add-volume-window .textbox-wrapper input[type="text"] { + box-sizing: border-box; + width: 100%; +} + +#sp-add-volume-window .textbox-wrapper label { + vertical-align: middle; +} + +#sp-add-volume-window input[type="text"][disabled] { + color: #bbb; + background-color: #fafafa; + cursor: not-allowed; +} diff --git a/ui/js/src/kimchi.storagepool_add_volume_main.js b/ui/js/src/kimchi.storagepool_add_volume_main.js new file mode 100644 index 0000000..52d08a2 --- /dev/null +++ b/ui/js/src/kimchi.storagepool_add_volume_main.js @@ -0,0 +1,110 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2014 + * + * 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.sp_add_volume_main = function() { + // download from remote server or upload from local file + var type = 'download'; + + var addButton = $('#sp-add-volume-button'); + + $('input.volume-type').change(function(e) { + $('.volume-input').prop('disabled', true); + $('.volume-input.' + this.value).prop('disabled', false); + type = this.value; + }); + + var onError = function(result) { + if (result['message']) { + var errText = result['message']; + } + else { + var errText = result['responseJSON']['reason']; + } + result && kimchi.message.error(errText); + var volumeName = result['target_uri'].split('/').pop(); + kimchi.topic('kimchi/volumeDownloadError').publish({ + sp: kimchi.selectedSP, + volume: volumeName + }); + }; + + var extractProgressData = function(data) { + var sizeArray = data.split('/'); + var downloaded = sizeArray[0]; + var percent = 0; + if(isNaN(downloaded)) { + downloaded = 0; + } + else { + var total = sizeArray[1]; + percent = downloaded / total * 100;
Can't you use eval() instead of splitting the string into 2 values
+ } + var formatted = kimchi.formatMeasurement(downloaded); + var size = formatted['v'].toFixed(1) + formatted['s']; + return { + size: size, + percent: percent + }; + }; + + var fetchRemoteFile = function() { + var volumeURL = $('#volume-remote-url').val(); + var volumeName = volumeURL.split(/(\\|\/)/g).pop(); + kimchi.downloadVolumeToSP({ + sp: kimchi.selectedSP, + name: volumeName, + url: volumeURL + }, function(resp) { + var taskID = resp['id']; + kimchi.window.close(); + kimchi.topic('kimchi/volumeDownloadStarted').publish({ + sp: kimchi.selectedSP, + volume: volumeName + }); + + kimchi.makeTaskTrackFunc(taskID)(function(result) { + var progress = extractProgressData(resp['message']); + var volumeName = result['target_uri'].split('/').pop(); + kimchi.topic('kimchi/volumeDownloadFinished').publish($.extend(progress, { + sp: kimchi.selectedSP, + volume: volumeName + })); + }, onError, onProgress); + }, onError); + }; + + var onProgress = function(resp) { + var progress = extractProgressData(resp['message']); + var volumeName = resp['target_uri'].split('/').pop(); + kimchi.topic('kimchi/volumeDownloadProgress').publish($.extend(progress, { + sp: kimchi.selectedSP, + volume: volumeName + })); + + }; + + $(addButton).on('click', function(event) { + $(this).prop('disabled', true); + if(type === 'download') { + fetchRemoteFile(); + } + else { + // uploadFile(); + } + event.preventDefault(); + }); +}; diff --git a/ui/pages/storagepool-add-volume.html.tmpl b/ui/pages/storagepool-add-volume.html.tmpl new file mode 100644 index 0000000..148a17b --- /dev/null +++ b/ui/pages/storagepool-add-volume.html.tmpl @@ -0,0 +1,80 @@ +#* + * Project Kimchi + * + * Copyright IBM, Corp. 2014 + * + * 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="sp-add-volume-window" class="window"> + <form id="form-sp-add-volume"> + <header class="window-header"> + <h1 class="title">$_("Add a Volume to Storage Pool")</h1> + <div class="close">X</div> + </header> + <section> + <div class="content"> + <div class="form-section"> + <h2> + <input type="radio" id="volume-type-download" class="volume-type" name="volumeType" value="download" checked="checked" /> + <label for="volume-type-download"> + $_("Fetch from remote URL") + </label> + </h2> + <div class="field"> + <p class="text-help"> + $_("Enter the remote URL here.") + </p> + <div class="textbox-wrapper"> + <input type="text" id="volume-remote-url" class="text volume-input download" name="volumeRemoteURL" /> + </div> + </div> + </div> + <div class="form-section"> + <h2> + <input type="radio" id="volume-type-upload" class="volume-type" name="volumeType" value="upload"/> + <label for="volume-type-upload"> + $_("Upload an file") + </label> + </h2> + <div class="field"> + <p class="text-help"> + $_("Choose the file you want to upload.") + </p> + <div class="textbox-wrapper"> + <input type="file" class="volume-input upload" id="volume-input-file" name="volumeLocalFile" disabled="disabled" /> + </div> + </div> + </div> + </div> + </section> + <footer> + <div class="btn-group"> + <button type="submit" id="sp-add-volume-button" class="btn-normal"> + <span class="text">$_("OK")</span> + </button> + </div> + </footer> + </form> +</div> +<script type="text/javascript"> + kimchi.sp_add_volume_main(); +</script>

On 09/11/2014 09:16 AM, Aline Manera wrote:
On 09/10/2014 09:02 AM, Hongliang Wang wrote:
Implemented add volume window.
Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/css/theme-default/storagepool-add-volume.css | 36 ++++++++ ui/js/src/kimchi.storagepool_add_volume_main.js | 110 ++++++++++++++++++++++++ ui/pages/storagepool-add-volume.html.tmpl | 80 +++++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 ui/css/theme-default/storagepool-add-volume.css create mode 100644 ui/js/src/kimchi.storagepool_add_volume_main.js create mode 100644 ui/pages/storagepool-add-volume.html.tmpl
diff --git a/ui/css/theme-default/storagepool-add-volume.css b/ui/css/theme-default/storagepool-add-volume.css new file mode 100644 index 0000000..6e8a551 --- /dev/null +++ b/ui/css/theme-default/storagepool-add-volume.css @@ -0,0 +1,36 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2014 + * + * 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. + */ +#sp-add-volume-window { + height: 400px; + width: 500px; +} + +#sp-add-volume-window .textbox-wrapper input[type="text"] { + box-sizing: border-box; + width: 100%; +} + +#sp-add-volume-window .textbox-wrapper label { + vertical-align: middle; +} + +#sp-add-volume-window input[type="text"][disabled] { + color: #bbb; + background-color: #fafafa; + cursor: not-allowed; +} diff --git a/ui/js/src/kimchi.storagepool_add_volume_main.js b/ui/js/src/kimchi.storagepool_add_volume_main.js new file mode 100644 index 0000000..52d08a2 --- /dev/null +++ b/ui/js/src/kimchi.storagepool_add_volume_main.js @@ -0,0 +1,110 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2014 + * + * 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.sp_add_volume_main = function() { + // download from remote server or upload from local file + var type = 'download'; + + var addButton = $('#sp-add-volume-button'); + + $('input.volume-type').change(function(e) { + $('.volume-input').prop('disabled', true); + $('.volume-input.' + this.value).prop('disabled', false); + type = this.value; + }); + + var onError = function(result) { + if (result['message']) { + var errText = result['message']; + } + else { + var errText = result['responseJSON']['reason']; + } + result && kimchi.message.error(errText); + var volumeName = result['target_uri'].split('/').pop(); + kimchi.topic('kimchi/volumeDownloadError').publish({ + sp: kimchi.selectedSP, + volume: volumeName + }); + }; + + var extractProgressData = function(data) { + var sizeArray = data.split('/'); + var downloaded = sizeArray[0]; + var percent = 0; + if(isNaN(downloaded)) { + downloaded = 0; + } + else { + var total = sizeArray[1]; + percent = downloaded / total * 100;
Can't you use eval() instead of splitting the string into 2 values
1. eval() is supposed not to be abused due to security and performance. (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Obj...) 2. We need 2 parts: downloaded size, and total size. When eval('1024/2048') we'll get only the percentage without total size information. I'll use regular expression to make here clearer.
+ } + var formatted = kimchi.formatMeasurement(downloaded); + var size = formatted['v'].toFixed(1) + formatted['s']; + return { + size: size, + percent: percent + }; + }; + + var fetchRemoteFile = function() { + var volumeURL = $('#volume-remote-url').val(); + var volumeName = volumeURL.split(/(\\|\/)/g).pop(); + kimchi.downloadVolumeToSP({ + sp: kimchi.selectedSP, + name: volumeName, + url: volumeURL + }, function(resp) { + var taskID = resp['id']; + kimchi.window.close(); + kimchi.topic('kimchi/volumeDownloadStarted').publish({ + sp: kimchi.selectedSP, + volume: volumeName + }); + + kimchi.makeTaskTrackFunc(taskID)(function(result) { + var progress = extractProgressData(resp['message']); + var volumeName = result['target_uri'].split('/').pop(); + kimchi.topic('kimchi/volumeDownloadFinished').publish($.extend(progress, { + sp: kimchi.selectedSP, + volume: volumeName + })); + }, onError, onProgress); + }, onError); + }; + + var onProgress = function(resp) { + var progress = extractProgressData(resp['message']); + var volumeName = resp['target_uri'].split('/').pop(); + kimchi.topic('kimchi/volumeDownloadProgress').publish($.extend(progress, { + sp: kimchi.selectedSP, + volume: volumeName + })); + + }; + + $(addButton).on('click', function(event) { + $(this).prop('disabled', true); + if(type === 'download') { + fetchRemoteFile(); + } + else { + // uploadFile(); + } + event.preventDefault(); + }); +}; diff --git a/ui/pages/storagepool-add-volume.html.tmpl b/ui/pages/storagepool-add-volume.html.tmpl new file mode 100644 index 0000000..148a17b --- /dev/null +++ b/ui/pages/storagepool-add-volume.html.tmpl @@ -0,0 +1,80 @@ +#* + * Project Kimchi + * + * Copyright IBM, Corp. 2014 + * + * 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="sp-add-volume-window" class="window"> + <form id="form-sp-add-volume"> + <header class="window-header"> + <h1 class="title">$_("Add a Volume to Storage Pool")</h1> + <div class="close">X</div> + </header> + <section> + <div class="content"> + <div class="form-section"> + <h2> + <input type="radio" id="volume-type-download" class="volume-type" name="volumeType" value="download" checked="checked" /> + <label for="volume-type-download"> + $_("Fetch from remote URL") + </label> + </h2> + <div class="field"> + <p class="text-help"> + $_("Enter the remote URL here.") + </p> + <div class="textbox-wrapper"> + <input type="text" id="volume-remote-url" class="text volume-input download" name="volumeRemoteURL" /> + </div> + </div> + </div> + <div class="form-section"> + <h2> + <input type="radio" id="volume-type-upload" class="volume-type" name="volumeType" value="upload"/> + <label for="volume-type-upload"> + $_("Upload an file") + </label> + </h2> + <div class="field"> + <p class="text-help"> + $_("Choose the file you want to upload.") + </p> + <div class="textbox-wrapper"> + <input type="file" class="volume-input upload" id="volume-input-file" name="volumeLocalFile" disabled="disabled" /> + </div> + </div> + </div> + </div> + </section> + <footer> + <div class="btn-group"> + <button type="submit" id="sp-add-volume-button" class="btn-normal"> + <span class="text">$_("OK")</span> + </button> + </div> + </footer> + </form> +</div> +<script type="text/javascript"> + kimchi.sp_add_volume_main(); +</script>

On 11-09-2014 04:37, Hongliang Wang wrote:
1. eval() is supposed not to be abused due to security and performance. (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Obj...)
ACK
2. We need 2 parts: downloaded size, and total size. When eval('1024/2048') we'll get only the percentage without total size information. I'll use regular expression to make here clearer.
ACK. Also, the second number (i.e. "total") may be "-" when the HTTP header "Content-Length" is not available. This patch needs to check that case as well.

On 09/11/2014 09:45 PM, Crístian Viana wrote:
On 11-09-2014 04:37, Hongliang Wang wrote:
1. eval() is supposed not to be abused due to security and performance. (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Obj...)
ACK
2. We need 2 parts: downloaded size, and total size. When eval('1024/2048') we'll get only the percentage without total size information. I'll use regular expression to make here clearer.
ACK.
Also, the second number (i.e. "total") may be "-" when the HTTP header "Content-Length" is not available. This patch needs to check that case as well. ACK. Thanks!

On 10-09-2014 09:02, Hongliang Wang wrote:
+ var fetchRemoteFile = function() { + var volumeURL = $('#volume-remote-url').val(); + var volumeName = volumeURL.split(/(\\|\/)/g).pop(); + kimchi.downloadVolumeToSP({ + sp: kimchi.selectedSP, + name: volumeName, + url: volumeURL
If you want to, you may omit the parameter 'name' when sending the POST request to create a storage volume because the backend uses a default value (the string after the last '/') when that parameter is not found.

On 09/11/2014 10:00 PM, Crístian Viana wrote:
On 10-09-2014 09:02, Hongliang Wang wrote:
+ var fetchRemoteFile = function() { + var volumeURL = $('#volume-remote-url').val(); + var volumeName = volumeURL.split(/(\\|\/)/g).pop(); + kimchi.downloadVolumeToSP({ + sp: kimchi.selectedSP, + name: volumeName, + url: volumeURL
If you want to, you may omit the parameter 'name' when sending the POST request to create a storage volume because the backend uses a default value (the string after the last '/') when that parameter is not found. OK. Cool!

Added i18n strings accordingly. Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/pages/i18n.json.tmpl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ui/pages/i18n.json.tmpl b/ui/pages/i18n.json.tmpl index d920ae2..b3bca53 100644 --- a/ui/pages/i18n.json.tmpl +++ b/ui/pages/i18n.json.tmpl @@ -169,6 +169,9 @@ "KCHPOOL6011M": "$_("No available partitions found.")", "KCHPOOL6012M": "$_("This storage pool is not persistent. Instead of deactivate, this action will permanently delete it. Would you like to continue?")", "KCHPOOL6013M": "$_("Unable to retrieve partitions information.")", + "KCHPOOL6014M": "$_("Downloading...")", + "KCHPOOL6015M": "$_("Done!")", + "KCHPOOL6016M": "$_("Failed!")", "KCHVMSTOR0001E": "$_("CDROM path need to be a valid local path and cannot be blank.")", "KCHVMSTOR0002E": "$_("Disk pool or volume cannot be blank.")" -- 1.8.1.4

Put things together to provide download remote image feature. Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/css/theme-default/storage.css | 31 +++++++++++++++- ui/js/src/kimchi.storage_main.js | 77 +++++++++++++++++++++++++++++++++++----- ui/pages/tabs/storage.html.tmpl | 12 ++++++- 3 files changed, 110 insertions(+), 10 deletions(-) diff --git a/ui/css/theme-default/storage.css b/ui/css/theme-default/storage.css index f635c2f..74c3574 100644 --- a/ui/css/theme-default/storage.css +++ b/ui/css/theme-default/storage.css @@ -336,7 +336,6 @@ float: left; padding: 4px; margin-bottom: 5px; - height: 40px; width: 130px; } @@ -622,3 +621,33 @@ #iSCSITarget input { width: 493px; } + +/* Progress bar */ +.volume-progress { + clear: both; + width: 140px; +} + +.volume-progress .progress-bar-outer { + background: #ccc; + height: 4px; + overflow: hidden; + width: 100%; +} + +.volume-progress .progress-bar-inner { + background: #090; + height: 100%; + width: 0%; +} + +.volume-progress .progress-label { + color: #999; + font-size: 10px; + line-height: 16px; +} + +.volume-progress .progress-downloaded { + float: right; +} +/* End of Progress bar */ diff --git a/ui/js/src/kimchi.storage_main.js b/ui/js/src/kimchi.storage_main.js index ae3f963..24168f9 100644 --- a/ui/js/src/kimchi.storage_main.js +++ b/ui/js/src/kimchi.storage_main.js @@ -135,6 +135,12 @@ kimchi.storageBindClick = function() { } }); + $('.pool-add-volume').on('click', function(event) { + var poolName = $(this).data('name'); + kimchi.selectedSP = poolName; + kimchi.window.open('storagepool-add-volume.html'); + }); + $('.storage-action').on('click', function() { var storage_action = $(this); var deleteButton = storage_action.find('.pool-delete'); @@ -149,10 +155,6 @@ kimchi.storageBindClick = function() { $("#logicalPoolExtend").dialog("option", "poolName", $(this).data('name')); $("#logicalPoolExtend").dialog("open"); }); - - $('#volume-doAdd').on('click', function() { - kimchi.window.open('storagevolume-add.html'); - }); } $('.storage-li').on('click', function(event) { @@ -173,8 +175,19 @@ kimchi.storageBindClick = function() { }); } +kimchi._generateVolumeHTML = function(volume) { + if(volume['type'] === 'kimchi-iso') { + return ''; + } + var volumeHtml = $('#volumeTmpl').html(); + volume.capacity = kimchi.changetoProperUnit(volume.capacity,1); + volume.allocation = kimchi.changetoProperUnit(volume.allocation,1); + return kimchi.substitute(volumeHtml, volume); +}; + kimchi.doListVolumes = function(poolObj) { var volumeDiv = $('#volume' + poolObj.data('name')); + $(volumeDiv).empty(); var slide = poolObj.next('.volumes'); var handleArrow = poolObj.children().last().children(); kimchi.listStorageVolumes(poolObj.data('name'), function(result) { @@ -184,9 +197,7 @@ kimchi.doListVolumes = function(poolObj) { var listHtml = ''; $.each(result, function(index, value) { value.poolname = poolObj.data('name'); - value.capacity = kimchi.changetoProperUnit(value.capacity,1); - value.allocation = kimchi.changetoProperUnit(value.allocation,1); - listHtml += kimchi.substitute(volumeHtml, value); + listHtml += kimchi._generateVolumeHTML(value); }); volumeDiv.html(listHtml); } else { @@ -255,7 +266,57 @@ kimchi.storage_main = function() { } kimchi.doListStoragePools(); kimchi.initLogicalPoolExtend(); -} + + kimchi.topic('kimchi/volumeDownloadStarted').subscribe(function(data) { + var sp = data['sp']; + var volumeName = data['volume']; + var volumesContainer = $('#volume' + sp); + var volume = { + poolName: sp, + ref_cnt: 0, + capacity: 0, + name: volumeName, + format: '', + bootable: true, + os_distro: '', + allocation: 0, + os_version: '', + path: '', + type: 'file' + }; + volumesContainer.prepend(kimchi._generateVolumeHTML(volume)); + var volumeBox = $('#volume' + sp + ' [data-volume-name="' + volumeName + '"]'); + $('.volume-progress', volumeBox).removeClass('hidden'); + $('.progress-status', volumeBox).text(i18n['KCHPOOL6014M']); + }); + + kimchi.topic('kimchi/volumeDownloadProgress').subscribe(function(data) { + var sp = data['sp'], + volumeName = data['volume'], + size = data['size'], + percent = data['percent']; + volumeBox = $('#volume' + sp + ' [data-volume-name="' + volumeName + '"]'); + $('.progress-bar-inner', volumeBox).css({ + width: percent + '%' + }); + $('.progress-status', volumeBox).text(i18n['KCHPOOL6014M']); + $('.progress-downloaded', volumeBox).text(size); + }); + + kimchi.topic('kimchi/volumeDownloadFinished').subscribe(function(data) { + var sp = data['sp'], + volumeName = data['volume'], + volumeBox = $('#volume' + sp + ' [data-volume-name="' + volumeName + '"]'); + $('.progress-status', volumeBox).text(i18n['KCHPOOL6015M']); + }); + + kimchi.topic('kimchi/volumeDownloadError').subscribe(function(data) { + var sp = data['sp'], + volumeName = data['volume'], + volumeBox = $('#volume' + sp + ' [data-volume-name="' + volumeName + '"]'); + $('.progress-status', volumeBox).text(i18n['KCHPOOL6016M']); + }); +}; kimchi.changeArrow = function(obj) { if ($(obj).hasClass('arrow-down')) { diff --git a/ui/pages/tabs/storage.html.tmpl b/ui/pages/tabs/storage.html.tmpl index 87205bd..d5aceef 100644 --- a/ui/pages/tabs/storage.html.tmpl +++ b/ui/pages/tabs/storage.html.tmpl @@ -82,6 +82,7 @@ <div class="popover actionsheet right-side" style="width: 250px"> <button class="button-big pool-deactivate" data-stat="{state}" data-name="{name}" data-persistent="{persistent}"><span class="text">$_("Deactivate")</span></button> <button class="button-big pool-activate" data-stat="{state}" data-name="{name}"><span class="text">$_("Activate")</span></button> + <button class="button-big pool-add-volume" data-stat="{state}" data-name="{name}"><span class="text">$_("Add Volume")</span></button> <button class="button-big pool-extend {enableExt}" data-stat="{state}" data-name="{name}"><span class="text">$_("Extend")</span></button> <button class="button-big red pool-delete" data-stat="{state}" data-name="{name}"><span class="text">$_("Undefine")</span></button> </div> @@ -98,11 +99,20 @@ </li> </script> <script id="volumeTmpl" type="html/text"> - <div class="volume-box white-box"> + <div class="volume-box white-box" data-volume-name="{name}"> <div class="storage-icon volume-default icon-{format} "> </div> <div class="volume-title"> <div class="volume-name" title="{name}">{name}</div> + <div class="volume-progress hidden"> + <div class="progress-bar-outer"> + <div class="progress-bar-inner"></div> + </div> + <div class="progress-label"> + <span class="progress-status"></span> + <span class="progress-downloaded"></span> + </div> + </div> </div> <div class="volume-setting"> </div> -- 1.8.1.4

Some comments: 1. The "Add volume" option must be available only for active pools. 2. The "Add volume" option is not allowed for iscsi and scsi storage pools. 3. Disable upload option as this patch set only cares about download. 4. When the download completes, the storage volume box should be updated to remove the progress bar On 09/10/2014 09:02 AM, Hongliang Wang wrote:
Implemented download remote image feature.
Seems something wrong with /tasks response. The "message" is always "OK" and I can't retrieve the progress information.
Dependancies: * [PATCH] storagevolume: Use default value for param 'name' when appropriate
Hongliang Wang (4): Download Remote Image UI: Add Common API to kimchi.api.js Download Remote Image UI: Add Corresponding Window Download Remote Image UI: Updated i18n Strings Download Remote Image UI: Implemented the Feature
ui/css/theme-default/storage.css | 31 ++++++- ui/css/theme-default/storagepool-add-volume.css | 36 ++++++++ ui/js/src/kimchi.api.js | 49 +++++++++++ ui/js/src/kimchi.storage_main.js | 77 +++++++++++++++-- ui/js/src/kimchi.storagepool_add_volume_main.js | 110 ++++++++++++++++++++++++ ui/pages/i18n.json.tmpl | 3 + ui/pages/storagepool-add-volume.html.tmpl | 80 +++++++++++++++++ ui/pages/tabs/storage.html.tmpl | 12 ++- 8 files changed, 388 insertions(+), 10 deletions(-) create mode 100644 ui/css/theme-default/storagepool-add-volume.css create mode 100644 ui/js/src/kimchi.storagepool_add_volume_main.js create mode 100644 ui/pages/storagepool-add-volume.html.tmpl

On 09/11/2014 09:29 AM, Aline Manera wrote:
Some comments:
1. The "Add volume" option must be available only for active pools.
ACK.
2. The "Add volume" option is not allowed for iscsi and scsi storage pools. ACK. 3. Disable upload option as this patch set only cares about download. ACK. I'll add upload one. 4. When the download completes, the storage volume box should be updated to remove the progress bar ACK.
On 09/10/2014 09:02 AM, Hongliang Wang wrote:
Implemented download remote image feature.
Seems something wrong with /tasks response. The "message" is always "OK" and I can't retrieve the progress information.
Dependancies: * [PATCH] storagevolume: Use default value for param 'name' when appropriate
Hongliang Wang (4): Download Remote Image UI: Add Common API to kimchi.api.js Download Remote Image UI: Add Corresponding Window Download Remote Image UI: Updated i18n Strings Download Remote Image UI: Implemented the Feature
ui/css/theme-default/storage.css | 31 ++++++- ui/css/theme-default/storagepool-add-volume.css | 36 ++++++++ ui/js/src/kimchi.api.js | 49 +++++++++++ ui/js/src/kimchi.storage_main.js | 77 +++++++++++++++-- ui/js/src/kimchi.storagepool_add_volume_main.js | 110 ++++++++++++++++++++++++ ui/pages/i18n.json.tmpl | 3 + ui/pages/storagepool-add-volume.html.tmpl | 80 +++++++++++++++++ ui/pages/tabs/storage.html.tmpl | 12 ++- 8 files changed, 388 insertions(+), 10 deletions(-) create mode 100644 ui/css/theme-default/storagepool-add-volume.css create mode 100644 ui/js/src/kimchi.storagepool_add_volume_main.js create mode 100644 ui/pages/storagepool-add-volume.html.tmpl

Most of my feedback from your previous WIP patch still apply. I'll put them here again, along with new comments: - When the button "OK" is clicked and there is some error (e.g. the URL field is empty, the URL text doesn't start with a correct protocol), the button gets disabled and it never gets enabled again unless the user closes and reopens the dialog. - When a download finishes, the progress box doesn't update the message "Downloading...". That message should disappear and the storage volume box should look like the other existing volumes in that pool. - Some downloads (e.g. http://distfiles.gentoo.org/releases/amd64/autobuilds/current-stage3-amd64/i...) don't display a progress bar at all. - The correct text when uploading a file should be "Upload a file" (instead of "...an file"). - IMO the submit button's label should be a verb (e.g. "Add") instead of "OK". - IMO the menu item "Add Volume" should be the first element on the menu. On 10-09-2014 09:02, Hongliang Wang wrote:
Implemented download remote image feature.
Seems something wrong with /tasks response. The "message" is always "OK" and I can't retrieve the progress information.
Dependancies: * [PATCH] storagevolume: Use default value for param 'name' when appropriate
Hongliang Wang (4): Download Remote Image UI: Add Common API to kimchi.api.js Download Remote Image UI: Add Corresponding Window Download Remote Image UI: Updated i18n Strings Download Remote Image UI: Implemented the Feature
ui/css/theme-default/storage.css | 31 ++++++- ui/css/theme-default/storagepool-add-volume.css | 36 ++++++++ ui/js/src/kimchi.api.js | 49 +++++++++++ ui/js/src/kimchi.storage_main.js | 77 +++++++++++++++-- ui/js/src/kimchi.storagepool_add_volume_main.js | 110 ++++++++++++++++++++++++ ui/pages/i18n.json.tmpl | 3 + ui/pages/storagepool-add-volume.html.tmpl | 80 +++++++++++++++++ ui/pages/tabs/storage.html.tmpl | 12 ++- 8 files changed, 388 insertions(+), 10 deletions(-) create mode 100644 ui/css/theme-default/storagepool-add-volume.css create mode 100644 ui/js/src/kimchi.storagepool_add_volume_main.js create mode 100644 ui/pages/storagepool-add-volume.html.tmpl

On 09/11/2014 10:03 PM, Crístian Viana wrote:
Most of my feedback from your previous WIP patch still apply. I'll put them here again, along with new comments:
- When the button "OK" is clicked and there is some error (e.g. the URL field is empty, the URL text doesn't start with a correct protocol), the button gets disabled and it never gets enabled again unless the user closes and reopens the dialog. ACK.
- When a download finishes, the progress box doesn't update the message "Downloading...". That message should disappear and the storage volume box should look like the other existing volumes in that pool. ACK.
- Some downloads (e.g. http://distfiles.gentoo.org/releases/amd64/autobuilds/current-stage3-amd64/i...) don't display a progress bar at all. I'll investigate it.
- The correct text when uploading a file should be "Upload a file" (instead of "...an file"). Which part do you mean? It's "Upload a File".
- IMO the submit button's label should be a verb (e.g. "Add") instead of "OK". ACK.
- IMO the menu item "Add Volume" should be the first element on the menu. I just put it alongside with "Extend".
On 10-09-2014 09:02, Hongliang Wang wrote:
Implemented download remote image feature.
Seems something wrong with /tasks response. The "message" is always "OK" and I can't retrieve the progress information.
Dependancies: * [PATCH] storagevolume: Use default value for param 'name' when appropriate
Hongliang Wang (4): Download Remote Image UI: Add Common API to kimchi.api.js Download Remote Image UI: Add Corresponding Window Download Remote Image UI: Updated i18n Strings Download Remote Image UI: Implemented the Feature
ui/css/theme-default/storage.css | 31 ++++++- ui/css/theme-default/storagepool-add-volume.css | 36 ++++++++ ui/js/src/kimchi.api.js | 49 +++++++++++ ui/js/src/kimchi.storage_main.js | 77 +++++++++++++++-- ui/js/src/kimchi.storagepool_add_volume_main.js | 110 ++++++++++++++++++++++++ ui/pages/i18n.json.tmpl | 3 + ui/pages/storagepool-add-volume.html.tmpl | 80 +++++++++++++++++ ui/pages/tabs/storage.html.tmpl | 12 ++- 8 files changed, 388 insertions(+), 10 deletions(-) create mode 100644 ui/css/theme-default/storagepool-add-volume.css create mode 100644 ui/js/src/kimchi.storagepool_add_volume_main.js create mode 100644 ui/pages/storagepool-add-volume.html.tmpl
participants (3)
-
Aline Manera
-
Crístian Viana
-
Hongliang Wang