diff --git a/modules/ui/src/app/pages/risk-assessment/profile-form/profile-form.component.spec.ts b/modules/ui/src/app/pages/risk-assessment/profile-form/profile-form.component.spec.ts index 6cfa020f6..c10d8b903 100644 --- a/modules/ui/src/app/pages/risk-assessment/profile-form/profile-form.component.spec.ts +++ b/modules/ui/src/app/pages/risk-assessment/profile-form/profile-form.component.spec.ts @@ -19,7 +19,6 @@ import { ProfileFormComponent } from './profile-form.component'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { COPY_PROFILE_MOCK, - DRAFT_COPY_PROFILE_MOCK, NEW_PROFILE_MOCK, NEW_PROFILE_MOCK_DRAFT, OUTDATED_DRAFT_PROFILE_MOCK, @@ -333,16 +332,6 @@ describe('ProfileFormComponent', () => { component.nameControl.hasError('has_same_profile_name') ).toBeTrue(); }); - - it('should have an error when uses the name of copy profile', fakeAsync(() => { - component.selectedProfile = DRAFT_COPY_PROFILE_MOCK; - component.profiles = [PROFILE_MOCK, PROFILE_MOCK_2, COPY_PROFILE_MOCK]; - fixture.detectChanges(); - - expect( - component.nameControl.hasError('has_same_profile_name') - ).toBeTrue(); - })); }); describe('with no profile', () => { @@ -372,7 +361,7 @@ describe('ProfileFormComponent', () => { ariaLabel: 'Discard the Risk Assessment changes', data: { title: 'Discard changes?', - content: `You have unsaved changes that would be permanently lost.`, + content: `You have unsaved changes in the New risk profile that would be permanently lost.`, confirmName: 'Discard', }, autoFocus: true, @@ -397,9 +386,8 @@ describe('ProfileFormComponent', () => { deleteCopyEmitSpy = spyOn(component.deleteCopy, 'emit'); }); - it('should set isOpenProfile to false and return of(true) if profileHasNoChanges is true and not isCopyProfile', done => { + it('should set isOpenProfile to false and return of(true) if profileHasNoChanges is true and not copyProfile', done => { spyOn(component, 'profileHasNoChanges').and.returnValue(true); - component.isCopyProfile = false; component.profileForm.markAsDirty(); component.close().subscribe(result => { @@ -411,10 +399,9 @@ describe('ProfileFormComponent', () => { }); }); - it('should set isOpenProfile to false and return of(true) if profileForm is pristine and not isCopyProfile', done => { + it('should set isOpenProfile to false and return of(true) if profileForm is pristine and not copyProfile', done => { spyOn(component, 'profileHasNoChanges').and.returnValue(false); component.profileForm.markAsPristine(); - component.isCopyProfile = false; component.close().subscribe(result => { expect(result).toBeTrue(); @@ -425,10 +412,9 @@ describe('ProfileFormComponent', () => { }); }); - it('should open dialog if there are changes and not isCopyProfile, and dialog confirms (returns true)', done => { + it('should open dialog if there are changes and not copyProfile, and dialog confirms (returns true)', done => { spyOn(component, 'profileHasNoChanges').and.returnValue(false); component.profileForm.markAsDirty(); - component.isCopyProfile = false; openDialogSpy.and.returnValue(of(true)); component.close().subscribe(result => { @@ -440,10 +426,9 @@ describe('ProfileFormComponent', () => { }); }); - it('should open dialog if there are changes and not isCopyProfile, and dialog cancels (returns false)', done => { + it('should open dialog if there are changes and not copyProfile, and dialog cancels (returns false)', done => { spyOn(component, 'profileHasNoChanges').and.returnValue(false); component.profileForm.markAsDirty(); - component.isCopyProfile = false; openDialogSpy.and.returnValue(of(false)); component.close().subscribe(result => { @@ -460,7 +445,7 @@ describe('ProfileFormComponent', () => { spyOn(component, 'profileHasNoChanges').and.returnValue(false); component.profileForm.markAsDirty(); component.isCopyProfile = true; - component.selectedProfile = { ...PROFILE_MOCK }; + component.selectedProfile = { ...COPY_PROFILE_MOCK }; openDialogSpy.and.returnValue(of(true)); component.close().subscribe(result => { diff --git a/modules/ui/src/app/pages/risk-assessment/profile-form/profile-form.component.ts b/modules/ui/src/app/pages/risk-assessment/profile-form/profile-form.component.ts index 87d3b86f2..539e5d724 100644 --- a/modules/ui/src/app/pages/risk-assessment/profile-form/profile-form.component.ts +++ b/modules/ui/src/app/pages/risk-assessment/profile-form/profile-form.component.ts @@ -18,6 +18,7 @@ import { afterNextRender, AfterViewInit, ChangeDetectionStrategy, + ChangeDetectorRef, Component, EventEmitter, inject, @@ -80,7 +81,9 @@ export class ProfileFormComponent implements OnInit, AfterViewInit { private profileValidators = inject(ProfileValidators); private fb = inject(FormBuilder); private store = inject(RiskAssessmentStore); + cd = inject(ChangeDetectorRef); private profile: Profile | null = null; + private copyProfile: Profile | null = null; private profileList!: Profile[]; private injector = inject(Injector); private nameValidator!: ValidatorFn; @@ -103,8 +106,8 @@ export class ProfileFormComponent implements OnInit, AfterViewInit { } @Input() set selectedProfile(profile: Profile | null) { - if (this.isCopyProfile && this.profile) { - this.deleteCopy.emit(this.profile); + if (profile?.name.trim().startsWith('Copy')) { + this.copyProfile = profile; } if (this.changeProfile || this.profileHasNoChanges()) { this.changeProfile = false; @@ -112,8 +115,14 @@ export class ProfileFormComponent implements OnInit, AfterViewInit { if (profile && this.nameControl) { this.updateNameValidator(profile); this.fillProfileForm(this.profileFormat, profile); + if (this.isCopyProfile && this.copyProfile) { + this.setCopy.emit(this.copyProfile); + } } else { this.profileForm.reset(); + if (this.copyProfile) { + this.setCopy.emit(this.copyProfile); + } } } else if (this.profile != profile) { // prevent select profile before user confirmation @@ -128,6 +137,7 @@ export class ProfileFormComponent implements OnInit, AfterViewInit { @Output() saveProfile = new EventEmitter(); @Output() deleteCopy = new EventEmitter(); + @Output() setCopy = new EventEmitter(); @Output() discard = new EventEmitter(); ngOnInit() { this.profileForm = this.createProfileForm(); @@ -207,7 +217,7 @@ export class ProfileFormComponent implements OnInit, AfterViewInit { } private compareProfiles(profile1: Profile, profile2: Profile) { - if (profile1.name !== profile2.name || this.isCopyProfile) { + if (profile1.name !== profile2.name || this.copyProfile) { return false; } if ( @@ -329,7 +339,7 @@ export class ProfileFormComponent implements OnInit, AfterViewInit { close(): Observable { if ( (this.profileHasNoChanges() || this.profileForm.pristine) && - !this.isCopyProfile + !this.copyProfile ) { this.store.setIsOpenProfile(false); return of(true); @@ -337,8 +347,8 @@ export class ProfileFormComponent implements OnInit, AfterViewInit { return this.openCloseDialog().pipe( tap(res => { if (res) { - if (this.isCopyProfile && this.profile) { - this.deleteCopy.emit(this.profile); + if (this.copyProfile) { + this.deleteCopy.emit(this.copyProfile); } this.store.setIsOpenProfile(false); } @@ -348,11 +358,12 @@ export class ProfileFormComponent implements OnInit, AfterViewInit { } openCloseDialog() { + const profileName = this.profile?.name || 'New risk profile'; const dialogRef = this.dialog.open(SimpleDialogComponent, { ariaLabel: 'Discard the Risk Assessment changes', data: { title: 'Discard changes?', - content: `You have unsaved changes that would be permanently lost.`, + content: `You have unsaved changes in the ${profileName} that would be permanently lost.`, confirmName: 'Discard', }, autoFocus: true, @@ -367,6 +378,10 @@ export class ProfileFormComponent implements OnInit, AfterViewInit { private openCloseDialogToChangeProfile(profile: Profile | null) { this.openCloseDialog().subscribe(close => { if (close) { + if (this.copyProfile) { + this.deleteCopy.emit(this.copyProfile); + this.copyProfile = null; + } this.changeProfile = true; this.store.updateSelectedProfile(profile); } diff --git a/modules/ui/src/app/pages/risk-assessment/risk-assessment.component.html b/modules/ui/src/app/pages/risk-assessment/risk-assessment.component.html index 502b7ad71..d22a26a7d 100644 --- a/modules/ui/src/app/pages/risk-assessment/risk-assessment.component.html +++ b/modules/ui/src/app/pages/risk-assessment/risk-assessment.component.html @@ -47,6 +47,7 @@ [profileFormat]="vm.profileFormat" (saveProfile)="saveProfileClicked($event, vm.selectedProfile)" (deleteCopy)="deleteCopy($event, vm.profiles)" + (setCopy)="setCopy($event, vm.profiles)" (discard)="discard($event, vm.profiles)"> diff --git a/modules/ui/src/app/pages/risk-assessment/risk-assessment.component.spec.ts b/modules/ui/src/app/pages/risk-assessment/risk-assessment.component.spec.ts index 2a06fc8e0..98a1bf5dd 100644 --- a/modules/ui/src/app/pages/risk-assessment/risk-assessment.component.spec.ts +++ b/modules/ui/src/app/pages/risk-assessment/risk-assessment.component.spec.ts @@ -316,10 +316,7 @@ describe('RiskAssessmentComponent', () => { it('#copyProfileAndOpenForm should call openForm with copy of profile', fakeAsync(() => { spyOn(component, 'openForm'); - component.copyProfileAndOpenForm(PROFILE_MOCK, [ - PROFILE_MOCK, - PROFILE_MOCK, - ]); + component.copyProfileAndOpenForm(PROFILE_MOCK); tick(); expect(component.openForm).toHaveBeenCalledWith(DRAFT_COPY_PROFILE_MOCK); diff --git a/modules/ui/src/app/pages/risk-assessment/risk-assessment.component.ts b/modules/ui/src/app/pages/risk-assessment/risk-assessment.component.ts index 4e6b38e7e..29ee99808 100644 --- a/modules/ui/src/app/pages/risk-assessment/risk-assessment.component.ts +++ b/modules/ui/src/app/pages/risk-assessment/risk-assessment.component.ts @@ -152,10 +152,9 @@ export class RiskAssessmentComponent this.cd.detectChanges(); } - async copyProfileAndOpenForm(profile: Profile, profiles: Profile[]) { + async copyProfileAndOpenForm(profile: Profile) { this.isCopyProfile = true; const copyOfProfile = this.getCopyOfProfile(profile); - this.store.updateProfiles([copyOfProfile, ...profiles]); await this.openForm(copyOfProfile); } @@ -290,6 +289,11 @@ export class RiskAssessmentComponent deleteCopy(copyOfProfile: Profile, profiles: Profile[]) { this.isCopyProfile = false; this.store.removeProfile(copyOfProfile.name, profiles); + this.cd.markForCheck(); + } + setCopy(copyOfProfile: Profile, profiles: Profile[]) { + this.store.updateProfiles([copyOfProfile, ...profiles]); + this.cd.detectChanges(); } actions(actions: EntityAction[]) { @@ -312,7 +316,7 @@ export class RiskAssessmentComponent ) { switch (action) { case ProfileAction.Copy: - this.copyProfileAndOpenForm(entity, profiles); + this.copyProfileAndOpenForm(entity); break; case ProfileAction.Delete: this.deleteProfile(entity, profiles, selectedProfile);