From e004098016d86a06b75fe5b75a793870a66bf3ec Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Mon, 23 Dec 2019 15:11:38 +0100 Subject: [PATCH] Added pagination to community's collection list in the community page --- ...ty-page-sub-collection-list.component.html | 15 +- ...page-sub-collection-list.component.spec.ts | 169 ++++++++++++++++++ ...nity-page-sub-collection-list.component.ts | 63 ++++++- 3 files changed, 235 insertions(+), 12 deletions(-) create mode 100644 src/app/+community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts diff --git a/src/app/+community-page/sub-collection-list/community-page-sub-collection-list.component.html b/src/app/+community-page/sub-collection-list/community-page-sub-collection-list.component.html index 9156a99b18..bf6ce7fd57 100644 --- a/src/app/+community-page/sub-collection-list/community-page-sub-collection-list.component.html +++ b/src/app/+community-page/sub-collection-list/community-page-sub-collection-list.component.html @@ -1,14 +1,13 @@

{{'community.sub-collection-list.head' | translate}}

- + +
diff --git a/src/app/+community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts b/src/app/+community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts new file mode 100644 index 0000000000..2150676dd6 --- /dev/null +++ b/src/app/+community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts @@ -0,0 +1,169 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { TranslateModule } from '@ngx-translate/core'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { By } from '@angular/platform-browser'; +import { RouterTestingModule } from '@angular/router/testing'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; + +import { CommunityPageSubCollectionListComponent } from './community-page-sub-collection-list.component'; +import { Community } from '../../core/shared/community.model'; +import { SharedModule } from '../../shared/shared.module'; +import { CollectionDataService } from '../../core/data/collection-data.service'; +import { FindListOptions } from '../../core/data/request.models'; +import { createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils'; +import { PaginatedList } from '../../core/data/paginated-list'; +import { PageInfo } from '../../core/shared/page-info.model'; +import { HostWindowService } from '../../shared/host-window.service'; +import { HostWindowServiceStub } from '../../shared/testing/host-window-service-stub'; + +describe('CommunityPageSubCollectionListComponent Component', () => { + let comp: CommunityPageSubCollectionListComponent; + let fixture: ComponentFixture; + let collectionDataServiceStub: any; + let subCollList = []; + + const collections = [Object.assign(new Community(), { + id: '123456789-1', + metadata: { + 'dc.title': [ + { language: 'en_US', value: 'Collection 1' } + ] + } + }), + Object.assign(new Community(), { + id: '123456789-2', + metadata: { + 'dc.title': [ + { language: 'en_US', value: 'Collection 2' } + ] + } + }), + Object.assign(new Community(), { + id: '123456789-3', + metadata: { + 'dc.title': [ + { language: 'en_US', value: 'Collection 3' } + ] + } + }), + Object.assign(new Community(), { + id: '123456789-4', + metadata: { + 'dc.title': [ + { language: 'en_US', value: 'Collection 4' } + ] + } + }), + Object.assign(new Community(), { + id: '123456789-5', + metadata: { + 'dc.title': [ + { language: 'en_US', value: 'Collection 5' } + ] + } + }), + Object.assign(new Community(), { + id: '123456789-6', + metadata: { + 'dc.title': [ + { language: 'en_US', value: 'Collection 6' } + ] + } + }), + Object.assign(new Community(), { + id: '123456789-7', + metadata: { + 'dc.title': [ + { language: 'en_US', value: 'Collection 7' } + ] + } + }) + ]; + + const mockCommunity = Object.assign(new Community(), { + id: '123456789', + metadata: { + 'dc.title': [ + { language: 'en_US', value: 'Test title' } + ] + } + }); + + collectionDataServiceStub = { + findByParent(parentUUID: string, options: FindListOptions = {}) { + let currentPage = options.currentPage; + let elementsPerPage = options.elementsPerPage; + if (currentPage === undefined) { + currentPage = 1 + } + elementsPerPage = 5; + const startPageIndex = (currentPage - 1) * elementsPerPage; + let endPageIndex = (currentPage * elementsPerPage); + if (endPageIndex > subCollList.length) { + endPageIndex = subCollList.length; + } + return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), subCollList.slice(startPageIndex, endPageIndex))); + + } + }; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot(), SharedModule, + RouterTestingModule.withRoutes([]), + NoopAnimationsModule], + declarations: [CommunityPageSubCollectionListComponent], + providers: [ + { provide: CollectionDataService, useValue: collectionDataServiceStub }, + { provide: HostWindowService, useValue: new HostWindowServiceStub(0) }, + ], + schemas: [NO_ERRORS_SCHEMA] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CommunityPageSubCollectionListComponent); + comp = fixture.componentInstance; + comp.community = mockCommunity; + }); + + it('should display a list of collections', () => { + subCollList = collections; + fixture.detectChanges(); + + const collList = fixture.debugElement.queryAll(By.css('li')); + expect(collList.length).toEqual(5); + expect(collList[0].nativeElement.textContent).toContain('Collection 1'); + expect(collList[1].nativeElement.textContent).toContain('Collection 2'); + expect(collList[2].nativeElement.textContent).toContain('Collection 3'); + expect(collList[3].nativeElement.textContent).toContain('Collection 4'); + expect(collList[4].nativeElement.textContent).toContain('Collection 5'); + }); + + it('should not display the header when collection list is empty', () => { + subCollList = []; + fixture.detectChanges(); + + const subComHead = fixture.debugElement.queryAll(By.css('h2')); + expect(subComHead.length).toEqual(0); + }); + + it('should update list of collection on pagination change', () => { + subCollList = collections; + fixture.detectChanges(); + + const pagination = Object.create({}); + pagination.pageId = comp.pageId; + pagination.page = 2; + pagination.pageSize = 5; + pagination.sortField = 'dc.title'; + pagination.sortDirection = 'ASC'; + comp.onPaginationChange(pagination); + fixture.detectChanges(); + + const collList = fixture.debugElement.queryAll(By.css('li')); + expect(collList.length).toEqual(2); + expect(collList[0].nativeElement.textContent).toContain('Collection 6'); + expect(collList[1].nativeElement.textContent).toContain('Collection 7'); + }); +}); diff --git a/src/app/+community-page/sub-collection-list/community-page-sub-collection-list.component.ts b/src/app/+community-page/sub-collection-list/community-page-sub-collection-list.component.ts index b8a5d60002..18f48c3482 100644 --- a/src/app/+community-page/sub-collection-list/community-page-sub-collection-list.component.ts +++ b/src/app/+community-page/sub-collection-list/community-page-sub-collection-list.component.ts @@ -1,12 +1,16 @@ import { Component, Input, OnInit } from '@angular/core'; -import { Observable } from 'rxjs'; + +import { BehaviorSubject } from 'rxjs'; +import { take } from 'rxjs/operators'; import { RemoteData } from '../../core/data/remote-data'; import { Collection } from '../../core/shared/collection.model'; import { Community } from '../../core/shared/community.model'; - import { fadeIn } from '../../shared/animations/fade'; import { PaginatedList } from '../../core/data/paginated-list'; +import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; +import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; +import { CollectionDataService } from '../../core/data/collection-data.service'; @Component({ selector: 'ds-community-page-sub-collection-list', @@ -16,9 +20,60 @@ import { PaginatedList } from '../../core/data/paginated-list'; }) export class CommunityPageSubCollectionListComponent implements OnInit { @Input() community: Community; - subCollectionsRDObs: Observable>>; + + /** + * The pagination configuration + */ + config: PaginationComponentOptions; + + /** + * The pagination id + */ + pageId = 'community-collections-pagination'; + + /** + * The sorting configuration + */ + sortConfig: SortOptions; + + /** + * A list of remote data objects of communities' collections + */ + subCollectionsRDObs: BehaviorSubject>> = new BehaviorSubject>>({} as any); + + constructor(private cds: CollectionDataService) {} ngOnInit(): void { - this.subCollectionsRDObs = this.community.collections; + this.config = new PaginationComponentOptions(); + this.config.id = this.pageId; + this.config.pageSize = 5; + this.config.currentPage = 1; + this.sortConfig = new SortOptions('dc.title', SortDirection.ASC); + this.updatePage(); + } + + /** + * Called when one of the pagination settings is changed + * @param event The new pagination data + */ + onPaginationChange(event) { + this.config.currentPage = event.page; + this.config.pageSize = event.pageSize; + this.sortConfig.field = event.sortField; + this.sortConfig.direction = event.sortDirection; + this.updatePage(); + } + + /** + * Update the list of collections + */ + updatePage() { + this.cds.findByParent(this.community.id,{ + currentPage: this.config.currentPage, + elementsPerPage: this.config.pageSize, + sort: { field: this.sortConfig.field, direction: this.sortConfig.direction } + }).pipe(take(1)).subscribe((results) => { + this.subCollectionsRDObs.next(results); + }); } }