From 646a4ccde34a098ef693e75e45a2541618ed5434 Mon Sep 17 00:00:00 2001 From: Petr Vobornik Date: Fri, 9 Mar 2012 13:31:08 +0100 Subject: Content is no more overwritten by error message When an error which caused calling of report_error occurt, the content of a facet got replaced by error message. There was no way how to force the facet to recreate its content and the facet became unusable. This patch creates a containter for an error message. On error, report_error writes its content to error container, content container is hidden and error container is shown. Older comment in a code suggested to move the error message to facet's footer. A message in a footer could be missed by the user and on top of that a footer is sometimes used by various facet and we would have to solve the same problem again. From experience the cause of an error is usually a missing pkey in a path. Therefore error information suggests user to navigate to top level. It causes to load default facets with default values so errors in navigation state shouldn't happen. Facet content is displayed back on facet_show. If user tries to display same object as before facet's need_update() would return false, therefore need_update was modified to always return true if error is displayed. Reproduction: 1) display any nested entity - ie DNS record 2) delete its parent pkey from path - &dnszone-pkey=example.com 3) reload the page with this path https://fedorahosted.org/freeipa/ticket/2449 --- install/ui/association.js | 2 + install/ui/details.js | 4 +- install/ui/facet.js | 84 +++++++++++++++++++++++++++++++++++--- install/ui/ipa.css | 15 +++++++ install/ui/navigation.js | 4 ++ install/ui/test/data/ipa_init.json | 8 ++++ ipalib/plugins/internal.py | 8 ++++ 7 files changed, 119 insertions(+), 6 deletions(-) diff --git a/install/ui/association.js b/install/ui/association.js index b170b39d2..87f2fd4ab 100644 --- a/install/ui/association.js +++ b/install/ui/association.js @@ -1063,6 +1063,8 @@ IPA.association_facet = function (spec) { var page = parseInt(IPA.nav.get_state(that.entity.name+'-page'), 10) || 1; if (that.table.current_page !== page) return true; + if (that.error_displayed()) return true; + return false; }; diff --git a/install/ui/details.js b/install/ui/details.js index 8d5dcff68..ee57875a0 100644 --- a/install/ui/details.js +++ b/install/ui/details.js @@ -419,7 +419,9 @@ IPA.details_facet = function(spec) { that.needs_update = function() { if (that._needs_update !== undefined) return that._needs_update; var pkey = IPA.nav.get_state(that.entity.name+'-pkey'); - return pkey !== that.pkey; + var needs_update = that.error_displayed(); + needs_update = needs_update || pkey !== that.pkey; + return needs_update; }; that.field_dirty_changed = function(dirty) { diff --git a/install/ui/facet.js b/install/ui/facet.js index 39478f1a8..ab71f820f 100644 --- a/install/ui/facet.js +++ b/install/ui/facet.js @@ -79,6 +79,11 @@ IPA.facet = function(spec) { that.content = $('
', { 'class': 'facet-content' }).appendTo(container); + + that.error_container = $('
', { + 'class': 'facet-content facet-error' + }).appendTo(container); + that.create_content(that.content); }; @@ -101,6 +106,22 @@ IPA.facet = function(spec) { that.show = function() { that.container.css('display', 'block'); + that.show_content(); + }; + + that.show_content = function() { + that.content.css('display', 'block'); + that.error_container.css('display', 'none'); + }; + + that.show_error = function() { + that.content.css('display', 'none'); + that.error_container.css('display', 'block'); + }; + + that.error_displayed = function() { + return that.error_container && + that.error_container.css('display') === 'block'; }; that.hide = function() { @@ -128,11 +149,64 @@ IPA.facet = function(spec) { }; that.report_error = function(error_thrown) { - // TODO: The error message should be displayed in the facet footer. - // There should be a standard footer section for all facets. - that.content.empty(); - that.content.append('

'+IPA.get_message('errors.error', 'Error')+': '+error_thrown.name+'

'); - that.content.append('

'+error_thrown.message+'

'); + + var add_option = function(ul, text, handler) { + + var li = $('
  • ').appendTo(ul); + $('', { + href: '#', + text: text, + click: function() { + handler(); + return false; + } + }).appendTo(li); + }; + + var title = IPA.messages.error_report.title; + title = title.replace('${error}', error_thrown.name); + + that.error_container.empty(); + that.error_container.append('

    '+title+'

    '); + + var details = $('
    ', { + 'class': 'error-details' + }).appendTo(that.error_container); + details.append('

    '+error_thrown.message+'

    '); + + $('
    ', { + text: IPA.messages.error_report.options + }).appendTo(that.error_container); + + var options_list = $('
      ').appendTo(that.error_container); + + add_option( + options_list, + IPA.messages.error_report.refresh, + function() { + that.refresh(); + } + ); + + add_option( + options_list, + IPA.messages.error_report.main_page, + function() { + IPA.nav.show_top_level_page(); + } + ); + + add_option( + options_list, + IPA.messages.error_report.reload, + function() { + window.location.reload(false); + } + ); + + that.error_container.append('

      '+IPA.messages.error_report.problem_persists+'

      '); + + that.show_error(); }; that.get_redirect_facet = function() { diff --git a/install/ui/ipa.css b/install/ui/ipa.css index e86f6135f..7e7956603 100644 --- a/install/ui/ipa.css +++ b/install/ui/ipa.css @@ -648,6 +648,21 @@ div[name=settings].facet-group li a { top: 70px; } +/* --- Facet error --- */ + +.facet-error { + padding: 2em 15em; +} + +.facet-error h1 { + text-align: center; +} + +.facet-error .error-details { + margin-top: 2em; + font-family: monospace; +} + /* ---- Search Facet ---- */ .content-table { diff --git a/install/ui/navigation.js b/install/ui/navigation.js index a4ad28980..502b05490 100644 --- a/install/ui/navigation.js +++ b/install/ui/navigation.js @@ -263,6 +263,10 @@ IPA.navigation = function(spec) { return that.push_state(state); }; + that.show_top_level_page = function() { + jQuery.bbq.pushState({}, 2); + }; + that.get_tab_facet = function(tab_name) { var facet = null; diff --git a/install/ui/test/data/ipa_init.json b/install/ui/test/data/ipa_init.json index 1b95762b4..36a3388d9 100644 --- a/install/ui/test/data/ipa_init.json +++ b/install/ui/test/data/ipa_init.json @@ -91,6 +91,14 @@ "validation_message": "Input form contains invalid or missing values.", "validation_title": "Validation error" }, + "error_report": { + "options": "Please try the following options:", + "problem_persists": "If the problem persists please contact the system administrator.", + "refresh": "Refresh the page.", + "reload": "Reload the browser.", + "main_page": "Return to the main page and retry the operation", + "title": "An error has occured (${error})" + }, "errors": { "error": "Error", "http_error": "HTTP Error", diff --git a/ipalib/plugins/internal.py b/ipalib/plugins/internal.py index d00f06ab3..541d85cfb 100644 --- a/ipalib/plugins/internal.py +++ b/ipalib/plugins/internal.py @@ -226,6 +226,14 @@ class i18n_messages(Command): "validation_title": _("Validation error"), "validation_message": _("Input form contains invalid or missing values."), }, + "error_report": { + "options": _("Please try the following options:"), + "problem_persists": _("If the problem persists please contact the system administrator."), + "refresh": _("Refresh the page."), + "reload": _("Reload the browser."), + "main_page": _("Return to the main page and retry the operation"), + "title": _("An error has occured (${error})"), + }, "errors": { "error": _("Error"), "http_error": _("HTTP Error"), -- cgit