Skip to content

Commit 3834d17

Browse files
authored
Merge pull request DSpace#1780 from mspalti/collection-thumbnail-embed
Show thumbnails in result lists
2 parents 37ac449 + a269817 commit 3834d17

102 files changed

Lines changed: 1632 additions & 254 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

config/config.example.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ browseBy:
174174
fiveYearLimit: 30
175175
# The absolute lowest year to display in the dropdown (only used when no lowest date can be found for all items)
176176
defaultLowerLimit: 1900
177+
# If true, thumbnail images for items will be added to BOTH search and browse result lists.
178+
showThumbnails: true
177179
# The number of entries in a paginated browse results list.
178180
# Rounded to the nearest size in the list of selectable sizes on the
179181
# settings menu.

src/app/admin/admin-search-page/admin-search-results/admin-search-result-list-element/collection-search-result/collection-admin-search-result-list-element.component.spec.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import { RouterTestingModule } from '@angular/router/testing';
1313
import { getCollectionEditRoute } from '../../../../../collection-page/collection-page-routing-paths';
1414
import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service';
1515
import { DSONameServiceMock } from '../../../../../shared/mocks/dso-name.service.mock';
16+
import { APP_CONFIG } from '../../../../../../config/app-config.interface';
17+
import { environment } from '../../../../../../environments/environment';
1618

1719
describe('CollectionAdminSearchResultListElementComponent', () => {
1820
let component: CollectionAdminSearchResultListElementComponent;
@@ -36,7 +38,8 @@ describe('CollectionAdminSearchResultListElementComponent', () => {
3638
],
3739
declarations: [CollectionAdminSearchResultListElementComponent],
3840
providers: [{ provide: TruncatableService, useValue: {} },
39-
{ provide: DSONameService, useClass: DSONameServiceMock }],
41+
{ provide: DSONameService, useClass: DSONameServiceMock },
42+
{ provide: APP_CONFIG, useValue: environment }],
4043
schemas: [NO_ERRORS_SCHEMA]
4144
})
4245
.compileComponents();

src/app/admin/admin-search-page/admin-search-results/admin-search-result-list-element/community-search-result/community-admin-search-result-list-element.component.spec.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import { Community } from '../../../../../core/shared/community.model';
1313
import { getCommunityEditRoute } from '../../../../../community-page/community-page-routing-paths';
1414
import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service';
1515
import { DSONameServiceMock } from '../../../../../shared/mocks/dso-name.service.mock';
16+
import { APP_CONFIG } from '../../../../../../config/app-config.interface';
17+
import { environment } from '../../../../../../environments/environment';
1618

1719
describe('CommunityAdminSearchResultListElementComponent', () => {
1820
let component: CommunityAdminSearchResultListElementComponent;
@@ -36,7 +38,8 @@ describe('CommunityAdminSearchResultListElementComponent', () => {
3638
],
3739
declarations: [CommunityAdminSearchResultListElementComponent],
3840
providers: [{ provide: TruncatableService, useValue: {} },
39-
{ provide: DSONameService, useClass: DSONameServiceMock }],
41+
{ provide: DSONameService, useClass: DSONameServiceMock },
42+
{ provide: APP_CONFIG, useValue: environment }],
4043
schemas: [NO_ERRORS_SCHEMA]
4144
})
4245
.compileComponents();

src/app/admin/admin-search-page/admin-search-results/admin-search-result-list-element/item-search-result/item-admin-search-result-list-element.component.spec.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { ItemAdminSearchResultListElementComponent } from './item-admin-search-r
1010
import { Item } from '../../../../../core/shared/item.model';
1111
import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service';
1212
import { DSONameServiceMock } from '../../../../../shared/mocks/dso-name.service.mock';
13+
import { APP_CONFIG } from '../../../../../../config/app-config.interface';
14+
import { environment } from '../../../../../../environments/environment';
1315

1416
describe('ItemAdminSearchResultListElementComponent', () => {
1517
let component: ItemAdminSearchResultListElementComponent;
@@ -33,7 +35,8 @@ describe('ItemAdminSearchResultListElementComponent', () => {
3335
],
3436
declarations: [ItemAdminSearchResultListElementComponent],
3537
providers: [{ provide: TruncatableService, useValue: {} },
36-
{ provide: DSONameService, useClass: DSONameServiceMock }],
38+
{ provide: DSONameService, useClass: DSONameServiceMock },
39+
{ provide: APP_CONFIG, useValue: environment }],
3740
schemas: [NO_ERRORS_SCHEMA]
3841
})
3942
.compileComponents();

src/app/admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/workflow-item/workflow-item-search-result-admin-workflow-list-element.component.spec.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import { createSuccessfulRemoteDataObject$ } from '../../../../../shared/remote-
1818
import { getMockLinkService } from '../../../../../shared/mocks/link-service.mock';
1919
import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service';
2020
import { DSONameServiceMock } from '../../../../../shared/mocks/dso-name.service.mock';
21+
import { APP_CONFIG } from '../../../../../../config/app-config.interface';
22+
import { environment } from '../../../../../../environments/environment';
2123

2224
describe('WorkflowItemAdminWorkflowListElementComponent', () => {
2325
let component: WorkflowItemSearchResultAdminWorkflowListElementComponent;
@@ -51,7 +53,8 @@ describe('WorkflowItemAdminWorkflowListElementComponent', () => {
5153
providers: [
5254
{ provide: TruncatableService, useValue: mockTruncatableService },
5355
{ provide: LinkService, useValue: linkService },
54-
{ provide: DSONameService, useClass: DSONameServiceMock }
56+
{ provide: DSONameService, useClass: DSONameServiceMock },
57+
{ provide: APP_CONFIG, useValue: environment }
5558
],
5659
schemas: [NO_ERRORS_SCHEMA]
5760
})

src/app/admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/workflow-item/workflow-item-search-result-admin-workflow-list-element.component.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, OnInit } from '@angular/core';
1+
import { Component, Inject, OnInit } from '@angular/core';
22
import { ViewMode } from '../../../../../core/shared/view-mode.model';
33
import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
44
import { Context } from '../../../../../core/shared/context.model';
@@ -13,6 +13,7 @@ import { SearchResultListElementComponent } from '../../../../../shared/object-l
1313
import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service';
1414
import { WorkflowItemSearchResult } from '../../../../../shared/object-collection/shared/workflow-item-search-result.model';
1515
import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service';
16+
import { APP_CONFIG, AppConfig } from '../../../../../../config/app-config.interface';
1617

1718
@listableObjectComponent(WorkflowItemSearchResult, ViewMode.ListElement, Context.AdminWorkflowSearch)
1819
@Component({
@@ -32,9 +33,10 @@ export class WorkflowItemSearchResultAdminWorkflowListElementComponent extends S
3233

3334
constructor(private linkService: LinkService,
3435
protected truncatableService: TruncatableService,
35-
protected dsoNameService: DSONameService
36+
protected dsoNameService: DSONameService,
37+
@Inject(APP_CONFIG) protected appConfig: AppConfig
3638
) {
37-
super(truncatableService, dsoNameService);
39+
super(truncatableService, dsoNameService, appConfig);
3840
}
3941

4042
/**

src/app/browse-by/browse-by-date-page/browse-by-date-page.component.spec.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,10 @@ import { BrowseEntrySearchOptions } from '../../core/browse/browse-entry-search-
1818
import { toRemoteData } from '../browse-by-metadata-page/browse-by-metadata-page.component.spec';
1919
import { VarDirective } from '../../shared/utils/var.directive';
2020
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
21-
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
22-
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
2321
import { PaginationService } from '../../core/pagination/pagination.service';
2422
import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub';
25-
import { FindListOptions } from '../../core/data/find-list-options.model';
26-
import { APP_CONFIG } from 'src/config/app-config.interface';
27-
import { environment } from 'src/environments/environment';
23+
import { APP_CONFIG } from '../../../config/app-config.interface';
24+
import { environment } from '../../../environments/environment';
2825

2926
describe('BrowseByDatePageComponent', () => {
3027
let comp: BrowseByDatePageComponent;

src/app/browse-by/browse-by-date-page/browse-by-date-page.component.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import { ChangeDetectorRef, Component, Inject } from '@angular/core';
22
import {
33
BrowseByMetadataPageComponent,
4-
browseParamsToOptions
4+
browseParamsToOptions, getBrowseSearchOptions
55
} from '../browse-by-metadata-page/browse-by-metadata-page.component';
6-
import { BrowseEntrySearchOptions } from '../../core/browse/browse-entry-search-options.model';
76
import { combineLatest as observableCombineLatest } from 'rxjs';
87
import { RemoteData } from '../../core/data/remote-data';
98
import { Item } from '../../core/shared/item.model';
@@ -13,7 +12,6 @@ import { BrowseService } from '../../core/browse/browse.service';
1312
import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service';
1413
import { StartsWithType } from '../../shared/starts-with/starts-with-decorator';
1514
import { BrowseByDataType, rendersBrowseBy } from '../browse-by-switcher/browse-by-decorator';
16-
import { environment } from '../../../environments/environment';
1715
import { PaginationService } from '../../core/pagination/pagination.service';
1816
import { map } from 'rxjs/operators';
1917
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
@@ -45,14 +43,15 @@ export class BrowseByDatePageComponent extends BrowseByMetadataPageComponent {
4543
protected router: Router,
4644
protected paginationService: PaginationService,
4745
protected cdRef: ChangeDetectorRef,
48-
@Inject(APP_CONFIG) protected appConfig: AppConfig) {
46+
@Inject(APP_CONFIG) public appConfig: AppConfig) {
4947
super(route, browseService, dsoService, paginationService, router, appConfig);
5048
}
5149

5250
ngOnInit(): void {
5351
const sortConfig = new SortOptions('default', SortDirection.ASC);
5452
this.startsWithType = StartsWithType.date;
55-
this.updatePage(new BrowseEntrySearchOptions(this.defaultBrowseId, this.paginationConfig, sortConfig));
53+
// include the thumbnail configuration in browse search options
54+
this.updatePage(getBrowseSearchOptions(this.defaultBrowseId, this.paginationConfig, sortConfig, this.fetchThumbnails));
5655
this.currentPagination$ = this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig);
5756
this.currentSort$ = this.paginationService.getCurrentSort(this.paginationConfig.id, sortConfig);
5857
this.subs.push(
@@ -65,7 +64,7 @@ export class BrowseByDatePageComponent extends BrowseByMetadataPageComponent {
6564
const metadataKeys = params.browseDefinition ? params.browseDefinition.metadataKeys : this.defaultMetadataKeys;
6665
this.browseId = params.id || this.defaultBrowseId;
6766
this.startsWith = +params.startsWith || params.startsWith;
68-
const searchOptions = browseParamsToOptions(params, currentPage, currentSort, this.browseId);
67+
const searchOptions = browseParamsToOptions(params, currentPage, currentSort, this.browseId, this.fetchThumbnails);
6968
this.updatePageWithItems(searchOptions, this.value, undefined);
7069
this.updateParent(params.scope);
7170
this.updateStartsWithOptions(this.browseId, metadataKeys, params.scope);
@@ -85,7 +84,7 @@ export class BrowseByDatePageComponent extends BrowseByMetadataPageComponent {
8584
updateStartsWithOptions(definition: string, metadataKeys: string[], scope?: string) {
8685
this.subs.push(
8786
this.browseService.getFirstItemFor(definition, scope).subscribe((firstItemRD: RemoteData<Item>) => {
88-
let lowerLimit = environment.browseBy.defaultLowerLimit;
87+
let lowerLimit = this.appConfig.browseBy.defaultLowerLimit;
8988
if (hasValue(firstItemRD.payload)) {
9089
const date = firstItemRD.payload.firstMetadataValue(metadataKeys);
9190
if (isNotEmpty(date) && isValidDate(date)) {
@@ -96,8 +95,8 @@ export class BrowseByDatePageComponent extends BrowseByMetadataPageComponent {
9695
}
9796
const options = [];
9897
const currentYear = new Date().getUTCFullYear();
99-
const oneYearBreak = Math.floor((currentYear - environment.browseBy.oneYearLimit) / 5) * 5;
100-
const fiveYearBreak = Math.floor((currentYear - environment.browseBy.fiveYearLimit) / 10) * 10;
98+
const oneYearBreak = Math.floor((currentYear - this.appConfig.browseBy.oneYearLimit) / 5) * 5;
99+
const fiveYearBreak = Math.floor((currentYear - this.appConfig.browseBy.fiveYearLimit) / 10) * 10;
101100
if (lowerLimit <= fiveYearBreak) {
102101
lowerLimit -= 10;
103102
} else if (lowerLimit <= oneYearBreak) {

src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.spec.ts

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { BrowseByMetadataPageComponent, browseParamsToOptions } from './browse-by-metadata-page.component';
1+
import {
2+
BrowseByMetadataPageComponent,
3+
browseParamsToOptions,
4+
getBrowseSearchOptions
5+
} from './browse-by-metadata-page.component';
26
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
37
import { BrowseService } from '../../core/browse/browse.service';
48
import { CommonModule } from '@angular/common';
@@ -14,7 +18,7 @@ import { RemoteData } from '../../core/data/remote-data';
1418
import { buildPaginatedList, PaginatedList } from '../../core/data/paginated-list.model';
1519
import { PageInfo } from '../../core/shared/page-info.model';
1620
import { BrowseEntrySearchOptions } from '../../core/browse/browse-entry-search-options.model';
17-
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
21+
import { SortDirection } from '../../core/cache/models/sort-options.model';
1822
import { Item } from '../../core/shared/item.model';
1923
import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service';
2024
import { Community } from '../../core/shared/community.model';
@@ -26,7 +30,6 @@ import { PaginationService } from '../../core/pagination/pagination.service';
2630
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
2731
import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub';
2832
import { APP_CONFIG } from '../../../config/app-config.interface';
29-
import { environment } from '../../../environments/environment';
3033

3134
describe('BrowseByMetadataPageComponent', () => {
3235
let comp: BrowseByMetadataPageComponent;
@@ -45,6 +48,13 @@ describe('BrowseByMetadataPageComponent', () => {
4548
]
4649
});
4750

51+
const environmentMock = {
52+
browseBy: {
53+
showThumbnails: true,
54+
pageSize: 10
55+
}
56+
};
57+
4858
const mockEntries = [
4959
{
5060
type: BrowseEntry.type,
@@ -100,7 +110,7 @@ describe('BrowseByMetadataPageComponent', () => {
100110
{ provide: DSpaceObjectDataService, useValue: mockDsoService },
101111
{ provide: PaginationService, useValue: paginationService },
102112
{ provide: Router, useValue: new RouterMock() },
103-
{ provide: APP_CONFIG, useValue: environment }
113+
{ provide: APP_CONFIG, useValue: environmentMock }
104114
],
105115
schemas: [NO_ERRORS_SCHEMA]
106116
}).compileComponents();
@@ -121,6 +131,10 @@ describe('BrowseByMetadataPageComponent', () => {
121131
expect(comp.items$).toBeUndefined();
122132
});
123133

134+
it('should set embed thumbnail property to true', () => {
135+
expect(comp.fetchThumbnails).toBeTrue();
136+
});
137+
124138
describe('when a value is provided', () => {
125139
beforeEach(() => {
126140
const paramsWithValue = {
@@ -148,14 +162,14 @@ describe('BrowseByMetadataPageComponent', () => {
148162
};
149163
const paginationOptions = Object.assign(new PaginationComponentOptions(), {
150164
currentPage: 5,
151-
pageSize: 10,
165+
pageSize: comp.appConfig.browseBy.pageSize,
152166
});
153167
const sortOptions = {
154168
direction: SortDirection.ASC,
155169
field: 'fake-field',
156170
};
157171

158-
result = browseParamsToOptions(paramsScope, paginationOptions, sortOptions, 'author');
172+
result = browseParamsToOptions(paramsScope, paginationOptions, sortOptions, 'author', comp.fetchThumbnails);
159173
});
160174

161175
it('should return BrowseEntrySearchOptions with the correct properties', () => {
@@ -166,6 +180,36 @@ describe('BrowseByMetadataPageComponent', () => {
166180
expect(result.sort.direction).toEqual(SortDirection.ASC);
167181
expect(result.sort.field).toEqual('fake-field');
168182
expect(result.scope).toEqual('fake-scope');
183+
expect(result.fetchThumbnail).toBeTrue();
184+
});
185+
});
186+
187+
describe('calling getBrowseSearchOptions', () => {
188+
let result: BrowseEntrySearchOptions;
189+
190+
beforeEach(() => {
191+
const paramsScope = {
192+
scope: 'fake-scope'
193+
};
194+
const paginationOptions = Object.assign(new PaginationComponentOptions(), {
195+
currentPage: 5,
196+
pageSize: comp.appConfig.browseBy.pageSize,
197+
});
198+
const sortOptions = {
199+
direction: SortDirection.ASC,
200+
field: 'fake-field',
201+
};
202+
203+
result = getBrowseSearchOptions('title', paginationOptions, sortOptions, comp.fetchThumbnails);
204+
});
205+
it('should return BrowseEntrySearchOptions with the correct properties', () => {
206+
207+
expect(result.metadataDefinition).toEqual('title');
208+
expect(result.pagination.currentPage).toEqual(5);
209+
expect(result.pagination.pageSize).toEqual(10);
210+
expect(result.sort.direction).toEqual(SortDirection.ASC);
211+
expect(result.sort.field).toEqual('fake-field');
212+
expect(result.fetchThumbnail).toBeTrue();
169213
});
170214
});
171215
});

0 commit comments

Comments
 (0)