mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 18:14:17 +00:00
Merge pull request #3811 from tdonohue/port_3701_to_8x
[Port dspace-8_x] Reduce browse definition requests on simple item page (#3701)
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
import { autoserialize } from 'cerialize';
|
||||
import {
|
||||
autoserialize,
|
||||
autoserializeAs,
|
||||
} from 'cerialize';
|
||||
|
||||
import { BrowseByDataType } from '../../browse-by/browse-by-switcher/browse-by-data-type';
|
||||
import { CacheableObject } from '../cache/cacheable-object.model';
|
||||
@@ -11,6 +14,9 @@ export abstract class BrowseDefinition extends CacheableObject {
|
||||
@autoserialize
|
||||
id: string;
|
||||
|
||||
@autoserializeAs('metadata')
|
||||
metadataKeys: string[];
|
||||
|
||||
/**
|
||||
* Get the render type of the BrowseDefinition model
|
||||
*/
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import {
|
||||
autoserialize,
|
||||
autoserializeAs,
|
||||
deserialize,
|
||||
inheritSerialization,
|
||||
} from 'cerialize';
|
||||
@@ -33,9 +32,6 @@ export class HierarchicalBrowseDefinition extends BrowseDefinition {
|
||||
@autoserialize
|
||||
vocabulary: string;
|
||||
|
||||
@autoserializeAs('metadata')
|
||||
metadataKeys: string[];
|
||||
|
||||
get self(): string {
|
||||
return this._links.self.href;
|
||||
}
|
||||
|
@@ -21,9 +21,6 @@ export abstract class NonHierarchicalBrowseDefinition extends BrowseDefinition {
|
||||
@autoserializeAs('order')
|
||||
defaultSortOrder: string;
|
||||
|
||||
@autoserializeAs('metadata')
|
||||
metadataKeys: string[];
|
||||
|
||||
@autoserialize
|
||||
dataType: BrowseByDataType;
|
||||
}
|
||||
|
@@ -15,8 +15,10 @@ import {
|
||||
|
||||
import { APP_CONFIG } from '../../../../../../config/app-config.interface';
|
||||
import { environment } from '../../../../../../environments/environment';
|
||||
import { BrowseService } from '../../../../../core/browse/browse.service';
|
||||
import { BrowseDefinitionDataService } from '../../../../../core/browse/browse-definition-data.service';
|
||||
import { BrowseDefinitionDataServiceStub } from '../../../../../shared/testing/browse-definition-data-service.stub';
|
||||
import { BrowseServiceStub } from '../../../../../shared/testing/browse-service.stub';
|
||||
import { TranslateLoaderMock } from '../../../../../shared/testing/translate-loader.mock';
|
||||
import { ItemPageAbstractFieldComponent } from './item-page-abstract-field.component';
|
||||
|
||||
@@ -38,6 +40,7 @@ describe('ItemPageAbstractFieldComponent', () => {
|
||||
providers: [
|
||||
{ provide: APP_CONFIG, useValue: environment },
|
||||
{ provide: BrowseDefinitionDataService, useValue: BrowseDefinitionDataServiceStub },
|
||||
{ provide: BrowseService, useValue: BrowseServiceStub },
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
}).overrideComponent(ItemPageAbstractFieldComponent, {
|
||||
|
@@ -15,9 +15,11 @@ import {
|
||||
|
||||
import { APP_CONFIG } from '../../../../../../config/app-config.interface';
|
||||
import { environment } from '../../../../../../environments/environment';
|
||||
import { BrowseService } from '../../../../../core/browse/browse.service';
|
||||
import { BrowseDefinitionDataService } from '../../../../../core/browse/browse-definition-data.service';
|
||||
import { ActivatedRouteStub } from '../../../../../shared/testing/active-router.stub';
|
||||
import { BrowseDefinitionDataServiceStub } from '../../../../../shared/testing/browse-definition-data-service.stub';
|
||||
import { BrowseServiceStub } from '../../../../../shared/testing/browse-service.stub';
|
||||
import { TranslateLoaderMock } from '../../../../../shared/testing/translate-loader.mock';
|
||||
import { MetadataValuesComponent } from '../../../../field-components/metadata-values/metadata-values.component';
|
||||
import { mockItemWithMetadataFieldsAndValue } from '../item-page-field.component.spec';
|
||||
@@ -41,6 +43,7 @@ describe('ItemPageAuthorFieldComponent', () => {
|
||||
providers: [
|
||||
{ provide: APP_CONFIG, useValue: environment },
|
||||
{ provide: BrowseDefinitionDataService, useValue: BrowseDefinitionDataServiceStub },
|
||||
{ provide: BrowseService, useValue: BrowseServiceStub },
|
||||
{ provide: ActivatedRoute, useValue: new ActivatedRouteStub() },
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
|
@@ -15,9 +15,11 @@ import {
|
||||
|
||||
import { APP_CONFIG } from '../../../../../../config/app-config.interface';
|
||||
import { environment } from '../../../../../../environments/environment';
|
||||
import { BrowseService } from '../../../../../core/browse/browse.service';
|
||||
import { BrowseDefinitionDataService } from '../../../../../core/browse/browse-definition-data.service';
|
||||
import { ActivatedRouteStub } from '../../../../../shared/testing/active-router.stub';
|
||||
import { BrowseDefinitionDataServiceStub } from '../../../../../shared/testing/browse-definition-data-service.stub';
|
||||
import { BrowseServiceStub } from '../../../../../shared/testing/browse-service.stub';
|
||||
import { TranslateLoaderMock } from '../../../../../shared/testing/translate-loader.mock';
|
||||
import { MetadataValuesComponent } from '../../../../field-components/metadata-values/metadata-values.component';
|
||||
import { mockItemWithMetadataFieldsAndValue } from '../item-page-field.component.spec';
|
||||
@@ -41,8 +43,8 @@ describe('ItemPageDateFieldComponent', () => {
|
||||
providers: [
|
||||
{ provide: APP_CONFIG, useValue: environment },
|
||||
{ provide: BrowseDefinitionDataService, useValue: BrowseDefinitionDataServiceStub },
|
||||
{ provide: BrowseService, useValue: BrowseServiceStub },
|
||||
{ provide: ActivatedRoute, useValue: new ActivatedRouteStub() },
|
||||
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
}).overrideComponent(ItemPageDateFieldComponent, {
|
||||
|
@@ -15,9 +15,11 @@ import {
|
||||
|
||||
import { APP_CONFIG } from '../../../../../../config/app-config.interface';
|
||||
import { environment } from '../../../../../../environments/environment';
|
||||
import { BrowseService } from '../../../../../core/browse/browse.service';
|
||||
import { BrowseDefinitionDataService } from '../../../../../core/browse/browse-definition-data.service';
|
||||
import { ActivatedRouteStub } from '../../../../../shared/testing/active-router.stub';
|
||||
import { BrowseDefinitionDataServiceStub } from '../../../../../shared/testing/browse-definition-data-service.stub';
|
||||
import { BrowseServiceStub } from '../../../../../shared/testing/browse-service.stub';
|
||||
import { TranslateLoaderMock } from '../../../../../shared/testing/translate-loader.mock';
|
||||
import { MetadataValuesComponent } from '../../../../field-components/metadata-values/metadata-values.component';
|
||||
import { mockItemWithMetadataFieldsAndValue } from '../item-page-field.component.spec';
|
||||
@@ -43,6 +45,7 @@ describe('GenericItemPageFieldComponent', () => {
|
||||
providers: [
|
||||
{ provide: APP_CONFIG, useValue: environment },
|
||||
{ provide: BrowseDefinitionDataService, useValue: BrowseDefinitionDataServiceStub },
|
||||
{ provide: BrowseService, useValue: BrowseServiceStub },
|
||||
{ provide: ActivatedRoute, useValue: new ActivatedRouteStub() },
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
|
@@ -14,8 +14,10 @@ import {
|
||||
|
||||
import { APP_CONFIG } from '../../../../../../config/app-config.interface';
|
||||
import { environment } from '../../../../../../environments/environment';
|
||||
import { BrowseService } from '../../../../../core/browse/browse.service';
|
||||
import { BrowseDefinitionDataService } from '../../../../../core/browse/browse-definition-data.service';
|
||||
import { BrowseDefinitionDataServiceStub } from '../../../../../shared/testing/browse-definition-data-service.stub';
|
||||
import { BrowseServiceStub } from '../../../../../shared/testing/browse-service.stub';
|
||||
import { TranslateLoaderMock } from '../../../../../shared/testing/translate-loader.mock';
|
||||
import { MetadataValuesComponent } from '../../../../field-components/metadata-values/metadata-values.component';
|
||||
import { GenericItemPageFieldComponent } from '../generic/generic-item-page-field.component';
|
||||
@@ -49,6 +51,7 @@ describe('ItemPageImgFieldComponent', () => {
|
||||
providers: [
|
||||
{ provide: APP_CONFIG, useValue: environment },
|
||||
{ provide: BrowseDefinitionDataService, useValue: BrowseDefinitionDataServiceStub },
|
||||
{ provide: BrowseService, useValue: BrowseServiceStub },
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
})
|
||||
|
@@ -16,6 +16,7 @@ import {
|
||||
|
||||
import { APP_CONFIG } from '../../../../../config/app-config.interface';
|
||||
import { environment } from '../../../../../environments/environment';
|
||||
import { BrowseService } from '../../../../core/browse/browse.service';
|
||||
import { BrowseDefinitionDataService } from '../../../../core/browse/browse-definition-data.service';
|
||||
import { Item } from '../../../../core/shared/item.model';
|
||||
import { MathService } from '../../../../core/shared/math.service';
|
||||
@@ -26,6 +27,7 @@ import {
|
||||
import { TranslateLoaderMock } from '../../../../shared/mocks/translate-loader.mock';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/remote-data.utils';
|
||||
import { BrowseDefinitionDataServiceStub } from '../../../../shared/testing/browse-definition-data-service.stub';
|
||||
import { BrowseServiceStub } from '../../../../shared/testing/browse-service.stub';
|
||||
import { createPaginatedList } from '../../../../shared/testing/utils.test';
|
||||
import { MarkdownDirective } from '../../../../shared/utils/markdown.directive';
|
||||
import { MetadataValuesComponent } from '../../../field-components/metadata-values/metadata-values.component';
|
||||
@@ -66,6 +68,7 @@ describe('ItemPageFieldComponent', () => {
|
||||
providers: [
|
||||
{ provide: APP_CONFIG, useValue: appConfig },
|
||||
{ provide: BrowseDefinitionDataService, useValue: BrowseDefinitionDataServiceStub },
|
||||
{ provide: BrowseService, useValue: BrowseServiceStub },
|
||||
{ provide: MathService, useValue: {} },
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
|
@@ -3,17 +3,26 @@ import {
|
||||
Component,
|
||||
Input,
|
||||
} from '@angular/core';
|
||||
import intersectionWith from 'lodash/intersectionWith';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import {
|
||||
filter,
|
||||
mergeAll,
|
||||
take,
|
||||
} from 'rxjs/operators';
|
||||
|
||||
import { BrowseService } from '../../../../core/browse/browse.service';
|
||||
import { BrowseDefinitionDataService } from '../../../../core/browse/browse-definition-data.service';
|
||||
import { BrowseDefinition } from '../../../../core/shared/browse-definition.model';
|
||||
import { Item } from '../../../../core/shared/item.model';
|
||||
import { getFirstCompletedRemoteData } from '../../../../core/shared/operators';
|
||||
import {
|
||||
getFirstCompletedRemoteData,
|
||||
getPaginatedListPayload,
|
||||
getRemoteDataPayload,
|
||||
} from '../../../../core/shared/operators';
|
||||
import { MetadataValuesComponent } from '../../../field-components/metadata-values/metadata-values.component';
|
||||
import { ImageField } from './image-field';
|
||||
|
||||
|
||||
/**
|
||||
* This component can be used to represent metadata on a simple item page.
|
||||
* It expects one input parameter of type Item to which the metadata belongs.
|
||||
@@ -30,7 +39,8 @@ import { ImageField } from './image-field';
|
||||
})
|
||||
export class ItemPageFieldComponent {
|
||||
|
||||
constructor(protected browseDefinitionDataService: BrowseDefinitionDataService) {
|
||||
constructor(protected browseDefinitionDataService: BrowseDefinitionDataService,
|
||||
protected browseService: BrowseService) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,9 +84,26 @@ export class ItemPageFieldComponent {
|
||||
* link in dspace.cfg (webui.browse.link.<n>)
|
||||
*/
|
||||
get browseDefinition(): Observable<BrowseDefinition> {
|
||||
return this.browseDefinitionDataService.findByFields(this.fields).pipe(
|
||||
return this.browseService.getBrowseDefinitions().pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
map((def) => def.payload),
|
||||
getRemoteDataPayload(),
|
||||
getPaginatedListPayload(),
|
||||
mergeAll(),
|
||||
filter((def: BrowseDefinition) =>
|
||||
intersectionWith(def.metadataKeys, this.fields, ItemPageFieldComponent.fieldMatch).length > 0,
|
||||
),
|
||||
take(1),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true iff the spec and field match.
|
||||
* @param spec Specification of a metadata field name: either a metadata field, or a prefix ending in ".*".
|
||||
* @param field A metadata field name.
|
||||
* @private
|
||||
*/
|
||||
private static fieldMatch(spec: string, field: string): boolean {
|
||||
return field === spec
|
||||
|| (spec.endsWith('.*') && field.substring(0, spec.length - 1) === spec.substring(0, spec.length - 1));
|
||||
}
|
||||
}
|
||||
|
@@ -14,8 +14,10 @@ import {
|
||||
|
||||
import { APP_CONFIG } from '../../../../../../config/app-config.interface';
|
||||
import { environment } from '../../../../../../environments/environment';
|
||||
import { BrowseService } from '../../../../../core/browse/browse.service';
|
||||
import { BrowseDefinitionDataService } from '../../../../../core/browse/browse-definition-data.service';
|
||||
import { BrowseDefinitionDataServiceStub } from '../../../../../shared/testing/browse-definition-data-service.stub';
|
||||
import { BrowseServiceStub } from '../../../../../shared/testing/browse-service.stub';
|
||||
import { TranslateLoaderMock } from '../../../../../shared/testing/translate-loader.mock';
|
||||
import { MetadataUriValuesComponent } from '../../../../field-components/metadata-uri-values/metadata-uri-values.component';
|
||||
import { mockItemWithMetadataFieldsAndValue } from '../item-page-field.component.spec';
|
||||
@@ -40,6 +42,7 @@ describe('ItemPageUriFieldComponent', () => {
|
||||
providers: [
|
||||
{ provide: APP_CONFIG, useValue: environment },
|
||||
{ provide: BrowseDefinitionDataService, useValue: BrowseDefinitionDataServiceStub },
|
||||
{ provide: BrowseService, useValue: BrowseServiceStub },
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
}).overrideComponent(ItemPageUriFieldComponent, {
|
||||
|
91
src/app/shared/testing/browse-service.stub.ts
Normal file
91
src/app/shared/testing/browse-service.stub.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import {
|
||||
EMPTY,
|
||||
Observable,
|
||||
} from 'rxjs';
|
||||
|
||||
import {
|
||||
buildPaginatedList,
|
||||
PaginatedList,
|
||||
} from '../../core/data/paginated-list.model';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { BrowseDefinition } from '../../core/shared/browse-definition.model';
|
||||
import { FlatBrowseDefinition } from '../../core/shared/flat-browse-definition.model';
|
||||
import { HierarchicalBrowseDefinition } from '../../core/shared/hierarchical-browse-definition.model';
|
||||
import { PageInfo } from '../../core/shared/page-info.model';
|
||||
import { ValueListBrowseDefinition } from '../../core/shared/value-list-browse-definition.model';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../remote-data.utils';
|
||||
|
||||
const mockData = [
|
||||
Object.assign(new FlatBrowseDefinition(), {
|
||||
'id': 'dateissued',
|
||||
'browseType': 'flatBrowse',
|
||||
'dataType': 'date',
|
||||
'sortOptions': EMPTY,
|
||||
'order': 'ASC',
|
||||
'type': 'browse',
|
||||
'metadataKeys': [
|
||||
'dc.date.issued',
|
||||
],
|
||||
'_links': EMPTY,
|
||||
}),
|
||||
|
||||
Object.assign(new ValueListBrowseDefinition(), {
|
||||
'id': 'author',
|
||||
'browseType': 'valueList',
|
||||
'dataType': 'text',
|
||||
'sortOptions': EMPTY,
|
||||
'order': 'ASC',
|
||||
'type': 'browse',
|
||||
'metadataKeys': [
|
||||
'dc.contributor.*',
|
||||
'dc.creator',
|
||||
],
|
||||
'_links': EMPTY,
|
||||
}),
|
||||
|
||||
Object.assign(new FlatBrowseDefinition(), {
|
||||
'id': 'title',
|
||||
'browseType': 'flatBrowse',
|
||||
'dataType': 'title',
|
||||
'sortOptions': EMPTY,
|
||||
'order': 'ASC',
|
||||
'type': 'browse',
|
||||
'metadataKeys': [
|
||||
'dc.title',
|
||||
],
|
||||
'_links': EMPTY,
|
||||
}),
|
||||
|
||||
Object.assign(new ValueListBrowseDefinition(), {
|
||||
'id': 'subject',
|
||||
'browseType': 'valueList',
|
||||
'dataType': 'text',
|
||||
'sortOptions': EMPTY,
|
||||
'order': 'ASC',
|
||||
'type': 'browse',
|
||||
'metadataKeys': [
|
||||
'dc.subject.*',
|
||||
],
|
||||
'_links': EMPTY,
|
||||
}),
|
||||
|
||||
Object.assign(new HierarchicalBrowseDefinition(), {
|
||||
'id': 'srsc',
|
||||
'browseType': 'hierarchicalBrowse',
|
||||
'facetType': 'subject',
|
||||
'vocabulary': 'srsc',
|
||||
'type': 'browse',
|
||||
'metadataKeys': [
|
||||
'dc.subject',
|
||||
],
|
||||
'_links': EMPTY,
|
||||
}),
|
||||
];
|
||||
export const BrowseServiceStub: any = {
|
||||
/**
|
||||
* Get all browse definitions.
|
||||
*/
|
||||
getBrowseDefinitions(): Observable<RemoteData<PaginatedList<BrowseDefinition>>> {
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), mockData));
|
||||
},
|
||||
};
|
Reference in New Issue
Block a user