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 --> -
+