syncope-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mdisabat...@apache.org
Subject [4/4] syncope git commit: Add AdminLTe theme provider, new Modal dialog, new Realms tab
Date Fri, 28 Aug 2015 16:40:45 GMT
Add AdminLTe theme provider, new Modal dialog, new Realms tab


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

Branch: refs/heads/SYNCOPE-156
Commit: 0419594e89a7416470bd8950b1cc8cd75d023833
Parents: b2eda99
Author: Marco Di Sabatino Di Diodoro <mdisabatino@apache.org>
Authored: Fri Aug 28 18:37:47 2015 +0200
Committer: Marco Di Sabatino Di Diodoro <mdisabatino@apache.org>
Committed: Fri Aug 28 18:37:47 2015 +0200

----------------------------------------------------------------------
 client/console/pom.xml                          |   16 +-
 .../console/SyncopeConsoleApplication.java      |   10 +
 .../console/pages/EditRealmModalPage.java       |   41 -
 .../client/console/pages/RealmModalPage.java    |  142 -
 .../syncope/client/console/pages/Realms.java    |  185 +-
 .../console/panels/AbstractModalPanel.java      |  120 +
 .../panels/AbstractSearchResultPanel.java       |    3 +-
 .../console/panels/ActionDataTablePanel.java    |    4 +-
 .../console/panels/AjaxDataTablePanel.java      |   13 +-
 .../console/panels/AnySearchResultPanel.java    |   16 +-
 .../client/console/panels/DataTablePanel.java   |    4 +-
 .../console/panels/EditRealmModalPanel.java     |   40 +
 .../console/panels/FailureMessageModal.java     |   40 +
 .../client/console/panels/GroupModalPanel.java  |  122 +
 .../client/console/panels/GroupPanel.java       |   75 +
 .../console/panels/GroupSearchResultPanel.java  |   64 +-
 .../syncope/client/console/panels/Realm.java    |  107 +-
 .../client/console/panels/RealmDetails.java     |   30 +-
 .../client/console/panels/RealmModalPanel.java  |  119 +
 .../console/panels/UserSearchResultPanel.java   |    7 +-
 .../console/rest/AnyObjectRestClient.java       |   17 +
 .../client/console/rest/RealmRestClient.java    |    2 +-
 .../syncope/client/console/themes/AdminLTE.java |   44 +
 .../themes/AdminLTECssResourceReference.java    |   48 +
 .../paging/AjaxDataNavigationToolbar.java       |   52 +
 .../data/table/AjaxFallbackDataTable.java       |   51 +
 .../buttons/DefaultModalCloseButton.java        |   34 +
 .../bootstrap/buttons/PrimaryModalButton.java   |   35 +
 .../markup/html/bootstrap/dialog/BaseModal.java |  110 +
 .../markup/html/form/AjaxTextFieldPanel.java    |    8 +-
 .../wicket/markup/html/form/FieldPanel.java     |    6 +
 .../dataTables/dataTables.bootstrap.css         |  369 ++
 .../META-INF/resources/js/AdminLTE-app.min.js   |   13 -
 .../client/console/pages/BaseModalPage.html     |    9 +-
 .../syncope/client/console/pages/BasePage.html  |    9 +-
 .../syncope/client/console/pages/Login.html     |    5 -
 .../client/console/pages/RealmModalPage.html    |   70 -
 .../syncope/client/console/pages/Realms.html    |    4 +-
 .../console/panels/AbstractModalPanel.html      |   45 +
 .../panels/AbstractSearchResultPanel.html       |   13 +-
 .../console/panels/AnyAjaxTabbedPanel.html      |   35 +
 .../client/console/panels/GroupModalPanel.html  |   52 +
 .../console/panels/GroupModalPanel.properties   |   48 +
 .../panels/GroupModalPanel_it.properties        |   50 +
 .../panels/GroupModalPanel_pt_BR.properties     |   48 +
 .../client/console/panels/ModalContent.html     |   34 +-
 .../syncope/client/console/panels/Realm.html    |   14 +-
 .../client/console/panels/RealmDetails.html     |   25 +-
 .../client/console/panels/RealmModalPanel.html  |   27 +
 .../console/panels/ResourceModalPage.html       |   56 +
 .../console/panels/ResourceModalPage.properties |   60 +
 .../client/console/themes/css/AdminLTE.css      | 4366 ++++++++++++++++++
 .../console/themes/js/AdminLTE-app.min.js       |   13 +
 .../paging/AjaxDataNavigationToolbar.html       |   33 +
 .../markup/html/bootstrap/dialog/BaseModal.html |   47 +
 .../html/bootstrap/dialog/BaseModal.properties  |   21 +
 .../bootstrap/dialog/BaseModal_it.properties    |   21 +
 .../bootstrap/dialog/BaseModal_pt_BR.properties |   21 +
 .../markup/html/form/AjaxTextFieldPanel.html    |    6 +-
 .../markup/html/form/AjaxTextFieldPanel_1.html  |   23 -
 .../wicket/markup/html/form/FieldPanel_1.html   |   34 -
 .../wicket/markup/html/form/LinkPanel_1.html    |   23 -
 pom.xml                                         |   15 +-
 63 files changed, 6553 insertions(+), 621 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/pom.xml
----------------------------------------------------------------------
diff --git a/client/console/pom.xml b/client/console/pom.xml
index 2a0f283..18f9a91 100644
--- a/client/console/pom.xml
+++ b/client/console/pom.xml
@@ -48,7 +48,7 @@ under the License.
       <groupId>org.springframework</groupId>
       <artifactId>spring-web</artifactId>
     </dependency>
-    
+
     <dependency>
       <groupId>org.apache.wicket</groupId>
       <artifactId>wicket</artifactId>
@@ -78,6 +78,14 @@ under the License.
       <groupId>org.apache.wicket</groupId>
       <artifactId>wicket-native-websocket-javax</artifactId>
     </dependency>
+    <dependency>
+      <groupId>de.agilecoders.wicket</groupId>
+      <artifactId>wicket-bootstrap-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>de.agilecoders.wicket</groupId>
+      <artifactId>wicket-bootstrap-extensions</artifactId>
+    </dependency>
       
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
@@ -92,7 +100,7 @@ under the License.
 
     <dependency>
       <groupId>org.webjars</groupId>
-      <artifactId>bootstrap</artifactId>
+      <artifactId>font-awesome</artifactId>
     </dependency>
     <dependency>
       <groupId>org.webjars</groupId>
@@ -100,10 +108,6 @@ under the License.
     </dependency>
     <dependency>
       <groupId>org.webjars</groupId>
-      <artifactId>font-awesome</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.webjars</groupId>
       <artifactId>ionicons</artifactId>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
index 2bff477..9c5a1d8 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
@@ -18,6 +18,10 @@
  */
 package org.apache.syncope.client.console;
 
+import de.agilecoders.wicket.core.Bootstrap;
+import de.agilecoders.wicket.core.settings.BootstrapSettings;
+import de.agilecoders.wicket.core.settings.IBootstrapSettings;
+import de.agilecoders.wicket.core.settings.SingleThemeProvider;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
@@ -29,6 +33,7 @@ import org.apache.syncope.client.console.pages.Login;
 import org.apache.syncope.client.console.resources.FilesystemResource;
 import org.apache.syncope.client.console.resources.WorkflowDefGETResource;
 import org.apache.syncope.client.console.resources.WorkflowDefPUTResource;
+import org.apache.syncope.client.console.themes.AdminLTE;
 import org.apache.wicket.Page;
 import org.apache.wicket.authroles.authentication.AbstractAuthenticatedWebSession;
 import org.apache.wicket.authroles.authentication.AuthenticatedWebApplication;
@@ -61,7 +66,12 @@ public class SyncopeConsoleApplication extends AuthenticatedWebApplication {
     @Override
     protected void init() {
         super.init();
+        IBootstrapSettings settings = new BootstrapSettings();
+        settings.setThemeProvider(new SingleThemeProvider(new AdminLTE()));
+        Bootstrap.install(this, settings);
 
+        // best place to do this is in Application#init()
+        //Bootstrap.install(this);
         getComponentInstantiationListeners().add(new SpringComponentInjector(this));
         getResourceSettings().setThrowExceptionOnMissingResource(true);
         getJavaScriptLibrarySettings().setJQueryReference(new DynamicJQueryResourceReference());

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/pages/EditRealmModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/EditRealmModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/EditRealmModalPage.java
deleted file mode 100644
index 248162e..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/EditRealmModalPage.java
+++ /dev/null
@@ -1,41 +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.pages;
-
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.RealmTO;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
-
-public class EditRealmModalPage<T extends AnyTO> extends RealmModalPage {
-
-    private static final long serialVersionUID = -4285220460543213901L;
-
-    public EditRealmModalPage(
-            final PageReference pageRef,
-            final ModalWindow window,
-            final RealmTO realmTO,
-            final String parentPath,
-            final String entitlement) {
-
-        super(pageRef, window, realmTO, parentPath, entitlement);
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/pages/RealmModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/RealmModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/RealmModalPage.java
deleted file mode 100644
index 5b8526d..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/RealmModalPage.java
+++ /dev/null
@@ -1,142 +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.pages;
-
-import static org.apache.syncope.client.console.pages.AbstractBasePage.CANCEL;
-import static org.apache.wicket.Component.ENABLE;
-
-import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.panels.RealmDetails;
-import org.apache.syncope.client.console.rest.RealmRestClient;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.RealmTO;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.markup.html.form.AjaxButton;
-import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
-import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
-import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.model.CompoundPropertyModel;
-import org.apache.wicket.model.ResourceModel;
-import org.apache.wicket.spring.injection.annot.SpringBean;
-
-public class RealmModalPage<T extends AnyTO> extends BaseModalPage {
-
-    private static final long serialVersionUID = -4285220460543213901L;
-
-    private static final int ROWS_PER_PAGE = 10;
-
-    protected RealmTO realmTO;
-
-    private final PageReference pageRef;
-
-    private final ModalWindow window;
-
-    @SpringBean
-    private RealmRestClient realmRestClient;
-    
-    private final String parentPath;
-
-    public RealmModalPage(
-            final PageReference pageRef,
-            final ModalWindow window,
-            final RealmTO realmTO,
-            final String parentPath,
-            final String entitlement) {
-
-        super();
-
-        this.pageRef = pageRef;
-        this.window = window;
-        this.realmTO = realmTO;
-        this.parentPath = parentPath;
-
-        final Form<RealmTO> form = new Form<RealmTO>("RealmForm");
-        form.setModel(new CompoundPropertyModel<RealmTO>(realmTO));
-
-        RealmDetails realmDetail = new RealmDetails("details", realmTO);
-        if (SyncopeConsoleSession.get().owns(entitlement)) {
-            MetaDataRoleAuthorizationStrategy.authorize(realmDetail, ENABLE, entitlement);
-        }
-        form.add(realmDetail);
-
-        final AjaxButton submit = getOnSubmit();
-        form.add(submit);
-        form.setDefaultButton(submit);
-
-        final AjaxButton cancel = new AjaxButton(CANCEL, new ResourceModel(CANCEL)) {
-
-            private static final long serialVersionUID = 530608535790823587L;
-
-            @Override
-            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
-                window.close(target);
-            }
-
-            @Override
-            protected void onError(final AjaxRequestTarget target, final Form<?> form) {
-            }
-        };
-
-        cancel.setDefaultFormProcessing(false);
-        form.add(cancel);
-
-        add(form);
-    }
-
-    protected AjaxButton getOnSubmit() {
-        return new IndicatingAjaxButton(APPLY, new ResourceModel(SUBMIT)) {
-
-            private static final long serialVersionUID = -958724007591692537L;
-
-            @Override
-            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
-                try {
-                    submitAction(target, form);
-
-                    if (pageRef.getPage() instanceof BasePage) {
-                        ((BasePage) pageRef.getPage()).setModalResult(true);
-                    }
-
-                    closeAction(target, form);
-                } catch (Exception e) {
-                    LOG.error("While creating or updating user", e);
-                    error(getString(Constants.ERROR) + ": " + e.getMessage());
-                    feedbackPanel.refresh(target);
-                }
-            }
-
-            @Override
-            protected void onError(final AjaxRequestTarget target, final Form<?> form) {
-                feedbackPanel.refresh(target);
-            }
-        };
-    }
-
-    protected void submitAction(final AjaxRequestTarget target, final Form<?> form) {
-        final RealmTO updatedRealmTO = (RealmTO) form.getModelObject();
-        realmRestClient.create(this.parentPath, updatedRealmTO);
-    }
-
-    protected void closeAction(final AjaxRequestTarget target, final Form<?> form) {
-        this.window.close(target);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
index 3c35ba3..914e5df 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
@@ -20,6 +20,9 @@ package org.apache.syncope.client.console.pages;
 
 import static org.apache.wicket.Component.ENABLE;
 
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.behavior.Draggable;
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.behavior.DraggableConfig;
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.behavior.Resizable;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -28,24 +31,29 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.panels.EditRealmModalPanel;
 import org.apache.syncope.client.console.panels.Realm;
+import org.apache.syncope.client.console.panels.RealmModalPanel;
 import org.apache.syncope.client.console.rest.RealmRestClient;
 import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxLink;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.buttons.DefaultModalCloseButton;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.common.lib.to.RealmTO;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.wicket.MarkupContainer;
-import org.apache.wicket.Page;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
 import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
 import org.apache.wicket.event.Broadcast;
 import org.apache.wicket.event.IEvent;
-import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow.WindowClosedCallback;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.panel.Fragment;
 import org.apache.wicket.markup.repeater.RepeatingView;
+import org.apache.wicket.model.Model;
 import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.spring.injection.annot.SpringBean;
 
@@ -58,70 +66,37 @@ public class Realms extends BasePage {
 
     private final WebMarkupContainer content;
 
-    private final ModalWindow editModalWin;
-
     protected RealmTO currentRealm;
 
     public Realms(final PageParameters parameters) {
         super(parameters);
-        
+
         final List<RealmTO> realms = realmRestClient.list();
         Collections.sort(realms, new RealmNameComparator());
 
-        add(getParentMap(realms), 0L, Realms.this);
+        addRealmTree(getParentMap(realms), 0L, Realms.this);
+        setCurrentRealm(realms.get(0));
 
         content = new WebMarkupContainer("content");
-        content.setOutputMarkupId(true);
-        add(content);
-
         content.add(new Label("header", "Root realm"));
         content.add(new Label("body", "Root realm"));
-
-        //create new realms                
-        final AjaxLink<Void> createLink = new ClearIndicatingAjaxLink<Void>("createLink", getPageReference()) {
-
-            private static final long serialVersionUID = -7978723352517770644L;
-
-            @Override
-            protected void onClickInternal(final AjaxRequestTarget target) {
-                editModalWin.setPageCreator(new ModalWindow.PageCreator() {
-
-                    private static final long serialVersionUID = -7834632442532690940L;
-
-                    @Override
-                    public Page createPage() {
-                        return new RealmModalPage(Realms.this.getPageReference(), editModalWin, new RealmTO(),
-                                Realms.this.getCurrentRealm().getFullPath(), Entitlement.REALM_CREATE);
-                    }
-                });
-
-                editModalWin.show(target);
-            }
-        };
-        if (SyncopeConsoleSession.get().owns(Entitlement.REALM_CREATE)) {
-            MetaDataRoleAuthorizationStrategy.authorize(createLink, ENABLE, Entitlement.REALM_CREATE);
-        }
-        content.add(createLink);
-
-        // Modal window for editing realms
-        editModalWin = new ModalWindow("editModal");
-        editModalWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
-        editModalWin.setCookieName("edit-modal");
-
-        content.add(editModalWin);
-        setCurrentRealm(realms.get(0));
+        content.setOutputMarkupId(true);
+        updateRealmContent(currentRealm);
+        add(content);
     }
 
-    private void add(final Map<Long, List<RealmTO>> parentMap, final Long key, final MarkupContainer container) {
+    private MarkupContainer addRealmTree(
+            final Map<Long, List<RealmTO>> parentMap, final Long key, final MarkupContainer container) {
         final RepeatingView listItems = new RepeatingView("list");
-        container.add(listItems);
+        listItems.setOutputMarkupId(true);
+        container.addOrReplace(listItems);
 
         for (final RealmTO realm : parentMap.get(key)) {
             final Fragment fragment;
 
             final AjaxLink<Void> link = new AjaxLink<Void>("link") {
 
-                private static final long serialVersionUID = 1L;
+                private static final long serialVersionUID = -7978723352517770644L;
 
                 @Override
                 public void onClick(final AjaxRequestTarget target) {
@@ -130,18 +105,21 @@ public class Realms extends BasePage {
                 }
             };
 
-            link.add(new Label("name", new PropertyModel<String>(realm, "name")));
+            link.addOrReplace(new Label("name", new PropertyModel<String>(realm, "name")));
 
             if (parentMap.containsKey(realm.getKey()) && !parentMap.get(realm.getKey()).isEmpty()) {
                 fragment = new Fragment(String.valueOf(realm.getKey()), "withChildren", Realms.this);
-                add(parentMap, realm.getKey(), fragment);
+                addRealmTree(parentMap, realm.getKey(), fragment);
             } else {
                 fragment = new Fragment(String.valueOf(realm.getKey()), "withoutChildren", Realms.this);
             }
 
-            fragment.add(link);
-            listItems.add(fragment);
+            fragment.addOrReplace(link);
+            fragment.setOutputMarkupId(true);
+            listItems.addOrReplace(fragment);
         }
+
+        return container;
     }
 
     private Map<Long, List<RealmTO>> getParentMap(final List<RealmTO> realms) {
@@ -190,40 +168,114 @@ public class Realms extends BasePage {
         if (event.getPayload() instanceof ControlSidebarClick) {
             @SuppressWarnings("unchecked")
             final ControlSidebarClick<RealmTO> controlSidebarClick = ControlSidebarClick.class.cast(event.getPayload());
-            content.addOrReplace(new Label("header", controlSidebarClick.getObj().getName()));
-            content.addOrReplace(new Realm("body", controlSidebarClick.getObj(), getPageReference()));
+            updateRealmContent(controlSidebarClick.getObj());
             controlSidebarClick.getTarget().add(content);
         }
     }
 
-    public void setCurrentRealm(final RealmTO realmTO) {
+    private void setCurrentRealm(final RealmTO realmTO) {
         this.currentRealm = realmTO;
-        setupEditModalPage(currentRealm);
     }
 
     public RealmTO getCurrentRealm() {
         return this.currentRealm;
     }
 
-    public void setupEditModalPage(final RealmTO realmTO) {
-        final AjaxLink<Void> edit = new ClearIndicatingAjaxLink<Void>("edit", getPageReference()) {
+    private void updateRealmContent(final RealmTO realmTO) {
+        content.addOrReplace(new Label("header", realmTO.getName()));
+        content.addOrReplace(new Realm("body", realmTO, getPageReference()));
+        setupCreateModal();
+        setupEditModal();
+    }
+
+    private void setupCreateModal() {
+        final BaseModal<RealmTO> createModal = new BaseModal<>("createModal");
+        createModal.add(new Resizable().withChildSelector(".modal-content"));
+        createModal.add(new Draggable(new DraggableConfig().withHandle(".modal-header").withCursor("move")));
+        createModal.addButton(new DefaultModalCloseButton());
+        createModal.header(new ResourceModel("createRealm"));
+        createModal.setUseKeyboard(true);
+        createModal.setFadeIn(true);
+
+        createModal.setWindowClosedCallback(new WindowClosedCallback() {
 
-            private static final long serialVersionUID = 1L;
+            private static final long serialVersionUID = 8804221891699487139L;
+
+            @Override
+            public void onClose(final AjaxRequestTarget target) {
+                final List<RealmTO> realms = realmRestClient.list();
+                Collections.sort(realms, new RealmNameComparator());
+                target.add(addRealmTree(getParentMap(realms), 0L, Realms.this));
+            }
+        });
+
+        content.addOrReplace(createModal);
+
+        final RealmModalPanel realmModalPanel = new RealmModalPanel(BaseModal.getModalContentId(),
+                this.getPageReference(), createModal,
+                new RealmTO(), this.getCurrentRealm().getFullPath(), Entitlement.REALM_CREATE);
+
+        realmModalPanel.setOutputMarkupId(true);
+        createModal.addOrReplace(realmModalPanel);
+
+        //create new realms                
+        final AjaxLink<Void> createLink = new ClearIndicatingAjaxLink<Void>("createLink", getPageReference()) {
+
+            private static final long serialVersionUID = -7978723352517770644L;
 
             @Override
             protected void onClickInternal(final AjaxRequestTarget target) {
-                editModalWin.setPageCreator(new ModalWindow.PageCreator() {
+                createModal.addOrReplace(realmModalPanel);
+                createModal.show(target);
+            }
+
+        };
+        if (SyncopeConsoleSession.get().owns(Entitlement.REALM_CREATE)) {
+            MetaDataRoleAuthorizationStrategy.authorize(createLink, ENABLE, Entitlement.REALM_CREATE);
+        }
+        content.addOrReplace(createLink);
+    }
+
+    private void setupEditModal() {
+
+        final BaseModal<RealmTO> editModal = new BaseModal<>("editModal");
+        editModal.add(new Resizable().withChildSelector(".modal-content"));
+        editModal.add(new Draggable(new DraggableConfig().withHandle(".modal-header").withCursor("move")));
+        editModal.addButton(new DefaultModalCloseButton());
+        editModal.header(Model.of(getCurrentRealm().getName()));
+        editModal.setUseKeyboard(true);
+        editModal.setFadeIn(true);
+
+        editModal.setWindowClosedCallback(new WindowClosedCallback() {
+
+            private static final long serialVersionUID = 8804221891699487139L;
+
+            @Override
+            public void onClose(final AjaxRequestTarget target) {
+                final List<RealmTO> realms = realmRestClient.list();
+                Collections.sort(realms, new RealmNameComparator());
+                target.add(addRealmTree(getParentMap(realms), 0L, Realms.this));
+            }
+        });
+
+        content.addOrReplace(editModal);
+
+        final RealmModalPanel ediRealmModalPanel =
+                new EditRealmModalPanel(BaseModal.getModalContentId(),
+                        Realms.this.getPageReference(),
+                        editModal, getCurrentRealm(), Realms.this.getCurrentRealm().getFullPath(),
+                        Entitlement.REALM_UPDATE);
+
+        ediRealmModalPanel.setOutputMarkupId(true);
+        editModal.addOrReplace(ediRealmModalPanel);
 
-                    private static final long serialVersionUID = -7834632442532690940L;
+        final AjaxLink<Void> edit = new ClearIndicatingAjaxLink<Void>("edit", getPageReference()) {
 
-                    @Override
-                    public Page createPage() {
-                        return new EditRealmModalPage(Realms.this.getPageReference(), editModalWin, realmTO,
-                                Realms.this.getCurrentRealm().getFullPath(), Entitlement.REALM_UPDATE);
-                    }
-                });
+            private static final long serialVersionUID = -6957616042924610290L;
 
-                editModalWin.show(target);
+            @Override
+            protected void onClickInternal(final AjaxRequestTarget target) {
+                editModal.show(target);
             }
         };
         content.addOrReplace(edit);
@@ -248,6 +300,5 @@ public class Realms extends BasePage {
         public AjaxRequestTarget getTarget() {
             return target;
         }
-
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractModalPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractModalPanel.java
new file mode 100644
index 0000000..c704d41
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractModalPanel.java
@@ -0,0 +1,120 @@
+/*
+ * 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.commons.Constants;
+import org.apache.syncope.client.console.init.MIMETypesLoader;
+import org.apache.syncope.client.console.rest.ConfigurationRestClient;
+import org.apache.syncope.client.console.rest.ConnectorRestClient;
+import org.apache.syncope.client.console.rest.ReportRestClient;
+import org.apache.syncope.client.console.rest.ResourceRestClient;
+import org.apache.syncope.client.console.rest.GroupRestClient;
+import org.apache.syncope.client.console.rest.SchemaRestClient;
+import org.apache.syncope.client.console.rest.TaskRestClient;
+import org.apache.syncope.client.console.rest.UserRestClient;
+import org.apache.syncope.client.console.rest.UserSelfRestClient;
+import org.apache.syncope.client.console.wicket.markup.head.MetaHeaderItem;
+import org.apache.wicket.markup.head.HeaderItem;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.PriorityHeaderItem;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AbstractModalPanel extends Panel {
+
+    private static final long serialVersionUID = 8611724965544132636L;
+
+    protected static final Logger LOG = LoggerFactory.getLogger(AbstractModalPanel.class);
+
+    protected static final String CANCEL = "cancel";
+
+    protected static final String SUBMIT = "submit";
+
+    protected static final String APPLY = "apply";
+
+    protected static final String FORM = "form";
+
+    protected final HeaderItem meta = new MetaHeaderItem("X-UA-Compatible", "IE=edge");
+
+    @SpringBean
+    protected UserRestClient userRestClient;
+
+    @SpringBean
+    protected UserSelfRestClient userSelfRestClient;
+
+    @SpringBean
+    protected GroupRestClient groupRestClient;
+
+    @SpringBean
+    protected TaskRestClient taskRestClient;
+
+    @SpringBean
+    protected SchemaRestClient schemaRestClient;
+
+    @SpringBean
+    protected ResourceRestClient resourceRestClient;
+
+    @SpringBean
+    protected ConnectorRestClient connectorRestClient;
+
+    @SpringBean
+    protected ReportRestClient reportRestClient;
+
+    @SpringBean
+    protected ConfigurationRestClient confRestClient;
+
+    @SpringBean
+    protected MIMETypesLoader mimeTypesInitializer;
+
+    protected NotificationPanel feedbackPanel;
+
+    /**
+     * Response flag set by the Modal Window after the operation is completed.
+     */
+    protected boolean modalResult = false;
+
+    public AbstractModalPanel(final String id) {
+        super(id);
+
+        feedbackPanel = new NotificationPanel(Constants.FEEDBACK);
+        feedbackPanel.setOutputMarkupId(true);
+        add(feedbackPanel);
+    }
+
+    public NotificationPanel getFeedbackPanel() {
+        return feedbackPanel;
+    }
+
+    public boolean isModalResult() {
+        return modalResult;
+    }
+
+    public void setModalResult(final boolean modalResult) {
+        this.modalResult = modalResult;
+    }
+
+    @Override
+    public void renderHead(final IHeaderResponse response) {
+        super.renderHead(response);
+        response.render(new PriorityHeaderItem(meta));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
index d91c083..5bda1fd 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
@@ -270,7 +270,8 @@ public abstract class AbstractSearchResultPanel extends Panel implements IEventS
                 restClient,
                 "key",
                 getPageId(),
-                page.getPageReference());
+                page.getPageReference(),
+                container);
 
         resultTable.setCurrentPage(currentPage);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/panels/ActionDataTablePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ActionDataTablePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ActionDataTablePanel.java
index 837c89d..289cf26 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ActionDataTablePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ActionDataTablePanel.java
@@ -23,6 +23,7 @@ import java.util.Collection;
 import java.util.List;
 import org.apache.syncope.client.console.commons.ActionTableCheckGroup;
 import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxButton;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.AjaxFallbackDataTable;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.CheckGroupColumn;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink.ActionType;
@@ -33,7 +34,6 @@ import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
 import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
-import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
 import org.apache.wicket.markup.html.WebMarkupContainer;
@@ -87,7 +87,7 @@ public class ActionDataTablePanel<T, S> extends DataTablePanel<T, S> {
         bulkActionForm.add(group);
 
         columns.add(0, new CheckGroupColumn<T, S>(group));
-        dataTable = new AjaxFallbackDefaultDataTable<>("dataTable", columns, dataProvider, rowsPerPage);
+        dataTable = new AjaxFallbackDataTable<>("dataTable", columns, dataProvider, rowsPerPage, this);
         group.add(dataTable);
 
         final WebMarkupContainer actionPanelContainer = new WebMarkupContainer("actionPanelContainer");

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
index 7c77228..b98ba71 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
@@ -28,6 +28,7 @@ import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.CheckGroupColumn;
 import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxButton;
 import org.apache.syncope.client.console.pages.BulkActionModalPage;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.AjaxFallbackDataTable;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Page;
 import org.apache.wicket.PageReference;
@@ -35,9 +36,9 @@ import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
 import org.apache.wicket.event.Broadcast;
 import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
-import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
+import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.form.CheckGroup;
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.panel.Fragment;
@@ -55,7 +56,8 @@ public class AjaxDataTablePanel<T, S> extends DataTablePanel<T, S> {
             final BaseRestClient bulkActionExecutor,
             final String itemKeyField,
             final String pageId,
-            final PageReference pageRef) {
+            final PageReference pageRef,
+            final WebMarkupContainer container) {
 
         super(id);
 
@@ -110,10 +112,9 @@ public class AjaxDataTablePanel<T, S> extends DataTablePanel<T, S> {
         bulkActionForm.add(group);
 
         columns.add(0, new CheckGroupColumn<T, S>(group));
-        dataTable = new AjaxFallbackDefaultDataTable<>("dataTable", columns, dataProvider, rowsPerPage);
-        dataTable.add(new AttributeModifier("class",
-                "ui-widget ui-widget-content table-hover table table-striped table-bordered"));
-
+        dataTable = new AjaxFallbackDataTable<>("dataTable", columns, dataProvider, rowsPerPage, container);
+        dataTable.add(new AttributeModifier("class", "table table-bordered table-hover dataTable"));
+        
         group.add(dataTable);
 
         fragment.add(new ClearIndicatingAjaxButton("bulkActionLink", bulkActionForm, pageRef) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/panels/AnySearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnySearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnySearchResultPanel.java
index a1c822e..e9b137d 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnySearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnySearchResultPanel.java
@@ -58,8 +58,6 @@ public class AnySearchResultPanel extends AbstractSearchResultPanel {
 
     protected static final Logger LOG = LoggerFactory.getLogger(AnySearchResultPanel.class);
 
-    private String customMarkupId;
-
     @SpringBean
     protected SchemaRestClient schemaRestClient;
 
@@ -68,14 +66,14 @@ public class AnySearchResultPanel extends AbstractSearchResultPanel {
     protected final List<String> dSchemaNames;
 
     protected final String pageID = "Any";
-
+    
     private final String entitlement = "USER_LIST";
 
-    public AnySearchResultPanel(final String type, final String parentId, final String markupId, final boolean filtered,
+    public AnySearchResultPanel(final String type, final String parentId, final boolean filtered,
             final String fiql, final PageReference callerRef, final AbstractAnyRestClient restClient,
             final List<AnyTypeClassTO> anyTypeClassTOs, final String realm) {
         super(parentId, filtered, fiql, callerRef, restClient, realm, type);
-        setCustomMarkupId(markupId);
+        //setCustomMarkupId(markupId);
         add(new Label("name", type));
 
         this.schemaNames = new ArrayList<String>();
@@ -90,14 +88,6 @@ public class AnySearchResultPanel extends AbstractSearchResultPanel {
         initResultTable();
     }
 
-    public String getCustomMarkupId() {
-        return customMarkupId;
-    }
-
-    public void setCustomMarkupId(final String markupId) {
-        this.customMarkupId = markupId;
-    }
-
     @Override
     protected List<IColumn<AnyTO, String>> getColumns() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java
index 1800d54..46237ab 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java
@@ -22,8 +22,8 @@ import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.AjaxFallbackDataTable;
 import org.apache.wicket.Component;
-import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
 import org.apache.wicket.extensions.markup.html.repeater.data.grid.DataGridView;
 import org.apache.wicket.markup.html.form.CheckGroup;
 import org.apache.wicket.markup.html.panel.Panel;
@@ -43,7 +43,7 @@ public abstract class DataTablePanel<T, S> extends Panel {
 
     protected CheckGroup<T> group;
 
-    protected AjaxFallbackDefaultDataTable<T, S> dataTable;
+    protected AjaxFallbackDataTable<T, S> dataTable;
 
     protected IModel<Collection<T>> model;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/panels/EditRealmModalPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/EditRealmModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/EditRealmModalPanel.java
new file mode 100644
index 0000000..c4ddfa1
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/EditRealmModalPanel.java
@@ -0,0 +1,40 @@
+/*
+ * 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.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.syncope.common.lib.to.RealmTO;
+import org.apache.wicket.PageReference;
+
+public class EditRealmModalPanel extends RealmModalPanel {
+
+    private static final long serialVersionUID = -4285220460543213901L;
+
+    public EditRealmModalPanel(
+            final String id,
+            final PageReference pageRef,
+            final BaseModal<RealmTO> window,
+            final RealmTO realmTO,
+            final String parentPath,
+            final String entitlement) {
+
+        super(id, pageRef, window, realmTO, parentPath, entitlement);
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/panels/FailureMessageModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/FailureMessageModal.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/FailureMessageModal.java
new file mode 100644
index 0000000..38edbf0
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/FailureMessageModal.java
@@ -0,0 +1,40 @@
+/*
+ * 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.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.model.Model;
+
+public class FailureMessageModal extends ModalContent {
+
+    private static final long serialVersionUID = 9216117990503199258L;
+
+    public FailureMessageModal(final PageReference pageRef, final ModalWindow window, final String failureMessage) {
+        super(window, pageRef);
+        final Label executionFailureMessage;
+        if (!failureMessage.isEmpty()) {
+            executionFailureMessage = new Label("failureMessage", new Model<String>(failureMessage));
+        } else {
+            executionFailureMessage = new Label("failureMessage");
+        }
+        add(executionFailureMessage.setOutputMarkupId(true));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupModalPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupModalPanel.java
new file mode 100644
index 0000000..9594e3f
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupModalPanel.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.Mode;
+import org.apache.syncope.common.lib.AnyOperations;
+import org.apache.syncope.common.lib.mod.GroupMod;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.ResourceModel;
+
+/**
+ * Modal window with Group form.
+ */
+public class GroupModalPanel extends AbstractModalPanel {
+
+    private static final long serialVersionUID = -1732493223434085205L;
+
+    protected final Mode mode;
+
+    protected final boolean createFlag;
+
+    protected final GroupPanel groupPanel;
+
+    protected GroupTO originalGroupTO;
+
+    public GroupModalPanel(final String id, final Modal window, final GroupTO groupTO) {
+        this(id, window, groupTO, Mode.ADMIN);
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public GroupModalPanel(final String id, final Modal window, final GroupTO groupTO, final Mode mode) {
+
+        super(id);
+
+        this.mode = mode;
+
+        this.createFlag = groupTO.getKey() == 0;
+        if (!createFlag) {
+            originalGroupTO = SerializationUtils.clone(groupTO);
+        }
+
+        final Form<GroupTO> form = new Form<>("groupForm");
+        form.setMultiPart(true);
+
+        add(new Label("displayName", groupTO.getKey() == 0 ? "" : groupTO.getDisplayName()));
+
+        form.setModel(new CompoundPropertyModel<>(groupTO));
+
+        this.groupPanel = new GroupPanel.Builder("groupPanel").
+                form(form).groupTO(groupTO).groupModalPageMode(mode).build();
+        form.add(groupPanel);
+
+        final AjaxButton submit = new IndicatingAjaxButton(SUBMIT, new ResourceModel(SUBMIT)) {
+
+            private static final long serialVersionUID = -958724007591692537L;
+
+            @Override
+            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+                try {
+                    submitAction(target, form);
+                    
+                } catch (Exception e) {
+                    LOG.error("Failure managing groupTO {}", groupTO, e);
+                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    feedbackPanel.refresh(target);
+                }
+            }
+
+            @Override
+            protected void onError(final AjaxRequestTarget target, final Form<?> form) {
+                feedbackPanel.refresh(target);
+            }
+        };
+        form.add(submit);
+        form.setDefaultButton(submit);
+    }
+
+    protected void submitAction(final AjaxRequestTarget target, final Form<?> form) {
+        final GroupTO groupTO = (GroupTO) form.getDefaultModelObject();
+
+        GroupTO result;
+        if (createFlag) {
+            result = groupRestClient.create(groupTO);
+        } else {
+            GroupMod groupMod = AnyOperations.diff(groupTO, groupTO);
+
+            // update group just if it is changed
+            if (groupMod.isEmpty()) {
+                result = groupTO;
+            } else {
+                result = groupRestClient.update(originalGroupTO.getETagValue(), groupMod);
+            }
+        }
+
+        //setResponsePage(new ResultStatusModal.Builder(window, result).build());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupPanel.java
new file mode 100644
index 0000000..3e58e61
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupPanel.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.io.Serializable;
+import org.apache.syncope.client.console.commons.Mode;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.Panel;
+
+public final class GroupPanel extends Panel {
+
+    private static final long serialVersionUID = 4216376097320768369L;
+
+    public static class Builder implements Serializable {
+
+        private static final long serialVersionUID = 8150440254654306070L;
+
+        private String id;
+
+        private Form form;
+
+        private GroupTO groupTO;
+
+        private Mode mode;
+
+        private PageReference pageReference;
+
+        public Builder(final String id) {
+            this.id = id;
+        }
+
+        public Builder form(final Form form) {
+            this.form = form;
+            return this;
+        }
+
+        public Builder groupTO(final GroupTO groupTO) {
+            this.groupTO = groupTO;
+            return this;
+        }
+
+        public Builder groupModalPageMode(final Mode mode) {
+            this.mode = mode;
+            return this;
+        }
+
+        public GroupPanel build() {
+            return new GroupPanel(this);
+        }
+    }
+
+    private GroupPanel(final Builder builder) {
+        super(builder.id);
+        
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchResultPanel.java
index 45b5239..b58acd8 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchResultPanel.java
@@ -18,6 +18,9 @@
  */
 package org.apache.syncope.client.console.panels;
 
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.behavior.Draggable;
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.behavior.DraggableConfig;
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.behavior.Resizable;
 import java.io.Serializable;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
@@ -28,9 +31,9 @@ import java.util.List;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.pages.GroupDisplayAttributesModalPage;
 import org.apache.syncope.client.console.rest.AbstractAnyRestClient;
-import org.apache.syncope.client.console.rest.GroupRestClient;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.ActionColumn;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.AttrColumn;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink.ActionType;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
@@ -59,18 +62,28 @@ public class GroupSearchResultPanel extends AnySearchResultPanel {
 
     private final String entitlement = "GROUP_READ";
 
-    public GroupSearchResultPanel(final String type, final String parentId, final String markupId,
+    private final BaseModal<AbstractModalPanel> editModal;
+
+    public GroupSearchResultPanel(final String type, final String parentId,
             final boolean filtered, final String fiql, final PageReference callerRef,
             final AbstractAnyRestClient restClient, final List<AnyTypeClassTO> anyTypeClassTOs, final String realm) {
 
-        super(type, parentId, markupId, filtered, fiql, callerRef, restClient, anyTypeClassTOs, realm);
+        super(type, parentId, filtered, fiql, callerRef, restClient, anyTypeClassTOs, realm);
+
+        editModal = new BaseModal<>("editModal");
+        editModal.add(new Resizable().withChildSelector(".modal-content"));
+        editModal.add(new Draggable(new DraggableConfig().withHandle(".modal-header").withCursor("move")));
+        editModal.setUseKeyboard(true).addCloseButton();
+        editModal.setFadeIn(true);
+        editModal.setFooterVisible(true);
+        editModal.setHeaderVisible(true);
+        editModal.setOutputMarkupId(true);
     }
 
     @Override
     protected List<IColumn<AnyTO, String>> getColumns() {
 
-        final List<IColumn<AnyTO, String>> columns =
-                new ArrayList<IColumn<AnyTO, String>>();
+        final List<IColumn<AnyTO, String>> columns = new ArrayList<>();
 
         for (String name : prefMan.getList(getRequest(), Constants.PREF_GROUP_DETAILS_VIEW)) {
             final Field field = ReflectionUtils.findField(GroupTO.class, name);
@@ -84,7 +97,7 @@ public class GroupSearchResultPanel extends AnySearchResultPanel {
                         new PropertyColumn<AnyTO, String>(new ResourceModel(name, name), name, name));
             }
         }
-        
+
         for (String name : prefMan.getList(getRequest(), Constants.PREF_GROUP_ATTRIBUTES_VIEW)) {
             if (schemaNames.contains(name)) {
                 columns.add(new AttrColumn(name, SchemaType.PLAIN));
@@ -116,26 +129,18 @@ public class GroupSearchResultPanel extends AnySearchResultPanel {
             public ActionLinksPanel getActions(final String componentId, final IModel<AnyTO> model) {
 
                 final ActionLinksPanel.Builder<AnyTO> panel = ActionLinksPanel.builder(page.getPageReference());
-                
+
                 panel.add(new ActionLink<AnyTO>() {
 
                     private static final long serialVersionUID = -7978723352517770644L;
 
                     @Override
                     public void onClick(final AjaxRequestTarget target, final AnyTO anyTO) {
-                        editmodal.setPageCreator(new ModalWindow.PageCreator() {
+                        editModal.addOrReplace(new GroupModalPanel(
+                                BaseModal.getModalContentId(), editModal, (GroupTO) model.getObject()));
 
-                            private static final long serialVersionUID = -7834632442532690940L;
-
-                            @Override
-                            public Page createPage() {
-                                // SYNCOPE-294: re-read groupTO before edit
-                                GroupTO groupTO = ((GroupRestClient) restClient).read(model.getObject().getKey());
-                                return null;
-                            }
-                        });
-
-                        editmodal.show(target);
+                        target.add(editModal);
+                        editModal.show(target);
                     }
                 }, ActionLink.ActionType.EDIT, entitlement).add(new ActionLink<AnyTO>() {
 
@@ -147,19 +152,12 @@ public class GroupSearchResultPanel extends AnySearchResultPanel {
                             final GroupTO groupTO = (GroupTO) restClient.
                                     delete(model.getObject().getETagValue(), model.getObject().getKey());
 
-                            page.setModalResult(true);
-
-                            editmodal.setPageCreator(new ModalWindow.PageCreator() {
-
-                                private static final long serialVersionUID = -7834632442532690940L;
-
-                                @Override
-                                public Page createPage() {
-                                    return null;
-                                }
-                            });
-
-                            editmodal.show(target);
+                            //editmodal.setContent(new ResultStatusModal.Builder(editmodal, groupTO).build());
+//                            editModal.addOrReplace(new GroupModalPanel(
+//                                    BaseModal.getModalContentId(), editModal, (GroupTO) model.getObject()));
+//
+//                            target.add(editModal);
+//                            editModal.show(target);
                         } catch (SyncopeClientException scce) {
                             error(getString(Constants.OPERATION_ERROR) + ": " + scce.getMessage());
                             feedbackPanel.refresh(target);
@@ -216,7 +214,7 @@ public class GroupSearchResultPanel extends AnySearchResultPanel {
 
     @Override
     protected <T extends AnyTO> Collection<ActionLink.ActionType> getBulkActions() {
-        final List<ActionType> bulkActions = new ArrayList<ActionType>();
+        final List<ActionType> bulkActions = new ArrayList<>();
 
         bulkActions.add(ActionType.DELETE);
         bulkActions.add(ActionType.SUSPEND);

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
index 5c37e14..49ab781 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
@@ -20,6 +20,8 @@ package org.apache.syncope.client.console.panels;
 
 import static org.apache.syncope.common.lib.types.AnyTypeKind.USER;
 
+import com.googlecode.wicket.jquery.core.panel.LabelPanel;
+import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
 import java.util.ArrayList;
 import java.util.List;
 import org.apache.syncope.client.console.rest.AnyObjectRestClient;
@@ -28,11 +30,11 @@ import org.apache.syncope.client.console.rest.GroupRestClient;
 import org.apache.syncope.client.console.rest.UserRestClient;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
 import org.apache.syncope.common.lib.to.RealmTO;
-import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.PageReference;
-import org.apache.wicket.markup.html.list.ListItem;
-import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
+import org.apache.wicket.extensions.markup.html.tabs.ITab;
 import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.Model;
 import org.apache.wicket.spring.injection.annot.SpringBean;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -45,7 +47,7 @@ public class Realm extends Panel {
 
     private final RealmTO realmTO;
 
-    private static Integer MARKUP_ID = 0;
+    private final List<AnyTypeTO> anyTypeTOs;
 
     @SpringBean
     private AnyTypeRestClient anyTypeRestClient;
@@ -59,71 +61,70 @@ public class Realm extends Panel {
     @SpringBean
     private AnyObjectRestClient anyObjectRestClient;
 
+    @SuppressWarnings({ "unchecked", "unchecked" })
     public Realm(final String id, final RealmTO realmTO, final PageReference pageReference) {
         super(id);
         this.realmTO = realmTO;
+        this.anyTypeTOs = anyTypeRestClient.getAll();
 
-        List<AnyTypeMenuItem> anyMenu = new ArrayList<>();
-        List<AnySearchResultPanel> anyList = new ArrayList<>();
+        add(new AjaxBootstrapTabbedPanel<>("tabbedPanel", buildTabList(pageReference)));
+    }
 
-        for (AnyTypeTO anyTypeTO : anyTypeRestClient.getAll()) {
-            anyMenu.add(new AnyTypeMenuItem(anyTypeTO.getKey(), MARKUP_ID.toString()));
+    public RealmTO getRealmTO() {
+        return realmTO;
+    }
 
-            switch (anyTypeTO.getKind()) {
-                case USER:
-                    anyList.add(
-                            new UserSearchResultPanel(anyTypeTO.getKey(), "anytype-contentitem", MARKUP_ID.toString(),
-                                    false, null, pageReference, userRestClient, anyTypeRestClient.getAnyTypeClass(
-                                            anyTypeTO.getClasses()), realmTO.getFullPath()));
-                    break;
-                case GROUP:
-                    anyList.add(
-                            new GroupSearchResultPanel(anyTypeTO.getKey(), "anytype-contentitem", MARKUP_ID.toString(),
-                                    false, null, pageReference, groupRestClient, anyTypeRestClient.getAnyTypeClass(
-                                            anyTypeTO.getClasses()), realmTO.getFullPath()));
-                    break;
-                case ANY_OBJECT:
-                    anyList.add(
-                            new AnySearchResultPanel(anyTypeTO.getKey(), "anytype-contentitem", MARKUP_ID.toString(),
-                                    false, null, pageReference, anyObjectRestClient, anyTypeRestClient.getAnyTypeClass(
-                                            anyTypeTO.getClasses()), realmTO.getFullPath()));
-                    break;
-                default:
-            }
-            MARKUP_ID++;
-        }
+    private List<ITab> buildTabList(final PageReference pageReference) {
 
-        ListView<AnyTypeMenuItem> menuListView = new ListView<AnyTypeMenuItem>("anytype-menu", anyMenu) {
+        final List<ITab> tabs = new ArrayList<>();
 
-            private static final long serialVersionUID = 4949588177564901031L;
+        tabs.add(new AbstractTab(new Model<>("DETAILS")) {
+
+            private static final long serialVersionUID = -5861786415855103549L;
 
             @Override
-            protected void populateItem(final ListItem<AnyTypeMenuItem> item) {
-                item.add(item.getModelObject());
-                if (item.getIndex() == 0) {
-                    item.add(new AttributeModifier("class", "active"));
-                }
+            public Panel getPanel(final String panelId) {
+                return new RealmDetails(panelId, realmTO);
             }
-        };
-        add(menuListView);
+        });
 
-        add(new ListView<AnySearchResultPanel>("anytype-content", anyList) {
+        for (final AnyTypeTO anyTypeTO : anyTypeTOs) {
 
-            private static final long serialVersionUID = 4949588177564901031L;
+            tabs.add(new AbstractTab(new Model<>(anyTypeTO.getKey())) {
 
-            @Override
-            protected void populateItem(final ListItem<AnySearchResultPanel> item) {
-                item.setMarkupId(item.getModelObject().getCustomMarkupId());
-                item.add(item.getModelObject());
-                if (item.getIndex() == 0) {
-                    item.add(new AttributeModifier("class", "tab-pane active"));
+                private static final long serialVersionUID = -5861786415855103549L;
+
+                @Override
+                public Panel getPanel(final String panelId) {
+                    return getAnyPanel(panelId, pageReference, anyTypeTO);
                 }
-            }
-        });
+            });
+        }
+        return tabs;
     }
 
-    public RealmTO getRealmTO() {
-        return realmTO;
-    }
+    private Panel getAnyPanel(final String id, final PageReference pageReference, final AnyTypeTO anyTypeTO) {
+        final Panel panel;
 
+            switch (anyTypeTO.getKind()) {
+                case USER:
+                    panel = new UserSearchResultPanel(anyTypeTO.getKey(), id,
+                            false, null, pageReference, userRestClient, anyTypeRestClient.getAnyTypeClass(
+                                    anyTypeTO.getClasses()), realmTO.getFullPath());
+                    break;
+                case GROUP:
+                    panel = new GroupSearchResultPanel(anyTypeTO.getKey(), id,
+                            false, null, pageReference, groupRestClient, anyTypeRestClient.getAnyTypeClass(
+                                    anyTypeTO.getClasses()), realmTO.getFullPath());
+                    break;
+                case ANY_OBJECT:
+                    panel = new AnySearchResultPanel(anyTypeTO.getKey(), id,
+                            false, null, pageReference, anyObjectRestClient, anyTypeRestClient.getAnyTypeClass(
+                                    anyTypeTO.getClasses()), realmTO.getFullPath());
+                    break;
+                default:
+                    panel = new LabelPanel(id, null);
+            }
+        return panel;
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java
index 8797d13..a106402 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java
@@ -18,14 +18,14 @@
  */
 package org.apache.syncope.client.console.panels;
 
-import org.apache.syncope.common.lib.to.RealmTO;
-import org.apache.wicket.markup.html.form.TextField;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.PropertyModel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class RealmDetails extends Panel {
+public class RealmDetails<RealmTO> extends Panel {
 
     private static final long serialVersionUID = -1100228004207271270L;
 
@@ -33,10 +33,24 @@ public class RealmDetails extends Panel {
 
     public RealmDetails(final String id, final RealmTO realmTO) {
         super(id);
-        add(new TextField<>("name", new PropertyModel<>(realmTO, "name")));
-        add(new TextField<>("path", new PropertyModel<>(realmTO, "fullPath")));
-        add(new TextField<>("accountPolicy", new PropertyModel<>(realmTO, "accountPolicy")));
-        add(new TextField<>("passwordPolicy", new PropertyModel<>(realmTO, "passwordPolicy")));
-    }
+        final FieldPanel<String> name =
+                new AjaxTextFieldPanel("name", "name", new PropertyModel<String>(realmTO, "name"));
+        name.addRequiredLabel();
+        add(name);
+
+        final FieldPanel<String> fullPath =
+                new AjaxTextFieldPanel("fullPath", "fullPath", new PropertyModel<String>(realmTO, "fullPath"));
+        fullPath.setEnabled(false);
+        add(fullPath);
 
+        final FieldPanel<String> accountPolicy =
+                new AjaxTextFieldPanel("accountPolicy",
+                        "accountPolicy", new PropertyModel<String>(realmTO, "accountPolicy"));
+        add(accountPolicy);
+
+        final FieldPanel<String> passwordPolicy =
+                new AjaxTextFieldPanel("passwordPolicy",
+                        "passwordPolicy", new PropertyModel<String>(realmTO, "passwordPolicy"));
+        add(passwordPolicy);
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmModalPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmModalPanel.java
new file mode 100644
index 0000000..36409e8
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmModalPanel.java
@@ -0,0 +1,119 @@
+/*
+ * 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 static org.apache.wicket.Component.ENABLE;
+
+import com.googlecode.wicket.jquery.ui.markup.html.link.AjaxSubmitLink;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.pages.BasePage;
+import org.apache.syncope.client.console.rest.RealmRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.buttons.PrimaryModalButton;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.syncope.common.lib.to.RealmTO;
+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.markup.html.form.Form;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+public class RealmModalPanel extends AbstractModalPanel {
+
+    private static final long serialVersionUID = -4285220460543213901L;
+
+    protected RealmTO realmTO;
+
+    private final PageReference pageRef;
+
+    private final BaseModal<RealmTO> modal;
+
+    @SpringBean
+    private RealmRestClient realmRestClient;
+
+    private final String parentPath;
+
+    public RealmModalPanel(
+            final String id,
+            final PageReference pageRef,
+            final BaseModal<RealmTO> modal,
+            final RealmTO realmTO,
+            final String parentPath,
+            final String entitlement) {
+
+        super(id);
+
+        this.pageRef = pageRef;
+        this.modal = modal;
+        this.realmTO = realmTO;
+        this.parentPath = parentPath;
+
+        final Form<RealmTO> form = new Form<>("realmForm");
+        form.setModel(new CompoundPropertyModel<>(realmTO));
+
+        final RealmDetails<RealmTO> realmDetail = new RealmDetails<>("details", realmTO);
+        if (SyncopeConsoleSession.get().owns(entitlement)) {
+            MetaDataRoleAuthorizationStrategy.authorize(realmDetail, ENABLE, entitlement);
+        }
+        form.add(realmDetail);
+
+        final AjaxSubmitLink submit = getOnSubmit(form);
+        modal.addFooterInput(submit);
+        add(form);
+    }
+
+    protected PrimaryModalButton getOnSubmit(final Form form) {
+        return new PrimaryModalButton(modal.getModalInputId(), "submit", form) {
+
+            private static final long serialVersionUID = -958724007591692537L;
+
+            @Override
+            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+                try {
+                    submitAction(target, form);
+
+                    if (pageRef.getPage() instanceof BasePage) {
+                        ((BasePage) pageRef.getPage()).setModalResult(true);
+                    }
+
+                    closeAction(target, form);
+                } catch (Exception e) {
+                    LOG.error("While creating or updating realm", e);
+                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    feedbackPanel.refresh(target);
+                }
+            }
+
+            @Override
+            protected void onError(final AjaxRequestTarget target, final Form<?> form) {
+                feedbackPanel.refresh(target);
+            }
+        };
+    }
+
+    protected void submitAction(final AjaxRequestTarget target, final Form<?> form) {
+        final RealmTO updatedRealmTO = (RealmTO) form.getModelObject();
+        realmRestClient.create(this.parentPath, updatedRealmTO);
+    }
+
+    protected void closeAction(final AjaxRequestTarget target, final Form<?> form) {
+        this.modal.close(target);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java
index 3dd2b4e..de4d65a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java
@@ -60,18 +60,17 @@ public class UserSearchResultPanel extends AnySearchResultPanel {
 
     private final String entitlement = "USER_LIST";
 
-    public UserSearchResultPanel(final String type, final String parentId, final String markupId,
+    public UserSearchResultPanel(final String type, final String parentId,
             final boolean filtered, final String fiql, final PageReference callerRef,
             final AbstractAnyRestClient restClient, final List<AnyTypeClassTO> anyTypeClassTOs, final String realm) {
 
-        super(type, parentId, markupId, filtered, fiql, callerRef, restClient, anyTypeClassTOs, realm);
+        super(type, parentId, filtered, fiql, callerRef, restClient, anyTypeClassTOs, realm);
     }
 
     @Override
     protected List<IColumn<AnyTO, String>> getColumns() {
 
-        final List<IColumn<AnyTO, String>> columns =
-                new ArrayList<IColumn<AnyTO, String>>();
+        final List<IColumn<AnyTO, String>> columns = new ArrayList<IColumn<AnyTO, String>>();
 
         for (String name : prefMan.getList(getRequest(), Constants.PREF_USERS_DETAILS_VIEW)) {
             final Field field = ReflectionUtils.findField(UserTO.class, name);

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/rest/AnyObjectRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/AnyObjectRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/AnyObjectRestClient.java
index 3fd98bd..b4a4642 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/AnyObjectRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/AnyObjectRestClient.java
@@ -19,8 +19,10 @@
 package org.apache.syncope.client.console.rest;
 
 import java.util.List;
+import javax.ws.rs.core.Response;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.BulkAction;
@@ -83,6 +85,21 @@ public class AnyObjectRestClient extends AbstractAnyRestClient {
         return anyObjectTO;
     }
 
+    public AnyObjectTO create(final AnyObjectTO anyObjectTO) {
+        final Response response = getService(AnyObjectService.class).create(anyObjectTO);
+        return response.readEntity(AnyObjectTO.class);
+    }
+
+    public AnyObjectTO update(final String etag, final AnyObjectMod anyObjectMod) {
+        AnyObjectTO result;
+        synchronized (this) {
+            AnyObjectService service = getService(etag, AnyObjectService.class);
+            result = service.update(anyObjectMod).readEntity(AnyObjectTO.class);
+            resetClient(AnyObjectService.class);
+        }
+        return result;
+    }
+
     @Override
     public AnyTO delete(final String etag, final Long key) {
         throw new UnsupportedOperationException("Not supported yet.");

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/rest/RealmRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/RealmRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/RealmRestClient.java
index 779495b..cb2bccc 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/RealmRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/RealmRestClient.java
@@ -36,6 +36,6 @@ public class RealmRestClient extends BaseRestClient {
     }
 
     public void create(final String parentPath, final RealmTO realmTO) {
-        getService(RealmService.class).create(parentPath, realmTO);         
+        getService(RealmService.class).create(parentPath, realmTO);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0419594e/client/console/src/main/java/org/apache/syncope/client/console/themes/AdminLTE.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/themes/AdminLTE.java b/client/console/src/main/java/org/apache/syncope/client/console/themes/AdminLTE.java
new file mode 100644
index 0000000..0d19213
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/themes/AdminLTE.java
@@ -0,0 +1,44 @@
+/*
+ * 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.themes;
+
+import de.agilecoders.wicket.core.settings.Theme;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.wicket.markup.head.CssHeaderItem;
+import org.apache.wicket.markup.head.HeaderItem;
+import org.apache.wicket.markup.head.JavaScriptHeaderItem;
+import org.apache.wicket.resource.JQueryPluginResourceReference;
+
+public class AdminLTE extends Theme {
+
+    public AdminLTE() {
+        super("adminLTE");
+    }
+
+    @Override
+    public List<HeaderItem> getDependencies() {
+        final List<HeaderItem> references = new ArrayList<>();
+        references.add(JavaScriptHeaderItem.forReference(
+                new JQueryPluginResourceReference(AdminLTE.class, "js/AdminLTE-app.min.js")));
+        references.add(CssHeaderItem.forReference(AdminLTECssResourceReference.INSTANCE));
+        references.addAll(super.getDependencies());
+        return references;
+    }
+}


Mime
View raw message