mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-30 10:47:08 -06:00
e84bd27af2
The test cases have been updated to use the new extensible mechanism for defining and registering entities. Ticket #2043
562 lines
15 KiB
JavaScript
562 lines
15 KiB
JavaScript
/*jsl:import ipa.js */
|
|
/*jsl:import facet.js */
|
|
/*jsl:import navigation.js */
|
|
|
|
/* Authors:
|
|
* Pavel Zuna <pzuna@redhat.com>
|
|
* Endi Sukma Dewata <edewata@redhat.com>
|
|
* Adam Young <ayoung@redhat.com>
|
|
* Petr Vobornik <pvoborni@redhat.com>
|
|
*
|
|
* Copyright (C) 2010-2011 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/* REQUIRES: ipa.js, facet.js, details.js, search.js, add.js */
|
|
|
|
IPA.entity = function(spec) {
|
|
|
|
spec = spec || {};
|
|
|
|
var that = {};
|
|
that.metadata = spec.metadata;
|
|
that.name = spec.name;
|
|
that.label = spec.label || spec.metadata.label || spec.name;
|
|
that.title = spec.title || that.label;
|
|
|
|
that.dialogs = $.ordered_map();
|
|
that.dialog_specs = spec.dialogs || [];
|
|
that.dialogs_created = false;
|
|
|
|
that.facets = $.ordered_map();
|
|
that.facet_groups = $.ordered_map();
|
|
that.facet_specs = spec.facets || [];
|
|
that.facets_created = false;
|
|
|
|
// current facet
|
|
that.facet = null;
|
|
|
|
that.redirect_facet = spec.redirect_facet;
|
|
that.containing_entity = null;
|
|
|
|
that.init = function(params) {
|
|
};
|
|
|
|
that.get_containing_entity = function() {
|
|
return that.containing_entity ?
|
|
IPA.get_entity(that.containing_entity) : null;
|
|
};
|
|
|
|
that.get_dialog = function(name) {
|
|
|
|
//build all dialogs on the first time
|
|
if(!that.dialogs_created) {
|
|
var builder = IPA.dialog_builder(that);
|
|
builder.build_dialogs();
|
|
that.dialogs_created = true;
|
|
}
|
|
|
|
return that.dialogs.get(name);
|
|
};
|
|
|
|
that.add_dialog = function(dialog) {
|
|
return that.dialog(dialog);
|
|
};
|
|
|
|
that.dialog = function(dialog) {
|
|
dialog.entity_name = that.name;
|
|
that.dialogs.put(dialog.name, dialog);
|
|
return that;
|
|
};
|
|
|
|
that.add_facet_group = function(facet_group) {
|
|
that.facet_groups.put(facet_group.name, facet_group);
|
|
};
|
|
|
|
that.get_facet_group = function(name) {
|
|
return that.facet_groups.get(name);
|
|
};
|
|
|
|
that.remove_facet_groups = function() {
|
|
that.facet_groups.empty();
|
|
};
|
|
|
|
that.get_facet = function(name) {
|
|
|
|
//build all facets on the first time
|
|
if(!that.facets_created) {
|
|
var builder = IPA.facet_builder(that);
|
|
builder.build_facets();
|
|
that.facets_created = true;
|
|
}
|
|
|
|
if (name === undefined) {
|
|
// return the current facet
|
|
if (that.facet) return that.facet;
|
|
|
|
// return the main facet
|
|
return that.facets.values[0];
|
|
|
|
} else if (name === 'default') {
|
|
// return the first facet in the first facet group
|
|
var facet_groups = that.facet_groups.values;
|
|
for (var i=0; i<facet_groups.length; i++) {
|
|
var facet_group = facet_groups[i];
|
|
var facets = facet_group.facets.values;
|
|
if (!facets.length) continue;
|
|
return facets[0];
|
|
}
|
|
|
|
return that.facets.values[0];
|
|
}
|
|
|
|
return that.facets.get(name);
|
|
};
|
|
|
|
that.add_facet = function(facet) {
|
|
facet.entity_name = that.name;
|
|
facet.entity = that;
|
|
|
|
that.facets.put(facet.name, facet);
|
|
|
|
if (facet.facet_group) {
|
|
var facet_group = that.get_facet_group(facet.facet_group);
|
|
if (facet_group) {
|
|
facet_group.add_facet(facet);
|
|
}
|
|
}
|
|
|
|
return that;
|
|
};
|
|
|
|
that.create = function(container) {
|
|
that.container = container;
|
|
};
|
|
|
|
that.display = function(container) {
|
|
|
|
var prev_entity = IPA.current_entity;
|
|
var prev_facet = prev_entity ? prev_entity.facet : null;
|
|
|
|
IPA.current_entity = that;
|
|
|
|
var facet_name = IPA.nav.get_state(that.name+'-facet');
|
|
that.facet = that.get_facet(facet_name);
|
|
|
|
var needs_update = that.facet.needs_update();
|
|
|
|
// same entity, same facet, and doesn't need updating => 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 = $('<div/>', {
|
|
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.entity_init = that.init;
|
|
|
|
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 = {};
|
|
|
|
var entity = null;
|
|
var facet_group = null;
|
|
var facet = null;
|
|
var section = null;
|
|
|
|
that.entity = function(spec) {
|
|
var factory = IPA.entity;
|
|
if (spec instanceof Object) {
|
|
factory = spec.factory || IPA.entity;
|
|
} else {
|
|
spec = { name: spec };
|
|
}
|
|
|
|
spec.metadata = spec.metadata || IPA.metadata.objects[spec.name];
|
|
if (!spec.metadata) {
|
|
throw {
|
|
expected: true,
|
|
message: "Entity " + spec.name + "not supported by server."
|
|
};
|
|
}
|
|
|
|
entity = factory(spec);
|
|
|
|
that.facet_groups([
|
|
'member',
|
|
'settings',
|
|
'memberof',
|
|
'managedby'
|
|
]);
|
|
|
|
return that;
|
|
};
|
|
|
|
that.facet_group = function(spec) {
|
|
spec.entity = entity;
|
|
if (spec instanceof Object) {
|
|
var factory = spec.factory || IPA.facet_group;
|
|
facet_group = factory(spec);
|
|
} else {
|
|
facet_group = IPA.facet_group({ name: spec });
|
|
}
|
|
|
|
if (facet_group.label == undefined) {
|
|
facet_group.label = IPA.messages.facet_groups[facet_group.name];
|
|
}
|
|
|
|
entity.add_facet_group(facet_group);
|
|
|
|
return that;
|
|
};
|
|
|
|
that.facet_groups = function(specs) {
|
|
|
|
entity.remove_facet_groups();
|
|
|
|
for (var i=0; i<specs.length; i++) {
|
|
specs[i].entity = entity;
|
|
that.facet_group(specs[i]);
|
|
}
|
|
|
|
return that;
|
|
};
|
|
|
|
that.facet = function(spec) {
|
|
|
|
spec.entity = entity;
|
|
entity.facet_specs.push(spec);
|
|
|
|
return that;
|
|
};
|
|
|
|
that.search_facet = function(spec) {
|
|
|
|
spec.type = spec.type || 'search';
|
|
|
|
that.facet(spec);
|
|
|
|
add_redirect_info();
|
|
|
|
return that;
|
|
};
|
|
|
|
that.nested_search_facet = function(spec) {
|
|
|
|
spec.type = spec.type || 'nested_search';
|
|
|
|
that.facet(spec);
|
|
|
|
return that;
|
|
};
|
|
|
|
that.details_facet = function(spec) {
|
|
|
|
spec.type = spec.type || 'details';
|
|
|
|
that.facet(spec);
|
|
|
|
return that;
|
|
};
|
|
|
|
that.association_facet = function(spec) {
|
|
|
|
spec.type = spec.type || 'association';
|
|
|
|
that.facet(spec);
|
|
|
|
return that;
|
|
};
|
|
|
|
that.standard_association_facets = function(spec) {
|
|
|
|
spec = spec || {};
|
|
spec.entity = entity;
|
|
|
|
var direct_associations = [];
|
|
var indirect_associations = [];
|
|
|
|
for (var association in entity.metadata.attribute_members) {
|
|
if (association == 'memberindirect' ||
|
|
association == 'memberofindirect') {
|
|
indirect_associations.push(association);
|
|
} else {
|
|
direct_associations.push(association);
|
|
}
|
|
}
|
|
|
|
// make sure direct facets are created first
|
|
var attribute_members = direct_associations.concat(indirect_associations);
|
|
|
|
for (var i=0; i<attribute_members.length; i++) {
|
|
var attribute_member = attribute_members[i];
|
|
var other_entities = entity.metadata.attribute_members[attribute_member];
|
|
|
|
for (var j=0; j<other_entities.length; j++) {
|
|
|
|
var other_entity = other_entities[j];
|
|
var association_name = attribute_member+'_'+other_entity;
|
|
|
|
//already prepared facet
|
|
var facet = get_spec_by_name(entity.facet_specs, association_name);
|
|
//already prepared direct facet for indirect facet
|
|
var direct_facet = get_direct_facet(entity.facet_specs,
|
|
attribute_member,
|
|
other_entity);
|
|
if (facet || direct_facet) {
|
|
continue; //in both cases don't prepare new facet
|
|
}
|
|
|
|
var tmp_spec = $.extend({}, spec);
|
|
tmp_spec.name = association_name;
|
|
|
|
that.association_facet(tmp_spec);
|
|
}
|
|
}
|
|
|
|
return that;
|
|
};
|
|
|
|
function get_spec_by_name(specs, name) {
|
|
if(!specs || !specs.length) return null;
|
|
|
|
for(var i=0; i<specs.length; i++) {
|
|
if(specs[i].name === name) {
|
|
return specs[i];
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/*
|
|
* If it's an indirect attribute member, return its direct facets spec
|
|
* if it exists.
|
|
*/
|
|
function get_direct_facet(facets, attribute_member, other_entity) {
|
|
|
|
var index = attribute_member.indexOf('indirect');
|
|
if(index > -1) {
|
|
var direct_attribute_member = attribute_member.substring(0, index);
|
|
return get_spec_by_name(facets,
|
|
direct_attribute_member+'_'+other_entity);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function add_redirect_info(facet_name){
|
|
if (!entity.redirect_facet){
|
|
entity.redirect_facet = 'search';
|
|
}
|
|
}
|
|
|
|
that.containing_entity = function(entity_name) {
|
|
add_redirect_info();
|
|
entity.containing_entity = entity_name;
|
|
return that;
|
|
};
|
|
|
|
that.dialog = function(spec) {
|
|
|
|
if (spec instanceof Object) {
|
|
spec.factory = spec.factory || IPA.dialog;
|
|
spec.entity = entity;
|
|
|
|
} else {
|
|
spec = {
|
|
factory: IPA.dialog,
|
|
name: spec,
|
|
entity: entity
|
|
};
|
|
}
|
|
|
|
entity.dialog_specs.push(spec);
|
|
return that;
|
|
};
|
|
|
|
that.adder_dialog = function(spec) {
|
|
spec.factory = spec.factory || IPA.entity_adder_dialog;
|
|
spec.name = spec.name || 'add';
|
|
|
|
if (!spec.title) {
|
|
var title = IPA.messages.dialogs.add_title;
|
|
var label = entity.metadata.label_singular;
|
|
spec.title = title.replace('${entity}', label);
|
|
}
|
|
|
|
return that.dialog(spec);
|
|
};
|
|
|
|
that.deleter_dialog = function(spec) {
|
|
spec.factory = spec.factory || IPA.search_deleter_dialog;
|
|
spec.name = spec.name || 'remove';
|
|
|
|
return that.dialog(spec);
|
|
};
|
|
|
|
that.build = function(){
|
|
return entity;
|
|
};
|
|
|
|
return that;
|
|
};
|
|
|
|
IPA.dialog_builder = function(entity) {
|
|
|
|
var that = {};
|
|
|
|
that.build_dialogs = function() {
|
|
|
|
if(entity.dialog_specs && entity.dialog_specs.length) {
|
|
var dialogs = entity.dialog_specs;
|
|
for(var i=0; i<dialogs.length; i++) {
|
|
that.build_dialog(dialogs[i]);
|
|
}
|
|
}
|
|
};
|
|
|
|
that.build_dialog = function(spec) {
|
|
//do common logic
|
|
spec.entity = entity;
|
|
|
|
//add dialog
|
|
var dialog = spec.factory(spec);
|
|
entity.dialog(dialog);
|
|
};
|
|
|
|
return that;
|
|
}; |