diff --git a/src/app/item-page/field-components/metadata-values/metadata-values.component.html b/src/app/item-page/field-components/metadata-values/metadata-values.component.html index 44a3db43cd8..857e82e3fc5 100644 --- a/src/app/item-page/field-components/metadata-values/metadata-values.component.html +++ b/src/app/item-page/field-components/metadata-values/metadata-values.component.html @@ -25,7 +25,7 @@ - + ; + +const mockField = 'organization.identifier.ror'; +const mockValue = 'http://ror.org/awesome-identifier'; +const mockLabel = 'ROR label'; +const mockUrlRegex = '(.*)ror.org'; +const mockImg = { + URI: './assets/images/ror-icon.svg', + alt: 'item.page.image.alt.ROR', + heightVar: '--ds-item-page-img-field-ror-inline-height' +} as ImageField; + +describe('ItemPageImgFieldComponent', () => { + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: TranslateLoaderMock + } + })], + providers: [ + { provide: APP_CONFIG, useValue: environment }, + { provide: BrowseDefinitionDataService, useValue: BrowseDefinitionDataServiceStub } + ], + declarations: [ItemPageImgFieldComponent, GenericItemPageFieldComponent, MetadataValuesComponent], + schemas: [NO_ERRORS_SCHEMA] + }) + .overrideComponent(GenericItemPageFieldComponent, { + set: { changeDetection: ChangeDetectionStrategy.Default } + }) + .compileComponents(); + + fixture = TestBed.createComponent(ItemPageImgFieldComponent); + component = fixture.componentInstance; + component.item = mockItemWithMetadataFieldsAndValue([mockField], mockValue); + component.fields = [mockField]; + component.label = mockLabel; + component.urlRegex = mockUrlRegex; + component.img = mockImg; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should display display img tag', () => { + const image = fixture.debugElement.query(By.css('img.link-logo')); + expect(image).not.toBeNull(); + }); + + it('should have right attributes', () => { + const image = fixture.debugElement.query(By.css('img.link-logo')); + expect(image.attributes.src).toEqual(mockImg.URI); + expect(image.attributes.alt).toEqual(mockImg.alt); + + const imageEl = image.nativeElement; + expect(imageEl.style.height).toContain(mockImg.heightVar); + }); + + it('should have the right value', () => { + const imageAnchor = fixture.debugElement.query(By.css('a.link-anchor')); + const anchorEl = imageAnchor.nativeElement; + expect(anchorEl.innerHTML).toContain(mockValue); + }); +}); diff --git a/src/app/item-page/simple/field-components/specific-field/img/item-page-img-field.component.ts b/src/app/item-page/simple/field-components/specific-field/img/item-page-img-field.component.ts new file mode 100644 index 00000000000..2d24120aeeb --- /dev/null +++ b/src/app/item-page/simple/field-components/specific-field/img/item-page-img-field.component.ts @@ -0,0 +1,64 @@ +import { Component, Input } from '@angular/core'; +import { ItemPageFieldComponent } from '../item-page-field.component'; +import { Item } from '../../../../../core/shared/item.model'; + +/** + * Interface that encapsulate Image configuration for this component. + */ +export interface ImageField { + /** + * URI that is used to retrieve the image. + */ + URI: string; + /** + * i18n Key that represents the alt text to display + */ + alt: string; + /** + * CSS variable that contains the height of the inline image. + */ + heightVar: string; +} + +@Component({ + selector: 'ds-item-page-img-field', + templateUrl: '../item-page-field.component.html' +}) +/** + * Component that renders an inline image for a given field. + * This component uses a given {@code ImageField} configuration to correctly render the img. + */ +export class ItemPageImgFieldComponent extends ItemPageFieldComponent { + + /** + * The item to display metadata for + */ + @Input() item: Item; + + /** + * Separator string between multiple values of the metadata fields defined + * @type {string} + */ + @Input() separator: string; + + /** + * Fields (schema.element.qualifier) used to render their values. + */ + @Input() fields: string[]; + + /** + * Label i18n key for the rendered metadata + */ + @Input() label: string; + + /** + * Image Configuration + */ + @Input() img: ImageField; + + /** + * Whether any valid HTTP(S) URL should be rendered as a link + */ + @Input() urlRegex?: string; + +} diff --git a/src/app/item-page/simple/field-components/specific-field/item-page-field.component.html b/src/app/item-page/simple/field-components/specific-field/item-page-field.component.html index 91d40b0ad70..f45d4657a46 100644 --- a/src/app/item-page/simple/field-components/specific-field/item-page-field.component.html +++ b/src/app/item-page/simple/field-components/specific-field/item-page-field.component.html @@ -6,5 +6,6 @@ [enableMarkdown]="enableMarkdown" [urlRegex]="urlRegex" [browseDefinition]="browseDefinition|async" + [img]="img" > diff --git a/src/app/item-page/simple/field-components/specific-field/item-page-field.component.ts b/src/app/item-page/simple/field-components/specific-field/item-page-field.component.ts index fc526dabcc5..dca269164a7 100644 --- a/src/app/item-page/simple/field-components/specific-field/item-page-field.component.ts +++ b/src/app/item-page/simple/field-components/specific-field/item-page-field.component.ts @@ -5,6 +5,7 @@ import { Observable } from 'rxjs'; import { BrowseDefinition } from '../../../../core/shared/browse-definition.model'; import { BrowseDefinitionDataService } from '../../../../core/browse/browse-definition-data.service'; import { getRemoteDataPayload } from '../../../../core/shared/operators'; +import { ImageField } from './img/item-page-img-field.component'; /** * This component can be used to represent metadata on a simple item page. @@ -51,6 +52,11 @@ export class ItemPageFieldComponent { */ urlRegex?: string; + /** + * Image Configuration + */ + img: ImageField; + /** * Return browse definition that matches any field used in this component if it is configured as a browse * link in dspace.cfg (webui.browse.link.) diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index e6ecdac911b..9d2a6905fe5 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -2564,19 +2564,19 @@ "item.preview.oaire.fundingStream": "Funding Stream:", - "item.preview.oairecerif.identifier.url" : "URL", + "item.preview.oairecerif.identifier.url": "URL", - "item.preview.organization.address.addressCountry" : "Country", + "item.preview.organization.address.addressCountry": "Country", - "item.preview.organization.foundingDate" : "Founding Date", + "item.preview.organization.foundingDate": "Founding Date", - "item.preview.organization.identifier.crossrefid" : "CrossRef ID", + "item.preview.organization.identifier.crossrefid": "CrossRef ID", - "item.preview.organization.identifier.isni" : "ISNI", + "item.preview.organization.identifier.isni": "ISNI", - "item.preview.organization.identifier.ror" : "ROR ID", + "item.preview.organization.identifier.ror": "ROR ID", - "item.preview.organization.legalName" : "Legal Name", + "item.preview.organization.legalName": "Legal Name", "item.select.confirm": "Confirm selected",