mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
fix issues with the group edit page
This commit is contained in:
@@ -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>
|
||||
|
@@ -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) => {
|
||||
|
@@ -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,
|
||||
elementsPerPage: this.config.pageSize
|
||||
});
|
||||
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 }));
|
||||
}
|
||||
|
@@ -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>
|
||||
|
@@ -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) => {
|
||||
|
@@ -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,
|
||||
elementsPerPage: this.config.pageSize
|
||||
});
|
||||
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 }));
|
||||
}
|
||||
|
@@ -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>>) => {
|
||||
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);
|
||||
}));
|
||||
}).pipe(
|
||||
getAllSucceededRemoteData()
|
||||
).subscribe((groupsRD: RemoteData<PaginatedList<Group>>) => {
|
||||
this.groups$.next(groupsRD);
|
||||
this.pageInfoState$.next(groupsRD.payload.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);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -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 {
|
||||
|
Reference in New Issue
Block a user