diff --git a/src/app/access-control/group-registry/groups-registry.component.ts b/src/app/access-control/group-registry/groups-registry.component.ts index b28ac043d9..9215399170 100644 --- a/src/app/access-control/group-registry/groups-registry.component.ts +++ b/src/app/access-control/group-registry/groups-registry.component.ts @@ -141,29 +141,35 @@ export class GroupsRegistryComponent implements OnInit, OnDestroy { if (groups.page.length === 0) { return observableOf(buildPaginatedList(groups.pageInfo, [])); } - return observableCombineLatest(groups.page.map((group: Group) => { - if (!this.deletedGroupsIds.includes(group.id)) { - return observableCombineLatest([ - this.authorizationService.isAuthorized(FeatureID.CanDelete, hasValue(group) ? group.self : undefined), - this.hasLinkedDSO(group), - this.getSubgroups(group), - this.getMembers(group) - ]).pipe( - map(([isAuthorized, hasLinkedDSO, subgroups, members]: - [boolean, boolean, RemoteData>, RemoteData>]) => { - const groupDtoModel: GroupDtoModel = new GroupDtoModel(); - groupDtoModel.ableToDelete = isAuthorized && !hasLinkedDSO; - groupDtoModel.group = group; - groupDtoModel.subgroups = subgroups.payload; - groupDtoModel.epersons = members.payload; - return groupDtoModel; - } - ) - ); - } - })).pipe(map((dtos: GroupDtoModel[]) => { - return buildPaginatedList(groups.pageInfo, dtos); - })); + return this.authorizationService.isAuthorized(FeatureID.AdministratorOf).pipe( + switchMap((isSiteAdmin: boolean) => { + return observableCombineLatest(groups.page.map((group: Group) => { + if (hasValue(group) && !this.deletedGroupsIds.includes(group.id)) { + return observableCombineLatest([ + this.authorizationService.isAuthorized(FeatureID.CanDelete, group.self), + this.canManageGroup$(isSiteAdmin, group), + this.hasLinkedDSO(group), + this.getSubgroups(group), + this.getMembers(group) + ]).pipe( + map(([canDelete, canManageGroup, hasLinkedDSO, subgroups, members]: + [boolean, boolean, boolean, RemoteData>, RemoteData>]) => { + const groupDtoModel: GroupDtoModel = new GroupDtoModel(); + groupDtoModel.ableToDelete = canDelete && !hasLinkedDSO; + groupDtoModel.ableToEdit = canManageGroup; + groupDtoModel.group = group; + groupDtoModel.subgroups = subgroups.payload; + groupDtoModel.epersons = members.payload; + return groupDtoModel; + } + ) + ); + } + })).pipe(map((dtos: GroupDtoModel[]) => { + return buildPaginatedList(groups.pageInfo, dtos); + })); + }) + ); }) ).subscribe((value: PaginatedList) => { this.groupsDto$.next(value); @@ -174,6 +180,14 @@ export class GroupsRegistryComponent implements OnInit, OnDestroy { this.subs.push(this.searchSub); } + canManageGroup$(isSiteAdmin: boolean, group: Group): Observable { + if (isSiteAdmin) { + return observableOf(true); + } else { + return this.authorizationService.isAuthorized(FeatureID.CanManageGroup, group.self); + } + } + /** * Delete Group */ diff --git a/src/app/core/data/feature-authorization/feature-id.ts b/src/app/core/data/feature-authorization/feature-id.ts index 6d070fcd4c..ac045b93b0 100644 --- a/src/app/core/data/feature-authorization/feature-id.ts +++ b/src/app/core/data/feature-authorization/feature-id.ts @@ -10,6 +10,7 @@ export enum FeatureID { ReinstateItem = 'reinstateItem', EPersonRegistration = 'epersonRegistration', CanManageGroups = 'canManageGroups', + CanManageGroup = 'canManageGroup', IsCollectionAdmin = 'isCollectionAdmin', IsCommunityAdmin = 'isCommunityAdmin', CanDownload = 'canDownload', diff --git a/src/app/core/eperson/models/group-dto.model.ts b/src/app/core/eperson/models/group-dto.model.ts index 47a70cf326..ef65c498fd 100644 --- a/src/app/core/eperson/models/group-dto.model.ts +++ b/src/app/core/eperson/models/group-dto.model.ts @@ -17,6 +17,11 @@ export class GroupDtoModel { */ public ableToDelete: boolean; + /** + * Whether or not the current user is able to edit the linked group + */ + public ableToEdit: boolean; + /** * List of subgroups of this group */