diff --git a/config/config.example.yml b/config/config.example.yml index abf74eb19c4..0a530b8752c 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -285,3 +285,13 @@ mediaViewer: info: enableEndUserAgreement: true enablePrivacyStatement: true + +# MyDSpace Config +myDSpace: + # Add additional metadata fields to display at the end of the item component. By default, this is an empty list. + additionalMetadataFields: [] + # Replace the empty list by some values here. + # additionalMetadataFields: + # - metadata.1 + # - metadata.2 + # - ... diff --git a/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.html b/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.html index c9c2da5c2ee..742ceaa8042 100644 --- a/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.html +++ b/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.html @@ -53,6 +53,11 @@
+
+ + + +
diff --git a/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.spec.ts b/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.spec.ts index 0b5acd343bd..c872ac49f55 100644 --- a/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.spec.ts +++ b/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.spec.ts @@ -32,6 +32,8 @@ import { ItemDetailPreviewFieldComponent } from './item-detail-preview-field/ite import { ItemDetailPreviewComponent } from './item-detail-preview.component'; import { createPaginatedList } from '../../../testing/utils.test'; import { FindListOptions } from '../../../../core/data/find-list-options.model'; +import { environment } from 'src/environments/environment'; +import { By } from '@angular/platform-browser'; function getMockFileService(): FileService { return jasmine.createSpyObj('FileService', { @@ -69,6 +71,12 @@ const mockItem: Item = Object.assign(new Item(), { language: null, value: 'Article' } + ], + 'dc.description.additional': [ + { + language: null, + value: 'This is an additional description metadata.' + } ] } }); @@ -122,14 +130,62 @@ describe('ItemDetailPreviewComponent', () => { component.item = mockItem; component.separator = ', '; // spyOn(component.item, 'getFiles').and.returnValue(mockItem.bundles as any); - fixture.detectChanges(); - })); - it('should get item bitstreams', (done) => { - component.getFiles().subscribe((bitstreams) => { - expect(bitstreams).toBeDefined(); - done(); + afterEach(() => { + environment.myDSpace.additionalMetadataFields = []; + }); + + describe('When the component is initialized', () => { + beforeEach(() => { + fixture.detectChanges(); + }); + + it('should get item bitstreams', (done) => { + component.getFiles().subscribe((bitstreams) => { + expect(bitstreams).toBeDefined(); + done(); + }); + }); + }); + + describe('When the config has no additional metadata', () => { + beforeEach(() => { + fixture.detectChanges(); + }); + + it('should not show the additional section', () => { + const additionalSection = fixture.debugElement.query(By.css('div.item-list-additional')); + expect(additionalSection).toBeNull(); + }); + }); + + describe('When the config has one additional metadata with no match', () => { + beforeEach(() => { + environment.myDSpace.additionalMetadataFields = ['fake']; + fixture.detectChanges(); + }); + + it('should show the additional section', () => { + const additionalSection = fixture.debugElement.query(By.css('div.item-list-additional')); + expect(additionalSection).not.toBeNull(); + }); + + it('should not show the additional metadata span', () => { + const additionalSpan = fixture.debugElement.query(By.css('span.item-additional')); + expect(additionalSpan).toBeNull(); + }); + }); + + describe('When the config has one additional metadata with a match', () => { + beforeEach(() => { + environment.myDSpace.additionalMetadataFields = ['dc.description.additional']; + fixture.detectChanges(); + }); + + it('should show the additional metadata span', () => { + const additionalSpan = fixture.debugElement.query(By.css('span.item-additional')); + expect(additionalSpan).not.toBeNull(); }); }); }); diff --git a/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.ts b/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.ts index 778e4550045..cd14640ceb2 100644 --- a/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.ts +++ b/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.ts @@ -12,6 +12,8 @@ import { Bitstream } from '../../../../core/shared/bitstream.model'; import { FileService } from '../../../../core/shared/file.service'; import { HALEndpointService } from '../../../../core/shared/hal-endpoint.service'; import { SearchResult } from '../../../search/models/search-result.model'; +import { environment } from 'src/environments/environment'; +import { hasValue, isNotEmpty } from 'src/app/shared/empty.util'; /** * This component show metadata for the given item object in the detail view. @@ -44,6 +46,11 @@ export class ItemDetailPreviewComponent { */ @Input() showSubmitter = false; + /** + * A list of additional metadata fields to display + */ + public additionalMetadataFields: string[]; + /** * The item's thumbnail */ @@ -66,6 +73,12 @@ export class ItemDetailPreviewComponent { private bitstreamDataService: BitstreamDataService) { } + ngOnInit() { + if (hasValue(environment.myDSpace) && isNotEmpty(environment.myDSpace.additionalMetadataFields)) { + this.additionalMetadataFields = environment.myDSpace.additionalMetadataFields; + } + } + /** * Perform bitstream download */ diff --git a/src/app/shared/object-list/my-dspace-result-list-element/item-list-preview/item-list-preview.component.html b/src/app/shared/object-list/my-dspace-result-list-element/item-list-preview/item-list-preview.component.html index d2db0ba2099..c0e41b84b5f 100644 --- a/src/app/shared/object-list/my-dspace-result-list-element/item-list-preview/item-list-preview.component.html +++ b/src/app/shared/object-list/my-dspace-result-list-element/item-list-preview/item-list-preview.component.html @@ -31,15 +31,18 @@

; - - + - +
+ + + +
diff --git a/src/app/shared/object-list/my-dspace-result-list-element/item-list-preview/item-list-preview.component.spec.ts b/src/app/shared/object-list/my-dspace-result-list-element/item-list-preview/item-list-preview.component.spec.ts index aaddebd8eba..0528c3f0e2b 100644 --- a/src/app/shared/object-list/my-dspace-result-list-element/item-list-preview/item-list-preview.component.spec.ts +++ b/src/app/shared/object-list/my-dspace-result-list-element/item-list-preview/item-list-preview.component.spec.ts @@ -11,6 +11,7 @@ import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { TranslateLoaderMock } from '../../../mocks/translate-loader.mock'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { APP_CONFIG } from '../../../../../config/app-config.interface'; +import { environment } from 'src/environments/environment'; let component: ItemListPreviewComponent; let fixture: ComponentFixture; @@ -66,6 +67,23 @@ const mockItemWithEntityType: Item = Object.assign(new Item(), { ] } }); +const mockItemWithAdditionalMeta: Item = Object.assign(new Item(), { + bundles: observableOf({}), + metadata: { + 'dc.title': [ + { + language: 'en_US', + value: 'This is just another title' + } + ], + 'dspace.description.additional': [ + { + language: null, + value: 'This is an additional description metadata.' + } + ] + } +}); const environmentUseThumbs = { browseBy: { @@ -113,6 +131,10 @@ describe('ItemListPreviewComponent', () => { component.object = { hitHighlights: {} } as any; }); + afterEach(() => { + environment.myDSpace.additionalMetadataFields = []; + }); + describe('When showThumbnails is true', () => { beforeEach(() => { component.item = mockItemWithAuthorAndDate; @@ -183,6 +205,49 @@ describe('ItemListPreviewComponent', () => { expect(entityField).not.toBeNull(); }); }); + + describe('When the config has no additional metadata', () => { + beforeEach(() => { + component.item = mockItemWithAdditionalMeta; + fixture.detectChanges(); + }); + + it('should not show the additional section', () => { + const additionalSection = fixture.debugElement.query(By.css('div.item-list-additional')); + expect(additionalSection).toBeNull(); + }); + }); + + describe('When the config has one additional metadata with no match', () => { + beforeEach(() => { + environment.myDSpace.additionalMetadataFields = ['fake']; + component.item = mockItemWithAdditionalMeta; + fixture.detectChanges(); + }); + + it('should show the additional section', () => { + const additionalSection = fixture.debugElement.query(By.css('div.item-list-additional')); + expect(additionalSection).not.toBeNull(); + }); + + it('should not show the additional metadata span', () => { + const additionalSpan = fixture.debugElement.query(By.css('span.item-additional')); + expect(additionalSpan).toBeNull(); + }); + }); + + describe('When the config has one additional metadata with a match', () => { + beforeEach(() => { + environment.myDSpace.additionalMetadataFields = ['dspace.description.additional']; + component.item = mockItemWithAdditionalMeta; + fixture.detectChanges(); + }); + + it('should show the additional metadata span', () => { + const additionalSpan = fixture.debugElement.query(By.css('span.item-additional')); + expect(additionalSpan).not.toBeNull(); + }); + }); }); describe('ItemListPreviewComponent', () => { diff --git a/src/app/shared/object-list/my-dspace-result-list-element/item-list-preview/item-list-preview.component.ts b/src/app/shared/object-list/my-dspace-result-list-element/item-list-preview/item-list-preview.component.ts index 04f1e24d7b8..19bbfe49e44 100644 --- a/src/app/shared/object-list/my-dspace-result-list-element/item-list-preview/item-list-preview.component.ts +++ b/src/app/shared/object-list/my-dspace-result-list-element/item-list-preview/item-list-preview.component.ts @@ -1,5 +1,6 @@ import { Component, Inject, Input, OnInit } from '@angular/core'; - +import { hasValue, isNotEmpty } from 'src/app/shared/empty.util'; +import { environment } from 'src/environments/environment'; import { Item } from '../../../../core/shared/item.model'; import { fadeInOut } from '../../../animations/fade'; import { @@ -40,6 +41,11 @@ export class ItemListPreviewComponent implements OnInit { */ @Input() showSubmitter = false; + /** + * A list of additional metadata fields to display + */ + public additionalMetadataFields: string[]; + /** * Display thumbnails if required by configuration */ @@ -56,6 +62,9 @@ export class ItemListPreviewComponent implements OnInit { ngOnInit(): void { this.showThumbnails = this.appConfig.browseBy.showThumbnails; this.dsoTitle = this.dsoNameService.getName(this.item); + if (hasValue(environment.myDSpace) && isNotEmpty(environment.myDSpace.additionalMetadataFields)) { + this.additionalMetadataFields = environment.myDSpace.additionalMetadataFields; + } } diff --git a/src/config/app-config.interface.ts b/src/config/app-config.interface.ts index 6fe55aa3283..68c981d544d 100644 --- a/src/config/app-config.interface.ts +++ b/src/config/app-config.interface.ts @@ -19,6 +19,7 @@ import { ActuatorsConfig } from './actuators.config'; import { InfoConfig } from './info-config.interface'; import { CommunityListConfig } from './community-list-config.interface'; import { HomeConfig } from './homepage-config.interface'; +import { MyDSpaceConfig } from './my-dspace.interface'; interface AppConfig extends Config { ui: UIServerConfig; @@ -42,6 +43,7 @@ interface AppConfig extends Config { bundle: BundleConfig; actuators: ActuatorsConfig info: InfoConfig; + myDSpace: MyDSpaceConfig; } /** diff --git a/src/config/default-app-config.ts b/src/config/default-app-config.ts index c2c0b308e76..68a7028aabe 100644 --- a/src/config/default-app-config.ts +++ b/src/config/default-app-config.ts @@ -9,6 +9,7 @@ import { FormConfig } from './form-config.interfaces'; import { ItemConfig } from './item-config.interface'; import { LangConfig } from './lang-config.interface'; import { MediaViewerConfig } from './media-viewer-config.interface'; +import { MyDSpaceConfig } from './my-dspace.interface'; import { INotificationBoardOptions } from './notifications-config.interfaces'; import { ServerConfig } from './server-config.interface'; import { SubmissionConfig } from './submission-config.interface'; @@ -364,4 +365,8 @@ export class DefaultAppConfig implements AppConfig { enableEndUserAgreement: true, enablePrivacyStatement: true }; + // The default MyDSpace Config + myDSpace: MyDSpaceConfig = { + additionalMetadataFields: [] + }; } diff --git a/src/config/my-dspace.interface.ts b/src/config/my-dspace.interface.ts new file mode 100644 index 00000000000..c6a4d5650bc --- /dev/null +++ b/src/config/my-dspace.interface.ts @@ -0,0 +1,12 @@ +import { Config } from './config.interface'; + +/** + * Config that determines some aspects of the MyDSpace section + */ +export interface MyDSpaceConfig extends Config { + /** + * The list of additional metadata fields to display at the end of the item component + */ + additionalMetadataFields: string[] +} + diff --git a/src/environments/environment.test.ts b/src/environments/environment.test.ts index edbf33b79c7..a51adc8831d 100644 --- a/src/environments/environment.test.ts +++ b/src/environments/environment.test.ts @@ -271,4 +271,7 @@ export const environment: BuildConfig = { enableEndUserAgreement: true, enablePrivacyStatement: true, }, + myDSpace: { + additionalMetadataFields: [] + } };