[Kimchi-devel] [PATCH] Adjustments on upload/download UI

Aline Manera alinefm at linux.vnet.ibm.com
Fri Sep 12 20:48:49 UTC 2014


- 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 at 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




More information about the Kimchi-devel mailing list