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(a)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?")",