Skip to content

Commit

Permalink
add a custom FindDataImpl for browsedefinitions
Browse files Browse the repository at this point in the history
  • Loading branch information
artlowel committed May 17, 2023
1 parent f3d4754 commit 3d7e61f
Show file tree
Hide file tree
Showing 17 changed files with 129 additions and 113 deletions.
4 changes: 2 additions & 2 deletions src/app/browse-by/browse-by-guard.spec.ts
Expand Up @@ -2,7 +2,7 @@ import { first } from 'rxjs/operators';
import { BrowseByGuard } from './browse-by-guard';
import { of as observableOf } from 'rxjs';
import { createSuccessfulRemoteDataObject$ } from '../shared/remote-data.utils';
import { FlatBrowseDefinition } from '../core/shared/flat-browse-definition.model';
import { BrowseDefinition } from '../core/shared/browse-definition.model';
import { BrowseByDataType } from './browse-by-switcher/browse-by-decorator';

describe('BrowseByGuard', () => {
Expand All @@ -18,7 +18,7 @@ describe('BrowseByGuard', () => {
const id = 'author';
const scope = '1234-65487-12354-1235';
const value = 'Filter';
const browseDefinition = Object.assign(new FlatBrowseDefinition(), { type: BrowseByDataType.Metadata, metadataKeys: ['dc.contributor'] });
const browseDefinition = Object.assign(new BrowseDefinition(), { type: BrowseByDataType.Metadata, metadataKeys: ['dc.contributor'] });

beforeEach(() => {
dsoService = {
Expand Down
4 changes: 2 additions & 2 deletions src/app/browse-by/browse-by-guard.ts
Expand Up @@ -7,7 +7,7 @@ import { getFirstSucceededRemoteData, getFirstSucceededRemoteDataPayload } from
import { TranslateService } from '@ngx-translate/core';
import { Observable, of as observableOf } from 'rxjs';
import { BrowseDefinitionDataService } from '../core/browse/browse-definition-data.service';
import { FlatBrowseDefinition } from '../core/shared/flat-browse-definition.model';
import { BrowseDefinition } from '../core/shared/browse-definition.model';

@Injectable()
/**
Expand All @@ -23,7 +23,7 @@ export class BrowseByGuard implements CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const title = route.data.title;
const id = route.params.id || route.queryParams.id || route.data.id;
let browseDefinition$: Observable<FlatBrowseDefinition>;
let browseDefinition$: Observable<BrowseDefinition>;
if (hasNoValue(route.data.browseDefinition) && hasValue(id)) {
browseDefinition$ = this.browseDefinitionService.findById(id).pipe(getFirstSucceededRemoteDataPayload());
} else {
Expand Down
Expand Up @@ -3,7 +3,7 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { BROWSE_BY_COMPONENT_FACTORY, BrowseByDataType } from './browse-by-decorator';
import { FlatBrowseDefinition } from '../../core/shared/flat-browse-definition.model';
import { BrowseDefinition } from '../../core/shared/browse-definition.model';
import { BehaviorSubject } from 'rxjs';
import { ThemeService } from '../../shared/theme-support/theme.service';

Expand All @@ -13,33 +13,33 @@ describe('BrowseBySwitcherComponent', () => {

const types = [
Object.assign(
new FlatBrowseDefinition(), {
new BrowseDefinition(), {
id: 'title',
dataType: BrowseByDataType.Title,
}
),
Object.assign(
new FlatBrowseDefinition(), {
new BrowseDefinition(), {
id: 'dateissued',
dataType: BrowseByDataType.Date,
metadataKeys: ['dc.date.issued']
}
),
Object.assign(
new FlatBrowseDefinition(), {
new BrowseDefinition(), {
id: 'author',
dataType: BrowseByDataType.Metadata,
}
),
Object.assign(
new FlatBrowseDefinition(), {
new BrowseDefinition(), {
id: 'subject',
dataType: BrowseByDataType.Metadata,
}
),
];

const data = new BehaviorSubject(createDataWithBrowseDefinition(new FlatBrowseDefinition()));
const data = new BehaviorSubject(createDataWithBrowseDefinition(new BrowseDefinition()));

const activatedRouteStub = {
data
Expand Down Expand Up @@ -70,7 +70,7 @@ describe('BrowseBySwitcherComponent', () => {
comp = fixture.componentInstance;
}));

types.forEach((type: FlatBrowseDefinition) => {
types.forEach((type: BrowseDefinition) => {
describe(`when switching to a browse-by page for "${type.id}"`, () => {
beforeEach(() => {
data.next(createDataWithBrowseDefinition(type));
Expand Down
Expand Up @@ -4,7 +4,7 @@ import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { BROWSE_BY_COMPONENT_FACTORY } from './browse-by-decorator';
import { GenericConstructor } from '../../core/shared/generic-constructor';
import { FlatBrowseDefinition } from '../../core/shared/flat-browse-definition.model';
import { BrowseDefinition } from '../../core/shared/browse-definition.model';
import { ThemeService } from '../../shared/theme-support/theme.service';

@Component({
Expand All @@ -31,7 +31,7 @@ export class BrowseBySwitcherComponent implements OnInit {
*/
ngOnInit(): void {
this.browseByComponent = this.route.data.pipe(
map((data: { browseDefinition: FlatBrowseDefinition }) => this.getComponentByBrowseByType(data.browseDefinition.getRenderType(), this.themeService.getThemeName()))
map((data: { browseDefinition: BrowseDefinition }) => this.getComponentByBrowseByType(data.browseDefinition.getRenderType(), this.themeService.getThemeName()))
);
}

Expand Down
71 changes: 37 additions & 34 deletions src/app/core/browse/browse-definition-data.service.ts
@@ -1,6 +1,5 @@
import { Injectable } from '@angular/core';
import { BROWSE_DEFINITION } from '../shared/browse-definition.resource-type';
import { FlatBrowseDefinition } from '../shared/flat-browse-definition.model';
import { RequestService } from '../data/request.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service';
Expand All @@ -16,6 +15,39 @@ import { dataService } from '../data/base/data-service.decorator';
import { isNotEmpty, isNotEmptyOperator, hasValue } from '../../shared/empty.util';
import { take } from 'rxjs/operators';
import { BrowseDefinitionRestRequest } from '../data/request.models';
import { BrowseDefinition } from '../shared/browse-definition.model';


class BrowseDefinitionDataImpl extends FindAllDataImpl<BrowseDefinition> {
/**
* Create a GET request for the given href, and send it.
* Use a GET request specific for BrowseDefinitions.
*
* @param href$ The url of browse we want to retrieve. Can be a string or
* an Observable<string>
* @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's
* no valid cached version. Defaults to true
*/
createAndSendGetRequest(href$: string | Observable<string>, useCachedVersionIfAvailable: boolean = true) {
if (isNotEmpty(href$)) {
if (typeof href$ === 'string') {
href$ = observableOf(href$);
}

href$.pipe(
isNotEmptyOperator(),
take(1)
).subscribe((href: string) => {
const requestId = this.requestService.generateRequestId();
const request = new BrowseDefinitionRestRequest(requestId, href);
if (hasValue(this.responseMsToLive)) {
request.responseMsToLive = this.responseMsToLive;
}
this.requestService.send(request, useCachedVersionIfAvailable);
});
}
}
}

/**
* Data service responsible for retrieving browse definitions from the REST server
Expand All @@ -24,8 +56,8 @@ import { BrowseDefinitionRestRequest } from '../data/request.models';
providedIn: 'root',
})
@dataService(BROWSE_DEFINITION)
export class BrowseDefinitionDataService extends IdentifiableDataService<FlatBrowseDefinition> implements FindAllData<FlatBrowseDefinition> {
private findAllData: FindAllDataImpl<FlatBrowseDefinition>;
export class BrowseDefinitionDataService extends IdentifiableDataService<BrowseDefinition> implements FindAllData<BrowseDefinition> {
private findAllData: BrowseDefinitionDataImpl;

constructor(
protected requestService: RequestService,
Expand All @@ -35,7 +67,7 @@ export class BrowseDefinitionDataService extends IdentifiableDataService<FlatBro
) {
super('browses', requestService, rdbService, objectCache, halService);

this.findAllData = new FindAllDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.responseMsToLive);
this.findAllData = new BrowseDefinitionDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.responseMsToLive);
}

/**
Expand All @@ -52,37 +84,8 @@ export class BrowseDefinitionDataService extends IdentifiableDataService<FlatBro
* @return {Observable<RemoteData<PaginatedList<T>>>}
* Return an observable that emits object list
*/
findAll(options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig<FlatBrowseDefinition>[]): Observable<RemoteData<PaginatedList<FlatBrowseDefinition>>> {
findAll(options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig<BrowseDefinition>[]): Observable<RemoteData<PaginatedList<BrowseDefinition>>> {
return this.findAllData.findAll(options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
}

/**
* Create a GET request for the given href, and send it.
* Use a GET request specific for BrowseDefinitions.
*
* @param href$ The url of browse we want to retrieve. Can be a string or
* an Observable<string>
* @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's
* no valid cached version. Defaults to true
*/
createAndSendGetRequest(href$: string | Observable<string>, useCachedVersionIfAvailable: boolean = true) {
if (isNotEmpty(href$)) {
if (typeof href$ === 'string') {
href$ = observableOf(href$);
}

href$.pipe(
isNotEmptyOperator(),
take(1)
).subscribe((href: string) => {
const requestId = this.requestService.generateRequestId();
const request = new BrowseDefinitionRestRequest(requestId, href);
if (hasValue(this.responseMsToLive)) {
request.responseMsToLive = this.responseMsToLive;
}
this.requestService.send(request, useCachedVersionIfAvailable);
});
}
}
}

6 changes: 3 additions & 3 deletions src/app/core/browse/browse.service.spec.ts
Expand Up @@ -6,7 +6,7 @@ import { getMockRequestService } from '../../shared/mocks/request.service.mock';
import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { RequestService } from '../data/request.service';
import { FlatBrowseDefinition } from '../shared/flat-browse-definition.model';
import { BrowseDefinition } from '../shared/browse-definition.model';
import { BrowseEntrySearchOptions } from './browse-entry-search-options.model';
import { BrowseService } from './browse.service';
import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
Expand All @@ -23,7 +23,7 @@ describe('BrowseService', () => {
const browsesEndpointURL = 'https://rest.api/browses';
const halService: any = new HALEndpointServiceStub(browsesEndpointURL);
const browseDefinitions = [
Object.assign(new FlatBrowseDefinition(), {
Object.assign(new BrowseDefinition(), {
id: 'date',
metadataBrowse: false,
sortOptions: [
Expand All @@ -50,7 +50,7 @@ describe('BrowseService', () => {
items: { href: 'https://rest.api/discover/browses/dateissued/items' }
}
}),
Object.assign(new FlatBrowseDefinition(), {
Object.assign(new BrowseDefinition(), {
id: 'author',
metadataBrowse: true,
sortOptions: [
Expand Down
16 changes: 11 additions & 5 deletions src/app/core/browse/browse.service.ts
Expand Up @@ -6,6 +6,7 @@ import { RemoteDataBuildService } from '../cache/builders/remote-data-build.serv
import { PaginatedList } from '../data/paginated-list.model';
import { RemoteData } from '../data/remote-data';
import { RequestService } from '../data/request.service';
import { BrowseDefinition } from '../shared/browse-definition.model';
import { FlatBrowseDefinition } from '../shared/flat-browse-definition.model';
import { BrowseEntry } from '../shared/browse-entry.model';
import { HALEndpointService } from '../shared/hal-endpoint.service';
Expand Down Expand Up @@ -60,7 +61,7 @@ export class BrowseService {
/**
* Get all BrowseDefinitions
*/
getBrowseDefinitions(): Observable<RemoteData<PaginatedList<FlatBrowseDefinition>>> {
getBrowseDefinitions(): Observable<RemoteData<PaginatedList<BrowseDefinition>>> {
// TODO properly support pagination
return this.browseDefinitionDataService.findAll({ elementsPerPage: 9999 }).pipe(
getFirstSucceededRemoteData(),
Expand Down Expand Up @@ -233,13 +234,18 @@ export class BrowseService {
return this.getBrowseDefinitions().pipe(
getRemoteDataPayload(),
getPaginatedListPayload(),
map((browseDefinitions: FlatBrowseDefinition[]) => browseDefinitions
.find((def: FlatBrowseDefinition) => {
const matchingKeys = def.metadataKeys.find((key: string) => searchKeyArray.indexOf(key) >= 0);
map((browseDefinitions: BrowseDefinition[]) => browseDefinitions
.find((def: BrowseDefinition) => {
let matchingKeys = '';

if (Array.isArray((def as FlatBrowseDefinition).metadataKeys)) {
matchingKeys = (def as FlatBrowseDefinition).metadataKeys.find((key: string) => searchKeyArray.indexOf(key) >= 0);
}

return isNotEmpty(matchingKeys);
})
),
map((def: FlatBrowseDefinition) => {
map((def: BrowseDefinition) => {
if (isEmpty(def) || isEmpty(def._links) || isEmpty(def._links[linkPath])) {
throw new Error(`A browse endpoint for ${linkPath} on ${metadataKey} isn't configured`);
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/app/core/core.module.ts
Expand Up @@ -73,7 +73,7 @@ import { ServerResponseService } from './services/server-response.service';
import { NativeWindowFactory, NativeWindowService } from './services/window.service';
import { BitstreamFormat } from './shared/bitstream-format.model';
import { Bitstream } from './shared/bitstream.model';
import { FlatBrowseDefinition } from './shared/flat-browse-definition.model';
import { BrowseDefinition } from './shared/browse-definition.model';
import { BrowseEntry } from './shared/browse-entry.model';
import { Bundle } from './shared/bundle.model';
import { Collection } from './shared/collection.model';
Expand Down Expand Up @@ -325,7 +325,7 @@ export const models =
SubmissionUploadsModel,
AuthStatus,
BrowseEntry,
FlatBrowseDefinition,
BrowseDefinition,
HierarchicalBrowseDefinition,
ClaimedTask,
TaskObject,
Expand Down
33 changes: 20 additions & 13 deletions src/app/core/data/browse-response-parsing.service.ts
@@ -1,35 +1,42 @@
import { Injectable } from '@angular/core';
import { ObjectCacheService } from '../cache/object-cache.service';
import { hasValue } from '../../shared/empty.util';
import { HIERARCHICAL_BROWSE_DEFINITION } from '../shared/hierarchical-browse-definition.resource-type';
import {
HIERARCHICAL_BROWSE_DEFINITION
} from '../shared/hierarchical-browse-definition.resource-type';
import { FLAT_BROWSE_DEFINITION } from '../shared/flat-browse-definition.resource-type';
import { HierarchicalBrowseDefinition } from '../shared/hierarchical-browse-definition.model';
import { FlatBrowseDefinition } from '../shared/flat-browse-definition.model';
import { DSOResponseParsingService } from './dso-response-parsing.service';
import { Serializer } from '../serializer';
import { BrowseDefinition } from '../shared/browse-definition.model';
import { BROWSE_DEFINITION } from '../shared/browse-definition.resource-type';

/**
* A ResponseParsingService used to parse RawRestResponse coming from the REST API to a BrowseDefinition object
*/
@Injectable({
providedIn: 'root',
})
providedIn: 'root',
})
export class BrowseResponseParsingService extends DSOResponseParsingService {
protected objectCache: ObjectCacheService;
protected toCache: boolean;
constructor(
protected objectCache: ObjectCacheService,
) {
super(objectCache);
}

protected deserialize<ObjectDomain>(obj): any {
const browseType: string = obj.browseType;
if (hasValue(browseType)) {
if (obj.type === BROWSE_DEFINITION.value && hasValue(browseType)) {
let serializer: Serializer<BrowseDefinition>;
if (browseType === HIERARCHICAL_BROWSE_DEFINITION.value) {
const serializer = new this.serializerConstructor(HierarchicalBrowseDefinition);
return serializer.deserialize(obj);
} else if (browseType === FLAT_BROWSE_DEFINITION.value) {
const serializer = new this.serializerConstructor(FlatBrowseDefinition);
return serializer.deserialize(obj);
serializer = new this.serializerConstructor(HierarchicalBrowseDefinition);
} else {
serializer = new this.serializerConstructor(FlatBrowseDefinition);
}
return serializer.deserialize(obj);
} else {
console.warn('cannot deserialize type ' + browseType);
return null;
return super.deserialize(obj);
}
}
}
16 changes: 16 additions & 0 deletions src/app/core/shared/browse-definition.model.ts
@@ -0,0 +1,16 @@
import { autoserialize } from 'cerialize';
import { CacheableObject } from '../cache/cacheable-object.model';

/**
* Base class for BrowseDefinition models
*/
export abstract class BrowseDefinition extends CacheableObject {

@autoserialize
id: string;

/**
* Get the render type of the BrowseDefinition model
*/
abstract getRenderType(): string;
}
10 changes: 0 additions & 10 deletions src/app/core/shared/browse-definition.ts

This file was deleted.

0 comments on commit 3d7e61f

Please sign in to comment.