From cdb708c9aa4c72c4f96be6dda15a3045da288ff8 Mon Sep 17 00:00:00 2001 From: guillermo2519 Date: Tue, 14 Apr 2026 17:54:14 -0600 Subject: [PATCH] Fix #5435: show permission denied message when 403 on collection mapper (cherry picked from commit 8d7b56dc1d6e1c83523945021d2807048bbf0fec) --- .../item-collection-mapper.component.spec.ts | 14 ++++++++++ .../item-collection-mapper.component.ts | 28 ++++++++++++++----- src/assets/i18n/en.json5 | 8 ++++++ 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/app/item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.spec.ts b/src/app/item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.spec.ts index 54bf321ad17..1c63a4e72f9 100644 --- a/src/app/item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.spec.ts @@ -180,6 +180,13 @@ describe('ItemCollectionMapperComponent', () => { expect(notificationsService.success).not.toHaveBeenCalled(); expect(notificationsService.error).toHaveBeenCalled(); }); + + it('should display a permission error message if mapping returns 403', () => { + spyOn(itemDataService, 'mapToCollection').and.returnValue(createFailedRemoteDataObject$('Forbidden', 403)); + comp.mapCollections(ids); + expect(notificationsService.success).not.toHaveBeenCalled(); + expect(notificationsService.error).toHaveBeenCalled(); + }); }); describe('removeMappings', () => { @@ -197,6 +204,13 @@ describe('ItemCollectionMapperComponent', () => { expect(notificationsService.success).not.toHaveBeenCalled(); expect(notificationsService.error).toHaveBeenCalled(); }); + + it('should display a permission error message if removal returns 403', () => { + spyOn(itemDataService, 'removeMappingFromCollection').and.returnValue(createFailedRemoteDataObject$('Forbidden', 403)); + comp.removeMappings(ids); + expect(notificationsService.success).not.toHaveBeenCalled(); + expect(notificationsService.error).toHaveBeenCalled(); + }); }); describe('tabChange', () => { diff --git a/src/app/item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.ts b/src/app/item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.ts index a50616fbc20..f5fff400557 100644 --- a/src/app/item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.ts +++ b/src/app/item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.ts @@ -287,14 +287,28 @@ export class ItemCollectionMapperComponent implements OnInit { this.shouldUpdate$.next(true); } if (unsuccessful.length > 0) { - const unsuccessMessages = observableCombineLatest([ - this.translateService.get(`${messagePrefix}.error.head`), - this.translateService.get(`${messagePrefix}.error.content`, { amount: unsuccessful.length }), - ]); + const forbidden = unsuccessful.filter((response: RemoteData) => response.statusCode === 403); + const otherErrors = unsuccessful.filter((response: RemoteData) => response.statusCode !== 403); - unsuccessMessages.subscribe(([head, content]) => { - this.notificationsService.error(head, content); - }); + if (forbidden.length > 0) { + const forbiddenMessages = observableCombineLatest([ + this.translateService.get(`${messagePrefix}.error.forbidden.head`), + this.translateService.get(`${messagePrefix}.error.forbidden.content`), + ]); + forbiddenMessages.subscribe(([head, content]) => { + this.notificationsService.error(head, content); + }); + } + + if (otherErrors.length > 0) { + const unsuccessMessages = observableCombineLatest([ + this.translateService.get(`${messagePrefix}.error.head`), + this.translateService.get(`${messagePrefix}.error.content`, { amount: otherErrors.length }), + ]); + unsuccessMessages.subscribe(([head, content]) => { + this.notificationsService.error(head, content); + }); + } } this.switchToFirstTab(); }); diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index e4b96624bc9..614df7d1316 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -2513,6 +2513,10 @@ "item.edit.item-mapper.notifications.add.error.content": "Errors occurred for mapping of item to {{amount}} collections.", + "item.edit.item-mapper.notifications.add.error.forbidden.head": "Permission denied", + + "item.edit.item-mapper.notifications.add.error.forbidden.content": "You do not have permission to map this item to a collection.", + "item.edit.item-mapper.notifications.add.error.head": "Mapping errors", "item.edit.item-mapper.notifications.add.success.content": "Successfully mapped item to {{amount}} collections.", @@ -2521,6 +2525,10 @@ "item.edit.item-mapper.notifications.remove.error.content": "Errors occurred for the removal of the mapping to {{amount}} collections.", + "item.edit.item-mapper.notifications.remove.error.forbidden.head": "Permission denied", + + "item.edit.item-mapper.notifications.remove.error.forbidden.content": "You do not have permission to remove this item from a collection.", + "item.edit.item-mapper.notifications.remove.error.head": "Removal of mapping errors", "item.edit.item-mapper.notifications.remove.success.content": "Successfully removed mapping of item to {{amount}} collections.",