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/02 16:21:13 UTC

syncope git commit: [SYNCOPE-744] New look for the dashboard, job widget completed

Repository: syncope
Updated Branches:
  refs/heads/master 981dba133 -> 03b743992


[SYNCOPE-744] New look for the dashboard, job widget completed


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

Branch: refs/heads/master
Commit: 03b743992215a24fe131fe4e00f2171911e55f1d
Parents: 981dba1
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Mar 2 16:20:08 2016 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Mar 2 16:20:08 2016 +0100

----------------------------------------------------------------------
 .../client/console/commons/Constants.java       |   4 -
 .../syncope/client/console/pages/Dashboard.java | 183 ++++---------------
 .../syncope/client/console/pages/Logs.java      |   4 +-
 .../syncope/client/console/pages/Types.java     |   6 +-
 .../console/panels/DashboardControlPanel.java   |  43 +++++
 .../panels/DashboardExtensionsPanel.java        |  31 ++++
 .../console/panels/DashboardOverviewPanel.java  | 181 ++++++++++++++++++
 .../client/console/panels/MultilevelPanel.java  |   3 -
 .../client/console/tasks/ExecMessage.java       |   2 +-
 .../ProvisioningTaskSearchResultPanel.java      |   2 +-
 .../console/tasks/SchedTaskWizardBuilder.java   |   6 +-
 .../tasks/SyncTaskSearchResultPanel.java        |   2 +-
 .../console/tasks/TaskSearchResultPanel.java    |   2 +-
 .../wicket/ajax/IndicatorAjaxEventBehavior.java |  40 ----
 .../client/console/widgets/JobWidget.java       |  47 +----
 .../client/console/wizards/WizardMgtPanel.java  |   2 +-
 .../syncope/client/console/pages/Dashboard.html |  35 +---
 .../client/console/pages/Dashboard.properties   |  18 ++
 .../console/pages/Dashboard_it.properties       |  18 ++
 .../console/pages/Dashboard_pt_BR.properties    |  18 ++
 .../console/panels/DashboardControlPanel.html   |  27 +++
 .../panels/DashboardExtensionsPanel.html        |  22 +++
 .../console/panels/DashboardOverviewPanel.html  |  48 +++++
 23 files changed, 459 insertions(+), 285 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
index 0c50aa5..2a508d1 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
@@ -26,10 +26,6 @@ public final class Constants {
 
     public static final String ON_BLUR = "blur";
 
-    public static final String ON_MOUSE_ENTER = "mouseenter";
-
-    public static final String ON_MOUSE_LEAVE = "mouseleave";
-
     public static final String PNG_EXT = ".png";
 
     public static final String FEEDBACK = "feedback";

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/java/org/apache/syncope/client/console/pages/Dashboard.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Dashboard.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Dashboard.java
index 4d26d93..10a6a5f 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Dashboard.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Dashboard.java
@@ -18,176 +18,65 @@
  */
 package org.apache.syncope.client.console.pages;
 
-import org.apache.commons.lang3.tuple.Triple;
-import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.wicket.ajax.IndicatorAjaxTimerBehavior;
-import org.apache.syncope.client.console.widgets.NumberWidget;
-import org.apache.syncope.client.console.widgets.AnyByRealmWidget;
-import org.apache.syncope.client.console.widgets.CompletenessWidget;
-import org.apache.syncope.client.console.widgets.JobWidget;
-import org.apache.syncope.client.console.widgets.LoadWidget;
-import org.apache.syncope.client.console.widgets.UsersByStatusWidget;
-import org.apache.syncope.common.lib.info.NumbersInfo;
-import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.common.rest.api.service.SyncopeService;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.syncope.client.console.panels.DashboardControlPanel;
+import org.apache.syncope.client.console.panels.DashboardExtensionsPanel;
+import org.apache.syncope.client.console.panels.DashboardOverviewPanel;
+import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
+import org.apache.wicket.extensions.markup.html.tabs.ITab;
 import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
-import org.apache.wicket.util.time.Duration;
 
 public class Dashboard extends BasePage {
 
     private static final long serialVersionUID = -1100228004207271270L;
 
-    private final NumberWidget totalUsers;
-
-    private final NumberWidget totalGroups;
-
-    private final NumberWidget totalAny1OrRoles;
-
-    private final NumberWidget totalAny2OrResources;
-
-    private final UsersByStatusWidget usersByStatus;
-
-    private final CompletenessWidget completeness;
-
-    private final AnyByRealmWidget anyByRealm;
-
-    private final LoadWidget load;
-
     public Dashboard(final PageParameters parameters) {
         super(parameters);
 
-        NumbersInfo numbers = SyncopeConsoleSession.get().getService(SyncopeService.class).numbers();
-
-        WebMarkupContainer timer = new WebMarkupContainer("timer");
-        timer.setOutputMarkupId(true);
-        body.add(timer);
+        WebMarkupContainer content = new WebMarkupContainer("content");
+        content.setOutputMarkupId(true);
+        content.add(new AjaxBootstrapTabbedPanel<>("tabbedPanel", buildTabList()));
+        body.add(content);
+    }
 
-        totalUsers = new NumberWidget(
-                "totalUsers", "bg-yellow", numbers.getTotalUsers(), getString("users"), "ion ion-person");
-        timer.add(totalUsers);
-        totalGroups = new NumberWidget(
-                "totalGroups", "bg-red", numbers.getTotalGroups(), getString("groups"), "ion ion-person-stalker");
-        timer.add(totalGroups);
+    private List<ITab> buildTabList() {
+        final List<ITab> tabs = new ArrayList<>();
 
-        Triple<Integer, String, String> built = buildTotalAny1OrRoles(numbers);
-        totalAny1OrRoles = new NumberWidget(
-                "totalAny1OrRoles", "bg-green", built.getLeft(), built.getMiddle(), built.getRight());
-        timer.add(totalAny1OrRoles);
+        tabs.add(new AbstractTab(new ResourceModel("overview")) {
 
-        built = buildTotalAny2OrResources(numbers);
-        totalAny2OrResources = new NumberWidget(
-                "totalAny2OrResources", "bg-aqua", built.getLeft(), built.getMiddle(), built.getRight());
-        timer.add(totalAny2OrResources);
+            private static final long serialVersionUID = -6815067322125799251L;
 
-        usersByStatus = new UsersByStatusWidget("usersByStatus", numbers.getUsersByStatus());
-        timer.add(usersByStatus);
+            @Override
+            public Panel getPanel(final String panelId) {
+                return new DashboardOverviewPanel(panelId);
+            }
+        });
 
-        completeness = new CompletenessWidget("completeness", numbers.getConfCompleteness());
-        timer.add(completeness);
+        tabs.add(new AbstractTab(new ResourceModel("control")) {
 
-        anyByRealm = new AnyByRealmWidget(
-                "anyByRealm",
-                numbers.getUsersByRealm(),
-                numbers.getGroupsByRealm(),
-                numbers.getAnyType1(),
-                numbers.getAny1ByRealm(),
-                numbers.getAnyType2(),
-                numbers.getAny2ByRealm());
-        timer.add(anyByRealm);
+            private static final long serialVersionUID = -6815067322125799251L;
 
-        load = new LoadWidget("load", SyncopeConsoleSession.get().getService(SyncopeService.class).system());
-        timer.add(load);
+            @Override
+            public Panel getPanel(final String panelId) {
+                return new DashboardControlPanel(panelId, getPageReference());
+            }
+        });
 
-        timer.add(new IndicatorAjaxTimerBehavior(Duration.seconds(60)) {
+        tabs.add(new AbstractTab(new ResourceModel("extensions")) {
 
-            private static final long serialVersionUID = -4426283634345968585L;
+            private static final long serialVersionUID = -6815067322125799251L;
 
             @Override
-            protected void onTimer(final AjaxRequestTarget target) {
-                NumbersInfo numbers = SyncopeConsoleSession.get().getService(SyncopeService.class).numbers();
-
-                if (totalUsers.refresh(numbers.getTotalUsers())) {
-                    target.add(totalUsers);
-                }
-                if (totalGroups.refresh(numbers.getTotalGroups())) {
-                    target.add(totalGroups);
-                }
-
-                Triple<Integer, String, String> updatedBuild = buildTotalAny1OrRoles(numbers);
-                if (totalAny1OrRoles.refresh(updatedBuild.getLeft())) {
-                    target.add(totalAny1OrRoles);
-                }
-                updatedBuild = buildTotalAny2OrResources(numbers);
-                if (totalAny2OrResources.refresh(updatedBuild.getLeft())) {
-                    target.add(totalAny2OrResources);
-                }
-
-                if (usersByStatus.refresh(numbers.getUsersByStatus())) {
-                    target.add(usersByStatus);
-                }
-
-                if (completeness.refresh(numbers.getConfCompleteness())) {
-                    target.add(completeness);
-                }
-
-                if (anyByRealm.refresh(
-                        numbers.getUsersByRealm(),
-                        numbers.getGroupsByRealm(),
-                        numbers.getAnyType1(),
-                        numbers.getAny1ByRealm(),
-                        numbers.getAnyType2(),
-                        numbers.getAny2ByRealm())) {
-
-                    target.add(anyByRealm);
-                }
-
-                load.refresh(SyncopeConsoleSession.get().getService(SyncopeService.class).system());
-                target.add(load);
+            public Panel getPanel(final String panelId) {
+                return new DashboardExtensionsPanel(panelId, getPageReference());
             }
         });
 
-        JobWidget job = new JobWidget("job", getPageReference());
-        MetaDataRoleAuthorizationStrategy.authorize(job, WebPage.ENABLE,
-                String.format("%s,%s,%s",
-                        StandardEntitlement.NOTIFICATION_LIST,
-                        StandardEntitlement.TASK_LIST,
-                        StandardEntitlement.REPORT_LIST));
-        body.add(job);
-    }
-
-    private Triple<Integer, String, String> buildTotalAny1OrRoles(final NumbersInfo numbers) {
-        int number;
-        String label;
-        String icon;
-        if (numbers.getAnyType1() == null) {
-            number = numbers.getTotalRoles();
-            label = getString("roles");
-            icon = "fa fa-users";
-        } else {
-            number = numbers.getTotalAny1();
-            label = numbers.getAnyType1();
-            icon = "ion ion-gear-a";
-        }
-        return Triple.of(number, label, icon);
-    }
-
-    private Triple<Integer, String, String> buildTotalAny2OrResources(final NumbersInfo numbers) {
-        int number;
-        String label;
-        String icon;
-        if (numbers.getAnyType2() == null) {
-            number = numbers.getTotalResources();
-            label = getString("resources");
-            icon = "fa fa-database";
-        } else {
-            number = numbers.getTotalAny2();
-            label = numbers.getAnyType2();
-            icon = "ion ion-gear-a";
-        }
-        return Triple.of(number, label, icon);
+        return tabs;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/java/org/apache/syncope/client/console/pages/Logs.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Logs.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Logs.java
index b0e4538..c1816b9 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Logs.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Logs.java
@@ -39,9 +39,7 @@ public class Logs extends BasePage {
 
         WebMarkupContainer content = new WebMarkupContainer("content");
         content.setOutputMarkupId(true);
-        AjaxBootstrapTabbedPanel<ITab> tabbedPanel = new AjaxBootstrapTabbedPanel<>("tabbedPanel", buildTabList());
-        content.add(tabbedPanel);
-
+        content.add(new AjaxBootstrapTabbedPanel<>("tabbedPanel", buildTabList()));
         body.add(content);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/java/org/apache/syncope/client/console/pages/Types.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Types.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Types.java
index e4f8877..d815958 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Types.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Types.java
@@ -36,8 +36,6 @@ public class Types extends BasePage {
 
     private static final long serialVersionUID = 8091922398776299403L;
 
-    private final AjaxBootstrapTabbedPanel<ITab> tabbedPanel;
-
     private enum Type {
         SCHEMA,
         ANYTYPECLASS,
@@ -51,13 +49,11 @@ public class Types extends BasePage {
 
         WebMarkupContainer content = new WebMarkupContainer("content");
         content.setOutputMarkupId(true);
-        tabbedPanel = new AjaxBootstrapTabbedPanel<>("tabbedPanel", buildTabList());
-        content.add(tabbedPanel);
+        content.add(new AjaxBootstrapTabbedPanel<>("tabbedPanel", buildTabList()));
         body.add(content);
     }
 
     private List<ITab> buildTabList() {
-
         final List<ITab> tabs = new ArrayList<>();
 
         tabs.add(new AbstractTab(new Model<>("RelationshipTypes")) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/java/org/apache/syncope/client/console/panels/DashboardControlPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/DashboardControlPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/DashboardControlPanel.java
new file mode 100644
index 0000000..0c993b8
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/DashboardControlPanel.java
@@ -0,0 +1,43 @@
+/*
+ * 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 org.apache.syncope.client.console.widgets.JobWidget;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.panel.Panel;
+
+public class DashboardControlPanel extends Panel {
+
+    private static final long serialVersionUID = -776362411304859269L;
+
+    public DashboardControlPanel(final String id, final PageReference pageRef) {
+        super(id);
+
+        JobWidget job = new JobWidget("job", pageRef);
+        MetaDataRoleAuthorizationStrategy.authorize(job, WebPage.ENABLE,
+                String.format("%s,%s,%s",
+                        StandardEntitlement.NOTIFICATION_LIST,
+                        StandardEntitlement.TASK_LIST,
+                        StandardEntitlement.REPORT_LIST));
+        add(job);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/java/org/apache/syncope/client/console/panels/DashboardExtensionsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/DashboardExtensionsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/DashboardExtensionsPanel.java
new file mode 100644
index 0000000..f2639f8
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/DashboardExtensionsPanel.java
@@ -0,0 +1,31 @@
+/*
+ * 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 org.apache.wicket.PageReference;
+import org.apache.wicket.markup.html.panel.Panel;
+
+public class DashboardExtensionsPanel extends Panel {
+
+    private static final long serialVersionUID = 6381578992589664490L;
+
+    public DashboardExtensionsPanel(final String id, final PageReference pageRef) {
+        super(id);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/java/org/apache/syncope/client/console/panels/DashboardOverviewPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/DashboardOverviewPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/DashboardOverviewPanel.java
new file mode 100644
index 0000000..98508ef
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/DashboardOverviewPanel.java
@@ -0,0 +1,181 @@
+/*
+ * 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 org.apache.commons.lang3.tuple.Triple;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.wicket.ajax.IndicatorAjaxTimerBehavior;
+import org.apache.syncope.client.console.widgets.AnyByRealmWidget;
+import org.apache.syncope.client.console.widgets.CompletenessWidget;
+import org.apache.syncope.client.console.widgets.LoadWidget;
+import org.apache.syncope.client.console.widgets.NumberWidget;
+import org.apache.syncope.client.console.widgets.UsersByStatusWidget;
+import org.apache.syncope.common.lib.info.NumbersInfo;
+import org.apache.syncope.common.rest.api.service.SyncopeService;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.util.time.Duration;
+
+public class DashboardOverviewPanel extends Panel {
+
+    private static final long serialVersionUID = 5989039374050260225L;
+
+    private final NumberWidget totalUsers;
+
+    private final NumberWidget totalGroups;
+
+    private final NumberWidget totalAny1OrRoles;
+
+    private final NumberWidget totalAny2OrResources;
+
+    private final UsersByStatusWidget usersByStatus;
+
+    private final CompletenessWidget completeness;
+
+    private final AnyByRealmWidget anyByRealm;
+
+    private final LoadWidget load;
+
+    public DashboardOverviewPanel(final String id) {
+        super(id);
+
+        NumbersInfo numbers = SyncopeConsoleSession.get().getService(SyncopeService.class).numbers();
+
+        WebMarkupContainer container = new WebMarkupContainer("container");
+        container.setOutputMarkupId(true);
+        add(container);
+
+        totalUsers = new NumberWidget(
+                "totalUsers", "bg-yellow", numbers.getTotalUsers(), getString("users"), "ion ion-person");
+        container.add(totalUsers);
+        totalGroups = new NumberWidget(
+                "totalGroups", "bg-red", numbers.getTotalGroups(), getString("groups"), "ion ion-person-stalker");
+        container.add(totalGroups);
+
+        Triple<Integer, String, String> built = buildTotalAny1OrRoles(numbers);
+        totalAny1OrRoles = new NumberWidget(
+                "totalAny1OrRoles", "bg-green", built.getLeft(), built.getMiddle(), built.getRight());
+        container.add(totalAny1OrRoles);
+
+        built = buildTotalAny2OrResources(numbers);
+        totalAny2OrResources = new NumberWidget(
+                "totalAny2OrResources", "bg-aqua", built.getLeft(), built.getMiddle(), built.getRight());
+        container.add(totalAny2OrResources);
+
+        usersByStatus = new UsersByStatusWidget("usersByStatus", numbers.getUsersByStatus());
+        container.add(usersByStatus);
+
+        completeness = new CompletenessWidget("completeness", numbers.getConfCompleteness());
+        container.add(completeness);
+
+        anyByRealm = new AnyByRealmWidget(
+                "anyByRealm",
+                numbers.getUsersByRealm(),
+                numbers.getGroupsByRealm(),
+                numbers.getAnyType1(),
+                numbers.getAny1ByRealm(),
+                numbers.getAnyType2(),
+                numbers.getAny2ByRealm());
+        container.add(anyByRealm);
+
+        load = new LoadWidget("load", SyncopeConsoleSession.get().getService(SyncopeService.class).system());
+        container.add(load);
+
+        container.add(new IndicatorAjaxTimerBehavior(Duration.seconds(60)) {
+
+            private static final long serialVersionUID = -4426283634345968585L;
+
+            @Override
+            protected void onTimer(final AjaxRequestTarget target) {
+                NumbersInfo numbers = SyncopeConsoleSession.get().getService(SyncopeService.class).numbers();
+
+                if (totalUsers.refresh(numbers.getTotalUsers())) {
+                    target.add(totalUsers);
+                }
+                if (totalGroups.refresh(numbers.getTotalGroups())) {
+                    target.add(totalGroups);
+                }
+
+                Triple<Integer, String, String> updatedBuild = buildTotalAny1OrRoles(numbers);
+                if (totalAny1OrRoles.refresh(updatedBuild.getLeft())) {
+                    target.add(totalAny1OrRoles);
+                }
+                updatedBuild = buildTotalAny2OrResources(numbers);
+                if (totalAny2OrResources.refresh(updatedBuild.getLeft())) {
+                    target.add(totalAny2OrResources);
+                }
+
+                if (usersByStatus.refresh(numbers.getUsersByStatus())) {
+                    target.add(usersByStatus);
+                }
+
+                if (completeness.refresh(numbers.getConfCompleteness())) {
+                    target.add(completeness);
+                }
+
+                if (anyByRealm.refresh(
+                        numbers.getUsersByRealm(),
+                        numbers.getGroupsByRealm(),
+                        numbers.getAnyType1(),
+                        numbers.getAny1ByRealm(),
+                        numbers.getAnyType2(),
+                        numbers.getAny2ByRealm())) {
+
+                    target.add(anyByRealm);
+                }
+
+                load.refresh(SyncopeConsoleSession.get().getService(SyncopeService.class).system());
+                target.add(load);
+            }
+        });
+    }
+
+    private Triple<Integer, String, String> buildTotalAny1OrRoles(final NumbersInfo numbers) {
+        int number;
+        String label;
+        String icon;
+        if (numbers.getAnyType1() == null) {
+            number = numbers.getTotalRoles();
+            label = getString("roles");
+            icon = "fa fa-users";
+        } else {
+            number = numbers.getTotalAny1();
+            label = numbers.getAnyType1();
+            icon = "ion ion-gear-a";
+        }
+        return Triple.of(number, label, icon);
+    }
+
+    private Triple<Integer, String, String> buildTotalAny2OrResources(final NumbersInfo numbers) {
+        int number;
+        String label;
+        String icon;
+        if (numbers.getAnyType2() == null) {
+            number = numbers.getTotalResources();
+            label = getString("resources");
+            icon = "fa fa-database";
+        } else {
+            number = numbers.getTotalAny2();
+            label = numbers.getAnyType2();
+            icon = "ion ion-gear-a";
+        }
+        return Triple.of(number, label, icon);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/java/org/apache/syncope/client/console/panels/MultilevelPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/MultilevelPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/MultilevelPanel.java
index a3cfeda..56711f4 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/MultilevelPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/MultilevelPanel.java
@@ -33,9 +33,6 @@ public class MultilevelPanel extends Panel implements IHeaderContributor {
 
     private static final long serialVersionUID = -4064294905566247729L;
 
-    /**
-     * Logger.
-     */
     protected static final Logger LOG = LoggerFactory.getLogger(MultilevelPanel.class);
 
     private boolean isFirstLevel = true;

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/java/org/apache/syncope/client/console/tasks/ExecMessage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/ExecMessage.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/ExecMessage.java
index 50a8fa8..9c30ce9 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/ExecMessage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/ExecMessage.java
@@ -28,7 +28,7 @@ public class ExecMessage extends MultilevelPanel.SecondLevel {
 
     public ExecMessage(final String message) {
         super();
-        final Label dialogContent = new Label("message", new Model<String>(message));
+        final Label dialogContent = new Label("message", new Model<>(message));
         add(dialogContent.setOutputMarkupId(true));
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/java/org/apache/syncope/client/console/tasks/ProvisioningTaskSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/ProvisioningTaskSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/ProvisioningTaskSearchResultPanel.java
index ee4a6b3..e3c589d 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/ProvisioningTaskSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/ProvisioningTaskSearchResultPanel.java
@@ -65,7 +65,7 @@ public abstract class ProvisioningTaskSearchResultPanel<T extends AbstractProvis
 
     @Override
     protected List<IColumn<T, String>> getFieldColumns() {
-        final List<IColumn<T, String>> columns = new ArrayList<IColumn<T, String>>();
+        final List<IColumn<T, String>> columns = new ArrayList<>();
 
         columns.add(new PropertyColumn<T, String>(
                 new StringResourceModel("key", this, null), "key", "key"));

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder.java
index 07e98b7..b7bd69c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder.java
@@ -93,8 +93,8 @@ public class SchedTaskWizardBuilder<T extends SchedTaskTO> extends AjaxWizardBui
         };
 
         public Profile(final SchedTaskTO taskTO) {
-            final AjaxTextFieldPanel name
-                    = new AjaxTextFieldPanel("name", "name", new PropertyModel<String>(taskTO, "name"), false);
+            final AjaxTextFieldPanel name =
+                    new AjaxTextFieldPanel("name", "name", new PropertyModel<String>(taskTO, "name"), false);
             name.setEnabled(true);
             add(name);
 
@@ -144,7 +144,7 @@ public class SchedTaskWizardBuilder<T extends SchedTaskTO> extends AjaxWizardBui
                     new PropertyModel<String>(taskTO, "destinationRealm"), false);
             syncTaskSpecifics.add(destinationRealm);
 
-            final AjaxDropDownChoicePanel<String> className = new AjaxDropDownChoicePanel<String>(
+            final AjaxDropDownChoicePanel<String> className = new AjaxDropDownChoicePanel<>(
                     "jobDelegateClassName",
                     getString("jobDelegateClassName"),
                     new PropertyModel<String>(taskTO, "jobDelegateClassName"), false);

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/java/org/apache/syncope/client/console/tasks/SyncTaskSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SyncTaskSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SyncTaskSearchResultPanel.java
index a5ad32f..6112d67 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SyncTaskSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SyncTaskSearchResultPanel.java
@@ -43,6 +43,6 @@ public abstract class SyncTaskSearchResultPanel extends ProvisioningTaskSearchRe
 
     @Override
     protected ProvisioningTasksProvider<SyncTaskTO> dataProvider() {
-        return new ProvisioningTasksProvider<SyncTaskTO>(reference, TaskType.SYNCHRONIZATION, rows);
+        return new ProvisioningTasksProvider<>(reference, TaskType.SYNCHRONIZATION, rows);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskSearchResultPanel.java
index c1793a0..db426af 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskSearchResultPanel.java
@@ -88,7 +88,7 @@ public abstract class TaskSearchResultPanel<T extends AbstractTaskTO>
 
             //Default sorting
             setSort("key", SortOrder.DESCENDING);
-            comparator = new SortableDataProviderComparator<T>(this);
+            comparator = new SortableDataProviderComparator<>(this);
             this.id = id;
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/IndicatorAjaxEventBehavior.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/IndicatorAjaxEventBehavior.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/IndicatorAjaxEventBehavior.java
deleted file mode 100644
index b286486..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/IndicatorAjaxEventBehavior.java
+++ /dev/null
@@ -1,40 +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;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.wicket.ajax.AjaxEventBehavior;
-import org.apache.wicket.ajax.IAjaxIndicatorAware;
-
-/**
- * An {@link AjaxEventBehavior} not showin veil.
- */
-public abstract class IndicatorAjaxEventBehavior extends AjaxEventBehavior implements IAjaxIndicatorAware {
-
-    private static final long serialVersionUID = 8531694702059356303L;
-
-    public IndicatorAjaxEventBehavior(final String event) {
-        super(event);
-    }
-
-    @Override
-    public String getAjaxIndicatorMarkupId() {
-        return StringUtils.EMPTY;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/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 4b49af8..89f1964 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
@@ -27,12 +27,10 @@ import java.util.List;
 import java.util.concurrent.TimeUnit;
 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.SearchableDataProvider;
 import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
 import org.apache.syncope.client.console.panels.AbstractSearchResultPanel;
 import org.apache.syncope.client.console.rest.BaseRestClient;
-import org.apache.syncope.client.console.wicket.ajax.IndicatorAjaxEventBehavior;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.BooleanPropertyColumn;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.DatePropertyColumn;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
@@ -46,7 +44,6 @@ import org.apache.syncope.common.rest.api.service.TaskService;
 import org.apache.wicket.Application;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ThreadContext;
-import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
 import org.apache.wicket.event.IEvent;
 import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
@@ -106,10 +103,6 @@ public class JobWidget extends AbstractWidget {
 
     private final RecentExecPanel recentExecPanel;
 
-    private boolean refresh = true;
-
-    private boolean pendingRefresh = false;
-
     public JobWidget(final String id, final PageReference pageRef) {
         super(id);
 
@@ -135,34 +128,6 @@ public class JobWidget extends AbstractWidget {
                 SyncopeConsoleSession.get().scheduleAtFixedRate(new JobInfoUpdater(message), 0, 10, TimeUnit.SECONDS);
             }
         });
-
-        add(new IndicatorAjaxEventBehavior(Constants.ON_MOUSE_ENTER) {
-
-            private static final long serialVersionUID = -7133385027739964990L;
-
-            @Override
-            protected void onEvent(final AjaxRequestTarget target) {
-                refresh = false;
-                LOG.debug("Refresh disabled");
-            }
-        });
-        add(new IndicatorAjaxEventBehavior(Constants.ON_MOUSE_LEAVE) {
-
-            private static final long serialVersionUID = -7133385027739964990L;
-
-            @Override
-            protected void onEvent(final AjaxRequestTarget target) {
-                refresh = true;
-                LOG.debug("Refresh enabled");
-
-                if (pendingRefresh) {
-                    LOG.debug("Refresh pending");
-
-                    target.add(availableJobsPanel);
-                    pendingRefresh = false;
-                }
-            }
-        });
     }
 
     @Override
@@ -176,14 +141,10 @@ public class JobWidget extends AbstractWidget {
                 recent.clear();
                 recent.addAll(((JobWidgetMessage) wsEvent.getMessage()).getUpdatedRecent());
 
-                if (refresh) {
-                    availableJobsPanel.modelChanged();
-                    wsEvent.getHandler().add(availableJobsPanel);
-                    recentExecPanel.modelChanged();
-                    wsEvent.getHandler().add(recentExecPanel);
-                } else {
-                    pendingRefresh = true;
-                }
+                availableJobsPanel.modelChanged();
+                wsEvent.getHandler().add(availableJobsPanel);
+                recentExecPanel.modelChanged();
+                wsEvent.getHandler().add(recentExecPanel);
             }
         } else if (event.getPayload() instanceof JobActionPanel.JobActionPayload) {
             available.clear();

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
index c0e86bd..1c90828 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
@@ -82,7 +82,7 @@ public abstract class WizardMgtPanel<T extends Serializable> extends Panel imple
     /**
      * Modal window.
      */
-    protected final BaseModal<T> alternativeDefaultModal = new BaseModal<T>("alternativeDefaultModal");
+    protected final BaseModal<T> alternativeDefaultModal = new BaseModal<>("alternativeDefaultModal");
 
     protected WizardMgtPanel(final String id) {
         this(id, false);

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard.html
index fd0f274..4455eb7 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard.html
@@ -24,38 +24,9 @@ under the License.
       </h1>
     </section>
 
-    <section class="content">
-      <div wicket:id="timer">
-        <div class="row">
-          <span wicket:id="totalUsers"/>
-          <span wicket:id="totalGroups"/>
-          <span wicket:id="totalAny1OrRoles"/>
-          <span wicket:id="totalAny2OrResources"/>
-        </div>
-
-        <div class="row">
-          <div class="col-md-4">
-            <span wicket:id="usersByStatus"/>
-          </div>
-          <div class="col-md-4">
-            <span wicket:id="completeness"/>
-          </div>
-          <div class="col-md-4">
-            <span wicket:id="load"/>
-          </div>
-        </div>
-
-        <div class="row">
-          <div class="col-md-6">
-            <span wicket:id="anyByRealm"/>
-          </div>
-        </div>
-      </div>
-
-      <div class="row">
-        <div class="col-md-12">
-          <span wicket:id="job"/>
-        </div>
+    <section class="content" wicket:id="content">
+      <div class="box">
+        <div class="box-body" wicket:id="tabbedPanel"/>
       </div>
     </section>
   </wicket:extend>

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard.properties
new file mode 100644
index 0000000..d736c6d
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard.properties
@@ -0,0 +1,18 @@
+# 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.
+overview=Overview
+control=Control

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard_it.properties
new file mode 100644
index 0000000..c35799a
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard_it.properties
@@ -0,0 +1,18 @@
+# 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.
+overview=Sommario
+control=Gestione

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard_pt_BR.properties
new file mode 100644
index 0000000..a104327
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard_pt_BR.properties
@@ -0,0 +1,18 @@
+# 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.
+overview=Resumo
+control=Gest\u00e3o

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardControlPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardControlPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardControlPanel.html
new file mode 100644
index 0000000..ae731af
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardControlPanel.html
@@ -0,0 +1,27 @@
+<!--
+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 class="row">
+      <div class="col-md-12">
+        <span wicket:id="job"/>
+      </div>
+    </div>
+  </wicket:panel>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardExtensionsPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardExtensionsPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardExtensionsPanel.html
new file mode 100644
index 0000000..102a587
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardExtensionsPanel.html
@@ -0,0 +1,22 @@
+<!--
+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>
+  </wicket:panel>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/03b74399/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardOverviewPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardOverviewPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardOverviewPanel.html
new file mode 100644
index 0000000..7d652b3
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardOverviewPanel.html
@@ -0,0 +1,48 @@
+<!--
+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">
+      <div class="row">
+        <span wicket:id="totalUsers"/>
+        <span wicket:id="totalGroups"/>
+        <span wicket:id="totalAny1OrRoles"/>
+        <span wicket:id="totalAny2OrResources"/>
+      </div>
+
+      <div class="row">
+        <div class="col-md-4">
+          <span wicket:id="usersByStatus"/>
+        </div>
+        <div class="col-md-4">
+          <span wicket:id="completeness"/>
+        </div>
+        <div class="col-md-4">
+          <span wicket:id="load"/>
+        </div>
+      </div>
+
+      <div class="row">
+        <div class="col-md-6">
+          <span wicket:id="anyByRealm"/>
+        </div>
+      </div>
+    </div>
+  </wicket:panel>
+</html>
\ No newline at end of file