diff options
author | Rob Crittenden <rcritten@redhat.com> | 2010-11-04 15:13:08 -0400 |
---|---|---|
committer | Rob Crittenden <rcritten@redhat.com> | 2010-11-04 15:13:08 -0400 |
commit | db758c92cd4865ae02c8da357ce5e850a060a4ad (patch) | |
tree | 96bd6a549725d0a5b78f4fc54d752cf94a5a9894 | |
parent | 7b296f2623610b0820a5553e2c570c6b3428c861 (diff) | |
parent | d99ebc0f3798c84e612c79c43eb85c31b20ab1ce (diff) | |
download | freeipa-db758c92cd4865ae02c8da357ce5e850a060a4ad.tar.gz freeipa-db758c92cd4865ae02c8da357ce5e850a060a4ad.tar.xz freeipa-db758c92cd4865ae02c8da357ce5e850a060a4ad.zip |
Merge branch 'master' of ssh://rcritten@git.fedorahosted.org/git/freeipa
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:"− "+name - })); + details.append($('<h2/>',{ + click: function(){_h2_on_click(this)}, + html:"− "+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 |