On 03/22/2014 03:39 AM, Aline Manera wrote:

Some comments:



Which operation failed?
I think we need to provide a detailed message

For example:

"An error occurs while checking for packages update."
ACK. "Operation failed." is confused because user doesn't know what operation means. Will replace it with your suggestion text.

The "Retry" button should be in the footer or be a link instead a button
   For pop-up window or dialog, we put the button in the footer, just as what we do in create VM window, edit VM window, etc. Though in this case, I still suggest keep the button be here. It's user-friendly to put the button after the message so the user will be able to take action immediately. It's consistent with grid design: toolbar (which contains action buttons) is above data or message.

And the button is intentionally here, rather than a link.
Be aware of that: button is for "action", while link is for "redirection", and sometimes we can choose either of them for button link or link button cases.
  1) For example, when we want to switch tabs, the tab pages are listed as links like "Guests", "Templates', "Network"; we can't use buttons here.
  2) For another example, when we create a VM with some properties (which are general organized as <form> <field>s and put in a <form> element), we should use a <button> to trigger the "create" action instead of a link (<a href="">).
  3) And the 3rd example, log-in/log-out buttons. Because log in or log out action often goes with a redirection: log-in will cause a redirection to main page, and log-out will cause a redirection to log-in page. So in the case, either button or link is OK.

  For our case, it's for "list software" so no redirection is here. Only button can be used here.


On 03/21/2014 06:48 AM, Hongliang Wang wrote:
Software update grid keeps loading on UI when server returns 500 error.
Instead, we shall remove the loading UI and add a message UI to let the
user know something is wrong, as well as add a button to allow the user
retry.

Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com>
---
 ui/css/theme-default/grid.css | 20 +++++++++++++
 ui/js/src/kimchi.api.js       |  4 +--
 ui/js/src/kimchi.grid.js      | 66 +++++++++++++++++++++++++++++++++----------
 ui/js/src/kimchi.host.js      | 11 +++++++-
 ui/pages/i18n.html.tmpl       |  5 ++++
 5 files changed, 87 insertions(+), 19 deletions(-)

diff --git a/ui/css/theme-default/grid.css b/ui/css/theme-default/grid.css
index 44ae614..684dd7b 100644
--- a/ui/css/theme-default/grid.css
+++ b/ui/css/theme-default/grid.css
@@ -239,3 +239,23 @@
     height: 48px;
     width: 49px;
 }
+
+.grid-message {
+    background: white;
+    box-sizing: border-box;
+    bottom: 0;
+    left: 0;
+    overflow: auto;
+    padding: .2em .5em;
+    position: absolute;
+    right: 0;
+    z-index: 5;
+}
+
+.grid-message-text {
+    line-height: 25px;
+}
+
+.retry-button {
+    margin: 0 1em;
+}
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
index 4310435..11f83df 100644
--- a/ui/js/src/kimchi.api.js
+++ b/ui/js/src/kimchi.api.js
@@ -838,10 +838,8 @@ var kimchi = {
                 }, 200);
                 break;
             case 'finished':
-                suc(result);
-                break;
             case 'failed':
-                err(result);
+                suc(result);
                 break;
             default:
                 break;
diff --git a/ui/js/src/kimchi.grid.js b/ui/js/src/kimchi.grid.js
index 540f1ba..f35228d 100644
--- a/ui/js/src/kimchi.grid.js
+++ b/ui/js/src/kimchi.grid.js
@@ -62,6 +62,18 @@ kimchi.widget.Grid = function(params) {
                 '</div>',
             '</div>',
         '</div>',
+        '<div class="grid-message hidden">',
+          '<div class="grid-message-text">',
+            i18n['KCHGRD6002M'],
+            '<button class="retry-button btn-small">',
+              i18n['KCHGRD6003M'],
+            '</button>',
+          '</div>',
+          '<div class="detailed-title">',
+            i18n['KCHGRD6004M'],
+          '</div>',
+          '<div class="detailed-text"></div>',
+        '</div>',
       '</div>'
     ];

@@ -161,6 +173,9 @@ kimchi.widget.Grid = function(params) {
     var maskNode = $('.grid-mask', gridNode);
     maskNode.css('top', captionHeight + 'px');

+    var messageNode = $('.grid-message', gridNode);
+    messageNode.css('top', captionHeight + 'px');
+
     var fillBody = function(container, fields, data) {
         var tbody = ($('tbody', container).length && $('tbody', container))
             || $('<tbody></tbody>').appendTo(container);
@@ -384,28 +399,49 @@ kimchi.widget.Grid = function(params) {
     $('body').on('mousemove', positionResizer);
     $('body').on('mouseup', endResizing);

+    this.showMessage = function(msg) {
+        $('.detailed-text', messageNode).text(msg);
+        $(messageNode).removeClass('hidden');
+    };
+
+    this.hideMessage = function() {
+        $(messageNode).addClass('hidden');
+    };
+
     this.destroy = function() {
         $('body').off('mousemove', positionResizer);
         $('body').off('mouseup', endResizing);
     };

     var data = params['data'];
-    if(!data) {
-        return;
-    }
+    var self = this;
+    var reload = function() {
+        if(!data) {
+            return;
+        }

-    if($.isArray(data)) {
-        this.setData(data);
-        return;
-    }
+        $(messageNode).addClass('hidden');

-    if($.isFunction(data)) {
-        var self = this;
-        var loadData = data;
-        maskNode.removeClass('hidden');
-        loadData(function(data) {
+        if($.isArray(data)) {
             self.setData(data);
-            maskNode.addClass('hidden');
-        });
-    }
+            return;
+        }
+
+        if($.isFunction(data)) {
+            var loadData = data;
+            maskNode.removeClass('hidden');
+            loadData(function(data) {
+                self.setData(data);
+                maskNode.addClass('hidden');
+            });
+        }
+    };
+
+    var reloadButton = $('.retry-button', gridNode);
+    $(reloadButton).on('click', function(event) {
+        reload();
+    });
+
+    this.reload = reload;
+    reload();
 };
diff --git a/ui/js/src/kimchi.host.js b/ui/js/src/kimchi.host.js
index 6e4678f..2990cdd 100644
--- a/ui/js/src/kimchi.host.js
+++ b/ui/js/src/kimchi.host.js
@@ -57,7 +57,9 @@ kimchi.host_main = function() {
                         kimchi.topic('kimchi/softwareUpdated').publish({
                             result: result
                         });
-                    }, function(result) {
+                    }, function(error) {
+                        var message = error && error['responseJSON'] && error['responseJSON']['reason'];
+                        kimchi.message.error(message || i18n['KCHUPD6009M']);
                         $(updateButton).text(i18n['KCHUPD6006M']).prop('disabled', false);
                     }, reloadProgressArea);
                 }
@@ -100,6 +102,13 @@ kimchi.host_main = function() {

             var updateButton = $('#' + softwareUpdatesGridID + '-update-button');
             $(updateButton).prop('disabled', softwareUpdates.length === 0);
+        }, function(error) {
+            var message = error && error['responseJSON'] && error['responseJSON']['reason'];
+            if($.isFunction(gridCallback)) {
+                gridCallback([]);
+            }
+            softwareUpdatesGrid &&
+                softwareUpdatesGrid.showMessage(message || i18n['KCHUPD6008M']);
         });
     };

diff --git a/ui/pages/i18n.html.tmpl b/ui/pages/i18n.html.tmpl
index 2f47e50..362cde2 100644
--- a/ui/pages/i18n.html.tmpl
+++ b/ui/pages/i18n.html.tmpl
@@ -60,6 +60,9 @@ var i18n = {
     'KCHAPI6006M': "$_("Warning")",

     'KCHGRD6001M': "$_("Loading...")",
+    'KCHGRD6002M': "$_("Operation failed.")",
+    'KCHGRD6003M': "$_("Retry")",
+    'KCHGRD6004M': "$_("Detailed message:")",

     'KCHTMPL6001W': "$_("No iso found")",

@@ -87,6 +90,8 @@ var i18n = {
     'KCHUPD6005M': "$_("Repository")",
     'KCHUPD6006M': "$_("Update All")",
     'KCHUPD6007M': "$_("Updating...")",
+    'KCHUPD6008M': "$_("Failed to retrieve updates.")",
+    'KCHUPD6009M': "$_("Failed to update package(s).")",


     'KCHDR6001M': "$_("Debug report will be removed permanently and can't be recovered. Do you want to continue?")",