diff options
author | Petr VobornÃk <pvoborni@redhat.com> | 2012-01-25 13:06:15 +0100 |
---|---|---|
committer | Endi S. Dewata <edewata@redhat.com> | 2012-02-01 12:47:46 -0600 |
commit | 199d6815d49617b4b438a93ccf99e1e4e32a6221 (patch) | |
tree | 4b60c83859682bafbad9ed89fd581313f8c49bff /install | |
parent | c00267308e2844b2a345c22df5c045117fcff9a2 (diff) | |
download | freeipa-199d6815d49617b4b438a93ccf99e1e4e32a6221.tar.gz freeipa-199d6815d49617b4b438a93ccf99e1e4e32a6221.tar.xz freeipa-199d6815d49617b4b438a93ccf99e1e4e32a6221.zip |
Automember UI
New UI for automember.
Implemented:
* search facet core
* rule details facet
* attribute_table_widget - new base class for tables which contains multivalued attribute with special add/remove commands
* adding/removing conditions in details facet
TODO:
* label translations
* UI for defining default rules
https://fedorahosted.org/freeipa/ticket/2195
Diffstat (limited to 'install')
-rw-r--r-- | install/ui/Makefile.am | 1 | ||||
-rw-r--r-- | install/ui/automember.js | 461 | ||||
-rw-r--r-- | install/ui/facet.js | 13 | ||||
-rw-r--r-- | install/ui/index.html | 1 | ||||
-rw-r--r-- | install/ui/jsl.conf | 1 | ||||
-rw-r--r-- | install/ui/test/data/automembergroup_add.json | 21 | ||||
-rw-r--r-- | install/ui/test/data/automembergroup_find_pkeys.json | 24 | ||||
-rw-r--r-- | install/ui/test/data/automembergroup_get_records.json | 27 | ||||
-rw-r--r-- | install/ui/test/data/automembergroup_show.json | 31 | ||||
-rw-r--r-- | install/ui/test/data/automemberhostgroup_add.json | 21 | ||||
-rw-r--r-- | install/ui/test/data/automemberhostgroup_find_pkeys.json | 24 | ||||
-rw-r--r-- | install/ui/test/data/automemberhostgroup_get_records.json | 27 | ||||
-rw-r--r-- | install/ui/test/data/automemberhostgroup_show.json | 30 | ||||
-rw-r--r-- | install/ui/test/data/ipa_init.json | 1 | ||||
-rw-r--r-- | install/ui/webui.js | 9 | ||||
-rw-r--r-- | install/ui/widget.js | 351 |
16 files changed, 1039 insertions, 4 deletions
diff --git a/install/ui/Makefile.am b/install/ui/Makefile.am index 822a6282..d87a0944 100644 --- a/install/ui/Makefile.am +++ b/install/ui/Makefile.am @@ -11,6 +11,7 @@ app_DATA = \ aci.js \ add.js \ association.js \ + automember.js \ automount.js \ browser.js \ certificate.js \ diff --git a/install/ui/automember.js b/install/ui/automember.js new file mode 100644 index 00000000..d6c3c7ee --- /dev/null +++ b/install/ui/automember.js @@ -0,0 +1,461 @@ +/*jsl:import ipa.js */ + +/* Authors: + * Petr Vobornik <pvoborni@redhat.com> + * + * Copyright (C) 2012 Red Hat + * see file 'COPYING' for use and warranty information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* REQUIRES: ipa.js, details.js, search.js, add.js, facet.js, entity.js */ + +IPA.automember = {}; + +IPA.automember.entity = function(spec) { + + //HACK: Automember takes_params is missing a cn attribute. This hack + //copies cn from mod command. Also it is set as pkey. + var pkey_attr = IPA.metadata.commands.automember_mod.takes_args[0]; + pkey_attr.primary_key = true; + IPA.metadata.objects.automember.takes_params.push(pkey_attr); + IPA.metadata.objects.automember.primary_key = pkey_attr.name; + + var that = IPA.entity(spec); + + that.init = function() { + + that.entity_init(); + + that.builder.search_facet({ + factory: IPA.automember.rule_search_facet, + name: 'searchgroup', + group_type: 'group', + label: 'User group rules', //TODO: translate + details_facet: 'usergrouprule', + columns: [ + 'cn', + 'description' + ] + }). + search_facet({ + factory: IPA.automember.rule_search_facet, + name: 'searchhostgroup', + group_type: 'hostgroup', + label: 'Host group rules', //TODO: translate + details_facet: 'hostgrouprule', + columns: [ + 'cn', + 'description' + ] + }). + details_facet({ + factory: IPA.automember.rule_details_facet, + name: 'usergrouprule', + group_type: 'group', + label: 'User group rule', //TODO: translate + disable_facet_tabs: true, + redirect_info: { tab: 'amgroup' } + }). + details_facet({ + factory: IPA.automember.rule_details_facet, + name: 'hostgrouprule', + group_type: 'hostgroup', + label: 'Host group rule',//TODO: translate + disable_facet_tabs: true, + redirect_info: { tab: 'amhostgroup' } + }). + adder_dialog({ + factory: IPA.automember.rule_adder_dialog, + fields: [ + { + type: 'entity_select', + name: 'cn', + other_entity: 'group', + other_field: 'cn' + } + ], + height: '300' + }). + deleter_dialog({ + factory: IPA.automember.rule_deleter_dialog + }); + }; + + return that; +}; + + +IPA.automember.rule_search_facet = function(spec) { + + spec = spec || {}; + + var that = IPA.search_facet(spec); + + that.group_type = spec.group_type; + + that.get_records_command_name = function() { + return that.managed_entity.name + that.group_type+'_get_records'; + }; + + that.get_search_command_name = function() { + var name = that.managed_entity.name + that.group_type + '_find'; + if (that.pagination && !that.search_all_entries) { + name += '_pkeys'; + } + return name; + }; + + that.create_get_records_command = function(pkeys, on_success, on_error) { + + var batch = that.table_facet_create_get_records_command(pkeys, on_success, on_error); + + for (var i=0; i<batch.commands.length; i++) { + var command = batch.commands[i]; + command.set_option('type', that.group_type); + } + + return batch; + }; + + that.create_refresh_command = function() { + + var command = that.search_facet_create_refresh_command(); + + command.set_option('type', that.group_type); + + return command; + }; + + return that; +}; + +IPA.automember.rule_details_facet = function(spec) { + + spec = spec || {}; + + spec.fields = [ + { + name: 'cn', + widget: 'general.cn' + }, + { + type: 'textarea', + name: 'description', + widget: 'general.description' + }, + { + type: 'automember_condition', + name: 'automemberinclusiveregex', + widget: 'inclusive.automemberinclusiveregex' + }, + { + type: 'automember_condition', + name: 'automemberexclusiveregex', + widget: 'exclusive.automemberexclusiveregex' + } + ]; + + spec.widgets = [ + { + type: 'details_table_section', + name: 'general', + label: IPA.messages.details.general, + widgets: [ + { + name: 'cn' + }, + { + type: 'textarea', + name: 'description' + } + ] + }, + { + factory: IPA.collapsible_section, + name: 'inclusive', + label: 'Inclusive', //TODO:translate + widgets: [ + { + type: 'automember_condition', + name: 'automemberinclusiveregex', + group_type: spec.group_type, + add_command: 'add_condition', + remove_command: 'remove_condition', + adder_dialog: { + title: 'Add Condition to ${pkey}', //TODO: translate + fields: [ + { + name: 'key', + type: 'select', + options: IPA.automember.get_condition_attributes(spec.group_type), + label: 'Attribute' //TODO: translate + }, + { + name: 'automemberinclusiveregex', + label: 'Expression' //TODO: translate + } + ] + } + } + ] + }, + { + factory: IPA.collapsible_section, + name: 'exclusive', + label: 'Exclusive', //TODO:translate + widgets: [ + { + type: 'automember_condition', + name: 'automemberexclusiveregex', + group_type: spec.group_type, + add_command: 'add_condition', + remove_command: 'remove_condition', + adder_dialog: { + title: 'Add Condition to ${pkey}', //TODO: translate + fields: [ + { + name: 'key', + type: 'select', + options: IPA.automember.get_condition_attributes(spec.group_type), + label: 'Attribute' //TODO: translate + }, + { + name: 'automemberexclusiveregex', + label: 'Expression' //TODO: translate + } + ] + } + } + ] + } + ]; + + var that = IPA.details_facet(spec); + + that.group_type = spec.group_type; + + that.get_refresh_command_name = function() { + return that.entity.name+that.group_type+'_show'; + }; + + that.create_refresh_command = function() { + + var command = that.details_facet_create_refresh_command(); + command.set_option('type', that.group_type); + + return command; + }; + + that.create_update_command = function() { + + var command = that.details_facet_create_update_command(); + command.set_option('type', that.group_type); + + return command; + }; + + return that; +}; + +IPA.automember.rule_adder_dialog = function(spec) { + + spec = spec || {}; + + var that = IPA.entity_adder_dialog(spec); + + that.reset = function() { + + var field = that.fields.get_field('cn'); + var facet = IPA.current_entity.get_facet(); + + field.widget.other_entity = IPA.get_entity(facet.group_type); + + that.dialog_reset(); + }; + + that.create_add_command = function(record) { + + var facet = IPA.current_entity.get_facet(); + var command = that.entity_adder_dialog_create_add_command(record); + command.name = that.entity.name+facet.group_type+'_show'; + command.set_option('type', facet.group_type); + + return command; + }; + + return that; +}; + +IPA.automember.rule_deleter_dialog = function(spec) { + + spec = spec || {}; + + var that = IPA.search_deleter_dialog(spec); + + that.create_command = function() { + + var facet = IPA.current_entity.get_facet(); + + var batch = that.search_deleter_dialog_create_command(); + + for (var i=0; i<batch.commands.length; i++) { + var command = batch.commands[i]; + command.set_option('type', facet.group_type); + } + + return batch; + }; + + return that; +}; + +IPA.automember.get_condition_attributes = function(type) { + var options = []; + + if (type === 'group') { + options = IPA.metadata.objects.user.aciattrs; + } else if (type === 'hostgroup') { + options = IPA.metadata.objects.host.aciattrs; + } + + var list_options = IPA.create_options(options); + return list_options; +}; + +IPA.automember.parse_condition_regex = function(regex) { + + var delimeter_index = regex.indexOf('='); + var condition = { + condition: regex, + attribute: regex.substring(0, delimeter_index), + expression: regex.substring(delimeter_index+1) + }; + + return condition; +}; + +IPA.automember.condition_field = function(spec) { + + spec = spec || {}; + var that = IPA.field(spec); + + that.attr_name = spec.attribute || that.name; + + that.load = function(record) { + + var regexes = record[that.attr_name]; + that.values = []; + + if (regexes) { + for (var i=0, j=0; i<regexes.length; i++) { + var condition = IPA.automember.parse_condition_regex(regexes[i]); + that.values.push(condition); + } + } + + that.load_writable(record); + that.reset(); + }; + + return that; +}; + +IPA.field_factories['automember_condition'] = IPA.automember.condition_field; + +IPA.automember.condition_widget = function(spec) { + + spec = spec || {}; + + spec.columns = $.merge(spec.columns || [], [ + { + name: 'attribute', + label: 'Attribute'//TODO:translate + }, + { + name: 'expression', + label: 'Expression'//TODO:translate + } + ]); + + spec.value_attribute = 'condition'; + + var that = IPA.attribute_table_widget(spec); + + that.group_type = spec.group_type; + + that.get_additional_options = function() { + return [ + { + name: 'type', + value: that.group_type + } + ]; + }; + + that.on_add = function(data) { + + if (data.result.completed === 0) { + that.refresh_facet(); + } else { + that.reload_facet(data); + } + }; + + that.on_remove = function(data) { + + var results = data.result.results; + + var i = results.length - 1; + while (i >= 0) { + if (results[i].completed === 1){ + that.reload_facet({ result: results[i] }); + return; + } + i--; + } + + that.refresh_facet(); + }; + + that.create_remove_command = function(values, on_success, on_error) { + + var batch = IPA.batch_command({ + name: 'automember_remove_condition', + on_success: on_success, + on_error: on_error + }); + + var pkeys = that.get_pkeys(); + + for (var i=0; i<values.length; i++) { + var condition = IPA.automember.parse_condition_regex(values[i]); + + var command = that.attribute_table_create_remove_command([]); + command.set_option('key', condition.attribute); + command.set_option(that.attribute_name, condition.expression); + + batch.add_command(command); + } + + return batch; + }; + + return that; +}; + +IPA.widget_factories['automember_condition'] = IPA.automember.condition_widget; + +IPA.register('automember', IPA.automember.entity);
\ No newline at end of file diff --git a/install/ui/facet.js b/install/ui/facet.js index 9821fddc..39478f1a 100644 --- a/install/ui/facet.js +++ b/install/ui/facet.js @@ -660,9 +660,9 @@ IPA.table_facet = function(spec) { return that.managed_entity.name+'_get_records'; }; - that.get_records = function(pkeys, on_success, on_error) { + that.create_get_records_command = function(pkeys, on_success, on_error) { - var batch = IPA.batch_command({ + var batch = IPA.batch_command({ name: that.get_records_command_name(), on_success: on_success, on_error: on_error @@ -681,6 +681,13 @@ IPA.table_facet = function(spec) { batch.add_command(command); } + return batch; + }; + + that.get_records = function(pkeys, on_success, on_error) { + + var batch = that.create_get_records_command(pkeys, on_success, on_error); + batch.execute(); }; @@ -766,6 +773,8 @@ IPA.table_facet = function(spec) { init(); + that.table_facet_create_get_records_command = that.create_get_records_command; + return that; }; diff --git a/install/ui/index.html b/install/ui/index.html index 64c87d89..db314331 100644 --- a/install/ui/index.html +++ b/install/ui/index.html @@ -25,6 +25,7 @@ <script type="text/javascript" src="navigation.js"></script> <script type="text/javascript" src="rule.js"></script> + <script type="text/javascript" src="automember.js"></script> <script type="text/javascript" src="automount.js"></script> <script type="text/javascript" src="dns.js"></script> <script type="text/javascript" src="certificate.js"></script> diff --git a/install/ui/jsl.conf b/install/ui/jsl.conf index 7373e987..508897af 100644 --- a/install/ui/jsl.conf +++ b/install/ui/jsl.conf @@ -155,4 +155,5 @@ +process aci.js +process dns.js +process automount.js ++process automember.js +process webui.js diff --git a/install/ui/test/data/automembergroup_add.json b/install/ui/test/data/automembergroup_add.json new file mode 100644 index 00000000..7b896d2a --- /dev/null +++ b/install/ui/test/data/automembergroup_add.json @@ -0,0 +1,21 @@ +{ + "error": null, + "id": null, + "result": { + "result": { + "automembertargetgroup": [ + "cn=foogroup,cn=groups,cn=accounts,dc=dev,dc=example,dc=com" + ], + "cn": [ + "foogroup" + ], + "dn": "cn=foogroup,cn=group,cn=automember,cn=etc,dc=dev,dc=example,dc=com", + "objectclass": [ + "top", + "automemberregexrule" + ] + }, + "summary": "Added automember rule \"foogroup\"", + "value": "foogroup" + } +}
\ No newline at end of file diff --git a/install/ui/test/data/automembergroup_find_pkeys.json b/install/ui/test/data/automembergroup_find_pkeys.json new file mode 100644 index 00000000..c8918c6c --- /dev/null +++ b/install/ui/test/data/automembergroup_find_pkeys.json @@ -0,0 +1,24 @@ +{ + "error": null, + "id": null, + "result": { + "count": 1, + "result": [ + { + "automembertargetgroup": [ + "cn=foogroup,cn=groups,cn=accounts,dc=dev,dc=example,dc=com" + ], + "cn": [ + "foogroup" + ], + "dn": "cn=foogroup,cn=group,cn=automember,cn=etc,dc=dev,dc=example,dc=com", + "objectclass": [ + "top", + "automemberregexrule" + ] + } + ], + "summary": "1 rules matched", + "truncated": false + } +}
\ No newline at end of file diff --git a/install/ui/test/data/automembergroup_get_records.json b/install/ui/test/data/automembergroup_get_records.json new file mode 100644 index 00000000..82bcc710 --- /dev/null +++ b/install/ui/test/data/automembergroup_get_records.json @@ -0,0 +1,27 @@ +{ + "error": null, + "id": null, + "result": { + "count": 1, + "results": [ + { + "error": null, + "result": { + "automembertargetgroup": [ + "cn=foogroup,cn=groups,cn=accounts,dc=dev,dc=example,dc=com" + ], + "cn": [ + "foogroup" + ], + "dn": "cn=foogroup,cn=group,cn=automember,cn=etc,dc=dev,dc=example,dc=com", + "objectclass": [ + "top", + "automemberregexrule" + ] + }, + "summary": null, + "value": "foogroup" + } + ] + } +}
\ No newline at end of file diff --git a/install/ui/test/data/automembergroup_show.json b/install/ui/test/data/automembergroup_show.json new file mode 100644 index 00000000..4b3f0b91 --- /dev/null +++ b/install/ui/test/data/automembergroup_show.json @@ -0,0 +1,31 @@ +{ + "error": null, + "id": null, + "result": { + "result": { + "automemberexclusiveregex": [ + "cn=^user5", + "cn=^user6" + ], + "automemberinclusiveregex": [ + "cn=^user[0-9]+" + ], + "automembertargetgroup": [ + "cn=foogroup,cn=groups,cn=accounts,dc=dev,dc=example,dc=com" + ], + "cn": [ + "foogroup" + ], + "description": [ + "userrule description" + ], + "dn": "cn=foogroup,cn=group,cn=automember,cn=etc,dc=dev,dc=example,dc=com", + "objectclass": [ + "top", + "automemberregexrule" + ] + }, + "summary": null, + "value": "foogroup" + } +}
\ No newline at end of file diff --git a/install/ui/test/data/automemberhostgroup_add.json b/install/ui/test/data/automemberhostgroup_add.json new file mode 100644 index 00000000..e58d2188 --- /dev/null +++ b/install/ui/test/data/automemberhostgroup_add.json @@ -0,0 +1,21 @@ +{ + "error": null, + "id": null, + "result": { + "result": { + "automembertargetgroup": [ + "cn=foohostgroup,cn=hostgroups,cn=accounts,dc=dev,dc=example,dc=com" + ], + "cn": [ + "foohostgroup" + ], + "dn": "cn=foohostgroup,cn=hostgroup,cn=automember,cn=etc,dc=dev,dc=example,dc=com", + "objectclass": [ + "top", + "automemberregexrule" + ] + }, + "summary": "Added automember rule \"foohostgroup\"", + "value": "foohostgroup" + } +}
\ No newline at end of file diff --git a/install/ui/test/data/automemberhostgroup_find_pkeys.json b/install/ui/test/data/automemberhostgroup_find_pkeys.json new file mode 100644 index 00000000..90968346 --- /dev/null +++ b/install/ui/test/data/automemberhostgroup_find_pkeys.json @@ -0,0 +1,24 @@ +{ + "error": null, + "id": null, + "result": { + "count": 1, + "result": [ + { + "automembertargetgroup": [ + "cn=foohostgroup,cn=hostgroups,cn=accounts,dc=dev,dc=example,dc=com" + ], + "cn": [ + "foohostgroup" + ], + "dn": "cn=foohostgroup,cn=hostgroup,cn=automember,cn=etc,dc=dev,dc=example,dc=com", + "objectclass": [ + "top", + "automemberregexrule" + ] + } + ], + "summary": "1 rules matched", + "truncated": false + } +}
\ No newline at end of file diff --git a/install/ui/test/data/automemberhostgroup_get_records.json b/install/ui/test/data/automemberhostgroup_get_records.json new file mode 100644 index 00000000..6ae23e32 --- /dev/null +++ b/install/ui/test/data/automemberhostgroup_get_records.json @@ -0,0 +1,27 @@ +{ + "error": null, + "id": null, + "result": { + "count": 1, + "results": [ + { + "error": null, + "result": { + "automembertargetgroup": [ + "cn=foohostgroup,cn=hostgroups,cn=accounts,dc=dev,dc=example,dc=com" + ], + "cn": [ + "foohostgroup" + ], + "dn": "cn=foohostgroup,cn=hostgroup,cn=automember,cn=etc,dc=dev,dc=example,dc=com", + "objectclass": [ + "top", + "automemberregexrule" + ] + }, + "summary": null, + "value": "foohostgroup" + } + ] + } +}
\ No newline at end of file diff --git a/install/ui/test/data/automemberhostgroup_show.json b/install/ui/test/data/automemberhostgroup_show.json new file mode 100644 index 00000000..e3f7814a --- /dev/null +++ b/install/ui/test/data/automemberhostgroup_show.json @@ -0,0 +1,30 @@ +{ + "error": null, + "id": null, + "result": { + "result": { + "automemberexclusiveregex": [ + "fqdn=^web5.example.com" + ], + "automemberinclusiveregex": [ + "fqdn=^web[1-9]+.example.com" + ], + "automembertargetgroup": [ + "cn=foohostgroup,cn=hostgroups,cn=accounts,dc=dev,dc=example,dc=com" + ], + "cn": [ + "foohostgroup" + ], + "description": [ + "hostrule description" + ], + "dn": "cn=foohostgroup,cn=hostgroup,cn=automember,cn=etc,dc=dev,dc=example,dc=com", + "objectclass": [ + "top", + "automemberregexrule" + ] + }, + "summary": null, + "value": "foohostgroup" + } +}
\ No newline at end of file diff --git a/install/ui/test/data/ipa_init.json b/install/ui/test/data/ipa_init.json index fc8ec06b..7b1b0d0a 100644 --- a/install/ui/test/data/ipa_init.json +++ b/install/ui/test/data/ipa_init.json @@ -368,6 +368,7 @@ }, "tabs": { "audit": "Audit", + "automember": "Automember", "automount": "Automount", "dns": "DNS", "hbac": "Host Based Access Control", diff --git a/install/ui/webui.js b/install/ui/webui.js index 59609734..42a85369 100644 --- a/install/ui/webui.js +++ b/install/ui/webui.js @@ -68,7 +68,14 @@ IPA.admin_navigation = function(spec) { {entity: 'automountkey', hidden: true}]}, {entity: 'pwpolicy'}, {entity: 'krbtpolicy'}, - {entity: 'selinuxusermap'} + {entity: 'selinuxusermap'}, + {name: 'automember', label: 'Automember', //TODO: translate IPA.messages.tabs.automember + children: [ + { name: 'amgroup', entity: 'automember', + facet: 'searchgroup', label: 'User group rules'}, //TODO: translate + { name: 'amhostgroup', entity: 'automember', + facet: 'searchhostgroup', label: 'Host group rules'} //TODO: translate + ]} ]}, {name: 'ipaserver', label: IPA.messages.tabs.ipaserver, children: [ {name: 'rolebased', label: IPA.messages.tabs.role, children: [ diff --git a/install/ui/widget.js b/install/ui/widget.js index 04c35bb6..807191e5 100644 --- a/install/ui/widget.js +++ b/install/ui/widget.js @@ -1678,6 +1678,355 @@ IPA.table_widget = function (spec) { return that; }; + +IPA.attribute_table_widget = function(spec) { + + + spec = spec || {}; + spec.columns = spec.columns || []; + + var that = IPA.table_widget(spec); + + that.attribute_name = spec.attribute_name || that.name; + that.adder_dialog_spec = spec.adder_dialog; + that.css_class = spec.css_class; + + that.add_command = spec.add_command; + that.remove_command = spec.remove_command; + + that.on_add = spec.on_add; + that.on_add_error = spec.on_add_error; + that.on_remove = spec.on_remove; + that.on_remove_error = spec.on_remove_error; + + that.create_column = function(spec) { + + if (typeof spec === 'string') { + spec = { + name: spec + }; + } + + spec.entity = that.entity; + + var factory = spec.factory || IPA.column; + + var column = factory(spec); + that.add_column(column); + return column; + }; + + that.create_columns = function() { + that.clear_columns(); + if (spec.columns) { + for (var i=0; i<spec.columns.length; i++) { + that.create_column(spec.columns[i]); + } + } + + that.post_create_columns(); + }; + + that.post_create_columns = function() { + }; + + that.create_buttons = function(container) { + + that.remove_button = IPA.action_button({ + name: 'remove', + label: IPA.messages.buttons.remove, + icon: 'remove-icon', + 'class': 'action-button-disabled', + click: function() { + if (!that.remove_button.hasClass('action-button-disabled')) { + that.remove_handler(); + } + return false; + } + }).appendTo(container); + + that.add_button = IPA.action_button({ + name: 'add', + label: IPA.messages.buttons.add, + icon: 'add-icon', + click: function() { + if (!that.add_button.hasClass('action-button-disabled')) { + that.add_handler(); + } + return false; + } + }).appendTo(container); + }; + + that.create = function(container) { + + that.create_columns(); + that.table_create(container); + if (that.css_class) + container.addClass(that.css_class); + that.create_buttons(that.buttons); + }; + + that.set_enabled = function(enabled) { + that.table_set_enabled(enabled); + if (enabled) { + if(that.add_button) { + that.add_button.removeClass('action-button-disabled'); + } + } else { + $('.action-button', that.table).addClass('action-button-disabled'); + that.unselect_all(); + } + that.enabled = enabled; + }; + + that.select_changed = function() { + + var values = that.get_selected_values(); + + if (that.remove_button) { + if (values.length === 0) { + that.remove_button.addClass('action-button-disabled'); + } else { + that.remove_button.removeClass('action-button-disabled'); + } + } + }; + + that.add_handler = function() { + var facet = that.entity.get_facet(); + + if (facet.is_dirty()) { + var dialog = IPA.dirty_dialog({ + entity:that.entity, + facet: facet + }); + + dialog.callback = function() { + that.show_add_dialog(); + }; + + dialog.open(that.container); + + } else { + that.show_add_dialog(); + } + }; + + that.remove_handler = function() { + var facet = that.entity.get_facet(); + + if (facet.is_dirty()) { + var dialog = IPA.dirty_dialog({ + entity:that.entity, + facet: facet + }); + + dialog.callback = function() { + that.show_remove_dialog(); + }; + + dialog.open(that.container); + + } else { + that.show_remove_dialog(); + } + }; + + that.show_remove_dialog = function() { + + var dialog = that.create_remove_dialog(); + if (dialog) dialog.open(that.container); + }; + + that.create_remove_dialog = function() { + var selected_values = that.get_selected_values(); + + if (!selected_values.length) { + var message = IPA.messages.dialogs.remove_empty; + alert(message); + return null; + } + + var dialog = IPA.deleter_dialog({ + entity: that.entity, + values: selected_values + }); + + dialog.execute = function() { + var command = that.create_remove_command( + selected_values, + function(data, text_status, xhr) { + var handler = that.on_remove || that.on_command_success; + handler.call(this, data, text_status, xhr); + dialog.close(); + }, + function(xhr, text_status, error_thrown) { + var handler = that.on_remove_error || that.on_command_error; + handler.call(this, xhr, text_status, error_thrown); + dialog.close(); + } + ); + command.execute(); + }; + + return dialog; + }; + + that.on_command_success = function(data) { + that.reload_facet(data); + }; + + that.on_command_error = function() { + that.refresh_facet(); + }; + + that.get_pkeys = function() { + var pkey = IPA.nav.get_state(that.entity.name+'-pkey'); + return [pkey]; + }; + + that.get_additional_options = function() { + return []; + }; + + that.create_remove_command = function(values, on_success, on_error) { + + var pkeys = that.get_pkeys(); + + var command = IPA.command({ + entity: that.entity.name, + method: that.remove_command || 'del', + args: pkeys, + on_success: on_success, + on_error: on_error + }); + + command.set_option(that.attribute_name, values.join(',')); + + var additional_options = that.get_additional_options(); + for (var i=0; i<additional_options.length; i++) { + var option = additional_options[i]; + command.set_option(option.name, option.value); + } + + return command; + }; + + that.create_add_dialog = function() { + + var dialog_spec = { + entity: that.entity, + method: that.add_command + }; + + if (that.adder_dialog_spec) { + $.extend(dialog_spec, that.adder_dialog_spec); + } + + var label = that.entity.metadata.label_singular; + var pkey = IPA.nav.get_state(that.entity.name+'-pkey'); + dialog_spec.title = dialog_spec.title || IPA.messages.dialogs.add_title; + dialog_spec.title = dialog_spec.title.replace('${entity}', label); + dialog_spec.title = dialog_spec.title.replace('${pkey}', pkey); + + + var factory = dialog_spec.factory || IPA.entity_adder_dialog; + var dialog = factory(dialog_spec); + + var cancel_button = dialog.buttons.get('cancel'); + dialog.buttons.empty(); + + dialog.create_button({ + name: 'add', + label: IPA.messages.buttons.add, + click: function() { + dialog.hide_message(); + dialog.add( + function(data, text_status, xhr) { + var handler = that.on_add || that.on_command_success; + handler.call(this, data, text_status, xhr); + dialog.close(); + }, + dialog.on_error); + } + }); + + dialog.create_button({ + name: 'add_and_add_another', + label: IPA.messages.buttons.add_and_add_another, + click: function() { + dialog.hide_message(); + dialog.add( + function(data, text_status, xhr) { + var label = that.entity.metadata.label_singular; + var message = IPA.messages.dialogs.add_confirmation; + message = message.replace('${entity}', label); + dialog.show_message(message); + + var handler = that.on_add || that.on_command_success; + handler.call(this, data, text_status, xhr); + + dialog.reset(); + }, + dialog.on_error); + } + }); + + dialog.buttons.put('cancel', cancel_button); + + dialog.create_add_command = function(record) { + return that.adder_dialog_create_command(dialog, record); + }; + + return dialog; + }; + + that.adder_dialog_create_command = function(dialog, record) { + var command = dialog.entity_adder_dialog_create_add_command(record); + command.args = that.get_pkeys(); + + var additional_options = that.get_additional_options(); + for (var i=0; i<additional_options.length; i++) { + var option = additional_options[i]; + command.set_option(option.name, option.value); + } + + return command; + }; + + that.show_add_dialog = function() { + + var dialog = that.create_add_dialog(); + dialog.open(that.container); + }; + + that.update = function(values) { + that.table_update(values); + that.unselect_all(); + }; + + that.reload_facet = function(data) { + + //FIXME: bad approach - widget is directly manipulating with facet + var facet = IPA.current_entity.get_facet(); + facet.load(data); + }; + + that.refresh_facet = function() { + + //FIXME: bad approach + var facet = IPA.current_entity.get_facet(); + facet.refresh(); + }; + + that.attribute_table_adder_dialog_create_command = that.adder_dialog_create_command; + that.attribute_table_create_remove_command = that.create_remove_command; + that.attribute_table_update = that.update; + + return that; +}; + IPA.combobox_widget = function(spec) { spec = spec || {}; @@ -2464,7 +2813,7 @@ IPA.widget_builder = function(spec) { }; - +IPA.widget_factories['attribute_table'] = IPA.attribute_table_widget; IPA.widget_factories['checkbox'] = IPA.checkbox_widget; IPA.widget_factories['checkboxes'] = IPA.checkboxes_widget; IPA.widget_factories['combobox'] = IPA.combobox_widget; |