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 2015/12/15 18:23:16 UTC

syncope git commit: [SYNCOPE-156] providing search panel for group ownership

Repository: syncope
Updated Branches:
  refs/heads/master 3395c6ed6 -> c95ca2fd2


[SYNCOPE-156] providing search panel for group ownership


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

Branch: refs/heads/master
Commit: c95ca2fd2f47dbe680798058ed6da1827a10b1f3
Parents: 3395c6e
Author: fmartelli <fa...@gmail.com>
Authored: Tue Dec 15 18:18:08 2015 +0100
Committer: fmartelli <fa...@gmail.com>
Committed: Tue Dec 15 18:18:08 2015 +0100

----------------------------------------------------------------------
 .../panels/search/AbstractSearchPanel.java      |  47 +--
 .../panels/search/AnyObjectSearchPanel.java     |   6 +-
 .../console/panels/search/GroupSearchPanel.java |   6 +-
 .../panels/search/SearchClausePanel.java        |  80 +++--
 .../console/panels/search/UserSearchPanel.java  |  28 +-
 .../client/console/wizards/any/Ownership.java   | 290 ++++++-------------
 .../META-INF/resources/css/syncopeConsole.css   |   6 +-
 .../panels/search/SearchClausePanel.html        |   8 +
 .../client/console/wizards/any/Ownership.html   |  19 +-
 9 files changed, 238 insertions(+), 252 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/c95ca2fd/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java
index 101ecf9..9a8dad8 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java
@@ -38,7 +38,6 @@ import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.LoadableDetachableModel;
 import org.apache.wicket.model.Model;
-import org.apache.wicket.model.PropertyModel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -55,40 +54,47 @@ public abstract class AbstractSearchPanel extends Panel {
 
     protected ResourceRestClient resourceRestClient = new ResourceRestClient();
 
-//    protected AuthRestClient authRestClient;
     protected IModel<List<String>> dnames;
 
     protected IModel<List<String>> anames;
 
     protected IModel<List<String>> resourceNames;
 
-//    protected IModel<List<String>> entitlements;
     protected IModel<List<SearchClause.Type>> types;
 
     protected IModel<List<Pair<Long, String>>> groupNames;
 
     protected NotificationPanel searchFeedback;
 
-    protected PropertyModel<List<SearchClause>> model;
+    protected IModel<List<SearchClause>> model;
 
     protected WebMarkupContainer searchFormContainer;
 
-    protected AnyTypeKind typeKind;
+    protected final AnyTypeKind typeKind;
 
-    protected boolean required;
+    protected final boolean required;
+
+    protected final boolean enableSearch;
 
     public abstract static class Builder<T extends AbstractSearchPanel> implements Serializable {
 
         private static final long serialVersionUID = 6308997285778809578L;
 
-        protected final PropertyModel<List<SearchClause>> model;
+        protected final IModel<List<SearchClause>> model;
 
         protected boolean required = true;
 
-        public Builder(final PropertyModel<List<SearchClause>> model) {
+        protected boolean enableSearch = false;
+
+        public Builder(final IModel<List<SearchClause>> model) {
             this.model = model;
         }
 
+        public Builder<T> enableSearch() {
+            this.enableSearch = true;
+            return this;
+        }
+
         public Builder<T> required(final boolean required) {
             this.required = required;
             return this;
@@ -97,24 +103,15 @@ public abstract class AbstractSearchPanel extends Panel {
         public abstract T build(final String id);
     }
 
-    protected AbstractSearchPanel(
-            final String id,
-            final PropertyModel<List<SearchClause>> model,
-            final AnyTypeKind typeKind) {
-        this(id, model, typeKind, true);
-    }
-
-    protected AbstractSearchPanel(
-            final String id,
-            final PropertyModel<List<SearchClause>> model,
-            final AnyTypeKind typeKind,
-            final boolean required) {
+    protected AbstractSearchPanel(final String id, final AnyTypeKind typeKind, final Builder<?> builder) {
 
         super(id);
         populate();
 
+        this.model = builder.model;
         this.typeKind = typeKind;
-        this.required = required;
+        this.required = builder.required;
+        this.enableSearch = builder.enableSearch;
 
         setOutputMarkupId(true);
 
@@ -149,6 +146,10 @@ public abstract class AbstractSearchPanel extends Panel {
                 required,
                 types, anames, dnames, groupNames, resourceNames);
 
+        if (enableSearch) {
+            searchClausePanel.enableSearch();
+        }
+
         final MultiFieldPanel.Builder<SearchClause> searchView = new MultiFieldPanel.Builder<SearchClause>(model) {
 
             private static final long serialVersionUID = 1L;
@@ -203,4 +204,8 @@ public abstract class AbstractSearchPanel extends Panel {
     public NotificationPanel getSearchFeedback() {
         return searchFeedback;
     }
+
+    public IModel<List<SearchClause>> getModel() {
+        return this.model;
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/c95ca2fd/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnyObjectSearchPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnyObjectSearchPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnyObjectSearchPanel.java
index b5e162e..681ab1c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnyObjectSearchPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/AnyObjectSearchPanel.java
@@ -25,8 +25,8 @@ import org.apache.syncope.client.console.rest.GroupRestClient;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
+import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.LoadableDetachableModel;
-import org.apache.wicket.model.PropertyModel;
 
 public class AnyObjectSearchPanel extends AbstractSearchPanel {
 
@@ -38,7 +38,7 @@ public class AnyObjectSearchPanel extends AbstractSearchPanel {
 
         private static final long serialVersionUID = 6308997285778809578L;
 
-        public Builder(final PropertyModel<List<SearchClause>> model) {
+        public Builder(final IModel<List<SearchClause>> model) {
             super(model);
         }
 
@@ -49,7 +49,7 @@ public class AnyObjectSearchPanel extends AbstractSearchPanel {
     }
 
     protected AnyObjectSearchPanel(final String id, final AnyTypeKind kind, final Builder builder) {
-        super(id, builder.model, kind, builder.required);
+        super(id, kind, builder);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/c95ca2fd/client/console/src/main/java/org/apache/syncope/client/console/panels/search/GroupSearchPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/GroupSearchPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/GroupSearchPanel.java
index 4dfbce3..b151568 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/GroupSearchPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/GroupSearchPanel.java
@@ -23,8 +23,8 @@ import java.util.Collections;
 import java.util.List;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.LoadableDetachableModel;
-import org.apache.wicket.model.PropertyModel;
 
 public final class GroupSearchPanel extends AbstractSearchPanel {
 
@@ -34,7 +34,7 @@ public final class GroupSearchPanel extends AbstractSearchPanel {
 
         private static final long serialVersionUID = 6308997285778809578L;
 
-        public Builder(final PropertyModel<List<SearchClause>> model) {
+        public Builder(final IModel<List<SearchClause>> model) {
             super(model);
         }
 
@@ -45,7 +45,7 @@ public final class GroupSearchPanel extends AbstractSearchPanel {
     }
 
     private GroupSearchPanel(final String id, final GroupSearchPanel.Builder builder) {
-        super(id, builder.model, AnyTypeKind.USER, builder.required);
+        super(id, AnyTypeKind.USER, builder);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/c95ca2fd/client/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java
index 497a5fb..2904053 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java
@@ -20,6 +20,7 @@ package org.apache.syncope.client.console.panels.search;
 
 import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggle;
 import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggleConfig;
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -41,12 +42,15 @@ import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
-import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
+import org.apache.wicket.event.Broadcast;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.form.CheckBox;
+import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.form.FormComponent;
 import org.apache.wicket.markup.html.form.IChoiceRenderer;
 import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.panel.Fragment;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.LoadableDetachableModel;
 import org.apache.wicket.model.Model;
@@ -74,6 +78,12 @@ public class SearchClausePanel extends FieldPanel<SearchClause> {
 
     private final LoadableDetachableModel<List<Pair<Long, String>>> properties;
 
+    private final Fragment operatorFragment;
+
+    private final Fragment searchButtonFragment;
+
+    private final AjaxSubmitLink searchButton;
+
     public SearchClausePanel(
             final String id,
             final String name,
@@ -97,6 +107,22 @@ public class SearchClausePanel extends FieldPanel<SearchClause> {
         this.groupNames = groupNames;
         this.resourceNames = resourceNames;
 
+        searchButton = new AjaxSubmitLink("search") {
+
+            private static final long serialVersionUID = 5538299138211283825L;
+
+            @Override
+            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+                send(this, Broadcast.BUBBLE, new SearchEvent(target));
+            }
+
+        };
+
+        searchButtonFragment = new Fragment("operator", "searchButtonFragment", this);
+        searchButtonFragment.add(searchButton.setEnabled(false));
+
+        operatorFragment = new Fragment("operator", "operatorFragment", this);
+
         field = new FormComponent<SearchClause>("container", this.clause) {
 
             private static final long serialVersionUID = 1L;
@@ -172,6 +198,10 @@ public class SearchClausePanel extends FieldPanel<SearchClause> {
         };
     }
 
+    public void enableSearch() {
+        this.searchButton.setEnabled(true);
+    }
+
     @Override
     public SearchClause getModelObject() {
         return this.clause.getObject();
@@ -205,22 +235,8 @@ public class SearchClausePanel extends FieldPanel<SearchClause> {
     public FieldPanel<SearchClause> settingsDependingComponents() {
         final SearchClause searchClause = this.clause.getObject();
 
-        final WebMarkupContainer operatorContainer = new WebMarkupContainer("operatorContainer") {
-
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            protected void onComponentTag(final ComponentTag tag) {
-                super.onComponentTag(tag);
-                if (getIndex() == 0) {
-                    tag.append("class", "glyphicon glyphicon-search", " ");
-                }
-            }
-
-        };
-
+        final WebMarkupContainer operatorContainer = new WebMarkupContainer("operatorContainer");
         operatorContainer.setOutputMarkupId(true);
-
         field.add(operatorContainer);
 
         final BootstrapToggleConfig config = new BootstrapToggleConfig();
@@ -230,7 +246,7 @@ public class SearchClausePanel extends FieldPanel<SearchClause> {
                 .withOnLabel("AND")
                 .withOffLabel("OR");
 
-        operatorContainer.add(new BootstrapToggle("operator", new Model<Boolean>() {
+        operatorFragment.add(new BootstrapToggle("operator", new Model<Boolean>() {
 
             private static final long serialVersionUID = 1L;
 
@@ -249,12 +265,12 @@ public class SearchClausePanel extends FieldPanel<SearchClause> {
 
             @Override
             protected IModel<String> getOffLabel() {
-                return Model.of(getString("Off", null, "Off"));
+                return Model.of(getString("Off", null, "OR"));
             }
 
             @Override
             protected IModel<String> getOnLabel() {
-                return Model.of(getString("On", null, "On"));
+                return Model.of(getString("On", null, "AND"));
             }
 
             @Override
@@ -270,7 +286,13 @@ public class SearchClausePanel extends FieldPanel<SearchClause> {
                 });
                 return checkBox;
             }
-        }.setVisible(getIndex() > 0).setOutputMarkupPlaceholderTag(true));
+        }.setOutputMarkupPlaceholderTag(true));
+
+        if (getIndex() > 0) {
+            operatorContainer.add(operatorFragment);
+        } else {
+            operatorContainer.add(searchButtonFragment);
+        }
 
         final AjaxDropDownChoicePanel<Pair<Long, String>> property = new AjaxDropDownChoicePanel<Pair<Long, String>>(
                 "property", "property", new PropertyModel<Pair<Long, String>>(searchClause, "property") {
@@ -531,6 +553,9 @@ public class SearchClausePanel extends FieldPanel<SearchClause> {
                 getId(), name, null, required, types, anames, dnames, groupNames, resourceNames);
         panel.setReadOnly(this.isReadOnly());
         panel.setRequired(this.isRequired());
+        if (searchButton.isEnabled()) {
+            panel.enableSearch();
+        }
         return panel;
     }
 
@@ -582,4 +607,19 @@ public class SearchClausePanel extends FieldPanel<SearchClause> {
             });
         }
     }
+
+    protected static class SearchEvent implements Serializable {
+
+        private static final long serialVersionUID = 2693338614198749301L;
+
+        private final AjaxRequestTarget target;
+
+        public SearchEvent(final AjaxRequestTarget target) {
+            this.target = target;
+        }
+
+        public AjaxRequestTarget getTarget() {
+            return target;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/c95ca2fd/client/console/src/main/java/org/apache/syncope/client/console/panels/search/UserSearchPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/UserSearchPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/UserSearchPanel.java
index bf6a4fc..8f9af18 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/search/UserSearchPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/search/UserSearchPanel.java
@@ -19,18 +19,25 @@
 package org.apache.syncope.client.console.panels.search;
 
 import java.util.List;
+import org.apache.syncope.client.console.rest.UserRestClient;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
+import org.apache.wicket.model.IModel;
 
 public final class UserSearchPanel extends AnyObjectSearchPanel {
 
     private static final long serialVersionUID = -1769527800450203738L;
 
+    private final UserRestClient userRestClient = new UserRestClient();
+
     public static class Builder extends AnyObjectSearchPanel.Builder {
 
         private static final long serialVersionUID = 6308997285778809578L;
 
-        public Builder(final PropertyModel<List<SearchClause>> model) {
+        public Builder(final IModel<List<SearchClause>> model) {
             super(model);
         }
 
@@ -43,4 +50,21 @@ public final class UserSearchPanel extends AnyObjectSearchPanel {
     private UserSearchPanel(final String id, final Builder builder) {
         super(id, AnyTypeKind.USER, builder);
     }
+
+    @Override
+    public void onEvent(final IEvent<?> event) {
+        if (event.getPayload() instanceof SearchClausePanel.SearchEvent) {
+            final String fiql = SearchUtils.buildFIQL(
+                    UserSearchPanel.this.getModel().getObject(), SyncopeClient.getUserSearchConditionBuilder());
+
+            final List<UserTO> res = userRestClient.search(
+                    "/", fiql, 1, 50, new SortParam<>("username", true), AnyTypeKind.USER.name());
+
+            // let's provide result panel to be populated ....
+            
+        } else {
+            super.onEvent(event);
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/c95ca2fd/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Ownership.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Ownership.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Ownership.java
index 4555d12..65cc758 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Ownership.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Ownership.java
@@ -18,257 +18,155 @@
  */
 package org.apache.syncope.client.console.wizards.any;
 
-import static org.apache.syncope.client.console.wizards.any.Details.LOG;
-
-import org.apache.syncope.client.console.rest.GroupRestClient;
-import org.apache.syncope.client.console.rest.UserRestClient;
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggle;
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggleConfig;
+import java.util.ArrayList;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.panels.search.AnyObjectSearchPanel;
+import org.apache.syncope.client.console.panels.search.GroupSearchPanel;
+import org.apache.syncope.client.console.panels.search.SearchClause;
+import org.apache.syncope.client.console.panels.search.UserSearchPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.wicket.Page;
 import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.markup.html.AjaxLink;
-import org.apache.wicket.event.IEvent;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
 import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
-import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
 import org.apache.wicket.extensions.wizard.WizardStep;
 import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.CheckBox;
+import org.apache.wicket.markup.html.panel.Fragment;
 import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.util.ListModel;
 
 public class Ownership extends WizardStep {
 
     private static final long serialVersionUID = 855618618337931784L;
 
-    private final UserRestClient userRestClient = new UserRestClient();
-
-    private final GroupRestClient groupRestClient = new GroupRestClient();
-
     private final WebMarkupContainer ownerContainer;
 
-    private final OwnerModel uOwnerModel;
+    private final Fragment groupSearchFragment;
 
-    private final OwnerModel gOwnerModel;
+    private final Fragment userSearchFragment;
 
     public Ownership(final GroupHandler groupHandler) {
         super();
-        final GroupTO groupTO = GroupHandler.class.cast(groupHandler).getInnerObject();
 
-        ownerContainer = new WebMarkupContainer("ownerContainer");
-        ownerContainer.setOutputMarkupId(true);
-        this.add(ownerContainer);
+        final Model<Boolean> isGroupOwnership = Model.of(groupHandler.getInnerObject().getGroupOwner() != null);
 
-        final ModalWindow userOwnerSelectWin = new ModalWindow("userOwnerSelectWin");
-        userOwnerSelectWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
-        userOwnerSelectWin.setCookieName("create-userOwnerSelect-modal");
-        this.add(userOwnerSelectWin);
-        final ModalWindow groupOwnerSelectWin = new ModalWindow("groupOwnerSelectWin");
-        groupOwnerSelectWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
-        groupOwnerSelectWin.setCookieName("create-groupOwnerSelect-modal");
-        this.add(groupOwnerSelectWin);
-
-        uOwnerModel = new OwnerModel(groupTO, AnyTypeKind.USER);
-        @SuppressWarnings("unchecked")
-        final AjaxTextFieldPanel userOwner = new AjaxTextFieldPanel("userOwner", "userOwner", uOwnerModel, false);
-        userOwner.setPlaceholder("userOwner");
-        userOwner.hideLabel();
-        userOwner.setReadOnly(true).setOutputMarkupId(true);
-        ownerContainer.add(userOwner);
-        final AjaxLink<Void> userOwnerSelect = new IndicatingAjaxLink<Void>("userOwnerSelect") {
+        final BootstrapToggleConfig config = new BootstrapToggleConfig();
+        config
+                .withOnStyle(BootstrapToggleConfig.Style.info).withOffStyle(BootstrapToggleConfig.Style.warning)
+                .withSize(BootstrapToggleConfig.Size.mini)
+                .withOnLabel(AnyTypeKind.GROUP.name())
+                .withOffLabel(AnyTypeKind.USER.name());
 
-            private static final long serialVersionUID = -7978723352517770644L;
+        add(new BootstrapToggle("ownership", new Model<Boolean>() {
 
-            @Override
-            public void onClick(final AjaxRequestTarget target) {
-                userOwnerSelectWin.setPageCreator(new ModalWindow.PageCreator() {
-
-                    private static final long serialVersionUID = -7834632442532690940L;
-
-                    @Override
-                    public Page createPage() {
-//                        return new UserOwnerSelectModalPage(getPage().getPageReference(), userOwnerSelectWin);
-                        return null;
-                    }
-                });
-                userOwnerSelectWin.show(target);
-            }
-        };
-        ownerContainer.add(userOwnerSelect.setEnabled(false));
-        final IndicatingAjaxLink<Void> userOwnerReset = new IndicatingAjaxLink<Void>("userOwnerReset") {
-
-            private static final long serialVersionUID = -7978723352517770644L;
+            private static final long serialVersionUID = 1L;
 
             @Override
-            public void onClick(final AjaxRequestTarget target) {
-                uOwnerModel.setObject(null);
-                target.add(userOwner);
+            public Boolean getObject() {
+                return isGroupOwnership.getObject();
             }
-        };
-        ownerContainer.add(userOwnerReset.setEnabled(false));
-
-        gOwnerModel = new OwnerModel(groupTO, AnyTypeKind.GROUP);
-        @SuppressWarnings("unchecked")
-        final AjaxTextFieldPanel groupOwner = new AjaxTextFieldPanel("groupOwner", "groupOwner", gOwnerModel, false);
-        groupOwner.setPlaceholder("groupOwner");
-        groupOwner.hideLabel();
-        groupOwner.setReadOnly(true).setOutputMarkupId(true);
-        ownerContainer.add(groupOwner);
-        final AjaxLink<Void> groupOwnerSelect = new IndicatingAjaxLink<Void>("groupOwnerSelect") {
-
-            private static final long serialVersionUID = -7978723352517770644L;
 
             @Override
-            public void onClick(final AjaxRequestTarget target) {
-                userOwnerSelectWin.setPageCreator(new ModalWindow.PageCreator() {
-
-                    private static final long serialVersionUID = -7834632442532690940L;
+            public void setObject(final Boolean object) {
 
-                    @Override
-                    public Page createPage() {
-//                        return new GroupSelectModalPage(getPage().getPageReference(), userOwnerSelectWin,
-//                                GroupOwnerSelectPayload.class);
-                        return null;
-                    }
-                });
-                userOwnerSelectWin.show(target);
             }
-        };
-        ownerContainer.add(groupOwnerSelect.setEnabled(false));
-        final IndicatingAjaxLink<Void> groupOwnerReset = new IndicatingAjaxLink<Void>("groupOwnerReset") {
+        }, config) {
 
-            private static final long serialVersionUID = -7978723352517770644L;
+            private static final long serialVersionUID = 1L;
 
             @Override
-            public void onClick(final AjaxRequestTarget target) {
-                gOwnerModel.setObject(null);
-                target.add(groupOwner);
+            protected IModel<String> getOffLabel() {
+                return Model.of(getString("Off", null, "USER Owner"));
             }
-        };
-        ownerContainer.add(groupOwnerReset.setEnabled(false));
-    }
-
-    /**
-     * This is waiting for events from opened modal windows: first to get the selected user / group, then to update the
-     * respective text panel.
-     *
-     * @param event event
-     */
-    @Override
-    public void onEvent(final IEvent<?> event) {
-        super.onEvent(event);
-
-        if (event.getPayload() instanceof UserOwnerSelectPayload) {
-            uOwnerModel.setObject(((UserOwnerSelectPayload) event.getPayload()).getUserId());
-        }
-        if (event.getPayload() instanceof GroupOwnerSelectPayload) {
-            gOwnerModel.setObject(((GroupOwnerSelectPayload) event.getPayload()).getGroupId());
-        }
 
-        if (event.getPayload() instanceof AjaxRequestTarget) {
-            ((AjaxRequestTarget) event.getPayload()).add(ownerContainer);
-        }
-    }
-
-    private class OwnerModel implements IModel {
-
-        private static final long serialVersionUID = -3865621970810102714L;
-
-        private final GroupTO groupTO;
+            @Override
+            protected IModel<String> getOnLabel() {
+                return Model.of(getString("On", null, "GROUP Owner"));
+            }
 
-        private final AnyTypeKind type;
+            @Override
+            protected CheckBox newCheckBox(final String id, final IModel<Boolean> model) {
+                final CheckBox checkBox = super.newCheckBox(id, model);
+                checkBox.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
 
-        OwnerModel(final GroupTO groupTO, final AnyTypeKind type) {
-            this.groupTO = groupTO;
-            this.type = type;
-        }
+                    private static final long serialVersionUID = 1L;
 
-        @Override
-        public Object getObject() {
-            String object = null;
-
-            switch (type) {
-                case USER:
-                    if (groupTO.getUserOwner() != null) {
-                        UserTO user = null;
-                        try {
-                            user = userRestClient.read(groupTO.getUserOwner());
-                        } catch (Exception e) {
-                            LOG.warn("Could not find user with id {}, ignoring", groupTO.getUserOwner(), e);
-                        }
-                        if (user == null) {
-                            groupTO.setUserOwner(null);
-                        } else {
-                            object = user.getKey() + " " + user.getUsername();
-                        }
-                    }
-                    break;
-
-                case GROUP:
-                    GroupTO group = null;
-                    if (groupTO.getGroupOwner() != null) {
-                        try {
-                            group = groupRestClient.read(groupTO.getGroupOwner());
-                        } catch (Exception e) {
-                            LOG.warn("Could not find group with id {}, ignoring", groupTO.getGroupOwner(), e);
-                        }
-                        if (group == null) {
-                            groupTO.setGroupOwner(null);
+                    @Override
+                    protected void onUpdate(final AjaxRequestTarget target) {
+                        isGroupOwnership.setObject(!isGroupOwnership.getObject());
+                        if (isGroupOwnership.getObject()) {
+                            ownerContainer.addOrReplace(groupSearchFragment);
                         } else {
-                            object = group.getName();
+                            ownerContainer.addOrReplace(userSearchFragment);
                         }
+                        target.add(ownerContainer);
                     }
-                    break;
-
-                default:
+                });
+                return checkBox;
             }
+        });
 
-            return object;
-        }
+        ownerContainer = new WebMarkupContainer("ownerContainer");
+        ownerContainer.setOutputMarkupId(true);
+        this.add(ownerContainer);
 
-        @Override
-        public void setObject(final Object object) {
-            switch (type) {
-                case USER:
-                    groupTO.setUserOwner((Long) object);
-                    break;
+        groupSearchFragment = new Fragment("search", "groupSearchFragment", this);
+        final GroupSearchPanel groupSearchPanel = new GroupSearchPanel.Builder(
+                new ListModel<>(new ArrayList<SearchClause>())).required(false).enableSearch().build("groupsearch");
+        groupSearchFragment.add(groupSearchPanel.setRenderBodyOnly(true));
 
-                case GROUP:
-                    groupTO.setGroupOwner((Long) object);
-                    break;
+        userSearchFragment = new Fragment("search", "userSearchFragment", this);
+        final AnyObjectSearchPanel userSearchPanel = new UserSearchPanel.Builder(
+                new ListModel<>(new ArrayList<SearchClause>())).required(false).enableSearch().build("usersearch");
+        userSearchFragment.add(userSearchPanel.setRenderBodyOnly(true));
 
-                default:
-            }
+        if (isGroupOwnership.getObject()) {
+            ownerContainer.add(groupSearchFragment);
+        } else {
+            ownerContainer.add(userSearchFragment);
         }
 
-        @Override
-        public void detach() {
-            // ignore
-        }
-    }
+        final GroupTO groupTO = GroupHandler.class.cast(groupHandler).getInnerObject();
 
-    public static class UserOwnerSelectPayload {
+        final AjaxTextFieldPanel userOwner
+                = new AjaxTextFieldPanel("userOwner", "userOwner", new Model<String>(), false);
+        userOwner.setPlaceholder("userOwner");
+        userOwner.hideLabel();
+        userOwner.setReadOnly(true).setOutputMarkupId(true);
+        userSearchFragment.add(userOwner);
 
-        private final Long userId;
+        final IndicatingAjaxLink<Void> userOwnerReset = new IndicatingAjaxLink<Void>("userOwnerReset") {
 
-        public UserOwnerSelectPayload(final Long userId) {
-            this.userId = userId;
-        }
+            private static final long serialVersionUID = -7978723352517770644L;
 
-        public Long getUserId() {
-            return userId;
-        }
-    }
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                target.add(userOwner);
+            }
+        };
+        userSearchFragment.add(userOwnerReset.setEnabled(false));
 
-    public static class GroupOwnerSelectPayload {
+        final AjaxTextFieldPanel groupOwner
+                = new AjaxTextFieldPanel("groupOwner", "groupOwner", new Model<String>(), false);
+        groupOwner.setPlaceholder("groupOwner");
+        groupOwner.hideLabel();
+        groupOwner.setReadOnly(true).setOutputMarkupId(true);
+        groupSearchFragment.add(groupOwner);
 
-        private final Long groupId;
+        final IndicatingAjaxLink<Void> groupOwnerReset = new IndicatingAjaxLink<Void>("groupOwnerReset") {
 
-        public GroupOwnerSelectPayload(final Long groupId) {
-            this.groupId = groupId;
-        }
+            private static final long serialVersionUID = -7978723352517770644L;
 
-        public Long getGroupId() {
-            return groupId;
-        }
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                target.add(groupOwner);
+            }
+        };
+        groupSearchFragment.add(groupOwnerReset.setEnabled(false));
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/c95ca2fd/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css b/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
index 6d5b469..39a0942 100644
--- a/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
+++ b/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
@@ -232,7 +232,7 @@ div.basepage-content{
 
 .wizard-view > div {
   display: block;
-  height: 100%;
+  height: 98%;
   position: relative;
 }
 
@@ -334,3 +334,7 @@ div.wrap{
 END - Style for Information panel
 */
 
+#ownership div.toggle {
+  width: 110px !important;
+}
+

http://git-wip-us.apache.org/repos/asf/syncope/blob/c95ca2fd/client/console/src/main/resources/org/apache/syncope/client/console/panels/search/SearchClausePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/search/SearchClausePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/search/SearchClausePanel.html
index 5e25b0c..bf8165e 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/search/SearchClausePanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/search/SearchClausePanel.html
@@ -27,6 +27,14 @@ under the License.
         <span wicket:id="comparator" class="field comparator"/>
         <span wicket:id="value" class="field value"/>
       </span>
+
+      <wicket:fragment wicket:id="searchButtonFragment">
+        <a href="#" wicket:id="search"><li class="glyphicon glyphicon-search"></li></a>
+      </wicket:fragment>
+
+      <wicket:fragment wicket:id="operatorFragment">
+        <span wicket:id="operator"/>
+      </wicket:fragment>
     </wicket:extend>
   </body>
 </html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/c95ca2fd/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Ownership.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Ownership.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Ownership.html
index 0f1ae61..2a3a916 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Ownership.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Ownership.html
@@ -20,22 +20,29 @@ under the License.
   <head><title></title></head>
   <body>
     <wicket:panel>
+      <div id="ownership">
+        <span wicket:id="ownership">[OWNERSHIP]</span>
+      </div>
+
       <div wicket:id="ownerContainer">
+        <span wicket:id="search">[SEARCH]</span>
+      </div>
+
+      <wicket:fragment wicket:id="userSearchFragment">
         <div class="form-group input-group">
           <span wicket:id="userOwner"/>
-          <a href="#" wicket:id="userOwnerSelect" class="input-group-addon"><i class="glyphicon glyphicon-search" alt="select group owner" title="Search"></i></a>
           <a href="#" wicket:id="userOwnerReset" class="input-group-addon"><i class="glyphicon glyphicon-remove-circle" alt="reset user owner" title="Delete"></i></a>
         </div>
+        <span wicket:id="usersearch">[USER SEARCH]</span>
+      </wicket:fragment>
 
+      <wicket:fragment wicket:id="groupSearchFragment">
         <div class="form-group input-group">
           <span wicket:id="groupOwner"/>
-          <a href="#" wicket:id="groupOwnerSelect" class="input-group-addon"><i class="glyphicon glyphicon-search" alt="select group owner" title="Search"></i></a>
           <a href="#" wicket:id="groupOwnerReset" class="input-group-addon"><i class="glyphicon glyphicon-remove-circle" alt="reset group owner" title="Delete"></i></a>
         </div>
-      </div>
-
-      <span wicket:id="userOwnerSelectWin"/>
-      <span wicket:id="groupOwnerSelectWin"/>
+        <span wicket:id="groupsearch">[GROUP SEARCH]</span>
+      </wicket:fragment>
     </wicket:panel>
   </body>
 </html>