From 50d36231aa532b2b2f7e60ad7c68a5aa85d1500e Mon Sep 17 00:00:00 2001 From: Agustina Martinez Date: Mon, 13 Mar 2023 16:17:31 +0000 Subject: [PATCH 01/21] Add support to send inheritPolicies flag when moving item collection --- src/app/core/data/item-data.service.ts | 8 ++++---- .../edit-item-page/item-move/item-move.component.spec.ts | 3 ++- .../edit-item-page/item-move/item-move.component.ts | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/app/core/data/item-data.service.ts b/src/app/core/data/item-data.service.ts index 80da91acb3..c3fa84dd6c 100644 --- a/src/app/core/data/item-data.service.ts +++ b/src/app/core/data/item-data.service.ts @@ -246,10 +246,10 @@ export abstract class BaseItemDataService extends IdentifiableDataService * Get the endpoint to move the item * @param itemId */ - public getMoveItemEndpoint(itemId: string): Observable { + public getMoveItemEndpoint(itemId: string, inheritPolicies: boolean): Observable { return this.halService.getEndpoint(this.linkPath).pipe( map((endpoint: string) => this.getIDHref(endpoint, itemId)), - map((endpoint: string) => `${endpoint}/owningCollection`), + map((endpoint: string) => `${endpoint}/owningCollection?inheritPolicies=${inheritPolicies}`) ); } @@ -258,14 +258,14 @@ export abstract class BaseItemDataService extends IdentifiableDataService * @param itemId * @param collection */ - public moveToCollection(itemId: string, collection: Collection): Observable> { + public moveToCollection(itemId: string, collection: Collection, inheritPolicies: boolean): Observable> { const options: HttpOptions = Object.create({}); let headers = new HttpHeaders(); headers = headers.append('Content-Type', 'text/uri-list'); options.headers = headers; const requestId = this.requestService.generateRequestId(); - const hrefObs = this.getMoveItemEndpoint(itemId); + const hrefObs = this.getMoveItemEndpoint(itemId, inheritPolicies); hrefObs.pipe( find((href: string) => hasValue(href)), diff --git a/src/app/item-page/edit-item-page/item-move/item-move.component.spec.ts b/src/app/item-page/edit-item-page/item-move/item-move.component.spec.ts index d200891629..43ac47e37b 100644 --- a/src/app/item-page/edit-item-page/item-move/item-move.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-move/item-move.component.spec.ts @@ -134,9 +134,10 @@ describe('ItemMoveComponent', () => { }); comp.selectedCollectionName = 'selected-collection-id'; comp.selectedCollection = collection1; + comp.inheritPolicies = false; comp.moveToCollection(); - expect(itemDataService.moveToCollection).toHaveBeenCalledWith('item-id', collection1); + expect(itemDataService.moveToCollection).toHaveBeenCalledWith('item-id', collection1, false); }); it('should call notificationsService success message on success', () => { comp.moveToCollection(); diff --git a/src/app/item-page/edit-item-page/item-move/item-move.component.ts b/src/app/item-page/edit-item-page/item-move/item-move.component.ts index b7ab761fe5..4f53fa7df1 100644 --- a/src/app/item-page/edit-item-page/item-move/item-move.component.ts +++ b/src/app/item-page/edit-item-page/item-move/item-move.component.ts @@ -104,7 +104,7 @@ export class ItemMoveComponent implements OnInit { */ moveToCollection() { this.processing = true; - const move$ = this.itemDataService.moveToCollection(this.item.id, this.selectedCollection) + const move$ = this.itemDataService.moveToCollection(this.item.id, this.selectedCollection, this.inheritPolicies) .pipe(getFirstCompletedRemoteData()); move$.subscribe((response: RemoteData) => { From aa4d56e2cf1b3158e56c3a1644f4722e70e838bc Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sun, 19 Mar 2023 11:42:09 +0100 Subject: [PATCH 02/21] Made it possible to only enable video media viewer Also: - Filtered out non-supported media file types from the mediaViewers mediaList - Fixed thumbnails not displaying with 0 ORIGINAL bitstreams --- .../media-viewer-image.component.ts | 17 ++--- .../media-viewer-video.component.html | 13 ++-- .../media-viewer-video.component.spec.ts | 2 - .../media-viewer-video.component.ts | 20 ++---- .../media-viewer/media-viewer.component.html | 36 ++++------ .../media-viewer.component.spec.ts | 12 +++- .../media-viewer/media-viewer.component.ts | 67 ++++++++++++------- .../publication/publication.component.html | 6 +- .../untyped-item/untyped-item.component.html | 6 +- 9 files changed, 89 insertions(+), 90 deletions(-) diff --git a/src/app/item-page/media-viewer/media-viewer-image/media-viewer-image.component.ts b/src/app/item-page/media-viewer/media-viewer-image/media-viewer-image.component.ts index 0c32b5603d..28c5b4efd6 100644 --- a/src/app/item-page/media-viewer/media-viewer-image/media-viewer-image.component.ts +++ b/src/app/item-page/media-viewer/media-viewer-image/media-viewer-image.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, OnInit } from '@angular/core'; +import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; import { NgxGalleryImage, NgxGalleryOptions } from '@kolkov/ngx-gallery'; import { MediaViewerItem } from '../../../core/shared/media-viewer-item.model'; import { NgxGalleryAnimation } from '@kolkov/ngx-gallery'; @@ -13,7 +13,7 @@ import { AuthService } from '../../../core/auth/auth.service'; templateUrl: './media-viewer-image.component.html', styleUrls: ['./media-viewer-image.component.scss'], }) -export class MediaViewerImageComponent implements OnInit { +export class MediaViewerImageComponent implements OnChanges, OnInit { @Input() images: MediaViewerItem[]; @Input() preview?: boolean; @Input() image?: string; @@ -30,11 +30,9 @@ export class MediaViewerImageComponent implements OnInit { constructor(private authService: AuthService) {} - /** - * Thi method sets up the gallery settings and data - */ - ngOnInit(): void { - this.isAuthenticated$ = this.authService.isAuthenticated(); + ngOnChanges(changes: SimpleChanges): void { + this.image = changes.image.currentValue; + this.preview = changes.preview.currentValue; this.galleryOptions = [ { preview: this.preview !== undefined ? this.preview : true, @@ -50,7 +48,6 @@ export class MediaViewerImageComponent implements OnInit { previewFullscreen: true, }, ]; - if (this.image) { this.galleryImages = [ { @@ -64,6 +61,10 @@ export class MediaViewerImageComponent implements OnInit { } } + ngOnInit(): void { + this.isAuthenticated$ = this.authService.isAuthenticated(); + } + /** * This method convert an array of MediaViewerItem into NgxGalleryImage array * @param medias input NgxGalleryImage array diff --git a/src/app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.html b/src/app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.html index a4493e36fc..aaec542f82 100644 --- a/src/app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.html +++ b/src/app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.html @@ -1,15 +1,14 @@ -
+
- + - - + + diff --git a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html index 04794717f1..7eb896f8ae 100644 --- a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html +++ b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html @@ -20,13 +20,13 @@
- + - - + + From b2a9c4f456474876632119a26e8de88ae2656f72 Mon Sep 17 00:00:00 2001 From: nwoodward Date: Fri, 24 Mar 2023 08:48:19 -0500 Subject: [PATCH 03/21] handle http status code 413 from the backend when an SAF file is larger than the limit --- .../batch-import-page.component.ts | 12 +++++++++--- src/assets/i18n/en.json5 | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/app/admin/admin-import-batch-page/batch-import-page.component.ts b/src/app/admin/admin-import-batch-page/batch-import-page.component.ts index 7171c67585..95e69277a8 100644 --- a/src/app/admin/admin-import-batch-page/batch-import-page.component.ts +++ b/src/app/admin/admin-import-batch-page/batch-import-page.component.ts @@ -97,9 +97,15 @@ export class BatchImportPageComponent { this.router.navigateByUrl(getProcessDetailRoute(rd.payload.processId)); } } else { - const title = this.translate.get('process.new.notification.error.title'); - const content = this.translate.get('process.new.notification.error.content'); - this.notificationsService.error(title, content); + if (rd.statusCode === 413) { + const title = this.translate.get('process.new.notification.error.title'); + const content = this.translate.get('process.new.notification.error.max-upload.content'); + this.notificationsService.error(title, content); + } else { + const title = this.translate.get('process.new.notification.error.title'); + const content = this.translate.get('process.new.notification.error.content'); + this.notificationsService.error(title, content); + } } }); } diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index a8fc1b1177..bf493fb0e3 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3255,6 +3255,8 @@ "process.new.notification.error.content": "An error occurred while creating this process", + "process.new.notification.error.max-upload.content": "One or more files exceeds the maximum upload size", + "process.new.header": "Create a new process", "process.new.title": "Create a new process", From 3a7ab491bf8bbc43cb36e3ff6301ca1720e28353 Mon Sep 17 00:00:00 2001 From: nwoodward Date: Fri, 24 Mar 2023 08:53:55 -0500 Subject: [PATCH 04/21] updated message to reflect only one file --- src/assets/i18n/en.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index bf493fb0e3..e7ba9169c3 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3255,7 +3255,7 @@ "process.new.notification.error.content": "An error occurred while creating this process", - "process.new.notification.error.max-upload.content": "One or more files exceeds the maximum upload size", + "process.new.notification.error.max-upload.content": "The file exceeds the maximum upload size", "process.new.header": "Create a new process", From 43dd508b10e4ca8dd5238080e60ad7900c0f6bae Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sun, 26 Mar 2023 01:04:02 +0100 Subject: [PATCH 05/21] Fix placeholder not being shown for items with not THUMBNAIL bitstreams --- .../media-viewer-image.component.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/app/item-page/media-viewer/media-viewer-image/media-viewer-image.component.ts b/src/app/item-page/media-viewer/media-viewer-image/media-viewer-image.component.ts index 28c5b4efd6..59a9513d4f 100644 --- a/src/app/item-page/media-viewer/media-viewer-image/media-viewer-image.component.ts +++ b/src/app/item-page/media-viewer/media-viewer-image/media-viewer-image.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; +import { Component, Input, OnChanges, OnInit } from '@angular/core'; import { NgxGalleryImage, NgxGalleryOptions } from '@kolkov/ngx-gallery'; import { MediaViewerItem } from '../../../core/shared/media-viewer-item.model'; import { NgxGalleryAnimation } from '@kolkov/ngx-gallery'; @@ -20,8 +20,9 @@ export class MediaViewerImageComponent implements OnChanges, OnInit { loggedin: boolean; - galleryOptions: NgxGalleryOptions[]; - galleryImages: NgxGalleryImage[]; + galleryOptions: NgxGalleryOptions[] = []; + + galleryImages: NgxGalleryImage[] = []; /** * Whether or not the current user is authenticated @@ -30,9 +31,7 @@ export class MediaViewerImageComponent implements OnChanges, OnInit { constructor(private authService: AuthService) {} - ngOnChanges(changes: SimpleChanges): void { - this.image = changes.image.currentValue; - this.preview = changes.preview.currentValue; + ngOnChanges(): void { this.galleryOptions = [ { preview: this.preview !== undefined ? this.preview : true, @@ -63,6 +62,7 @@ export class MediaViewerImageComponent implements OnChanges, OnInit { ngOnInit(): void { this.isAuthenticated$ = this.authService.isAuthenticated(); + this.ngOnChanges(); } /** From 44699186406c10aebfa40b49772a0d62a204abaa Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Tue, 4 Apr 2023 22:05:09 +0200 Subject: [PATCH 06/21] Show ThumbnailComponent as fallback instead of a MediaViewerImageComponent placeholder when only one of the mediaviewers options is enabled --- src/app/item-page/media-viewer/media-viewer.component.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/app/item-page/media-viewer/media-viewer.component.html b/src/app/item-page/media-viewer/media-viewer.component.html index 3d2a863f61..b9b7ba1932 100644 --- a/src/app/item-page/media-viewer/media-viewer.component.html +++ b/src/app/item-page/media-viewer/media-viewer.component.html @@ -16,9 +16,12 @@
- + + From 05d73abbe214c2b05e44907c21d9e1f536175ef7 Mon Sep 17 00:00:00 2001 From: Leonardo Guerrero Date: Wed, 5 Apr 2023 11:35:23 -0500 Subject: [PATCH 07/21] Update es.json5 --- src/assets/i18n/es.json5 | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/assets/i18n/es.json5 b/src/assets/i18n/es.json5 index 303fc7fc61..2a85ffc155 100644 --- a/src/assets/i18n/es.json5 +++ b/src/assets/i18n/es.json5 @@ -752,8 +752,8 @@ // "admin.access-control.groups.form.tooltip.editGroup.addEpeople": "To add or remove an EPerson to/from this group, either click the 'Browse All' button or use the search bar below to search for users (use the dropdown to the left of the search bar to choose whether to search by metadata or by email). Then click the plus icon for each user you wish to add in the list below, or the trash can icon for each user you wish to remove. The list below may have several pages: use the page controls below the list to navigate to the next pages. Once you are ready, save your changes by clicking the 'Save' button in the top section.", "admin.access-control.groups.form.tooltip.editGroup.addEpeople": "Para agregar o remover una persona en este grupo, pulse el botón ‘Examinar todo’ o utilice la barra de búsqueda de abajo para buscar los usuario (Use el desplegable que se encuentra a la derecha de la barra de búsqueda para seleccionar entre buscar por metadato o por correo electrónico). Posteriormente pulse el botón con el icono más por cada usuario que desea agregar a la lista, o el icono de papelera por cada usuario que desea remover. La lista puede contener varias páginas: utilice los controles de paginación debajo de la lista, para navegar a las siguientes páginas. Cuando haya finalizado, guarde sus cambios pulsando el botón ‘Guardar’ ubicado en la parte superior de la sección.", - // "admin.access-control.groups.form.tooltip.editGroup.addSubgroups": "To add or remove a Subgroup to/from this group, either click the 'Browse All' button or use the search bar below to search for subgroups. Then click the plus icon for each subgroup you wish to add in the list below, or the trash can icon for each subgroup you wish to remove. The list below may have several pages: use the page controls below the list to navigate to the next pages. Once you are ready, save your changes by clicking the 'Save' button in the top section.", - "admin.access-control.groups.form.tooltip.editGroup.addSubgroups": "Para agregar o remover un sub-grupo en este grupo, pulse el botón ‘Examinar todo’ o utilice la barra de búsqueda de abajo para buscar los subgrupos- Posteriormente pulse el botón con el icono más por cada sub-grupo que desea agregar a la lista, o el icono de papelera por cada sub-grupo que desea remover. La lista puede contener varias páginas: utilice los controles de paginación debajo de la lista, para navegar a las siguientes páginas. Cuando haya finalizado, guarde sus cambios pulsando el botón ‘Guardar’ ubicado en la parte superior de la sección.", + // "admin.access-control.groups.form.tooltip.editGroup.addSubgroups": "To add or remove a Subgroup to/from this group, either click the 'Browse All' button or use the search bar below to search for users. Then click the plus icon for each user you wish to add in the list below, or the trash can icon for each user you wish to remove. The list below may have several pages: use the page controls below the list to navigate to the next pages. Once you are ready, save your changes by clicking the 'Save' button in the top section.", + "admin.access-control.groups.form.tooltip.editGroup.addSubgroups": "Para agregar o remover un sub-grupo en este grupo, pulse el botón 'Examinar todo' o utilice la barra de búsqueda de abajo para buscar los subgrupos- Posteriormente pulse el botón con el icono más por cada sub-grupo que desea agregar a la lista, o el icono de papelera por cada sub-grupo que desea remover. La lista puede contener varias páginas: utilice los controles de paginación debajo de la lista, para navegar a las siguientes páginas. Cuando haya finalizado, guarde sus cambios pulsando el botón ‘Guardar’ ubicado en la parte superior de la sección.", // "admin.search.breadcrumbs": "Administrative Search", "admin.search.breadcrumbs": "Búsqueda administrativa", @@ -1891,12 +1891,10 @@ // "comcol-role.edit.scorereviewers.name": "Score Reviewers", - // TODO New key - Add a translation - "comcol-role.edit.scorereviewers.name": "Score Reviewers", + "comcol-role.edit.scorereviewers.name": "Revisores de puntuación", // "comcol-role.edit.scorereviewers.description": "Reviewers are able to give a score to incoming submissions, this will define whether the submission will be rejected or not.", - // TODO New key - Add a translation - "comcol-role.edit.scorereviewers.description": "Reviewers are able to give a score to incoming submissions, this will define whether the submission will be rejected or not.", + "comcol-role.edit.scorereviewers.description": "Los revisores pueden dar una puntuación a un envío entrante, esto definirá si el envío será rechazado o no.", // "community.form.abstract": "Short Description", "community.form.abstract": "Breve descripción", @@ -2588,6 +2586,9 @@ // "form.submit": "Save", "form.submit": "Guardar", + // "form.create": "Create", + "form.create": "Crear", + // "form.repeatable.sort.tip": "Drop the item in the new position", "form.repeatable.sort.tip": "Suelte el ítem en la nueva posición", @@ -3953,8 +3954,8 @@ // "itemtemplate.edit.metadata.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", "itemtemplate.edit.metadata.notifications.discarded.content": "Sus cambios fueron descartados. Para recuperar sus cambios pulse el botón 'Deshacer'", - // "itemtemplate.edit.metadata.notifications.discarded.title": "Changed discarded", - "itemtemplate.edit.metadata.notifications.discarded.title": "Cambio descartado", + // "itemtemplate.edit.metadata.notifications.discarded.title": "Changes discarded", + "itemtemplate.edit.metadata.notifications.discarded.title": "Cambios descartados", // "itemtemplate.edit.metadata.notifications.error.title": "An error occurred", "itemtemplate.edit.metadata.notifications.error.title": "Ocurrió un error", @@ -3968,8 +3969,8 @@ // "itemtemplate.edit.metadata.notifications.outdated.content": "The item template you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", "itemtemplate.edit.metadata.notifications.outdated.content": "La plantilla de ítem en la que usted esta trabajando actualmente ha sido cambiada por otro usuario. Sus cambios han sido descartados para evitar conflictos", - // "itemtemplate.edit.metadata.notifications.outdated.title": "Changed outdated", - "itemtemplate.edit.metadata.notifications.outdated.title": "Cambiado obsoleto", + // "itemtemplate.edit.metadata.notifications.outdated.title": "Changes outdated", + "itemtemplate.edit.metadata.notifications.outdated.title": "Cambios obsoletos", // "itemtemplate.edit.metadata.notifications.saved.content": "Your changes to this item template's metadata were saved.", "itemtemplate.edit.metadata.notifications.saved.content": "Sus cambios a los metadatos de esta plantilla de ítem han sido guardados.", @@ -5211,7 +5212,6 @@ // "register-page.registration.google-recaptcha.must-accept-cookies": "In order to register you must accept the Registration and Password recovery (Google reCaptcha) cookies.", "register-page.registration.google-recaptcha.must-accept-cookies": "Para registrarse debe aceptar las cookies de Registro y recuperación de contraseña (Google reCaptcha).", - // "register-page.registration.error.maildomain": "This email address is not on the list of domains who can register. Allowed domains are {{ domains }}", "register-page.registration.error.maildomain": "Este correo electrónico no esta en la lista de dominios que pueden registrarse. Los dominios permitidos son {{ domains }}", @@ -5226,7 +5226,6 @@ // "register-page.registration.google-recaptcha.notification.message.expired": "Verification expired. Please verify again.", "register-page.registration.google-recaptcha.notification.message.expired": "Verificación caducada. Verifique de nuevo.", - // "register-page.registration.info.maildomain": "Accounts can be registered for mail addresses of the domains", "register-page.registration.info.maildomain": "Las cuentas pueden registrarse para las direcciones de correo de los dominios", @@ -5943,6 +5942,8 @@ // "statistics.table.header.views": "Views", "statistics.table.header.views": "Visitas", + // "statistics.table.no-name": "(object name could not be loaded)", + "statistics.table.no-name": "(el nombre del objeto no pudo ser cargado)", // "submission.edit.breadcrumbs": "Edit Submission", @@ -6936,8 +6937,8 @@ // "submission.workflow.generic.delete": "Delete", "submission.workflow.generic.delete": "Eliminar", - // "submission.workflow.generic.delete-help": "If you would to discard this item, select \"Delete\". You will then be asked to confirm it.", - "submission.workflow.generic.delete-help": "Si desea descartar este ítem, seleccione \"Eliminar\". Luego se le pedirá que lo confirme.", + // "submission.workflow.generic.delete-help": "Select this option to discard this item. You will then be asked to confirm it.", + "submission.workflow.generic.delete-help": "Seleccione esta opción para descartar este ítem. A contunuación se le pedirá confirmación.", // "submission.workflow.generic.edit": "Edit", "submission.workflow.generic.edit": "Editar", @@ -7089,7 +7090,7 @@ // "subscriptions.modal.new-subscription-form.type.content": "Content", "subscriptions.modal.new-subscription-form.type.content": "Contenido", - // "subscriptions.modal.new-subscription-form.frequency.D": "Diario", + // "subscriptions.modal.new-subscription-form.frequency.D": "Daily", "subscriptions.modal.new-subscription-form.frequency.D": "Diario", // "subscriptions.modal.new-subscription-form.frequency.W": "Weekly", @@ -7345,8 +7346,8 @@ "workflow-item.selectrevieweraction.button.confirm": "Confirmar", - // "workflow-item.scorereviewaction.notification.success.title": "Revisar evaluación", - "workflow-item.scorereviewaction.notification.success.title": "Revisar evaluación", + // "workflow-item.scorereviewaction.notification.success.title": "Rating review", + "workflow-item.scorereviewaction.notification.success.title": "Revisión de evaluación", // "workflow-item.scorereviewaction.notification.success.content": "The rating for this item workflow item has been successfully submitted", "workflow-item.scorereviewaction.notification.success.content": "La evaluación para este ítem ha sido enviada exitosamente", From d6147e52364a3533d1b843f166470fe2fd6ae741 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Wed, 8 Feb 2023 15:21:07 +0100 Subject: [PATCH 08/21] Fixed default @Input() values not working for themed components --- src/app/shared/theme-support/themed.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/shared/theme-support/themed.component.ts b/src/app/shared/theme-support/themed.component.ts index 2ff0713f46..3a0bc36886 100644 --- a/src/app/shared/theme-support/themed.component.ts +++ b/src/app/shared/theme-support/themed.component.ts @@ -103,7 +103,7 @@ export abstract class ThemedComponent implements OnInit, OnDestroy, OnChanges protected connectInputsAndOutputs(): void { if (isNotEmpty(this.inAndOutputNames) && hasValue(this.compRef) && hasValue(this.compRef.instance)) { - this.inAndOutputNames.forEach((name: any) => { + this.inAndOutputNames.filter((name: any) => this[name] !== undefined).forEach((name: any) => { this.compRef.instance[name] = this[name]; }); } From 1752b1afd4d49d68f0264f9e1d189bc2bb27e0b0 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Fri, 24 Mar 2023 16:47:42 +0100 Subject: [PATCH 09/21] 100479: Removed the default input values to make it possible to override them in themes --- src/app/footer/themed-footer.component.ts | 4 ++-- .../themed-header-navbar-wrapper.component.ts | 6 +++--- src/app/home-page/themed-home-page.component.ts | 2 -- .../my-dspace-page/themed-my-dspace-page.component.ts | 1 - .../themed-configuration-search-page.component.ts | 9 ++++----- src/app/shared/search/search.component.ts | 2 +- 6 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/app/footer/themed-footer.component.ts b/src/app/footer/themed-footer.component.ts index c52a0af29f..e8f64f3434 100644 --- a/src/app/footer/themed-footer.component.ts +++ b/src/app/footer/themed-footer.component.ts @@ -7,7 +7,7 @@ import { FooterComponent } from './footer.component'; */ @Component({ selector: 'ds-themed-footer', - styleUrls: ['footer.component.scss'], + styleUrls: [], templateUrl: '../shared/theme-support/themed.component.html', }) export class ThemedFooterComponent extends ThemedComponent { @@ -20,6 +20,6 @@ export class ThemedFooterComponent extends ThemedComponent { } protected importUnthemedComponent(): Promise { - return import(`./footer.component`); + return import('./footer.component'); } } diff --git a/src/app/header-nav-wrapper/themed-header-navbar-wrapper.component.ts b/src/app/header-nav-wrapper/themed-header-navbar-wrapper.component.ts index 7f9c181fe2..02d09c44ef 100644 --- a/src/app/header-nav-wrapper/themed-header-navbar-wrapper.component.ts +++ b/src/app/header-nav-wrapper/themed-header-navbar-wrapper.component.ts @@ -3,11 +3,11 @@ import { ThemedComponent } from '../shared/theme-support/themed.component'; import { HeaderNavbarWrapperComponent } from './header-navbar-wrapper.component'; /** - * Themed wrapper for BreadcrumbsComponent + * Themed wrapper for {@link HeaderNavbarWrapperComponent} */ @Component({ selector: 'ds-themed-header-navbar-wrapper', - styleUrls: ['./themed-header-navbar-wrapper.component.scss'], + styleUrls: [], templateUrl: '../shared/theme-support/themed.component.html', }) export class ThemedHeaderNavbarWrapperComponent extends ThemedComponent { @@ -20,6 +20,6 @@ export class ThemedHeaderNavbarWrapperComponent extends ThemedComponent { - return import(`./header-navbar-wrapper.component`); + return import('./header-navbar-wrapper.component'); } } diff --git a/src/app/home-page/themed-home-page.component.ts b/src/app/home-page/themed-home-page.component.ts index e50f955cb1..c0ef723b38 100644 --- a/src/app/home-page/themed-home-page.component.ts +++ b/src/app/home-page/themed-home-page.component.ts @@ -8,8 +8,6 @@ import { Component } from '@angular/core'; templateUrl: '../shared/theme-support/themed.component.html', }) export class ThemedHomePageComponent extends ThemedComponent { - protected inAndOutputNames: (keyof HomePageComponent & keyof this)[]; - protected getComponentName(): string { return 'HomePageComponent'; diff --git a/src/app/my-dspace-page/themed-my-dspace-page.component.ts b/src/app/my-dspace-page/themed-my-dspace-page.component.ts index 2c74da052e..55ebc51c8d 100644 --- a/src/app/my-dspace-page/themed-my-dspace-page.component.ts +++ b/src/app/my-dspace-page/themed-my-dspace-page.component.ts @@ -11,7 +11,6 @@ import { MyDSpacePageComponent } from './my-dspace-page.component'; templateUrl: './../shared/theme-support/themed.component.html' }) export class ThemedMyDSpacePageComponent extends ThemedComponent { - protected inAndOutputNames: (keyof MyDSpacePageComponent & keyof this)[]; protected getComponentName(): string { return 'MyDSpacePageComponent'; diff --git a/src/app/search-page/themed-configuration-search-page.component.ts b/src/app/search-page/themed-configuration-search-page.component.ts index e4d6e93402..e367ee5238 100644 --- a/src/app/search-page/themed-configuration-search-page.component.ts +++ b/src/app/search-page/themed-configuration-search-page.component.ts @@ -28,19 +28,18 @@ export class ThemedConfigurationSearchPageComponent extends ThemedComponent { - return import(`./configuration-search-page.component`); + return import('./configuration-search-page.component'); } } diff --git a/src/app/shared/search/search.component.ts b/src/app/shared/search/search.component.ts index c017a5065b..b04575f546 100644 --- a/src/app/shared/search/search.component.ts +++ b/src/app/shared/search/search.component.ts @@ -127,7 +127,7 @@ export class SearchComponent implements OnInit { /** * List of available view mode */ - @Input() useUniquePageId: false; + @Input() useUniquePageId: boolean; /** * List of available view mode From 187cdd7ae2e1d7bd8948e5afdcbb75f2717718d5 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Mon, 17 Apr 2023 15:06:51 -0500 Subject: [PATCH 10/21] Split Codecov upload into a separate job. Make it auto-retry up to five times --- .github/workflows/build.yml | 43 ++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5470b3cc2a..42c29d2002 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -93,12 +93,16 @@ jobs: - name: Run specs (unit tests) run: yarn run test:headless + # Upload code coverage report to artifact (for one version of Node only), + # so that it can be shared with the 'codecov' job (see below) # NOTE: Angular CLI only supports code coverage for specs. See https://github.com/angular/angular-cli/issues/6286 - # Upload coverage reports to Codecov (for one version of Node only) - # https://github.com/codecov/codecov-action - - name: Upload coverage to Codecov.io - uses: codecov/codecov-action@v3 - if: matrix.node-version == '16.x' + - name: Upload code coverage report to Artifact + uses: actions/upload-artifact@v3 + if: matrix.node-version == '18.x' + with: + name: dspace-angular coverage report + path: 'coverage/dspace-angular/lcov.info' + retention-days: 14 # Using docker-compose start backend using CI configuration # and load assetstore from a cached copy @@ -176,3 +180,32 @@ jobs: - name: Shutdown Docker containers run: docker-compose -f ./docker/docker-compose-ci.yml down + + # Codecov upload is a separate job in order to allow us to restart this separate from the entire build/test + # job above. This is necessary because Codecov uploads seem to randomly fail at times. + # See https://community.codecov.com/t/upload-issues-unable-to-locate-build-via-github-actions-api/3954 + codecov: + # Must run after 'tests' job above + needs: tests + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + # Download artifacts from previous 'tests' job + - name: Download coverage artifacts + uses: actions/download-artifact@v3 + + # Now attempt upload to Codecov using its action. + # NOTE: We use a retry action to retry the Codecov upload if it fails the first time. + # + # Retry action: https://github.com/marketplace/actions/retry-action + # Codecov action: https://github.com/codecov/codecov-action + - name: Upload coverage to Codecov.io + uses: Wandalen/wretry.action@v1.0.36 + with: + action: codecov/codecov-action@v3 + # Try upload 5 times max + attempt_limit: 5 + # Run again in 30 seconds + attempt_delay: 30000 From fef1ba966304a3ded17541f8c9f93e55477e4564 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Mon, 17 Apr 2023 15:07:09 -0500 Subject: [PATCH 11/21] Update to latest version of actions --- .github/workflows/issue_opened.yml | 2 +- .github/workflows/label_merge_conflicts.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/issue_opened.yml b/.github/workflows/issue_opened.yml index 5d7c1c30f7..b4436dca3a 100644 --- a/.github/workflows/issue_opened.yml +++ b/.github/workflows/issue_opened.yml @@ -16,7 +16,7 @@ jobs: # Only add to project board if issue is flagged as "needs triage" or has no labels # NOTE: By default we flag new issues as "needs triage" in our issue template if: (contains(github.event.issue.labels.*.name, 'needs triage') || join(github.event.issue.labels.*.name) == '') - uses: actions/add-to-project@v0.3.0 + uses: actions/add-to-project@v0.5.0 # Note, the authentication token below is an ORG level Secret. # It must be created/recreated manually via a personal access token with admin:org, project, public_repo permissions # See: https://docs.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token#permissions-for-the-github_token diff --git a/.github/workflows/label_merge_conflicts.yml b/.github/workflows/label_merge_conflicts.yml index a840a4fd17..c1396b6f45 100644 --- a/.github/workflows/label_merge_conflicts.yml +++ b/.github/workflows/label_merge_conflicts.yml @@ -23,7 +23,7 @@ jobs: steps: # See: https://github.com/prince-chrismc/label-merge-conflicts-action - name: Auto-label PRs with merge conflicts - uses: prince-chrismc/label-merge-conflicts-action@v2 + uses: prince-chrismc/label-merge-conflicts-action@v3 # Add "merge conflict" label if a merge conflict is detected. Remove it when resolved. # Note, the authentication token is created automatically # See: https://docs.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token From 80b90524b653d220f4269965f29d1697238aa79a Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Fri, 24 Mar 2023 16:47:42 +0100 Subject: [PATCH 12/21] 100479: Removed the default input values to make it possible to override them in themes --- .../loading/themed-loading.component.ts | 4 +- .../themed-item-list-preview.component.ts | 2 +- .../themed-object-list.component.ts | 67 ++++++------------- .../themed-search-results.component.ts | 14 ++-- .../shared/search/themed-search.component.ts | 36 +++++----- 5 files changed, 50 insertions(+), 73 deletions(-) diff --git a/src/app/shared/loading/themed-loading.component.ts b/src/app/shared/loading/themed-loading.component.ts index ffdf9d3cbe..48773d75c8 100644 --- a/src/app/shared/loading/themed-loading.component.ts +++ b/src/app/shared/loading/themed-loading.component.ts @@ -14,8 +14,8 @@ import { ThemeService } from '../theme-support/theme.service'; export class ThemedLoadingComponent extends ThemedComponent { @Input() message: string; - @Input() showMessage = true; - @Input() spinner = false; + @Input() showMessage: boolean; + @Input() spinner: boolean; protected inAndOutputNames: (keyof LoadingComponent & keyof this)[] = ['message', 'showMessage', 'spinner']; diff --git a/src/app/shared/object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component.ts b/src/app/shared/object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component.ts index 3fe825d236..eff5911dca 100644 --- a/src/app/shared/object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component.ts +++ b/src/app/shared/object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component.ts @@ -22,7 +22,7 @@ export class ThemedItemListPreviewComponent extends ThemedComponent { - /** - * The view mode of the this component - */ - viewMode = ViewMode.ListElement; /** * The current pagination configuration @@ -37,18 +33,20 @@ export class ThemedObjectListComponent extends ThemedComponent