/*jsl:import ipa.js */ /* Authors: * Pavel Zuna * Adam Young * Endi S. Dewata * * 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, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /* IPA Object Details - populating definiton lists from entry data */ /* REQUIRES: ipa.js */ IPA.expand_icon = 'ui-icon-minus'; IPA.collapse_icon = 'ui-icon-plus'; IPA.is_field_writable = function(rights){ if (!rights){ alert('no right'); } return rights.indexOf('w') > -1; }; IPA.details_field = function (spec) { spec = spec || {}; var that = IPA.widget(spec); that.load = spec.load || load; that.save = spec.save || save; function load(record) { that.record = record; that.values = record[that.name]; that.reset(); var param_info = IPA.get_param_info(that.entity_name, that.name); if (param_info) { if (param_info['primary_key']) { that.read_only = true; } if ('no_update' in param_info['flags']) { that.read_only = true; } } } that.update = function() { if (!that.record) return; /* remove all
tags i.e. all attribute values */ $('dd', that.container).remove(); var multivalue = false; var hint_span = null; var dd; 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; var hint = param_info['doc']; if (hint){ hint_span = $('',{ 'class': 'attrhint', 'html': 'Hint: ' + hint}); } } var rights = 'rsc'; if (that.record.attributelevelrights){ rights = that.record.attributelevelrights[this.name] || rights ; } if (that.values) { /* Too much logic currently assumes an array. This is true everywhere but ACIs. */ if (!(that.values instanceof Array)){ that.values = [that.values]; } dd = IPA.create_first_dd(that.name); dd.append(that.create_value(that.values[0], hint_span, rights, 0)); dd.appendTo(that.container); for (var i = 1; i < that.values.length; ++i) { dd = IPA.create_other_dd(that.name); dd.append(that.create_value(that.values[i], hint_span, rights, i)); dd.appendTo(that.container); } if (multivalue && IPA.is_field_writable(rights) ) { dd = IPA.create_other_dd(that.name); dd.append(IPA.details_field_create_add_link.call(that, that.name, rights, that.values.length)); dd.appendTo(that.container); } } else { if (multivalue && IPA.is_field_writable(rights)) { dd = IPA.create_first_dd(that.name); dd.append(IPA.details_field_create_add_link.call(that, that.name, rights, 0)); dd.appendTo(that.container); } else { dd = IPA.create_first_dd(that.name); dd.append(that.create_value('', hint_span, rights, 0)); dd.appendTo(that.container); } } }; /* creates a Remove link for deleting attribute values */ function create_remove_link(attr, param_info){ function remove_on_click(obj){ var jobj = $(obj); var attr = jobj.attr('title'); var par = jobj.parent(); var input = par.find('input'); if (input.is('.strikethrough')){ input.removeClass('strikethrough'); jobj.text("Remove"); }else{ input.addClass('strikethrough'); jobj.text("Undo"); } return (false); } if (param_info){ /* check if the param is required or of the Password type * if it is, then we don't want people to be able to remove it */ if ((param_info['required']) || (param_info['class'] == 'Password')){ return (''); } } return $('',{ href:"jslink", click: function (){return (remove_on_click(this));}, title: attr, text: 'Remove'}); } /* create an HTML element for displaying/editing an attribute * arguments: * attr - LDAP attribute name * value - the attributes value */ that.create_value = function(value, hint, rights, index) { // if field is primary key or non-writable, return a label var label = $('", { html:"undo", "class":"ui-state-highlight ui-corner-all undo", style:"display:none", click: function(){ var previous_value = that.values || ''; if (index >= previous_value.length){ previous_value = ''; }else{ previous_value= previous_value[index]; } this.previousElementSibling.value = previous_value; this.style.display = "none"; var error_link = this.nextElementSibling; validate_input(previous_value, param_info,error_link); } })); span.append($("", { html:"Does not match pattern", "class":"ui-state-error ui-corner-all", style:"display:none" })); return span; }; function save() { var values = []; $('dd', that.container).each(function () { var input = $('input', $(this)); if (!input.length) return; if (input.is('.strikethrough')) return; var value = $.trim(input.val()); if (!value) value = ''; values.push(value); }); return values; } return that; }; IPA.details_section = function (spec){ spec = spec || {}; var that = {}; that.name = spec.name || ''; that.label = spec.label || ''; that.template = spec.template; that._entity_name = spec.entity_name; that.fields = []; that.fields_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', { 'name': field.name }).appendTo(container); field.create(span); } }; that.setup = function(container) { that.container = container; if (that.template) return; var fields = that.fields; for (var i = 0; i < fields.length; ++i) { var field = fields[i]; var span = $('span[name='+field.name+']', this.container).first(); field.setup(span); } }; that.load = function(record) { that.record = record; var fields = that.fields; if (that.template) { var template = IPA.get_template(that.template); this.container.load( template, function(data, text_status, xhr) { for (var i = 0; i < fields.length; ++i) { var field = fields[i]; var span = $('span[name='+field.name+']', this.container).first(); field.setup(span); field.load(record); } } ); return; } for (var j=0; j tag. * The attribute name is defined inside a
tag. The attribute * value is defined using a
tag inside a tag. If the * attribute has multiple values the content inside will * be duplicated to display each value. * * Example: *
* *
First Name:
* *
*
* *
Telephone Number:
* *
*
*
* *
*/ IPA.details_list_section = function (spec){ spec = spec || {}; var that = IPA.details_section(spec); that.create = function(container) { // do not call section_create() here if (that.template) return; var dl = $('
', { 'id': that.name, 'class': 'entryattrs' }).appendTo(container); var fields = that.fields; for (var i = 0; i < fields.length; ++i) { var field = fields[i]; var label = field.label || ''; // no need to get i18n label from metadata // because it's already done by field.init() $('
', { html: label+':', title: label }).appendTo(dl); var span = $('', { 'name': field.name }).appendTo(dl); field.create(span); } }; return that; }; /* shorthand notation used for declarative definitions of details pages */ IPA.stanza = function (spec) { spec = spec || {}; var that = IPA.details_list_section(spec); // This is to allow declarative style programming for details that.input = function(spec) { that.create_field(spec); return that; }; that.custom_input = function(input) { that.add_field(input); return that; }; return that; }; IPA.details_facet = function (spec) { spec = spec || {}; spec.name = spec.name || 'details'; var that = IPA.facet(spec); that.label = ( IPA.messages && IPA.messages.facets && IPA.messages.facets.details) || spec.label; that.is_dirty = spec.is_dirty || is_dirty; that.create = spec.create || create; that.setup = spec.setup || setup; that.load = spec.load || load; that.update = spec.update || IPA.details_update; that.reset = spec.reset || reset; that.refresh = spec.refresh || IPA.details_refresh; that.sections = []; 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'; } else { return ''; } }; function create(container) { container.attr('title', that.entity_name); $('

',{ html: ""+that.entity_name + ' Settings' }).append(IPA.create_network_spinner()). appendTo(container); var details = $('
', { 'class': 'content' }).appendTo(container); var action_panel = that.get_action_panel(); var ul = $('ul', action_panel); var buttons = $('.action-controls',action_panel); $('', { 'type': 'text', 'name': 'reset' }).appendTo(buttons); $('', { 'type': 'text', 'name': 'update' }).appendTo(buttons); for (var i = 0; i < that.sections.length; ++i) { var section = that.sections[i]; $('

', { name: section.name, title: section.label, html: that.get_section_header_prefix(true) + ' ' + section.label }).appendTo(details); var div = $('
', { 'id': that.entity_name+'-'+that.name+'-'+section.name, 'class': 'details-section' }).appendTo(details); section.create(div); details.append('
'); } } function setup(container) { that.facet_setup(container); var button = $('input[name=reset]', that.container); that.reset_button = IPA.action_button({ 'label': 'Reset', 'icon': 'ui-icon-refresh', 'class': 'details-reset', 'click': function() { that.reset(); return false; } }); button.replaceWith(that.reset_button); button = $('input[name=update]', that.container); that.update_button = IPA.action_button({ 'label': 'Update', 'icon': 'ui-icon-check', 'class': 'details-update', 'click': function() { that.update(); return false; } }); button.replaceWith(that.update_button); for (var i = 0; i < that.sections.length; ++i) { var section = that.sections[i]; var header = $('h2[name='+section.name+']', that.container); var div = $('#'+that.entity_name+'-'+that.name+'-'+section.name, that.container); header.click(function(section, header, div) { return function() { var visible = div.is(":visible"); header.html(that.get_section_header_prefix(!visible) + ' ' + section.label); div.slideToggle(); }; }(section, header, div)); section.setup(div); } } function new_key(){ var pkey = $.bbq.getState(that.entity_name + '-pkey', true) || ''; return pkey != that.pkey; } that.new_key = new_key; function is_dirty() { var i; for ( i =0; i < that.sections.length; i +=1 ){ if (that.sections[i].is_dirty()){ return true; } } return false; } function load(record) { that.record = record; for (var i=0; i', { id: spec.id, html: spec.label, title: spec.title || spec.label, 'class': 'ui-state-default ui-corner-all' }); if (spec.click) button.click(spec.click); if (spec['class']) button.addClass(spec['class']); if (spec.icon) { button.addClass('input_link'); button.append(' '); } else { button.addClass('button-without-icon'); } return button; }; IPA.details_refresh = function () { var that = this; that.pkey = $.bbq.getState(that.entity_name + '-pkey', true) || ''; var command = IPA.command({ 'method': that.entity_name+'_show', 'args': [that.pkey], 'options': { 'all': true, 'rights': true } }); command.on_success = function(data, text_status, xhr) { that.load(data.result.result); }; command.on_error = function(xhr, text_status, error_thrown) { var details = $('.details', that.container).empty(); details.append('

Error: '+error_thrown.name+'

'); details.append('

'+error_thrown.title+'

'); details.append('

'+error_thrown.message+'

'); }; command.execute(); }; IPA.details_update = function (on_win, on_fail) { var that = this; var entity_name = that.entity_name; function on_success(data, text_status, xhr) { if (on_win) on_win(data, text_status, xhr); if (data.error) return; var result = data.result.result; that.load(result); } function on_error(xhr, text_status, error_thrown) { if (on_fail) on_fail(xhr, text_status, error_thrown); } var values; var modlist = {'all': true, 'setattr': [], 'addattr': [], 'rights': true}; var attrs_wo_option = {}; for (var i=0; i 1){ if (field.join) { modlist[field.name] = values.join(','); } else { modlist[field.name] = values; } } else if (param_info['multivalue']){ modlist[field.name] = []; } } else { if (values.length) attrs_wo_option[field.name] = values; } } } for (var attr in attrs_wo_option) { values = attrs_wo_option[attr]; modlist['setattr'].push(attr + '=' + values[0]); for (var k = 1; k < values.length; ++k){ modlist['addattr'].push(attr + '=' + values[k]); } } var pkey = that.get_primary_key(); var args = pkey ? [pkey] : []; var command = IPA.command({ method: entity_name+'_mod', args: args, options: modlist, on_success: on_success, on_error: on_error }); //alert(JSON.stringify(command.to_json())); command.execute(); }; IPA.create_first_dd = function (field_name, content){ var dd = $('
', { 'class': 'first', 'title': field_name }); if (content) dd.append(content); return dd; }; IPA.create_other_dd = function (field_name, content){ return $('
', { 'class': 'other', 'title': field_name }).append(content); }; IPA.details_field_create_add_link = function (title, rights, index) { var that = this; var link = $('', { 'href': 'jslink', 'title': title, 'html': 'Add', 'click': function () { var param_info = IPA.get_param_info(that.entity_name, ''); var input = that.create_input('', param_info, rights, index); link.replaceWith(input); input.focus(); var dd = IPA.create_other_dd(that.name); dd.append(IPA.details_field_create_add_link.call(that, that.name, rights, index+1)); dd.appendTo(that.container); return false; } }); return link; };