From aee2544e1633eccb83015d6adacb91c52f6e3bff Mon Sep 17 00:00:00 2001 From: Petr Vobornik Date: Thu, 11 Aug 2011 10:28:50 +0200 Subject: error dialog for batch command https://fedorahosted.org/freeipa/ticket/1597 https://fedorahosted.org/freeipa/ticket/1592 Added option to show multiple errors in error dialog. --- install/ui/ipa.js | 138 +++++++++++++++++++++++++++++++++---- install/ui/search.js | 4 +- install/ui/test/data/ipa_init.json | 7 +- ipalib/plugins/internal.py | 5 ++ 4 files changed, 140 insertions(+), 14 deletions(-) diff --git a/install/ui/ipa.js b/install/ui/ipa.js index 8a3dd4e7d..9a252f1e5 100644 --- a/install/ui/ipa.js +++ b/install/ui/ipa.js @@ -417,6 +417,11 @@ IPA.batch_command = function (spec) { var that = IPA.command(spec); that.commands = []; + that.errors = []; + that.error_message = spec.error_message || (IPA.messages.dialogs ? + IPA.messages.dialogs.batch_error_message : 'Some operations failed.'); + that.show_error = typeof spec.show_error == 'undefined' ? + true : spec.show_error; that.add_command = function(command) { that.commands.push(command); @@ -429,7 +434,21 @@ IPA.batch_command = function (spec) { } }; + var clear_errors = function() { + that.errors = []; + }; + + var add_error = function(command, name, message, status) { + that.errors.push({ + command: command, + name: name, + message: message, + status: status + }); + }; + that.execute = function() { + clear_errors(); IPA.command({ name: that.name, @@ -444,25 +463,38 @@ IPA.batch_command = function (spec) { var command = that.commands[i]; var result = data.result.results[i]; + var name = ''; + var message = ''; + if (!result) { + name = 'Internal Error '+xhr.status; + message = result ? xhr.statusText : "Internal error"; + + add_error(command, name, message, text_status); + if (command.on_error) command.on_error.call( this, xhr, text_status, { - name: 'Internal Error '+xhr.status, - message: result ? xhr.statusText : "Internal error" + name: name, + message: message } ); } else if (result.error) { + name = 'IPA Error ' + (result.error.code || ''); + message = result.error.message || result.error; + + add_error(command, name, message, text_status); + if (command.on_error) command.on_error.call( this, xhr, text_status, { - name: 'IPA Error '+result.error.code, - message: result.error.message + name: name, + message: message } ); @@ -470,6 +502,22 @@ IPA.batch_command = function (spec) { if (command.on_success) command.on_success.call(this, result, text_status, xhr); } } + //check for partial errors and show error dialog + if(that.show_error && that.errors.length > 0) { + var dialog = IPA.error_dialog({ + xhr: xhr, + text_status: text_status, + error_thrown: { + name: IPA.messages.dialogs ? IPA.messages.dialogs.batch_error_title : + 'Operations Error', + message: that.error_message + }, + command: that, + errors: that.errors, + visible_buttons: ['ok'] + }); + dialog.open(); + } if (that.on_success) that.on_success.call(this, data, text_status, xhr); }, on_error: function(xhr, text_status, error_thrown) { @@ -625,6 +673,8 @@ IPA.error_dialog = function(spec) { that.error_thrown = spec.error_thrown || {}; that.command = spec.command; that.title = spec.error_thrown.name; + that.errors = spec.errors; + that.visible_buttons = spec.visible_buttons || ['retry', 'cancel']; }; that.create = function() { @@ -637,6 +687,54 @@ IPA.error_dialog = function(spec) { $('

', { html: that.error_thrown.message }).appendTo(that.container); + + if(that.errors && that.errors.length > 0) { + //render errors + var errors_title_div = $('

', { + 'class': 'errors_title' + }).appendTo(that.container); + + var show_details = $('', { + href: '#', + title: IPA.messages.dialogs.show_details, + text: IPA.messages.dialogs.show_details + }).appendTo(errors_title_div); + + var hide_details = $('', { + href: '#', + title: IPA.messages.dialogs.hide_details, + text: IPA.messages.dialogs.hide_details, + style : 'display: none' + }).appendTo(errors_title_div); + + var errors_container = $('
    ', { + 'class' : 'error-container', + style : 'display: none' + }).appendTo(that.container); + + for(var i=0; i < that.errors.length; i++) { + var error = that.errors[i]; + if(error.message) { + var error_div = $('
  • ', { + text: error.message + }).appendTo(errors_container); + } + } + + show_details.click(function() { + errors_container.show(); + show_details.hide(); + hide_details.show(); + return false; + }); + + hide_details.click(function() { + errors_container.hide(); + hide_details.hide(); + show_details.show(); + return false; + }); + } }; that.create_buttons = function() { @@ -645,16 +743,28 @@ IPA.error_dialog = function(spec) { * ticket, the messages including the button labels have not * been loaded yet, so the button labels need default values. */ - var label = IPA.messages.buttons ? IPA.messages.buttons.retry : 'Retry'; + var label; - that.add_button(label, function() { - that.on_retry(); - }); + if(that.visible_buttons.indexOf('retry') > -1) { + label = IPA.messages.buttons ? IPA.messages.buttons.retry : 'Retry'; + that.add_button(label, function() { + that.on_retry(); + }); + } - label = IPA.messages.buttons ? IPA.messages.buttons.cancel : 'Cancel'; - that.add_button(label, function() { - that.on_cancel(); - }); + if(that.visible_buttons.indexOf('ok') > -1) { + label = IPA.messages.buttons ? IPA.messages.buttons.ok : 'OK'; + that.add_button(label, function() { + that.on_ok(); + }); + } + + if(that.visible_buttons.indexOf('cancel') > -1) { + label = IPA.messages.buttons ? IPA.messages.buttons.cancel : 'Cancel'; + that.add_button(label, function() { + that.on_cancel(); + }); + } }; that.on_retry = function() { @@ -662,6 +772,10 @@ IPA.error_dialog = function(spec) { that.command.execute(); }; + that.on_ok = function() { + that.close(); + }; + that.on_cancel = function() { that.close(); }; diff --git a/install/ui/search.js b/install/ui/search.js index fe0b07f72..bee55c067 100644 --- a/install/ui/search.js +++ b/install/ui/search.js @@ -300,7 +300,9 @@ IPA.search_deleter_dialog = function(spec) { var that = IPA.deleter_dialog(spec); that.create_command = function() { - var batch = IPA.batch_command(); + var batch = IPA.batch_command({ + error_message: IPA.messages.search.partial_delete + }); var pkeys = that.entity.get_primary_key_prefix(); diff --git a/install/ui/test/data/ipa_init.json b/install/ui/test/data/ipa_init.json index 659ddfc61..bd3255054 100644 --- a/install/ui/test/data/ipa_init.json +++ b/install/ui/test/data/ipa_init.json @@ -15880,13 +15880,17 @@ "dialogs": { "add_title": "Add ${entity}", "available": "Available", + "batch_error_message": "Some operations failed.", + "batch_error_title": "Operations Error", "confirmation": "Confirmation", "dirty_message": "This page has unsaved changes. Please save or revert.", "dirty_title": "Dirty", "hide_already_enrolled": "Hide already enrolled.", + "hide_details": "Hide details", "prospective": "Prospective", "remove_empty": "Select entries to be removed.", - "remove_title": "Remove ${entity}" + "remove_title": "Remove ${entity}", + "show_details": "Show details" }, "facet_groups": { "managedby": "${primary_key} is managed by:", @@ -16125,6 +16129,7 @@ }, "search": { "delete_confirm": "Are you sure you want to delete selected entries?", + "partial_delete": "Some entries were not deleted", "quick_links": "Quick Links", "select_all": "Select All", "truncated": "Query returned more results than the configured size limit. Displaying the first ${counter} results.", diff --git a/ipalib/plugins/internal.py b/ipalib/plugins/internal.py index 0c16841b9..84d8fd3fa 100644 --- a/ipalib/plugins/internal.py +++ b/ipalib/plugins/internal.py @@ -350,14 +350,18 @@ class i18n_messages(Command): "dialogs": { "add_title":_("Add ${entity}"), "available":_("Available"), + "batch_error_message":_("Some operations failed."), + "batch_error_title":_("Operations Error"), "confirmation":_("Confirmation"), "dirty_message":_("This page has unsaved changes. Please save or revert."), "dirty_title":_("Dirty"), "hide_already_enrolled":_("Hide already enrolled."), + "hide_details":_("Hide details"),\ "redirection":_("Redirection"), "remove_empty":_("Select entries to be removed."), "remove_title":_("Remove ${entity}"), "prospective":_("Prospective"), + "show_details":_("Show details"),\ }, "facet_groups": { "managedby":_("${primary_key} is managed by:"), @@ -369,6 +373,7 @@ class i18n_messages(Command): "details": _("Settings"), }, "search": { + "partial_delete":_("Some entries were not deleted"), "quick_links":_("Quick Links"), "select_all":_("Select All"), "unselect_all":_("Unselect All"), -- cgit