freeipa/install/ui/entity.js
Endi Sukma Dewata e84bd27af2 Fixed entity definition in test cases.
The test cases have been updated to use the new extensible mechanism
for defining and registering entities.

Ticket #2043
2011-11-18 15:57:00 +00:00

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;
};