mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 18:14:17 +00:00
85993: comcol/switcher/guard browse by changes + test updates
This commit is contained in:
@@ -12,12 +12,13 @@ import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
import { BrowseService } from '../../core/browse/browse.service';
|
||||
import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service';
|
||||
import { StartsWithType } from '../../shared/starts-with/starts-with-decorator';
|
||||
import { BrowseByType, rendersBrowseBy } from '../browse-by-switcher/browse-by-decorator';
|
||||
import { BrowseByDataType, rendersBrowseBy } from '../browse-by-switcher/browse-by-decorator';
|
||||
import { environment } from '../../../environments/environment';
|
||||
import { PaginationService } from '../../core/pagination/pagination.service';
|
||||
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 { BrowseDefinition } from '../../core/shared/browse-definition.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-browse-by-date-page',
|
||||
@@ -29,13 +30,13 @@ import { SortDirection, SortOptions } from '../../core/cache/models/sort-options
|
||||
* A metadata definition (a.k.a. browse id) is a short term used to describe one or multiple metadata fields.
|
||||
* An example would be 'dateissued' for 'dc.date.issued'
|
||||
*/
|
||||
@rendersBrowseBy(BrowseByType.Date)
|
||||
@rendersBrowseBy(BrowseByDataType.Date)
|
||||
export class BrowseByDatePageComponent extends BrowseByMetadataPageComponent {
|
||||
|
||||
/**
|
||||
* The default metadata-field to use for determining the lower limit of the StartsWith dropdown options
|
||||
*/
|
||||
defaultMetadataField = 'dc.date.issued';
|
||||
defaultBrowseDefinition = Object.assign(new BrowseDefinition(), {metadataKeys: ['dc.date.issued']});
|
||||
|
||||
public constructor(protected route: ActivatedRoute,
|
||||
protected browseService: BrowseService,
|
||||
@@ -59,13 +60,13 @@ export class BrowseByDatePageComponent extends BrowseByMetadataPageComponent {
|
||||
return [Object.assign({}, routeParams, queryParams, data), currentPage, currentSort];
|
||||
})
|
||||
).subscribe(([params, currentPage, currentSort]: [Params, PaginationComponentOptions, SortOptions]) => {
|
||||
const metadataField = params.metadataField || this.defaultMetadataField;
|
||||
const browseDefinition = params.browseDefinition || this.defaultBrowseDefinition;
|
||||
this.browseId = params.id || this.defaultBrowseId;
|
||||
this.startsWith = +params.startsWith || params.startsWith;
|
||||
const searchOptions = browseParamsToOptions(params, currentPage, currentSort, this.browseId);
|
||||
this.updatePageWithItems(searchOptions, this.value);
|
||||
this.updateParent(params.scope);
|
||||
this.updateStartsWithOptions(this.browseId, metadataField, params.scope);
|
||||
this.updateStartsWithOptions(this.browseId, browseDefinition, params.scope);
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -79,12 +80,12 @@ export class BrowseByDatePageComponent extends BrowseByMetadataPageComponent {
|
||||
* @param metadataField The metadata field 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, metadataField: string, scope?: string) {
|
||||
updateStartsWithOptions(definition: string, browseDefinition: BrowseDefinition, scope?: string) {
|
||||
this.subs.push(
|
||||
this.browseService.getFirstItemFor(definition, scope).subscribe((firstItemRD: RemoteData<Item>) => {
|
||||
let lowerLimit = environment.browseBy.defaultLowerLimit;
|
||||
if (hasValue(firstItemRD.payload)) {
|
||||
const date = firstItemRD.payload.firstMetadataValue(metadataField);
|
||||
const date = firstItemRD.payload.firstMetadataValue(browseDefinition.metadataKeys);
|
||||
if (hasValue(date)) {
|
||||
const dateObj = new Date(date);
|
||||
// TODO: it appears that getFullYear (based on local time) is sometimes unreliable. Switching to UTC.
|
||||
|
@@ -1,20 +1,25 @@
|
||||
import { first } from 'rxjs/operators';
|
||||
import { BrowseByGuard } from './browse-by-guard';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { BrowseDefinitionDataService } from '../core/browse/browse-definition-data.service';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../shared/remote-data.utils';
|
||||
import { BrowseDefinition } from '../core/shared/browse-definition.model';
|
||||
import { BrowseByDataType } from './browse-by-switcher/browse-by-decorator';
|
||||
|
||||
describe('BrowseByGuard', () => {
|
||||
describe('canActivate', () => {
|
||||
let guard: BrowseByGuard;
|
||||
let dsoService: any;
|
||||
let translateService: any;
|
||||
let browseDefinitionService: any;
|
||||
|
||||
const name = 'An interesting DSO';
|
||||
const title = 'Author';
|
||||
const field = 'Author';
|
||||
const id = 'author';
|
||||
const metadataField = 'dc.contributor';
|
||||
const scope = '1234-65487-12354-1235';
|
||||
const value = 'Filter';
|
||||
const browseDefinition = Object.assign(new BrowseDefinition(), { type: BrowseByDataType.Metadata, metadataKeys: ['dc.contributor'] });
|
||||
|
||||
beforeEach(() => {
|
||||
dsoService = {
|
||||
@@ -24,14 +29,19 @@ describe('BrowseByGuard', () => {
|
||||
translateService = {
|
||||
instant: () => field
|
||||
};
|
||||
guard = new BrowseByGuard(dsoService, translateService);
|
||||
|
||||
browseDefinitionService = {
|
||||
findById: () => createSuccessfulRemoteDataObject$(browseDefinition)
|
||||
};
|
||||
|
||||
guard = new BrowseByGuard(dsoService, translateService, browseDefinitionService);
|
||||
});
|
||||
|
||||
it('should return true, and sets up the data correctly, with a scope and value', () => {
|
||||
const scopedRoute = {
|
||||
data: {
|
||||
title: field,
|
||||
metadataField,
|
||||
browseDefinition,
|
||||
},
|
||||
params: {
|
||||
id,
|
||||
@@ -48,7 +58,7 @@ describe('BrowseByGuard', () => {
|
||||
const result = {
|
||||
title,
|
||||
id,
|
||||
metadataField,
|
||||
browseDefinition,
|
||||
collection: name,
|
||||
field,
|
||||
value: '"' + value + '"'
|
||||
@@ -63,7 +73,7 @@ describe('BrowseByGuard', () => {
|
||||
const scopedNoValueRoute = {
|
||||
data: {
|
||||
title: field,
|
||||
metadataField,
|
||||
browseDefinition,
|
||||
},
|
||||
params: {
|
||||
id,
|
||||
@@ -80,7 +90,7 @@ describe('BrowseByGuard', () => {
|
||||
const result = {
|
||||
title,
|
||||
id,
|
||||
metadataField,
|
||||
browseDefinition,
|
||||
collection: name,
|
||||
field,
|
||||
value: ''
|
||||
@@ -95,7 +105,7 @@ describe('BrowseByGuard', () => {
|
||||
const route = {
|
||||
data: {
|
||||
title: field,
|
||||
metadataField,
|
||||
browseDefinition,
|
||||
},
|
||||
params: {
|
||||
id,
|
||||
@@ -111,7 +121,7 @@ describe('BrowseByGuard', () => {
|
||||
const result = {
|
||||
title,
|
||||
id,
|
||||
metadataField,
|
||||
browseDefinition,
|
||||
collection: '',
|
||||
field,
|
||||
value: '"' + value + '"'
|
||||
|
@@ -2,11 +2,14 @@ import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot } from '@angul
|
||||
import { Injectable } from '@angular/core';
|
||||
import { DSpaceObjectDataService } from '../core/data/dspace-object-data.service';
|
||||
import { hasNoValue, hasValue } from '../shared/empty.util';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { getFirstSucceededRemoteData } from '../core/shared/operators';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { getFirstSucceededRemoteData, getFirstSucceededRemoteDataPayload } from '../core/shared/operators';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
import { environment } from '../../environments/environment';
|
||||
import { BrowseDefinitionDataService } from '../core/browse/browse-definition-data.service';
|
||||
import { RemoteData } from '../core/data/remote-data';
|
||||
import { BrowseDefinition } from '../core/shared/browse-definition.model';
|
||||
|
||||
@Injectable()
|
||||
/**
|
||||
@@ -15,42 +18,46 @@ import { environment } from '../../environments/environment';
|
||||
export class BrowseByGuard implements CanActivate {
|
||||
|
||||
constructor(protected dsoService: DSpaceObjectDataService,
|
||||
protected translate: TranslateService) {
|
||||
protected translate: TranslateService,
|
||||
protected browseDefinitionService: BrowseDefinitionDataService) {
|
||||
}
|
||||
|
||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
||||
const title = route.data.title;
|
||||
const id = route.params.id || route.queryParams.id || route.data.id;
|
||||
let metadataField = route.data.metadataField;
|
||||
if (hasNoValue(metadataField) && hasValue(id)) {
|
||||
const config = environment.browseBy.types.find((conf) => conf.id === id);
|
||||
if (hasValue(config) && hasValue(config.metadataField)) {
|
||||
metadataField = config.metadataField;
|
||||
}
|
||||
let browseDefinition$: Observable<BrowseDefinition>;
|
||||
if (hasNoValue(route.data.browseDefinition) && hasValue(id)) {
|
||||
browseDefinition$ = this.browseDefinitionService.findById(id).pipe(getFirstSucceededRemoteDataPayload());
|
||||
} else {
|
||||
browseDefinition$ = observableOf(route.data.browseDefinition);
|
||||
}
|
||||
const scope = route.queryParams.scope;
|
||||
const value = route.queryParams.value;
|
||||
const metadataTranslated = this.translate.instant('browse.metadata.' + id);
|
||||
if (hasValue(scope)) {
|
||||
const dsoAndMetadata$ = this.dsoService.findById(scope).pipe(getFirstSucceededRemoteData());
|
||||
return dsoAndMetadata$.pipe(
|
||||
map((dsoRD) => {
|
||||
const name = dsoRD.payload.name;
|
||||
route.data = this.createData(title, id, metadataField, name, metadataTranslated, value, route);
|
||||
return true;
|
||||
})
|
||||
);
|
||||
} else {
|
||||
route.data = this.createData(title, id, metadataField, '', metadataTranslated, value, route);
|
||||
return observableOf(true);
|
||||
}
|
||||
return browseDefinition$.pipe(
|
||||
switchMap((browseDefinition) => {
|
||||
if (hasValue(scope)) {
|
||||
const dsoAndMetadata$ = this.dsoService.findById(scope).pipe(getFirstSucceededRemoteData());
|
||||
return dsoAndMetadata$.pipe(
|
||||
map((dsoRD) => {
|
||||
const name = dsoRD.payload.name;
|
||||
route.data = this.createData(title, id, browseDefinition, name, metadataTranslated, value, route);
|
||||
return true;
|
||||
})
|
||||
);
|
||||
} else {
|
||||
route.data = this.createData(title, id, browseDefinition, '', metadataTranslated, value, route);
|
||||
return observableOf(true);
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
private createData(title, id, metadataField, collection, field, value, route) {
|
||||
private createData(title, id, browseDefinition, collection, field, value, route) {
|
||||
return Object.assign({}, route.data, {
|
||||
title: title,
|
||||
id: id,
|
||||
metadataField: metadataField,
|
||||
browseDefinition: browseDefinition,
|
||||
collection: collection,
|
||||
field: field,
|
||||
value: hasValue(value) ? `"${value}"` : ''
|
||||
|
@@ -14,7 +14,7 @@ import { getFirstSucceededRemoteData } from '../../core/shared/operators';
|
||||
import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service';
|
||||
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
||||
import { StartsWithType } from '../../shared/starts-with/starts-with-decorator';
|
||||
import { BrowseByType, rendersBrowseBy } from '../browse-by-switcher/browse-by-decorator';
|
||||
import { BrowseByDataType, rendersBrowseBy } from '../browse-by-switcher/browse-by-decorator';
|
||||
import { PaginationService } from '../../core/pagination/pagination.service';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@@ -28,7 +28,7 @@ import { map } from 'rxjs/operators';
|
||||
* 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(BrowseByType.Metadata)
|
||||
@rendersBrowseBy(BrowseByDataType.Metadata)
|
||||
export class BrowseByMetadataPageComponent implements OnInit {
|
||||
|
||||
/**
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import { BrowseByType, rendersBrowseBy } from './browse-by-decorator';
|
||||
import { BrowseByDataType, rendersBrowseBy } from './browse-by-decorator';
|
||||
|
||||
describe('BrowseByDecorator', () => {
|
||||
const titleDecorator = rendersBrowseBy(BrowseByType.Title);
|
||||
const dateDecorator = rendersBrowseBy(BrowseByType.Date);
|
||||
const metadataDecorator = rendersBrowseBy(BrowseByType.Metadata);
|
||||
const titleDecorator = rendersBrowseBy(BrowseByDataType.Title);
|
||||
const dateDecorator = rendersBrowseBy(BrowseByDataType.Date);
|
||||
const metadataDecorator = rendersBrowseBy(BrowseByDataType.Metadata);
|
||||
it('should have a decorator for all types', () => {
|
||||
expect(titleDecorator.length).not.toEqual(0);
|
||||
expect(dateDecorator.length).not.toEqual(0);
|
||||
|
@@ -2,13 +2,13 @@ import { hasNoValue } from '../../shared/empty.util';
|
||||
import { InjectionToken } from '@angular/core';
|
||||
import { GenericConstructor } from '../../core/shared/generic-constructor';
|
||||
|
||||
export enum BrowseByType {
|
||||
export enum BrowseByDataType {
|
||||
Title = 'title',
|
||||
Metadata = 'metadata',
|
||||
Metadata = 'text',
|
||||
Date = 'date'
|
||||
}
|
||||
|
||||
export const DEFAULT_BROWSE_BY_TYPE = BrowseByType.Metadata;
|
||||
export const DEFAULT_BROWSE_BY_TYPE = BrowseByDataType.Metadata;
|
||||
|
||||
export const BROWSE_BY_COMPONENT_FACTORY = new InjectionToken<(browseByType) => GenericConstructor<any>>('getComponentByBrowseByType', {
|
||||
providedIn: 'root',
|
||||
@@ -21,7 +21,7 @@ const map = new Map();
|
||||
* Decorator used for rendering Browse-By pages by type
|
||||
* @param browseByType The type of page
|
||||
*/
|
||||
export function rendersBrowseBy(browseByType: BrowseByType) {
|
||||
export function rendersBrowseBy(browseByType: BrowseByDataType) {
|
||||
return function decorator(component: any) {
|
||||
if (hasNoValue(map.get(browseByType))) {
|
||||
map.set(browseByType, component);
|
||||
|
@@ -2,20 +2,46 @@ import { BrowseBySwitcherComponent } from './browse-by-switcher.component';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { environment } from '../../../environments/environment';
|
||||
import { BROWSE_BY_COMPONENT_FACTORY } from './browse-by-decorator';
|
||||
import { BROWSE_BY_COMPONENT_FACTORY, BrowseByDataType } from './browse-by-decorator';
|
||||
import { BrowseDefinition } from '../../core/shared/browse-definition.model';
|
||||
import { BehaviorSubject, of as observableOf } from 'rxjs';
|
||||
|
||||
describe('BrowseBySwitcherComponent', () => {
|
||||
let comp: BrowseBySwitcherComponent;
|
||||
let fixture: ComponentFixture<BrowseBySwitcherComponent>;
|
||||
|
||||
const types = environment.browseBy.types;
|
||||
const types = [
|
||||
Object.assign(
|
||||
new BrowseDefinition(), {
|
||||
id: 'title',
|
||||
dataType: BrowseByDataType.Title,
|
||||
}
|
||||
),
|
||||
Object.assign(
|
||||
new BrowseDefinition(), {
|
||||
id: 'dateissued',
|
||||
dataType: BrowseByDataType.Date,
|
||||
metadataKeys: ['dc.date.issued']
|
||||
}
|
||||
),
|
||||
Object.assign(
|
||||
new BrowseDefinition(), {
|
||||
id: 'author',
|
||||
dataType: BrowseByDataType.Metadata,
|
||||
}
|
||||
),
|
||||
Object.assign(
|
||||
new BrowseDefinition(), {
|
||||
id: 'subject',
|
||||
dataType: BrowseByDataType.Metadata,
|
||||
}
|
||||
),
|
||||
];
|
||||
|
||||
const params = new BehaviorSubject(createParamsWithId('initialValue'));
|
||||
const data = new BehaviorSubject(createDataWithBrowseDefinition(new BrowseDefinition()));
|
||||
|
||||
const activatedRouteStub = {
|
||||
params: params
|
||||
data
|
||||
};
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
@@ -34,20 +60,20 @@ describe('BrowseBySwitcherComponent', () => {
|
||||
comp = fixture.componentInstance;
|
||||
}));
|
||||
|
||||
types.forEach((type) => {
|
||||
types.forEach((type: BrowseDefinition) => {
|
||||
describe(`when switching to a browse-by page for "${type.id}"`, () => {
|
||||
beforeEach(() => {
|
||||
params.next(createParamsWithId(type.id));
|
||||
data.next(createDataWithBrowseDefinition(type));
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it(`should call getComponentByBrowseByType with type "${type.type}"`, () => {
|
||||
expect((comp as any).getComponentByBrowseByType).toHaveBeenCalledWith(type.type);
|
||||
it(`should call getComponentByBrowseByType with type "${type.dataType}"`, () => {
|
||||
expect((comp as any).getComponentByBrowseByType).toHaveBeenCalledWith(type.dataType);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
export function createParamsWithId(id) {
|
||||
return { id: id };
|
||||
export function createDataWithBrowseDefinition(browseDefinition) {
|
||||
return { browseDefinition: browseDefinition };
|
||||
}
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
import { BrowseByTypeConfig } from '../../../config/browse-by-type-config.interface';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { BROWSE_BY_COMPONENT_FACTORY } from './browse-by-decorator';
|
||||
import { environment } from '../../../environments/environment';
|
||||
import { GenericConstructor } from '../../core/shared/generic-constructor';
|
||||
import { BrowseDefinition } from '../../core/shared/browse-definition.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-browse-by-switcher',
|
||||
@@ -26,15 +26,11 @@ export class BrowseBySwitcherComponent implements OnInit {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the correct browse-by component by using the relevant config from environment.js
|
||||
* Fetch the correct browse-by component by using the relevant config from the route data
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.browseByComponent = this.route.params.pipe(
|
||||
map((params) => {
|
||||
const id = params.id;
|
||||
return environment.browseBy.types.find((config: BrowseByTypeConfig) => config.id === id);
|
||||
}),
|
||||
map((config: BrowseByTypeConfig) => this.getComponentByBrowseByType(config.type))
|
||||
this.browseByComponent = this.route.data.pipe(
|
||||
map((data: { browseDefinition: BrowseDefinition }) => this.getComponentByBrowseByType(data.browseDefinition.dataType))
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -10,7 +10,7 @@ import { BrowseEntrySearchOptions } from '../../core/browse/browse-entry-search-
|
||||
import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service';
|
||||
import { BrowseService } from '../../core/browse/browse.service';
|
||||
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
|
||||
import { BrowseByType, rendersBrowseBy } from '../browse-by-switcher/browse-by-decorator';
|
||||
import { BrowseByDataType, rendersBrowseBy } from '../browse-by-switcher/browse-by-decorator';
|
||||
import { PaginationService } from '../../core/pagination/pagination.service';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
|
||||
@@ -23,7 +23,7 @@ import { PaginationComponentOptions } from '../../shared/pagination/pagination-c
|
||||
/**
|
||||
* Component for browsing items by title (dc.title)
|
||||
*/
|
||||
@rendersBrowseBy(BrowseByType.Title)
|
||||
@rendersBrowseBy(BrowseByDataType.Title)
|
||||
export class BrowseByTitlePageComponent extends BrowseByMetadataPageComponent {
|
||||
|
||||
public constructor(protected route: ActivatedRoute,
|
||||
|
@@ -106,6 +106,21 @@ export class BrowseDefinitionDataService {
|
||||
findAllByHref(href: string, findListOptions: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig<BrowseDefinition>[]): Observable<RemoteData<PaginatedList<BrowseDefinition>>> {
|
||||
return this.dataService.findAllByHref(href, findListOptions, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an observable of {@link RemoteData} of an object, based on its ID, with a list of
|
||||
* {@link FollowLinkConfig}, to automatically resolve {@link HALLink}s of the object
|
||||
* @param id ID of object we want to retrieve
|
||||
* @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's
|
||||
* no valid cached version. Defaults to true
|
||||
* @param reRequestOnStale Whether or not the request should automatically be re-
|
||||
* requested after the response becomes stale
|
||||
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which
|
||||
* {@link HALLink}s should be automatically resolved
|
||||
*/
|
||||
findById(id: string, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig<BrowseDefinition>[]): Observable<RemoteData<BrowseDefinition>> {
|
||||
return this.dataService.findById(id, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
|
||||
}
|
||||
}
|
||||
|
||||
/* tslint:enable:max-classes-per-file */
|
||||
|
@@ -6,6 +6,7 @@ import { BROWSE_DEFINITION } from './browse-definition.resource-type';
|
||||
import { HALLink } from './hal-link.model';
|
||||
import { ResourceType } from './resource-type';
|
||||
import { SortOption } from './sort-option.model';
|
||||
import { BrowseByDataType } from '../../browse-by/browse-by-switcher/browse-by-decorator';
|
||||
|
||||
@typedObject
|
||||
export class BrowseDefinition extends CacheableObject {
|
||||
@@ -33,6 +34,9 @@ export class BrowseDefinition extends CacheableObject {
|
||||
@autoserializeAs('metadata')
|
||||
metadataKeys: string[];
|
||||
|
||||
@autoserializeAs('dataType')
|
||||
dataType: BrowseByDataType;
|
||||
|
||||
get self(): string {
|
||||
return this._links.self.href;
|
||||
}
|
||||
|
@@ -13,15 +13,48 @@ import { MenuService } from '../shared/menu/menu.service';
|
||||
import { MenuServiceStub } from '../shared/testing/menu-service.stub';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { BrowseService } from '../core/browse/browse.service';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../shared/remote-data.utils';
|
||||
import { buildPaginatedList } from '../core/data/paginated-list.model';
|
||||
import { BrowseDefinition } from '../core/shared/browse-definition.model';
|
||||
import { BrowseByDataType } from '../browse-by/browse-by-switcher/browse-by-decorator';
|
||||
|
||||
let comp: NavbarComponent;
|
||||
let fixture: ComponentFixture<NavbarComponent>;
|
||||
|
||||
describe('NavbarComponent', () => {
|
||||
const menuService = new MenuServiceStub();
|
||||
|
||||
let browseDefinitions;
|
||||
// waitForAsync beforeEach
|
||||
beforeEach(waitForAsync(() => {
|
||||
browseDefinitions = [
|
||||
Object.assign(
|
||||
new BrowseDefinition(), {
|
||||
id: 'title',
|
||||
dataType: BrowseByDataType.Title,
|
||||
}
|
||||
),
|
||||
Object.assign(
|
||||
new BrowseDefinition(), {
|
||||
id: 'dateissued',
|
||||
dataType: BrowseByDataType.Date,
|
||||
metadataKeys: ['dc.date.issued']
|
||||
}
|
||||
),
|
||||
Object.assign(
|
||||
new BrowseDefinition(), {
|
||||
id: 'author',
|
||||
dataType: BrowseByDataType.Metadata,
|
||||
}
|
||||
),
|
||||
Object.assign(
|
||||
new BrowseDefinition(), {
|
||||
id: 'subject',
|
||||
dataType: BrowseByDataType.Metadata,
|
||||
}
|
||||
),
|
||||
];
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
@@ -33,7 +66,8 @@ describe('NavbarComponent', () => {
|
||||
Injector,
|
||||
{ provide: MenuService, useValue: menuService },
|
||||
{ provide: HostWindowService, useValue: new HostWindowServiceStub(800) },
|
||||
{ provide: ActivatedRoute, useValue: {} }
|
||||
{ provide: ActivatedRoute, useValue: {} },
|
||||
{ provide: BrowseService, useValue: { getBrowseDefinitions: createSuccessfulRemoteDataObject$(buildPaginatedList(undefined, browseDefinitions)) } }
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
})
|
||||
|
@@ -2,8 +2,6 @@ import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
import { BrowseByTypeConfig } from '../../../config/browse-by-type-config.interface';
|
||||
import { environment } from '../../../environments/environment';
|
||||
import { getCommunityPageRoute } from '../../community-page/community-page-routing-paths';
|
||||
import { getCollectionPageRoute } from '../../collection-page/collection-page-routing-paths';
|
||||
import { getFirstCompletedRemoteData } from '../../core/shared/operators';
|
||||
@@ -34,10 +32,6 @@ export class ComcolPageBrowseByComponent implements OnInit {
|
||||
*/
|
||||
@Input() id: string;
|
||||
@Input() contentType: string;
|
||||
/**
|
||||
* List of currently active browse configurations
|
||||
*/
|
||||
types: BrowseByTypeConfig[];
|
||||
|
||||
allOptions: ComColPageNavOption[];
|
||||
|
||||
@@ -46,7 +40,7 @@ export class ComcolPageBrowseByComponent implements OnInit {
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
public browseService: BrowseService
|
||||
private browseService: BrowseService
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -62,23 +56,23 @@ export class ComcolPageBrowseByComponent implements OnInit {
|
||||
routerLink: `/browse/${config.id}`,
|
||||
params: { scope: this.id }
|
||||
}));
|
||||
|
||||
if (this.contentType === 'collection') {
|
||||
this.allOptions = [{
|
||||
id: this.id,
|
||||
label: 'collection.page.browse.recent.head',
|
||||
routerLink: getCollectionPageRoute(this.id)
|
||||
}, ...this.allOptions];
|
||||
} else if (this.contentType === 'community') {
|
||||
this.allOptions = [{
|
||||
id: this.id,
|
||||
label: 'community.all-lists.head',
|
||||
routerLink: getCommunityPageRoute(this.id)
|
||||
}, ...this.allOptions];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (this.contentType === 'collection') {
|
||||
this.allOptions = [{
|
||||
id: this.id,
|
||||
label: 'collection.page.browse.recent.head',
|
||||
routerLink: getCollectionPageRoute(this.id)
|
||||
}, ...this.allOptions];
|
||||
} else if (this.contentType === 'community') {
|
||||
this.allOptions = [{
|
||||
id: this.id,
|
||||
label: 'community.all-lists.head',
|
||||
routerLink: getCommunityPageRoute(this.id)
|
||||
}, ...this.allOptions];
|
||||
}
|
||||
|
||||
this.currentOptionId$ = this.route.params.pipe(
|
||||
map((params: Params) => params.id)
|
||||
);
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import { Config } from './config.interface';
|
||||
import { BrowseByTypeConfig } from './browse-by-type-config.interface';
|
||||
|
||||
/**
|
||||
* Config that determines how the dropdown list of years are created for browse-by-date components
|
||||
@@ -19,9 +18,4 @@ export interface BrowseByConfig extends Config {
|
||||
* The absolute lowest year to display in the dropdown when no lowest date can be found for all items
|
||||
*/
|
||||
defaultLowerLimit: number;
|
||||
|
||||
/**
|
||||
* A list of all the active Browse-By pages
|
||||
*/
|
||||
types: BrowseByTypeConfig[];
|
||||
}
|
||||
|
@@ -1,23 +0,0 @@
|
||||
import { Config } from './config.interface';
|
||||
import { BrowseByType } from '../app/browse-by/browse-by-switcher/browse-by-decorator';
|
||||
|
||||
/**
|
||||
* Config used for rendering Browse-By pages and links
|
||||
*/
|
||||
export interface BrowseByTypeConfig extends Config {
|
||||
/**
|
||||
* The browse id used for fetching browse data from the rest api
|
||||
* e.g. author
|
||||
*/
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* The type of Browse-By page to render
|
||||
*/
|
||||
type: BrowseByType | string;
|
||||
|
||||
/**
|
||||
* The metadata field to use for rendering starts-with options (only necessary when type is set to BrowseByType.Date)
|
||||
*/
|
||||
metadataField?: string;
|
||||
}
|
@@ -6,13 +6,13 @@ import { INotificationBoardOptions } from './notifications-config.interfaces';
|
||||
import { SubmissionConfig } from './submission-config.interface';
|
||||
import { FormConfig } from './form-config.interfaces';
|
||||
import { LangConfig } from './lang-config.interface';
|
||||
import { BrowseByConfig } from './browse-by-config.interface';
|
||||
import { ItemPageConfig } from './item-page-config.interface';
|
||||
import { CollectionPageConfig } from './collection-page-config.interface';
|
||||
import { ThemeConfig } from './theme.model';
|
||||
import { AuthConfig } from './auth-config.interfaces';
|
||||
import { UIServerConfig } from './ui-server-config.interface';
|
||||
import { MediaViewerConfig } from './media-viewer-config.interface';
|
||||
import { BrowseByConfig } from './browse-by-config.interface';
|
||||
|
||||
export interface GlobalConfig extends Config {
|
||||
ui: UIServerConfig;
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import { GlobalConfig } from '../config/global-config.interface';
|
||||
import { NotificationAnimationsType } from '../app/shared/notifications/models/notification-animations-type';
|
||||
import { BrowseByType } from '../app/browse-by/browse-by-switcher/browse-by-decorator';
|
||||
import { RestRequestMethod } from '../app/core/data/rest-request-method';
|
||||
|
||||
export const environment: GlobalConfig = {
|
||||
@@ -207,32 +206,6 @@ export const environment: GlobalConfig = {
|
||||
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,
|
||||
// List of all the active Browse-By types
|
||||
// Adding a type will activate their Browse-By page and add them to the global navigation menu,
|
||||
// as well as community and collection pages
|
||||
// Allowed fields and their purpose:
|
||||
// id: The browse id to use for fetching info from the rest api
|
||||
// type: The type of Browse-By page to display
|
||||
// metadataField: The metadata-field used to create starts-with options (only necessary when the type is set to 'date')
|
||||
types: [
|
||||
{
|
||||
id: 'title',
|
||||
type: BrowseByType.Title,
|
||||
},
|
||||
{
|
||||
id: 'dateissued',
|
||||
type: BrowseByType.Date,
|
||||
metadataField: 'dc.date.issued'
|
||||
},
|
||||
{
|
||||
id: 'author',
|
||||
type: BrowseByType.Metadata
|
||||
},
|
||||
{
|
||||
id: 'subject',
|
||||
type: BrowseByType.Metadata
|
||||
}
|
||||
]
|
||||
},
|
||||
item: {
|
||||
edit: {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
// This configuration is only used for unit tests, end-to-end tests use environment.prod.ts
|
||||
import { BrowseByType } from '../app/browse-by/browse-by-switcher/browse-by-decorator';
|
||||
import { BrowseByDataType } from '../app/browse-by/browse-by-switcher/browse-by-decorator';
|
||||
import { RestRequestMethod } from '../app/core/data/rest-request-method';
|
||||
import { NotificationAnimationsType } from '../app/shared/notifications/models/notification-animations-type';
|
||||
import { GlobalConfig } from '../config/global-config.interface';
|
||||
@@ -169,32 +169,6 @@ export const environment: Partial<GlobalConfig> = {
|
||||
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,
|
||||
// List of all the active Browse-By types
|
||||
// Adding a type will activate their Browse-By page and add them to the global navigation menu,
|
||||
// as well as community and collection pages
|
||||
// Allowed fields and their purpose:
|
||||
// id: The browse id to use for fetching info from the rest api
|
||||
// type: The type of Browse-By page to display
|
||||
// metadataField: The metadata-field used to create starts-with options (only necessary when the type is set to 'date')
|
||||
types: [
|
||||
{
|
||||
id: 'title',
|
||||
type: BrowseByType.Title,
|
||||
},
|
||||
{
|
||||
id: 'dateissued',
|
||||
type: BrowseByType.Date,
|
||||
metadataField: 'dc.date.issued'
|
||||
},
|
||||
{
|
||||
id: 'author',
|
||||
type: BrowseByType.Metadata
|
||||
},
|
||||
{
|
||||
id: 'subject',
|
||||
type: BrowseByType.Metadata
|
||||
}
|
||||
]
|
||||
},
|
||||
item: {
|
||||
edit: {
|
||||
|
Reference in New Issue
Block a user