summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2010-11-04 15:13:08 -0400
committerRob Crittenden <rcritten@redhat.com>2010-11-04 15:13:08 -0400
commitdb758c92cd4865ae02c8da357ce5e850a060a4ad (patch)
tree96bd6a549725d0a5b78f4fc54d752cf94a5a9894
parent7b296f2623610b0820a5553e2c570c6b3428c861 (diff)
parentd99ebc0f3798c84e612c79c43eb85c31b20ab1ce (diff)
downloadfreeipa-db758c92cd4865ae02c8da357ce5e850a060a4ad.tar.gz
freeipa-db758c92cd4865ae02c8da357ce5e850a060a4ad.tar.xz
freeipa-db758c92cd4865ae02c8da357ce5e850a060a4ad.zip
Merge branch 'master' of ssh://rcritten@git.fedorahosted.org/git/freeipa
-rw-r--r--install/configure.ac2
-rw-r--r--install/static/Makefile.am2
-rw-r--r--install/static/add.js24
-rw-r--r--install/static/associate.js717
-rwxr-xr-xinstall/static/certificate.js26
-rw-r--r--install/static/details.js366
-rw-r--r--install/static/entity.js65
-rwxr-xr-xinstall/static/hbac.js664
-rw-r--r--install/static/host.js7
-rw-r--r--install/static/index.xhtml1
-rw-r--r--install/static/ipa.css19
-rw-r--r--install/static/ipa.js11
-rw-r--r--install/static/layouts/Makefile.am22
-rw-r--r--install/static/layouts/default/Makefile.am25
-rwxr-xr-xinstall/static/layouts/default/hbac-details-accesstime.html46
-rwxr-xr-xinstall/static/layouts/default/hbac-details-general.html45
-rwxr-xr-xinstall/static/layouts/default/hbac-details-host.html75
-rwxr-xr-xinstall/static/layouts/default/hbac-details-service.html75
-rwxr-xr-xinstall/static/layouts/default/hbac-details-sourcehost.html75
-rwxr-xr-xinstall/static/layouts/default/hbac-details-user.html75
-rw-r--r--install/static/navigation.js6
-rw-r--r--install/static/policy.js25
-rw-r--r--install/static/search.js66
-rw-r--r--install/static/service.js23
-rw-r--r--install/static/test/all_tests.html1
-rw-r--r--install/static/test/association_tests.js46
-rw-r--r--install/static/test/details_tests.html1
-rw-r--r--install/static/test/details_tests.js187
-rw-r--r--install/static/test/entity_tests.html1
-rw-r--r--install/static/test/entity_tests.js2
-rw-r--r--install/static/test/navigation_tests.html2
-rw-r--r--install/static/user.js18
-rwxr-xr-xinstall/static/widget.js473
-rw-r--r--ipa.spec.in3
34 files changed, 2439 insertions, 757 deletions
diff --git a/install/configure.ac b/install/configure.ac
index 3d0c1db02..5cdfb791e 100644
--- a/install/configure.ac
+++ b/install/configure.ac
@@ -73,6 +73,8 @@ AC_CONFIG_FILES([
migration/Makefile
share/Makefile
static/Makefile
+ static/layouts/Makefile
+ static/layouts/default/Makefile
tools/Makefile
tools/man/Makefile
updates/Makefile
diff --git a/install/static/Makefile.am b/install/static/Makefile.am
index 7097a1f6a..787cc4185 100644
--- a/install/static/Makefile.am
+++ b/install/static/Makefile.am
@@ -3,6 +3,7 @@ AUTOMAKE_OPTIONS = 1.7
NULL =
SUBDIRS = \
+ layouts \
$(NULL)
appdir = $(IPA_DATA_DIR)/static
@@ -32,6 +33,7 @@ app_DATA = \
details.js \
entity.js \
webui.js \
+ widget.js \
user.js \
ipalogo.png \
gray-fade-line.png \
diff --git a/install/static/add.js b/install/static/add.js
index b5f9c16d4..fbf9031b9 100644
--- a/install/static/add.js
+++ b/install/static/add.js
@@ -31,10 +31,19 @@ function ipa_add_field(spec) {
var that = {};
that.name = spec.name;
that.label = spec.label;
+ that._entity_name = spec.entity_name;
that.init = spec.init;
that.setup = spec.setup;
+ that.__defineGetter__("entity_name", function(){
+ return that._entity_name;
+ });
+
+ that.__defineSetter__("entity_name", function(entity_name){
+ that._entity_name = entity_name;
+ });
+
return that;
}
@@ -45,7 +54,7 @@ function ipa_add_dialog(spec) {
var that = {};
that.name = spec.name;
that.title = spec.title;
- that.entity_name = spec.entity_name;
+ that._entity_name = spec.entity_name;
that.init = spec.init;
@@ -54,6 +63,18 @@ function ipa_add_dialog(spec) {
var dialog = $('<div/>');
+ that.__defineGetter__("entity_name", function(){
+ return that._entity_name;
+ });
+
+ that.__defineSetter__("entity_name", function(entity_name){
+ that._entity_name = entity_name;
+
+ for (var i=0; i<that.fields.length; i++) {
+ that.fields[i].entity_name = entity_name;
+ }
+ });
+
that.get_fields = function() {
return that.fields;
};
@@ -85,6 +106,7 @@ function ipa_add_dialog(spec) {
} else {
dialog.append('<label>' + field.label + '</label>');
dialog.append('<input type="text" name="' + field.name + '" />');
+ dialog.append('<br/>');
}
}
diff --git a/install/static/associate.js b/install/static/associate.js
index 2050e468e..088d4079a 100644
--- a/install/static/associate.js
+++ b/install/static/associate.js
@@ -22,227 +22,196 @@
/* CURRENTLY ALSO REQUIRES search.js, because it reuses it's code to create
* the AssociationList elements; IT NEEDS IT'S OWN CODE! */
+function ipa_associator(spec) {
+
+ spec = spec || {};
+
+ var that = {};
+
+ that.entity_name = spec.entity_name;
+ that.pkey = spec.pkey;
+
+ that.other_entity = spec.other_entity;
+ that.values = spec.values;
+
+ that.method = spec.method;
+
+ that.on_success = spec.on_success;
+ that.on_error = spec.on_error;
+
+ that.execute = function() {
+ };
+
+ return that;
+}
+
/**
*This associator is built for the case where each association requires a separate rpc
*/
-function serial_associate(form, manyObjPkeys, on_success)
-{
- var associator = this;
- this.form = form;
- this.manyObjPkeys = manyObjPkeys;
- this.on_success = on_success;
-
- this.associate_next = function(){
- var form = this.form;
- //TODO assert pre-conditions
- var manyObjPkey = manyObjPkeys.shift();
- if (manyObjPkey){
- var options = {};
- options[form.oneObj] = form.pkey;
- var args = [manyObjPkey];
-
- ipa_cmd( form.method,args, options ,
- function(data, text_status, xhr) {
- if (data.error){
- alert('error adding member: '+data.error.message);
- }else{
- associator.associate_next();
- }
- },
- function(xhr, text_status, error_thrown) {
- alert('associateFailure');
- },
- form.manyObj );
- }else{
- associator.on_success();
- }
- }
- this.associate_next();
-}
+function serial_associator(spec) {
+ spec = spec || {};
-function serial_delete(delete_method, one_entity, one_entity_pkey, many_entity,
- many_entity_pkeys, on_success){
- var that = {};
- that.one_entity = one_entity;
- that.on_success = on_success;
- that.many_entity_pkeys = many_entity_pkeys;
- that.delete_next = function(){
- var many_entity_pkey = this.many_entity_pkeys.shift();
- if (many_entity_pkey){
- var options = {};
- options[one_entity] = one_entity_pkey;
- var args = [many_entity_pkey];
- ipa_cmd( delete_method,args, options ,
- function(data, text_status, xhr) {
- if (data.error){
- alert("error deleting member: "
- +data.error.message);
- }else{
- that.delete_next();
- }
- },
- function(xhr, text_status, error_thrown) {
- alert("associateFailure");
- },
- many_entity );
- }else{
- this.on_success();
+ var that = ipa_associator(spec);
+
+ that.execute = function() {
+
+ if (!that.values || !that.values.length) {
+ that.on_success();
+ return;
}
- }
- that.delete_next();
-}
+ var value = that.values.shift();
+ if (!value) {
+ that.on_success();
+ return;
+ }
-function bulk_delete(delete_method, one_entity, one_entity_pkey, many_entity,
- many_entity_pkeys, on_success){
- if (many_entity_pkeys.length){
+ var args = [value];
var options = {};
- options[one_entity] = one_entity_pkey;
- var option = many_entity_pkeys.shift();
- while(many_entity_pkeys.length > 0) {
- option += ',' + many_entity_pkeys.shift();
- }
+ options[that.entity_name] = that.pkey;
+
+ ipa_cmd(
+ that.method,
+ args,
+ options,
+ that.execute,
+ that.on_error,
+ that.other_entity
+ );
+ };
- var options = {
- 'all':true
- };
- options[many_entity] = option;
- var args = [one_entity_pkey];
- ipa_cmd( delete_method,args, options ,
- function(data, text_status, xhr) {
- if (data.error){
- alert("error deleting member: "
- +data.error.message);
- }else{
- on_success();
- }
- },
- function(xhr, text_status, error_thrown) {
- alert("associateFailure");
- },
- one_entity );
- }else{
- on_success();
- }
+ return that;
}
-
/**
*This associator is for the common case where all the asociations can be sent
in a single rpc
*/
-function bulk_associate(form, manyObjPkeys, on_success)
-{
- var associator = this;
- this.form = form;
- this.manyObjPkeys = manyObjPkeys;
- this.on_success = on_success;
-
- var form = this.form;
- var option = manyObjPkeys.shift();
- while(manyObjPkeys.length > 0) {
- option += ',' + manyObjPkeys.shift();
- }
- var options = {
- 'all':true
+function bulk_associator(spec) {
+
+ spec = spec || {};
+
+ var that = ipa_associator(spec);
+
+ that.execute = function() {
+
+ if (!that.values || !that.values.length) {
+ that.on_success();
+ return;
+ }
+
+ var value = that.values.shift();
+ if (!value) {
+ that.on_success();
+ return;
+ }
+
+ while (that.values.length > 0) {
+ value += ',' + that.values.shift();
+ }
+
+ var args = [that.pkey];
+ var options = { 'all': true };
+ options[that.other_entity] = value;
+
+ ipa_cmd(
+ that.method,
+ args,
+ options,
+ that.on_success,
+ that.on_error,
+ that.entity_name
+ );
};
- options[form.manyObj] = option;
- var args = [form.pkey];
- ipa_cmd( form.method,args, options ,
- function(data, text_status, xhr) {
- if (data.error){
- alert('error adding member: '+data.error.message);
- }else{
- associator.on_success();
- }
- },
- function(xhr, text_status, error_thrown) {
- alert('associateFailure');
- },
- form.oneObj );
+
+ return that;
}
/**
* Create a form for a one to many association.
*
*/
-function AssociationForm(oneObj, pkey, manyObj, on_success, associator, method)
-{
- var form = this;
+function ipa_adder_dialog(spec) {
- this.oneObj = oneObj;
- this.pkey = pkey;
- this.manyObj = manyObj;
- this.on_success = on_success;
+ spec = spec || {};
- this.dialog = $('<div></div>');
+ var that = {};
- //An optional parameter to determine what ipa method to call to create
- //the association
- if (method)
- this.method = method;
- else
- this.method = 'add_member';
+ that.name = spec.name;
+ that.title = spec.title;
+ that.entity_name = spec.entity_name;
- this.associator = associator;
+ that.pkey = spec.pkey;
+ that.other_entity = spec.other_entity;
+ that.setup = spec.setup || ipa_adder_dialog_setup;
+ that.execute = spec.execute || execute;
+ that.on_success = spec.on_success;
+ that.on_error = spec.on_error;
+ that.associator = spec.associator;
+ that.method = spec.method || 'add_member';
- this.setup = function() {
- var label = IPA.metadata[form.manyObj].label;
+ that.dialog = $('<div/>', {
+ 'title': that.title
+ });
- form.dialog.attr('title', 'Enroll '+form.oneObj+' '+form.pkey+' in '+label);
+ that.open = function() {
- association_form_create(form.dialog);
+ that.setup();
- var availableList = $('#availableList', form.dialog);
+ var availableList = $('#availableList', that.dialog);
availableList.html('');
- var enrollments = $('#enrollments', form.dialog);
+ var enrollments = $('#enrollments', that.dialog);
enrollments.html('');
- $('#addToList', form.dialog).click(function(){
- $('#availableList :selected', form.dialog).each(function(i, selected){
+ $('#addToList', that.dialog).click(function(){
+ $('#availableList :selected', that.dialog).each(function(i, selected){
enrollments.append(selected);
});
- $('#availableList :selected', form.dialog).remove();
+ $('#availableList :selected', that.dialog).remove();
});
- $('#removeFromList', form.dialog).click(function(){
- $('#enrollments :selected', form.dialog).each(function(i, selected){
+ $('#removeFromList', that.dialog).click(function(){
+ $('#enrollments :selected', that.dialog).each(function(i, selected){
availableList.append(selected);
});
- $('#enrollments :selected', form.dialog).remove();
+ $('#enrollments :selected', that.dialog).remove();
});
- $('#find', form.dialog).click(function(){
- form.search();
+ $('#find', that.dialog).click(function(){
+ that.search();
});
- form.dialog.dialog({
+ that.dialog.dialog({
modal: true,
width: 600,
buttons: {
- 'Enroll': function(evt) {
- form.associate(form.on_success);
+ 'Enroll': function() {
+ var values = [];
+ $('#enrollments', that.dialog).children().each(function (i, selected) {
+ values.push(selected.value);
+ });
+ that.execute(values);
},
- 'Cancel': form.close
+ 'Cancel': that.close
}
});
};
- this.close = function() {
- form.dialog.dialog('close');
+ that.close = function() {
+ that.dialog.dialog('close');
};
- this.search = function() {
+ that.search = function() {
function search_on_win(data, text_status, xhr) {
var results = data.result;
- var list = $('#availableList', form.dialog);
+ var list = $('#availableList', that.dialog);
list.html('');
- var searchColumn = IPA.metadata[form.manyObj].primary_key;
+ var searchColumn = IPA.metadata[that.other_entity].primary_key;
for (var i =0; i != results.count; i++){
var result = results.result[i];
@@ -257,246 +226,298 @@ function AssociationForm(oneObj, pkey, manyObj, on_success, associator, method)
alert('associationSearchFailure');
}
- var queryFilter = $('#associateFilter', form.dialog).val();
- ipa_cmd('find', [queryFilter], {}, search_on_win, null, form.manyObj);
+ var queryFilter = $('#associateFilter', that.dialog).val();
+ ipa_cmd('find', [queryFilter], {}, search_on_win, null, that.other_entity);
};
- this.associate = function (on_success) {
- var manyObjPkeys = [];
- $('#enrollments', form.dialog).children().each(function (i, selected) {
- manyObjPkeys.push(selected.value);
+ that.get_values = function() {
+ var values = [];
+ $('#enrollments', that.dialog).children().each(function (i, selected) {
+ values.push(selected.value);
});
- this.associator(form, manyObjPkeys, on_success);
+ return values;
};
-}
-function ipa_association_config(spec) {
- spec = spec || {};
+ function execute(values) {
- var that = {};
+ var associator = that.associator({
+ 'entity_name': that.entity_name,
+ 'pkey': that.pkey,
+ 'other_entity': that.other_entity,
+ 'values': that.get_values(),
+ 'method': that.method,
+ 'on_success': that.on_success,
+ 'on_error': that.on_error
+ });
- that.name = spec.name;
- that.associator = spec.associator;
- that.method = spec.method;
+ associator.execute();
+ }
return that;
}
-function ipa_association_facet(spec) {
+function ipa_deleter_dialog(spec) {
spec = spec || {};
- var that = ipa_facet(spec);
+ var that = {};
- that.configs = [];
- that.configs_by_name = {};
+ that.name = spec.name;
+ that.title = spec.title || IPA.messages.button.deletes;
+ that.entity_name = spec.entity_name;
- that.other_entity = null;
+ that.pkey = spec.pkey;
+ that.other_entity = spec.other_entity;
+
+ that.setup = spec.setup || ipa_deleter_dialog_setup;
+ that.execute = spec.execute || execute;
+ that.on_success = spec.on_success;
+ that.on_error = spec.on_error;
+
+ that.associator = spec.associator;
+ that.method = spec.method || 'remove_member';
+
+ that.values = spec.values || [];
- that.get_configs = function() {
- return that.configs;
+ that.dialog = $('<div/>', {
+ 'title': that.title,
+ 'class': 'search-dialog-delete'
+ });
+
+ that.add_value = function(value) {
+ that.values.push(value);
};
- that.get_config = function(name) {
- return that.configs_by_name[name];
+ that.set_values = function(values) {
+ that.values = that.values.concat(values);
};
- that.add_config = function(config) {
- that.configs.push(config);
- that.configs_by_name[config.name] = config;
+ that.get_values = function() {
+ return that.values;
};
- that.create_config = function(spec) {
- var config = ipa_association_config(spec);
- that.add_config(config);
- return config;
+ that.open = function() {
+
+ that.setup();
+
+ that.dialog.dialog({
+ modal: true,
+ width: 400,
+ buttons: {
+ 'Delete': that.execute,
+ 'Cancel': that.close
+ }
+ });
};
- that.is_dirty = function() {
- var pkey = $.bbq.getState(that.entity_name + '-pkey', true) || '';
- var other_entity = $.bbq.getState(that.entity_name + '-enroll', true) || '';
- return pkey != that.pkey || other_entity != that.other_entity;
+ function execute() {
+
+ var associator = that.associator({
+ 'entity_name': that.entity_name,
+ 'pkey': that.pkey,
+ 'other_entity': that.other_entity,
+ 'values': that.values,
+ 'method': that.method,
+ 'on_success': that.on_success,
+ 'on_error': that.on_error
+ });
+
+ associator.execute();
+ }
+
+ that.close = function() {
+ that.dialog.dialog('close');
};
- that.setup = function(container, unspecified) {
+ return that;
+}
- that.pkey = $.bbq.getState(that.entity_name + '-pkey', true) || '';
- that.other_entity = $.bbq.getState(that.entity_name + '-enroll', true) || '';
+function ipa_association_config(spec) {
+ spec = spec || {};
- that.member_attrribute = ipa_get_member_attribute(that.entity_name, that.other_entity);
- that.columns = [
- {
- 'title': IPA.metadata[that.other_entity].label,
- 'column': that.member_attrribute + '_' + that.other_entity
- }
- ];
+ var that = {};
- var config = that.get_config(that.other_entity);
+ that.name = spec.name;
+ that.associator = spec.associator;
+ that.add_method = spec.add_method;
+ that.delete_method = spec.delete_method;
- if ( config && config.associator === 'serial' ){
- that.associator = serial_associate;
- that.deleter = serial_delete;
- }else{
- that.associator = bulk_associate;
- that.deleter = bulk_delete;
- }
+ return that;
+}
- that.method = config ? config.method : null;
+function ipa_association_widget(spec) {
- that.setup_views(container);
+ spec = spec || {};
- //TODO I18N
- var header_message = that.other_entity + '(s) enrolled in ' +
- that.entity_name + ' ' + that.pkey;
- container.append($('<h2/>',{html: header_message }) );
- association_list_create(that.entity_name, container);
- container.find('.search-filter').css('display', 'none');
- container.find('.search-buttons').html('');
+ spec.add = spec.add || add;
+ spec.remove = spec.remove || remove;
+
+ var that = ipa_table_widget(spec);
+
+ that.other_entity = spec.other_entity;
+
+ that.super_create = that.super('create');
+ that.super_setup = that.super('setup');
+
+ that.create = function(container) {
+
+ that.member_attribute = ipa_get_member_attribute(that.entity_name, that.other_entity);
- var ctrls = container.find('.search-buttons');
+ that.create_column({
+ 'name': that.member_attribute + '_' + that.other_entity,
+ 'label': IPA.metadata[that.other_entity].label,
+ 'primary_key': true
+ });
+
+ that.super_create(container);
+
+ var div = $('#'+that.id, container);
+ var buttons = $('span[name=buttons]', div);
- ipa_make_button( 'ui-icon-plus',IPA.messages.button.enroll).
- click(function() {
- that.show_enrollment_dialog(container);
- }).appendTo(ctrls);
+ $('<input/>', {
+ 'type': 'button',
+ 'name': 'remove',
+ 'value': IPA.messages.button.delete
+ }).appendTo(buttons);
- ipa_make_button('ui-icon-trash',IPA.messages.button.delete).
- click(function(){
- that.delete_on_click(container);
- }).appendTo(ctrls);
+ $('<input/>', {
+ 'type': 'button',
+ 'name': 'add',
+ 'value': IPA.messages.button.enroll
+ }).appendTo(buttons);
+ }
+
+ that.setup = function(container) {
+ that.super_setup(container);
+ var entity = IPA.get_entity(that.entity_name);
+ var association = entity.get_association(that.other_entity);
- var header = container.find('.search-table thead:last').find("tr");;
- for (var i =0 ; i != that.columns.length ;i++){
- $('<th></th>',{
- html: that.columns[i].title
- }).appendTo(header);
+ if (association && association.associator == 'serial') {
+ that.associator = serial_associator;
+ } else {
+ that.associator = bulk_associator;
}
- that.refresh(container);
+
+ that.add_method = association ? association.add_method : null;
+ that.delete_method = association ? association.delete_method : null;
};
- that.delete_on_click = function(container) {
- var delete_list = [];
- var delete_dialog = $('<div></div>', {
- title: IPA.messages.button.delete,
- 'class': 'search-dialog-delete'
- });
+ function add(container) {
- function delete_on_click() {
- that.deleter('remove_member', that.entity_name,
- that.pkey, that.other_entity, delete_list,
- function(){ that.refresh(container)});
- delete_dialog.dialog('close');
- }
- function delete_on_win() {
- delete_dialog.dialog('close');
- }
- function cancel_on_click() {
- delete_dialog.dialog('close');
- }
- var confirm_list = $('<ul/>');
- var delete_list = [];
- container.find('.search-selector').each(function () {
- if (this.checked){
- delete_list.push(this.title);
- confirm_list.append($('<li/>',{text: this.title}));
+ var pkey = $.bbq.getState(that.entity_name + '-pkey', true) || '';
+ var label = IPA.metadata[that.other_entity].label;
+ var title = 'Enroll '+that.entity_name+' '+pkey+' in '+label;
+
+ var dialog = ipa_adder_dialog({
+ 'name': 'adder_dialog',
+ 'title': title,
+ 'entity_name': that.entity_name,
+ 'pkey': pkey,
+ 'other_entity': that.other_entity,
+ 'associator': that.associator,
+ 'method': that.add_method,
+ 'on_success': function() {
+ that.refresh(container);
+ dialog.close();
+ },
+ 'on_error': function() {
+ that.refresh(container);
+ dialog.close();
}
});
- if (delete_list.length == 0){
+
+ dialog.open();
+ }
+
+ function remove(container) {
+
+ var values = that.get_selected_values();
+
+ if (!values.length) {
+ alert('Select '+that.label+' to be removed.');
return;
}
- delete_dialog.append(confirm_list);
- delete_dialog.append(
- $('<p/>',
- {text:IPA.messages.search.delete_confirm}));
-
- delete_dialog.dialog({
- modal: true,
- buttons: {
- 'Delete': delete_on_click,
- 'Cancel': cancel_on_click
+ var pkey = $.bbq.getState(that.entity_name + '-pkey', true) || '';
+ var label = IPA.metadata[that.other_entity].label;
+ var title = 'Remove '+label+' from '+that.entity_name+' '+pkey;
+
+ var dialog = ipa_deleter_dialog({
+ 'name': 'deleter_dialog',
+ 'title': title,
+ 'entity_name': that.entity_name,
+ 'pkey': pkey,
+ 'other_entity': that.other_entity,
+ 'values': values,
+ 'associator': that.associator,
+ 'method': that.delete_method,
+ 'on_success': function() {
+ that.refresh(container);
+ dialog.close();
+ },
+ 'on_error': function() {
+ that.refresh(container);
+ dialog.close();
}
});
+
+ dialog.open();
}
- that.refresh = function(container) {
+ return that;
+}
- function refresh_on_success(data, text_status, xhr) {
- var tbody = container.find('.search-table tbody');
- tbody.empty();
- var associationList = data.result.result[that.columns[0].column];
- //TODO, this is masking an error where the wrong
- //direction association is presented upon page reload.
- //if the associationList is unset, it is because
- //form.associationColumns[0] doesn't exist in the results
- if (!associationList) return;
+function ipa_association_facet(spec) {
+ spec = spec || {};
- for (var j = 0; j < associationList.length; j++){
- var association = associationList[j];
- var row = $('<tr/>').appendTo(tbody);
- search_generate_checkbox_td(row, association);
+ var that = ipa_facet(spec);
+ that.other_entity = null;
- for (var k = 0; k < that.columns.length ;k++){
- var column = that.columns[k].column;
- $('<td></td>',{
- html:data.result.result[column][j],
- }).appendTo(row);
- }
- }
+ that.is_dirty = function() {
+ var pkey = $.bbq.getState(that.entity_name + '-pkey', true) || '';
+ var other_entity = $.bbq.getState(that.entity_name + '-enroll', true) || '';
+ return pkey != that.pkey || other_entity != that.other_entity;
+ };
- tbody.find('.search-a-pkey').click(function () {
- var jobj = $(this);
- var state = {};
- state[that.other_entity + '-facet'] = 'details';
- state[that.other_entity + '-pkey'] = $(this).text();
- //Before this will work, we need to set the tab one level up
- //for example:
- //state['identity'] = 0;
- //but we have no way of getting the index.
-
- $.bbq.pushState(state);
- return (false);
- });
- }
+ that.setup = function(container, unspecified) {
- function refresh_on_error(xhr, text_status, error_thrown) {
- var search_results = $('.search-results', container).empty();
- search_results.append('<p>Error: '+error_thrown.name+'</p>');
- search_results.append('<p>'+error_thrown.title+'</p>');
- search_results.append('<p>'+error_thrown.message+'</p>');
- }
+ that.pkey = $.bbq.getState(that.entity_name + '-pkey', true) || '';
+ that.other_entity = $.bbq.getState(that.entity_name + '-enroll', true) || '';
- ipa_cmd('show', [that.pkey], {}, refresh_on_success, refresh_on_error, that.entity_name);
- };
+ that.setup_views(container);
- that.show_enrollment_dialog = function(container) {
+ //TODO I18N
+ var header_message = that.other_entity + '(s) enrolled in ' +
+ that.entity_name + ' ' + that.pkey;
+ container.append( $('<h2/>',{ html: header_message }) );
+ $('<div/>', {
+ 'id': that.entity_name+'-'+that.other_entity
+ }).appendTo(container);
+ var table = ipa_association_widget({
+ 'id': that.entity_name+'-'+that.other_entity,
+ 'name': that.other_entity, 'label': IPA.metadata[that.other_entity].label,
+ 'entity_name': that.entity_name, 'other_entity': that.other_entity
+ });
- var enrollment_dialog = new AssociationForm(
- that.entity_name,
- that.pkey,
- that.other_entity,
- function() {
- that.refresh(container);
- enrollment_dialog.close();
- },
- that.associator,
- that.method
- );
- enrollment_dialog.setup();
+ table.create(container);
+ table.setup(container);
+ table.refresh(container);
};
return that;
}
-function association_form_create(jobj)
-{
+function ipa_adder_dialog_setup() {
+
+ var that = this;
+
var div = $('<div id="associations"></div>');
var form = $('<form></form>');
@@ -561,27 +582,8 @@ function association_form_create(jobj)
}));
form_div.append(sub_div);
form.append(form_div);
- form.append($('<hr />'));
- form.append($('<div></div>', {
- text: 'Message Area'
- }));
- form.append($('<hr />'));
- var form_div = $('<div></div>');
- var span = $('<span></span>');
- span.css('float', 'left');
- span.append($('<p></p>', {
- text: '*Enter Group Names and Press Groups'
- }));
- span.append($('<p></p>', {
- text: '*More stuff'
- }));
- span.append($('<p></p>', {
- text: '*More stuff'
- }));
- form_div.append(span);
- form.append(form_div);
div.append(form);
- jobj.append(div);
+ that.dialog.append(div);
}
function association_list_create(obj_name, jobj)
@@ -589,3 +591,20 @@ function association_list_create(obj_name, jobj)
search_create(obj_name, [], jobj);
}
+function ipa_deleter_dialog_setup() {
+
+ var that = this;
+
+ var ul = $('<ul/>');
+ ul.appendTo(that.dialog);
+
+ for (var i=0; i<that.values.length; i++) {
+ $('<li/>',{
+ 'text': that.values[i]
+ }).appendTo(ul);
+ }
+
+ $('<p/>', {
+ 'text': IPA.messages.search.delete_confirm
+ }).appendTo(that.dialog);
+} \ No newline at end of file
diff --git a/install/static/certificate.js b/install/static/certificate.js
index e1297a834..affc58aa4 100755
--- a/install/static/certificate.js
+++ b/install/static/certificate.js
@@ -421,10 +421,9 @@ function certificate_status_panel(spec) {
td.append('Valid Certificate Present:');
td = $('<td/>').appendTo(tr);
- $('<input/>', {
+ ipa_button({
'id': 'get_button',
- 'type': 'button',
- 'value': 'Get',
+ 'label': 'Get',
'click': function() {
ipa_cmd(that.entity_type+'_show', [pkey], {},
function(data, text_status, xhr) {
@@ -434,10 +433,9 @@ function certificate_status_panel(spec) {
}
}).appendTo(td);
- $('<input/>', {
+ ipa_button({
'id': 'revoke_button',
- 'type': 'button',
- 'value': 'Revoke',
+ 'label': 'Revoke',
'click': function() {
ipa_cmd(that.entity_type+'_show', [pkey], {},
function(data, text_status, xhr) {
@@ -447,10 +445,9 @@ function certificate_status_panel(spec) {
}
}).appendTo(td);
- $('<input/>', {
+ ipa_button({
'id': 'view_button',
- 'type': 'button',
- 'value': 'View',
+ 'label': 'View',
'click': function() {
ipa_cmd(that.entity_type+'_show', [pkey], {},
function(data, text_status, xhr) {
@@ -476,10 +473,9 @@ function certificate_status_panel(spec) {
}));
td.append(' ');
- $('<input/>', {
+ ipa_button({
'id': 'restore_button',
- 'type': 'button',
- 'value': 'Restore',
+ 'label': 'Restore',
'click': function() {
ipa_cmd(that.entity_type+'_show', [pkey], {},
function(data, text_status, xhr) {
@@ -500,9 +496,9 @@ function certificate_status_panel(spec) {
td.append('No Valid Certificate:');
td = $('<td/>').appendTo(tr);
- $('<input/>', {
- 'type': 'button',
- 'value': 'New Certificate',
+ ipa_button({
+ 'id': 'create_button',
+ 'label': 'New Certificate',
'click': function() {
request_certificate(that.result);
}
diff --git a/install/static/details.js b/install/static/details.js
index e4cbec77e..e69a5dace 100644
--- a/install/static/details.js
+++ b/install/static/details.js
@@ -30,39 +30,44 @@ function ipa_details_field(spec) {
spec = spec || {};
- var that = {};
- that.name = spec.name;
- that.label = spec.label;
+ spec.create = spec.create || create;
+ spec.setup = spec.setup || setup;
+ spec.load = spec.load || load;
+ spec.save = spec.save || save;
+
+ var that = ipa_widget(spec);
+
+ function create(container) {
+ }
- that.setup = spec.setup || setup;
- that.load = spec.load || load;
- that.save = spec.save || save;
+ function setup(container) {
- function setup(container, dl, section) {
+ var dl = $('dl', container);
- var obj_name = container.attr('title');
- var title = this.name;
+ var title = that.name;
var label = '';
- var param_info = ipa_get_param_info(obj_name, this.name);
+ var param_info = ipa_get_param_info(that.entity_name, that.name);
if (param_info)
label = param_info['label'];
if (!label)
- label = this.label;
+ label = that.label;
$('<dt></dt>', {
- id: this.name,
+ id: that.name,
title: title,
html: label + ':'
}).appendTo(dl);
}
- function load(container, dt, entry_attrs) {
+ function load(container, result) {
- var obj_name = container.attr('id');
var multivalue = false;
var hint_span = null;
var dd;
- var param_info = ipa_get_param_info(obj_name, this.name);
+ var dt = $('dt[title='+that.name+']', container);
+ if (!dt.length) return;
+
+ var param_info = ipa_get_param_info(that.entity_name, that.name);
if (param_info) {
if (param_info['multivalue'] || param_info['class'] == 'List')
multivalue = true;
@@ -74,35 +79,35 @@ function ipa_details_field(spec) {
}
}
- var value = entry_attrs[this.name];
+ var value = result[that.name];
if (value) {
dd = ipa_create_first_dd(
- this.name, ipa_create_input(obj_name, this.name, value[0],hint_span)
+ that.name, ipa_create_input(that.entity_name, that.name, value[0],hint_span)
);
dt.after(dd);
var last_dd = dd;
for (var i = 1; i < value.length; ++i) {
dd = ipa_create_other_dd(
- this.name, ipa_create_input(obj_name, this.name, value[i],hint_span)
+ that.name, ipa_create_input(that.entity_name, that.name, value[i],hint_span)
);
last_dd.after(dd);
last_dd = dd;
}
if (multivalue) {
dd = ipa_create_other_dd(
- this.name, _ipa_a_add_template.replace('A', this.name)
+ that.name, _ipa_a_add_template.replace('A', that.name)
);
last_dd.after(dd);
}
} else {
if (multivalue) {
dd = ipa_create_first_dd(
- this.name, _ipa_a_add_template.replace('A', this.name) /*.append(hint_span)*/
+ that.name, _ipa_a_add_template.replace('A', that.name) /*.append(hint_span)*/
);
dt.after(dd);
} else {
dd = ipa_create_first_dd(
- this.name, ipa_create_input(obj_name, this.name, '') /*.append(hint_span)*/
+ that.name, ipa_create_input(that.entity_name, that.name, '') /*.append(hint_span)*/
);
dt.after(dd);
}
@@ -139,10 +144,35 @@ function ipa_details_section(spec){
var that = {};
that.name = spec.name || '';
that.label = spec.label || '';
+ that.template = spec.template;
+ that._entity_name = spec.entity_name;
+
+ that.setup = spec.setup || ipa_details_section_setup;
+ that.create = spec.create || ipa_details_section_create;
+ that.load = spec.load || ipa_details_section_load;
that.fields = [];
that.fields_by_name = {};
+ that.super = function(name) {
+ var method = that[name];
+ return function () {
+ return method.apply(that, arguments);
+ };
+ };
+
+ that.__defineGetter__("entity_name", function(){
+ return that._entity_name;
+ });
+
+ that.__defineSetter__("entity_name", function(entity_name){
+ that._entity_name = entity_name;
+
+ for (var i=0; i<that.fields.length; i++) {
+ that.fields[i].entity_name = entity_name;
+ }
+ });
+
that.get_fields = function() {
return that.fields;
};
@@ -152,6 +182,7 @@ function ipa_details_section(spec){
};
that.add_field = function(field) {
+ field.entity_name = that.entity_name;
that.fields.push(field);
that.fields_by_name[field.name] = field;
};
@@ -162,6 +193,30 @@ function ipa_details_section(spec){
return field;
};
+ that.create_text = function(spec) {
+ var field = ipa_text_widget(spec);
+ that.add_field(field);
+ return field;
+ };
+
+ that.create_radio = function(spec) {
+ var field = ipa_radio_widget(spec);
+ that.add_field(field);
+ return field;
+ };
+
+ that.create_textarea = function(spec) {
+ var field = ipa_textarea_widget(spec);
+ that.add_field(field);
+ return field;
+ };
+
+ that.create_button = function(spec) {
+ var field = ipa_button_widget(spec);
+ that.add_field(field);
+ return field;
+ };
+
// Deprecated: Used for backward compatibility only.
function input(spec){
that.create_field(spec);
@@ -184,12 +239,26 @@ function ipa_details_facet(spec) {
var that = ipa_facet(spec);
- that.init = spec.init;
- that.setup = spec.setup || setup;
+ that.init = spec.init || init;
+ that.is_dirty = spec.is_dirty || ipa_details_is_dirty;
+ that.setup = spec.setup || ipa_details_setup;
+ that.create = spec.create || ipa_details_create;
that.sections = [];
that.sections_by_name = {};
+ that.__defineGetter__("entity_name", function(){
+ return that._entity_name;
+ });
+
+ that.__defineSetter__("entity_name", function(entity_name){
+ that._entity_name = entity_name;
+
+ for (var i=0; i<that.sections.length; i++) {
+ that.sections[i].entity_name = entity_name;
+ }
+ });
+
that.get_sections = function() {
return that.sections;
};
@@ -199,70 +268,87 @@ function ipa_details_facet(spec) {
};
that.add_section = function(section) {
+ section.entity_name = that.entity_name;
that.sections.push(section);
that.sections_by_name[section.name] = section;
};
that.create_section = function(spec) {
- var section = ipa_stanza(spec);
+ var section = ipa_details_section(spec);
that.add_section(section);
return section;
};
- that.is_dirty = function() {
- var pkey = $.bbq.getState(that.entity_name + '-pkey', true) || '';
- return pkey != that.pkey;
- };
-
- function setup(container, unspecified) {
+ function init() {
+ }
- that.pkey = $.bbq.getState(that.entity_name + '-pkey', true) || '';
+ return that;
+}
- that.setup_views(container);
- ipa_details_create(container, that.sections);
+function ipa_button(spec) {
- container.find('.details-reset').click(function() {
- ipa_details_reset(container);
- return false;
- });
+ spec = spec || {};
- container.find('.details-update').click(function() {
- var pkey_name = IPA.metadata[that.entity_name].primary_key;
- ipa_details_update(container, ipa_details_cache[that.entity_name][pkey_name][0]);
- return false;
- });
+ var button = $('<a/>', {
+ 'id': spec.id,
+ 'html': spec.label,
+ 'class': 'ui-state-default ui-corner-all input_link'
+ });
- if (that.pkey||unspecified){
- ipa_details_load(container, that.pkey, null, null);
- }
- }
+ if (spec.click) button.click(spec.click);
+ if (spec.class) button.addClass(spec.class);
+ if (spec.icon) button.append('<span class="ui-icon '+spec.icon+'" ></span> ');
- if (that.init) that.init();
+ return button;
+}
- return that;
+function ipa_details_is_dirty() {
+ var pkey = $.bbq.getState(this.entity_name + '-pkey', true) || '';
+ return pkey != this.pkey;
}
-function ipa_make_button(which,text,details_class){
+function ipa_details_setup(container, unspecified) {
- var button_class= details_class +
- " ui-state-default ui-corner-all input_link ";
- return $('<a ></a>',{
- "class": button_class
- }).
- append('<span class="ui-icon ' + which +'" ></span> ').
- append(text);
+ var facet = this;
+
+ facet.setup_views(container);
+
+ facet.pkey = $.bbq.getState(facet.entity_name + '-pkey', true) || '';
+ if (!facet.pkey && !unspecified) return;
+
+ function on_success(data, text_status, xhr) {
+ var result = data.result.result;
+
+ ipa_details_cache[facet.entity_name] = $.extend(true, {}, result);
+ facet.create(container, result);
+ }
+
+ function on_failure(xhr, text_status, error_thrown) {
+ var details = $('.details', container).empty();
+ details.append('<p>Error: '+error_thrown.name+'</p>');
+ details.append('<p>'+error_thrown.title+'</p>');
+ details.append('<p>'+error_thrown.message+'</p>');
+ }
+
+ var params = [];
+ if (facet.pkey) params.push(facet.pkey);
+
+ ipa_cmd(
+ 'show', params, {all: true}, on_success, on_failure, facet.entity_name
+ );
}
-function ipa_details_create(container, sections)
+function ipa_details_create(container, result)
{
+ var facet = this;
+
if (!container) {
alert('ERROR: ipa_details_create: Missing container argument!');
return;
}
- var obj_name = container.attr('id');
- container.attr('title', obj_name);
- container.addClass('details-container');
+ var entity_name = container.attr('id');
+ container.attr('title', entity_name);
var details = $('<div/>', {
'class': 'details'
@@ -272,81 +358,97 @@ function ipa_details_create(container, sections)
'class': 'details-buttons'
}).appendTo(details);
- buttons.append(ipa_make_button('ui-icon-refresh','Reset','details-reset'));
- buttons.append(ipa_make_button('ui-icon-check','Update','details-update'));
-
- details.append('<hr />');
-
- for (var i = 0; i < sections.length; ++i) {
- var section = sections[i];
- ipa_details_section_setup(container, details, section);
- }
+ buttons.append(ipa_button({
+ 'label': 'Reset',
+ 'icon': 'ui-icon-refresh',
+ 'class': 'details-reset',
+ 'click': function() {
+ ipa_details_reset(container);
+ return false;
+ }
+ }));
-}
+ var pkey_name = IPA.metadata[facet.entity_name].primary_key;
+ buttons.append(ipa_button({
+ 'label': 'Update',
+ 'icon': 'ui-icon-check',
+ 'class': 'details-update',
+ 'click': function() {
+ ipa_details_update(container, ipa_details_cache[facet.entity_name][pkey_name][0]);
+ return false;
+ }
+ }));
-function ipa_details_section_setup(container, details, section)
-{
- var id = section.name;
- var name = section.label;
- var fields = section.fields;
+ details.append('<br/>');
+ details.append('<hr/>');
- if (!fields)
- return;
+ for (var i = 0; i < facet.sections.length; ++i) {
+ var section = facet.sections[i];
- details.append($("<h2/>",{
- click: function(){_h2_on_click(this)},
- html:"&#8722; "+name
- }));
+ details.append($('<h2/>',{
+ click: function(){_h2_on_click(this)},
+ html:"&#8722; "+section.label
+ }));
- var dl = $('<dl></dl>',{
- id:id,
- "class":"entryattrs"
- }).appendTo(details);
+ var div = $('<div/>', {
+ 'id': facet.entity_name+'-'+facet.name+'-'+section.name,
+ 'class': 'details-section'
+ }).appendTo(details);
- for (var i = 0; i < fields.length; ++i) {
- var field = fields[i];
+ section.setup(div, result);
- field.setup(container, dl, section);
+ details.append('<hr/>');
}
-
- details.append('<hr/>');
}
-function ipa_details_load(container, pkey, on_win, on_fail)
-{
- var obj_name = container.attr('id');
-
- function load_on_win(data, text_status, xhr) {
- if (on_win)
- on_win(data, text_status, xhr);
- if (data.error)
- return;
+function ipa_details_section_setup(container, result) {
+ var section = this;
+ var fields = section.get_fields();
- var result = data.result.result;
- ipa_details_cache[obj_name] = $.extend(true, {}, result);
- ipa_details_display(container, result);
+ if (section.template) {
+ var template = IPA.get_template(section.template);
+ container.load(template, function(data, text_status, xhr) {
+ for (var i = 0; i < fields.length; ++i) {
+ var field = fields[i];
+ field.create(container);
+ field.setup(container);
+ field.load(container, result);
+ }
+ });
+ return;
}
- function load_on_fail(xhr, text_status, error_thrown) {
- if (on_fail)
- on_fail(xhr, text_status, error_thrown);
+ section.create(container);
- var details = $('.details', container).empty();
- details.append('<p>Error: '+error_thrown.name+'</p>');
- details.append('<p>'+error_thrown.title+'</p>');
- details.append('<p>'+error_thrown.message+'</p>');
+ for (var i = 0; i < fields.length; ++i) {
+ var field = fields[i];
+ field.create(container);
+ field.setup(container);
+ field.load(container, result);
}
+}
- var params = [pkey];
- if (!pkey){
- params = [];
+function ipa_details_section_create(container, result) {
+ var section = this;
+
+ var dl = $('<dl/>', {
+ 'id': section.name,
+ 'class': 'entryattrs'
+ }).appendTo(container);
+}
+
+function ipa_details_section_load(container, result) {
+ var section = this;
+ var fields = section.get_fields();
+
+ for (var j=0; j<fields.length; j++) {
+ var field = fields[j];
+ field.load(container, result);
}
- ipa_cmd(
- 'show', params, {all: true}, load_on_win, load_on_fail, obj_name
- );
}
+
function ipa_details_update(container, pkey, on_win, on_fail)
{
var obj_name = container.attr('id');
@@ -378,13 +480,14 @@ function ipa_details_update(container, pkey, on_win, on_fail)
var sections = facet.get_sections();
for (var i=0; i<sections.length; i++) {
var section = sections[i];
- var fields = section.fields;
- if (!fields) continue;
+ var fields = section.get_fields();
+
+ var div = $('#'+facet.entity_name+'-'+facet.name+'-'+section.name, container);
for (var j=0; j<fields.length; j++) {
var field = fields[j];
- values = field.save(container);
+ values = field.save(div);
var param_info = ipa_get_param_info(obj_name, field.name);
if (param_info) {
@@ -434,29 +537,24 @@ var _ipa_span_hint_template = '<span class="attrhint">Hint: D</span>';
* </dl>
*
* arguments:
- * entry_attrs - 'result' field as returned by ipa *-show commnads
+ * result - 'result' field as returned by ipa *-show commnads
* (basically an associative array with attr:value pairs) */
-function ipa_details_display(container, entry_attrs)
+function ipa_details_display(container, result)
{
- var obj_name = container.attr('id');
+ var entity_name = container.attr('id');
/* remove all <dd> tags i.e. all attribute values */
$('dd', container).remove();
/* go through all <dt> tags and pair them with newly created <dd>s */
- var facet = ipa_entity_get_details_facet(obj_name);
+ var facet = ipa_entity_get_details_facet(entity_name);
var sections = facet.get_sections();
for (var i=0; i<sections.length; i++) {
var section = sections[i];
- var fields = section.fields;
- if (!fields) continue;
- for (var j=0; j<fields.length; j++) {
- var field = fields[j];
- var dt = $('dt[title='+field.name+']', container);
- if (!dt.length) continue;
- field.load(container, dt, entry_attrs);
- }
+ var div = $('#'+facet.entity_name+'-'+facet.name+'-'+section.name, container);
+
+ section.load(div, result);
}
}
@@ -501,10 +599,10 @@ var _ipa_param_type_2_handler_map = {
* arguments:
* attr - LDAP attribute name
* value - the attributes value */
-function ipa_create_input(obj_name, attr, value,hint)
+function ipa_create_input(entity_name, attr, value,hint)
{
var input = $("<label>",{html:value.toString()});
- var param_info = ipa_get_param_info(obj_name, attr);
+ var param_info = ipa_get_param_info(entity_name, attr);
if (!param_info) {
/* no information about the param is available, default to text input */
input = _ipa_create_text_input(attr, value, null);
@@ -606,7 +704,7 @@ function _ipa_create_text_input(attr, value, param_info)
style:"display:none",
click: function(){
var key = this.previousElementSibling.name;
- var entity_divs = $(this).parents('.details-container');
+ var entity_divs = $(this).parents('.entity-container');
var entry_attrs = ipa_details_cache[entity_divs[0].id];
index = calculate_dd_index($(this));
@@ -649,7 +747,7 @@ function _ipa_add_on_click(obj)
var jobj = $(obj);
var attr = jobj.attr('title');
var par = jobj.parent();
- var obj_name = jobj.closest('.details-container').attr('title');
+ var obj_name = jobj.closest('.entity-container').attr('title');
var param_info = ipa_get_param_info(obj_name, '');
var input = _ipa_create_text_input(attr, '', param_info);
diff --git a/install/static/entity.js b/install/static/entity.js
index f26f219b7..24a49fc76 100644
--- a/install/static/entity.js
+++ b/install/static/entity.js
@@ -28,11 +28,19 @@ function ipa_facet(spec) {
var that = {};
that.name = spec.name;
that.label = spec.label;
- that.entity_name = spec.entity_name;
+ that._entity_name = spec.entity_name;
that.init = spec.init;
that.setup = spec.setup;
+ that.__defineGetter__("entity_name", function(){
+ return that._entity_name;
+ });
+
+ that.__defineSetter__("entity_name", function(entity_name){
+ that._entity_name = entity_name;
+ });
+
that.setup_views = ipa_facet_setup_views;
return that;
@@ -55,6 +63,9 @@ function ipa_entity(spec) {
this.facet_name = null;
+ that.associations = [];
+ that.associations_by_name = {};
+
that.get_add_dialog = function() {
return that.add_dialog;
};
@@ -74,31 +85,49 @@ function ipa_entity(spec) {
};
that.add_facet = function(facet) {
+ facet.entity_name = that.name;
that.facets.push(facet);
that.facets_by_name[facet.name] = facet;
};
that.create_search_facet = function(spec) {
- spec.entity_name = that.name;
var facet = ipa_search_facet(spec);
that.add_facet(facet);
return facet;
};
that.create_details_facet = function(spec) {
- spec.entity_name = that.name;
var facet = ipa_details_facet(spec);
that.add_facet(facet);
+ facet.init();
return facet;
};
that.create_association_facet = function(spec) {
- spec.entity_name = that.name;
var facet = ipa_association_facet(spec);
that.add_facet(facet);
return facet;
};
+ that.get_associations = function() {
+ return that.associations;
+ };
+
+ that.get_association = function(name) {
+ return that.associations_by_name[name];
+ };
+
+ that.add_association = function(config) {
+ that.associations.push(config);
+ that.associations_by_name[config.name] = config;
+ };
+
+ that.create_association = function(spec) {
+ var config = ipa_association_config(spec);
+ that.add_association(config);
+ return config;
+ };
+
return that;
}
@@ -213,14 +242,17 @@ function ipa_entity_get_association_facet(entity_name) {
function ipa_entity_set_association_definition(entity_name, data) {
- var facet = ipa_entity_get_association_facet(entity_name);
+ var entity = ipa_get_entity(entity_name);
+
+ ipa_entity_get_association_facet(entity_name);
for (var other_entity in data) {
var config = data[other_entity];
- facet.create_config({
+ entity.create_association({
'name': other_entity,
'associator': config.associator,
- 'method': config.method
+ 'add_method': config.add_method,
+ 'delete_method': config.delete_method
});
}
}
@@ -231,7 +263,6 @@ function ipa_entity_set_facet_definition(entity_name, list) {
for (var i=0; i<list.length; i++) {
var facet = list[i];
- facet.entity_name = entity_name;
entity.add_facet(facet);
}
}
@@ -244,8 +275,6 @@ function ipa_entity_setup(container, unspecified) {
var entity = this;
- container.empty();
-
var facet_name = $.bbq.getState(entity.name + '-facet', true) || unspecified || 'search';
var facet = entity.get_facet(facet_name);
@@ -262,6 +291,8 @@ function ipa_entity_setup(container, unspecified) {
IPA.entity_name = entity.name;
}
+ container.empty();
+
if (facet.setup) {
facet.setup(container, unspecified);
}
@@ -271,7 +302,7 @@ function ipa_facet_setup_views(container) {
var facet = this;
- var ul = $('<ul/>', {'class': 'entity-views'});
+ var ul = $('<ul/>', {'class': 'entity-views'}).appendTo(container);
var entity = IPA.get_entity(facet.entity_name);
var facets = entity.get_facets();
@@ -289,7 +320,9 @@ function ipa_facet_setup_views(container) {
title: other_facet.name,
text: label,
click: function(entity_name, facet_name) {
- return function() { IPA.show_page(entity_name, facet_name); }
+ return function() {
+ IPA.show_page(entity_name, facet_name);
+ };
}(facet.entity_name, facet_name)
}));
@@ -308,20 +341,20 @@ function ipa_facet_setup_views(container) {
title: other_entity,
text: label,
click: function(entity_name, facet_name, other_entity) {
- return function() { IPA.show_page(entity_name, facet_name, other_entity); }
+ return function() {
+ IPA.show_page(entity_name, facet_name, other_entity);
+ };
}(facet.entity_name, facet_name, other_entity)
}));
}
}
}
}
-
- container.append(ul);
}
function ipa_entity_quick_links(tr, attr, value, entry_attrs) {
- var obj_name = tr.closest('.search-container').attr('title');
+ var obj_name = tr.closest('.entity-container').attr('title');
var pkey = IPA.metadata[obj_name].primary_key;
var pkey_value = entry_attrs[pkey][0];
diff --git a/install/static/hbac.js b/install/static/hbac.js
index 94b05fbd4..528fdec92 100755
--- a/install/static/hbac.js
+++ b/install/static/hbac.js
@@ -27,6 +27,7 @@ function ipa_hbac() {
});
that.init = function() {
+
that.create_add_dialog({
'name': 'add',
'title': 'Add New Rule',
@@ -43,12 +44,7 @@ function ipa_hbac() {
that.create_details_facet({
'name': 'details',
'label': 'Details',
- 'init': ipa_hbac_details_init,
- 'setup': ipa_hbac_details_setup
- });
-
- that.create_association_facet({
- 'name': 'associate'
+ 'init': ipa_hbac_details_init
});
};
@@ -61,6 +57,7 @@ IPA.add_entity(ipa_hbac());
function ipa_hbac_add_init() {
this.create_field({name:'cn', label:'Rule Name'});
+ this.create_field({name:'accessruletype', label:'Rule type (allow/deny)'});
}
function ipa_hbac_search_init() {
@@ -81,51 +78,51 @@ function ipa_hbac_search_init() {
function ipa_hbac_search_setup(container) {
- var facet = this;
+ var that = this;
- facet.filter = $.bbq.getState(facet.entity_name + '-filter', true) || '';
+ that.filter = $.bbq.getState(that.entity_name + '-filter', true) || '';
+/*
+ // Not yet implemented
- var toolbar = $('<span/>').appendTo(container);
+ var left_buttons = $('<span/>', {
+ 'style': 'float: left;'
+ }).appendTo(container);
- $('<input/>', {
- 'type': 'button',
- 'value': 'Troubleshoot Rules',
- 'click': function() {
- }
- }).appendTo(toolbar);
+ left_buttons.append(ipa_button({
+ 'label': 'Troubleshoot Rules'
+ }));
- $('<input/>', {
- 'type': 'button',
- 'value': 'Cull Disabled Rules',
- 'click': function() {
- }
- }).appendTo(toolbar);
+ left_buttons.append(ipa_button({
+ 'label': 'Cull Disabled Rules'
+ }));
- $('<input/>', {
- 'type': 'button',
- 'value': 'Login Services',
- 'click': function() {
- }
- }).appendTo(toolbar);
+ var right_buttons = $('<span/>', {
+ 'style': 'float: right;'
+ }).appendTo(container);
- $('<input/>', {
- 'type': 'button',
- 'value': 'Login Svc Groups',
- 'click': function() {
- }
- }).appendTo(toolbar);
+ right_buttons.append(ipa_button({
+ 'label': 'Login Services'
+ }));
+
+ right_buttons.append(ipa_button({
+ 'label': 'Login Svc Groups'
+ }));
- search_create(facet.entity_name, facet.columns, container);
+ container.append('<br/><br/>');
+*/
+ search_create(that.entity_name, that.columns, container);
- ipa_make_button('ui-icon-plus', IPA.messages.button.add).
- click(function() {
- var entity = IPA.get_entity(facet.entity_name);
+ ipa_button({
+ 'label': IPA.messages.button.add,
+ 'icon': 'ui-icon-plus',
+ 'click': function() {
+ var entity = IPA.get_entity(that.entity_name);
entity.add_dialog.open();
return false;
- }).
- appendTo($('.search-controls', container));
+ }
+ }).appendTo($('.search-controls', container));
- search_load(container, facet.filter);
+ search_load(container, that.filter);
}
function ipa_hbac_quick_links(tr, attr, value, entry_attrs) {
@@ -133,7 +130,7 @@ function ipa_hbac_quick_links(tr, attr, value, entry_attrs) {
var column = this;
var facet = column.facet;
- var pkey = IPA.metadata[facet.entity_name].primary_key;
+ var pkey = IPA.metadata[column.entity_name].primary_key;
var pkey_value = entry_attrs[pkey][0];
var td = $('<td/>').appendTo(tr);
@@ -144,8 +141,8 @@ function ipa_hbac_quick_links(tr, attr, value, entry_attrs) {
'text': 'Details',
'click': function() {
var state = {};
- state[facet.entity_name+'-facet'] = 'details';
- state[facet.entity_name+'-pkey'] = pkey_value;
+ state[column.entity_name+'-facet'] = 'details';
+ state[column.entity_name+'-pkey'] = pkey_value;
nav_push_state(state);
return false;
}
@@ -159,8 +156,8 @@ function ipa_hbac_quick_links(tr, attr, value, entry_attrs) {
'text': 'Test Rule',
'click': function() {
var state = {};
- state[facet.entity_name+'-facet'] = 'test-rule';
- state[facet.entity_name+'-pkey'] = pkey_value;
+ state[column.entity_name+'-facet'] = 'test-rule';
+ state[column.entity_name+'-pkey'] = pkey_value;
nav_push_state(state);
return false;
}
@@ -169,46 +166,565 @@ function ipa_hbac_quick_links(tr, attr, value, entry_attrs) {
function ipa_hbac_details_init() {
- var section = this.create_section({name:'general', label:'General'});
- section.create_field({name:'cn', label:'Name'});
- section.create_field({name:'accessruletype', label:'Rule Type'});
- section.create_field({name:'description', label:'Description'});
- section.create_field({name:'ipaenabledflag', label:'Enabled'});
+ var that = this;
+ var section;
- section = this.create_section({name:'user', label:'Who'});
- section.create_field({name:'usercategory', label:'User Category'});
+ if (IPA.layout) {
+ section = that.create_section({
+ 'name': 'general',
+ 'label': 'General',
+ 'template': 'hbac-details-general.html #contents'
+ });
- section = this.create_section({name:'host', label:'Accessing'});
- section.create_field({name:'hostcategory', label:'Host Category'});
+ } else {
+ section = ipa_hbac_details_general_section({
+ 'name': 'general',
+ 'label': 'General'
+ });
+ that.add_section(section);
+ }
+
+ section.create_text({ 'name': 'cn', 'label': 'Name' });
+ section.create_radio({ 'name': 'accessruletype', 'label': 'Rule Type' });
+ section.create_textarea({ 'name': 'description', 'label': 'Description' });
+ section.create_radio({ 'name': 'ipaenabledflag', 'label': 'Enabled' });
+
+ if (IPA.layout) {
+ section = that.create_section({
+ 'name': 'user',
+ 'label': 'Who',
+ 'template': 'hbac-details-user.html #contents'
+ });
- section = this.create_section({name:'service', label:'Via Service'});
- section.create_field({name:'servicecategory', label:'Service Category'});
+ } else {
+ section = ipa_hbac_details_tables_section({
+ 'name': 'user',
+ 'label': 'Who',
+ 'text': 'Rule applies when access is requested by:',
+ 'field_name': 'usercategory',
+ 'options': [
+ { 'value': 'all', 'label': 'Anyone' },
+ { 'value': '', 'label': 'Specified Users and Groups' }
+ ],
+ 'tables': [
+ { 'field_name': 'memberuser_user' },
+ { 'field_name': 'memberuser_group' }
+ ]
+ });
+ that.add_section(section);
+ }
+
+ section.create_radio({ name: 'usercategory', label: 'User category' });
+ section.add_field(ipa_hbac_association_widget({
+ 'id': that.entity_name+'-memberuser_user',
+ 'name': 'memberuser_user', 'label': 'Users',
+ 'other_entity': 'user', 'add_method': 'add_user', 'delete_method': 'remove_user'
+ }));
+ section.add_field(ipa_hbac_association_widget({
+ 'id': that.entity_name+'-memberuser_group',
+ 'name': 'memberuser_group', 'label': 'Groups',
+ 'other_entity': 'group', 'add_method': 'add_user', 'delete_method': 'remove_user'
+ }));
+
+ if (IPA.layout) {
+ section = that.create_section({
+ 'name': 'host',
+ 'label': 'Accessing',
+ 'template': 'hbac-details-host.html #contents'
+ });
- section = this.create_section({name:'sourcehost', label:'From'});
- section.create_field({name:'sourcehostcategory', label:'Source Host Category'});
+ } else {
+ section = ipa_hbac_details_tables_section({
+ 'name': 'host',
+ 'label': 'Accessing',
+ 'text': 'Rule applies when access is requested to:',
+ 'field_name': 'hostcategory',
+ 'options': [
+ { 'value': 'all', 'label': 'Any Host' },
+ { 'value': '', 'label': 'Specified Hosts and Groups' }
+ ],
+ 'tables': [
+ { 'field_name': 'memberhost_host' },
+ { 'field_name': 'memberhost_hostgroup' }
+ ],
+ 'columns': [
+ ]
+ });
+ that.add_section(section);
+ }
+
+ section.create_radio({ 'name': 'hostcategory', 'label': 'Host category' });
+ section.add_field(ipa_hbac_association_widget({
+ 'id': that.entity_name+'-memberhost_host',
+ 'name': 'memberhost_host', 'label': 'Hosts',
+ 'other_entity': 'host', 'add_method': 'add_host', 'delete_method': 'remove_host'
+ }));
+ section.add_field(ipa_hbac_association_widget({
+ 'id': that.entity_name+'-memberhost_hostgroup',
+ 'name': 'memberhost_hostgroup', 'label': 'Host Groups',
+ 'other_entity': 'hostgroup', 'add_method': 'add_host', 'delete_method': 'remove_host'
+ }));
+
+ if (IPA.layout) {
+ section = that.create_section({
+ 'name': 'service',
+ 'label': 'Via Service',
+ 'template': 'hbac-details-service.html #contents'
+ });
+
+ } else {
+ section = ipa_hbac_details_tables_section({
+ 'name': 'service',
+ 'label': 'Via Service',
+ 'text': 'Rule applies when access is requested via:',
+ 'field_name': 'servicecategory',
+ 'options': [
+ { 'value': 'all', 'label': 'Any Service' },
+ { 'value': '', 'label': 'Specified Services and Groups' }
+ ],
+ 'tables': [
+ { 'field_name': 'memberservice_hbacsvc' },
+ { 'field_name': 'memberservice_hbacsvcgroup' }
+ ]
+ });
+ that.add_section(section);
+ }
+
+ section.create_radio({ 'name': 'servicecategory', 'label': 'Service category' });
+ section.add_field(ipa_hbac_association_widget({
+ 'id': that.entity_name+'-memberservice_hbacsvc',
+ 'name': 'memberservice_hbacsvc', 'label': 'Services',
+ 'other_entity': 'hbacsvc', 'add_method': 'add_service', 'delete_method': 'remove_service'
+ }));
+ section.add_field(ipa_hbac_association_widget({
+ 'id': that.entity_name+'-memberservice_hbacsvcgroup',
+ 'name': 'memberservice_hbacsvcgroup', 'label': 'Service Groups',
+ 'other_entity': 'hbacsvcgroup', 'add_method': 'add_service', 'delete_method': 'remove_service'
+ }));
+
+ if (IPA.layout) {
+ section = that.create_section({
+ 'name': 'sourcehost',
+ 'label': 'From',
+ 'template': 'hbac-details-sourcehost.html #contents'
+ });
+
+ } else {
+ section = ipa_hbac_details_tables_section({
+ 'name': 'sourcehost',
+ 'label': 'From',
+ 'text': 'Rule applies when access is being initiated from:',
+ 'field_name': 'sourcehostcategory',
+ 'options': [
+ { 'value': 'all', 'label': 'Any Host' },
+ { 'value': '', 'label': 'Specified Hosts and Groups' }
+ ],
+ 'tables': [
+ { 'field_name': 'sourcehost_host' },
+ { 'field_name': 'sourcehost_hostgroup' }
+ ]
+ });
+ that.add_section(section);
+ }
+
+ section.create_radio({ 'name': 'sourcehostcategory', 'label': 'Source host category' });
+ section.add_field(ipa_hbac_association_widget({
+ 'id': that.entity_name+'-sourcehost_host',
+ 'name': 'sourcehost_host', 'label': 'Host',
+ 'other_entity': 'host', 'add_method': 'add_sourcehost', 'delete_method': 'remove_sourcehost'
+ }));
+ section.add_field(ipa_hbac_association_widget({
+ 'id': that.entity_name+'-sourcehost_hostgroup',
+ 'name': 'sourcehost_hostgroup', 'label': 'Host Groups',
+ 'other_entity': 'hostgroup', 'add_method': 'add_sourcehost', 'delete_method': 'remove_sourcehost'
+ }));
+
+ if (IPA.layout) {
+ section = that.create_section({
+ 'name': 'accesstime',
+ 'label': 'When',
+ 'template': 'hbac-details-accesstime.html #contents'
+ });
+
+ } else {
+ section = ipa_hbac_details_tables_section({
+ 'name': 'accesstime',
+ 'label': 'When',
+ 'text': 'Rule applies when access is being requested at:',
+ 'field_name': 'sourcehostcategory',
+ 'options': [
+ { 'value': 'all', 'label': 'Any Time' },
+ { 'value': '', 'label': 'Specified Times' }
+ ],
+ 'tables': [
+ { 'field_name': 'accesstime' }
+ ]
+ });
+ that.add_section(section);
+ }
+
+ section.add_field(ipa_hbac_accesstime_widget({
+ 'id': that.entity_name+'-accesstime',
+ 'name': 'accesstime', 'label': 'Access Time'
+ }));
}
-function ipa_hbac_details_setup(container, unspecified) {
+function ipa_hbac_details_general_section(spec){
- var facet = this;
+ spec = spec || {};
- var pkey = $.bbq.getState(facet.entity_name + '-pkey', true);
- var pkey_name = IPA.metadata[facet.entity_name].primary_key;
+ var that = ipa_details_section(spec);
- facet.setup_views(container);
+ that.create = function(container) {
- var sections = facet.get_sections();
- ipa_details_create(container, sections);
+ var table = $('<table/>', {
+ 'style': 'width: 100%;'
+ }).appendTo(container);
- container.find('.details-reset').click(function() {
- ipa_details_reset(container);
- return false;
- });
+ var tr = $('<tr/>', {
+ }).appendTo(table);
- container.find('.details-update').click(function() {
- ipa_details_update(container, ipa_details_cache[facet.entity_name][pkey_name][0]);
- return false;
- });
+ var td = $('<td/>', {
+ 'style': 'width: 100px; text-align: right;',
+ 'html': 'Name:'
+ }).appendTo(tr);
+
+ td = $('<td/>').appendTo(tr);
+
+ $('<input/>', {
+ 'type': 'text',
+ 'name': 'cn',
+ 'size': 30
+ }).appendTo(td);
+
+ td = $('<td/>', {
+ 'style': 'text-align: right;'
+ }).appendTo(tr);
+
+ td.append('Rule type:');
+
+ $('<input/>', {
+ 'type': 'radio',
+ 'name': 'accessruletype',
+ 'value': 'allow'
+ }).appendTo(td);
+
+ td.append('Allow');
+
+ $('<input/>', {
+ 'type': 'radio',
+ 'name': 'accessruletype',
+ 'value': 'deny'
+ }).appendTo(td);
+
+ td.append('Deny');
+
+ tr = $('<tr/>', {
+ }).appendTo(table);
+
+ td = $('<td/>', {
+ 'style': 'text-align: right; vertical-align: top;',
+ 'html': 'Description:'
+ }).appendTo(tr);
+
+ td = $('<td/>', {
+ 'colspan': 2
+ }).appendTo(tr);
+
+ $('<textarea/>', {
+ 'name': 'description',
+ 'rows': 5,
+ 'style': 'width: 100%'
+ }).appendTo(td);
+
+ tr = $('<tr/>', {
+ }).appendTo(table);
+
+ td = $('<td/>', {
+ 'style': 'text-align: right; vertical-align: top;',
+ 'html': 'Rule status:'
+ }).appendTo(tr);
+
+ td = $('<td/>', {
+ 'colspan': 2
+ }).appendTo(tr);
+
+ $('<input/>', {
+ 'type': 'radio',
+ 'name': 'ipaenabledflag',
+ 'value': 'TRUE'
+ }).appendTo(td);
+
+ td.append('Active');
+
+ $('<input/>', {
+ 'type': 'radio',
+ 'name': 'ipaenabledflag',
+ 'value': 'FALSE'
+ }).appendTo(td);
+
+ td.append('Inactive');
+ };
+
+ return that;
+}
+
+function ipa_hbac_details_tables_section(spec){
+
+ spec = spec || {};
+
+ spec.create = create;
+
+ var that = ipa_details_section(spec);
+
+ that.text = spec.text;
+ that.field_name = spec.field_name;
+ that.options = spec.options;
+ that.tables = spec.tables;
+ that.columns = spec.columns;
+
+ that.super_setup = that.super('setup');
+
+ function create(container) {
+
+ if (that.template) return;
+
+ container.append(that.text);
+
+ for (var i=0; i<that.options.length; i++) {
+ var option = that.options[i];
+
+ $('<input/>', {
+ 'type': 'radio',
+ 'name': that.field_name,
+ 'value': option.value
+ }).appendTo(container);
+
+ container.append(option.label);
+ }
+
+ container.append('<br/>');
- ipa_details_load(container, pkey, null, null);
+ for (var i=0; i<that.tables.length; i++) {
+ var table = that.tables[i];
+
+ $('<div/>', {
+ 'id': that.entity_name+'-'+table.field_name
+ }).appendTo(container);
+ }
+ }
+
+ return that;
+}
+
+/**
+ * This widget adds & deletes the rows of the table in the UI, but does not
+ * execute IPA command to apply the changes on the server.
+ */
+function ipa_hbac_association_widget(spec) {
+
+ spec = spec || {};
+
+ spec.add = spec.add || add;
+ spec.remove = spec.remove || remove;
+ spec.save = spec.save || save;
+
+ var that = ipa_table_widget(spec);
+
+ that.other_entity = spec.other_entity;
+
+ that.add_method = spec.add_method;
+ that.delete_method = spec.delete_method;
+
+ that.super_create = that.super('create');
+ that.super_setup = that.super('setup');
+
+ that.create = function(container) {
+
+ // create a column when none defined
+ if (!that.columns.length) {
+ that.create_column({
+ 'name': that.name,
+ 'label': IPA.metadata[that.other_entity].label,
+ 'primary_key': true,
+ 'link': false
+ });
+ }
+
+ that.super_create(container);
+
+ var div = $('#'+that.id, container);
+
+ var buttons = $('span[name=buttons]', div);
+ if (buttons.children().length) {
+ // widget loaded from template
+ return;
+ }
+
+ $('<input/>', {
+ 'type': 'button',
+ 'name': 'remove',
+ 'value': 'Remove '+that.label
+ }).appendTo(buttons);
+
+ $('<input/>', {
+ 'type': 'button',
+ 'name': 'add',
+ 'value': 'Add '+that.label
+ }).appendTo(buttons);
+ };
+
+ that.setup = function(container) {
+
+ that.super_setup(container);
+
+ var entity = IPA.get_entity(that.entity_name);
+ var association = entity.get_association(that.other_entity);
+
+ if (association && association.associator == 'serial') {
+ that.associator = serial_associator;
+ } else {
+ that.associator = bulk_associator;
+ }
+ };
+
+ function add(container) {
+
+ var pkey = $.bbq.getState(that.entity_name + '-pkey', true) || '';
+ var label = IPA.metadata[that.other_entity].label;
+ var title = 'Add '+label+' to '+that.entity_name+' '+pkey;
+
+ var dialog = ipa_adder_dialog({
+ 'name': 'adder_dialog',
+ 'title': title,
+ 'entity_name': that.entity_name,
+ 'pkey': pkey,
+ 'other_entity': that.other_entity,
+ 'associator': that.associator,
+ 'method': that.add_method,
+ 'on_success': function() {
+ that.refresh(container);
+ dialog.close();
+ },
+ 'on_error': function() {
+ that.refresh(container);
+ dialog.close();
+ }
+ });
+
+ dialog.open();
+ }
+
+ function remove(container) {
+
+ var values = that.get_selected_values();
+
+ if (!values.length) {
+ alert('Select '+that.label+' to be removed.');
+ return;
+ }
+
+ var pkey = $.bbq.getState(that.entity_name + '-pkey', true) || '';
+ var label = IPA.metadata[that.other_entity].label;
+ var title = 'Remove '+label+' from '+that.entity_name+' '+pkey;
+
+ var dialog = ipa_deleter_dialog({
+ 'name': 'deleter_dialog',
+ 'title': title,
+ 'entity_name': that.entity_name,
+ 'pkey': pkey,
+ 'other_entity': that.other_entity,
+ 'values': values,
+ 'associator': that.associator,
+ 'method': that.delete_method,
+ 'on_success': function() {
+ that.refresh(container);
+ dialog.close();
+ },
+ 'on_error': function() {
+ that.refresh(container);
+ dialog.close();
+ }
+ });
+
+ dialog.open();
+ }
+
+ function save(container) {
+ return [];
+ }
+
+ return that;
+}
+
+function ipa_hbac_accesstime_widget(spec) {
+
+ spec = spec || {};
+
+ spec.load = spec.load || load;
+ spec.save = spec.save || save;
+
+ var that = ipa_table_widget(spec);
+
+ that.super_create = that.super('create');
+ that.super_setup = that.super('setup');
+
+ that.create = function(container) {
+
+ // create a column when none defined
+ if (!that.columns.length) {
+ that.create_column({
+ 'name': that.name,
+ 'label': that.label,
+ 'primary_key': true,
+ 'link': false
+ });
+ }
+
+ that.super_create(container);
+
+ var div = $('#'+that.id);
+
+ var buttons = $('span[name=buttons]', div);
+ if (buttons.children().length) {
+ // widget loaded from template
+ return;
+ }
+
+ $('<input/>', {
+ 'type': 'button',
+ 'name': 'remove',
+ 'value': 'Remove '+that.label
+ }).appendTo(buttons);
+
+ $('<input/>', {
+ 'type': 'button',
+ 'name': 'add',
+ 'value': 'Add '+that.label
+ }).appendTo(buttons);
+ };
+
+ function load(container, result) {
+ var values = result[that.name] || '';
+
+ if (values == '') {
+ $('input[name="'+that.name+'"][value="all"]', container).attr('checked', 'checked');
+ } else {
+ $('input[name="'+that.name+'"][value=""]', container).attr('checked', 'checked');
+ }
+
+ that.tbody.empty();
+ for (var i=0; i<values.length; i++) {
+ var tr = that.row.clone();
+ $('input[name="select"]', tr).val(values[i]);
+ $('span[name="'+that.name+'"]', tr).html(values[i]);
+ tr.appendTo(that.tbody);
+ }
+ }
+
+ function save(container) {
+ return [];
+ }
+
+ return that;
}
diff --git a/install/static/host.js b/install/static/host.js
index 8407e269d..65c2b571a 100644
--- a/install/static/host.js
+++ b/install/static/host.js
@@ -52,11 +52,14 @@ ipa_entity_set_association_definition('host', {
'rolegroup': { associator: 'serial' }
});
-function host_enrollment_status_load(container, dt, result) {
+function host_enrollment_status_load(container, result) {
// skip enrollment_status
}
-function host_usercertificate_load(container, dt, result) {
+function host_usercertificate_load(container, result) {
+
+ var dt = $('dt[title='+this.name+']', container);
+ if (!dt.length) return;
var panel = certificate_status_panel({
'entity_type': 'host',
diff --git a/install/static/index.xhtml b/install/static/index.xhtml
index bcb7cd0bb..4ba51fa38 100644
--- a/install/static/index.xhtml
+++ b/install/static/index.xhtml
@@ -12,6 +12,7 @@
<script type="text/javascript" src="jquery.ba-bbq.js"></script>
<script type="text/javascript" src="ipa.js"></script>
+ <script type="text/javascript" src="widget.js"></script>
<script type="text/javascript" src="search.js"></script>
<script type="text/javascript" src="details.js"></script>
<script type="text/javascript" src="add.js"></script>
diff --git a/install/static/ipa.css b/install/static/ipa.css
index 940a1d57b..491142d53 100644
--- a/install/static/ipa.css
+++ b/install/static/ipa.css
@@ -103,12 +103,12 @@ ul#viewtype li a {
font-weight: normal;
}
-div#details div#buttons {
+div.details div.details-buttons {
float: right;
margin-right: 15px;
}
-div#details div#buttons img {
+div.details div.details-buttons img {
border: 0;
}
@@ -131,6 +131,15 @@ hr {
margin-top: 10px;
}
+.details-section {
+ margin-left: 45px;
+ margin-right: 15px;
+ margin-top: 18px;
+ white-space: nowrap;
+ padding-bottom: 18px;
+ padding-right: 18px;
+}
+
dl.entryattrs {
clear: both;
margin-left: 15px;
@@ -226,9 +235,9 @@ span.main-separator{
-/* Search */
+/* Entity */
-.search-container{
+.entity-container{
float: left;
width: 80%;
margin: 10px;
@@ -236,6 +245,8 @@ span.main-separator{
background: #e8e8e8;
}
+/* Search */
+
.search-controls {
background:#a5a5a5;
}
diff --git a/install/static/ipa.js b/install/static/ipa.js
index 18833e677..be8e3b6ad 100644
--- a/install/static/ipa.js
+++ b/install/static/ipa.js
@@ -51,6 +51,14 @@ var IPA = ( function () {
id: 'error_dialog'
});
+ that.layout = $.bbq.getState('layout');
+ that.layouts_dir = 'layouts';
+
+ that.get_template = function(path) {
+ if (!that.layout) return path;
+ return that.layouts_dir+'/'+that.layout+'/'+path;
+ };
+
/* initialize the IPA JSON-RPC helper
* arguments:
* url - JSON-RPC URL to use (optional) */
@@ -92,9 +100,6 @@ var IPA = ( function () {
that.show_page = function (entity_name, facet_name, other_entity) {
- //var entity = IPA.get_entity(entity_name);
- //var facet = entity.get_facet(facet_name);
-
var state = {};
state[entity_name + '-facet'] = facet_name;
state[entity_name + '-enroll'] = other_entity ? other_entity : '';
diff --git a/install/static/layouts/Makefile.am b/install/static/layouts/Makefile.am
new file mode 100644
index 000000000..9e1ee7b74
--- /dev/null
+++ b/install/static/layouts/Makefile.am
@@ -0,0 +1,22 @@
+AUTOMAKE_OPTIONS = 1.7
+
+NULL =
+
+SUBDIRS = \
+ default \
+ $(NULL)
+
+appdir = $(IPA_DATA_DIR)/static/layouts
+app_DATA = \
+ $(NULL)
+
+EXTRA_DIST = \
+ $(app_DATA) \
+ $(NULL)
+
+MAINTAINERCLEANFILES = \
+ *~ \
+ Makefile.in
+ $(NULL)
+
+distclean:
diff --git a/install/static/layouts/default/Makefile.am b/install/static/layouts/default/Makefile.am
new file mode 100644
index 000000000..904fad171
--- /dev/null
+++ b/install/static/layouts/default/Makefile.am
@@ -0,0 +1,25 @@
+AUTOMAKE_OPTIONS = 1.7
+
+NULL =
+
+SUBDIRS = \
+ $(NULL)
+
+appdir = $(IPA_DATA_DIR)/static/layouts/default
+app_DATA = \
+ hbac-details-accesstime.html \
+ hbac-details-general.html \
+ hbac-details-host.html \
+ hbac-details-service.html \
+ hbac-details-sourcehost.html \
+ hbac-details-user.html \
+ $(NULL)
+
+EXTRA_DIST = \
+ $(app_DATA) \
+ $(NULL)
+
+MAINTAINERCLEANFILES = \
+ *~ \
+ Makefile.in
+ $(NULL)
diff --git a/install/static/layouts/default/hbac-details-accesstime.html b/install/static/layouts/default/hbac-details-accesstime.html
new file mode 100755
index 000000000..4122c76a6
--- /dev/null
+++ b/install/static/layouts/default/hbac-details-accesstime.html
@@ -0,0 +1,46 @@
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>When</title>
+
+ <link rel="stylesheet" type="text/css" href="jquery-ui.css" />
+ <link rel="stylesheet" type="text/css" href="ipa.css" />
+</head>
+<body>
+<div id="contents">
+ Rule applies when access is being requested at:
+ <input type="radio" name="accesstime" value="all"/>Any Time
+ <input type="radio" name="accesstime" value=""/>Specified Times
+ <br/>
+
+ <div id="hbac-accesstime">
+ <table class="search-table">
+ <thead>
+ <tr>
+ <th style="width: 25px;">
+ <input type="checkbox" name="select"/>
+ </th>
+ <th>
+ <span style="float: left;">Access Time</span>
+ <span name="buttons" style="float: right;">
+ <input type="button" name="remove" value="Remove Access Times"/>
+ <input type="button" name="add" value="Add Access Times"/>
+ </span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <input type="checkbox" name="select" value="time"/>
+ </td>
+ <td>
+ <span name="accesstime">time</span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/install/static/layouts/default/hbac-details-general.html b/install/static/layouts/default/hbac-details-general.html
new file mode 100755
index 000000000..81b2a4ae6
--- /dev/null
+++ b/install/static/layouts/default/hbac-details-general.html
@@ -0,0 +1,45 @@
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>General</title>
+
+ <link rel="stylesheet" type="text/css" href="jquery-ui.css" />
+ <link rel="stylesheet" type="text/css" href="ipa.css" />
+</head>
+<body>
+<div id="contents">
+ <table style="width: 100%; border: 0 solid black;">
+ <tr>
+ <td style="width: 100px; text-align: right;">
+ Name:
+ </td>
+ <td>
+ <input type="text" name="cn" size="30"/>
+ </td>
+ <td style="text-align: right;">
+ Rule type:
+ <input type="radio" name="accessruletype" value="allow"/>Allow
+ <input type="radio" name="accessruletype" value="deny"/>Deny
+ </td>
+ </tr>
+ <tr>
+ <td style="text-align: right; vertical-align: top;">
+ Description:
+ </td>
+ <td colspan="2">
+ <textarea name="description" rows="5" style="width: 100%;" cols="40"></textarea>
+ </td>
+ </tr>
+ <tr>
+ <td style="text-align: right; vertical-align: top;">
+ Rule status:
+ </td>
+ <td colspan="2">
+ <input type="radio" name="ipaenabledflag" value="TRUE"/>Active
+ <input type="radio" name="ipaenabledflag" value="FALSE"/>Inactive
+ </td>
+ </tr>
+ </table>
+</div>
+</body>
+</html>
diff --git a/install/static/layouts/default/hbac-details-host.html b/install/static/layouts/default/hbac-details-host.html
new file mode 100755
index 000000000..a20e8115a
--- /dev/null
+++ b/install/static/layouts/default/hbac-details-host.html
@@ -0,0 +1,75 @@
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Accessing</title>
+
+ <link rel="stylesheet" type="text/css" href="jquery-ui.css" />
+ <link rel="stylesheet" type="text/css" href="ipa.css" />
+</head>
+<body>
+<div id="contents">
+ Rule applies when access is requested to:
+ <input type="radio" name="hostcategory" value="all"/>Any Host
+ <input type="radio" name="hostcategory" value=""/>Specified Hosts and Groups
+ <br/>
+
+ <div id="hbac-memberhost_host">
+ <table class="search-table">
+ <thead>
+ <tr>
+ <th style="width: 25px;">
+ <input type="checkbox" name="select"/>
+ </th>
+ <th>
+ <span style="float: left;">Host</span>
+ <span name="buttons" style="float: right;">
+ <input type="button" name="remove" value="Remove Hosts"/>
+ <input type="button" name="add" value="Add Hosts"/>
+ </span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <input type="checkbox" name="select" value="host"/>
+ </td>
+ <td>
+ <span name="memberhost_host">host</span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <div id="hbac-memberhost_hostgroup">
+ <table class="search-table">
+ <thead>
+ <tr>
+ <th style="width: 25px;">
+ <input type="checkbox" name="select"/>
+ </th>
+ <th>
+ <span style="float: left;">Host Group</span>
+ <span name="buttons" style="float: right;">
+ <input type="button" name="remove" value="Remove Host Groups"/>
+ <input type="button" name="add" value="Add Host Groups"/>
+ </span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <input type="checkbox" name="select" value="hostgroups"/>
+ </td>
+ <td>
+ <span name="memberhost_hostgroup">hostgroups</span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/install/static/layouts/default/hbac-details-service.html b/install/static/layouts/default/hbac-details-service.html
new file mode 100755
index 000000000..380cb1bb4
--- /dev/null
+++ b/install/static/layouts/default/hbac-details-service.html
@@ -0,0 +1,75 @@
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Via Service</title>
+
+ <link rel="stylesheet" type="text/css" href="jquery-ui.css" />
+ <link rel="stylesheet" type="text/css" href="ipa.css" />
+</head>
+<body>
+<div id="contents">
+ Rule applies when access is requested via:
+ <input type="radio" name="servicecategory" value="all"/>Any Service
+ <input type="radio" name="servicecategory" value=""/>Specified Services and Groups
+ <br/>
+
+ <div id="hbac-memberservice_hbacsvc">
+ <table class="search-table">
+ <thead>
+ <tr>
+ <th style="width: 25px;">
+ <input type="checkbox" name="select"/>
+ </th>
+ <th>
+ <span style="float: left;">Service</span>
+ <span name="buttons" style="float: right;">
+ <input type="button" name="remove" value="Remove Services"/>
+ <input type="button" name="add" value="Add Services"/>
+ </span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <input type="checkbox" name="select" value="service"/>
+ </td>
+ <td>
+ <span name="memberservice_hbacsvc">service</span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <div id="hbac-memberservice_hbacsvcgroup">
+ <table class="search-table">
+ <thead>
+ <tr>
+ <th style="width: 25px;">
+ <input type="checkbox" name="select"/>
+ </th>
+ <th>
+ <span style="float: left;">Service Group</span>
+ <span name="buttons" style="float: right;">
+ <input type="button" name="remove" value="Remove Service Groups"/>
+ <input type="button" name="add" value="Add Service Groups"/>
+ </span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <input type="checkbox" name="select" value="services"/>
+ </td>
+ <td>
+ <span name="memberservice_hbacsvcgroup">services</span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/install/static/layouts/default/hbac-details-sourcehost.html b/install/static/layouts/default/hbac-details-sourcehost.html
new file mode 100755
index 000000000..12e934c0d
--- /dev/null
+++ b/install/static/layouts/default/hbac-details-sourcehost.html
@@ -0,0 +1,75 @@
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>From</title>
+
+ <link rel="stylesheet" type="text/css" href="jquery-ui.css" />
+ <link rel="stylesheet" type="text/css" href="ipa.css" />
+</head>
+<body>
+<div id="contents">
+ Rule applies when access is being initiated from:
+ <input type="radio" name="sourcehostcategory" value="all"/>Any Host
+ <input type="radio" name="sourcehostcategory" value=""/>Specified Hosts and Groups
+ <br/>
+
+ <div id="hbac-sourcehost_host">
+ <table class="search-table">
+ <thead>
+ <tr>
+ <th style="width: 25px;">
+ <input type="checkbox" name="select"/>
+ </th>
+ <th>
+ <span style="float: left;">Host</span>
+ <span name="buttons" style="float: right;">
+ <input type="button" name="remove" value="Remove Hosts"/>
+ <input type="button" name="add" value="Add Hosts"/>
+ </span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <input type="checkbox" name="select" value="host"/>
+ </td>
+ <td>
+ <span name="sourcehost_host">host</span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <div id="hbac-sourcehost_hostgroup">
+ <table class="search-table">
+ <thead>
+ <tr>
+ <th style="width: 25px;">
+ <input type="checkbox" name="select"/>
+ </th>
+ <th>
+ <span style="float: left;">Host Group</span>
+ <span name="buttons" style="float: right;">
+ <input type="button" name="remove" value="Remove Host Groups"/>
+ <input type="button" name="add" value="Add Host Groups"/>
+ </span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <input type="checkbox" name="select" value="hosts"/>
+ </td>
+ <td>
+ <span name="sourcehost_hostgroup">hosts</span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/install/static/layouts/default/hbac-details-user.html b/install/static/layouts/default/hbac-details-user.html
new file mode 100755
index 000000000..ef41b6f8d
--- /dev/null
+++ b/install/static/layouts/default/hbac-details-user.html
@@ -0,0 +1,75 @@
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Who</title>
+
+ <link rel="stylesheet" type="text/css" href="jquery-ui.css" />
+ <link rel="stylesheet" type="text/css" href="ipa.css" />
+</head>
+<body>
+<div id="contents">
+ Rule applies when access is requested by:
+ <input type="radio" name="usercategory" value="all"/>Anyone
+ <input type="radio" name="usercategory" value=""/>Specified Users and Groups
+ <br/>
+
+ <div id="hbac-memberuser_user">
+ <table class="search-table">
+ <thead>
+ <tr>
+ <th style="width: 25px;">
+ <input type="checkbox" name="select"/>
+ </th>
+ <th>
+ <span style="float: left;">User</span>
+ <span name="buttons" style="float: right;">
+ <input type="button" name="remove" value="Remove Users"/>
+ <input type="button" name="add" value="Add Users"/>
+ </span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <input type="checkbox" name="select" value="user"/>
+ </td>
+ <td>
+ <span name="memberuser_user">user</span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <div id="hbac-memberuser_group">
+ <table class="search-table">
+ <thead>
+ <tr>
+ <th style="width: 25px;">
+ <input type="checkbox" name="select"/>
+ </th>
+ <th>
+ <span style="float: left;">User Group</span>
+ <span name="buttons" style="float: right;">
+ <input type="button" name="remove" value="Remove User Groups"/>
+ <input type="button" name="add" value="Add User Groups"/>
+ </span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <input type="checkbox" name="select" value="users"/>
+ </td>
+ <td>
+ <span name="memberuser_group">users</span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/install/static/navigation.js b/install/static/navigation.js
index 72b58ee09..0434f58ca 100644
--- a/install/static/navigation.js
+++ b/install/static/navigation.js
@@ -51,8 +51,10 @@ function nav_create(nls, container, tabclass)
var tabs = $('.' + tabclass);
tabs.tabs({
select: function(event, ui) {
+ var panel = $(ui.panel);
+ var parent = panel.parent();
+ var id = parent.attr('id');
var state = {};
- var id = $(ui.panel).parent().attr('id');
state[id] = ui.index;
nav_push_state(state);
return true;
@@ -87,6 +89,8 @@ function nav_generate_tabs(nls, container, tabclass, depth)
if (tab.children) {
nav_generate_tabs(tab.children, div, tabclass, depth +1 );
} else {
+ div.addClass('entity-container');
+
var entity = ipa_get_entity(tab.name);
entity.label = tab.label;
entity.setup = tab.setup;
diff --git a/install/static/policy.js b/install/static/policy.js
index dd5447718..f0fa0cd9a 100644
--- a/install/static/policy.js
+++ b/install/static/policy.js
@@ -259,7 +259,6 @@ function ipa_records_facet(spec){
that.setup_views(container);
container.attr('title', that.entity_name);
- container.addClass('search-container');
var h2 = $('<h2></h2>',{
text: "Records for DNS Zone:" + that.pkey
@@ -291,15 +290,23 @@ function ipa_records_facet(spec){
//}));
- ipa_make_button('ui-icon-search', IPA.messages.button.find).
- click(function(){load(container)}).appendTo(control_span);
+ ipa_button({
+ 'label': IPA.messages.button.find,
+ 'icon': 'ui-icon-search',
+ 'click': function(){load(container)}
+ }).appendTo(control_span);
- ipa_make_button('ui-icon-plus', IPA.messages.button.add).
- click(add_click).appendTo(control_span);
+ ipa_button({
+ 'label': IPA.messages.button.add,
+ 'icon': 'ui-icon-plus',
+ 'click': add_click
+ }).appendTo(control_span);
- ipa_make_button('ui-icon-trash', IPA.messages.button.delete).
- click(function(){delete_records(records_table);}).
- appendTo(control_span);
+ ipa_button({
+ 'label': IPA.messages.button.delete,
+ 'icon': 'ui-icon-trash',
+ 'click': function(){delete_records(records_table);}
+ }).appendTo(control_span);
div.append('<span class="records-buttons"></span>');
@@ -416,7 +423,7 @@ function ipa_records_facet(spec){
//TODO this is cut and pasted from search, we need to unify
function display(obj_name, data){
- var selector = '.search-container[title=' + obj_name + ']';
+ var selector = '.entity-container[title=' + obj_name + ']';
var thead = $(selector + ' thead');
var tbody = $(selector + ' tbody');
var tfoot = $(selector + ' tfoot');
diff --git a/install/static/search.js b/install/static/search.js
index 62fffbe99..508f6ed40 100644
--- a/install/static/search.js
+++ b/install/static/search.js
@@ -25,14 +25,10 @@ function ipa_search_column(spec) {
spec = spec || {};
- var that = {};
+ spec.init = spec.init || init;
+ spec.setup = spec.setup || setup;
- that.name = spec.name;
- that.label = spec.label || that.name;
- that.facet = spec.facet;
-
- that.init = spec.init || init;
- that.setup = spec.setup || setup;
+ var that = ipa_column_widget(spec);
function init() {
}
@@ -56,6 +52,18 @@ function ipa_search_facet(spec) {
that.columns = [];
that.columns_by_name = {};
+ that.__defineGetter__("entity_name", function(){
+ return that._entity_name;
+ });
+
+ that.__defineSetter__("entity_name", function(entity_name){
+ that._entity_name = entity_name;
+
+ for (var i=0; i<that.columns.length; i++) {
+ that.columns[i].entity_name = entity_name;
+ }
+ });
+
that.get_columns = function() {
return that.columns;
};
@@ -65,12 +73,12 @@ function ipa_search_facet(spec) {
};
that.add_column = function(column) {
+ column.entity_name = that.entity_name;
that.columns.push(column);
that.columns_by_name[column.name] = column;
};
that.create_column = function(spec) {
- spec.facet = that;
var column = ipa_search_column(spec);
that.add_column(column);
return column;
@@ -90,8 +98,10 @@ function ipa_search_facet(spec) {
search_create(that.entity_name, that.columns, container);
- ipa_make_button('ui-icon-plus', IPA.messages.button.add).
- click(function() {
+ ipa_button({
+ 'label': IPA.messages.button.add,
+ 'icon': 'ui-icon-plus',
+ 'click': function() {
var entity = IPA.get_entity(that.entity_name);
if (entity) {
entity.add_dialog.open();
@@ -102,8 +112,8 @@ function ipa_search_facet(spec) {
dialog.open();
return false;
- }).
- appendTo($('.search-controls', container));
+ }
+ }).appendTo($('.search-controls', container));
search_load(container, that.filter);
}
@@ -183,7 +193,6 @@ function search_create(entity_name, columns, container) {
}
container.attr('title', entity_name);
- container.addClass('search-container');
var search_controls = $('<div/>', {
'class': 'search-controls'
@@ -198,11 +207,17 @@ function search_create(entity_name, columns, container) {
'name': 'search-' + entity_name + '-filter'
}).appendTo(search_filter);
- ipa_make_button('ui-icon-search', IPA.messages.button.find).
- click(find_on_click).appendTo(search_filter);
+ ipa_button({
+ 'label': IPA.messages.button.find,
+ 'icon': 'ui-icon-search',
+ 'click': find_on_click
+ }).appendTo(search_filter);
- ipa_make_button('ui-icon-trash',IPA.messages.button.delete).
- click(delete_on_click_outer).appendTo(search_filter);
+ ipa_button({
+ 'label': IPA.messages.button.delete,
+ 'icon': 'ui-icon-trash',
+ 'click': delete_on_click_outer
+ }).appendTo(search_filter);
search_controls.append('<span class="search-buttons"></span>');
@@ -231,20 +246,17 @@ function search_insert_checkbox_th(jobj)
function select_all_on_click() {
var jobj = $(this);
- var checked = null;
- if (jobj.attr('checked')) {
- checked = true;
+ var checked = jobj.is(':checked');
+ if (checked) {
jobj.attr('title', 'Unselect All');
} else {
- checked = false;
jobj.attr('title', 'Select All');
}
- jobj.attr('checked', checked);
- var chks = jobj.closest('.search-container').find('.search-selector');
+ var chks = jobj.closest('.entity-container').find('.search-selector').get();
for (var i = 0; i < chks.length; ++i)
chks[i].checked = checked;
- };
+ }
var checkbox = $('<input />', {
type: 'checkbox',
@@ -307,7 +319,7 @@ function search_load(container, criteria, on_win, on_fail)
function search_generate_tr(thead, tbody, entry_attrs)
{
- var obj_name = tbody.closest('.search-container').attr('title');
+ var obj_name = tbody.closest('.entity-container').attr('title');
var pkey = IPA.metadata[obj_name].primary_key;
var pkey_value = entry_attrs[pkey];
@@ -368,7 +380,7 @@ var _search_a_pkey_template = '<a href="jslink" class="search-a-pkey">V</a>';
function search_generate_td(tr, attr, value, entry_attrs)
{
- var obj_name = tr.closest('.search-container').attr('title');
+ var obj_name = tr.closest('.entity-container').attr('title');
var param_info = ipa_get_param_info(obj_name, attr);
if (param_info && param_info['primary_key'])
@@ -379,7 +391,7 @@ function search_generate_td(tr, attr, value, entry_attrs)
function search_display(obj_name, data)
{
- var selector = '.search-container[title=' + obj_name + ']';
+ var selector = '.entity-container[title=' + obj_name + ']';
var thead = $(selector + ' thead');
var tbody = $(selector + ' tbody');
var tfoot = $(selector + ' tfoot');
diff --git a/install/static/service.js b/install/static/service.js
index 21b2d0b92..1b467cb59 100644
--- a/install/static/service.js
+++ b/install/static/service.js
@@ -126,36 +126,45 @@ function service_add_krbprincipalname(add_dialog, mode) {
}
ipa_entity_set_association_definition('service', {
- 'host': { method: 'add_host' }
+ 'host': { add_method: 'add_host', delete_host: 'remove_host' }
});
-function service_krbprincipalname_setup(container, dl, section) {
+function service_krbprincipalname_setup(container) {
// skip krbprincipalname
}
-function service_krbprincipalname_load(container, dt, result) {
+function service_krbprincipalname_load(container, result) {
// skip krbprincipalname
}
-function service_service_load(container, dt, result) {
+function service_service_load(container, result) {
+ var dt = $('dt[title='+this.name+']', container);
+ if (!dt.length) return;
+
var krbprincipalname = result['krbprincipalname'][0];
var service = krbprincipalname.replace(/\/.*$/, '');
var dd = ipa_create_first_dd(this.name, service);
dt.after(dd);
}
-function service_host_load(container, dt, result) {
+function service_host_load(container, result) {
+ var dt = $('dt[title='+this.name+']', container);
+ if (!dt.length) return;
+
var krbprincipalname = result['krbprincipalname'][0];
var host = krbprincipalname.replace(/^.*\//, '').replace(/@.*$/, '');
var dd = ipa_create_first_dd(this.name, host);
dt.after(dd);
}
-function service_provisioning_status_load(container, dt, result) {
+function service_provisioning_status_load(container, result) {
// skip provisioning_status
}
-function service_usercertificate_load(container, dt, result) {
+function service_usercertificate_load(container, result) {
+
+ var dt = $('dt[title='+this.name+']', container);
+ if (!dt.length) return;
var panel = certificate_status_panel({
'entity_type': 'service',
diff --git a/install/static/test/all_tests.html b/install/static/test/all_tests.html
index 50c5155dc..64412b01b 100644
--- a/install/static/test/all_tests.html
+++ b/install/static/test/all_tests.html
@@ -8,6 +8,7 @@
<script type="text/javascript" src="../jquery.ba-bbq.js"></script>
<script type="text/javascript" src="../jquery-ui.js"></script>
<script type="text/javascript" src="../ipa.js"></script>
+ <script type="text/javascript" src="../widget.js"></script>
<script type="text/javascript" src="../details.js"></script>
<script type="text/javascript" src="../search.js"></script>
<script type="text/javascript" src="../add.js"></script>
diff --git a/install/static/test/association_tests.js b/install/static/test/association_tests.js
index 05e43ce4a..9f49abf73 100644
--- a/install/static/test/association_tests.js
+++ b/install/static/test/association_tests.js
@@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-test("Testing serial_associate().", function() {
+test("Testing serial_associator().", function() {
expect(10);
@@ -26,25 +26,25 @@ test("Testing serial_associate().", function() {
var counter = 0;
- var form = {
+ var params = {
method: "add_member",
pkey: "test",
- oneObj: "user",
- manyObj: "group"
+ entity_name: "user",
+ other_entity: "group"
};
- var manyObjPkeys = ['user1', 'user2', 'user3'];
+ params.values = ['user1', 'user2', 'user3'];
ipa_cmd = function(name, args, options, win_callback, fail_callback, objname) {
counter++;
equals(
- name, form.method,
+ name, params.method,
"Checking ipa_cmd() parameter: method"
);
equals(
- objname, form.manyObj,
+ objname, params.other_entity,
"Checking ipa_cmd() parameter: object name"
);
@@ -58,17 +58,17 @@ test("Testing serial_associate().", function() {
return 0;
};
- var on_success = function() {
+ params.on_success = function() {
ok(true, "on_success() is invoked.");
};
- var associator = serial_associate(form, manyObjPkeys, on_success);
- //associator.associateNext();
+ var associator = serial_associator(params);
+ associator.execute();
ipa_cmd = orig_ipa_cmd;
});
-test("Testing BulkAssociator().", function() {
+test("Testing bulk_associator().", function() {
expect(5);
@@ -76,36 +76,36 @@ test("Testing BulkAssociator().", function() {
var counter = 0;
- var form = {
+ var params = {
method: "add_member",
pkey: "test",
- oneObj: "user",
- manyObj: "group"
+ entity_name: "user",
+ other_entity: "group"
};
- var manyObjPkeys = ['user1', 'user2', 'user3'];
+ params.values = ['user1', 'user2', 'user3'];
ipa_cmd = function(name, args, options, win_callback, fail_callback, objname) {
counter++;
equals(
- name, form.method,
+ name, params.method,
"Checking ipa_cmd() parameter: method"
);
equals(
- objname, form.oneObj,
+ objname, params.entity_name,
"Checking ipa_cmd() parameter: object name"
);
equals(
- args[0], form.pkey,
+ args[0], params.pkey,
"Checking ipa_cmd() parameter: primary key"
);
equals(
- options[form.manyObj], "user1,user2,user3",
- "Checking ipa_cmd() parameter: options[\""+form.manyObj+"\"]"
+ options[params.other_entity], "user1,user2,user3",
+ "Checking ipa_cmd() parameter: options[\""+params.other_entity+"\"]"
);
var response = {};
@@ -113,12 +113,12 @@ test("Testing BulkAssociator().", function() {
return 0;
};
- var on_success = function() {
+ params.on_success = function() {
ok(true, "on_success() is invoked.");
};
- var associator = bulk_associate(form, manyObjPkeys, on_success);
- //associator.associateNext();
+ var associator = bulk_associator(params);
+ associator.execute();
ipa_cmd = orig_ipa_cmd;
});
diff --git a/install/static/test/details_tests.html b/install/static/test/details_tests.html
index e96fa4b72..3cb20c562 100644
--- a/install/static/test/details_tests.html
+++ b/install/static/test/details_tests.html
@@ -8,6 +8,7 @@
<script type="text/javascript" src="../jquery.ba-bbq.js"></script>
<script type="text/javascript" src="../jquery-ui.js"></script>
<script type="text/javascript" src="../ipa.js"></script>
+ <script type="text/javascript" src="../widget.js"></script>
<script type="text/javascript" src="../details.js"></script>
<script type="text/javascript" src="../entity.js"></script>
diff --git a/install/static/test/details_tests.js b/install/static/test/details_tests.js
index 4a60216ef..8482f6df0 100644
--- a/install/static/test/details_tests.js
+++ b/install/static/test/details_tests.js
@@ -19,45 +19,96 @@
*/
-test("Testing ipa_details_create().", function() {
+test("Testing ipa_details_section.setup().", function() {
- var name = 'NAMENAMENAME';
- var identity = 'IDIDID';
+ IPA.ajax_options.async = false;
+
+ IPA.init(
+ "data",
+ true,
+ function(data, text_status, xhr) {
+ ok(true, "ipa_init() succeeded.");
+ },
+ function(xhr, text_status, error_thrown) {
+ ok(false, "ipa_init() failed: "+error_thrown);
+ }
+ );
+
+ var result = {};
- var section = ipa_stanza({name:identity, label:name}).
+ var section = ipa_stanza({name:'IDIDID', label:'NAMENAMENAME'}).
input({name:'cn', label:'Entity Name'}).
input({name:'description', label:'Description'}).
input({name:'number', label:'Entity ID'});
- var details = section.fields;
- var parent = $("<div/>");
- var container = $("<div title='entity'/>");
- parent.append(container);
- ipa_details_section_setup(parent,container, section);
+ var fields = section.fields;
+ var container = $("<div/>");
+ section.setup(container, result);
- ok(parent.find('hr').length);
+ var dl = container.find('dl');
- var h2= parent.find('h2');
- ok(h2.length);
- ok(h2[0].innerHTML.indexOf(name) > 1,"find name in html");
+ same(
+ dl.length, 1,
+ 'Checking dl tag'
+ );
+
+ same(
+ dl.attr('id'), section.name,
+ 'Checking section name'
+ );
+
+ var dts = $('dt', dl);
+ same(
+ dts.length, fields.length, // each field generates dt & dd
+ 'Checking number of children'
+ );
+
+ for (var i=0; i<fields.length; i++) {
+ var dt = dts.get(i);
+ same(
+ dt.title, fields[i].name,
+ 'Checking field '+i+'\'s title'
+ );
+
+ same(
+ dt.innerHTML, fields[i].label+':',
+ 'Checking field '+i+'\'s label'
+ );
+ }
+});
- var dl = parent.find('dl');
- ok(dl.length);
- same(dl[0].children.length,3,"children tag count");
- same(dl[0].id, identity,"identity");
- same(details[0].name, dl[0].children[0].title,"name");
- var d = dl[0].children[0].innerHTML;
- same(details[0].label+":",d);
- same(details[2].name,dl[0].children[2].title);
- d = dl[0].children[2].innerHTML;
- same(details[2].label+":" ,d);
-});
+test("Testing details lifecycle: create, save ().", function(){
+ IPA.ajax_options.async = false;
-test("Testing details lifecycle:setup, load, save ().", function(){
+ IPA.init(
+ "data",
+ true,
+ function(data, text_status, xhr) {
+ ok(true, "ipa_init() succeeded.");
+ },
+ function(xhr, text_status, error_thrown) {
+ ok(false, "ipa_init() failed: "+error_thrown);
+ }
+ );
+
+ var result = {};
+
+ ipa_cmd(
+ 'user_show',
+ ['kfrog'],
+ {},
+ function(data, text_status, xhr) {
+ result = data.result.result;
+ ok(true, "ipa_cmd() succeeded.");
+ },
+ function(xhr, text_status, error_thrown) {
+ ok(false, "ipa_cmd() failed: "+error_thrown);
+ }
+ );
var setup_status_called = false;
var save_password_called= false;
@@ -82,6 +133,7 @@ test("Testing details lifecycle:setup, load, save ().", function(){
function setup_st(){
}
+
var container = $("<div/>");
var obj_name = 'user';
ipa_entity_set_details_definition(obj_name, [
@@ -116,46 +168,42 @@ test("Testing details lifecycle:setup, load, save ().", function(){
var entity = ipa_get_entity(obj_name);
var facet = entity.get_facet('details');
- var sections = facet.get_sections();
- ipa_details_create(container, sections);
+ facet.create(container, result);
var contact = container.find('dl#contact.entryattrs');
- ok(contact);
- var identity = container.find('dl#identity.entryattrs');
- ok(identity);
- var dts= identity.find('dt');
- ok(dts);
- same(6, dts.length);
- same('initials',dts[5].title);
- //TODO extract into Fixture
- IPA.ajax_options.async = false;
- $.ajaxSetup(IPA.ajax_options);
- IPA.json_url = './data';
- IPA.use_static_files = true;
-
- container.attr('id','user');
-
- ok (setup_status_called , 'setup status called');
+ ok(
+ contact,
+ 'dl tag for contact is created'
+ );
+ var identity = container.find('dl#identity.entryattrs');
- ipa_details_load(container,
- 'kfrog',
- function(){load_success_called = true},
- function(){load_failure_called = true});
+ ok(
+ identity,
+ 'dl tag for identity is created'
+ );
- ok (load_success_called,'load success called');
- ok (!load_failure_called,'load failure not called');
+ var dts= identity.find('dt');
+ same(
+ dts.length, 6,
+ 'Checking dt tags for identity'
+ );
- ok (load_manager_called, 'load manager called');
+ same(
+ dts[5].title, facet.get_sections()[0].get_fields()[5].name,
+ 'Checking dt title'
+ );
+ container.attr('id','user');
- ipa_details_load(container,
- 'kfrog',
- function(){load_success_called = true},
- function(){load_failure_called = true});
+ ok (
+ setup_status_called,
+ 'Setup status called'
+ );
+ ok (load_manager_called, 'load manager called');
ipa_details_update(container,
'kfrog',
@@ -183,34 +231,3 @@ test("Testing _ipa_create_text_input().", function(){
same(text[0].value,value );
same(text[0].type,"text" );
});
-
-
-test("Testing ipa_details_section_setup()",function(){
-
- var section = ipa_stanza({name: 'IDIDID', label: 'NAMENAMENAME'}).
- input({name:'cn', label:'Entity Name'}).
- input({name:'description', label:'Description'}).
- input({name:'number', label:'Entity ID'});
- var fields = section.fields;
- var container = $("<div title='entity'/>");
- var details = $("<div/>");
- container.append(details);
-
- ipa_details_section_setup(container, details, section);
-
- ok(container.find('hr'));
-
- var h2= container.find('h2');
- ok(h2);
- ok(h2[0].innerHTML.indexOf(section.label) > 1,"find name in html");
-
- var dl = container.find('dl');
- ok(dl);
- same(dl[0].children.length,3);
- same(dl[0].id, section.name);
- same(dl[0].children[0].title, fields[0].name);
- same(dl[0].children[0].innerHTML, fields[0].label+":");
- same(dl[0].children[2].title, fields[2].name);
- same(dl[0].children[2].innerHTML, fields[2].label+":");
-
-});
diff --git a/install/static/test/entity_tests.html b/install/static/test/entity_tests.html
index 0f7962952..cd6b64095 100644
--- a/install/static/test/entity_tests.html
+++ b/install/static/test/entity_tests.html
@@ -7,6 +7,7 @@
<script type="text/javascript" src="../jquery.js"></script>
<script type="text/javascript" src="../jquery.ba-bbq.js"></script>
<script type="text/javascript" src="../ipa.js"></script>
+ <script type="text/javascript" src="../widget.js"></script>
<script type="text/javascript" src="../details.js"></script>
<script type="text/javascript" src="../search.js"></script>
<script type="text/javascript" src="../add.js"></script>
diff --git a/install/static/test/entity_tests.js b/install/static/test/entity_tests.js
index cc43b8798..08fc3111d 100644
--- a/install/static/test/entity_tests.js
+++ b/install/static/test/entity_tests.js
@@ -170,7 +170,7 @@ test('Testing ipa_entity_quick_links().', function() {
var container = $('<div/>', {
title: obj_name,
- class: 'search-container'
+ class: 'entity-container'
});
var search_table = $('<table/>', {
diff --git a/install/static/test/navigation_tests.html b/install/static/test/navigation_tests.html
index fa911d6e6..16d095aca 100644
--- a/install/static/test/navigation_tests.html
+++ b/install/static/test/navigation_tests.html
@@ -7,6 +7,8 @@
<script type="text/javascript" src="../jquery.js"></script>
<script type="text/javascript" src="../jquery.ba-bbq.js"></script>
<script type="text/javascript" src="../jquery-ui.js"></script>
+ <script type="text/javascript" src="../ipa.js"></script>
+ <script type="text/javascript" src="../entity.js"></script>
<script type="text/javascript" src="../navigation.js"></script>
<script type="text/javascript" src="navigation_tests.js"></script>
</head>
diff --git a/install/static/user.js b/install/static/user.js
index 5645967d2..1b6054d7e 100644
--- a/install/static/user.js
+++ b/install/static/user.js
@@ -151,8 +151,10 @@ function on_lock_win(data, textStatus, xhr)
/* ATTRIBUTE CALLBACKS */
var toggle_temp = 'S <a href="jslink" onclick="return (toggle_on_click(this))" title="S">Toggle</a>';
-function user_status_load(container, dt, result)
-{
+function user_status_load(container, result) {
+ var dt = $('dt[title='+this.name+']', container);
+ if (!dt.length) return;
+
var memberof = result['memberof'];
var dd;
@@ -223,8 +225,10 @@ function resetpwd_on_click(){
return false;
}
-function user_password_load(container, dt, result)
-{
+function user_password_load(container, result) {
+ var dt = $('dt[title='+this.name+']', container);
+ if (!dt.length) return;
+
dt.after(ipa_create_first_dd(
this.name,
$('<a/>',{
@@ -245,8 +249,10 @@ var states = [
'PA', 'PR', 'RI', 'SC', 'SD', 'TN', 'TX', 'UT', 'VT', 'VI', 'VA',
'WA', 'WV', 'WI', 'WY', ''
];
-function user_state_load(container, dt, result)
-{
+function user_state_load(container, result) {
+ var dt = $('dt[title='+this.name+']', container);
+ if (!dt.length) return;
+
var next = dt.next();
next.css('clear', 'none');
next.css('width', '70px');
diff --git a/install/static/widget.js b/install/static/widget.js
new file mode 100755
index 000000000..bf893e042
--- /dev/null
+++ b/install/static/widget.js
@@ -0,0 +1,473 @@
+/* Authors:
+ * Endi Sukma Dewata <edewata@redhat.com>
+ *
+ * Copyright (C) 2010 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; version 2 only
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* REQUIRES: ipa.js */
+
+function ipa_widget(spec) {
+
+ spec = spec || {};
+
+ var that = {};
+
+ that.id = spec.id;
+ that.name = spec.name;
+ that.label = spec.label;
+ that.read_only = spec.read_only;
+ that._entity_name = spec.entity_name;
+
+ that.create = spec.create || create;
+ that.setup = spec.setup || setup;
+ that.load = spec.load || load;
+ that.save = spec.save || save;
+
+ that.super = function(name) {
+ var method = that[name];
+ return function () {
+ return method.apply(that, arguments);
+ };
+ };
+
+ that.__defineGetter__("entity_name", function(){
+ return that._entity_name;
+ });
+
+ that.__defineSetter__("entity_name", function(entity_name){
+ that._entity_name = entity_name;
+ });
+
+ function create(container) {
+ }
+
+ function setup(container) {
+ }
+
+ function load(container, result) {
+ }
+
+ function save(container) {
+ return [];
+ }
+
+ return that;
+}
+
+function ipa_text_widget(spec) {
+
+ spec = spec || {};
+
+ spec.setup = spec.setup || setup;
+ spec.load = spec.load || load;
+ spec.save = spec.save || save;
+
+ var that = ipa_widget(spec);
+
+ function setup(container) {
+ }
+
+ function load(container, result) {
+ that.value = result[that.name] || '';
+ var input = $('input[name="'+that.name+'"]', container);
+
+ var param_info = ipa_get_param_info(that.entity_name, that.name);
+ if (param_info.primary_key) {
+ input.replaceWith($('<label/>', { 'html': that.value.toString() }));
+
+ } else {
+ input.val(that.value);
+ }
+ }
+
+ function save(container) {
+ var values = [];
+
+ if (that.value) {
+ values.push(that.value);
+
+ } else {
+ var input = $('input[name="'+that.name+'"]', container);
+ values.push(input.val());
+ }
+
+ return values;
+ }
+
+ return that;
+}
+
+function ipa_radio_widget(spec) {
+
+ spec = spec || {};
+
+ spec.setup = spec.setup || setup;
+ spec.load = spec.load || load;
+ spec.save = spec.save || save;
+
+ var that = ipa_widget(spec);
+
+ function setup(container) {
+ }
+
+ function load(container, result) {
+ var value = result[that.name] || '';
+ $('input[name="'+that.name+'"][value="'+value+'"]', container).attr('checked', 'checked');
+ }
+
+ function save(container) {
+ var values = [];
+
+ var value = $('input[name="'+that.name+'"]:checked', container).val();
+ values.push(value);
+
+ return values;
+ }
+
+ return that;
+}
+
+function ipa_textarea_widget(spec) {
+
+ spec = spec || {};
+
+ spec.setup = spec.setup || setup;
+ spec.load = spec.load || load;
+ spec.save = spec.save || save;
+
+ var that = ipa_widget(spec);
+
+ function setup(container) {
+ }
+
+ function load(container, result) {
+ var value = result[that.name] || '';
+ $('textarea[name="'+that.name+'"]', container).val(value);
+ }
+
+ function save(container) {
+ var values = [];
+
+ var value = $('textarea[name="'+that.name+'"]', container).val();
+ values.push(value);
+
+ return values;
+ }
+
+ return that;
+}
+
+function ipa_button_widget(spec) {
+
+ spec = spec || {};
+
+ spec.setup = spec.setup || setup;
+ spec.load = spec.load || load;
+ spec.save = spec.save || save;
+
+ var that = ipa_widget(spec);
+
+ that.click = spec.click;
+
+ function setup(container) {
+ var input = $('[name="'+that.name+'"]', container);
+ input.replaceWith(ipa_button({ 'label': that.label, 'click': that.click }));
+ }
+
+ function load(container, result) {
+ }
+
+ function save(container) {
+ var values = [];
+ return values;
+ }
+
+ return that;
+}
+
+function ipa_column_widget(spec) {
+
+ spec = spec || {};
+
+ var that = ipa_widget(spec);
+
+ that.primary_key = spec.primary_key;
+ that.link = spec.link;
+
+ return that;
+}
+
+function ipa_table_widget(spec) {
+
+ spec = spec || {};
+
+ spec.create = spec.create || create;
+ spec.setup = spec.setup || setup;
+ spec.load = spec.load || load;
+ spec.save = spec.save || save;
+
+ var that = ipa_widget(spec);
+
+ that.add = spec.add;
+ that.remove = spec.remove;
+
+ that.columns = [];
+ that.columns_by_name = {};
+
+ that.get_columns = function() {
+ return that.columns;
+ };
+
+ that.get_column = function(name) {
+ return that.columns_by_name[name];
+ };
+
+ that.add_column = function(column) {
+ column.entity_name = that.entity_name;
+ that.columns.push(column);
+ that.columns_by_name[column.name] = column;
+ };
+
+ that.create_column = function(spec) {
+ var column = ipa_column_widget(spec);
+ that.add_column(column);
+ return column;
+ };
+
+ function create(container) {
+
+ var div = $('#'+that.id, container);
+ if (div.children().length) {
+ // widget loaded from template
+ return;
+ }
+
+ div.empty();
+
+ var table = $('<table/>', {
+ 'class': 'search-table'
+ }).appendTo(div);
+
+ var thead = $('<thead/>').appendTo(table);
+
+ var tr = $('<tr/>').appendTo(thead);
+
+ var th = $('<th/>', {
+ 'style': 'width: 25px;'
+ }).appendTo(tr);
+
+ $('<input/>', {
+ 'type': 'checkbox',
+ 'name': 'select'
+ }).appendTo(th);
+
+ for (var i=0; i<that.columns.length; i++) {
+ th = $('<th/>').appendTo(tr);
+
+ $('<span/>', {
+ 'style': 'float: left;',
+ 'html': that.columns[i].label
+ }).appendTo(th);
+
+ if (i == that.columns.length-1) {
+ $('<span/>', {
+ 'name': 'buttons',
+ 'style': 'float: right;'
+ }).appendTo(th);
+ }
+ }
+
+ var tbody = $('<tbody/>').appendTo(table);
+
+ tr = $('<tr/>').appendTo(tbody);
+
+ var td = $('<td/>').appendTo(tr);
+
+ $('<input/>', {
+ 'type': 'checkbox',
+ 'name': 'select',
+ 'value': 'user'
+ }).appendTo(td);
+
+ for (var i=0; i<that.columns.length; i++) {
+ td = $('<td/>').appendTo(tr);
+
+ $('<span/>', {
+ 'name': that.columns[i].name
+ }).appendTo(td);
+ }
+ }
+
+ function setup(container) {
+ var div = $('#'+that.id, container);
+ that.table = $('table', div);
+ that.thead = $('thead', that.table);
+ that.tbody = $('tbody', that.table);
+
+ var select_all_checkbox = $('input[name=select]', that.thead);
+ select_all_checkbox.attr('title', 'Select All');
+
+ select_all_checkbox.click(function() {
+ var checked = select_all_checkbox.is(':checked');
+ select_all_checkbox.attr('title', checked ? 'Unselect All' : 'Select All');
+ var checkboxes = $('input[name=select]', that.tbody).get();
+ for (var i=0; i<checkboxes.length; i++) {
+ checkboxes[i].checked = checked;
+ }
+ });
+
+ var button = $('input[name=remove]', that.table);
+ button.replaceWith(ipa_button({
+ 'label': button.val(),
+ 'icon': 'ui-icon-trash',
+ 'click': function() { that.remove(container); }
+ }));
+
+ button = $('input[name=add]', that.table);
+ button.replaceWith(ipa_button({
+ 'label': button.val(),
+ 'icon': 'ui-icon-plus',
+ 'click': function() { that.add(container) }
+ }));
+
+ that.row = that.tbody.children().first();
+ that.row.detach();
+ }
+
+ function load(container, result) {
+
+ that.tbody.empty();
+
+ var values = result[that.name];
+ if (!values) return;
+
+ for (var i=0; i<values.length; i++) {
+ var record = that.get_record(result, i);
+ that.add_row(container, record);
+ }
+ }
+
+ function save(container) {
+ var values = [];
+
+ $('input[name="select"]', that.tbody).each(function() {
+ values.push($(this).val());
+ });
+
+ return values;
+ }
+
+ that.get_selected_values = function(container) {
+ var values = [];
+
+ $('input[name="select"]:checked', that.tbody).each(function() {
+ values.push($(this).val());
+ });
+
+ return values;
+ };
+
+ that.get_record = function(result, index) {
+ var record = {};
+ for (var i=0; i<that.columns.length; i++){
+ var name = that.columns[i].name;
+ record[name] = result[name][index];
+ }
+ return record;
+ };
+
+ that.add_row = function(container, record) {
+
+ var tr = that.row.clone();
+ tr.appendTo(that.tbody);
+
+ for (var i=0; i<that.columns.length; i++){
+ var column = that.columns[i];
+
+ var name = column.name;
+ var value = record[name];
+
+ var span = $('span[name="'+name+'"]', tr);
+ span.html(value);
+
+ if (column.primary_key) {
+ // set checkbox value
+ $('input[name="select"]', tr).val(value);
+ }
+
+ if (column.primary_key && column.link) {
+ // wrap value with a link
+ var link = $('<a/>', {
+ 'click': function (value) {
+ return function() {
+ var state = {};
+ state[that.other_entity + '-facet'] = 'details';
+ state[that.other_entity + '-pkey'] = value;
+ //Before this will work, we need to set the tab one level up
+ //for example:
+ //state['identity'] = 0;
+ //but we have no way of getting the index.
+
+ $.bbq.pushState(state);
+ return false;
+ }
+ }(value)
+ });
+ span.before(link);
+ link.append(span);
+ }
+ }
+ };
+
+ that.refresh = function(container) {
+
+ function on_success(data, text_status, xhr) {
+
+ that.tbody.empty();
+
+ var column_name = that.columns[0].name;
+ var values = data.result.result[column_name];
+ //TODO, this is masking an error where the wrong
+ //direction association is presented upon page reload.
+ //if the values is unset, it is because
+ //form.associationColumns[0] doesn't exist in the results
+ if (!values) return;
+
+ for (var i = 0; i<values.length; i++){
+ var record = that.get_record(data.result.result, i);
+ that.add_row(container, record);
+ }
+ }
+
+ function on_error(xhr, text_status, error_thrown) {
+ var div = $('#'+that.id, container).empty();
+ div.append('<p>Error: '+error_thrown.name+'</p>');
+ div.append('<p>'+error_thrown.title+'</p>');
+ div.append('<p>'+error_thrown.message+'</p>');
+ }
+
+ var pkey = $.bbq.getState(that.entity_name + '-pkey', true) || '';
+ ipa_cmd('show', [pkey], {}, on_success, on_error, that.entity_name);
+ };
+
+ if (spec.columns) {
+ for (var i=0; i<spec.columns; i++) {
+ that.create_column(spec.columns[i]);
+ }
+ }
+ return that;
+} \ No newline at end of file
diff --git a/ipa.spec.in b/ipa.spec.in
index ee5db47ac..92fb838df 100644
--- a/ipa.spec.in
+++ b/ipa.spec.in
@@ -393,6 +393,9 @@ fi
%{_usr}/share/ipa/static/*.png
%{_usr}/share/ipa/static/*.css
%{_usr}/share/ipa/static/*.js
+%dir %{_usr}/share/ipa/static/layouts
+%dir %{_usr}/share/ipa/static/layouts/default
+%{_usr}/share/ipa/static/layouts/default/*.html
%dir %{_sysconfdir}/ipa
%dir %{_sysconfdir}/ipa/html
%config(noreplace) %{_sysconfdir}/ipa/html/ssbrowser.html