- Set dataType (dataType: 'json') instead of add Accept header
- Use .show() and .hide() to display or not the "Add Volume button"
- Allow any type of file to be uploaded
- Change upload/download handlers to query for running Tasks while
listing storage volumes in a pool
That way all users get the same view when a storage volume is being
downloaded or uploaded
This patch set was made based on:
[Kimchi-devel] [PATCH v2 0/4] UI:Download Remote Image Feature
Signed-off-by: Aline Manera <alinefm(a)linux.vnet.ibm.com>
---
ui/js/src/kimchi.api.js | 4 +-
ui/js/src/kimchi.storage_main.js | 195 +++++++++++++++---------
ui/js/src/kimchi.storagepool_add_volume_main.js | 154 ++-----------------
3 files changed, 131 insertions(+), 222 deletions(-)
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
index 0e27987..3398bd4 100644
--- a/ui/js/src/kimchi.api.js
+++ b/ui/js/src/kimchi.api.js
@@ -1156,9 +1156,7 @@ var kimchi = {
data : fd,
processData : false,
contentType : false,
- headers : {
- Accept : 'application/json; charset=utf-8'
- },
+ dataType: 'json',
success : suc,
error : err
});
diff --git a/ui/js/src/kimchi.storage_main.js b/ui/js/src/kimchi.storage_main.js
index 6c1aade..910f08d 100644
--- a/ui/js/src/kimchi.storage_main.js
+++ b/ui/js/src/kimchi.storage_main.js
@@ -42,7 +42,6 @@ kimchi.doListStoragePools = function() {
}, function(err) {
kimchi.message.error(err.responseJSON.reason);
});
-
}
kimchi.storageBindClick = function() {
@@ -85,10 +84,10 @@ kimchi.storageBindClick = function() {
$(this).data('type') !== 'iscsi' &&
$(this).data('type') !== 'scsi';
if(canAddVolume) {
- $(this).removeClass('hidden');
+ $(this).show();
}
else {
- $(this).addClass('hidden');
+ $(this).hide();
}
});
@@ -198,33 +197,80 @@ kimchi._generateVolumeHTML = function(volume) {
return kimchi.substitute(volumeHtml, volume);
};
-kimchi._updateVolumeBoxUI = function(box, volume) {
- var html = kimchi._generateVolumeHTML(volume);
- $(box).replaceWith(html);
-};
-
kimchi.doListVolumes = function(poolObj) {
- var volumeDiv = $('#volume' + poolObj.data('name'));
+ var poolName = poolObj.data('name')
+
+ var getOngoingVolumes = function() {
+ var result = {}
+ var filter = 'status=running&target_uri=' +
encodeURIComponent('^/storagepools/' + poolName + '/*')
+ kimchi.getTasksByFilter(filter, function(tasks) {
+ for(var i = 0; i < tasks.length; i++) {
+ var volumeName = tasks[i].target_uri.split('/').pop();
+ result[volumeName] = tasks[i];
+
+ if(kimchi.trackingTasks.indexOf(tasks[i].id) >= 0) {
+ continue;
+ }
+
+ kimchi.trackTask(tasks[i].id, function(result) {
+
kimchi.topic('kimchi/volumeTransferFinished').publish(result);
+ }, function(result) {
+ kimchi.topic('kimchi/volumeTransferError').publish(result);
+ }, function(result) {
+
kimchi.topic('kimchi/volumeTransferProgress').publish(result);
+ });
+ }
+ }, null, true);
+ return result;
+ };
+
+ var volumeDiv = $('#volume' + poolName);
$(volumeDiv).empty();
var slide = poolObj.next('.volumes');
var handleArrow = poolObj.children().last().children();
- kimchi.listStorageVolumes(poolObj.data('name'), function(result) {
- var volumeHtml = $('#volumeTmpl').html();
- if (result) {
- if (result.length) {
- var listHtml = '';
- $.each(result, function(index, value) {
- value.poolname = poolObj.data('name');
- listHtml += kimchi._generateVolumeHTML(value);
- });
- volumeDiv.html(listHtml);
- } else {
- volumeDiv.html("<div class='pool-empty'>" +
i18n['KCHPOOL6002M'] + "</div>");
+
+ kimchi.listStorageVolumes(poolName, function(result) {
+ var listHtml = '';
+ var ongoingVolumes = [];
+ var ongoingVolumesMap = getOngoingVolumes();
+ $.each(ongoingVolumesMap, function(volumeName, task) {
+ ongoingVolumes.push(volumeName)
+ var volume = {
+ poolName: poolName,
+ ref_cnt: 0,
+ capacity: 0,
+ name: volumeName,
+ format: '',
+ bootable: null,
+ os_distro: '',
+ allocation: 0,
+ os_version: '',
+ path: '',
+ type: 'file'
+ };
+ listHtml += kimchi._generateVolumeHTML(volume);
+ });
+
+ $.each(result, function(index, value) {
+ if (ongoingVolumes.indexOf(value.name) == -1) {
+ value.poolname = poolName;
+ listHtml += kimchi._generateVolumeHTML(value);
}
- poolObj.removeClass('in');
- kimchi.changeArrow(handleArrow);
- slide.slideDown('slow');
+ });
+
+ if (listHtml.length > 0) {
+ volumeDiv.html(listHtml);
+ } else {
+ volumeDiv.html("<div class='pool-empty'>" +
i18n['KCHPOOL6002M'] + "</div>");
}
+
+ $.each(ongoingVolumesMap, function(volumeName, task) {
+ kimchi.topic('kimchi/volumeTransferProgress').publish(task);
+ });
+
+ poolObj.removeClass('in');
+ kimchi.changeArrow(handleArrow);
+ slide.slideDown('slow');
}, function(err) {
kimchi.message.error(err.responseJSON.reason);
});
@@ -285,74 +331,75 @@ kimchi.storage_main = function() {
kimchi.doListStoragePools();
kimchi.initLogicalPoolExtend();
- kimchi.topic('kimchi/allVolumeTasksFinished').subscribe(function(data) {
- var sp = data['sp'];
- var poolNode = $('.storage-li[data-name="' + sp +
'"]');
+ kimchi.topic('kimchi/storageVolumeAdded').subscribe(function() {
+ pool = kimchi.selectedSP;
+ var poolNode = $('.storage-li[data-name="' + pool +
'"]');
kimchi.doListVolumes(poolNode);
});
- kimchi.topic('kimchi/volumeTransferStarted').subscribe(function(data) {
- var sp = data['sp'],
- type = data['type'],
- 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'
+ kimchi.topic('kimchi/volumeTransferProgress').subscribe(function(result) {
+ var extractProgressData = function(data) {
+ var sizeArray = /(\d+)\/(\d+)/g.exec(data) || [0, 0, 0];
+ var downloaded = sizeArray[1];
+ var percent = 0;
+ if(downloaded) {
+ var total = sizeArray[2];
+ if(!isNaN(total)) {
+ percent = downloaded / total * 100;
+ }
+ }
+ var formatted = kimchi.formatMeasurement(downloaded);
+ var size = (1.0 * formatted['v']).toFixed(1) +
formatted['s'];
+ return {
+ size: size,
+ percent: percent
+ };
};
- if($('.volume-box', volumesContainer).length === 0) {
- volumesContainer.empty();
- }
- volumesContainer.prepend(kimchi._generateVolumeHTML(volume));
- var volumeBox = $('#volume' + sp + ' [data-volume-name="' +
volumeName + '"]');
- $('.volume-progress', volumeBox).removeClass('hidden');
- $('.progress-status', volumeBox).text(
- type === 'download' ? i18n['KCHPOOL6014M'] :
i18n['KCHPOOL6017M']
- );
- });
- kimchi.topic('kimchi/volumeTransferProgress').subscribe(function(data) {
- var sp = data['sp'],
- type = data['type'],
- volumeName = data['volume'],
- size = data['size'],
- percent = data['percent'];
- volumeBox = $('#volume' + sp + ' [data-volume-name="' +
volumeName + '"]');
+ var uriElements = result.target_uri.split('/');
+ var poolName = uriElements[2];
+ var volumeName = uriElements.pop();
+ var progress = extractProgressData(result['message']);
+ var size = progress['size'];
+ var percent = progress['percent'];
+
+ volumeBox = $('#volume' + poolName + ' [data-volume-name="'
+ volumeName + '"]');
$('.progress-bar-inner', volumeBox).css({
width: percent + '%'
});
- $('.progress-status', volumeBox).text(
- type === 'download' ? i18n['KCHPOOL6014M'] :
i18n['KCHPOOL6017M']
- );
$('.progress-transferred', volumeBox).text(size);
$('.volume-progress', volumeBox).removeClass('hidden');
});
- kimchi.topic('kimchi/volumeTransferFinished').subscribe(function(data) {
- var sp = data['sp'],
- volumeName = data['volume'],
- volumeBox = $('#volume' + sp + ' [data-volume-name="' +
volumeName + '"]');
+ kimchi.topic('kimchi/volumeTransferFinished').subscribe(function(result) {
+ var uriElements = result.target_uri.split('/');
+ var poolName = uriElements[2];
+ var volumeName = uriElements.pop();
+ var volumeBox = $('#volume' + poolName + '
[data-volume-name="' + volumeName + '"]');
$('.volume-progress', volumeBox).addClass('hidden');
- kimchi.getStoragePoolVolume(sp, volumeName, function(volume) {
- kimchi._updateVolumeBoxUI(volumeBox, volume);
+ kimchi.getStoragePoolVolume(poolName, volumeName, function(volume) {
+ var html = kimchi._generateVolumeHTML(volume);
+ $(volumeBox).replaceWith(html);
}, function(err) {
kimchi.message.error(err.responseJSON.reason);
});
});
- kimchi.topic('kimchi/volumeTransferError').subscribe(function(data) {
- var sp = data['sp'],
- volumeName = data['volume'],
- volumeBox = $('#volume' + sp + ' [data-volume-name="' +
volumeName + '"]');
+ kimchi.topic('kimchi/volumeTransferError').subscribe(function(result) {
+ // Error message from Async Task status
+ if (result['message']) {
+ var errText = result['message'];
+ }
+ // Error message from standard kimchi exception
+ else {
+ var errText = result['responseJSON']['reason'];
+ }
+ result && kimchi.message.error(errText);
+
+ var uriElements = result.target_uri.split('/');
+ var poolName = uriElements[2];
+ var volumeName = uriElements.pop();
+ volumeBox = $('#volume' + poolName + ' [data-volume-name="'
+ volumeName + '"]');
$('.progress-status', volumeBox).text(i18n['KCHPOOL6016M']);
});
};
diff --git a/ui/js/src/kimchi.storagepool_add_volume_main.js
b/ui/js/src/kimchi.storagepool_add_volume_main.js
index 9435e28..590ccde 100644
--- a/ui/js/src/kimchi.storagepool_add_volume_main.js
+++ b/ui/js/src/kimchi.storagepool_add_volume_main.js
@@ -31,8 +31,7 @@ kimchi.sp_add_volume_main = function() {
var isValidFile = function() {
var fileName = $(localFileBox).val();
- return fileName &&
- /[Ii][Ss][Oo]/g.test(fileName.split('.').pop());
+ return fileName.length > 0;
};
$(typeRadios).change(function(event) {
@@ -55,142 +54,6 @@ kimchi.sp_add_volume_main = function() {
$(addButton).prop('disabled', !isValidFile());
});
- if(!kimchi.volumeTransferTracker) {
- kimchi.volumeTransferTracker = (function() {
- var tasks = {},
- sps = {};
- var addTask = function(task) {
- var taskID = task['id'];
- tasks[taskID] = task;
- var sp = task['sp'];
- if(sps[sp] === undefined) {
- sps[sp] = 1;
- }
- else {
- sps[sp]++;
- }
- };
- var getTask = function(taskID) {
- return tasks[taskID];
- };
- var removeTask = function(task) {
- var taskID = task['id'];
- var sp = tasks[taskID]['sp'];
- delete tasks[taskID];
- if(--sps[sp] === 0) {
- delete sps[sp];
- kimchi.topic('kimchi/allVolumeTasksFinished').publish({
- sp: sp
- });
- }
- };
- return {
- add: addTask,
- get: getTask,
- remove: removeTask
- };
- })();
- }
- var taskTracker = kimchi.volumeTransferTracker;
-
- var makeCallback = function(trackType, sp, transType, callback) {
- return function(resp) {
- var taskID = resp['id'];
- var volumeName = resp['target_uri'].split('/').pop();
- if(trackType === 'add') {
- taskTracker.add({
- id: taskID,
- sp: sp,
- volume: volumeName
- });
- }
- callback(transType, resp);
- };
- };
-
- var extractProgressData = function(data) {
- var sizeArray = /(\d+)\/(\d+)/g.exec(data) || [0, 0, 0];
- var downloaded = sizeArray[1];
- var percent = 0;
- if(downloaded) {
- var total = sizeArray[2];
- if(!isNaN(total)) {
- percent = downloaded / total * 100;
- }
- }
- var formatted = kimchi.formatMeasurement(downloaded);
- var size = (1.0 * formatted['v']).toFixed(1) + formatted['s'];
- return {
- size: size,
- percent: percent
- };
- };
-
- var onFinished = function(type, result) {
- var progress = extractProgressData(resp['message']);
- var task = taskTracker.get([result['id']]);
- kimchi.topic('kimchi/volumeTransferFinished').publish($.extend(progress,
{
- sp: task['sp'],
- type: type,
- volume: task['volume']
- }));
- taskTracker.remove({
- id: result['id']
- });
- };
-
- var onProgress = function(type, resp) {
- var progress = extractProgressData(resp['message']);
- var task = taskTracker.get([resp['id']]);
- kimchi.topic('kimchi/volumeTransferProgress').publish($.extend(progress,
{
- sp: task['sp'],
- type: type,
- volume: task['volume']
- }));
- };
-
- var onTransferError = function(type, result) {
- if(!result) {
- return;
- }
- var msg = result && (result['message'] || (
- result['responseJSON'] &&
result['responseJSON']['reason'])
- );
- kimchi.message.error(msg);
-
- if(!result['target_uri']) {
- return;
- }
- var task = taskTracker.get(result['id']);
- kimchi.topic('kimchi/volumeTransferError').publish({
- sp: task['sp'],
- type: type,
- volume: task['volume']
- });
- taskTracker.remove({
- id: result['id']
- });
- };
-
- var onAccepted = function(type, resp) {
- var taskID = resp['id'];
- var task = taskTracker.get(taskID);
- kimchi.window.close();
- kimchi.topic('kimchi/volumeTransferStarted').publish({
- sp: task['sp'],
- type: type,
- volume: task['volume']
- });
-
- kimchi.trackTask(taskID, function(resp) {
- onFinished(type, resp);
- }, function(resp) {
- onTransferError(type, resp);
- }, function(resp) {
- onProgress(type, resp);
- });
- };
-
var onError = function(result) {
$(this).prop('disabled', false);
$(typeRadios).prop('disabled', false);
@@ -208,11 +71,11 @@ kimchi.sp_add_volume_main = function() {
var volumeName = volumeURL.split(/(\\|\/)/g).pop();
kimchi.downloadVolumeToSP({
sp: kimchi.selectedSP,
- name: volumeName,
url: volumeURL
- }, makeCallback('add', kimchi.selectedSP, 'download',
onAccepted),
- onError
- );
+ }, function(result) {
+ kimchi.window.close();
+ kimchi.topic('kimchi/storageVolumeAdded').publish();
+ }, onError);
};
var uploadFile = function() {
@@ -224,9 +87,10 @@ kimchi.sp_add_volume_main = function() {
kimchi.uploadVolumeToSP({
sp: kimchi.selectedSP,
formData: fd
- }, makeCallback('add', kimchi.selectedSP, 'upload', onAccepted),
- onError
- );
+ }, function(result) {
+ kimchi.window.close();
+ kimchi.topic('kimchi/storageVolumeAdded').publish();
+ }, onError);
};
$(addButton).on('click', function(event) {
--
1.9.3