----- "Adam Young" <ayo...@redhat.com> wrote:

> Endi, can you add in a Unit test for this? If need be, extend the
> ipa_cmd so that it looks for an optional command line param that makes
> it try to fetch a .json file that doesn't exist:
> 
> 
> Something like
> var suffix = $.bbq.get("cmd_suffix");
> if (suffix){
> method += suffix;
> }
> method += '.json';
> 
> ...

Attached is a new patch based on the latest master with unit tests.
ipa_cmd() error can be simulated by overriding $.ajax with a mockup
function. Thanks!

--
Endi S. Dewata
>From 9684ca8f41277792d8873fe8052078b51c87acb3 Mon Sep 17 00:00:00 2001
From: Endi S. Dewata <edew...@redhat.com>
Date: Wed, 29 Sep 2010 00:52:56 -0500
Subject: [PATCH] Added error handler for ipa_cmd().

The ipa_cmd() has been modified such that when an error occurs a
dialog box will appear showing the error message with 2 buttons:
Retry and Cancel. If Retry is clicked, it will attempt to execute
the same operation again. If Cancel is clicked, the operation will
be canceled and the control is returned to the caller.

New unit tests have been added to test ipa_cmd() on successfull
and unsuccessfull cases.

The associate.js, details.js, entity.js, search.js, and webui.js
have been modified to display the error message inside the page.
This behavior can be changed in the future (e.g. redirect to error
page).

The navigation.js and webui.js have been modified to render only
the visible tabs. This improves the performance and reduce hidden
errors. The navigation unit test has been modified to reflect this
behavior.

Some variables/functions also have been renamed for consistency.
---
 install/static/associate.js             |   42 ++++----
 install/static/details.js               |   29 +++--
 install/static/entity.js                |    5 +-
 install/static/ipa.js                   |   38 +++++-
 install/static/navigation.js            |   64 ++++++++++-
 install/static/search.js                |   38 ++++--
 install/static/test/ipa_tests.html      |    3 +
 install/static/test/ipa_tests.js        |  201 +++++++++++++++++++++++++++++++
 install/static/test/navigation_tests.js |   12 +-
 install/static/webui.js                 |   67 ++---------
 10 files changed, 380 insertions(+), 119 deletions(-)

diff --git a/install/static/associate.js b/install/static/associate.js
index 207c745..c3453e9 100644
--- a/install/static/associate.js
+++ b/install/static/associate.js
@@ -222,30 +222,30 @@ function AssociationList(obj, pkey, manyObj, associationColumns, jobj)
     this.manyObj = manyObj;
     this.parentTab = jobj;
 
-    this.populate = function(userData) {
-       var tbody = this.parentTab.find('.search-table tbody');
-       tbody.empty();
-       var associationList = userData.result.result[this.associationColumns[0].column];
-       for (var j = 0; j < associationList.length; j++){
-            var row  = $("<tr/>").appendTo(tbody);
-            for (var k = 0; k < associationColumns.length ;k++){
-                var column = this.associationColumns[k].column;
-                $("<td></td>",{
-                    html: userData.result.result[column][j]
-                }).appendTo(row);
+    this.refresh = function() {
+
+        function refresh_on_success(userData) {
+           var tbody = this.parentTab.find('.search-table tbody');
+           tbody.empty();
+           var associationList = userData.result.result[this.associationColumns[0].column];
+           for (var j = 0; j < associationList.length; j++){
+                var row  = $("<tr/>").appendTo(tbody);
+                for (var k = 0; k < associationColumns.length ;k++){
+                    var column = this.associationColumns[k].column;
+                    $("<td></td>",{
+                        html: userData.result.result[column][j]
+                    }).appendTo(row);
+                }
             }
         }
-    }
 
-    this.refresh = function() {
-        ipa_cmd( 'show', [this.pkey], {},
-                 function(result){
-                     form.populate(result);
-                 },
-                 function(){
-                     alert("associationListFailure");
-                 },
-                 form.obj);
+        function refresh_on_error(xhr, text_status, error_thrown) {
+            var search_results = $('.search-results', jobj).empty();
+            search_results.append('<p>Error: '+error_thrown.name+'</p>');
+            search_results.append('<p>'+error_thrown.message+'</p>');
+        }
+
+        ipa_cmd('show', [this.pkey], {}, refresh_on_success, refresh_on_error, form.obj);
     }
 
     this.setup = function() {
diff --git a/install/static/details.js b/install/static/details.js
index f68c773..4e37ed6 100644
--- a/install/static/details.js
+++ b/install/static/details.js
@@ -37,20 +37,24 @@ function ipa_details_create(obj_name, dls, container)
     container.attr('title', obj_name);
     container.addClass('details-container');
 
-    container.append('<div class="details-buttons"></div>');
-    var jobj = container.children().last();
+    var details = $('<div/>', {
+        class: 'details'
+    }).appendTo(container);
+
+    details.append('<div class="details-buttons"></div>');
+    var jobj = details.children().last();
     jobj.append('<a class="details-reset" href="jslink">Reset</a>');
     jobj.append('<a class="details-update" href="jslink">Update</a>');
 
-    container.append('<hr />');
+    details.append('<hr />');
 
     for (var i = 0; i < dls.length; ++i) {
         var d = dls[i];
-        ipa_generate_dl(container.children().last(), d[0], d[1], d[2]);
+        ipa_generate_dl(details.children().last(), d[0], d[1], d[2]);
     }
 
-    container.append('<div class="details-back"></div>');
-    var jobj = container.children().last();
+    details.append('<div class="details-back"></div>');
+    var jobj = details.children().last();
     jobj.append('<a href="#details-viewtype">Back to Top</a>');
 }
 
@@ -87,8 +91,10 @@ function ipa_generate_dl(jobj, id, name, dts)
     jobj.after('<hr />');
 }
 
-function ipa_details_load(obj_name, pkey, on_win, on_fail, sampleData)
+function ipa_details_load(jobj, pkey, on_win, on_fail)
 {
+    var obj_name = jobj.attr('id');
+
     function load_on_win(data, text_status, xhr) {
         if (on_win)
             on_win(data, text_status, xhr);
@@ -103,14 +109,17 @@ function ipa_details_load(obj_name, pkey, on_win, on_fail, sampleData)
     function load_on_fail(xhr, text_status, error_thrown) {
         if (on_fail)
             on_fail(xhr, text_status, error_thrown);
+
+        var details = $('.details', jobj).empty();
+        details.append('<p>Error: '+error_thrown.name+'</p>');
+        details.append('<p>'+error_thrown.message+'</p>');
     };
 
     if (!pkey)
         return;
 
     ipa_cmd(
-        'show', [pkey], {all: true}, load_on_win, load_on_fail,
-        obj_name, sampleData
+        'show', [pkey], {all: true}, load_on_win, load_on_fail, obj_name
     );
 }
 
@@ -301,7 +310,7 @@ var _ipa_param_type_2_handler_map = {
     'Str': _ipa_create_text_input,
     'Int': _ipa_create_text_input,
     'Bool': _ipa_create_text_input,
-    'List': _ipa_create_text_input,
+    'List': _ipa_create_text_input
 };
 
 /* create an HTML element for displaying/editing an attribute
diff --git a/install/static/entity.js b/install/static/entity.js
index 7fb19fc..7b82c06 100644
--- a/install/static/entity.js
+++ b/install/static/entity.js
@@ -83,7 +83,7 @@ function ipa_entity_setup(jobj)
         }).appendTo($( "div#" + obj_name + " > div.search-controls"));
 
         if (typeof filter != 'undefined')
-            search_load(obj_name, filter, null, null);
+            search_load(jobj, filter, null, null);
     };
 
     function setup_details_facet() {
@@ -92,8 +92,9 @@ function ipa_entity_setup(jobj)
         ipa_details_create(obj_name, ipa_entity_details_list[obj_name], jobj);
         jobj.find('.details-reset').click(reset_on_click);
         jobj.find('.details-update').click(update_on_click);
+
         if (pkey)
-            ipa_details_load(obj_name, pkey, null, null);
+            ipa_details_load(jobj, pkey, null, null);
     };
 
     function setup_associate_facet() {
diff --git a/install/static/ipa.js b/install/static/ipa.js
index 6000fb7..25a3f1b 100644
--- a/install/static/ipa.js
+++ b/install/static/ipa.js
@@ -30,7 +30,7 @@ var ipa_ajax_options = {
     contentType: 'application/json',
     dataType: 'json',
     async: true,
-    processData: false,
+    processData: false
 };
 
 /* JSON-RPC ID counter */
@@ -40,6 +40,7 @@ var ipa_jsonrpc_id = 0;
 var ipa_messages = {};
 var ipa_objs = {};
 
+var ipa_dialog = $('<div/>', {id: 'ipa_dialog'});
 
 /* initialize the IPA JSON-RPC helper
  * arguments:
@@ -74,9 +75,33 @@ function ipa_init(url, use_static_files, on_win, on_error)
  *   objname - name of an IPA object (optional) */
 function ipa_cmd(name, args, options, win_callback, fail_callback, objname)
 {
+    function ipa_error_handler(xhr, text_status, error_thrown) {
+        ipa_dialog.empty();
+        ipa_dialog.attr('title', 'Error: '+error_thrown.name);
+        ipa_dialog.append('<p>'+error_thrown.message+'</p>');
+
+        ipa_dialog.dialog({
+            modal: true,
+            width: 400,
+            buttons: {
+                'Retry': function() {
+                    ipa_dialog.dialog('close');
+                    ipa_cmd(name, args, options, win_callback, fail_callback, objname);
+                },
+                'Cancel': function() {
+                    ipa_dialog.dialog('close');
+                    fail_callback(xhr, text_status, error_thrown);
+                }
+            }
+        });
+    };
+
     id = ipa_jsonrpc_id++;
+
+    var method_name = name;
+
     if (objname)
-        name = objname + '_' + name;
+        method_name = objname + '_' + name;
 
     var url = ipa_json_url;
 
@@ -84,19 +109,19 @@ function ipa_cmd(name, args, options, win_callback, fail_callback, objname)
         url = IPA_DEFAULT_JSON_URL;
 
     if (ipa_use_static_files)
-        url += '/' + name + '.json';
+        url += '/' + method_name + '.json';
 
     var data = {
-        method: name,
+        method: method_name,
         params: [args, options],
-        id: id,
+        id: id
     };
 
     var request = {
         url: url,
         data: JSON.stringify(data),
         success: win_callback,
-        error: fail_callback,
+        error: ipa_error_handler
     };
 
     $.ajax(request);
@@ -163,4 +188,3 @@ function ipa_get_member_attribute(obj_name, member)
 
     return null;
 }
-
diff --git a/install/static/navigation.js b/install/static/navigation.js
index 169729b..3aa49fe 100644
--- a/install/static/navigation.js
+++ b/install/static/navigation.js
@@ -18,6 +18,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
 
+/* use this to track individual changes between two hashchange events */
+var window_hash_cache = {};
 
 function nav_create(nls, container, tabclass)
 {
@@ -38,6 +40,8 @@ function nav_create(nls, container, tabclass)
             return true;
         }
     });
+
+    nav_update_tabs(nls, container);
 }
 
 function nav_generate_tabs(nls, container, tabclass, depth)
@@ -62,9 +66,7 @@ function nav_generate_tabs(nls, container, tabclass, depth)
         var div = nav_create_tab_div(n.name);
         container.append(div);
 
-        if (n.setup) {
-            n.setup(div);
-        } else if (n.children) {
+        if (n.children) {
             nav_generate_tabs(n.children, div, tabclass, depth +1 );
         }
     }
@@ -103,3 +105,59 @@ function nav_select_tabs(nls, container)
         }
     }
 }
+
+function nav_update_tabs(nls, container)
+{
+    nav_select_tabs(nls, container);
+
+    var index1 = container.tabs('option', 'selected');
+    if (index1 >= nls.length) return;
+
+    var tab1 = nls[index1];
+    if (!tab1.children) return;
+
+    var div1 = $('#' + tab1.name);
+    var index2 = div1.tabs('option', 'selected');
+    if (index2 >= tab1.children.length) return;
+
+    var tab2 = tab1.children[index2];
+    var obj_name = tab2.name;
+    var entity_setup = tab2.setup;
+    var div2 = $('#' + tab2.name);
+
+    var state = obj_name + '-facet';
+    var facet = $.bbq.getState(state, true) || 'search';
+    var last_facet = window_hash_cache[state];
+
+    if (facet != last_facet) {
+        entity_setup(div2);
+        window_hash_cache[state] = facet;
+
+    } else if (facet == 'search') {
+        state = obj_name + '-filter';
+        var filter = $.bbq.getState(state, true);
+        var last_filter = window_hash_cache[state];
+        if (filter == last_filter) return;
+
+        entity_setup(div2);
+        window_hash_cache[state] = filter;
+
+    } else if (facet == 'details') {
+        state = obj_name + '-pkey';
+        var pkey = $.bbq.getState(state, true);
+        var last_pkey = window_hash_cache[state];
+        if (pkey == last_pkey) return;
+
+        entity_setup(div2);
+        window_hash_cache[state] = pkey;
+
+    } else if (facet == 'associate') {
+        state = obj_name + '-enroll';
+        var enroll = $.bbq.getState(state, true);
+        var last_enroll = window_hash_cache[state];
+        if (enroll == last_enroll) return;
+
+        entity_setup(div2);
+        window_hash_cache[state] = enroll;
+    }
+}
diff --git a/install/static/search.js b/install/static/search.js
index 5e5be8f..59caf71 100644
--- a/install/static/search.js
+++ b/install/static/search.js
@@ -52,13 +52,19 @@ function search_create(obj_name, scl, container)
     jobj.children().last().click(find_on_click);
     div.append('<span class="search-buttons"></span>');
 
-    container.append('<table class="search-table"></table>');
-    jobj = container.children().last();
-    jobj.append('<thead><tr></tr></thead>');
-    jobj.append('<tbody></tbody>');
-    jobj.append('<tfoot></tfoot>');
+    var search_results = $('<div/>', {
+        class: 'search-results'
+    }).appendTo(container);
 
-    var tr = jobj.find('tr');
+    var search_table = $('<table/>', {
+        class: 'search-table'
+    }).appendTo(search_results);
+
+    search_table.append('<thead><tr></tr></thead>');
+    search_table.append('<tbody></tbody>');
+    search_table.append('<tfoot></tfoot>');
+
+    var tr = search_table.find('tr');
     for (var i = 0; i < scl.length; ++i) {
         var c = scl[i];
         search_insert_th(tr, obj_name, c[0], c[1], c[2]);
@@ -85,23 +91,29 @@ function search_insert_th(jobj, obj_name, attr, name, render_call)
     jobj.append(th);
 }
 
-function search_load(obj_name, criteria, on_win, on_fail)
+function search_load(jobj, criteria, on_win, on_fail)
 {
-    function load_on_win(data, text_status, xhr) {
+    var obj_name = jobj.attr('id');
+
+    function search_on_success(data, text_status, xhr) {
+        if (on_win)
+            on_win(data, text_status, xhr);
         if (data.error)
             return;
         search_display(obj_name, data);
-        if (on_win)
-            on_win(data, text_status, xhr);
     };
 
-    function load_on_fail(xhr, text_status, error_thrown) {
+    function search_on_error(xhr, text_status, error_thrown) {
         if (on_fail)
             on_fail(xhr, text_status, error_thrown);
-    };
+
+        var search_results = $('.search-results', jobj);
+        search_results.append('<p>Error: '+error_thrown.name+'</p>');
+        search_results.append('<p>'+error_thrown.message+'</p>');
+    }
 
     ipa_cmd(
-      'find', [criteria], {all: true}, load_on_win, load_on_fail, obj_name
+      'find', [criteria], {all: true}, search_on_success, search_on_error, obj_name
     );
 }
 
diff --git a/install/static/test/ipa_tests.html b/install/static/test/ipa_tests.html
index 3031f23..dfe2720 100644
--- a/install/static/test/ipa_tests.html
+++ b/install/static/test/ipa_tests.html
@@ -3,8 +3,11 @@
 <head>
     <title>Core Test Suite</title>
     <link rel="stylesheet" href="qunit.css" type="text/css" media="screen">
+    <link rel="stylesheet" type="text/css" href="../jquery-ui.css" />
+
     <script type="text/javascript" src="qunit.js"></script>
     <script type="text/javascript" src="../jquery.js"></script>
+    <script type="text/javascript" src="../jquery-ui.js"></script>
     <script type="text/javascript" src="../ipa.js"></script>
     <script type="text/javascript" src="ipa_tests.js"></script>
 </head>
diff --git a/install/static/test/ipa_tests.js b/install/static/test/ipa_tests.js
index 8dbdd62..8617a84 100644
--- a/install/static/test/ipa_tests.js
+++ b/install/static/test/ipa_tests.js
@@ -92,3 +92,204 @@ test("Testing ipa_get_member_attribute().", function() {
         "ipa_get_member_attribute(null, \"group\")"
     );
 });
+
+test("Testing successful ipa_cmd().", function() {
+
+    var method = 'method';
+    var args = ['arg1', 'arg2', 'arg3'];
+    var options = {
+        opt1: 'val1',
+        opt2: 'val2',
+        opt3: 'val3'
+    };
+    var object = 'object';
+
+    var success_handler_counter = 0;
+    var error_handler_counter = 0;
+
+    function success_handler(data, status, xhr) {
+        success_handler_counter++;
+    }
+
+    function error_handler(xhr, text_status, error_thrown) {
+        error_handler_counter++;
+    }
+
+    var orig = $.ajax;
+
+    var xhr = {};
+    var text_status = null;
+    var error_thrown = {name:'ERROR', message:'An error has occured'};
+
+    var ajax_counter = 0;
+
+    $.ajax = function(request) {
+        ajax_counter++;
+
+        equals(
+            request.url, "data/"+object+"_"+method+".json",
+            "Checking request.url"
+        );
+
+        var data = JSON.parse(request.data);
+
+        equals(
+            data.method, object+'_'+method,
+            "Checking method"
+        );
+
+        same(
+            data.params, [args, options],
+            "Checking parameters"
+        );
+
+        request.success(xhr, text_status, error_thrown);
+    };
+
+    ipa_cmd(method, args, options, success_handler, error_handler, object);
+
+    equals(
+        ajax_counter, 1,
+        "Checking ajax invocation counter"
+    );
+
+    var dialog = ipa_dialog.parent('.ui-dialog');
+
+    ok(
+        !dialog.length,
+        "The dialog box is not created."
+    );
+
+    ok(
+        success_handler_counter == 1 && error_handler_counter == 0,
+        "Only the success handler is called."
+    );
+
+    $.ajax = orig;
+});
+
+test("Testing unsuccessful ipa_cmd().", function() {
+
+    var method = 'method';
+    var args = ['arg1', 'arg2', 'arg3'];
+    var options = {
+        opt1: 'val1',
+        opt2: 'val2',
+        opt3: 'val3'
+    };
+    var object = 'object';
+
+    var success_handler_counter = 0;
+    var error_handler_counter = 0;
+
+    function success_handler(data, status, xhr) {
+        success_handler_counter++;
+    }
+
+    function error_handler(xhr, text_status, error_thrown) {
+        error_handler_counter++;
+    }
+
+    var orig = $.ajax;
+
+    var xhr = {};
+    var text_status = null;
+    var error_thrown = {name:'ERROR', message:'An error has occured'};
+
+    var ajax_counter = 0;
+
+    $.ajax = function(request) {
+        ajax_counter++;
+
+        equals(
+            request.url, "data/"+object+"_"+method+".json",
+            "Checking request.url"
+        );
+
+        var data = JSON.parse(request.data);
+
+        equals(
+            data.method, object+'_'+method,
+            "Checking method"
+        );
+
+        same(
+            data.params, [args, options],
+            "Checking parameters"
+        );
+
+        request.error(xhr, text_status, error_thrown);
+    };
+
+    ipa_cmd(method, args, options, success_handler, error_handler, object);
+
+    var dialog = ipa_dialog.parent('.ui-dialog');
+
+    equals(
+        ajax_counter, 1,
+        "Checking ajax invocation counter"
+    );
+
+    ok(
+        dialog.length == 1 && ipa_dialog.dialog('isOpen'),
+        "The dialog box is created and open."
+    );
+
+    ok(
+        success_handler_counter == 0 && error_handler_counter == 0,
+        "Initially none of the handlers are called."
+    );
+
+    // search the retry button from the beginning
+    var retry = $('button', dialog).first();
+    retry.trigger('click');
+
+    equals(
+        ajax_counter, 2,
+        "Checking ajax invocation counter"
+    );
+
+    ok(
+        success_handler_counter == 0 && error_handler_counter == 0,
+        "After 1st retry, none of the handlers are called."
+    );
+
+    // search the retry button from the beginning again because the dialog
+    // has been recreated
+    dialog = ipa_dialog.parent('.ui-dialog');
+    retry = $('button', dialog).first();
+    retry.trigger('click');
+
+    equals(
+        ajax_counter, 3,
+        "Checking ajax invocation counter"
+    );
+
+    ok(
+        success_handler_counter == 0 && error_handler_counter == 0,
+        "After 2nd retry, none of the handlers are called."
+    );
+
+    // search the cancel button from the beginning because the dialog has
+    // been recreated
+    dialog = ipa_dialog.parent('.ui-dialog');
+    var cancel = $('button', dialog).first().next();
+    cancel.trigger('click');
+
+    equals(
+        ajax_counter, 3,
+        "Checking ajax invocation counter"
+    );
+
+    ok(
+        !ipa_dialog.dialog('isOpen'),
+        "After cancel, the dialog box is closed."
+    );
+
+    ok(
+        success_handler_counter == 0 && error_handler_counter == 1,
+        "Only the error handler is called."
+    );
+
+    $.ajax = orig;
+});
diff --git a/install/static/test/navigation_tests.js b/install/static/test/navigation_tests.js
index 16b3ae9..4144e81 100644
--- a/install/static/test/navigation_tests.js
+++ b/install/static/test/navigation_tests.js
@@ -41,17 +41,17 @@ test("Testing nav_create().", function() {
 
     }
     ipa_objs= {};
-    var navigation = $('<div id="navigation"/>');
+    var navigation = $('<div id="navigation"/>').appendTo(document.body);
     var user_mock_called = false;
     var group_mock_called = false;
     nav_create(mock_tabs_lists, navigation, 'tabs')
-    ok(user_mock_called, "mock setup was called");
-    ok(group_mock_called, "mock setup was called");
+    ok(user_mock_called, "mock user setup was called");
+    ok(!group_mock_called, "mock group setup was not called because the tab is inactive");
     same( navigation[0].children.length, 2, "Two Child tabs");
     same( navigation[0].children[1].id, 'identity', "Identity Tab");
     same( navigation[0].children[1].children[1].id, 'user', "User Tab");
     same( navigation[0].children[1].children[2].id, 'group', "User Tab");
-
+    navigation.remove();
 });
 
 test("Testing  nav_select_tabs().", function() {
@@ -64,12 +64,14 @@ test("Testing  nav_select_tabs().", function() {
                 {name:'two', label:'Two', setup: function (){}},
             ]}];
 
-    var navigation = $('<div id="navigation"/>');
+    var navigation = $('<div id="navigation"/>').appendTo(document.body);
 
     nav_create(mock_tabs_lists, navigation, 'tabs')
 
     $.bbq.pushState({"identity":2});
     nav_select_tabs(mock_tabs_lists, navigation);
     same( navigation[0].children[1].children[2].id, 'two', "Tab two");
+    $.bbq.removeState(["identity"]);
 
+    navigation.remove();
 });
diff --git a/install/static/webui.js b/install/static/webui.js
index 331ec82..ac28412 100644
--- a/install/static/webui.js
+++ b/install/static/webui.js
@@ -75,7 +75,6 @@ $(function() {
 
             var navigation = $('#navigation');
             nav_create(nav_tabs_lists, navigation, 'tabs');
-            nav_select_tabs(nav_tabs_lists, navigation);
 
             $('#login_header').html(ipa_messages.login.header);
         }else{
@@ -84,71 +83,23 @@ $(function() {
     };
 
     function init_on_win(data, text_status, xhr) {
-        ipa_cmd('user_find', [], {"whoami":"true","all":"true"}, whoami_on_win,
-            function(xhr, options, thrownError) {
-                alert("Error: "+thrownError);
-            },
-            null
-        );
+        ipa_cmd('user_find', [], {"whoami":"true","all":"true"}, whoami_on_win, init_on_error, null);
     };
 
-    ipa_init(null, null, init_on_win,
-        function(xhr, options, thrownError) {
-            alert("Error: "+thrownError);
-        }
-    );
-});
+    function init_on_error(xhr, text_status, error_thrown) {
+        var navigation = $('#navigation').empty();
+        navigation.append('<p>Error: '+error_thrown.name+'</p>');
+        navigation.append('<p>'+error_thrown.message+'</p>');
+    }
 
-/* use this to track individual changes between two hashchange events */
-var window_hash_cache = {};
+    ipa_init(null, null, init_on_win, init_on_error);
+});
 
 /* main loop (hashchange event handler) */
 function window_hashchange(evt)
 {
     var navigation = $('#navigation');
-    nav_select_tabs(nav_tabs_lists, navigation);
-
-    for (var i = 0; i < nav_tabs_lists.length; ++i) {
-        var t = nav_tabs_lists[i];
-        if (!(t.setup) && t.children) {
-            for (var j = 0; j < t.children.length; ++j) {
-                var tt = t.children[j];
-                var obj_name = tt.name;
-                var entity_setup = tt.setup;
-                var div = $('#' + tt.name);
-
-                var state = obj_name + '-facet';
-                var facet = $.bbq.getState(state, true) || 'search';
-                var last_facet = window_hash_cache[state] || 'search';
-                if (facet != last_facet) {
-                    entity_setup(div);
-                    continue;
-                }
-
-                if (facet == 'search') {
-                    state = obj_name + '-filter';
-                    var filter = $.bbq.getState(state, true);
-                    var last_filter = window_hash_cache[state];
-                    if (filter != last_filter)
-                        entity_setup(div);
-                } else if (facet == 'details') {
-                    state = obj_name + '-pkey';
-                    var pkey = $.bbq.getState(state, true);
-                    var last_pkey = window_hash_cache[state];
-                    if (pkey != last_pkey)
-                        entity_setup(div);
-                } else if (facet == 'associate') {
-                    state = obj_name + '-enroll';
-                    var enroll = $.bbq.getState(state, true);
-                    var last_enroll = window_hash_cache[state];
-                    if (enroll != last_enroll)
-                        entity_setup(div);
-                }
-            }
-        }
-    }
-
-    window_hash_cache = $.bbq.getState();
+    nav_update_tabs(nav_tabs_lists, navigation);
 }
 
 /* builder function for unimplemented tab content */
-- 
1.6.6.1

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to