Skip to content
Snippets Groups Projects
Commit 6f75ab62 authored by Marie Verdonck's avatar Marie Verdonck
Browse files

69111: bug fix isMemberOf, notifications add/delete member/group, group count...

69111: bug fix isMemberOf, notifications add/delete member/group, group count added to member count, bug fix disappearing group table in registry after leaving edit
parent 8e3699f6
Branches
No related merge requests found
......@@ -290,6 +290,14 @@
"admin.access-control.groups.form.members-list.table.edit.buttons.remove": "Remove member with name \"{{name}}\"",
"admin.access-control.groups.form.members-list.notification.success.addMember": "Successfully added member: \"{{name}}\"",
"admin.access-control.groups.form.members-list.notification.failure.addMember": "Failed to add member: \"{{name}}\"",
"admin.access-control.groups.form.members-list.notification.success.deleteMember": "Successfully deleted member: \"{{name}}\"",
"admin.access-control.groups.form.members-list.notification.failure.deleteMember": "Failed to delete member: \"{{name}}\"",
"admin.access-control.groups.form.members-list.table.edit.buttons.add": "Add member with name \"{{name}}\"",
"admin.access-control.groups.form.members-list.notification.failure.noActiveGroup": "No current active group, submit a name first.",
......@@ -316,6 +324,14 @@
"admin.access-control.groups.form.subgroups-list.table.edit.buttons.add": "Add subgroup with name \"{{name}}\"",
"admin.access-control.groups.form.subgroups-list.notification.success.addSubgroup": "Successfully added subgroup: \"{{name}}\"",
"admin.access-control.groups.form.subgroups-list.notification.failure.addSubgroup": "Failed to add subgroup: \"{{name}}\"",
"admin.access-control.groups.form.subgroups-list.notification.success.deleteSubgroup": "Successfully deleted subgroup: \"{{name}}\"",
"admin.access-control.groups.form.subgroups-list.notification.failure.deleteSubgroup": "Failed to delete subgroup: \"{{name}}\"",
"admin.access-control.groups.form.subgroups-list.notification.failure.noActiveGroup": "No current active group, submit a name first.",
"admin.access-control.groups.form.subgroups-list.no-items": "No groups found with this in their name or this as UUID",
......
......@@ -3,6 +3,7 @@ import { FormBuilder } from '@angular/forms';
import { TranslateService } from '@ngx-translate/core';
import { Observable, of as observableOf, Subscription } from 'rxjs';
import { map, mergeMap, take } from 'rxjs/operators';
import { RestResponse } from '../../../../../core/cache/response.models';
import { PaginatedList } from '../../../../../core/data/paginated-list';
import { RemoteData } from '../../../../../core/data/remote-data';
import { EPersonDataService } from '../../../../../core/eperson/eperson-data.service';
......@@ -101,7 +102,8 @@ export class MembersListComponent implements OnInit, OnDestroy {
deleteMemberFromGroup(ePerson: EPerson) {
this.groupDataService.getActiveGroup().pipe(take(1)).subscribe((activeGroup: Group) => {
if (activeGroup != null) {
this.groupDataService.deleteMemberFromGroup(activeGroup, ePerson);
const response = this.groupDataService.deleteMemberFromGroup(activeGroup, ePerson);
this.showNotifications('deleteMember', response, ePerson.name, activeGroup);
this.forceUpdateEPeople(activeGroup);
} else {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.noActiveGroup'));
......@@ -116,7 +118,8 @@ export class MembersListComponent implements OnInit, OnDestroy {
addMemberToGroup(ePerson: EPerson) {
this.groupDataService.getActiveGroup().pipe(take(1)).subscribe((activeGroup: Group) => {
if (activeGroup != null) {
this.groupDataService.addMemberToGroup(activeGroup, ePerson);
const response = this.groupDataService.addMemberToGroup(activeGroup, ePerson);
this.showNotifications('addMember', response, ePerson.name, activeGroup);
this.forceUpdateEPeople(activeGroup);
} else {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.noActiveGroup'));
......@@ -132,15 +135,15 @@ export class MembersListComponent implements OnInit, OnDestroy {
return this.groupDataService.getActiveGroup().pipe(take(1),
mergeMap((group: Group) => {
if (group != null) {
return this.groupDataService.findAllByHref(possibleMember._links.groups.href, {
return this.ePersonDataService.findAllByHref(group._links.epersons.href, {
currentPage: 0,
elementsPerPage: Number.MAX_SAFE_INTEGER
})
.pipe(
getSucceededRemoteData(),
getRemoteDataPayload(),
map((listTotalGroups: PaginatedList<Group>) => listTotalGroups.page.filter((groupInList: Group) => groupInList.id === group.id)),
map((groups: Group[]) => groups.length > 0))
map((listEPeopleInGroup: PaginatedList<EPerson>) => listEPeopleInGroup.page.filter((ePersonInList: EPerson) => ePersonInList.id === possibleMember.id)),
map((epeople: EPerson[]) => epeople.length > 0))
} else {
return observableOf(false);
}
......@@ -179,4 +182,21 @@ export class MembersListComponent implements OnInit, OnDestroy {
ngOnDestroy(): void {
this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
}
/**
* Shows a notification based on the success/failure of the request
* @param messageSuffix Suffix for message
* @param response RestResponse observable containing success/failure request
* @param nameObject Object request was about
* @param activeGroup Group currently being edited
*/
showNotifications(messageSuffix: string, response: Observable<RestResponse>, nameObject: string, activeGroup: Group) {
response.pipe(take(1)).subscribe((restResponse: RestResponse) => {
if (restResponse.isSuccessful) {
this.notificationsService.success(this.translateService.get(this.messagePrefix + '.notification.success.' + messageSuffix, { name: nameObject }));
} else {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.' + messageSuffix, { name: nameObject }));
}
})
}
}
......@@ -3,6 +3,7 @@ import { FormBuilder } from '@angular/forms';
import { TranslateService } from '@ngx-translate/core';
import { Observable, of as observableOf, Subscription } from 'rxjs';
import { map, mergeMap, take } from 'rxjs/operators';
import { RestResponse } from '../../../../../core/cache/response.models';
import { PaginatedList } from '../../../../../core/data/paginated-list';
import { RemoteData } from '../../../../../core/data/remote-data';
import { GroupDataService } from '../../../../../core/eperson/group-data.service';
......@@ -121,7 +122,8 @@ export class SubgroupsListComponent implements OnInit, OnDestroy {
deleteSubgroupFromGroup(subgroup: Group) {
this.groupDataService.getActiveGroup().pipe(take(1)).subscribe((activeGroup: Group) => {
if (activeGroup != null) {
this.groupDataService.deleteSubGroupFromGroup(activeGroup, subgroup);
const response = this.groupDataService.deleteSubGroupFromGroup(activeGroup, subgroup);
this.showNotifications('addSubgroup', response, subgroup.name, activeGroup);
this.forceUpdateGroups(activeGroup);
} else {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.noActiveGroup'));
......@@ -136,7 +138,8 @@ export class SubgroupsListComponent implements OnInit, OnDestroy {
addSubgroupToGroup(subgroup: Group) {
this.groupDataService.getActiveGroup().pipe(take(1)).subscribe((activeGroup: Group) => {
if (activeGroup != null) {
this.groupDataService.addSubGroupToGroup(activeGroup, subgroup);
const response = this.groupDataService.addSubGroupToGroup(activeGroup, subgroup);
this.showNotifications('deleteSubgroup', response, subgroup.name, activeGroup);
this.forceUpdateGroups(activeGroup);
} else {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.noActiveGroup'));
......@@ -175,4 +178,21 @@ export class SubgroupsListComponent implements OnInit, OnDestroy {
ngOnDestroy(): void {
this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
}
/**
* Shows a notification based on the success/failure of the request
* @param messageSuffix Suffix for message
* @param response RestResponse observable containing success/failure request
* @param nameObject Object request was about
* @param activeGroup Group currently being edited
*/
showNotifications(messageSuffix: string, response: Observable<RestResponse>, nameObject: string, activeGroup: Group) {
response.pipe(take(1)).subscribe((restResponse: RestResponse) => {
if (restResponse.isSuccessful) {
this.notificationsService.success(this.translateService.get(this.messagePrefix + '.notification.success.' + messageSuffix, { name: nameObject }));
} else {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.' + messageSuffix, { name: nameObject }));
}
})
}
}
......@@ -50,7 +50,7 @@
<tr *ngFor="let group of (groups | async)?.payload?.page">
<td>{{group.id}}</td>
<td>{{group.name}}</td>
<td>{{(getMembers(group) | async)?.payload?.totalElements}}</td>
<td>{{(getMembers(group) | async)?.payload?.totalElements + (getSubgroups(group) | async)?.payload?.totalElements}}</td>
<!-- <td>{{getOptionalComColFromName(group.name)}}</td>-->
<td>
<div class="btn-group edit-field">
......
import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { TranslateService } from '@ngx-translate/core';
import { Observable } from 'rxjs';
......@@ -22,7 +22,7 @@ import { followLink } from '../../../shared/utils/follow-link-config.model';
* A component used for managing all existing groups within the repository.
* The admin can create, edit or delete groups here.
*/
export class GroupsRegistryComponent {
export class GroupsRegistryComponent implements OnInit {
messagePrefix = 'admin.access-control.groups.';
......@@ -48,13 +48,16 @@ export class GroupsRegistryComponent {
private translateService: TranslateService,
private notificationsService: NotificationsService,
private formBuilder: FormBuilder) {
this.searchForm = this.formBuilder.group(({
query: '',
}));
}
ngOnInit() {
this.updateGroups({
currentPage: 1,
elementsPerPage: this.config.pageSize
});
this.searchForm = this.formBuilder.group(({
query: '',
}));
}
/**
......@@ -72,7 +75,7 @@ export class GroupsRegistryComponent {
* Update the list of groups by fetching it from the rest api or cache
*/
private updateGroups(options) {
this.groups = this.groupService.getGroups(options, followLink('epersons'));
this.groups = this.groupService.getGroups(options, followLink('epersons'), followLink('groups'));
}
/**
......@@ -115,13 +118,21 @@ export class GroupsRegistryComponent {
}
/**
* Get the amount of members (epersons embedded value of a group)
* Get the members (epersons embedded value of a group)
* @param group
*/
getMembers(group: Group): Observable<RemoteData<PaginatedList<EPerson>>> {
return this.ePersonDataService.findAllByHref(group._links.epersons.href);
}
/**
* Get the subgroups (groups embedded value of a group)
* @param group
*/
getSubgroups(group: Group): Observable<RemoteData<PaginatedList<Group>>> {
return this.groupService.findAllByHref(group._links.groups.href);
}
/**
* Extract optional UUID from a group name => To be resolved to community or collection with link
* (Or will be resolved in backend and added to group object, tbd) //TODO
......
......@@ -16,15 +16,17 @@ import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { SearchParam } from '../cache/models/search-param.model';
import { ObjectCacheService } from '../cache/object-cache.service';
import { RestResponse } from '../cache/response.models';
import { DataService } from '../data/data.service';
import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service';
import { PaginatedList } from '../data/paginated-list';
import { RemoteData } from '../data/remote-data';
import { DeleteRequest, FindListOptions, FindListRequest, PostRequest } from '../data/request.models';
import { DeleteRequest, FindListOptions, FindListRequest, PostRequest, RestRequest } from '../data/request.models';
import { RequestService } from '../data/request.service';
import { HttpOptions } from '../dspace-rest-v2/dspace-rest-v2.service';
import { HALEndpointService } from '../shared/hal-endpoint.service';
import { getResponseFromEntry } from '../shared/operators';
import { EPerson } from './models/eperson.model';
import { Group } from './models/group.model';
import { dataService } from '../cache/builders/build-decorators';
......@@ -154,7 +156,7 @@ export class GroupDataService extends DataService<Group> {
* @param activeGroup Group we want to add subgroup to
* @param subgroup Group we want to add as subgroup to activeGroup
*/
addSubGroupToGroup(activeGroup: Group, subgroup: Group) {
addSubGroupToGroup(activeGroup: Group, subgroup: Group): Observable<RestResponse> {
const requestId = this.requestService.generateRequestId();
const options: HttpOptions = Object.create({});
let headers = new HttpHeaders();
......@@ -162,6 +164,8 @@ export class GroupDataService extends DataService<Group> {
options.headers = headers;
const postRequest = new PostRequest(requestId, activeGroup.self + '/' + this.subgroupsEndpoint, subgroup.self, options);
this.requestService.configure(postRequest);
return this.fetchResponse(requestId);
}
/**
......@@ -169,10 +173,12 @@ export class GroupDataService extends DataService<Group> {
* @param activeGroup Group we want to delete subgroup from
* @param subgroup Subgroup we want to delete from activeGroup
*/
deleteSubGroupFromGroup(activeGroup: Group, subgroup: Group) {
deleteSubGroupFromGroup(activeGroup: Group, subgroup: Group): Observable<RestResponse> {
const requestId = this.requestService.generateRequestId();
const deleteRequest = new DeleteRequest(requestId, activeGroup.self + '/' + this.subgroupsEndpoint + '/' + subgroup.id);
this.requestService.configure(deleteRequest);
return this.fetchResponse(requestId);
}
/**
......@@ -180,7 +186,7 @@ export class GroupDataService extends DataService<Group> {
* @param activeGroup Group we want to add member to
* @param ePerson EPerson we want to add as member to given activeGroup
*/
addMemberToGroup(activeGroup: Group, ePerson: EPerson) {
addMemberToGroup(activeGroup: Group, ePerson: EPerson): Observable<RestResponse> {
const requestId = this.requestService.generateRequestId();
const options: HttpOptions = Object.create({});
let headers = new HttpHeaders();
......@@ -188,6 +194,8 @@ export class GroupDataService extends DataService<Group> {
options.headers = headers;
const postRequest = new PostRequest(requestId, activeGroup.self + '/' + this.ePersonsEndpoint, ePerson.self, options);
this.requestService.configure(postRequest);
return this.fetchResponse(requestId);
}
/**
......@@ -195,10 +203,25 @@ export class GroupDataService extends DataService<Group> {
* @param activeGroup Group we want to delete member from
* @param ePerson EPerson we want to delete from members of given activeGroup
*/
deleteMemberFromGroup(activeGroup: Group, ePerson: EPerson) {
deleteMemberFromGroup(activeGroup: Group, ePerson: EPerson): Observable<RestResponse> {
const requestId = this.requestService.generateRequestId();
const deleteRequest = new DeleteRequest(requestId, activeGroup.self + '/' + this.ePersonsEndpoint + '/' + ePerson.id);
this.requestService.configure(deleteRequest);
return this.fetchResponse(requestId);
}
/**
* Gets the restResponse from the requestService
* @param requestId
*/
protected fetchResponse(requestId: string): Observable<RestResponse> {
return this.requestService.getByUUID(requestId).pipe(
getResponseFromEntry(),
map((response: RestResponse) => {
return response;
})
);
}
/**
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment