Skip to content

Commit

Permalink
Merge pull request #1 from iam-vir-harshit/fix-2869
Browse files Browse the repository at this point in the history
fix for DSpace#2869
  • Loading branch information
iam-vir-harshit authored Dec 10, 2024
2 parents dcea3ba + 346e46a commit c2df345
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ <h2>{{messagePrefix + '.groupsEPersonIsMemberOf' | translate}}</h2>
<th scope="col" class="align-middle">{{messagePrefix + '.table.id' | translate}}</th>
<th scope="col" class="align-middle">{{messagePrefix + '.table.name' | translate}}</th>
<th scope="col" class="align-middle">{{messagePrefix + '.table.collectionOrCommunity' | translate}}</th>
<th scope="col" class="align-middle">{{messagePrefix + '.table.remove' | translate}}</th>
</tr>
</thead>
<tbody>
Expand All @@ -78,6 +79,13 @@ <h2>{{messagePrefix + '.groupsEPersonIsMemberOf' | translate}}</h2>
<td class="align-middle">
{{ dsoNameService.getName((group.object | async)?.payload) }}
</td>
<td class="align-middle">
<button *ngIf="canDelete$ | async" before (click)="deleteGroupFromMember(group)"
type="button" [ngClass]="['btn btn-sm delete-button', 'btn-outline-danger']"
title="{{messagePrefix + '.table.edit.buttons.removegroup' | translate: { name: dsoNameService.getName(group) } }}">
<i class="fas fa-trash-alt fa-fw"></i>
</button>
</td>
</tr>
</tbody>
</table>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,38 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
}
}

/**
* Deletes a given group from the Group list of the eperson currently being edited present in
* @param group group we want to delete as of which the current eperson being edited is member of
*/
deleteGroupFromMember(group: Group) {
this.epersonService.getActiveEPerson().pipe(take(1)).subscribe((activeEPerson: EPerson) => {
if (activeEPerson != null) {
const response = this.groupsDataService.deleteMemberFromGroup(group, activeEPerson);
this.showNotifications('deleteMembership', response, this.dsoNameService.getName(group), activeEPerson);
} else {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.noActiveEPerson'));
}
});
}

/**
* 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 activeEPerson EPerson currently being edited
*/
showNotifications(messageSuffix: string, response: Observable<RemoteData<any>>, nameObject: string, activeEPerson: EPerson) {
response.pipe(getFirstCompletedRemoteData()).subscribe((rd: RemoteData<any>) => {
if (rd.hasSucceeded) {
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 }));
}
});
}

/**
* Cancel the current edit when component is destroyed & unsub all subscriptions
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@
<h2 class="border-bottom pb-2">{{messagePrefix + '.head' | translate}}</h2>

<h3>{{messagePrefix + '.headMembers' | translate}}</h3>

<form [formGroup]="searchCurrentMembersForm" (ngSubmit)="searchMembers(searchCurrentMembersForm.value)" class="d-flex justify-content-between">
<div class="flex-grow-1 mr-3">
<div class="form-group input-group mr-3">
<input type="text" name="queryCurrentMembers" id="queryCurrentMembers" formControlName="queryCurrentMembers"
class="form-control" aria-label="Search input">
<span class="input-group-append">
<button type="submit" class="search-button btn btn-primary">
<i class="fas fa-search"></i> {{ messagePrefix + '.search.button' | translate }}</button>
</span>
</div>
</div>
<div>
<button (click)="clearCurrentMembersFormAndResetResult()"
class="btn btn-secondary">{{messagePrefix + '.button.see-all' | translate}}</button>
</div>
</form>

<ds-pagination *ngIf="(ePeopleMembersOfGroup | async)?.totalElements > 0"
[paginationOptions]="config"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,21 @@ export class MembersListComponent implements OnInit, OnDestroy {
// The search form
searchForm;

// The current member search form
searchCurrentMembersForm;

// Current search in edit group - epeople search form
currentSearchQuery: string;

// Current search in edit group - epeople current members search form
currentMembersSearchQuery: string;

// Whether or not user has done a EPeople search yet
searchDone: boolean;

// Whether or not user has done a EPeople Member search yet
searchCurrentMembersDone: boolean;

// current active group being edited
groupBeingEdited: Group;

Expand All @@ -194,12 +203,18 @@ export class MembersListComponent implements OnInit, OnDestroy {
public dsoNameService: DSONameService,
) {
this.currentSearchQuery = '';
this.currentMembersSearchQuery = '';
}

ngOnInit(): void {
this.searchForm = this.formBuilder.group(({
query: '',
}));

this.searchCurrentMembersForm = this.formBuilder.group(({
queryCurrentMembers: '',
}));

this.subs.set(SubKey.ActiveGroup, this.groupDataService.getActiveGroup().subscribe((activeGroup: Group) => {
if (activeGroup != null) {
this.groupBeingEdited = activeGroup;
Expand Down Expand Up @@ -354,6 +369,55 @@ export class MembersListComponent implements OnInit, OnDestroy {
}));
}

/**
* Search all EPeople who are a member of the current group by name, email or metadata
* @param data Contains query param
*/
searchMembers(data: any) {
this.unsubFrom(SubKey.Members);
this.subs.set(SubKey.Members,
this.paginationService.getCurrentPagination(this.config.id, this.config).pipe(
switchMap((paginationOptions) => {
const query: string = data.queryCurrentMembers;
if (query != null && this.currentMembersSearchQuery !== query && this.groupBeingEdited) {
this.currentMembersSearchQuery = query;
this.paginationService.resetPage(this.config.id);
}
this.searchCurrentMembersDone = true;

return this.ePersonDataService.searchMembers(this.currentMembersSearchQuery, this.groupBeingEdited.id, {
currentPage: paginationOptions.currentPage,
elementsPerPage: paginationOptions.pageSize,
}, false, true);
}),
getAllCompletedRemoteData(),
map((rd: RemoteData<any>) => {
if (rd.hasFailed) {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure', { cause: rd.errorMessage }));
} else {
return rd;
}
}),
switchMap((epersonListRD: RemoteData<PaginatedList<EPerson>>) => {
const dtos$ = observableCombineLatest([...epersonListRD.payload.page.map((member: EPerson) => {
const dto$: Observable<EpersonDtoModel> = observableCombineLatest(
this.isMemberOfGroup(member), (isMember: ObservedValueOf<Observable<boolean>>) => {
const epersonDtoModel: EpersonDtoModel = new EpersonDtoModel();
epersonDtoModel.eperson = member;
epersonDtoModel.ableToDelete = isMember;
return epersonDtoModel;
});
return dto$;
})]);
return dtos$.pipe(defaultIfEmpty([]), map((dtos: EpersonDtoModel[]) => {
return buildPaginatedList(epersonListRD.payload.pageInfo, dtos);
}));
}),
).subscribe((paginatedListOfDTOs: PaginatedList<EpersonDtoModel>) => {
this.ePeopleMembersOfGroup.next(paginatedListOfDTOs);
}));
}

/**
* unsub all subscriptions
*/
Expand Down Expand Up @@ -391,4 +455,14 @@ export class MembersListComponent implements OnInit, OnDestroy {
});
this.search({ query: '' });
}

/**
* Reset all input-fields to be empty and search all search
*/
clearCurrentMembersFormAndResetResult() {
this.searchCurrentMembersForm.patchValue({
queryCurrentMembers:'',
});
this.searchMembers({ queryCurrentMembers: '' });
}
}
28 changes: 28 additions & 0 deletions src/app/core/eperson/eperson-data.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,34 @@ export class EPersonDataService extends IdentifiableDataService<EPerson> impleme
return this.searchBy('isNotMemberOf', findListOptions, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
}

/**
* Searches for all EPerons which are a member of a given group, via a passed in query
* (searches all EPerson metadata and by exact UUID).
* Endpoint used: /eperson/epesons/search/isMemberOf?query=<:string>&group=<:uuid>
* @param query search query param
* @param group UUID of group to include results from. Members of this group will only 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 searchMembers(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('isMemberOf', findListOptions, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
}

/**
* 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ export class ReviewersListComponent extends MembersListComponent implements OnIn
query: '',
}));
}

searchCurrentMembersForm = this.formBuilder.group(({
queryCurrentMembers: '',
}));

ngOnChanges(changes: SimpleChanges): void {
this.groupId = changes.groupId.currentValue;
Expand Down
4 changes: 4 additions & 0 deletions src/assets/i18n/en.json5
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,10 @@
"admin.access-control.epeople.form.table.name": "Name",

"admin.access-control.epeople.form.table.collectionOrCommunity": "Collection/Community",

"admin.access-control.epeople.form.table.remove": "Remove",

"admin.access-control.epeople.form.table.edit.buttons.removegroup": "Remove member from group \"{{name}}\"",

"admin.access-control.epeople.form.memberOfNoGroups": "This EPerson is not a member of any groups",

Expand Down

0 comments on commit c2df345

Please sign in to comment.