On 19.9.2014 14:29, Petr Vobornik wrote:
Hello,

attached patches implements Web UI part of ID Views. Backend is
currently on review as well - thread "[PATCHES 247-259] ID views -
management part".

https://fedorahosted.org/freeipa/ticket/4535

I expect that backed can change and that the UI might influence it as
well. Therefore no UI integration tests nor static data files are
included in this patchset. They will follow when backend is stable.

First 5 patches extends UI framework to support the main patch (#754).


== [PATCH] 749 webui: improve breadcrumb navigation ==

Fixes issue when:
- user navigates to a nested facet
- refreshes browser
- uses breadcrumb navigation to go to parent entity page which requires
a pkey. E.g. from automount keys to maps.

The old code relies on the facet, that user visited the parent facet
before and therefore the facet has pkey stored. It fails after the
browser reload.

Allows to specify a containing_facet. It allows breadcrumb navigation to
return to a different facet than the 'default'.

== [PATCH] 750 webui: treat value as pkey in link widget ==

Current default mechanism of a link widget assumes that pkeys of a
current facet are pkeys for the link. It works for the only usage - in
password policy. It's rather inflexible since it can't be used if the
keys are in other attribute. This behavior is also bad in nested
entities - creates a link to itself which is pointless.

This patch changes the default behavior to assume that the supplied
value are the pkeys and that the last pkey is the value to display.

It also keeps the old method of overriding `other_pkeys` method so if
the last and only pkey is the actual value to display then the method
can tranform it into the pkeys which keeps compatibility with descendant
widgets (`host_dnsrecord_entity_link_widget`,
`dnsrecord_host_link_widget`).

== [PATCH] 751 webui: do not show internal facet name to user ==

== [PATCH] 752 webui: allow to skip link widget link validation ==

== [PATCH] 753 webui: add simple link column suppor ==

Usual link columns are link with primary key of current entity.

This patch allows to create a link to arbitrary non-nested entity.

== [PATCH] 754 webui: new ID views section ==


Attaching new version of #754. It:

- makes anchor fields in id override adder dialogs editable in order to allow specifying trusted domain users/groups - adds tooltip to explain that search doesn't list users/groups from trusted domains

a ticket to offer prefixes of trusted domains filed:

https://fedorahosted.org/freeipa/ticket/4554
--
Petr Vobornik
From 3033448509776ef0846afe665a7cca7efd26aff3 Mon Sep 17 00:00:00 2001
From: Petr Vobornik <pvobo...@redhat.com>
Date: Wed, 3 Sep 2014 14:45:05 +0200
Subject: [PATCH] webui: new ID views section

https://fedorahosted.org/freeipa/ticket/4535
---
 install/ui/doc/categories.json                     |   1 +
 install/ui/less/widgets.less                       |   6 +
 install/ui/src/freeipa/_base/Singleton_registry.js |  17 +
 install/ui/src/freeipa/app.js                      |   3 +-
 install/ui/src/freeipa/association.js              |  17 +-
 install/ui/src/freeipa/dialog.js                   |   4 +-
 install/ui/src/freeipa/idviews.js                  | 673 +++++++++++++++++++++
 install/ui/src/freeipa/navigation/menu_spec.js     |   1 +
 install/ui/test/data/ipa_init.json                 |  26 +
 ipalib/plugins/internal.py                         |  26 +
 10 files changed, 769 insertions(+), 5 deletions(-)
 create mode 100644 install/ui/src/freeipa/idviews.js

diff --git a/install/ui/doc/categories.json b/install/ui/doc/categories.json
index 153c366c43a9e51b61e941acbe54da62a6c7e35a..e9507795b9557880cfb4ce34c0808b6bd2d2ab2c 100644
--- a/install/ui/doc/categories.json
+++ b/install/ui/doc/categories.json
@@ -241,6 +241,7 @@
                 "name": "Plugins",
                 "classes": [
                     "aci",
+                    "idviews",
                     "otptoken",
                     "radiusproxy",
                     "user",
diff --git a/install/ui/less/widgets.less b/install/ui/less/widgets.less
index be594f470aa0649a34b3ffe77e78a1fc9c377e23..edfa005a7231d8c57338d4d07983126612148ec9 100644
--- a/install/ui/less/widgets.less
+++ b/install/ui/less/widgets.less
@@ -83,4 +83,10 @@
 
 .sshkey-status {
     margin-right: 5px;
+}
+
+// Make bootstrap tooltips wider
+.tooltip-inner {
+    min-width: 200px;
+    max-width: 400px;
 }
\ No newline at end of file
diff --git a/install/ui/src/freeipa/_base/Singleton_registry.js b/install/ui/src/freeipa/_base/Singleton_registry.js
index e0c55ca14af2b2c738ff51112630966e27977d73..6aa10545630da9b0dc95c165f19c2b12ad63832b 100644
--- a/install/ui/src/freeipa/_base/Singleton_registry.js
+++ b/install/ui/src/freeipa/_base/Singleton_registry.js
@@ -116,6 +116,23 @@ define(['dojo/_base/declare',
             this.builder.registry.register(type, func, default_spec);
         },
 
+        /**
+         * Makes a copy of construct specification of original type. Extends
+         * it with values in supplied construct specification.
+         *
+         * @param {string} org_type Original type
+         * @param {string} new_type New type
+         * @param {Object} construct_spec Construction specification
+         */
+        copy: function(org_type, new_type, construct_spec) {
+            if (!lang.exists('builder.registry', this)) {
+                throw {
+                    error: 'Object Initialized Exception: builder not initalized',
+                    context: this
+                };
+            }
+            this.builder.registry.copy(org_type, new_type, construct_spec);
+        },
 
         constructor: function(spec) {
 
diff --git a/install/ui/src/freeipa/app.js b/install/ui/src/freeipa/app.js
index 2297b866dde99fe5964f8e0c3516ed458d5ba0dc..46752fa09e47be9e14e5fa37ce1bd1cbd0b0afdf 100644
--- a/install/ui/src/freeipa/app.js
+++ b/install/ui/src/freeipa/app.js
@@ -35,6 +35,7 @@ define([
     './hostgroup',
     './host',
     './idrange',
+    './idviews',
     './netgroup',
     './otptoken',
     './policy',
@@ -50,4 +51,4 @@ define([
     'dojo/domReady!'
 ],function(app_container) {
     return app_container;
-});
\ No newline at end of file
+});
diff --git a/install/ui/src/freeipa/association.js b/install/ui/src/freeipa/association.js
index 8fe612e913c3fc8bb8c2fa86423eb4b46f224ddc..89edeeb1a97359009b38b4eeae5b5a4fc3144015 100644
--- a/install/ui/src/freeipa/association.js
+++ b/install/ui/src/freeipa/association.js
@@ -133,6 +133,7 @@ IPA.bulk_associator = function(spec) {
     spec = spec || {};
 
     var that = IPA.associator(spec);
+    that.options = spec.options || { 'all': true };
 
     that.execute = function() {
 
@@ -145,7 +146,7 @@ IPA.bulk_associator = function(spec) {
             entity: that.entity.name,
             method: that.method,
             args: [that.pkey],
-            options: { 'all': true },
+            options: that.options,
             on_success: that.on_success,
             on_error: that.on_error
         });
@@ -1407,6 +1408,15 @@ exp.attribute_facet = IPA.attribute_facet = function(spec, no_init) {
 
     that.refresh = function() {
 
+        var command = that.get_refresh_command();
+        command.execute();
+    };
+
+    /**
+     * Create refresh command
+     */
+    that.get_refresh_command = function() {
+
         var pkey = that.get_pkeys();
 
         var command = rpc.command({
@@ -1431,8 +1441,7 @@ exp.attribute_facet = IPA.attribute_facet = function(spec, no_init) {
             that.redirect_error(error_thrown);
             that.report_error(error_thrown);
         };
-
-        command.execute();
+        return command;
     };
 
     that.clear = function() {
@@ -1525,6 +1534,8 @@ exp.attribute_facet = IPA.attribute_facet = function(spec, no_init) {
 
     if (!no_init) that.init_attribute_facet();
 
+    that.attribute_get_refresh_command = that.get_refresh_command;
+
     return that;
 };
 
diff --git a/install/ui/src/freeipa/dialog.js b/install/ui/src/freeipa/dialog.js
index f430e5604e0d0b58e48db3be026208322eb32d56..def29cfca73f6a2874514ad7cd649190f53b00ab 100644
--- a/install/ui/src/freeipa/dialog.js
+++ b/install/ui/src/freeipa/dialog.js
@@ -796,6 +796,8 @@ IPA.adder_dialog = function(spec) {
     /** @property {number} height=300 Height */
     that.height = spec.height || 360;
 
+    that.add_button_label = spec.add_button_label || '@i18n:buttons.add';
+
     if (!that.entity) {
         var except = {
             expected: false,
@@ -1045,7 +1047,7 @@ IPA.adder_dialog = function(spec) {
 
         var add_button = that.create_button({
             name: 'add',
-            label: '@i18n:buttons.add',
+            label: that.add_button_label,
             click: function() {
                 if (!add_button.is_enabled()) return;
                 that.execute();
diff --git a/install/ui/src/freeipa/idviews.js b/install/ui/src/freeipa/idviews.js
new file mode 100644
index 0000000000000000000000000000000000000000..aa24122546a289a3dad43dce61b9c47381af8f33
--- /dev/null
+++ b/install/ui/src/freeipa/idviews.js
@@ -0,0 +1,673 @@
+/*
+ *  Authors:
+ *    Petr Vobornik <pvobo...@redhat.com>
+ *
+ * Copyright (C) 2014 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/>.
+ */
+
+define([
+        './ipa',
+        './jquery',
+        './menu',
+        './phases',
+        './reg',
+        './rpc',
+        './text',
+        './details',
+        './facet',
+        './search',
+        './entity'],
+            function(IPA, $, menu, phases, reg, rpc, text, mod_details, mod_facet) {
+/**
+ * ID Views module
+ * @class
+ * @singleton
+ */
+var idviews = IPA.idviews = {};
+
+var make_spec = function() {
+return {
+    name: 'idview',
+    enable_test: function() {
+        return true;
+    },
+    facet_groups: ['appliedto', 'overrides', 'settings'],
+    facets: [
+        {
+            $type: 'search',
+            columns: [
+                'cn',
+                'description'
+            ],
+            actions: [
+                'idview_unapply_host',
+                'idview_unapply_hostgroups'
+            ],
+            control_buttons: [
+                {
+                    name: 'idview_unapply_host',
+                    label: '@i18n:objects.idview.unapply_hosts_all',
+                    icon: 'fa-trash-o'
+                },
+                {
+                    name: 'idview_unapply_hostgroups',
+                    label: '@i18n:objects.idview.unapply_hostgroups',
+                    icon: 'fa-trash-o'
+                }
+            ]
+        },
+        {
+            $type: 'details',
+            actions: [
+                'delete'
+            ],
+            header_actions: ['delete'],
+            state: {
+            },
+            sections: [
+                {
+                    name: 'details',
+                    fields: [
+                        'cn',
+                        {
+                            $type: 'textarea',
+                            name: 'description'
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            $type: 'nested_search',
+            facet_group: 'overrides',
+            nested_entity: 'idoverrideuser',
+            search_all_entries: true,
+            label: '@mo:idoverrideuser.label',
+            tab_label: '@mo:idoverrideuser.label',
+            name: 'idoverrideuser',
+            columns: [
+                {
+                    name: 'ipaanchoruuid',
+                    label: '@i18n:objects.idoverrideuser.anchor_label'
+                },
+                'uid',
+                'uidnumber',
+                'homedirectory',
+                'description'
+            ]
+        },
+        {
+            $type: 'nested_search',
+            facet_group: 'overrides',
+            nested_entity: 'idoverridegroup',
+            search_all_entries: true,
+            label: '@mo:idoverridegroup.label',
+            tab_label: '@mo:idoverridegroup.label',
+            name: 'idoverridegroup',
+            columns: [
+                {
+                    name: 'ipaanchoruuid',
+                    label: '@i18n:objects.idoverridegroup.anchor_label'
+                },
+                'cn',
+                'gidnumber',
+                'description'
+            ]
+        },
+        {
+            $type: 'idview_appliedtohosts',
+            name: 'appliedtohosts',
+            attribute: 'appliedtohosts',
+            tab_label: '@i18n:objects.idview.appliedtohosts',
+            facet_group: 'appliedto',
+            actions: [
+                'idview_apply',
+                'idview_apply_hostgroups',
+                'idview_unapply',
+                'idview_unapply_hostgroups'
+            ],
+            control_buttons: [
+                {
+                    name: 'idview_unapply',
+                    label: '@i18n:objects.idview.unapply_hosts',
+                    icon: 'fa-trash-o'
+                },
+                {
+                    name: 'idview_unapply_hostgroups',
+                    label: '@i18n:objects.idview.unapply_hostgroups',
+                    icon: 'fa-trash-o'
+                },
+                {
+                    name: 'idview_apply',
+                    label: '@i18n:objects.idview.apply_hosts',
+                    icon: 'fa-plus'
+                },
+                {
+                    name: 'idview_apply_hostgroups',
+                    label: '@i18n:objects.idview.apply_hostgroups',
+                    icon: 'fa-plus'
+                }
+            ],
+            columns: [
+                {
+                    name: 'appliedtohosts',
+                    label: '@mo:host.label_singular',
+                    link: true,
+                    target_entity: 'host',
+                    target_facet: 'details'
+                }
+            ]
+        }
+    ],
+
+    adder_dialog: {
+        fields: [
+            'cn',
+            {
+                $type: 'textarea',
+                name: 'description'
+            }
+        ]
+    }
+};};
+
+var make_idoverrideuser_spec = function() {
+return {
+    name: 'idoverrideuser',
+    enable_test: function() {
+        return true;
+    },
+    policies:[
+        {
+            $factory: IPA.facet_update_policy,
+            source_facet: 'details',
+            dest_entity: 'idview',
+            dest_facet: 'idoverrideuser'
+        }
+    ],
+    containing_entity: 'idview',
+    facets: [
+        {
+            $type: 'details',
+            disable_breadcrumb: false,
+            containing_facet: 'idoverrideuser',
+            actions: [
+                'delete'
+            ],
+            header_actions: ['delete'],
+            state: {
+            },
+            sections: [
+                {
+                    name: 'details',
+                    fields: [
+                        {
+                            $type: 'link',
+                            name: 'ipaanchoruuid',
+                            label: '@i18n:objects.idoverrideuser.anchor_label',
+                            other_entity: 'user'
+                        },
+                        {
+                            $type: 'textarea',
+                            name: 'description'
+                        },
+                        'uid',
+                        'uidnumber',
+                        'homedirectory'
+                    ]
+                }
+            ]
+        }
+    ],
+
+    adder_dialog: {
+        fields: [
+            {
+                $type: 'entity_select',
+                label: '@i18n:objects.idoverrideuser.anchor_label',
+                name: 'ipaanchoruuid',
+                other_entity: 'user',
+                other_field: 'uid',
+                editable: true,
+                tooltip: '@i18n:objects.idoverrideuser.anchor_tooltip'
+            },
+            'uid',
+            'uidnumber',
+            'homedirectory',
+            {
+                $type: 'textarea',
+                name: 'description'
+            }
+        ]
+    }
+};};
+
+var make_idoverridegroup_spec = function() {
+return {
+    name: 'idoverridegroup',
+    enable_test: function() {
+        return true;
+    },
+    policies:[
+        {
+            $factory: IPA.facet_update_policy,
+            source_facet: 'details',
+            dest_entity: 'idview',
+            dest_facet: 'idoverridegroup'
+        }
+    ],
+    containing_entity: 'idview',
+    facets: [
+        {
+            $type: 'details',
+            disable_breadcrumb: false,
+            containing_facet: 'idoverridegroup',
+            actions: [
+                'delete'
+            ],
+            header_actions: ['delete'],
+            state: {
+            },
+            sections: [
+                {
+                    name: 'details',
+                    fields: [
+                        {
+                            $type: 'link',
+                            name: 'ipaanchoruuid',
+                            label: '@i18n:objects.idoverridegroup.anchor_label',
+                            other_entity: 'group'
+                        },
+                        {
+                            $type: 'textarea',
+                            name: 'description'
+                        },
+                        'cn',
+                        'gidnumber'
+                    ]
+                }
+            ]
+        }
+    ],
+
+    adder_dialog: {
+        fields: [
+             {
+                $type: 'entity_select',
+                label: '@i18n:objects.idoverridegroup.anchor_label',
+                name: 'ipaanchoruuid',
+                other_entity: 'group',
+                other_field: 'cn',
+                editable: true,
+                tooltip: '@i18n:objects.idoverridegroup.anchor_tooltip'
+            },
+            'cn',
+            'gidnumber',
+            {
+                $type: 'textarea',
+                name: 'description'
+            }
+        ]
+    }
+};};
+
+
+/**
+ * Facet for hosts which have current id view applied on
+ *
+ * @class idviews.appliedtohosts_facet
+ * @extends IPA.attribute_facet
+ */
+idviews.appliedtohosts_facet = function(spec, no_init) {
+
+    spec = spec || {};
+
+    var that = IPA.attribute_facet(spec, no_init);
+
+    /**
+     * @inheritDoc
+     */
+    that.get_refresh_command = function() {
+        var command = that.attribute_get_refresh_command();
+        command.set_option('show_hosts', true);
+        return command;
+    };
+
+    return that;
+};
+
+/**
+ * Apply Id view on hosts on hostgroup action base class
+ *
+ * @class idviews.apply_action
+ * @extends IPA.action
+ */
+idviews.apply_action = function(spec) {
+
+    spec = spec || {};
+    spec.name = spec.name || 'idview_apply';
+    spec.label = spec.label || '@i18n:objects.idview.apply_hosts';
+
+    var that = IPA.action(spec);
+
+    /**
+     * Confirm button label
+     * @property {string}
+     */
+    that.confirm_button_label = spec.confirm_button_label || '@i18n:buttons.apply';
+
+    /**
+     * Entity to apply
+     * @property {entity.entity|string}
+     */
+    that.other_entity = spec.other_entity || 'host';
+
+    /**
+     * Dialog title
+     * @property {string}
+     */
+    that.dialog_title = spec.dialog_title || '@i18n:objects.idview.apply_hosts_title';
+
+    /**
+     * Method
+     * @property {string}
+     */
+    that.method = spec.method || 'apply';
+
+    /**
+     * Success message
+     * @property {string}
+     */
+    that.success_msg = spec.success_msg || '@i18n:association.added';
+
+    /**
+     * @inheritDoc
+     */
+    that.execute_action = function(facet, on_success, on_error) {
+
+        that.show_dialog(facet);
+    };
+
+    /**
+     * Create and open dialog
+     */
+    that.show_dialog = function(facet, current_pkeys) {
+
+        var pkey = facet.get_pkey();
+        var other_entity = reg.entity.get(that.other_entity);
+        var other_entity_label = other_entity.metadata.label;
+        var title = text.get(that.dialog_title);
+        title = title.replace('${entity}', other_entity_label);
+        title = title.replace('${primary_key}', pkey);
+
+        var dialog = IPA.association_adder_dialog({
+            title: title,
+            entity: facet.entity,
+            pkey: pkey,
+            other_entity: other_entity,
+            attribute_member: that.attribute_member,
+            exclude: current_pkeys || [],
+            add_button_label: that.confirm_button_label
+        });
+
+        dialog.execute = function() {
+            var values = dialog.get_selected_values();
+            var command = that.get_command(
+                facet,
+                values,
+                function(data) {
+                    that.notify_change(facet);
+                    dialog.close();
+                    var succeeded = IPA.get_succeeded(data);
+                    var msg = text.get(that.success_msg).replace('${count}', succeeded);
+                    IPA.notify_success(msg);
+                },
+                function() {
+                    that.notify_change(facet);
+                    dialog.close();
+                });
+            command.execute();
+            return command;
+        };
+
+        dialog.open();
+    };
+
+    /**
+     * Construct action command
+     */
+    that.get_command = function(facet, values, on_success, on_error) {
+        var other_entity = reg.entity.get(that.other_entity);
+        var pkey = facet.get_pkey();
+        var args = pkey ? [pkey] : [];
+        var command = rpc.command({
+                entity: 'idview',
+                method: that.method,
+                args: args,
+                options: {},
+                on_success: on_success,
+                on_error: on_error
+            });
+
+        command.set_option(other_entity.name, values);
+        return command;
+    };
+
+    /**
+     * Notify idview.appliedtohosts facet that there were possible changes
+     * and a refresh is needed.
+     */
+    that.notify_change = function(current_facet) {
+
+        if (current_facet && current_facet.name === 'appliedtohosts') {
+            current_facet.refresh();
+        } else {
+            reg.entity.get('idview').
+                get_facet('appliedtohosts').
+                set_expired_flag();
+        }
+    };
+
+    that.apply_action_get_command = that.get_command;
+
+    return that;
+};
+
+
+/**
+ * Apply Id view on hosts of a hostgroup
+ *
+ * @class idviews.apply_hostgroup_action
+ * @extends idviews.apply_action
+ */
+idviews.apply_hostgroups_action = function(spec) {
+
+    spec = spec || {};
+    spec.name = spec.name || 'idview_apply_hostgroups';
+    spec.label = spec.label || '@i18n:objects.idview.apply_hostgroups';
+    spec.other_entity = spec.other_entity || 'hostgroup';
+    spec.dialog_title = spec.dialog_title || '@i18n:objects.idview.apply_hostgroups_title';
+
+    var that = idviews.apply_action(spec);
+    return that;
+};
+
+/**
+ * Unapply Id view from hosts
+ *
+ * @class idviews.unapply_host_action
+ * @extends idviews.apply_action
+ */
+idviews.unapply_host_action = function(spec) {
+
+    spec = spec || {};
+    spec.name = spec.name || 'idview_unapply_host';
+    spec.label = spec.label || '@i18n:objects.idview.unapply_hosts_all';
+    spec.other_entity = spec.other_entity || 'host';
+    spec.method = spec.method || 'unapply';
+    spec.dialog_title = spec.dialog_title || '@i18n:objects.idview.unapply_hosts_all_title';
+    spec.confirm_button_label = spec.confirm_button_label || '@i18n:buttons.unapply';
+    spec.success_msg = spec.success_msg || '@i18n:association.removed';
+
+    var that = idviews.apply_action(spec);
+
+    /**
+     * @inheritDoc
+     */
+    that.get_command = function(facet, values, on_success, on_error) {
+        var command = that.apply_action_get_command(facet, values, on_success, on_error);
+        // idview_unapply doesn't support primary keys to narrow down idviews
+        // to un-apply yet
+        command.args = [];
+        return command;
+    };
+
+    return that;
+};
+
+/**
+ * Unapply Id view from all hosts of a hostgroup
+ *
+ * @class idviews.unapply_hostgroups_action
+ * @extends idviews.unapply_host_action
+ */
+idviews.unapply_hostgroups_action = function(spec) {
+
+    spec = spec || {};
+    spec.name = spec.name || 'idview_unapply_hostgroups';
+    spec.label = spec.label || '@i18n:objects.idview.unapply_hostgroups';
+    spec.other_entity = spec.other_entity || 'hostgroup';
+    spec.dialog_title = spec.dialog_title || '@i18n:objects.idview.unapply_hostgroups_all_title';
+
+    var that = idviews.unapply_host_action(spec);
+    return that;
+};
+
+/**
+ * Unapply Id view from selected hosts
+ *
+ * @class idviews.unapply_action
+ * @extends idviews.unapply_host_action
+ */
+idviews.unapply_action = function(spec) {
+
+    spec = spec || {};
+    spec.name = spec.name || 'idview_unapply';
+    spec.label = spec.label || '@i18n:objects.idview.unapply_hosts';
+    spec.enable_cond = spec.enable_cond || ['item-selected'];
+    spec.enabled = spec.enabled === undefined ? false : spec.enabled;
+    spec.confirm_button_label = spec.confirm_button_label || '@i18n:buttons.unapply';
+    spec.method = spec.method || 'unapply';
+    spec.dialog_title = spec.dialog_title || '@i18n:objects.idview.unapply_hosts_title';
+
+    var that = idviews.unapply_host_action(spec);
+
+    /**
+     * @inheritDoc
+     */
+    that.show_dialog = function(facet, current_pkeys) {
+
+        var selected_values = facet.get_selected_values();
+
+        if (!selected_values.length) {
+            var message = text.get('@i18n:dialogs.remove_empty');
+            IPA.notify(message, 'error');
+            return;
+        }
+
+        var pkey = facet.get_pkey();
+        var other_entity = reg.entity.get('host');
+        var title = text.get(that.dialog_title);
+        title = title.replace('${primary_key}', pkey);
+
+        var dialog = IPA.association_deleter_dialog({
+            title: title,
+            entity: facet.entity,
+            pkey: pkey,
+            other_entity: other_entity,
+            values: selected_values,
+            method: that.method,
+            ok_label: that.confirm_button_label,
+            message: '@i18n:objects.idview.unapply_hosts_confirm'
+        });
+
+        dialog.execute = function() {
+            var command = that.get_command(
+                facet,
+                selected_values,
+                function(data) {
+                    that.notify_change(facet);
+                    var succeeded = IPA.get_succeeded(data);
+                    var msg = text.get('@i18n:association.removed').replace('${count}', succeeded);
+                    IPA.notify_success(msg);
+                },
+                function() {
+                    that.notify_change(facet);
+                }
+            );
+            command.execute();
+        };
+
+        dialog.open();
+    };
+
+    return that;
+};
+
+/**
+ * ID View entity specification object
+ * @member idviews
+ */
+idviews.spec = make_spec();
+
+/**
+ * ID user override entity specification object
+ * @member idviews
+ */
+idviews.idoverrideuser_spec = make_idoverrideuser_spec();
+
+/**
+ * ID group override entity specification object
+ * @member idviews
+ */
+idviews.idoverridegroup_spec = make_idoverridegroup_spec();
+
+/**
+ * Register entity
+ * @member idviews
+ */
+idviews.register = function() {
+    var e = reg.entity;
+    var f = reg.facet;
+    var a = reg.action;
+    e.register({type: 'idview', spec: idviews.spec});
+    e.register({type: 'idoverrideuser', spec: idviews.idoverrideuser_spec});
+    e.register({type: 'idoverridegroup', spec: idviews.idoverridegroup_spec});
+    f.copy('attribute', 'idview_appliedtohosts', {
+        factory: idviews.appliedtohosts_facet
+    });
+    a.register('idview_apply', idviews.apply_action);
+    a.register('idview_apply_hostgroups', idviews.apply_hostgroups_action);
+    a.register('idview_unapply', idviews.unapply_action);
+    a.register('idview_unapply_host', idviews.unapply_host_action);
+    a.register('idview_unapply_hostgroups', idviews.unapply_hostgroups_action);
+};
+
+phases.on('registration', idviews.register);
+
+return idviews;
+});
diff --git a/install/ui/src/freeipa/navigation/menu_spec.js b/install/ui/src/freeipa/navigation/menu_spec.js
index 9182d11bf56c73e1fce724d438fe2211105b75ad..ca1a290f479fd0cc6a399e6bc93bd3e8ed1fca40 100644
--- a/install/ui/src/freeipa/navigation/menu_spec.js
+++ b/install/ui/src/freeipa/navigation/menu_spec.js
@@ -159,6 +159,7 @@ var nav = {};
                     ]
                 },
                 { entity: 'idrange' },
+                { entity: 'idview' },
                 { entity: 'realmdomains' },
                 {
                     name: 'trusts',
diff --git a/install/ui/test/data/ipa_init.json b/install/ui/test/data/ipa_init.json
index 2f42b3613c86894f98a41427c96849e5e6822550..dfeffd9d1924ab0a8978f2225fcac4af9f437000 100644
--- a/install/ui/test/data/ipa_init.json
+++ b/install/ui/test/data/ipa_init.json
@@ -62,6 +62,7 @@
                         "add_and_close": "Add and Close",
                         "add_and_edit": "Add and Edit",
                         "add_many": "Add Many",
+                        "apply": "Apply",
                         "back": "Back",
                         "cancel": "Cancel",
                         "close": "Close",
@@ -81,6 +82,7 @@
                         "retry": "Retry",
                         "revoke": "Revoke",
                         "set": "Set",
+                        "unapply": "Un-apply",
                         "update": "Update",
                         "view": "View"
                     },
@@ -358,6 +360,30 @@
                         "hostgroup": {
                             "identity": "Host Group Settings"
                         },
+                        "idoverrideuser": {
+                            "anchor_label": "User to override",
+                            "anchor_tooltip": "Enter trusted or IPA user login. Note: search doesn't list users from trusted domains."
+                        },
+                        "idoverridegroup": {
+                            "anchor_label": "Group to override",
+                            "anchor_tooltip": "Enter trusted or IPA group name. Note: search doesn't list groups from trusted domains."
+                        },
+                        "idview": {
+                            "appliedtohosts": "Applied to hosts",
+                            "appliedtohosts_title": "Applied to hosts",
+                            "apply_hostgroups": "Apply to host groups",
+                            "apply_hostgroups_title": "Apply ID View ${primary_key} on hosts of ${entity}",
+                            "apply_hosts": "Apply to hosts",
+                            "apply_hosts_title": "Apply ID view ${primary_key} on ${entity}",
+                            "unapply_hostgroups": "Un-apply from host groups",
+                            "unapply_hostgroups_all_title": "Un-apply ID Views from hosts of hostgroups",
+                            "unapply_hostgroups_title": "Un-apply ID View ${primary_key} from hosts of ${entity}",
+                            "unapply_hosts": "Un-apply",
+                            "unapply_hosts_all": "Un-apply from hosts",
+                            "unapply_hosts_all_title": "Un-apply ID Views from hosts",
+                            "unapply_hosts_confirm": "Are you sure you want to un-apply ID view from selected entries?",
+                            "unapply_hosts_title": "Un-apply ID View ${primary_key} from hosts"
+                        },
                         "krbtpolicy": {
                             "identity": "Kerberos Ticket Policy"
                         },
diff --git a/ipalib/plugins/internal.py b/ipalib/plugins/internal.py
index af51cab63aa748456e0442c7a2a2d857f39ed82f..c2e0bc0e8367463c04bd1606501e28fc643efe80 100644
--- a/ipalib/plugins/internal.py
+++ b/ipalib/plugins/internal.py
@@ -204,6 +204,7 @@ class i18n_messages(Command):
             "add_and_close": _("Add and Close"),
             "add_and_edit": _("Add and Edit"),
             "add_many": _("Add Many"),
+            "apply": _("Apply"),
             "back": _("Back"),
             "cancel": _("Cancel"),
             "close": _("Close"),
@@ -223,6 +224,7 @@ class i18n_messages(Command):
             "retry": _("Retry"),
             "revoke": _("Revoke"),
             "set": _("Set"),
+            "unapply": ("Un-apply"),
             "update": _("Update"),
             "view": _("View"),
         },
@@ -502,6 +504,30 @@ class i18n_messages(Command):
             "hostgroup": {
                 "identity": _("Host Group Settings"),
             },
+            "idoverrideuser": {
+                "anchor_label": _("User to override"),
+                "anchor_tooltip": _("Enter trusted or IPA user login. Note: search doesn't list users from trusted domains."),
+            },
+            "idoverridegroup": {
+                "anchor_label": _("Group to override"),
+                "anchor_tooltip": _("Enter trusted or IPA group name. Note: search doesn't list groups from trusted domains."),
+            },
+            "idview": {
+                "appliedtohosts": _("Applied to hosts"),
+                "appliedtohosts_title": _("Applied to hosts"),
+                "apply_hostgroups": _("Apply to host groups"),
+                "apply_hostgroups_title": _("Apply ID View ${primary_key} on hosts of ${entity}"),
+                "apply_hosts": _("Apply to hosts"),
+                "apply_hosts_title": _("Apply ID view ${primary_key} on ${entity}"),
+                "unapply_hostgroups": _("Un-apply from host groups"),
+                "unapply_hostgroups_all_title": _("Un-apply ID Views from hosts of hostgroups"),
+                "unapply_hostgroups_title": _("Un-apply ID View ${primary_key} from hosts of ${entity}"),
+                "unapply_hosts": _("Un-apply"),
+                "unapply_hosts_all": _("Un-apply from hosts"),
+                "unapply_hosts_all_title": _("Un-apply ID Views from hosts"),
+                "unapply_hosts_confirm": _("Are you sure you want to un-apply ID view from selected entries?"),
+                "unapply_hosts_title": _("Un-apply ID View ${primary_key} from hosts"),
+            },
             "krbtpolicy": {
                 "identity": _("Kerberos Ticket Policy"),
             },
-- 
1.9.3

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to