[SYNCOPE-156] fix for ajax component panels

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

Branch: refs/heads/master
Commit: b2e93ca73f22b8a28fc6565d8c9da0fcd8ad9514
Parents: 767a30a
Author: fmartelli <[email protected]>
Authored: Wed Sep 23 15:10:10 2015 +0200
Committer: fmartelli <[email protected]>
Committed: Wed Sep 23 15:10:10 2015 +0200

----------------------------------------------------------------------
 .../syncope/client/console/pages/Login.java     |   5 +-
 .../console/panels/AbstractModalPanel.java      |   8 +-
 .../console/panels/AbstractResourceModal.java   |   9 +-
 .../client/console/panels/ConnectorModal.java   | 192 +++++++---------
 .../console/panels/FailureMessageModal.java     |   8 +-
 .../client/console/panels/GroupModalPanel.java  |  11 +-
 .../console/panels/GroupSearchResultPanel.java  |   5 +-
 .../client/console/panels/ModalContent.java     | 103 ---------
 .../client/console/panels/RealmModalPanel.java  |   7 +-
 .../console/panels/ResourceConnConfPanel.java   |   2 +-
 .../console/panels/ResourceDetailsPanel.java    | 131 +++--------
 .../client/console/panels/ResourceModal.java    | 209 +++++++++---------
 .../console/panels/ResourceSecurityPanel.java   |  16 +-
 .../client/console/topology/Topology.java       |  31 ++-
 .../console/topology/TopologyNodePanel.java     |  93 +++++---
 .../markup/html/bootstrap/dialog/BaseModal.java |  35 ++-
 .../markup/html/form/AbstractFieldPanel.java    |  29 ++-
 .../markup/html/form/AjaxCheckBoxPanel.java     |   4 +
 .../html/form/AjaxDropDownChoicePanel.java      |  22 +-
 .../markup/html/form/AjaxPalettePanel.java      |   2 +-
 .../markup/html/form/AjaxTextFieldPanel.java    |   4 +-
 .../form/CheckBoxMultipleChoiceFieldPanel.java  |   2 +-
 .../wicket/markup/html/form/FieldPanel.java     |  17 +-
 .../markup/html/form/MultiFieldPanel.java       | 103 ++++++---
 .../markup/html/form/SpinnerFieldPanel.java     | 184 ++++------------
 .../html/list/ConnConfPropertyListView.java     |   6 +-
 .../META-INF/resources/css/syncopeConsole.css   |   5 +-
 .../syncope/client/console/pages/Login.html     |  29 ++-
 .../client/console/panels/ConnectorModal.html   | 219 +++++++++----------
 .../client/console/panels/ModalContent.html     |  45 ----
 .../console/panels/ModalContent.properties      |  20 --
 .../console/panels/ModalContent_it.properties   |  20 --
 .../panels/ModalContent_pt_BR.properties        |  20 --
 .../console/panels/ResourceDetailsPanel.html    | 146 +++----------
 .../client/console/panels/ResourceModal.html    |  33 +--
 .../console/panels/ResourceSecurityPanel.html   |  43 +---
 .../markup/html/form/AjaxCheckBoxPanel.html     |  18 +-
 .../html/form/AjaxDropDownChoicePanel.html      |  11 +-
 .../markup/html/form/AjaxTextFieldPanel.html    |  19 +-
 .../markup/html/form/MultiFieldPanel.html       |  49 ++++-
 .../markup/html/form/SpinnerFieldPanel.html     |  11 +-
 pom.xml                                         |   3 +-
 42 files changed, 808 insertions(+), 1121 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e93ca7/client/console/src/main/java/org/apache/syncope/client/console/pages/Login.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/pages/Login.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/pages/Login.java
index 23fb25f..7e56e92 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/pages/Login.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/pages/Login.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.pages;
 
+import 
de.agilecoders.wicket.extensions.markup.html.bootstrap.form.select.BootstrapSelect;
 import java.security.AccessControlException;
 import java.util.Locale;
 import org.apache.syncope.client.console.SyncopeConsoleApplication;
@@ -120,7 +121,7 @@ public class Login extends WebPage {
     /**
      * Inner class which implements (custom) Locale DropDownChoice component.
      */
-    private class LocaleDropDown extends DropDownChoice<Locale> {
+    private class LocaleDropDown extends BootstrapSelect<Locale> {
 
         private static final long serialVersionUID = 2349382679992357202L;
 
@@ -171,7 +172,7 @@ public class Login extends WebPage {
     /**
      * Inner class which implements (custom) Domain DropDownChoice component.
      */
-    private class DomainDropDown extends DropDownChoice<String> {
+    private class DomainDropDown extends BootstrapSelect<String> {
 
         private static final long serialVersionUID = -7401167913360133325L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e93ca7/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
index 139283f..96d538b 100644
--- 
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
@@ -30,6 +30,7 @@ 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.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.markup.head.HeaderItem;
 import org.apache.wicket.markup.head.IHeaderResponse;
@@ -54,6 +55,10 @@ public class AbstractModalPanel extends Panel {
 
     protected static final String APPLY = "apply";
 
+    protected static final String FORM = "form";
+
+    protected final PageReference pageRef;
+
     protected final HeaderItem meta = new MetaHeaderItem("X-UA-Compatible", 
"IE=edge");
 
     @SpringBean
@@ -86,8 +91,9 @@ public class AbstractModalPanel extends Panel {
     @SpringBean
     protected MIMETypesLoader mimeTypesInitializer;
 
-    public AbstractModalPanel(final BaseModal<?> modal) {
+    public AbstractModalPanel(final BaseModal<?> modal, final PageReference 
pageRef) {
         super(BaseModal.getContentId());
+        this.pageRef = pageRef;
         this.modal = modal;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e93ca7/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractResourceModal.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractResourceModal.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractResourceModal.java
index 1ed9050..fa18012 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractResourceModal.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractResourceModal.java
@@ -20,19 +20,20 @@ package org.apache.syncope.client.console.panels;
 
 import java.io.Serializable;
 import org.apache.syncope.client.console.topology.TopologyNode;
+import 
org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import 
org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal.ModalEvent;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
 
 /**
  * Modal window with Resource form.
  */
-public abstract class AbstractResourceModal extends ModalContent {
+public abstract class AbstractResourceModal extends AbstractModalPanel {
 
     private static final long serialVersionUID = 1734415311027284221L;
 
-    public AbstractResourceModal(final ModalWindow window, final PageReference 
pageRef) {
-        super(window, pageRef);
+    public AbstractResourceModal(final BaseModal<?> modal, final PageReference 
pageRef) {
+        super(modal, pageRef);
     }
 
     public static class CreateEvent extends ModalEvent {

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e93ca7/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
index 4f5e8eb..8a1ecdb 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.panels;
 
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -30,6 +31,7 @@ import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.topology.Topology;
 import org.apache.syncope.client.console.topology.TopologyNode;
+import 
org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
 import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import 
org.apache.syncope.client.console.wicket.markup.html.form.CheckBoxMultipleChoiceFieldPanel;
@@ -42,16 +44,13 @@ import org.apache.syncope.common.lib.to.ConnPoolConfTO;
 import org.apache.syncope.common.lib.types.ConnConfPropSchema;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.ConnectorCapability;
-import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
 import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
-import 
org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
 import org.apache.wicket.event.Broadcast;
 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.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.DropDownChoice;
@@ -82,10 +81,16 @@ public class ConnectorModal extends AbstractResourceModal {
 
     private final WebMarkupContainer propertiesContainer;
 
+    private final ListView<ConnConfProperty> connPropView;
+
+    private final ConnInstanceTO connInstanceTO;
+
     public ConnectorModal(
-            final ModalWindow window, final PageReference pageRef, final 
ConnInstanceTO connInstanceTO) {
+            final BaseModal<Serializable> modal, final PageReference pageRef, 
final ConnInstanceTO connInstanceTO) {
+
+        super(modal, pageRef);
 
-        super(window, pageRef);
+        this.connInstanceTO = connInstanceTO;
 
         this.add(new Label("new", connInstanceTO.getKey() == 0
                 ? new ResourceModel("new")
@@ -122,15 +127,9 @@ public class ConnectorModal extends AbstractResourceModal {
         bundleTO = getSelectedBundleTO(connInstanceTO);
         properties = fillProperties(bundleTO, connInstanceTO);
 
-        // form - first tab
-        final Form<ConnInstanceTO> connectorForm = new Form<>(FORM);
-        connectorForm.setModel(new CompoundPropertyModel<>(connInstanceTO));
-        connectorForm.setOutputMarkupId(true);
-        add(connectorForm);
-
         propertiesContainer = new WebMarkupContainer("container");
         propertiesContainer.setOutputMarkupId(true);
-        connectorForm.add(propertiesContainer);
+        add(propertiesContainer);
 
         final Form<ConnInstanceTO> connectorPropForm = new 
Form<>("connectorPropForm");
         connectorPropForm.setModel(new 
CompoundPropertyModel<>(connInstanceTO));
@@ -141,7 +140,7 @@ public class ConnectorModal extends AbstractResourceModal {
                 "displayName", "display name", new 
PropertyModel<String>(connInstanceTO, "displayName"));
         displayName.setOutputMarkupId(true);
         displayName.addRequiredLabel();
-        connectorForm.add(displayName);
+        add(displayName);
 
         final AjaxDropDownChoicePanel<String> location = new 
AjaxDropDownChoicePanel<>("location", "location",
                 new Model<>(bundleTO == null ? connInstanceTO.getLocation() : 
bundleTO.getLocation()));
@@ -153,7 +152,7 @@ public class ConnectorModal extends AbstractResourceModal {
         location.setOutputMarkupId(true);
         location.setEnabled(connInstanceTO.getKey() == 0 && 
StringUtils.isBlank(connInstanceTO.getLocation()));
         location.getField().setOutputMarkupId(true);
-        connectorForm.add(location);
+        add(location);
 
         final AjaxDropDownChoicePanel<String> connectorName = new 
AjaxDropDownChoicePanel<>("connectorName",
                 "connectorName",
@@ -170,7 +169,7 @@ public class ConnectorModal extends AbstractResourceModal {
         connectorName.setOutputMarkupId(true);
         connectorName.setEnabled(connInstanceTO.getKey() == 0);
         connectorName.getField().setOutputMarkupId(true);
-        connectorForm.add(connectorName);
+        add(connectorName);
 
         final AjaxDropDownChoicePanel<String> version = new 
AjaxDropDownChoicePanel<>("version", "version",
                 new Model<>(bundleTO == null ? null : bundleTO.getVersion()));
@@ -185,13 +184,13 @@ public class ConnectorModal extends AbstractResourceModal 
{
         version.setOutputMarkupId(true);
         version.addRequiredLabel();
         version.getField().setOutputMarkupId(true);
-        connectorForm.add(version);
+        add(version);
 
         final SpinnerFieldPanel<Integer> connRequestTimeout = new 
SpinnerFieldPanel<>("connRequestTimeout",
                 "connRequestTimeout", Integer.class,
                 new PropertyModel<Integer>(connInstanceTO, 
"connRequestTimeout"), 0, null);
         connRequestTimeout.getField().add(new RangeValidator<>(0, 
Integer.MAX_VALUE));
-        connectorForm.add(connRequestTimeout);
+        add(connRequestTimeout);
 
         if (connInstanceTO.getPoolConf() == null) {
             connInstanceTO.setPoolConf(new ConnPoolConfTO());
@@ -200,27 +199,27 @@ public class ConnectorModal extends AbstractResourceModal 
{
                 Integer.class,
                 new PropertyModel<Integer>(connInstanceTO.getPoolConf(), 
"maxObjects"), 0, null);
         poolMaxObjects.getField().add(new RangeValidator<>(0, 
Integer.MAX_VALUE));
-        connectorForm.add(poolMaxObjects);
+        add(poolMaxObjects);
         final SpinnerFieldPanel<Integer> poolMinIdle = new 
SpinnerFieldPanel<>("poolMinIdle", "poolMinIdle",
                 Integer.class,
                 new PropertyModel<Integer>(connInstanceTO.getPoolConf(), 
"minIdle"), 0, null);
         poolMinIdle.getField().add(new RangeValidator<>(0, Integer.MAX_VALUE));
-        connectorForm.add(poolMinIdle);
+        add(poolMinIdle);
         final SpinnerFieldPanel<Integer> poolMaxIdle = new 
SpinnerFieldPanel<>("poolMaxIdle", "poolMaxIdle",
                 Integer.class,
                 new PropertyModel<Integer>(connInstanceTO.getPoolConf(), 
"maxIdle"), 0, null);
         poolMaxIdle.getField().add(new RangeValidator<>(0, Integer.MAX_VALUE));
-        connectorForm.add(poolMaxIdle);
+        add(poolMaxIdle);
         final SpinnerFieldPanel<Long> poolMaxWait = new 
SpinnerFieldPanel<>("poolMaxWait", "poolMaxWait", Long.class,
                 new PropertyModel<Long>(connInstanceTO.getPoolConf(), 
"maxWait"), 0L, null);
         poolMaxWait.getField().add(new RangeValidator<>(0L, Long.MAX_VALUE));
-        connectorForm.add(poolMaxWait);
+        add(poolMaxWait);
         final SpinnerFieldPanel<Long> poolMinEvictableIdleTime = new 
SpinnerFieldPanel<>("poolMinEvictableIdleTime",
                 "poolMinEvictableIdleTime", Long.class,
                 new PropertyModel<Long>(connInstanceTO.getPoolConf(), 
"minEvictableIdleTimeMillis"),
                 0L, null);
         poolMinEvictableIdleTime.getField().add(new RangeValidator<>(0L, 
Long.MAX_VALUE));
-        connectorForm.add(poolMinEvictableIdleTime);
+        add(poolMinEvictableIdleTime);
 
         // form - first tab - onchange()
         location.getField().add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
@@ -284,7 +283,7 @@ public class ConnectorModal extends AbstractResourceModal {
         });
 
         // form - second tab (properties)
-        final ListView<ConnConfProperty> connPropView = new 
ConnConfPropertyListView("connectorProperties",
+        connPropView = new ConnConfPropertyListView("connectorProperties",
                 new PropertyModel<List<ConnConfProperty>>(this, "properties"),
                 true, connInstanceTO.getConfiguration());
         connPropView.setOutputMarkupId(true);
@@ -309,14 +308,14 @@ public class ConnectorModal extends AbstractResourceModal 
{
                     error(getString("error_connection"));
                 }
 
-                feedbackPanel.refresh(target);
+                modal.getFeedbackPanel().refresh(target);
             }
         };
         connectorPropForm.add(check);
 
         // form - third tab (capabilities)
-        final IModel<List<ConnectorCapability>> capabilities =
-                 new LoadableDetachableModel<List<ConnectorCapability>>() {
+        final IModel<List<ConnectorCapability>> capabilities
+                = new LoadableDetachableModel<List<ConnectorCapability>>() {
 
                     private static final long serialVersionUID = 
5275935387613157437L;
 
@@ -325,8 +324,8 @@ public class ConnectorModal extends AbstractResourceModal {
                         return Arrays.asList(ConnectorCapability.values());
                     }
                 };
-        CheckBoxMultipleChoiceFieldPanel<ConnectorCapability> 
capabilitiesPalette =
-                 new CheckBoxMultipleChoiceFieldPanel<>(
+        CheckBoxMultipleChoiceFieldPanel<ConnectorCapability> 
capabilitiesPalette
+                = new CheckBoxMultipleChoiceFieldPanel<>(
                         "capabilitiesPalette",
                         new PropertyModel<List<ConnectorCapability>>(this, 
"selectedCapabilities"), capabilities);
 
@@ -339,86 +338,7 @@ public class ConnectorModal extends AbstractResourceModal {
             }
         });
 
-        connectorForm.add(capabilitiesPalette);
-
-        // form - submit / cancel buttons
-        final AjaxButton submit = new IndicatingAjaxButton(APPLY, new 
Model<>(getString(SUBMIT))) {
-
-            private static final long serialVersionUID = -958724007591692537L;
-
-            @Override
-            protected void onSubmit(final AjaxRequestTarget target, final 
Form<?> form) {
-                final ConnInstanceTO conn = (ConnInstanceTO) 
form.getModelObject();
-
-                conn.setConnectorName(bundleTO.getConnectorName());
-                conn.setBundleName(bundleTO.getBundleName());
-                conn.setVersion(bundleTO.getVersion());
-                conn.getConfiguration().clear();
-                conn.getConfiguration().addAll(connPropView.getModelObject());
-
-                // Set the model object's capabilities to 
capabilitiesPalette's converted Set
-                conn.getCapabilities().clear();
-                conn.getCapabilities().addAll(selectedCapabilities.isEmpty()
-                        ? EnumSet.noneOf(ConnectorCapability.class)
-                        : EnumSet.copyOf(selectedCapabilities));
-
-                // Reset pool configuration if all fields are null
-                if (conn.getPoolConf() != null
-                        && conn.getPoolConf().getMaxIdle() == null
-                        && conn.getPoolConf().getMaxObjects() == null
-                        && conn.getPoolConf().getMaxWait() == null
-                        && conn.getPoolConf().getMinEvictableIdleTimeMillis() 
== null
-                        && conn.getPoolConf().getMinIdle() == null) {
-
-                    conn.setPoolConf(null);
-                }
-
-                try {
-                    if (connInstanceTO.getKey() == 0) {
-                        connectorRestClient.create(conn);
-                        send(pageRef.getPage(), Broadcast.BREADTH, new 
CreateEvent(
-                                conn.getKey(),
-                                conn.getDisplayName(),
-                                TopologyNode.Kind.CONNECTOR,
-                                
conn.getLocation().startsWith(Topology.CONNECTOR_SERVER_LOCATION_PREFIX)
-                                        ? conn.getLocation() : 
Topology.ROOT_NAME,
-                                target));
-                    } else {
-                        connectorRestClient.update(conn);
-                    }
-
-                    ((BasePage) pageRef.getPage()).setModalResult(true);
-                    window.close(target);
-                } catch (SyncopeClientException e) {
-                    error(getString(Constants.ERROR) + ": " + e.getMessage());
-                    feedbackPanel.refresh(target);
-                    ((BasePage) pageRef.getPage()).setModalResult(false);
-                    LOG.error("While creating or updating connector {}", conn, 
e);
-                }
-            }
-
-            @Override
-            protected void onError(final AjaxRequestTarget target, final 
Form<?> form) {
-                feedbackPanel.refresh(target);
-            }
-        };
-        String entitlements = connInstanceTO.getKey() == 0
-                ? Entitlement.CONNECTOR_CREATE : Entitlement.CONNECTOR_UPDATE;
-
-        MetaDataRoleAuthorizationStrategy.authorize(submit, ENABLE, 
entitlements);
-        connectorForm.add(submit);
-
-        final IndicatingAjaxButton cancel = new IndicatingAjaxButton(CANCEL, 
new ResourceModel(CANCEL)) {
-
-            private static final long serialVersionUID = -958724007591692537L;
-
-            @Override
-            protected void onSubmit(final AjaxRequestTarget target, final 
Form<?> form) {
-                window.close(target);
-            }
-        };
-        cancel.setDefaultFormProcessing(false);
-        connectorForm.add(cancel);
+        add(capabilitiesPalette);
     }
 
     private ConnBundleTO getSelectedBundleTO(final ConnInstanceTO 
connInstanceTO) {
@@ -482,4 +402,60 @@ public class ConnectorModal extends AbstractResourceModal {
     public List<ConnConfProperty> getProperties() {
         return properties;
     }
+
+    @Override
+    public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+        final ConnInstanceTO conn = (ConnInstanceTO) form.getModelObject();
+
+        conn.setConnectorName(bundleTO.getConnectorName());
+        conn.setBundleName(bundleTO.getBundleName());
+        conn.setVersion(bundleTO.getVersion());
+        conn.getConfiguration().clear();
+        conn.getConfiguration().addAll(connPropView.getModelObject());
+
+        // Set the model object's capabilities to capabilitiesPalette's 
converted Set
+        conn.getCapabilities().clear();
+        conn.getCapabilities().addAll(selectedCapabilities.isEmpty()
+                ? EnumSet.noneOf(ConnectorCapability.class)
+                : EnumSet.copyOf(selectedCapabilities));
+
+        // Reset pool configuration if all fields are null
+        if (conn.getPoolConf() != null
+                && conn.getPoolConf().getMaxIdle() == null
+                && conn.getPoolConf().getMaxObjects() == null
+                && conn.getPoolConf().getMaxWait() == null
+                && conn.getPoolConf().getMinEvictableIdleTimeMillis() == null
+                && conn.getPoolConf().getMinIdle() == null) {
+
+            conn.setPoolConf(null);
+        }
+
+        try {
+            if (connInstanceTO.getKey() == 0) {
+                connectorRestClient.create(conn);
+                send(pageRef.getPage(), Broadcast.BREADTH, new CreateEvent(
+                        conn.getKey(),
+                        conn.getDisplayName(),
+                        TopologyNode.Kind.CONNECTOR,
+                        
conn.getLocation().startsWith(Topology.CONNECTOR_SERVER_LOCATION_PREFIX)
+                                ? conn.getLocation() : Topology.ROOT_NAME,
+                        target));
+            } else {
+                connectorRestClient.update(conn);
+            }
+
+            ((BasePage) pageRef.getPage()).setModalResult(true);
+            modal.close(target);
+        } catch (SyncopeClientException e) {
+            error(getString(Constants.ERROR) + ": " + e.getMessage());
+            modal.getFeedbackPanel().refresh(target);
+            ((BasePage) pageRef.getPage()).setModalResult(false);
+            LOG.error("While creating or updating connector {}", conn, e);
+        }
+    }
+
+    @Override
+    public void onError(final AjaxRequestTarget target, final Form<?> form) {
+        modal.getFeedbackPanel().refresh(target);
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e93ca7/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
index 38edbf0..f23cecb 100644
--- 
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
@@ -18,17 +18,17 @@
  */
 package org.apache.syncope.client.console.panels;
 
+import 
org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 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 {
+public class FailureMessageModal extends AbstractModalPanel {
 
     private static final long serialVersionUID = 9216117990503199258L;
 
-    public FailureMessageModal(final PageReference pageRef, final ModalWindow 
window, final String failureMessage) {
-        super(window, pageRef);
+    public FailureMessageModal(final BaseModal<?> modal, final PageReference 
pageRef, final String failureMessage) {
+        super(modal, pageRef);
         final Label executionFailureMessage;
         if (!failureMessage.isEmpty()) {
             executionFailureMessage = new Label("failureMessage", new 
Model<String>(failureMessage));

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e93ca7/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
index 8c0e0ae..2e4caf5 100644
--- 
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
@@ -23,6 +23,7 @@ import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.Mode;
 import 
org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
 import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
@@ -46,14 +47,16 @@ public class GroupModalPanel extends AbstractModalPanel {
 
     protected GroupTO originalGroupTO;
 
-    public GroupModalPanel(final BaseModal<?> modal, final GroupTO groupTO) {
-        this(modal, groupTO, Mode.ADMIN);
+    public GroupModalPanel(
+            final BaseModal<?> modal, final PageReference pageRef, final 
GroupTO groupTO) {
+        this(modal, pageRef, groupTO, Mode.ADMIN);
     }
 
     @SuppressWarnings({ "unchecked", "rawtypes" })
-    public GroupModalPanel(final BaseModal<?> modal, final GroupTO groupTO, 
final Mode mode) {
+    public GroupModalPanel(
+            final BaseModal<?> modal, final PageReference pageRef, final 
GroupTO groupTO, final Mode mode) {
 
-        super(modal);
+        super(modal, pageRef);
 
         this.mode = mode;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e93ca7/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 ffc232a..60fb1b7 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
@@ -55,7 +55,7 @@ public class GroupSearchResultPanel extends 
AnySearchResultPanel {
 
     private final String entitlement = "GROUP_READ";
 
-    private final BaseModal<AbstractModalPanel> editModal;
+    private final BaseModal<?> editModal;
 
     public GroupSearchResultPanel(final String type, final String parentId,
             final boolean filtered, final String fiql, final PageReference 
callerRef,
@@ -125,7 +125,8 @@ public class GroupSearchResultPanel extends 
AnySearchResultPanel {
 
                     @Override
                     public void onClick(final AjaxRequestTarget target, final 
AnyTO anyTO) {
-                        editModal.addOrReplace(new GroupModalPanel(editModal, 
(GroupTO) model.getObject()));
+                        editModal.addOrReplace(new GroupModalPanel(
+                                editModal, getPage().getPageReference(), 
GroupTO.class.cast(model.getObject())));
 
                         target.add(editModal);
                         editModal.show(target);

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e93ca7/client/console/src/main/java/org/apache/syncope/client/console/panels/ModalContent.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ModalContent.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ModalContent.java
deleted file mode 100644
index 6a123c0..0000000
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ModalContent.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.panels;
-
-import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.rest.ConnectorRestClient;
-import org.apache.syncope.client.console.rest.ResourceRestClient;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
-import org.apache.wicket.markup.html.panel.Panel;
-import org.apache.wicket.spring.injection.annot.SpringBean;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Modal window with Resource form.
- */
-public class ModalContent extends Panel {
-
-    private static final long serialVersionUID = 8611724965544132636L;
-
-    protected static final Logger LOG = 
LoggerFactory.getLogger(ModalContent.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";
-
-    @SpringBean
-    protected ResourceRestClient resourceRestClient;
-
-    @SpringBean
-    protected ConnectorRestClient connectorRestClient;
-
-    protected NotificationPanel feedbackPanel;
-
-    protected final PageReference pageRef;
-
-    protected final ModalWindow window;
-
-    public ModalContent(final ModalWindow window, final PageReference pageRef) 
{
-        super(window.getContentId());
-        this.pageRef = pageRef;
-        this.window = window;
-
-        feedbackPanel = new NotificationPanel(Constants.FEEDBACK);
-        feedbackPanel.setOutputMarkupId(true);
-        add(feedbackPanel);
-    }
-
-    public NotificationPanel getFeedbackPanel() {
-        return feedbackPanel;
-    }
-
-    /**
-     * Generic modal event.
-     */
-    public static class ModalEvent {
-
-        /**
-         * Request target.
-         */
-        private final AjaxRequestTarget target;
-
-        /**
-         * Constructor.
-         *
-         * @param target request target.
-         */
-        public ModalEvent(final AjaxRequestTarget target) {
-            this.target = target;
-        }
-
-        /**
-         * Target getter.
-         *
-         * @return request target.
-         */
-        public AjaxRequestTarget getTarget() {
-            return target;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e93ca7/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
index 7e8f415..9ea299f 100644
--- 
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
@@ -39,8 +39,6 @@ public class RealmModalPanel extends AbstractModalPanel {
 
     protected RealmTO realmTO;
 
-    private final PageReference pageRef;
-
     private boolean newRealm = false;
 
     @SpringBean
@@ -65,10 +63,9 @@ public class RealmModalPanel extends AbstractModalPanel {
             final String entitlement,
             final boolean newRealm) {
 
-        super(modal);
-        this.newRealm = newRealm;
+        super(modal, pageRef);
 
-        this.pageRef = pageRef;
+        this.newRealm = newRealm;
         this.realmTO = realmTO;
         this.parentPath = parentPath;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e93ca7/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
index 1b536c4..0101895 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
@@ -24,9 +24,9 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import org.apache.syncope.client.console.pages.BaseModalPage;
-import org.apache.syncope.client.console.panels.ModalContent.ModalEvent;
 import 
org.apache.syncope.client.console.panels.ResourceDetailsPanel.DetailsModEvent;
 import org.apache.syncope.client.console.rest.ConnectorRestClient;
+import 
org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal.ModalEvent;
 import 
org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel.MultiValueSelectorEvent;
 import 
org.apache.syncope.client.console.wicket.markup.html.list.ConnConfPropertyListView;
 import org.apache.syncope.common.lib.to.ResourceTO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e93ca7/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
index d556346..ba5388d 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
@@ -20,13 +20,13 @@ package org.apache.syncope.client.console.panels;
 
 import java.util.Arrays;
 import java.util.List;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.panels.ModalContent.ModalEvent;
 import org.apache.syncope.client.console.rest.ConnectorRestClient;
+import 
org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal.ModalEvent;
 import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel;
 import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
 import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import 
org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel;
 import 
org.apache.syncope.client.console.wicket.markup.html.form.SpinnerFieldPanel;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
@@ -34,14 +34,9 @@ import org.apache.syncope.common.lib.types.PropagationMode;
 import org.apache.syncope.common.lib.types.TraceLevel;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
-import org.apache.wicket.ajax.markup.html.AjaxLink;
 import org.apache.wicket.event.Broadcast;
-import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.form.ChoiceRenderer;
-import org.apache.wicket.markup.html.form.DropDownChoice;
-import org.apache.wicket.markup.html.list.ListItem;
-import org.apache.wicket.markup.html.list.ListView;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.LoadableDetachableModel;
@@ -72,139 +67,83 @@ public class ResourceDetailsPanel extends Panel {
         super(id);
         setOutputMarkupId(true);
 
+        final WebMarkupContainer container = new 
WebMarkupContainer("container");
+        container.setOutputMarkupId(true);
+        container.setRenderBodyOnly(true);
+        add(container);
+
         final AjaxTextFieldPanel resourceName = new AjaxTextFieldPanel("name", 
new ResourceModel("name", "name").
                 getObject(), new PropertyModel<String>(resourceTO, "key"));
 
         resourceName.setEnabled(createFlag);
         resourceName.addRequiredLabel();
-        add(resourceName);
+        container.add(resourceName);
 
         final AjaxCheckBoxPanel enforceMandatoryCondition = new 
AjaxCheckBoxPanel("enforceMandatoryCondition",
                 new ResourceModel("enforceMandatoryCondition", 
"enforceMandatoryCondition").getObject(),
                 new PropertyModel<Boolean>(resourceTO, 
"enforceMandatoryCondition"));
-        add(enforceMandatoryCondition);
+        container.add(enforceMandatoryCondition);
 
         final AjaxCheckBoxPanel propagationPrimary = new 
AjaxCheckBoxPanel("propagationPrimary", new ResourceModel(
                 "propagationPrimary", "propagationPrimary").getObject(), new 
PropertyModel<Boolean>(resourceTO,
                         "propagationPrimary"));
-        add(propagationPrimary);
+        container.add(propagationPrimary);
 
-        final SpinnerFieldPanel<Integer> propagationPriority = new 
SpinnerFieldPanel<>("propagationPriority",
-                "propagationPriority", Integer.class,
-                new PropertyModel<Integer>(resourceTO, "propagationPriority"), 
null, null);
-        add(propagationPriority);
+        final SpinnerFieldPanel<Integer> propagationPriority = new 
SpinnerFieldPanel<>(
+                "propagationPriority",
+                "propagationPriority",
+                Integer.class,
+                new PropertyModel<Integer>(resourceTO, "propagationPriority"));
+        container.add(propagationPriority);
 
         final AjaxDropDownChoicePanel<PropagationMode> propagationMode = new 
AjaxDropDownChoicePanel<>(
                 "propagationMode", new ResourceModel("propagationMode", 
"propagationMode").getObject(),
                 new PropertyModel<PropagationMode>(resourceTO, 
"propagationMode"));
         propagationMode.setChoices(Arrays.asList(PropagationMode.values()));
-        add(propagationMode);
+        container.add(propagationMode);
 
         final AjaxCheckBoxPanel randomPwdIfNotProvided = new 
AjaxCheckBoxPanel("randomPwdIfNotProvided",
                 new ResourceModel("randomPwdIfNotProvided", 
"randomPwdIfNotProvided").getObject(),
                 new PropertyModel<Boolean>(resourceTO, 
"randomPwdIfNotProvided"));
-        add(randomPwdIfNotProvided);
-
-        final WebMarkupContainer propagationActionsClassNames = new 
WebMarkupContainer("propagationActionsClassNames");
-        propagationActionsClassNames.setOutputMarkupId(true);
-        add(propagationActionsClassNames);
+        container.add(randomPwdIfNotProvided);
 
-        final AjaxLink<Void> first = new IndicatingAjaxLink<Void>("first") {
+        final AjaxDropDownChoicePanel<String> template
+                = new AjaxDropDownChoicePanel<>("panel", "panel", new 
Model<String>());
+        template.setChoices(actionClassNames);
+        template.setNullValid(true);
+        template.setRequired(true);
 
-            private static final long serialVersionUID = -7978723352517770644L;
+        final MultiFieldPanel<String> actions = new MultiFieldPanel<>(
+                "actionsClasses",
+                "actionsClasses",
+                new PropertyModel<List<String>>(resourceTO, 
"propagationActionsClassNames"),
+                template);
 
-            @Override
-            public void onClick(final AjaxRequestTarget target) {
-                
resourceTO.getPropagationActionsClassNames().add(StringUtils.EMPTY);
-                setVisible(false);
-                target.add(propagationActionsClassNames);
-            }
-        };
-        first.setOutputMarkupPlaceholderTag(true);
-        
first.setVisible(resourceTO.getPropagationActionsClassNames().isEmpty());
-        propagationActionsClassNames.add(first);
-
-        final ListView<String> actionsClasses = new 
ListView<String>("actionsClasses",
-                new PropertyModel<List<String>>(resourceTO, 
"propagationActionsClassNames")) {
-
-                    private static final long serialVersionUID = 
9101744072914090143L;
-
-                    @Override
-                    protected void populateItem(final ListItem<String> item) {
-                        final String className = item.getModelObject();
-
-                        final DropDownChoice<String> actionsClass = new 
DropDownChoice<>(
-                                "actionsClass", new Model<>(className), 
actionClassNames);
-                        actionsClass.setNullValid(true);
-                        actionsClass.setRequired(true);
-                        actionsClass.add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) {
-
-                            private static final long serialVersionUID = 
-1107858522700306810L;
-
-                            @Override
-                            protected void onUpdate(final AjaxRequestTarget 
target) {
-                                resourceTO.getPropagationActionsClassNames().
-                                set(item.getIndex(), 
actionsClass.getModelObject());
-                            }
-                        });
-                        actionsClass.setRequired(true);
-                        actionsClass.setOutputMarkupId(true);
-                        actionsClass.setRequired(true);
-                        item.add(actionsClass);
-
-                        final AjaxLink<Void> minus = new 
IndicatingAjaxLink<Void>("drop") {
-
-                            private static final long serialVersionUID = 
-7978723352517770644L;
-
-                            @Override
-                            public void onClick(final AjaxRequestTarget 
target) {
-                                
resourceTO.getPropagationActionsClassNames().remove(className);
-                                
first.setVisible(resourceTO.getPropagationActionsClassNames().isEmpty());
-                                target.add(propagationActionsClassNames);
-                            }
-                        };
-                        item.add(minus);
-
-                        final AjaxLink<Void> plus = new 
IndicatingAjaxLink<Void>("add") {
-
-                            private static final long serialVersionUID = 
-7978723352517770644L;
-
-                            @Override
-                            public void onClick(final AjaxRequestTarget 
target) {
-                                
resourceTO.getPropagationActionsClassNames().add(StringUtils.EMPTY);
-                                target.add(propagationActionsClassNames);
-                            }
-                        };
-                        plus.setOutputMarkupPlaceholderTag(true);
-                        plus.setVisible(item.getIndex() == 
resourceTO.getPropagationActionsClassNames().size() - 1);
-                        item.add(plus);
-                    }
-                };
-        propagationActionsClassNames.add(actionsClasses);
+        container.add(actions);
 
         final AjaxDropDownChoicePanel<TraceLevel> createTraceLevel = new 
AjaxDropDownChoicePanel<>(
                 "createTraceLevel", new ResourceModel("createTraceLevel", 
"createTraceLevel").getObject(),
                 new PropertyModel<TraceLevel>(resourceTO, "createTraceLevel"));
         createTraceLevel.setChoices(Arrays.asList(TraceLevel.values()));
-        add(createTraceLevel);
+        container.add(createTraceLevel);
 
         final AjaxDropDownChoicePanel<TraceLevel> updateTraceLevel = new 
AjaxDropDownChoicePanel<>(
                 "updateTraceLevel", new ResourceModel("updateTraceLevel", 
"updateTraceLevel").getObject(),
                 new PropertyModel<TraceLevel>(resourceTO, "updateTraceLevel"));
         updateTraceLevel.setChoices(Arrays.asList(TraceLevel.values()));
-        add(updateTraceLevel);
+        container.add(updateTraceLevel);
 
         final AjaxDropDownChoicePanel<TraceLevel> deleteTraceLevel = new 
AjaxDropDownChoicePanel<>(
                 "deleteTraceLevel", new ResourceModel("deleteTraceLevel", 
"deleteTraceLevel").getObject(),
                 new PropertyModel<TraceLevel>(resourceTO, "deleteTraceLevel"));
         deleteTraceLevel.setChoices(Arrays.asList(TraceLevel.values()));
-        add(deleteTraceLevel);
+        container.add(deleteTraceLevel);
 
         final AjaxDropDownChoicePanel<TraceLevel> syncTraceLevel = new 
AjaxDropDownChoicePanel<>(
                 "syncTraceLevel", new ResourceModel("syncTraceLevel", 
"syncTraceLevel").getObject(),
                 new PropertyModel<TraceLevel>(resourceTO, "syncTraceLevel"));
         syncTraceLevel.setChoices(Arrays.asList(TraceLevel.values()));
-        add(syncTraceLevel);
+        container.add(syncTraceLevel);
 
         final IModel<List<ConnInstanceTO>> connectors = new 
LoadableDetachableModel<List<ConnInstanceTO>>() {
 
@@ -257,7 +196,9 @@ public class ResourceDetailsPanel extends Panel {
             }
         });
 
-        add(conn);
+        container.add(conn);
+
+        add(new AnnotatedBeanPanel("systeminformation", resourceTO));
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e93ca7/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceModal.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceModal.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceModal.java
index 54b22b8..7b84312 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceModal.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceModal.java
@@ -18,14 +18,20 @@
  */
 package org.apache.syncope.client.console.panels;
 
+import static org.apache.wicket.Component.ENABLE;
+
+import 
de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.commons.lang3.SerializationUtils;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.pages.AbstractBasePage;
 import org.apache.syncope.client.console.topology.TopologyNode;
+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.wizards.AjaxWizard;
 import 
org.apache.syncope.client.console.wizards.provision.ProvisionWizardBuilder;
@@ -35,14 +41,12 @@ import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.Entitlement;
 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.event.Broadcast;
-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.WebMarkupContainer;
+import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
+import org.apache.wicket.extensions.markup.html.tabs.ITab;
 import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.ResourceModel;
 
 /**
@@ -52,33 +56,39 @@ public class ResourceModal extends AbstractResourceModal {
 
     private static final long serialVersionUID = 1734415311027284221L;
 
-    @SuppressWarnings({ "unchecked", "rawtypes" })
+    private final boolean createFlag;
+
     public ResourceModal(
-            final ModalWindow window,
+            final BaseModal<Serializable> modal,
             final PageReference pageRef,
             final ResourceTO resourceTO,
             final boolean createFlag) {
 
-        super(window, pageRef);
+        super(modal, pageRef);
+
+        this.createFlag = createFlag;
 
-        final Form<ResourceTO> form = new Form<>(FORM);
-        form.setModel(new CompoundPropertyModel<>(resourceTO));
+        final List<ITab> tabs = new ArrayList<>();
+        add(new AjaxBootstrapTabbedPanel<>("tabbedPanel", tabs));
 
         //--------------------------------
         // Resource details panel
         //--------------------------------
-        form.add(new ResourceDetailsPanel("details", resourceTO,
-                resourceRestClient.getPropagationActionsClasses(), 
createFlag));
+        tabs.add(new AbstractTab(new ResourceModel("resource", "resource")) {
 
-        form.add(new AnnotatedBeanPanel("systeminformation", resourceTO));
+            private static final long serialVersionUID = -5861786415855103549L;
+
+            @Override
+            public Panel getPanel(final String panelId) {
+                return new ResourceDetailsPanel(panelId, resourceTO,
+                        resourceRestClient.getPropagationActionsClasses(), 
createFlag);
+            }
+        });
         //--------------------------------
 
         //--------------------------------
         // Resource provision panels
         //--------------------------------
-        final WebMarkupContainer provisions = new 
WebMarkupContainer("pcontainer");
-        form.add(provisions.setOutputMarkupId(true));
-
         final ListViewPanel.Builder<ProvisionTO> builder = 
ListViewPanel.builder(ProvisionTO.class, pageRef);
         builder.setItems(resourceTO.getProvisions());
         builder.includes("anyType", "objectClass");
@@ -133,114 +143,109 @@ public class ResourceModal extends 
AbstractResourceModal {
         }, ActionLink.ActionType.DELETE, Entitlement.RESOURCE_DELETE);
 
         builder.addNewItemPanelBuilder(new ProvisionWizardBuilder("wizard", 
resourceTO, pageRef));
-        builder.addNotificationPanel(feedbackPanel);
+        builder.addNotificationPanel(modal.getFeedbackPanel());
+
+        tabs.add(new AbstractTab(new ResourceModel("provisions", 
"provisions")) {
 
-        provisions.add(builder.build("provisions"));
+            private static final long serialVersionUID = -5861786415855103549L;
+
+            @Override
+            public Panel getPanel(final String panelId) {
+                return builder.build(panelId);
+            }
+        });
         //--------------------------------
 
         //--------------------------------
         // Resource connector configuration panel
         //--------------------------------
-        ResourceConnConfPanel resourceConnConfPanel = new 
ResourceConnConfPanel("connconf", resourceTO, createFlag);
-        MetaDataRoleAuthorizationStrategy.authorize(resourceConnConfPanel, 
ENABLE, Entitlement.CONNECTOR_READ);
-        form.add(resourceConnConfPanel);
+        tabs.add(new AbstractTab(new ResourceModel("connectorProperties", 
"connectorProperties")) {
+
+            private static final long serialVersionUID = -5861786415855103549L;
+
+            @Override
+            public Panel getPanel(final String panelId) {
+                final ResourceConnConfPanel panel = new 
ResourceConnConfPanel(panelId, resourceTO, createFlag);
+                MetaDataRoleAuthorizationStrategy.authorize(panel, ENABLE, 
Entitlement.CONNECTOR_READ);
+                return panel;
+            }
+        });
         //--------------------------------
 
         //--------------------------------
         // Resource security panel
         //--------------------------------
-        form.add(new ResourceSecurityPanel("security", resourceTO));
-        //--------------------------------
-
-        AjaxButton submit = new IndicatingAjaxButton(APPLY, new 
ResourceModel(SUBMIT, SUBMIT)) {
+        tabs.add(new AbstractTab(new ResourceModel("security", "security")) {
 
-            private static final long serialVersionUID = -958724007591692537L;
+            private static final long serialVersionUID = -5861786415855103549L;
 
             @Override
-            protected void onSubmit(final AjaxRequestTarget target, final 
Form<?> form) {
-                final ResourceTO resourceTO = (ResourceTO) 
form.getDefaultModelObject();
-
-                boolean connObjectKeyError = false;
-
-                final Collection<ProvisionTO> provisions = new 
ArrayList<>(resourceTO.getProvisions());
-
-                for (ProvisionTO provision : provisions) {
-                    if (provision != null) {
-                        if (provision.getMapping() == null || 
provision.getMapping().getItems().isEmpty()) {
-                            resourceTO.getProvisions().remove(provision);
-                        } else {
-                            int uConnObjectKeyCount = 
CollectionUtils.countMatches(
-                                    provision.getMapping().getItems(), new 
Predicate<MappingItemTO>() {
-
-                                        @Override
-                                        public boolean evaluate(final 
MappingItemTO item) {
-                                            return item.isConnObjectKey();
-                                        }
-                                    });
-
-                            connObjectKeyError = uConnObjectKeyCount != 1;
-                        }
-                    }
-                }
-
-                if (connObjectKeyError) {
-                    error(getString("connObjectKeyValidation"));
-                    feedbackPanel.refresh(target);
-                } else {
-                    try {
-                        if (createFlag) {
-                            resourceRestClient.create(resourceTO);
-                            send(pageRef.getPage(), Broadcast.BREADTH, new 
CreateEvent(
-                                    resourceTO.getKey(),
-                                    resourceTO.getKey(),
-                                    TopologyNode.Kind.RESOURCE,
-                                    resourceTO.getConnector(),
-                                    target));
-                        } else {
-                            resourceRestClient.update(resourceTO);
-                        }
-
-                        if (pageRef.getPage() instanceof AbstractBasePage) {
-                            ((AbstractBasePage) 
pageRef.getPage()).setModalResult(true);
-                        }
-                        window.close(target);
-                    } catch (Exception e) {
-                        LOG.error("Failure managing resource {}", resourceTO, 
e);
-                        error(getString(Constants.ERROR) + ": " + 
e.getMessage());
-                        feedbackPanel.refresh(target);
-                    }
-                }
+            public Panel getPanel(final String panelId) {
+                return new ResourceSecurityPanel(panelId, resourceTO);
             }
+        });
+        //--------------------------------
+    }
 
-            @Override
-            protected void onError(final AjaxRequestTarget target, final 
Form<?> form) {
-                feedbackPanel.refresh(target);
-            }
-        };
-
-        form.add(submit);
-        form.setDefaultButton(submit);
+    @Override
+    public void onError(final AjaxRequestTarget target, final Form<?> form) {
+        modal.getFeedbackPanel().refresh(target);
+    }
 
-        final AjaxButton cancel = new IndicatingAjaxButton(CANCEL, new 
ResourceModel(CANCEL)) {
+    @Override
+    public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+        final ResourceTO resourceTO = (ResourceTO) 
form.getDefaultModelObject();
 
-            private static final long serialVersionUID = -958724007591692537L;
+        boolean connObjectKeyError = false;
 
-            @Override
-            protected void onSubmit(final AjaxRequestTarget target, final 
Form<?> form) {
-                window.close(target);
-            }
+        final Collection<ProvisionTO> provisions = new 
ArrayList<>(resourceTO.getProvisions());
 
-            @Override
-            protected void onError(final AjaxRequestTarget target, final 
Form<?> form) {
-            }
-        };
+        for (ProvisionTO provision : provisions) {
+            if (provision != null) {
+                if (provision.getMapping() == null || 
provision.getMapping().getItems().isEmpty()) {
+                    resourceTO.getProvisions().remove(provision);
+                } else {
+                    int uConnObjectKeyCount = CollectionUtils.countMatches(
+                            provision.getMapping().getItems(), new 
Predicate<MappingItemTO>() {
 
-        cancel.setDefaultFormProcessing(false);
-        form.add(cancel);
+                                @Override
+                                public boolean evaluate(final MappingItemTO 
item) {
+                                    return item.isConnObjectKey();
+                                }
+                            });
 
-        add(form);
+                    connObjectKeyError = uConnObjectKeyCount != 1;
+                }
+            }
+        }
+
+        if (connObjectKeyError) {
+            error(getString("connObjectKeyValidation"));
+            modal.getFeedbackPanel().refresh(target);
+        } else {
+            try {
+                if (createFlag) {
+                    resourceRestClient.create(resourceTO);
+                    send(pageRef.getPage(), Broadcast.BREADTH, new CreateEvent(
+                            resourceTO.getKey(),
+                            resourceTO.getKey(),
+                            TopologyNode.Kind.RESOURCE,
+                            resourceTO.getConnector(),
+                            target));
+                } else {
+                    resourceRestClient.update(resourceTO);
+                }
 
-        MetaDataRoleAuthorizationStrategy.authorize(
-                submit, ENABLE, createFlag ? Entitlement.RESOURCE_CREATE : 
Entitlement.RESOURCE_UPDATE);
+                if (pageRef.getPage() instanceof AbstractBasePage) {
+                    ((AbstractBasePage) 
pageRef.getPage()).setModalResult(true);
+                }
+                modal.close(target);
+            } catch (Exception e) {
+                LOG.error("Failure managing resource {}", resourceTO, e);
+                error(getString(Constants.ERROR) + ": " + e.getMessage());
+                modal.getFeedbackPanel().refresh(target);
+            }
+        }
     }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e93ca7/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceSecurityPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceSecurityPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceSecurityPanel.java
index a0a1ddc..2be0d95 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceSecurityPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceSecurityPanel.java
@@ -53,6 +53,11 @@ public class ResourceSecurityPanel extends Panel {
 
         super(id);
 
+        final WebMarkupContainer container = new 
WebMarkupContainer("container");
+        container.setOutputMarkupId(true);
+        container.setRenderBodyOnly(true);
+        add(container);
+
         setOutputMarkupId(true);
 
         passwordPolicies = new LoadableDetachableModel<Map<Long, String>>() {
@@ -97,11 +102,6 @@ public class ResourceSecurityPanel extends Panel {
             }
         };
 
-        final WebMarkupContainer securityContainer = new 
WebMarkupContainer("security");
-
-        securityContainer.setOutputMarkupId(true);
-        add(securityContainer);
-
         // -------------------------------
         // Password policy specification
         // -------------------------------
@@ -115,7 +115,7 @@ public class ResourceSecurityPanel extends Panel {
 
         ((DropDownChoice<?>) passwordPolicy.getField()).setNullValid(true);
 
-        securityContainer.add(passwordPolicy);
+        container.add(passwordPolicy);
         // -------------------------------
 
         // -------------------------------
@@ -131,7 +131,7 @@ public class ResourceSecurityPanel extends Panel {
 
         ((DropDownChoice<?>) accountPolicy.getField()).setNullValid(true);
 
-        securityContainer.add(accountPolicy);
+        container.add(accountPolicy);
         // -------------------------------
 
         // -------------------------------
@@ -147,7 +147,7 @@ public class ResourceSecurityPanel extends Panel {
 
         ((DropDownChoice<?>) syncPolicy.getField()).setNullValid(true);
 
-        securityContainer.add(syncPolicy);
+        container.add(syncPolicy);
         // -------------------------------
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e93ca7/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
index 409a16b..8b2fa75 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java
@@ -29,8 +29,10 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.cxf.jaxrs.client.WebClient;
 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.panels.AbstractResourceModal.CreateEvent;
+import 
org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import 
org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
@@ -64,11 +66,7 @@ public class Topology extends BasePage {
 
     private final int origY = 2800;
 
-    private static final int RESOURCE_MODAL_WIN_HEIGHT = 700;
-
-    private static final int RESOURCE_MODAL_WIN_WIDTH = 1000;
-
-    private final ModalWindow modal;
+    private final BaseModal<Serializable> modal;
 
     private final WebMarkupContainer newlyCreatedContainer;
 
@@ -140,13 +138,24 @@ public class Topology extends BasePage {
     }
 
     public Topology() {
-        modal = new ModalWindow("modal");
+        modal = new BaseModal<>("modal");
         add(modal);
 
-        modal.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
-        modal.setInitialHeight(RESOURCE_MODAL_WIN_HEIGHT);
-        modal.setInitialWidth(RESOURCE_MODAL_WIN_WIDTH);
-        modal.setCookieName("resource-modal");
+        modal.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
+
+            private static final long serialVersionUID = 8804221891699487139L;
+
+            @Override
+            public void onClose(final AjaxRequestTarget target) {
+                modal.show(false);
+
+                if (isModalResult()) {
+                    info(getString(Constants.OPERATION_SUCCEEDED));
+                    feedbackPanel.refresh(target);
+                    setModalResult(false);
+                }
+            }
+        });
 
         add(new WebSocketBehavior());
 
@@ -509,7 +518,7 @@ public class Topology extends BasePage {
 
     private TopologyNodePanel topologyNodePanel(final String id, final 
TopologyNode node) {
 
-        final TopologyNodePanel panel = new TopologyNodePanel(id, node, 
getPageReference(), modal);
+        final TopologyNodePanel panel = new TopologyNodePanel(id, node, modal, 
getPageReference());
         panel.setMarkupId(String.valueOf(node.getKey()));
         panel.setOutputMarkupId(true);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e93ca7/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyNodePanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyNodePanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyNodePanel.java
index 7756a25..d3aa975 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyNodePanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyNodePanel.java
@@ -18,6 +18,9 @@
  */
 package org.apache.syncope.client.console.topology;
 
+import static org.apache.wicket.Component.ENABLE;
+
+import java.io.Serializable;
 import java.text.MessageFormat;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.commons.Constants;
@@ -27,19 +30,22 @@ import 
org.apache.syncope.client.console.panels.ResourceModal;
 import org.apache.syncope.client.console.rest.ConnectorRestClient;
 import org.apache.syncope.client.console.rest.ResourceRestClient;
 import 
org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxLink;
+import 
org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.IAjaxIndicatorAware;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
+import 
org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
 import org.apache.wicket.behavior.AttributeAppender;
-import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.panel.Fragment;
 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;
@@ -50,7 +56,7 @@ public class TopologyNodePanel extends Panel implements 
IAjaxIndicatorAware {
 
     protected static final Logger LOG = 
LoggerFactory.getLogger(TopologyNodePanel.class);
 
-    private final ModalWindow modal;
+    private final BaseModal<Serializable> modal;
 
     @SpringBean
     private ResourceRestClient resourceRestClient;
@@ -61,8 +67,8 @@ public class TopologyNodePanel extends Panel implements 
IAjaxIndicatorAware {
     public TopologyNodePanel(
             final String id,
             final TopologyNode node,
-            final PageReference pageRef,
-            final ModalWindow modal) {
+            final BaseModal<Serializable> modal,
+            final PageReference pageRef) {
         super(id);
 
         final String resourceName = node.getDisplayName().length() > 20
@@ -124,16 +130,24 @@ public class TopologyNodePanel extends Panel implements 
IAjaxIndicatorAware {
 
             @Override
             public void onClickInternal(final AjaxRequestTarget target) {
+                final ConnInstanceTO model = new ConnInstanceTO();
+                model.setLocation(node.getKey().toString());
+
+                modal.setFormModel(model);
+                target.add(modal.setContent(new ConnectorModal(modal, pageRef, 
model)));
+
+                modal.header(new 
Model<String>(MessageFormat.format(getString("connector.new"), node.getKey())));
 
-                final ConnInstanceTO connectorTO = new ConnInstanceTO();
-                connectorTO.setLocation(node.getKey().toString());
-                modal.setContent(new ConnectorModal(modal, pageRef, 
connectorTO));
-                
modal.setTitle(MessageFormat.format(getString("connector.new"), node.getKey()));
-                modal.show(target);
+                MetaDataRoleAuthorizationStrategy.
+                        authorize(modal.addSumbitButton(), ENABLE, 
Entitlement.CONNECTOR_CREATE);
+
+                modal.show(true);
             }
         };
         fragment.add(create);
 
+        MetaDataRoleAuthorizationStrategy.authorize(create, ENABLE, 
Entitlement.CONNECTOR_CREATE);
+
         return fragment;
     }
 
@@ -158,40 +172,56 @@ public class TopologyNodePanel extends Panel implements 
IAjaxIndicatorAware {
         };
         fragment.add(delete);
 
+        MetaDataRoleAuthorizationStrategy.authorize(delete, ENABLE, 
Entitlement.CONNECTOR_DELETE);
+
         final AjaxLink<String> create = new 
ClearIndicatingAjaxLink<String>("create", pageRef) {
 
             private static final long serialVersionUID = 3776750333491622263L;
 
             @Override
             public void onClickInternal(final AjaxRequestTarget target) {
-                final ResourceTO resourceTO = new ResourceTO();
-                resourceTO.setConnector(Long.class.cast(node.getKey()));
-                resourceTO.setConnectorDisplayName(node.getDisplayName());
-                modal.setContent(new ResourceModal(modal, pageRef, resourceTO, 
true));
-                modal.setTitle(getString("resource.new"));
-                modal.show(target);
+                final ResourceTO model = new ResourceTO();
+                model.setConnector(Long.class.cast(node.getKey()));
+                model.setConnectorDisplayName(node.getDisplayName());
+
+                modal.setFormModel(model);
+                target.add(modal.setContent(new ResourceModal(modal, pageRef, 
model, true)));
+
+                modal.header(new 
Model<String>(MessageFormat.format(getString("resource.new"), node.getKey())));
+
+                MetaDataRoleAuthorizationStrategy.
+                        authorize(modal.addSumbitButton(), ENABLE, 
Entitlement.RESOURCE_CREATE);
+
+                modal.show(true);
             }
         };
         fragment.add(create);
 
+        MetaDataRoleAuthorizationStrategy.authorize(create, ENABLE, 
Entitlement.RESOURCE_CREATE);
+
         final AjaxLink<String> edit = new 
ClearIndicatingAjaxLink<String>("edit", pageRef) {
 
             private static final long serialVersionUID = 3776750333491622263L;
 
             @Override
             public void onClickInternal(final AjaxRequestTarget target) {
+                final ConnInstanceTO model = 
connectorRestClient.read(Long.class.cast(node.getKey()));
+
+                modal.setFormModel(model);
+                target.add(modal.setContent(new ConnectorModal(modal, pageRef, 
model)));
+
+                modal.header(new 
Model<String>(MessageFormat.format(getString("connector.edit"), 
node.getKey())));
 
-                modal.setContent(new ConnectorModal(
-                        modal,
-                        pageRef,
-                        
connectorRestClient.read(Long.class.cast(node.getKey()))));
+                MetaDataRoleAuthorizationStrategy.
+                        authorize(modal.addSumbitButton(), ENABLE, 
Entitlement.CONNECTOR_UPDATE);
 
-                
modal.setTitle(MessageFormat.format(getString("connector.edit"), 
node.getKey()));
-                modal.show(target);
+                modal.show(true);
             }
         };
         fragment.add(edit);
 
+        MetaDataRoleAuthorizationStrategy.authorize(edit, ENABLE, 
Entitlement.CONNECTOR_UPDATE);
+
         return fragment;
     }
 
@@ -216,6 +246,8 @@ public class TopologyNodePanel extends Panel implements 
IAjaxIndicatorAware {
         };
         fragment.add(delete);
 
+        MetaDataRoleAuthorizationStrategy.authorize(delete, ENABLE, 
Entitlement.RESOURCE_DELETE);
+
         final AjaxLink<String> edit = new 
ClearIndicatingAjaxLink<String>("edit", pageRef) {
 
             private static final long serialVersionUID = 3776750333491622263L;
@@ -223,18 +255,23 @@ public class TopologyNodePanel extends Panel implements 
IAjaxIndicatorAware {
             @Override
             public void onClickInternal(final AjaxRequestTarget target) {
 
-                modal.setContent(new ResourceModal(
-                        modal,
-                        pageRef,
-                        resourceRestClient.read(node.getKey().toString()),
-                        false));
+                final ResourceTO model = 
resourceRestClient.read(node.getKey().toString());
 
-                
modal.setTitle(MessageFormat.format(getString("resource.edit"), node.getKey()));
-                modal.show(target);
+                modal.setFormModel(model);
+                target.add(modal.setContent(new ResourceModal(modal, pageRef, 
model, false)));
+
+                modal.header(new 
Model<String>(MessageFormat.format(getString("resource.edit"), node.getKey())));
+
+                MetaDataRoleAuthorizationStrategy.
+                        authorize(modal.addSumbitButton(), ENABLE, 
Entitlement.RESOURCE_UPDATE);
+
+                modal.show(true);
             }
         };
         fragment.add(edit);
 
+        MetaDataRoleAuthorizationStrategy.authorize(edit, ENABLE, 
Entitlement.RESOURCE_UPDATE);
+
         return fragment;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e93ca7/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
index e67daac..2d26c08 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
@@ -78,7 +78,7 @@ public class BaseModal<T extends Serializable> extends 
Modal<T> {
         form = new Form<T>(FORM);
         add(form);
 
-        content = new AbstractModalPanel(this) {
+        content = new AbstractModalPanel(this, null) {
 
             private static final long serialVersionUID = 1L;
 
@@ -153,7 +153,7 @@ public class BaseModal<T extends Serializable> extends 
Modal<T> {
         }
     }
 
-    public void addSumbitButton() {
+    public PrimaryModalButton addSumbitButton() {
 
         final PrimaryModalButton submit = new PrimaryModalButton(SUBMIT, 
SUBMIT, form) {
 
@@ -179,6 +179,8 @@ public class BaseModal<T extends Serializable> extends 
Modal<T> {
             submitButton.replaceWith(submit);
             submitButton = submit;
         }
+
+        return submit;
     }
 
     @Override
@@ -196,4 +198,33 @@ public class BaseModal<T extends Serializable> extends 
Modal<T> {
             }
         }.setOutputMarkupId(true));
     }
+
+    /**
+     * Generic modal event.
+     */
+    public static class ModalEvent {
+
+        /**
+         * Request target.
+         */
+        private final AjaxRequestTarget target;
+
+        /**
+         * Constructor.
+         *
+         * @param target request target.
+         */
+        public ModalEvent(final AjaxRequestTarget target) {
+            this.target = target;
+        }
+
+        /**
+         * Target getter.
+         *
+         * @return request target.
+         */
+        public AjaxRequestTarget getTarget() {
+            return target;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e93ca7/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractFieldPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractFieldPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractFieldPanel.java
index 41643ea..165f20d 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractFieldPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractFieldPanel.java
@@ -18,8 +18,11 @@
  */
 package org.apache.syncope.client.console.wicket.markup.html.form;
 
+import org.apache.wicket.Component;
+import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.ResourceModel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -32,8 +35,32 @@ public abstract class AbstractFieldPanel<T> extends Panel {
 
     private static final long serialVersionUID = 5958017546318855690L;
 
-    public AbstractFieldPanel(final String id, final IModel<T> model) {
+    protected final String name;
+
+    public AbstractFieldPanel(final String id, final String name, final 
IModel<T> model) {
         super(id, model);
+        this.name = name;
+
+        addLabel();
+        setOutputMarkupId(true);
+    }
+
+    public final AbstractFieldPanel<T> addLabel() {
+        return addLabel(this.name);
+    }
+
+    public final AbstractFieldPanel<T> addLabel(final String name) {
+        addOrReplace(new Label("field-label", new ResourceModel(name, name)));
+        return this;
+    }
+
+    public AbstractFieldPanel<T> hideLabel() {
+        final Component label = get("field-label");
+
+        if (label != null) {
+            label.setVisible(false);
+        }
+        return this;
     }
 
     public abstract AbstractFieldPanel<T> setModelObject(T object);

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e93ca7/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxCheckBoxPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxCheckBoxPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxCheckBoxPanel.java
index ff64fbe..bd1cd0d 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxCheckBoxPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxCheckBoxPanel.java
@@ -23,10 +23,12 @@ import java.util.List;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.CheckBox;
 import org.apache.wicket.markup.html.list.ListItem;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
 
 public class AjaxCheckBoxPanel extends FieldPanel<Boolean> {
 
@@ -54,6 +56,8 @@ public class AjaxCheckBoxPanel extends FieldPanel<Boolean> {
                 }
             });
         }
+
+        add(new Label("label", new ResourceModel(name, name)));
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e93ca7/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDropDownChoicePanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDropDownChoicePanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDropDownChoicePanel.java
index ae3a01f..daba6e9 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDropDownChoicePanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDropDownChoicePanel.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.wicket.markup.html.form;
 
+import 
de.agilecoders.wicket.extensions.markup.html.bootstrap.form.select.BootstrapSelect;
 import java.io.Serializable;
 import java.util.Collections;
 import java.util.List;
@@ -41,9 +42,11 @@ public class AjaxDropDownChoicePanel<T extends Serializable> 
extends FieldPanel<
     public AjaxDropDownChoicePanel(
             final String id, final String name, final IModel<T> model, final 
boolean enableOnBlur) {
 
-        super(id, model);
+        super(id, name, model);
+
+        field = new BootstrapSelect<>(
+                "dropDownChoiceField", model, Collections.<T>emptyList(), new 
ChoiceRenderer<T>());
 
-        field = new DropDownChoice<>("dropDownChoiceField", model, 
Collections.<T>emptyList(), new ChoiceRenderer<T>());
         add(field.setLabel(new Model<>(name)).setOutputMarkupId(true));
 
         if (enableOnBlur) {
@@ -61,19 +64,24 @@ public class AjaxDropDownChoicePanel<T extends 
Serializable> extends FieldPanel<
 
     @SuppressWarnings("unchecked")
     public AjaxDropDownChoicePanel<T> setChoiceRenderer(final 
IChoiceRenderer<T> renderer) {
-        ((DropDownChoice) field).setChoiceRenderer(renderer);
+        DropDownChoice.class.cast(field).setChoiceRenderer(renderer);
         return this;
     }
 
     @SuppressWarnings("unchecked")
     public AjaxDropDownChoicePanel<T> setChoices(final List<T> choices) {
-        ((DropDownChoice) field).setChoices(choices);
+        DropDownChoice.class.cast(field).setChoices(choices);
         return this;
     }
 
     @SuppressWarnings("unchecked")
     public AjaxDropDownChoicePanel<T> setChoices(final IModel<? extends List<? 
extends T>> choices) {
-        ((DropDownChoice) field).setChoices(choices);
+        DropDownChoice.class.cast(field).setChoices(choices);
+        return this;
+    }
+
+    public AjaxDropDownChoicePanel<T> setNullValid(final boolean validity) {
+        DropDownChoice.class.cast(field).setNullValid(validity);
         return this;
     }
 
@@ -81,8 +89,8 @@ public class AjaxDropDownChoicePanel<T extends Serializable> 
extends FieldPanel<
     @SuppressWarnings("unchecked")
     public FieldPanel<T> clone() {
         final AjaxDropDownChoicePanel<T> panel = (AjaxDropDownChoicePanel<T>) 
super.clone();
-        panel.setChoiceRenderer(((DropDownChoice) field).getChoiceRenderer());
-        panel.setChoices(((DropDownChoice) field).getChoices());
+        
panel.setChoiceRenderer(DropDownChoice.class.cast(field).getChoiceRenderer());
+        panel.setChoices(DropDownChoice.class.cast(field).getChoices());
         return panel;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b2e93ca7/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxPalettePanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxPalettePanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxPalettePanel.java
index 932948b..97866e3 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxPalettePanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxPalettePanel.java
@@ -44,7 +44,7 @@ public class AjaxPalettePanel<T> extends 
AbstractFieldPanel<List<T>> {
     public AjaxPalettePanel(final String id, final IModel<List<T>> model, 
final ListModel<T> choices,
             final IChoiceRenderer<T> renderer, final boolean allowOrder, final 
boolean allowMoveAll) {
 
-        super(id, model);
+        super(id, id, model);
 
         this.palette = createPalette(model, choices, renderer, allowOrder, 
allowMoveAll);
         add(palette.setOutputMarkupId(true));

Reply via email to