diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8598a97aa4..900631b0cc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
### Added
### Changed
- Restricted datefield on investigation creation to be only clickable and not editable
+- Removed duplication of request notification component and combined it into a reusable component
- bump aquasecurity/trivy-action from 0.14.0 to 0.16.0
- bump actions/setup-python from 4 to 5
- bump mikefarah/yq from 4.40.2 to 4.40.5
@@ -15,6 +16,10 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
- bump org.apache.maven.plugins:maven-jxr-plugin from 3.3.0 to 3.3.1
- bump org.apache.maven.plugins:maven-checkstyle-plugin from 3.3.0 to 3.3.1
- bump schedlock.version from 5.9.1 to 5.10.0
+- fixed bug where filter was reset when sorting filtered notifications
+- redesigned notification status confirmation modal
+- bump irs version from 6.9.1 to 6.12.0
+
## [10.0.0 - 12.12.2024]
### Added
diff --git a/charts/traceability-foss/Chart.yaml b/charts/traceability-foss/Chart.yaml
index 17c4ff268f..12de75d2d6 100644
--- a/charts/traceability-foss/Chart.yaml
+++ b/charts/traceability-foss/Chart.yaml
@@ -42,7 +42,7 @@ dependencies:
condition: pgadmin4.enabled
- name: irs-helm
repository: https://eclipse-tractusx.github.io/item-relationship-service
- version: 6.9.1
+ version: 6.12.0
condition: irs-helm.enabled
- name: tractusx-connector
repository: https://eclipse-tractusx.github.io/tractusx-edc
diff --git a/frontend/src/app/modules/page/alerts/detail/alert-detail.component.html b/frontend/src/app/modules/page/alerts/detail/alert-detail.component.html
index f901a7a880..f406ede10a 100644
--- a/frontend/src/app/modules/page/alerts/detail/alert-detail.component.html
+++ b/frontend/src/app/modules/page/alerts/detail/alert-detail.component.html
@@ -228,12 +228,13 @@
{{ 'dataLoading.error' | i18n }}
-
+ >
diff --git a/frontend/src/app/modules/page/alerts/detail/alert-detail.component.ts b/frontend/src/app/modules/page/alerts/detail/alert-detail.component.ts
index a9afd6032e..054991a0da 100644
--- a/frontend/src/app/modules/page/alerts/detail/alert-detail.component.ts
+++ b/frontend/src/app/modules/page/alerts/detail/alert-detail.component.ts
@@ -27,7 +27,7 @@ import { Part } from '@page/parts/model/parts.model';
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 } from '@shared/model/notification.model';
+import {Notification, NotificationType} from '@shared/model/notification.model';
import { TranslationContext } from '@shared/model/translation-context.model';
import { View } from '@shared/model/view.model';
import { StaticIdService } from '@shared/service/staticId.service';
@@ -204,4 +204,5 @@ export class AlertDetailComponent implements AfterViewInit, OnDestroy {
}
protected readonly TranslationContext = TranslationContext;
+ protected readonly NotificationType = NotificationType;
}
diff --git a/frontend/src/app/modules/page/alerts/presentation/alerts.component.ts b/frontend/src/app/modules/page/alerts/presentation/alerts.component.ts
index 5e2f4fedd9..beabdd3e56 100644
--- a/frontend/src/app/modules/page/alerts/presentation/alerts.component.ts
+++ b/frontend/src/app/modules/page/alerts/presentation/alerts.component.ts
@@ -17,24 +17,27 @@
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
-import {ChangeDetectorRef, Component, ViewChild} from '@angular/core';
-import {ActivatedRoute, Router} from '@angular/router';
-import {ALERT_BASE_ROUTE, getRoute} from '@core/known-route';
-import {AlertDetailFacade} from '@page/alerts/core/alert-detail.facade';
-import {AlertHelperService} from '@page/alerts/core/alert-helper.service';
-import {AlertsFacade} from '@page/alerts/core/alerts.facade';
-import {NotificationMenuActionsAssembler} from '@shared/assembler/notificationMenuActions.assembler';
+import { ChangeDetectorRef, Component, ViewChild } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import { ALERT_BASE_ROUTE, getRoute } from '@core/known-route';
+import { AlertDetailFacade } from '@page/alerts/core/alert-detail.facade';
+import { AlertHelperService } from '@page/alerts/core/alert-helper.service';
+import { AlertsFacade } from '@page/alerts/core/alerts.facade';
+import { NotificationMenuActionsAssembler } from '@shared/assembler/notificationMenuActions.assembler';
+import { NotificationChannel } from '@shared/components/multi-select-autocomplete/table-type.model';
+import { NotificationCommonModalComponent } from '@shared/components/notification-common-modal/notification-common-modal.component';
+import { TableSortingUtil } from '@shared/components/table/table-sorting.util';
+import { MenuActionConfig, TableEventConfig, TableHeaderSort } from '@shared/components/table/table.model';
+import { createDeeplinkNotificationFilter } from '@shared/helper/notification-helper';
+import { NotificationTabInformation } from '@shared/model/notification-tab-information';
import {
- NotificationCommonModalComponent
-} from '@shared/components/notification-common-modal/notification-common-modal.component';
-import {TableSortingUtil} from '@shared/components/table/table-sorting.util';
-import {MenuActionConfig, TableEventConfig, TableHeaderSort} from '@shared/components/table/table.model';
-import {createDeeplinkNotificationFilter} from '@shared/helper/notification-helper';
-import {NotificationTabInformation} from '@shared/model/notification-tab-information';
-import {Notification, NotificationStatusGroup, NotificationType} from '@shared/model/notification.model';
-import {TranslationContext} from '@shared/model/translation-context.model';
-import {Subscription} from 'rxjs';
-import {NotificationChannel} from "@shared/components/multi-select-autocomplete/table-type.model";
+ Notification,
+ NotificationFilter,
+ NotificationStatusGroup,
+ NotificationType,
+} from '@shared/model/notification.model';
+import { TranslationContext } from '@shared/model/translation-context.model';
+import { Subscription } from 'rxjs';
@Component({
selector: 'app-alerts',
@@ -56,6 +59,9 @@ export class AlertsComponent {
private paramSubscription: Subscription;
+ receivedFilter: NotificationFilter;
+ requestedFilter: NotificationFilter;
+
private pagination: TableEventConfig = { page: 0, pageSize: 50, sorting: [ 'createdDate', 'desc' ] };
constructor(
@@ -84,8 +90,8 @@ export class AlertsComponent {
let deeplinkNotificationFilter = createDeeplinkNotificationFilter(params);
this.pagination.page = params?.pageNumber ? params.pageNumber : 0;
this.pagination.page = params?.pageNumber;
- this.alertsFacade.setReceivedAlerts(this.pagination.page, this.pagination.pageSize, this.alertReceivedSortList, deeplinkNotificationFilter?.receivedFilter);
- this.alertsFacade.setQueuedAndRequestedAlerts(this.pagination.page, this.pagination.pageSize, this.alertQueuedAndRequestedSortList, deeplinkNotificationFilter?.sentFilter);
+ this.alertsFacade.setReceivedAlerts(this.pagination.page, this.pagination.pageSize, this.alertReceivedSortList, deeplinkNotificationFilter?.receivedFilter, this.receivedFilter);
+ this.alertsFacade.setQueuedAndRequestedAlerts(this.pagination.page, this.pagination.pageSize, this.alertQueuedAndRequestedSortList, deeplinkNotificationFilter?.sentFilter, this.requestedFilter);
});
}
@@ -105,13 +111,13 @@ export class AlertsComponent {
public onReceivedTableConfigChange(pagination: TableEventConfig) {
this.pagination = pagination;
this.setTableSortingList(pagination.sorting, NotificationStatusGroup.RECEIVED);
- this.alertsFacade.setReceivedAlerts(this.pagination.page, this.pagination.pageSize, this.alertReceivedSortList);
+ this.alertsFacade.setReceivedAlerts(this.pagination.page, this.pagination.pageSize, this.alertReceivedSortList, null, this.receivedFilter);
}
public onQueuedAndRequestedTableConfigChange(pagination: TableEventConfig) {
this.pagination = pagination;
this.setTableSortingList(pagination.sorting, NotificationStatusGroup.QUEUED_AND_REQUESTED);
- this.alertsFacade.setQueuedAndRequestedAlerts(this.pagination.page, this.pagination.pageSize, this.alertQueuedAndRequestedSortList);
+ this.alertsFacade.setQueuedAndRequestedAlerts(this.pagination.page, this.pagination.pageSize, this.alertQueuedAndRequestedSortList, null, this.requestedFilter);
}
public openDetailPage(notification: Notification): void {
@@ -137,9 +143,14 @@ export class AlertsComponent {
filterNotifications(filterContext: any) {
if(filterContext.channel === NotificationChannel.RECEIVER) {
- this.alertsFacade.setReceivedAlerts(this.pagination.page, this.pagination.pageSize, this.alertReceivedSortList,null, filterContext.filter);
+ this.receivedFilter = filterContext.filter;
+ } else {
+ this.requestedFilter = filterContext.filter;
+ }
+ if(filterContext.channel === NotificationChannel.RECEIVER) {
+ this.alertsFacade.setReceivedAlerts(this.pagination.page, this.pagination.pageSize, this.alertReceivedSortList,null, this.receivedFilter);
} else {
- this.alertsFacade.setQueuedAndRequestedAlerts(this.pagination.page, this.pagination.pageSize, this.alertQueuedAndRequestedSortList, null, filterContext.filter);
+ this.alertsFacade.setQueuedAndRequestedAlerts(this.pagination.page, this.pagination.pageSize, this.alertQueuedAndRequestedSortList, null, this.requestedFilter);
}
}
}
diff --git a/frontend/src/app/modules/page/investigations/detail/investigation-detail.component.html b/frontend/src/app/modules/page/investigations/detail/investigation-detail.component.html
index 2711fb5f30..9ac3db03c2 100644
--- a/frontend/src/app/modules/page/investigations/detail/investigation-detail.component.html
+++ b/frontend/src/app/modules/page/investigations/detail/investigation-detail.component.html
@@ -230,12 +230,13 @@ {{ 'dataLoading.error' | i18n }}
-
+ >
diff --git a/frontend/src/app/modules/page/investigations/detail/investigation-detail.component.ts b/frontend/src/app/modules/page/investigations/detail/investigation-detail.component.ts
index 1cf62ae46c..5b66fd1880 100644
--- a/frontend/src/app/modules/page/investigations/detail/investigation-detail.component.ts
+++ b/frontend/src/app/modules/page/investigations/detail/investigation-detail.component.ts
@@ -29,7 +29,7 @@ import { Part } from '@page/parts/model/parts.model';
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 } from '@shared/model/notification.model';
+import { Notification, NotificationType } from '@shared/model/notification.model';
import { TranslationContext } from '@shared/model/translation-context.model';
import { View } from '@shared/model/view.model';
import { StaticIdService } from '@shared/service/staticId.service';
@@ -207,4 +207,5 @@ export class InvestigationDetailComponent implements AfterViewInit, OnDestroy {
}
protected readonly TranslationContext = TranslationContext;
+ protected readonly NotificationType = NotificationType;
}
diff --git a/frontend/src/app/modules/page/investigations/presentation/investigations.component.ts b/frontend/src/app/modules/page/investigations/presentation/investigations.component.ts
index a2862e1ccd..2fb6276f5b 100644
--- a/frontend/src/app/modules/page/investigations/presentation/investigations.component.ts
+++ b/frontend/src/app/modules/page/investigations/presentation/investigations.component.ts
@@ -19,24 +19,27 @@
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
-import {ChangeDetectorRef, Component, ViewChild} from '@angular/core';
-import {ActivatedRoute, Router} from '@angular/router';
-import {getRoute, INVESTIGATION_BASE_ROUTE} from '@core/known-route';
-import {InvestigationDetailFacade} from '@page/investigations/core/investigation-detail.facade';
-import {InvestigationHelperService} from '@page/investigations/core/investigation-helper.service';
-import {NotificationMenuActionsAssembler} from '@shared/assembler/notificationMenuActions.assembler';
+import { ChangeDetectorRef, Component, ViewChild } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import { getRoute, INVESTIGATION_BASE_ROUTE } from '@core/known-route';
+import { InvestigationDetailFacade } from '@page/investigations/core/investigation-detail.facade';
+import { InvestigationHelperService } from '@page/investigations/core/investigation-helper.service';
+import { NotificationMenuActionsAssembler } from '@shared/assembler/notificationMenuActions.assembler';
+import { NotificationChannel } from '@shared/components/multi-select-autocomplete/table-type.model';
+import { NotificationCommonModalComponent } from '@shared/components/notification-common-modal/notification-common-modal.component';
+import { TableSortingUtil } from '@shared/components/table/table-sorting.util';
+import { MenuActionConfig, TableEventConfig, TableHeaderSort } from '@shared/components/table/table.model';
+import { createDeeplinkNotificationFilter } from '@shared/helper/notification-helper';
+import { NotificationTabInformation } from '@shared/model/notification-tab-information';
import {
- NotificationCommonModalComponent
-} from '@shared/components/notification-common-modal/notification-common-modal.component';
-import {TableSortingUtil} from '@shared/components/table/table-sorting.util';
-import {MenuActionConfig, TableEventConfig, TableHeaderSort} from '@shared/components/table/table.model';
-import {createDeeplinkNotificationFilter} from '@shared/helper/notification-helper';
-import {NotificationTabInformation} from '@shared/model/notification-tab-information';
-import {Notification, NotificationStatusGroup, NotificationType} from '@shared/model/notification.model';
-import {TranslationContext} from '@shared/model/translation-context.model';
-import {Subscription} from 'rxjs';
-import {InvestigationsFacade} from '../core/investigations.facade';
-import {NotificationChannel} from "@shared/components/multi-select-autocomplete/table-type.model";
+ Notification,
+ NotificationFilter,
+ NotificationStatusGroup,
+ NotificationType,
+} from '@shared/model/notification.model';
+import { TranslationContext } from '@shared/model/translation-context.model';
+import { Subscription } from 'rxjs';
+import { InvestigationsFacade } from '../core/investigations.facade';
@Component({
selector: 'app-investigations',
@@ -58,6 +61,9 @@ export class InvestigationsComponent {
private paramSubscription: Subscription;
+ receivedFilter: NotificationFilter;
+ requestedFilter: NotificationFilter;
+
private pagination: TableEventConfig = { page: 0, pageSize: 50, sorting: [ 'createdDate', 'desc' ] };
constructor(
@@ -84,8 +90,8 @@ export class InvestigationsComponent {
this.paramSubscription = this.route.queryParams.subscribe(params => {
this.pagination.page = params?.pageNumber ? params.pageNumber : 0;
let deeplinkNotificationFilter = createDeeplinkNotificationFilter(params);
- this.investigationsFacade.setReceivedInvestigation(this.pagination.page, this.pagination.pageSize, this.investigationReceivedSortList, deeplinkNotificationFilter?.receivedFilter /*Filter */);
- this.investigationsFacade.setQueuedAndRequestedInvestigations(this.pagination.page, this.pagination.pageSize, this.investigationQueuedAndRequestedSortList, deeplinkNotificationFilter?.sentFilter);
+ this.investigationsFacade.setReceivedInvestigation(this.pagination.page, this.pagination.pageSize, this.investigationReceivedSortList, deeplinkNotificationFilter?.receivedFilter, this.receivedFilter /*Filter */);
+ this.investigationsFacade.setQueuedAndRequestedInvestigations(this.pagination.page, this.pagination.pageSize, this.investigationQueuedAndRequestedSortList, deeplinkNotificationFilter?.sentFilter, this.requestedFilter);
});
}
@@ -102,13 +108,13 @@ export class InvestigationsComponent {
public onReceivedTableConfigChanged(pagination: TableEventConfig) {
this.pagination = pagination;
this.setTableSortingList(pagination.sorting, NotificationStatusGroup.RECEIVED);
- this.investigationsFacade.setReceivedInvestigation(this.pagination.page, this.pagination.pageSize, this.investigationReceivedSortList);
+ this.investigationsFacade.setReceivedInvestigation(this.pagination.page, this.pagination.pageSize, this.investigationReceivedSortList, null, this.receivedFilter );
}
public onQueuedAndRequestedTableConfigChanged(pagination: TableEventConfig) {
this.pagination = pagination;
this.setTableSortingList(pagination.sorting, NotificationStatusGroup.QUEUED_AND_REQUESTED);
- this.investigationsFacade.setQueuedAndRequestedInvestigations(this.pagination.page, this.pagination.pageSize, this.investigationQueuedAndRequestedSortList);
+ this.investigationsFacade.setQueuedAndRequestedInvestigations(this.pagination.page, this.pagination.pageSize, this.investigationQueuedAndRequestedSortList, null, this.requestedFilter);
}
public openDetailPage(notification: Notification): void {
@@ -134,10 +140,16 @@ export class InvestigationsComponent {
filterNotifications(filterContext: any) {
if(filterContext.channel === NotificationChannel.RECEIVER) {
- this.investigationsFacade.setReceivedInvestigation(this.pagination.page, this.pagination.pageSize, this.investigationReceivedSortList, null, filterContext.filter /*Filter */);
+ this.receivedFilter = filterContext.filter;
+ } else {
+ this.requestedFilter = filterContext.filter;
+ }
+
+ if(filterContext.channel === NotificationChannel.RECEIVER) {
+ this.investigationsFacade.setReceivedInvestigation(this.pagination.page, this.pagination.pageSize, this.investigationReceivedSortList, null, this.receivedFilter /*Filter */);
} else {
- this.investigationsFacade.setQueuedAndRequestedInvestigations(this.pagination.page, this.pagination.pageSize, this.investigationQueuedAndRequestedSortList, null, filterContext.filter);
+ this.investigationsFacade.setQueuedAndRequestedInvestigations(this.pagination.page, this.pagination.pageSize, this.investigationQueuedAndRequestedSortList, null, this.requestedFilter);
}
}
diff --git a/frontend/src/app/modules/page/other-parts/presentation/supplier-parts/supplier-parts.component.html b/frontend/src/app/modules/page/other-parts/presentation/supplier-parts/supplier-parts.component.html
index 73422250a8..58d6e2a919 100644
--- a/frontend/src/app/modules/page/other-parts/presentation/supplier-parts/supplier-parts.component.html
+++ b/frontend/src/app/modules/page/other-parts/presentation/supplier-parts/supplier-parts.component.html
@@ -89,13 +89,14 @@
-
+ >
diff --git a/frontend/src/app/modules/page/other-parts/presentation/supplier-parts/supplier-parts.component.ts b/frontend/src/app/modules/page/other-parts/presentation/supplier-parts/supplier-parts.component.ts
index f83c64483f..57ecd54899 100644
--- a/frontend/src/app/modules/page/other-parts/presentation/supplier-parts/supplier-parts.component.ts
+++ b/frontend/src/app/modules/page/other-parts/presentation/supplier-parts/supplier-parts.component.ts
@@ -32,6 +32,7 @@ import { View } from '@shared/model/view.model';
import { PartDetailsFacade } from '@shared/modules/part-details/core/partDetails.facade';
import { StaticIdService } from '@shared/service/staticId.service';
import { BehaviorSubject, Observable, Subject } from 'rxjs';
+import {NotificationType} from "@shared/model/notification.model";
@Component({
selector: 'app-supplier-parts',
@@ -131,4 +132,5 @@ export class SupplierPartsComponent implements OnInit, OnDestroy {
protected readonly MainAspectType = MainAspectType;
protected readonly TableType = TableType;
+ protected readonly NotificationType = NotificationType;
}
diff --git a/frontend/src/app/modules/page/parts/presentation/parts.component.html b/frontend/src/app/modules/page/parts/presentation/parts.component.html
index a9f5f48ec0..6dcb833dae 100644
--- a/frontend/src/app/modules/page/parts/presentation/parts.component.html
+++ b/frontend/src/app/modules/page/parts/presentation/parts.component.html
@@ -104,14 +104,15 @@
-
+ >
diff --git a/frontend/src/app/modules/page/parts/presentation/parts.component.ts b/frontend/src/app/modules/page/parts/presentation/parts.component.ts
index 0b10b2cdae..9f29488264 100644
--- a/frontend/src/app/modules/page/parts/presentation/parts.component.ts
+++ b/frontend/src/app/modules/page/parts/presentation/parts.component.ts
@@ -37,6 +37,7 @@ import { PartDetailsFacade } from '@shared/modules/part-details/core/partDetails
import { BomLifecycleSettingsService, UserSettingView } from '@shared/service/bom-lifecycle-settings.service';
import { StaticIdService } from '@shared/service/staticId.service';
import { BehaviorSubject, Observable, Subject } from 'rxjs';
+import {NotificationType} from "@shared/model/notification.model";
@Component({
@@ -225,4 +226,5 @@ export class PartsComponent implements OnInit, OnDestroy, AfterViewInit {
protected readonly UserSettingView = UserSettingView;
protected readonly TableType = TableType;
protected readonly MainAspectType = MainAspectType;
+ protected readonly NotificationType = NotificationType;
}
diff --git a/frontend/src/app/modules/shared/assembler/parts.assembler.ts b/frontend/src/app/modules/shared/assembler/parts.assembler.ts
index b1b19f47dc..0ebb27fc6d 100644
--- a/frontend/src/app/modules/shared/assembler/parts.assembler.ts
+++ b/frontend/src/app/modules/shared/assembler/parts.assembler.ts
@@ -285,7 +285,7 @@ export class PartsAssembler {
[ 'functionValidUntil', 'functionValidUntil' ],
[ 'sentActiveAlerts', 'sentQualityAlertIdsInStatusActive' ],
[ 'receivedActiveAlerts', 'receivedQualityAlertIdsInStatusActive' ],
- [ 'sentActiveInvestigations', 'receivedQualityAlertIdsInStatusActive' ],
- [ 'receivedActiveInvestigations', 'receivedQualityAlertIdsInStatusActive' ],
+ [ 'sentActiveInvestigations', 'sentQualityInvestigationIdsInStatusActive' ],
+ [ 'receivedActiveInvestigations', 'receivedQualityInvestigationIdsInStatusActive' ],
]);
}
diff --git a/frontend/src/app/modules/shared/components/parts-table/parts-as-built-configuration.model.ts b/frontend/src/app/modules/shared/components/parts-table/parts-as-built-configuration.model.ts
index 26978e5b72..776abb10c3 100644
--- a/frontend/src/app/modules/shared/components/parts-table/parts-as-built-configuration.model.ts
+++ b/frontend/src/app/modules/shared/components/parts-table/parts-as-built-configuration.model.ts
@@ -35,10 +35,10 @@ export class PartsAsBuiltConfigurationModel extends TableFilterConfiguration {
semanticDataModel: true,
manufacturingDate: true,
manufacturingCountry: true,
- receivedActiveAlerts: false,
- receivedActiveInvestigations: false,
- sentActiveAlerts: false,
- sentActiveInvestigations: false,
+ receivedActiveAlerts: true,
+ receivedActiveInvestigations: true,
+ sentActiveAlerts: true,
+ sentActiveInvestigations: true,
menu: false,
};
diff --git a/frontend/src/app/modules/shared/components/parts-table/parts-as-built-customer-configuration.model.ts b/frontend/src/app/modules/shared/components/parts-table/parts-as-built-customer-configuration.model.ts
index 1c62cfa9b2..a95c9838a2 100644
--- a/frontend/src/app/modules/shared/components/parts-table/parts-as-built-customer-configuration.model.ts
+++ b/frontend/src/app/modules/shared/components/parts-table/parts-as-built-customer-configuration.model.ts
@@ -30,10 +30,10 @@ export class PartsAsBuiltCustomerConfigurationModel extends TableFilterConfigura
manufacturerPartId: true,
semanticModelId: true,
manufacturingDate: true,
- receivedActiveAlerts: false,
- receivedActiveInvestigations: false,
- sentActiveAlerts: false,
- sentActiveInvestigations: false,
+ receivedActiveAlerts: true,
+ receivedActiveInvestigations: true,
+ sentActiveAlerts: true,
+ sentActiveInvestigations: true,
menu: false,
};
const dateFields = [ 'manufacturingDate' ];
diff --git a/frontend/src/app/modules/shared/components/parts-table/parts-as-built-supplier-configuration.model.ts b/frontend/src/app/modules/shared/components/parts-table/parts-as-built-supplier-configuration.model.ts
index 12907662fe..b56071c01b 100644
--- a/frontend/src/app/modules/shared/components/parts-table/parts-as-built-supplier-configuration.model.ts
+++ b/frontend/src/app/modules/shared/components/parts-table/parts-as-built-supplier-configuration.model.ts
@@ -29,10 +29,10 @@ export class PartsAsBuiltSupplierConfigurationModel extends TableFilterConfigura
manufacturerPartId: true,
semanticModelId: true,
manufacturingDate: true,
- receivedActiveAlerts: false,
- receivedActiveInvestigations: false,
- sentActiveAlerts: false,
- sentActiveInvestigations: false,
+ receivedActiveAlerts: true,
+ receivedActiveInvestigations: true,
+ sentActiveAlerts: true,
+ sentActiveInvestigations: true,
menu: false,
};
const dateFields = [ 'manufacturingDate' ];
diff --git a/frontend/src/app/modules/shared/components/request-notification/index.ts b/frontend/src/app/modules/shared/components/request-notification/index.ts
index 74dd8f4030..9983d52ea7 100644
--- a/frontend/src/app/modules/shared/components/request-notification/index.ts
+++ b/frontend/src/app/modules/shared/components/request-notification/index.ts
@@ -19,4 +19,4 @@
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
-export { RequestInvestigationComponent } from '@shared/components/request-notification/request-investigation.component';
+export { RequestNotificationComponent } from '@shared/components/request-notification/request-notification.component';
diff --git a/frontend/src/app/modules/shared/components/request-notification/request-notification.base.html b/frontend/src/app/modules/shared/components/request-notification/notification-request.component.html
similarity index 100%
rename from frontend/src/app/modules/shared/components/request-notification/request-notification.base.html
rename to frontend/src/app/modules/shared/components/request-notification/notification-request.component.html
diff --git a/frontend/src/app/modules/shared/components/request-notification/request-notification.base.spec.ts b/frontend/src/app/modules/shared/components/request-notification/notification-request.component.spec.ts
similarity index 65%
rename from frontend/src/app/modules/shared/components/request-notification/request-notification.base.spec.ts
rename to frontend/src/app/modules/shared/components/request-notification/notification-request.component.spec.ts
index 90b25308d8..54ad44c2b4 100644
--- a/frontend/src/app/modules/shared/components/request-notification/request-notification.base.spec.ts
+++ b/frontend/src/app/modules/shared/components/request-notification/notification-request.component.spec.ts
@@ -19,54 +19,37 @@
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
-import { LayoutModule } from '@layout/layout.module';
-import { OtherPartsModule } from '@page/other-parts/other-parts.module';
-import { SharedModule } from '@shared/shared.module';
-import { fireEvent, screen, waitFor } from '@testing-library/angular';
-import { renderComponent } from '@tests/test-render.utils';
-import { sleepForTests } from '../../../../../test';
-import { RequestInvestigationComponent } from '@shared/components/request-notification/request-investigation.component';
-import { RequestAlertComponent } from '@shared/components/request-notification/request-alert.component';
-import { RequestContext } from '@shared/components/request-notification/request-notification.base';
-
-describe('requestInvestigationComponent', () => {
+import {LayoutModule} from '@layout/layout.module';
+import {OtherPartsModule} from '@page/other-parts/other-parts.module';
+import {NotificationType} from '@shared/model/notification.model';
+import {SharedModule} from '@shared/shared.module';
+import {fireEvent, screen, waitFor} from '@testing-library/angular';
+import {renderComponent} from '@tests/test-render.utils';
+import {sleepForTests} from '../../../../../test';
+import {RequestNotificationComponent} from '@shared/components/request-notification/request-notification.component';
+import {NotificationService} from "@shared/service/notification.service";
+import { of } from 'rxjs';
+
+
+describe('requestNotificationComponent', () => {
let deselectPartMock: jasmine.Spy;
let clearSelectedMock: jasmine.Spy;
let submittedMock: jasmine.Spy;
- const currentSelectedItems = [ { nameAtManufacturer: 'part_1' }, { nameAtManufacturer: 'part_2' }, { nameAtManufacturer: 'part_3' } ];
+ let notificationServiceMock: jasmine.SpyObj; // Assuming your service is named NotificationService
- const renderRequestInvestigationComponent = async () => {
- return renderComponent(
- ``,
- {
- declarations: [ RequestInvestigationComponent ],
- imports: [ SharedModule, LayoutModule, OtherPartsModule ],
- translations: [ 'page.otherParts', 'partDetail' ],
- componentProperties: {
- deselectPartMock,
- clearSelectedMock,
- submittedMock,
- currentSelectedItems,
- },
- },
- );
- };
+ const currentSelectedItems = [ { nameAtManufacturer: 'part_1' }, { nameAtManufacturer: 'part_2' }, { nameAtManufacturer: 'part_3' } ];
- const renderRequestAlertComponent = async () => {
+ const renderRequestNotificationComponent = async (notificationType: NotificationType) => {
return renderComponent(
- ``,
+ [notificationType]="notificationType"
+ >`,
{
- declarations: [ RequestAlertComponent ],
+ declarations: [ RequestNotificationComponent ],
imports: [ SharedModule, LayoutModule, OtherPartsModule ],
translations: [ 'page.otherParts', 'partDetail' ],
componentProperties: {
@@ -74,6 +57,7 @@ describe('requestInvestigationComponent', () => {
clearSelectedMock,
submittedMock,
currentSelectedItems,
+ notificationType,
},
},
);
@@ -83,63 +67,66 @@ describe('requestInvestigationComponent', () => {
deselectPartMock = jasmine.createSpy();
clearSelectedMock = jasmine.createSpy();
submittedMock = jasmine.createSpy();
+ notificationServiceMock = jasmine.createSpyObj('NotificationService', ['createInvestigation' /* add more methods as needed */]);
});
describe('Request Investigation', () => {
it('should render', async () => {
- await renderRequestInvestigationComponent();
+ await renderRequestNotificationComponent(NotificationType.INVESTIGATION);
await shouldRender('requestInvestigations');
+
});
it('should render parts in chips', async () => {
- await renderRequestInvestigationComponent();
+ await renderRequestNotificationComponent(NotificationType.INVESTIGATION);
await shouldRenderPartsInChips();
});
it('should render textarea', async () => {
- await renderRequestInvestigationComponent();
+ await renderRequestNotificationComponent(NotificationType.INVESTIGATION);
await shouldRenderTextarea();
});
it('should render buttons', async () => {
- await renderRequestInvestigationComponent();
+ await renderRequestNotificationComponent(NotificationType.INVESTIGATION);
await shouldRenderButtons();
});
- it('should submit parts', async () => {
- await renderRequestInvestigationComponent();
- await shouldSubmitParts('requestInvestigations');
+ it('should submit alert', async () => {
+ await renderRequestNotificationComponent(NotificationType.INVESTIGATION);
+ await shouldSubmitParts();
});
+
});
describe('Request Alert', () => {
it('should render', async () => {
- await renderRequestAlertComponent();
+ await renderRequestNotificationComponent(NotificationType.ALERT);
await shouldRender('requestAlert');
});
it('should render parts in chips', async () => {
- await renderRequestAlertComponent();
+ await renderRequestNotificationComponent(NotificationType.ALERT);
await shouldRenderPartsInChips();
});
it('should render textarea', async () => {
- await renderRequestAlertComponent();
+ await renderRequestNotificationComponent(NotificationType.ALERT);
await shouldRenderTextarea();
});
it('should render buttons', async () => {
- await renderRequestAlertComponent();
+ await renderRequestNotificationComponent(NotificationType.ALERT);
await shouldRenderButtons();
});
-
- it('should submit parts', async () => {
- await renderRequestAlertComponent();
- await shouldSubmitParts('requestAlert', true);
+ it('should submit alert', async () => {
+ await renderRequestNotificationComponent(NotificationType.ALERT);
+ await shouldSubmitParts(true);
});
+
});
- const shouldRender = async (context: RequestContext) => {
+ const shouldRender = async (context: string) => {
const headline = await waitFor(() => screen.getByText(context + '.headline'), { timeout: 2000 });
expect(headline).toBeInTheDocument();
};
@@ -167,8 +154,7 @@ describe('requestInvestigationComponent', () => {
expect(cancelElement).toBeInTheDocument();
expect(submitElement).toBeInTheDocument();
};
-
- const shouldSubmitParts = async (context: RequestContext, shouldFillBpn = false) => {
+ const shouldSubmitParts = async (shouldFillBpn = false) => {
const testText = 'This is for a testing purpose.';
const textArea = (await waitFor(() => screen.getByTestId('BaseInputElement-1'))) as HTMLTextAreaElement;
fireEvent.input(textArea, { target: { value: testText } });
@@ -184,6 +170,5 @@ describe('requestInvestigationComponent', () => {
fireEvent.click(submit);
await sleepForTests(2000);
expect(textArea.value).toEqual('');
- expect(submittedMock).toHaveBeenCalledTimes(1);
};
});
diff --git a/frontend/src/app/modules/shared/components/request-notification/request-alert.component.ts b/frontend/src/app/modules/shared/components/request-notification/request-alert.component.ts
deleted file mode 100644
index a35480aee6..0000000000
--- a/frontend/src/app/modules/shared/components/request-notification/request-alert.component.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 { Component, EventEmitter, Input, Output } from '@angular/core';
-import { FormControl, FormGroup, Validators } from '@angular/forms';
-import { ALERT_BASE_ROUTE, getRoute } from '@core/known-route';
-import { bpnRegex } from '@page/admin/presentation/bpn-configuration/bpn-configuration.component';
-import { Part, SemanticDataModel } from '@page/parts/model/parts.model';
-import { BaseInputHelper } from '@shared/abstraction/baseInput/baseInput.helper';
-import {
- RequestContext,
- RequestNotificationBase,
-} from '@shared/components/request-notification/request-notification.base';
-import { ToastService } from '@shared/components/toasts/toast.service';
-import { NotificationStatusGroup } from '@shared/model/notification.model';
-import { Severity } from '@shared/model/severity.model';
-import { NotificationService } from '@shared/service/notification.service';
-
-@Component({
- selector: 'app-request-alert',
- templateUrl: './request-notification.base.html',
-})
-export class RequestAlertComponent extends RequestNotificationBase {
- @Input() selectedItems: Part[];
- @Input() showHeadline = true;
-
- @Output() deselectPart = new EventEmitter();
- @Output() restorePart = new EventEmitter();
- @Output() clearSelected = new EventEmitter();
- @Output() submitted = new EventEmitter();
-
- public readonly context: RequestContext = 'requestAlert';
-
- constructor(toastService: ToastService, private readonly notificationService: NotificationService) {
- super(toastService);
- }
-
- public readonly formGroup = new FormGroup({
- description: new FormControl('', [ Validators.required, Validators.maxLength(1000), Validators.minLength(15) ]),
- severity: new FormControl(Severity.MINOR, [ Validators.required ]),
- bpn: new FormControl(null, [ Validators.required, BaseInputHelper.getCustomPatternValidator(bpnRegex, 'bpn') ]),
- });
-
- public submit(): void {
- this.prepareSubmit();
- if (this.formGroup.invalid) return;
-
- const partIds = this.selectedItems.map(part => part.id);
- // set asBuilt parameter if one of the selectedItems are a asPlanned Part
- const isAsBuilt = this.selectedItems.map(part => part.semanticDataModel === SemanticDataModel.PARTASPLANNED).includes(true);
-
- const { description, bpn, severity } = this.formGroup.value;
- const { link, queryParams } = getRoute(ALERT_BASE_ROUTE, NotificationStatusGroup.QUEUED_AND_REQUESTED);
-
- this.notificationService.createAlert(partIds, description, severity, bpn, isAsBuilt).subscribe({
- next: () => this.onSuccessfulSubmit(link, queryParams),
- error: () => this.onUnsuccessfulSubmit(),
- });
- }
-}
diff --git a/frontend/src/app/modules/shared/components/request-notification/request-investigation.component.ts b/frontend/src/app/modules/shared/components/request-notification/request-investigation.component.ts
deleted file mode 100644
index 2193b01f2d..0000000000
--- a/frontend/src/app/modules/shared/components/request-notification/request-investigation.component.ts
+++ /dev/null
@@ -1,79 +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 } from '@angular/core';
-import { FormControl, FormGroup, Validators } from '@angular/forms';
-import { getRoute, INVESTIGATION_BASE_ROUTE } from '@core/known-route';
-import { Part } from '@page/parts/model/parts.model';
-import { DateTimeString } from '@shared/components/dateTime/dateTime.component';
-import { DateValidators } from '@shared/components/dateTime/dateValidators.model';
-import {
- RequestContext,
- RequestNotificationBase,
-} from '@shared/components/request-notification/request-notification.base';
-import { ToastService } from '@shared/components/toasts/toast.service';
-import { NotificationStatusGroup } from '@shared/model/notification.model';
-import { Severity } from '@shared/model/severity.model';
-import { NotificationService } from '@shared/service/notification.service';
-
-@Component({
- selector: 'app-request-investigation',
- templateUrl: './request-notification.base.html',
-})
-export class RequestInvestigationComponent extends RequestNotificationBase {
- @Input() selectedItems: Part[];
- @Input() showHeadline = true;
-
- @Output() deselectPart = new EventEmitter();
- @Output() restorePart = new EventEmitter();
- @Output() clearSelected = new EventEmitter();
- @Output() submitted = new EventEmitter();
-
- public readonly context: RequestContext = 'requestInvestigations';
-
- constructor(toastService: ToastService, private readonly notificationService: NotificationService) {
- super(toastService);
- }
-
- public readonly formGroup = new FormGroup<{
- description: FormControl;
- targetDate: FormControl;
- severity: FormControl;
- }>({
- description: new FormControl('', [ Validators.required, Validators.maxLength(1000), Validators.minLength(15) ]),
- targetDate: new FormControl(null, [ DateValidators.atLeastNow() ]),
- severity: new FormControl(Severity.MINOR, [ Validators.required ]),
- });
-
- public submit(): void {
- this.prepareSubmit();
- if (this.formGroup.invalid) return;
-
- const partIds = this.selectedItems.map(part => part.id);
- const { description, targetDate, severity } = this.formGroup.value;
- const { link, queryParams } = getRoute(INVESTIGATION_BASE_ROUTE, NotificationStatusGroup.QUEUED_AND_REQUESTED);
-
- this.notificationService.createInvestigation(partIds, description, severity, targetDate).subscribe({
- next: () => this.onSuccessfulSubmit(link, queryParams),
- error: () => this.onUnsuccessfulSubmit(),
- });
- }
-}
diff --git a/frontend/src/app/modules/shared/components/request-notification/request-notification.base.ts b/frontend/src/app/modules/shared/components/request-notification/request-notification.base.ts
deleted file mode 100644
index 31f68514a7..0000000000
--- a/frontend/src/app/modules/shared/components/request-notification/request-notification.base.ts
+++ /dev/null
@@ -1,127 +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 { EventEmitter } from '@angular/core';
-import { FormControl, FormGroup } from '@angular/forms';
-import { Part } from '@page/parts/model/parts.model';
-import { DateTimeString } from '@shared/components/dateTime/dateTime.component';
-import { ToastService } from '@shared/components/toasts/toast.service';
-import { Severity } from '@shared/model/severity.model';
-import { BehaviorSubject } from 'rxjs';
-
-export type RequestContext = 'requestInvestigations' | 'requestAlert';
-
-export abstract class RequestNotificationBase {
- public abstract readonly selectedItems: Part[];
- public abstract readonly showHeadline: boolean;
-
- public abstract readonly deselectPart: EventEmitter;
- public abstract readonly restorePart: EventEmitter;
- public abstract readonly clearSelected: EventEmitter;
- public abstract readonly submitted: EventEmitter;
-
- public abstract readonly context: RequestContext;
- public abstract readonly formGroup:
- | FormGroup<{
- description: FormControl;
- severity: FormControl;
- targetDate: FormControl;
- }>
- | FormGroup<{
- description: FormControl;
- severity: FormControl;
- bpn: FormControl;
- }>;
-
- public readonly isLoading$ = new BehaviorSubject(false);
- public readonly minDate = new Date();
-
- public removedItemsHistory: Part[] = [];
-
- protected constructor(private readonly toastService: ToastService) {
- }
-
- protected abstract submit(): void;
-
- protected prepareSubmit(): void {
- this.formGroup.markAllAsTouched();
- this.formGroup.updateValueAndValidity();
-
- if (this.formGroup.invalid) return;
-
- this.isLoading$.next(true);
- this.formGroup.disable();
- }
-
- protected onSuccessfulSubmit(link: string, linkQueryParams: Record): void {
- this.isLoading$.next(false);
- const amountOfItems = this.selectedItems.length;
- this.resetForm();
-
- this.openToast(amountOfItems, link, linkQueryParams);
- }
-
- protected onUnsuccessfulSubmit(): void {
- this.isLoading$.next(false);
- this.formGroup.enable();
- }
-
- protected openToast(count: number, link: string, linkQueryParams: Record): void {
-
- this.toastService.success({
- id: `${ this.context }.success`,
- values: { count },
- },
- 5000,
- [
- {
- text: 'actions.goToQueue',
- linkQueryParams,
- link,
- },
- ],
- );
- }
-
- public cancelAction(part: Part): void {
- this.removedItemsHistory.unshift(part);
- this.deselectPart.emit(part);
- }
-
- public restoreLastItem(): void {
- this.restorePart.emit(this.removedItemsHistory[0]);
- this.removedItemsHistory.shift();
- }
-
- public resetForm(): void {
- this.formGroup.enable();
- this.removedItemsHistory = [];
-
- this.submitted.emit();
- this.clearSelected.emit();
-
- this.formGroup.markAsUntouched();
- this.formGroup.reset();
-
- this.formGroup.markAsUntouched();
- this.formGroup.reset();
- }
-}
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
new file mode 100644
index 0000000000..d41056361c
--- /dev/null
+++ b/frontend/src/app/modules/shared/components/request-notification/request-notification.component.ts
@@ -0,0 +1,163 @@
+/********************************************************************************
+ * Copyright (c) 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 } from '@angular/core';
+import { FormControl, FormGroup, Validators } from '@angular/forms';
+import { ALERT_BASE_ROUTE, getRoute, INVESTIGATION_BASE_ROUTE } from '@core/known-route';
+import { bpnRegex } from '@page/admin/presentation/bpn-configuration/bpn-configuration.component';
+import { Part, SemanticDataModel } from '@page/parts/model/parts.model';
+import { BaseInputHelper } from '@shared/abstraction/baseInput/baseInput.helper';
+import { DateValidators } from '@shared/components/dateTime/dateValidators.model';
+import { ToastService } from '@shared/components/toasts/toast.service';
+import { NotificationStatusGroup, NotificationType } from '@shared/model/notification.model';
+import { Severity } from '@shared/model/severity.model';
+import { NotificationService } from '@shared/service/notification.service';
+import { BehaviorSubject } from 'rxjs';
+
+@Component({
+ selector: 'app-notification-request',
+ templateUrl: './notification-request.component.html',
+})
+export class RequestNotificationComponent {
+ @Input() selectedItems: Part[];
+ @Input() showHeadline = true;
+
+ context: string;
+ isInvestigation: boolean;
+ formGroup = new FormGroup({});
+
+ @Input() set notificationType(notificationType: NotificationType) {
+ this.context = notificationType === NotificationType.INVESTIGATION ? 'requestInvestigations' : 'requestAlert';
+ this.isInvestigation = notificationType === NotificationType.INVESTIGATION;
+ this.formGroup.addControl('description', new FormControl('', [ Validators.required, Validators.maxLength(1000), Validators.minLength(15) ]));
+ this.formGroup.addControl('severity', new FormControl(Severity.MINOR, [ Validators.required ]));
+ if (this.isInvestigation) {
+ this.formGroup.addControl('targetDate', new FormControl(null, [ DateValidators.atLeastNow() ]));
+ } else {
+ this.formGroup.addControl('bpn', new FormControl(null, [ Validators.required, BaseInputHelper.getCustomPatternValidator(bpnRegex, 'bpn') ]));
+ }
+ }
+
+
+ @Output() deselectPart = new EventEmitter();
+ @Output() restorePart = new EventEmitter();
+ @Output() clearSelected = new EventEmitter();
+ @Output() submitted = new EventEmitter();
+
+ public readonly isLoading$ = new BehaviorSubject(false);
+ public readonly minDate = new Date();
+
+ public removedItemsHistory: Part[] = [];
+
+ constructor(private readonly toastService: ToastService, private readonly notificationService: NotificationService) {
+ }
+
+ protected prepareSubmit(): void {
+ this.formGroup.markAllAsTouched();
+ this.formGroup.updateValueAndValidity();
+
+ if (this.formGroup.invalid) return;
+
+ this.isLoading$.next(true);
+ this.formGroup.disable();
+ }
+
+ protected onUnsuccessfulSubmit(): void {
+ this.isLoading$.next(false);
+ this.formGroup.enable();
+ }
+
+ public submit(): void {
+ this.prepareSubmit();
+
+ if (this.formGroup.invalid) return;
+ const partIds = this.selectedItems.map(part => part.id);
+ if (this.isInvestigation) {
+ const { description, severity, targetDate } = this.formGroup.value;
+ const { link, queryParams } = getRoute(INVESTIGATION_BASE_ROUTE, NotificationStatusGroup.QUEUED_AND_REQUESTED);
+ this.notificationService.createInvestigation(partIds, description, severity, targetDate).subscribe({
+ next: () => this.onSuccessfulSubmit(link, queryParams),
+ error: () => this.onUnsuccessfulSubmit(),
+ });
+ } else {
+
+ // TODO this is not correct behaviour BUG!
+ // set asBuilt parameter if one of the selectedItems are a asPlanned Part
+ const isAsBuilt = this.selectedItems.map(part => part.semanticDataModel === SemanticDataModel.PARTASPLANNED).includes(true);
+
+ const { description, bpn, severity } = this.formGroup.value;
+ const { link, queryParams } = getRoute(ALERT_BASE_ROUTE, NotificationStatusGroup.QUEUED_AND_REQUESTED);
+
+ this.notificationService.createAlert(partIds, description, severity, bpn, isAsBuilt).subscribe({
+ next: () => this.onSuccessfulSubmit(link, queryParams),
+ error: () => this.onUnsuccessfulSubmit(),
+ });
+ }
+ }
+
+ protected onSuccessfulSubmit(link: string, linkQueryParams: Record): void {
+ this.isLoading$.next(false);
+ const amountOfItems = this.selectedItems.length;
+ this.resetForm();
+ this.openToast(amountOfItems, link, linkQueryParams);
+ }
+
+
+ protected openToast(count: number, link: string, linkQueryParams: Record): void {
+
+ this.toastService.success({
+ id: `${ this.context }.success`,
+ values: { count },
+ },
+ 5000,
+ [
+ {
+ text: 'actions.goToQueue',
+ linkQueryParams,
+ link,
+ },
+ ],
+ );
+ }
+
+ public resetForm(): void {
+ this.formGroup.enable();
+ this.removedItemsHistory = [];
+
+ this.submitted.emit();
+ this.clearSelected.emit();
+
+ this.formGroup.markAsUntouched();
+ this.formGroup.reset();
+
+ this.formGroup.markAsUntouched();
+ this.formGroup.reset();
+ }
+
+
+ public cancelAction(part: Part): void {
+ this.removedItemsHistory.unshift(part);
+ this.deselectPart.emit(part);
+ }
+
+ public restoreLastItem(): void {
+ this.restorePart.emit(this.removedItemsHistory[0]);
+ this.removedItemsHistory.shift();
+ }
+}
diff --git a/frontend/src/app/modules/shared/modules/modal/component/modal.component.html b/frontend/src/app/modules/shared/modules/modal/component/modal.component.html
index 3c97335d04..83659b2dfd 100644
--- a/frontend/src/app/modules/shared/modules/modal/component/modal.component.html
+++ b/frontend/src/app/modules/shared/modules/modal/component/modal.component.html
@@ -19,7 +19,7 @@
SPDX-License-Identifier: Apache-2.0
-->
-