syncope-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fmarte...@apache.org
Subject syncope git commit: profides bulk actions support
Date Fri, 04 Mar 2016 16:09:50 GMT
Repository: syncope
Updated Branches:
  refs/heads/master 3826d0238 -> 48b5a10f4


profides bulk actions support


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

Branch: refs/heads/master
Commit: 48b5a10f49e659d6fc24e116d4c56307ac9721c9
Parents: 3826d02
Author: fmartelli <fabio.martelli@gmail.com>
Authored: Fri Mar 4 17:09:30 2016 +0100
Committer: fmartelli <fabio.martelli@gmail.com>
Committed: Fri Mar 4 17:09:30 2016 +0100

----------------------------------------------------------------------
 .../syncope/client/console/pages/Realms.java    |  45 +--
 .../syncope/client/console/panels/Realm.java    |   1 -
 .../client/console/panels/RealmChoicePanel.java | 254 +++++++++++++++++
 .../console/panels/RealmSidebarPanel.java       | 271 ------------------
 .../console/status/StatusSearchResultPanel.java |   2 +-
 .../client/console/tasks/PropagationTasks.java  |   2 +-
 .../syncope/client/console/tasks/PushTasks.java |   2 +-
 .../client/console/tasks/SchedTasks.java        |   2 +-
 .../syncope/client/console/tasks/SyncTasks.java |   2 +-
 .../console/tasks/TaskExecutionDetails.java     |   5 +-
 .../client/console/tasks/TaskExecutions.java    |  22 +-
 .../markup/html/form/ActionLinksPanel.java      |   8 +-
 .../html/form/IndicatingOnConfirmAjaxLink.java  |  10 +-
 .../META-INF/resources/css/syncopeConsole.css   |  30 +-
 .../syncope/client/console/pages/Realms.html    |  61 +---
 .../client/console/panels/RealmChoicePanel.html |  30 ++
 .../console/panels/RealmSidebarPanel.html       |  52 ----
 .../tasks/TaskExecutionDetails.properties       |   2 +-
 .../tasks/TaskExecutionDetails_it.properties    |   2 +-
 .../tasks/TaskExecutionDetails_pt_BR.properties |   2 +-
 .../rest/cxf/service/AbstractAnyService.java    |   4 +-
 .../fit/console/AbstractConsoleITCase.java      |   6 +-
 .../fit/console/AbstractTypesITCase.java        |   2 +-
 .../syncope/fit/console/BulkActionITCase.java   | 280 +++++++++++++++++++
 .../syncope/fit/console/RealmsITCase.java       |   2 +-
 .../apache/syncope/fit/console/RolesITCase.java |   4 +-
 .../fit/console/SecurityQuestionsITCase.java    |  13 +-
 27 files changed, 688 insertions(+), 428 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
index e52af24..2db04c4 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
@@ -22,8 +22,8 @@ import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.panels.Realm;
 import org.apache.syncope.client.console.panels.RealmModalPanel;
-import org.apache.syncope.client.console.panels.RealmSidebarPanel;
-import org.apache.syncope.client.console.panels.RealmSidebarPanel.ControlSidebarClick;
+import org.apache.syncope.client.console.panels.RealmChoicePanel;
+import org.apache.syncope.client.console.panels.RealmChoicePanel.ChoosenRealm;
 import org.apache.syncope.client.console.rest.RealmRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.common.lib.to.RealmTO;
@@ -43,7 +43,7 @@ public class Realms extends BasePage {
 
     private final RealmRestClient realmRestClient = new RealmRestClient();
 
-    private final RealmSidebarPanel realmSidebarPanel;
+    private final RealmChoicePanel realmChoicePanel;
 
     private final WebMarkupContainer content;
 
@@ -52,13 +52,12 @@ public class Realms extends BasePage {
     public Realms(final PageParameters parameters) {
         super(parameters);
 
-        realmSidebarPanel = new RealmSidebarPanel("realmSidebarPanel", getPageReference());
-        realmSidebarPanel.setMarkupId("sidebar");
-        realmSidebarPanel.setOutputMarkupId(true);
-        body.add(realmSidebarPanel);
-
         content = new WebMarkupContainer("content");
-        content.add(new Label("header", "Root realm"));
+
+        realmChoicePanel = new RealmChoicePanel("realmChoicePanel", getPageReference());
+        realmChoicePanel.setOutputMarkupId(true);
+        content.add(realmChoicePanel);
+
         content.add(new Label("body", "Root realm"));
         content.setOutputMarkupId(true);
         body.add(content);
@@ -72,29 +71,30 @@ public class Realms extends BasePage {
 
             @Override
             public void onClose(final AjaxRequestTarget target) {
-                target.add(realmSidebarPanel.reloadRealmTree());
-                target.add(updateRealmContent(realmSidebarPanel.getCurrentRealm()));
+                target.add(realmChoicePanel.reloadRealmTree(target));
                 modal.show(false);
             }
         });
 
-        updateRealmContent(realmSidebarPanel.getCurrentRealm());
+        updateRealmContent(realmChoicePanel.getCurrentRealm());
     }
 
     @Override
     public void onEvent(final IEvent<?> event) {
         super.onEvent(event);
 
-        if (event.getPayload() instanceof ControlSidebarClick) {
+        if (event.getPayload() instanceof ChoosenRealm) {
             @SuppressWarnings("unchecked")
-            final ControlSidebarClick<RealmTO> controlSidebarClick = ControlSidebarClick.class.cast(event.getPayload());
-            updateRealmContent(controlSidebarClick.getObj());
-            controlSidebarClick.getTarget().add(content);
+            final ChoosenRealm<RealmTO> choosenRealm = ChoosenRealm.class.cast(event.getPayload());
+            updateRealmContent(choosenRealm.getObj());
+            choosenRealm.getTarget().add(content);
         }
     }
 
     private WebMarkupContainer updateRealmContent(final RealmTO realmTO) {
-        content.addOrReplace(new Label("header", realmTO.getFullPath()));
+        if (realmTO == null) {
+            return content;
+        }
         content.addOrReplace(new Realm("body", realmTO, getPageReference()) {
 
             private static final long serialVersionUID = 8221398624379357183L;
@@ -111,7 +111,7 @@ public class Realms extends BasePage {
                         modal,
                         Realms.this.getPageReference(),
                         newRealmTO,
-                        realmSidebarPanel.getCurrentRealm().getFullPath(),
+                        realmChoicePanel.getCurrentRealm().getFullPath(),
                         StandardEntitlement.REALM_CREATE,
                         true);
                 target.add(modal.setContent(panel));
@@ -122,7 +122,7 @@ public class Realms extends BasePage {
 
             @Override
             protected void onClickEdit(final AjaxRequestTarget target, final RealmTO realmTO) {
-                modal.header(Model.of(realmSidebarPanel.getCurrentRealm().getName()));
+                modal.header(Model.of(realmChoicePanel.getCurrentRealm().getName()));
 
                 modal.setFormModel(realmTO);
 
@@ -146,8 +146,11 @@ public class Realms extends BasePage {
                         throw new Exception("Root realm cannot be deleted");
                     }
                     realmRestClient.delete(realmTO.getFullPath());
-                    target.add(realmSidebarPanel.reloadRealmTree());
-                    target.add(updateRealmContent(realmSidebarPanel.getCurrentRealm()));
+                    RealmTO parent = realmChoicePanel.moveToParentRealm(realmTO.getKey());
+                    target.add(realmChoicePanel.reloadRealmTree(target));
+
+                    updateRealmContent(parent);
+                    target.add(content);
                     info(getString(Constants.OPERATION_SUCCEEDED));
                 } catch (Exception e) {
                     LOG.error("While deleting realm", e);

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
index c4309d2..183e23e 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
@@ -142,7 +142,6 @@ public abstract class Realm extends Panel {
 
     private Panel getAnyPanel(final String id, final PageReference pageReference, final AnyTypeTO anyTypeTO) {
         final Panel panel;
-
         switch (anyTypeTO.getKind()) {
             case USER:
                 final UserTO userTO = new UserTO();

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
new file mode 100644
index 0000000..0a33538
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
@@ -0,0 +1,254 @@
+/*
+ * 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 de.agilecoders.wicket.core.markup.html.bootstrap.behavior.AlignmentBehavior;
+import de.agilecoders.wicket.core.markup.html.bootstrap.button.BootstrapAjaxLink;
+import de.agilecoders.wicket.core.markup.html.bootstrap.button.ButtonList;
+import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
+import de.agilecoders.wicket.core.markup.html.bootstrap.button.dropdown.DropDownButton;
+import de.agilecoders.wicket.core.markup.html.bootstrap.image.GlyphIconType;
+import de.agilecoders.wicket.core.markup.html.bootstrap.image.IconType;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.client.console.rest.RealmRestClient;
+import org.apache.syncope.common.lib.to.RealmTO;
+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.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.link.AbstractLink;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.LoadableDetachableModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+
+public class RealmChoicePanel extends Panel {
+
+    private static final long serialVersionUID = -1100228004207271270L;
+
+    private final RealmRestClient realmRestClient = new RealmRestClient();
+
+    private final PageReference pageRef;
+
+    private final LoadableDetachableModel<List<Pair<String, RealmTO>>> ldm;
+
+    private final WebMarkupContainer container;
+
+    private final Model<RealmTO> model;
+
+    private final Map<Long, Pair<RealmTO, List<RealmTO>>> tree;
+
+    public RealmChoicePanel(final String id, final PageReference pageRef) {
+        super(id);
+        this.pageRef = pageRef;
+        tree = new HashMap<>();
+
+        final RealmTO def = new RealmTO();
+        def.setName("/");
+        def.setFullPath("/");
+        model = Model.of(def);
+
+        ldm = new LoadableDetachableModel<List<Pair<String, RealmTO>>>() {
+
+            private static final long serialVersionUID = -7688359318035249200L;
+
+            private void getChildren(
+                    final List<Pair<String, RealmTO>> full,
+                    final long key,
+                    final Map<Long, Pair<RealmTO, List<RealmTO>>> tree,
+                    final String indent) {
+
+                if (tree.containsKey(key)) {
+                    Pair<RealmTO, List<RealmTO>> subtree = tree.get(key);
+                    for (RealmTO child : subtree.getValue()) {
+                        full.add(Pair.of(indent + child.getName(), child));
+                        getChildren(full, child.getKey(), tree, "     " + indent + (indent.isEmpty() ? "|--- " : ""));
+                    }
+                }
+            }
+
+            @Override
+            protected List<Pair<String, RealmTO>> load() {
+                final List<Pair<String, RealmTO>> full = new ArrayList<>();
+                getChildren(full, 0L, reloadRealmParentMap(), StringUtils.EMPTY);
+                return full;
+            }
+        };
+
+        container = new WebMarkupContainer("container", ldm);
+        container.setOutputMarkupId(true);
+        add(container);
+
+        reloadRealmTree();
+    }
+
+    public final void reloadRealmTree() {
+        final Label label = new Label("realm", model.getObject().getFullPath());
+        label.setOutputMarkupId(true);
+        container.addOrReplace(label);
+
+        final DropDownButton realms = new DropDownButton(
+                "realms", new ResourceModel("select", ""), new Model<IconType>(GlyphIconType.folderopen)) {
+
+            private static final long serialVersionUID = -5560086780455361131L;
+
+            @Override
+            protected List<AbstractLink> newSubMenuButtons(final String buttonMarkupId) {
+                List<AbstractLink> links = new ArrayList<>();
+
+                for (Pair<String, RealmTO> link : ldm.getObject()) {
+                    final RealmTO realmTO = link.getValue();
+                    links.add(new BootstrapAjaxLink<String>(
+                            ButtonList.getButtonMarkupId(),
+                            new Model<String>(),
+                            Buttons.Type.Link,
+                            new Model<>(link.getKey())) {
+
+                        private static final long serialVersionUID = -7978723352517770644L;
+
+                        @Override
+                        public void onClick(final AjaxRequestTarget target) {
+                            model.setObject(realmTO);
+                            label.setDefaultModelObject(model.getObject().getFullPath());
+                            target.add(label);
+                            send(pageRef.getPage(), Broadcast.EXACT, new ChoosenRealm<>(realmTO, target));
+                        }
+                    });
+                }
+                return links;
+            }
+        };
+        realms.setOutputMarkupId(true);
+        realms.setAlignment(AlignmentBehavior.Alignment.RIGHT);
+        realms.setType(Buttons.Type.Menu);
+
+        MetaDataRoleAuthorizationStrategy.authorize(realms, ENABLE, StandardEntitlement.REALM_LIST);
+
+        container.addOrReplace(realms);
+    }
+
+    public final RealmChoicePanel reloadRealmTree(final AjaxRequestTarget target) {
+        reloadRealmTree();
+        target.add(container);
+        return this;
+    }
+
+    private Map<Long, Pair<RealmTO, List<RealmTO>>> reloadRealmParentMap() {
+        final List<RealmTO> realms = realmRestClient.list();
+        Collections.sort(realms, new RealmNameComparator());
+        return reloadRealmParentMap(realms);
+    }
+
+    private Map<Long, Pair<RealmTO, List<RealmTO>>> reloadRealmParentMap(final List<RealmTO> realms) {
+        tree.clear();
+        tree.put(0L, Pair.<RealmTO, List<RealmTO>>of(realms.get(0), new ArrayList<RealmTO>()));
+
+        final Map<Long, List<RealmTO>> cache = new HashMap<>();
+
+        for (RealmTO realm : realms) {
+            final List<RealmTO> children = new ArrayList<>();
+            tree.put(realm.getKey(), Pair.<RealmTO, List<RealmTO>>of(realm, children));
+
+            if (cache.containsKey(realm.getKey())) {
+                children.addAll(cache.get(realm.getKey()));
+                cache.remove(realm.getKey());
+            }
+
+            if (tree.containsKey(realm.getParent())) {
+                tree.get(realm.getParent()).getRight().add(realm);
+            } else if (cache.containsKey(realm.getParent())) {
+                cache.get(realm.getParent()).add(realm);
+            } else {
+                cache.put(realm.getParent(), new ArrayList<>(Collections.singleton(realm)));
+            }
+        }
+
+        return tree;
+    }
+
+    private static class RealmNameComparator implements Comparator<RealmTO>, Serializable {
+
+        private static final long serialVersionUID = 7085057398406518811L;
+
+        @Override
+        public int compare(final RealmTO r1, final RealmTO r2) {
+            if (r1 == null && r2 == null) {
+                return 0;
+            } else if (r1 != null && r2 != null) {
+                return r1.getName().compareTo(r2.getName());
+            } else if (r1 == null && r2 != null) {
+                return -1;
+            } else {
+                return 1;
+            }
+        }
+    }
+
+    /**
+     * Gets current selected realm.
+     *
+     * @return selected realm.
+     */
+    public RealmTO getCurrentRealm() {
+        return model.getObject();
+    }
+
+    public RealmTO moveToParentRealm(final long key) {
+        for (Pair<RealmTO, List<RealmTO>> subtree : tree.values()) {
+            for (RealmTO child : subtree.getRight()) {
+                if (child.getKey() == key) {
+                    model.setObject(subtree.getLeft());
+                    return subtree.getLeft();
+                }
+            }
+        }
+        return null;
+    }
+
+    public static class ChoosenRealm<T> {
+
+        private final AjaxRequestTarget target;
+
+        private final T obj;
+
+        public ChoosenRealm(final T obj, final AjaxRequestTarget target) {
+            this.obj = obj;
+            this.target = target;
+        }
+
+        public T getObj() {
+            return obj;
+        }
+
+        public AjaxRequestTarget getTarget() {
+            return target;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmSidebarPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmSidebarPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmSidebarPanel.java
deleted file mode 100644
index 6436354..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmSidebarPanel.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * 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.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.client.console.panels.RealmSidebarPanel.ControlSidebarClick;
-import org.apache.syncope.client.console.rest.RealmRestClient;
-import org.apache.syncope.common.lib.to.RealmTO;
-import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.wicket.MarkupContainer;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.markup.html.AjaxLink;
-import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
-import org.apache.wicket.event.Broadcast;
-import org.apache.wicket.markup.ComponentTag;
-import org.apache.wicket.markup.head.IHeaderResponse;
-import org.apache.wicket.markup.head.OnLoadHeaderItem;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.html.link.Link;
-import org.apache.wicket.markup.html.panel.Fragment;
-import org.apache.wicket.markup.html.panel.Panel;
-import org.apache.wicket.markup.repeater.RepeatingView;
-import org.apache.wicket.model.PropertyModel;
-
-public class RealmSidebarPanel extends Panel {
-
-    private static final long serialVersionUID = -1100228004207271270L;
-
-    private final RealmRestClient realmRestClient = new RealmRestClient();
-
-    private final WebMarkupContainer menu;
-
-    private List<RealmTO> currentPath;
-
-    private final PageReference pageRef;
-
-    private Map<Long, Pair<RealmTO, List<RealmTO>>> tree;
-
-    private boolean reload = false;
-
-    public RealmSidebarPanel(final String id, final PageReference pageRef) {
-        super(id);
-        this.pageRef = pageRef;
-
-        final List<RealmTO> realms = realmRestClient.list();
-        Collections.sort(realms, new RealmNameComparator());
-
-        menu = new WebMarkupContainer("menu");
-        menu.setOutputMarkupId(true);
-        add(menu);
-
-        reloadRealmTree(reloadRealmParentMap(realms), 0L, menu);
-    }
-
-    public final RealmSidebarPanel reloadRealmTree() {
-        reloadRealmTree(reloadRealmParentMap(), 0L, menu);
-        return this;
-    }
-
-    private MarkupContainer reloadRealmTree(
-            final Map<Long, Pair<RealmTO, List<RealmTO>>> parentMap, final Long key, final MarkupContainer container) {
-
-        // set the current active path base on the current parent map
-        setCurrentRealm(getCurrentRealm());
-
-        final RepeatingView listItems = new RepeatingView("list");
-        listItems.setOutputMarkupId(true);
-        container.addOrReplace(listItems);
-
-        if (!parentMap.containsKey(key)) {
-            return container;
-        }
-
-        for (final RealmTO realm : parentMap.get(key).getRight()) {
-            final Fragment fragment;
-
-            final AjaxLink<Void> link = new AjaxLink<Void>("link") {
-
-                private static final long serialVersionUID = -7978723352517770644L;
-
-                @Override
-                public void onClick(final AjaxRequestTarget target) {
-                    RealmSidebarPanel.this.setCurrentRealm(realm);
-                    send(pageRef.getPage(), Broadcast.EXACT, new ControlSidebarClick<>(realm, target));
-                }
-
-                @Override
-                protected void onComponentTag(final ComponentTag tag) {
-                    super.onComponentTag(tag);
-                    tag.put("href", "#");
-                }
-            };
-
-            link.setMarkupId("item-" + realm.getKey());
-            link.addOrReplace(new Label("name", new PropertyModel<String>(realm, "name")));
-
-            if (parentMap.containsKey(realm.getKey()) && !parentMap.get(realm.getKey()).getRight().isEmpty()) {
-                fragment = new Fragment(String.valueOf(realm.getKey()), "withChildren", RealmSidebarPanel.this);
-
-                final Link<Void> angle = new Link<Void>("angle") {
-
-                    private static final long serialVersionUID = -7978723352517770644L;
-
-                    @Override
-                    public void onClick() {
-                    }
-
-                    @Override
-                    protected void onComponentTag(final ComponentTag tag) {
-                        super.onComponentTag(tag);
-                        tag.put("href", "#");
-                    }
-                };
-
-                angle.setMarkupId("angle-" + realm.getKey());
-                fragment.addOrReplace(angle);
-
-                final WebMarkupContainer subtree = new WebMarkupContainer("subtree");
-                subtree.setOutputMarkupId(true);
-                subtree.setMarkupId("subtree");
-                fragment.add(subtree);
-
-                reloadRealmTree(parentMap, realm.getKey(), subtree);
-            } else {
-                fragment = new Fragment(String.valueOf(realm.getKey()), "withoutChildren", RealmSidebarPanel.this);
-            }
-
-            fragment.addOrReplace(link);
-            fragment.setOutputMarkupId(true);
-            listItems.addOrReplace(fragment);
-
-            MetaDataRoleAuthorizationStrategy.authorize(link, ENABLE, StandardEntitlement.REALM_LIST);
-        }
-
-        return container;
-    }
-
-    private Map<Long, Pair<RealmTO, List<RealmTO>>> reloadRealmParentMap() {
-        final List<RealmTO> realms = realmRestClient.list();
-        Collections.sort(realms, new RealmNameComparator());
-        return reloadRealmParentMap(realms);
-    }
-
-    private Map<Long, Pair<RealmTO, List<RealmTO>>> reloadRealmParentMap(final List<RealmTO> realms) {
-        tree = new HashMap<>();
-        tree.put(0L, Pair.<RealmTO, List<RealmTO>>of(realms.get(0), new ArrayList<RealmTO>()));
-
-        final Map<Long, List<RealmTO>> cache = new HashMap<>();
-
-        for (RealmTO realm : realms) {
-            final List<RealmTO> children = new ArrayList<>();
-            tree.put(realm.getKey(), Pair.<RealmTO, List<RealmTO>>of(realm, children));
-
-            if (cache.containsKey(realm.getKey())) {
-                children.addAll(cache.get(realm.getKey()));
-                cache.remove(realm.getKey());
-            }
-
-            if (tree.containsKey(realm.getParent())) {
-                tree.get(realm.getParent()).getRight().add(realm);
-            } else if (cache.containsKey(realm.getParent())) {
-                cache.get(realm.getParent()).add(realm);
-            } else {
-                cache.put(realm.getParent(), new ArrayList<>(Collections.singleton(realm)));
-            }
-        }
-
-        return tree;
-    }
-
-    private static class RealmNameComparator implements Comparator<RealmTO>, Serializable {
-
-        private static final long serialVersionUID = 7085057398406518811L;
-
-        @Override
-        public int compare(final RealmTO r1, final RealmTO r2) {
-            if (r1 == null && r2 == null) {
-                return 0;
-            } else if (r1 != null && r2 != null) {
-                return r1.getName().compareTo(r2.getName());
-            } else if (r1 == null && r2 != null) {
-                return -1;
-            } else {
-                return 1;
-            }
-        }
-    }
-
-    public final void setCurrentRealm(final RealmTO realmTO) {
-        RealmTO realm;
-
-        if (tree.containsKey(realmTO.getKey())) {
-            realm = tree.get(realmTO.getKey()).getLeft();
-        } else if (tree.containsKey(realmTO.getParent())) {
-            realm = tree.get(realmTO.getParent()).getLeft();
-        } else {
-            realm = tree.get(0L).getLeft();
-        }
-
-        this.currentPath = new ArrayList<>();
-        this.currentPath.add(realm);
-
-        while (realm.getParent() != 0L) {
-            realm = tree.get(realm.getParent()).getLeft();
-            this.currentPath.add(realm);
-        }
-    }
-
-    public RealmTO getCurrentRealm() {
-        return this.currentPath == null || this.currentPath.isEmpty()
-                ? tree.get(0L).getLeft() : this.currentPath.get(0);
-    }
-
-    public static class ControlSidebarClick<T> {
-
-        private final AjaxRequestTarget target;
-
-        private final T obj;
-
-        public ControlSidebarClick(final T obj, final AjaxRequestTarget target) {
-            this.obj = obj;
-            this.target = target;
-        }
-
-        public T getObj() {
-            return obj;
-        }
-
-        public AjaxRequestTarget getTarget() {
-            return target;
-        }
-    }
-
-    @Override
-    public void renderHead(final IHeaderResponse response) {
-        if (reload) {
-            response.render(OnLoadHeaderItem.forScript("$.AdminLTE.tree('.syncopeSidebar');"));
-
-            for (RealmTO realm : this.currentPath.subList(1, this.currentPath.size())) {
-                response.render(OnLoadHeaderItem.forScript(String.format("$('#angle-%d').click();", realm.getKey())));
-            }
-        } else {
-            reload = true;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/client/console/src/main/java/org/apache/syncope/client/console/status/StatusSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/status/StatusSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/status/StatusSearchResultPanel.java
index cfd370e..11adf29 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/status/StatusSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/status/StatusSearchResultPanel.java
@@ -64,7 +64,7 @@ public class StatusSearchResultPanel
 
     private final BaseModal<?> baseModal;
 
-    protected final MultilevelPanel multiLevelPanelRef;
+    private final MultilevelPanel multiLevelPanelRef;
 
     private final AnyTO anyTO;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/client/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTasks.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTasks.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTasks.java
index d1ca6ca..7f3bb9c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTasks.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTasks.java
@@ -42,7 +42,7 @@ public class PropagationTasks extends AbstractTasks {
 
             @Override
             protected void viewTask(final PropagationTaskTO taskTO, final AjaxRequestTarget target) {
-                mlp.next("task.view", new TaskExecutionDetails<>(taskTO, pageReference), target);
+                mlp.next("task.view", new TaskExecutionDetails<>(baseModal, taskTO, pageReference), target);
             }
         });
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/client/console/src/main/java/org/apache/syncope/client/console/tasks/PushTasks.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/PushTasks.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/PushTasks.java
index 058c0c5..87810aa 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/PushTasks.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/PushTasks.java
@@ -46,7 +46,7 @@ public class PushTasks extends AbstractTasks {
             protected void viewTask(final PushTaskTO taskTO, final AjaxRequestTarget target) {
                 mlp.next(
                         new StringResourceModel("task.view", this, new Model<>(taskTO)).getObject(),
-                        new TaskExecutionDetails<>(taskTO, pageReference), target);
+                        new TaskExecutionDetails<>(baseModal, taskTO, pageReference), target);
             }
         });
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTasks.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTasks.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTasks.java
index 3dc3cc1..7ca1f16 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTasks.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTasks.java
@@ -46,7 +46,7 @@ public class SchedTasks extends AbstractTasks {
             protected void viewTask(final SchedTaskTO taskTO, final AjaxRequestTarget target) {
                 mlp.next(
                         new StringResourceModel("task.view", this, new Model<>(taskTO)).getObject(),
-                        new TaskExecutionDetails<>(taskTO, pageReference), target);
+                        new TaskExecutionDetails<>(baseModal, taskTO, pageReference), target);
             }
         });
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/client/console/src/main/java/org/apache/syncope/client/console/tasks/SyncTasks.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SyncTasks.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SyncTasks.java
index 6429d66..b03af35 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SyncTasks.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SyncTasks.java
@@ -46,7 +46,7 @@ public class SyncTasks extends AbstractTasks {
             protected void viewTask(final SyncTaskTO taskTO, final AjaxRequestTarget target) {
                 mlp.next(
                         new StringResourceModel("task.view", this, new Model<>(taskTO)).getObject(),
-                        new TaskExecutionDetails<>(taskTO, pageReference), target);
+                        new TaskExecutionDetails<>(baseModal, taskTO, pageReference), target);
             }
         });
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskExecutionDetails.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskExecutionDetails.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskExecutionDetails.java
index 8b6e447..e02e6c5 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskExecutionDetails.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskExecutionDetails.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.client.console.tasks;
 
 import org.apache.syncope.client.console.panels.MultilevelPanel;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.common.lib.to.AbstractTaskTO;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -32,13 +33,13 @@ public class TaskExecutionDetails<T extends AbstractTaskTO> extends MultilevelPa
 
     private static final long serialVersionUID = -4110576026663173545L;
 
-    public TaskExecutionDetails(final T taskTO, final PageReference pageRef) {
+    public TaskExecutionDetails(final BaseModal<?> baseModal, final T taskTO, final PageReference pageRef) {
         super();
 
         final MultilevelPanel mlp = new MultilevelPanel("executions");
         add(mlp);
 
-        mlp.setFirstLevel(new TaskExecutions(MultilevelPanel.FIRST_LEVEL_ID, taskTO, pageRef) {
+        mlp.setFirstLevel(new TaskExecutions(baseModal, mlp, taskTO, pageRef) {
 
             private static final long serialVersionUID = 5691719817252887541L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskExecutions.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskExecutions.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskExecutions.java
index 9fc136d..1d08460 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskExecutions.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskExecutions.java
@@ -29,11 +29,14 @@ import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.SearchableDataProvider;
 import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
 import org.apache.syncope.client.console.panels.AbstractSearchResultPanel;
+import org.apache.syncope.client.console.panels.AjaxDataTablePanel;
+import org.apache.syncope.client.console.panels.MultilevelPanel;
 import org.apache.syncope.client.console.panels.MultilevelPanel.SecondLevel;
 import org.apache.syncope.client.console.rest.TaskRestClient;
 import org.apache.syncope.client.console.tasks.TaskExecutions.TaskExecProvider;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.ActionColumn;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.DatePropertyColumn;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
 import org.apache.syncope.common.lib.SyncopeClientException;
@@ -54,18 +57,33 @@ public abstract class TaskExecutions
 
     private static final long serialVersionUID = 2039393934721149162L;
 
+    private final BaseModal<?> baseModal;
+
+    private final MultilevelPanel multiLevelPanelRef;
+
     protected TaskRestClient taskRestClient = new TaskRestClient();
 
     private final AbstractTaskTO taskTO;
 
-    public TaskExecutions(final String id, final AbstractTaskTO taskTO, final PageReference pageRef) {
-        super(id, pageRef, false);
+    public TaskExecutions(
+            final BaseModal<?> baseModal,
+            final MultilevelPanel multiLevelPanelRef,
+            final AbstractTaskTO taskTO,
+            final PageReference pageRef) {
+        super(MultilevelPanel.FIRST_LEVEL_ID, pageRef, false);
+        this.baseModal = baseModal;
+        this.multiLevelPanelRef = multiLevelPanelRef;
         restClient = taskRestClient;
         setOutputMarkupId(true);
         this.taskTO = taskTO;
         initResultTable();
     }
 
+    @Override
+    protected void resultTableCustomChanges(final AjaxDataTablePanel.Builder<ExecTO, String> resultTableBuilder) {
+        resultTableBuilder.setMultiLevelPanel(baseModal, multiLevelPanelRef);
+    }
+
     protected abstract void next(final String title, final SecondLevel secondLevel, final AjaxRequestTarget target);
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java
index b3e989d..de7baf5 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.java
@@ -443,7 +443,7 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
             case DELETE:
                 fragment = new Fragment("panelDelete", "fragmentDelete", this);
 
-                fragment.addOrReplace(new IndicatingOnConfirmAjaxLink<Void>("deleteLink") {
+                fragment.addOrReplace(new IndicatingOnConfirmAjaxLink<Void>("deleteLink", enabled) {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
@@ -601,7 +601,7 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
             case UNLINK:
                 fragment = new Fragment("panelUnlink", "fragmentUnlink", this);
 
-                fragment.addOrReplace(new IndicatingOnConfirmAjaxLink<Void>("unlinkLink", "confirmUnlink") {
+                fragment.addOrReplace(new IndicatingOnConfirmAjaxLink<Void>("unlinkLink", "confirmUnlink", enabled) {
 
                     private static final long serialVersionUID = -6957616042924610293L;
 
@@ -640,7 +640,7 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                 fragment = new Fragment("panelUnassign", "fragmentUnassign", this);
 
                 fragment.addOrReplace(
-                        new IndicatingOnConfirmAjaxLink<Void>("unassignLink", "confirmUnassign") {
+                        new IndicatingOnConfirmAjaxLink<Void>("unassignLink", "confirmUnassign", enabled) {
 
                     private static final long serialVersionUID = -6957616042924610294L;
 
@@ -680,7 +680,7 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                 fragment = new Fragment("panelDeprovision", "fragmentDeprovision", this);
 
                 fragment.addOrReplace(
-                        new IndicatingOnConfirmAjaxLink<Void>("deprovisionLink", "confirmDeprovision") {
+                        new IndicatingOnConfirmAjaxLink<Void>("deprovisionLink", "confirmDeprovision", enabled) {
 
                     private static final long serialVersionUID = -6957616042924610295L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/IndicatingOnConfirmAjaxLink.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/IndicatingOnConfirmAjaxLink.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/IndicatingOnConfirmAjaxLink.java
index bbd9182..98b3541 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/IndicatingOnConfirmAjaxLink.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/IndicatingOnConfirmAjaxLink.java
@@ -27,13 +27,15 @@ public abstract class IndicatingOnConfirmAjaxLink<T> extends IndicatingAjaxLink<
 
     private final String msg;
 
-    public IndicatingOnConfirmAjaxLink(final String id) {
-        this(id, "confirmDelete");
+    public IndicatingOnConfirmAjaxLink(final String id, final boolean enabled) {
+        this(id, "confirmDelete", enabled);
     }
 
-    public IndicatingOnConfirmAjaxLink(final String id, final String msg) {
+    public IndicatingOnConfirmAjaxLink(final String id, final String msg, final boolean enabled) {
         super(id);
         this.msg = msg;
-        this.add(new ConfirmationModalBehavior(msg));
+        if (enabled) {
+            this.add(new ConfirmationModalBehavior(msg));
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/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 b6ceeb9..0f71eeb 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
@@ -75,6 +75,34 @@ pre {
   min-height: 554px
 }
 
+.realm-header {
+  clear: both;
+  display:block;
+  display: inline-table;
+  margin: 0 0 10px;
+  line-height: 25px;
+}
+
+.realm-label {
+  float: left;
+  font-size: 16px;
+}
+
+.realm-label label {
+  font-weight: 600 !important;
+}
+
+.realm-choice {
+  right: 0px;
+  position: absolute;
+}
+
+.realm-header .dropdown-menu li a {
+  text-align: left !important;
+  white-space: pre !important;
+  line-height: 7px;
+}
+
 .block-header {
   position: fixed !important;
   width: 100% !important;
@@ -501,5 +529,5 @@ END - Result page
 }
 
 .nav-tabs-custom > .nav-tabs > li.active {
-    border-top-color: #d2d6de !important;
+  border-top-color: #d2d6de !important;
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html
index e579a2a..ab19e43 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html
@@ -17,55 +17,24 @@ specific language governing permissions and limitations
 under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
-  <wicket:extend>
-    <section class="content-header">
-      <h1>
-        <wicket:message key="realms"/>
-      </h1>
-    </section>
+  <head><title>Realms</title></head>
+  <body>
+    <wicket:extend>
+      <section class="content-header">
+        <h1>
+          <wicket:message key="realms"/>
+        </h1>
+      </section>
 
-    <div class="wrapper">
-      <div class="admin-content-page content-margin-layout" wicket:id="content">
-        <div class="box box-solid box-primary">
-          <div class="box-header with-border">
-            <h3 class="box-title">
-              <wicket:container wicket:id="header"></wicket:container>
-            </h3>
-            <div class="box-tools pull-right">
-            </div><!-- /.box-tools -->
-          </div><!-- /.box-header -->
+      <section class="content" wicket:id="content">
+        <div class="box">
           <div class="box-body">
-            <div class="realms">
-              <wicket:container wicket:id="body"></wicket:container>
-            </div>
+            <span wicket:id="realmChoicePanel">[Realm Sidebar Panel]</span>
+            <wicket:container wicket:id="body"></wicket:container>
           </div>
         </div>
         <div wicket:id="modal"></div>
-      </div>
-
-      <span wicket:id="realmSidebarPanel">[Realm Sidebar Panel]</span>
-    </div>
-
-    <wicket:fragment wicket:id="withChildren">
-      <li class="treeview">
-        <a href="#" wicket:id="link"><i class="fa fa-folder-o">
-          </i><span wicket:id="name">[ITEM NAME]</span>
-        </a>
-        <a haref="#" class="angle">
-          <i class="fa fa-angle-left pull-right"></i>
-        </a>
-        <ul class="treeview-menu">
-          <wicket:container wicket:id="list"></wicket:container>
-        </ul>
-      </li>
-    </wicket:fragment>
-
-    <wicket:fragment wicket:id="withoutChildren">
-      <li>
-        <a href="#" wicket:id="link">
-          <i class="fa fa-leaf"></i><span wicket:id="name">[ITEM NAME]</span>
-        </a>
-      </li>
-    </wicket:fragment>
-  </wicket:extend>
+      </section>
+    </wicket:extend>
+  </body>
 </html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmChoicePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmChoicePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmChoicePanel.html
new file mode 100644
index 0000000..6ead5a4
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmChoicePanel.html
@@ -0,0 +1,30 @@
+<!--
+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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:panel>
+    <div wicket:id="container" class="realm-header">
+      <div class="realm-label">
+        Realm: <label wicket:id="realm"/>
+      </div>
+      <div class="realm-choice">
+        <button wicket:id="realms"/>
+      </div>
+    </div>
+  </wicket:panel>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmSidebarPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmSidebarPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmSidebarPanel.html
deleted file mode 100644
index b97f8b8..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmSidebarPanel.html
+++ /dev/null
@@ -1,52 +0,0 @@
-<!--
-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.
--->
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
-  <wicket:panel>
-    <aside id="aside" name="aside" class="control-sidebar control-sidebar-dark control-sidebar-open block-sidebar">
-      <section id="section" name="section" class="sidebar syncopeSidebar">
-        <ul id="tree" name="tree" class="sidebar-menu" wicket:id="menu">
-          <wicket:container wicket:id="list"></wicket:container>
-        </ul>
-      </section>
-    </aside>
-    <div id="control" name="control" class="control-sidebar-bg inner-control-sidebar" style="width: 245px;"></div>
-
-    <wicket:fragment wicket:id="withChildren">
-      <li id="treeview" name="treeview" class="treeview">
-        <a href="#" wicket:id="link"><i class="fa fa-folder-o">
-          </i><span wicket:id="name">[ITEM NAME]</span>
-        </a>
-        <a href="#" class="angle" wicket:id="angle">
-          <i class="fa fa-angle-left pull-right"></i>
-        </a>
-        <ul wicket:id="subtree" name="subtree" class="treeview-menu">
-          <wicket:container wicket:id="list"></wicket:container>
-        </ul>
-      </li>
-    </wicket:fragment>
-
-    <wicket:fragment wicket:id="withoutChildren">
-      <li>
-        <a name="label" href="#" wicket:id="link">
-          <i class="fa fa-leaf"></i><span wicket:id="name">[ITEM NAME]</span>
-        </a>
-      </li>
-    </wicket:fragment>
-  </wicket:panel>
-</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TaskExecutionDetails.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TaskExecutionDetails.properties b/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TaskExecutionDetails.properties
index e61a012..99f323a 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TaskExecutionDetails.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TaskExecutionDetails.properties
@@ -16,5 +16,5 @@
 # under the License.
 start=Start
 end=End
-
+status=Status
 execution.view=Result status of execution '${key}'

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TaskExecutionDetails_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TaskExecutionDetails_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TaskExecutionDetails_it.properties
index 5eb816a..3c525b7 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TaskExecutionDetails_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TaskExecutionDetails_it.properties
@@ -16,5 +16,5 @@
 # under the License.
 start=Start
 end=End
-
+status=Stato
 execution.view=Risultato dello stato dell'esecuzione '${key}'

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TaskExecutionDetails_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TaskExecutionDetails_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TaskExecutionDetails_pt_BR.properties
index e61a012..99f323a 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TaskExecutionDetails_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TaskExecutionDetails_pt_BR.properties
@@ -16,5 +16,5 @@
 # under the License.
 start=Start
 end=End
-
+status=Status
 execution.view=Result status of execution '${key}'

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
index e1b43b4..ca324a8 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
@@ -306,8 +306,8 @@ public abstract class AbstractAnyService<TO extends AnyTO, P extends AnyPatch>
             for (String resource : patch.getResources()) {
                 result.getResults().put(resource,
                         updated.getAny().getResources().contains(resource)
-                        ? BulkActionResult.Status.FAILURE
-                        : BulkActionResult.Status.SUCCESS);
+                        ? BulkActionResult.Status.SUCCESS
+                        : BulkActionResult.Status.FAILURE);
             }
         } else {
             for (PropagationStatus propagationStatusTO : updated.getPropagationStatuses()) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java
index 27ad920..eb2acbc 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.fit.console;
 
+import java.io.Serializable;
 import java.lang.reflect.InvocationTargetException;
 import javax.servlet.ServletContext;
 import org.apache.syncope.client.console.SyncopeConsoleApplication;
@@ -35,7 +36,7 @@ import org.apache.wicket.util.visit.IVisit;
 import org.apache.wicket.util.visit.IVisitor;
 import org.junit.Before;
 
-public abstract class AbstractConsoleITCase<T> extends AbstractITCase {
+public abstract class AbstractConsoleITCase extends AbstractITCase {
 
     protected static final String KEY = "key";
 
@@ -78,7 +79,8 @@ public abstract class AbstractConsoleITCase<T> extends AbstractITCase {
         formTester.submit("submit");
     }
 
-    protected Component findComponentByProp(final String property, final String searchPath, final T key) {
+    protected <V extends Serializable> Component findComponentByProp(
+            final String property, final String searchPath, final V key) {
         Component component = wicketTester.getComponentFromLastRenderedPage(searchPath);
 
         Component result = component.getPage().

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractTypesITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractTypesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractTypesITCase.java
index 241c54c..0e228db 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractTypesITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractTypesITCase.java
@@ -24,7 +24,7 @@ import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.
 import org.apache.wicket.util.tester.FormTester;
 import org.junit.Before;
 
-public abstract class AbstractTypesITCase extends AbstractConsoleITCase<String> {
+public abstract class AbstractTypesITCase extends AbstractConsoleITCase{
 
     protected static final String PLAIN_DATATABLE_PATH = "body:content:tabbedPanel:panel:"
             + "accordionPanel:tabs:0:body:content:container:content:searchContainer:resultTable";

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java
new file mode 100644
index 0000000..49b6d21
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java
@@ -0,0 +1,280 @@
+/*
+ * 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.fit.console;
+
+import static org.junit.Assert.assertNotNull;
+
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.wicket.Component;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.util.tester.FormTester;
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class BulkActionITCase extends AbstractConsoleITCase {
+
+    @Before
+    public void login() {
+        doLogin(ADMIN_UNAME, ADMIN_PWD);
+    }
+
+    @Test
+    public void usersBulkAction() {
+        wicketTester.clickLink("body:realmsLI:realms");
+        wicketTester.clickLink("body:content:body:tabbedPanel:tabs-container:tabs:1:link");
+
+        Component component = findComponentByProp("username", "body:content:body:tabbedPanel:panel:container:content"
+                + ":searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", "rossini");
+        assertNotNull(component);
+
+        final FormTester formTester = wicketTester.newFormTester("body:content:body:tabbedPanel:panel:container:"
+                + "content:searchContainer:resultTable:tablePanel:groupForm");
+        assertNotNull(formTester);
+
+        formTester.select("checkgroup", 1);
+
+        wicketTester.executeAjaxEvent("body:content:body:tabbedPanel:panel:container:content:searchContainer:"
+                + "resultTable:tablePanel:bulkActionLink", Constants.ON_CLICK);
+
+        wicketTester.assertComponent("body:content:body:tabbedPanel:panel:container:content:searchContainer:resultTable"
+                + ":bulkModal:form:content:content:container", WebMarkupContainer.class);
+
+        assertNotNull(findComponentByProp("username", "body:content:body:tabbedPanel:panel:container:content:"
+                + "searchContainer:resultTable:bulkModal:form:content:content:container:selectedObjects", "rossini"));
+    }
+
+    @Test
+    public void userResourceBulkAction() {
+        wicketTester.clickLink("body:realmsLI:realms");
+        wicketTester.clickLink("body:content:body:tabbedPanel:tabs-container:tabs:1:link");
+
+        Component component = findComponentByProp("username", "body:content:body:tabbedPanel:panel:container:content"
+                + ":searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", "rossini");
+        assertNotNull(component);
+
+        wicketTester.clickLink(component.getPageRelativePath()
+                + ":cells:5:cell:panelManageResources:manageResourcesLink");
+
+        wicketTester.assertComponent("body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:"
+                + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:groupForm:"
+                + "checkgroup:dataTable", WebMarkupContainer.class);
+
+        component = findComponentByProp("resourceName",
+                "body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:"
+                + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:groupForm:"
+                + "checkgroup:dataTable", "resource-csv");
+        assertNotNull(component);
+
+        final FormTester formTester = wicketTester.newFormTester(
+                "body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:firstLevelContainer:"
+                + "first:container:content:searchContainer:resultTable:tablePanel:groupForm");
+        assertNotNull(formTester);
+
+        formTester.select("checkgroup", 1);
+
+        wicketTester.executeAjaxEvent("body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:"
+                + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:bulkActionLink",
+                Constants.ON_CLICK);
+
+        wicketTester.assertComponent("body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:"
+                + "secondLevelContainer:second:container", WebMarkupContainer.class);
+
+        assertNotNull(findComponentByProp("resourceName", "body:content:body:tabbedPanel:panel:alternativeDefaultModal:"
+                + "form:content:status:secondLevelContainer:second:container:selectedObjects", "resource-csv"));
+    }
+
+    @Test
+    public void userStatusBulkAction() {
+        // suspend 
+
+        wicketTester.clickLink("body:realmsLI:realms");
+        wicketTester.clickLink("body:content:body:tabbedPanel:tabs-container:tabs:1:link");
+
+        Component component = findComponentByProp("username", "body:content:body:tabbedPanel:panel:container:content"
+                + ":searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", "rossini");
+        assertNotNull(component);
+
+        wicketTester.clickLink(component.getPageRelativePath() + ":cells:5:cell:panelEnable:enableLink");
+
+        wicketTester.assertComponent("body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:"
+                + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:groupForm:"
+                + "checkgroup:dataTable", WebMarkupContainer.class);
+
+        FormTester formTester = wicketTester.newFormTester(
+                "body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:firstLevelContainer:"
+                + "first:container:content:searchContainer:resultTable:tablePanel:groupForm");
+        assertNotNull(formTester);
+
+        formTester.select("checkgroup", 2);
+
+        wicketTester.executeAjaxEvent("body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:"
+                + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:bulkActionLink",
+                Constants.ON_CLICK);
+
+        wicketTester.assertComponent("body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:"
+                + "secondLevelContainer:second:container", WebMarkupContainer.class);
+
+        wicketTester.executeAjaxEvent("body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:"
+                + "status:secondLevelContainer:second:container:actions:panelSuspend:suspendLink",
+                Constants.ON_CLICK);
+
+        wicketTester.assertLabel("body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:"
+                + "secondLevelContainer:second:container:selectedObjects:body:rows:1:cells:3:cell", "SUCCESS");
+
+        // re-activate
+        wicketTester.clickLink("body:realmsLI:realms");
+        wicketTester.clickLink("body:content:body:tabbedPanel:tabs-container:tabs:1:link");
+
+        component = findComponentByProp("username", "body:content:body:tabbedPanel:panel:container:content"
+                + ":searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", "rossini");
+        assertNotNull(component);
+
+        wicketTester.clickLink(component.getPageRelativePath() + ":cells:5:cell:panelEnable:enableLink");
+
+        wicketTester.assertComponent("body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:"
+                + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:groupForm:"
+                + "checkgroup:dataTable", WebMarkupContainer.class);
+
+        formTester = wicketTester.newFormTester(
+                "body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:firstLevelContainer:"
+                + "first:container:content:searchContainer:resultTable:tablePanel:groupForm");
+        assertNotNull(formTester);
+
+        formTester.select("checkgroup", 2);
+
+        wicketTester.executeAjaxEvent("body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:"
+                + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:bulkActionLink",
+                Constants.ON_CLICK);
+
+        wicketTester.assertComponent("body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:"
+                + "secondLevelContainer:second:container", WebMarkupContainer.class);
+
+        wicketTester.executeAjaxEvent("body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:"
+                + "status:secondLevelContainer:second:container:actions:panelReactivate:reactivateLink",
+                Constants.ON_CLICK);
+
+        wicketTester.assertLabel("body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:"
+                + "secondLevelContainer:second:container:selectedObjects:body:rows:1:cells:3:cell", "SUCCESS");
+    }
+
+    @Test
+    public void groupResourceBulkAction() {
+        wicketTester.clickLink("body:realmsLI:realms");
+        wicketTester.clickLink("body:content:body:tabbedPanel:tabs-container:tabs:2:link");
+
+        Component component = findComponentByProp("name", "body:content:body:tabbedPanel:panel:container:content"
+                + ":searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", "root");
+        assertNotNull(component);
+
+        wicketTester.clickLink(component.getPageRelativePath()
+                + ":cells:4:cell:panelManageResources:manageResourcesLink");
+
+        wicketTester.assertComponent("body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:"
+                + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:groupForm:"
+                + "checkgroup:dataTable", WebMarkupContainer.class);
+
+        component = findComponentByProp("resourceName",
+                "body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:"
+                + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:groupForm:"
+                + "checkgroup:dataTable", "ws-target-resource-1");
+        assertNotNull(component);
+
+        final FormTester formTester = wicketTester.newFormTester(
+                "body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:firstLevelContainer:"
+                + "first:container:content:searchContainer:resultTable:tablePanel:groupForm");
+        assertNotNull(formTester);
+
+        formTester.select("checkgroup", 1);
+
+        wicketTester.executeAjaxEvent("body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:"
+                + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:bulkActionLink",
+                Constants.ON_CLICK);
+
+        wicketTester.assertComponent("body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:"
+                + "secondLevelContainer:second:container", WebMarkupContainer.class);
+
+        assertNotNull(findComponentByProp("resourceName", "body:content:body:tabbedPanel:panel:alternativeDefaultModal:"
+                + "form:content:status:secondLevelContainer:second:container:selectedObjects", "ws-target-resource-1"));
+    }
+
+    @Test
+    public void printerResourceBulkAction() {
+        wicketTester.clickLink("body:realmsLI:realms");
+        wicketTester.clickLink("body:content:body:tabbedPanel:tabs-container:tabs:3:link");
+
+        Component component = findComponentByProp("key", "body:content:body:tabbedPanel:panel:container:content"
+                + ":searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", 1L);
+        assertNotNull(component);
+
+        wicketTester.clickLink(component.getPageRelativePath()
+                + ":cells:3:cell:panelManageResources:manageResourcesLink");
+
+        wicketTester.assertComponent("body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:"
+                + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:groupForm:"
+                + "checkgroup:dataTable", WebMarkupContainer.class);
+
+        component = findComponentByProp("resourceName",
+                "body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:"
+                + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:groupForm:"
+                + "checkgroup:dataTable", "ws-target-resource-1");
+        assertNotNull(component);
+
+        final FormTester formTester = wicketTester.newFormTester(
+                "body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:firstLevelContainer:"
+                + "first:container:content:searchContainer:resultTable:tablePanel:groupForm");
+        assertNotNull(formTester);
+
+        formTester.select("checkgroup", 1);
+
+        wicketTester.executeAjaxEvent("body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:"
+                + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:bulkActionLink",
+                Constants.ON_CLICK);
+
+        wicketTester.assertComponent("body:content:body:tabbedPanel:panel:alternativeDefaultModal:form:content:status:"
+                + "secondLevelContainer:second:container", WebMarkupContainer.class);
+
+        assertNotNull(findComponentByProp("resourceName", "body:content:body:tabbedPanel:panel:alternativeDefaultModal:"
+                + "form:content:status:secondLevelContainer:second:container:selectedObjects", "ws-target-resource-1"));
+    }
+
+    @Test
+    public void executeSyncTask() {
+        wicketTester.clickLink("body:topologyLI:topology");
+        wicketTester.executeAjaxEvent("body:resources:2:resources:0:res", Constants.ON_CLICK);
+        wicketTester.clickLink("body:toggle:togglePanelContainer:container:actions:propagation");
+
+        final FormTester formTester = wicketTester.newFormTester(
+                "body:toggle:outerObjectsRepeater:1:outer:form:content:tasks:firstLevelContainer:first:container:"
+                + "content:searchContainer:resultTable:tablePanel:groupForm");
+        assertNotNull(formTester);
+
+        formTester.select("checkgroup", 0);
+
+        wicketTester.executeAjaxEvent("body:toggle:outerObjectsRepeater:1:outer:form:content:tasks:"
+                + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:bulkActionLink",
+                Constants.ON_CLICK);
+
+        wicketTester.assertComponent("body:toggle:outerObjectsRepeater:1:outer:form:content:tasks:secondLevelContainer:"
+                + "second:container:selectedObjects:body:rows:1:cells:1:cell", Label.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
index bfe486f..a1f329c 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
@@ -27,7 +27,7 @@ import org.junit.Test;
 import org.junit.runners.MethodSorters;
 
 @FixMethodOrder(MethodSorters.JVM)
-public class RealmsITCase extends AbstractConsoleITCase<String> {
+public class RealmsITCase extends AbstractConsoleITCase {
 
     @Before
     public void login() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RolesITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RolesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RolesITCase.java
index 22bbd58..dae373b 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RolesITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RolesITCase.java
@@ -31,7 +31,7 @@ import org.junit.Test;
 import org.junit.runners.MethodSorters;
 
 @FixMethodOrder(MethodSorters.JVM)
-public class RolesITCase extends AbstractConsoleITCase<String> {
+public class RolesITCase extends AbstractConsoleITCase {
 
     private void createRole(final String name) {
         wicketTester.clickLink("body:content:rolesPanel:container:content:add");
@@ -52,7 +52,7 @@ public class RolesITCase extends AbstractConsoleITCase<String> {
 
         wicketTester.assertInfoMessages("Operation executed successfully");
         wicketTester.cleanupFeedbackMessages();
-        
+
         wicketTester.clickLink("body:configurationLI:configurationUL:rolesLI:roles");
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/48b5a10f/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SecurityQuestionsITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SecurityQuestionsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SecurityQuestionsITCase.java
index 02a615f..a3bb92d 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SecurityQuestionsITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SecurityQuestionsITCase.java
@@ -32,7 +32,7 @@ import org.junit.Test;
 import org.junit.runners.MethodSorters;
 
 @FixMethodOrder(MethodSorters.JVM)
-public class SecurityQuestionsITCase extends AbstractConsoleITCase<String> {
+public class SecurityQuestionsITCase extends AbstractConsoleITCase {
 
     private void createRealm(final String name) {
         wicketTester.clickLink("body:content:securityQuestionPanel:container:content:add");
@@ -88,11 +88,9 @@ public class SecurityQuestionsITCase extends AbstractConsoleITCase<String> {
 
         assertNotNull(result);
 
-        wicketTester.clickLink(
-                result.getPageRelativePath() + ":cells:3:cell:panelEdit:editLink");
+        wicketTester.clickLink(result.getPageRelativePath() + ":cells:3:cell:panelEdit:editLink");
 
-        FormTester formTester = wicketTester.newFormTester("body:content:securityQuestionPanel"
-                + ":modal:form");
+        FormTester formTester = wicketTester.newFormTester("body:content:securityQuestionPanel:modal:form");
         formTester.setValue("content:securityQuestionDetailsPanel:container:form:content:textField",
                 "What's your favorite car?");
 
@@ -114,9 +112,8 @@ public class SecurityQuestionsITCase extends AbstractConsoleITCase<String> {
         assertNotNull(result);
 
         wicketTester.getRequest().addParameter("confirm", "true");
-        wicketTester.clickLink(
-                wicketTester.getComponentFromLastRenderedPage(
-                        result.getPageRelativePath() + ":cells:3:cell:panelDelete:deleteLink"));
+        wicketTester.clickLink(wicketTester.getComponentFromLastRenderedPage(
+                result.getPageRelativePath() + ":cells:3:cell:panelDelete:deleteLink"));
 
         wicketTester.executeAjaxEvent(wicketTester.getComponentFromLastRenderedPage(
                 result.getPageRelativePath() + ":cells:3:cell:panelDelete:deleteLink"), "onclick");


Mime
View raw message