You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by fm...@apache.org on 2016/06/14 14:55:53 UTC

[2/2] syncope git commit: [SYNCOPE-860] provides role and group members inspecting feature

[SYNCOPE-860] provides role and group members inspecting feature


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/f5f6270e
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/f5f6270e
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/f5f6270e

Branch: refs/heads/master
Commit: f5f6270ef2f437a036f36e5cd6a9e31d0515e7ab
Parents: befa49c
Author: fmartelli <fa...@gmail.com>
Authored: Tue Jun 14 16:55:27 2016 +0200
Committer: fmartelli <fa...@gmail.com>
Committed: Tue Jun 14 16:55:27 2016 +0200

----------------------------------------------------------------------
 .../console/panels/AnyDirectoryPanel.java       |   6 +-
 .../console/panels/AnyObjectDirectoryPanel.java | 109 +++++++-----
 .../syncope/client/console/panels/AnyPanel.java |  23 ++-
 .../client/console/panels/DirectoryPanel.java   |  11 +-
 .../console/panels/GroupDirectoryPanel.java     | 130 +++++++++++++-
 .../client/console/panels/ListViewPanel.java    |   8 +-
 .../console/panels/MembersTogglePanel.java      | 118 +++++++++++++
 .../client/console/panels/ParametersPanel.java  |   6 +-
 .../console/panels/RoleDirectoryPanel.java      |  65 ++++++-
 .../console/panels/SecurityQuestionsPanel.java  |   6 +-
 .../console/panels/UserDirectoryPanel.java      | 139 ++++++++-------
 .../AnyObjectSelectionDirectoryPanel.java       |   8 +-
 .../search/AnySelectionDirectoryPanel.java      |   7 +-
 .../search/GroupSelectionDirectoryPanel.java    |   8 +-
 .../search/UserSelectionDirectoryPanel.java     |   8 +-
 .../wicket/markup/html/form/ActionLink.java     |   5 +
 .../markup/html/form/ActionLinksPanel.java      | 171 +++++++++++++------
 .../client/console/widgets/JobWidget.java       |  12 +-
 .../ReconciliationDetailsModalPanel.java        |   4 +-
 .../console/widgets/ReconciliationWidget.java   |  10 +-
 .../client/console/wizards/WizardMgtPanel.java  |  19 ++-
 .../console/wizards/any/Relationships.java      |   2 +-
 .../panels/GroupDirectoryPanel.properties       |   1 +
 .../panels/GroupDirectoryPanel_it.properties    |   1 +
 .../panels/GroupDirectoryPanel_pt_BR.properties |   1 +
 .../panels/GroupDirectoryPanel_ru.properties    |   1 +
 .../console/panels/MembersTogglePanel.html      |  32 ++++
 .../panels/RoleDirectoryPanel.properties        |   1 +
 .../panels/RoleDirectoryPanel_it.properties     |   1 +
 .../panels/RoleDirectoryPanel_pt_BR.properties  |   1 +
 .../panels/RoleDirectoryPanel_ru.properties     |   5 +-
 .../markup/html/form/ActionLinksPanel.html      |   5 +
 .../panels/CamelRoutesDirectoryPanel.java       |   4 +-
 .../syncope/fit/console/GroupsITCase.java       |  28 +++
 .../apache/syncope/fit/console/RolesITCase.java |  17 ++
 35 files changed, 754 insertions(+), 219 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/f5f6270e/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
index f2e8aec..256df52 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
@@ -83,7 +83,11 @@ public abstract class AnyDirectoryPanel<A extends AnyTO, E extends AbstractAnyRe
     protected final BaseModal<Serializable> utilityModal = new BaseModal<>("outer");
 
     protected AnyDirectoryPanel(final String id, final Builder<A, E> builder) {
-        super(id, builder);
+        this(id, builder, true);
+    }
+
+    protected AnyDirectoryPanel(final String id, final Builder<A, E> builder, final boolean wizardInModal) {
+        super(id, builder, wizardInModal);
         this.realm = builder.realm;
         this.type = builder.type;
         this.fiql = builder.fiql;

http://git-wip-us.apache.org/repos/asf/syncope/blob/f5f6270e/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
index ecdb0ff..5473ee0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
@@ -60,8 +60,8 @@ public class AnyObjectDirectoryPanel extends AnyDirectoryPanel<AnyObjectTO, AnyO
 
     private static final long serialVersionUID = -1100228004207271270L;
 
-    protected AnyObjectDirectoryPanel(final String id, final Builder builder) {
-        super(id, builder);
+    protected AnyObjectDirectoryPanel(final String id, final Builder builder, final boolean wizardInModal) {
+        super(id, builder, wizardInModal);
     }
 
     @Override
@@ -106,8 +106,6 @@ public class AnyObjectDirectoryPanel extends AnyDirectoryPanel<AnyObjectTO, AnyO
                     Arrays.asList(AnyObjectDisplayAttributesModalPanel.DEFAULT_SELECTION));
         }
 
-        setWindowClosedReloadCallback(displayAttributeModal);
-
         columns.add(new ActionColumn<AnyObjectTO, String>(new ResourceModel("actions")) {
 
             private static final long serialVersionUID = -3503023501954863131L;
@@ -118,24 +116,6 @@ public class AnyObjectDirectoryPanel extends AnyDirectoryPanel<AnyObjectTO, AnyO
 
                 panel.add(new ActionLink<AnyObjectTO>() {
 
-                    private static final long serialVersionUID = -7978723352517770645L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
-                        final IModel<AnyWrapper<AnyObjectTO>> formModel = new CompoundPropertyModel<>(new AnyWrapper<>(
-                                model.getObject()));
-                        altDefaultModal.setFormModel(formModel);
-
-                        target.add(altDefaultModal.setContent(new StatusModal<>(
-                                altDefaultModal, pageRef, formModel.getObject().getInnerObject(), false)));
-
-                        altDefaultModal.header(new Model<>(
-                                getString("any.edit", new Model<>(new AnyWrapper<>(model.getObject())))));
-
-                        altDefaultModal.show(true);
-                    }
-                }, ActionType.MANAGE_RESOURCES, AnyEntitlement.READ.getFor(type)).add(new ActionLink<AnyObjectTO>() {
-
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
@@ -156,31 +136,12 @@ public class AnyObjectDirectoryPanel extends AnyDirectoryPanel<AnyObjectTO, AnyO
                         send(AnyObjectDirectoryPanel.this, Broadcast.EXACT,
                                 new AjaxWizard.NewItemActionEvent<>(new AnyWrapper<>(clone), target));
                     }
-                }, ActionType.CLONE, AnyEntitlement.CREATE.getFor(type)).add(new ActionLink<AnyObjectTO>() {
-
-                    private static final long serialVersionUID = -7978723352517770644L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
-                        target.add(utilityModal.setContent(new AnyPropagationTasks(
-                                utilityModal, AnyTypeKind.ANY_OBJECT, model.getObject().getKey(), pageRef)));
-
-                        utilityModal.header(new StringResourceModel("any.propagation.tasks", model));
-                        utilityModal.show(true);
-                    }
-                }, ActionType.PROPAGATION_TASKS, StandardEntitlement.TASK_LIST).add(new ActionLink<AnyObjectTO>() {
-
-                    private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
-                        target.add(utilityModal.setContent(
-                                new NotificationTasks(AnyTypeKind.ANY_OBJECT, model.getObject().getKey(), pageRef)));
-                        utilityModal.header(new StringResourceModel("any.notification.tasks", model));
-                        utilityModal.show(true);
-                        target.add(utilityModal);
+                    protected boolean statusCondition(final AnyObjectTO modelObject) {
+                        return addAjaxLink.isVisibleInHierarchy();
                     }
-                }, ActionType.NOTIFICATION_TASKS, StandardEntitlement.TASK_LIST).add(new ActionLink<AnyObjectTO>() {
+                }, ActionType.CLONE, AnyEntitlement.CREATE.getFor(type)).add(new ActionLink<AnyObjectTO>() {
 
                     private static final long serialVersionUID = -7978723352517770646L;
 
@@ -192,13 +153,62 @@ public class AnyObjectDirectoryPanel extends AnyDirectoryPanel<AnyObjectTO, AnyO
                             target.add(container);
                         } catch (SyncopeClientException e) {
                             LOG.error("While deleting object {}", model.getObject().getKey(), e);
-                           SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
+                            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
                                     ? e.getClass().getName() : e.getMessage());
                         }
                         SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                     }
                 }, ActionType.DELETE, AnyEntitlement.DELETE.getFor(type));
 
+                if (wizardInModal) {
+                    panel.add(new ActionLink<AnyObjectTO>() {
+
+                        private static final long serialVersionUID = -7978723352517770645L;
+
+                        @Override
+                        public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
+                            final IModel<AnyWrapper<AnyObjectTO>> formModel = new CompoundPropertyModel<>(
+                                    new AnyWrapper<>(
+                                            model.getObject()));
+                            altDefaultModal.setFormModel(formModel);
+
+                            target.add(altDefaultModal.setContent(new StatusModal<>(
+                                    altDefaultModal, pageRef, formModel.getObject().getInnerObject(), false)));
+
+                            altDefaultModal.header(new Model<>(
+                                    getString("any.edit", new Model<>(new AnyWrapper<>(model.getObject())))));
+
+                            altDefaultModal.show(true);
+                        }
+                    }, ActionType.MANAGE_RESOURCES, AnyEntitlement.READ.getFor(type)).add(
+                            new ActionLink<AnyObjectTO>() {
+
+                        private static final long serialVersionUID = -7978723352517770644L;
+
+                        @Override
+                        public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
+                            target.add(utilityModal.setContent(new AnyPropagationTasks(
+                                    utilityModal, AnyTypeKind.ANY_OBJECT, model.getObject().getKey(), pageRef)));
+
+                            utilityModal.header(new StringResourceModel("any.propagation.tasks", model));
+                            utilityModal.show(true);
+                        }
+                    }, ActionType.PROPAGATION_TASKS, StandardEntitlement.TASK_LIST).add(new ActionLink<AnyObjectTO>() {
+
+                                private static final long serialVersionUID = -7978723352517770644L;
+
+                                @Override
+                                public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) {
+                                    target.add(utilityModal.setContent(
+                                            new NotificationTasks(AnyTypeKind.ANY_OBJECT, model.getObject().getKey(),
+                                                    pageRef)));
+                                    utilityModal.header(new StringResourceModel("any.notification.tasks", model));
+                                    utilityModal.show(true);
+                                    target.add(utilityModal);
+                                }
+                            }, ActionType.NOTIFICATION_TASKS, StandardEntitlement.TASK_LIST);
+                }
+
                 return panel.build(componentId, model.getObject());
             }
 
@@ -218,6 +228,11 @@ public class AnyObjectDirectoryPanel extends AnyDirectoryPanel<AnyObjectTO, AnyO
                         displayAttributeModal.header(new ResourceModel("any.attr.display"));
                         displayAttributeModal.show(true);
                     }
+
+                    @Override
+                    protected boolean statusCondition(final Serializable modelObject) {
+                        return wizardInModal;
+                    }
                 }, ActionType.CHANGE_VIEW, AnyEntitlement.READ.getFor(type)).add(
                         new ActionLink<Serializable>() {
 
@@ -250,8 +265,8 @@ public class AnyObjectDirectoryPanel extends AnyDirectoryPanel<AnyObjectTO, AnyO
         }
 
         @Override
-        protected WizardMgtPanel<AnyWrapper<AnyObjectTO>> newInstance(final String id) {
-            return new AnyObjectDirectoryPanel(id, this);
+        protected WizardMgtPanel<AnyWrapper<AnyObjectTO>> newInstance(final String id, final boolean wizardInModal) {
+            return new AnyObjectDirectoryPanel(id, this, wizardInModal);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f5f6270e/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyPanel.java
index 9a3d8c6..04d57ff 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyPanel.java
@@ -61,7 +61,7 @@ import org.apache.wicket.model.util.ListModel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class AnyPanel extends Panel {
+public class AnyPanel extends Panel implements ModalPanel {
 
     private static final long serialVersionUID = -1100228004207271270L;
 
@@ -88,6 +88,17 @@ public class AnyPanel extends Panel {
             final RealmTO realmTO,
             final Triple<UserFormLayoutInfo, GroupFormLayoutInfo, Map<String, AnyObjectFormLayoutInfo>> formLayoutInfo,
             final PageReference pageRef) {
+        this(id, anyTypeTO, realmTO, formLayoutInfo, true, pageRef);
+    }
+
+    @SuppressWarnings({ "unchecked", "unchecked" })
+    public AnyPanel(
+            final String id,
+            final AnyTypeTO anyTypeTO,
+            final RealmTO realmTO,
+            final Triple<UserFormLayoutInfo, GroupFormLayoutInfo, Map<String, AnyObjectFormLayoutInfo>> formLayoutInfo,
+            final boolean enableSearch,
+            final PageReference pageRef) {
 
         super(id);
         this.anyTypeTO = anyTypeTO;
@@ -136,7 +147,7 @@ public class AnyPanel extends Panel {
             }
         };
         accordion.setOutputMarkupId(true);
-        add(accordion);
+        add(accordion.setEnabled(enableSearch).setVisible(enableSearch));
 
         directoryPanel = getDirectoryPanel("searchResult");
         add(directoryPanel);
@@ -197,7 +208,7 @@ public class AnyPanel extends Panel {
         return panel;
     }
 
-    private Panel getDirectoryPanel(final String id) {
+    protected Panel getDirectoryPanel(final String id) {
         final Panel panel;
         final String fiql;
         switch (anyTypeTO.getKind()) {
@@ -209,7 +220,7 @@ public class AnyPanel extends Panel {
                         anyTypeClassRestClient.list(anyTypeTO.getClasses()),
                         anyTypeTO.getKey(),
                         pageRef).setRealm(realmTO.getFullPath()).setFiltered(true).
-                        setFiql(fiql).addNewItemPanelBuilder(FormLayoutInfoUtils.instantiate(
+                        setFiql(fiql).setWizardInModal(true).addNewItemPanelBuilder(FormLayoutInfoUtils.instantiate(
                         userTO,
                         anyTypeTO.getClasses(),
                         formLayoutInfo.getLeft(),
@@ -225,7 +236,7 @@ public class AnyPanel extends Panel {
                         anyTypeClassRestClient.list(anyTypeTO.getClasses()),
                         anyTypeTO.getKey(),
                         pageRef).setRealm(realmTO.getFullPath()).setFiltered(true).
-                        setFiql(fiql).addNewItemPanelBuilder(FormLayoutInfoUtils.instantiate(
+                        setFiql(fiql).setWizardInModal(true).addNewItemPanelBuilder(FormLayoutInfoUtils.instantiate(
                         groupTO,
                         anyTypeTO.getClasses(),
                         formLayoutInfo.getMiddle(),
@@ -243,7 +254,7 @@ public class AnyPanel extends Panel {
                         anyTypeClassRestClient.list(anyTypeTO.getClasses()),
                         anyTypeTO.getKey(),
                         pageRef).setRealm(realmTO.getFullPath()).setFiltered(true).
-                        setFiql(fiql).addNewItemPanelBuilder(FormLayoutInfoUtils.instantiate(
+                        setFiql(fiql).setWizardInModal(true).addNewItemPanelBuilder(FormLayoutInfoUtils.instantiate(
                         anyObjectTO,
                         anyTypeTO.getClasses(),
                         formLayoutInfo.getRight().get(anyTypeTO.getKey()),

http://git-wip-us.apache.org/repos/asf/syncope/blob/f5f6270e/client/console/src/main/java/org/apache/syncope/client/console/panels/DirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/DirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/DirectoryPanel.java
index 1ce1f19..330590e 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/DirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/DirectoryPanel.java
@@ -117,7 +117,7 @@ public abstract class DirectoryPanel<
             private static final long serialVersionUID = -8424727765826509309L;
 
             @Override
-            protected WizardMgtPanel<W> newInstance(final String id) {
+            protected WizardMgtPanel<W> newInstance(final String id, final boolean wizardInModal) {
                 throw new UnsupportedOperationException("Not supported yet.");
             }
         }.setFiltered(false), wizardInModal);
@@ -160,9 +160,12 @@ public abstract class DirectoryPanel<
 
             @Override
             public void onClose(final AjaxRequestTarget target) {
-                DirectoryPanel.EventDataWrapper event = new DirectoryPanel.EventDataWrapper();
-                event.setTarget(target);
-                send(DirectoryPanel.this, Broadcast.EXACT, event);
+                final EventDataWrapper data = new EventDataWrapper();
+                data.setTarget(target);
+                data.setRows(rows);
+
+                send(DirectoryPanel.this, Broadcast.EXACT, data);
+
                 modal.show(false);
             }
         });

http://git-wip-us.apache.org/repos/asf/syncope/blob/f5f6270e/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
index 60d70b9..3da0f44 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
@@ -25,9 +25,13 @@ import java.util.Arrays;
 import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.layout.FormLayoutInfoUtils;
 import org.apache.syncope.client.console.notifications.NotificationTasks;
+import org.apache.syncope.client.console.rest.AnyTypeClassRestClient;
+import org.apache.syncope.client.console.rest.AnyTypeRestClient;
 import org.apache.syncope.client.console.rest.GroupRestClient;
 import org.apache.syncope.client.console.status.StatusModal;
 import org.apache.syncope.client.console.tasks.AnyPropagationTasks;
@@ -41,17 +45,25 @@ import org.apache.syncope.client.console.wizards.AjaxWizard;
 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
 import org.apache.syncope.client.console.wizards.any.AnyWrapper;
 import org.apache.syncope.client.console.wizards.any.GroupWrapper;
+import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.to.AnyTypeTO;
 import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyEntitlement;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.BulkMembersActionType;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
 import org.apache.wicket.event.Broadcast;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.CompoundPropertyModel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
@@ -65,13 +77,103 @@ public class GroupDirectoryPanel extends AnyDirectoryPanel<GroupTO, GroupRestCli
 
     private final BaseModal<Serializable> typeExtensionsModal = new BaseModal<>("outer");
 
-    protected GroupDirectoryPanel(final String id, final Builder builder) {
-        super(id, builder);
+    protected final BaseModal<Serializable> membersModal = new BaseModal<>("outer");
+
+    protected final MembersTogglePanel templates;
+
+    protected GroupDirectoryPanel(final String id, final Builder builder, final boolean wizardInModal) {
+        super(id, builder, wizardInModal);
 
         typeExtensionsModal.size(Modal.Size.Large);
         addOuterObject(typeExtensionsModal);
         setWindowClosedReloadCallback(typeExtensionsModal);
         typeExtensionsModal.addSubmitButton();
+
+        addOuterObject(membersModal);
+        membersModal.size(Modal.Size.Large);
+
+        templates = new MembersTogglePanel(page.getPageReference()) {
+
+            private static final long serialVersionUID = -8765794727538618705L;
+
+            @Override
+            protected Serializable onApplyInternal(
+                    final GroupTO groupTO, final String type, final AjaxRequestTarget target) {
+
+                final AnyTypeRestClient typeRestClient = new AnyTypeRestClient();
+                final AnyTypeClassRestClient classRestClient = new AnyTypeClassRestClient();
+
+                final AnyTypeTO anyTypeTO = typeRestClient.read(type);
+
+                ModalPanel panel = new AnyPanel(BaseModal.CONTENT_ID, anyTypeTO, null, null, false, pageRef) {
+
+                    private static final long serialVersionUID = 1L;
+
+                    @Override
+                    protected Panel getDirectoryPanel(final String id) {
+
+                        final Panel panel;
+
+                        if (AnyTypeKind.USER.name().equals(type)) {
+                            String query = SyncopeClient.getUserSearchConditionBuilder().and(
+                                    SyncopeClient.getUserSearchConditionBuilder().inGroups(groupTO.getKey()),
+                                    SyncopeClient.getUserSearchConditionBuilder().is("key").notNullValue()).query();
+
+                            panel = new UserDirectoryPanel.Builder(
+                                    classRestClient.list(anyTypeTO.getClasses()), anyTypeTO.getKey(), pageRef).
+                                    setRealm("/").
+                                    setFiltered(true).
+                                    setFiql(query).
+                                    disableCheckBoxes().
+                                    addNewItemPanelBuilder(FormLayoutInfoUtils.instantiate(
+                                            new UserTO(),
+                                            anyTypeTO.getClasses(),
+                                            FormLayoutInfoUtils.fetch(typeRestClient.list()).getLeft(),
+                                            pageRef), false).
+                                    setWizardInModal(false).build(id);
+
+                            MetaDataRoleAuthorizationStrategy.authorize(
+                                    panel, WebPage.RENDER, StandardEntitlement.USER_LIST);
+                        } else {
+                            String query = SyncopeClient.getAnyObjectSearchConditionBuilder(type).and(
+                                    SyncopeClient.getUserSearchConditionBuilder().inGroups(groupTO.getKey()),
+                                    SyncopeClient.getUserSearchConditionBuilder().is("key").notNullValue()).query();
+
+                            panel = new AnyObjectDirectoryPanel.Builder(
+                                    classRestClient.list(anyTypeTO.getClasses()), anyTypeTO.getKey(), pageRef).
+                                    setRealm("/").
+                                    setFiltered(true).
+                                    setFiql(query).
+                                    disableCheckBoxes().
+                                    addNewItemPanelBuilder(FormLayoutInfoUtils.instantiate(
+                                            new AnyObjectTO(),
+                                            anyTypeTO.getClasses(),
+                                            FormLayoutInfoUtils.fetch(typeRestClient.list()).getRight().get(type),
+                                            pageRef), false).
+                                    setWizardInModal(false).build(id);
+
+                            MetaDataRoleAuthorizationStrategy.authorize(
+                                    panel, WebPage.RENDER, AnyEntitlement.LIST.getFor(anyTypeTO.getKey()));
+                        }
+
+                        return panel;
+                    }
+                };
+
+                membersModal.header(new StringResourceModel(
+                        "group.members",
+                        GroupDirectoryPanel.this,
+                        Model.of(Pair.of(groupTO, type))));
+
+                membersModal.setContent(panel);
+                membersModal.show(true);
+                target.add(membersModal);
+
+                return null;
+            }
+        };
+
+        addOuterObject(templates);
     }
 
     @Override
@@ -125,6 +227,20 @@ public class GroupDirectoryPanel extends AnyDirectoryPanel<GroupTO, GroupRestCli
 
                     @Override
                     public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
+                        templates.setTargetObject(model.getObject());
+                        templates.toggle(target, true);
+                    }
+
+                    @Override
+                    public boolean isIndicatorEnabled() {
+                        return false;
+                    }
+                }, ActionType.MEMBERS, StandardEntitlement.GROUP_READ).add(new ActionLink<GroupTO>() {
+
+                    private static final long serialVersionUID = -7978723352517770645L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target, final GroupTO ignore) {
                         IModel<AnyWrapper<GroupTO>> formModel = new CompoundPropertyModel<>(
                                 new AnyWrapper<>(model.getObject()));
                         altDefaultModal.setFormModel(formModel);
@@ -203,7 +319,7 @@ public class GroupDirectoryPanel extends AnyDirectoryPanel<GroupTO, GroupRestCli
                             target.add(container);
                         } catch (SyncopeClientException e) {
                             LOG.error("While deleting object {}", model.getObject().getKey(), e);
-                           SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
+                            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
                                     ? e.getClass().getName() : e.getMessage());
                         }
                         SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
@@ -220,7 +336,7 @@ public class GroupDirectoryPanel extends AnyDirectoryPanel<GroupTO, GroupRestCli
                             target.add(container);
                         } catch (SyncopeClientException e) {
                             LOG.error("While provisioning members of group {}", model.getObject().getKey(), e);
-                           SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
+                            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
                                     ? e.getClass().getName() : e.getMessage());
                         }
                         SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
@@ -239,7 +355,7 @@ public class GroupDirectoryPanel extends AnyDirectoryPanel<GroupTO, GroupRestCli
                             target.add(container);
                         } catch (SyncopeClientException e) {
                             LOG.error("While provisioning members of group {}", model.getObject().getKey(), e);
-                           SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
+                            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
                                     ? e.getClass().getName() : e.getMessage());
                         }
                         SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
@@ -293,8 +409,8 @@ public class GroupDirectoryPanel extends AnyDirectoryPanel<GroupTO, GroupRestCli
         }
 
         @Override
-        protected WizardMgtPanel<AnyWrapper<GroupTO>> newInstance(final String id) {
-            return new GroupDirectoryPanel(id, this);
+        protected WizardMgtPanel<AnyWrapper<GroupTO>> newInstance(final String id, final boolean wizardInModal) {
+            return new GroupDirectoryPanel(id, this, wizardInModal);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f5f6270e/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
index ca63496..b649c4f 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
@@ -100,8 +100,9 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
             final ActionLinksPanel.Builder<T> actions,
             final CheckAvailability check,
             final boolean reuseItem,
+            final boolean wizardInModal,
             final IModel<? extends Collection<T>> model) {
-        super(id);
+        super(id, wizardInModal);
         setOutputMarkupId(true);
 
         this.check = Model.of(check);
@@ -354,8 +355,9 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
         }
 
         @Override
-        protected WizardMgtPanel<T> newInstance(final String id) {
-            return new ListViewPanel<T>(id, items, reference, includes, actions, check, reuseItem, model) {
+        protected WizardMgtPanel<T> newInstance(final String id, final boolean wizardInModal) {
+            return new ListViewPanel<T>(
+                    id, items, reference, includes, actions, check, reuseItem, wizardInModal, model) {
 
                 private static final long serialVersionUID = 1L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f5f6270e/client/console/src/main/java/org/apache/syncope/client/console/panels/MembersTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/MembersTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/MembersTogglePanel.java
new file mode 100644
index 0000000..1b8695c
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/MembersTogglePanel.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.rest.AnyTypeRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
+import org.apache.syncope.common.lib.EntityTOUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AnyTypeTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.model.LoadableDetachableModel;
+import org.apache.wicket.model.Model;
+
+public abstract class MembersTogglePanel extends TogglePanel<Serializable> {
+
+    private static final long serialVersionUID = -3195479265440591519L;
+
+    private GroupTO groupTO;
+
+    protected final Form<?> form;
+
+    protected final Model<String> typeModel = new Model<>();
+
+    private final LoadableDetachableModel<List<String>> anyTypes = new LoadableDetachableModel<List<String>>() {
+
+        private static final long serialVersionUID = 5275935387613157437L;
+
+        @Override
+        protected List<String> load() {
+            final List<String> res = new ArrayList<>();
+            CollectionUtils.collect(
+                    CollectionUtils.select(new AnyTypeRestClient().list(), new Predicate<AnyTypeTO>() {
+
+                        @Override
+                        public boolean evaluate(final AnyTypeTO object) {
+                            return object.getKind() != AnyTypeKind.GROUP;
+                        }
+                    }), EntityTOUtils.<AnyTypeTO>keyTransformer(), res);
+            return res;
+        }
+    };
+
+    public MembersTogglePanel(final PageReference pageRef) {
+        super("outer", "groupMembers");
+        this.pageRef = pageRef;
+
+        form = new Form<>("membersForm");
+        addInnerObject(form);
+
+        final FieldPanel<String> type = new AjaxDropDownChoicePanel<>("type", "type", typeModel, false).
+                setChoices(anyTypes).
+                setStyleSheet("form-control").
+                setRequired(true);
+
+        type.hideLabel();
+        form.add(type);
+
+        form.add(new AjaxSubmitLink("changeit", form) {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+                try {
+                    onApplyInternal(groupTO, typeModel.getObject(), target);
+                    toggle(target, false);
+                } catch (SyncopeClientException e) {
+                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
+                            ? e.getClass().getName()
+                            : e.getMessage());
+                    LOG.error("While inspecting group memebers of type {}", typeModel.getObject(), e);
+                }
+                SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
+            }
+
+            @Override
+            protected void onError(final AjaxRequestTarget target, final Form<?> form) {
+                SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
+            }
+        });
+    }
+
+    protected abstract Serializable onApplyInternal(
+            final GroupTO groupTO, final String type, final AjaxRequestTarget target);
+
+    public void setTargetObject(final GroupTO groupTO) {
+        this.groupTO = groupTO;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f5f6270e/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersPanel.java
index 00e274a..e1fbfe1 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersPanel.java
@@ -77,8 +77,8 @@ public class ParametersPanel extends DirectoryPanel<
             private static final long serialVersionUID = 8769126634538601689L;
 
             @Override
-            protected WizardMgtPanel<AttrTO> newInstance(final String id) {
-                return new ParametersPanel(id, this);
+            protected WizardMgtPanel<AttrTO> newInstance(final String id, final boolean wizardInModal) {
+                throw new UnsupportedOperationException();
             }
         });
 
@@ -173,7 +173,7 @@ public class ParametersPanel extends DirectoryPanel<
                                     target.add(container);
                                 } catch (Exception e) {
                                     LOG.error("While deleting {}", model.getObject(), e);
-                                   SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
+                                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
                                             ? e.getClass().getName() : e.getMessage());
                                 }
                                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);

http://git-wip-us.apache.org/repos/asf/syncope/blob/f5f6270e/client/console/src/main/java/org/apache/syncope/client/console/panels/RoleDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RoleDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RoleDirectoryPanel.java
index fb7fa26..1bcd7bb 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/RoleDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/RoleDirectoryPanel.java
@@ -29,6 +29,9 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.RoleDataProvider;
+import org.apache.syncope.client.console.layout.FormLayoutInfoUtils;
+import org.apache.syncope.client.console.rest.AnyTypeClassRestClient;
+import org.apache.syncope.client.console.rest.AnyTypeRestClient;
 import org.apache.syncope.client.console.rest.RoleRestClient;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.ActionColumn;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
@@ -38,8 +41,12 @@ import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPane
 import org.apache.syncope.client.console.wizards.AjaxWizard;
 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
 import org.apache.syncope.client.console.wizards.role.RoleWrapper;
+import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AnyTypeTO;
 import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -47,8 +54,11 @@ import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDa
 import org.apache.wicket.event.Broadcast;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.model.StringResourceModel;
 
 public class RoleDirectoryPanel extends DirectoryPanel<RoleTO, RoleWrapper, RoleDataProvider, RoleRestClient> {
 
@@ -56,6 +66,8 @@ public class RoleDirectoryPanel extends DirectoryPanel<RoleTO, RoleWrapper, Role
 
     protected final BaseModal<Serializable> utilityModal = new BaseModal<>("outer");
 
+    protected final BaseModal<Serializable> membersModal = new BaseModal<>("outer");
+
     protected RoleDirectoryPanel(final String id, final Builder builder) {
         super(id, builder);
         setShowResultPage(true);
@@ -68,6 +80,9 @@ public class RoleDirectoryPanel extends DirectoryPanel<RoleTO, RoleWrapper, Role
         utilityModal.size(Modal.Size.Large);
         utilityModal.addSubmitButton();
 
+        addOuterObject(membersModal);
+        membersModal.size(Modal.Size.Large);
+
         MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, ENABLE, StandardEntitlement.ROLE_CREATE);
     }
 
@@ -106,6 +121,54 @@ public class RoleDirectoryPanel extends DirectoryPanel<RoleTO, RoleWrapper, Role
 
                     @Override
                     public void onClick(final AjaxRequestTarget target, final RoleTO ignore) {
+                        final String query = SyncopeClient.getUserSearchConditionBuilder().and(
+                                SyncopeClient.getUserSearchConditionBuilder().inRoles(model.getObject().getKey()),
+                                SyncopeClient.getUserSearchConditionBuilder().is("key").notNullValue()).query();
+
+                        final AnyTypeRestClient typeRestClient = new AnyTypeRestClient();
+                        final AnyTypeClassRestClient classRestClient = new AnyTypeClassRestClient();
+
+                        final AnyTypeTO anyTypeTO = typeRestClient.read(AnyTypeKind.USER.name());
+
+                        ModalPanel panel = new AnyPanel(BaseModal.CONTENT_ID, anyTypeTO, null, null, false, pageRef) {
+
+                            private static final long serialVersionUID = 1L;
+
+                            @Override
+                            protected Panel getDirectoryPanel(final String id) {
+                                final Panel panel = new UserDirectoryPanel.Builder(
+                                        classRestClient.list(anyTypeTO.getClasses()), anyTypeTO.getKey(), pageRef).
+                                        setRealm("/").
+                                        setFiltered(true).
+                                        setFiql(query).
+                                        disableCheckBoxes().
+                                        addNewItemPanelBuilder(FormLayoutInfoUtils.instantiate(
+                                                new UserTO(),
+                                                anyTypeTO.getClasses(),
+                                                FormLayoutInfoUtils.fetch(typeRestClient.list()).getLeft(),
+                                                pageRef), false).
+                                        setWizardInModal(false).build(id);
+
+                                MetaDataRoleAuthorizationStrategy.authorize(
+                                        panel,
+                                        WebPage.RENDER,
+                                        StandardEntitlement.USER_LIST);
+
+                                return panel;
+                            }
+                        };
+
+                        membersModal.header(new StringResourceModel("role.members", RoleDirectoryPanel.this, model));
+                        membersModal.setContent(panel);
+                        membersModal.show(true);
+                        target.add(membersModal);
+                    }
+                }, ActionLink.ActionType.MEMBERS, StandardEntitlement.USER_LIST).add(new ActionLink<RoleTO>() {
+
+                    private static final long serialVersionUID = -7978723352517770644L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target, final RoleTO ignore) {
                         send(RoleDirectoryPanel.this, Broadcast.EXACT,
                                 new AjaxWizard.EditItemActionEvent<>(
                                         new RoleWrapper(new RoleRestClient().read(model.getObject().getKey())),
@@ -197,7 +260,7 @@ public class RoleDirectoryPanel extends DirectoryPanel<RoleTO, RoleWrapper, Role
         }
 
         @Override
-        protected WizardMgtPanel<RoleWrapper> newInstance(final String id) {
+        protected WizardMgtPanel<RoleWrapper> newInstance(final String id, final boolean wizardInModal) {
             return new RoleDirectoryPanel(id, this);
         }
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f5f6270e/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsPanel.java
index 2d65fbd..03af4fe 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsPanel.java
@@ -63,8 +63,8 @@ public class SecurityQuestionsPanel extends DirectoryPanel<
             private static final long serialVersionUID = 8769126634538601689L;
 
             @Override
-            protected WizardMgtPanel<SecurityQuestionTO> newInstance(final String id) {
-                return new SecurityQuestionsPanel(id, this);
+            protected WizardMgtPanel<SecurityQuestionTO> newInstance(final String id, final boolean wizardInModal) {
+                throw new UnsupportedOperationException();
             }
         }.disableCheckBoxes());
 
@@ -153,7 +153,7 @@ public class SecurityQuestionsPanel extends DirectoryPanel<
                                     target.add(container);
                                 } catch (Exception e) {
                                     LOG.error("While deleting {}", model.getObject(), e);
-                                   SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
+                                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
                                             ? e.getClass().getName() : e.getMessage());
                                 }
                                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);

http://git-wip-us.apache.org/repos/asf/syncope/blob/f5f6270e/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
index 920ad11..fed9254 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
@@ -62,7 +62,11 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient
     private static final long serialVersionUID = -1100228004207271270L;
 
     protected UserDirectoryPanel(final String id, final Builder builder) {
-        super(id, builder);
+        this(id, builder, true);
+    }
+
+    protected UserDirectoryPanel(final String id, final Builder builder, final boolean wizardInModal) {
+        super(id, builder, wizardInModal);
     }
 
     @Override
@@ -146,42 +150,6 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient
 
                     @Override
                     public void onClick(final AjaxRequestTarget target, final UserTO ignore) {
-                        IModel<AnyWrapper<UserTO>> formModel = new CompoundPropertyModel<>(
-                                new AnyWrapper<>(model.getObject()));
-                        altDefaultModal.setFormModel(formModel);
-
-                        target.add(altDefaultModal.setContent(new StatusModal<>(
-                                altDefaultModal, pageRef, formModel.getObject().getInnerObject(), false)));
-
-                        altDefaultModal.header(new Model<>(
-                                getString("any.edit", new Model<>(new AnyWrapper<>(model.getObject())))));
-
-                        altDefaultModal.show(true);
-                    }
-                }, ActionType.MANAGE_RESOURCES, StandardEntitlement.USER_READ).add(new ActionLink<UserTO>() {
-
-                    private static final long serialVersionUID = -7978723352517770644L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final UserTO ignore) {
-                        IModel<AnyWrapper<UserTO>> formModel = new CompoundPropertyModel<>(
-                                new AnyWrapper<>(model.getObject()));
-                        altDefaultModal.setFormModel(formModel);
-
-                        target.add(altDefaultModal.setContent(new StatusModal<>(
-                                altDefaultModal, pageRef, formModel.getObject().getInnerObject(), true)));
-
-                        altDefaultModal.header(new Model<>(
-                                getString("any.edit", new Model<>(new AnyWrapper<>(model.getObject())))));
-
-                        altDefaultModal.show(true);
-                    }
-                }, ActionType.ENABLE, StandardEntitlement.USER_READ).add(new ActionLink<UserTO>() {
-
-                    private static final long serialVersionUID = -7978723352517770644L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final UserTO ignore) {
                         send(UserDirectoryPanel.this, Broadcast.EXACT,
                                 new AjaxWizard.EditItemActionEvent<>(
                                         new UserWrapper(new UserRestClient().read(model.getObject().getKey())),
@@ -199,31 +167,13 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient
                         send(UserDirectoryPanel.this, Broadcast.EXACT,
                                 new AjaxWizard.NewItemActionEvent<>(new UserWrapper(clone), target));
                     }
-                }, ActionType.CLONE, StandardEntitlement.USER_CREATE).add(new ActionLink<UserTO>() {
-
-                    private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    public void onClick(final AjaxRequestTarget target, final UserTO ignore) {
-                        target.add(utilityModal.setContent(new AnyPropagationTasks(
-                                utilityModal, AnyTypeKind.USER, model.getObject().getKey(), pageRef)));
-
-                        utilityModal.header(new StringResourceModel("any.propagation.tasks", model));
-                        utilityModal.show(true);
+                    protected boolean statusCondition(final UserTO modelObject) {
+                        return addAjaxLink.isVisibleInHierarchy();
                     }
-                }, ActionType.PROPAGATION_TASKS, StandardEntitlement.TASK_LIST).add(new ActionLink<UserTO>() {
-
-                    private static final long serialVersionUID = -7978723352517770644L;
 
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final UserTO ignore) {
-                        target.add(utilityModal.setContent(
-                                new NotificationTasks(AnyTypeKind.USER, model.getObject().getKey(), pageRef)));
-                        utilityModal.header(new StringResourceModel("any.notification.tasks", model));
-                        utilityModal.show(true);
-                        target.add(utilityModal);
-                    }
-                }, ActionType.NOTIFICATION_TASKS, StandardEntitlement.TASK_LIST).add(new ActionLink<UserTO>() {
+                }, ActionType.CLONE, StandardEntitlement.USER_CREATE).add(new ActionLink<UserTO>() {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
@@ -242,6 +192,70 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient
                     }
                 }, ActionType.DELETE, StandardEntitlement.USER_DELETE);
 
+                if (wizardInModal) {
+                    panel.add(new ActionLink<UserTO>() {
+
+                        private static final long serialVersionUID = -7978723352517770644L;
+
+                        @Override
+                        public void onClick(final AjaxRequestTarget target, final UserTO ignore) {
+                            IModel<AnyWrapper<UserTO>> formModel = new CompoundPropertyModel<>(
+                                    new AnyWrapper<>(model.getObject()));
+                            altDefaultModal.setFormModel(formModel);
+
+                            target.add(altDefaultModal.setContent(new StatusModal<>(
+                                    altDefaultModal, pageRef, formModel.getObject().getInnerObject(), false)));
+
+                            altDefaultModal.header(new Model<>(
+                                    getString("any.edit", new Model<>(new AnyWrapper<>(model.getObject())))));
+
+                            altDefaultModal.show(true);
+                        }
+                    }, ActionType.MANAGE_RESOURCES, StandardEntitlement.USER_READ).add(new ActionLink<UserTO>() {
+
+                        private static final long serialVersionUID = -7978723352517770644L;
+
+                        @Override
+                        public void onClick(final AjaxRequestTarget target, final UserTO ignore) {
+                            IModel<AnyWrapper<UserTO>> formModel = new CompoundPropertyModel<>(
+                                    new AnyWrapper<>(model.getObject()));
+                            altDefaultModal.setFormModel(formModel);
+
+                            target.add(altDefaultModal.setContent(new StatusModal<>(
+                                    altDefaultModal, pageRef, formModel.getObject().getInnerObject(), true)));
+
+                            altDefaultModal.header(new Model<>(
+                                    getString("any.edit", new Model<>(new AnyWrapper<>(model.getObject())))));
+
+                            altDefaultModal.show(true);
+                        }
+                    }, ActionType.ENABLE, StandardEntitlement.USER_READ).add(new ActionLink<UserTO>() {
+
+                        private static final long serialVersionUID = -7978723352517770644L;
+
+                        @Override
+                        public void onClick(final AjaxRequestTarget target, final UserTO ignore) {
+                            target.add(utilityModal.setContent(new AnyPropagationTasks(
+                                    utilityModal, AnyTypeKind.USER, model.getObject().getKey(), pageRef)));
+
+                            utilityModal.header(new StringResourceModel("any.propagation.tasks", model));
+                            utilityModal.show(true);
+                        }
+                    }, ActionType.PROPAGATION_TASKS, StandardEntitlement.TASK_LIST).add(new ActionLink<UserTO>() {
+
+                        private static final long serialVersionUID = -7978723352517770644L;
+
+                        @Override
+                        public void onClick(final AjaxRequestTarget target, final UserTO ignore) {
+                            target.add(utilityModal.setContent(
+                                    new NotificationTasks(AnyTypeKind.USER, model.getObject().getKey(), pageRef)));
+                            utilityModal.header(new StringResourceModel("any.notification.tasks", model));
+                            utilityModal.show(true);
+                            target.add(utilityModal);
+                        }
+                    }, ActionType.NOTIFICATION_TASKS, StandardEntitlement.TASK_LIST);
+                }
+
                 return panel.build(componentId, model.getObject());
             }
 
@@ -262,6 +276,11 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient
                         displayAttributeModal.addSubmitButton();
                         displayAttributeModal.show(true);
                     }
+
+                    @Override
+                    protected boolean statusCondition(final Serializable modelObject) {
+                        return wizardInModal;
+                    }
                 }, ActionType.CHANGE_VIEW, StandardEntitlement.USER_READ).add(
                         new ActionLink<Serializable>() {
 
@@ -290,8 +309,8 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient
         }
 
         @Override
-        protected WizardMgtPanel<AnyWrapper<UserTO>> newInstance(final String id) {
-            return new UserDirectoryPanel(id, this);
+        protected WizardMgtPanel<AnyWrapper<UserTO>> newInstance(final String id, final boolean wizardInModal) {
+            return new UserDirectoryPanel(id, this, wizardInModal);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f5f6270e/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnyObjectSelectionDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnyObjectSelectionDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnyObjectSelectionDirectoryPanel.java
index e9eb5bf..d89b3ea 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnyObjectSelectionDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnyObjectSelectionDirectoryPanel.java
@@ -33,8 +33,8 @@ public final class AnyObjectSelectionDirectoryPanel
 
     private static final long serialVersionUID = -1100228004207271272L;
 
-    private AnyObjectSelectionDirectoryPanel(final String id, final Builder builder) {
-        super(id, builder, AnyObjectTO.class);
+    private AnyObjectSelectionDirectoryPanel(final String id, final Builder builder, final boolean wizardInModal) {
+        super(id, builder, AnyObjectTO.class, wizardInModal);
     }
 
     @Override
@@ -73,8 +73,8 @@ public final class AnyObjectSelectionDirectoryPanel
         }
 
         @Override
-        protected WizardMgtPanel<AnyWrapper<AnyObjectTO>> newInstance(final String id) {
-            return new AnyObjectSelectionDirectoryPanel(id, this);
+        protected WizardMgtPanel<AnyWrapper<AnyObjectTO>> newInstance(final String id, final boolean wizardInModal) {
+            return new AnyObjectSelectionDirectoryPanel(id, this, wizardInModal);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f5f6270e/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnySelectionDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnySelectionDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnySelectionDirectoryPanel.java
index 3a0815c..5919dee 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnySelectionDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnySelectionDirectoryPanel.java
@@ -61,9 +61,12 @@ public abstract class AnySelectionDirectoryPanel<A extends AnyTO, E extends Abst
     private final Class<A> reference;
 
     protected AnySelectionDirectoryPanel(
-            final String id, final AnyDirectoryPanel.Builder<A, E> builder, final Class<A> reference) {
+            final String id,
+            final AnyDirectoryPanel.Builder<A, E> builder,
+            final Class<A> reference,
+            final boolean wizardInModal) {
 
-        super(id, builder);
+        super(id, builder, wizardInModal);
         this.reference = reference;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f5f6270e/client/console/src/main/java/org/apache/syncope/client/console/panels/search/GroupSelectionDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/GroupSelectionDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/GroupSelectionDirectoryPanel.java
index 0076af9..65c7bd6 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/GroupSelectionDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/GroupSelectionDirectoryPanel.java
@@ -32,8 +32,8 @@ public final class GroupSelectionDirectoryPanel extends AnySelectionDirectoryPan
 
     private static final long serialVersionUID = -1100228004207271271L;
 
-    private GroupSelectionDirectoryPanel(final String id, final Builder builder) {
-        super(id, builder, GroupTO.class);
+    private GroupSelectionDirectoryPanel(final String id, final Builder builder, final boolean wizardInModal) {
+        super(id, builder, GroupTO.class, wizardInModal);
     }
 
     @Override
@@ -72,8 +72,8 @@ public final class GroupSelectionDirectoryPanel extends AnySelectionDirectoryPan
         }
 
         @Override
-        protected WizardMgtPanel<AnyWrapper<GroupTO>> newInstance(final String id) {
-            return new GroupSelectionDirectoryPanel(id, this);
+        protected WizardMgtPanel<AnyWrapper<GroupTO>> newInstance(final String id, final boolean wizardInModal) {
+            return new GroupSelectionDirectoryPanel(id, this, wizardInModal);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f5f6270e/client/console/src/main/java/org/apache/syncope/client/console/panels/search/UserSelectionDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/UserSelectionDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/UserSelectionDirectoryPanel.java
index 7545ec7..c3c8825 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/UserSelectionDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/UserSelectionDirectoryPanel.java
@@ -32,8 +32,8 @@ public final class UserSelectionDirectoryPanel extends AnySelectionDirectoryPane
 
     private static final long serialVersionUID = -1100228004207271272L;
 
-    private UserSelectionDirectoryPanel(final String id, final Builder builder) {
-        super(id, builder, UserTO.class);
+    private UserSelectionDirectoryPanel(final String id, final Builder builder, final boolean wizardInModal) {
+        super(id, builder, UserTO.class, wizardInModal);
     }
 
     @Override
@@ -72,8 +72,8 @@ public final class UserSelectionDirectoryPanel extends AnySelectionDirectoryPane
         }
 
         @Override
-        protected WizardMgtPanel<AnyWrapper<UserTO>> newInstance(final String id) {
-            return new UserSelectionDirectoryPanel(id, this);
+        protected WizardMgtPanel<AnyWrapper<UserTO>> newInstance(final String id, final boolean wizardInModal) {
+            return new UserSelectionDirectoryPanel(id, this, wizardInModal);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f5f6270e/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
index 4faf86e..f772eec 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
@@ -58,6 +58,7 @@ public abstract class ActionLink<T extends Serializable> implements Serializable
         ENABLE("update"),
         NOT_FOND("read"),
         VIEW("view"),
+        MEMBERS("members"),
         SEARCH("search"),
         DELETE("delete"),
         EXECUTE("execute"),
@@ -132,4 +133,8 @@ public abstract class ActionLink<T extends Serializable> implements Serializable
     public final boolean isEnabled(final T modelObject) {
         return this.enabled && statusCondition(modelObject);
     }
+
+    public boolean isIndicatorEnabled() {
+        return true;
+    }
 }