keycloak-memoizeit

Merge pull request #1483 from stianst/master KEYCLOAK-1591

7/23/2015 8:26:38 AM

Changes

Details

diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js
index 3fd0fb0..6331c9d 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js
@@ -483,15 +483,22 @@ module.controller('ClientImportCtrl', function($scope, $location, $upload, realm
 });
 
 
-module.controller('ClientListCtrl', function($scope, realm, clients, Client, serverInfo, $location) {
+module.controller('ClientListCtrl', function($scope, realm, clients, Client, serverInfo, $route, Dialog, Notifications) {
     $scope.realm = realm;
     $scope.clients = clients;
     $scope.importButton = serverInfo.clientImporters.length > 0;
-    $scope.$watch(function() {
-        return $location.path();
-    }, function() {
-        $scope.path = $location.path().substring(1).split("/");
-    });
+
+    $scope.removeClient = function(client) {
+        Dialog.confirmDelete(client.clientId, 'client', function() {
+            Client.remove({
+                realm : realm.realm,
+                client : client.id
+            }, function() {
+                $route.reload();
+                Notifications.success("The client has been deleted.");
+            });
+        });
+    };
 });
 
 module.controller('ClientInstallationCtrl', function($scope, realm, client, ClientInstallation,ClientInstallationJBoss, $http, $routeParams) {
@@ -1003,7 +1010,7 @@ module.controller('ClientRevocationCtrl', function($scope, realm, client, Client
 
 });
 
-module.controller('ClientClusteringCtrl', function($scope, client, Client, ClientTestNodesAvailable, realm, $location, $route, Notifications, TimeUnit) {
+module.controller('ClientClusteringCtrl', function($scope, client, Client, ClientTestNodesAvailable, ClientClusterNode, realm, $location, $route, Dialog, Notifications, TimeUnit) {
     $scope.client = client;
     $scope.realm = realm;
 
@@ -1066,6 +1073,15 @@ module.controller('ClientClusteringCtrl', function($scope, client, Client, Clien
 
         $scope.nodeRegistrations = nodeRegistrations;
     };
+
+    $scope.removeNode = function(node) {
+        Dialog.confirmDelete(node.host, 'node', function() {
+            ClientClusterNode.remove({ realm : realm.realm, client : client.id , node: node.host }, function() {
+                Notifications.success('Node ' + node.host + ' unregistered successfully.');
+                $route.reload();
+            });
+        });
+    };
 });
 
 module.controller('ClientClusteringNodeCtrl', function($scope, client, Client, ClientClusterNode, realm, $location, $routeParams, Notifications) {
@@ -1172,8 +1188,8 @@ module.controller('AddBuiltinProtocolMapperCtrl', function($scope, realm, client
 });
 
 module.controller('ClientProtocolMapperListCtrl', function($scope, realm, client, serverInfo,
-                                                           ClientProtocolMappersByProtocol,
-                                                           $http, $location, Dialog, Notifications) {
+                                                           ClientProtocolMappersByProtocol, ClientProtocolMapper,
+                                                           $route, Dialog, Notifications) {
     $scope.realm = realm;
     $scope.client = client;
     if (client.protocol == null) {
@@ -1187,6 +1203,15 @@ module.controller('ClientProtocolMapperListCtrl', function($scope, realm, client
     }
     $scope.mapperTypes = mapperTypes;
 
+    $scope.removeMapper = function(mapper) {
+        console.debug(mapper);
+        Dialog.confirmDelete(mapper.name, 'mapper', function() {
+            ClientProtocolMapper.remove({ realm: realm.realm, client: client.id, id : mapper.id }, function() {
+                Notifications.success("The mapper has been deleted.");
+                $route.reload();
+            });
+        });
+    };
 
     var updateMappers = function() {
         $scope.mappers = ClientProtocolMappersByProtocol.query({realm : realm.realm, client : client.id, protocol : client.protocol});
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
index 84effda..85ad18b 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
@@ -861,6 +861,18 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
         $scope.hidePassword = flag;
     };
 
+    $scope.removeIdentityProvider = function(identityProvider) {
+        Dialog.confirmDelete(identityProvider.alias, 'provider', function() {
+            IdentityProvider.remove({
+                realm : realm.realm,
+                alias : identityProvider.alias
+            }, function() {
+                $route.reload();
+                Notifications.success("The identity provider has been deleted.");
+            });
+        });
+    };
+
 });
 
 module.controller('RealmIdentityProviderExportCtrl', function(realm, identityProvider, $scope, $http, IdentityProviderExport) {
@@ -1052,16 +1064,21 @@ module.controller('RealmRevocationCtrl', function($scope, Realm, RealmPushRevoca
 });
 
 
-module.controller('RoleListCtrl', function($scope, $location, realm, roles) {
-
+module.controller('RoleListCtrl', function($scope, $route, Dialog, Notifications, realm, roles, RoleById) {
     $scope.realm = realm;
     $scope.roles = roles;
 
-    $scope.$watch(function() {
-        return $location.path();
-    }, function() {
-        $scope.path = $location.path().substring(1).split("/");
-    });
+    $scope.removeRole = function (role) {
+        Dialog.confirmDelete(role.name, 'role', function () {
+            RoleById.remove({
+                realm: realm.realm,
+                role: role.id
+            }, function () {
+                $route.reload();
+                Notifications.success("The role has been deleted.");
+            });
+        });
+    };
 });
 
 
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/users.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/users.js
index 3508bf2..175a3b3 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/users.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/users.js
@@ -217,7 +217,7 @@ module.controller('UserConsentsCtrl', function($scope, realm, user, userConsents
 });
 
 
-module.controller('UserListCtrl', function($scope, realm, User, UserImpersonation, BruteForce, Notifications) {
+module.controller('UserListCtrl', function($scope, realm, User, UserImpersonation, BruteForce, Notifications, $route, Dialog) {
     $scope.realm = realm;
     $scope.page = 0;
 
@@ -271,6 +271,20 @@ module.controller('UserListCtrl', function($scope, realm, User, UserImpersonatio
             $scope.lastSearch = $scope.query.search;
         });
     };
+
+    $scope.removeUser = function(user) {
+        Dialog.confirmDelete(user.id, 'user', function() {
+            user.$remove({
+                realm : realm.realm,
+                userId : user.id
+            }, function() {
+                $route.reload();
+                Notifications.success("The user has been deleted.");
+            }, function() {
+                Notifications.error("User couldn't be deleted");
+            });
+        });
+    };
 });
 
 
@@ -532,7 +546,7 @@ module.controller('UserCredentialsCtrl', function($scope, realm, user, User, Use
     };
 });
 
-module.controller('UserFederationCtrl', function($scope, $location, realm, UserFederationProviders, UserFederationInstances, Notifications, Dialog) {
+module.controller('UserFederationCtrl', function($scope, $location, $route, realm, UserFederationProviders, UserFederationInstances, Notifications, Dialog) {
     console.log('UserFederationCtrl ++++****');
     $scope.realm = realm;
     $scope.providers = UserFederationProviders.query({realm: realm.realm});
@@ -544,11 +558,22 @@ module.controller('UserFederationCtrl', function($scope, $location, realm, UserF
 
     $scope.instances = UserFederationInstances.query({realm: realm.realm});
 
+    $scope.removeUserFederation = function(instance) {
+        Dialog.confirmDelete(instance.displayName, 'user federation provider', function() {
+            UserFederationInstances.remove({
+                realm : realm.realm,
+                instance : instance.id
+            }, function() {
+                $route.reload();
+                Notifications.success("The provider has been deleted.");
+            });
+        });
+    };
 });
 
 module.controller('UserFederationTabCtrl', function(Dialog, $scope, Current, Notifications, $location) {
     $scope.removeUserFederation = function() {
-        Dialog.confirm('Delete', 'Are you sure you want to permanently delete this provider?  All imported users will also be deleted.', function() {
+        Dialog.confirmDelete($scope.instance.displayName, 'user federation provider', function() {
             $scope.instance.$remove({
                 realm : Current.realm.realm,
                 instance : $scope.instance.id
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/brute-force.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/brute-force.html
index 5ea711e..e26e126 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/brute-force.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/brute-force.html
@@ -17,15 +17,15 @@
             <div class="form-group" data-ng-show="realm.bruteForceProtected">
                 <label class="col-md-2 control-label" for="failureFactor">Max Login Failures</label>
 
-                <div class="col-md-2">
+                <div class="col-md-6">
                     <input class="form-control" type="number" min="1" max="31536000" id="failureFactor" name="failureFactor" data-ng-model="realm.failureFactor" autofocus
                            required>
                 </div>
                 <kc-tooltip>How many failures before wait is triggered.</kc-tooltip>
             </div>
-            <div class="form-group input-select" data-ng-show="realm.bruteForceProtected">
+            <div class="form-group" data-ng-show="realm.bruteForceProtected">
                 <label class="col-md-2 control-label" for="waitIncrement">Wait Increment</label>
-                <div class="col-md-6 form-inline">
+                <div class="col-md-6 time-selector">
                     <input class="form-control" type="number" required min="1"
                            max="31536000" data-ng-model="realm.waitIncrement"
                            id="waitIncrement" name="waitIncrement"/>
@@ -41,15 +41,15 @@
             <div class="form-group" data-ng-show="realm.bruteForceProtected">
                 <label class="col-md-2 control-label" for="quickLoginCheckMilliSeconds">Quick Login Check Milli Seconds</label>
 
-                <div class="col-md-2">
+                <div class="col-md-6">
                     <input class="form-control" type="number" min="1" max="31536000" id="quickLoginCheckMilliSeconds" name="quickLoginCheckMilliSeconds" data-ng-model="realm.quickLoginCheckMilliSeconds" autofocus
                            required>
                 </div>
                 <kc-tooltip>If a failure happens concurrently too quickly, lock out the user.</kc-tooltip>
             </div>
-            <div class="form-group input-select" data-ng-show="realm.bruteForceProtected">
+            <div class="form-group" data-ng-show="realm.bruteForceProtected">
                 <label class="col-md-2 control-label" for="minimumQuickLoginWait">Minimum Quick Login Wait</label>
-                <div class="col-md-6 form-inline">
+                <div class="col-md-6 time-selector">
                     <input class="form-control" type="number" required min="1"
                            max="31536000" data-ng-model="realm.minimumQuickLoginWait"
                            id="minimumQuickLoginWait" name="minimumQuickLoginWait"/>
@@ -62,9 +62,9 @@
                 </div>
                 <kc-tooltip>How long to wait after a quick login failure.</kc-tooltip>
             </div>
-            <div class="form-group input-select" data-ng-show="realm.bruteForceProtected">
+            <div class="form-group" data-ng-show="realm.bruteForceProtected">
                 <label class="col-md-2 control-label" for="maxFailureWait">Max Wait</label>
-                <div class="col-md-6 form-inline">
+                <div class="col-md-6 time-selector">
                     <input class="form-control" type="number" required min="1"
                                    max="31536000" data-ng-model="realm.maxFailureWait"
                                    id="maxFailureWait" name="maxFailureWait"/>
@@ -77,9 +77,9 @@
                 </div>
                 <kc-tooltip>Max time a user will be locked out.</kc-tooltip>
             </div>
-            <div class="form-group input-select" data-ng-show="realm.bruteForceProtected">
+            <div class="form-group" data-ng-show="realm.bruteForceProtected">
                 <label class="col-md-2 control-label" for="maxDeltaTime">Failure Reset Time</label>
-                <div class="col-md-6 form-inline">
+                <div class="col-md-6 time-selector">
                     <input class="form-control" type="number" required min="1"
                            max="31536000" data-ng-model="realm.maxDeltaTime"
                            id="maxDeltaTime" name="maxDeltaTime"/>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering.html
index 5f59d02..932321d 100644
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering.html
@@ -43,7 +43,7 @@
             <table class="table table-striped table-bordered">
                 <thead>
                     <tr>
-                        <th class="kc-table-actions" colspan="3" data-ng-show="access.manageClients">
+                        <th class="kc-table-actions" colspan="5" data-ng-show="access.manageClients">
                             <div class="pull-right">
                                 <a class="btn btn-default" tooltip="Manually register cluster node. This is usually not needed as cluster node should be registered automatically by adapter"
                                    tooltip-placement="bottom" href="#/register-node/realms/{{realm.realm}}/clients/{{client.id}}/clustering">Register node manually</a>
@@ -54,12 +54,19 @@
                     <tr data-ng-hide="!nodeRegistrations || nodeRegistrations.length == 0">
                         <th>Node host</th>
                         <th>Last registration</th>
+                        <th colspan="2">Actions</th>
                     </tr>
                 </thead>
                 <tbody>
                     <tr ng-repeat="node in nodeRegistrations">
                         <td><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/clustering/{{node.host}}">{{node.host}}</a></td>
                         <td>{{node.lastRegistration}}</td>
+                        <td class="kc-action-cell">
+                            <button class="btn btn-default btn-block btn-sm" kc-open="/realms/{{realm.realm}}/clients/{{client.id}}/clustering/{{node.host}}">Edit</button>
+                        </td>
+                        <td class="kc-action-cell">
+                            <button class="btn btn-default btn-block btn-sm" data-ng-click="removeNode(node)">Delete</button>
+                        </td>
                     </tr>
                     <tr data-ng-show="!nodeRegistrations || nodeRegistrations.length == 0">
                         <td class="text-muted">No registered cluster nodes available</td>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering-node.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering-node.html
index 2a7d705..442fa0d 100644
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering-node.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering-node.html
@@ -3,26 +3,29 @@
         <li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
         <li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/clustering">Cluster Nodes</a></li>
-        <li>Add Node</li>
+        <li data-ng-show="create">Add Node</li>
+        <li data-ng-hide="create">{{node.host|capitalize}}</li>
     </ol>
 
+    <h1 data-ng-show="create">Add Node</h1>
+    <h1 data-ng-hide="create">
+        {{node.host|capitalize}}
+        <i id="removeClient" class="pficon pficon-delete clickable" data-ng-show="access.manageClients" data-ng-click="unregisterNode()"></i>
+    </h1>
+
     <form class="form-horizontal" name="clusteringForm" novalidate kc-read-only="!access.manageClients" data-ng-show="create || registered">
-        <fieldset >
-            <legend><span class="text">Configuration of cluster node<i class="pficon pficon-delete clickable" data-ng-show="access.manageRealm" 
-    			data-ng-hide="create" data-ng-click="unregisterNode()"></i></span></legend>
-            <div class="form-group">
-                <label class="col-md-2 control-label" for="host">Host</label>
-                <div class="col-sm-6">
-                    <input ng-disabled="!create" class="form-control" type="text" id="host" name="host" data-ng-model="node.host">
-                </div>
+        <div class="form-group">
+            <label class="col-md-2 control-label" for="host">Host</label>
+            <div class="col-sm-6">
+                <input ng-disabled="!create" class="form-control" type="text" id="host" name="host" data-ng-model="node.host">
             </div>
-            <div class="form-group">
-                <label class="col-md-2 control-label" for="lastRegistration">Last Registration</label>
-                <div class="col-sm-6">
-                    <input ng-disabled="true" class="form-control" type="text" id="lastRegistration" name="lastRegistration" data-ng-model="node.lastRegistration">
-                </div>
+        </div>
+        <div class="form-group">
+            <label class="col-md-2 control-label" for="lastRegistration">Last Registration</label>
+            <div class="col-sm-6">
+                <input ng-disabled="true" class="form-control" type="text" id="lastRegistration" name="lastRegistration" data-ng-model="node.lastRegistration">
             </div>
-        </fieldset>
+        </div>
         <div class="form-group">
             <div class="col-md-10 col-md-offset-2" data-ng-show="access.manageRealm">
                 <button data-kc-save data-ng-show="create">Save</button>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-list.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-list.html
index 9c1cb14..52917f5 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-list.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-list.html
@@ -7,7 +7,7 @@
     <table class="table table-striped table-bordered">
         <thead>
         <tr>
-            <th class="kc-table-actions" colspan="4">
+            <th class="kc-table-actions" colspan="5">
                 <div class="form-inline">
                     <div class="form-group">
                         <div class="input-group">
@@ -29,7 +29,7 @@
             <th>Client ID</th>
             <th>Enabled</th>
             <th>Base URL</th>
-            <th>Actions</th>
+            <th colspan="2">Actions</th>
         </tr>
         </thead>
         <tbody>
@@ -43,6 +43,9 @@
             <td class="kc-action-cell">
                 <button class="btn btn-default btn-block btn-sm" kc-open="/realms/{{realm.realm}}/clients/{{client.id}}">Edit</button>
             </td>
+            <td class="kc-action-cell">
+                <button class="btn btn-default btn-block btn-sm" data-ng-click="removeClient(client)">Delete</button>
+            </td>
         </tr>
         <tr data-ng-show="(clients | filter:search).length == 0">
             <td class="text-muted" colspan="3" data-ng-show="search.clientId">No results</td>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-mappers.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-mappers.html
index 88be5e1..3ef2ed3 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-mappers.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-mappers.html
@@ -10,7 +10,7 @@
     <table class="table table-striped table-bordered">
         <thead>
         <tr>
-            <th class="kc-table-actions" colspan="4">
+            <th class="kc-table-actions" colspan="6">
                 <div class="form-inline">
                     <div class="form-group">
                         <div class="input-group">
@@ -32,6 +32,7 @@
             <th>Name</th>
             <th>Category</th>
             <th>Type</th>
+            <th colspan="2">Actions</th>
         </tr>
         </thead>
         <tbody>
@@ -39,6 +40,12 @@
             <td><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/mappers/{{mapper.id}}">{{mapper.name}}</a></td>
             <td>{{mapperTypes[mapper.protocolMapper].category}}</td>
             <td>{{mapperTypes[mapper.protocolMapper].name}}</td>
+            <td class="kc-action-cell">
+                <button class="btn btn-default btn-block btn-sm" kc-open="/realms/{{realm.realm}}/clients/{{client.id}}/mappers/{{mapper.id}}">Edit</button>
+            </td>
+            <td class="kc-action-cell">
+                <button class="btn btn-default btn-block btn-sm" data-ng-click="removeMapper(mapper)">Delete</button>
+            </td>
         </tr>
         <tr data-ng-show="mappers.length == 0">
             <td>No mappers available</td>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-detail.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-detail.html
index e1ff683..469e8c6 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-detail.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-detail.html
@@ -1,7 +1,7 @@
 <div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
     <kc-tabs-realm></kc-tabs-realm>
 
-    <form class="form-horizontal " name="realmForm" novalidate kc-read-only="!access.manageRealm">
+    <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
             <div class="form-group">
                 <label class="col-md-2 control-label" for="name"><span class="required">*</span> Name</label>
                 <div class="col-md-6">
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html
index 8c817bc..b3b8139 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html
@@ -8,7 +8,7 @@
                     <caption class="hidden">Table of identity providers</caption>
                     <thead>
                     <tr>
-                        <th colspan="5" class="kc-table-actions">
+                        <th colspan="6" class="kc-table-actions">
                             <div class="dropdown pull-right">
                                 <select class="form-control" ng-model="provider"
                                         ng-options="p.name group by p.groupName for p in allProviders track by p.id"
@@ -23,7 +23,7 @@
                         <th>Provider</th>
                         <th>Enabled</th>
                         <th width="15%">GUI order</th>
-                        <th>Actions</th>
+                        <th colspan="2">Actions</th>
                     </tr>
                     </thead>
                     <tbody ng-show="configuredProviders.length > 0">
@@ -37,6 +37,9 @@
                         <td class="kc-action-cell">
                             <button class="btn btn-default btn-block btn-sm" kc-open="/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">Edit</button>
                         </td>
+                        <td class="kc-action-cell">
+                            <button class="btn btn-default btn-block btn-sm" data-ng-click="removeIdentityProvider(identityProvider)">Delete</button>
+                        </td>
                     </tr>
                     </tbody>
                 </table>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-tokens.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-tokens.html
index 4f5518d..56ed0d7 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-tokens.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-tokens.html
@@ -2,115 +2,107 @@
     <kc-tabs-realm></kc-tabs-realm>
 
     <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
-        <fieldset class="border-top">
-            <div class="form-group input-select">
-                <label class="col-md-2 control-label" for="ssoSessionIdleTimeout">SSO Session Idle Timeout</label>
-                <div class="col-sm-5">
-                    <div class="row">
-                        <div class="col-md-6 form-inline">
-                            <input class="form-control" type="number" required min="1"
-                                   max="31536000" data-ng-model="realm.ssoSessionIdleTimeout"
-                                   id="ssoSessionIdleTimeout" name="ssoSessionIdleTimeout"/>
-                            <select class="form-control" name="ssoSessionIdleTimeoutUnit" data-ng-model="realm.ssoSessionIdleTimeoutUnit" >
-                                <option data-ng-selected="!realm.ssoSessionIdleTimeoutUnit">Seconds</option>
-                                <option>Minutes</option>
-                                <option>Hours</option>
-                                <option>Days</option>
-                            </select>
-                        </div>
-                    </div>
-                </div>
-                <kc-tooltip>Time a session is allowed to be idle before it expires.  Tokens and browser sessions are invalidated when a session is expired.</kc-tooltip>
+
+        <div class="form-group">
+            <label class="col-md-2 control-label" for="ssoSessionIdleTimeout">SSO Session Idle</label>
+
+            <div class="col-md-6 time-selector">
+                <input class="form-control" type="number" required min="1" max="31536000" data-ng-model="realm.ssoSessionIdleTimeout" id="ssoSessionIdleTimeout"
+                       name="ssoSessionIdleTimeout"/>
+                <select class="form-control" name="ssoSessionIdleTimeoutUnit" data-ng-model="realm.ssoSessionIdleTimeoutUnit">
+                    <option data-ng-selected="!realm.ssoSessionIdleTimeoutUnit">Seconds</option>
+                    <option>Minutes</option>
+                    <option>Hours</option>
+                    <option>Days</option>
+                </select>
             </div>
-            <div class="form-group input-select">
-                <label class="col-md-2 control-label" for="ssoSessionMaxLifespan">SSO Session Max Lifespan</label>
-                <div class="col-sm-5">
-                    <div class="row">
-                        <div class="col-md-6 form-inline">
-                            <input class="form-control" type="number" required min="1"
-                                   max="31536000" data-ng-model="realm.ssoSessionMaxLifespan"
-                                   id="ssoSessionMaxLifespan" name="ssoSessionMaxLifespan"/>
-                            <select class="form-control" name="ssoSessionMaxLifespanUnit" data-ng-model="realm.ssoSessionMaxLifespanUnit" >
-                                <option data-ng-selected="!realm.ssoSessionMaxLifespanUnit">Seconds</option>
-                                <option>Minutes</option>
-                                <option>Hours</option>
-                                <option>Days</option>
-                            </select>
-                        </div>
-                    </div>
-                </div>
-                <kc-tooltip>Max time before a session is expired.  Tokens and browser sessions are invalidated when a session is expired.</kc-tooltip>
+            <kc-tooltip>Time a session is allowed to be idle before it expires. Tokens and browser sessions are invalidated when a session is expired.
+            </kc-tooltip>
+        </div>
+
+        <div class="form-group">
+            <label class="col-md-2 control-label" for="ssoSessionMaxLifespan">SSO Session Max</label>
+
+            <div class="col-md-6 time-selector">
+                <input class="form-control" type="number" required min="1"
+                       max="31536000" data-ng-model="realm.ssoSessionMaxLifespan"
+                       id="ssoSessionMaxLifespan" name="ssoSessionMaxLifespan"/>
+                <select class="form-control" name="ssoSessionMaxLifespanUnit" data-ng-model="realm.ssoSessionMaxLifespanUnit">
+                    <option data-ng-selected="!realm.ssoSessionMaxLifespanUnit">Seconds</option>
+                    <option>Minutes</option>
+                    <option>Hours</option>
+                    <option>Days</option>
+                </select>
             </div>
-            <div class="form-group input-select">
-                <label class="col-md-2 control-label" for="accessTokenLifespan">Access Token Lifespan</label>
-                <div class="col-sm-5">
-                    <div class="row">
-                        <div class="col-md-6 form-inline">
-                            <input class="form-control" type="number" required min="1"
-                                   max="31536000" data-ng-model="realm.accessTokenLifespan"
-                                   id="accessTokenLifespan" name="accessTokenLifespan"/>
-                            <select class="form-control" name="accessTokenLifespanUnit" data-ng-model="realm.accessTokenLifespanUnit" >
-                                <option data-ng-selected="!realm.accessTokenLifespanUnit">Seconds</option>
-                                <option>Minutes</option>
-                                <option>Hours</option>
-                                <option>Days</option>
-                            </select>
-                        </div>
-                    </div>
-                </div>
-                <kc-tooltip>Max time before an access token is expired.  This value is recommended to be short relative to the SSO timeout.</kc-tooltip>
+            <kc-tooltip>Max time before a session is expired. Tokens and browser sessions are invalidated when a session is expired.</kc-tooltip>
+        </div>
+
+        <div class="form-group">
+            <label class="col-md-2 control-label" for="accessTokenLifespan">Access Token Lifespan</label>
+
+            <div class="col-md-6 time-selector">
+                <input class="form-control" type="number" required min="1"
+                       max="31536000" data-ng-model="realm.accessTokenLifespan"
+                       id="accessTokenLifespan" name="accessTokenLifespan"/>
+                <select class="form-control" name="accessTokenLifespanUnit" data-ng-model="realm.accessTokenLifespanUnit">
+                    <option data-ng-selected="!realm.accessTokenLifespanUnit">Seconds</option>
+                    <option>Minutes</option>
+                    <option>Hours</option>
+                    <option>Days</option>
+                </select>
             </div>
-            <div class="form-group">
-                <label class="col-md-2 control-label" for="accessCodeLifespan">Client login timeout</label>
-                <div class="col-sm-5">
-                    <div class="row">
-                        <div class="col-md-6 form-inline">
-                            <input class="form-control" type="number" required min="1" max="31536000" data-ng-model="realm.accessCodeLifespan" id="accessCodeLifespan" name="accessCodeLifespan">
-                            <select class="form-control" name="accessCodeLifespanUnit" data-ng-model="realm.accessCodeLifespanUnit">
-                                <option data-ng-selected="!realm.accessCodeLifespanUnit">Seconds</option>
-                                <option>Minutes</option>
-                                <option>Hours</option>
-                                <option>Days</option>
-                            </select>
-                        </div>
-                    </div>
-                </div>
-                <kc-tooltip>Max time an client has to finish the access token protocol.  This should normally be 1 minute.</kc-tooltip>                </div>
-            <div class="form-group input-select">
-                <label class="col-md-2 control-label" for="accessCodeLifespanLogin" class="two-lines">Login lifespan</label>
-                <div class="col-sm-5">
-                    <div class="row">
-                        <div class="col-md-6 form-inline">
-                            <input class="form-control" type="number" required min="1" max="31536000" data-ng-model="realm.accessCodeLifespanLogin" id="accessCodeLifespanLogin" name="accessCodeLifespanLogin">
-                            <select class="form-control" name="accessCodeLifespanLoginUnit" data-ng-model="realm.accessCodeLifespanLoginUnit">
-                                <option data-ng-selected="!realm.accessCodeLifespanLoginUnit">Seconds</option>
-                                <option>Minutes</option>
-                                <option>Hours</option>
-                                <option>Days</option>
-                            </select>
-                        </div>
-                    </div>
-                </div>
-                <kc-tooltip>Max time a user has to complete a login.  This is recommended to be relatively long.  30 minutes or more.</kc-tooltip>
+            <kc-tooltip>Max time before an access token is expired. This value is recommended to be short relative to the SSO timeout.</kc-tooltip>
+        </div>
+
+        <div class="form-group">
+            <label class="col-md-2 control-label" for="accessCodeLifespan">Client login timeout</label>
+
+            <div class="col-md-6 time-selector">
+                <input class="form-control" type="number" required min="1" max="31536000" data-ng-model="realm.accessCodeLifespan" id="accessCodeLifespan"
+                       name="accessCodeLifespan">
+                <select class="form-control" name="accessCodeLifespanUnit" data-ng-model="realm.accessCodeLifespanUnit">
+                    <option data-ng-selected="!realm.accessCodeLifespanUnit">Seconds</option>
+                    <option>Minutes</option>
+                    <option>Hours</option>
+                    <option>Days</option>
+                </select>
             </div>
-            <div class="form-group input-select">
-                <label class="col-md-2 control-label" for="accessCodeLifespanUserAction" class="two-lines">Login user action lifespan</label>
-                <div class="col-sm-5">
-                    <div class="row">
-                        <div class="col-md-6 form-inline">
-                            <input class="form-control" type="number" required min="1" max="31536000" data-ng-model="realm.accessCodeLifespanUserAction" id="accessCodeLifespanUserAction" name="accessCodeLifespanUserAction">
-                            <select class="form-control" name="accessCodeLifespanUserActionUnit" data-ng-model="realm.accessCodeLifespanUserActionUnit">
-                                <option data-ng-selected="!realm.accessCodeLifespanUserActionUnit">Seconds</option>
-                                <option>Minutes</option>
-                                <option>Hours</option>
-                                <option>Days</option>
-                            </select>
-                        </div>
-                    </div>
-                </div>
-                <kc-tooltip>Max time a user has to complete login related actions like update password or configure totp.  This is recommended to be relatively long.  5 minutes or more.</kc-tooltip>
+            <kc-tooltip>Max time an client has to finish the access token protocol. This should normally be 1 minute.</kc-tooltip>
+        </div>
+
+        <div class="form-group">
+            <label class="col-md-2 control-label" for="accessCodeLifespanLogin" class="two-lines">Login timeout</label>
+
+            <div class="col-md-6 time-selector">
+                <input class="form-control" type="number" required min="1" max="31536000" data-ng-model="realm.accessCodeLifespanLogin"
+                       id="accessCodeLifespanLogin" name="accessCodeLifespanLogin">
+                <select class="form-control" name="accessCodeLifespanLoginUnit" data-ng-model="realm.accessCodeLifespanLoginUnit">
+                    <option data-ng-selected="!realm.accessCodeLifespanLoginUnit">Seconds</option>
+                    <option>Minutes</option>
+                    <option>Hours</option>
+                    <option>Days</option>
+                </select>
             </div>
-        </fieldset>
+            <kc-tooltip>Max time a user has to complete a login. This is recommended to be relatively long. 30 minutes or more.</kc-tooltip>
+        </div>
+
+        <div class="form-group">
+            <label class="col-md-2 control-label" for="accessCodeLifespanUserAction" class="two-lines">Login action timeout</label>
+
+            <div class="col-md-6 time-selector">
+                <input class="form-control" type="number" required min="1" max="31536000" data-ng-model="realm.accessCodeLifespanUserAction"
+                       id="accessCodeLifespanUserAction" name="accessCodeLifespanUserAction">
+                <select class="form-control" name="accessCodeLifespanUserActionUnit" data-ng-model="realm.accessCodeLifespanUserActionUnit">
+                    <option data-ng-selected="!realm.accessCodeLifespanUserActionUnit">Seconds</option>
+                    <option>Minutes</option>
+                    <option>Hours</option>
+                    <option>Days</option>
+                </select>
+            </div>
+            <kc-tooltip>
+                Max time a user has to complete login related actions like update password or configure totp. This is recommended to be relatively long. 5 minutes or more.
+            </kc-tooltip>
+        </div>
 
         <div class="form-group">
             <div class="col-md-10 col-md-offset-2" data-ng-show="access.manageRealm">
@@ -118,7 +110,9 @@
                 <button kc-reset data-ng-disabled="!changed">Cancel</button>
             </div>
         </div>
+
     </form>
+
 </div>
 
 <kc-menu></kc-menu>
\ No newline at end of file
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-list.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-list.html
index 3703023..668484b 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-list.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/role-list.html
@@ -9,7 +9,7 @@
     <table class="table table-striped table-bordered">
         <thead>
         <tr>
-            <th class="kc-table-actions" colspan="4">
+            <th class="kc-table-actions" colspan="5">
                 <div class="form-inline">
                     <div class="form-group">
                         <div class="input-group">
@@ -30,7 +30,7 @@
             <th>Role Name</th>
             <th>Composite</th>
             <th>Description</th>
-            <th>Actions</th>
+            <th colspan="2">Actions</th>
         </tr>
         </thead>
         <tbody>
@@ -41,6 +41,9 @@
             <td class="kc-action-cell">
                 <button class="btn btn-default btn-block btn-sm" kc-open="/realms/{{realm.realm}}/roles/{{role.id}}">Edit</button>
             </td>
+            <td class="kc-action-cell">
+                <button class="btn btn-default btn-block btn-sm" data-ng-click="removeRole(role)">Delete</button>
+            </td>
         </tr>
         <tr data-ng-show="(roles | filter:{name: searchQuery}).length == 0">
             <td class="text-muted" colspan="3" data-ng-show="searchQuery">No results</td>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-federation.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-federation.html
index 8738690..8a7a247 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-federation.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-federation.html
@@ -6,7 +6,7 @@
     <table class="table table-striped table-bordered">
         <thead>
         <tr ng-show="providers.length > 0 && access.manageUsers">
-            <th colspan="4" class="kc-table-actions">
+            <th colspan="5" class="kc-table-actions">
                 <div class="pull-right">
                     <div>
                         <select class="form-control" ng-model="selectedProvider"
@@ -22,7 +22,7 @@
             <th>ID</th>
             <th>Provider Name</th>
             <th>Priority</th>
-            <th>Actions</th>
+            <th colspan="2">Actions</th>
         </tr>
         </thead>
         <tbody>
@@ -33,6 +33,9 @@
             <td class="kc-action-cell">
                 <button class="btn btn-default btn-block btn-sm" kc-open="/realms/{{realm.realm}}/user-federation/providers/{{instance.providerName}}/{{instance.id}}">Edit</button>
             </td>
+            <td class="kc-action-cell">
+                <button class="btn btn-default btn-block btn-sm" data-ng-click="removeUserFederation(instance)">Delete</button>
+            </td>
          </tr>
         <tr data-ng-show="!instances || instances.length == 0">
             <td class="text-muted">No user federation providers configured</td>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-list.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-list.html
index 0d069e0..e8ac723 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-list.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/user-list.html
@@ -5,7 +5,7 @@
         <caption data-ng-show="users" class="hidden">Table of realm users</caption>
         <thead>
         <tr>
-            <th colspan="{{access.impersonation == true ? '6' : '5'}}">
+            <th colspan="{{access.impersonation == true ? '7' : '6'}}">
                 <div class="form-inline">
                     <div class="form-group">
                         <div class="input-group">
@@ -30,7 +30,7 @@
             <th>Last Name</th>
             <th>First Name</th>
             <th>Email</th>
-            <th colspan="{{access.impersonation == true ? '2' : '1'}}">Actions</th>
+            <th colspan="{{access.impersonation == true ? '3' : '2'}}">Actions</th>
         </tr>
         </tr>
         </thead>
@@ -57,6 +57,9 @@
             <td data-ng-show="access.impersonation" class="kc-action-cell">
                 <button class="btn btn-default btn-block btn-sm" data-ng-click="impersonate(user.id)" tooltip="Login as this user.  If user is in same realm as you, your current login session will be logged out before you are logged in as this user.">Impersonate</button>
             </td>
+            <td data-ng-show="access.manageUsers" class="kc-action-cell">
+                <button class="btn btn-default btn-block btn-sm" data-ng-click="removeUser(user)">Delete</button>
+            </td>
         </tr>
         <tr data-ng-show="!users || users.length == 0">
             <td class="text-muted" data-ng-show="!users">Please enter a search, or click on view all users</td>
diff --git a/forms/common-themes/src/main/resources/theme/keycloak/admin/resources/css/styles.css b/forms/common-themes/src/main/resources/theme/keycloak/admin/resources/css/styles.css
index 83f0929..30fb25a 100644
--- a/forms/common-themes/src/main/resources/theme/keycloak/admin/resources/css/styles.css
+++ b/forms/common-themes/src/main/resources/theme/keycloak/admin/resources/css/styles.css
@@ -312,4 +312,21 @@ h1 i {
     left: 0;
     right: 0;
     bottom: 0;
+}
+
+
+/* Time selector */
+
+.time-selector input {
+    display: inline-block;
+    width: 120px;
+    padding-right: 0;
+    margin-right: 0;
+}
+
+.time-selector select {
+    display: inline-block;
+    width: 80px;
+    margin-left: 0;
+    padding-left: 0;
 }
\ No newline at end of file