KEYCLOAK 2538 - UI group pagination
This commit is contained in:
parent
c8aa708cff
commit
2c24b39268
15 changed files with 384 additions and 240 deletions
|
@ -90,6 +90,19 @@ public interface GroupsResource {
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
Response count(@QueryParam("search") String search);
|
Response count(@QueryParam("search") String search);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counts groups by name search.
|
||||||
|
* @param search max number of occurrences
|
||||||
|
* @param onlyTopGroups <code>true</code> or <code>false</code> for filter only top level groups count
|
||||||
|
* @return The number of group containing search therm.
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@NoCache
|
||||||
|
@Path("/count")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
Response count(@QueryParam("search") String search, @QueryParam("top") String onlyTopGroups);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create or add a top level realm groupSet or create child. This will update the group and set the parent if it exists. Create it and set the parent
|
* create or add a top level realm groupSet or create child. This will update the group and set the parent if it exists. Create it and set the parent
|
||||||
* if the group doesn't exist.
|
* if the group doesn't exist.
|
||||||
|
|
|
@ -1213,8 +1213,8 @@ public class RealmAdapter implements CachedRealmModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long getGroupsCount() {
|
public Long getGroupsCount(Boolean onlyTopGroups) {
|
||||||
return cacheSession.getGroupsCount(this);
|
return cacheSession.getGroupsCount(this, onlyTopGroups);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -843,8 +843,8 @@ public class RealmCacheSession implements CacheRealmProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long getGroupsCount(RealmModel realm) {
|
public Long getGroupsCount(RealmModel realm, Boolean onlyTopGroups) {
|
||||||
return getDelegate().getGroupsCount(realm);
|
return getDelegate().getGroupsCount(realm, onlyTopGroups);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
package org.keycloak.models.jpa;
|
package org.keycloak.models.jpa;
|
||||||
|
|
||||||
|
import com.sun.org.apache.xpath.internal.operations.Bool;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.common.util.Time;
|
import org.keycloak.common.util.Time;
|
||||||
import org.keycloak.connections.jpa.util.JpaUtils;
|
import org.keycloak.connections.jpa.util.JpaUtils;
|
||||||
|
@ -339,8 +340,12 @@ public class JpaRealmProvider implements RealmProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long getGroupsCount(RealmModel realm) {
|
public Long getGroupsCount(RealmModel realm, Boolean onlyTopGroups) {
|
||||||
Long count = em.createNamedQuery("getGroupCount", Long.class)
|
String query = "getGroupCount";
|
||||||
|
if(Objects.equals(onlyTopGroups, Boolean.TRUE)) {
|
||||||
|
query = "getTopLevelGroupCount";
|
||||||
|
}
|
||||||
|
Long count = em.createNamedQuery(query, Long.class)
|
||||||
.setParameter("realm", realm.getId())
|
.setParameter("realm", realm.getId())
|
||||||
.getSingleResult();
|
.getSingleResult();
|
||||||
|
|
||||||
|
@ -577,7 +582,7 @@ public class JpaRealmProvider implements RealmProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<GroupModel> searchForGroupByName(RealmModel realm, String search, Integer first, Integer max) {
|
public List<GroupModel> searchForGroupByName(RealmModel realm, String search, Integer first, Integer max) {
|
||||||
TypedQuery<String> query = em.createNamedQuery("getGroupIdsByNameContaining", String.class)
|
TypedQuery<String> query = em.createNamedQuery("getTopLevelGroupIdsByNameContaining", String.class)
|
||||||
.setParameter("realm", realm.getId())
|
.setParameter("realm", realm.getId())
|
||||||
.setParameter("search", search);
|
.setParameter("search", search);
|
||||||
if(Objects.nonNull(first) && Objects.nonNull(max)) {
|
if(Objects.nonNull(first) && Objects.nonNull(max)) {
|
||||||
|
|
|
@ -1687,8 +1687,8 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long getGroupsCount() {
|
public Long getGroupsCount(Boolean onlyTopGroups) {
|
||||||
return session.realms().getGroupsCount(this);
|
return session.realms().getGroupsCount(this, onlyTopGroups);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -27,9 +27,10 @@ import java.util.Collection;
|
||||||
*/
|
*/
|
||||||
@NamedQueries({
|
@NamedQueries({
|
||||||
@NamedQuery(name="getGroupIdsByParent", query="select u.id from GroupEntity u where u.parent = :parent"),
|
@NamedQuery(name="getGroupIdsByParent", query="select u.id from GroupEntity u where u.parent = :parent"),
|
||||||
@NamedQuery(name="getGroupIdsByNameContaining", query="select u.id from GroupEntity u where u.realm.id = :realm and u.name like concat('%',:search,'%') order by u.name ASC"),
|
@NamedQuery(name="getTopLevelGroupIdsByNameContaining", query="select u.id from GroupEntity u where u.realm.id = :realm and u.name like concat('%',:search,'%') and u.parent is null order by u.name ASC"),
|
||||||
@NamedQuery(name="getTopLevelGroupIds", query="select u.id from GroupEntity u where u.parent is null and u.realm.id = :realm"),
|
@NamedQuery(name="getTopLevelGroupIds", query="select u.id from GroupEntity u where u.parent is null and u.realm.id = :realm"),
|
||||||
@NamedQuery(name="getGroupCount", query="select count(u) from GroupEntity u where u.realm.id = :realm"),
|
@NamedQuery(name="getGroupCount", query="select count(u) from GroupEntity u where u.realm.id = :realm"),
|
||||||
|
@NamedQuery(name="getTopLevelGroupCount", query="select count(u) from GroupEntity u where u.realm.id = :realm and u.parent is null"),
|
||||||
@NamedQuery(name="getGroupCountByNameContaining", query="select count(u) from GroupEntity u where u.realm.id = :realm and u.name like concat('%',:name,'%')"),
|
@NamedQuery(name="getGroupCountByNameContaining", query="select count(u) from GroupEntity u where u.realm.id = :realm and u.name like concat('%',:name,'%')"),
|
||||||
})
|
})
|
||||||
@Entity
|
@Entity
|
||||||
|
|
|
@ -400,7 +400,7 @@ public interface RealmModel extends RoleContainerModel {
|
||||||
|
|
||||||
GroupModel getGroupById(String id);
|
GroupModel getGroupById(String id);
|
||||||
List<GroupModel> getGroups();
|
List<GroupModel> getGroups();
|
||||||
Long getGroupsCount();
|
Long getGroupsCount(Boolean onlyTopGroups);
|
||||||
Long getGroupsCountByNameContaining(String search);
|
Long getGroupsCountByNameContaining(String search);
|
||||||
List<GroupModel> getTopLevelGroups();
|
List<GroupModel> getTopLevelGroups();
|
||||||
List<GroupModel> getTopLevelGroups(Integer first, Integer max);
|
List<GroupModel> getTopLevelGroups(Integer first, Integer max);
|
||||||
|
|
|
@ -40,7 +40,7 @@ public interface RealmProvider extends Provider {
|
||||||
|
|
||||||
List<GroupModel> getGroups(RealmModel realm);
|
List<GroupModel> getGroups(RealmModel realm);
|
||||||
|
|
||||||
Long getGroupsCount(RealmModel realm);
|
Long getGroupsCount(RealmModel realm, Boolean onlyTopGroups);
|
||||||
|
|
||||||
Long getGroupsCountByNameContaining(RealmModel realm, String search);
|
Long getGroupsCountByNameContaining(RealmModel realm, String search);
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.services.resources.admin;
|
package org.keycloak.services.resources.admin;
|
||||||
|
|
||||||
|
import org.apache.http.HttpStatus;
|
||||||
import org.jboss.resteasy.annotations.cache.NoCache;
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
import org.jboss.resteasy.spi.NotFoundException;
|
import org.jboss.resteasy.spi.NotFoundException;
|
||||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
|
@ -38,6 +39,8 @@ import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import org.keycloak.services.ErrorResponse;
|
import org.keycloak.services.ErrorResponse;
|
||||||
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
|
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
|
||||||
|
import twitter4j.JSONException;
|
||||||
|
import twitter4j.JSONObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @resource Groups
|
* @resource Groups
|
||||||
|
@ -111,15 +114,22 @@ public class GroupsResource {
|
||||||
@GET
|
@GET
|
||||||
@NoCache
|
@NoCache
|
||||||
@Path("/count")
|
@Path("/count")
|
||||||
public Response getGroupCount(@QueryParam("search") String search) {
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
auth.requireView();
|
public Response getGroupCount(@QueryParam("search") String search, @QueryParam("top") String onlyTopGroups) {
|
||||||
Long results;
|
Long results;
|
||||||
|
JSONObject response = new JSONObject();
|
||||||
if (Objects.nonNull(search)) {
|
if (Objects.nonNull(search)) {
|
||||||
results = realm.getGroupsCountByNameContaining(search);
|
results = realm.getGroupsCountByNameContaining(search);
|
||||||
} else {
|
} else {
|
||||||
results = realm.getGroupsCount();
|
results = realm.getGroupsCount(Objects.equals(onlyTopGroups, Boolean.TRUE.toString()));
|
||||||
}
|
}
|
||||||
return Response.ok(results).build();
|
try {
|
||||||
|
response.put("count", results);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return ErrorResponse.error("Cannot create response object", Response.Status.INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
return Response.ok(response.toString(), MediaType.APPLICATION_JSON).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1031,6 +1031,7 @@ group-membership.tooltip=Groups user is a member of. Select a listed group and c
|
||||||
membership.available-groups.tooltip=Groups a user can join. Select a group and click the join button.
|
membership.available-groups.tooltip=Groups a user can join. Select a group and click the join button.
|
||||||
table-of-realm-users=Table of Realm Users
|
table-of-realm-users=Table of Realm Users
|
||||||
view-all-users=View all users
|
view-all-users=View all users
|
||||||
|
view-all-groups=View all groups
|
||||||
unlock-users=Unlock users
|
unlock-users=Unlock users
|
||||||
no-users-available=No users available
|
no-users-available=No users available
|
||||||
users.instruction=Please enter a search, or click on view all users
|
users.instruction=Please enter a search, or click on view all users
|
||||||
|
|
|
@ -790,6 +790,9 @@ module.config([ '$routeProvider', function($routeProvider) {
|
||||||
},
|
},
|
||||||
groups : function(GroupListLoader) {
|
groups : function(GroupListLoader) {
|
||||||
return GroupListLoader();
|
return GroupListLoader();
|
||||||
|
},
|
||||||
|
groupsCount : function(GroupCountLoader) {
|
||||||
|
return GroupCountLoader();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
controller : 'GroupListCtrl'
|
controller : 'GroupListCtrl'
|
||||||
|
@ -1924,7 +1927,7 @@ module.factory('spinnerInterceptor', function($q, $window, $rootScope, $location
|
||||||
$('#loading').hide();
|
$('#loading').hide();
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
},
|
},
|
||||||
responseError: function(response) {
|
responseError: function(response) {
|
||||||
resourceRequests--;
|
resourceRequests--;
|
||||||
if (resourceRequests == 0) {
|
if (resourceRequests == 0) {
|
||||||
|
@ -1944,7 +1947,7 @@ module.factory('errorInterceptor', function($q, $window, $rootScope, $location,
|
||||||
return {
|
return {
|
||||||
response: function(response) {
|
response: function(response) {
|
||||||
return response;
|
return response;
|
||||||
},
|
},
|
||||||
responseError: function(response) {
|
responseError: function(response) {
|
||||||
if (response.status == 401) {
|
if (response.status == 401) {
|
||||||
Auth.authz.logout();
|
Auth.authz.logout();
|
||||||
|
@ -2186,17 +2189,17 @@ module.directive('kcEnter', function() {
|
||||||
|
|
||||||
module.directive('kcSave', function ($compile, $timeout, Notifications) {
|
module.directive('kcSave', function ($compile, $timeout, Notifications) {
|
||||||
var clickDelay = 500; // 500 ms
|
var clickDelay = 500; // 500 ms
|
||||||
|
|
||||||
return {
|
return {
|
||||||
restrict: 'A',
|
restrict: 'A',
|
||||||
link: function ($scope, elem, attr, ctrl) {
|
link: function ($scope, elem, attr, ctrl) {
|
||||||
elem.addClass("btn btn-primary");
|
elem.addClass("btn btn-primary");
|
||||||
elem.attr("type","submit");
|
elem.attr("type","submit");
|
||||||
|
|
||||||
var disabled = false;
|
var disabled = false;
|
||||||
elem.on('click', function(evt) {
|
elem.on('click', function(evt) {
|
||||||
if ($scope.hasOwnProperty("changed") && !$scope.changed) return;
|
if ($scope.hasOwnProperty("changed") && !$scope.changed) return;
|
||||||
|
|
||||||
// KEYCLOAK-4121: Prevent double form submission
|
// KEYCLOAK-4121: Prevent double form submission
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
|
@ -2206,7 +2209,7 @@ module.directive('kcSave', function ($compile, $timeout, Notifications) {
|
||||||
disabled = true;
|
disabled = true;
|
||||||
$timeout(function () { disabled = false; }, clickDelay, false);
|
$timeout(function () { disabled = false; }, clickDelay, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.$apply(function() {
|
$scope.$apply(function() {
|
||||||
var form = elem.closest('form');
|
var form = elem.closest('form');
|
||||||
if (form && form.attr('name')) {
|
if (form && form.attr('name')) {
|
||||||
|
@ -2869,35 +2872,35 @@ module.directive('kcOnReadFile', function ($parse) {
|
||||||
|
|
||||||
module.controller('PagingCtrl', function ($scope) {
|
module.controller('PagingCtrl', function ($scope) {
|
||||||
$scope.currentPageInput = 1;
|
$scope.currentPageInput = 1;
|
||||||
|
|
||||||
$scope.firstPage = function() {
|
$scope.firstPage = function() {
|
||||||
if (!$scope.hasPrevious()) return;
|
if (!$scope.hasPrevious()) return;
|
||||||
$scope.currentPage = 1;
|
$scope.currentPage = 1;
|
||||||
$scope.currentPageInput = 1;
|
$scope.currentPageInput = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.lastPage = function() {
|
$scope.lastPage = function() {
|
||||||
if (!$scope.hasNext()) return;
|
if (!$scope.hasNext()) return;
|
||||||
$scope.currentPage = $scope.numberOfPages;
|
$scope.currentPage = $scope.numberOfPages;
|
||||||
$scope.currentPageInput = $scope.numberOfPages;
|
$scope.currentPageInput = $scope.numberOfPages;
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.previousPage = function() {
|
$scope.previousPage = function() {
|
||||||
if (!$scope.hasPrevious()) return;
|
if (!$scope.hasPrevious()) return;
|
||||||
$scope.currentPage--;
|
$scope.currentPage--;
|
||||||
$scope.currentPageInput = $scope.currentPage;
|
$scope.currentPageInput = $scope.currentPage;
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.nextPage = function() {
|
$scope.nextPage = function() {
|
||||||
if (!$scope.hasNext()) return;
|
if (!$scope.hasNext()) return;
|
||||||
$scope.currentPage++;
|
$scope.currentPage++;
|
||||||
$scope.currentPageInput = $scope.currentPage;
|
$scope.currentPageInput = $scope.currentPage;
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.hasNext = function() {
|
$scope.hasNext = function() {
|
||||||
return $scope.currentPage < $scope.numberOfPages;
|
return $scope.currentPage < $scope.numberOfPages;
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.hasPrevious = function() {
|
$scope.hasPrevious = function() {
|
||||||
return $scope.currentPage > 1;
|
return $scope.currentPage > 1;
|
||||||
};
|
};
|
||||||
|
@ -2927,11 +2930,11 @@ module.directive('kcValidPage', function() {
|
||||||
if (viewValue >= 1 && viewValue <= scope.numberOfPages) {
|
if (viewValue >= 1 && viewValue <= scope.numberOfPages) {
|
||||||
scope.currentPage = viewValue;
|
scope.currentPage = viewValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// filter used for paged tables
|
// filter used for paged tables
|
||||||
|
|
|
@ -1,31 +1,104 @@
|
||||||
module.controller('GroupListCtrl', function($scope, $route, realm, groups, Groups, Group, GroupChildren, Notifications, $location, Dialog) {
|
module.controller('GroupListCtrl', function($scope, $route, $q, realm, groups, groupsCount, Groups, GroupsCount, Group, GroupChildren, Notifications, $location, Dialog) {
|
||||||
$scope.realm = realm;
|
$scope.realm = realm;
|
||||||
$scope.groupList = [
|
$scope.groupList = [
|
||||||
{"id" : "realm", "name": "Groups",
|
{
|
||||||
"subGroups" : groups}
|
"id" : "realm",
|
||||||
|
"name": "Groups",
|
||||||
|
"subGroups" : groups
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$scope.searchTerms = '';
|
||||||
|
$scope.currentPage = 1;
|
||||||
|
$scope.currentPageInput = $scope.currentPage;
|
||||||
|
$scope.pageSize = groups.length;
|
||||||
|
$scope.numberOfPages = Math.ceil(groupsCount.count/$scope.pageSize);
|
||||||
|
|
||||||
$scope.tree = [];
|
$scope.tree = [];
|
||||||
|
|
||||||
|
var refreshGroups = function (search) {
|
||||||
|
var queryParams = {
|
||||||
|
realm : realm.id,
|
||||||
|
first : ($scope.currentPage * $scope.pageSize) - $scope.pageSize,
|
||||||
|
max : $scope.pageSize
|
||||||
|
};
|
||||||
|
var countParams = {
|
||||||
|
realm : realm.id,
|
||||||
|
top : 'true'
|
||||||
|
};
|
||||||
|
|
||||||
|
if(angular.isDefined(search) && search !== '') {
|
||||||
|
queryParams.search = search;
|
||||||
|
countParams.search = search;
|
||||||
|
}
|
||||||
|
|
||||||
|
var promiseGetGroups = $q.defer();
|
||||||
|
Groups.query(queryParams, function(entry) {
|
||||||
|
promiseGetGroups.resolve(entry);
|
||||||
|
}, function() {
|
||||||
|
promiseGetGroups.reject('Unable to fetch ' + i);
|
||||||
|
});
|
||||||
|
var promiseGetGroupsChain = promiseGetGroups.promise.then(function(entry) {
|
||||||
|
groups = entry;
|
||||||
|
$scope.groupList = [
|
||||||
|
{
|
||||||
|
"id" : "realm",
|
||||||
|
"name": "Groups",
|
||||||
|
"subGroups" : groups
|
||||||
|
}
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
var promiseCount = $q.defer();
|
||||||
|
GroupsCount.query(countParams, function(entry) {
|
||||||
|
promiseCount.resolve(entry);
|
||||||
|
}, function() {
|
||||||
|
promiseCount.reject('Unable to fetch ' + i);
|
||||||
|
});
|
||||||
|
var promiseCountChain = promiseCount.promise.then(function(entry) {
|
||||||
|
groupsCount = entry;
|
||||||
|
$scope.numberOfPages = Math.ceil(groupsCount.count/$scope.pageSize);
|
||||||
|
});
|
||||||
|
|
||||||
|
$q.all([promiseGetGroupsChain, promiseCountChain]);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.$watch('currentPage', function(newValue, oldValue) {
|
||||||
|
if(newValue !== oldValue) {
|
||||||
|
refreshGroups();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.clearSearch = function() {
|
||||||
|
$scope.searchTerms = '';
|
||||||
|
$scope.currentPage = 1;
|
||||||
|
refreshGroups();
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.searchGroup = function() {
|
||||||
|
$scope.currentPage = 1;
|
||||||
|
refreshGroups($scope.searchTerms);
|
||||||
|
};
|
||||||
|
|
||||||
$scope.edit = function(selected) {
|
$scope.edit = function(selected) {
|
||||||
if (selected.id == 'realm') return;
|
if (selected.id === 'realm') return;
|
||||||
$location.url("/realms/" + realm.realm + "/groups/" + selected.id);
|
$location.url("/realms/" + realm.realm + "/groups/" + selected.id);
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.cut = function(selected) {
|
$scope.cut = function(selected) {
|
||||||
$scope.cutNode = selected;
|
$scope.cutNode = selected;
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.isDisabled = function() {
|
$scope.isDisabled = function() {
|
||||||
if (!$scope.tree.currentNode) return true;
|
if (!$scope.tree.currentNode) return true;
|
||||||
return $scope.tree.currentNode.id == 'realm';
|
return $scope.tree.currentNode.id === 'realm';
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.paste = function(selected) {
|
$scope.paste = function(selected) {
|
||||||
if (selected == null) return;
|
if (selected === null) return;
|
||||||
if ($scope.cutNode == null) return;
|
if ($scope.cutNode === null) return;
|
||||||
if (selected.id == $scope.cutNode.id) return;
|
if (selected.id === $scope.cutNode.id) return;
|
||||||
if (selected.id == 'realm') {
|
if (selected.id === 'realm') {
|
||||||
Groups.save({realm: realm.realm}, {id:$scope.cutNode.id}, function() {
|
Groups.save({realm: realm.realm}, {id:$scope.cutNode.id}, function() {
|
||||||
$route.reload();
|
$route.reload();
|
||||||
Notifications.success("Group moved.");
|
Notifications.success("Group moved.");
|
||||||
|
@ -41,10 +114,10 @@ module.controller('GroupListCtrl', function($scope, $route, realm, groups, Group
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.remove = function(selected) {
|
$scope.remove = function(selected) {
|
||||||
if (selected == null) return;
|
if (selected === null) return;
|
||||||
Dialog.confirmDelete(selected.name, 'group', function() {
|
Dialog.confirmDelete(selected.name, 'group', function() {
|
||||||
Group.remove({ realm: realm.realm, groupId : selected.id }, function() {
|
Group.remove({ realm: realm.realm, groupId : selected.id }, function() {
|
||||||
$route.reload();
|
$route.reload();
|
||||||
|
@ -52,7 +125,7 @@ module.controller('GroupListCtrl', function($scope, $route, realm, groups, Group
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.createGroup = function(selected) {
|
$scope.createGroup = function(selected) {
|
||||||
var parent = 'realm';
|
var parent = 'realm';
|
||||||
|
@ -61,13 +134,13 @@ module.controller('GroupListCtrl', function($scope, $route, realm, groups, Group
|
||||||
}
|
}
|
||||||
$location.url("/create/group/" + realm.realm + '/parent/' + parent);
|
$location.url("/create/group/" + realm.realm + '/parent/' + parent);
|
||||||
|
|
||||||
}
|
};
|
||||||
var isLeaf = function(node) {
|
var isLeaf = function(node) {
|
||||||
return node.id != "realm" && (!node.subGroups || node.subGroups.length == 0);
|
return node.id !== "realm" && (!node.subGroups || node.subGroups.length === 0);
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.getGroupClass = function(node) {
|
$scope.getGroupClass = function(node) {
|
||||||
if (node.id == "realm") {
|
if (node.id === "realm") {
|
||||||
return 'pficon pficon-users';
|
return 'pficon pficon-users';
|
||||||
}
|
}
|
||||||
if (isLeaf(node)) {
|
if (isLeaf(node)) {
|
||||||
|
@ -77,12 +150,12 @@ module.controller('GroupListCtrl', function($scope, $route, realm, groups, Group
|
||||||
if (node.subGroups.length && !node.collapsed) return 'expanded';
|
if (node.subGroups.length && !node.collapsed) return 'expanded';
|
||||||
return 'collapsed';
|
return 'collapsed';
|
||||||
|
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.getSelectedClass = function(node) {
|
$scope.getSelectedClass = function(node) {
|
||||||
if (node.selected) {
|
if (node.selected) {
|
||||||
return 'selected';
|
return 'selected';
|
||||||
} else if ($scope.cutNode && $scope.cutNode.id == node.id) {
|
} else if ($scope.cutNode && $scope.cutNode.id === node.id) {
|
||||||
return 'cut';
|
return 'cut';
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -95,8 +168,8 @@ module.controller('GroupCreateCtrl', function($scope, $route, realm, parentId, G
|
||||||
$scope.group = {};
|
$scope.group = {};
|
||||||
$scope.save = function() {
|
$scope.save = function() {
|
||||||
console.log('save!!!');
|
console.log('save!!!');
|
||||||
if (parentId == 'realm') {
|
if (parentId === 'realm') {
|
||||||
console.log('realm')
|
console.log('realm');
|
||||||
Groups.save({realm: realm.realm}, $scope.group, function(data, headers) {
|
Groups.save({realm: realm.realm}, $scope.group, function(data, headers) {
|
||||||
var l = headers().location;
|
var l = headers().location;
|
||||||
|
|
||||||
|
@ -120,7 +193,7 @@ module.controller('GroupCreateCtrl', function($scope, $route, realm, parentId, G
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
};
|
||||||
$scope.cancel = function() {
|
$scope.cancel = function() {
|
||||||
$location.url("/realms/" + realm.realm + "/groups");
|
$location.url("/realms/" + realm.realm + "/groups");
|
||||||
};
|
};
|
||||||
|
@ -176,8 +249,7 @@ module.controller('GroupDetailCtrl', function(Dialog, $scope, realm, group, Grou
|
||||||
var attrs = $scope.group.attributes;
|
var attrs = $scope.group.attributes;
|
||||||
for (var attribute in attrs) {
|
for (var attribute in attrs) {
|
||||||
if (typeof attrs[attribute] === "string") {
|
if (typeof attrs[attribute] === "string") {
|
||||||
var attrVals = attrs[attribute].split("##");
|
attrs[attribute] = attrs[attribute].split("##");
|
||||||
attrs[attribute] = attrVals;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,8 +258,7 @@ module.controller('GroupDetailCtrl', function(Dialog, $scope, realm, group, Grou
|
||||||
var attrs = group.attributes;
|
var attrs = group.attributes;
|
||||||
for (var attribute in attrs) {
|
for (var attribute in attrs) {
|
||||||
if (typeof attrs[attribute] === "object") {
|
if (typeof attrs[attribute] === "object") {
|
||||||
var attrVals = attrs[attribute].join("##");
|
attrs[attribute] = attrs[attribute].join("##");
|
||||||
attrs[attribute] = attrVals;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,8 +283,8 @@ module.controller('GroupDetailCtrl', function(Dialog, $scope, realm, group, Grou
|
||||||
});
|
});
|
||||||
|
|
||||||
module.controller('GroupRoleMappingCtrl', function($scope, $http, realm, group, clients, client, Notifications, GroupRealmRoleMapping,
|
module.controller('GroupRoleMappingCtrl', function($scope, $http, realm, group, clients, client, Notifications, GroupRealmRoleMapping,
|
||||||
GroupClientRoleMapping, GroupAvailableRealmRoleMapping, GroupAvailableClientRoleMapping,
|
GroupClientRoleMapping, GroupAvailableRealmRoleMapping, GroupAvailableClientRoleMapping,
|
||||||
GroupCompositeRealmRoleMapping, GroupCompositeClientRoleMapping) {
|
GroupCompositeRealmRoleMapping, GroupCompositeClientRoleMapping) {
|
||||||
$scope.realm = realm;
|
$scope.realm = realm;
|
||||||
$scope.group = group;
|
$scope.group = group;
|
||||||
$scope.selectedRealmRoles = [];
|
$scope.selectedRealmRoles = [];
|
||||||
|
@ -237,70 +308,70 @@ module.controller('GroupRoleMappingCtrl', function($scope, $http, realm, group,
|
||||||
$scope.selectedRealmRoles = [];
|
$scope.selectedRealmRoles = [];
|
||||||
$http.post(authUrl + '/admin/realms/' + realm.realm + '/groups/' + group.id + '/role-mappings/realm',
|
$http.post(authUrl + '/admin/realms/' + realm.realm + '/groups/' + group.id + '/role-mappings/realm',
|
||||||
roles).then(function() {
|
roles).then(function() {
|
||||||
$scope.realmMappings = GroupRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
$scope.realmMappings = GroupRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
$scope.realmRoles = GroupAvailableRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
$scope.realmRoles = GroupAvailableRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
$scope.realmComposite = GroupCompositeRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
$scope.realmComposite = GroupCompositeRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
$scope.selectedRealmMappings = [];
|
$scope.selectedRealmMappings = [];
|
||||||
$scope.selectRealmRoles = [];
|
$scope.selectRealmRoles = [];
|
||||||
if ($scope.targetClient) {
|
if ($scope.targetClient) {
|
||||||
console.log('load available');
|
console.log('load available');
|
||||||
$scope.clientComposite = GroupCompositeClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
$scope.clientComposite = GroupCompositeClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
||||||
$scope.clientRoles = GroupAvailableClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
$scope.clientRoles = GroupAvailableClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
||||||
$scope.clientMappings = GroupClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
$scope.clientMappings = GroupClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
||||||
$scope.selectedClientRoles = [];
|
$scope.selectedClientRoles = [];
|
||||||
$scope.selectedClientMappings = [];
|
$scope.selectedClientMappings = [];
|
||||||
}
|
}
|
||||||
Notifications.success("Role mappings updated.");
|
Notifications.success("Role mappings updated.");
|
||||||
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.deleteRealmRole = function() {
|
$scope.deleteRealmRole = function() {
|
||||||
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/groups/' + group.id + '/role-mappings/realm',
|
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/groups/' + group.id + '/role-mappings/realm',
|
||||||
{data : $scope.selectedRealmMappings, headers : {"content-type" : "application/json"}}).then(function() {
|
{data : $scope.selectedRealmMappings, headers : {"content-type" : "application/json"}}).then(function() {
|
||||||
$scope.realmMappings = GroupRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
$scope.realmMappings = GroupRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
$scope.realmRoles = GroupAvailableRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
$scope.realmRoles = GroupAvailableRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
$scope.realmComposite = GroupCompositeRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
$scope.realmComposite = GroupCompositeRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
$scope.selectedRealmMappings = [];
|
$scope.selectedRealmMappings = [];
|
||||||
$scope.selectRealmRoles = [];
|
$scope.selectRealmRoles = [];
|
||||||
if ($scope.targetClient) {
|
if ($scope.targetClient) {
|
||||||
console.log('load available');
|
console.log('load available');
|
||||||
$scope.clientComposite = GroupCompositeClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
$scope.clientComposite = GroupCompositeClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
||||||
$scope.clientRoles = GroupAvailableClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
$scope.clientRoles = GroupAvailableClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
||||||
$scope.clientMappings = GroupClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
$scope.clientMappings = GroupClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
||||||
$scope.selectedClientRoles = [];
|
$scope.selectedClientRoles = [];
|
||||||
$scope.selectedClientMappings = [];
|
$scope.selectedClientMappings = [];
|
||||||
}
|
}
|
||||||
Notifications.success("Role mappings updated.");
|
Notifications.success("Role mappings updated.");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.addClientRole = function() {
|
$scope.addClientRole = function() {
|
||||||
$http.post(authUrl + '/admin/realms/' + realm.realm + '/groups/' + group.id + '/role-mappings/clients/' + $scope.targetClient.id,
|
$http.post(authUrl + '/admin/realms/' + realm.realm + '/groups/' + group.id + '/role-mappings/clients/' + $scope.targetClient.id,
|
||||||
$scope.selectedClientRoles).then(function() {
|
$scope.selectedClientRoles).then(function() {
|
||||||
$scope.clientMappings = GroupClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
$scope.clientMappings = GroupClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
||||||
$scope.clientRoles = GroupAvailableClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
$scope.clientRoles = GroupAvailableClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
||||||
$scope.clientComposite = GroupCompositeClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
$scope.clientComposite = GroupCompositeClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
||||||
$scope.selectedClientRoles = [];
|
$scope.selectedClientRoles = [];
|
||||||
$scope.selectedClientMappings = [];
|
$scope.selectedClientMappings = [];
|
||||||
$scope.realmComposite = GroupCompositeRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
$scope.realmComposite = GroupCompositeRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
$scope.realmRoles = GroupAvailableRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
$scope.realmRoles = GroupAvailableRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
Notifications.success("Role mappings updated.");
|
Notifications.success("Role mappings updated.");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.deleteClientRole = function() {
|
$scope.deleteClientRole = function() {
|
||||||
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/groups/' + group.id + '/role-mappings/clients/' + $scope.targetClient.id,
|
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/groups/' + group.id + '/role-mappings/clients/' + $scope.targetClient.id,
|
||||||
{data : $scope.selectedClientMappings, headers : {"content-type" : "application/json"}}).then(function() {
|
{data : $scope.selectedClientMappings, headers : {"content-type" : "application/json"}}).then(function() {
|
||||||
$scope.clientMappings = GroupClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
$scope.clientMappings = GroupClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
||||||
$scope.clientRoles = GroupAvailableClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
$scope.clientRoles = GroupAvailableClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
||||||
$scope.clientComposite = GroupCompositeClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
$scope.clientComposite = GroupCompositeClientRoleMapping.query({realm : realm.realm, groupId : group.id, client : $scope.targetClient.id});
|
||||||
$scope.selectedClientRoles = [];
|
$scope.selectedClientRoles = [];
|
||||||
$scope.selectedClientMappings = [];
|
$scope.selectedClientMappings = [];
|
||||||
$scope.realmComposite = GroupCompositeRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
$scope.realmComposite = GroupCompositeRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
$scope.realmRoles = GroupAvailableRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
$scope.realmRoles = GroupAvailableRealmRoleMapping.query({realm : realm.realm, groupId : group.id});
|
||||||
Notifications.success("Role mappings updated.");
|
Notifications.success("Role mappings updated.");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -332,13 +403,13 @@ module.controller('GroupMembersCtrl', function($scope, realm, group, GroupMember
|
||||||
groupId: group.id,
|
groupId: group.id,
|
||||||
max : 5,
|
max : 5,
|
||||||
first : 0
|
first : 0
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
$scope.firstPage = function() {
|
$scope.firstPage = function() {
|
||||||
$scope.query.first = 0;
|
$scope.query.first = 0;
|
||||||
$scope.searchQuery();
|
$scope.searchQuery();
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.previousPage = function() {
|
$scope.previousPage = function() {
|
||||||
$scope.query.first -= parseInt($scope.query.max);
|
$scope.query.first -= parseInt($scope.query.max);
|
||||||
|
@ -346,12 +417,12 @@ module.controller('GroupMembersCtrl', function($scope, realm, group, GroupMember
|
||||||
$scope.query.first = 0;
|
$scope.query.first = 0;
|
||||||
}
|
}
|
||||||
$scope.searchQuery();
|
$scope.searchQuery();
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.nextPage = function() {
|
$scope.nextPage = function() {
|
||||||
$scope.query.first += parseInt($scope.query.max);
|
$scope.query.first += parseInt($scope.query.max);
|
||||||
$scope.searchQuery();
|
$scope.searchQuery();
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.searchQuery = function() {
|
$scope.searchQuery = function() {
|
||||||
console.log("query.search: " + $scope.query.search);
|
console.log("query.search: " + $scope.query.search);
|
||||||
|
@ -368,7 +439,7 @@ module.controller('GroupMembersCtrl', function($scope, realm, group, GroupMember
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.controller('DefaultGroupsCtrl', function($scope, $route, realm, groups, DefaultGroups, Notifications, $location, Dialog) {
|
module.controller('DefaultGroupsCtrl', function($scope, $route, realm, groups, DefaultGroups, Notifications) {
|
||||||
$scope.realm = realm;
|
$scope.realm = realm;
|
||||||
$scope.groupList = groups;
|
$scope.groupList = groups;
|
||||||
$scope.selectedGroup = null;
|
$scope.selectedGroup = null;
|
||||||
|
@ -383,7 +454,7 @@ module.controller('DefaultGroupsCtrl', function($scope, $route, realm, groups, D
|
||||||
if (!$scope.tree.currentNode) {
|
if (!$scope.tree.currentNode) {
|
||||||
Notifications.error('Please select a group to add');
|
Notifications.error('Please select a group to add');
|
||||||
return;
|
return;
|
||||||
};
|
}
|
||||||
|
|
||||||
DefaultGroups.update({realm: realm.realm, groupId: $scope.tree.currentNode.id}, function() {
|
DefaultGroups.update({realm: realm.realm, groupId: $scope.tree.currentNode.id}, function() {
|
||||||
Notifications.success('Added default group');
|
Notifications.success('Added default group');
|
||||||
|
@ -401,11 +472,11 @@ module.controller('DefaultGroupsCtrl', function($scope, $route, realm, groups, D
|
||||||
};
|
};
|
||||||
|
|
||||||
var isLeaf = function(node) {
|
var isLeaf = function(node) {
|
||||||
return node.id != "realm" && (!node.subGroups || node.subGroups.length == 0);
|
return node.id !== "realm" && (!node.subGroups || node.subGroups.length === 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.getGroupClass = function(node) {
|
$scope.getGroupClass = function(node) {
|
||||||
if (node.id == "realm") {
|
if (node.id === "realm") {
|
||||||
return 'pficon pficon-users';
|
return 'pficon pficon-users';
|
||||||
}
|
}
|
||||||
if (isLeaf(node)) {
|
if (isLeaf(node)) {
|
||||||
|
@ -415,12 +486,12 @@ module.controller('DefaultGroupsCtrl', function($scope, $route, realm, groups, D
|
||||||
if (node.subGroups.length && !node.collapsed) return 'expanded';
|
if (node.subGroups.length && !node.collapsed) return 'expanded';
|
||||||
return 'collapsed';
|
return 'collapsed';
|
||||||
|
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.getSelectedClass = function(node) {
|
$scope.getSelectedClass = function(node) {
|
||||||
if (node.selected) {
|
if (node.selected) {
|
||||||
return 'selected';
|
return 'selected';
|
||||||
} else if ($scope.cutNode && $scope.cutNode.id == node.id) {
|
} else if ($scope.cutNode && $scope.cutNode.id === node.id) {
|
||||||
return 'cut';
|
return 'cut';
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|
|
@ -15,7 +15,7 @@ module.factory('Loader', function($q) {
|
||||||
});
|
});
|
||||||
return delay.promise;
|
return delay.promise;
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
loader.query = function(service, id) {
|
loader.query = function(service, id) {
|
||||||
return function() {
|
return function() {
|
||||||
var i = id && id();
|
var i = id && id();
|
||||||
|
@ -27,7 +27,7 @@ module.factory('Loader', function($q) {
|
||||||
});
|
});
|
||||||
return delay.promise;
|
return delay.promise;
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
return loader;
|
return loader;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -490,7 +490,18 @@ module.factory('AuthenticationConfigLoader', function(Loader, AuthenticationConf
|
||||||
module.factory('GroupListLoader', function(Loader, Groups, $route, $q) {
|
module.factory('GroupListLoader', function(Loader, Groups, $route, $q) {
|
||||||
return Loader.query(Groups, function() {
|
return Loader.query(Groups, function() {
|
||||||
return {
|
return {
|
||||||
realm : $route.current.params.realm
|
realm : $route.current.params.realm,
|
||||||
|
first : 1,
|
||||||
|
max : 20
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('GroupCountLoader', function(Loader, GroupsCount, $route, $q) {
|
||||||
|
return Loader.query(GroupsCount, function() {
|
||||||
|
return {
|
||||||
|
realm : $route.current.params.realm,
|
||||||
|
top : 'true'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
var module = angular.module('keycloak.services', [ 'ngResource', 'ngRoute' ]);
|
var module = angular.module('keycloak.services', [ 'ngResource', 'ngRoute' ]);
|
||||||
|
|
||||||
module.service('Dialog', function($modal) {
|
module.service('Dialog', function($modal) {
|
||||||
var dialog = {};
|
var dialog = {};
|
||||||
|
|
||||||
var openDialog = function(title, message, btns, template) {
|
var openDialog = function(title, message, btns, template) {
|
||||||
var controller = function($scope, $modalInstance, title, message, btns) {
|
var controller = function($scope, $modalInstance, title, message, btns) {
|
||||||
|
@ -36,15 +36,15 @@ module.service('Dialog', function($modal) {
|
||||||
}).result;
|
}).result;
|
||||||
}
|
}
|
||||||
|
|
||||||
var escapeHtml = function(str) {
|
var escapeHtml = function(str) {
|
||||||
var div = document.createElement('div');
|
var div = document.createElement('div');
|
||||||
div.appendChild(document.createTextNode(str));
|
div.appendChild(document.createTextNode(str));
|
||||||
return div.innerHTML;
|
return div.innerHTML;
|
||||||
};
|
};
|
||||||
|
|
||||||
dialog.confirmDelete = function(name, type, success) {
|
dialog.confirmDelete = function(name, type, success) {
|
||||||
var title = 'Delete ' + escapeHtml(type.charAt(0).toUpperCase() + type.slice(1));
|
var title = 'Delete ' + escapeHtml(type.charAt(0).toUpperCase() + type.slice(1));
|
||||||
var msg = 'Are you sure you want to permanently delete the ' + type + ' ' + name + '?';
|
var msg = 'Are you sure you want to permanently delete the ' + type + ' ' + name + '?';
|
||||||
var btns = {
|
var btns = {
|
||||||
ok: {
|
ok: {
|
||||||
label: 'Delete',
|
label: 'Delete',
|
||||||
|
@ -57,7 +57,7 @@ module.service('Dialog', function($modal) {
|
||||||
}
|
}
|
||||||
|
|
||||||
openDialog(title, msg, btns, '/templates/kc-modal.html').then(success);
|
openDialog(title, msg, btns, '/templates/kc-modal.html').then(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog.confirmGenerateKeys = function(name, type, success) {
|
dialog.confirmGenerateKeys = function(name, type, success) {
|
||||||
var title = 'Generate new keys for realm';
|
var title = 'Generate new keys for realm';
|
||||||
|
@ -138,10 +138,10 @@ module.service('CopyDialog', function($modal) {
|
||||||
});
|
});
|
||||||
|
|
||||||
module.factory('Notifications', function($rootScope, $timeout) {
|
module.factory('Notifications', function($rootScope, $timeout) {
|
||||||
// time (in ms) the notifications are shown
|
// time (in ms) the notifications are shown
|
||||||
var delay = 5000;
|
var delay = 5000;
|
||||||
|
|
||||||
var notifications = {};
|
var notifications = {};
|
||||||
notifications.current = { display: false };
|
notifications.current = { display: false };
|
||||||
notifications.current.remove = function() {
|
notifications.current.remove = function() {
|
||||||
if (notifications.scheduled) {
|
if (notifications.scheduled) {
|
||||||
|
@ -157,9 +157,9 @@ module.factory('Notifications', function($rootScope, $timeout) {
|
||||||
|
|
||||||
$rootScope.notification = notifications.current;
|
$rootScope.notification = notifications.current;
|
||||||
|
|
||||||
notifications.message = function(type, header, message) {
|
notifications.message = function(type, header, message) {
|
||||||
notifications.current.remove();
|
notifications.current.remove();
|
||||||
|
|
||||||
notifications.current.type = type;
|
notifications.current.type = type;
|
||||||
notifications.current.header = header;
|
notifications.current.header = header;
|
||||||
notifications.current.message = message;
|
notifications.current.message = message;
|
||||||
|
@ -170,25 +170,25 @@ module.factory('Notifications', function($rootScope, $timeout) {
|
||||||
}, delay);
|
}, delay);
|
||||||
|
|
||||||
console.debug("Added message");
|
console.debug("Added message");
|
||||||
}
|
}
|
||||||
|
|
||||||
notifications.info = function(message) {
|
notifications.info = function(message) {
|
||||||
notifications.message("info", "Info!", message);
|
notifications.message("info", "Info!", message);
|
||||||
};
|
};
|
||||||
|
|
||||||
notifications.success = function(message) {
|
notifications.success = function(message) {
|
||||||
notifications.message("success", "Success!", message);
|
notifications.message("success", "Success!", message);
|
||||||
};
|
};
|
||||||
|
|
||||||
notifications.error = function(message) {
|
notifications.error = function(message) {
|
||||||
notifications.message("danger", "Error!", message);
|
notifications.message("danger", "Error!", message);
|
||||||
};
|
};
|
||||||
|
|
||||||
notifications.warn = function(message) {
|
notifications.warn = function(message) {
|
||||||
notifications.message("warning", "Warning!", message);
|
notifications.message("warning", "Warning!", message);
|
||||||
};
|
};
|
||||||
|
|
||||||
return notifications;
|
return notifications;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -237,12 +237,12 @@ module.factory('ComponentUtils', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
module.factory('Realm', function($resource) {
|
module.factory('Realm', function($resource) {
|
||||||
return $resource(authUrl + '/admin/realms/:id', {
|
return $resource(authUrl + '/admin/realms/:id', {
|
||||||
id : '@realm'
|
id : '@realm'
|
||||||
}, {
|
}, {
|
||||||
update : {
|
update : {
|
||||||
method : 'PUT'
|
method : 'PUT'
|
||||||
},
|
},
|
||||||
create : {
|
create : {
|
||||||
method : 'POST',
|
method : 'POST',
|
||||||
params : { id : ''}
|
params : { id : ''}
|
||||||
|
@ -325,9 +325,9 @@ module.factory('RealmSMTPConnectionTester', function($resource) {
|
||||||
realm : '@realm',
|
realm : '@realm',
|
||||||
config : '@config'
|
config : '@config'
|
||||||
}, {
|
}, {
|
||||||
send: {
|
send: {
|
||||||
method: 'POST'
|
method: 'POST'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -777,67 +777,67 @@ function roleControl($scope, realm, role, roles, clients,
|
||||||
$scope.addRealmRole = function() {
|
$scope.addRealmRole = function() {
|
||||||
$scope.compositeSwitchDisabled=true;
|
$scope.compositeSwitchDisabled=true;
|
||||||
$http.post(authUrl + '/admin/realms/' + realm.realm + '/roles-by-id/' + role.id + '/composites',
|
$http.post(authUrl + '/admin/realms/' + realm.realm + '/roles-by-id/' + role.id + '/composites',
|
||||||
$scope.selectedRealmRoles).then(function() {
|
$scope.selectedRealmRoles).then(function() {
|
||||||
for (var i = 0; i < $scope.selectedRealmRoles.length; i++) {
|
for (var i = 0; i < $scope.selectedRealmRoles.length; i++) {
|
||||||
var role = $scope.selectedRealmRoles[i];
|
var role = $scope.selectedRealmRoles[i];
|
||||||
var idx = $scope.realmRoles.indexOf($scope.selectedRealmRoles[i]);
|
var idx = $scope.realmRoles.indexOf($scope.selectedRealmRoles[i]);
|
||||||
if (idx != -1) {
|
if (idx != -1) {
|
||||||
$scope.realmRoles.splice(idx, 1);
|
$scope.realmRoles.splice(idx, 1);
|
||||||
$scope.realmMappings.push(role);
|
$scope.realmMappings.push(role);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$scope.selectedRealmRoles = [];
|
}
|
||||||
Notifications.success("Role added to composite.");
|
$scope.selectedRealmRoles = [];
|
||||||
});
|
Notifications.success("Role added to composite.");
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.deleteRealmRole = function() {
|
$scope.deleteRealmRole = function() {
|
||||||
$scope.compositeSwitchDisabled=true;
|
$scope.compositeSwitchDisabled=true;
|
||||||
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/roles-by-id/' + role.id + '/composites',
|
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/roles-by-id/' + role.id + '/composites',
|
||||||
{data : $scope.selectedRealmMappings, headers : {"content-type" : "application/json"}}).then(function() {
|
{data : $scope.selectedRealmMappings, headers : {"content-type" : "application/json"}}).then(function() {
|
||||||
for (var i = 0; i < $scope.selectedRealmMappings.length; i++) {
|
for (var i = 0; i < $scope.selectedRealmMappings.length; i++) {
|
||||||
var role = $scope.selectedRealmMappings[i];
|
var role = $scope.selectedRealmMappings[i];
|
||||||
var idx = $scope.realmMappings.indexOf($scope.selectedRealmMappings[i]);
|
var idx = $scope.realmMappings.indexOf($scope.selectedRealmMappings[i]);
|
||||||
if (idx != -1) {
|
if (idx != -1) {
|
||||||
$scope.realmMappings.splice(idx, 1);
|
$scope.realmMappings.splice(idx, 1);
|
||||||
$scope.realmRoles.push(role);
|
$scope.realmRoles.push(role);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$scope.selectedRealmMappings = [];
|
}
|
||||||
Notifications.success("Role removed from composite.");
|
$scope.selectedRealmMappings = [];
|
||||||
});
|
Notifications.success("Role removed from composite.");
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.addClientRole = function() {
|
$scope.addClientRole = function() {
|
||||||
$scope.compositeSwitchDisabled=true;
|
$scope.compositeSwitchDisabled=true;
|
||||||
$http.post(authUrl + '/admin/realms/' + realm.realm + '/roles-by-id/' + role.id + '/composites',
|
$http.post(authUrl + '/admin/realms/' + realm.realm + '/roles-by-id/' + role.id + '/composites',
|
||||||
$scope.selectedClientRoles).then(function() {
|
$scope.selectedClientRoles).then(function() {
|
||||||
for (var i = 0; i < $scope.selectedClientRoles.length; i++) {
|
for (var i = 0; i < $scope.selectedClientRoles.length; i++) {
|
||||||
var role = $scope.selectedClientRoles[i];
|
var role = $scope.selectedClientRoles[i];
|
||||||
var idx = $scope.clientRoles.indexOf($scope.selectedClientRoles[i]);
|
var idx = $scope.clientRoles.indexOf($scope.selectedClientRoles[i]);
|
||||||
if (idx != -1) {
|
if (idx != -1) {
|
||||||
$scope.clientRoles.splice(idx, 1);
|
$scope.clientRoles.splice(idx, 1);
|
||||||
$scope.clientMappings.push(role);
|
$scope.clientMappings.push(role);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$scope.selectedClientRoles = [];
|
}
|
||||||
});
|
$scope.selectedClientRoles = [];
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.deleteClientRole = function() {
|
$scope.deleteClientRole = function() {
|
||||||
$scope.compositeSwitchDisabled=true;
|
$scope.compositeSwitchDisabled=true;
|
||||||
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/roles-by-id/' + role.id + '/composites',
|
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/roles-by-id/' + role.id + '/composites',
|
||||||
{data : $scope.selectedClientMappings, headers : {"content-type" : "application/json"}}).then(function() {
|
{data : $scope.selectedClientMappings, headers : {"content-type" : "application/json"}}).then(function() {
|
||||||
for (var i = 0; i < $scope.selectedClientMappings.length; i++) {
|
for (var i = 0; i < $scope.selectedClientMappings.length; i++) {
|
||||||
var role = $scope.selectedClientMappings[i];
|
var role = $scope.selectedClientMappings[i];
|
||||||
var idx = $scope.clientMappings.indexOf($scope.selectedClientMappings[i]);
|
var idx = $scope.clientMappings.indexOf($scope.selectedClientMappings[i]);
|
||||||
if (idx != -1) {
|
if (idx != -1) {
|
||||||
$scope.clientMappings.splice(idx, 1);
|
$scope.clientMappings.splice(idx, 1);
|
||||||
$scope.clientRoles.push(role);
|
$scope.clientRoles.push(role);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$scope.selectedClientMappings = [];
|
}
|
||||||
});
|
$scope.selectedClientMappings = [];
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1054,10 +1054,10 @@ module.factory('ClientTestNodesAvailable', function($resource) {
|
||||||
|
|
||||||
module.factory('ClientCertificate', function($resource) {
|
module.factory('ClientCertificate', function($resource) {
|
||||||
return $resource(authUrl + '/admin/realms/:realm/clients/:client/certificates/:attribute', {
|
return $resource(authUrl + '/admin/realms/:realm/clients/:client/certificates/:attribute', {
|
||||||
realm : '@realm',
|
realm : '@realm',
|
||||||
client : "@client",
|
client : "@client",
|
||||||
attribute: "@attribute"
|
attribute: "@attribute"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
module.factory('ClientCertificateGenerate', function($resource) {
|
module.factory('ClientCertificateGenerate', function($resource) {
|
||||||
|
@ -1075,10 +1075,10 @@ module.factory('ClientCertificateGenerate', function($resource) {
|
||||||
|
|
||||||
module.factory('ClientCertificateDownload', function($resource) {
|
module.factory('ClientCertificateDownload', function($resource) {
|
||||||
return $resource(authUrl + '/admin/realms/:realm/clients/:client/certificates/:attribute/download', {
|
return $resource(authUrl + '/admin/realms/:realm/clients/:client/certificates/:attribute/download', {
|
||||||
realm : '@realm',
|
realm : '@realm',
|
||||||
client : "@client",
|
client : "@client",
|
||||||
attribute: "@attribute"
|
attribute: "@attribute"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
download : {
|
download : {
|
||||||
method : 'POST',
|
method : 'POST',
|
||||||
|
@ -1142,9 +1142,9 @@ module.factory('ClientInstallationJBoss', function($resource) {
|
||||||
var url = authUrl + '/admin/realms/:realm/clients/:client/installation/jboss';
|
var url = authUrl + '/admin/realms/:realm/clients/:client/installation/jboss';
|
||||||
return {
|
return {
|
||||||
url : function(parameters)
|
url : function(parameters)
|
||||||
{
|
{
|
||||||
return url.replace(':realm', parameters.realm).replace(':client', parameters.client);
|
return url.replace(':realm', parameters.realm).replace(':client', parameters.client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1606,10 +1606,26 @@ module.factory('GroupChildren', function($resource) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
module.factory('GroupsCount', function($resource) {
|
||||||
|
return $resource(authUrl + '/admin/realms/:realm/groups/count', {
|
||||||
|
realm : '@realm'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
query: {
|
||||||
|
isArray: false,
|
||||||
|
method: 'GET',
|
||||||
|
params: {},
|
||||||
|
transformResponse: function (data) {
|
||||||
|
return angular.fromJson(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
module.factory('Groups', function($resource) {
|
module.factory('Groups', function($resource) {
|
||||||
return $resource(authUrl + '/admin/realms/:realm/groups', {
|
return $resource(authUrl + '/admin/realms/:realm/groups', {
|
||||||
realm : '@realm'
|
realm : '@realm'
|
||||||
});
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
module.factory('GroupRealmRoleMapping', function($resource) {
|
module.factory('GroupRealmRoleMapping', function($resource) {
|
||||||
|
|
|
@ -1,37 +1,50 @@
|
||||||
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
||||||
<kc-tabs-group-list></kc-tabs-group-list>
|
<kc-tabs-group-list></kc-tabs-group-list>
|
||||||
|
|
||||||
<table class="table table-striped table-bordered">
|
<table class="table table-striped table-bordered" style="margin-bottom: 0">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="kc-table-actions" colspan="5">
|
<th class="kc-table-actions" colspan="5">
|
||||||
<div class="form-inline">
|
<div class="form-inline">
|
||||||
<div class="pull-right" data-ng-show="access.manageUsers">
|
<div class="form-group">
|
||||||
<button id="createGroup" class="btn btn-default" ng-click="createGroup(tree.currentNode)">{{:: 'new' | translate}}</button>
|
<div class="input-group">
|
||||||
<button id="editGroup" ng-disabled="isDisabled()" class="btn btn-default" ng-click="edit(tree.currentNode)">{{:: 'edit' | translate}}</button>
|
<input type="text" placeholder="{{:: 'search.placeholder' | translate}}" ng-model="searchTerms" class="form-control search" onkeydown="if (event.keyCode == 13) document.getElementById('groupSearch').click()">
|
||||||
<button id="cutGroup" ng-disabled="isDisabled()" class="btn btn-default" ng-click="cut(tree.currentNode)">{{:: 'cut' | translate}}</button>
|
<div class="input-group-addon">
|
||||||
<button id="pasteGroup" ng-disabled="!cutNode" class="btn btn-default" ng-click="paste(tree.currentNode)">{{:: 'paste' | translate}}</button>
|
<i class="fa fa-search" id="groupSearch" ng-click="searchGroup()"></i>
|
||||||
<button id="removeGroup" ng-disabled="isDisabled()" class="btn btn-default" ng-click="remove(tree.currentNode)">{{:: 'delete' | translate}}</button>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
<button id="viewAllGroups" class="btn btn-default" ng-click="clearSearch()">{{:: 'view-all-groups' | translate}}</button>
|
||||||
</tr>
|
<div class="pull-right" data-ng-show="access.manageUsers">
|
||||||
</thead>
|
<div class="form-inline">
|
||||||
<tbody>
|
<button id="createGroup" class="btn btn-default" ng-click="createGroup(tree.currentNode)">{{:: 'new' | translate}}</button>
|
||||||
<tr>
|
<button id="editGroup" ng-disabled="isDisabled()" class="btn btn-default" ng-click="edit(tree.currentNode)">{{:: 'edit' | translate}}</button>
|
||||||
<td> <div
|
<button id="cutGroup" ng-disabled="isDisabled()" class="btn btn-default" ng-click="cut(tree.currentNode)">{{:: 'cut' | translate}}</button>
|
||||||
tree-id="tree"
|
<button id="pasteGroup" ng-disabled="!cutNode" class="btn btn-default" ng-click="paste(tree.currentNode)">{{:: 'paste' | translate}}</button>
|
||||||
|
<button id="removeGroup" ng-disabled="isDisabled()" class="btn btn-default" ng-click="remove(tree.currentNode)">{{:: 'delete' | translate}}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div tree-id="tree"
|
||||||
angular-treeview="true"
|
angular-treeview="true"
|
||||||
tree-model="groupList"
|
tree-model="groupList"
|
||||||
node-id="id"
|
node-id="id"
|
||||||
node-label="name"
|
node-label="name"
|
||||||
node-children="subGroups" >
|
node-children="subGroups" >
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<div style="margin-bottom: 50px">
|
||||||
</div>
|
<kc-paging current-page="currentPage" number-of-pages="numberOfPages" current-page-input="currentPageInput"></kc-paging>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<kc-menu></kc-menu>
|
<kc-menu></kc-menu>
|
Loading…
Reference in a new issue