http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/confirmpasswordreset.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/confirmpasswordreset.html
 
b/client/enduser/src/main/resources/META-INF/resources/app/views/confirmpasswordreset.html
index 70a94a9..8d165f3 100644
--- 
a/client/enduser/src/main/resources/META-INF/resources/app/views/confirmpasswordreset.html
+++ 
b/client/enduser/src/main/resources/META-INF/resources/app/views/confirmpasswordreset.html
@@ -17,25 +17,26 @@ specific language governing permissions and limitations
 under the License.
 -->
 <div ng-cloak class="container">
-  <div ng-controller="UserController" style="box-sizing: border-box; ">
+  <div ng-controller="UserController">
 
-    <div id="form-container" class="col-md-6 col-md-offset-3" 
style="box-sizing: border-box; background-color: #F7F7F7;">
+    <div id="form-container" class="col-md-6 col-md-offset-3">
 
       <div>
-        <div class="page-header" style="text-align: left; font-weight: 700;">
+        <div class="page-header">
           <span>{{'CONFIRM_PASSWORD_RESET'| translate}}</span>
         </div>
         <div class="breadcrumb-header text-center">
 
           <div class="row">            
-            <div id="status-buttons" class="btn-group btn-breadcrumb">
-              <a href="#/self" class="btn btn-default"><i class="glyphicon 
glyphicon-home"></i></a>
+            <div id="status-buttons" class="btn-group btn-breadcrumb col-md-12 
col-md-offset-3">
+              <a href="#/self" class="btn btn-secondary btn-default"><i 
class="fa fa-home"></i></a>
               <!--add class breadcrumb-disabled-link to buttons to prevent 
click-->
-              <a ui-sref-active="active" class="btn btn-default">Password 
reset</a>
+              <a ui-sref-active="active" class="btn btn-secondary 
btn-default">Password reset</a>
             </div>
           </div>
         </div>
-        <form class="signup-form" name="confirmPasswordResetForm" 
ng-submit="confirmPasswordReset(user, $event)" novalidate>
+        <form class="signup-form" name="confirmPasswordResetForm" 
ng-submit="confirmPasswordReset(user, $event)" 
+              novalidate>
 
           <div id="form-views" ui-view>
             <div id="attribute" class="form-group">
@@ -45,7 +46,8 @@ under the License.
 
             <div id="attribute" class="form-group">
               <label for="confirmPassword">{{'CONFIRM_PASSWORD'| 
translate}}</label>
-              <input name="password" type="password" class="form-control" 
equals="user.password" ng-model="confirmPassword.value"
+              <input name="password" type="password" class="form-control" 
equals="user.password" 
+                     ng-model="confirmPassword.value"
                      placeholder="confirm password" validate="true">
               <validation-message name="password"/>
             </div>
@@ -53,16 +55,18 @@ under the License.
             <div id="attribute" class="form-group">
               <div class="suggestions">
                 {{'PASSWORD_STRENGTH'| translate}}:
-                <span ng-if="passStrength < 50">{{'INSECURE' | 
translate}}</span>
+                <span ng-if="passStrength < 50">{{'INSECURE'| 
translate}}</span>
                 <span ng-if="passStrength >= 50 && passStrength <= 
82">{{'ALMOSTSECURE'| translate}}</span>
                 <span ng-if="passStrength > 82">{{'VERYGOOD'| 
translate}}</span>
               </div>
-              <div ng-password-strength="user.password" 
strength="passStrength" inner-class="progress-bar" 
inner-class-prefix="progress-bar-">
+              <div ng-password-strength="user.password" 
strength="passStrength" inner-class="progress-bar" 
+                   inner-class-prefix="progress-bar-">
               </div>
             </div>
             <div id="attribute" class="form-group row">
-              <button id="resetpassword" type="submit" class="btn btn-default 
pull-right">{{'SUBMIT'| translate}}</button>
-              <div class="pull-left">
+              <button id="resetpassword" type="submit" 
+                      class="btn btn-secondary btn-default 
float-right">{{'SUBMIT'| translate}}</button>
+              <div class="float-left">
                 <a id="cancel" href="#/self" class="btn 
btn-danger">{{'CANCEL'| translate}}</a>
               </div>
             </div>

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicDerivedAttributes.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicDerivedAttributes.html
 
b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicDerivedAttributes.html
index c64fcbb..714f7c2 100644
--- 
a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicDerivedAttributes.html
+++ 
b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicDerivedAttributes.html
@@ -17,30 +17,35 @@ specific language governing permissions and limitations
 under the License.
 -->
 <div ng-repeat="groupSchema in dynamicForm.groupSchemas">
-  <uib-accordion ng-if="getByGroup(groupSchema).length > 0">
+  <uib-accordion ng-if="getByGroup(groupSchema).length">
     <div uib-accordion-group heading="{{groupSchema| translate}}"
          ng-init="status = {isOpen: (groupSchema == 'own')}" 
is-open="status.isOpen"
-         class="breadcrumb-header">
+         class="breadcrumb-header panel panel-default">
+
       <div id="attribute" class="form-group" ng-repeat="derSchema in 
getByGroup(groupSchema) track by $index">
-        <label for="derSchema.key">{{derSchema.simpleKey| translate}} <span 
ng-if="derSchema.mandatoryCondition === 'true'">*</span></label>
+        <label for="derSchema.key">{{derSchema.simpleKey| translate}} 
+          <span ng-if="derSchema.mandatoryCondition === 'true'">*</span>
+        </label>
         <div ng-if="!derSchema.multivalue">
           <dynamic-derived-attribute schema="derSchema" user="user" 
index="0"></dynamic-derived-attribute>
           <validation-message name="{{derSchema.key| translate}}"/>
         </div>
+
         <div ng-if="derSchema.multivalue">
           <div ng-repeat="field in 
dynamicForm.attributeTable[derSchema.key].fields track by $index" 
                
ng-model='dynamicForm.attributeTable[derSchema.key].fields[$index]'>
             <dynamic-derived-attribute schema="derSchema" user="user" 
index="$index"></dynamic-derived-attribute>
             <span>
-              <button class="btn btn-default btn-sm minus" ng-if="$index > 0" 
type="button" 
+              <button class="btn btn-secondary btn-default btn-sm minus" 
ng-if="$index > 0" type="button" 
                       ng-click="removeAttributeField(derSchema.key, $index)">
-                <i class="glyphicon glyphicon-minus" title="Remove value"></i>
+                <i class="fa fa-minus" title="Remove value"></i>
               </button>
             </span>
           </div>
           <span>
-            <button class="btn btn-default btn-sm" type="button" 
ng-click="addAttributeField(derSchema.key)">
-              <i class="glyphicon glyphicon-plus" title="Add value"></i>
+            <button class="btn btn-secondary btn-default btn-sm" type="button" 
+                    ng-click="addAttributeField(derSchema.key)">
+              <i class="fa fa-plus" title="Add value"></i>
             </button>
           </span>
         </div>

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttribute.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttribute.html
 
b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttribute.html
index e7b5bcc..c6b5042 100644
--- 
a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttribute.html
+++ 
b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttribute.html
@@ -26,7 +26,7 @@ under the License.
 
   <div ng-switch-when="Encrypted" class="input-group input-group-sm">
     <span class="input-group-btn" ng-disabled="schema.readonly || 
customReadonly(schema.key)">  
-      <button type="button" class="btn btn-default btn-flat"
+      <button type="button" class="btn btn-default btn-sm btn-flat"
               confirm="{{'CONFIRM_REMOVE'| translate}}"
               onclick="var pwd = $(this).parent().next('input');
                   if (pwd.is('[readonly]')) {
@@ -49,9 +49,10 @@ under the License.
     <input class="form-control" type="password" readonly="true"
            ng-model="user.plainAttrs[schema.key].values[index]"
            ng-required="{{schema.mandatoryCondition}}" validate="true"
-           ng-disabled="schema.readonly || customReadonly(schema.key)" 
ng-init="initAttribute(schema, index)" name="{{schema.key}}"/>
+           ng-disabled="schema.readonly || customReadonly(schema.key)" 
ng-init="initAttribute(schema, index)" 
+           name="{{schema.key}}"/>
     <span class="input-group-btn">  
-      <button type="button" class="btn btn-default btn-flat"
+      <button type="button" class="btn btn-default btn-sm btn-flat"
               onmousedown="var pwd = $(this).parent().prev('input');
                   if (!pwd.is('[readonly]')) {
                     pwd.attr('type', 'text');
@@ -63,87 +64,85 @@ under the License.
                     $(this).children().attr('class', 'fa fa-eye');
                   }"
               >
-  <i class="fa fa-eye"></i>
-</button>
-</span>
-</div>
+        <i class="fa fa-eye"></i>
+      </button>
+    </span>
+  </div>
 
-<div ng-switch-when="Boolean">
-  <input type="checkbox" ng-model="user.plainAttrs[schema.key].values[index]" 
+  <div ng-switch-when="Boolean">
+    <input type="checkbox" 
ng-model="user.plainAttrs[schema.key].values[index]" 
            ng-true-value="'true'" 
            ng-false-value="'false'" 
            ng-required="{{schema.mandatoryCondition}}"
            ng-disabled="schema.readonly || customReadonly(schema.key)"
            ng-init="initAttribute(schema, index)" />
-</div>
+  </div>
 
-<input ng-switch-when="Long" class="form-control"
-           type="number"
-           ng-model="user.plainAttrs[schema.key].values[index]" 
-           ng-required="{{schema.mandatoryCondition}}"
+  <input ng-switch-when="Long" class="form-control"
+         type="number"
+         ng-model="user.plainAttrs[schema.key].values[index]" 
+         ng-required="{{schema.mandatoryCondition}}"
+         ng-disabled="schema.readonly || customReadonly(schema.key)"
+         validate="true"
+         ng-init="initAttribute(schema, index)"
+         name="{{schema.key}}"/>
+
+  <input ng-switch-when="Double" class="form-control" type="number" 
ng-model="user.plainAttrs[schema.key].values[index]"
+         ng-required="{{schema.mandatoryCondition}}" validate="true"
+         ng-disabled="schema.readonly || customReadonly(schema.key)"
+         ng-init="initAttribute(schema, index)" name="{{schema.key}}"/>
+
+  <div ng-switch-when="Date" id="date">
+    <input type="text" class="dateTimePicker"
+           kendo-date-time-picker
+           ng-show="!isDateOnly"
+           ng-model="extendedDate"
+           ng-required="{{schema.mandatoryCondition}}" close-text="Close"
+           ng-init="initAttribute(schema, index)"
+           ng-change="bindDateToModel(selectedDate, extendedDate)"
            ng-disabled="schema.readonly || customReadonly(schema.key)"
-           validate="true"
+           k-ng-model="selectedDate"
+           data-k-format="languageFormat"
+           />
+    <input type="text" class="datePicker"
+           kendo-date-picker
+           ng-show="isDateOnly"
+           ng-model="extendedDate"
+           ng-required="{{schema.mandatoryCondition}}" close-text="Close"
            ng-init="initAttribute(schema, index)"
-           name="{{schema.key}}"/>
-
-<input ng-switch-when="Double" class="form-control" type="number" 
ng-model="user.plainAttrs[schema.key].values[index]"
-           ng-required="{{schema.mandatoryCondition}}" validate="true"
+           ng-change="bindDateToModel(selectedDate, extendedDate)"
            ng-disabled="schema.readonly || customReadonly(schema.key)"
-           ng-init="initAttribute(schema, index)" name="{{schema.key}}"/>
+           k-ng-model="selectedDate"
+           data-k-format="languageFormat"
+           />
+  </div>
 
-<div ng-switch-when="Date" id="date">
-<input type="text" class="dateTimePicker"
-       id="dateTimePicker"
-       kendo-date-time-picker
-       ng-show="!isDateOnly"
-       ng-model="extendedDate"
-       ng-required="{{schema.mandatoryCondition}}" close-text="Close"
-       ng-init="initAttribute(schema, index)"
-       ng-change="bindDateToModel(selectedDate, extendedDate)"
-ng-disabled="schema.readonly || customReadonly(schema.key)"
-k-ng-model="selectedDate"
-data-k-format="languageFormat"
-/>
-<input type="text" class="datePicker"
-       id="datePicker"
-       kendo-date-picker
-       ng-show="isDateOnly"
-       ng-model="extendedDate"
-       ng-required="{{schema.mandatoryCondition}}" close-text="Close"
-       ng-init="initAttribute(schema, index)"
-       ng-change="bindDateToModel(selectedDate, extendedDate)"
-       ng-disabled="schema.readonly || customReadonly(schema.key)"
-       k-ng-model="selectedDate"
-       data-k-format="languageFormat"
-             />
-    </div>
+  <div ng-switch-when="Enum" ng-init="initAttribute(schema, index)">
+    <select class="form-control custom-select"
+            ng-model="user.plainAttrs[schema.key].values[index]"
+            ng-required="{{schema.mandatoryCondition}}"
+            ng-disabled="schema.readonly || customReadonly(schema.key)">
+      <option ng-repeat="value in enumerationValues" value="{{value}}">
+        {{enumerationKeys[$index]|| value}}
+      </option>
+    </select>
+  </div>
 
-    <div ng-switch-when="Enum" ng-init="initAttribute(schema, index)">
-      <select class="form-control"
-              ng-model="user.plainAttrs[schema.key].values[index]"
-              ng-required="{{schema.mandatoryCondition}}"
-              ng-disabled="schema.readonly || customReadonly(schema.key)">
-        <option ng-repeat="value in enumerationValues" value="{{value}}">
-          {{enumerationKeys[$index]|| value}}
-        </option>
-      </select>
-    </div>
+  <div ng-switch-when="Binary"
+       ng-disabled="schema.readonly || customReadonly(schema.key)"
+       ng-init="initAttribute(schema, index)">
+    <input file-input type="file" id="fileInput" name="fileInput"/>
+    <button type="button" title="Download file" class="fileButton btn 
btn-default btn-sm" ng-click="download()">
+      <i class="fa fa-arrow-circle-down" ></i>
+    </button>
+  </div>
 
-    <div ng-switch-when="Binary"
+  <input ng-switch-default class="form-control" type="text"
+         ng-model="user.plainAttrs[schema.key].values[index]"
+         ng-required="{{schema.mandatoryCondition}}" 
          ng-disabled="schema.readonly || customReadonly(schema.key)"
-         ng-init="initAttribute(schema, index)">
-      <input file-input type="file" id="fileInput" name="fileInput"/>
-      <button type="button" title="Download file" class="fileButton btn 
btn-default btn-sm" ng-click="download()">
-        <i class="glyphicon glyphicon-download" ></i>
-      </button>
-    </div>
-
-    <input ng-switch-default class="form-control" type="text"
-           ng-model="user.plainAttrs[schema.key].values[index]"
-           ng-required="{{schema.mandatoryCondition}}" 
-           ng-disabled="schema.readonly || customReadonly(schema.key)"
-           ng-init="initAttribute(schema, index)"/>
-  </div>
+         ng-init="initAttribute(schema, index)"/>
+</div>
 
 
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttributes.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttributes.html
 
b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttributes.html
index 9932f8b..dd12581 100644
--- 
a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttributes.html
+++ 
b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttributes.html
@@ -17,28 +17,30 @@ specific language governing permissions and limitations
 under the License.
 -->
 <div ng-repeat="groupSchema in dynamicForm.groupSchemas">
-  <uib-accordion ng-if="getByGroup(groupSchema).length > 0">
+  <uib-accordion ng-if="getByGroup(groupSchema).length">
     <div uib-accordion-group heading="{{groupSchema| translate}}"
          ng-init="status = {isOpen: (groupSchema == 'own')}" 
is-open="status.isOpen"
-         class="breadcrumb-header">
+         class="breadcrumb-header panel panel-default">
 
       <div id="attribute" class="form-group" ng-repeat="plainSchema in 
getByGroup(groupSchema) track by $index">
-        <label for="plainSchema.key">{{plainSchema.simpleKey| translate}} 
<span ng-if="plainSchema.mandatoryCondition === 'true'">*</span></label>
+        <label for="plainSchema.key">{{plainSchema.simpleKey| translate}} 
+          <span ng-if="plainSchema.mandatoryCondition === 'true'">*</span>
+        </label>
         <div ng-if="!plainSchema.multivalue">
           <dynamic-plain-attribute schema="plainSchema" user="user" 
index="0"></dynamic-plain-attribute>
           <validation-message name="{{plainSchema.key| translate}}"/>
         </div>
-        
+
         <div ng-if="plainSchema.multivalue">
           <div ng-repeat="field in 
dynamicForm.attributeTable[plainSchema.key].fields track by $index" 
                
ng-model='dynamicForm.attributeTable[plainSchema.key].fields[$index]'>
             <div class="multivalue">
               <button class="btn btn-default btn-sm" type="button" 
ng-click="addAttributeField(plainSchema.key)">
-                <i class="glyphicon glyphicon-plus" title="Add value"></i>
+                <i class="fa fa-plus" title="Add value"></i>
               </button>
               <button class="btn btn-default btn-sm minus" ng-if="$index > 0" 
type="button" 
                       ng-click="removeAttributeField(plainSchema.key, $index)">
-                <i class="glyphicon glyphicon-minus" title="Remove value"></i>
+                <i class="fa fa-minus" title="Remove value"></i>
               </button>
               <dynamic-plain-attribute schema="plainSchema" user="user" 
index="$index"></dynamic-plain-attribute>
             </div>

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicVirtualAttributes.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicVirtualAttributes.html
 
b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicVirtualAttributes.html
index 4dcca94..5dc7ebe 100644
--- 
a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicVirtualAttributes.html
+++ 
b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicVirtualAttributes.html
@@ -17,26 +17,30 @@ specific language governing permissions and limitations
 under the License.
 -->
 <div  ng-repeat="groupSchema in dynamicForm.groupSchemas">
-  <uib-accordion ng-if="getByGroup(groupSchema).length > 0">
+  <uib-accordion ng-if="getByGroup(groupSchema).length">
     <div uib-accordion-group heading="{{groupSchema| translate}}"
          ng-init="status = {isOpen: (groupSchema == 'own')}" 
is-open="status.isOpen"
-         class="breadcrumb-header">
+         class="breadcrumb-header panel panel-default">
+      
       <div id="attribute" class="form-group" ng-repeat="virSchema in 
getByGroup(groupSchema) track by $index">
-        <label for="virSchema.key">{{virSchema.simpleKey| translate}} <span 
ng-if="virSchema.mandatoryCondition === 'true'">*</span></label>
+        <label for="virSchema.key">{{virSchema.simpleKey| translate}} 
+          <span ng-if="virSchema.mandatoryCondition === 'true'">*</span>
+        </label>
         <div ng-if="!virSchema.multivalue">
           <dynamic-virtual-attribute schema="virSchema" user="user" 
index="0"></dynamic-virtual-attribute>
           <validation-message name="{{virSchema.key| translate}}"/>
         </div>
+        
         <div ng-if="virSchema.multivalue">
           <div ng-repeat="field in 
dynamicForm.attributeTable[virSchema.key].fields track by $index" 
                
ng-model='dynamicForm.attributeTable[virSchema.key].fields[$index]'>
             <div class="multivalue">
               <dynamic-virtual-attribute schema="virSchema" user="user" 
index="$index"></dynamic-virtual-attribute>
-              <button class="btn btn-default btn-sm minus" ng-if="$index > 0" 
type="button" 
+              <button class="btn btn-secondary btn-default btn-sm minus" 
ng-if="$index > 0" type="button" 
                       ng-click="removeAttributeField(virSchema.key, $index)">
-                <i class="glyphicon glyphicon-minus" title="Remove value"></i>
-              </button><button class="btn btn-default btn-sm" type="button" 
ng-click="addAttributeField(virSchema.key)">
-                <i class="glyphicon glyphicon-plus" title="Add value"></i>
+                <i class="fa fa-minus" title="Remove value"></i>
+              </button><button class="btn btn-secondary btn-default btn-sm" 
type="button" ng-click="addAttributeField(virSchema.key)">
+                <i class="fa fa-plus" title="Add value"></i>
               </button>
             </div>
           </div>

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/editUser.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/editUser.html 
b/client/enduser/src/main/resources/META-INF/resources/app/views/editUser.html
index b4ea868..3d0d013 100644
--- 
a/client/enduser/src/main/resources/META-INF/resources/app/views/editUser.html
+++ 
b/client/enduser/src/main/resources/META-INF/resources/app/views/editUser.html
@@ -17,34 +17,5 @@ specific language governing permissions and limitations
 under the License.
 -->
 <div ng-cloak class="container">
-  <div class="login-container" ng-controller="UserController" 
ng-init="initUser();" style="box-sizing: border-box; ">
-    <div id="form-container" class="col-md-6 col-md-offset-3" 
style="box-sizing: border-box; background-color: #F7F7F7;">
-      <div>
-        <div class="page-header" style="text-align: left; font-weight: 700;">  
        
-          <span ng-show="createMode">{{'NEWUSER'| translate}}</span>
-          <span ng-show="!createMode">{{'USER'| translate}} 
{{user.username}}</span>
-        </div>
-        <div class="breadcrumb-header text-center">
-          <!-- the links to our nested states using relative paths -->
-          <!-- add the active class if the state matches our ui-sref -->
-          <!--<div id="status-buttons" class="text-center">-->
-          <div class="row">
-            <div growl reference="2" inline="true"></div>              
-            <div id="status-buttons" class="btn-group btn-breadcrumb">
-              <a class="btn btn-default" ng-show="createMode" 
ng-click="logout()"><i class="glyphicon glyphicon-home"></i></a>
-              <a id="logout" class="btn btn-default" ng-show="!createMode" 
ng-click="logout()"><i class="glyphicon glyphicon-off"style="color:red"></i></a>
-              <!--add class breadcrumb-disabled-link to buttons to prevent 
click-->              
-              <a ng-repeat="(key, value) in wizard" ui-sref-active="active" 
ui-sref=".{{key}}" class="btn btn-default" 
-                 ng-class="createMode && !endReached ? 'disable-link' : 
''">{{key | translate}}</a>       
-            </div>
-          </div>
-        </div>
-        <form class="signup-form" name="userForm" ng-submit="saveUser(user)" 
novalidate>
-          <div id="form-views" ui-view >
-
-          </div>
-        </form>
-      </div>
-    </div>
-  </div>
+  <dynamic-template-item type="edit_user"/>
 </div>

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/mustchangepassword.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/mustchangepassword.html
 
b/client/enduser/src/main/resources/META-INF/resources/app/views/mustchangepassword.html
index 083f988..1245214 100644
--- 
a/client/enduser/src/main/resources/META-INF/resources/app/views/mustchangepassword.html
+++ 
b/client/enduser/src/main/resources/META-INF/resources/app/views/mustchangepassword.html
@@ -17,21 +17,23 @@ specific language governing permissions and limitations
 under the License.
 -->
 <div ng-cloak class="container">
-  <div ng-controller="UserController" style="box-sizing: border-box; ">
+  <div ng-controller="UserController">
 
-    <div id="form-container" class="col-md-6 col-md-offset-3" 
style="box-sizing: border-box; background-color: #F7F7F7;">
+    <div id="form-container" class="col-md-6 col-md-offset-3">
 
       <div>
-        <div class="page-header" style="text-align: left; font-weight: 700;">
+        <div class="page-header">
           <span>{{'PASSWORD_CHANGE_REQUIRED'| translate}}</span>
         </div>
         <div class="breadcrumb-header text-center">
 
           <div class="row">            
-            <div id="status-buttons" class="btn-group btn-breadcrumb">
-              <a class="btn btn-default" ng-click="logout()"><i 
class="glyphicon glyphicon-off"style="color:red"></i></a>
+            <div id="status-buttons" class="btn-group btn-breadcrumb col-md-12 
col-md-offset-3">
+              <a class="btn btn-secondary btn-default breadcrumb-home" 
ng-click="logout()">
+                <i class="fa fa-power-off"style="color:red"></i>
+              </a>
               <!--add class breadcrumb-disabled-link to buttons to prevent 
click-->
-              <a ui-sref-active="active" class="btn 
btn-default">{{'PASSWORD_CHANGE'| translate}}</a>
+              <a ui-sref-active="active" class="btn btn-secondary 
btn-default">{{'PASSWORD_CHANGE'| translate}}</a>
             </div>
           </div>
         </div>
@@ -57,12 +59,14 @@ under the License.
                 <span ng-if="passStrength >= 50 && passStrength <= 
82">{{'ALMOSTSECURE'| translate}}</span>
                 <span ng-if="passStrength > 82">{{'VERYGOOD'| 
translate}}</span>
               </div>
-              <div ng-password-strength="user.password" 
strength="passStrength" inner-class="progress-bar" 
inner-class-prefix="progress-bar-">
+              <div ng-password-strength="user.password" 
strength="passStrength" inner-class="progress-bar" 
+                   inner-class-prefix="progress-bar-">
               </div>
             </div>
             <div id="attribute" class="form-group row">
-              <button id="resetpassword" type="submit" class="btn btn-default 
pull-right">{{'SUBMIT'| translate}}</button>
-              <div class="pull-left">
+              <button id="resetpassword" type="submit" 
+                      class="btn btn-secondary btn-default 
float-right">{{'SUBMIT'| translate}}</button>
+              <div class="float-left">
                 <a id="cancel" href="#/self" class="btn 
btn-danger">{{'CANCEL'| translate}}</a>
               </div>
             </div>

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/navigationButtons.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/navigationButtons.html
 
b/client/enduser/src/main/resources/META-INF/resources/app/views/navigationButtons.html
deleted file mode 100644
index 98b63fa..0000000
--- 
a/client/enduser/src/main/resources/META-INF/resources/app/views/navigationButtons.html
+++ /dev/null
@@ -1,26 +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.
--->
-<div class="pull-right">
-  <a ng-show="next !== 'none'" id="next" class="btn btn-default" 
ng-click="validateAndNext($event)">
-    {{'NEXT' | translate}} <span class="glyphicon 
glyphicon-circle-arrow-right"></span>
-  </a>
-  <a ng-show="previous !== 'none'" id="previous" ng-click="previousTab()" 
class="btn btn-default">
-    <span class="glyphicon glyphicon-circle-arrow-left"></span> {{'PREVIOUS' | 
translate}}
-  </a>
-</div>

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/navigationButtonsPartial.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/navigationButtonsPartial.html
 
b/client/enduser/src/main/resources/META-INF/resources/app/views/navigationButtonsPartial.html
new file mode 100644
index 0000000..cd2f907
--- /dev/null
+++ 
b/client/enduser/src/main/resources/META-INF/resources/app/views/navigationButtonsPartial.html
@@ -0,0 +1,29 @@
+<!--
+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.
+-->
+<div class="float-right">
+  <a ng-show="next !== 'none'" id="next" class="btn btn-secondary btn-default" 
ng-click="validateAndNext($event)">
+    {{'NEXT'| translate}}
+    <span class="fa fa-arrow-circle-right"></span>
+  </a>
+  <a ng-show="previous !== 'none'" id="previous" 
+     ng-click="previousTab()" class="btn btn-secondary btn-default float-left">
+    <span class="fa fa-arrow-circle-left"></span>
+    {{'PREVIOUS'| translate}}
+  </a>
+</div>

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/passwordreset.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/passwordreset.html
 
b/client/enduser/src/main/resources/META-INF/resources/app/views/passwordreset.html
index 118b0d4..baeee40 100644
--- 
a/client/enduser/src/main/resources/META-INF/resources/app/views/passwordreset.html
+++ 
b/client/enduser/src/main/resources/META-INF/resources/app/views/passwordreset.html
@@ -17,58 +17,5 @@ specific language governing permissions and limitations
 under the License.
 -->
 <div ng-cloak class="container">
-  <div ng-controller="UserController" style="box-sizing: border-box; ">
-
-    <div id="form-container" class="col-md-6 col-md-offset-3" 
style="box-sizing: border-box; background-color: #F7F7F7;">
-
-      <div>
-        <div class="page-header" style="text-align: left; font-weight: 700;">
-          <span>Password reset</span>
-        </div>
-        <div class="breadcrumb-header text-center">
-
-          <div class="row">            
-            <div id="status-buttons" class="btn-group btn-breadcrumb">
-              <a class="btn btn-default" ng-click="logout()"><i 
class="glyphicon glyphicon-home"></i></a>
-              <!--add class breadcrumb-disabled-link to buttons to prevent 
click-->
-              <a ui-sref-active="active" class="btn 
btn-default">{{'USERDETAILS'| translate}}</a>
-            </div>
-          </div>
-        </div>
-        <form class="signup-form" name="passwordResetForm" 
ng-submit="resetPassword(user)" novalidate>
-
-          <div id="form-views" ui-view>
-            <div id="attribute" class="form-group">
-              <label for="user.username">{{'USER'| translate}}</label>
-              <input name="username" type="text" class="form-control" 
ng-model="user.username" required 
-                     placeholder="{{'USERNAME_PLACEHOLDER'|translate}}" 
ng-blur="retrieveSecurityQuestion(user)">
-              <p ng-show="(userForm.username.$error.required && 
!userForm.username.$pristine)" 
-                 class="text-validation-error">Username is required</p>
-            </div>
-            <div id="attribute" class="form-group" 
ng-show="$root.pwdResetRequiringSecurityQuestions">
-              <label for="user.securityquestion">{{'SECURITYQUESTION'| 
translate}}</label> 
-              <div class="suggestions">(Not Loading? <a href 
ng-click="retrieveSecurityQuestion(user)">Reload</a>)</div>
-              <input name="securityquestion" type="text" class="form-control" 
ng-model="userSecurityQuestion" 
-                     disabled="disabled">              
-            </div>
-            <div id="attribute" class="form-group" 
ng-show="$root.pwdResetRequiringSecurityQuestions">
-              <label for="user.securityAnswer">{{'SECURITYANSWER'| 
translate}}</label>
-              <input name="securityAnswer" type="text" class="form-control" 
ng-model="user.securityAnswer" 
-                     placeholder="{{'SECURITYANSWER_PLACEHOLDER'| translate}}" 
id="securityAnswer">              
-            </div>
-            <div id="attribute" class="form-group row">
-              <!--captcha-->
-              <div class="form-group row">
-                <captcha input="captchaInput" 
enabled="captchaEnabled"></captcha>
-              </div>
-              <button id="resetpassword" type="submit" class="btn btn-default 
pull-right">{{'SUBMIT'| translate}}</button>
-              <div class="pull-left">
-                <a id="cancel" class="btn btn-danger" 
ng-click="logout()">{{'CANCEL'| translate}}</a>
-              </div>
-            </div>
-          </div>
-        </form>
-      </div>
-    </div>
-  </div>
+  <dynamic-template-item type="password_reset"/>
 </div>

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/self.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/self.html 
b/client/enduser/src/main/resources/META-INF/resources/app/views/self.html
index defab42..b7bf74d 100644
--- a/client/enduser/src/main/resources/META-INF/resources/app/views/self.html
+++ b/client/enduser/src/main/resources/META-INF/resources/app/views/self.html
@@ -26,65 +26,7 @@ under the License.
   </head>
   <body>
     <div ng-cloak class="container">
-      <div id="login-container" ng-controller="LoginController" 
style="box-sizing: border-box;">
-        <div id="login" class="card card-container">
-          <div>
-            <img class="login-logo" src="img/logo-green.png" />
-            <div id="login-form" class="form">              
-            </div>
-            <form id="login-form" class="form form-signin" novalidate>
-              <fieldset class="form-group input-group">
-                <div class="form-group">
-                  <input autofocus="autofocus" type="text" 
class="form-control" id="login-username" 
-                         placeholder="{{'USERNAME_PLACEHOLDER'| translate}}"
-                         ng-required ng-model="credentials.username">
-                </div>
-                <div class="form-group">
-                  <input type="password" class="form-control" 
id="login-password" 
-                         placeholder="{{'PASSWORD_PLACEHOLDER'| translate}}" 
-                         ng-required ng-model="credentials.password">
-                </div>
-                <div class="form-group" ng-controller="UserController">
-                  <select  ng-change="switchLanguage()"
-                           id="language" style="width: 100%; text-align: 
left;" class="btn dropdown-toggle btn-default" 
-                           ng-options="language.name for language in 
languages.availableLanguages track by language.id" 
-                           ng-model="languages.selectedLanguage"></select>
-                </div>                 
-                <div class="form-group">
-                  <button type="submit" id="login-btn" class="btn btn-default 
btn-signin login-btn" 
-                          ng-click="login(credentials)">Login</button>
-                </div>
-                <div class="form-group">
-                  <span ng-if="$root.saml2spExtAvailable()">SAML 2.0</span>
-                  <select id="saml2sp" style="width: 100%; text-align: left;" 
class="btn dropdown-toggle btn-default"
-                          ng-if="$root.saml2spExtAvailable()"
-                          ng-options="idp.name for idp in saml2idps.available 
track by idp.entityID"
-                          ng-model="saml2idps.selected" 
ng-change="saml2login()">
-                  </select>
-                </div>
-                <div class="form-group">
-                  <span ng-if="$root.oidcclientExtAvailable()">OpenID 
Connect</span>
-                  <select id="oiscclient" style="width: 100%; text-align: 
left;" class="btn dropdown-toggle btn-default"
-                          ng-if="$root.oidcclientExtAvailable()"
-                          ng-options="op.name for op in oidcops.available 
track by op.name"
-                          ng-model="oidcops.selected" ng-change="oidclogin()">
-                  </select>
-                </div>
-              </fieldset>
-            </form>
-          </div>
-        </div>
-        <div class="text-center" ng-show="$root.isSelfRegAllowed()">
-          <a href="#" class="btn btn-link" 
ng-click="$event.preventDefault();selfCreate();" id="register">
-            {{ 'SELFREGISTRATION' | translate}}
-          </a>
-        </div>
-        <div class="text-center" ng-show="$root.isPwdResetAllowed()">
-          <a href="#" class="btn btn-link" 
ng-click="$event.preventDefault();passwordReset();" id="passwordreset">
-            {{ 'PASSWORDRESET' | translate}}
-          </a>
-        </div>
-      </div> <!-- /#login -->
+      <dynamic-template-item type="login"/>
     </div>
   </body>
 </html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/templates/editUserTemplate.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/templates/editUserTemplate.html
 
b/client/enduser/src/main/resources/META-INF/resources/app/views/templates/editUserTemplate.html
new file mode 100644
index 0000000..a309f71
--- /dev/null
+++ 
b/client/enduser/src/main/resources/META-INF/resources/app/views/templates/editUserTemplate.html
@@ -0,0 +1,57 @@
+<!--
+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.
+-->
+<div class="login-container" ng-controller="UserController" 
ng-init="initUser();">
+  <div id="form-container" class="col-md-12 col-md-offset-3">
+    <div>
+      <div class="page-header">          
+        <span ng-show="createMode">{{'NEWUSER'| translate}}</span>
+        <span ng-show="!createMode">{{'USER'| translate}} 
{{user.username}}</span>
+      </div>
+
+      <div class="breadcrumb-header text-center">
+        <!-- the links to our nested states using relative paths add the 
active class if the state matches our ui-sref -->
+        <div class="text-center">
+          <div class="row">
+            <div growl reference="2" inline="true"></div>              
+            <div id="status-buttons" class="btn-group btn-breadcrumb">
+              <a class="btn btn-secondary btn-default breadcrumb-btn-elem 
breadcrumb-home" 
+                 ng-show="createMode" ng-click="logout()">
+                <i class="fa fa-home"></i>
+              </a>
+              <a id="logout" class="btn btn-secondary btn-default 
breadcrumb-btn-elem" 
+                 ng-show="!createMode" ng-click="logout()">
+                <i class="fa fa-power-off" style="color:red"></i>
+              </a>
+              <!-- add class breadcrumb-disabled-link to buttons to prevent 
click -->              
+              <a ng-repeat="(key, value) in wizard" ui-sref-active="active" 
ui-sref=".{{key}}" 
+                 class="btn btn-secondary btn-default breadcrumb-btn-elem" 
+                 ng-class="createMode && !endReached ? 'disable-link' : 
''">{{key| translate}}</a>       
+            </div>
+          </div>
+        </div>
+
+        <form class="signup-form" name="userForm" ng-submit="saveUser(user)" 
novalidate>
+          <div id="form-views" ui-view >
+
+          </div>
+        </form>
+      </div>
+    </div>
+  </div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/templates/onlyPlainAttrsDetails/editUserTemplate.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/templates/onlyPlainAttrsDetails/editUserTemplate.html
 
b/client/enduser/src/main/resources/META-INF/resources/app/views/templates/onlyPlainAttrsDetails/editUserTemplate.html
new file mode 100644
index 0000000..a309f71
--- /dev/null
+++ 
b/client/enduser/src/main/resources/META-INF/resources/app/views/templates/onlyPlainAttrsDetails/editUserTemplate.html
@@ -0,0 +1,57 @@
+<!--
+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.
+-->
+<div class="login-container" ng-controller="UserController" 
ng-init="initUser();">
+  <div id="form-container" class="col-md-12 col-md-offset-3">
+    <div>
+      <div class="page-header">          
+        <span ng-show="createMode">{{'NEWUSER'| translate}}</span>
+        <span ng-show="!createMode">{{'USER'| translate}} 
{{user.username}}</span>
+      </div>
+
+      <div class="breadcrumb-header text-center">
+        <!-- the links to our nested states using relative paths add the 
active class if the state matches our ui-sref -->
+        <div class="text-center">
+          <div class="row">
+            <div growl reference="2" inline="true"></div>              
+            <div id="status-buttons" class="btn-group btn-breadcrumb">
+              <a class="btn btn-secondary btn-default breadcrumb-btn-elem 
breadcrumb-home" 
+                 ng-show="createMode" ng-click="logout()">
+                <i class="fa fa-home"></i>
+              </a>
+              <a id="logout" class="btn btn-secondary btn-default 
breadcrumb-btn-elem" 
+                 ng-show="!createMode" ng-click="logout()">
+                <i class="fa fa-power-off" style="color:red"></i>
+              </a>
+              <!-- add class breadcrumb-disabled-link to buttons to prevent 
click -->              
+              <a ng-repeat="(key, value) in wizard" ui-sref-active="active" 
ui-sref=".{{key}}" 
+                 class="btn btn-secondary btn-default breadcrumb-btn-elem" 
+                 ng-class="createMode && !endReached ? 'disable-link' : 
''">{{key| translate}}</a>       
+            </div>
+          </div>
+        </div>
+
+        <form class="signup-form" name="userForm" ng-submit="saveUser(user)" 
novalidate>
+          <div id="form-views" ui-view >
+
+          </div>
+        </form>
+      </div>
+    </div>
+  </div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/templates/passwordresetTemplate.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/templates/passwordresetTemplate.html
 
b/client/enduser/src/main/resources/META-INF/resources/app/views/templates/passwordresetTemplate.html
new file mode 100644
index 0000000..b2d6a3b
--- /dev/null
+++ 
b/client/enduser/src/main/resources/META-INF/resources/app/views/templates/passwordresetTemplate.html
@@ -0,0 +1,79 @@
+<!--
+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.
+-->
+<div ng-controller="UserController">
+  <div id="form-container" class="col-md-12 col-md-offset-3">
+
+    <div>
+      <div class="page-header">
+        <span>Password reset</span>
+      </div>
+      <div class="breadcrumb-header text-center">
+        <div id="status-buttons" class="btn-group btn-breadcrumb">
+          <a class="btn btn-default breadcrumb-btn-elem breadcrumb-home" 
ng-click="logout()">
+            <i class="fa fa-home"></i>
+          </a>
+          <!--add class breadcrumb-disabled-link to buttons to prevent click-->
+          <a ui-sref-active="active" class="btn btn-secondary btn-default 
active">{{'USERDETAILS'| translate}}</a>
+        </div>
+      </div>
+      <form class="signup-form" name="passwordResetForm" 
ng-submit="resetPassword(user)" novalidate>
+
+        <div id="form-views" ui-view>
+          <div id="attribute" class="form-group">
+            <label for="user.username">{{'USER'| translate}}</label>
+            <input name="username" type="text" class="form-control" 
ng-model="user.username" required 
+                   placeholder="{{'USERNAME_PLACEHOLDER'|translate}}" 
ng-blur="retrieveSecurityQuestion(user)">
+            <p ng-show="(userForm.username.$error.required && 
!userForm.username.$pristine)" 
+               class="text-validation-error">Username is required</p>
+          </div>
+          <div id="attribute" class="form-group" 
ng-show="$root.pwdResetRequiringSecurityQuestions">
+            <label for="user.securityquestion">{{'SECURITYQUESTION'| 
translate}}</label> 
+            <div class="suggestions">(Not Loading? <a href 
ng-click="retrieveSecurityQuestion(user)">Reload</a>)</div>
+            <input name="securityquestion" type="text" class="form-control" 
ng-model="userSecurityQuestion" 
+                   disabled="disabled">              
+          </div>
+          <div id="attribute" class="form-group" 
ng-show="$root.pwdResetRequiringSecurityQuestions">
+            <label for="user.securityAnswer">{{'SECURITYANSWER'| 
translate}}</label>
+            <input name="securityAnswer" type="text" class="form-control" 
ng-model="user.securityAnswer" 
+                   placeholder="{{'SECURITYANSWER_PLACEHOLDER'| translate}}" 
id="securityAnswer">              
+          </div>
+          <div id="attribute" class="form-group row">
+            <!--captcha-->
+            <div class="form-group row">
+              <div class="col-md-12">
+                <captcha input="captchaInput" 
enabled="captchaEnabled"></captcha>
+              </div>
+            </div>
+            <div class="col-xs-6">
+              <a id="cancel" class="btn btn-danger float-left nav-button" 
tabindex="0" ng-click="logout()">
+                {{'CANCEL'| translate}}
+              </a>
+            </div>
+            <div class="col-xs-6">
+              <button id="resetpassword" type="submit" tabindex="0"
+                      class="btn btn-secondary btn-default float-right 
nav-button">
+                {{'SUBMIT'| translate}}
+              </button>
+            </div>
+          </div>
+        </div>
+      </form>
+    </div>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/templates/selfTemplate.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/templates/selfTemplate.html
 
b/client/enduser/src/main/resources/META-INF/resources/app/views/templates/selfTemplate.html
new file mode 100644
index 0000000..efd3350
--- /dev/null
+++ 
b/client/enduser/src/main/resources/META-INF/resources/app/views/templates/selfTemplate.html
@@ -0,0 +1,77 @@
+<!--
+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.
+-->
+<div id="login-container" ng-controller="LoginController">
+  <div id="login" class="card card-container">
+    <div>
+      <img class="login-logo" src="img/logo-green.png" />
+      <div id="login-form" class="form">              
+      </div>
+      <form id="login-form" class="form form-signin" novalidate>
+        <fieldset class="form-group input-group">
+          <div class="form-group">
+            <input autofocus="autofocus" type="text" class="form-control" 
id="login-username" 
+                   placeholder="{{'USERNAME_PLACEHOLDER'| translate}}"
+                   ng-required ng-model="credentials.username">
+          </div>
+          <div class="form-group">
+            <input type="password" class="form-control" id="login-password" 
+                   placeholder="{{'PASSWORD_PLACEHOLDER'| translate}}" 
+                   ng-required ng-model="credentials.password">
+          </div>
+          <div class="form-group" ng-controller="UserController">
+            <select  ng-change="switchLanguage()"
+                     id="language" class="dropdown-toggle custom-select btn 
btn-default" 
+                     ng-options="language.name for language in 
languages.availableLanguages track by language.id" 
+                     ng-model="languages.selectedLanguage"></select>
+          </div>                 
+          <div class="form-group">
+            <button type="submit" id="login-btn" class="btn btn-secondary 
btn-default btn-signin login-btn" 
+                    ng-click="login(credentials)">Login</button>
+          </div>
+          <div class="form-group">
+            <span ng-if="$root.saml2spExtAvailable()">SAML 2.0</span>
+            <select id="saml2sp" class="dropdown-toggle custom-select btn 
btn-default"
+                    ng-if="$root.saml2spExtAvailable()"
+                    ng-options="idp.name for idp in saml2idps.available track 
by idp.entityID"
+                    ng-model="saml2idps.selected" ng-change="saml2login()">
+            </select>
+          </div>
+          <div class="form-group">
+            <span ng-if="$root.oidcclientExtAvailable()">OpenID Connect</span>
+            <select id="oiscclient" class="dropdown-toggle custom-select btn 
btn-default"
+                    ng-if="$root.oidcclientExtAvailable()"
+                    ng-options="op.name for op in oidcops.available track by 
op.name"
+                    ng-model="oidcops.selected" ng-change="oidclogin()">
+            </select>
+          </div>
+        </fieldset>
+      </form>
+    </div>
+  </div>
+  <div class="text-center" ng-show="$root.isSelfRegAllowed()">
+    <a href="#" class="btn btn-link" ng-click="$event.preventDefault(); 
selfCreate();" id="register">
+      {{ 'SELFREGISTRATION' | translate }}
+    </a>
+  </div>
+  <div class="text-center" ng-show="$root.isPwdResetAllowed()">
+    <a href="#" class="btn btn-link" ng-click="$event.preventDefault(); 
passwordReset();" id="passwordreset">
+      {{ 'PASSWORDRESET' | translate }}
+    </a>
+  </div>
+</div> <!-- /#login -->

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/user-credentials.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/user-credentials.html
 
b/client/enduser/src/main/resources/META-INF/resources/app/views/user-credentials.html
index 274e4bd..6a3524e 100644
--- 
a/client/enduser/src/main/resources/META-INF/resources/app/views/user-credentials.html
+++ 
b/client/enduser/src/main/resources/META-INF/resources/app/views/user-credentials.html
@@ -18,36 +18,40 @@ under the License.
 -->
 <div id="attribute" class="form-group">
   <label for="user.username">{{'USERNAME'| translate}} <span>*</span></label>
-  <input name="username" type="text" class="form-control" 
ng-model="user.username" required 
placeholder="{{'USERNAME_PLACEHOLDER'|translate}}" validate="true"/>
+  <input name="username" type="text" class="form-control" 
ng-model="user.username" 
+         required placeholder="{{'USERNAME_PLACEHOLDER'|translate}}" 
validate="true"/>
   <validation-message name="username" template="requiredMessage" />
 </div>
 
 <div id="attribute" class="form-group">
-  <label for="user.password">{{"PASSWORD"|translate}}</label>
-  <input type="password" class="form-control" name="password" 
ng-model="user.password" placeholder="{{'PASSWORD_PLACEHOLDER'|translate}}">
+  <label class="p-0" for="user.password">{{"PASSWORD"|translate}}</label>
+  <input type="password" class="form-control" name="password" 
ng-model="user.password" 
+         placeholder="{{'PASSWORD_PLACEHOLDER'|translate}}">
 </div>
 
 <div id="attribute" class="form-group">
-  <label for="confirmPassword">{{'CONFIRM_PASSWORD'| translate}}</label>
-  <input name="password" type="password" class="form-control" 
equals="user.password" ng-model="confirmPassword.value"
-         placeholder="{{'CONFIRM_PASSWORD_PLACEHOLDER'| translate}}" 
validate="true">
+  <label class="p-0" for="confirmPassword">{{'CONFIRM_PASSWORD'| 
translate}}</label>
+  <input name="password" type="password" class="form-control" 
equals="user.password" 
+         ng-model="confirmPassword.value" 
placeholder="{{'CONFIRM_PASSWORD_PLACEHOLDER'| translate}}" validate="true">
   <validation-message name="password"/>
 </div>
 
 <div id="attribute" class="form-group">
-  <div class="suggestions">
+  <div class="suggestions p-0">
     {{'PASSWORD_STRENGTH'| translate}}: 
     <span ng-if="passStrength < 50">{{'NOTSECURE'| translate}}</span>
     <span ng-if="passStrength >= 50 && passStrength <= 82">{{'ALMOSTSECURE'| 
translate}}</span>
     <span ng-if="passStrength > 82">{{'VERYGOOD'| translate}}</span>
   </div>
-  <div ng-password-strength="user.password" strength="passStrength" 
inner-class="progress-bar" inner-class-prefix="progress-bar-">
+  <div class="col-md-12" 
+       ng-password-strength="user.password" strength="passStrength" 
inner-class="progress-bar" 
+       inner-class-prefix="progress-bar-">
   </div>
 </div>
 
 <div id="attribute" class="form-group">
-  <label for="securityQuestion">{{'SECURITYQUESTION'| translate}}</label>
-  <select name="securityQuestion" class="form-control"
+  <label class="p-0" for="securityQuestion">{{'SECURITYQUESTION'| 
translate}}</label>
+  <select name="securityQuestion" class="form-control custom-select"
           ng-model="user.securityQuestion"
           ng-options="securityQuestion.key as securityQuestion.content for 
securityQuestion in availableSecurityQuestions">
     <option value="">{{'SELECTSECURITYQUESTION'| translate}}</option>
@@ -55,23 +59,35 @@ under the License.
 </div>
 
 <div id="attribute" class="form-group">
-  <label for="securityAnswer">{{'SECURITYANSWER'| translate}}</label>
-  <input ng-disabled="user.securityQuestion === null || user.securityQuestion 
=== ''" name="securityAnswer" type="text" class="form-control" 
+  <label class="p-0" for="securityAnswer">{{'SECURITYANSWER'| 
translate}}</label>
+  <input ng-disabled="user.securityQuestion === null || user.securityQuestion 
=== ''" name="securityAnswer" 
+         type="text" class="form-control" 
          ng-model="user.securityAnswer"
          placeholder="{{'SECURITYANSWER_PLACEHOLDER'| translate}}">
 </div>
-<div id="attribute" class="form-group row">
-    <div class="pull-right">
-    <div id="navButtons" class="pull-left">
-      <navigation-buttons ng-show="createMode" base="create" 
current="credentials" wizard="{{wizard}}"></navigation-buttons>
-      <navigation-buttons ng-show="!createMode" base="update" 
current="credentials" wizard="{{wizard}}"></navigation-buttons>
+
+<div id="attribute" class="form-group row justify-content-between p-0">
+  <div class="col-xs-3">
+    <a id="cancel" class="btn btn-danger float-left nav-button" tabindex="0" 
ng-click="logout()">
+      {{'CANCEL'| translate}}
+    </a>
+  </div>
+  <div class="col-xs-9">
+    <div id="navButtons" class="float-left"
+         ng-class="(!createMode || (createMode && endReached)) ? 'col-xs-10' : 
'col-xs-12'">
+      <navigation-buttons-partial ng-show="createMode" base="create" 
current="credentials" wizard="{{wizard}}">
+      </navigation-buttons-partial>
+      <navigation-buttons-partial ng-show="!createMode" base="update" 
current="credentials" wizard="{{wizard}}">
+      </navigation-buttons-partial>
     </div>
-    <div class="pull-right">
-      <button id="finish" ng-show="!createMode" type="button" class="btn 
btn-default pull-right" ng-click="finish()">{{'FINISH'| translate}}</button>
-      <button id="finish" ng-show="createMode && endReached" type="button" 
class="btn btn-default pull-right" ng-click="finish()">{{'FINISH'| 
translate}}</button>  
+    <div class="float-right p-0" 
+         ng-class="(!createMode || (createMode && endReached)) ? 'col-xs-2' : 
''" 
+         ng-show="!createMode || (createMode && endReached)">
+      <button id="finish" type="button" tabindex="0"
+              class="btn btn-secondary btn-default float-right nav-button" 
+              ng-click="finish()">
+        {{'FINISH'| translate}}
+      </button>
     </div>
   </div>
-  <div class="pull-left">
-    <a id="cancel" class="btn btn-danger pull-left" 
ng-click="logout()">{{'CANCEL'| translate}}</a>
-  </div>
 </div>

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/user-derived-schemas.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/user-derived-schemas.html
 
b/client/enduser/src/main/resources/META-INF/resources/app/views/user-derived-schemas.html
index 5836742..8146e44 100644
--- 
a/client/enduser/src/main/resources/META-INF/resources/app/views/user-derived-schemas.html
+++ 
b/client/enduser/src/main/resources/META-INF/resources/app/views/user-derived-schemas.html
@@ -19,18 +19,29 @@ under the License.
 <div>
   <dynamic-derived-attributes user="user" 
form="dynamicForm"></dynamic-derived-attributes>
 </div>
-<div id="attribute" class="form-group row">
-  <div class="pull-right">
-    <div id="navButtons" class="pull-left">
-      <navigation-buttons ng-show="createMode" base="create" 
current="derivedSchemas" wizard="{{wizard}}"></navigation-buttons>
-      <navigation-buttons ng-show="!createMode" base="update" 
current="derivedSchemas" wizard="{{wizard}}"></navigation-buttons>
+
+<div id="attribute" class="form-group row justify-content-between p-0">
+  <div class="col-xs-3">
+    <a id="cancel" class="btn btn-danger float-left nav-button" tabindex="0" 
ng-click="logout()">
+      {{'CANCEL'| translate}}
+    </a>
+  </div>
+  <div class="col-xs-9">
+    <div id="navButtons" class="float-left"
+         ng-class="(!createMode || (createMode && endReached)) ? 'col-xs-10' : 
'col-xs-12'">
+      <navigation-buttons-partial ng-show="createMode" base="create" 
current="derivedSchemas" wizard="{{wizard}}">
+      </navigation-buttons-partial>
+      <navigation-buttons-partial ng-show="!createMode" base="update" 
current="derivedSchemas" wizard="{{wizard}}">
+      </navigation-buttons-partial>
     </div>
-    <div class="pull-right">
-      <button id="finish" ng-show="!createMode" type="button" class="btn 
btn-default pull-right" ng-click="finish()">{{'FINISH'| translate}}</button>
-      <button id="finish" ng-show="createMode && endReached" type="button" 
class="btn btn-default pull-right" ng-click="finish()">{{'FINISH'| 
translate}}</button>  
+    <div class="float-right p-0" 
+         ng-class="(!createMode || (createMode && endReached)) ? 'col-xs-2' : 
''" 
+         ng-show="!createMode || (createMode && endReached)">
+      <button id="finish" type="button" tabindex="0"
+              class="btn btn-secondary btn-default float-right nav-button" 
+              ng-click="finish()">
+        {{'FINISH'| translate}}
+      </button>
     </div>
   </div>
-  <div class="pull-left">
-    <a id="cancel" class="btn btn-danger pull-left" 
ng-click="logout()">{{'CANCEL'| translate}}</a>
-  </div>
 </div>

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/user-form-finish.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/user-form-finish.html
 
b/client/enduser/src/main/resources/META-INF/resources/app/views/user-form-finish.html
index 8e58f23..ad3485b 100644
--- 
a/client/enduser/src/main/resources/META-INF/resources/app/views/user-form-finish.html
+++ 
b/client/enduser/src/main/resources/META-INF/resources/app/views/user-form-finish.html
@@ -16,22 +16,29 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 -->
-<div id="attribute" class="form-group row">
+<div id="attribute" class="form-group row justify-content-between p-0">
   <!--captcha-->
-  <div class="form-group row">
+  <div class="form-group row col-md-12">
     <captcha input="captchaInput" enabled="captchaEnabled"></captcha>
   </div>
+
   <!--navigation buttons-->
-  <div class="pull-right">
-    <div id="navButtons" class="pull-left">
-      <navigation-buttons ng-show="createMode" base="create" current="finish" 
wizard="{{wizard}}"></navigation-buttons>
-      <navigation-buttons ng-show="!createMode" base="update" current="finish" 
wizard="{{wizard}}"></navigation-buttons>
+  <div class="col-xs-3">
+    <a id="cancel" class="btn btn-danger float-left nav-button" tabindex="0" 
ng-click="logout()">
+      {{'CANCEL'| translate}}
+    </a>
+  </div>
+  <div class="col-xs-9">
+    <div id="navButtons" class="col-xs-10 float-left">
+      <navigation-buttons-partial ng-show="createMode" base="create" 
current="finish" wizard="{{wizard}}">
+      </navigation-buttons-partial>
+      <navigation-buttons-partial ng-show="!createMode" base="update" 
current="finish" wizard="{{wizard}}">
+      </navigation-buttons-partial>
     </div>
-    <div class="pull-right">
-      <button id="save" type="submit" class="btn btn-default 
pull-right">{{'SAVE'| translate}}</button>
+    <div class="col-xs-2 float-right p-0">
+      <button id="save" type="submit" tabindex="0" class="btn btn-secondary 
btn-default float-right nav-button">
+        {{'SAVE'| translate}}
+      </button>
     </div>
   </div>
-  <div class="pull-left">
-    <a id="cancel" class="btn btn-danger pull-left" 
ng-click="logout()">{{'CANCEL'| translate}}</a>
-  </div>
 </div>

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/user-groups.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/user-groups.html
 
b/client/enduser/src/main/resources/META-INF/resources/app/views/user-groups.html
index 70c3030..dbec0ac 100644
--- 
a/client/enduser/src/main/resources/META-INF/resources/app/views/user-groups.html
+++ 
b/client/enduser/src/main/resources/META-INF/resources/app/views/user-groups.html
@@ -17,33 +17,44 @@ specific language governing permissions and limitations
 under the License.
 -->
 <div id="attribute" class="form-group row upper-select">
-  <label>{{"REALM"|translate}}</label>
-  <select class="form-control"
+  <label class="col-md-12 p-0">{{"REALM"|translate}}</label>
+  <select class="form-control col-md-12 custom-select"
           ng-model="user.realm" ng-change="refreshGroups()"
           ng-required="true">
     <option ng-repeat="realm in availableRealms" 
value="{{realm}}">{{realm}}</option>
   </select>
 </div>
 <div id="attribute" class="form-group row upper-select">
-  <label>{{"GROUPS"|translate}}</label><br/>
-  <groups form="dynamicForm" user="user"></groups>
+  <label class="col-md-12 p-0">{{"GROUPS"|translate}}</label><br/>
+  <groups class="col-md-12 p-0" form="dynamicForm" user="user"></groups>
 </div>
 <div id="attribute" class="form-group row upper-select">
-  <label>{{"AUXILIARY CLASSES"|translate}}</label><br/>
-  <auxiliary form="dynamicForm" user="user"></auxiliary>
+  <label class="col-md-12 p-0">{{"AUXILIARY CLASSES"|translate}}</label>
+  <auxiliary class="col-md-12 p-0" form="dynamicForm" user="user"></auxiliary>
 </div>
-<div id="attribute" class="form-group row">
-  <div class="pull-right">
-    <div id="navButtons" class="pull-left">
-      <navigation-buttons ng-show="createMode" base="create" current="groups" 
wizard="{{wizard}}"></navigation-buttons>
-      <navigation-buttons ng-show="!createMode" base="update" current="groups" 
wizard="{{wizard}}"></navigation-buttons>
+
+<div id="attribute" class="form-group row justify-content-between p-0">
+  <div class="col-xs-3">
+    <a id="cancel" class="btn btn-danger float-left nav-button" tabindex="0" 
ng-click="logout()">
+      {{'CANCEL'| translate}}
+    </a>
+  </div>
+  <div class="col-xs-9">
+    <div id="navButtons" class="float-left"
+         ng-class="(!createMode || (createMode && endReached)) ? 'col-xs-10' : 
'col-xs-12'">
+      <navigation-buttons-partial ng-show="createMode" base="create" 
current="groups" wizard="{{wizard}}">
+      </navigation-buttons-partial>
+      <navigation-buttons-partial ng-show="!createMode" base="update" 
current="groups" wizard="{{wizard}}">
+      </navigation-buttons-partial>
     </div>
-    <div class="pull-right">
-      <button id="finish" ng-show="!createMode" type="button" class="btn 
btn-default pull-right" ng-click="finish()">{{'FINISH'| translate}}</button>
-      <button id="finish" ng-show="createMode && endReached" type="button" 
class="btn btn-default pull-right" ng-click="finish()">{{'FINISH'| 
translate}}</button>  
+    <div class="float-right p-0" 
+         ng-class="(!createMode || (createMode && endReached)) ? 'col-xs-2' : 
''" 
+         ng-show="!createMode || (createMode && endReached)">
+      <button id="finish" type="button" tabindex="0"
+              class="btn btn-secondary btn-default float-right nav-button" 
+              ng-click="finish()">
+        {{'FINISH'| translate}}
+      </button>
     </div>
   </div>
-  <div class="pull-left">
-    <a id="cancel" class="btn btn-danger pull-left" 
ng-click="logout()">{{'CANCEL'| translate}}</a>
-  </div>
-</div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/user-plain-schemas.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/user-plain-schemas.html
 
b/client/enduser/src/main/resources/META-INF/resources/app/views/user-plain-schemas.html
index b7d93eb..d04c466 100644
--- 
a/client/enduser/src/main/resources/META-INF/resources/app/views/user-plain-schemas.html
+++ 
b/client/enduser/src/main/resources/META-INF/resources/app/views/user-plain-schemas.html
@@ -19,18 +19,29 @@ under the License.
 <div>
   <dynamic-plain-attributes form="dynamicForm" 
user="user"></dynamic-plain-attributes>
 </div>
-<div id="attribute" class="form-group row">
-  <div class="pull-right">
-    <div id="navButtons" class="pull-left">
-      <navigation-buttons ng-show="createMode" base="create" 
current="plainSchemas" wizard="{{wizard}}"></navigation-buttons>
-      <navigation-buttons ng-show="!createMode" base="update" 
current="plainSchemas" wizard="{{wizard}}"></navigation-buttons>
+
+<div id="attribute" class="form-group row justify-content-between p-0">
+  <div class="col-xs-3">
+    <a id="cancel" class="btn btn-danger float-left nav-button" tabindex="0" 
ng-click="logout()">
+      {{'CANCEL'| translate}}
+    </a>
+  </div>
+  <div class="col-xs-9">
+    <div id="navButtons" class="float-left"
+         ng-class="(!createMode || (createMode && endReached)) ? 'col-xs-10' : 
'col-xs-12'">
+      <navigation-buttons-partial ng-show="createMode" base="create" 
current="plainSchemas" wizard="{{wizard}}">
+      </navigation-buttons-partial>
+      <navigation-buttons-partial ng-show="!createMode" base="update" 
current="plainSchemas" wizard="{{wizard}}">
+      </navigation-buttons-partial>
     </div>
-    <div class="pull-right">
-      <button id="finish" ng-show="!createMode" type="button" class="btn 
btn-default pull-right" ng-click="finish()">{{'FINISH'| translate}}</button>
-      <button id="finish" ng-show="createMode && endReached" type="button" 
class="btn btn-default pull-right" ng-click="finish()">{{'FINISH'| 
translate}}</button>  
+    <div class="float-right p-0" 
+         ng-class="(!createMode || (createMode && endReached)) ? 'col-xs-2' : 
''" 
+         ng-show="!createMode || (createMode && endReached)">
+      <button id="finish" type="button" tabindex="0"
+              class="btn btn-secondary btn-default float-right nav-button"
+              ng-click="finish()">
+        {{'FINISH'| translate}}
+      </button>
     </div>
   </div>
-  <div class="pull-left">
-    <a id="cancel" class="btn btn-danger pull-left" 
ng-click="logout()">{{'CANCEL'| translate}}</a>
-  </div>
-</div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/user-resources.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/user-resources.html
 
b/client/enduser/src/main/resources/META-INF/resources/app/views/user-resources.html
index 86ee3bd..a8cde79 100644
--- 
a/client/enduser/src/main/resources/META-INF/resources/app/views/user-resources.html
+++ 
b/client/enduser/src/main/resources/META-INF/resources/app/views/user-resources.html
@@ -17,20 +17,31 @@ specific language governing permissions and limitations
 under the License.
 -->
 <div id="attribute" class="form-group row upper-select ng-scope">
-  <resources form="dynamicForm" user="user"></resources>
+  <resources class="col-md-12 p-0" form="dynamicForm" user="user"></resources>
 </div>
-<div id="attribute" class="form-group row">
-  <div class="pull-right">
-    <div id="navButtons" class="pull-left">
-      <navigation-buttons ng-show="createMode" base="create" 
current="resources" wizard="{{wizard}}"></navigation-buttons>
-      <navigation-buttons ng-show="!createMode" base="update" 
current="resources" wizard="{{wizard}}"></navigation-buttons>
+
+<div id="attribute" class="form-group row justify-content-between p-0">
+  <div class="col-xs-3">
+    <a id="cancel" class="btn btn-danger float-left nav-button" tabindex="0" 
ng-click="logout()">
+      {{'CANCEL'| translate}}
+    </a>
+  </div>
+  <div class="col-xs-9">
+    <div id="navButtons" class="float-left"
+         ng-class="(!createMode || (createMode && endReached)) ? 'col-xs-10' : 
'col-xs-12'">
+      <navigation-buttons-partial ng-show="createMode" base="create" 
current="resources" wizard="{{wizard}}">
+      </navigation-buttons-partial>
+      <navigation-buttons-partial ng-show="!createMode" base="update" 
current="resources" wizard="{{wizard}}">
+      </navigation-buttons-partial>
     </div>
-    <div class="pull-right">
-      <button id="finish" ng-show="!createMode" type="button" class="btn 
btn-default pull-right" ng-click="finish()">{{'FINISH'| translate}}</button>
-      <button id="finish" ng-show="createMode && endReached" type="button" 
class="btn btn-default pull-right" ng-click="finish()">{{'FINISH'| 
translate}}</button>  
+    <div class="float-right p-0" 
+         ng-class="(!createMode || (createMode && endReached)) ? 'col-xs-2' : 
''" 
+         ng-show="!createMode || (createMode && endReached)">
+      <button id="finish" type="button" tabindex="0"
+              class="btn btn-secondary btn-default float-right nav-button" 
+              ng-click="finish()">
+        {{'FINISH'| translate}}
+      </button>
     </div>
   </div>
-  <div class="pull-left">
-    <a id="cancel" class="btn btn-danger pull-left" 
ng-click="logout()">{{'CANCEL'| translate}}</a>
-  </div>
-</div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/META-INF/resources/app/views/user-virtual-schemas.html
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/main/resources/META-INF/resources/app/views/user-virtual-schemas.html
 
b/client/enduser/src/main/resources/META-INF/resources/app/views/user-virtual-schemas.html
index 81e4e78..216d624 100644
--- 
a/client/enduser/src/main/resources/META-INF/resources/app/views/user-virtual-schemas.html
+++ 
b/client/enduser/src/main/resources/META-INF/resources/app/views/user-virtual-schemas.html
@@ -19,18 +19,29 @@ under the License.
 <div>
   <dynamic-virtual-attributes form="dynamicForm" 
user="user"></dynamic-virtual-attributes>
 </div>
-<div id="attribute" class="form-group row">
-  <div class="pull-right">
-    <div id="navButtons" class="pull-left">
-      <navigation-buttons ng-show="createMode" base="create" 
current="virtualSchemas" wizard="{{wizard}}"></navigation-buttons>
-      <navigation-buttons ng-show="!createMode" base="update" 
current="virtualSchemas" wizard="{{wizard}}"></navigation-buttons>
+
+<div id="attribute" class="form-group row justify-content-between p-0">
+  <div class="col-xs-3">
+    <a id="cancel" class="btn btn-danger float-left nav-button" tabindex="0" 
ng-click="logout()">
+      {{'CANCEL'| translate}}
+    </a>
+  </div>
+  <div class="col-xs-9">
+    <div id="navButtons" class="float-left"
+         ng-class="(!createMode || (createMode && endReached)) ? 'col-xs-10' : 
'col-xs-12'">
+      <navigation-buttons-partial ng-show="createMode" base="create" 
current="virtualSchemas" wizard="{{wizard}}">
+      </navigation-buttons-partial>
+      <navigation-buttons-partial ng-show="!createMode" base="update" 
current="virtualSchemas" wizard="{{wizard}}">
+      </navigation-buttons-partial>
     </div>
-    <div class="pull-right">
-      <button id="finish" ng-show="!createMode" type="button" class="btn 
btn-default pull-right" ng-click="finish()">{{'FINISH'| translate}}</button>
-      <button id="finish" ng-show="createMode && endReached" type="button" 
class="btn btn-default pull-right" ng-click="finish()">{{'FINISH'| 
translate}}</button>  
+    <div class="float-right p-0" 
+         ng-class="(!createMode || (createMode && endReached)) ? 'col-xs-2' : 
''" 
+         ng-show="!createMode || (createMode && endReached)">
+      <button id="finish" type="button" tabindex="0"
+              class="btn btn-secondary btn-default float-right nav-button" 
+              ng-click="finish()">
+        {{'FINISH'| translate}}
+      </button>
     </div>
   </div>
-  <div class="pull-left">
-    <a id="cancel" class="btn btn-danger pull-left" 
ng-click="logout()">{{'CANCEL'| translate}}</a>
-  </div>
 </div>

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/customForm.json
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/customForm.json 
b/client/enduser/src/main/resources/customForm.json
deleted file mode 100644
index 9e26dfe..0000000
--- a/client/enduser/src/main/resources/customForm.json
+++ /dev/null
@@ -1 +0,0 @@
-{}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/customFormAttributes.json
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/customFormAttributes.json 
b/client/enduser/src/main/resources/customFormAttributes.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/client/enduser/src/main/resources/customFormAttributes.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/main/resources/customTemplate.json
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/customTemplate.json 
b/client/enduser/src/main/resources/customTemplate.json
new file mode 100644
index 0000000..6b0efc1
--- /dev/null
+++ b/client/enduser/src/main/resources/customTemplate.json
@@ -0,0 +1,65 @@
+{
+  "templates": 
+          {
+            "login":
+                    {
+                      "templateUrl": "views/templates/selfTemplate.html",
+                      "css": [
+                        "css/login.css"
+                      ]
+                    },
+
+            "edit_user":
+                    {
+                      "templateUrl": "views/templates/editUserTemplate.html",
+                      "css": [
+                        "css/editUser.css"
+                      ]
+                    },
+
+            "password_reset":
+                    {
+                      "templateUrl": 
"views/templates/passwordresetTemplate.html",
+                      "css": [
+                        "css/editUser.css",
+                        "css/passwordReset.css"
+                      ]
+                    }
+          },
+
+  "generalAssets": 
+          {
+            "css": [
+              "css/notification.css",
+              "css/app.css"
+            ]
+          },
+
+  "wizard": 
+          {
+            "firstStep": "credentials",
+            "steps": {
+              "credentials": {
+                "url": "/credentials"
+              },
+              "groups": {
+                "url": "/groups"
+              },
+              "plainSchemas": {
+                "url": "/plainSchemas"
+              },
+              "derivedSchemas": {
+                "url": "/derivedSchemas"
+              },
+              "virtualSchemas": {
+                "url": "/virtualSchemas"
+              },
+              "resources": {
+                "url": "/resources"
+              },
+              "finish": {
+                "url": "/finish"
+              }
+            }
+          }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/test/java/org/apache/syncope/client/enduser/util/UserRequestValidatorTest.java
----------------------------------------------------------------------
diff --git 
a/client/enduser/src/test/java/org/apache/syncope/client/enduser/util/UserRequestValidatorTest.java
 
b/client/enduser/src/test/java/org/apache/syncope/client/enduser/util/UserRequestValidatorTest.java
index d8c021a..7625741 100644
--- 
a/client/enduser/src/test/java/org/apache/syncope/client/enduser/util/UserRequestValidatorTest.java
+++ 
b/client/enduser/src/test/java/org/apache/syncope/client/enduser/util/UserRequestValidatorTest.java
@@ -28,6 +28,7 @@ import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 import org.apache.syncope.client.enduser.model.CustomAttributesInfo;
+import org.apache.syncope.client.enduser.model.CustomTemplateInfo;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.junit.Test;
@@ -49,38 +50,48 @@ public class UserRequestValidatorTest {
         AttrTO notAllowed = attrTO("not_allowed", "notAllowedValue");
         userTO.getPlainAttrs().addAll(Arrays.asList(firstname, surname, 
notAllowed, additionalCtype));
 
-        Map<String, CustomAttributesInfo> customForm = new 
ObjectMapper().readValue(new ClassPathResource(
-                "customForm.json").getFile(), new 
TypeReference<HashMap<String, CustomAttributesInfo>>() {
+        Map<String, CustomAttributesInfo> customFormAttributes = new 
ObjectMapper().readValue(new ClassPathResource(
+                "customFormAttributes.json").getFile(), new 
TypeReference<HashMap<String, CustomAttributesInfo>>() {
         });
+        
+        CustomTemplateInfo customTemplate = new ObjectMapper().readValue(new 
ClassPathResource(
+                "customTemplate.json").getFile(), CustomTemplateInfo.class);
 
         // not allowed because of presence of notAllowed attribute
-        assertFalse(UserRequestValidator.compliant(userTO, customForm, true));
+        assertFalse(UserRequestValidator.compliant(userTO, 
customFormAttributes, true));
 
         // remove notAllowed attribute and make it compliant
         userTO.getPlainAttrs().remove(notAllowed);
-        assertTrue(UserRequestValidator.compliant(userTO, customForm, true));
+        assertTrue(UserRequestValidator.compliant(userTO, 
customFormAttributes, true));
 
         // firstname must have only one defaultValue
         
userTO.getPlainAttr("firstname").getValues().add("notAllowedFirstnameValue");
-        assertFalse(UserRequestValidator.compliant(userTO, customForm, true));
-        assertTrue(UserRequestValidator.compliant(userTO, customForm, false));
+        assertFalse(UserRequestValidator.compliant(userTO, 
customFormAttributes, true));
+        assertTrue(UserRequestValidator.compliant(userTO, 
customFormAttributes, false));
         // clean
         
userTO.getPlainAttr("firstname").getValues().remove("notAllowedFirstnameValue");
 
-        // derived must not be present
-        AttrTO derivedNotAllowed = attrTO("derivedNotAllowed");
-        userTO.getDerAttrs().add(derivedNotAllowed);
-        assertFalse(UserRequestValidator.compliant(userTO, customForm, true));
-        // clean 
-        userTO.getDerAttrs().clear();
-
         // virtual
         AttrTO virtualdata = attrTO("virtualdata", "defaultVirtualData");
         userTO.getVirAttrs().add(virtualdata);
-        assertTrue(UserRequestValidator.compliant(userTO, customForm, true));
+        assertTrue(UserRequestValidator.compliant(userTO, 
customFormAttributes, true));
 
         // with empty form is compliant by definition
         assertTrue(UserRequestValidator.compliant(userTO, new HashMap<String, 
CustomAttributesInfo>(), true));
+        
+        // check wizard steps
+        // only "credentials", "plainSchemas" and "finish" steps must be 
visible
+        assertTrue(UserRequestValidator.validateSteps(customTemplate));
+        
+        assertTrue(UserRequestValidator.validateStep("credentials", 
customTemplate));
+        assertTrue(UserRequestValidator.validateStep("plainSchemas", 
customTemplate));
+        assertTrue(UserRequestValidator.validateStep("finish", 
customTemplate));
+        
+        assertFalse(UserRequestValidator.validateStep("test", customTemplate));
+        assertFalse(UserRequestValidator.validateStep("resources", 
customTemplate));
+        assertFalse(UserRequestValidator.validateStep("virtualSchemas", 
customTemplate));
+        assertFalse(UserRequestValidator.validateStep("derivedSchemas", 
customTemplate));
+        assertFalse(UserRequestValidator.validateStep("groups", 
customTemplate));
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/19d9e93e/client/enduser/src/test/resources/customForm.json
----------------------------------------------------------------------
diff --git a/client/enduser/src/test/resources/customForm.json 
b/client/enduser/src/test/resources/customForm.json
deleted file mode 100644
index 3866474..0000000
--- a/client/enduser/src/test/resources/customForm.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
-  "PLAIN": 
-          {
-            "show": true,
-            "attributes": {
-              "firstname": {
-                "readonly": true,
-                "defaultValues": ["defaultFirstname"]
-              },
-              "surname": {
-                "readonly": false,
-                "defaultValues": []
-              },
-              "fullname": {
-                "readonly": false
-              },
-              "userId": {
-                "readonly": false
-              },
-              "loginDate": {
-                "readonly": false
-              },
-              "additional#loginDate": {
-                "readonly": false
-              },
-              "additional#ctype": {
-                "readonly": false,
-                "defaultValues": ["ctypeDefault"]
-              },
-              "additional#cool": {
-                "readonly": false,
-                "defaultValues": ["true"]
-              }
-            }
-          },
-  "DERIVED":
-          {
-            "show": false
-          },
-  "VIRTUAL": 
-          {
-            "show": true,
-            "attributes": {
-              "virtualdata": {
-                "readonly": true,
-                "defaultValues": ["defaultVirtualData"]
-              }
-            }
-          }
-}
\ No newline at end of file

Reply via email to