mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
Refactor members-list and subgroups-list components to use new isNotMemberOf endpoints (via services)
(cherry picked from commit 8a10888d2a
)
This commit is contained in:

committed by
github-actions[bot]
![github-actions[bot]](/assets/img/avatar_default.png)
parent
1f1dc59f8b
commit
4a1f2a1b75
@@ -15,14 +15,8 @@
|
|||||||
</h4>
|
</h4>
|
||||||
|
|
||||||
<form [formGroup]="searchForm" (ngSubmit)="search(searchForm.value)" class="d-flex justify-content-between">
|
<form [formGroup]="searchForm" (ngSubmit)="search(searchForm.value)" class="d-flex justify-content-between">
|
||||||
<div>
|
<div class="flex-grow-1 mr-3">
|
||||||
<select name="scope" id="scope" formControlName="scope" class="form-control" aria-label="Search scope">
|
<div class="form-group input-group mr-3">
|
||||||
<option value="metadata">{{messagePrefix + '.search.scope.metadata' | translate}}</option>
|
|
||||||
<option value="email">{{messagePrefix + '.search.scope.email' | translate}}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="flex-grow-1 mr-3 ml-3">
|
|
||||||
<div class="form-group input-group">
|
|
||||||
<input type="text" name="query" id="query" formControlName="query"
|
<input type="text" name="query" id="query" formControlName="query"
|
||||||
class="form-control" aria-label="Search input">
|
class="form-control" aria-label="Search input">
|
||||||
<span class="input-group-append">
|
<span class="input-group-append">
|
||||||
|
@@ -56,7 +56,7 @@ describe('MembersListComponent', () => {
|
|||||||
return createSuccessfulRemoteDataObject$(buildPaginatedList<EPerson>(new PageInfo(), groupsDataServiceStub.getEPersonMembers()));
|
return createSuccessfulRemoteDataObject$(buildPaginatedList<EPerson>(new PageInfo(), groupsDataServiceStub.getEPersonMembers()));
|
||||||
},
|
},
|
||||||
// This method is used to search across *non-members*
|
// This method is used to search across *non-members*
|
||||||
searchByScope(scope: string, query: string): Observable<RemoteData<PaginatedList<EPerson>>> {
|
searchNonMembers(query: string, group: string): Observable<RemoteData<PaginatedList<EPerson>>> {
|
||||||
if (query === '') {
|
if (query === '') {
|
||||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), epersonNonMembers));
|
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), epersonNonMembers));
|
||||||
}
|
}
|
||||||
|
@@ -124,7 +124,6 @@ export class MembersListComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
// Current search in edit group - epeople search form
|
// Current search in edit group - epeople search form
|
||||||
currentSearchQuery: string;
|
currentSearchQuery: string;
|
||||||
currentSearchScope: string;
|
|
||||||
|
|
||||||
// Whether or not user has done a EPeople search yet
|
// Whether or not user has done a EPeople search yet
|
||||||
searchDone: boolean;
|
searchDone: boolean;
|
||||||
@@ -143,12 +142,10 @@ export class MembersListComponent implements OnInit, OnDestroy {
|
|||||||
public dsoNameService: DSONameService,
|
public dsoNameService: DSONameService,
|
||||||
) {
|
) {
|
||||||
this.currentSearchQuery = '';
|
this.currentSearchQuery = '';
|
||||||
this.currentSearchScope = 'metadata';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.searchForm = this.formBuilder.group(({
|
this.searchForm = this.formBuilder.group(({
|
||||||
scope: 'metadata',
|
|
||||||
query: '',
|
query: '',
|
||||||
}));
|
}));
|
||||||
this.subs.set(SubKey.ActiveGroup, this.groupDataService.getActiveGroup().subscribe((activeGroup: Group) => {
|
this.subs.set(SubKey.ActiveGroup, this.groupDataService.getActiveGroup().subscribe((activeGroup: Group) => {
|
||||||
@@ -213,6 +210,11 @@ export class MembersListComponent implements OnInit, OnDestroy {
|
|||||||
if (activeGroup != null) {
|
if (activeGroup != null) {
|
||||||
const response = this.groupDataService.deleteMemberFromGroup(activeGroup, eperson);
|
const response = this.groupDataService.deleteMemberFromGroup(activeGroup, eperson);
|
||||||
this.showNotifications('deleteMember', response, this.dsoNameService.getName(eperson), activeGroup);
|
this.showNotifications('deleteMember', response, this.dsoNameService.getName(eperson), activeGroup);
|
||||||
|
// Reload search results (if there is an active query).
|
||||||
|
// This will potentially add this deleted subgroup into the list of search results.
|
||||||
|
if (this.currentSearchQuery != null) {
|
||||||
|
this.search({query: this.currentSearchQuery});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.noActiveGroup'));
|
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.noActiveGroup'));
|
||||||
}
|
}
|
||||||
@@ -228,6 +230,11 @@ export class MembersListComponent implements OnInit, OnDestroy {
|
|||||||
if (activeGroup != null) {
|
if (activeGroup != null) {
|
||||||
const response = this.groupDataService.addMemberToGroup(activeGroup, eperson);
|
const response = this.groupDataService.addMemberToGroup(activeGroup, eperson);
|
||||||
this.showNotifications('addMember', response, this.dsoNameService.getName(eperson), activeGroup);
|
this.showNotifications('addMember', response, this.dsoNameService.getName(eperson), activeGroup);
|
||||||
|
// Reload search results (if there is an active query).
|
||||||
|
// This will potentially add this deleted subgroup into the list of search results.
|
||||||
|
if (this.currentSearchQuery != null) {
|
||||||
|
this.search({query: this.currentSearchQuery});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.noActiveGroup'));
|
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.noActiveGroup'));
|
||||||
}
|
}
|
||||||
@@ -235,17 +242,15 @@ export class MembersListComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search in the EPeople by name, email or metadata
|
* Search all EPeople who are NOT a member of the current group by name, email or metadata
|
||||||
* @param data Contains scope and query param
|
* @param data Contains query param
|
||||||
*/
|
*/
|
||||||
search(data: any) {
|
search(data: any) {
|
||||||
this.unsubFrom(SubKey.SearchResults);
|
this.unsubFrom(SubKey.SearchResults);
|
||||||
this.subs.set(SubKey.SearchResults,
|
this.subs.set(SubKey.SearchResults,
|
||||||
this.paginationService.getCurrentPagination(this.configSearch.id, this.configSearch).pipe(
|
this.paginationService.getCurrentPagination(this.configSearch.id, this.configSearch).pipe(
|
||||||
switchMap((paginationOptions) => {
|
switchMap((paginationOptions) => {
|
||||||
|
|
||||||
const query: string = data.query;
|
const query: string = data.query;
|
||||||
const scope: string = data.scope;
|
|
||||||
if (query != null && this.currentSearchQuery !== query && this.groupBeingEdited) {
|
if (query != null && this.currentSearchQuery !== query && this.groupBeingEdited) {
|
||||||
this.router.navigate([], {
|
this.router.navigate([], {
|
||||||
queryParamsHandling: 'merge'
|
queryParamsHandling: 'merge'
|
||||||
@@ -253,19 +258,12 @@ export class MembersListComponent implements OnInit, OnDestroy {
|
|||||||
this.currentSearchQuery = query;
|
this.currentSearchQuery = query;
|
||||||
this.paginationService.resetPage(this.configSearch.id);
|
this.paginationService.resetPage(this.configSearch.id);
|
||||||
}
|
}
|
||||||
if (scope != null && this.currentSearchScope !== scope && this.groupBeingEdited) {
|
|
||||||
this.router.navigate([], {
|
|
||||||
queryParamsHandling: 'merge'
|
|
||||||
});
|
|
||||||
this.currentSearchScope = scope;
|
|
||||||
this.paginationService.resetPage(this.configSearch.id);
|
|
||||||
}
|
|
||||||
this.searchDone = true;
|
this.searchDone = true;
|
||||||
|
|
||||||
return this.ePersonDataService.searchByScope(this.currentSearchScope, this.currentSearchQuery, {
|
return this.ePersonDataService.searchNonMembers(this.currentSearchQuery, this.groupBeingEdited.id, {
|
||||||
currentPage: paginationOptions.currentPage,
|
currentPage: paginationOptions.currentPage,
|
||||||
elementsPerPage: paginationOptions.pageSize
|
elementsPerPage: paginationOptions.pageSize
|
||||||
});
|
}, false, true);
|
||||||
}),
|
}),
|
||||||
getAllCompletedRemoteData(),
|
getAllCompletedRemoteData(),
|
||||||
map((rd: RemoteData<any>) => {
|
map((rd: RemoteData<any>) => {
|
||||||
|
@@ -62,10 +62,7 @@
|
|||||||
<td class="align-middle">{{ dsoNameService.getName((group.object | async)?.payload) }}</td>
|
<td class="align-middle">{{ dsoNameService.getName((group.object | async)?.payload) }}</td>
|
||||||
<td class="align-middle">
|
<td class="align-middle">
|
||||||
<div class="btn-group edit-field">
|
<div class="btn-group edit-field">
|
||||||
<span *ngIf="(isActiveGroup(group) | async)">{{ messagePrefix + '.table.edit.currentGroup' | translate }}</span>
|
<button (click)="addSubgroupToGroup(group)"
|
||||||
|
|
||||||
<button *ngIf="!(isActiveGroup(group) | async)"
|
|
||||||
(click)="addSubgroupToGroup(group)"
|
|
||||||
class="btn btn-outline-primary btn-sm addButton"
|
class="btn btn-outline-primary btn-sm addButton"
|
||||||
title="{{messagePrefix + '.table.edit.buttons.add' | translate: { name: dsoNameService.getName(group) } }}">
|
title="{{messagePrefix + '.table.edit.buttons.add' | translate: { name: dsoNameService.getName(group) } }}">
|
||||||
<i class="fas fa-plus fa-fw"></i>
|
<i class="fas fa-plus fa-fw"></i>
|
||||||
|
@@ -87,7 +87,7 @@ describe('SubgroupsListComponent', () => {
|
|||||||
return '/access-control/groups/' + group.id;
|
return '/access-control/groups/' + group.id;
|
||||||
},
|
},
|
||||||
// This method is used to get all groups which are NOT currently a subgroup member
|
// This method is used to get all groups which are NOT currently a subgroup member
|
||||||
searchGroups(query: string): Observable<RemoteData<PaginatedList<Group>>> {
|
searchNonMemberGroups(query: string, group: string): Observable<RemoteData<PaginatedList<Group>>> {
|
||||||
if (query === '') {
|
if (query === '') {
|
||||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), groupNonMembers));
|
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), groupNonMembers));
|
||||||
}
|
}
|
||||||
|
@@ -2,8 +2,8 @@ import { Component, Input, OnDestroy, OnInit } from '@angular/core';
|
|||||||
import { UntypedFormBuilder } from '@angular/forms';
|
import { UntypedFormBuilder } from '@angular/forms';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { BehaviorSubject, Observable, of as observableOf, Subscription } from 'rxjs';
|
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
|
||||||
import { mergeMap, switchMap, take } from 'rxjs/operators';
|
import { switchMap, take } from 'rxjs/operators';
|
||||||
import { PaginatedList } from '../../../../core/data/paginated-list.model';
|
import { PaginatedList } from '../../../../core/data/paginated-list.model';
|
||||||
import { RemoteData } from '../../../../core/data/remote-data';
|
import { RemoteData } from '../../../../core/data/remote-data';
|
||||||
import { GroupDataService } from '../../../../core/eperson/group-data.service';
|
import { GroupDataService } from '../../../../core/eperson/group-data.service';
|
||||||
@@ -129,20 +129,6 @@ export class SubgroupsListComponent implements OnInit, OnDestroy {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether or not the given group is the current group being edited
|
|
||||||
* @param group Group that is possibly the current group being edited
|
|
||||||
*/
|
|
||||||
isActiveGroup(group: Group): Observable<boolean> {
|
|
||||||
return this.groupDataService.getActiveGroup().pipe(take(1),
|
|
||||||
mergeMap((activeGroup: Group) => {
|
|
||||||
if (activeGroup != null && activeGroup.uuid === group.uuid) {
|
|
||||||
return observableOf(true);
|
|
||||||
}
|
|
||||||
return observableOf(false);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes given subgroup from the group currently being edited
|
* Deletes given subgroup from the group currently being edited
|
||||||
* @param subgroup Group we want to delete from the subgroups of the group currently being edited
|
* @param subgroup Group we want to delete from the subgroups of the group currently being edited
|
||||||
@@ -152,6 +138,11 @@ export class SubgroupsListComponent implements OnInit, OnDestroy {
|
|||||||
if (activeGroup != null) {
|
if (activeGroup != null) {
|
||||||
const response = this.groupDataService.deleteSubGroupFromGroup(activeGroup, subgroup);
|
const response = this.groupDataService.deleteSubGroupFromGroup(activeGroup, subgroup);
|
||||||
this.showNotifications('deleteSubgroup', response, this.dsoNameService.getName(subgroup), activeGroup);
|
this.showNotifications('deleteSubgroup', response, this.dsoNameService.getName(subgroup), activeGroup);
|
||||||
|
// Reload search results (if there is an active query).
|
||||||
|
// This will potentially add this deleted subgroup into the list of search results.
|
||||||
|
if (this.currentSearchQuery != null) {
|
||||||
|
this.search({query: this.currentSearchQuery});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.noActiveGroup'));
|
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.noActiveGroup'));
|
||||||
}
|
}
|
||||||
@@ -168,6 +159,11 @@ export class SubgroupsListComponent implements OnInit, OnDestroy {
|
|||||||
if (activeGroup.uuid !== subgroup.uuid) {
|
if (activeGroup.uuid !== subgroup.uuid) {
|
||||||
const response = this.groupDataService.addSubGroupToGroup(activeGroup, subgroup);
|
const response = this.groupDataService.addSubGroupToGroup(activeGroup, subgroup);
|
||||||
this.showNotifications('addSubgroup', response, this.dsoNameService.getName(subgroup), activeGroup);
|
this.showNotifications('addSubgroup', response, this.dsoNameService.getName(subgroup), activeGroup);
|
||||||
|
// Reload search results (if there is an active query).
|
||||||
|
// This will potentially remove this added subgroup from search results.
|
||||||
|
if (this.currentSearchQuery != null) {
|
||||||
|
this.search({query: this.currentSearchQuery});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.subgroupToAddIsActiveGroup'));
|
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.subgroupToAddIsActiveGroup'));
|
||||||
}
|
}
|
||||||
@@ -178,7 +174,8 @@ export class SubgroupsListComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search in the groups (searches by group name and by uuid exact match)
|
* Search all non-member groups (searches by group name and by uuid exact match). Used to search for
|
||||||
|
* groups that could be added to current group as a subgroup.
|
||||||
* @param data Contains query param
|
* @param data Contains query param
|
||||||
*/
|
*/
|
||||||
search(data: any) {
|
search(data: any) {
|
||||||
@@ -192,10 +189,10 @@ export class SubgroupsListComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
this.unsubFrom(SubKey.SearchResults);
|
this.unsubFrom(SubKey.SearchResults);
|
||||||
this.subs.set(SubKey.SearchResults, this.paginationService.getCurrentPagination(this.configSearch.id, this.configSearch).pipe(
|
this.subs.set(SubKey.SearchResults, this.paginationService.getCurrentPagination(this.configSearch.id, this.configSearch).pipe(
|
||||||
switchMap((config) => this.groupDataService.searchGroups(this.currentSearchQuery, {
|
switchMap((config) => this.groupDataService.searchNonMemberGroups(this.currentSearchQuery, this.groupBeingEdited.id, {
|
||||||
currentPage: config.currentPage,
|
currentPage: config.currentPage,
|
||||||
elementsPerPage: config.pageSize
|
elementsPerPage: config.pageSize
|
||||||
}, true, true, followLink('object')
|
}, false, true, followLink('object')
|
||||||
))
|
))
|
||||||
).subscribe((rd: RemoteData<PaginatedList<Group>>) => {
|
).subscribe((rd: RemoteData<PaginatedList<Group>>) => {
|
||||||
this.searchResults$.next(rd);
|
this.searchResults$.next(rd);
|
||||||
|
@@ -11,6 +11,7 @@ import {
|
|||||||
EPeopleRegistryCancelEPersonAction,
|
EPeopleRegistryCancelEPersonAction,
|
||||||
EPeopleRegistryEditEPersonAction
|
EPeopleRegistryEditEPersonAction
|
||||||
} from '../../access-control/epeople-registry/epeople-registry.actions';
|
} from '../../access-control/epeople-registry/epeople-registry.actions';
|
||||||
|
import { GroupMock } from '../../shared/testing/group-mock';
|
||||||
import { RequestParam } from '../cache/models/request-param.model';
|
import { RequestParam } from '../cache/models/request-param.model';
|
||||||
import { ChangeAnalyzer } from '../data/change-analyzer';
|
import { ChangeAnalyzer } from '../data/change-analyzer';
|
||||||
import { PatchRequest, PostRequest } from '../data/request.models';
|
import { PatchRequest, PostRequest } from '../data/request.models';
|
||||||
@@ -140,6 +141,30 @@ describe('EPersonDataService', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('searchNonMembers', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(service, 'searchBy');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('search with empty query and a group ID', () => {
|
||||||
|
service.searchNonMembers('', GroupMock.id);
|
||||||
|
const options = Object.assign(new FindListOptions(), {
|
||||||
|
searchParams: [Object.assign(new RequestParam('query', '')),
|
||||||
|
Object.assign(new RequestParam('group', GroupMock.id))]
|
||||||
|
});
|
||||||
|
expect(service.searchBy).toHaveBeenCalledWith('isNotMemberOf', options, true, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('search with query and a group ID', () => {
|
||||||
|
service.searchNonMembers('test', GroupMock.id);
|
||||||
|
const options = Object.assign(new FindListOptions(), {
|
||||||
|
searchParams: [Object.assign(new RequestParam('query', 'test')),
|
||||||
|
Object.assign(new RequestParam('group', GroupMock.id))]
|
||||||
|
});
|
||||||
|
expect(service.searchBy).toHaveBeenCalledWith('isNotMemberOf', options, true, true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('updateEPerson', () => {
|
describe('updateEPerson', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
spyOn(service, 'findByHref').and.returnValue(createSuccessfulRemoteDataObject$(EPersonMock));
|
spyOn(service, 'findByHref').and.returnValue(createSuccessfulRemoteDataObject$(EPersonMock));
|
||||||
|
@@ -177,6 +177,34 @@ export class EPersonDataService extends IdentifiableDataService<EPerson> impleme
|
|||||||
return this.searchBy(searchMethod, findListOptions, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
|
return this.searchBy(searchMethod, findListOptions, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for all EPerons which are *not* a member of a given group, via a passed in query
|
||||||
|
* (searches all EPerson metadata and by exact UUID).
|
||||||
|
* Endpoint used: /eperson/epesons/search/isNotMemberOf?query=<:string>&group=<:uuid>
|
||||||
|
* @param query search query param
|
||||||
|
* @param group UUID of group to exclude results from. Members of this group will never be returned.
|
||||||
|
* @param options
|
||||||
|
* @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's
|
||||||
|
* no valid cached version. Defaults to true
|
||||||
|
* @param reRequestOnStale Whether or not the request should automatically be re-
|
||||||
|
* requested after the response becomes stale
|
||||||
|
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which
|
||||||
|
* {@link HALLink}s should be automatically resolved
|
||||||
|
*/
|
||||||
|
public searchNonMembers(query: string, group: string, options?: FindListOptions, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig<EPerson>[]): Observable<RemoteData<PaginatedList<EPerson>>> {
|
||||||
|
const searchParams = [new RequestParam('query', query), new RequestParam('group', group)];
|
||||||
|
let findListOptions = new FindListOptions();
|
||||||
|
if (options) {
|
||||||
|
findListOptions = Object.assign(new FindListOptions(), options);
|
||||||
|
}
|
||||||
|
if (findListOptions.searchParams) {
|
||||||
|
findListOptions.searchParams = [...findListOptions.searchParams, ...searchParams];
|
||||||
|
} else {
|
||||||
|
findListOptions.searchParams = searchParams;
|
||||||
|
}
|
||||||
|
return this.searchBy('isNotMemberOf', findListOptions, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new patch to the object cache
|
* Add a new patch to the object cache
|
||||||
* The patch is derived from the differences between the given object and its version in the object cache
|
* The patch is derived from the differences between the given object and its version in the object cache
|
||||||
|
@@ -43,11 +43,11 @@ describe('GroupDataService', () => {
|
|||||||
let rdbService;
|
let rdbService;
|
||||||
let objectCache;
|
let objectCache;
|
||||||
function init() {
|
function init() {
|
||||||
restEndpointURL = 'https://dspace.4science.it/dspace-spring-rest/api/eperson';
|
restEndpointURL = 'https://rest.api/server/api/eperson';
|
||||||
groupsEndpoint = `${restEndpointURL}/groups`;
|
groupsEndpoint = `${restEndpointURL}/groups`;
|
||||||
groups = [GroupMock, GroupMock2];
|
groups = [GroupMock, GroupMock2];
|
||||||
groups$ = createSuccessfulRemoteDataObject$(createPaginatedList(groups));
|
groups$ = createSuccessfulRemoteDataObject$(createPaginatedList(groups));
|
||||||
rdbService = getMockRemoteDataBuildServiceHrefMap(undefined, { 'https://dspace.4science.it/dspace-spring-rest/api/eperson/groups': groups$ });
|
rdbService = getMockRemoteDataBuildServiceHrefMap(undefined, { 'https://rest.api/server/api/eperson/groups': groups$ });
|
||||||
halService = new HALEndpointServiceStub(restEndpointURL);
|
halService = new HALEndpointServiceStub(restEndpointURL);
|
||||||
objectCache = getMockObjectCacheService();
|
objectCache = getMockObjectCacheService();
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
@@ -111,6 +111,30 @@ describe('GroupDataService', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('searchNonMemberGroups', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(service, 'searchBy');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('search with empty query and a group ID', () => {
|
||||||
|
service.searchNonMemberGroups('', GroupMock.id);
|
||||||
|
const options = Object.assign(new FindListOptions(), {
|
||||||
|
searchParams: [Object.assign(new RequestParam('query', '')),
|
||||||
|
Object.assign(new RequestParam('group', GroupMock.id))]
|
||||||
|
});
|
||||||
|
expect(service.searchBy).toHaveBeenCalledWith('isNotMemberOf', options, true, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('search with query and a group ID', () => {
|
||||||
|
service.searchNonMemberGroups('test', GroupMock.id);
|
||||||
|
const options = Object.assign(new FindListOptions(), {
|
||||||
|
searchParams: [Object.assign(new RequestParam('query', 'test')),
|
||||||
|
Object.assign(new RequestParam('group', GroupMock.id))]
|
||||||
|
});
|
||||||
|
expect(service.searchBy).toHaveBeenCalledWith('isNotMemberOf', options, true, true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('addSubGroupToGroup', () => {
|
describe('addSubGroupToGroup', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
objectCache.getByHref.and.returnValue(observableOf({
|
objectCache.getByHref.and.returnValue(observableOf({
|
||||||
|
@@ -3,7 +3,7 @@ import { Injectable } from '@angular/core';
|
|||||||
|
|
||||||
import { createSelector, select, Store } from '@ngrx/store';
|
import { createSelector, select, Store } from '@ngrx/store';
|
||||||
import { Observable, zip as observableZip } from 'rxjs';
|
import { Observable, zip as observableZip } from 'rxjs';
|
||||||
import { filter, map, take } from 'rxjs/operators';
|
import { take } from 'rxjs/operators';
|
||||||
import {
|
import {
|
||||||
GroupRegistryCancelGroupAction,
|
GroupRegistryCancelGroupAction,
|
||||||
GroupRegistryEditGroupAction
|
GroupRegistryEditGroupAction
|
||||||
@@ -105,23 +105,31 @@ export class GroupDataService extends IdentifiableDataService<Group> implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the current user is member of to the indicated group
|
* Searches for all groups which are *not* a member of a given group, via a passed in query
|
||||||
*
|
* (searches in group name and by exact UUID).
|
||||||
* @param groupName
|
* Endpoint used: /eperson/groups/search/isNotMemberOf?query=<:string>&group=<:uuid>
|
||||||
* the group name
|
* @param query search query param
|
||||||
* @return boolean
|
* @param group UUID of group to exclude results from. Members of this group will never be returned.
|
||||||
* true if user is member of the indicated group, false otherwise
|
* @param options
|
||||||
|
* @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's
|
||||||
|
* no valid cached version. Defaults to true
|
||||||
|
* @param reRequestOnStale Whether or not the request should automatically be re-
|
||||||
|
* requested after the response becomes stale
|
||||||
|
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which
|
||||||
|
* {@link HALLink}s should be automatically resolved
|
||||||
*/
|
*/
|
||||||
isMemberOf(groupName: string): Observable<boolean> {
|
public searchNonMemberGroups(query: string, group: string, options?: FindListOptions, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig<Group>[]): Observable<RemoteData<PaginatedList<Group>>> {
|
||||||
const searchHref = 'isMemberOf';
|
const searchParams = [new RequestParam('query', query), new RequestParam('group', group)];
|
||||||
const options = new FindListOptions();
|
let findListOptions = new FindListOptions();
|
||||||
options.searchParams = [new RequestParam('groupName', groupName)];
|
if (options) {
|
||||||
|
findListOptions = Object.assign(new FindListOptions(), options);
|
||||||
return this.searchBy(searchHref, options).pipe(
|
}
|
||||||
filter((groups: RemoteData<PaginatedList<Group>>) => !groups.isResponsePending),
|
if (findListOptions.searchParams) {
|
||||||
take(1),
|
findListOptions.searchParams = [...findListOptions.searchParams, ...searchParams];
|
||||||
map((groups: RemoteData<PaginatedList<Group>>) => groups.payload.totalElements > 0)
|
} else {
|
||||||
);
|
findListOptions.searchParams = searchParams;
|
||||||
|
}
|
||||||
|
return this.searchBy('isNotMemberOf', findListOptions, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -434,10 +434,6 @@
|
|||||||
|
|
||||||
"admin.access-control.groups.form.members-list.headMembers": "Current Members",
|
"admin.access-control.groups.form.members-list.headMembers": "Current Members",
|
||||||
|
|
||||||
"admin.access-control.groups.form.members-list.search.scope.metadata": "Metadata",
|
|
||||||
|
|
||||||
"admin.access-control.groups.form.members-list.search.scope.email": "E-mail (exact)",
|
|
||||||
|
|
||||||
"admin.access-control.groups.form.members-list.search.button": "Search",
|
"admin.access-control.groups.form.members-list.search.button": "Search",
|
||||||
|
|
||||||
"admin.access-control.groups.form.members-list.table.id": "ID",
|
"admin.access-control.groups.form.members-list.table.id": "ID",
|
||||||
@@ -494,8 +490,6 @@
|
|||||||
|
|
||||||
"admin.access-control.groups.form.subgroups-list.table.edit.buttons.add": "Add subgroup with name \"{{name}}\"",
|
"admin.access-control.groups.form.subgroups-list.table.edit.buttons.add": "Add subgroup with name \"{{name}}\"",
|
||||||
|
|
||||||
"admin.access-control.groups.form.subgroups-list.table.edit.currentGroup": "Current group",
|
|
||||||
|
|
||||||
"admin.access-control.groups.form.subgroups-list.notification.success.addSubgroup": "Successfully added subgroup: \"{{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.failure.addSubgroup": "Failed to add subgroup: \"{{name}}\"",
|
||||||
@@ -632,10 +626,6 @@
|
|||||||
|
|
||||||
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.headMembers": "Current Members",
|
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.headMembers": "Current Members",
|
||||||
|
|
||||||
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.search.scope.metadata": "Metadata",
|
|
||||||
|
|
||||||
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.search.scope.email": "E-mail (exact)",
|
|
||||||
|
|
||||||
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.search.button": "Search",
|
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.search.button": "Search",
|
||||||
|
|
||||||
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.id": "ID",
|
"advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.id": "ID",
|
||||||
|
Reference in New Issue
Block a user