From 8b2bd87eece9145481668c76ad7003e95abef6fc Mon Sep 17 00:00:00 2001 From: Maximilian Wesener Date: Thu, 28 Mar 2024 16:01:11 +0100 Subject: [PATCH 01/14] chore(feature): 616 - Fixed title of nav. Removed investigation logic. --- .../presentation/dashboard.component.html | 6 +-- .../presentation/dashboard.component.ts | 10 +---- .../presentation/notifications.component.html | 4 +- .../autocomplete-strategy.spec.ts | 10 ++--- .../autocomplete-strategy.ts | 38 +++---------------- .../table-type.model.ts | 6 +-- .../notification-tab.component.html | 2 +- .../notification-tab.component.ts | 14 +------ .../presentation/notification.component.html | 14 +++---- .../notification.component.spec.ts | 5 +-- .../presentation/notification.component.ts | 7 +--- frontend/src/assets/locales/de/common.json | 2 +- frontend/src/assets/locales/en/common.json | 2 +- 13 files changed, 29 insertions(+), 91 deletions(-) diff --git a/frontend/src/app/modules/page/dashboard/presentation/dashboard.component.html b/frontend/src/app/modules/page/dashboard/presentation/dashboard.component.html index b703b7cacf..522bc44916 100644 --- a/frontend/src/app/modules/page/dashboard/presentation/dashboard.component.html +++ b/frontend/src/app/modules/page/dashboard/presentation/dashboard.component.html @@ -114,10 +114,9 @@

diff --git a/frontend/src/app/modules/page/dashboard/presentation/dashboard.component.ts b/frontend/src/app/modules/page/dashboard/presentation/dashboard.component.ts index e3a55fe9d9..e34539dab0 100644 --- a/frontend/src/app/modules/page/dashboard/presentation/dashboard.component.ts +++ b/frontend/src/app/modules/page/dashboard/presentation/dashboard.component.ts @@ -21,16 +21,11 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { Router } from '@angular/router'; -import { NOTIFICATION_BASE_ROUTE, getRoute } from '@core/known-route'; +import { getRoute, NOTIFICATION_BASE_ROUTE } from '@core/known-route'; import { DashboardStats } from '@page/dashboard/model/dashboard.model'; import { MetricData } from '@page/dashboard/presentation/dashboard.model'; import { TableType } from '@shared/components/multi-select-autocomplete/table-type.model'; -import { - Notification, - Notifications, - NotificationStatusGroup, - NotificationType, -} from '@shared/model/notification.model'; +import { Notification, Notifications, NotificationStatusGroup } from '@shared/model/notification.model'; import { View } from '@shared/model/view.model'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @@ -134,6 +129,5 @@ export class DashboardComponent implements OnInit, OnDestroy { this.router.navigate([ `/${ link }/${ notification.id }` ]).then(); } - protected readonly NotificationType = NotificationType; protected readonly TableType = TableType; } diff --git a/frontend/src/app/modules/page/notifications/presentation/notifications.component.html b/frontend/src/app/modules/page/notifications/presentation/notifications.component.html index 3eae3d38bb..f4d0e22639 100644 --- a/frontend/src/app/modules/page/notifications/presentation/notifications.component.html +++ b/frontend/src/app/modules/page/notifications/presentation/notifications.component.html @@ -24,10 +24,8 @@ > diff --git a/frontend/src/app/modules/shared/components/multi-select-autocomplete/autocomplete-strategy.spec.ts b/frontend/src/app/modules/shared/components/multi-select-autocomplete/autocomplete-strategy.spec.ts index efc284ae60..4607c7c09d 100644 --- a/frontend/src/app/modules/shared/components/multi-select-autocomplete/autocomplete-strategy.spec.ts +++ b/frontend/src/app/modules/shared/components/multi-select-autocomplete/autocomplete-strategy.spec.ts @@ -16,13 +16,13 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -import {Owner} from '@page/parts/model/owner.enum'; +import { Owner } from '@page/parts/model/owner.enum'; import { channelOfNotification, getOwnerOfTable, isAsBuilt, } from '@shared/components/multi-select-autocomplete/autocomplete-strategy'; -import {NotificationChannel, TableType} from '@shared/components/multi-select-autocomplete/table-type.model'; +import { NotificationChannel, TableType } from '@shared/components/multi-select-autocomplete/table-type.model'; describe('Autocomplete Strategies', () => { @@ -46,9 +46,7 @@ describe('Autocomplete Strategies', () => { }); it('should determine channel of notification', async () => { - expect(channelOfNotification(TableType.CREATED_INVESTIGATION)).toBe(NotificationChannel.SENDER); - expect(channelOfNotification(TableType.CREATED_ALERT)).toBe(NotificationChannel.SENDER); - expect(channelOfNotification(TableType.RECEIVED_INVESTIGATION)).toBe(NotificationChannel.RECEIVER); - expect(channelOfNotification(TableType.RECEIVED_INVESTIGATION)).toBe(NotificationChannel.RECEIVER); + expect(channelOfNotification(TableType.SENT_NOTIFICATION)).toBe(NotificationChannel.SENDER); + expect(channelOfNotification(TableType.RECEIVED_NOTIFICATION)).toBe(NotificationChannel.RECEIVER); }); }); diff --git a/frontend/src/app/modules/shared/components/multi-select-autocomplete/autocomplete-strategy.ts b/frontend/src/app/modules/shared/components/multi-select-autocomplete/autocomplete-strategy.ts index 2a3fc4da18..02b757ccdb 100644 --- a/frontend/src/app/modules/shared/components/multi-select-autocomplete/autocomplete-strategy.ts +++ b/frontend/src/app/modules/shared/components/multi-select-autocomplete/autocomplete-strategy.ts @@ -53,29 +53,7 @@ export class PartsStrategy extends AutocompleteStrategy { @Injectable({ providedIn: 'any', }) -export class InvestigationStrategy extends AutocompleteStrategy { - notificationService: NotificationService; - - constructor(notificationService: NotificationService) { - super(); - this.notificationService = notificationService; - } - - retrieveSuggestionValues(tableType: TableType, filterColumns: string, searchElement: string): any { - const notificationChannel = channelOfNotification(tableType); - return this.notificationService.getDistinctFilterValues( - notificationChannel, - filterColumns, - searchElement, - true, - ); - } -} - -@Injectable({ - providedIn: 'any', -}) -export class AlertStrategy extends AutocompleteStrategy { +export class NotificationStrategy extends AutocompleteStrategy { notificationService: NotificationService; constructor(notificationService: NotificationService) { @@ -120,11 +98,9 @@ export const AutocompleteStrategyMap = new Map([ [ TableType.AS_PLANNED_OWN, PartsStrategy ], [ TableType.AS_PLANNED_CUSTOMER, PartsStrategy ], [ TableType.AS_PLANNED_SUPPLIER, PartsStrategy ], - [ TableType.RECEIVED_INVESTIGATION, InvestigationStrategy ], - [ TableType.CREATED_INVESTIGATION, InvestigationStrategy ], - [ TableType.RECEIVED_ALERT, AlertStrategy ], - [ TableType.CREATED_ALERT, AlertStrategy ], - [ TableType.CONTRACTS, ContractsStrategy] + [ TableType.RECEIVED_NOTIFICATION, NotificationStrategy ], + [ TableType.SENT_NOTIFICATION, NotificationStrategy ], + [ TableType.CONTRACTS, ContractsStrategy ], ]); export function getOwnerOfTable(tableType: TableType): Owner { @@ -145,14 +121,10 @@ export function isAsBuilt(tableType: TableType): boolean { } export function channelOfNotification(tableType: TableType): NotificationChannel { - if (tableType === TableType.CREATED_ALERT || tableType === TableType.CREATED_INVESTIGATION) { + if (tableType === TableType.SENT_NOTIFICATION) { return NotificationChannel.SENDER; } else { return NotificationChannel.RECEIVER; } } - -export function isInvestigation(tableType: TableType): boolean { - return [ TableType.RECEIVED_INVESTIGATION, TableType.CREATED_INVESTIGATION ].includes(tableType); -} diff --git a/frontend/src/app/modules/shared/components/multi-select-autocomplete/table-type.model.ts b/frontend/src/app/modules/shared/components/multi-select-autocomplete/table-type.model.ts index a87d2e271c..b18f55f3a0 100644 --- a/frontend/src/app/modules/shared/components/multi-select-autocomplete/table-type.model.ts +++ b/frontend/src/app/modules/shared/components/multi-select-autocomplete/table-type.model.ts @@ -24,10 +24,8 @@ export enum TableType { AS_BUILT_CUSTOMER = 'AS_BUILT_CUSTOMER', AS_PLANNED_SUPPLIER = 'AS_PLANNED_SUPPLIER', AS_PLANNED_CUSTOMER = 'AS_PLANNED_CUSTOMER', - RECEIVED_INVESTIGATION = 'RECEIVED_INVESTIGATION', - CREATED_INVESTIGATION = 'CREATED_INVESTIGATION', - RECEIVED_ALERT = 'RECEIVED_ALERT', - CREATED_ALERT = 'CREATED_ALERT', + RECEIVED_NOTIFICATION = 'RECEIVED_NOTIFICATION', + SENT_NOTIFICATION = 'SENT_NOTIFICATION', CONTRACTS='CONTRACTS' } diff --git a/frontend/src/app/modules/shared/modules/notification/notification-tab/notification-tab.component.html b/frontend/src/app/modules/shared/modules/notification/notification-tab/notification-tab.component.html index eaa1a90900..bd9d7028b4 100644 --- a/frontend/src/app/modules/shared/modules/notification/notification-tab/notification-tab.component.html +++ b/frontend/src/app/modules/shared/modules/notification/notification-tab/notification-tab.component.html @@ -27,7 +27,7 @@ [paginationData]="notifications.data" [additionalTableHeader]="true" [autocompleteEnabled]="autocompleteEnabled" - [tableHeader]="(notificationType === NotificationType.INVESTIGATION) ? ('pageTitle.investigations') : ('pageTitle.alerts')" + [tableHeader]="('pageTitle.alerts')" [tableConfig]="tableConfig" [noShadow]="true" [labelId]="labelId" diff --git a/frontend/src/app/modules/shared/modules/notification/notification-tab/notification-tab.component.ts b/frontend/src/app/modules/shared/modules/notification/notification-tab/notification-tab.component.ts index f14f4b82d3..81d579eb77 100644 --- a/frontend/src/app/modules/shared/modules/notification/notification-tab/notification-tab.component.ts +++ b/frontend/src/app/modules/shared/modules/notification/notification-tab/notification-tab.component.ts @@ -47,13 +47,11 @@ export class NotificationTabComponent implements AfterViewInit { @Input() optionalColumns: Array<'title'|'targetDate' | 'severity' | 'createdBy' | 'sendTo' | 'sendToName' | 'createdByName' | 'type'> = []; @Input() sortableColumns: Record = {}; @Input() multiSortList: TableHeaderSort[] = []; - @Input() notificationType = NotificationType.INVESTIGATION; @Input() tableType: TableType; @Input() autocompleteEnabled = false; @Output() tableConfigChanged = new EventEmitter(); - @Output() investigationsFilterChanged = new EventEmitter(); - @Output() alertsFilterChanged = new EventEmitter(); + @Output() notificationsFilterChanged = new EventEmitter(); @Output() selected = new EventEmitter(); @ViewChild('titleTmp') titleTemplate: TemplateRef; @ViewChild('statusTmp') statusTemplate: TemplateRef; @@ -105,18 +103,10 @@ export class NotificationTabComponent implements AfterViewInit { this.notificationFilter = notificationFilter; const channel = notificationFilter['createdBy'] ? NotificationChannel.RECEIVER : NotificationChannel.SENDER; - if (this.notificationType === NotificationType.INVESTIGATION) { - this.investigationsFilterChanged.emit({ + this.notificationsFilterChanged.emit({ channel: channel, filter: notificationFilter, }); - } - if (this.notificationType === NotificationType.ALERT) { - this.alertsFilterChanged.emit({ - channel: channel, - filter: notificationFilter, - }); - } } public selectNotification(notification: Record): void { diff --git a/frontend/src/app/modules/shared/modules/notification/presentation/notification.component.html b/frontend/src/app/modules/shared/modules/notification/presentation/notification.component.html index e713f1f297..81f7442ef1 100644 --- a/frontend/src/app/modules/shared/modules/notification/presentation/notification.component.html +++ b/frontend/src/app/modules/shared/modules/notification/presentation/notification.component.html @@ -35,19 +35,17 @@ @@ -60,11 +58,10 @@ diff --git a/frontend/src/app/modules/shared/modules/notification/presentation/notification.component.spec.ts b/frontend/src/app/modules/shared/modules/notification/presentation/notification.component.spec.ts index d81ba05e22..382abcacbb 100644 --- a/frontend/src/app/modules/shared/modules/notification/presentation/notification.component.spec.ts +++ b/frontend/src/app/modules/shared/modules/notification/presentation/notification.component.spec.ts @@ -86,18 +86,15 @@ describe('NotificationsInboxComponent', () => { const isInvestigation = true; return renderComponent( ``, { imports: [ SharedModule, NotificationModule, TemplateModule ], diff --git a/frontend/src/app/modules/shared/modules/notification/presentation/notification.component.ts b/frontend/src/app/modules/shared/modules/notification/presentation/notification.component.ts index 4ea4446bc1..bf87c7a2fc 100644 --- a/frontend/src/app/modules/shared/modules/notification/presentation/notification.component.ts +++ b/frontend/src/app/modules/shared/modules/notification/presentation/notification.component.ts @@ -23,7 +23,7 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { TableType } from '@shared/components/multi-select-autocomplete/table-type.model'; import { MenuActionConfig, TableEventConfig, TableHeaderSort } from '@shared/components/table/table.model'; -import { Notification, Notifications, NotificationType } from '@shared/model/notification.model'; +import { Notification, Notifications } from '@shared/model/notification.model'; import { View } from '@shared/model/view.model'; import { StaticIdService } from '@shared/service/staticId.service'; import { Observable } from 'rxjs'; @@ -44,13 +44,10 @@ export class NotificationComponent { @Input() queuedAndRequestedSortableColumns: Record = {}; @Input() receivedMultiSortList: TableHeaderSort[] = []; @Input() queuedAndRequestedMultiSortList: TableHeaderSort[] = []; - @Input() notificationType = NotificationType.INVESTIGATION; - @Input() isInvestigation: boolean = true; @Output() onReceivedTableConfigChanged = new EventEmitter(); @Output() onQueuedAndRequestedTableConfigChanged = new EventEmitter(); @Output() selected = new EventEmitter(); - @Output() investigationFilterChanged = new EventEmitter(); - @Output() alertFilterChanged = new EventEmitter(); + @Output() notificationsFilterChanged = new EventEmitter(); public readonly tabIndex$ = this.route.queryParams.pipe(map(params => parseInt(params.tabIndex, 10) || 0)); diff --git a/frontend/src/assets/locales/de/common.json b/frontend/src/assets/locales/de/common.json index c717fa93e3..fc586d945e 100644 --- a/frontend/src/assets/locales/de/common.json +++ b/frontend/src/assets/locales/de/common.json @@ -8,7 +8,7 @@ "about": "Über uns", "relations": "Beziehungen", "admin": "Verwaltung", - "alerts": "Inbox", + "inbox": "Inbox", "adminRegistry": "Registry-Abfragen", "adminBpn": "BPN - EDC Konfiguration", "adminImport": "Datenbereitstellung", diff --git a/frontend/src/assets/locales/en/common.json b/frontend/src/assets/locales/en/common.json index aa869d6be9..0cda9ef316 100644 --- a/frontend/src/assets/locales/en/common.json +++ b/frontend/src/assets/locales/en/common.json @@ -8,7 +8,7 @@ "about": "About", "relations": "Relations", "admin": "Administration", - "alerts": "Inbox", + "inbox": "Inbox", "adminRegistry": "Registry lookups", "adminBpn": "BPN - EDC configuration", "adminImport": "Data provisioning", From 81e6ef1c094c11276e33313684e90531e16e2589 Mon Sep 17 00:00:00 2001 From: Maximilian Wesener Date: Thu, 28 Mar 2024 16:57:45 +0100 Subject: [PATCH 02/14] chore(feature): 616 - Fixed modal translations. --- .../detail/notification-detail.component.html | 1 - .../detail/notification-detail.component.ts | 1 - .../presentation/notifications.component.html | 1 - .../notification-common-modal.component.html | 6 - .../notification-common-modal.component.ts | 128 ++++++++++-------- .../shared/helper/notification-helper.ts | 11 +- .../shared/model/translation-context.model.ts | 3 +- .../accept-notification-modal.component.ts | 7 +- ...cknowledge-notification-modal.component.ts | 7 +- .../approve-notification-modal.component.ts | 81 +++++------ .../cancel-notification-modal.component.ts | 9 +- .../close-notification-modal.component.ts | 7 +- .../decline-notification-modal.component.ts | 7 +- frontend/src/assets/locales/de/common.json | 42 ++++++ frontend/src/assets/locales/en/common.json | 42 ++++++ 15 files changed, 227 insertions(+), 126 deletions(-) diff --git a/frontend/src/app/modules/page/notifications/detail/notification-detail.component.html b/frontend/src/app/modules/page/notifications/detail/notification-detail.component.html index 4ddcb98805..322edbf532 100644 --- a/frontend/src/app/modules/page/notifications/detail/notification-detail.component.html +++ b/frontend/src/app/modules/page/notifications/detail/notification-detail.component.html @@ -157,7 +157,6 @@ (confirmActionCompleted)="handleConfirmActionCompletedEvent()" [helperService]="helperService" [selectedNotification]="selectedNotification" - [translationContext]="TranslationContext.COMMONALERT" >
diff --git a/frontend/src/app/modules/page/notifications/detail/notification-detail.component.ts b/frontend/src/app/modules/page/notifications/detail/notification-detail.component.ts index 1b9757e9e0..06b528a4b8 100644 --- a/frontend/src/app/modules/page/notifications/detail/notification-detail.component.ts +++ b/frontend/src/app/modules/page/notifications/detail/notification-detail.component.ts @@ -206,7 +206,6 @@ export class NotificationDetailComponent implements AfterViewInit, OnDestroy { .subscribe(); } - protected readonly TranslationContext = TranslationContext; protected readonly NotificationType = NotificationType; protected readonly NotificationAction = NotificationAction; diff --git a/frontend/src/app/modules/page/notifications/presentation/notifications.component.html b/frontend/src/app/modules/page/notifications/presentation/notifications.component.html index f4d0e22639..19f3909881 100644 --- a/frontend/src/app/modules/page/notifications/presentation/notifications.component.html +++ b/frontend/src/app/modules/page/notifications/presentation/notifications.component.html @@ -20,7 +20,6 @@ diff --git a/frontend/src/app/modules/shared/components/notification-common-modal/notification-common-modal.component.ts b/frontend/src/app/modules/shared/components/notification-common-modal/notification-common-modal.component.ts index cbbef22108..ad9c606a4e 100644 --- a/frontend/src/app/modules/shared/components/notification-common-modal/notification-common-modal.component.ts +++ b/frontend/src/app/modules/shared/components/notification-common-modal/notification-common-modal.component.ts @@ -16,79 +16,87 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -import { Component, EventEmitter, Input, Optional, Output, ViewChild } from '@angular/core'; -import { NotificationHelperService } from '@page/notifications/core/notification-helper.service'; -import { NotificationsFacade } from '@page/notifications/core/notifications.facade'; -import { Notification } from '@shared/model/notification.model'; -import { TranslationContext } from '@shared/model/translation-context.model'; -import { AcceptNotificationModalComponent } from '@shared/modules/notification/modal/accept/accept-notification-modal.component'; -import { AcknowledgeNotificationModalComponent } from '@shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component'; -import { ApproveNotificationModalComponent } from '@shared/modules/notification/modal/approve/approve-notification-modal.component'; -import { CancelNotificationModalComponent } from '@shared/modules/notification/modal/cancel/cancel-notification-modal.component'; -import { CloseNotificationModalComponent } from '@shared/modules/notification/modal/close/close-notification-modal.component'; -import { DeclineNotificationModalComponent } from '@shared/modules/notification/modal/decline/decline-notification-modal.component'; +import {Component, EventEmitter, Input, Optional, Output, ViewChild} from '@angular/core'; +import {NotificationHelperService} from '@page/notifications/core/notification-helper.service'; +import {NotificationsFacade} from '@page/notifications/core/notifications.facade'; +import {Notification} from '@shared/model/notification.model'; +import { + AcceptNotificationModalComponent +} from '@shared/modules/notification/modal/accept/accept-notification-modal.component'; +import { + AcknowledgeNotificationModalComponent +} from '@shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component'; +import { + ApproveNotificationModalComponent +} from '@shared/modules/notification/modal/approve/approve-notification-modal.component'; +import { + CancelNotificationModalComponent +} from '@shared/modules/notification/modal/cancel/cancel-notification-modal.component'; +import { + CloseNotificationModalComponent +} from '@shared/modules/notification/modal/close/close-notification-modal.component'; +import { + DeclineNotificationModalComponent +} from '@shared/modules/notification/modal/decline/decline-notification-modal.component'; @Component({ - selector: 'app-notification-common-modal', - templateUrl: './notification-common-modal.component.html', + selector: 'app-notification-common-modal', + templateUrl: './notification-common-modal.component.html', }) export class NotificationCommonModalComponent { - @Input() selectedNotification: Notification; - @Input() translationContext: TranslationContext; - @Input() helperService: NotificationHelperService; - @Output() confirmActionCompleted = new EventEmitter(); + @Input() selectedNotification: Notification; + @Input() helperService: NotificationHelperService; + @Output() confirmActionCompleted = new EventEmitter(); - @ViewChild(ApproveNotificationModalComponent) approveModal: ApproveNotificationModalComponent; - @ViewChild(CloseNotificationModalComponent) closeModal: CloseNotificationModalComponent; - @ViewChild(CancelNotificationModalComponent) cancelModal: CancelNotificationModalComponent; + @ViewChild(ApproveNotificationModalComponent) approveModal: ApproveNotificationModalComponent; + @ViewChild(CloseNotificationModalComponent) closeModal: CloseNotificationModalComponent; + @ViewChild(CancelNotificationModalComponent) cancelModal: CancelNotificationModalComponent; - @ViewChild(AcceptNotificationModalComponent) acceptModal: AcceptNotificationModalComponent; - @ViewChild(AcknowledgeNotificationModalComponent) acknowledgeModal: AcknowledgeNotificationModalComponent; - @ViewChild(DeclineNotificationModalComponent) declineModal: DeclineNotificationModalComponent; + @ViewChild(AcceptNotificationModalComponent) acceptModal: AcceptNotificationModalComponent; + @ViewChild(AcknowledgeNotificationModalComponent) acknowledgeModal: AcknowledgeNotificationModalComponent; + @ViewChild(DeclineNotificationModalComponent) declineModal: DeclineNotificationModalComponent; // TODO do not delete the facade here. This will lead to a nullpointer exception within the modal call. - public constructor( - @Optional() private readonly notificationsFacade: NotificationsFacade, - ) { - } - + public constructor( + @Optional() private readonly notificationsFacade: NotificationsFacade, + ) { + } - public handleModalConfirmActionCompletedEvent(): void { - this.confirmActionCompleted.emit(); - } - public show(modalContext: string, notification?: Notification) { - let notificationToShow = notification || this.selectedNotification; - switch (modalContext) { - case 'approve': { - this.approveModal.show(notificationToShow); - break; - } - case 'close': { - this.closeModal.show(notificationToShow); - break; - } - case 'cancel': { - this.cancelModal.show(notificationToShow); - break; - } - case 'accept': { - this.acceptModal.show(notificationToShow); - break; - } - case 'acknowledge': { - this.acknowledgeModal.show(notificationToShow); - break; - } - case 'decline': { - this.declineModal.show(notificationToShow); - break; - } + public handleModalConfirmActionCompletedEvent(): void { + this.confirmActionCompleted.emit(); } - } + public show(modalContext: string, notification?: Notification) { + let notificationToShow = notification || this.selectedNotification; + switch (modalContext) { + case 'approve': { + this.approveModal.show(notificationToShow); + break; + } + case 'close': { + this.closeModal.show(notificationToShow); + break; + } + case 'cancel': { + this.cancelModal.show(notificationToShow); + break; + } + case 'accept': { + this.acceptModal.show(notificationToShow); + break; + } + case 'acknowledge': { + this.acknowledgeModal.show(notificationToShow); + break; + } + case 'decline': { + this.declineModal.show(notificationToShow); + break; + } + } + } - protected readonly TranslationContext = TranslationContext; } diff --git a/frontend/src/app/modules/shared/helper/notification-helper.ts b/frontend/src/app/modules/shared/helper/notification-helper.ts index 85a1385ce5..359744cb5f 100644 --- a/frontend/src/app/modules/shared/helper/notification-helper.ts +++ b/frontend/src/app/modules/shared/helper/notification-helper.ts @@ -18,7 +18,8 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -import { NotificationDeeplinkFilter } from '@shared/model/notification.model'; +import {Notification, NotificationDeeplinkFilter, NotificationType} from '@shared/model/notification.model'; +import {TranslationContext} from "@shared/model/translation-context.model"; export interface DeeplinkNotificationFilter { receivedFilter: NotificationDeeplinkFilter, @@ -38,3 +39,11 @@ export function createDeeplinkNotificationFilter(params: any): DeeplinkNotificat return { receivedFilter, sentFilter }; } } + +export function getTranslationContext(notification: Notification):TranslationContext{ + if (notification?.type === NotificationType.ALERT.valueOf()){ + return TranslationContext.COMMONALERT + } else { + return TranslationContext.COMMONINVESTIGATION; + } +} diff --git a/frontend/src/app/modules/shared/model/translation-context.model.ts b/frontend/src/app/modules/shared/model/translation-context.model.ts index 2db479e94e..2411ae3e29 100644 --- a/frontend/src/app/modules/shared/model/translation-context.model.ts +++ b/frontend/src/app/modules/shared/model/translation-context.model.ts @@ -17,5 +17,6 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ export enum TranslationContext { - COMMONALERT = 'commonAlert' + COMMONALERT = 'commonAlert', + COMMONINVESTIGATION = 'commonInvestigation' } diff --git a/frontend/src/app/modules/shared/modules/notification/modal/accept/accept-notification-modal.component.ts b/frontend/src/app/modules/shared/modules/notification/modal/accept/accept-notification-modal.component.ts index 754a937aad..228b9879d7 100644 --- a/frontend/src/app/modules/shared/modules/notification/modal/accept/accept-notification-modal.component.ts +++ b/frontend/src/app/modules/shared/modules/notification/modal/accept/accept-notification-modal.component.ts @@ -27,6 +27,7 @@ import { TranslationContext } from '@shared/model/translation-context.model'; import { ModalData } from '@shared/modules/modal/core/modal.model'; import { ModalService } from '@shared/modules/modal/core/modal.service'; import { Observable } from 'rxjs'; +import {getTranslationContext} from "@shared/helper/notification-helper"; @Component({ selector: 'app-accept-notification-modal', @@ -60,17 +61,17 @@ export class AcceptNotificationModalComponent { this.acceptCall(notification.id, reason).subscribe({ next: () => { - this.toastService.success(this.translationContext + '.modal.successfullyAccepted'); + this.toastService.success(getTranslationContext(notification) + '.modal.successfullyAccepted'); this.confirmActionCompleted.emit(); }, error: () => { - this.toastService.error(this.translationContext + '.modal.failedAccept'); + this.toastService.error(getTranslationContext(notification) + '.modal.failedAccept'); }, }); }; const options: ModalData = { - title: this.translationContext + '.modal.acceptTitle', + title: getTranslationContext(notification) + '.modal.acceptTitle', buttonRight: 'actions.accept', template: this.modal, formGroup: this.formGroup, diff --git a/frontend/src/app/modules/shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component.ts b/frontend/src/app/modules/shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component.ts index c1a82ec6e7..e67727b848 100644 --- a/frontend/src/app/modules/shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component.ts +++ b/frontend/src/app/modules/shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component.ts @@ -26,6 +26,7 @@ import { TranslationContext } from '@shared/model/translation-context.model'; import { ModalData } from '@shared/modules/modal/core/modal.model'; import { ModalService } from '@shared/modules/modal/core/modal.service'; import { Observable } from 'rxjs'; +import {getTranslationContext} from "@shared/helper/notification-helper"; @Component({ selector: 'app-acknowledge-notification-modal', @@ -49,17 +50,17 @@ export class AcknowledgeNotificationModalComponent { this.acknowledgeCall(notification.id).subscribe({ next: () => { - this.toastService.success(this.translationContext + '.modal.successfullyAcknowledged'); + this.toastService.success(getTranslationContext(notification) + '.modal.successfullyAcknowledged'); this.confirmActionCompleted.emit(); }, error: () => { - this.toastService.error(this.translationContext + '.modal.failedAcknowledge'); + this.toastService.error(getTranslationContext(notification) + '.modal.failedAcknowledge'); }, }); }; const options: ModalData = { - title: this.translationContext + '.modal.acknowledgeTitle', + title: getTranslationContext(notification) + '.modal.acknowledgeTitle', buttonRight: 'actions.acknowledge', template: this.modal, diff --git a/frontend/src/app/modules/shared/modules/notification/modal/approve/approve-notification-modal.component.ts b/frontend/src/app/modules/shared/modules/notification/modal/approve/approve-notification-modal.component.ts index 0f21b9cf63..49bccbc1bb 100644 --- a/frontend/src/app/modules/shared/modules/notification/modal/approve/approve-notification-modal.component.ts +++ b/frontend/src/app/modules/shared/modules/notification/modal/approve/approve-notification-modal.component.ts @@ -19,54 +19,57 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -import { Component, EventEmitter, Input, Output, TemplateRef, ViewChild } from '@angular/core'; -import { ToastService } from '@shared/components/toasts/toast.service'; -import { Notification } from '@shared/model/notification.model'; -import { TranslationContext } from '@shared/model/translation-context.model'; -import { ModalData } from '@shared/modules/modal/core/modal.model'; -import { ModalService } from '@shared/modules/modal/core/modal.service'; -import { Observable } from 'rxjs'; +import {Component, EventEmitter, Input, Output, TemplateRef, ViewChild} from '@angular/core'; +import {ToastService} from '@shared/components/toasts/toast.service'; +import {Notification} from '@shared/model/notification.model'; +import {TranslationContext} from '@shared/model/translation-context.model'; +import {ModalData} from '@shared/modules/modal/core/modal.model'; +import {ModalService} from '@shared/modules/modal/core/modal.service'; +import {Observable} from 'rxjs'; +import {getTranslationContext} from "@shared/helper/notification-helper"; @Component({ - selector: 'app-approve-notification-modal', - templateUrl: './approve-notification-modal.component.html', + selector: 'app-approve-notification-modal', + templateUrl: './approve-notification-modal.component.html', }) export class ApproveNotificationModalComponent { - @ViewChild('Modal') modal: TemplateRef; - @Input() approveCall: (id: string) => Observable; - @Input() translationContext: TranslationContext; - @Output() confirmActionCompleted = new EventEmitter(); + @ViewChild('Modal') modal: TemplateRef; + @Input() approveCall: (id: string) => Observable; + @Input() translationContext: TranslationContext; + @Output() confirmActionCompleted = new EventEmitter(); - public notification: Notification; + public notification: Notification; - constructor(private readonly toastService: ToastService, private readonly confirmModalService: ModalService) { - this.toastService.retryAction.subscribe(() => this.show(this.notification)) - } + constructor(private readonly toastService: ToastService, private readonly confirmModalService: ModalService) { + this.toastService.retryAction.subscribe(() => this.show(this.notification)); - public show(notification: Notification): void { - this.notification = notification; - const onConfirm = (isConfirmed: boolean) => { - if (!isConfirmed) return; + } - this.approveCall(notification.id).subscribe({ - next: () => { - this.toastService.success(this.translationContext + '.modal.successfullyApproved'); - this.confirmActionCompleted.emit(); - }, - error: (err) => { - this.toastService.error(this.translationContext + '.modal.failedApprove', 15000,true); - }, - }); - }; - const options: ModalData = { - title: this.translationContext + '.modal.approvalTitle', - buttonRight: 'actions.confirm', + public show(notification: Notification): void { + this.notification = notification; + const onConfirm = (isConfirmed: boolean) => { + if (!isConfirmed) return; - template: this.modal, - onConfirm, - }; + this.approveCall(notification.id).subscribe({ + next: () => { + this.toastService.success(getTranslationContext(notification) + '.modal.successfullyApproved'); + this.confirmActionCompleted.emit(); + }, + error: (err) => { + this.toastService.error(getTranslationContext(notification)+ '.modal.failedApprove', 15000, true); + }, + }); + }; - this.confirmModalService.open(options); - } + const options: ModalData = { + title: getTranslationContext(notification) + '.modal.approvalTitle', + buttonRight: 'actions.confirm', + + template: this.modal, + onConfirm, + }; + + this.confirmModalService.open(options); + } } diff --git a/frontend/src/app/modules/shared/modules/notification/modal/cancel/cancel-notification-modal.component.ts b/frontend/src/app/modules/shared/modules/notification/modal/cancel/cancel-notification-modal.component.ts index de0b9ce3b1..a6ba79e601 100644 --- a/frontend/src/app/modules/shared/modules/notification/modal/cancel/cancel-notification-modal.component.ts +++ b/frontend/src/app/modules/shared/modules/notification/modal/cancel/cancel-notification-modal.component.ts @@ -26,6 +26,7 @@ import { TranslationContext } from '@shared/model/translation-context.model'; import { ModalData } from '@shared/modules/modal/core/modal.model'; import { ModalService } from '@shared/modules/modal/core/modal.service'; import { Observable } from 'rxjs'; +import {getTranslationContext} from "@shared/helper/notification-helper"; @Component({ selector: 'app-cancel-notification-modal', @@ -52,18 +53,18 @@ export class CancelNotificationModalComponent { this.cancelCall(notification.id).subscribe({ next: () => { - this.toastService.success(this.translationContext + '.modal.successfullyCanceled'); + this.toastService.success(getTranslationContext(notification) + '.modal.successfullyCanceled'); this.confirmActionCompleted.emit(); }, error: () => { - this.toastService.error(this.translationContext + '.modal.failedCancel'); + this.toastService.error(getTranslationContext(notification) + '.modal.failedCancel'); }, }); }; const options: ModalData = { - title: this.translationContext + '.modal.cancellationTitle', - type: this.translationContext + '.modal.cancellationConfirmationLabel', + title: getTranslationContext(notification) + '.modal.cancellationTitle', + type: getTranslationContext(notification) + '.modal.cancellationConfirmationLabel', buttonRight: 'actions.cancellationConfirm', primaryButtonColour: 'warn', notificationId: this.notification.id, diff --git a/frontend/src/app/modules/shared/modules/notification/modal/close/close-notification-modal.component.ts b/frontend/src/app/modules/shared/modules/notification/modal/close/close-notification-modal.component.ts index 66b121d5b6..65c62e5f38 100644 --- a/frontend/src/app/modules/shared/modules/notification/modal/close/close-notification-modal.component.ts +++ b/frontend/src/app/modules/shared/modules/notification/modal/close/close-notification-modal.component.ts @@ -27,6 +27,7 @@ import { TranslationContext } from '@shared/model/translation-context.model'; import { ModalData } from '@shared/modules/modal/core/modal.model'; import { ModalService } from '@shared/modules/modal/core/modal.service'; import { Observable } from 'rxjs'; +import {getTranslationContext} from "@shared/helper/notification-helper"; @Component({ selector: 'app-close-notification-modal', @@ -58,17 +59,17 @@ export class CloseNotificationModalComponent { this.closeCall(notification.id, reason).subscribe({ next: () => { - this.toastService.success(this.translationContext + '.modal.successfullyClosed'); + this.toastService.success(getTranslationContext(notification) + '.modal.successfullyClosed'); this.confirmActionCompleted.emit(); }, error: () => { - this.toastService.error(this.translationContext + '.modal.failedClose'); + this.toastService.error(getTranslationContext(notification) + '.modal.failedClose'); }, }); }; const options: ModalData = { - title: this.translationContext + '.modal.closeTitle', + title: getTranslationContext(notification) + '.modal.closeTitle', buttonRight: 'actions.close', template: this.modal, diff --git a/frontend/src/app/modules/shared/modules/notification/modal/decline/decline-notification-modal.component.ts b/frontend/src/app/modules/shared/modules/notification/modal/decline/decline-notification-modal.component.ts index 48d37b730c..43ca92a80e 100644 --- a/frontend/src/app/modules/shared/modules/notification/modal/decline/decline-notification-modal.component.ts +++ b/frontend/src/app/modules/shared/modules/notification/modal/decline/decline-notification-modal.component.ts @@ -27,6 +27,7 @@ import { TranslationContext } from '@shared/model/translation-context.model'; import { ModalData } from '@shared/modules/modal/core/modal.model'; import { ModalService } from '@shared/modules/modal/core/modal.service'; import { Observable } from 'rxjs'; +import {getTranslationContext} from "@shared/helper/notification-helper"; @Component({ selector: 'app-decline-notification-modal', @@ -58,17 +59,17 @@ export class DeclineNotificationModalComponent { this.declineCall(notification.id, reason).subscribe({ next: () => { - this.toastService.success(this.translationContext + '.modal.successfullyDeclined'); + this.toastService.success(getTranslationContext(notification) + '.modal.successfullyDeclined'); this.confirmActionCompleted.emit(); }, error: () => { - this.toastService.error(this.translationContext + '.modal.failedDecline'); + this.toastService.error(getTranslationContext(notification) + '.modal.failedDecline'); }, }); }; const options: ModalData = { - title: this.translationContext + '.modal.declineTitle', + title: getTranslationContext(notification) + '.modal.declineTitle', buttonRight: 'actions.decline', template: this.modal, diff --git a/frontend/src/assets/locales/de/common.json b/frontend/src/assets/locales/de/common.json index fc586d945e..9f9eb9088d 100644 --- a/frontend/src/assets/locales/de/common.json +++ b/frontend/src/assets/locales/de/common.json @@ -226,6 +226,48 @@ "emptyRange": "0 von {{length}}", "range": "{{startIndex}} – {{endIndex}} von {{length}}" }, + "commonInvestigation": { + "viewAll": "Alle anzeigen", + "tabs": { + "received": "Zugewiesene", + "queuedAndRequested": "Erstellte und Angefragte" + }, + "status": { + "RECEIVED": "Erhalten", + "CREATED": "Erstellt", + "SENT": "Zugestellt", + "CANCELED": "Abgebrochen", + "CLOSED": "Abgeschlossen", + "ACCEPTED": "Akzeptiert", + "ACKNOWLEDGED": "Bestätigt", + "DECLINED": "Abgelehnt" + }, + "modal": { + "acceptTitle": "Annehmen der Untersuchung", + "acceptReasonHint": "Geben Sie den Grund für die Annahme dieser Untersuchung ein.", + "acknowledgeTitle": "Bestätigung der Untersuchung", + "approvalTitle": "Genehmigung der Untersuchung", + "closeTitle": "Schließen der Untersuchung", + "closeReasonHint": "Geben Sie den Grund für das Schließen ein.", + "cancellationTitle": "Abbruch der Untersuchung", + "cancellationHint": "Geben Sie die ID der Untersuchung ein, um Ihre Abbruchanfrage zu bestätigen.", + "cancellationConfirmationLabel": "Ja, ich bestätige die Stornierung der Untersuchung mit der ID: ", + "declineTitle": "Ablehnung der Untersuchung", + "declineReasonHint": "Geben Sie den Grund für die Ablehnung dieser Untersuchung ein.", + "successfullyAccepted": "Untersuchung wurde erfolgreich angenommen.", + "successfullyAcknowledged": "Untersuchung wurde erfolgreich bestätigt", + "successfullyApproved": "Untersuchung wurde erfolgreich genehmigt.", + "successfullyCanceled": "Untersuchung wurde erfolgreich abgebrochen.", + "successfullyClosed": "Untersuchung wurde erfolgreich geschlossen.", + "successfullyDeclined": "Untersuchung wurde erfolgreich abgelehnt.", + "failedAccept": "Untersuchung konnte nicht akzeptiert werden, bitte versuchen Sie es erneut.", + "failedAcknowledge": "Untersuchung konnte nicht bestätigt werden, bitte versuchen Sie es erneut.", + "failedApprove": "Die Untersuchung konnte nicht genehmigt werden, bitte versuchen Sie es erneut.", + "failedCancel": "Die Untersuchung konnte nicht gelöscht werden, bitte versuchen Sie es erneut.", + "failedClose": "Die Untersuchung konnte nicht abgeschlossen werden, bitte versuchen Sie es erneut.", + "failedDecline": "Untersuchung konnte nicht abgelehnt werden, bitte versuchen Sie es erneut." + } + }, "commonAlert": { "viewAll": "Alle anzeigen", "tabs": { diff --git a/frontend/src/assets/locales/en/common.json b/frontend/src/assets/locales/en/common.json index 0cda9ef316..c94cdaf946 100644 --- a/frontend/src/assets/locales/en/common.json +++ b/frontend/src/assets/locales/en/common.json @@ -227,6 +227,48 @@ "emptyRange": "0 of {{length}}", "range": "{{startIndex}} – {{endIndex}} of {{length}}" }, + "commonInvestigation": { + "viewAll": "View all", + "tabs": { + "received": "Received", + "queuedAndRequested": "Queued & Requested" + }, + "status": { + "SENT": "Requested", + "CANCELED": "Cancelled", + "CLOSED": "Closed", + "CREATED": "Queued", + "RECEIVED": "Received", + "ACCEPTED": "Accepted", + "ACKNOWLEDGED": "Acknowledged", + "DECLINED": "Declined" + }, + "modal": { + "acceptTitle": "Accept of investigation", + "acceptReasonHint": "Enter the reason for accepting this investigation.", + "acknowledgeTitle": "Acknowledgment of investigation", + "approvalTitle": "Approval of investigation", + "closeTitle": "Close of investigation", + "closeReasonHint": "Enter the reason for close action.", + "cancellationTitle": "Cancellation of investigation", + "cancellationHint": "Enter the ID of the investigation to confirm your cancellation.", + "cancellationConfirmationLabel": "Yes, I confirm that I want to cancel the investigation with the ID: ", + "declineTitle": "Decline of investigation", + "declineReasonHint": "Enter the reason for declining this investigation.", + "successfullyAccepted": "Investigation was accepted successfully.", + "successfullyAcknowledged": "Investigation was acknowledged successfully.", + "successfullyApproved": "Investigation was approved successfully.", + "successfullyCanceled": "Investigation was canceled successfully.", + "successfullyClosed": "Investigation was closed successfully.", + "successfullyDeclined": "Investigation was declined successfully.", + "failedAccept": "Investigation failed to accept, please try again.", + "failedAcknowledge": "Investigation failed to acknowledge, please try again.", + "failedApprove": "Investigation failed to approve, please try again.", + "failedCancel": "Investigation failed to cancel, please try again.", + "failedClose": "Investigation failed to close, please try again.", + "failedDecline": "Investigation failed to decline, please try again." + } + }, "commonAlert": { "viewAll": "View all", "tabs": { From 1f43f417b08d120423f0a09cfcfcf369355270ab Mon Sep 17 00:00:00 2001 From: Maximilian Wesener Date: Thu, 28 Mar 2024 17:02:34 +0100 Subject: [PATCH 03/14] chore(feature): 616 - Fixed modal translations. --- .../modal/modalTestHelper.spec.ts | 45 ++++++++++++------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/frontend/src/app/modules/shared/modules/notification/modal/modalTestHelper.spec.ts b/frontend/src/app/modules/shared/modules/notification/modal/modalTestHelper.spec.ts index 57e218e763..64972dab2b 100644 --- a/frontend/src/app/modules/shared/modules/notification/modal/modalTestHelper.spec.ts +++ b/frontend/src/app/modules/shared/modules/notification/modal/modalTestHelper.spec.ts @@ -19,22 +19,34 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -import { AfterViewInit, Component, Input, ViewChild } from '@angular/core'; -import { CalendarDateModel } from '@core/model/calendar-date.model'; -import { Notification, NotificationStatus } from '@shared/model/notification.model'; -import { Severity } from '@shared/model/severity.model'; -import { TranslationContext } from '@shared/model/translation-context.model'; -import { AcceptNotificationModalComponent } from '@shared/modules/notification/modal/accept/accept-notification-modal.component'; -import { AcknowledgeNotificationModalComponent } from '@shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component'; -import { ApproveNotificationModalComponent } from '@shared/modules/notification/modal/approve/approve-notification-modal.component'; -import { CancelNotificationModalComponent } from '@shared/modules/notification/modal/cancel/cancel-notification-modal.component'; -import { CloseNotificationModalComponent } from '@shared/modules/notification/modal/close/close-notification-modal.component'; -import { DeclineNotificationModalComponent } from '@shared/modules/notification/modal/decline/decline-notification-modal.component'; -import { NotificationModule } from '@shared/modules/notification/notification.module'; -import { SharedModule } from '@shared/shared.module'; -import { TemplateModule } from '@shared/template.module'; -import { renderComponent } from '@tests/test-render.utils'; -import { of } from 'rxjs'; +import {AfterViewInit, Component, Input, ViewChild} from '@angular/core'; +import {CalendarDateModel} from '@core/model/calendar-date.model'; +import {Notification, NotificationStatus, NotificationType} from '@shared/model/notification.model'; +import {Severity} from '@shared/model/severity.model'; +import {TranslationContext} from '@shared/model/translation-context.model'; +import { + AcceptNotificationModalComponent +} from '@shared/modules/notification/modal/accept/accept-notification-modal.component'; +import { + AcknowledgeNotificationModalComponent +} from '@shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component'; +import { + ApproveNotificationModalComponent +} from '@shared/modules/notification/modal/approve/approve-notification-modal.component'; +import { + CancelNotificationModalComponent +} from '@shared/modules/notification/modal/cancel/cancel-notification-modal.component'; +import { + CloseNotificationModalComponent +} from '@shared/modules/notification/modal/close/close-notification-modal.component'; +import { + DeclineNotificationModalComponent +} from '@shared/modules/notification/modal/decline/decline-notification-modal.component'; +import {NotificationModule} from '@shared/modules/notification/notification.module'; +import {SharedModule} from '@shared/shared.module'; +import {TemplateModule} from '@shared/template.module'; +import {renderComponent} from '@tests/test-render.utils'; +import {of} from 'rxjs'; @Component({ selector: '', @@ -151,6 +163,7 @@ export const notificationTemplate: Notification = { assetIds: [ 'MOCK_part_1' ], status: null, severity: Severity.MINOR, + type: NotificationType.ALERT, createdDate: new CalendarDateModel('2022-05-01T10:34:12.000Z'), }; From 848c7c89641ef552943de479e0443615877e4835 Mon Sep 17 00:00:00 2001 From: Maximilian Wesener Date: Mon, 1 Apr 2024 22:25:39 +0200 Subject: [PATCH 04/14] chore(feature): 616 - Fixed modal translations. --- .../core/notification-helper.service.ts | 21 ++ .../notification-common-modal.component.html | 30 +-- .../notification-common-modal.component.ts | 117 ++++----- ...ccept-notification-modal.component.spec.ts | 78 ------ .../accept-notification-modal.component.ts | 83 ------- ...nowledge-notification-modal.component.html | 24 -- ...ledge-notification-modal.component.spec.ts | 52 ---- ...cknowledge-notification-modal.component.ts | 72 ------ .../notification-action-modal.component.html} | 6 +- .../notification-action-modal.component.ts | 173 +++++++++++++ .../approve-notification-modal.component.html | 24 -- ...prove-notification-modal.component.spec.ts | 50 ---- .../approve-notification-modal.component.ts | 75 ------ .../cancel-notification-modal.component.html | 24 -- ...ancel-notification-modal.component.spec.ts | 43 ---- .../cancel-notification-modal.component.ts | 77 ------ .../close-notification-modal.component.html | 29 --- ...close-notification-modal.component.spec.ts | 78 ------ .../close-notification-modal.component.ts | 82 ------ .../decline-notification-modal.component.html | 29 --- ...cline-notification-modal.component.spec.ts | 78 ------ .../decline-notification-modal.component.ts | 82 ------ .../modal/modalTestHelper.spec.ts | 234 ------------------ .../notification/notification.module.ts | 21 +- 24 files changed, 251 insertions(+), 1331 deletions(-) delete mode 100644 frontend/src/app/modules/shared/modules/notification/modal/accept/accept-notification-modal.component.spec.ts delete mode 100644 frontend/src/app/modules/shared/modules/notification/modal/accept/accept-notification-modal.component.ts delete mode 100644 frontend/src/app/modules/shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component.html delete mode 100644 frontend/src/app/modules/shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component.spec.ts delete mode 100644 frontend/src/app/modules/shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component.ts rename frontend/src/app/modules/shared/modules/notification/modal/{accept/accept-notification-modal.component.html => actions/notification-action-modal.component.html} (87%) create mode 100644 frontend/src/app/modules/shared/modules/notification/modal/actions/notification-action-modal.component.ts delete mode 100644 frontend/src/app/modules/shared/modules/notification/modal/approve/approve-notification-modal.component.html delete mode 100644 frontend/src/app/modules/shared/modules/notification/modal/approve/approve-notification-modal.component.spec.ts delete mode 100644 frontend/src/app/modules/shared/modules/notification/modal/approve/approve-notification-modal.component.ts delete mode 100644 frontend/src/app/modules/shared/modules/notification/modal/cancel/cancel-notification-modal.component.html delete mode 100644 frontend/src/app/modules/shared/modules/notification/modal/cancel/cancel-notification-modal.component.spec.ts delete mode 100644 frontend/src/app/modules/shared/modules/notification/modal/cancel/cancel-notification-modal.component.ts delete mode 100644 frontend/src/app/modules/shared/modules/notification/modal/close/close-notification-modal.component.html delete mode 100644 frontend/src/app/modules/shared/modules/notification/modal/close/close-notification-modal.component.spec.ts delete mode 100644 frontend/src/app/modules/shared/modules/notification/modal/close/close-notification-modal.component.ts delete mode 100644 frontend/src/app/modules/shared/modules/notification/modal/decline/decline-notification-modal.component.html delete mode 100644 frontend/src/app/modules/shared/modules/notification/modal/decline/decline-notification-modal.component.spec.ts delete mode 100644 frontend/src/app/modules/shared/modules/notification/modal/decline/decline-notification-modal.component.ts delete mode 100644 frontend/src/app/modules/shared/modules/notification/modal/modalTestHelper.spec.ts diff --git a/frontend/src/app/modules/page/notifications/core/notification-helper.service.ts b/frontend/src/app/modules/page/notifications/core/notification-helper.service.ts index 2407130f1c..f687662415 100644 --- a/frontend/src/app/modules/page/notifications/core/notification-helper.service.ts +++ b/frontend/src/app/modules/page/notifications/core/notification-helper.service.ts @@ -19,6 +19,7 @@ import { Injectable } from '@angular/core'; import { NotificationsFacade } from '@page/notifications/core/notifications.facade'; +import { NotificationStatus } from '@shared/model/notification.model'; import { Observable } from 'rxjs'; @Injectable({ @@ -52,4 +53,24 @@ export class NotificationHelperService { return this.notificationsFacade.declineNotification(id, reason); } + modalCallback(status: NotificationStatus, id: string, reason?: string): Observable { + switch (status) { + case NotificationStatus.ACKNOWLEDGED: + return this.notificationsFacade.acknowledgeNotification(id); + case NotificationStatus.APPROVED: + return this.notificationsFacade.approveNotification(id); + case NotificationStatus.CANCELED: + return this.notificationsFacade.cancelNotification(id); + case NotificationStatus.CLOSED: + return this.notificationsFacade.closeNotification(id, reason); + case NotificationStatus.ACCEPTED: + return this.notificationsFacade.acceptNotification(id, reason); + case NotificationStatus.DECLINED: + return this.notificationsFacade.declineNotification(id, reason); + default: + return null; + } + } + + } diff --git a/frontend/src/app/modules/shared/components/notification-common-modal/notification-common-modal.component.html b/frontend/src/app/modules/shared/components/notification-common-modal/notification-common-modal.component.html index 4b925a8ee8..82aac18b29 100644 --- a/frontend/src/app/modules/shared/components/notification-common-modal/notification-common-modal.component.html +++ b/frontend/src/app/modules/shared/components/notification-common-modal/notification-common-modal.component.html @@ -16,30 +16,8 @@ SPDX-License-Identifier: Apache-2.0 --> - + - - - - - - - - + [callback]="helperService.modalCallback.bind(this)" +> diff --git a/frontend/src/app/modules/shared/components/notification-common-modal/notification-common-modal.component.ts b/frontend/src/app/modules/shared/components/notification-common-modal/notification-common-modal.component.ts index ad9c606a4e..bf12e07272 100644 --- a/frontend/src/app/modules/shared/components/notification-common-modal/notification-common-modal.component.ts +++ b/frontend/src/app/modules/shared/components/notification-common-modal/notification-common-modal.component.ts @@ -16,87 +16,64 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -import {Component, EventEmitter, Input, Optional, Output, ViewChild} from '@angular/core'; -import {NotificationHelperService} from '@page/notifications/core/notification-helper.service'; -import {NotificationsFacade} from '@page/notifications/core/notifications.facade'; -import {Notification} from '@shared/model/notification.model'; -import { - AcceptNotificationModalComponent -} from '@shared/modules/notification/modal/accept/accept-notification-modal.component'; -import { - AcknowledgeNotificationModalComponent -} from '@shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component'; -import { - ApproveNotificationModalComponent -} from '@shared/modules/notification/modal/approve/approve-notification-modal.component'; -import { - CancelNotificationModalComponent -} from '@shared/modules/notification/modal/cancel/cancel-notification-modal.component'; -import { - CloseNotificationModalComponent -} from '@shared/modules/notification/modal/close/close-notification-modal.component'; -import { - DeclineNotificationModalComponent -} from '@shared/modules/notification/modal/decline/decline-notification-modal.component'; +import { Component, EventEmitter, Input, Optional, Output, ViewChild } from '@angular/core'; +import { NotificationHelperService } from '@page/notifications/core/notification-helper.service'; +import { NotificationsFacade } from '@page/notifications/core/notifications.facade'; +import { Notification, NotificationStatus } from '@shared/model/notification.model'; +import { NotificationActionModalComponent } from '@shared/modules/notification/modal/actions/notification-action-modal.component'; @Component({ - selector: 'app-notification-common-modal', - templateUrl: './notification-common-modal.component.html', + selector: 'app-notification-common-modal', + templateUrl: './notification-common-modal.component.html', }) export class NotificationCommonModalComponent { - @Input() selectedNotification: Notification; - @Input() helperService: NotificationHelperService; - @Output() confirmActionCompleted = new EventEmitter(); + @Input() selectedNotification: Notification; + @Input() helperService: NotificationHelperService; + @Output() confirmActionCompleted = new EventEmitter(); - - @ViewChild(ApproveNotificationModalComponent) approveModal: ApproveNotificationModalComponent; - @ViewChild(CloseNotificationModalComponent) closeModal: CloseNotificationModalComponent; - @ViewChild(CancelNotificationModalComponent) cancelModal: CancelNotificationModalComponent; - - @ViewChild(AcceptNotificationModalComponent) acceptModal: AcceptNotificationModalComponent; - @ViewChild(AcknowledgeNotificationModalComponent) acknowledgeModal: AcknowledgeNotificationModalComponent; - @ViewChild(DeclineNotificationModalComponent) declineModal: DeclineNotificationModalComponent; + @ViewChild(NotificationActionModalComponent) acknowledgeAndApproveModal: NotificationActionModalComponent; // TODO do not delete the facade here. This will lead to a nullpointer exception within the modal call. - public constructor( - @Optional() private readonly notificationsFacade: NotificationsFacade, - ) { - } + public constructor( + @Optional() private readonly notificationsFacade: NotificationsFacade, + ) { + } - public handleModalConfirmActionCompletedEvent(): void { - this.confirmActionCompleted.emit(); - } + public handleModalConfirmActionCompletedEvent(): void { + this.confirmActionCompleted.emit(); + } - public show(modalContext: string, notification?: Notification) { - let notificationToShow = notification || this.selectedNotification; - switch (modalContext) { - case 'approve': { - this.approveModal.show(notificationToShow); - break; - } - case 'close': { - this.closeModal.show(notificationToShow); - break; - } - case 'cancel': { - this.cancelModal.show(notificationToShow); - break; - } - case 'accept': { - this.acceptModal.show(notificationToShow); - break; - } - case 'acknowledge': { - this.acknowledgeModal.show(notificationToShow); - break; - } - case 'decline': { - this.declineModal.show(notificationToShow); - break; - } - } + public show(modalContext: string, notification?: Notification) { + let notificationToShow = notification || this.selectedNotification; + switch (modalContext) { + case 'approve': { + this.acknowledgeAndApproveModal.show(notificationToShow, NotificationStatus.APPROVED); + break; + } + case 'close': { + this.acknowledgeAndApproveModal.show(notificationToShow, NotificationStatus.CLOSED); + break; + } + case 'cancel': { + this.acknowledgeAndApproveModal.show(notificationToShow, NotificationStatus.CANCELED); + break; + } + case 'accept': { + this.acknowledgeAndApproveModal.show(notificationToShow, NotificationStatus.ACCEPTED); + break; + } + case 'acknowledge': { + this.acknowledgeAndApproveModal.show(notificationToShow, NotificationStatus.ACKNOWLEDGED); + break; + } + case 'decline': { + this.acknowledgeAndApproveModal.show(notificationToShow, NotificationStatus.DECLINED); + break; + } } + } + protected readonly NotificationStatus = NotificationStatus; } diff --git a/frontend/src/app/modules/shared/modules/notification/modal/accept/accept-notification-modal.component.spec.ts b/frontend/src/app/modules/shared/modules/notification/modal/accept/accept-notification-modal.component.spec.ts deleted file mode 100644 index 3794fb0dea..0000000000 --- a/frontend/src/app/modules/shared/modules/notification/modal/accept/accept-notification-modal.component.spec.ts +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2022, 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2022, 2023 ZF Friedrichshafen AG - * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -import { NotificationStatus } from '@shared/model/notification.model'; -import { AcceptNotificationModalComponent } from '@shared/modules/notification/modal/accept/accept-notification-modal.component'; -import { renderAcceptModal } from '@shared/modules/notification/modal/modalTestHelper.spec'; -import { fireEvent, screen, waitFor } from '@testing-library/angular'; -import { getRandomText } from '../../../../../../mocks/services/text-generator.helper'; - -describe('AcceptNotificationModalComponent', () => { - it('should create accept modal', async () => { - await renderAcceptModal(NotificationStatus.ACKNOWLEDGED); - const title = await waitFor(() => screen.getByText('commonAlert.modal.acceptTitle')); - const hint2 = await waitFor(() => screen.getByText('commonAlert.modal.acceptReasonHint')); - const buttonR = await waitFor(() => screen.getByText('actions.accept')); - - expect(title).toBeInTheDocument(); - expect(hint2).toBeInTheDocument(); - expect(buttonR).toBeInTheDocument(); - }); - - it('should render investigation description', async () => { - const { notification } = await renderAcceptModal(NotificationStatus.ACKNOWLEDGED); - const description = await waitFor(() => screen.getByText(notification.description)); - - expect(description).toBeInTheDocument(); - }); - - it('should check validation of textarea', async () => { - await renderAcceptModal(NotificationStatus.ACKNOWLEDGED); - fireEvent.click(await waitFor(() => screen.getByText('actions.accept'))); - - const textArea = await waitFor(() => screen.getByTestId('BaseInputElement-0')); - const errorMessage_1 = await waitFor(() => screen.getByText('errorMessage.required')); - expect(errorMessage_1).toBeInTheDocument(); - - fireEvent.input(textArea, { target: { value: 'Some Text' } }); - const errorMessage_2 = await waitFor(() => screen.getByText('errorMessage.minLength')); - expect(errorMessage_2).toBeInTheDocument(); - - fireEvent.input(textArea, { target: { value: getRandomText(1500) } }); - const errorMessage_3 = await waitFor(() => screen.getByText('errorMessage.maxLength')); - expect(errorMessage_3).toBeInTheDocument(); - - fireEvent.input(textArea, { target: { value: 'Some longer text with at least 15 chars' } }); - expect(errorMessage_1).not.toBeInTheDocument(); - expect(errorMessage_2).not.toBeInTheDocument(); - expect(errorMessage_3).not.toBeInTheDocument(); - }); - - it('should call close function', async () => { - await renderAcceptModal(NotificationStatus.ACKNOWLEDGED); - - const textArea: HTMLTextAreaElement = await waitFor(() => screen.getByTestId('BaseInputElement-0')); - fireEvent.input(textArea, { target: { value: 'Some Text Some Text Some Text' } }); - - fireEvent.click(await waitFor(() => screen.getByText('actions.accept'))); - await waitFor(() => expect(screen.getByText('commonAlert.modal.successfullyAccepted')).toBeInTheDocument()); - }); -}); diff --git a/frontend/src/app/modules/shared/modules/notification/modal/accept/accept-notification-modal.component.ts b/frontend/src/app/modules/shared/modules/notification/modal/accept/accept-notification-modal.component.ts deleted file mode 100644 index 228b9879d7..0000000000 --- a/frontend/src/app/modules/shared/modules/notification/modal/accept/accept-notification-modal.component.ts +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2022, 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2022, 2023 ZF Friedrichshafen AG - * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -import { Component, EventEmitter, Input, Output, TemplateRef, ViewChild } from '@angular/core'; -import { UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms'; -import { ToastService } from '@shared/components/toasts/toast.service'; -import { Notification } from '@shared/model/notification.model'; -import { TranslationContext } from '@shared/model/translation-context.model'; -import { ModalData } from '@shared/modules/modal/core/modal.model'; -import { ModalService } from '@shared/modules/modal/core/modal.service'; -import { Observable } from 'rxjs'; -import {getTranslationContext} from "@shared/helper/notification-helper"; - -@Component({ - selector: 'app-accept-notification-modal', - templateUrl: './accept-notification-modal.component.html', -}) -export class AcceptNotificationModalComponent { - @ViewChild('Modal') modal: TemplateRef; - @Input() acceptCall: (id: string, reason: string) => Observable; - @Input() translationContext: TranslationContext; - @Output() confirmActionCompleted = new EventEmitter(); - - public notification: Notification; - public readonly formGroup; - private readonly textAreaControl = new UntypedFormControl(); - - constructor(private readonly toastService: ToastService, private readonly confirmModalService: ModalService) { - this.formGroup = new UntypedFormGroup({ reason: this.textAreaControl }); - } - - public show(notification: Notification): void { - this.notification = notification; - - - this.textAreaControl.setValidators([ Validators.required, Validators.maxLength(1000), Validators.minLength(15) ]); - - const onConfirm = (isConfirmed: boolean) => { - const reason = this.formGroup.get('reason').value; - this.formGroup.reset(); - - if (!isConfirmed) return; - - this.acceptCall(notification.id, reason).subscribe({ - next: () => { - this.toastService.success(getTranslationContext(notification) + '.modal.successfullyAccepted'); - this.confirmActionCompleted.emit(); - }, - error: () => { - this.toastService.error(getTranslationContext(notification) + '.modal.failedAccept'); - }, - }); - }; - - const options: ModalData = { - title: getTranslationContext(notification) + '.modal.acceptTitle', - buttonRight: 'actions.accept', - template: this.modal, - formGroup: this.formGroup, - onConfirm, - }; - - this.confirmModalService.open(options); - } -} diff --git a/frontend/src/app/modules/shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component.html b/frontend/src/app/modules/shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component.html deleted file mode 100644 index 2c315d6465..0000000000 --- a/frontend/src/app/modules/shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - diff --git a/frontend/src/app/modules/shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component.spec.ts b/frontend/src/app/modules/shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component.spec.ts deleted file mode 100644 index 55165dc230..0000000000 --- a/frontend/src/app/modules/shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component.spec.ts +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2022, 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2022, 2023 ZF Friedrichshafen AG - * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -import { NotificationStatus } from '@shared/model/notification.model'; -import { renderAcknowledgeModal } from '@shared/modules/notification/modal/modalTestHelper.spec'; -import { fireEvent, screen, waitFor } from '@testing-library/angular'; -import { AcknowledgeNotificationModalComponent } from './acknowledge-notification-modal.component'; - -describe('AcknowledgeNotificationModalComponent', () => { - it('should create acknowledge modal', async () => { - await renderAcknowledgeModal(NotificationStatus.RECEIVED); - const title = await waitFor(() => screen.getByText('commonAlert.modal.acknowledgeTitle')); - const buttonR = await waitFor(() => screen.getByText('actions.acknowledge')); - - expect(title).toBeInTheDocument(); - expect(buttonR).toBeInTheDocument(); - }); - - it('should render investigation description', async () => { - const { notification } = await renderAcknowledgeModal(NotificationStatus.RECEIVED); - const description = await waitFor(() => screen.getByText(notification.description)); - - expect(description).toBeInTheDocument(); - }); - - it('should call acknowledge function', async () => { - await renderAcknowledgeModal(NotificationStatus.RECEIVED); - fireEvent.click(await waitFor(() => screen.getByText('actions.acknowledge'))); - - await waitFor(() => - expect(screen.getByText('commonAlert.modal.successfullyAcknowledged')).toBeInTheDocument(), - ); - }); -}); diff --git a/frontend/src/app/modules/shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component.ts b/frontend/src/app/modules/shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component.ts deleted file mode 100644 index e67727b848..0000000000 --- a/frontend/src/app/modules/shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component.ts +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2022, 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2022, 2023 ZF Friedrichshafen AG - * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -import { Component, EventEmitter, Input, Output, TemplateRef, ViewChild } from '@angular/core'; -import { ToastService } from '@shared/components/toasts/toast.service'; -import { Notification } from '@shared/model/notification.model'; -import { TranslationContext } from '@shared/model/translation-context.model'; -import { ModalData } from '@shared/modules/modal/core/modal.model'; -import { ModalService } from '@shared/modules/modal/core/modal.service'; -import { Observable } from 'rxjs'; -import {getTranslationContext} from "@shared/helper/notification-helper"; - -@Component({ - selector: 'app-acknowledge-notification-modal', - templateUrl: './acknowledge-notification-modal.component.html', -}) -export class AcknowledgeNotificationModalComponent { - @ViewChild('Modal') modal: TemplateRef; - @Input() acknowledgeCall: (id: string) => Observable; - @Input() translationContext: TranslationContext; - @Output() confirmActionCompleted = new EventEmitter(); - - public notification: Notification; - - constructor(private readonly toastService: ToastService, private readonly confirmModalService: ModalService) { - } - - public show(notification: Notification): void { - this.notification = notification; - const onConfirm = (isConfirmed: boolean) => { - if (!isConfirmed) return; - - this.acknowledgeCall(notification.id).subscribe({ - next: () => { - this.toastService.success(getTranslationContext(notification) + '.modal.successfullyAcknowledged'); - this.confirmActionCompleted.emit(); - }, - error: () => { - this.toastService.error(getTranslationContext(notification) + '.modal.failedAcknowledge'); - }, - }); - }; - - const options: ModalData = { - title: getTranslationContext(notification) + '.modal.acknowledgeTitle', - buttonRight: 'actions.acknowledge', - - template: this.modal, - onConfirm, - }; - - this.confirmModalService.open(options); - } -} diff --git a/frontend/src/app/modules/shared/modules/notification/modal/accept/accept-notification-modal.component.html b/frontend/src/app/modules/shared/modules/notification/modal/actions/notification-action-modal.component.html similarity index 87% rename from frontend/src/app/modules/shared/modules/notification/modal/accept/accept-notification-modal.component.html rename to frontend/src/app/modules/shared/modules/notification/modal/actions/notification-action-modal.component.html index cc20a09582..2b7ab619c4 100644 --- a/frontend/src/app/modules/shared/modules/notification/modal/accept/accept-notification-modal.component.html +++ b/frontend/src/app/modules/shared/modules/notification/modal/actions/notification-action-modal.component.html @@ -21,8 +21,8 @@ -
- {{ translationContext + '.modal.acceptReasonHint' | i18n }} + + {{ reasonHintLabel | i18n }}
-
+ diff --git a/frontend/src/app/modules/shared/modules/notification/modal/actions/notification-action-modal.component.ts b/frontend/src/app/modules/shared/modules/notification/modal/actions/notification-action-modal.component.ts new file mode 100644 index 0000000000..097d65d0ab --- /dev/null +++ b/frontend/src/app/modules/shared/modules/notification/modal/actions/notification-action-modal.component.ts @@ -0,0 +1,173 @@ +/******************************************************************************** + * Copyright (c) 2022, 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2022, 2023 ZF Friedrichshafen AG + * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +import { Component, EventEmitter, Input, Output, TemplateRef, ViewChild } from '@angular/core'; +import { UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms'; +import { ToastService } from '@shared/components/toasts/toast.service'; +import { getTranslationContext } from '@shared/helper/notification-helper'; +import { Notification, NotificationStatus } from '@shared/model/notification.model'; +import { TranslationContext } from '@shared/model/translation-context.model'; +import { ModalData } from '@shared/modules/modal/core/modal.model'; +import { ModalService } from '@shared/modules/modal/core/modal.service'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'app-notification-action-modal', + templateUrl: './notification-action-modal.component.html', +}) + +export class NotificationActionModalComponent { + @ViewChild('Modal') modal: TemplateRef; + @Input() callback: (status: NotificationStatus, id: string, reason?: string) => Observable; + @Input() translationContext: TranslationContext; + @Output() confirmActionCompleted = new EventEmitter(); + + public showTextArea = false; + public notification: Notification; + public readonly formGroup; + private readonly textAreaControl = new UntypedFormControl(); + public reasonHintLabel = null; + + constructor(private readonly toastService: ToastService, private readonly confirmModalService: ModalService) { + this.formGroup = new UntypedFormGroup({ reason: this.textAreaControl }); + } + + getModalDataBasedOnNotificationStatus(desiredStatus: NotificationStatus): NotificationModalData { + const context = getTranslationContext(this.notification); + switch (desiredStatus) { + case NotificationStatus.ACCEPTED: { + this.reasonHintLabel = context + '.modal.acceptReasonHint'; + return { + title: context + '.modal.acceptTitle', + buttonRight: 'actions.accept', + successMessage: context + '.modal.successfullyAccepted', + errorMessage: context + '.modal.failedAccept', + reasonHint: context + '.modal.acceptReasonHint' + }; + } + case NotificationStatus.DECLINED: { + this.reasonHintLabel = context + '.modal.declineReasonHint'; + + return { + title: context + '.modal.declineTitle', + buttonRight: 'actions.decline', + successMessage: context + '.modal.successfullyDeclined', + errorMessage: context + '.modal.failedDecline', + reasonHint: context + '.modal.declineReasonHint' + }; + } + case NotificationStatus.ACKNOWLEDGED: { + return { + title: context + '.modal.acknowledgeTitle', + buttonRight: 'actions.acknowledge', + successMessage: context + '.modal.successfullyAcknowledged', + errorMessage: context + '.modal.failedAcknowledge', + }; + } + case NotificationStatus.APPROVED: { + return { + title: context + '.modal.approvalTitle', + buttonRight: 'actions.confirm', + successMessage: context + '.modal.successfullyApproved', + errorMessage: context + '.modal.failedApprove', + }; + } + case NotificationStatus.CANCELED: { + return { + title: context + '.modal.cancellationTitle', + buttonRight: 'actions.cancellationConfirm', + successMessage: context + '.modal.successfullyCanceled', + errorMessage: context + '.modal.failedCancel', + }; + } + case NotificationStatus.CLOSED: { + this.reasonHintLabel = context + '.modal.closeReasonHint'; + return { + title: context + '.modal.closeTitle', + buttonRight: 'actions.close', + successMessage: context + '.modal.successfullyClosed', + errorMessage: context + '.modal.failedClose', + reasonHint: context + '.modal.closeReasonHint' + }; + } + } + + } +// TODO + // 1. Title of notification in modal not correct (alert / investigation) + // 2. Success has wrong type + public show(notification: Notification, desiredStatus: NotificationStatus): void { + const modalData = this.getModalDataBasedOnNotificationStatus(desiredStatus); + this.notification = notification; + + if (this.hasTextArea(desiredStatus)){ + this.showTextArea = true; + this.textAreaControl.setValidators([ Validators.required, Validators.maxLength(1000), Validators.minLength(15) ]); + this.formGroup.reset(); + } + const onConfirm = (isConfirmed: boolean) => { + if (!isConfirmed) return; + + const reason = this.formGroup.get('reason').value; + this.callback(desiredStatus, notification.id, reason).subscribe({ + next: () => { + this.toastService.success(modalData.successMessage); + this.confirmActionCompleted.emit(); + }, + error: () => { + this.toastService.error(modalData.errorMessage, 15000, true); + }, + }); + }; + + const options: ModalData = { + title: modalData.title, + buttonRight: modalData.buttonRight, + template: this.modal, + onConfirm, + }; + + if (desiredStatus === NotificationStatus.CANCELED) { + options.primaryButtonColour = 'warn'; + options.notificationId = this.notification.id; + options.type = getTranslationContext(this.notification) + '.modal.cancellationConfirmationLabel'; + } + if (this.hasTextArea(desiredStatus)){ + options.formGroup = this.formGroup; + } + + this.confirmModalService.open(options); + } + + + private hasTextArea(desiredStatus: NotificationStatus | NotificationStatus.ACCEPTED | NotificationStatus.ACKNOWLEDGED | NotificationStatus.APPROVED | NotificationStatus.CANCELED | NotificationStatus.CREATED | NotificationStatus.DECLINED | NotificationStatus.RECEIVED | NotificationStatus.SENT) { + return desiredStatus === NotificationStatus.CLOSED || desiredStatus === NotificationStatus.ACCEPTED || desiredStatus === NotificationStatus.DECLINED; + } +} + +export interface NotificationModalData { + title: string, + buttonRight: string, + successMessage: string, + errorMessage: string, + reason?: string + reasonHint?: string +} diff --git a/frontend/src/app/modules/shared/modules/notification/modal/approve/approve-notification-modal.component.html b/frontend/src/app/modules/shared/modules/notification/modal/approve/approve-notification-modal.component.html deleted file mode 100644 index 2c315d6465..0000000000 --- a/frontend/src/app/modules/shared/modules/notification/modal/approve/approve-notification-modal.component.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - diff --git a/frontend/src/app/modules/shared/modules/notification/modal/approve/approve-notification-modal.component.spec.ts b/frontend/src/app/modules/shared/modules/notification/modal/approve/approve-notification-modal.component.spec.ts deleted file mode 100644 index 49df4ff40e..0000000000 --- a/frontend/src/app/modules/shared/modules/notification/modal/approve/approve-notification-modal.component.spec.ts +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2022, 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2022, 2023 ZF Friedrichshafen AG - * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -import { NotificationStatus } from '@shared/model/notification.model'; -import { renderApproveModal } from '@shared/modules/notification/modal/modalTestHelper.spec'; -import { fireEvent, screen, waitFor } from '@testing-library/angular'; -import { ApproveNotificationModalComponent } from './approve-notification-modal.component'; - -describe('ApproveNotificationModalComponent', () => { - it('should create approve modal', async () => { - await renderApproveModal(NotificationStatus.CREATED); - const title = await waitFor(() => screen.getByText('commonAlert.modal.approvalTitle')); - const buttonR = await waitFor(() => screen.getByText('actions.confirm')); - - expect(title).toBeInTheDocument(); - expect(buttonR).toBeInTheDocument(); - }); - - it('should render investigation description', async () => { - const { notification } = await renderApproveModal(NotificationStatus.CREATED); - const description = await waitFor(() => screen.getByText(notification.description)); - - expect(description).toBeInTheDocument(); - }); - - it('should call approve function', async () => { - await renderApproveModal(NotificationStatus.CREATED); - fireEvent.click(await waitFor(() => screen.getByText('actions.confirm'))); - - await waitFor(() => expect(screen.getByText('commonAlert.modal.successfullyApproved')).toBeInTheDocument()); - }); -}); diff --git a/frontend/src/app/modules/shared/modules/notification/modal/approve/approve-notification-modal.component.ts b/frontend/src/app/modules/shared/modules/notification/modal/approve/approve-notification-modal.component.ts deleted file mode 100644 index 49bccbc1bb..0000000000 --- a/frontend/src/app/modules/shared/modules/notification/modal/approve/approve-notification-modal.component.ts +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2022, 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2022, 2023 ZF Friedrichshafen AG - * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -import {Component, EventEmitter, Input, Output, TemplateRef, ViewChild} from '@angular/core'; -import {ToastService} from '@shared/components/toasts/toast.service'; -import {Notification} from '@shared/model/notification.model'; -import {TranslationContext} from '@shared/model/translation-context.model'; -import {ModalData} from '@shared/modules/modal/core/modal.model'; -import {ModalService} from '@shared/modules/modal/core/modal.service'; -import {Observable} from 'rxjs'; -import {getTranslationContext} from "@shared/helper/notification-helper"; - -@Component({ - selector: 'app-approve-notification-modal', - templateUrl: './approve-notification-modal.component.html', -}) -export class ApproveNotificationModalComponent { - @ViewChild('Modal') modal: TemplateRef; - @Input() approveCall: (id: string) => Observable; - @Input() translationContext: TranslationContext; - @Output() confirmActionCompleted = new EventEmitter(); - - public notification: Notification; - - constructor(private readonly toastService: ToastService, private readonly confirmModalService: ModalService) { - this.toastService.retryAction.subscribe(() => this.show(this.notification)); - - } - - - public show(notification: Notification): void { - this.notification = notification; - const onConfirm = (isConfirmed: boolean) => { - if (!isConfirmed) return; - - this.approveCall(notification.id).subscribe({ - next: () => { - this.toastService.success(getTranslationContext(notification) + '.modal.successfullyApproved'); - this.confirmActionCompleted.emit(); - }, - error: (err) => { - this.toastService.error(getTranslationContext(notification)+ '.modal.failedApprove', 15000, true); - }, - }); - }; - - const options: ModalData = { - title: getTranslationContext(notification) + '.modal.approvalTitle', - buttonRight: 'actions.confirm', - - template: this.modal, - onConfirm, - }; - - this.confirmModalService.open(options); - } -} diff --git a/frontend/src/app/modules/shared/modules/notification/modal/cancel/cancel-notification-modal.component.html b/frontend/src/app/modules/shared/modules/notification/modal/cancel/cancel-notification-modal.component.html deleted file mode 100644 index 2c315d6465..0000000000 --- a/frontend/src/app/modules/shared/modules/notification/modal/cancel/cancel-notification-modal.component.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - diff --git a/frontend/src/app/modules/shared/modules/notification/modal/cancel/cancel-notification-modal.component.spec.ts b/frontend/src/app/modules/shared/modules/notification/modal/cancel/cancel-notification-modal.component.spec.ts deleted file mode 100644 index db47e2749a..0000000000 --- a/frontend/src/app/modules/shared/modules/notification/modal/cancel/cancel-notification-modal.component.spec.ts +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2022, 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2022, 2023 ZF Friedrichshafen AG - * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -import { NotificationStatus } from '@shared/model/notification.model'; -import { CancelNotificationModalComponent } from '@shared/modules/notification/modal/cancel/cancel-notification-modal.component'; -import { renderCancelModal } from '@shared/modules/notification/modal/modalTestHelper.spec'; -import { screen, waitFor } from '@testing-library/angular'; - -describe('CancelNotificationModalComponent', () => { - it('should create cancel modal', async () => { - await renderCancelModal(NotificationStatus.CREATED); - const title = await waitFor(() => screen.getByText('commonAlert.modal.cancellationTitle')); - const buttonR = await waitFor(() => screen.getByText('actions.cancellationConfirm')); - - expect(title).toBeInTheDocument(); - expect(buttonR).toBeInTheDocument(); - }); - - it('should render investigation description', async () => { - const { notification } = await renderCancelModal(NotificationStatus.CREATED); - const description = await waitFor(() => screen.getByText(notification.description)); - - expect(description).toBeInTheDocument(); - }); -}); diff --git a/frontend/src/app/modules/shared/modules/notification/modal/cancel/cancel-notification-modal.component.ts b/frontend/src/app/modules/shared/modules/notification/modal/cancel/cancel-notification-modal.component.ts deleted file mode 100644 index a6ba79e601..0000000000 --- a/frontend/src/app/modules/shared/modules/notification/modal/cancel/cancel-notification-modal.component.ts +++ /dev/null @@ -1,77 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2022, 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2022, 2023 ZF Friedrichshafen AG - * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -import { Component, EventEmitter, Input, Output, TemplateRef, ViewChild } from '@angular/core'; -import { ToastService } from '@shared/components/toasts/toast.service'; -import { Notification } from '@shared/model/notification.model'; -import { TranslationContext } from '@shared/model/translation-context.model'; -import { ModalData } from '@shared/modules/modal/core/modal.model'; -import { ModalService } from '@shared/modules/modal/core/modal.service'; -import { Observable } from 'rxjs'; -import {getTranslationContext} from "@shared/helper/notification-helper"; - -@Component({ - selector: 'app-cancel-notification-modal', - templateUrl: './cancel-notification-modal.component.html', -}) -export class CancelNotificationModalComponent { - @ViewChild('Modal') modal: TemplateRef; - @Input() cancelCall: (id: string) => Observable; - @Input() translationContext: TranslationContext; - @Output() confirmActionCompleted = new EventEmitter(); - - - public notification: Notification; - - constructor(private readonly toastService: ToastService, private readonly confirmModalService: ModalService) { - } - - public show(notification: Notification): void { - this.notification = notification; - - const onConfirm = (isConfirmed: boolean) => { - - if (!isConfirmed) return; - - this.cancelCall(notification.id).subscribe({ - next: () => { - this.toastService.success(getTranslationContext(notification) + '.modal.successfullyCanceled'); - this.confirmActionCompleted.emit(); - }, - error: () => { - this.toastService.error(getTranslationContext(notification) + '.modal.failedCancel'); - }, - }); - }; - - const options: ModalData = { - title: getTranslationContext(notification) + '.modal.cancellationTitle', - type: getTranslationContext(notification) + '.modal.cancellationConfirmationLabel', - buttonRight: 'actions.cancellationConfirm', - primaryButtonColour: 'warn', - notificationId: this.notification.id, - template: this.modal, - onConfirm, - }; - - this.confirmModalService.open(options); - } -} diff --git a/frontend/src/app/modules/shared/modules/notification/modal/close/close-notification-modal.component.html b/frontend/src/app/modules/shared/modules/notification/modal/close/close-notification-modal.component.html deleted file mode 100644 index 6b53b86df4..0000000000 --- a/frontend/src/app/modules/shared/modules/notification/modal/close/close-notification-modal.component.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - -
- {{ translationContext + '.modal.closeReasonHint' | i18n }} - -
-
diff --git a/frontend/src/app/modules/shared/modules/notification/modal/close/close-notification-modal.component.spec.ts b/frontend/src/app/modules/shared/modules/notification/modal/close/close-notification-modal.component.spec.ts deleted file mode 100644 index 282aeee0e2..0000000000 --- a/frontend/src/app/modules/shared/modules/notification/modal/close/close-notification-modal.component.spec.ts +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2022, 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2022, 2023 ZF Friedrichshafen AG - * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -import { NotificationStatus } from '@shared/model/notification.model'; -import { CloseNotificationModalComponent } from '@shared/modules/notification/modal/close/close-notification-modal.component'; -import { renderCloseModal } from '@shared/modules/notification/modal/modalTestHelper.spec'; -import { fireEvent, screen, waitFor } from '@testing-library/angular'; -import { getRandomText } from '../../../../../../mocks/services/text-generator.helper'; - -describe('CloseNotificationModalComponent', () => { - it('should create close modal', async () => { - await renderCloseModal(NotificationStatus.SENT); - const title = await waitFor(() => screen.getByText('commonAlert.modal.closeTitle')); - const hint2 = await waitFor(() => screen.getByText('commonAlert.modal.closeReasonHint')); - const buttonR = await waitFor(() => screen.getByText('actions.close')); - - expect(title).toBeInTheDocument(); - expect(hint2).toBeInTheDocument(); - expect(buttonR).toBeInTheDocument(); - }); - - it('should render investigation description', async () => { - const { notification } = await renderCloseModal(NotificationStatus.SENT); - const description = await waitFor(() => screen.getByText(notification.description)); - - expect(description).toBeInTheDocument(); - }); - - it('should check validation of textarea', async () => { - await renderCloseModal(NotificationStatus.SENT); - fireEvent.click(await waitFor(() => screen.getByText('actions.close'))); - const textArea: HTMLTextAreaElement = await waitFor(() => screen.getByTestId('BaseInputElement-0')); - - const errorMessage_1 = await waitFor(() => screen.getByText('errorMessage.required')); - expect(errorMessage_1).toBeInTheDocument(); - - fireEvent.input(textArea, { target: { value: 'Some Text' } }); - const errorMessage_2 = await waitFor(() => screen.getByText('errorMessage.minLength')); - expect(errorMessage_2).toBeInTheDocument(); - - fireEvent.input(textArea, { target: { value: getRandomText(1500) } }); - const errorMessage_3 = await waitFor(() => screen.getByText('errorMessage.maxLength')); - expect(errorMessage_3).toBeInTheDocument(); - - fireEvent.input(textArea, { target: { value: 'Some longer text with at least 15 chars' } }); - expect(errorMessage_1).not.toBeInTheDocument(); - expect(errorMessage_2).not.toBeInTheDocument(); - expect(errorMessage_3).not.toBeInTheDocument(); - }); - - it('should call close function', async () => { - await renderCloseModal(NotificationStatus.SENT); - - const textArea = await waitFor(() => screen.getByTestId('BaseInputElement-0')); - fireEvent.input(textArea, { target: { value: 'Some Text Some Text Some Text' } }); - - fireEvent.click(await waitFor(() => screen.getByText('actions.close'))); - await waitFor(() => expect(screen.getByText('commonAlert.modal.successfullyClosed')).toBeInTheDocument()); - }); -}); diff --git a/frontend/src/app/modules/shared/modules/notification/modal/close/close-notification-modal.component.ts b/frontend/src/app/modules/shared/modules/notification/modal/close/close-notification-modal.component.ts deleted file mode 100644 index 65c62e5f38..0000000000 --- a/frontend/src/app/modules/shared/modules/notification/modal/close/close-notification-modal.component.ts +++ /dev/null @@ -1,82 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2022, 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2022, 2023 ZF Friedrichshafen AG - * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -import { Component, EventEmitter, Input, Output, TemplateRef, ViewChild } from '@angular/core'; -import { UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms'; -import { ToastService } from '@shared/components/toasts/toast.service'; -import { Notification } from '@shared/model/notification.model'; -import { TranslationContext } from '@shared/model/translation-context.model'; -import { ModalData } from '@shared/modules/modal/core/modal.model'; -import { ModalService } from '@shared/modules/modal/core/modal.service'; -import { Observable } from 'rxjs'; -import {getTranslationContext} from "@shared/helper/notification-helper"; - -@Component({ - selector: 'app-close-notification-modal', - templateUrl: './close-notification-modal.component.html', -}) -export class CloseNotificationModalComponent { - @ViewChild('Modal') modal: TemplateRef; - @Input() closeCall: (id: string, reason: string) => Observable; - @Input() translationContext: TranslationContext; - @Output() confirmActionCompleted = new EventEmitter(); - - public notification: Notification; - public readonly formGroup; - private readonly textAreaControl = new UntypedFormControl(); - - constructor(private readonly toastService: ToastService, private readonly confirmModalService: ModalService) { - this.formGroup = new UntypedFormGroup({ reason: this.textAreaControl }); - } - - public show(notification: Notification): void { - this.notification = notification; - this.textAreaControl.setValidators([ Validators.required, Validators.maxLength(1000), Validators.minLength(15) ]); - - const onConfirm = (isConfirmed: boolean) => { - const reason = this.formGroup.get('reason').value; - this.formGroup.reset(); - - if (!isConfirmed) return; - - this.closeCall(notification.id, reason).subscribe({ - next: () => { - this.toastService.success(getTranslationContext(notification) + '.modal.successfullyClosed'); - this.confirmActionCompleted.emit(); - }, - error: () => { - this.toastService.error(getTranslationContext(notification) + '.modal.failedClose'); - }, - }); - }; - - const options: ModalData = { - title: getTranslationContext(notification) + '.modal.closeTitle', - buttonRight: 'actions.close', - - template: this.modal, - formGroup: this.formGroup, - onConfirm, - }; - - this.confirmModalService.open(options); - } -} diff --git a/frontend/src/app/modules/shared/modules/notification/modal/decline/decline-notification-modal.component.html b/frontend/src/app/modules/shared/modules/notification/modal/decline/decline-notification-modal.component.html deleted file mode 100644 index 64e86996c0..0000000000 --- a/frontend/src/app/modules/shared/modules/notification/modal/decline/decline-notification-modal.component.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - -
- {{ translationContext + '.modal.declineReasonHint' | i18n }} - -
-
diff --git a/frontend/src/app/modules/shared/modules/notification/modal/decline/decline-notification-modal.component.spec.ts b/frontend/src/app/modules/shared/modules/notification/modal/decline/decline-notification-modal.component.spec.ts deleted file mode 100644 index 252d130a0a..0000000000 --- a/frontend/src/app/modules/shared/modules/notification/modal/decline/decline-notification-modal.component.spec.ts +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2022, 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2022, 2023 ZF Friedrichshafen AG - * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -import { NotificationStatus } from '@shared/model/notification.model'; -import { renderDeclineModal } from '@shared/modules/notification/modal/modalTestHelper.spec'; -import { fireEvent, screen, waitFor } from '@testing-library/angular'; -import { getRandomText } from '../../../../../../mocks/services/text-generator.helper'; - -describe('DeclineNotificationModalComponent', () => { - it('should create close modal', async () => { - await renderDeclineModal(NotificationStatus.ACKNOWLEDGED); - const title = await waitFor(() => screen.getByText('commonAlert.modal.declineTitle')); - const hint2 = await waitFor(() => screen.getByText('commonAlert.modal.declineReasonHint')); - const buttonR = await waitFor(() => screen.getByText('actions.decline')); - - expect(title).toBeInTheDocument(); - expect(hint2).toBeInTheDocument(); - expect(buttonR).toBeInTheDocument(); - }); - - it('should render investigation description', async () => { - const { notification } = await renderDeclineModal(NotificationStatus.ACKNOWLEDGED); - const description = await waitFor(() => screen.getByText(notification.description)); - - expect(description).toBeInTheDocument(); - }); - - it('should check validation of textarea', async () => { - await renderDeclineModal(NotificationStatus.ACKNOWLEDGED); - fireEvent.click(await waitFor(() => screen.getByText('actions.decline'))); - - const textArea: HTMLTextAreaElement = await waitFor(() => screen.getByTestId('BaseInputElement-0')); - - const errorMessage_1 = await waitFor(() => screen.getByText('errorMessage.required')); - expect(errorMessage_1).toBeInTheDocument(); - - fireEvent.input(textArea, { target: { value: 'Some Text' } }); - const errorMessage_2 = await waitFor(() => screen.getByText('errorMessage.minLength')); - expect(errorMessage_2).toBeInTheDocument(); - - fireEvent.input(textArea, { target: { value: getRandomText(1500) } }); - const errorMessage_3 = await waitFor(() => screen.getByText('errorMessage.maxLength')); - expect(errorMessage_3).toBeInTheDocument(); - - fireEvent.input(textArea, { target: { value: 'Some longer text with at least 15 chars' } }); - expect(errorMessage_1).not.toBeInTheDocument(); - expect(errorMessage_2).not.toBeInTheDocument(); - expect(errorMessage_3).not.toBeInTheDocument(); - }); - - it('should call close function', async () => { - await renderDeclineModal(NotificationStatus.ACKNOWLEDGED); - - const textArea: HTMLTextAreaElement = await waitFor(() => screen.getByTestId('BaseInputElement-0')); - fireEvent.input(textArea, { target: { value: 'Some Text Some Text Some Text' } }); - fireEvent.click(await waitFor(() => screen.getByText('actions.decline'))); - - await waitFor(() => expect(screen.getByText('commonAlert.modal.successfullyDeclined')).toBeInTheDocument()); - }); -}); diff --git a/frontend/src/app/modules/shared/modules/notification/modal/decline/decline-notification-modal.component.ts b/frontend/src/app/modules/shared/modules/notification/modal/decline/decline-notification-modal.component.ts deleted file mode 100644 index 43ca92a80e..0000000000 --- a/frontend/src/app/modules/shared/modules/notification/modal/decline/decline-notification-modal.component.ts +++ /dev/null @@ -1,82 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2022, 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2022, 2023 ZF Friedrichshafen AG - * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -import { Component, EventEmitter, Input, Output, TemplateRef, ViewChild } from '@angular/core'; -import { UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms'; -import { ToastService } from '@shared/components/toasts/toast.service'; -import { Notification } from '@shared/model/notification.model'; -import { TranslationContext } from '@shared/model/translation-context.model'; -import { ModalData } from '@shared/modules/modal/core/modal.model'; -import { ModalService } from '@shared/modules/modal/core/modal.service'; -import { Observable } from 'rxjs'; -import {getTranslationContext} from "@shared/helper/notification-helper"; - -@Component({ - selector: 'app-decline-notification-modal', - templateUrl: './decline-notification-modal.component.html', -}) -export class DeclineNotificationModalComponent { - @ViewChild('Modal') modal: TemplateRef; - @Input() declineCall: (id: string, reason: string) => Observable; - @Input() translationContext: TranslationContext; - @Output() confirmActionCompleted = new EventEmitter(); - - public notification: Notification; - public readonly formGroup; - private readonly textAreaControl = new UntypedFormControl(); - - constructor(private readonly toastService: ToastService, private readonly confirmModalService: ModalService) { - this.formGroup = new UntypedFormGroup({ reason: this.textAreaControl }); - } - - public show(notification: Notification): void { - this.notification = notification; - this.textAreaControl.setValidators([ Validators.required, Validators.maxLength(1000), Validators.minLength(15) ]); - - const onConfirm = (isConfirmed: boolean) => { - const reason = this.formGroup.get('reason').value; - this.formGroup.reset(); - - if (!isConfirmed) return; - - this.declineCall(notification.id, reason).subscribe({ - next: () => { - this.toastService.success(getTranslationContext(notification) + '.modal.successfullyDeclined'); - this.confirmActionCompleted.emit(); - }, - error: () => { - this.toastService.error(getTranslationContext(notification) + '.modal.failedDecline'); - }, - }); - }; - - const options: ModalData = { - title: getTranslationContext(notification) + '.modal.declineTitle', - buttonRight: 'actions.decline', - - template: this.modal, - formGroup: this.formGroup, - onConfirm, - }; - - this.confirmModalService.open(options); - } -} diff --git a/frontend/src/app/modules/shared/modules/notification/modal/modalTestHelper.spec.ts b/frontend/src/app/modules/shared/modules/notification/modal/modalTestHelper.spec.ts deleted file mode 100644 index 64972dab2b..0000000000 --- a/frontend/src/app/modules/shared/modules/notification/modal/modalTestHelper.spec.ts +++ /dev/null @@ -1,234 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2022, 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2022, 2023 ZF Friedrichshafen AG - * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -import {AfterViewInit, Component, Input, ViewChild} from '@angular/core'; -import {CalendarDateModel} from '@core/model/calendar-date.model'; -import {Notification, NotificationStatus, NotificationType} from '@shared/model/notification.model'; -import {Severity} from '@shared/model/severity.model'; -import {TranslationContext} from '@shared/model/translation-context.model'; -import { - AcceptNotificationModalComponent -} from '@shared/modules/notification/modal/accept/accept-notification-modal.component'; -import { - AcknowledgeNotificationModalComponent -} from '@shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component'; -import { - ApproveNotificationModalComponent -} from '@shared/modules/notification/modal/approve/approve-notification-modal.component'; -import { - CancelNotificationModalComponent -} from '@shared/modules/notification/modal/cancel/cancel-notification-modal.component'; -import { - CloseNotificationModalComponent -} from '@shared/modules/notification/modal/close/close-notification-modal.component'; -import { - DeclineNotificationModalComponent -} from '@shared/modules/notification/modal/decline/decline-notification-modal.component'; -import {NotificationModule} from '@shared/modules/notification/notification.module'; -import {SharedModule} from '@shared/shared.module'; -import {TemplateModule} from '@shared/template.module'; -import {renderComponent} from '@tests/test-render.utils'; -import {of} from 'rxjs'; - -@Component({ - selector: '', - template: - '', -}) -class AcceptModalComponent implements AfterViewInit { - @ViewChild(AcceptNotificationModalComponent) modal: AcceptNotificationModalComponent; - @Input() notification: Notification; - public call = (id: string) => of(null); - - public ngAfterViewInit() { - this.modal.show(this.notification); - } - - protected readonly TranslationContext = TranslationContext; -} - -@Component({ - selector: '', - template: - '', -}) -class AcknowledgeModalComponent implements AfterViewInit { - @ViewChild(AcknowledgeNotificationModalComponent) modal: AcknowledgeNotificationModalComponent; - @Input() notification: Notification; - public call = (id: string) => of(null); - - public ngAfterViewInit() { - this.modal.show(this.notification); - } - - protected readonly TranslationContext = TranslationContext; -} - -@Component({ - selector: '', - template: - '', -}) -class ApproveModalComponent implements AfterViewInit { - @ViewChild(ApproveNotificationModalComponent) modal: ApproveNotificationModalComponent; - @Input() notification: Notification; - public call = (id: string) => of(null); - - public ngAfterViewInit() { - this.modal.show(this.notification); - } - - protected readonly TranslationContext = TranslationContext; -} - -@Component({ - selector: '', - template: - '', -}) -class CancelModalComponent implements AfterViewInit { - @ViewChild(CancelNotificationModalComponent) modal: CancelNotificationModalComponent; - @Input() notification: Notification; - public call = (id: string) => of(null); - - public ngAfterViewInit() { - this.modal.show(this.notification); - } - - protected readonly TranslationContext = TranslationContext; -} - -@Component({ - selector: '', - template: - '', -}) -class DeclineModalComponent implements AfterViewInit { - @ViewChild(DeclineNotificationModalComponent) modal: DeclineNotificationModalComponent; - @Input() notification: Notification; - public call = (id: string) => of(null); - - public ngAfterViewInit() { - this.modal.show(this.notification); - } - - protected readonly TranslationContext = TranslationContext; -} - -@Component({ - selector: '', - template: - '', -}) -class CloseModalComponent implements AfterViewInit { - @ViewChild(CloseNotificationModalComponent) modal: CloseNotificationModalComponent; - @Input() notification: Notification; - public call = (id: string) => of(null); - - public ngAfterViewInit() { - this.modal.show(this.notification); - } - - protected readonly TranslationContext = TranslationContext; -} - -export const notificationTemplate: Notification = { - id: 'id-1', - description: 'Investigation No 1', - createdBy: 'BPNA', - title: 'Title', - createdByName: 'CompanyA', - sendTo: 'BPNB', - sendToName: 'CompanyB', - reason: { close: '', accept: '', decline: '' }, - isFromSender: false, - assetIds: [ 'MOCK_part_1' ], - status: null, - severity: Severity.MINOR, - type: NotificationType.ALERT, - createdDate: new CalendarDateModel('2022-05-01T10:34:12.000Z'), -}; - -export const renderAcceptModal = async (status: NotificationStatus) => { - const notification = { ...notificationTemplate, status }; - const { fixture } = await renderComponent(AcceptModalComponent, { - declarations: [ AcceptModalComponent ], - imports: [ NotificationModule, SharedModule, TemplateModule ], - componentProperties: { notification }, - }); - - return { fixture, notification }; -}; - -export const renderAcknowledgeModal = async (status: NotificationStatus) => { - const notification = { ...notificationTemplate, status }; - const { fixture } = await renderComponent(AcknowledgeModalComponent, { - declarations: [ AcknowledgeModalComponent ], - imports: [ NotificationModule, SharedModule, TemplateModule ], - componentProperties: { notification }, - }); - - return { fixture, notification }; -}; - -export const renderApproveModal = async (status: NotificationStatus) => { - const notification = { ...notificationTemplate, status }; - const { fixture } = await renderComponent(ApproveModalComponent, { - declarations: [ ApproveModalComponent ], - imports: [ NotificationModule, SharedModule, TemplateModule ], - componentProperties: { notification }, - }); - - return { fixture, notification }; -}; - -export const renderCancelModal = async (status: NotificationStatus) => { - const notification = { ...notificationTemplate, status }; - const { fixture } = await renderComponent(CancelModalComponent, { - declarations: [ CancelModalComponent ], - imports: [ NotificationModule, SharedModule, TemplateModule ], - componentProperties: { notification }, - }); - - return { fixture, notification }; -}; - -export const renderCloseModal = async (status: NotificationStatus) => { - const notification = { ...notificationTemplate, status }; - const { fixture } = await renderComponent(CloseModalComponent, { - declarations: [ CloseModalComponent ], - imports: [ NotificationModule, SharedModule, TemplateModule ], - componentProperties: { notification }, - }); - - return { fixture, notification }; -}; - -export const renderDeclineModal = async (status: NotificationStatus) => { - const notification = { ...notificationTemplate, status }; - const { fixture } = await renderComponent(DeclineModalComponent, { - declarations: [ DeclineModalComponent ], - imports: [ NotificationModule, SharedModule, TemplateModule ], - componentProperties: { notification }, - }); - - return { fixture, notification }; -}; diff --git a/frontend/src/app/modules/shared/modules/notification/notification.module.ts b/frontend/src/app/modules/shared/modules/notification/notification.module.ts index 84f850e503..991f07f04c 100644 --- a/frontend/src/app/modules/shared/modules/notification/notification.module.ts +++ b/frontend/src/app/modules/shared/modules/notification/notification.module.ts @@ -23,27 +23,17 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { NotificationCommonModalComponent } from '@shared/components/notification-common-modal/notification-common-modal.component'; import { ModalModule } from '@shared/modules/modal/modal.module'; -import { AcceptNotificationModalComponent } from '@shared/modules/notification/modal/accept/accept-notification-modal.component'; -import { AcknowledgeNotificationModalComponent } from '@shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component'; -import { ApproveNotificationModalComponent } from '@shared/modules/notification/modal/approve/approve-notification-modal.component'; -import { CancelNotificationModalComponent } from '@shared/modules/notification/modal/cancel/cancel-notification-modal.component'; -import { DeclineNotificationModalComponent } from '@shared/modules/notification/modal/decline/decline-notification-modal.component'; +import { NotificationActionModalComponent } from '@shared/modules/notification/modal/actions/notification-action-modal.component'; import { NotificationTabComponent } from '@shared/modules/notification/notification-tab/notification-tab.component'; import { SharedModule } from '@shared/shared.module'; import { TemplateModule } from '@shared/template.module'; -import { CloseNotificationModalComponent } from './modal/close/close-notification-modal.component'; import { NotificationComponent } from './presentation/notification.component'; @NgModule({ declarations: [ NotificationComponent, NotificationTabComponent, - CloseNotificationModalComponent, - ApproveNotificationModalComponent, - CancelNotificationModalComponent, - AcceptNotificationModalComponent, - AcknowledgeNotificationModalComponent, - DeclineNotificationModalComponent, + NotificationActionModalComponent, NotificationCommonModalComponent, ], imports: [ CommonModule, TemplateModule, SharedModule, ModalModule ], @@ -51,12 +41,7 @@ import { NotificationComponent } from './presentation/notification.component'; NotificationCommonModalComponent, NotificationComponent, NotificationTabComponent, - CloseNotificationModalComponent, - ApproveNotificationModalComponent, - CancelNotificationModalComponent, - AcknowledgeNotificationModalComponent, - AcceptNotificationModalComponent, - DeclineNotificationModalComponent, + NotificationActionModalComponent, ], }) export class NotificationModule { From f99e4aa89a2014c55de91421f35baa61c1290518 Mon Sep 17 00:00:00 2001 From: Maximilian Wesener Date: Mon, 1 Apr 2024 22:48:05 +0200 Subject: [PATCH 05/14] chore(feature): 616 - Fixed modal functions --- .../detail/notification-detail.component.html | 12 +++---- .../detail/notification-detail.component.ts | 3 +- .../notificationMenuActions.assembler.ts | 14 ++++---- .../notification-common-modal.component.ts | 33 +++---------------- .../notification-action-modal.component.ts | 12 +++---- 5 files changed, 26 insertions(+), 48 deletions(-) diff --git a/frontend/src/app/modules/page/notifications/detail/notification-detail.component.html b/frontend/src/app/modules/page/notifications/detail/notification-detail.component.html index 322edbf532..d86fcc533b 100644 --- a/frontend/src/app/modules/page/notifications/detail/notification-detail.component.html +++ b/frontend/src/app/modules/page/notifications/detail/notification-detail.component.html @@ -40,7 +40,7 @@ > @@ -60,7 +60,7 @@ > @@ -80,7 +80,7 @@ > @@ -100,7 +100,7 @@ > @@ -120,7 +120,7 @@ > @@ -140,7 +140,7 @@ > diff --git a/frontend/src/app/modules/page/notifications/detail/notification-detail.component.ts b/frontend/src/app/modules/page/notifications/detail/notification-detail.component.ts index 06b528a4b8..975e6103b3 100644 --- a/frontend/src/app/modules/page/notifications/detail/notification-detail.component.ts +++ b/frontend/src/app/modules/page/notifications/detail/notification-detail.component.ts @@ -28,7 +28,7 @@ import { NotificationActionHelperService } from '@shared/assembler/notification- import { NotificationCommonModalComponent } from '@shared/components/notification-common-modal/notification-common-modal.component'; import { CreateHeaderFromColumns, TableConfig, TableEventConfig } from '@shared/components/table/table.model'; import { ToastService } from '@shared/components/toasts/toast.service'; -import { Notification, NotificationType } from '@shared/model/notification.model'; +import { Notification, NotificationStatus, NotificationType } from '@shared/model/notification.model'; import { TranslationContext } from '@shared/model/translation-context.model'; import { View } from '@shared/model/view.model'; import { NotificationAction } from '@shared/modules/notification/notification-action.enum'; @@ -209,4 +209,5 @@ export class NotificationDetailComponent implements AfterViewInit, OnDestroy { protected readonly NotificationType = NotificationType; protected readonly NotificationAction = NotificationAction; + protected readonly NotificationStatus = NotificationStatus; } diff --git a/frontend/src/app/modules/shared/assembler/notificationMenuActions.assembler.ts b/frontend/src/app/modules/shared/assembler/notificationMenuActions.assembler.ts index 2217e506b6..aec5385a9e 100644 --- a/frontend/src/app/modules/shared/assembler/notificationMenuActions.assembler.ts +++ b/frontend/src/app/modules/shared/assembler/notificationMenuActions.assembler.ts @@ -19,7 +19,7 @@ import { NotificationActionHelperService } from '@shared/assembler/notification-action-helper.service'; import { NotificationCommonModalComponent } from '@shared/components/notification-common-modal/notification-common-modal.component'; import { MenuActionConfig } from '@shared/components/table/table.model'; -import { Notification } from '@shared/model/notification.model'; +import { Notification, NotificationStatus } from '@shared/model/notification.model'; import { NotificationAction } from '@shared/modules/notification/notification-action.enum'; export class NotificationMenuActionsAssembler { @@ -28,42 +28,42 @@ export class NotificationMenuActionsAssembler { { label: 'actions.close', icon: 'close', - action: data => modal.show('close', data), + action: data => modal.show(NotificationStatus.CLOSED, data), condition: data => helperService.showCloseButton(data), isAuthorized: helperService.isAuthorizedForButton(NotificationAction.CLOSE), }, { label: 'actions.approve', icon: 'share', - action: data => modal.show('approve', data), + action: data => modal.show(NotificationStatus.APPROVED, data), condition: data => helperService.showApproveButton(data), isAuthorized: helperService.isAuthorizedForButton(NotificationAction.APPROVE), }, { label: 'actions.cancel', icon: 'cancel', - action: data => modal.show('cancel', data), + action: data => modal.show(NotificationStatus.CANCELED, data), condition: data => helperService.showCancelButton(data), isAuthorized: helperService.isAuthorizedForButton(NotificationAction.CANCEL), }, { label: 'actions.acknowledge', icon: 'work', - action: data => modal.show('acknowledge', data), + action: data => modal.show(NotificationStatus.ACKNOWLEDGED, data), condition: data => helperService.showAcknowledgeButton(data), isAuthorized: helperService.isAuthorizedForButton(NotificationAction.ACKNOWLEDGE), }, { label: 'actions.accept', icon: 'assignment_turned_in', - action: data => modal.show('accept', data), + action: data => modal.show(NotificationStatus.ACCEPTED, data), condition: data => helperService.showAcceptButton(data), isAuthorized: helperService.isAuthorizedForButton(NotificationAction.ACCEPT), }, { label: 'actions.decline', icon: 'assignment_late', - action: data => modal.show('decline', data), + action: data => modal.show(NotificationStatus.DECLINED, data), condition: data => helperService.showDeclineButton(data), isAuthorized: helperService.isAuthorizedForButton(NotificationAction.DECLINE), }, diff --git a/frontend/src/app/modules/shared/components/notification-common-modal/notification-common-modal.component.ts b/frontend/src/app/modules/shared/components/notification-common-modal/notification-common-modal.component.ts index bf12e07272..30cceeeeb0 100644 --- a/frontend/src/app/modules/shared/components/notification-common-modal/notification-common-modal.component.ts +++ b/frontend/src/app/modules/shared/components/notification-common-modal/notification-common-modal.component.ts @@ -32,7 +32,7 @@ export class NotificationCommonModalComponent { @Input() helperService: NotificationHelperService; @Output() confirmActionCompleted = new EventEmitter(); - @ViewChild(NotificationActionModalComponent) acknowledgeAndApproveModal: NotificationActionModalComponent; + @ViewChild(NotificationActionModalComponent) notificationActionModalComponent: NotificationActionModalComponent; // TODO do not delete the facade here. This will lead to a nullpointer exception within the modal call. public constructor( @@ -45,34 +45,11 @@ export class NotificationCommonModalComponent { this.confirmActionCompleted.emit(); } - public show(modalContext: string, notification?: Notification) { + public show(desiredStatus: NotificationStatus, notification?: Notification) { let notificationToShow = notification || this.selectedNotification; - switch (modalContext) { - case 'approve': { - this.acknowledgeAndApproveModal.show(notificationToShow, NotificationStatus.APPROVED); - break; - } - case 'close': { - this.acknowledgeAndApproveModal.show(notificationToShow, NotificationStatus.CLOSED); - break; - } - case 'cancel': { - this.acknowledgeAndApproveModal.show(notificationToShow, NotificationStatus.CANCELED); - break; - } - case 'accept': { - this.acknowledgeAndApproveModal.show(notificationToShow, NotificationStatus.ACCEPTED); - break; - } - case 'acknowledge': { - this.acknowledgeAndApproveModal.show(notificationToShow, NotificationStatus.ACKNOWLEDGED); - break; - } - case 'decline': { - this.acknowledgeAndApproveModal.show(notificationToShow, NotificationStatus.DECLINED); - break; - } - } + console.log(notificationToShow, "notification"); + console.log(desiredStatus, "desiredstatus"); + this.notificationActionModalComponent.show(notificationToShow, desiredStatus); } protected readonly NotificationStatus = NotificationStatus; diff --git a/frontend/src/app/modules/shared/modules/notification/modal/actions/notification-action-modal.component.ts b/frontend/src/app/modules/shared/modules/notification/modal/actions/notification-action-modal.component.ts index 097d65d0ab..e06c0ddb5e 100644 --- a/frontend/src/app/modules/shared/modules/notification/modal/actions/notification-action-modal.component.ts +++ b/frontend/src/app/modules/shared/modules/notification/modal/actions/notification-action-modal.component.ts @@ -37,7 +37,6 @@ import { Observable } from 'rxjs'; export class NotificationActionModalComponent { @ViewChild('Modal') modal: TemplateRef; @Input() callback: (status: NotificationStatus, id: string, reason?: string) => Observable; - @Input() translationContext: TranslationContext; @Output() confirmActionCompleted = new EventEmitter(); public showTextArea = false; @@ -111,17 +110,17 @@ export class NotificationActionModalComponent { } } -// TODO - // 1. Title of notification in modal not correct (alert / investigation) - // 2. Success has wrong type + public show(notification: Notification, desiredStatus: NotificationStatus): void { - const modalData = this.getModalDataBasedOnNotificationStatus(desiredStatus); this.notification = notification; + const modalData = this.getModalDataBasedOnNotificationStatus(desiredStatus); if (this.hasTextArea(desiredStatus)){ this.showTextArea = true; this.textAreaControl.setValidators([ Validators.required, Validators.maxLength(1000), Validators.minLength(15) ]); this.formGroup.reset(); + } else { + this.showTextArea = false; } const onConfirm = (isConfirmed: boolean) => { if (!isConfirmed) return; @@ -158,7 +157,8 @@ export class NotificationActionModalComponent { } - private hasTextArea(desiredStatus: NotificationStatus | NotificationStatus.ACCEPTED | NotificationStatus.ACKNOWLEDGED | NotificationStatus.APPROVED | NotificationStatus.CANCELED | NotificationStatus.CREATED | NotificationStatus.DECLINED | NotificationStatus.RECEIVED | NotificationStatus.SENT) { + private hasTextArea(desiredStatus: NotificationStatus) { + console.log(desiredStatus, "desired from textarea"); return desiredStatus === NotificationStatus.CLOSED || desiredStatus === NotificationStatus.ACCEPTED || desiredStatus === NotificationStatus.DECLINED; } } From 82ee66098b42bbb36836472882bab7509605733c Mon Sep 17 00:00:00 2001 From: Maximilian Wesener Date: Mon, 1 Apr 2024 22:52:57 +0200 Subject: [PATCH 06/14] chore(feature): 616 - Fixed modal functions --- .../notificationMenuActions.assembler.spec.ts | 2 - .../notification-reason.component.spec.ts | 58 ------------------- 2 files changed, 60 deletions(-) delete mode 100644 frontend/src/app/modules/shared/components/notification-reason/notification-reason.component.spec.ts diff --git a/frontend/src/app/modules/shared/assembler/notificationMenuActions.assembler.spec.ts b/frontend/src/app/modules/shared/assembler/notificationMenuActions.assembler.spec.ts index 24a9821b33..9bcf57678a 100644 --- a/frontend/src/app/modules/shared/assembler/notificationMenuActions.assembler.spec.ts +++ b/frontend/src/app/modules/shared/assembler/notificationMenuActions.assembler.spec.ts @@ -28,7 +28,6 @@ import { NotificationMenuActionsAssembler } from '@shared/assembler/notification import { NotificationCommonModalComponent } from '@shared/components/notification-common-modal/notification-common-modal.component'; import { Notification, NotificationStatus } from '@shared/model/notification.model'; import { Severity } from '@shared/model/severity.model'; -import { CloseNotificationModalComponent } from '@shared/modules/notification/modal/close/close-notification-modal.component'; import { KeycloakService } from 'keycloak-angular'; describe('NotificationMenuActionsAssembler', () => { @@ -52,7 +51,6 @@ describe('NotificationMenuActionsAssembler', () => { NotificationActionHelperService, NotificationCommonModalComponent, NotificationMenuActionsAssembler, - CloseNotificationModalComponent, ], }); notificationCommonModalComponent = TestBed.inject(NotificationCommonModalComponent); diff --git a/frontend/src/app/modules/shared/components/notification-reason/notification-reason.component.spec.ts b/frontend/src/app/modules/shared/components/notification-reason/notification-reason.component.spec.ts deleted file mode 100644 index 2967b2f40c..0000000000 --- a/frontend/src/app/modules/shared/components/notification-reason/notification-reason.component.spec.ts +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2022, 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2022, 2023 ZF Friedrichshafen AG - * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -import { NotificationStatus } from '@shared/model/notification.model'; -import { notificationTemplate } from '@shared/modules/notification/modal/modalTestHelper.spec'; -import { SharedModule } from '@shared/shared.module'; -import { screen } from '@testing-library/angular'; -import { renderComponent } from '@tests/test-render.utils'; - -describe('NotificationReasonComponent', () => { - const defaultNotification = Object.assign({ ...notificationTemplate }); - const renderReason = (notification: Notification = defaultNotification) => { - return renderComponent(``, { - imports: [ SharedModule ], - componentProperties: { notification }, - }); - }; - - it('should render description', async () => { - await renderReason(); - expect(screen.getByText(defaultNotification.description)).toBeInTheDocument(); - }); - - it('should render accept reason with sent status', async () => { - const reason = { accept: 'Accept reason', close: '', decline: '' }; - const status = NotificationStatus.SENT; - - await renderReason({ ...defaultNotification, reason, status }); - expect(screen.getByText(reason.accept)).toBeInTheDocument(); - expect(screen.getByText('commonAlert.status.SENT')).toBeInTheDocument(); - expect(screen.getByText(defaultNotification.createdByName)).toBeInTheDocument(); - expect(screen.getByText(defaultNotification.sendToName)).toBeInTheDocument(); - }); - - - it('should render username from sender', async () => { - await renderReason(); - expect(screen.getByText(defaultNotification.createdByName)).toBeInTheDocument(); - }); -}); From af0d30edb4e827a415b0eba73acc97fad09fade5 Mon Sep 17 00:00:00 2001 From: Maximilian Wesener Date: Tue, 2 Apr 2024 08:33:28 +0200 Subject: [PATCH 07/14] chore(feature): 616 - Fixed title, close notification and modal comp. --- .../request-notification/request-notification.component.ts | 4 ++-- .../src/app/modules/shared/service/notification.service.ts | 4 ++-- .../tractusx/traceability/common/model/SecurityUtils.java | 1 + .../notification/mapper/NotificationResponseMapper.java | 1 + .../notification/domain/base/model/NotificationStatus.java | 5 +++-- .../domain/base/service/AbstractNotificationService.java | 5 +++-- .../java/notification/request/StartNotificationRequest.java | 2 +- 7 files changed, 13 insertions(+), 9 deletions(-) diff --git a/frontend/src/app/modules/shared/components/request-notification/request-notification.component.ts b/frontend/src/app/modules/shared/components/request-notification/request-notification.component.ts index 5e8c59463b..7e8fefaf9f 100644 --- a/frontend/src/app/modules/shared/components/request-notification/request-notification.component.ts +++ b/frontend/src/app/modules/shared/components/request-notification/request-notification.component.ts @@ -95,12 +95,12 @@ export class RequestNotificationComponent { // set asBuilt parameter if one of the selectedItems are a asPlanned Part const isAsBuilt = this.selectedItems.map(part => part.semanticDataModel === SemanticDataModel.PARTASPLANNED).includes(true); - const { description, bpn, severity } = this.formGroup.value; + const { description, bpn, severity, title } = this.formGroup.value; const { link, queryParams } = getRoute(NOTIFICATION_BASE_ROUTE, NotificationStatusGroup.QUEUED_AND_REQUESTED); let type = this.isInvestigation ? 'INVESTIGATION' : 'ALERT'; - this.notificationService.createNotification(partIds, description, severity, bpn, isAsBuilt, type).subscribe({ + this.notificationService.createNotification(partIds, description, severity, bpn, isAsBuilt, type, title).subscribe({ next: () => this.onSuccessfulSubmit(link, queryParams), error: (err) => this.onUnsuccessfulSubmit(err.error.message), }); diff --git a/frontend/src/app/modules/shared/service/notification.service.ts b/frontend/src/app/modules/shared/service/notification.service.ts index 6c76a13b60..c71244366a 100644 --- a/frontend/src/app/modules/shared/service/notification.service.ts +++ b/frontend/src/app/modules/shared/service/notification.service.ts @@ -100,8 +100,8 @@ export class NotificationService { .pipe(map(notification => NotificationAssembler.assembleNotification(notification))); } - public createNotification(partIds: string[], description: string, severity: Severity, bpn: string, isAsBuilt: boolean, type: string): Observable { - const body = { partIds, description, severity, receiverBpn: bpn, isAsBuilt, type }; + public createNotification(partIds: string[], description: string, severity: Severity, bpn: string, isAsBuilt: boolean, type: string, title: string): Observable { + const body = { partIds, description, severity, receiverBpn: bpn, isAsBuilt, type, title }; return this.apiService.post(`${ this.url }/notifications`, body).pipe(map(({ id }) => id)); } diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/model/SecurityUtils.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/model/SecurityUtils.java index df8603ec3e..e739309b34 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/model/SecurityUtils.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/model/SecurityUtils.java @@ -57,6 +57,7 @@ public static StartNotificationRequest sanitize(StartNotificationRequest request String cleanReceiverBpn = sanitize(request.getReceiverBpn()); List cleanPartIds = sanitize(request.getPartIds()); return StartNotificationRequest.builder() + .title(request.getTitle()) .description(cleanDescription) .targetDate(request.getTargetDate()) .severity(request.getSeverity()) diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/application/notification/mapper/NotificationResponseMapper.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/application/notification/mapper/NotificationResponseMapper.java index 78fb1bfb73..f7adc8e55b 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/application/notification/mapper/NotificationResponseMapper.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/application/notification/mapper/NotificationResponseMapper.java @@ -53,6 +53,7 @@ public static NotificationResponse from(Notification notification) { .assetIds(Collections.unmodifiableList(notification.getAssetIds())) .channel(NotificationMessageMapper.from(notification.getNotificationSide())) .type(NotificationMessageMapper.from(notification.getNotificationType())) + .title(notification.getTitle()) .reason(new NotificationReasonResponse( notification.getCloseReason(), notification.getAcceptReason(), diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/model/NotificationStatus.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/model/NotificationStatus.java index c05a9ceb44..dcab76eac1 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/model/NotificationStatus.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/model/NotificationStatus.java @@ -80,11 +80,12 @@ public static NotificationStatus fromStringValue(String value) { return MAPPINGS.get(value); } - public static NotificationStatus getPreviousStatus(NotificationStatus status) { + public static NotificationStatus getPreviousStatus(NotificationStatus status, List messages) { return switch (status) { case CREATED, SENT, CANCELED -> NotificationStatus.CREATED; - case ACKNOWLEDGED, RECEIVED, CLOSED -> NotificationStatus.SENT; + case ACKNOWLEDGED, RECEIVED -> NotificationStatus.SENT; case ACCEPTED, DECLINED -> NotificationStatus.ACKNOWLEDGED; + case CLOSED -> messages.size() > 1 ? NotificationStatus.SENT : NotificationStatus.CREATED; }; } public boolean transitionAllowed(NotificationStatus to) { diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/service/AbstractNotificationService.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/service/AbstractNotificationService.java index e81db3cab7..c09dad7b83 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/service/AbstractNotificationService.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/service/AbstractNotificationService.java @@ -71,12 +71,13 @@ public NotificationId start(StartNotification startNotification) { public void update(Long notificationId, NotificationStatus notificationStatus, String reason) { Notification notification = loadOrNotFoundException(new NotificationId(notificationId)); - NotificationStatus previousStatus = NotificationStatus.getPreviousStatus(notificationStatus); + List messages = notification.getNotifications(); + NotificationStatus previousStatus = NotificationStatus.getPreviousStatus(notificationStatus, messages); /* Create a copy of the latest notifications. As per asset there will be a notification created on start it is possible that several elements with the same previous state are returned.*/ - notification.getNotifications().stream() + messages.stream() .filter(notificationMessage -> notificationMessage.getNotificationStatus().equals(previousStatus)) .forEach(notificationMessage -> { NotificationMessage notificationMessageSwitchedSenderAndReceiver = notificationMessage.copyAndSwitchSenderAndReceiver(traceabilityProperties.getBpn()); diff --git a/tx-models/src/main/java/notification/request/StartNotificationRequest.java b/tx-models/src/main/java/notification/request/StartNotificationRequest.java index 2bf7190f94..3aa31ebb11 100644 --- a/tx-models/src/main/java/notification/request/StartNotificationRequest.java +++ b/tx-models/src/main/java/notification/request/StartNotificationRequest.java @@ -39,7 +39,7 @@ @AllArgsConstructor public class StartNotificationRequest { - @Size(min = 1, max = 255, message = "Specify at least 1 and at most 50 assetIds") + @Size(min = 1, max = 255, message = "Specify at least 1 and at most 255 characters for the title") @Schema(example = "title", minLength = 1, maxLength = 255) private String title; From 2b646d494141c3464397d6c25820e9bf81e92ef5 Mon Sep 17 00:00:00 2001 From: ds-mwesener <124587888+ds-mwesener@users.noreply.github.com> Date: Tue, 2 Apr 2024 06:59:28 +0000 Subject: [PATCH 08/14] Update Dependencies Backend Action --- DEPENDENCIES_BACKEND | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPENDENCIES_BACKEND b/DEPENDENCIES_BACKEND index 754930490a..6b5ca2b1cf 100644 --- a/DEPENDENCIES_BACKEND +++ b/DEPENDENCIES_BACKEND @@ -333,9 +333,9 @@ maven/mavencentral/org.jboss.logging/jboss-logging/3.5.3.Final, Apache-2.0, appr maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib-common/1.9.0, Apache-2.0, approved, #14186 maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib-common/1.9.23, Apache-2.0, approved, #14186 maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.6.10, Apache-2.0, approved, clearlydefined -maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.9.23, None, restricted, #14188 +maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.9.23, Apache-2.0, approved, #14188 maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib-jdk8/1.6.10, Apache-2.0, approved, clearlydefined -maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib-jdk8/1.9.23, None, restricted, #14185 +maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib-jdk8/1.9.23, Apache-2.0, approved, #14185 maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib/1.6.20, Apache-2.0, approved, clearlydefined maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib/1.9.23, Apache-2.0, approved, #11827 maven/mavencentral/org.jetbrains/annotations/24.1.0, Apache-2.0, approved, clearlydefined From e6a3c6cb39cafd5bc7ba77a20ae3c02e413f766f Mon Sep 17 00:00:00 2001 From: Maximilian Wesener Date: Tue, 2 Apr 2024 09:34:08 +0200 Subject: [PATCH 09/14] chore(feature): 616 - Removed all flags for investigation / alert differentiations which are not necessary anymore. --- .../dashboard/abstraction/dashboard.facade.ts | 9 +- .../core/notifications.facade.ts | 19 +-- .../presentation/notifications.component.ts | 1 - .../autocomplete-strategy.ts | 3 +- .../notification.component.spec.ts | 4 +- .../service/notification.service.spec.ts | 149 +++++++++--------- .../shared/service/notification.service.ts | 40 ++--- 7 files changed, 98 insertions(+), 127 deletions(-) diff --git a/frontend/src/app/modules/page/dashboard/abstraction/dashboard.facade.ts b/frontend/src/app/modules/page/dashboard/abstraction/dashboard.facade.ts index db6fe92728..b2fecb0b4d 100644 --- a/frontend/src/app/modules/page/dashboard/abstraction/dashboard.facade.ts +++ b/frontend/src/app/modules/page/dashboard/abstraction/dashboard.facade.ts @@ -20,6 +20,7 @@ ********************************************************************************/ import { Injectable } from '@angular/core'; +import { NotificationChannel } from '@shared/components/multi-select-autocomplete/table-type.model'; import { Notifications } from '@shared/model/notification.model'; import { View } from '@shared/model/view.model'; import { NotificationService } from '@shared/service/notification.service'; @@ -97,7 +98,7 @@ export class DashboardFacade { private setReceivedInvestigations(): void { this.investigationsReceivedSubscription?.unsubscribe(); - this.investigationsReceivedSubscription = this.notificationService.getReceived(0, 5, [ [ 'createdDate', 'desc' ] ], null, null, true).subscribe({ + this.investigationsReceivedSubscription = this.notificationService.getNotifications(0, 5, [ [ 'createdDate', 'desc' ] ], NotificationChannel.RECEIVER, null, null).subscribe({ next: data => this.dashboardState.setRecentReceivedInvestigations({ data }), error: (error: Error) => this.dashboardState.setRecentReceivedInvestigations({ error }), }); @@ -105,7 +106,7 @@ export class DashboardFacade { private setCreatedInvestigations(): void { this.investigationsCreatedSubscription?.unsubscribe(); - this.investigationsCreatedSubscription = this.notificationService.getCreated(0, 5, [ [ 'createdDate', 'desc' ] ], null, null, true).subscribe({ + this.investigationsCreatedSubscription = this.notificationService.getNotifications(0, 5, [ [ 'createdDate', 'desc' ] ], NotificationChannel.SENDER, null, null).subscribe({ next: data => this.dashboardState.setRecentCreatedInvestigations({ data }), error: (error: Error) => this.dashboardState.setRecentCreatedInvestigations({ error }), }); @@ -113,7 +114,7 @@ export class DashboardFacade { private setReceivedAlerts(): void { this.alertsReceivedSubscription?.unsubscribe(); - this.alertsReceivedSubscription = this.notificationService.getReceived(0, 5, [ [ 'createdDate', 'desc' ] ], null, null, false).subscribe({ + this.alertsReceivedSubscription = this.notificationService.getNotifications(0, 5, [ [ 'createdDate', 'desc' ] ], NotificationChannel.RECEIVER, null, null).subscribe({ next: data => this.dashboardState.setRecentReceivedAlerts({ data }), error: (error: Error) => this.dashboardState.setRecentReceivedAlerts({ error }), }); @@ -122,7 +123,7 @@ export class DashboardFacade { private setCreatedAlerts(): void { this.alertsCreatedSubscription?.unsubscribe(); - this.alertsCreatedSubscription = this.notificationService.getCreated(0, 5, [ [ 'createdDate', 'desc' ] ], null, null, false).subscribe({ + this.alertsCreatedSubscription = this.notificationService.getNotifications(0, 5, [ [ 'createdDate', 'desc' ] ], NotificationChannel.SENDER, null, null).subscribe({ next: data => this.dashboardState.setRecentCreatedAlerts({ data }), error: (error: Error) => this.dashboardState.setRecentCreatedAlerts({ error }), }); diff --git a/frontend/src/app/modules/page/notifications/core/notifications.facade.ts b/frontend/src/app/modules/page/notifications/core/notifications.facade.ts index b59b9d0494..79734f395b 100644 --- a/frontend/src/app/modules/page/notifications/core/notifications.facade.ts +++ b/frontend/src/app/modules/page/notifications/core/notifications.facade.ts @@ -20,6 +20,7 @@ import { Injectable } from '@angular/core'; import { NotificationsState } from '@page/notifications/core/notifications.state'; import { provideDataObject } from '@page/parts/core/parts.helper'; +import { NotificationChannel } from '@shared/components/multi-select-autocomplete/table-type.model'; import { TableHeaderSort } from '@shared/components/table/table.model'; import { Notification, @@ -51,13 +52,13 @@ export class NotificationsFacade { } public getNotification(id: string): Observable { - return this.notificationService.getNotificationById(id, false); + return this.notificationService.getNotificationById(id); } public setReceivedNotifications(page = 0, pageSize = 50, sorting: TableHeaderSort[] = [], filter?: NotificationDeeplinkFilter, fullFilter?: any): void { this.notificationReceivedSubscription?.unsubscribe(); this.notificationReceivedSubscription = this.notificationService - .getReceived(page, pageSize, sorting, filter, fullFilter, false) + .getNotifications(page, pageSize, sorting, NotificationChannel.RECEIVER, filter, fullFilter) .subscribe({ next: data => (this.notificationsState.notificationsReceived = { data: provideDataObject(data) }), error: (error: Error) => (this.notificationsState.notificationsReceived = { error }), @@ -67,7 +68,7 @@ export class NotificationsFacade { public setQueuedAndRequestedNotifications(page = 0, pageSize = 50, sorting: TableHeaderSort[] = [], filter?: NotificationDeeplinkFilter, fullFilter?: any): void { this.notificationQueuedAndRequestedSubscription?.unsubscribe(); this.notificationQueuedAndRequestedSubscription = this.notificationService - .getCreated(page, pageSize, sorting, filter, fullFilter, false) + .getNotifications(page, pageSize, sorting, NotificationChannel.SENDER, filter, fullFilter) .subscribe({ next: data => (this.notificationsState.notificationsQueuedAndRequested = { data: provideDataObject(data) }), error: (error: Error) => (this.notificationsState.notificationsQueuedAndRequested = { error }), @@ -81,26 +82,26 @@ export class NotificationsFacade { public closeNotification(notificationId: string, reason: string): Observable { - return this.notificationService.closeNotification(notificationId, reason, false); + return this.notificationService.closeNotification(notificationId, reason); } public approveNotification(notificationId: string): Observable { - return this.notificationService.approveNotification(notificationId, false); + return this.notificationService.approveNotification(notificationId); } public cancelNotification(notificationId: string): Observable { - return this.notificationService.cancelNotification(notificationId, false); + return this.notificationService.cancelNotification(notificationId); } public acknowledgeNotification(notificationId: string): Observable { - return this.notificationService.updateNotification(notificationId, NotificationStatus.ACKNOWLEDGED, null, false); + return this.notificationService.updateNotification(notificationId, NotificationStatus.ACKNOWLEDGED, null); } public acceptNotification(notificationId: string, reason: string): Observable { - return this.notificationService.updateNotification(notificationId, NotificationStatus.ACCEPTED, reason, false); + return this.notificationService.updateNotification(notificationId, NotificationStatus.ACCEPTED, reason); } public declineNotification(notificationId: string, reason: string): Observable { - return this.notificationService.updateNotification(notificationId, NotificationStatus.DECLINED, reason, false); + return this.notificationService.updateNotification(notificationId, NotificationStatus.DECLINED, reason); } } diff --git a/frontend/src/app/modules/page/notifications/presentation/notifications.component.ts b/frontend/src/app/modules/page/notifications/presentation/notifications.component.ts index afeef13beb..c9d112c859 100644 --- a/frontend/src/app/modules/page/notifications/presentation/notifications.component.ts +++ b/frontend/src/app/modules/page/notifications/presentation/notifications.component.ts @@ -52,7 +52,6 @@ export class NotificationsComponent { public readonly notificationsReceived$; public readonly notificationsQueuedAndRequested$; - public isInvestigation = false; public menuActionsConfig: MenuActionConfig[]; public notificationReceivedSortList: TableHeaderSort[] = []; diff --git a/frontend/src/app/modules/shared/components/multi-select-autocomplete/autocomplete-strategy.ts b/frontend/src/app/modules/shared/components/multi-select-autocomplete/autocomplete-strategy.ts index 02b757ccdb..844312b540 100644 --- a/frontend/src/app/modules/shared/components/multi-select-autocomplete/autocomplete-strategy.ts +++ b/frontend/src/app/modules/shared/components/multi-select-autocomplete/autocomplete-strategy.ts @@ -66,8 +66,7 @@ export class NotificationStrategy extends AutocompleteStrategy { return this.notificationService.getDistinctFilterValues( notificationChannel, filterColumns, - searchElement, - false, + searchElement ); } } diff --git a/frontend/src/app/modules/shared/modules/notification/presentation/notification.component.spec.ts b/frontend/src/app/modules/shared/modules/notification/presentation/notification.component.spec.ts index 382abcacbb..57d472b59a 100644 --- a/frontend/src/app/modules/shared/modules/notification/presentation/notification.component.spec.ts +++ b/frontend/src/app/modules/shared/modules/notification/presentation/notification.component.spec.ts @@ -83,7 +83,6 @@ describe('NotificationsInboxComponent', () => { }).pipe(delay(0)); const menuActionsConfig = []; const notificationType = NotificationType.INVESTIGATION; - const isInvestigation = true; return renderComponent( ` { receivedNotifications$, clickHandler, menuActionsConfig, - notificationType, - isInvestigation, + notificationType }, }, ); diff --git a/frontend/src/app/modules/shared/service/notification.service.spec.ts b/frontend/src/app/modules/shared/service/notification.service.spec.ts index 761f64441e..35aa48109e 100644 --- a/frontend/src/app/modules/shared/service/notification.service.spec.ts +++ b/frontend/src/app/modules/shared/service/notification.service.spec.ts @@ -16,102 +16,97 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -import {NotificationService} from "@shared/service/notification.service"; -import {HttpClientTestingModule, HttpTestingController} from "@angular/common/http/testing"; -import {TestBed} from "@angular/core/testing"; -import {NotificationStatus} from "@shared/model/notification.model"; -import {NotificationChannel} from "@shared/components/multi-select-autocomplete/table-type.model"; -import {AuthService} from "@core/auth/auth.service"; -import {ApiService} from "@core/api/api.service"; -import {KeycloakService} from "keycloak-angular"; +import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; +import { TestBed } from '@angular/core/testing'; +import { ApiService } from '@core/api/api.service'; +import { AuthService } from '@core/auth/auth.service'; +import { NotificationChannel } from '@shared/components/multi-select-autocomplete/table-type.model'; +import { NotificationStatus } from '@shared/model/notification.model'; +import { NotificationService } from '@shared/service/notification.service'; +import { KeycloakService } from 'keycloak-angular'; describe('NotificationService', () => { - let service: NotificationService; - let httpTestingController: HttpTestingController; - let authService: AuthService; - - beforeEach(() => { - TestBed.configureTestingModule({ - imports: [HttpClientTestingModule], - providers: [NotificationService, ApiService, KeycloakService, AuthService], - }); - service = TestBed.inject(NotificationService); - httpTestingController = TestBed.inject(HttpTestingController); - authService = TestBed.inject(AuthService); + let service: NotificationService; + let httpTestingController: HttpTestingController; + let authService: AuthService; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ HttpClientTestingModule ], + providers: [ NotificationService, ApiService, KeycloakService, AuthService ], }); + service = TestBed.inject(NotificationService); + httpTestingController = TestBed.inject(HttpTestingController); + authService = TestBed.inject(AuthService); + }); - afterEach(() => { - httpTestingController.verify(); - }); + afterEach(() => { + httpTestingController.verify(); + }); - it('should close a notification', () => { - const notificationId = '123'; - const reason = 'Test reason'; - const isInvestigation = true; - spyOn(authService, 'getBearerToken').and.returnValue('testtoken'); + it('should close a notification', () => { + const notificationId = '123'; + const reason = 'Test reason'; + spyOn(authService, 'getBearerToken').and.returnValue('testtoken'); - service.closeNotification(notificationId, reason, isInvestigation).subscribe(); + service.closeNotification(notificationId, reason).subscribe(); - const req = httpTestingController.expectOne(`${service.notificationUrl()}/${notificationId}/close`); - expect(req.request.method).toBe('POST'); - expect(req.request.body).toEqual( '{"reason":"Test reason"}'); - req.flush({}); - }); + const req = httpTestingController.expectOne(`${ service.notificationUrl() }/${ notificationId }/close`); + expect(req.request.method).toBe('POST'); + expect(req.request.body).toEqual('{"reason":"Test reason"}'); + req.flush({}); + }); - it('should approve a notification', () => { - const notificationId = '123'; - const isInvestigation = true; - spyOn(authService, 'getBearerToken').and.returnValue('testtoken'); + it('should approve a notification', () => { + const notificationId = '123'; + spyOn(authService, 'getBearerToken').and.returnValue('testtoken'); - service.approveNotification(notificationId, isInvestigation).subscribe(); + service.approveNotification(notificationId).subscribe(); - const req = httpTestingController.expectOne(`${service.notificationUrl()}/${notificationId}/approve`); - expect(req.request.method).toBe('POST'); - req.flush({}); - }); + const req = httpTestingController.expectOne(`${ service.notificationUrl() }/${ notificationId }/approve`); + expect(req.request.method).toBe('POST'); + req.flush({}); + }); - it('should cancel a notification', () => { - const notificationId = '123'; - const isInvestigation = true; - spyOn(authService, 'getBearerToken').and.returnValue('testtoken'); + it('should cancel a notification', () => { + const notificationId = '123'; + spyOn(authService, 'getBearerToken').and.returnValue('testtoken'); - service.cancelNotification(notificationId, isInvestigation).subscribe(); + service.cancelNotification(notificationId).subscribe(); - const req = httpTestingController.expectOne(`${service.notificationUrl()}/${notificationId}/cancel`); - expect(req.request.method).toBe('POST'); - req.flush({}); - }); + const req = httpTestingController.expectOne(`${ service.notificationUrl() }/${ notificationId }/cancel`); + expect(req.request.method).toBe('POST'); + req.flush({}); + }); - it('should update a notification', () => { - const notificationId = '123'; - const status = NotificationStatus.ACKNOWLEDGED; - const reason = 'Test reason'; - const isInvestigation = true; - spyOn(authService, 'getBearerToken').and.returnValue('testtoken'); + it('should update a notification', () => { + const notificationId = '123'; + const status = NotificationStatus.ACKNOWLEDGED; + const reason = 'Test reason'; + spyOn(authService, 'getBearerToken').and.returnValue('testtoken'); - service.updateNotification(notificationId, status, reason, isInvestigation).subscribe(); + service.updateNotification(notificationId, status, reason).subscribe(); - const req = httpTestingController.expectOne(`${service.notificationUrl()}/${notificationId}/update`); - expect(req.request.method).toBe('POST'); - expect(req.request.body).toEqual('{"reason":"Test reason","status":"ACKNOWLEDGED"}'); - req.flush({}); - }); + const req = httpTestingController.expectOne(`${ service.notificationUrl() }/${ notificationId }/update`); + expect(req.request.method).toBe('POST'); + expect(req.request.body).toEqual('{"reason":"Test reason","status":"ACKNOWLEDGED"}'); + req.flush({}); + }); - it('should get distinct filter values', () => { - const channel: NotificationChannel = NotificationChannel.SENDER; - const fieldNames = 'SomeField'; - const startsWith = 'Test'; - const isInvestigation = true; - spyOn(authService, 'getBearerToken').and.returnValue('testtoken'); + it('should get distinct filter values', () => { + const channel: NotificationChannel = NotificationChannel.SENDER; + const fieldNames = 'SomeField'; + const startsWith = 'Test'; + spyOn(authService, 'getBearerToken').and.returnValue('testtoken'); - service.getDistinctFilterValues(channel, fieldNames, startsWith, isInvestigation).subscribe(); + service.getDistinctFilterValues(channel, fieldNames, startsWith).subscribe(); - const req = httpTestingController.expectOne( - `${service.notificationUrl()}/distinctFilterValues?fieldName=SomeField&startWith=Test&size=200&channel=SENDER` - ); - expect(req.request.method).toBe('GET'); - req.flush({}); - }); + const req = httpTestingController.expectOne( + `${ service.notificationUrl() }/distinctFilterValues?fieldName=SomeField&startWith=Test&size=200&channel=SENDER`, + ); + expect(req.request.method).toBe('GET'); + req.flush({}); + }); }); diff --git a/frontend/src/app/modules/shared/service/notification.service.ts b/frontend/src/app/modules/shared/service/notification.service.ts index c71244366a..bc3f312a57 100644 --- a/frontend/src/app/modules/shared/service/notification.service.ts +++ b/frontend/src/app/modules/shared/service/notification.service.ts @@ -48,33 +48,11 @@ export class NotificationService { constructor(private readonly apiService: ApiService) { } - - // TODO: merge functions for created and received notifications - public getCreated(page: number, pageSize: number, sorting: TableHeaderSort[], filter?: NotificationDeeplinkFilter, fullFilter?: any, isInvestigation = true): Observable { - const sort = sorting.length ? sorting.map(array => `${ array[0] },${ array[1] }`) : [ 'createdDate,desc' ]; - const requestUrl = this.notificationUrl() + '/filter'; - const additionalFilters = new Set([ ...provideFilterListForNotifications(filter, fullFilter), 'channel,EQUAL,SENDER,AND' ]); - - const body = { - pageAble: { - page: page, - size: pageSize, - sort: [ ...sort ], - }, - searchCriteria: { - filter: [ ...additionalFilters ], - }, - }; - - return this.apiService - .post(requestUrl, body) - .pipe(map(data => NotificationAssembler.assembleNotifications(data))); - } - - public getReceived(page: number, pageSize: number, sorting: TableHeaderSort[], filter?: NotificationDeeplinkFilter, fullFilter?: any, isInvestigation = true): Observable { + public getNotifications(page: number, pageSize: number, sorting: TableHeaderSort[], channel: NotificationChannel, filter?: NotificationDeeplinkFilter, fullFilter?: any): Observable { const sort = sorting.length ? sorting.map(array => `${ array[0] },${ array[1] }`) : [ 'createdDate,desc' ]; const requestUrl = this.notificationUrl() + '/filter'; - const additionalFilters = new Set([ ...provideFilterListForNotifications(filter, fullFilter), 'channel,EQUAL,RECEIVER,AND' ]); + const channelFilter = channel === NotificationChannel.RECEIVER ? 'channel,EQUAL,RECEIVER,AND' : 'channel,EQUAL,SENDER,AND'; + const additionalFilters = new Set([ ...provideFilterListForNotifications(filter, fullFilter), channelFilter ]); const body = { pageAble: { @@ -93,7 +71,7 @@ export class NotificationService { } - public getNotificationById(id: string, isInvestigation = true): Observable { + public getNotificationById(id: string): Observable { const requestUrl = this.notificationUrl(); return this.apiService .get(`${ requestUrl }/${ id }`) @@ -107,18 +85,18 @@ export class NotificationService { } - public closeNotification(id: string, reason: string, isInvestigation = true): Observable { + public closeNotification(id: string, reason: string): Observable { const requestUrl = this.notificationUrl(); const body = { reason }; return this.apiService.post(`${ requestUrl }/${ id }/close`, body); } - public approveNotification(id: string, isInvestigation = true): Observable { + public approveNotification(id: string): Observable { const requestUrl = this.notificationUrl(); return this.apiService.post(`${ requestUrl }/${ id }/approve`); } - public cancelNotification(id: string, isInvestigation = true): Observable { + public cancelNotification(id: string): Observable { const requestUrl = this.notificationUrl(); return this.apiService.post(`${ requestUrl }/${ id }/cancel`); } @@ -126,14 +104,14 @@ export class NotificationService { public updateNotification( id: string, status: NotificationStatus.ACKNOWLEDGED | NotificationStatus.ACCEPTED | NotificationStatus.DECLINED, - reason = '', isInvestigation = true, + reason = '', ): Observable { const requestUrl = this.notificationUrl(); const body = { reason, status }; return this.apiService.post(`${ requestUrl }/${ id }/update`, body); } - public getDistinctFilterValues(channel: NotificationChannel, fieldNames: string, startsWith: string, isInvestigation = true) { + public getDistinctFilterValues(channel: NotificationChannel, fieldNames: string, startsWith: string) { const mappedFieldName = PartsAssembler.mapFieldNameToApi(fieldNames); const requestUrl = this.notificationUrl(); let params = new HttpParams() From 89358c0d1ac7f364bf8f6a1c1bf05ba9bdd04d05 Mon Sep 17 00:00:00 2001 From: Maximilian Wesener Date: Tue, 2 Apr 2024 10:14:31 +0200 Subject: [PATCH 10/14] chore(feature): 616 - Removed all flags for investigation / alert differentiations which are not necessary anymore. --- .../java/notification/request/StartNotificationRequest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tx-models/src/main/java/notification/request/StartNotificationRequest.java b/tx-models/src/main/java/notification/request/StartNotificationRequest.java index 3aa31ebb11..e839db9718 100644 --- a/tx-models/src/main/java/notification/request/StartNotificationRequest.java +++ b/tx-models/src/main/java/notification/request/StartNotificationRequest.java @@ -39,8 +39,8 @@ @AllArgsConstructor public class StartNotificationRequest { - @Size(min = 1, max = 255, message = "Specify at least 1 and at most 255 characters for the title") - @Schema(example = "title", minLength = 1, maxLength = 255) + @Size(max = 255, message = "Specify at least 1 and at most 255 characters for the title") + @Schema(example = "title", maxLength = 255) private String title; @Size(min = 1, max = 50, message = "Specify at least 1 and at most 50 assetIds") From 7ba0f7a4e8b113f015c64532249b839f4f790735 Mon Sep 17 00:00:00 2001 From: Maximilian Wesener Date: Tue, 2 Apr 2024 10:19:21 +0200 Subject: [PATCH 11/14] chore(feature): 616 - Removed all flags for investigation / alert differentiations which are not necessary anymore. --- .../request-notification/request-notification.component.ts | 5 ++++- .../java/notification/request/StartNotificationRequest.java | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/modules/shared/components/request-notification/request-notification.component.ts b/frontend/src/app/modules/shared/components/request-notification/request-notification.component.ts index 7e8fefaf9f..8f3f0bceaf 100644 --- a/frontend/src/app/modules/shared/components/request-notification/request-notification.component.ts +++ b/frontend/src/app/modules/shared/components/request-notification/request-notification.component.ts @@ -95,10 +95,13 @@ export class RequestNotificationComponent { // set asBuilt parameter if one of the selectedItems are a asPlanned Part const isAsBuilt = this.selectedItems.map(part => part.semanticDataModel === SemanticDataModel.PARTASPLANNED).includes(true); - const { description, bpn, severity, title } = this.formGroup.value; + let { description, bpn, severity, title } = this.formGroup.value; const { link, queryParams } = getRoute(NOTIFICATION_BASE_ROUTE, NotificationStatusGroup.QUEUED_AND_REQUESTED); let type = this.isInvestigation ? 'INVESTIGATION' : 'ALERT'; + if (title === ""){ + title = null; + } this.notificationService.createNotification(partIds, description, severity, bpn, isAsBuilt, type, title).subscribe({ next: () => this.onSuccessfulSubmit(link, queryParams), diff --git a/tx-models/src/main/java/notification/request/StartNotificationRequest.java b/tx-models/src/main/java/notification/request/StartNotificationRequest.java index e839db9718..3aa31ebb11 100644 --- a/tx-models/src/main/java/notification/request/StartNotificationRequest.java +++ b/tx-models/src/main/java/notification/request/StartNotificationRequest.java @@ -39,8 +39,8 @@ @AllArgsConstructor public class StartNotificationRequest { - @Size(max = 255, message = "Specify at least 1 and at most 255 characters for the title") - @Schema(example = "title", maxLength = 255) + @Size(min = 1, max = 255, message = "Specify at least 1 and at most 255 characters for the title") + @Schema(example = "title", minLength = 1, maxLength = 255) private String title; @Size(min = 1, max = 50, message = "Specify at least 1 and at most 50 assetIds") From 314ac9e1d0dfaaaff7058ea443baef1656f420bb Mon Sep 17 00:00:00 2001 From: Maximilian Wesener Date: Tue, 2 Apr 2024 11:00:45 +0200 Subject: [PATCH 12/14] chore(feature): 616 - Adapt policy doc. --- .../arc42/runtime-view/policies/policy-assets.puml | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/docs/src/uml-diagrams/arc42/runtime-view/policies/policy-assets.puml b/docs/src/uml-diagrams/arc42/runtime-view/policies/policy-assets.puml index ab6f6b49d2..156295f813 100644 --- a/docs/src/uml-diagrams/arc42/runtime-view/policies/policy-assets.puml +++ b/docs/src/uml-diagrams/arc42/runtime-view/policies/policy-assets.puml @@ -5,18 +5,11 @@ skinparam defaultFontName "Architects daughter" title Sequence diagram: Policy handling on asset provisioning flow participant "Trace-X" as TraceX -participant "EDC Consumer" as EdcConsumer participant "EDC Provider (other)" as EdcProvider activate TraceX TraceX -> TraceX: Publish asset to core services -TraceX -> EdcConsumer: Register policy -activate EdcConsumer -EdcConsumer -> EdcProvider: Register policy -activate EdcProvider -EdcProvider --> EdcConsumer: Ok -deactivate EdcProvider -EdcConsumer --> TraceX: Ok -deactivate EdcConsumer +TraceX -> EdcProvider: Register policy +EdcProvider --> TraceX: Ok TraceX -> TraceX: Reuse policy for contract definition creation @enduml From 1df54b4ce001ea15916edfe156a4618f67e32068 Mon Sep 17 00:00:00 2001 From: Maximilian Wesener Date: Tue, 2 Apr 2024 14:00:48 +0200 Subject: [PATCH 13/14] chore(feature): 616 - Cypress test fix. --- .../page/notifications/core/notification-helper.service.ts | 3 +++ .../page/notifications/detail/notification-detail.component.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/modules/page/notifications/core/notification-helper.service.ts b/frontend/src/app/modules/page/notifications/core/notification-helper.service.ts index f687662415..95d3881fb4 100644 --- a/frontend/src/app/modules/page/notifications/core/notification-helper.service.ts +++ b/frontend/src/app/modules/page/notifications/core/notification-helper.service.ts @@ -54,6 +54,9 @@ export class NotificationHelperService { } modalCallback(status: NotificationStatus, id: string, reason?: string): Observable { + console.log(status, "status"); + console.log(id, "id"); + console.log(reason, "reason"); switch (status) { case NotificationStatus.ACKNOWLEDGED: return this.notificationsFacade.acknowledgeNotification(id); diff --git a/frontend/src/app/modules/page/notifications/detail/notification-detail.component.ts b/frontend/src/app/modules/page/notifications/detail/notification-detail.component.ts index 975e6103b3..ff80d00e3f 100644 --- a/frontend/src/app/modules/page/notifications/detail/notification-detail.component.ts +++ b/frontend/src/app/modules/page/notifications/detail/notification-detail.component.ts @@ -196,7 +196,7 @@ export class NotificationDetailComponent implements AfterViewInit, OnDestroy { } private selectedNotificationBasedOnUrl(): void { - const notificationId = this.route.snapshot.paramMap.get('alertId'); + const notificationId = this.route.snapshot.paramMap.get('notificationId'); this.notificationsFacade .getNotification(notificationId) .pipe( From e157d248866251629bcdd9918a6984dca9021fe8 Mon Sep 17 00:00:00 2001 From: Maximilian Wesener Date: Tue, 2 Apr 2024 15:04:08 +0200 Subject: [PATCH 14/14] chore(feature): 616 - Cypress test fix. --- .../page/notifications/core/notification-helper.service.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/frontend/src/app/modules/page/notifications/core/notification-helper.service.ts b/frontend/src/app/modules/page/notifications/core/notification-helper.service.ts index 95d3881fb4..f687662415 100644 --- a/frontend/src/app/modules/page/notifications/core/notification-helper.service.ts +++ b/frontend/src/app/modules/page/notifications/core/notification-helper.service.ts @@ -54,9 +54,6 @@ export class NotificationHelperService { } modalCallback(status: NotificationStatus, id: string, reason?: string): Observable { - console.log(status, "status"); - console.log(id, "id"); - console.log(reason, "reason"); switch (status) { case NotificationStatus.ACKNOWLEDGED: return this.notificationsFacade.acknowledgeNotification(id);