Added pagination to community's sub-community list in the community page

This commit is contained in:
Giuseppe Digilio
2019-12-23 15:12:05 +01:00
parent e004098016
commit fcbb690b29
3 changed files with 178 additions and 41 deletions

View File

@@ -1,14 +1,13 @@
<ng-container *ngVar="(subCommunitiesRDObs | async) as subCommunitiesRD"> <ng-container *ngVar="(subCommunitiesRDObs | async) as subCommunitiesRD">
<div *ngIf="subCommunitiesRD?.hasSucceeded && subCommunitiesRD?.payload.totalElements > 0" @fadeIn> <div *ngIf="subCommunitiesRD?.hasSucceeded && subCommunitiesRD?.payload.totalElements > 0" @fadeIn>
<h2>{{'community.sub-community-list.head' | translate}}</h2> <h2>{{'community.sub-community-list.head' | translate}}</h2>
<ul> <ds-viewable-collection
<li *ngFor="let community of subCommunitiesRD?.payload.page"> [config]="config"
<p> [sortConfig]="sortConfig"
<span class="lead"><a [routerLink]="['/communities', community.id]">{{community.name}}</a></span><br> [objects]="subCommunitiesRD"
<span class="text-muted">{{community.shortDescription}}</span> [hideGear]="false"
</p> (paginationChange)="onPaginationChange($event)">
</li> </ds-viewable-collection>
</ul>
</div> </div>
<ds-error *ngIf="subCommunitiesRD?.hasFailed" message="{{'error.sub-communities' | translate}}"></ds-error> <ds-error *ngIf="subCommunitiesRD?.hasFailed" message="{{'error.sub-communities' | translate}}"></ds-error>
<ds-loading *ngIf="subCommunitiesRD?.isLoading" message="{{'loading.sub-communities' | translate}}"></ds-loading> <ds-loading *ngIf="subCommunitiesRD?.isLoading" message="{{'loading.sub-communities' | translate}}"></ds-loading>

View File

@@ -1,21 +1,26 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {TranslateModule} from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import {NO_ERRORS_SCHEMA} from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import {CommunityPageSubCommunityListComponent} from './community-page-sub-community-list.component'; import { RouterTestingModule } from '@angular/router/testing';
import {Community} from '../../core/shared/community.model'; import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import {RemoteData} from '../../core/data/remote-data'; import { By } from '@angular/platform-browser';
import {PaginatedList} from '../../core/data/paginated-list';
import {PageInfo} from '../../core/shared/page-info.model'; import { CommunityPageSubCommunityListComponent } from './community-page-sub-community-list.component';
import {SharedModule} from '../../shared/shared.module'; import { Community } from '../../core/shared/community.model';
import {RouterTestingModule} from '@angular/router/testing'; import { PaginatedList } from '../../core/data/paginated-list';
import {NoopAnimationsModule} from '@angular/platform-browser/animations'; import { PageInfo } from '../../core/shared/page-info.model';
import {By} from '@angular/platform-browser'; import { SharedModule } from '../../shared/shared.module';
import {of as observableOf, Observable } from 'rxjs';
import { createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils'; import { createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils';
import { FindListOptions } from '../../core/data/request.models';
import { HostWindowService } from '../../shared/host-window.service';
import { HostWindowServiceStub } from '../../shared/testing/host-window-service-stub';
import { CommunityDataService } from '../../core/data/community-data.service';
describe('SubCommunityList Component', () => { describe('SubCommunityList Component', () => {
let comp: CommunityPageSubCommunityListComponent; let comp: CommunityPageSubCommunityListComponent;
let fixture: ComponentFixture<CommunityPageSubCommunityListComponent>; let fixture: ComponentFixture<CommunityPageSubCommunityListComponent>;
let communityDataServiceStub: any;
let subCommList = [];
const subcommunities = [Object.assign(new Community(), { const subcommunities = [Object.assign(new Community(), {
id: '123456789-1', id: '123456789-1',
@@ -32,27 +37,76 @@ describe('SubCommunityList Component', () => {
{ language: 'en_US', value: 'SubCommunity 2' } { language: 'en_US', value: 'SubCommunity 2' }
] ]
} }
}),
Object.assign(new Community(), {
id: '123456789-3',
metadata: {
'dc.title': [
{ language: 'en_US', value: 'SubCommunity 3' }
]
}
}),
Object.assign(new Community(), {
id: '12345678942',
metadata: {
'dc.title': [
{ language: 'en_US', value: 'SubCommunity 4' }
]
}
}),
Object.assign(new Community(), {
id: '123456789-5',
metadata: {
'dc.title': [
{ language: 'en_US', value: 'SubCommunity 5' }
]
}
}),
Object.assign(new Community(), {
id: '123456789-6',
metadata: {
'dc.title': [
{ language: 'en_US', value: 'SubCommunity 6' }
]
}
}),
Object.assign(new Community(), {
id: '123456789-7',
metadata: {
'dc.title': [
{ language: 'en_US', value: 'SubCommunity 7' }
]
}
}) })
]; ];
const emptySubCommunitiesCommunity = Object.assign(new Community(), { const mockCommunity = Object.assign(new Community(), {
id: '123456789',
metadata: { metadata: {
'dc.title': [ 'dc.title': [
{ language: 'en_US', value: 'Test title' } { language: 'en_US', value: 'Test title' }
] ]
}, }
subcommunities: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), []))
}); });
const mockCommunity = Object.assign(new Community(), { communityDataServiceStub = {
metadata: { findByParent(parentUUID: string, options: FindListOptions = {}) {
'dc.title': [ let currentPage = options.currentPage;
{ language: 'en_US', value: 'Test title' } let elementsPerPage = options.elementsPerPage;
] if (currentPage === undefined) {
}, currentPage = 1
subcommunities: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), subcommunities)) }
}) elementsPerPage = 5;
;
const startPageIndex = (currentPage - 1) * elementsPerPage;
let endPageIndex = (currentPage * elementsPerPage);
if (endPageIndex > subCommList.length) {
endPageIndex = subCommList.length;
}
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), subCommList.slice(startPageIndex, endPageIndex)));
}
};
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
@@ -60,6 +114,10 @@ describe('SubCommunityList Component', () => {
RouterTestingModule.withRoutes([]), RouterTestingModule.withRoutes([]),
NoopAnimationsModule], NoopAnimationsModule],
declarations: [CommunityPageSubCommunityListComponent], declarations: [CommunityPageSubCommunityListComponent],
providers: [
{ provide: CommunityDataService, useValue: communityDataServiceStub },
{ provide: HostWindowService, useValue: new HostWindowServiceStub(0) },
],
schemas: [NO_ERRORS_SCHEMA] schemas: [NO_ERRORS_SCHEMA]
}).compileComponents(); }).compileComponents();
})); }));
@@ -67,23 +125,47 @@ describe('SubCommunityList Component', () => {
beforeEach(() => { beforeEach(() => {
fixture = TestBed.createComponent(CommunityPageSubCommunityListComponent); fixture = TestBed.createComponent(CommunityPageSubCommunityListComponent);
comp = fixture.componentInstance; comp = fixture.componentInstance;
comp.community = mockCommunity;
}); });
it('should display a list of subCommunities', () => { it('should display a list of subCommunities', () => {
comp.community = mockCommunity; subCommList = subcommunities;
fixture.detectChanges(); fixture.detectChanges();
const subComList = fixture.debugElement.queryAll(By.css('li')); const subComList = fixture.debugElement.queryAll(By.css('li'));
expect(subComList.length).toEqual(2); expect(subComList.length).toEqual(5);
expect(subComList[0].nativeElement.textContent).toContain('SubCommunity 1'); expect(subComList[0].nativeElement.textContent).toContain('SubCommunity 1');
expect(subComList[1].nativeElement.textContent).toContain('SubCommunity 2'); expect(subComList[1].nativeElement.textContent).toContain('SubCommunity 2');
expect(subComList[2].nativeElement.textContent).toContain('SubCommunity 3');
expect(subComList[3].nativeElement.textContent).toContain('SubCommunity 4');
expect(subComList[4].nativeElement.textContent).toContain('SubCommunity 5');
}); });
it('should not display the header when subCommunities are empty', () => { it('should not display the header when subCommunities are empty', () => {
comp.community = emptySubCommunitiesCommunity; subCommList = [];
fixture.detectChanges(); fixture.detectChanges();
const subComHead = fixture.debugElement.queryAll(By.css('h2')); const subComHead = fixture.debugElement.queryAll(By.css('h2'));
expect(subComHead.length).toEqual(0); expect(subComHead.length).toEqual(0);
}); });
it('should update list of collection on pagination change', () => {
subCommList = subcommunities;
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('SubCommunity 6');
expect(collList[1].nativeElement.textContent).toContain('SubCommunity 7');
});
}); });

View File

@@ -1,26 +1,82 @@
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { take } from 'rxjs/operators';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { Community } from '../../core/shared/community.model'; import { Community } from '../../core/shared/community.model';
import { fadeIn } from '../../shared/animations/fade'; import { fadeIn } from '../../shared/animations/fade';
import { PaginatedList } from '../../core/data/paginated-list'; import { PaginatedList } from '../../core/data/paginated-list';
import {Observable} from 'rxjs'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
import { CommunityDataService } from '../../core/data/community-data.service';
@Component({ @Component({
selector: 'ds-community-page-sub-community-list', selector: 'ds-community-page-sub-community-list',
styleUrls: ['./community-page-sub-community-list.component.scss'], styleUrls: ['./community-page-sub-community-list.component.scss'],
templateUrl: './community-page-sub-community-list.component.html', templateUrl: './community-page-sub-community-list.component.html',
animations:[fadeIn] animations: [fadeIn]
}) })
/** /**
* Component to render the sub-communities of a Community * Component to render the sub-communities of a Community
*/ */
export class CommunityPageSubCommunityListComponent implements OnInit { export class CommunityPageSubCommunityListComponent implements OnInit {
@Input() community: Community; @Input() community: Community;
subCommunitiesRDObs: Observable<RemoteData<PaginatedList<Community>>>;
/**
* The pagination configuration
*/
config: PaginationComponentOptions;
/**
* The pagination id
*/
pageId = 'community-subCommunities-pagination';
/**
* The sorting configuration
*/
sortConfig: SortOptions;
/**
* A list of remote data objects of communities' collections
*/
subCommunitiesRDObs: BehaviorSubject<RemoteData<PaginatedList<Community>>> = new BehaviorSubject<RemoteData<PaginatedList<Community>>>({} as any);
constructor(private cds: CommunityDataService) {
}
ngOnInit(): void { ngOnInit(): void {
this.subCommunitiesRDObs = this.community.subcommunities; 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 sub-communities
*/
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.subCommunitiesRDObs.next(results);
});
} }
} }