<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<div class="moz-cite-prefix">On 03/22/2014 03:39 AM, Aline Manera
wrote:<br>
</div>
<blockquote cite="mid:532C955F.6000401@linux.vnet.ibm.com"
type="cite">
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
<div class="moz-cite-prefix"><br>
Some comments:<br>
<br>
<img src="cid:part1.03080502.07000408@linux.vnet.ibm.com" alt=""><br>
<br>
Which operation failed?<br>
I think we need to provide a detailed message<br>
<br>
For example:<br>
<br>
"An error occurs while checking for packages update."<br>
</div>
</blockquote>
ACK. "Operation failed." is confused because user doesn't know what
operation means. Will replace it with your suggestion text.<br>
<blockquote cite="mid:532C955F.6000401@linux.vnet.ibm.com"
type="cite">
<div class="moz-cite-prefix"> <br>
The "Retry" button should be in the footer or be a link instead
a button<br>
</div>
</blockquote>
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.<br>
<br>
And the button is intentionally here, rather than a link.<br>
Be aware of that: button is for "<b>action</b>", while link is for "<b>redirection</b>",
and sometimes we can choose either of them for button link or link
button cases.<br>
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.<br>
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="">).<br>
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.<br>
<br>
For our case, it's for "list software" so no redirection is here.
Only button can be used here.<br>
<blockquote cite="mid:532C955F.6000401@linux.vnet.ibm.com"
type="cite">
<div class="moz-cite-prefix"> <br>
<br>
On 03/21/2014 06:48 AM, Hongliang Wang wrote:<br>
</div>
<blockquote
cite="mid:1395395321-15918-1-git-send-email-hlwang@linux.vnet.ibm.com"
type="cite">
<pre wrap="">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 <a moz-do-not-send="true" class="moz-txt-link-rfc2396E" href="mailto:hlwang@linux.vnet.ibm.com"><hlwang@linux.vnet.ibm.com></a>
---
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?")",
</pre>
</blockquote>
<br>
</blockquote>
<br>
</body>
</html>