diff --git a/config/config.example.yml b/config/config.example.yml index 83161263eb..b0112ef13a 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -162,6 +162,9 @@ languages: - code: bn label: বাংলা active: true + - code: el + label: Ελληνικά + active: true # Browse-By Pages browseBy: @@ -171,6 +174,25 @@ browseBy: fiveYearLimit: 30 # The absolute lowest year to display in the dropdown (only used when no lowest date can be found for all items) defaultLowerLimit: 1900 + # The number of entries in a paginated browse results list. + # Rounded to the nearest size in the list of selectable sizes on the + # settings menu. + pageSize: 20 + +communityList: + # No. of communities to list per expansion (show more) + pageSize: 20 + +homePage: + recentSubmissions: + # The number of item showing in recent submission components + pageSize: 5 + # Sort record of recent submission + sortField: 'dc.date.accessioned' + topLevelCommunityList: + # No. of communities to list per page on the home page + # This will always round to the nearest number from the list of page sizes. e.g. if you set it to 7 it'll use 10 + pageSize: 5 # Item Config item: @@ -261,10 +283,3 @@ mediaViewer: info: enableEndUserAgreement: true enablePrivacyStatement: true -# Home Page -homePage: - recentSubmissions: - # The number of item showing in recent submission components - pageSize: 5 - # Sort record of recent submission - sortField: 'dc.date.accessioned' diff --git a/src/app/access-control/group-registry/group-form/members-list/members-list.component.ts b/src/app/access-control/group-registry/group-form/members-list/members-list.component.ts index eb6a38b5cf..5c02e02d78 100644 --- a/src/app/access-control/group-registry/group-form/members-list/members-list.component.ts +++ b/src/app/access-control/group-registry/group-form/members-list/members-list.component.ts @@ -10,7 +10,7 @@ import { combineLatest as observableCombineLatest, ObservedValueOf, } from 'rxjs'; -import { map, mergeMap, switchMap, take } from 'rxjs/operators'; +import { defaultIfEmpty, map, mergeMap, switchMap, take } from 'rxjs/operators'; import {buildPaginatedList, PaginatedList} from '../../../../core/data/paginated-list.model'; import { RemoteData } from '../../../../core/data/remote-data'; import { EPersonDataService } from '../../../../core/eperson/eperson-data.service'; @@ -144,7 +144,7 @@ export class MembersListComponent implements OnInit, OnDestroy { } }), switchMap((epersonListRD: RemoteData>) => { - const dtos$ = observableCombineLatest(...epersonListRD.payload.page.map((member: EPerson) => { + const dtos$ = observableCombineLatest([...epersonListRD.payload.page.map((member: EPerson) => { const dto$: Observable = observableCombineLatest( this.isMemberOfGroup(member), (isMember: ObservedValueOf>) => { const epersonDtoModel: EpersonDtoModel = new EpersonDtoModel(); @@ -153,8 +153,8 @@ export class MembersListComponent implements OnInit, OnDestroy { return epersonDtoModel; }); return dto$; - })); - return dtos$.pipe(map((dtos: EpersonDtoModel[]) => { + })]); + return dtos$.pipe(defaultIfEmpty([]), map((dtos: EpersonDtoModel[]) => { return buildPaginatedList(epersonListRD.payload.pageInfo, dtos); })); })) @@ -174,7 +174,7 @@ export class MembersListComponent implements OnInit, OnDestroy { return this.ePersonDataService.findListByHref(group._links.epersons.href, { currentPage: 1, elementsPerPage: 9999 - }, false) + }) .pipe( getFirstSucceededRemoteData(), getRemoteDataPayload(), @@ -274,7 +274,7 @@ export class MembersListComponent implements OnInit, OnDestroy { } }), switchMap((epersonListRD: RemoteData>) => { - const dtos$ = observableCombineLatest(...epersonListRD.payload.page.map((member: EPerson) => { + const dtos$ = observableCombineLatest([...epersonListRD.payload.page.map((member: EPerson) => { const dto$: Observable = observableCombineLatest( this.isMemberOfGroup(member), (isMember: ObservedValueOf>) => { const epersonDtoModel: EpersonDtoModel = new EpersonDtoModel(); @@ -283,8 +283,8 @@ export class MembersListComponent implements OnInit, OnDestroy { return epersonDtoModel; }); return dto$; - })); - return dtos$.pipe(map((dtos: EpersonDtoModel[]) => { + })]); + return dtos$.pipe(defaultIfEmpty([]), map((dtos: EpersonDtoModel[]) => { return buildPaginatedList(epersonListRD.payload.pageInfo, dtos); })); })) diff --git a/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.spec.ts b/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.spec.ts index 15ec9d78db..b6ff177d3d 100644 --- a/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.spec.ts +++ b/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.spec.ts @@ -23,6 +23,8 @@ import { SortDirection, SortOptions } from '../../core/cache/models/sort-options import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; import { FindListOptions } from '../../core/data/find-list-options.model'; +import { APP_CONFIG } from 'src/config/app-config.interface'; +import { environment } from 'src/environments/environment'; describe('BrowseByDatePageComponent', () => { let comp: BrowseByDatePageComponent; @@ -83,7 +85,8 @@ describe('BrowseByDatePageComponent', () => { { provide: DSpaceObjectDataService, useValue: mockDsoService }, { provide: Router, useValue: new RouterMock() }, { provide: PaginationService, useValue: paginationService }, - { provide: ChangeDetectorRef, useValue: mockCdRef } + { provide: ChangeDetectorRef, useValue: mockCdRef }, + { provide: APP_CONFIG, useValue: environment } ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); diff --git a/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.ts b/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.ts index 271828a38e..9b031260ce 100644 --- a/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.ts +++ b/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectorRef, Component } from '@angular/core'; +import { ChangeDetectorRef, Component, Inject } from '@angular/core'; import { BrowseByMetadataPageComponent, browseParamsToOptions @@ -19,6 +19,7 @@ import { map } from 'rxjs/operators'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; import { isValidDate } from '../../shared/date.util'; +import { AppConfig, APP_CONFIG } from '../../../config/app-config.interface'; @Component({ selector: 'ds-browse-by-date-page', @@ -43,8 +44,9 @@ export class BrowseByDatePageComponent extends BrowseByMetadataPageComponent { protected dsoService: DSpaceObjectDataService, protected router: Router, protected paginationService: PaginationService, - protected cdRef: ChangeDetectorRef) { - super(route, browseService, dsoService, paginationService, router); + protected cdRef: ChangeDetectorRef, + @Inject(APP_CONFIG) protected appConfig: AppConfig) { + super(route, browseService, dsoService, paginationService, router, appConfig); } ngOnInit(): void { diff --git a/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.spec.ts b/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.spec.ts index 60d2fa549b..03152d0d3e 100644 --- a/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.spec.ts +++ b/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.spec.ts @@ -25,6 +25,8 @@ import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.util import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; +import { APP_CONFIG } from '../../../config/app-config.interface'; +import { environment } from '../../../environments/environment'; describe('BrowseByMetadataPageComponent', () => { let comp: BrowseByMetadataPageComponent; @@ -97,7 +99,8 @@ describe('BrowseByMetadataPageComponent', () => { { provide: BrowseService, useValue: mockBrowseService }, { provide: DSpaceObjectDataService, useValue: mockDsoService }, { provide: PaginationService, useValue: paginationService }, - { provide: Router, useValue: new RouterMock() } + { provide: Router, useValue: new RouterMock() }, + { provide: APP_CONFIG, useValue: environment } ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); diff --git a/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.ts b/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.ts index c685fe31a7..20817d9675 100644 --- a/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.ts +++ b/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.ts @@ -1,5 +1,6 @@ import { combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs'; -import { Component, OnInit } from '@angular/core'; +import { Component, Inject, OnInit } from '@angular/core'; +import { AppConfig, APP_CONFIG } from '../../../config/app-config.interface'; import { RemoteData } from '../../core/data/remote-data'; import { PaginatedList } from '../../core/data/paginated-list.model'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; @@ -26,9 +27,10 @@ export const BBM_PAGINATION_ID = 'bbm'; templateUrl: './browse-by-metadata-page.component.html' }) /** - * Component for browsing (items) by metadata definition - * A metadata definition (a.k.a. browse id) is a short term used to describe one or multiple metadata fields. - * An example would be 'author' for 'dc.contributor.*' + * Component for browsing (items) by metadata definition. + * A metadata definition (a.k.a. browse id) is a short term used to describe one + * or multiple metadata fields. An example would be 'author' for + * 'dc.contributor.*' */ @rendersBrowseBy(BrowseByDataType.Metadata) export class BrowseByMetadataPageComponent implements OnInit { @@ -51,11 +53,7 @@ export class BrowseByMetadataPageComponent implements OnInit { /** * The pagination config used to display the values */ - paginationConfig: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), { - id: BBM_PAGINATION_ID, - currentPage: 1, - pageSize: 20 - }); + paginationConfig: PaginationComponentOptions; /** * The pagination observable @@ -115,8 +113,14 @@ export class BrowseByMetadataPageComponent implements OnInit { protected browseService: BrowseService, protected dsoService: DSpaceObjectDataService, protected paginationService: PaginationService, - protected router: Router) { - } + protected router: Router, + @Inject(APP_CONFIG) protected appConfig: AppConfig) { + this.paginationConfig = Object.assign(new PaginationComponentOptions(), { + id: BBM_PAGINATION_ID, + currentPage: 1, + pageSize: this.appConfig.browseBy.pageSize, + }); + } ngOnInit(): void { const sortConfig = new SortOptions('default', SortDirection.ASC); diff --git a/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.spec.ts b/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.spec.ts index 554b059ac5..600eab575b 100644 --- a/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.spec.ts +++ b/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.spec.ts @@ -23,6 +23,8 @@ import { SortDirection, SortOptions } from '../../core/cache/models/sort-options import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; import { FindListOptions } from '../../core/data/find-list-options.model'; +import { APP_CONFIG } from 'src/config/app-config.interface'; +import { environment } from 'src/environments/environment'; describe('BrowseByTitlePageComponent', () => { let comp: BrowseByTitlePageComponent; @@ -77,7 +79,8 @@ describe('BrowseByTitlePageComponent', () => { { provide: BrowseService, useValue: mockBrowseService }, { provide: DSpaceObjectDataService, useValue: mockDsoService }, { provide: PaginationService, useValue: paginationService }, - { provide: Router, useValue: new RouterMock() } + { provide: Router, useValue: new RouterMock() }, + { provide: APP_CONFIG, useValue: environment } ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); diff --git a/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.ts b/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.ts index 6504a8700a..a6528bed49 100644 --- a/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.ts +++ b/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.ts @@ -1,5 +1,5 @@ import { combineLatest as observableCombineLatest } from 'rxjs'; -import { Component } from '@angular/core'; +import { Component, Inject } from '@angular/core'; import { ActivatedRoute, Params, Router } from '@angular/router'; import { hasValue } from '../../shared/empty.util'; import { @@ -14,6 +14,7 @@ import { BrowseByDataType, rendersBrowseBy } from '../browse-by-switcher/browse- import { PaginationService } from '../../core/pagination/pagination.service'; import { map } from 'rxjs/operators'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; +import { AppConfig, APP_CONFIG } from '../../../config/app-config.interface'; @Component({ selector: 'ds-browse-by-title-page', @@ -30,8 +31,9 @@ export class BrowseByTitlePageComponent extends BrowseByMetadataPageComponent { protected browseService: BrowseService, protected dsoService: DSpaceObjectDataService, protected paginationService: PaginationService, - protected router: Router) { - super(route, browseService, dsoService, paginationService, router); + protected router: Router, + @Inject(APP_CONFIG) protected appConfig: AppConfig) { + super(route, browseService, dsoService, paginationService, router, appConfig); } ngOnInit(): void { diff --git a/src/app/community-list-page/community-list-service.spec.ts b/src/app/community-list-page/community-list-service.spec.ts index 401ffe0b11..410dd9f804 100644 --- a/src/app/community-list-page/community-list-service.spec.ts +++ b/src/app/community-list-page/community-list-service.spec.ts @@ -15,6 +15,8 @@ import { Collection } from '../core/shared/collection.model'; import { PageInfo } from '../core/shared/page-info.model'; import { FlatNode } from './flat-node.model'; import { FindListOptions } from '../core/data/find-list-options.model'; +import { APP_CONFIG } from 'src/config/app-config.interface'; +import { environment } from 'src/environments/environment.test'; describe('CommunityListService', () => { let store: StoreMock; @@ -191,13 +193,14 @@ describe('CommunityListService', () => { }; TestBed.configureTestingModule({ providers: [CommunityListService, + { provide: APP_CONFIG, useValue: environment }, { provide: CollectionDataService, useValue: collectionDataServiceStub }, { provide: CommunityDataService, useValue: communityDataServiceStub }, { provide: Store, useValue: StoreMock }, ], }); store = TestBed.inject(Store as any); - service = new CommunityListService(communityDataServiceStub, collectionDataServiceStub, store); + service = new CommunityListService(environment, communityDataServiceStub, collectionDataServiceStub, store); }); it('should create', inject([CommunityListService], (serviceIn: CommunityListService) => { diff --git a/src/app/community-list-page/community-list-service.ts b/src/app/community-list-page/community-list-service.ts index 89b68812ae..99e9dbeb0d 100644 --- a/src/app/community-list-page/community-list-service.ts +++ b/src/app/community-list-page/community-list-service.ts @@ -1,5 +1,5 @@ /* eslint-disable max-classes-per-file */ -import { Injectable } from '@angular/core'; +import { Inject, Injectable } from '@angular/core'; import { createSelector, Store } from '@ngrx/store'; import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs'; @@ -23,6 +23,7 @@ import { followLink } from '../shared/utils/follow-link-config.model'; import { FlatNode } from './flat-node.model'; import { ShowMoreFlatNode } from './show-more-flat-node.model'; import { FindListOptions } from '../core/data/find-list-options.model'; +import { AppConfig, APP_CONFIG } from 'src/config/app-config.interface'; // Helper method to combine an flatten an array of observables of flatNode arrays export const combineAndFlatten = (obsList: Observable[]): Observable => @@ -80,8 +81,6 @@ const communityListStateSelector = (state: AppState) => state.communityList; const expandedNodesSelector = createSelector(communityListStateSelector, (communityList: CommunityListState) => communityList.expandedNodes); const loadingNodeSelector = createSelector(communityListStateSelector, (communityList: CommunityListState) => communityList.loadingNode); -export const MAX_COMCOLS_PER_PAGE = 20; - /** * Service class for the community list, responsible for the creating of the flat list used by communityList dataSource * and connection to the store to retrieve and save the state of the community list @@ -89,8 +88,15 @@ export const MAX_COMCOLS_PER_PAGE = 20; @Injectable() export class CommunityListService { - constructor(private communityDataService: CommunityDataService, private collectionDataService: CollectionDataService, - private store: Store) { + private pageSize: number; + + constructor( + @Inject(APP_CONFIG) protected appConfig: AppConfig, + private communityDataService: CommunityDataService, + private collectionDataService: CollectionDataService, + private store: Store + ) { + this.pageSize = appConfig.communityList.pageSize; } private configOnePage: FindListOptions = Object.assign(new FindListOptions(), { @@ -145,7 +151,7 @@ export class CommunityListService { private getTopCommunities(options: FindListOptions): Observable> { return this.communityDataService.findTop({ currentPage: options.currentPage, - elementsPerPage: MAX_COMCOLS_PER_PAGE, + elementsPerPage: this.pageSize, sort: { field: options.sort.field, direction: options.sort.direction @@ -216,7 +222,7 @@ export class CommunityListService { let subcoms = []; for (let i = 1; i <= currentCommunityPage; i++) { const nextSetOfSubcommunitiesPage = this.communityDataService.findByParent(community.uuid, { - elementsPerPage: MAX_COMCOLS_PER_PAGE, + elementsPerPage: this.pageSize, currentPage: i }, followLink('subcommunities', { findListOptions: this.configOnePage }), @@ -241,7 +247,7 @@ export class CommunityListService { let collections = []; for (let i = 1; i <= currentCollectionPage; i++) { const nextSetOfCollectionsPage = this.collectionDataService.findByParent(community.uuid, { - elementsPerPage: MAX_COMCOLS_PER_PAGE, + elementsPerPage: this.pageSize, currentPage: i }) .pipe( diff --git a/src/app/community-page/community-page.component.html b/src/app/community-page/community-page.component.html index 6b277bd07f..17512f10a9 100644 --- a/src/app/community-page/community-page.component.html +++ b/src/app/community-page/community-page.component.html @@ -25,12 +25,13 @@
+ - - + +