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 { PaginationServiceStub } from '../../shared/testing/pagination-service.stub';
|
||||||
import { APP_CONFIG } from '../../../config/app-config.interface';
|
import { APP_CONFIG } from '../../../config/app-config.interface';
|
||||||
import { environment } from '../../../environments/environment';
|
import { environment } from '../../../environments/environment';
|
||||||
|
import { SortDirection } from '../../core/cache/models/sort-options.model';
|
||||||
|
|
||||||
describe('BrowseByDatePageComponent', () => {
|
describe('BrowseByDatePageComponent', () => {
|
||||||
let comp: BrowseByDatePageComponent;
|
let comp: BrowseByDatePageComponent;
|
||||||
@@ -49,12 +50,22 @@ describe('BrowseByDatePageComponent', () => {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const lastItem = Object.assign(new Item(), {
|
||||||
|
id: 'last-item-id',
|
||||||
|
metadata: {
|
||||||
|
'dc.date.issued': [
|
||||||
|
{
|
||||||
|
value: '1960-01-01'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const mockBrowseService = {
|
const mockBrowseService = {
|
||||||
getBrowseEntriesFor: (options: BrowseEntrySearchOptions) => toRemoteData([]),
|
getBrowseEntriesFor: (options: BrowseEntrySearchOptions) => toRemoteData([]),
|
||||||
getBrowseItemsFor: (value: string, options: BrowseEntrySearchOptions) => toRemoteData([firstItem]),
|
getBrowseItemsFor: (value: string, options: BrowseEntrySearchOptions) => toRemoteData([firstItem]),
|
||||||
getFirstItemFor: () => createSuccessfulRemoteDataObject$(firstItem)
|
getFirstItemFor: (definition: string, scope?: string, sortDirection?: SortDirection) => null
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockDsoService = {
|
const mockDsoService = {
|
||||||
findById: () => createSuccessfulRemoteDataObject$(mockCommunity)
|
findById: () => createSuccessfulRemoteDataObject$(mockCommunity)
|
||||||
@@ -91,9 +102,14 @@ describe('BrowseByDatePageComponent', () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(BrowseByDatePageComponent);
|
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;
|
comp = fixture.componentInstance;
|
||||||
fixture.detectChanges();
|
|
||||||
route = (comp as any).route;
|
route = (comp as any).route;
|
||||||
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should initialize the list of items', () => {
|
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', () => {
|
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 { ChangeDetectorRef, Component, Inject } from '@angular/core';
|
||||||
import {
|
import {
|
||||||
BrowseByMetadataPageComponent,
|
BrowseByMetadataPageComponent,
|
||||||
browseParamsToOptions, getBrowseSearchOptions
|
browseParamsToOptions,
|
||||||
|
getBrowseSearchOptions
|
||||||
} from '../browse-by-metadata-page/browse-by-metadata-page.component';
|
} from '../browse-by-metadata-page/browse-by-metadata-page.component';
|
||||||
import { combineLatest as observableCombineLatest } from 'rxjs';
|
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 { hasValue, isNotEmpty } from '../../shared/empty.util';
|
||||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||||
import { BrowseService } from '../../core/browse/browse.service';
|
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 { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
|
||||||
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
|
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
|
||||||
import { isValidDate } from '../../shared/date.util';
|
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({
|
@Component({
|
||||||
selector: 'ds-browse-by-date-page',
|
selector: 'ds-browse-by-date-page',
|
||||||
@@ -72,30 +73,24 @@ export class BrowseByDatePageComponent extends BrowseByMetadataPageComponent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the StartsWith options
|
* Update the StartsWith options
|
||||||
* In this implementation, it creates a list of years starting from now, going all the way back to the earliest
|
* In this implementation, it creates a list of years starting from the most recent item or the current year, going
|
||||||
* date found on an item within this scope. The further back in time, the bigger the change in years become to avoid
|
* all the way back to the earliest date found on an item within this scope. The further back in time, the bigger
|
||||||
* extremely long lists with a one-year difference.
|
* 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.
|
* 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 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 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
|
* @param scope The scope under which to fetch the earliest item for
|
||||||
*/
|
*/
|
||||||
updateStartsWithOptions(definition: string, metadataKeys: string[], scope?: string) {
|
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.subs.push(
|
||||||
this.browseService.getFirstItemFor(definition, scope).subscribe((firstItemRD: RemoteData<Item>) => {
|
observableCombineLatest([firstItemRD, lastItemRD]).subscribe(([firstItem, lastItem]) => {
|
||||||
let lowerLimit = this.appConfig.browseBy.defaultLowerLimit;
|
let lowerLimit = this.getLimit(firstItem, metadataKeys, this.appConfig.browseBy.defaultLowerLimit);
|
||||||
if (hasValue(firstItemRD.payload)) {
|
let upperLimit = this.getLimit(lastItem, metadataKeys, new Date().getUTCFullYear());
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const options = [];
|
const options = [];
|
||||||
const currentYear = new Date().getUTCFullYear();
|
const oneYearBreak = Math.floor((upperLimit - this.appConfig.browseBy.oneYearLimit) / 5) * 5;
|
||||||
const oneYearBreak = Math.floor((currentYear - this.appConfig.browseBy.oneYearLimit) / 5) * 5;
|
const fiveYearBreak = Math.floor((upperLimit - this.appConfig.browseBy.fiveYearLimit) / 10) * 10;
|
||||||
const fiveYearBreak = Math.floor((currentYear - this.appConfig.browseBy.fiveYearLimit) / 10) * 10;
|
|
||||||
if (lowerLimit <= fiveYearBreak) {
|
if (lowerLimit <= fiveYearBreak) {
|
||||||
lowerLimit -= 10;
|
lowerLimit -= 10;
|
||||||
} else if (lowerLimit <= oneYearBreak) {
|
} else if (lowerLimit <= oneYearBreak) {
|
||||||
@@ -103,7 +98,7 @@ export class BrowseByDatePageComponent extends BrowseByMetadataPageComponent {
|
|||||||
} else {
|
} else {
|
||||||
lowerLimit -= 1;
|
lowerLimit -= 1;
|
||||||
}
|
}
|
||||||
let i = currentYear;
|
let i = upperLimit;
|
||||||
while (i > lowerLimit) {
|
while (i > lowerLimit) {
|
||||||
options.push(i);
|
options.push(i);
|
||||||
if (i <= fiveYearBreak) {
|
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 { HrefOnlyDataService } from '../data/href-only-data.service';
|
||||||
import { followLink, FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
|
import { followLink, FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
|
||||||
import { BrowseDefinitionDataService } from './browse-definition-data.service';
|
import { BrowseDefinitionDataService } from './browse-definition-data.service';
|
||||||
|
import { SortDirection } from '../cache/models/sort-options.model';
|
||||||
|
|
||||||
|
|
||||||
export const BROWSE_LINKS_TO_FOLLOW: FollowLinkConfig<BrowseEntry | Item>[] = [
|
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
|
* Get the first item for a metadata definition in an optional scope
|
||||||
* @param definition
|
* @param definition
|
||||||
* @param scope
|
* @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(
|
const href$ = this.getBrowseDefinitions().pipe(
|
||||||
getBrowseDefinitionLinks(definition),
|
getBrowseDefinitionLinks(definition),
|
||||||
hasValueOperator(),
|
hasValueOperator(),
|
||||||
@@ -177,6 +179,9 @@ export class BrowseService {
|
|||||||
}
|
}
|
||||||
args.push('page=0');
|
args.push('page=0');
|
||||||
args.push('size=1');
|
args.push('size=1');
|
||||||
|
if (sortDirection) {
|
||||||
|
args.push('sort=default,' + sortDirection);
|
||||||
|
}
|
||||||
if (isNotEmpty(args)) {
|
if (isNotEmpty(args)) {
|
||||||
href = new URLCombiner(href, `?${args.join('&')}`).toString();
|
href = new URLCombiner(href, `?${args.join('&')}`).toString();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user