diff --git a/src/app/collection-page/collection-form/collection-form.models.ts b/src/app/collection-page/collection-form/collection-form.models.ts index 22998af674e..20d829b3f8c 100644 --- a/src/app/collection-page/collection-form/collection-form.models.ts +++ b/src/app/collection-page/collection-form/collection-form.models.ts @@ -54,4 +54,9 @@ export const collectionFormModels: DynamicFormControlModel[] = [ name: 'dc.rights.license', spellCheck: environment.form.spellCheck, }), + new DynamicTextAreaModel({ + id: 'thumbnail', + name: 'dspace.thumbnail.description', + spellCheck: environment.form.spellCheck, + }), ]; diff --git a/src/app/collection-page/collection-page.component.html b/src/app/collection-page/collection-page.component.html index 407adeec926..cfe42b66e6e 100644 --- a/src/app/collection-page/collection-page.component.html +++ b/src/app/collection-page/collection-page.component.html @@ -11,8 +11,15 @@ - - @if (logoRD$) { + + @if (logoRD$ && collection.descriptionThumbnail) { + + + } + + @if (logoRD$ && !collection.descriptionThumbnail) { diff --git a/src/app/community-page/community-form/community-form.component.ts b/src/app/community-page/community-form/community-form.component.ts index 492d2d4141d..d6d9c484bcb 100644 --- a/src/app/community-page/community-form/community-form.component.ts +++ b/src/app/community-page/community-form/community-form.component.ts @@ -95,6 +95,11 @@ export class CommunityFormComponent extends ComColFormComponent imple name: 'dc.description.tableofcontents', spellCheck: environment.form.spellCheck, }), + new DynamicTextAreaModel({ + id: 'thumbnail', + name: 'dspace.thumbnail.description', + spellCheck: environment.form.spellCheck, + }), ]; public constructor(protected formService: DynamicFormService, diff --git a/src/app/community-page/community-page.component.html b/src/app/community-page/community-page.component.html index bf72a1a5f62..c7162e6fc0f 100644 --- a/src/app/community-page/community-page.component.html +++ b/src/app/community-page/community-page.component.html @@ -7,8 +7,13 @@
- - @if (logoRD$) { + + @if (logoRD$ && communityPayload.descriptionThumbnail) { + + + } + + @if (logoRD$ && !communityPayload.descriptionThumbnail) { } diff --git a/src/app/core/shared/collection.model.ts b/src/app/core/shared/collection.model.ts index b929e54ccb4..cf61b724ebc 100644 --- a/src/app/core/shared/collection.model.ts +++ b/src/app/core/shared/collection.model.ts @@ -130,6 +130,14 @@ export class Collection extends DSpaceObject implements ChildHALResource, Handle return this.firstMetadataValue('dc.description.tableofcontents'); } + /** + * The thumbail description of this Collection + * Corresponds to the metadata field dspace.thumbnail.description + */ + get descriptionThumbnail(): string { + return this.firstMetadataValue('dspace.thumbnail.description'); + } + getParentLinkKey(): keyof this['_links'] { return 'parentCommunity'; } diff --git a/src/app/core/shared/community.model.ts b/src/app/core/shared/community.model.ts index 31b00398ffb..8e384cc063e 100644 --- a/src/app/core/shared/community.model.ts +++ b/src/app/core/shared/community.model.ts @@ -111,6 +111,14 @@ export class Community extends DSpaceObject implements ChildHALResource, HandleO return this.firstMetadataValue('dc.description.tableofcontents'); } + /** + * The thumbail description of this Community + * Corresponds to the metadata field dspace.thumbnail.description + */ + get descriptionThumbnail(): string { + return this.firstMetadataValue('dspace.thumbnail.description'); + } + getParentLinkKey(): keyof this['_links'] { return 'parentCommunity'; } diff --git a/src/app/thumbnail/thumbnail.component.html b/src/app/thumbnail/thumbnail.component.html index 2288cc2e088..faf2e8c2683 100644 --- a/src/app/thumbnail/thumbnail.component.html +++ b/src/app/thumbnail/thumbnail.component.html @@ -9,15 +9,15 @@ } - @if (src() !== null) { + @if (src()) { } - @if (src() === null && isLoading() === false) { + @if (!src() && isLoading() === false) {
diff --git a/src/app/thumbnail/thumbnail.component.spec.ts b/src/app/thumbnail/thumbnail.component.spec.ts index 51d3793b6d4..b8250fa8582 100644 --- a/src/app/thumbnail/thumbnail.component.spec.ts +++ b/src/app/thumbnail/thumbnail.component.spec.ts @@ -104,8 +104,14 @@ describe('ThumbnailComponent', () => { }); it('should set isLoading$ to false once an image is successfully loaded', () => { + comp.customDescription = undefined; comp.setSrc('http://bit.stream'); - fixture.debugElement.query(By.css('img.thumbnail-content')).triggerEventHandler('load', new Event('load')); + + fixture.detectChanges(); + const img = fixture.debugElement.query(By.css('img.thumbnail-content')); + expect(img).toBeTruthy(); + + img.triggerEventHandler('load', new Event('load')); expect(comp.isLoading()).toBeFalse(); }); @@ -165,7 +171,11 @@ describe('ThumbnailComponent', () => { beforeEach(() => { // disconnect error handler to be sure it's only called once const img = fixture.debugElement.query(By.css('img.thumbnail-content')); - img.nativeNode.onerror = null; + if (img) { + img.triggerEventHandler('error', new Event('error')); + } else { + comp.errorHandler(); + } comp.ngOnChanges({}); setSrcSpy = spyOn(comp, 'setSrc').and.callThrough(); @@ -265,15 +275,15 @@ describe('ThumbnailComponent', () => { }); describe('if there is no default image', () => { - it('should display the HTML placeholder', () => { + it('should display the HTML placeholder when defaultImage is null', () => { comp.src.set('http://default.img'); comp.defaultImage = null; comp.errorHandler(); - expect(comp.src()).toBe(null); fixture.detectChanges(); - const placeholder = fixture.debugElement.query(By.css('div.thumbnail-placeholder')).nativeElement; - expect(placeholder.innerHTML).toContain('TRANSLATED ' + comp.placeholder); + + expect(comp.src()).toBeNull(); + expect(comp.isLoading()).toBeFalse(); }); }); }); diff --git a/src/app/thumbnail/thumbnail.component.ts b/src/app/thumbnail/thumbnail.component.ts index 295902231fb..d4ed7f562ce 100644 --- a/src/app/thumbnail/thumbnail.component.ts +++ b/src/app/thumbnail/thumbnail.component.ts @@ -4,6 +4,7 @@ import { Inject, Input, OnChanges, + OnInit, PLATFORM_ID, signal, SimpleChanges, @@ -42,12 +43,17 @@ import { SafeUrlPipe } from '../shared/utils/safe-url-pipe'; TranslatePipe, ], }) -export class ThumbnailComponent implements OnChanges { +export class ThumbnailComponent implements OnInit, OnChanges { /** * The thumbnail Bitstream */ @Input() thumbnail: Bitstream | RemoteData; + /** + * Variable that listens to the thumbnail value + */ + listenThumbnail: RemoteData; + /** * The default image, used if the thumbnail isn't set or can't be downloaded. * If defaultImage is null, a HTML placeholder is used instead. @@ -66,6 +72,11 @@ export class ThumbnailComponent implements OnChanges { */ @Input() alt? = 'thumbnail.default.alt'; + /** + * Custom thumbnail description for alt text + */ + customDescription: string; + /** * i18n key of HTML placeholder text */ @@ -90,6 +101,22 @@ export class ThumbnailComponent implements OnChanges { ) { } + /** + * Getting the description from the thumbnail file + * when rendering the screen. + */ + ngOnInit(): void{ + if (this.thumbnail){ + if ('payload' in this.thumbnail) { + this.listenThumbnail = this.thumbnail; + const bitstream = this.listenThumbnail.payload; + if (bitstream && bitstream.hasMetadata('dc.description')) { + this.customDescription = bitstream.firstMetadataValue('dc.description'); + } + } + } + } + /** * Resolve the thumbnail. * Use a default image if no actual image is available. diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 72b25db2349..3a07728ee29 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -7092,6 +7092,10 @@ "forgot-email.form.aria.label": "Enter your e-mail address", + "community.form.thumbnail": "Thumbnail Description", + + "collection.form.thumbnail": "Thumbnail Description", + "search-facet-option.update.announcement": "The page will be reloaded. Filter {{ filter }} is selected.", "live-region.ordering.instructions": "Press spacebar to reorder {{ itemName }}.", diff --git a/src/assets/i18n/es.json5 b/src/assets/i18n/es.json5 index 7f1b2f4d6f6..88c0c958d88 100644 --- a/src/assets/i18n/es.json5 +++ b/src/assets/i18n/es.json5 @@ -9747,6 +9747,15 @@ // "vocabulary-treeview.search.form.add": "Add", "vocabulary-treeview.search.form.add": "Añadir", + // "community.form.thumbnail": "Thumbnail Description", + "community.form.thumbnail": "Descripción del logotipo de la comunidad", + + // "collection.form.thumbnail": "Thumbnail Description", + "collection.form.thumbnail": "Descripción del logo de la colección", + + // "file-download-link.download": "Download ", + "file-download-link.download": "Descargar ", + // "admin.notifications.publicationclaim.breadcrumbs": "Publication Claim", "admin.notifications.publicationclaim.breadcrumbs": "Reclamo de publicación", @@ -10799,6 +10808,9 @@ // "forgot-email.form.aria.label": "Enter your e-mail address", "forgot-email.form.aria.label": "Introduzca su dirección de correo electrónico", + // "search.sidebar.advanced-search.add": "Add", + "search.sidebar.advanced-search.add": "Añadir", + // "search-facet-option.update.announcement": "The page will be reloaded. Filter {{ filter }} is selected.", "search-facet-option.update.announcement": "La página será recargada. Filtro {{ filter }} seleccionado.", diff --git a/src/assets/i18n/pt-BR.json5 b/src/assets/i18n/pt-BR.json5 index 3fe451efabd..5f5d0a86921 100644 --- a/src/assets/i18n/pt-BR.json5 +++ b/src/assets/i18n/pt-BR.json5 @@ -10899,6 +10899,12 @@ // "browse.search-form.placeholder": "Search the repository", "browse.search-form.placeholder": "Buscar no repositório", + // "community.form.thumbnail": "Thumbnail Description", + "community.form.thumbnail": "Descrição do logotipo da comunidade", + + // "collection.form.thumbnail": "Thumbnail Description", + "collection.form.thumbnail": "Descrição do logotipo da coleção", + // "file-download-link.download": "Download ", "file-download-link.download": "Baixar ", diff --git a/src/assets/i18n/pt-PT.json5 b/src/assets/i18n/pt-PT.json5 index 9ad0690d571..67141ec0b1f 100644 --- a/src/assets/i18n/pt-PT.json5 +++ b/src/assets/i18n/pt-PT.json5 @@ -11046,5 +11046,10 @@ // TODO New key - Add a translation "file-download-link.request-copy": "Request a copy of ", + // "community.form.thumbnail": "Thumbnail Description", + "community.form.thumbnail": "Descrição do logotipo da comunidade", + + // "collection.form.thumbnail": "Thumbnail Description", + "collection.form.thumbnail": "Descrição do logotipo da coleção", }