diff --git a/modules/ui/src/app/pages/devices/components/device-qualification-from/device-qualification-from.component.ts b/modules/ui/src/app/pages/devices/components/device-qualification-from/device-qualification-from.component.ts index a75a20e08..5bf437c16 100644 --- a/modules/ui/src/app/pages/devices/components/device-qualification-from/device-qualification-from.component.ts +++ b/modules/ui/src/app/pages/devices/components/device-qualification-from/device-qualification-from.component.ts @@ -22,6 +22,7 @@ import { output, ChangeDetectorRef, AfterViewInit, + viewChild, } from '@angular/core'; import { AbstractControl, @@ -63,6 +64,9 @@ import { FormControlType, QuestionFormat } from '../../../../model/question'; import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; import { SimpleDialogComponent } from '../../../../components/simple-dialog/simple-dialog.component'; import { MatDialog } from '@angular/material/dialog'; +import { of } from 'rxjs/internal/observable/of'; +import { Observable } from 'rxjs/internal/Observable'; +import { map } from 'rxjs/internal/operators/map'; const MAC_ADDRESS_PATTERN = '^[\\s]*[a-fA-F0-9]{2}(?:[:][a-fA-F0-9]{2}){5}[\\s]*$'; @@ -94,6 +98,7 @@ const MAC_ADDRESS_PATTERN = export class DeviceQualificationFromComponent implements OnInit, AfterViewInit { readonly TestingType = TestingType; readonly DeviceView = DeviceView; + readonly testModulesComponent = viewChild(DeviceTestsComponent); private fb = inject(FormBuilder); private cdr = inject(ChangeDetectorRef); @@ -114,6 +119,10 @@ export class DeviceQualificationFromComponent implements OnInit, AfterViewInit { initialDevice = input(null); initialDeviceEffect = effect(() => { + this.changeDeviceInForm(); + }); + + changeDeviceInForm() { if ( this.changeDevice || this.deviceHasNoChanges(this.device, this.createDeviceFromForm()) @@ -126,12 +135,24 @@ export class DeviceQualificationFromComponent implements OnInit, AfterViewInit { this.resetForm(); } this.updateMacAddressValidator(); - } else if (this.device != this.initialDevice()) { + } else if ( + this.device != this.initialDevice() || + (this.device === null && this.initialDevice() === null) + ) { // prevent select new device before user confirmation this.devicesStore.selectDevice(this.device); - this.openCloseDialog(this.initialDevice()); + this.openCloseDialog().subscribe(close => { + if (close) { + if (this.initialDevice() !== null) { + this.changeDevice = true; + this.devicesStore.selectDevice(this.initialDevice()); + } else { + this.resetForm(); + } + } + }); } - }); + } devices = input([]); testModules = input([]); @@ -221,6 +242,7 @@ export class DeviceQualificationFromComponent implements OnInit, AfterViewInit { this.deviceQualificationForm.reset({ test_pack: TestingType.Qualification, }); + this.testModulesComponent()?.fillTestModulesFormControls(); } createDeviceFromForm(): Device { @@ -249,7 +271,8 @@ export class DeviceQualificationFromComponent implements OnInit, AfterViewInit { }); response.answer = answer; } else { - response.answer = this.deviceQualificationForm.value[index]?.trim(); + response.answer = + this.deviceQualificationForm.value[index]?.trim() || ''; } additionalInfo.push(response); }); @@ -261,8 +284,8 @@ export class DeviceQualificationFromComponent implements OnInit, AfterViewInit { mac_addr: this.mac_addr?.value?.trim(), test_pack: this.test_pack?.value, test_modules: testModules, - type: this.type?.value, - technology: this.technology?.value, + type: this.type?.value || '', + technology: this.technology?.value ?? '', additional_info: additionalInfo, } as Device; } @@ -274,6 +297,15 @@ export class DeviceQualificationFromComponent implements OnInit, AfterViewInit { ); } + close(): Observable { + if ( + this.deviceHasNoChanges(this.initialDevice(), this.createDeviceFromForm()) + ) { + return of(true); + } + return this.openCloseDialog().pipe(map(res => !!res)); + } + private deviceIsEmpty(device: Device) { if (device.manufacturer && device.manufacturer !== '') { return false; @@ -445,7 +477,7 @@ export class DeviceQualificationFromComponent implements OnInit, AfterViewInit { }); } - private openCloseDialog(device: Device | null) { + private openCloseDialog() { const dialogRef = this.dialog.open(SimpleDialogComponent, { ariaLabel: 'Discard the Device changes', data: { @@ -459,12 +491,7 @@ export class DeviceQualificationFromComponent implements OnInit, AfterViewInit { panelClass: ['simple-dialog', 'close-device'], }); - dialogRef?.beforeClosed().subscribe(close => { - if (close) { - this.changeDevice = true; - this.devicesStore.selectDevice(device); - } - }); + return dialogRef?.beforeClosed(); } private updateMacAddressValidator() { diff --git a/modules/ui/src/app/pages/devices/devices.component.html b/modules/ui/src/app/pages/devices/devices.component.html index 8f2b31776..2a2c2a207 100644 --- a/modules/ui/src/app/pages/devices/devices.component.html +++ b/modules/ui/src/app/pages/devices/devices.component.html @@ -26,7 +26,7 @@ [initialDevice]="vm.selectedDevice" [entityDisabled]="deviceIsDisabled(vm.deviceInProgress?.mac_addr)" [entityTooltip]="getDeviceTooltip(vm.deviceInProgress?.mac_addr)" - (addEntity)="openForm()" + (addEntity)="openForm(null, vm.selectedDevice)" (menuItemClicked)="menuItemClicked($event, vm.devices, vm.testModules)"> diff --git a/modules/ui/src/app/pages/devices/devices.component.ts b/modules/ui/src/app/pages/devices/devices.component.ts index db780738d..569440527 100644 --- a/modules/ui/src/app/pages/devices/devices.component.ts +++ b/modules/ui/src/app/pages/devices/devices.component.ts @@ -20,6 +20,7 @@ import { OnInit, ChangeDetectorRef, inject, + viewChild, } from '@angular/core'; import { MatDialog, MatDialogModule } from '@angular/material/dialog'; import { @@ -53,6 +54,9 @@ import { ListLayoutComponent } from '../../components/list-layout/list-layout.co import { EntityActionResult } from '../../model/entity-action'; import { NoEntitySelectedComponent } from '../../components/no-entity-selected/no-entity-selected.component'; import { LiveAnnouncer } from '@angular/cdk/a11y'; +import { CanComponentDeactivate } from '../../guards/can-deactivate.guard'; +import { Observable } from 'rxjs/internal/Observable'; +import { of } from 'rxjs/internal/observable/of'; @Component({ selector: 'app-device-repository', @@ -76,9 +80,12 @@ import { LiveAnnouncer } from '@angular/cdk/a11y'; ], providers: [DevicesStore], }) -export class DevicesComponent implements OnInit, OnDestroy { +export class DevicesComponent + implements OnInit, OnDestroy, CanComponentDeactivate +{ readonly DeviceView = DeviceView; readonly LayoutType = LayoutType; + readonly form = viewChild(DeviceQualificationFromComponent); private readonly focusManagerService = inject(FocusManagerService); private readonly changeDetectorRef = inject(ChangeDetectorRef); private readonly liveAnnouncer = inject(LiveAnnouncer); @@ -90,6 +97,15 @@ export class DevicesComponent implements OnInit, OnDestroy { viewModel$ = this.devicesStore.viewModel$; isOpenDeviceForm = false; + canDeactivate(): Observable { + const form = this.form(); + if (form) { + return form.close(); + } else { + return of(true); + } + } + ngOnInit(): void { combineLatest([ this.devicesStore.devices$, @@ -164,10 +180,18 @@ export class DevicesComponent implements OnInit, OnDestroy { }); } - async openForm(device: Device | null = null) { + async openForm( + device: Device | null = null, + selectedDevice: Device | null = null + ) { this.devicesStore.selectDevice(device); - this.isOpenDeviceForm = true; - await this.liveAnnouncer.announce('Device qualification form'); + if (!this.isOpenDeviceForm) { + this.isOpenDeviceForm = true; + await this.liveAnnouncer.announce('Device qualification form'); + } + if (device === null && selectedDevice === null) { + this.form()?.changeDeviceInForm(); + } this.focusManagerService.focusFirstElementInContainer( window.document.querySelector('app-device-qualification-from') );