mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
Added upper limit to browse by date
This commit is contained in:
@@ -22,6 +22,7 @@ import { PaginationService } from '../../core/pagination/pagination.service';
|
||||
import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub';
|
||||
import { APP_CONFIG } from '../../../config/app-config.interface';
|
||||
import { environment } from '../../../environments/environment';
|
||||
import { SortDirection } from '../../core/cache/models/sort-options.model';
|
||||
|
||||
describe('BrowseByDatePageComponent', () => {
|
||||
let comp: BrowseByDatePageComponent;
|
||||
@@ -49,11 +50,21 @@ describe('BrowseByDatePageComponent', () => {
|
||||
]
|
||||
}
|
||||
});
|
||||
const lastItem = Object.assign(new Item(), {
|
||||
id: 'last-item-id',
|
||||
metadata: {
|
||||
'dc.date.issued': [
|
||||
{
|
||||
value: '1960-01-01'
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
const mockBrowseService = {
|
||||
getBrowseEntriesFor: (options: BrowseEntrySearchOptions) => toRemoteData([]),
|
||||
getBrowseItemsFor: (value: string, options: BrowseEntrySearchOptions) => toRemoteData([firstItem]),
|
||||
getFirstItemFor: () => createSuccessfulRemoteDataObject$(firstItem)
|
||||
getFirstItemFor: (definition: string, scope?: string, sortDirection?: SortDirection) => null
|
||||
};
|
||||
|
||||
const mockDsoService = {
|
||||
@@ -91,9 +102,14 @@ describe('BrowseByDatePageComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(BrowseByDatePageComponent);
|
||||
const browseService = fixture.debugElement.injector.get(BrowseService);
|
||||
spyOn(browseService, 'getFirstItemFor')
|
||||
// ok to expect the default browse as first param since we just need the mock items obtained via sort direction.
|
||||
.withArgs('author', undefined, SortDirection.ASC).and.returnValue(createSuccessfulRemoteDataObject$(firstItem))
|
||||
.withArgs('author', undefined, SortDirection.DESC).and.returnValue(createSuccessfulRemoteDataObject$(lastItem));
|
||||
comp = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
route = (comp as any).route;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should initialize the list of items', () => {
|
||||
@@ -107,6 +123,7 @@ describe('BrowseByDatePageComponent', () => {
|
||||
});
|
||||
|
||||
it('should create a list of startsWith options with the current year first', () => {
|
||||
expect(comp.startsWithOptions[0]).toEqual(new Date().getUTCFullYear());
|
||||
//expect(comp.startsWithOptions[0]).toEqual(new Date().getUTCFullYear());
|
||||
expect(comp.startsWithOptions[0]).toEqual(1960);
|
||||
});
|
||||
});
|
||||
|
@@ -1,11 +1,10 @@
|
||||
import { ChangeDetectorRef, Component, Inject } from '@angular/core';
|
||||
import {
|
||||
BrowseByMetadataPageComponent,
|
||||
browseParamsToOptions, getBrowseSearchOptions
|
||||
browseParamsToOptions,
|
||||
getBrowseSearchOptions
|
||||
} from '../browse-by-metadata-page/browse-by-metadata-page.component';
|
||||
import { combineLatest as observableCombineLatest } from 'rxjs';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Item } from '../../core/shared/item.model';
|
||||
import { hasValue, isNotEmpty } from '../../shared/empty.util';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
import { BrowseService } from '../../core/browse/browse.service';
|
||||
@@ -16,7 +15,9 @@ 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';
|
||||
import { APP_CONFIG, AppConfig } from '../../../config/app-config.interface';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Item } from '../../core/shared/item.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-browse-by-date-page',
|
||||
@@ -72,30 +73,24 @@ export class BrowseByDatePageComponent extends BrowseByMetadataPageComponent {
|
||||
|
||||
/**
|
||||
* Update the StartsWith options
|
||||
* In this implementation, it creates a list of years starting from now, going all the way back to the earliest
|
||||
* date found on an item within this scope. The further back in time, the bigger the change in years become to avoid
|
||||
* extremely long lists with a one-year difference.
|
||||
* In this implementation, it creates a list of years starting from the most recent item or the current year, going
|
||||
* all the way back to the earliest date found on an item within this scope. The further back in time, the bigger
|
||||
* the change in years become to avoid extremely long lists with a one-year difference.
|
||||
* To determine the change in years, the config found under GlobalConfig.BrowseBy is used for this.
|
||||
* @param definition The metadata definition to fetch the first item for
|
||||
* @param metadataKeys The metadata fields to fetch the earliest date from (expects a date field)
|
||||
* @param scope The scope under which to fetch the earliest item for
|
||||
*/
|
||||
updateStartsWithOptions(definition: string, metadataKeys: string[], scope?: string) {
|
||||
const firstItemRD = this.browseService.getFirstItemFor(definition, scope, SortDirection.ASC);
|
||||
const lastItemRD = this.browseService.getFirstItemFor(definition, scope, SortDirection.DESC);
|
||||
this.subs.push(
|
||||
this.browseService.getFirstItemFor(definition, scope).subscribe((firstItemRD: RemoteData<Item>) => {
|
||||
let lowerLimit = this.appConfig.browseBy.defaultLowerLimit;
|
||||
if (hasValue(firstItemRD.payload)) {
|
||||
const date = firstItemRD.payload.firstMetadataValue(metadataKeys);
|
||||
if (isNotEmpty(date) && isValidDate(date)) {
|
||||
const dateObj = new Date(date);
|
||||
// TODO: it appears that getFullYear (based on local time) is sometimes unreliable. Switching to UTC.
|
||||
lowerLimit = isNaN(dateObj.getUTCFullYear()) ? lowerLimit : dateObj.getUTCFullYear();
|
||||
}
|
||||
}
|
||||
observableCombineLatest([firstItemRD, lastItemRD]).subscribe(([firstItem, lastItem]) => {
|
||||
let lowerLimit = this.getLimit(firstItem, metadataKeys, this.appConfig.browseBy.defaultLowerLimit);
|
||||
let upperLimit = this.getLimit(lastItem, metadataKeys, new Date().getUTCFullYear());
|
||||
const options = [];
|
||||
const currentYear = new Date().getUTCFullYear();
|
||||
const oneYearBreak = Math.floor((currentYear - this.appConfig.browseBy.oneYearLimit) / 5) * 5;
|
||||
const fiveYearBreak = Math.floor((currentYear - this.appConfig.browseBy.fiveYearLimit) / 10) * 10;
|
||||
const oneYearBreak = Math.floor((upperLimit - this.appConfig.browseBy.oneYearLimit) / 5) * 5;
|
||||
const fiveYearBreak = Math.floor((upperLimit - this.appConfig.browseBy.fiveYearLimit) / 10) * 10;
|
||||
if (lowerLimit <= fiveYearBreak) {
|
||||
lowerLimit -= 10;
|
||||
} else if (lowerLimit <= oneYearBreak) {
|
||||
@@ -103,7 +98,7 @@ export class BrowseByDatePageComponent extends BrowseByMetadataPageComponent {
|
||||
} else {
|
||||
lowerLimit -= 1;
|
||||
}
|
||||
let i = currentYear;
|
||||
let i = upperLimit;
|
||||
while (i > lowerLimit) {
|
||||
options.push(i);
|
||||
if (i <= fiveYearBreak) {
|
||||
@@ -121,4 +116,24 @@ export class BrowseByDatePageComponent extends BrowseByMetadataPageComponent {
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the year from the item metadata field or the limit.
|
||||
* @param itemRD the item remote data
|
||||
* @param metadataKeys The metadata fields to fetch the earliest date from (expects a date field)
|
||||
* @param limit the limit to use if the year can't be found in metadata
|
||||
* @private
|
||||
*/
|
||||
private getLimit(itemRD: RemoteData<Item>, metadataKeys: string[], limit: number): number {
|
||||
if (hasValue(itemRD.payload)) {
|
||||
const date = itemRD.payload.firstMetadataValue(metadataKeys);
|
||||
if (isNotEmpty(date) && isValidDate(date)) {
|
||||
const dateObj = new Date(date);
|
||||
// TODO: it appears that getFullYear (based on local time) is sometimes unreliable. Switching to UTC.
|
||||
return isNaN(dateObj.getUTCFullYear()) ? limit : dateObj.getUTCFullYear();
|
||||
} else {
|
||||
return new Date().getUTCFullYear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -22,6 +22,7 @@ import { BrowseEntrySearchOptions } from './browse-entry-search-options.model';
|
||||
import { HrefOnlyDataService } from '../data/href-only-data.service';
|
||||
import { followLink, FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
|
||||
import { BrowseDefinitionDataService } from './browse-definition-data.service';
|
||||
import { SortDirection } from '../cache/models/sort-options.model';
|
||||
|
||||
|
||||
export const BROWSE_LINKS_TO_FOLLOW: FollowLinkConfig<BrowseEntry | Item>[] = [
|
||||
@@ -160,8 +161,9 @@ export class BrowseService {
|
||||
* Get the first item for a metadata definition in an optional scope
|
||||
* @param definition
|
||||
* @param scope
|
||||
* @param sortDirection optional sort parameter
|
||||
*/
|
||||
getFirstItemFor(definition: string, scope?: string): Observable<RemoteData<Item>> {
|
||||
getFirstItemFor(definition: string, scope?: string, sortDirection?: SortDirection): Observable<RemoteData<Item>> {
|
||||
const href$ = this.getBrowseDefinitions().pipe(
|
||||
getBrowseDefinitionLinks(definition),
|
||||
hasValueOperator(),
|
||||
@@ -177,6 +179,9 @@ export class BrowseService {
|
||||
}
|
||||
args.push('page=0');
|
||||
args.push('size=1');
|
||||
if (sortDirection) {
|
||||
args.push('sort=default,' + sortDirection);
|
||||
}
|
||||
if (isNotEmpty(args)) {
|
||||
href = new URLCombiner(href, `?${args.join('&')}`).toString();
|
||||
}
|
||||
|
Reference in New Issue
Block a user