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
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
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/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/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/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/detail/notification-detail.component.html b/frontend/src/app/modules/page/notifications/detail/notification-detail.component.html
index 4ddcb98805..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 @@
>
@@ -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..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
@@ -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';
@@ -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(
@@ -206,8 +206,8 @@ export class NotificationDetailComponent implements AfterViewInit, OnDestroy {
.subscribe();
}
- protected readonly TranslationContext = TranslationContext;
protected readonly NotificationType = NotificationType;
protected readonly NotificationAction = NotificationAction;
+ protected readonly NotificationStatus = NotificationStatus;
}
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..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,14 +20,11 @@
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/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/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/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..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
@@ -53,7 +53,7 @@ export class PartsStrategy extends AutocompleteStrategy {
@Injectable({
providedIn: 'any',
})
-export class InvestigationStrategy extends AutocompleteStrategy {
+export class NotificationStrategy extends AutocompleteStrategy {
notificationService: NotificationService;
constructor(notificationService: NotificationService) {
@@ -66,30 +66,7 @@ export class InvestigationStrategy extends AutocompleteStrategy {
return this.notificationService.getDistinctFilterValues(
notificationChannel,
filterColumns,
- searchElement,
- true,
- );
- }
-}
-
-@Injectable({
- providedIn: 'any',
-})
-export class AlertStrategy 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,
- false,
+ searchElement
);
}
}
@@ -120,11 +97,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 +120,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/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 8659bd5efe..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,36 +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 cbbef22108..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
@@ -19,14 +19,8 @@
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 { 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',
@@ -35,18 +29,10 @@ import { DeclineNotificationModalComponent } from '@shared/modules/notification/
export class NotificationCommonModalComponent {
@Input() selectedNotification: Notification;
- @Input() translationContext: TranslationContext;
@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) notificationActionModalComponent: NotificationActionModalComponent;
// TODO do not delete the facade here. This will lead to a nullpointer exception within the modal call.
public constructor(
@@ -59,36 +45,12 @@ 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.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;
- }
- }
+ console.log(notificationToShow, "notification");
+ console.log(desiredStatus, "desiredstatus");
+ this.notificationActionModalComponent.show(notificationToShow, desiredStatus);
}
-
- protected readonly TranslationContext = TranslationContext;
+ protected readonly NotificationStatus = NotificationStatus;
}
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();
- });
-});
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..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,12 +95,15 @@ 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;
+ 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).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/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.html b/frontend/src/app/modules/shared/modules/notification/modal/accept/accept-notification-modal.component.html
deleted file mode 100644
index cc20a09582..0000000000
--- a/frontend/src/app/modules/shared/modules/notification/modal/accept/accept-notification-modal.component.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
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 754a937aad..0000000000
--- a/frontend/src/app/modules/shared/modules/notification/modal/accept/accept-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';
-
-@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(this.translationContext + '.modal.successfullyAccepted');
- this.confirmActionCompleted.emit();
- },
- error: () => {
- this.toastService.error(this.translationContext + '.modal.failedAccept');
- },
- });
- };
-
- const options: ModalData = {
- title: this.translationContext + '.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 c1a82ec6e7..0000000000
--- a/frontend/src/app/modules/shared/modules/notification/modal/acknowledge/acknowledge-notification-modal.component.ts
+++ /dev/null
@@ -1,71 +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';
-
-@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(this.translationContext + '.modal.successfullyAcknowledged');
- this.confirmActionCompleted.emit();
- },
- error: () => {
- this.toastService.error(this.translationContext + '.modal.failedAcknowledge');
- },
- });
- };
-
- const options: ModalData = {
- title: this.translationContext + '.modal.acknowledgeTitle',
- buttonRight: 'actions.acknowledge',
-
- 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/actions/notification-action-modal.component.html
similarity index 87%
rename from frontend/src/app/modules/shared/modules/notification/modal/close/close-notification-modal.component.html
rename to frontend/src/app/modules/shared/modules/notification/modal/actions/notification-action-modal.component.html
index 6b53b86df4..2b7ab619c4 100644
--- a/frontend/src/app/modules/shared/modules/notification/modal/close/close-notification-modal.component.html
+++ b/frontend/src/app/modules/shared/modules/notification/modal/actions/notification-action-modal.component.html
@@ -21,9 +21,8 @@
-
-
-
+
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..e06c0ddb5e
--- /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;
+ @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'
+ };
+ }
+ }
+
+ }
+
+ public show(notification: Notification, desiredStatus: NotificationStatus): void {
+ 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;
+
+ 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) {
+ console.log(desiredStatus, "desired from textarea");
+ 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 0f21b9cf63..0000000000
--- a/frontend/src/app/modules/shared/modules/notification/modal/approve/approve-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';
-
-@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(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',
-
- 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 de0b9ce3b1..0000000000
--- a/frontend/src/app/modules/shared/modules/notification/modal/cancel/cancel-notification-modal.component.ts
+++ /dev/null
@@ -1,76 +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';
-
-@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(this.translationContext + '.modal.successfullyCanceled');
- this.confirmActionCompleted.emit();
- },
- error: () => {
- this.toastService.error(this.translationContext + '.modal.failedCancel');
- },
- });
- };
-
- const options: ModalData = {
- title: this.translationContext + '.modal.cancellationTitle',
- type: this.translationContext + '.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.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 66b121d5b6..0000000000
--- a/frontend/src/app/modules/shared/modules/notification/modal/close/close-notification-modal.component.ts
+++ /dev/null
@@ -1,81 +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';
-
-@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(this.translationContext + '.modal.successfullyClosed');
- this.confirmActionCompleted.emit();
- },
- error: () => {
- this.toastService.error(this.translationContext + '.modal.failedClose');
- },
- });
- };
-
- const options: ModalData = {
- title: this.translationContext + '.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 @@
-
-
-
-
-
-
-
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 48d37b730c..0000000000
--- a/frontend/src/app/modules/shared/modules/notification/modal/decline/decline-notification-modal.component.ts
+++ /dev/null
@@ -1,81 +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';
-
-@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(this.translationContext + '.modal.successfullyDeclined');
- this.confirmActionCompleted.emit();
- },
- error: () => {
- this.toastService.error(this.translationContext + '.modal.failedDecline');
- },
- });
- };
-
- const options: ModalData = {
- title: this.translationContext + '.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 57e218e763..0000000000
--- a/frontend/src/app/modules/shared/modules/notification/modal/modalTestHelper.spec.ts
+++ /dev/null
@@ -1,221 +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 } 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,
- 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-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/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 {
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..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,21 +83,17 @@ describe('NotificationsInboxComponent', () => {
}).pipe(delay(0));
const menuActionsConfig = [];
const notificationType = NotificationType.INVESTIGATION;
- const isInvestigation = true;
return renderComponent(
``,
{
imports: [ SharedModule, NotificationModule, TemplateModule ],
@@ -108,8 +104,7 @@ describe('NotificationsInboxComponent', () => {
receivedNotifications$,
clickHandler,
menuActionsConfig,
- notificationType,
- isInvestigation,
+ notificationType
},
},
);
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/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 6c76a13b60..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,32 +71,32 @@ 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 }`)
.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));
}
- 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()
diff --git a/frontend/src/assets/locales/de/common.json b/frontend/src/assets/locales/de/common.json
index c717fa93e3..9f9eb9088d 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",
@@ -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 aa869d6be9..c94cdaf946 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",
@@ -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": {
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;