From 31d7486b88bc0e30c8a84ab4d2f73c35a700dad8 Mon Sep 17 00:00:00 2001 From: Petr Vobornik Date: Thu, 31 Jan 2013 17:25:14 +0100 Subject: Remove IPA.nav usage, obsolete entity.get_primary_key https://fedorahosted.org/freeipa/ticket/3236 --- install/ui/src/freeipa/aci.js | 2 +- install/ui/src/freeipa/add.js | 8 +- install/ui/src/freeipa/association.js | 60 ++--- install/ui/src/freeipa/automember.js | 10 +- install/ui/src/freeipa/automount.js | 41 +-- install/ui/src/freeipa/details.js | 53 +--- install/ui/src/freeipa/dns.js | 33 ++- install/ui/src/freeipa/entity.js | 148 +---------- install/ui/src/freeipa/facet.js | 464 ++++++++++++++++++++++++++++++---- install/ui/src/freeipa/field.js | 8 +- install/ui/src/freeipa/hbactest.js | 29 +-- install/ui/src/freeipa/host.js | 2 +- install/ui/src/freeipa/ipa.js | 13 +- install/ui/src/freeipa/navigation.js | 150 +++++++++++ install/ui/src/freeipa/navigation2.js | 150 ----------- install/ui/src/freeipa/rule.js | 2 +- install/ui/src/freeipa/search.js | 44 +--- install/ui/src/freeipa/sudo.js | 4 +- install/ui/src/freeipa/user.js | 24 +- install/ui/src/freeipa/widget.js | 8 +- 20 files changed, 712 insertions(+), 541 deletions(-) create mode 100644 install/ui/src/freeipa/navigation.js delete mode 100644 install/ui/src/freeipa/navigation2.js diff --git a/install/ui/src/freeipa/aci.js b/install/ui/src/freeipa/aci.js index ceda40f8d..0852994fd 100644 --- a/install/ui/src/freeipa/aci.js +++ b/install/ui/src/freeipa/aci.js @@ -221,7 +221,7 @@ IPA.aci.permission_details_facet = function(spec) { var that = IPA.details_facet(spec); that.get_refresh_command_name = function() { - return that.entity.name+'_show_'+that.pkey; + return that.entity.name+'_show_'+that.get_pkey(); }; return that; diff --git a/install/ui/src/freeipa/add.js b/install/ui/src/freeipa/add.js index 1b4a1ae59..388b4e497 100644 --- a/install/ui/src/freeipa/add.js +++ b/install/ui/src/freeipa/add.js @@ -19,7 +19,8 @@ * along with this program. If not, see . */ -define(['./ipa', './jquery', './field', './widget', './dialog'], function(IPA, $) { +define(['./ipa', './jquery', './navigation', './field', './widget', './dialog'], + function(IPA, $, navigation) { IPA.entity_adder_dialog = function(spec) { @@ -127,7 +128,10 @@ IPA.entity_adder_dialog = function(spec) { if (pkey instanceof Array) { pkey = pkey[0]; } - IPA.nav.show_entity_page(that.entity, 'default', pkey); + + var pkeys = that.facet.get_pkeys(); + pkeys.push(pkey); + navigation.show_entity(that.entity.name, 'default', [pkeys]); } that.create_add_command = function(record) { diff --git a/install/ui/src/freeipa/association.js b/install/ui/src/freeipa/association.js index c6b9e5a4e..93b5ba7ad 100644 --- a/install/ui/src/freeipa/association.js +++ b/install/ui/src/freeipa/association.js @@ -22,7 +22,8 @@ /* CURRENTLY ALSO REQUIRES search.js, because it reuses it's code to create * the AssociationList elements; IT NEEDS IT'S OWN CODE! */ -define(['./ipa', './jquery', './search', './dialog'], function(IPA, $) { +define(['./ipa', './jquery', './navigation', './search', './dialog'], + function(IPA, $, navigation) { IPA.associator = function (spec) { @@ -384,7 +385,7 @@ IPA.association_table_widget = function (spec) { if (column.link) { column.link_handler = function(value) { - IPA.nav.show_page(that.other_entity.name, 'default', value); + navigation.show_entity(that.other_entity.name, 'default', [value]); return false; }; } @@ -536,7 +537,7 @@ IPA.association_table_widget = function (spec) { that.create_add_dialog = function() { var entity_label = that.entity.metadata.label_singular; - var pkey = IPA.nav.get_state(that.entity.name+'-pkey'); + var pkey = that.facet.get_pkey(); var other_entity_label = that.other_entity.metadata.label; var title = that.add_title; @@ -584,7 +585,7 @@ IPA.association_table_widget = function (spec) { that.add = function(values, on_success, on_error) { - var pkey = IPA.nav.get_state(that.entity.name+'-pkey'); + var pkey = that.facet.get_pkey(); var command = IPA.command({ entity: that.entity.name, @@ -609,7 +610,7 @@ IPA.association_table_widget = function (spec) { } var entity_label = that.entity.metadata.label_singular; - var pkey = IPA.nav.get_state(that.entity.name+'-pkey'); + var pkey = that.facet.get_pkey(); var other_entity_label = that.other_entity.metadata.label; var title = that.remove_title; @@ -645,7 +646,7 @@ IPA.association_table_widget = function (spec) { that.remove = function(values, on_success, on_error) { - var pkey = IPA.nav.get_state(that.entity.name+'-pkey'); + var pkey = that.facet.get_pkey(); var command = IPA.command({ entity: that.entity.name, @@ -704,7 +705,7 @@ IPA.association_table_field = function (spec) { that.widget.summary.text(error_thrown.name+': '+error_thrown.message); } - var pkey = IPA.nav.get_state(that.entity.name+'-pkey'); + var pkey = that.facet.get_pkey(); IPA.command({ entity: that.entity.name, method: 'show', @@ -952,15 +953,14 @@ IPA.association_facet = function (spec, no_init) { that.show = function() { that.facet_show(); - - that.pkey = IPA.nav.get_state(that.entity.name+'-pkey'); - that.header.set_pkey(that.pkey); + var pkey = that.get_pkey(); + that.header.set_pkey(pkey); }; that.show_add_dialog = function() { var entity_label = that.entity.metadata.label_singular; - var pkey = IPA.nav.get_state(that.entity.name+'-pkey'); + var pkey = that.get_pkey(); var other_entity_label = that.other_entity.metadata.label; var title = that.add_title; @@ -986,7 +986,7 @@ IPA.association_facet = function (spec, no_init) { dialog.execute = function() { - var pkey = IPA.nav.get_state(that.entity.name+'-pkey'); + var pkey = that.get_pkey(); var associator = that.associator({ entity: that.entity, @@ -1022,7 +1022,7 @@ IPA.association_facet = function (spec, no_init) { } var entity_label = that.entity.metadata.label_singular; - var pkey = IPA.nav.get_state(that.entity.name+'-pkey'); + var pkey = that.get_pkey(); var other_entity_label = that.other_entity.metadata.label; var title = that.remove_title; @@ -1086,12 +1086,13 @@ IPA.association_facet = function (spec, no_init) { if (that.indirect_radio) that.indirect_radio.prop('checked', true); } - var pkey = that.entity.get_primary_key(); + //var pkey = that.entity.get_primary_key(); + var pkeys = that.get_pkeys(); var command = IPA.command({ entity: that.entity.name, method: 'show', - args: pkey + args: pkeys }); command.on_success = function(data, text_status, xhr) { @@ -1112,18 +1113,6 @@ IPA.association_facet = function (spec, no_init) { that.table.clear(); }; - that.needs_update = function() { - if (that._needs_update !== undefined) return that._needs_update; - - var pkey = IPA.nav.get_state(that.entity.name+'-pkey'); - if (that.pkey !== pkey) return true; - - var page = parseInt(IPA.nav.get_state(that.entity.name+'-page'), 10) || 1; - if (that.table.current_page !== page) return true; - - return that.facet_needs_update(); - }; - that.init_association_facet = function() { that.init_facet(); @@ -1208,9 +1197,8 @@ IPA.attribute_facet = function(spec, no_init) { that.show = function() { that.facet_show(); - - that.pkey = IPA.nav.get_state(that.entity.name+'-pkey'); - that.header.set_pkey(that.pkey); + var pkey = that.get_pkey(); + that.header.set_pkey(pkey); }; that.get_records_map = function(data) { @@ -1263,18 +1251,6 @@ IPA.attribute_facet = function(spec, no_init) { that.table.clear(); }; - that.needs_update = function() { - if (that._needs_update !== undefined) return that._needs_update; - - var pkey = IPA.nav.get_state(that.entity.name+'-pkey'); - if (that.pkey !== pkey) return true; - - var page = parseInt(IPA.nav.get_state(that.entity.name+'-page'), 10) || 1; - if (that.table.current_page !== page) return true; - - return that.facet_needs_update(); - }; - that.show_add_dialog = function() { var dialog = IPA.attribute_adder_dialog({ diff --git a/install/ui/src/freeipa/automember.js b/install/ui/src/freeipa/automember.js index 2d61f7ebf..0e05b8c59 100644 --- a/install/ui/src/freeipa/automember.js +++ b/install/ui/src/freeipa/automember.js @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -define(['./ipa', './jquery', './details', './search', './association', - './entity'], function(IPA, $) { +define(['./ipa', './jquery', './navigation', './details', './search', './association', + './entity'], function(IPA, $, navigation) { IPA.automember = {}; @@ -82,7 +82,7 @@ IPA.automember.entity = function(spec) { label: IPA.messages.objects.automember.usergrouprule, disable_facet_tabs: true, check_rights: false, - redirect_info: { tab: 'amgroup' } + redirect_info: { facet: 'searchgroup' } }). details_facet({ factory: IPA.automember.rule_details_facet, @@ -91,7 +91,7 @@ IPA.automember.entity = function(spec) { label: IPA.messages.objects.automember.hostgrouprule, disable_facet_tabs: true, check_rights: false, - redirect_info: { tab: 'amhostgroup' } + redirect_info: { facet: 'searchhostgroup' } }). adder_dialog({ factory: IPA.automember.rule_adder_dialog, @@ -335,7 +335,7 @@ IPA.automember.rule_adder_dialog = function(spec) { var facetname = facet.group_type === 'group' ? 'usergrouprule' : 'hostgrouprule'; - IPA.nav.show_entity_page(that.entity, facetname, pkey); + navigation.show_entity(that.entity.name, facetname, [pkey]); }; that.reset = function() { diff --git a/install/ui/src/freeipa/automount.js b/install/ui/src/freeipa/automount.js index 6e8547c7f..aead97d16 100644 --- a/install/ui/src/freeipa/automount.js +++ b/install/ui/src/freeipa/automount.js @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -define(['./ipa', './jquery', './details', './search', './association', - './entity'], function(IPA, $) { +define(['./ipa', './jquery', './navigation', './details', './search', './association', + './entity'], function(IPA, $, navigation) { IPA.automount = {}; @@ -191,11 +191,15 @@ IPA.automount.key_entity = function(spec) { show_edit_page : function(entity, result){ var key = result.automountkey[0]; var info = result.automountinformation[0]; - var state = IPA.nav.get_path_state(entity.name); - state[entity.name + '-facet'] = 'default'; - state[entity.name + '-info'] = info; - state[entity.name + '-pkey'] = key; - IPA.nav.push_state(state); + var pkeys = that.facet.get_pkeys(); + pkeys.push(key); + + var args = { + info: info, + key: key + }; + + navigation.show_entity(entity.name, 'details', pkeys, args); return false; }, fields:['automountkey','automountinformation'] @@ -215,8 +219,8 @@ IPA.automount.key_details_facet = function(spec) { command.args.pop(); - var key = IPA.nav.get_state(that.entity.name + '-pkey'); - var info = IPA.nav.get_state(that.entity.name + '-info'); + var key = that.state.key; + var info = that.state.info; command.options.newautomountinformation = command.options.automountinformation; command.options.automountkey = key; @@ -231,8 +235,8 @@ IPA.automount.key_details_facet = function(spec) { command.args.pop(); - var key = IPA.nav.get_state(that.entity.name + '-pkey'); - var info = IPA.nav.get_state(that.entity.name + '-info'); + var key = that.state.key; + var info = that.state.info; command.options.automountkey = key; command.options.automountinformation = info; @@ -260,11 +264,16 @@ IPA.automount_key_column = function(spec) { href: '#'+key, text: key, click: function() { - var state = IPA.nav.get_path_state(that.entity.name); - state[that.entity.name + '-facet'] = 'default'; - state[that.entity.name + '-info'] = info; - state[that.entity.name + '-pkey'] = key; - IPA.nav.push_state(state); + + var pkeys = that.facet.get_pkeys(); + pkeys.push(key); + + var args = { + info: info, + key: key + }; + + navigation.show_entity(that.entity.name, 'details', pkeys, args); return false; } }).appendTo(container); diff --git a/install/ui/src/freeipa/details.js b/install/ui/src/freeipa/details.js index bd23e564e..929c3a7d4 100644 --- a/install/ui/src/freeipa/details.js +++ b/install/ui/src/freeipa/details.js @@ -294,26 +294,11 @@ IPA.details_facet = function(spec, no_init) { /* the primary key used for show and update is built as an array. for most entities, this will be a single element long, but for some it requires the containing entities primary keys as well.*/ + //FIXME: obsolete this stuff that.get_primary_key = function(from_url) { - var pkey = that.entity.get_primary_key_prefix(); - - if (from_url) { - pkey.push(that.pkey); - } else { - var pkey_name = that.entity.metadata.primary_key; - if (!pkey_name){ - return pkey; - } - var pkey_val = that.data.result.result[pkey_name]; - if (pkey_val instanceof Array) { - pkey.push(pkey_val[0]); - } else { - pkey.push(pkey_val); - } - } - - return pkey; + var pkeys = that.get_pkeys(); + return pkeys; }; that.create = function(container) { @@ -403,24 +388,8 @@ IPA.details_facet = function(spec, no_init) { that.show = function() { that.facet_show(); - - that.pkey = IPA.nav.get_state(that.entity.name+'-pkey'); - that.old_key_prefix = that.entity.get_primary_key_prefix(); - that.header.set_pkey(that.pkey); - }; - - that.needs_update = function() { - if (that._needs_update !== undefined) return that._needs_update; - - var needs_update = that.facet_needs_update(); - - var pkey = IPA.nav.get_state(that.entity.name+'-pkey'); - var key_prefix = that.entity.get_primary_key_prefix(); - - needs_update = needs_update || pkey !== that.pkey; - needs_update = needs_update || IPA.array_diff(key_prefix, that.old_key_prefix); - - return needs_update; + var pkey = that.get_pkey(); + that.header.set_pkey(pkey); }; that.field_dirty_changed = function(dirty) { @@ -649,7 +618,7 @@ IPA.details_facet = function(spec, no_init) { options: options }); - if (that.pkey) { + if (that.get_pkey()) { command.args = that.get_primary_key(true); } @@ -668,9 +637,7 @@ IPA.details_facet = function(spec, no_init) { that.refresh = function(on_success, on_error) { - that.pkey = IPA.nav.get_state(that.entity.name+'-pkey'); - - if (!that.pkey && that.entity.redirect_facet) { + if (!that.get_pkey() && that.entity.redirect_facet) { that.redirect(); return; } @@ -1120,12 +1087,12 @@ IPA.object_action = function(spec) { that.execute_action = function(facet, on_success, on_error) { var entity_name = facet.entity.name; - var pkey = IPA.nav.get_state(entity_name+'-pkey'); + var pkeys = facet.get_pkeys(); IPA.command({ entity: entity_name, method: that.method, - args: [pkey], + args: pkeys, options: that.options, on_success: that.get_on_success(facet, on_success), on_error: that.get_on_error(facet, on_error) @@ -1156,7 +1123,7 @@ IPA.object_action = function(spec) { }; that.get_confirm_message = function(facet) { - var pkey = IPA.nav.get_state(facet.entity.name+'-pkey'); + var pkey = that.get_pkey(); var msg = that.confirm_msg.replace('${object}', pkey); return msg; }; diff --git a/install/ui/src/freeipa/dns.js b/install/ui/src/freeipa/dns.js index 920bbd00c..525debb5b 100644 --- a/install/ui/src/freeipa/dns.js +++ b/install/ui/src/freeipa/dns.js @@ -20,8 +20,8 @@ */ -define(['./ipa', './jquery', './net', './details', './search', './association', - './entity'], function(IPA, $, NET) { +define(['./ipa', './jquery', './net', './navigation', './details', './search', './association', + './entity'], function(IPA, $, NET, navigation) { IPA.dns = { zone_permission_name: 'Manage DNS zone ${dnszone}' @@ -332,7 +332,7 @@ IPA.dnszone_details_facet = function(spec, no_init) { that.create_refresh_command = function() { - var pkey = IPA.nav.get_state(that.entity.name+'-pkey'); + var pkey = that.get_pkey(); var batch = IPA.batch_command({ name: 'dnszone_details_refresh' @@ -597,7 +597,7 @@ IPA.dns.add_permission_action = function(spec) { that.execute_action = function(facet) { - var pkey = IPA.nav.get_state('dnszone-pkey'); + var pkey = that.get_pkey(); var command = IPA.command({ entity: 'dnszone', @@ -627,7 +627,7 @@ IPA.dns.remove_permission_action = function(spec) { that.execute_action = function(facet) { - var pkey = IPA.nav.get_state('dnszone-pkey'); + var pkey = that.get_pkey(); var command = IPA.command({ entity: 'dnszone', @@ -678,7 +678,7 @@ IPA.dns.record_search_facet = function(spec) { on_error: on_error }); - var zone = IPA.nav.get_state('dnszone-pkey'); + var zone = that.get_pkey(); for (var i=0; i return - if (that == prev_entity && that.facet == prev_facet && !needs_update) { - return; - } - - if (prev_facet) { - prev_facet.hide(); - } - - var facet_container = $('.facet[name="'+that.facet.name+'"]', that.container); - if (!facet_container.length) { - facet_container = $('
', { - name: that.facet.name, - 'class': 'facet' - }).appendTo(that.container); - - that.facet.create(facet_container); - } - - if (needs_update) { - that.facet.clear(); - that.facet.show(); - that.facet.header.select_tab(); - that.facet.refresh(); - } else { - that.facet.show(); - that.facet.header.select_tab(); - } - }; - - that.get_primary_key_prefix = function() { - var pkey = []; - var current_entity = that; - current_entity = current_entity.get_containing_entity(); - while(current_entity !== null){ - - var key = IPA.nav.get_state(current_entity.name+'-pkey'); - if (key){ - pkey.unshift(key); - } - current_entity = current_entity.get_containing_entity(); - } - return pkey; - }; - - /*gets the primary key for the current entity out of the URL parameters */ - that.get_primary_key = function() { - var pkey = that.get_primary_key_prefix(); - var current_entity = that; - pkey.unshift(IPA.nav.get_state(current_entity.name+'-pkey')); - return pkey; - }; - - /* most entites only require -pkey for their primary keys, but some - are more specific. This call allows those entites a place - to override the other parameters. */ - that.get_key_names = function() { - return [that.name + '-pkey']; + that.get_primary_key = function(facet) { + window.console.log('Obsolete function usage: entity.get_primary_key'); + facet = facet || that.facet; + var pkeys = facet.get_pkeys(); + return pkeys; }; that.entity_init = that.init; @@ -244,72 +182,6 @@ IPA.entity = function(spec) { return that; }; -IPA.nested_tab_labels = {}; - -IPA.get_nested_tab_label = function(entity_name){ - - if (!IPA.nested_tab_labels[entity_name]){ - IPA.nested_tab_labels[entity_name] = "LABEL"; - - } - return IPA.nested_tab_labels[entity_name]; - -}; - -/*Returns the entity requested, as well as: - any nested tabs underneath it or - its parent tab and the others nested at the same level*/ - -IPA.nested_tabs = function(entity_name) { - - var siblings = []; - var i; - var i2; - var nested_entities; - var sub_i; - var sub_tab; - - var key = entity_name; - function push_sibling(sibling){ - siblings.push (sibling); - IPA.nested_tab_labels[key] = sub_tab; - } - - - if (!IPA.nav.tabs) { - siblings.push(entity_name); - return siblings; - } - - for (var top_i = 0; top_i < IPA.nav.tabs.length; top_i++) { - var top_tab = IPA.nav.tabs[top_i]; - for (sub_i = 0; sub_i < top_tab.children.length; sub_i++) { - sub_tab = top_tab.children[sub_i]; - nested_entities = sub_tab.children; - if (sub_tab.name === entity_name){ - push_sibling(entity_name); - } - if (sub_tab.children){ - for (i = 0; i < nested_entities.length; i += 1){ - if (sub_tab.name === entity_name){ - push_sibling(nested_entities[i].name); - }else{ - if (nested_entities[i].name === entity_name){ - push_sibling(sub_tab.name); - for (i2 = 0; i2 < nested_entities.length; i2 += 1){ - key = nested_entities[i].name; - push_sibling(nested_entities[i2].name); - } - } - } - } - } - } - } - - return siblings; -}; - IPA.entity_builder = function() { var that = {}; diff --git a/install/ui/src/freeipa/facet.js b/install/ui/src/freeipa/facet.js index 3ad868e84..f63e6d7ae 100644 --- a/install/ui/src/freeipa/facet.js +++ b/install/ui/src/freeipa/facet.js @@ -21,8 +21,80 @@ * along with this program. If not, see . */ -define(['./ipa', './jquery', './dialog', './field', './widget'], function(IPA, $) { - +define([ + 'dojo/_base/declare', + 'dojo/_base/lang', + 'dojo/topic', + 'dojo/dom-construct', + 'dojo/on', + 'dojo/Stateful', + 'dojo/Evented', + './ipa', + './jquery', + './navigation', + './dialog', + './field', + './widget' + ], function(declare, lang, topic, construct, on, Stateful, Evented, + IPA, $, navigation) { + +/** + * Facet represents the content of currently displayed page. + * + * = Show, Clear, Refresh mechanism = + * + * Use cases: + * a) Display facet with defined arguments. + * b) Switch to facet + * c) Update facet state + * + * == Display facet by route == + * 1) somebody sets route + * 2) Route is evaluated, arguments extracted. + * 3) Facet state is updated `update_state(args, pkeys)`.(saves previous state) + * 4) Facet show() is called + * + * == Display facet with defined arguments == + * 1) Somebody calls navigation.show(xxx); + * 2) Facet state is updated `update_state(args, pkeys)`.(saves previous state) + * 3) Route is updated, but the hash change is ignored + * 4) Facet show() is called. + * 5.1) First time show + * a) creates DOM + * b) display DOM + * c) refresh(); + * 5.2) Next time + * a) display DOM + * b) needs_update()? (compares previous state with current) + * true: + * 1) clear() - each facet can override to supress clear or + * control the behaviour + * 2) refresh() + * + * == Swith to facet == + * Same as display facet but only without arguments. Arguments are extracted at + * step 2. + * + * == Update facet state == + * 1) update_state(args, pkeys?) + * 2) needs_update()? + * true: + * a) clear() + * b) refresh() + * 2) Update route, ignore hash change event + * + * == Updating hash == + * Hash updates are responsibility of navigation component and application + * controller. Application controller should listen to facet's `state_change` + * event. And call something like navigation.update_hash(facet). + * + * navigation.update_hash should find all the necessary state properties (args, + * pkeys). + * + * == needs_update method == + * + * + */ IPA.facet = function(spec, no_init) { spec = spec || {}; @@ -58,12 +130,190 @@ IPA.facet = function(spec, no_init) { that.dialogs = $.ordered_map(); + /** + * domNode of container + * Suppose to contain domNode of this and other facets. + */ + that.container_node = spec.container_node; + + /** + * FIXME: that.container should be eliminated + * now it's the same as domNode + */ + //that.container + + /** + * domNode which contains all content of a facet. + * Should contain error content and content. When error is moved to + * standalone facet it will replace functionality of content. + */ + that.domNode = null; + // facet group name that.facet_group = spec.facet_group; that.redirect_info = spec.redirect_info; - that.state = {}; + /** + * Public state + * + */ + that.state = new FacetState(); + + that.set_pkeys = function(pkeys) { + + pkeys = that.get_pkeys(pkeys); + that.state.set('pkeys', pkeys); + }; + + /** + * Return THE pkey of this facet. Basically the last one of pkeys list. + * + * @type String + */ + that.get_pkey = function() { + var pkeys = that.state.get('pkeys'); + if (pkeys.length) { + return pkeys[pkeys.length-1]; + } + return ''; + }; + + /** + * Gets copy of pkeys list. + * It automatically adds empty pkeys ('') for each containing entity if not + * specified. + * + * One can get merge current pkeys with supplied if `pkeys` param is + * specified. + * + * @param String[] new pkeys to merge + */ + that.get_pkeys = function(pkeys) { + var new_keys = []; + var cur_keys = that.state.get('pkeys') || []; + var current_entity = that.entity; + pkeys = pkeys || []; + var arg_l = pkeys.length; + var cur_l = cur_keys.length; + var tot_c = 0; + while (current_entity) { + current_entity = current_entity.get_containing_entity(); + tot_c++; + } + + if (tot_c < arg_l || tot_c < cur_l) throw { + error: 'Invalid pkeys count. Supplied more than expected.' + }; + + var arg_off = tot_c - arg_l; + var cur_off = cur_l - tot_c; + + for (var i=0; i', { + 'class': 'facet', + name: that.name + }); + } + + var domNode = that.domNode; + that.container = domNode; + + if (!that.container_node) throw { + error: 'Can\'t create facet. No container node defined.' + }; + var node = domNode[0]; + construct.place(node,that.container_node); - if (that.disable_facet_tabs) that.container.addClass('no-facet-tabs'); - that.container.addClass(that.display_class); + + if (that.disable_facet_tabs) domNode.addClass('no-facet-tabs'); + domNode.addClass(that.display_class); that.header_container = $('
', { 'class': 'facet-header' - }).appendTo(container); + }).appendTo(domNode); that.create_header(that.header_container); that.content = $('
', { 'class': 'facet-content' - }).appendTo(container); + }).appendTo(domNode); that.error_container = $('
', { 'class': 'facet-content facet-error' - }).appendTo(container); + }).appendTo(domNode); that.create_content(that.content); + + }; that.create_header = function(container) { @@ -122,8 +392,30 @@ IPA.facet = function(spec, no_init) { }; that.show = function() { - that.container.css('display', 'block'); - that.show_content(); + + that.entity.facet = that; // FIXME: remove + + if (!that.domNode) { + that.create(); + + var needs_update = that.needs_update(); + + if (needs_update) { + that.clear(); + } + + that.domNode.css('display', 'block'); + that.show_content(); + that.header.select_tab(); + + if (needs_update) { + that.refresh(); + } + } else { + that.domNode.css('display', 'block'); + that.show_content(); + that.header.select_tab(); + } }; that.show_content = function() { @@ -142,7 +434,7 @@ IPA.facet = function(spec, no_init) { }; that.hide = function() { - that.container.css('display', 'none'); + that.domNode.css('display', 'none'); }; that.load = function(data) { @@ -175,6 +467,8 @@ IPA.facet = function(spec, no_init) { needs_update = needs_update || that.expired_flag; needs_update = needs_update || that.error_displayed(); + needs_update = needs_update || that.state_diff(that.old_state || {}, that.state); + return needs_update; }; @@ -191,6 +485,29 @@ IPA.facet = function(spec, no_init) { return false; }; + /** + * Wheater we can switch to different facet. + * @returns Boolean + */ + that.can_leave = function() { + return !that.is_dirty(); + }; + + /** + * Show dialog displaying a message explaining why we can't switch facet. + * User can supply callback which is called when a leave is permitted. + * + * Listeneres should set 'callback' property to listen state evaluation. + */ + that.show_leave_dialog = function(permit_callback) { + + var dialog = IPA.dirty_dialog({ + facet: that + }); + + return dialog; + }; + that.report_error = function(error_thrown) { var add_option = function(ul, text, handler) { @@ -235,7 +552,7 @@ IPA.facet = function(spec, no_init) { options_list, IPA.messages.error_report.main_page, function() { - IPA.nav.show_top_level_page(); + navigation.show_default(); } ); @@ -260,16 +577,11 @@ IPA.facet = function(spec, no_init) { } var facet_name = that.entity.redirect_facet; var entity_name = entity.name; - var tab_name, facet; + var facet; if (that.redirect_info) { entity_name = that.redirect_info.entity || entity_name; facet_name = that.redirect_info.facet || facet_name; - tab_name = that.redirect_info.tab; - } - - if (tab_name) { - facet = IPA.nav.get_tab_facet(tab_name); } if (!facet) { @@ -284,7 +596,7 @@ IPA.facet = function(spec, no_init) { var facet = that.get_redirect_facet(); if (!facet) return; - IPA.nav.show_page(facet.entity.name, facet.name); + navigation.show(facet); }; var redirect_error_codes = [4001]; @@ -306,6 +618,8 @@ IPA.facet = function(spec, no_init) { that.action_state.init(that); that.actions.init(that); that.header.init(); + on(that.state, 'reset', that.on_state_reset); + that.state.watch(that.on_state_change); var buttons_spec = { factory: IPA.control_buttons_widget, @@ -369,7 +683,7 @@ IPA.facet_header = function(spec) { if (that.facet.disable_facet_tabs) return; $(that.facet_tabs).find('a').removeClass('selected'); - var facet_name = IPA.nav.get_state(that.facet.entity.name+'-facet'); + var facet_name = that.facet.name; if (!facet_name || facet_name === 'default') { that.facet_tabs.find('a:first').addClass('selected'); @@ -388,26 +702,29 @@ IPA.facet_header = function(spec) { if (!that.facet.disable_breadcrumb) { var breadcrumb = []; - var keys = []; + + // all pkeys should be available in facet + var keys = that.facet.get_pkeys(); var entity = that.facet.entity.get_containing_entity(); + i = keys.length - 2; //set pointer to first containing entity while (entity) { - key = IPA.nav.get_state(entity.name+'-pkey'); + key = keys[i]; breadcrumb.unshift($('', { 'class': 'breadcrumb-element', text: key, title: entity.metadata.label_singular, click: function(entity) { return function() { - IPA.nav.show_page(entity.name, 'default'); + navigation.show_entity(entity.name, 'default'); return false; }; }(entity) })); entity = entity.get_containing_entity(); - keys.unshift(key); + i--; } //calculation of breadcrumb keys length @@ -471,8 +788,8 @@ IPA.facet_header = function(spec) { return false; } - var pkey = IPA.nav.get_state(that.facet.entity.name+'-pkey'); - IPA.nav.show_page(that.facet.entity.name, other_facet.name, pkey); + var pkeys = that.facet.get_pkeys(); + navigation.show(other_facet, [pkeys]); return false; } @@ -762,6 +1079,7 @@ IPA.table_facet = function(spec, no_init) { that.add_column = function(column) { column.entity = that.managed_entity; + column.facet = that; that.columns.put(column.name, column); }; @@ -865,15 +1183,12 @@ IPA.table_facet = function(spec, no_init) { delete that.table.current_page; - var state = {}; - var page = parseInt(IPA.nav.get_state(that.entity.name+'-page'), 10) || 1; + var page = parseInt(that.state.page, 10) || 1; if (page < 1) { - state[that.entity.name+'-page'] = 1; - IPA.nav.push_state(state); + that.state.set({page: 1}); return; } else if (page > that.table.total_pages) { - state[that.entity.name+'-page'] = that.table.total_pages; - IPA.nav.push_state(state); + that.state.set({page: that.table.total_pages}); return; } that.table.current_page = page; @@ -1027,7 +1342,16 @@ IPA.table_facet = function(spec, no_init) { if (column.link && column.primary_key) { column.link_handler = function(value) { - IPA.nav.show_page(entity.name, that.details_facet_name, value); + var pkeys = [value]; + + // for nested entities + var containing_entity = entity.get_containing_entity(); + if (containing_entity && that.entity.name === containing_entity.name) { + pkeys = that.get_pkeys(); + pkeys.push(value); + } + + navigation.show_entity(entity.name, that.details_facet_name, pkeys); return false; }; } @@ -1042,19 +1366,17 @@ IPA.table_facet = function(spec, no_init) { that.table.prev_page = function() { if (that.table.current_page > 1) { - var state = {}; - state[that.entity.name+'-page'] = that.table.current_page - 1; + var page = that.table.current_page - 1; that.set_expired_flag(); - IPA.nav.push_state(state); + that.state.set({page: page}); } }; that.table.next_page = function() { if (that.table.current_page < that.table.total_pages) { - var state = {}; - state[that.entity.name+'-page'] = that.table.current_page + 1; + var page = that.table.current_page + 1; that.set_expired_flag(); - IPA.nav.push_state(state); + that.state.set({page: page}); } }; @@ -1064,10 +1386,8 @@ IPA.table_facet = function(spec, no_init) { } else if (page > that.total_pages) { page = that.total_pages; } - var state = {}; - state[that.entity.name+'-page'] = page; that.set_expired_flag(); - IPA.nav.push_state(state); + that.state.set({page: page}); }; }; @@ -1657,9 +1977,7 @@ IPA.self_service_state_evaluator = function(spec) { var old_state = that.state; that.state = []; - var self_service = IPA.nav.name === 'self-service'; - - if (self_service) { + if (IPA.is_selfservice) { that.state.push('self-service'); } @@ -2042,5 +2360,55 @@ IPA.action_list_widget = function(spec) { return that; }; -return {}; +var FacetState = declare([Stateful, Evented], { + + /** + * Properties to ignore in clear and clone operation + */ + _ignore_properties: {_watchCallbacks:1, onreset:1}, + + /** + * Gets object containing shallow copy of state's properties. + */ + clone: function() { + var clone = {}; + for(var x in this){ + if (this.hasOwnProperty(x) && !(x in this._ignore_properties)) { + clone[x] = lang.clone(this[x]); + } + } + return clone; + }, + + /** + * Unset all properties. + */ + clear: function() { + var undefined; + for(var x in this){ + if (this.hasOwnProperty(x) && !(x in this._ignore_properties)) { + this.set(x, undefined); + } + } + }, + + /** + * Set completly new state. Old state is cleared. + * + * Supresses all watch callbacks. + * Others can be notified by listening to 'reset' event. + */ + reset: function(object) { + var _watchCallbacks = this._watchCallbacks; + delete this._watchCallbacks; //prevent watch callbacks + var old_state = this.clone(); + this.clear(); + this.set(object); + var new_state = this.clone(); + this._watchCallbacks = _watchCallbacks; + this.emit('reset', new_state, old_state); + } +}); + +return { FacetState: FacetState}; }); diff --git a/install/ui/src/freeipa/field.js b/install/ui/src/freeipa/field.js index 9654c8051..8a0e3fbdf 100644 --- a/install/ui/src/freeipa/field.js +++ b/install/ui/src/freeipa/field.js @@ -21,7 +21,9 @@ * along with this program. If not, see . */ -define(['dojo/_base/array', './ipa', './jquery'], function(array, IPA, $) { + +define(['dojo/_base/array', './ipa', './jquery', './navigation'], + function(array, IPA, $, navigation) { IPA.field = function(spec) { spec = spec || {}; @@ -735,8 +737,8 @@ IPA.link_field = function(spec) { that.on_link_clicked = function() { - IPA.nav.show_entity_page( - that.other_entity, + navigation.show_entity( + that.other_entity.name, 'default', that.other_pkeys()); }; diff --git a/install/ui/src/freeipa/hbactest.js b/install/ui/src/freeipa/hbactest.js index cf3617807..247e5efb7 100644 --- a/install/ui/src/freeipa/hbactest.js +++ b/install/ui/src/freeipa/hbactest.js @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -define(['./ipa', './jquery', './details', './search', './association', - './entity', './hbac'], function(IPA, $) { +define(['./ipa', './jquery', './navigation', './details', './search', + './association', './entity', './hbac'], function(IPA, $, navigation) { IPA.hbac.test_entity = function(spec) { @@ -198,9 +198,7 @@ IPA.hbac.test_facet = function(spec) { var facet = facet_group.get_facet_by_index(index - 1); - var state = {}; - state[that.entity.name+'-facet'] = facet.name; - IPA.nav.push_state(state); + navigation.show(facet); }; that.next = function() { @@ -210,9 +208,7 @@ IPA.hbac.test_facet = function(spec) { var facet = facet_group.get_facet_by_index(index + 1); - var state = {}; - state[that.entity.name+'-facet'] = facet.name; - IPA.nav.push_state(state); + navigation.show(facet); }; that.get_search_command_name = function() { @@ -221,7 +217,7 @@ IPA.hbac.test_facet = function(spec) { that.refresh = function() { - var filter = IPA.nav.get_state(that.entity.name+'-'+that.name+'-filter'); + var filter = that.state.filter; var command = IPA.command({ name: that.get_search_command_name(), @@ -357,7 +353,7 @@ IPA.hbac.test_select_facet = function(spec) { that.find = function() { - var old_filter = IPA.nav.get_state(that.entity.name+'-'+that.name+'-filter'); + var old_filter = that.state.filter; var filter = that.filter.val(); that.set_expired_flag(); @@ -365,9 +361,7 @@ IPA.hbac.test_select_facet = function(spec) { if (old_filter === filter) { that.refresh(); } else { - var state = {}; - state[that.entity.name+'-'+that.name+'-filter'] = filter; - IPA.nav.push_state(state); + that.state.set({filter: filter}); } }; @@ -621,6 +615,7 @@ IPA.hbac.test_run_facet = function(spec) { that.new_test = function() { var facet = that.entity.get_facet('user'); facet.reset(); + var entry_point = facet; facet = that.entity.get_facet('targethost'); facet.reset(); @@ -634,9 +629,7 @@ IPA.hbac.test_run_facet = function(spec) { facet = that.entity.get_facet('run_test'); facet.reset(); - var state = {}; - state[that.entity.name+'-facet'] = 'user'; - IPA.nav.push_state(state); + navigation.show(entry_point); }; that.reset = function() { @@ -806,9 +799,7 @@ IPA.hbac.validation_dialog = function(spec) { that.redirect_to_facet = function(facet) { that.close(); - var state = {}; - state[facet.entity.name+'-facet'] = facet.name; - IPA.nav.push_state(state); + navigation.show(facet); }; return that; diff --git a/install/ui/src/freeipa/host.js b/install/ui/src/freeipa/host.js index 40214a119..c7637a951 100644 --- a/install/ui/src/freeipa/host.js +++ b/install/ui/src/freeipa/host.js @@ -248,7 +248,7 @@ IPA.host.details_facet = function(spec, no_init) { that.certificate_updated = IPA.observer(); that.get_refresh_command_name = function() { - return that.entity.name+'_show_'+that.pkey; + return that.entity.name+'_show_'+that.get_pkey(); }; if (!no_init) that.init_details_facet(); diff --git a/install/ui/src/freeipa/ipa.js b/install/ui/src/freeipa/ipa.js index c1ed72214..7097aae8d 100644 --- a/install/ui/src/freeipa/ipa.js +++ b/install/ui/src/freeipa/ipa.js @@ -2058,9 +2058,16 @@ IPA.is_empty = function(value) { if (value instanceof Array) { empty = empty || value.length === 0 || (value.length === 1) && (value[0] === ''); - } - - if (value === '') empty = true; + } else if (typeof value === 'object') { + var has_p = false; + for (var p in value) { + if (value.hasOwnProperty(p)) { + has_p = true; + break; + } + } + empty = !has_p; + } else if (value === '') empty = true; return empty; }; diff --git a/install/ui/src/freeipa/navigation.js b/install/ui/src/freeipa/navigation.js new file mode 100644 index 000000000..4278d0457 --- /dev/null +++ b/install/ui/src/freeipa/navigation.js @@ -0,0 +1,150 @@ +/* Authors: + * Petr Vobornik + * + * Copyright (C) 2013 Red Hat + * see file 'COPYING' for use and warranty information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +/** + * Navigation tells application to show certain facet. + * + * It's proxy for navigation/Router instace in current running + * application. + * + * Modules just use the interface, they don't have to care about the logic in + * the background. + */ +define([ + 'dojo/_base/lang', + './app', // creates circullar dependency + './ipa', + 'exports' // for handling circullar dependency + ], + function(lang, app, IPA, exports) { + + + var get_router = function() { + return app.app.router; + }, + + /** + * Sets property of params depending on arg type following way: + * for String sets params.facet + * for Facet sets params.facet (based on show function) + * for Object sets params.args + * for Array sets params.pkeys + * + * @param Object params + * @param {Object|Facet|String|Function} arg + */ + set_params = function(params, arg) { + if (lang.isArray(arg)) { + params.pkeys = arg; + } else if (typeof arg === 'object') { + + if (typeof arg.show === 'function') params.facet = arg; + else params.args = arg; + } else if (typeof arg === 'string') { + params.facet = arg; + } + }, + + /** + * Show facet. + * + * Takes 3 arguments: + * * facet(String or Facet) + * * pkeys (Array) + * * args (Object) + * + * Argument order is not defined. They are recognized based on their + * type. + * + * When facet is defined as a string it has to be registered in + * facet register. //FIXME: not yet implemented + * + * When it's an object (Facet) and has an entity set it will be + * dealt as entity facet. + * + */ + show = function(arg1, arg2, arg3) { + + var nav = get_router(); + var params = {}; + + set_params(params, arg1); + set_params(params, arg2); + set_params(params, arg3); + + var facet = params.facet; + + if (typeof facet === 'string') { + // FIXME: doesn't work at the moment + throw 'Not yet supported'; + //facet = IPA.get_facet(facet); + } + + if (!facet) throw 'Argument exception: missing facet'; + + if (facet && facet.entity) { + return nav.navigate_to_entity_facet( + facet.entity.name, + facet.name, + params.pkeys, + params.args); + } else { + return nav.navigate_to_facet(facet.name, params.args); + } + }, + + /** + * Show entity facet. + * + * @param String Enity name + * @param {Object|Facet|String|Function} arg1 + * @param {Object|Facet|String|Function} arg2 + * @param {Object|Facet|String|Function} arg3 + * + * arg1,arg2,arg3 are: + * facet name as String + * pkeys as Array + * args as Object + */ + show_entity = function(entity_name, arg1, arg2, arg3) { + var nav = get_router(); + var params = {}; + + set_params(params, arg1); + set_params(params, arg2); + set_params(params, arg3); + return nav.navigate_to_entity_facet(entity_name, params.facet, + params.pkeys, params.args); + }, + + show_default = function() { + // TODO: make configurable + return show_entity('user', 'search'); + }; + + // Module export + exports = { + show: show, + show_entity: show_entity, + show_default: show_default + }; + + return exports; +}); diff --git a/install/ui/src/freeipa/navigation2.js b/install/ui/src/freeipa/navigation2.js deleted file mode 100644 index 4278d0457..000000000 --- a/install/ui/src/freeipa/navigation2.js +++ /dev/null @@ -1,150 +0,0 @@ -/* Authors: - * Petr Vobornik - * - * Copyright (C) 2013 Red Hat - * see file 'COPYING' for use and warranty information - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -/** - * Navigation tells application to show certain facet. - * - * It's proxy for navigation/Router instace in current running - * application. - * - * Modules just use the interface, they don't have to care about the logic in - * the background. - */ -define([ - 'dojo/_base/lang', - './app', // creates circullar dependency - './ipa', - 'exports' // for handling circullar dependency - ], - function(lang, app, IPA, exports) { - - - var get_router = function() { - return app.app.router; - }, - - /** - * Sets property of params depending on arg type following way: - * for String sets params.facet - * for Facet sets params.facet (based on show function) - * for Object sets params.args - * for Array sets params.pkeys - * - * @param Object params - * @param {Object|Facet|String|Function} arg - */ - set_params = function(params, arg) { - if (lang.isArray(arg)) { - params.pkeys = arg; - } else if (typeof arg === 'object') { - - if (typeof arg.show === 'function') params.facet = arg; - else params.args = arg; - } else if (typeof arg === 'string') { - params.facet = arg; - } - }, - - /** - * Show facet. - * - * Takes 3 arguments: - * * facet(String or Facet) - * * pkeys (Array) - * * args (Object) - * - * Argument order is not defined. They are recognized based on their - * type. - * - * When facet is defined as a string it has to be registered in - * facet register. //FIXME: not yet implemented - * - * When it's an object (Facet) and has an entity set it will be - * dealt as entity facet. - * - */ - show = function(arg1, arg2, arg3) { - - var nav = get_router(); - var params = {}; - - set_params(params, arg1); - set_params(params, arg2); - set_params(params, arg3); - - var facet = params.facet; - - if (typeof facet === 'string') { - // FIXME: doesn't work at the moment - throw 'Not yet supported'; - //facet = IPA.get_facet(facet); - } - - if (!facet) throw 'Argument exception: missing facet'; - - if (facet && facet.entity) { - return nav.navigate_to_entity_facet( - facet.entity.name, - facet.name, - params.pkeys, - params.args); - } else { - return nav.navigate_to_facet(facet.name, params.args); - } - }, - - /** - * Show entity facet. - * - * @param String Enity name - * @param {Object|Facet|String|Function} arg1 - * @param {Object|Facet|String|Function} arg2 - * @param {Object|Facet|String|Function} arg3 - * - * arg1,arg2,arg3 are: - * facet name as String - * pkeys as Array - * args as Object - */ - show_entity = function(entity_name, arg1, arg2, arg3) { - var nav = get_router(); - var params = {}; - - set_params(params, arg1); - set_params(params, arg2); - set_params(params, arg3); - return nav.navigate_to_entity_facet(entity_name, params.facet, - params.pkeys, params.args); - }, - - show_default = function() { - // TODO: make configurable - return show_entity('user', 'search'); - }; - - // Module export - exports = { - show: show, - show_entity: show_entity, - show_default: show_default - }; - - return exports; -}); diff --git a/install/ui/src/freeipa/rule.js b/install/ui/src/freeipa/rule.js index 436e934ca..8699ba8fb 100644 --- a/install/ui/src/freeipa/rule.js +++ b/install/ui/src/freeipa/rule.js @@ -132,7 +132,7 @@ IPA.rule_association_table_widget = function(spec) { that.create_add_dialog = function() { var entity_label = that.entity.metadata.label_singular; - var pkey = IPA.nav.get_state(that.entity.name+'-pkey'); + var pkey = that.facet.get_pkey(); var other_entity_label = that.other_entity.metadata.label; var title = that.add_title; diff --git a/install/ui/src/freeipa/search.js b/install/ui/src/freeipa/search.js index be37f88b7..8956470e4 100644 --- a/install/ui/src/freeipa/search.js +++ b/install/ui/src/freeipa/search.js @@ -114,27 +114,13 @@ IPA.search_facet = function(spec, no_init) { that.show = function() { that.facet_show(); - var filter = IPA.nav.get_state(that.entity.name+'-filter'); - that.old_filter = filter || ''; - that.old_pkeys = that.managed_entity.get_primary_key_prefix(); + var filter = that.state.filter || ''; if (that.filter) { that.filter.val(filter); } }; - that.needs_update = function() { - if (that._needs_update !== undefined) return that._needs_update; - - var needs_update = that.facet_needs_update(); - - //check if state changed - var pkeys = that.managed_entity.get_primary_key_prefix(); - needs_update = needs_update || IPA.array_diff(pkeys, that.old_pkeys); - - return needs_update; - }; - that.show_add_dialog = function() { var dialog = that.managed_entity.get_dialog('add'); dialog.open(that.container); @@ -172,13 +158,13 @@ IPA.search_facet = function(spec, no_init) { that.find = function() { var filter = that.filter.val(); - var old_filter = IPA.nav.get_state(that.managed_entity.name+'-filter'); + var old_filter = that.state.filter; var state = {}; state[that.managed_entity.name + '-filter'] = filter; if (filter !== old_filter) that.set_expired_flag(); - IPA.nav.push_state(state); + that.state.set({filter: filter}); }; that.get_search_command_name = function() { @@ -191,8 +177,7 @@ IPA.search_facet = function(spec, no_init) { that.create_refresh_command = function() { - var filter = that.managed_entity.get_primary_key_prefix(); - filter.push(IPA.nav.get_state(that.managed_entity.name+'-filter')); + var filter = that.state.filter || ''; var command = IPA.command({ name: that.get_search_command_name(), @@ -237,10 +222,11 @@ IPA.search_facet = function(spec, no_init) { that.needs_clear = function() { var clear = false; - var filter = IPA.nav.get_state(that.entity.name+'-filter') || ''; + + var filter = that.state.filter; clear = that.old_filter !== '' || that.old_filter !== filter; - var pkeys = that.managed_entity.get_primary_key_prefix(); + var pkeys = that.get_pkeys(); clear = clear || IPA.array_diff(pkeys, that.old_pkeys); return clear; @@ -275,7 +261,8 @@ IPA.search_deleter_dialog = function(spec) { error_message: IPA.messages.search.partial_delete }); - var pkeys = that.entity.get_primary_key_prefix(); + var pkeys = that.facet.get_pkeys(); + pkeys.pop(); for (var i=0; i