fix issues with the group edit page

This commit is contained in:
Art Lowel
2021-01-21 14:30:59 +01:00
parent c66de4fe91
commit 634836158b
9 changed files with 202 additions and 129 deletions

View File

@@ -24,10 +24,10 @@
</div>
</form>
<ds-pagination *ngIf="(ePeopleSearch | async)?.payload?.totalElements > 0"
<ds-pagination *ngIf="(searchResults$ | async)?.payload?.totalElements > 0"
[paginationOptions]="configSearch"
[pageInfoState]="(ePeopleSearch | async)?.payload"
[collectionSize]="(ePeopleSearch | async)?.payload?.totalElements"
[pageInfoState]="(searchResults$ | async)?.payload"
[collectionSize]="(searchResults$ | async)?.payload?.totalElements"
[hideGear]="true"
[hidePagerWhenSinglePage]="true"
(pageChange)="onPageChangeSearch($event)">
@@ -42,7 +42,7 @@
</tr>
</thead>
<tbody>
<tr *ngFor="let ePerson of (ePeopleSearch | async)?.payload?.page">
<tr *ngFor="let ePerson of (searchResults$ | async)?.payload?.page">
<td>{{ePerson.id}}</td>
<td><a (click)="ePersonDataService.startEditingNewEPerson(ePerson)"
[routerLink]="[ePersonDataService.getEPeoplePageRouterLink()]">{{ePerson.name}}</a></td>
@@ -70,7 +70,7 @@
</ds-pagination>
<div *ngIf="(ePeopleSearch | async)?.payload?.totalElements == 0 && searchDone"
<div *ngIf="(searchResults$ | async)?.payload?.totalElements == 0 && searchDone"
class="alert alert-info w-100 mb-2"
role="alert">
{{messagePrefix + '.no-items' | translate}}
@@ -78,10 +78,10 @@
<h4>{{messagePrefix + '.headMembers' | translate}}</h4>
<ds-pagination *ngIf="(ePeopleMembersOfGroup | async)?.payload?.totalElements > 0"
<ds-pagination *ngIf="(members$ | async)?.payload?.totalElements > 0"
[paginationOptions]="config"
[pageInfoState]="(ePeopleMembersOfGroup | async)?.payload"
[collectionSize]="(ePeopleMembersOfGroup | async)?.payload?.totalElements"
[pageInfoState]="(members$ | async)?.payload"
[collectionSize]="(members$ | async)?.payload?.totalElements"
[hideGear]="true"
[hidePagerWhenSinglePage]="true"
(pageChange)="onPageChange($event)">
@@ -96,7 +96,7 @@
</tr>
</thead>
<tbody>
<tr *ngFor="let ePerson of (ePeopleMembersOfGroup | async)?.payload?.page">
<tr *ngFor="let ePerson of (members$ | async)?.payload?.page">
<td>{{ePerson.id}}</td>
<td><a (click)="ePersonDataService.startEditingNewEPerson(ePerson)"
[routerLink]="[ePersonDataService.getEPeoplePageRouterLink()]">{{ePerson.name}}</a></td>
@@ -116,7 +116,7 @@
</ds-pagination>
<div *ngIf="(ePeopleMembersOfGroup | async)?.payload?.totalElements == 0" class="alert alert-info w-100 mb-2"
<div *ngIf="(members$ | async)?.payload?.totalElements == 0" class="alert alert-info w-100 mb-2"
role="alert">
{{messagePrefix + '.no-members-yet' | translate}}
</div>

View File

@@ -150,7 +150,7 @@ describe('MembersListComponent', () => {
}));
it('should show list of eperson members of current active group', () => {
const epersonIdsFound = fixture.debugElement.queryAll(By.css('#ePeopleMembersOfGroup tr td:first-child'));
const epersonIdsFound = fixture.debugElement.queryAll(By.css('#members$ tr td:first-child'));
expect(epersonIdsFound.length).toEqual(1);
epersonMembers.map((eperson: EPerson) => {
expect(epersonIdsFound.find((foundEl) => {

View File

@@ -2,7 +2,7 @@ import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { Observable, of as observableOf, Subscription } from 'rxjs';
import { Observable, of as observableOf, Subscription, BehaviorSubject } from 'rxjs';
import { map, mergeMap, take } from 'rxjs/operators';
import { PaginatedList } from '../../../../../core/data/paginated-list.model';
import { RemoteData } from '../../../../../core/data/remote-data';
@@ -15,10 +15,18 @@ import {
getFirstSucceededRemoteData,
getFirstCompletedRemoteData
} from '../../../../../core/shared/operators';
import { hasValue } from '../../../../../shared/empty.util';
import { NotificationsService } from '../../../../../shared/notifications/notifications.service';
import { PaginationComponentOptions } from '../../../../../shared/pagination/pagination-component-options.model';
/**
* Keys to keep track of specific subscriptions
*/
enum SubKey {
Members,
ActiveGroup,
SearchResults,
}
@Component({
selector: 'ds-members-list',
templateUrl: './members-list.component.html'
@@ -34,11 +42,11 @@ export class MembersListComponent implements OnInit, OnDestroy {
/**
* EPeople being displayed in search result, initially all members, after search result of search
*/
ePeopleSearch: Observable<RemoteData<PaginatedList<EPerson>>>;
searchResults$: BehaviorSubject<RemoteData<PaginatedList<EPerson>>> = new BehaviorSubject(undefined);
/**
* List of EPeople members of currently active group being edited
*/
ePeopleMembersOfGroup: Observable<RemoteData<PaginatedList<EPerson>>>;
members$: BehaviorSubject<RemoteData<PaginatedList<EPerson>>> = new BehaviorSubject(undefined);
/**
* Pagination config used to display the list of EPeople that are result of EPeople search
@@ -58,9 +66,9 @@ export class MembersListComponent implements OnInit, OnDestroy {
});
/**
* List of subscriptions
* Map of active subscriptions
*/
subs: Subscription[] = [];
subs: Map<SubKey, Subscription> = new Map();
// The search form
searchForm;
@@ -90,10 +98,10 @@ export class MembersListComponent implements OnInit, OnDestroy {
scope: 'metadata',
query: '',
}));
this.subs.push(this.groupDataService.getActiveGroup().subscribe((activeGroup: Group) => {
this.subs.set(SubKey.ActiveGroup, this.groupDataService.getActiveGroup().subscribe((activeGroup: Group) => {
if (activeGroup != null) {
this.groupBeingEdited = activeGroup;
this.forceUpdateEPeople(activeGroup);
this.retrieveMembers(this.config.currentPage);
}
}));
}
@@ -112,10 +120,40 @@ export class MembersListComponent implements OnInit, OnDestroy {
* @param event
*/
onPageChange(event) {
this.ePeopleMembersOfGroup = this.ePersonDataService.findAllByHref(this.groupBeingEdited._links.epersons.href, {
currentPage: event,
this.retrieveMembers(event);
}
/**
* Retrieve the EPersons that are members of the group
*
* @param page the number of the page to retrieve
* @private
*/
private retrieveMembers(page: number) {
this.unsubFrom(SubKey.Members);
this.subs.set(
SubKey.Members,
this.ePersonDataService.findAllByHref(this.groupBeingEdited._links.epersons.href, {
currentPage: page,
elementsPerPage: this.config.pageSize
});
}
).subscribe((rd: RemoteData<PaginatedList<EPerson>>) => {
this.members$.next(rd);
}));
}
/**
* Unsubscribe from a subscription if it's still subscribed, and remove it from the map of
* active subscriptions
*
* @param key The key of the subscription to unsubscribe from
* @private
*/
private unsubFrom(key: SubKey) {
if (this.subs.has(key)) {
this.subs.get(key).unsubscribe();
this.subs.delete(key);
}
}
/**
@@ -127,7 +165,6 @@ export class MembersListComponent implements OnInit, OnDestroy {
if (activeGroup != null) {
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'));
}
@@ -147,7 +184,6 @@ export class MembersListComponent implements OnInit, OnDestroy {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.noActiveGroup'));
}
});
this.forceUpdateEPeople(this.groupBeingEdited, ePerson);
}
/**
@@ -159,7 +195,7 @@ export class MembersListComponent implements OnInit, OnDestroy {
mergeMap((group: Group) => {
if (group != null) {
return this.ePersonDataService.findAllByHref(group._links.epersons.href, {
currentPage: 0,
currentPage: 1,
elementsPerPage: 9999
})
.pipe(
@@ -191,33 +227,23 @@ export class MembersListComponent implements OnInit, OnDestroy {
this.configSearch.currentPage = 1;
}
this.searchDone = true;
this.ePeopleSearch = this.ePersonDataService.searchByScope(this.currentSearchScope, this.currentSearchQuery, {
currentPage: this.configSearch.currentPage,
elementsPerPage: this.configSearch.pageSize
});
}
/**
* Force-update the list of EPeople by first clearing the cache related to EPeople, then performing
* a new REST call
* @param activeGroup Group currently being edited
*/
public forceUpdateEPeople(activeGroup: Group, ePersonToUpdate?: EPerson) {
if (ePersonToUpdate != null) {
this.ePersonDataService.clearLinkRequests(ePersonToUpdate._links.groups.href);
}
this.router.navigateByUrl(this.groupDataService.getGroupEditPageRouterLink(activeGroup));
this.ePeopleMembersOfGroup = this.ePersonDataService.findAllByHref(activeGroup._links.epersons.href, {
this.unsubFrom(SubKey.SearchResults);
this.subs.set(SubKey.SearchResults, this.ePersonDataService.searchByScope(this.currentSearchScope, this.currentSearchQuery, {
currentPage: this.configSearch.currentPage,
elementsPerPage: this.configSearch.pageSize
}, false);
}).subscribe((rd: RemoteData<PaginatedList<EPerson>>) => {
this.searchResults$.next(rd);
}));
}
/**
* unsub all subscriptions
*/
ngOnDestroy(): void {
this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
for (const key of this.subs.keys()) {
this.unsubFrom(key);
}
}
/**
@@ -231,6 +257,7 @@ export class MembersListComponent implements OnInit, OnDestroy {
response.pipe(getFirstCompletedRemoteData()).subscribe((rd: RemoteData<any>) => {
if (rd.hasSucceeded) {
this.notificationsService.success(this.translateService.get(this.messagePrefix + '.notification.success.' + messageSuffix, { name: nameObject }));
this.ePersonDataService.clearLinkRequests(activeGroup._links.epersons.href);
} else {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.' + messageSuffix, { name: nameObject }));
}

View File

@@ -18,10 +18,10 @@
</div>
</form>
<ds-pagination *ngIf="(groupsSearch | async)?.payload?.totalElements > 0"
<ds-pagination *ngIf="(searchResults$ | async)?.payload?.totalElements > 0"
[paginationOptions]="configSearch"
[pageInfoState]="(groupsSearch | async)?.payload"
[collectionSize]="(groupsSearch | async)?.payload?.totalElements"
[pageInfoState]="(searchResults$ | async)?.payload"
[collectionSize]="(searchResults$ | async)?.payload?.totalElements"
[hideGear]="true"
[hidePagerWhenSinglePage]="true"
(pageChange)="onPageChangeSearch($event)">
@@ -36,7 +36,7 @@
</tr>
</thead>
<tbody>
<tr *ngFor="let group of (groupsSearch | async)?.payload?.page">
<tr *ngFor="let group of (searchResults$ | async)?.payload?.page">
<td>{{group.id}}</td>
<td><a (click)="groupDataService.startEditingNewGroup(group)"
[routerLink]="[groupDataService.getGroupEditPageRouterLink(group)]">{{group.name}}</a></td>
@@ -65,17 +65,17 @@
</div>
</ds-pagination>
<div *ngIf="(groupsSearch | async)?.payload?.totalElements == 0 && searchDone" class="alert alert-info w-100 mb-2"
<div *ngIf="(searchResults$ | async)?.payload?.totalElements == 0 && searchDone" class="alert alert-info w-100 mb-2"
role="alert">
{{messagePrefix + '.no-items' | translate}}
</div>
<h4>{{messagePrefix + '.headSubgroups' | translate}}</h4>
<ds-pagination *ngIf="(subgroupsOfGroup | async)?.payload?.totalElements > 0"
<ds-pagination *ngIf="(subGroups$ | async)?.payload?.totalElements > 0"
[paginationOptions]="config"
[pageInfoState]="(subgroupsOfGroup | async)?.payload"
[collectionSize]="(subgroupsOfGroup | async)?.payload?.totalElements"
[pageInfoState]="(subGroups$ | async)?.payload"
[collectionSize]="(subGroups$ | async)?.payload?.totalElements"
[hideGear]="true"
[hidePagerWhenSinglePage]="true"
(pageChange)="onPageChange($event)">
@@ -90,7 +90,7 @@
</tr>
</thead>
<tbody>
<tr *ngFor="let group of (subgroupsOfGroup | async)?.payload?.page">
<tr *ngFor="let group of (subGroups$ | async)?.payload?.page">
<td>{{group.id}}</td>
<td><a (click)="groupDataService.startEditingNewGroup(group)"
[routerLink]="[groupDataService.getGroupEditPageRouterLink(group)]">{{group.name}}</a></td>
@@ -109,7 +109,7 @@
</div>
</ds-pagination>
<div *ngIf="(subgroupsOfGroup | async)?.payload?.totalElements == 0" class="alert alert-info w-100 mb-2"
<div *ngIf="(subGroups$ | async)?.payload?.totalElements == 0" class="alert alert-info w-100 mb-2"
role="alert">
{{messagePrefix + '.no-subgroups-yet' | translate}}
</div>

View File

@@ -120,7 +120,7 @@ describe('SubgroupsListComponent', () => {
}));
it('should show list of subgroups of current active group', () => {
const groupIdsFound = fixture.debugElement.queryAll(By.css('#subgroupsOfGroup tr td:first-child'));
const groupIdsFound = fixture.debugElement.queryAll(By.css('#subgroupsOfGroup$ tr td:first-child'));
expect(groupIdsFound.length).toEqual(1);
activeGroup.subgroups.map((group: Group) => {
expect(groupIdsFound.find((foundEl) => {
@@ -132,7 +132,7 @@ describe('SubgroupsListComponent', () => {
describe('if first group delete button is pressed', () => {
let groupsFound;
beforeEach(fakeAsync(() => {
const addButton = fixture.debugElement.query(By.css('#subgroupsOfGroup tbody .deleteButton'));
const addButton = fixture.debugElement.query(By.css('#subgroupsOfGroup$ tbody .deleteButton'));
addButton.triggerEventHandler('click', {
preventDefault: () => {/**/
}
@@ -141,7 +141,7 @@ describe('SubgroupsListComponent', () => {
fixture.detectChanges();
}));
it('one less subgroup in list from 1 to 0 (of 2 total groups)', () => {
groupsFound = fixture.debugElement.queryAll(By.css('#subgroupsOfGroup tbody tr'));
groupsFound = fixture.debugElement.queryAll(By.css('#subgroupsOfGroup$ tbody tr'));
expect(groupsFound.length).toEqual(0);
});
});
@@ -151,15 +151,15 @@ describe('SubgroupsListComponent', () => {
let groupsFound;
beforeEach(fakeAsync(() => {
component.search({ query: '' });
groupsFound = fixture.debugElement.queryAll(By.css('#groupsSearch tbody tr'));
groupsFound = fixture.debugElement.queryAll(By.css('#searchResults$ tbody tr'));
}));
it('should display all groups', () => {
fixture.detectChanges();
groupsFound = fixture.debugElement.queryAll(By.css('#groupsSearch tbody tr'));
groupsFound = fixture.debugElement.queryAll(By.css('#searchResults$ tbody tr'));
expect(groupsFound.length).toEqual(2);
groupsFound = fixture.debugElement.queryAll(By.css('#groupsSearch tbody tr'));
const groupIdsFound = fixture.debugElement.queryAll(By.css('#groupsSearch tbody tr td:first-child'));
groupsFound = fixture.debugElement.queryAll(By.css('#searchResults$ tbody tr'));
const groupIdsFound = fixture.debugElement.queryAll(By.css('#searchResults$ tbody tr td:first-child'));
allGroups.map((group: Group) => {
expect(groupIdsFound.find((foundEl) => {
return (foundEl.nativeElement.textContent.trim() === group.uuid);
@@ -170,7 +170,7 @@ describe('SubgroupsListComponent', () => {
describe('if group is already a subgroup', () => {
it('should have delete button, else it should have add button', () => {
fixture.detectChanges();
groupsFound = fixture.debugElement.queryAll(By.css('#groupsSearch tbody tr'));
groupsFound = fixture.debugElement.queryAll(By.css('#searchResults$ tbody tr'));
const getSubgroups = groupsDataServiceStub.getSubgroups().subgroups;
if (getSubgroups !== undefined && getSubgroups.length > 0) {
groupsFound.map((foundGroupRowElement) => {

View File

@@ -2,7 +2,7 @@ import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { Observable, of as observableOf, Subscription } from 'rxjs';
import { Observable, of as observableOf, Subscription, BehaviorSubject } from 'rxjs';
import { map, mergeMap, take } from 'rxjs/operators';
import { PaginatedList } from '../../../../../core/data/paginated-list.model';
import { RemoteData } from '../../../../../core/data/remote-data';
@@ -13,9 +13,18 @@ import {
getFirstSucceededRemoteData,
getFirstCompletedRemoteData
} from '../../../../../core/shared/operators';
import { hasValue } from '../../../../../shared/empty.util';
import { NotificationsService } from '../../../../../shared/notifications/notifications.service';
import { PaginationComponentOptions } from '../../../../../shared/pagination/pagination-component-options.model';
import { EPerson } from '../../../../../core/eperson/models/eperson.model';
/**
* Keys to keep track of specific subscriptions
*/
enum SubKey {
Members,
ActiveGroup,
SearchResults,
}
@Component({
selector: 'ds-subgroups-list',
@@ -32,16 +41,16 @@ export class SubgroupsListComponent implements OnInit, OnDestroy {
/**
* Result of search groups, initially all groups
*/
groupsSearch: Observable<RemoteData<PaginatedList<Group>>>;
searchResults$: BehaviorSubject<RemoteData<PaginatedList<Group>>> = new BehaviorSubject(undefined);
/**
* List of all subgroups of group being edited
*/
subgroupsOfGroup: Observable<RemoteData<PaginatedList<Group>>>;
subGroups$: BehaviorSubject<RemoteData<PaginatedList<Group>>> = new BehaviorSubject(undefined);
/**
* List of subscriptions
* Map of active subscriptions
*/
subs: Subscription[] = [];
subs: Map<SubKey, Subscription> = new Map();
/**
* Pagination config used to display the list of groups that are result of groups search
@@ -84,10 +93,10 @@ export class SubgroupsListComponent implements OnInit, OnDestroy {
this.searchForm = this.formBuilder.group(({
query: '',
}));
this.subs.push(this.groupDataService.getActiveGroup().subscribe((activeGroup: Group) => {
this.subs.set(SubKey.ActiveGroup, this.groupDataService.getActiveGroup().subscribe((activeGroup: Group) => {
if (activeGroup != null) {
this.groupBeingEdited = activeGroup;
this.forceUpdateGroups(activeGroup);
this.retrieveSubGroups(this.config.currentPage);
}
}));
}
@@ -106,10 +115,26 @@ export class SubgroupsListComponent implements OnInit, OnDestroy {
* @param event
*/
onPageChange(event) {
this.subgroupsOfGroup = this.groupDataService.findAllByHref(this.groupBeingEdited._links.subgroups.href, {
currentPage: event,
this.retrieveSubGroups(event);
}
/**
* Retrieve the Subgroups that are members of the group
*
* @param page the number of the page to retrieve
* @private
*/
private retrieveSubGroups(page: number) {
this.unsubFrom(SubKey.Members);
this.subs.set(
SubKey.Members,
this.groupDataService.findAllByHref(this.groupBeingEdited._links.subgroups.href, {
currentPage: page,
elementsPerPage: this.config.pageSize
});
}
).subscribe((rd: RemoteData<PaginatedList<Group>>) => {
this.subGroups$.next(rd);
}));
}
/**
@@ -124,7 +149,7 @@ export class SubgroupsListComponent implements OnInit, OnDestroy {
return observableOf(false);
} else {
return this.groupDataService.findAllByHref(activeGroup._links.subgroups.href, {
currentPage: 0,
currentPage: 1,
elementsPerPage: 9999
})
.pipe(
@@ -162,7 +187,6 @@ export class SubgroupsListComponent implements OnInit, OnDestroy {
if (activeGroup != null) {
const response = this.groupDataService.deleteSubGroupFromGroup(activeGroup, subgroup);
this.showNotifications('deleteSubgroup', response, subgroup.name, activeGroup);
this.forceUpdateGroups(activeGroup);
} else {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.noActiveGroup'));
}
@@ -186,7 +210,6 @@ export class SubgroupsListComponent implements OnInit, OnDestroy {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.noActiveGroup'));
}
});
this.forceUpdateGroups(this.groupBeingEdited);
}
/**
@@ -201,29 +224,37 @@ export class SubgroupsListComponent implements OnInit, OnDestroy {
this.configSearch.currentPage = 1;
}
this.searchDone = true;
this.groupsSearch = this.groupDataService.searchGroups(this.currentSearchQuery, {
this.unsubFrom(SubKey.SearchResults);
this.subs.set(SubKey.SearchResults, this.groupDataService.searchGroups(this.currentSearchQuery, {
currentPage: this.configSearch.currentPage,
elementsPerPage: this.configSearch.pageSize
});
}).subscribe((rd: RemoteData<PaginatedList<Group>>) => {
this.searchResults$.next(rd);
}));
}
/**
* Force-update the list of groups by first clearing the cache of results of this active groups' subgroups, then performing a new REST call
* @param activeGroup Group currently being edited
* Unsubscribe from a subscription if it's still subscribed, and remove it from the map of
* active subscriptions
*
* @param key The key of the subscription to unsubscribe from
* @private
*/
public forceUpdateGroups(activeGroup: Group) {
this.router.navigateByUrl(this.groupDataService.getGroupEditPageRouterLink(activeGroup));
this.subgroupsOfGroup = this.groupDataService.findAllByHref(activeGroup._links.subgroups.href, {
currentPage: this.config.currentPage,
elementsPerPage: this.config.pageSize
}, false);
private unsubFrom(key: SubKey) {
if (this.subs.has(key)) {
this.subs.get(key).unsubscribe();
this.subs.delete(key);
}
}
/**
* unsub all subscriptions
*/
ngOnDestroy(): void {
this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
for (const key of this.subs.keys()) {
this.unsubFrom(key);
}
}
/**
@@ -237,6 +268,7 @@ export class SubgroupsListComponent implements OnInit, OnDestroy {
response.pipe(getFirstCompletedRemoteData()).subscribe((rd: RemoteData<Group>) => {
if (rd.hasSucceeded) {
this.notificationsService.success(this.translateService.get(this.messagePrefix + '.notification.success.' + messageSuffix, { name: nameObject }));
this.groupDataService.clearGroupLinkRequests(activeGroup._links.subgroups.href);
} else {
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.' + messageSuffix, { name: nameObject }));
}

View File

@@ -2,9 +2,14 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { BehaviorSubject, combineLatest as observableCombineLatest, Subscription, Observable, ObservedValueOf, of as observableOf } from 'rxjs';
import { filter } from 'rxjs/operators';
import { catchError, map, switchMap, take } from 'rxjs/operators';
import {
BehaviorSubject,
combineLatest as observableCombineLatest,
Subscription,
Observable,
of as observableOf
} from 'rxjs';
import { filter, catchError, map, switchMap, take } from 'rxjs/operators';
import { DSpaceObjectDataService } from '../../../core/data/dspace-object-data.service';
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
@@ -20,7 +25,7 @@ import { RouteService } from '../../../core/services/route.service';
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
import {
getAllSucceededRemoteDataPayload,
getFirstCompletedRemoteData
getFirstCompletedRemoteData, getAllSucceededRemoteData
} from '../../../core/shared/operators';
import { PageInfo } from '../../../core/shared/page-info.model';
import { hasValue } from '../../../shared/empty.util';
@@ -70,6 +75,11 @@ export class GroupsRegistryComponent implements OnInit, OnDestroy {
// Current search in groups registry
currentSearchQuery: string;
/**
* The subscription for the search method
*/
searchSub: Subscription;
/**
* List of subscriptions
*/
@@ -93,6 +103,30 @@ export class GroupsRegistryComponent implements OnInit, OnDestroy {
ngOnInit() {
this.search({ query: this.currentSearchQuery });
this.subs.push(this.groups$.pipe(
getAllSucceededRemoteDataPayload(),
switchMap((groups: PaginatedList<Group>) => {
return observableCombineLatest(groups.page.map((group: Group) => {
return observableCombineLatest([
this.authorizationService.isAuthorized(FeatureID.CanDelete, hasValue(group) ? group.self : undefined),
this.hasLinkedDSO(group)
]).pipe(
map(([isAuthorized, hasLinkedDSO]: boolean[]) => {
const groupDtoModel: GroupDtoModel = new GroupDtoModel();
groupDtoModel.ableToDelete = isAuthorized && !hasLinkedDSO;
groupDtoModel.group = group;
return groupDtoModel;
}
)
);
})).pipe(map((dtos: GroupDtoModel[]) => {
return buildPaginatedList(groups.pageInfo, dtos);
}));
})).subscribe((value: PaginatedList<GroupDtoModel>) => {
this.groupsDto$.next(value);
this.pageInfoState$.next(value.pageInfo);
}));
}
/**
@@ -115,37 +149,20 @@ export class GroupsRegistryComponent implements OnInit, OnDestroy {
this.currentSearchQuery = query;
this.config.currentPage = 1;
}
this.subs.push(this.groupService.searchGroups(this.currentSearchQuery.trim(), {
if (hasValue(this.searchSub)) {
this.searchSub.unsubscribe();
this.subs = this.subs.filter((sub: Subscription) => sub !== this.searchSub);
}
this.searchSub = this.groupService.searchGroups(this.currentSearchQuery.trim(), {
currentPage: this.config.currentPage,
elementsPerPage: this.config.pageSize
}).pipe(getFirstCompletedRemoteData())
.subscribe((groupsRD: RemoteData<PaginatedList<Group>>) => {
}).pipe(
getAllSucceededRemoteData()
).subscribe((groupsRD: RemoteData<PaginatedList<Group>>) => {
this.groups$.next(groupsRD);
this.pageInfoState$.next(groupsRD.payload.pageInfo);
}
));
this.subs.push(this.groups$.pipe(
getAllSucceededRemoteDataPayload(),
switchMap((groups: PaginatedList<Group>) => {
return observableCombineLatest(...groups.page.map((group: Group) => {
return observableCombineLatest(
this.authorizationService.isAuthorized(FeatureID.CanDelete, hasValue(group) ? group.self : undefined),
this.hasLinkedDSO(group),
(isAuthorized: ObservedValueOf<Observable<boolean>>, hasLinkedDSO: ObservedValueOf<Observable<boolean>>) => {
const groupDtoModel: GroupDtoModel = new GroupDtoModel();
groupDtoModel.ableToDelete = isAuthorized && !hasLinkedDSO;
groupDtoModel.group = group;
return groupDtoModel;
}
);
})).pipe(map((dtos: GroupDtoModel[]) => {
return buildPaginatedList(groups.pageInfo, dtos);
}));
})).subscribe((value: PaginatedList<GroupDtoModel>) => {
this.groupsDto$.next(value);
this.pageInfoState$.next(value.pageInfo);
}));
});
this.subs.push(this.searchSub);
}
/**
@@ -168,16 +185,13 @@ export class GroupsRegistryComponent implements OnInit, OnDestroy {
}
/**
* This method will ensure that the page gets reset and that the cache is cleared
* This method will set everything to stale, which will cause the lists on this page to update.
*/
reset() {
this.groupService.getBrowseEndpoint().pipe(
switchMap((href) => this.requestService.removeByHrefSubstring(href)),
filter((isCached) => isCached),
take(1)
).subscribe(() => {
this.cleanupSubscribes();
this.search({ query: this.currentSearchQuery });
).subscribe((href: string) => {
this.requestService.setStaleByHrefSubstring(href);
});
}

View File

@@ -224,7 +224,7 @@ export class EPersonDataService extends DataService<EPerson> {
* Method that clears a link's requests in cache
*/
public clearLinkRequests(href: string): void {
this.requestService.removeByHrefSubstring(href);
this.requestService.setStaleByHrefSubstring(href);
}
/**

View File

@@ -205,7 +205,7 @@ export class GroupDataService extends DataService<Group> {
* Method that clears a cached get subgroups of certain group request
*/
public clearGroupLinkRequests(href: string): void {
this.requestService.removeByHrefSubstring(href);
this.requestService.setStaleByHrefSubstring(href);
}
public getGroupRegistryRouterLink(): string {