You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2016/03/07 16:52:20 UTC

[4/6] syncope git commit: [SYNCOPE-744] Here is the reconciliation status widget

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTaskSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTaskSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTaskSearchResultPanel.java
index ca7f5ea..2f572d5 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTaskSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTaskSearchResultPanel.java
@@ -24,6 +24,7 @@ import java.util.Collections;
 import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.TaskDataProvider;
@@ -69,7 +70,7 @@ public abstract class PropagationTaskSearchResultPanel extends TaskSearchResultP
 
     @Override
     protected List<IColumn<PropagationTaskTO, String>> getColumns() {
-        final List<IColumn<PropagationTaskTO, String>> columns = new ArrayList<IColumn<PropagationTaskTO, String>>();
+        final List<IColumn<PropagationTaskTO, String>> columns = new ArrayList<>();
 
         columns.add(new PropertyColumn<PropagationTaskTO, String>(
                 new StringResourceModel("key", this, null), "key", "key"));
@@ -110,7 +111,7 @@ public abstract class PropagationTaskSearchResultPanel extends TaskSearchResultP
 
                 final PropagationTaskTO taskTO = model.getObject();
 
-                final ActionLinksPanel<PropagationTaskTO> panel = ActionLinksPanel.<PropagationTaskTO>builder(pageRef).
+                final ActionLinksPanel<PropagationTaskTO> panel = ActionLinksPanel.<PropagationTaskTO>builder().
                         add(new ActionLink<PropagationTaskTO>() {
 
                             private static final long serialVersionUID = -3722207913631435501L;
@@ -119,7 +120,7 @@ public abstract class PropagationTaskSearchResultPanel extends TaskSearchResultP
                             public void onClick(final AjaxRequestTarget target, final PropagationTaskTO modelObject) {
                                 viewTask(taskTO, target);
                             }
-                        }, ActionLink.ActionType.SEARCH, StandardEntitlement.TASK_READ).
+                        }, ActionLink.ActionType.VIEW, StandardEntitlement.TASK_READ).
                         add(new ActionLink<PropagationTaskTO>() {
 
                             private static final long serialVersionUID = -3722207913631435501L;
@@ -131,8 +132,9 @@ public abstract class PropagationTaskSearchResultPanel extends TaskSearchResultP
                                     info(getString(Constants.OPERATION_SUCCEEDED));
                                     target.add(container);
                                 } catch (SyncopeClientException e) {
-                                    error(getString(Constants.ERROR) + ": " + e.getMessage());
-                                    LOG.error("While running propagation task {}", taskTO.getKey(), e);
+                                    error(StringUtils.isBlank(e.getMessage())
+                                            ? e.getClass().getName() : e.getMessage());
+                                    LOG.error("While running {}", taskTO.getKey(), e);
                                 }
                                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                             }
@@ -148,8 +150,9 @@ public abstract class PropagationTaskSearchResultPanel extends TaskSearchResultP
                                     info(getString(Constants.OPERATION_SUCCEEDED));
                                     target.add(container);
                                 } catch (SyncopeClientException e) {
-                                    error(getString(Constants.ERROR) + ": " + e.getMessage());
-                                    LOG.error("While deleting propagation task {}", taskTO.getKey(), e);
+                                    LOG.error("While deleting {}", taskTO.getKey(), e);
+                                    error(StringUtils.isBlank(e.getMessage())
+                                            ? e.getClass().getName() : e.getMessage());
                                 }
                                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                             }
@@ -160,8 +163,7 @@ public abstract class PropagationTaskSearchResultPanel extends TaskSearchResultP
 
             @Override
             public ActionLinksPanel<PropagationTaskTO> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<PropagationTaskTO> panel = ActionLinksPanel.builder(page.
-                        getPageReference());
+                final ActionLinksPanel.Builder<PropagationTaskTO> panel = ActionLinksPanel.builder();
 
                 return panel.add(new ActionLink<PropagationTaskTO>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskSearchResultPanel.java
index 899a624..8345fb4 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskSearchResultPanel.java
@@ -24,6 +24,7 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.TaskDataProvider;
@@ -165,7 +166,7 @@ public abstract class SchedTaskSearchResultPanel<T extends SchedTaskTO> extends
 
                 final T taskTO = model.getObject();
 
-                final ActionLinksPanel<T> panel = ActionLinksPanel.<T>builder(pageRef).
+                final ActionLinksPanel<T> panel = ActionLinksPanel.<T>builder().
                         add(new ActionLink<T>() {
 
                             private static final long serialVersionUID = -3722207913631435501L;
@@ -174,7 +175,7 @@ public abstract class SchedTaskSearchResultPanel<T extends SchedTaskTO> extends
                             public void onClick(final AjaxRequestTarget target, final T ignore) {
                                 viewTask(taskTO, target);
                             }
-                        }, ActionLink.ActionType.SEARCH, StandardEntitlement.TASK_READ).
+                        }, ActionLink.ActionType.VIEW, StandardEntitlement.TASK_READ).
                         add(new ActionLink<T>() {
 
                             private static final long serialVersionUID = -3722207913631435501L;
@@ -220,7 +221,8 @@ public abstract class SchedTaskSearchResultPanel<T extends SchedTaskTO> extends
                                     info(getString(Constants.OPERATION_SUCCEEDED));
                                     target.add(container);
                                 } catch (SyncopeClientException e) {
-                                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                                    error(StringUtils.isBlank(e.getMessage())
+                                            ? e.getClass().getName() : e.getMessage());
                                     LOG.error("While running propagation task {}", taskTO.getKey(), e);
                                 }
                                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
@@ -237,7 +239,8 @@ public abstract class SchedTaskSearchResultPanel<T extends SchedTaskTO> extends
                                     info(getString(Constants.OPERATION_SUCCEEDED));
                                     target.add(container);
                                 } catch (SyncopeClientException e) {
-                                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                                    error(StringUtils.isBlank(e.getMessage())
+                                            ? e.getClass().getName() : e.getMessage());
                                     LOG.error("While deleting propagation task {}", taskTO.getKey(), e);
                                 }
                                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
@@ -249,7 +252,7 @@ public abstract class SchedTaskSearchResultPanel<T extends SchedTaskTO> extends
 
             @Override
             public ActionLinksPanel<T> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<T> panel = ActionLinksPanel.builder(page.getPageReference());
+                final ActionLinksPanel.Builder<T> panel = ActionLinksPanel.builder();
 
                 return panel.add(new ActionLink<T>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/tasks/StartAtTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/StartAtTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/StartAtTogglePanel.java
index e03f56e..7219c4c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/StartAtTogglePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/StartAtTogglePanel.java
@@ -20,6 +20,7 @@ package org.apache.syncope.client.console.tasks;
 
 import java.io.Serializable;
 import java.util.Date;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.panels.TogglePanel;
@@ -48,7 +49,7 @@ public class StartAtTogglePanel extends TogglePanel<Serializable> {
         final Form<?> form = new Form<>("startAtForm");
         addInnerObject(form);
 
-        final Model<Date> startAtDateModel = new Model<Date>();
+        final Model<Date> startAtDateModel = new Model<>();
 
         final AjaxDateFieldPanel startAtDate = new AjaxDateFieldPanel(
                 "startAtDate", "startAtDate", startAtDateModel, SyncopeConstants.DATE_PATTERNS[3]);
@@ -57,7 +58,7 @@ public class StartAtTogglePanel extends TogglePanel<Serializable> {
         form.add(startAtDate);
 
         final AjaxCheckBoxPanel startAtCheck = new AjaxCheckBoxPanel(
-                "startAtCheck", "startAtCheck", new Model<Boolean>(false), false);
+                "startAtCheck", "startAtCheck", new Model<>(false), false);
 
         form.add(startAtCheck);
 
@@ -83,7 +84,7 @@ public class StartAtTogglePanel extends TogglePanel<Serializable> {
                     toggle(target, false);
                     target.add(container);
                 } catch (SyncopeClientException e) {
-                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
                     LOG.error("While running propagation task {}", taskTO.getKey(), e);
                 }
                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/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 1d08460..43de894 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
@@ -103,12 +103,10 @@ public abstract class TaskExecutions
             private static final long serialVersionUID = -3503023501954863131L;
 
             @Override
-            public ActionLinksPanel<ExecTO> getActions(
-                    final String componentId, final IModel<ExecTO> model) {
-
+            public ActionLinksPanel<ExecTO> getActions(final String componentId, final IModel<ExecTO> model) {
                 final ExecTO taskExecutionTO = model.getObject();
 
-                final ActionLinksPanel.Builder<ExecTO> panel = ActionLinksPanel.builder(pageRef);
+                final ActionLinksPanel.Builder<ExecTO> panel = ActionLinksPanel.builder();
 
                 panel.
                         add(new ActionLink<ExecTO>() {
@@ -120,7 +118,7 @@ public abstract class TaskExecutions
                                 next(new StringResourceModel("execution.view", TaskExecutions.this, model).getObject(),
                                         new ExecMessage(model.getObject().getMessage()), target);
                             }
-                        }, ActionLink.ActionType.SEARCH, StandardEntitlement.TASK_READ).
+                        }, ActionLink.ActionType.VIEW, StandardEntitlement.TASK_READ).
                         add(new ActionLink<ExecTO>() {
 
                             private static final long serialVersionUID = -3722207913631435501L;
@@ -144,7 +142,7 @@ public abstract class TaskExecutions
 
             @Override
             public ActionLinksPanel<Serializable> getHeader(final String componentId) {
-                final ActionLinksPanel.Builder<Serializable> panel = ActionLinksPanel.builder(pageRef);
+                final ActionLinksPanel.Builder<Serializable> panel = ActionLinksPanel.builder();
 
                 return panel.add(new ActionLink<Serializable>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java b/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
index 8017238..2b90e96 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
@@ -167,7 +167,7 @@ public class Topology extends BasePage {
         // -----------------------------------------
         // Add Zoom panel
         // -----------------------------------------
-        final ActionLinksPanel.Builder<Serializable> zoomActionPanel = ActionLinksPanel.builder(getPageReference());
+        final ActionLinksPanel.Builder<Serializable> zoomActionPanel = ActionLinksPanel.builder();
         zoomActionPanel.setDisableIndicator(true);
 
         zoomActionPanel.add(new ActionLink<Serializable>() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
index 40a4942..48f2588 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
@@ -21,6 +21,7 @@ package org.apache.syncope.client.console.topology;
 import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
 import java.io.Serializable;
 import java.text.MessageFormat;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.panels.ConnectorModal;
@@ -185,7 +186,7 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
                     target.appendJavaScript(String.format("jsPlumb.remove('%s');", node.getKey()));
                     info(getString(Constants.OPERATION_SUCCEEDED));
                 } catch (SyncopeClientException e) {
-                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
                     LOG.error("While deleting resource {}", node.getKey(), e);
                 }
                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
@@ -266,7 +267,7 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
                     target.appendJavaScript(String.format("jsPlumb.remove('%s');", node.getKey()));
                     info(getString(Constants.OPERATION_SUCCEEDED));
                 } catch (SyncopeClientException e) {
-                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
                     LOG.error("While deleting resource {}", node.getKey(), e);
                 }
                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/IndicatorAjaxTimerBehavior.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/IndicatorAjaxTimerBehavior.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/IndicatorAjaxTimerBehavior.java
index 5efc5a9..6026ecf 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/IndicatorAjaxTimerBehavior.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/IndicatorAjaxTimerBehavior.java
@@ -24,7 +24,7 @@ import org.apache.wicket.ajax.IAjaxIndicatorAware;
 import org.apache.wicket.util.time.Duration;
 
 /**
- * An {@link AbstractAjaxTimerBehavior} not showin veil.
+ * An {@link AbstractAjaxTimerBehavior} not showing veil.
  */
 public abstract class IndicatorAjaxTimerBehavior extends AbstractAjaxTimerBehavior implements IAjaxIndicatorAware {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/ClearIndicatingAjaxButton.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/ClearIndicatingAjaxButton.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/ClearIndicatingAjaxButton.java
deleted file mode 100644
index 449bcd3..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/ClearIndicatingAjaxButton.java
+++ /dev/null
@@ -1,66 +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.wicket.ajax.markup.html;
-
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.model.IModel;
-
-public abstract class ClearIndicatingAjaxButton extends IndicatingAjaxButton {
-
-    private static final long serialVersionUID = 7206379812788748287L;
-
-    private final PageReference pageRef;
-
-    public ClearIndicatingAjaxButton(final String id, final PageReference pageRef) {
-        super(id);
-        this.pageRef = pageRef;
-    }
-
-    public ClearIndicatingAjaxButton(final String id, final Form<?> form, final PageReference pageRef) {
-        super(id, form);
-        this.pageRef = pageRef;
-    }
-
-    public ClearIndicatingAjaxButton(final String id, final IModel<String> model, final PageReference pageRef) {
-        super(id, model);
-        this.pageRef = pageRef;
-    }
-
-    public ClearIndicatingAjaxButton(final String id, final IModel<String> model, final Form<?> form,
-            final PageReference pageRef) {
-
-        super(id, model, form);
-        this.pageRef = pageRef;
-    }
-
-    protected abstract void onSubmitInternal(final AjaxRequestTarget target, final Form<?> form);
-
-    public ClearIndicatingAjaxButton feedbackPanelAutomaticReload(final boolean reloadFeedbackPanel) {
-        return this;
-    }
-
-    @Override
-    protected final void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
-        super.onSubmit(target, form);
-        onSubmitInternal(target, form);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/ClearIndicatingAjaxLink.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/ClearIndicatingAjaxLink.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/ClearIndicatingAjaxLink.java
deleted file mode 100644
index adab320..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/ClearIndicatingAjaxLink.java
+++ /dev/null
@@ -1,61 +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.wicket.ajax.markup.html;
-
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
-import org.apache.wicket.model.IModel;
-
-public abstract class ClearIndicatingAjaxLink<T> extends IndicatingAjaxLink<T> {
-
-    private static final long serialVersionUID = 7913625094362339643L;
-
-    private final PageReference pageRef;
-
-    private boolean reloadFeedbackPanel = true;
-
-    public ClearIndicatingAjaxLink(final String id, final PageReference pageRef) {
-        super(id);
-        this.pageRef = pageRef;
-        setOutputMarkupId(true);
-    }
-
-    public ClearIndicatingAjaxLink(final String id, final IModel<T> model, final PageReference pageRef) {
-        super(id, model);
-        this.pageRef = pageRef;
-        setOutputMarkupId(true);
-    }
-
-    public ClearIndicatingAjaxLink<T> feedbackPanelAutomaticReload(final boolean reloadFeedbackPanel) {
-        this.reloadFeedbackPanel = reloadFeedbackPanel;
-        return this;
-    }
-
-    protected abstract void onClickInternal(final AjaxRequestTarget target);
-
-    @Override
-    public final void onClick(final AjaxRequestTarget target) {
-//        final Page page = pageRef.getPage();
-//        if (reloadFeedbackPanel && page instanceof NotificationAwareComponent) {
-//            ((NotificationAwareComponent) page).getNotification().refresh(target);
-//        }
-        onClickInternal(target);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/IndicatorAjaxLink.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/IndicatorAjaxLink.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/IndicatorAjaxLink.java
new file mode 100644
index 0000000..d894954
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/IndicatorAjaxLink.java
@@ -0,0 +1,41 @@
+/*
+ * 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.wicket.ajax.markup.html;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.wicket.ajax.IAjaxIndicatorAware;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+
+/**
+ * An {@link AjaxLink} not showing veil.
+ */
+public abstract class IndicatorAjaxLink<T> extends AjaxLink<T> implements IAjaxIndicatorAware {
+
+    private static final long serialVersionUID = -1390762132437554937L;
+
+    public IndicatorAjaxLink(final String id) {
+        super(id);
+    }
+
+    @Override
+    public String getAjaxIndicatorMarkupId() {
+        return StringUtils.EMPTY;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/BooleanPropertyColumn.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/BooleanPropertyColumn.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/BooleanPropertyColumn.java
index 843fd3a..c069470 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/BooleanPropertyColumn.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/BooleanPropertyColumn.java
@@ -43,7 +43,6 @@ public class BooleanPropertyColumn<T> extends PropertyColumn<T, String> {
 
     @Override
     public void populateItem(final Item<ICellPopulator<T>> item, final String componentId, final IModel<T> rowModel) {
-
         BeanWrapper bwi = new BeanWrapperImpl(rowModel.getObject());
         Object obj = bwi.getPropertyValue(getPropertyExpression());
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
index 708fd92..93fda56 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
@@ -50,7 +50,9 @@ public abstract class ActionLink<T extends Serializable> implements Serializable
         GROUP_TEMPLATE("read"),
         RESET("update"),
         ENABLE("update"),
-        SEARCH("read"),
+        NOT_FOND("read"),
+        VIEW("view"),
+        SEARCH("search"),
         DELETE("delete"),
         EXECUTE("execute"),
         DRYRUN("execute"),

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/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 de7baf5..b56da38 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
@@ -24,8 +24,6 @@ import java.util.Map;
 import java.util.Map.Entry;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Triple;
-import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxLink;
-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.extensions.ajax.markup.html.IndicatingAjaxLink;
@@ -43,16 +41,13 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
 
     private static final long serialVersionUID = 322966537010107771L;
 
-    private final PageReference pageRef;
-
     private final IModel<T> model;
 
     private boolean disableIndicator = false;
 
-    private ActionLinksPanel(final String componentId, final IModel<T> model, final PageReference pageRef) {
+    private ActionLinksPanel(final String componentId, final IModel<T> model) {
         super(componentId, model);
         this.model = model;
-        this.pageRef = pageRef;
 
         setOutputMarkupId(true);
 
@@ -70,6 +65,8 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
         super.add(new Fragment("panelUserTemplate", "emptyFragment", this));
         super.add(new Fragment("panelGroupTemplate", "emptyFragment", this));
         super.add(new Fragment("panelEnable", "emptyFragment", this));
+        super.add(new Fragment("panelNotFound", "emptyFragment", this));
+        super.add(new Fragment("panelView", "emptyFragment", this));
         super.add(new Fragment("panelSearch", "emptyFragment", this));
         super.add(new Fragment("panelDelete", "emptyFragment", this));
         super.add(new Fragment("panelExecute", "emptyFragment", this));
@@ -104,12 +101,12 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
             case CLAIM:
                 fragment = new Fragment("panelClaim", "fragmentClaim", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("claimLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("claimLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -117,19 +114,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case MANAGE_RESOURCES:
                 fragment = new Fragment("panelManageResources", "fragmentManageResources", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("manageResourcesLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("manageResourcesLink") {
 
                     private static final long serialVersionUID = -6957616042924610291L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -137,19 +133,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case MANAGE_USERS:
                 fragment = new Fragment("panelManageUsers", "fragmentManageUsers", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("manageUsersLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("manageUsersLink") {
 
                     private static final long serialVersionUID = -6957616042924610292L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -157,19 +152,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case MANAGE_GROUPS:
                 fragment = new Fragment("panelManageGroups", "fragmentManageGroups", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("manageGroupsLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("manageGroupsLink") {
 
                     private static final long serialVersionUID = -6957616042924610293L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -177,19 +171,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case MAPPING:
                 fragment = new Fragment("panelMapping", "fragmentMapping", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("mappingLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("mappingLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -197,19 +190,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case ACCOUNT_LINK:
                 fragment = new Fragment("panelAccountLink", "fragmentAccountLink", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("accountLinkLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("accountLinkLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -217,19 +209,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case RESET_TIME:
                 fragment = new Fragment("panelResetTime", "fragmentResetTime", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("resetTimeLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("resetTimeLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -237,19 +228,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case CLONE:
                 fragment = new Fragment("panelClone", "fragmentClone", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("cloneLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("cloneLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -257,19 +247,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case CREATE:
                 fragment = new Fragment("panelCreate", "fragmentCreate", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("createLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("createLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -277,19 +266,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case RESET:
                 fragment = new Fragment("panelReset", "fragmentReset", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("resetLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("resetLink") {
 
                     private static final long serialVersionUID = -6957616042924610290L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -303,12 +291,12 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
             case EDIT:
                 fragment = new Fragment("panelEdit", "fragmentEdit", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("editLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("editLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -316,19 +304,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case USER_TEMPLATE:
                 fragment = new Fragment("panelUserTemplate", "fragmentUserTemplate", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("userTemplateLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("userTemplateLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -336,19 +323,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case GROUP_TEMPLATE:
                 fragment = new Fragment("panelGroupTemplate", "fragmentGroupTemplate", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("groupTemplateLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("groupTemplateLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -356,19 +342,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case ENABLE:
                 fragment = new Fragment("panelEnable", "fragmentEnable", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("enableLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("enableLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -376,19 +361,40 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
+                break;
+
+            case NOT_FOND:
+                fragment = new Fragment("panelNotFound", "fragmentNotFound", this);
+                break;
+
+            case VIEW:
+                fragment = new Fragment("panelView", "fragmentView", this);
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("viewLink") {
+
+                    private static final long serialVersionUID = -1876519166660008562L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        link.onClick(target, model.getObject());
+                    }
+
+                    @Override
+                    public String getAjaxIndicatorMarkupId() {
+                        return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
+                    }
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case SEARCH:
                 fragment = new Fragment("panelSearch", "fragmentSearch", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("searchLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("searchLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -396,19 +402,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case EXECUTE:
                 fragment = new Fragment("panelExecute", "fragmentExecute", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("executeLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("executeLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -416,19 +421,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case DRYRUN:
                 fragment = new Fragment("panelDryRun", "fragmentDryRun", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("dryRunLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("dryRunLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -436,8 +440,7 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case DELETE:
@@ -463,12 +466,12 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
             case SELECT:
                 fragment = new Fragment("panelSelect", "fragmentSelect", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("selectLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("selectLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -482,12 +485,12 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
             case CLOSE:
                 fragment = new Fragment("panelClose", "fragmentClose", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("closeLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("closeLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -502,12 +505,12 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
             case EXPORT:
                 fragment = new Fragment("panelExport", "fragmentExport", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("exportLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("exportLink") {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -521,12 +524,12 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
             case SUSPEND:
                 fragment = new Fragment("panelSuspend", "fragmentSuspend", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("suspendLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("suspendLink") {
 
                     private static final long serialVersionUID = -6957616042924610291L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -534,19 +537,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case REACTIVATE:
                 fragment = new Fragment("panelReactivate", "fragmentReactivate", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("reactivateLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("reactivateLink") {
 
                     private static final long serialVersionUID = -6957616042924610292L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -554,19 +556,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case RELOAD:
                 fragment = new Fragment("panelReload", "fragmentReload", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("reloadLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("reloadLink") {
 
                     private static final long serialVersionUID = -6957616042924610293L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -574,19 +575,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case CHANGE_VIEW:
                 fragment = new Fragment("panelChangeView", "fragmentChangeView", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("changeViewLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("changeViewLink") {
 
                     private static final long serialVersionUID = -6957616042924610292L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -594,8 +594,7 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case UNLINK:
@@ -659,12 +658,12 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
             case ASSIGN:
                 fragment = new Fragment("panelAssign", "fragmentAssign", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("assignLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("assignLink") {
 
                     private static final long serialVersionUID = -6957616042924610304L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -672,8 +671,7 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
 
             case DEPROVISION:
@@ -699,12 +697,12 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
             case PROVISION:
                 fragment = new Fragment("panelProvision", "fragmentProvision", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("provisionLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("provisionLink") {
 
                     private static final long serialVersionUID = -6957616042924610305L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -712,18 +710,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
+
             case ZOOM_IN:
                 fragment = new Fragment("panelZoomIn", "fragmentZoomIn", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("zoomInLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("zoomInLink") {
 
                     private static final long serialVersionUID = -6957616042924610305L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -731,18 +729,18 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
+
             case ZOOM_OUT:
                 fragment = new Fragment("panelZoomOut", "fragmentZoomOut", this);
 
-                fragment.addOrReplace(new ClearIndicatingAjaxLink<Void>("zoomOutLink", pageRef) {
+                fragment.addOrReplace(new IndicatingAjaxLink<Void>("zoomOutLink") {
 
                     private static final long serialVersionUID = -6957616042924610305L;
 
                     @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
+                    public void onClick(final AjaxRequestTarget target) {
                         link.onClick(target, model.getObject());
                     }
 
@@ -750,9 +748,9 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                     public String getAjaxIndicatorMarkupId() {
                         return disableIndicator ? StringUtils.EMPTY : super.getAjaxIndicatorMarkupId();
                     }
-                }.feedbackPanelAutomaticReload(link.feedbackPanelAutomaticReload()).
-                        setVisible(link.isEnabled(model.getObject())));
+                }.setVisible(link.isEnabled(model.getObject())));
                 break;
+
             default:
             // do nothing
         }
@@ -814,6 +812,10 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
                 super.addOrReplace(new Fragment("panelUserTemplate", "emptyFragment", this));
                 break;
 
+            case VIEW:
+                super.addOrReplace(new Fragment("panelView", "emptyFragment", this));
+                break;
+
             case SEARCH:
                 super.addOrReplace(new Fragment("panelSearch", "emptyFragment", this));
                 break;
@@ -897,8 +899,8 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
         return this;
     }
 
-    public static <T extends Serializable> Builder<T> builder(final PageReference pageRef) {
-        return new Builder<T>(pageRef);
+    public static <T extends Serializable> Builder<T> builder() {
+        return new Builder<>();
     }
 
     /**
@@ -912,14 +914,8 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
 
         private final Map<ActionLink.ActionType, Triple<ActionLink<T>, String, Boolean>> actions = new HashMap<>();
 
-        private final PageReference pageRef;
-
         private boolean disableIndicator = false;
 
-        private Builder(final PageReference pageRef) {
-            this.pageRef = pageRef;
-        }
-
         public Builder<T> setDisableIndicator(final boolean disableIndicator) {
             this.disableIndicator = disableIndicator;
             return this;
@@ -982,8 +978,8 @@ public final class ActionLinksPanel<T extends Serializable> extends Panel {
          */
         public ActionLinksPanel<T> build(final String id, final T modelObject) {
             final ActionLinksPanel<T> panel = modelObject == null
-                    ? new ActionLinksPanel<>(id, new Model<T>(), this.pageRef)
-                    : new ActionLinksPanel<>(id, new Model<>(modelObject), this.pageRef);
+                    ? new ActionLinksPanel<>(id, new Model<T>())
+                    : new ActionLinksPanel<>(id, new Model<>(modelObject));
 
             panel.setDisableIndicator(disableIndicator);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java
index cae2e9a..6ef9a94 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java
@@ -139,7 +139,7 @@ public class BinaryFieldPanel extends FieldPanel<String> {
 
                     getRequestCycle().scheduleRequestHandlerAfterCurrent(rsrh);
                 } catch (Exception e) {
-                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
                 }
             }
         };

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobActionPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobActionPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobActionPanel.java
index bd55689..9c20635 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobActionPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobActionPanel.java
@@ -19,15 +19,16 @@
 package org.apache.syncope.client.console.widgets;
 
 import java.io.Serializable;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.wicket.ajax.markup.html.IndicatorAjaxLink;
 import org.apache.syncope.common.lib.to.JobTO;
 import org.apache.syncope.common.lib.types.JobAction;
 import org.apache.syncope.common.rest.api.service.NotificationService;
 import org.apache.syncope.common.rest.api.service.ReportService;
 import org.apache.syncope.common.rest.api.service.TaskService;
 import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.markup.html.AjaxLink;
 import org.apache.wicket.event.Broadcast;
 import org.apache.wicket.markup.html.panel.Fragment;
 import org.apache.wicket.markup.html.panel.Panel;
@@ -47,7 +48,7 @@ public class JobActionPanel extends Panel {
         Fragment controls;
         if (jobTO.isRunning()) {
             controls = new Fragment("controls", "runningFragment", this);
-            controls.add(new AjaxLink<Void>("stop") {
+            controls.add(new IndicatorAjaxLink<Void>("stop") {
 
                 private static final long serialVersionUID = -7978723352517770644L;
 
@@ -76,14 +77,14 @@ public class JobActionPanel extends Panel {
                         send(widget, Broadcast.EXACT, new JobActionPayload(target));
                     } catch (Exception e) {
                         LOG.error("While stopping {}", jobTO.getRefDesc(), e);
-                        error(getString(Constants.ERROR) + ": " + e.getMessage());
+                        error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
                     }
                     SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                 }
             });
         } else {
             controls = new Fragment("controls", "notRunningFragment", this);
-            controls.add(new AjaxLink<Void>("start") {
+            controls.add(new IndicatorAjaxLink<Void>("start") {
 
                 private static final long serialVersionUID = -7978723352517770644L;
 
@@ -111,8 +112,8 @@ public class JobActionPanel extends Panel {
                         info(getString(Constants.OPERATION_SUCCEEDED));
                         send(widget, Broadcast.EXACT, new JobActionPayload(target));
                     } catch (Exception e) {
-                        LOG.error("While stopping {}", jobTO.getRefDesc(), e);
-                        error(getString(Constants.ERROR) + ": " + e.getMessage());
+                        LOG.error("While starting {}", jobTO.getRefDesc(), e);
+                        error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
                     }
                     SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
                 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java
index 89f1964..9fd5186 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.widgets;
 
+import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -51,7 +52,10 @@ import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
+import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
+import org.apache.wicket.extensions.markup.html.tabs.ITab;
 import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.markup.repeater.Item;
 import org.apache.wicket.model.CompoundPropertyModel;
 import org.apache.wicket.model.IModel;
@@ -97,26 +101,20 @@ public class JobWidget extends AbstractWidget {
 
     private final List<JobTO> available;
 
-    private final AvailableJobsPanel availableJobsPanel;
+    private AvailableJobsPanel availableJobsPanel;
 
     private final List<ExecTO> recent;
 
-    private final RecentExecPanel recentExecPanel;
+    private RecentExecPanel recentExecPanel;
 
     public JobWidget(final String id, final PageReference pageRef) {
         super(id);
-
         setOutputMarkupId(true);
 
         available = getAvailable(SyncopeConsoleSession.get());
-        availableJobsPanel = new AvailableJobsPanel("available", pageRef);
-        availableJobsPanel.setOutputMarkupId(true);
-        add(availableJobsPanel);
-
         recent = getRecent(SyncopeConsoleSession.get());
-        recentExecPanel = new RecentExecPanel("recent", pageRef);
-        recentExecPanel.setOutputMarkupId(true);
-        add(recentExecPanel);
+
+        add(new AjaxBootstrapTabbedPanel<>("tabbedPanel", buildTabList(pageRef)));
 
         add(new WebSocketBehavior() {
 
@@ -130,6 +128,36 @@ public class JobWidget extends AbstractWidget {
         });
     }
 
+    private List<ITab> buildTabList(final PageReference pageRef) {
+        final List<ITab> tabs = new ArrayList<>();
+
+        tabs.add(new AbstractTab(new ResourceModel("available")) {
+
+            private static final long serialVersionUID = -6815067322125799251L;
+
+            @Override
+            public Panel getPanel(final String panelId) {
+                availableJobsPanel = new AvailableJobsPanel(panelId, pageRef);
+                availableJobsPanel.setOutputMarkupId(true);
+                return availableJobsPanel;
+            }
+        });
+
+        tabs.add(new AbstractTab(new ResourceModel("recent")) {
+
+            private static final long serialVersionUID = -6815067322125799251L;
+
+            @Override
+            public Panel getPanel(final String panelId) {
+                recentExecPanel = new RecentExecPanel(panelId, pageRef);
+                recentExecPanel.setOutputMarkupId(true);
+                return recentExecPanel;
+            }
+        });
+
+        return tabs;
+    }
+
     @Override
     public void onEvent(final IEvent<?> event) {
         if (event.getPayload() instanceof WebSocketPushPayload) {
@@ -141,10 +169,14 @@ public class JobWidget extends AbstractWidget {
                 recent.clear();
                 recent.addAll(((JobWidgetMessage) wsEvent.getMessage()).getUpdatedRecent());
 
-                availableJobsPanel.modelChanged();
-                wsEvent.getHandler().add(availableJobsPanel);
-                recentExecPanel.modelChanged();
-                wsEvent.getHandler().add(recentExecPanel);
+                if (availableJobsPanel != null) {
+                    availableJobsPanel.modelChanged();
+                    wsEvent.getHandler().add(availableJobsPanel);
+                }
+                if (recentExecPanel != null) {
+                    recentExecPanel.modelChanged();
+                    wsEvent.getHandler().add(recentExecPanel);
+                }
             }
         } else if (event.getPayload() instanceof JobActionPanel.JobActionPayload) {
             available.clear();
@@ -402,6 +434,5 @@ public class JobWidget extends AbstractWidget {
         public List<ExecTO> getUpdatedRecent() {
             return updatedRecent;
         }
-
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressBean.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressBean.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressBean.java
new file mode 100644
index 0000000..3882471
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressBean.java
@@ -0,0 +1,71 @@
+/*
+ * 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.widgets;
+
+import java.io.Serializable;
+
+public class ProgressBean implements Serializable {
+
+    private static final long serialVersionUID = 7135463859007124458L;
+
+    private String text;
+
+    private int fraction;
+
+    private int total;
+
+    private String cssClass;
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(final String text) {
+        this.text = text;
+    }
+
+    public int getFraction() {
+        return fraction;
+    }
+
+    public void setFraction(final int fraction) {
+        this.fraction = fraction;
+    }
+
+    public int getTotal() {
+        return total;
+    }
+
+    public void setTotal(final int total) {
+        this.total = total;
+    }
+
+    public float getPercent() {
+        return getTotal() == 0 ? 0 : 100 * getFraction() / getTotal();
+    }
+
+    public String getCssClass() {
+        return cssClass;
+    }
+
+    public void setCssClass(final String cssClass) {
+        this.cssClass = cssClass;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressPanel.java
new file mode 100644
index 0000000..f82aedd
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressPanel.java
@@ -0,0 +1,45 @@
+/*
+ * 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.widgets;
+
+import org.apache.wicket.AttributeModifier;
+import org.apache.wicket.behavior.AttributeAppender;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.panel.Panel;
+
+public class ProgressPanel extends Panel {
+
+    private static final long serialVersionUID = -8854916811656228816L;
+
+    public ProgressPanel(final String id, final ProgressBean progressBean) {
+        super(id);
+        setOutputMarkupId(true);
+
+        add(new Label("text", progressBean.getText()));
+        add(new Label("fraction", progressBean.getFraction()));
+        add(new Label("total", progressBean.getTotal()));
+
+        WebMarkupContainer progress = new WebMarkupContainer("progress");
+        progress.add(new AttributeModifier("style", "width: " + progressBean.getPercent() + "%"));
+        progress.add(new AttributeAppender("class", " " + progressBean.getCssClass()));
+        add(progress);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressesPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressesPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressesPanel.java
new file mode 100644
index 0000000..923a653
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ProgressesPanel.java
@@ -0,0 +1,51 @@
+/*
+ * 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.widgets;
+
+import java.util.Date;
+import java.util.List;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.markup.html.panel.Panel;
+
+public class ProgressesPanel extends Panel {
+
+    private static final long serialVersionUID = 7837262802315339565L;
+
+    public ProgressesPanel(final String id, final Date lastUpdate, final List<ProgressBean> progressBeans) {
+        super(id);
+
+        add(new Label("lastUpdate", SyncopeConsoleSession.get().getDateFormat().format(lastUpdate)));
+
+        ListView<ProgressBean> progresses = new ListView<ProgressBean>("progresses", progressBeans) {
+
+            private static final long serialVersionUID = -9180479401817023838L;
+
+            @Override
+            protected void populateItem(final ListItem<ProgressBean> item) {
+                item.add(new ProgressPanel("progress", item.getModelObject()));
+            }
+        };
+        progresses.setOutputMarkupId(true);
+        add(progresses);
+    }
+
+}