diff --git a/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.ts b/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.ts index 7da6b5ede0..317b3c45c2 100644 --- a/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.ts +++ b/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.ts @@ -1,9 +1,8 @@ import { ChangeDetectorRef, Component, Inject } from '@angular/core'; import { BrowseByMetadataPageComponent, - browseParamsToOptions + browseParamsToOptions, getBrowseSearchOptions } from '../browse-by-metadata-page/browse-by-metadata-page.component'; -import { BrowseEntrySearchOptions } from '../../core/browse/browse-entry-search-options.model'; import { combineLatest as observableCombineLatest } from 'rxjs'; import { RemoteData } from '../../core/data/remote-data'; import { Item } from '../../core/shared/item.model'; @@ -51,8 +50,8 @@ export class BrowseByDatePageComponent extends BrowseByMetadataPageComponent { ngOnInit(): void { const sortConfig = new SortOptions('default', SortDirection.ASC); this.startsWithType = StartsWithType.date; - this.updatePage(new BrowseEntrySearchOptions(this.defaultBrowseId, this.paginationConfig, sortConfig, null, - null)); + // include the thumbnail configuration in browse search options + this.updatePage(getBrowseSearchOptions(this.defaultBrowseId, this.paginationConfig, sortConfig, this.fetchThumbnails)); this.currentPagination$ = this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig); this.currentSort$ = this.paginationService.getCurrentSort(this.paginationConfig.id, sortConfig); this.subs.push( @@ -65,7 +64,7 @@ export class BrowseByDatePageComponent extends BrowseByMetadataPageComponent { const metadataKeys = params.browseDefinition ? params.browseDefinition.metadataKeys : this.defaultMetadataKeys; this.browseId = params.id || this.defaultBrowseId; this.startsWith = +params.startsWith || params.startsWith; - const searchOptions = browseParamsToOptions(params, currentPage, currentSort, this.browseId, this.embedThumbnail); + const searchOptions = browseParamsToOptions(params, currentPage, currentSort, this.browseId, this.fetchThumbnails); this.updatePageWithItems(searchOptions, this.value, undefined); this.updateParent(params.scope); this.updateStartsWithOptions(this.browseId, metadataKeys, params.scope); diff --git a/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.spec.ts b/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.spec.ts index 763279ebe5..1b3d5d0664 100644 --- a/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.spec.ts +++ b/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.spec.ts @@ -1,4 +1,8 @@ -import { BrowseByMetadataPageComponent, browseParamsToOptions } from './browse-by-metadata-page.component'; +import { + BrowseByMetadataPageComponent, + browseParamsToOptions, + getBrowseSearchOptions +} from './browse-by-metadata-page.component'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { BrowseService } from '../../core/browse/browse.service'; import { CommonModule } from '@angular/common'; @@ -127,7 +131,7 @@ describe('BrowseByMetadataPageComponent', () => { }); it('should set embed thumbnail property to true', () => { - expect(comp.embedThumbnail).toBeTrue(); + expect(comp.fetchThumbnails).toBeTrue(); }); describe('when a value is provided', () => { @@ -164,7 +168,7 @@ describe('BrowseByMetadataPageComponent', () => { field: 'fake-field', }; - result = browseParamsToOptions(paramsScope, paginationOptions, sortOptions, 'author', comp.embedThumbnail); + result = browseParamsToOptions(paramsScope, paginationOptions, sortOptions, 'author', comp.fetchThumbnails); }); it('should return BrowseEntrySearchOptions with the correct properties', () => { @@ -175,7 +179,36 @@ describe('BrowseByMetadataPageComponent', () => { expect(result.sort.direction).toEqual(SortDirection.ASC); expect(result.sort.field).toEqual('fake-field'); expect(result.scope).toEqual('fake-scope'); - expect(result.embedThumbnail).toBeTrue(); + expect(result.fetchThumbnail).toBeTrue(); + }); + }); + + describe('calling getBrowseSearchOptions', () => { + let result: BrowseEntrySearchOptions; + + beforeEach(() => { + const paramsScope = { + scope: 'fake-scope' + }; + const paginationOptions = Object.assign(new PaginationComponentOptions(), { + currentPage: 5, + pageSize: 10, + }); + const sortOptions = { + direction: SortDirection.ASC, + field: 'fake-field', + }; + + result = getBrowseSearchOptions('title', paginationOptions, sortOptions, comp.fetchThumbnails); + }); + it('should return BrowseEntrySearchOptions with the correct properties', () => { + + expect(result.metadataDefinition).toEqual('title'); + expect(result.pagination.currentPage).toEqual(5); + expect(result.pagination.pageSize).toEqual(10); + expect(result.sort.direction).toEqual(SortDirection.ASC); + expect(result.sort.field).toEqual('fake-field'); + expect(result.fetchThumbnail).toBeTrue(); }); }); }); diff --git a/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.ts b/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.ts index 2c0e05302c..e14532c2fd 100644 --- a/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.ts +++ b/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.ts @@ -115,7 +115,7 @@ export class BrowseByMetadataPageComponent implements OnInit { /** * Determines whether to request embedded thumbnail. */ - embedThumbnail: boolean; + fetchThumbnails: boolean; public constructor(protected route: ActivatedRoute, protected browseService: BrowseService, @@ -123,14 +123,13 @@ export class BrowseByMetadataPageComponent implements OnInit { protected paginationService: PaginationService, protected router: Router, @Inject(APP_CONFIG) protected appConfig: AppConfig) { - this.embedThumbnail = this.appConfig.browseBy.showThumbnails; + this.fetchThumbnails = this.appConfig.browseBy.showThumbnails; } ngOnInit(): void { const sortConfig = new SortOptions('default', SortDirection.ASC); - this.updatePage(new BrowseEntrySearchOptions(this.defaultBrowseId, this.paginationConfig, sortConfig, null, - null, false)); + this.updatePage(getBrowseSearchOptions(this.defaultBrowseId, this.paginationConfig, sortConfig)); this.currentPagination$ = this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig); this.currentSort$ = this.paginationService.getCurrentSort(this.paginationConfig.id, sortConfig); this.subs.push( @@ -145,7 +144,7 @@ export class BrowseByMetadataPageComponent implements OnInit { this.startsWith = +params.startsWith || params.startsWith; if (isNotEmpty(this.value)) { this.updatePageWithItems( - browseParamsToOptions(params, currentPage, currentSort, this.browseId, this.embedThumbnail), this.value, this.authority); + browseParamsToOptions(params, currentPage, currentSort, this.browseId, false), this.value, this.authority); } else { this.updatePage(browseParamsToOptions(params, currentPage, currentSort, this.browseId, false)); } @@ -172,7 +171,6 @@ export class BrowseByMetadataPageComponent implements OnInit { * scope: string } */ updatePage(searchOptions: BrowseEntrySearchOptions) { - searchOptions.embedThumbnail = this.embedThumbnail; this.browseEntries$ = this.browseService.getBrowseEntriesFor(searchOptions); this.items$ = undefined; } @@ -240,25 +238,44 @@ export class BrowseByMetadataPageComponent implements OnInit { } +/** + * Creates browse entry search options. + * @param defaultBrowseId the metadata definition to fetch entries or items for + * @param paginationConfig the required pagination configuration + * @param sortConfig the required sort configuration + * @param fetchThumbnails optional boolean for fetching thumbnails + * @returns BrowseEntrySearchOptions instance + */ +export function getBrowseSearchOptions(defaultBrowseId: string, + paginationConfig: PaginationComponentOptions, + sortConfig: SortOptions, + fetchThumbnails?: boolean) { + if (!hasValue(fetchThumbnails)) { + fetchThumbnails = false; + } + return new BrowseEntrySearchOptions(defaultBrowseId, paginationConfig, sortConfig, null, + null, fetchThumbnails); +} + /** * Function to transform query and url parameters into searchOptions used to fetch browse entries or items * @param params URL and query parameters * @param paginationConfig Pagination configuration * @param sortConfig Sorting configuration * @param metadata Optional metadata definition to fetch browse entries/items for - * @param embedThumbnails Optional parameter for requesting thumbnail images + * @param fetchThumbnail Optional parameter for requesting thumbnail images */ export function browseParamsToOptions(params: any, paginationConfig: PaginationComponentOptions, sortConfig: SortOptions, metadata?: string, - embedThumbnails?: boolean): BrowseEntrySearchOptions { + fetchThumbnail?: boolean): BrowseEntrySearchOptions { return new BrowseEntrySearchOptions( metadata, paginationConfig, sortConfig, +params.startsWith || params.startsWith, params.scope, - embedThumbnails + fetchThumbnail ); } diff --git a/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.ts b/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.ts index 351d177899..b2281efe97 100644 --- a/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.ts +++ b/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.ts @@ -4,9 +4,8 @@ import { ActivatedRoute, Params, Router } from '@angular/router'; import { hasValue } from '../../shared/empty.util'; import { BrowseByMetadataPageComponent, - browseParamsToOptions + browseParamsToOptions, getBrowseSearchOptions } from '../browse-by-metadata-page/browse-by-metadata-page.component'; -import { BrowseEntrySearchOptions } from '../../core/browse/browse-entry-search-options.model'; 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'; @@ -38,8 +37,8 @@ export class BrowseByTitlePageComponent extends BrowseByMetadataPageComponent { ngOnInit(): void { const sortConfig = new SortOptions('dc.title', SortDirection.ASC); - this.updatePage(new BrowseEntrySearchOptions(this.defaultBrowseId, this.paginationConfig, sortConfig, null, - null)); + // include the thumbnail configuration in browse search options + this.updatePage(getBrowseSearchOptions(this.defaultBrowseId, this.paginationConfig, sortConfig, this.fetchThumbnails)); this.currentPagination$ = this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig); this.currentSort$ = this.paginationService.getCurrentSort(this.paginationConfig.id, sortConfig); this.subs.push( @@ -50,7 +49,7 @@ export class BrowseByTitlePageComponent extends BrowseByMetadataPageComponent { ).subscribe(([params, currentPage, currentSort]: [Params, PaginationComponentOptions, SortOptions]) => { this.startsWith = +params.startsWith || params.startsWith; this.browseId = params.id || this.defaultBrowseId; - this.updatePageWithItems(browseParamsToOptions(params, currentPage, currentSort, this.browseId, this.embedThumbnail), undefined, undefined); + this.updatePageWithItems(browseParamsToOptions(params, currentPage, currentSort, this.browseId, this.fetchThumbnails), undefined, undefined); this.updateParent(params.scope); })); this.updateStartsWithTextOptions(); diff --git a/src/app/core/browse/browse-entry-search-options.model.ts b/src/app/core/browse/browse-entry-search-options.model.ts index a4b04e0d57..1604c693e9 100644 --- a/src/app/core/browse/browse-entry-search-options.model.ts +++ b/src/app/core/browse/browse-entry-search-options.model.ts @@ -8,7 +8,7 @@ import { SortOptions } from '../cache/models/sort-options.model'; * - sort: Optional sorting options to use * - startsWith An optional value to use to filter the browse results * - scope: An optional scope to limit the results within a specific collection or community - * - embedThumbnail An optional boolean to request thumbnail for items + * - fetchThumbnail An optional boolean to request thumbnail for items */ export class BrowseEntrySearchOptions { constructor(public metadataDefinition: string, @@ -16,6 +16,6 @@ export class BrowseEntrySearchOptions { public sort?: SortOptions, public startsWith?: string, public scope?: string, - public embedThumbnail?: boolean) { + public fetchThumbnail?: boolean) { } } diff --git a/src/app/core/browse/browse.service.ts b/src/app/core/browse/browse.service.ts index d970db9d02..2fab189254 100644 --- a/src/app/core/browse/browse.service.ts +++ b/src/app/core/browse/browse.service.ts @@ -102,7 +102,7 @@ export class BrowseService { return href; }) ); - if (options.embedThumbnail) { + if (options.fetchThumbnail ) { return this.hrefOnlyDataService.findListByHref(href$, {}, null, null, ...BROWSE_LINKS_TO_FOLLOW); } return this.hrefOnlyDataService.findListByHref(href$); @@ -150,7 +150,7 @@ export class BrowseService { return href; }), ); - if (options.embedThumbnail) { + if (options.fetchThumbnail) { return this.hrefOnlyDataService.findListByHref(href$, {}, null, null, ...BROWSE_LINKS_TO_FOLLOW); } return this.hrefOnlyDataService.findListByHref(href$); diff --git a/src/app/core/data/find-list-options.model.ts b/src/app/core/data/find-list-options.model.ts index 7467b019f5..dc567d4b53 100644 --- a/src/app/core/data/find-list-options.model.ts +++ b/src/app/core/data/find-list-options.model.ts @@ -11,5 +11,5 @@ export class FindListOptions { sort?: SortOptions; searchParams?: RequestParam[]; startsWith?: string; - embedThumbnail?: boolean; + fetchThumbnail?: boolean; } diff --git a/src/app/core/data/relationship-data.service.spec.ts b/src/app/core/data/relationship-data.service.spec.ts index 50a10945a6..39aa7cbd58 100644 --- a/src/app/core/data/relationship-data.service.spec.ts +++ b/src/app/core/data/relationship-data.service.spec.ts @@ -202,7 +202,7 @@ describe('RelationshipDataService', () => { }); it('should call getItemRelationshipsByLabel with the correct params', (done) => { - mockOptions = Object.assign(mockOptions, { embedThumbnail: true }); + mockOptions = Object.assign(mockOptions, { fetchThumbnail: true }); service.getRelatedItemsByLabel( mockItem, mockLabel, diff --git a/src/app/core/data/relationship-data.service.ts b/src/app/core/data/relationship-data.service.ts index fc01880c2b..85adeff754 100644 --- a/src/app/core/data/relationship-data.service.ts +++ b/src/app/core/data/relationship-data.service.ts @@ -45,6 +45,7 @@ import { SearchData, SearchDataImpl } from './base/search-data'; import { PutData, PutDataImpl } from './base/put-data'; import { IdentifiableDataService } from './base/identifiable-data.service'; import { dataService } from './base/data-service.decorator'; +import { itemLinksToFollow } from '../../shared/utils/relation-query.utils'; const relationshipListsStateSelector = (state: AppState) => state.relationshipLists; @@ -185,7 +186,7 @@ export class RelationshipDataService extends IdentifiableDataService !existsInOC && !existsInRC), take(1), - ).subscribe(() => this.itemService.findByHref(item._links.self.href, false, true, followLink('thumbnail'))); + ).subscribe(() => this.itemService.findByHref(item._links.self.href)); } /** @@ -258,15 +259,9 @@ export class RelationshipDataService extends IdentifiableDataService>> { - let linksToFollow: FollowLinkConfig[]; - if (options.embedThumbnail) { - linksToFollow = [ - followLink('leftItem',{}, followLink('thumbnail')), - followLink('rightItem',{}, followLink('thumbnail')), - followLink('relationshipType') ]; - } else { - linksToFollow = [followLink('leftItem'), followLink('rightItem'), followLink('relationshipType')]; - } + let linksToFollow: FollowLinkConfig[] = itemLinksToFollow(options.fetchThumbnail); + linksToFollow.push(followLink('relationshipType')); + return this.getItemRelationshipsByLabel(item, label, options, true, true, ...linksToFollow).pipe(this.paginatedRelationsToItems(item.uuid)); } diff --git a/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.ts b/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.ts index 14a748c4b2..b8542f5806 100644 --- a/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.ts +++ b/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.ts @@ -29,7 +29,7 @@ import { DsDynamicLookupRelationModalComponent } from '../../../../shared/form/b import { RelationshipOptions } from '../../../../shared/form/builder/models/relationship-options.model'; import { SelectableListService } from '../../../../shared/object-list/selectable-list/selectable-list.service'; import { SearchResult } from '../../../../shared/search/models/search-result.model'; -import { followLink, FollowLinkConfig } from '../../../../shared/utils/follow-link-config.model'; +import { FollowLinkConfig } from '../../../../shared/utils/follow-link-config.model'; import { PaginatedList } from '../../../../core/data/paginated-list.model'; import { RemoteData } from '../../../../core/data/remote-data'; import { Collection } from '../../../../core/shared/collection.model'; @@ -40,6 +40,7 @@ import { FieldUpdate } from '../../../../core/data/object-updates/field-update.m import { FieldUpdates } from '../../../../core/data/object-updates/field-updates.model'; import { FieldChangeType } from '../../../../core/data/object-updates/field-change-type.model'; import { APP_CONFIG, AppConfig } from '../../../../../config/app-config.interface'; +import { itemLinksToFollow } from '../../../../shared/utils/relation-query.utils'; @Component({ selector: 'ds-edit-relationship-list', @@ -142,7 +143,7 @@ export class EditRelationshipListComponent implements OnInit, OnDestroy { /** * Determines whether to ask for the embedded item thumbnail. */ - embedThumbnail: boolean; + fetchThumbnail: boolean; constructor( protected objectUpdatesService: ObjectUpdatesService, @@ -154,7 +155,7 @@ export class EditRelationshipListComponent implements OnInit, OnDestroy { protected selectableListService: SelectableListService, @Inject(APP_CONFIG) protected appConfig: AppConfig ) { - this.embedThumbnail = this.appConfig.browseBy.showThumbnails; + this.fetchThumbnail = this.appConfig.browseBy.showThumbnails; } /** @@ -492,15 +493,7 @@ export class EditRelationshipListComponent implements OnInit, OnDestroy { ); // this adds thumbnail images when required by configuration - let linksToFollow: FollowLinkConfig[]; - if (this.embedThumbnail) { - linksToFollow = [ - followLink('leftItem',{}, followLink('thumbnail')), - followLink('rightItem',{}, followLink('thumbnail')), - followLink('relationshipType') ]; - } else { - linksToFollow = [followLink('leftItem'), followLink('rightItem'), followLink('relationshipType')]; - } + let linksToFollow: FollowLinkConfig[] = itemLinksToFollow(this.fetchThumbnail); this.subs.push( observableCombineLatest([ diff --git a/src/app/item-page/simple/related-items/related-items-component.ts b/src/app/item-page/simple/related-items/related-items-component.ts index b58a86d2da..4c76bb3828 100644 --- a/src/app/item-page/simple/related-items/related-items-component.ts +++ b/src/app/item-page/simple/related-items/related-items-component.ts @@ -59,14 +59,14 @@ export class RelatedItemsComponent extends AbstractIncrementalListComponent>> { return this.relationshipService.getRelatedItemsByLabel(this.parentItem, this.relationType, Object.assign(this.options, - { elementsPerPage: this.incrementBy, currentPage: page, embedThumbnail: this.embedThumbnail })); + { elementsPerPage: this.incrementBy, currentPage: page, fetchThumbnail: this.fetchThumbnail })); } } diff --git a/src/app/item-page/simple/related-items/related-items.component.spec.ts b/src/app/item-page/simple/related-items/related-items.component.spec.ts index 89ad1685e5..4307c1aaa2 100644 --- a/src/app/item-page/simple/related-items/related-items.component.spec.ts +++ b/src/app/item-page/simple/related-items/related-items.component.spec.ts @@ -97,7 +97,7 @@ describe('RelatedItemsComponent', () => { expect(relationshipService.getRelatedItemsByLabel).toHaveBeenCalledWith(parentItem, relationType, Object.assign(comp.options, { elementsPerPage: comp.incrementBy, currentPage: 2, - embedThumbnail: true + fetchThumbnail: true })); }); @@ -151,7 +151,7 @@ describe('RelatedItemsComponent', () => { expect(relationshipService.getRelatedItemsByLabel).toHaveBeenCalledWith(parentItem, relationType, Object.assign(comp.options, { elementsPerPage: comp.incrementBy, currentPage: 2, - embedThumbnail: false + fetchThumbnail: false })); }); }); diff --git a/src/app/shared/utils/relation-query.utils.ts b/src/app/shared/utils/relation-query.utils.ts index 13248c5a6b..62a69075fc 100644 --- a/src/app/shared/utils/relation-query.utils.ts +++ b/src/app/shared/utils/relation-query.utils.ts @@ -1,3 +1,6 @@ +import { followLink, FollowLinkConfig } from './follow-link-config.model'; +import { Relationship } from '../../core/shared/item-relationships/relationship.model'; + /** * Get the query for looking up items by relation type * @param {string} relationType Relation type @@ -16,3 +19,21 @@ export function getQueryByRelations(relationType: string, itemUUID: string): str export function getFilterByRelation(relationType: string, itemUUID: string): string { return `f.${relationType}=${itemUUID},equals`; } + +/** + * Creates links to follow for the leftItem and rightItem. Links will include + * @param showThumbnail thumbnail image configuration + * @returns followLink array + */ +export function itemLinksToFollow(showThumbnail: boolean): FollowLinkConfig[] { + let linksToFollow: FollowLinkConfig[]; + if (showThumbnail) { + linksToFollow = [ + followLink('leftItem',{}, followLink('thumbnail')), + followLink('rightItem',{}, followLink('thumbnail')) + ]; + } else { + linksToFollow = [followLink('leftItem'), followLink('rightItem')]; + } + return linksToFollow; +}