mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
83783: Show owning and mapped collections on item page
This commit is contained in:
@@ -208,10 +208,20 @@ export class CollectionDataService extends ComColDataService<Collection> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link RemoteData} of {@link Collection} that is the owing collection of the given item
|
||||
* Returns {@link RemoteData} of {@link Collection} that is the owning collection of the given item
|
||||
* @param item Item we want the owning collection of
|
||||
*/
|
||||
findOwningCollectionFor(item: Item): Observable<RemoteData<Collection>> {
|
||||
return this.findByHref(item._links.owningCollection.href);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of mapped collections for the given item.
|
||||
* @param item Item for which the mapped collections should be retrieved.
|
||||
* @param findListOptions Pagination and search options.
|
||||
*/
|
||||
findMappedCollectionsFor(item: Item, findListOptions?: FindListOptions): Observable<RemoteData<PaginatedList<Collection>>> {
|
||||
return this.findAllByHref(item._links.mappedCollections.href, findListOptions);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,7 +1,21 @@
|
||||
<ds-metadata-field-wrapper *ngIf="(this.collectionsRD$ | async)?.hasSucceeded" [label]="label | translate">
|
||||
<ds-metadata-field-wrapper [label]="label | translate">
|
||||
<div class="collections">
|
||||
<a *ngFor="let collection of (this.collectionsRD$ | async)?.payload?.page; let last=last;" [routerLink]="['/collections', collection.id]">
|
||||
<a *ngFor="let collection of (this.collections$ | async); let last=last;" [routerLink]="['/collections', collection.id]">
|
||||
<span>{{collection?.name}}</span><span *ngIf="!last" [innerHTML]="separator"></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div *ngIf="isLoading$ | async">
|
||||
{{'item.page.collections.loading' | translate}}
|
||||
</div>
|
||||
|
||||
<a
|
||||
*ngIf="!(isLoading$ | async) && (hasMore$ | async)"
|
||||
(click)="$event.preventDefault(); handleLoadMore()"
|
||||
class="load-more-btn btn btn-sm btn-outline-secondary"
|
||||
role="button"
|
||||
href="#"
|
||||
>
|
||||
{{'item.page.collections.load-more' | translate}}
|
||||
</a>
|
||||
</ds-metadata-field-wrapper>
|
||||
|
@@ -9,46 +9,45 @@ import { Item } from '../../../core/shared/item.model';
|
||||
import { getMockRemoteDataBuildService } from '../../../shared/mocks/remote-data-build.service.mock';
|
||||
import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
|
||||
import { CollectionsComponent } from './collections.component';
|
||||
import { FindListOptions } from '../../../core/data/request.models';
|
||||
import { buildPaginatedList, PaginatedList } from '../../../core/data/paginated-list.model';
|
||||
import { PageInfo } from '../../../core/shared/page-info.model';
|
||||
|
||||
let collectionsComponent: CollectionsComponent;
|
||||
let fixture: ComponentFixture<CollectionsComponent>;
|
||||
|
||||
let collectionDataServiceStub;
|
||||
|
||||
const mockCollection1: Collection = Object.assign(new Collection(), {
|
||||
metadata: {
|
||||
'dc.description.abstract': [
|
||||
{
|
||||
language: 'en_US',
|
||||
value: 'Short description'
|
||||
}
|
||||
]
|
||||
},
|
||||
_links: {
|
||||
self: { href: 'collection-selflink' }
|
||||
}
|
||||
const createMockCollection = (id: string) => Object.assign(new Collection(), {
|
||||
id: id,
|
||||
name: `collection-${id}`,
|
||||
});
|
||||
|
||||
const succeededMockItem: Item = Object.assign(new Item(), {owningCollection: createSuccessfulRemoteDataObject$(mockCollection1)});
|
||||
const failedMockItem: Item = Object.assign(new Item(), {owningCollection: createFailedRemoteDataObject$('error', 500)});
|
||||
const mockItem: Item = new Item();
|
||||
|
||||
describe('CollectionsComponent', () => {
|
||||
collectionDataServiceStub = {
|
||||
findOwningCollectionFor(item: Item) {
|
||||
if (item === succeededMockItem) {
|
||||
return createSuccessfulRemoteDataObject$(mockCollection1);
|
||||
} else {
|
||||
return createFailedRemoteDataObject$('error', 500);
|
||||
}
|
||||
}
|
||||
};
|
||||
let collectionDataService;
|
||||
|
||||
let mockCollection1: Collection;
|
||||
let mockCollection2: Collection;
|
||||
let mockCollection3: Collection;
|
||||
let mockCollection4: Collection;
|
||||
|
||||
let component: CollectionsComponent;
|
||||
let fixture: ComponentFixture<CollectionsComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
collectionDataService = jasmine.createSpyObj([
|
||||
'findOwningCollectionFor',
|
||||
'findMappedCollectionsFor',
|
||||
]);
|
||||
|
||||
mockCollection1 = createMockCollection('c1');
|
||||
mockCollection2 = createMockCollection('c2');
|
||||
mockCollection3 = createMockCollection('c3');
|
||||
mockCollection4 = createMockCollection('c4');
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot()],
|
||||
declarations: [ CollectionsComponent ],
|
||||
providers: [
|
||||
{ provide: RemoteDataBuildService, useValue: getMockRemoteDataBuildService()},
|
||||
{ provide: CollectionDataService, useValue: collectionDataServiceStub },
|
||||
{ provide: CollectionDataService, useValue: collectionDataService },
|
||||
],
|
||||
|
||||
schemas: [ NO_ERRORS_SCHEMA ]
|
||||
@@ -59,33 +58,264 @@ describe('CollectionsComponent', () => {
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
fixture = TestBed.createComponent(CollectionsComponent);
|
||||
collectionsComponent = fixture.componentInstance;
|
||||
collectionsComponent.label = 'test.test';
|
||||
collectionsComponent.separator = '<br/>';
|
||||
|
||||
component = fixture.componentInstance;
|
||||
component.item = mockItem;
|
||||
component.label = 'test.test';
|
||||
component.separator = '<br/>';
|
||||
component.pageSize = 2;
|
||||
}));
|
||||
|
||||
describe('When the requested item request has succeeded', () => {
|
||||
describe('when the item has only an owning collection', () => {
|
||||
let mockPage1: PaginatedList<Collection>;
|
||||
|
||||
beforeEach(() => {
|
||||
collectionsComponent.item = succeededMockItem;
|
||||
mockPage1 = buildPaginatedList(Object.assign(new PageInfo(), {
|
||||
currentPage: 1,
|
||||
elementsPerPage: 2,
|
||||
totalPages: 0,
|
||||
totalElements: 0,
|
||||
}), []);
|
||||
|
||||
collectionDataService.findOwningCollectionFor.and.returnValue(createSuccessfulRemoteDataObject$(mockCollection1));
|
||||
collectionDataService.findMappedCollectionsFor.and.returnValue(createSuccessfulRemoteDataObject$(mockPage1));
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should show the collection', () => {
|
||||
const collectionField = fixture.debugElement.query(By.css('ds-metadata-field-wrapper div.collections'));
|
||||
expect(collectionField).not.toBeNull();
|
||||
it('should display the owning collection', () => {
|
||||
const collectionFields = fixture.debugElement.queryAll(By.css('ds-metadata-field-wrapper div.collections a'));
|
||||
const loadMoreBtn = fixture.debugElement.query(By.css('ds-metadata-field-wrapper .load-more-btn'));
|
||||
|
||||
expect(collectionDataService.findOwningCollectionFor).toHaveBeenCalledOnceWith(mockItem);
|
||||
expect(collectionDataService.findMappedCollectionsFor).toHaveBeenCalledOnceWith(mockItem, Object.assign(new FindListOptions(), {
|
||||
elementsPerPage: 2,
|
||||
currentPage: 1,
|
||||
}));
|
||||
|
||||
expect(collectionFields.length).toBe(1);
|
||||
expect(collectionFields[0].nativeElement.textContent).toEqual('collection-c1');
|
||||
|
||||
expect(component.lastPage$.getValue()).toBe(1);
|
||||
expect(component.hasMore$.getValue()).toBe(false);
|
||||
expect(component.isLoading$.getValue()).toBe(false);
|
||||
|
||||
expect(loadMoreBtn).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('When the requested item request has failed', () => {
|
||||
describe('when the item has an owning collection and one mapped collection', () => {
|
||||
let mockPage1: PaginatedList<Collection>;
|
||||
|
||||
beforeEach(() => {
|
||||
collectionsComponent.item = failedMockItem;
|
||||
mockPage1 = buildPaginatedList(Object.assign(new PageInfo(), {
|
||||
currentPage: 1,
|
||||
elementsPerPage: 2,
|
||||
totalPages: 1,
|
||||
totalElements: 1,
|
||||
}), [mockCollection2]);
|
||||
|
||||
collectionDataService.findOwningCollectionFor.and.returnValue(createSuccessfulRemoteDataObject$(mockCollection1));
|
||||
collectionDataService.findMappedCollectionsFor.and.returnValue(createSuccessfulRemoteDataObject$(mockPage1));
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should not show the collection', () => {
|
||||
const collectionField = fixture.debugElement.query(By.css('ds-metadata-field-wrapper div.collections'));
|
||||
expect(collectionField).toBeNull();
|
||||
it('should display the owning collection and the mapped collection', () => {
|
||||
const collectionFields = fixture.debugElement.queryAll(By.css('ds-metadata-field-wrapper div.collections a'));
|
||||
const loadMoreBtn = fixture.debugElement.query(By.css('ds-metadata-field-wrapper .load-more-btn'));
|
||||
|
||||
expect(collectionDataService.findOwningCollectionFor).toHaveBeenCalledOnceWith(mockItem);
|
||||
expect(collectionDataService.findMappedCollectionsFor).toHaveBeenCalledOnceWith(mockItem, Object.assign(new FindListOptions(), {
|
||||
elementsPerPage: 2,
|
||||
currentPage: 1,
|
||||
}));
|
||||
|
||||
expect(collectionFields.length).toBe(2);
|
||||
expect(collectionFields[0].nativeElement.textContent).toEqual('collection-c1');
|
||||
expect(collectionFields[1].nativeElement.textContent).toEqual('collection-c2');
|
||||
|
||||
expect(component.lastPage$.getValue()).toBe(1);
|
||||
expect(component.hasMore$.getValue()).toBe(false);
|
||||
expect(component.isLoading$.getValue()).toBe(false);
|
||||
|
||||
expect(loadMoreBtn).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the item has an owning collection and multiple mapped collections', () => {
|
||||
let mockPage1: PaginatedList<Collection>;
|
||||
let mockPage2: PaginatedList<Collection>;
|
||||
|
||||
beforeEach(() => {
|
||||
mockPage1 = buildPaginatedList(Object.assign(new PageInfo(), {
|
||||
currentPage: 1,
|
||||
elementsPerPage: 2,
|
||||
totalPages: 2,
|
||||
totalElements: 3,
|
||||
}), [mockCollection2, mockCollection3]);
|
||||
|
||||
mockPage2 = buildPaginatedList(Object.assign(new PageInfo(), {
|
||||
currentPage: 2,
|
||||
elementsPerPage: 2,
|
||||
totalPages: 2,
|
||||
totalElements: 1,
|
||||
}), [mockCollection4]);
|
||||
|
||||
collectionDataService.findOwningCollectionFor.and.returnValue(createSuccessfulRemoteDataObject$(mockCollection1));
|
||||
collectionDataService.findMappedCollectionsFor.and.returnValues(
|
||||
createSuccessfulRemoteDataObject$(mockPage1),
|
||||
createSuccessfulRemoteDataObject$(mockPage2),
|
||||
);
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should display the owning collection, two mapped collections and a load more button', () => {
|
||||
const collectionFields = fixture.debugElement.queryAll(By.css('ds-metadata-field-wrapper div.collections a'));
|
||||
const loadMoreBtn = fixture.debugElement.query(By.css('ds-metadata-field-wrapper .load-more-btn'));
|
||||
|
||||
expect(collectionDataService.findOwningCollectionFor).toHaveBeenCalledOnceWith(mockItem);
|
||||
expect(collectionDataService.findMappedCollectionsFor).toHaveBeenCalledOnceWith(mockItem, Object.assign(new FindListOptions(), {
|
||||
elementsPerPage: 2,
|
||||
currentPage: 1,
|
||||
}));
|
||||
|
||||
expect(collectionFields.length).toBe(3);
|
||||
expect(collectionFields[0].nativeElement.textContent).toEqual('collection-c1');
|
||||
expect(collectionFields[1].nativeElement.textContent).toEqual('collection-c2');
|
||||
expect(collectionFields[2].nativeElement.textContent).toEqual('collection-c3');
|
||||
|
||||
expect(component.lastPage$.getValue()).toBe(1);
|
||||
expect(component.hasMore$.getValue()).toBe(true);
|
||||
expect(component.isLoading$.getValue()).toBe(false);
|
||||
|
||||
expect(loadMoreBtn).toBeTruthy();
|
||||
});
|
||||
|
||||
describe('when the load more button is clicked', () => {
|
||||
beforeEach(() => {
|
||||
const loadMoreBtn = fixture.debugElement.query(By.css('ds-metadata-field-wrapper .load-more-btn'));
|
||||
loadMoreBtn.nativeElement.click();
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should display the owning collection and three mapped collections', () => {
|
||||
const collectionFields = fixture.debugElement.queryAll(By.css('ds-metadata-field-wrapper div.collections a'));
|
||||
const loadMoreBtn = fixture.debugElement.query(By.css('ds-metadata-field-wrapper .load-more-btn'));
|
||||
|
||||
expect(collectionDataService.findOwningCollectionFor).toHaveBeenCalledOnceWith(mockItem);
|
||||
expect(collectionDataService.findMappedCollectionsFor).toHaveBeenCalledTimes(2);
|
||||
expect(collectionDataService.findMappedCollectionsFor).toHaveBeenCalledWith(mockItem, Object.assign(new FindListOptions(), {
|
||||
elementsPerPage: 2,
|
||||
currentPage: 1,
|
||||
}));
|
||||
expect(collectionDataService.findMappedCollectionsFor).toHaveBeenCalledWith(mockItem, Object.assign(new FindListOptions(), {
|
||||
elementsPerPage: 2,
|
||||
currentPage: 2,
|
||||
}));
|
||||
|
||||
expect(collectionFields.length).toBe(4);
|
||||
expect(collectionFields[0].nativeElement.textContent).toEqual('collection-c1');
|
||||
expect(collectionFields[1].nativeElement.textContent).toEqual('collection-c2');
|
||||
expect(collectionFields[2].nativeElement.textContent).toEqual('collection-c3');
|
||||
expect(collectionFields[3].nativeElement.textContent).toEqual('collection-c4');
|
||||
|
||||
expect(component.lastPage$.getValue()).toBe(2);
|
||||
expect(component.hasMore$.getValue()).toBe(false);
|
||||
expect(component.isLoading$.getValue()).toBe(false);
|
||||
|
||||
expect(loadMoreBtn).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the request for the owning collection fails', () => {
|
||||
let mockPage1: PaginatedList<Collection>;
|
||||
|
||||
beforeEach(() => {
|
||||
mockPage1 = buildPaginatedList(Object.assign(new PageInfo(), {
|
||||
currentPage: 1,
|
||||
elementsPerPage: 2,
|
||||
totalPages: 1,
|
||||
totalElements: 1,
|
||||
}), [mockCollection2]);
|
||||
|
||||
collectionDataService.findOwningCollectionFor.and.returnValue(createFailedRemoteDataObject$());
|
||||
collectionDataService.findMappedCollectionsFor.and.returnValue(createSuccessfulRemoteDataObject$(mockPage1));
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should display the mapped collection only', () => {
|
||||
const collectionFields = fixture.debugElement.queryAll(By.css('ds-metadata-field-wrapper div.collections a'));
|
||||
const loadMoreBtn = fixture.debugElement.query(By.css('ds-metadata-field-wrapper .load-more-btn'));
|
||||
|
||||
expect(collectionDataService.findOwningCollectionFor).toHaveBeenCalledOnceWith(mockItem);
|
||||
expect(collectionDataService.findMappedCollectionsFor).toHaveBeenCalledOnceWith(mockItem, Object.assign(new FindListOptions(), {
|
||||
elementsPerPage: 2,
|
||||
currentPage: 1,
|
||||
}));
|
||||
|
||||
expect(collectionFields.length).toBe(1);
|
||||
expect(collectionFields[0].nativeElement.textContent).toEqual('collection-c2');
|
||||
|
||||
expect(component.lastPage$.getValue()).toBe(1);
|
||||
expect(component.hasMore$.getValue()).toBe(false);
|
||||
expect(component.isLoading$.getValue()).toBe(false);
|
||||
|
||||
expect(loadMoreBtn).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the request for the mapped collections fails', () => {
|
||||
beforeEach(() => {
|
||||
collectionDataService.findOwningCollectionFor.and.returnValue(createSuccessfulRemoteDataObject$(mockCollection1));
|
||||
collectionDataService.findMappedCollectionsFor.and.returnValue(createFailedRemoteDataObject$());
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should display the owning collection only', () => {
|
||||
const collectionFields = fixture.debugElement.queryAll(By.css('ds-metadata-field-wrapper div.collections a'));
|
||||
const loadMoreBtn = fixture.debugElement.query(By.css('ds-metadata-field-wrapper .load-more-btn'));
|
||||
|
||||
expect(collectionDataService.findOwningCollectionFor).toHaveBeenCalledOnceWith(mockItem);
|
||||
expect(collectionDataService.findMappedCollectionsFor).toHaveBeenCalledOnceWith(mockItem, Object.assign(new FindListOptions(), {
|
||||
elementsPerPage: 2,
|
||||
currentPage: 1,
|
||||
}));
|
||||
|
||||
expect(collectionFields.length).toBe(1);
|
||||
expect(collectionFields[0].nativeElement.textContent).toEqual('collection-c1');
|
||||
|
||||
expect(component.lastPage$.getValue()).toBe(0);
|
||||
expect(component.hasMore$.getValue()).toBe(true);
|
||||
expect(component.isLoading$.getValue()).toBe(false);
|
||||
|
||||
expect(loadMoreBtn).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when both requests fail', () => {
|
||||
beforeEach(() => {
|
||||
collectionDataService.findOwningCollectionFor.and.returnValue(createFailedRemoteDataObject$());
|
||||
collectionDataService.findMappedCollectionsFor.and.returnValue(createFailedRemoteDataObject$());
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should display no collections', () => {
|
||||
const collectionFields = fixture.debugElement.queryAll(By.css('ds-metadata-field-wrapper div.collections a'));
|
||||
const loadMoreBtn = fixture.debugElement.query(By.css('ds-metadata-field-wrapper .load-more-btn'));
|
||||
|
||||
expect(collectionDataService.findOwningCollectionFor).toHaveBeenCalledOnceWith(mockItem);
|
||||
expect(collectionDataService.findMappedCollectionsFor).toHaveBeenCalledOnceWith(mockItem, Object.assign(new FindListOptions(), {
|
||||
elementsPerPage: 2,
|
||||
currentPage: 1,
|
||||
}));
|
||||
|
||||
expect(collectionFields.length).toBe(0);
|
||||
|
||||
expect(component.lastPage$.getValue()).toBe(0);
|
||||
expect(component.hasMore$.getValue()).toBe(true);
|
||||
expect(component.isLoading$.getValue()).toBe(false);
|
||||
|
||||
expect(loadMoreBtn).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
@@ -1,14 +1,19 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
|
||||
import {map, scan, startWith, switchMap, tap, withLatestFrom} from 'rxjs/operators';
|
||||
import { CollectionDataService } from '../../../core/data/collection-data.service';
|
||||
import { PaginatedList, buildPaginatedList } from '../../../core/data/paginated-list.model';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list.model';
|
||||
|
||||
import { Collection } from '../../../core/shared/collection.model';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { PageInfo } from '../../../core/shared/page-info.model';
|
||||
import { hasValue } from '../../../shared/empty.util';
|
||||
import { FindListOptions } from '../../../core/data/request.models';
|
||||
import {
|
||||
getAllCompletedRemoteData,
|
||||
getAllSucceededRemoteDataPayload,
|
||||
getFirstSucceededRemoteDataPayload,
|
||||
getPaginatedListPayload,
|
||||
} from '../../../core/shared/operators';
|
||||
|
||||
/**
|
||||
* This component renders the parent collections section of the item
|
||||
@@ -27,42 +32,92 @@ export class CollectionsComponent implements OnInit {
|
||||
|
||||
separator = '<br/>';
|
||||
|
||||
collectionsRD$: Observable<RemoteData<PaginatedList<Collection>>>;
|
||||
/**
|
||||
* Amount of mapped collections that should be fetched at once.
|
||||
*/
|
||||
pageSize = 5;
|
||||
|
||||
/**
|
||||
* Last page of the mapped collections that has been fetched.
|
||||
*/
|
||||
lastPage$: BehaviorSubject<number> = new BehaviorSubject<number>(0);
|
||||
|
||||
/**
|
||||
* Push an event to this observable to fetch the next page of mapped collections.
|
||||
* Because this observable is a behavior subject, the first page will be requested
|
||||
* immediately after subscription.
|
||||
*/
|
||||
loadMore$: BehaviorSubject<void> = new BehaviorSubject(undefined);
|
||||
|
||||
/**
|
||||
* Whether or not a page of mapped collections is currently being loaded.
|
||||
*/
|
||||
isLoading$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
|
||||
|
||||
/**
|
||||
* Whether or not more pages of mapped collections are available.
|
||||
*/
|
||||
hasMore$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
|
||||
|
||||
/**
|
||||
* All collections that have been retrieved so far. This includes the owning collection,
|
||||
* as well as any number of pages of mapped collections.
|
||||
*/
|
||||
collections$: Observable<Collection[]>;
|
||||
|
||||
constructor(private cds: CollectionDataService) {
|
||||
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
// this.collections = this.item.parents.payload;
|
||||
const owningCollection$: Observable<Collection> = this.cds.findOwningCollectionFor(this.item).pipe(
|
||||
getFirstSucceededRemoteDataPayload(),
|
||||
startWith(null as Collection),
|
||||
);
|
||||
|
||||
// TODO: this should use parents, but the collections
|
||||
// for an Item aren't returned by the REST API yet,
|
||||
// only the owning collection
|
||||
this.collectionsRD$ = this.cds.findOwningCollectionFor(this.item).pipe(
|
||||
map((rd: RemoteData<Collection>) => {
|
||||
if (hasValue(rd.payload)) {
|
||||
return new RemoteData(
|
||||
rd.timeCompleted,
|
||||
rd.msToLive,
|
||||
rd.lastUpdated,
|
||||
rd.state,
|
||||
rd.errorMessage,
|
||||
buildPaginatedList({
|
||||
elementsPerPage: 10,
|
||||
totalPages: 1,
|
||||
currentPage: 1,
|
||||
totalElements: 1,
|
||||
_links: {
|
||||
self: rd.payload._links.self
|
||||
}
|
||||
} as PageInfo, [rd.payload]),
|
||||
rd.statusCode
|
||||
);
|
||||
} else {
|
||||
return rd as any;
|
||||
}
|
||||
})
|
||||
const mappedCollections$: Observable<Collection[]> = this.loadMore$.pipe(
|
||||
// update isLoading$
|
||||
tap(() => this.isLoading$.next(true)),
|
||||
|
||||
// request next batch of mapped collections
|
||||
withLatestFrom(this.lastPage$),
|
||||
switchMap(([_, lastPage]: [void, number]) => {
|
||||
return this.cds.findMappedCollectionsFor(this.item, Object.assign(new FindListOptions(), {
|
||||
elementsPerPage: this.pageSize,
|
||||
currentPage: lastPage + 1,
|
||||
}));
|
||||
}),
|
||||
|
||||
getAllCompletedRemoteData<PaginatedList<Collection>>(),
|
||||
|
||||
// update isLoading$
|
||||
tap(() => this.isLoading$.next(false)),
|
||||
|
||||
getAllSucceededRemoteDataPayload(),
|
||||
|
||||
// update hasMore$
|
||||
tap((response: PaginatedList<Collection>) => this.hasMore$.next(response.currentPage < response.totalPages)),
|
||||
|
||||
// update lastPage$
|
||||
tap((response: PaginatedList<Collection>) => this.lastPage$.next(response.currentPage)),
|
||||
|
||||
getPaginatedListPayload<Collection>(),
|
||||
|
||||
// add current batch to list of collections
|
||||
scan((prev: Collection[], current: Collection[]) => [...prev, ...current], []),
|
||||
|
||||
startWith([]),
|
||||
) as Observable<Collection[]>;
|
||||
|
||||
this.collections$ = combineLatest([owningCollection$, mappedCollections$]).pipe(
|
||||
map(([owningCollection, mappedCollections]: [Collection, Collection[]]) => {
|
||||
return [owningCollection, ...mappedCollections].filter(collection => hasValue(collection));
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
handleLoadMore() {
|
||||
this.loadMore$.next();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1874,6 +1874,10 @@
|
||||
|
||||
"item.page.collections": "Collections",
|
||||
|
||||
"item.page.collections.loading": "Loading...",
|
||||
|
||||
"item.page.collections.load-more": "Load more",
|
||||
|
||||
"item.page.date": "Date",
|
||||
|
||||
"item.page.edit": "Edit this item",
|
||||
|
Reference in New Issue
Block a user