From ae0141922b7752a605fbf9456bdc98e459c12120 Mon Sep 17 00:00:00 2001 From: kurilova Date: Fri, 14 Feb 2025 13:23:32 +0000 Subject: [PATCH 1/7] Remove Copy of profile on discard click --- .../risk-assessment.component.html | 2 +- .../risk-assessment.component.spec.ts | 23 ++++++++++++++++--- .../risk-assessment.component.ts | 20 +++++++++++----- 3 files changed, 35 insertions(+), 10 deletions(-) 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 49c44420f..8d464ee6b 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,7 +47,7 @@ (deleteCopy)="deleteCopy($event, vm.profiles)" (delete)="deleteProfile($event)" (copyProfile)="copyProfile($event, vm.profiles)" - (discard)="discard($event)"> + (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 c23f0c7ab..85d8b7650 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 @@ -70,6 +70,7 @@ describe('RiskAssessmentComponent', () => { 'setFocusOnSelectedProfile', 'setFocusOnProfileForm', 'updateProfiles', + 'removeProfile', ]); await TestBed.configureTestingModule({ @@ -407,7 +408,7 @@ describe('RiskAssessmentComponent', () => { 'openCloseDialog' ).and.returnValue(of(true)); - component.discard(null); + component.discard(null, []); expect(openCloseDialogSpy).toHaveBeenCalled(); @@ -420,7 +421,7 @@ describe('RiskAssessmentComponent', () => { component.form(), 'openCloseDialog' ).and.returnValue(of(true)); - component.discard(null); + component.discard(null, []); }); it('should call setFocusOnCreateButton', () => { @@ -440,7 +441,7 @@ describe('RiskAssessmentComponent', () => { component.form(), 'openCloseDialog' ).and.returnValue(of(true)); - component.discard(PROFILE_MOCK); + component.discard(PROFILE_MOCK, []); tick(100); })); @@ -456,6 +457,22 @@ describe('RiskAssessmentComponent', () => { ).toHaveBeenCalledWith(null); }); }); + + describe('with selected copy profile', () => { + beforeEach(fakeAsync(() => { + spyOn( + component.form(), + 'openCloseDialog' + ).and.returnValue(of(true)); + component.isCopyProfile = true; + component.discard(DRAFT_COPY_PROFILE_MOCK, [DRAFT_COPY_PROFILE_MOCK]); + tick(100); + })); + + it('should remove copy if not saved', () => { + expect(mockRiskAssessmentStore.removeProfile).toHaveBeenCalled(); + }); + }); }); }); }); 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 f85a4bd80..05e63777c 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 @@ -203,25 +203,33 @@ export class RiskAssessmentComponent } } - discard(selectedProfile: Profile | null) { + discard(selectedProfile: Profile | null, profiles: Profile[]) { this.liveAnnouncer.clear(); - this.openCloseDialog(selectedProfile); + this.openCloseDialog(selectedProfile, profiles); } copyProfile(profile: Profile, profiles: Profile[]) { this.copyProfileAndOpenForm(profile, profiles); } - private openCloseDialog(selectedProfile: Profile | null) { + private openCloseDialog( + selectedProfile: Profile | null, + profiles: Profile[] + ) { this.form() ?.openCloseDialog() .pipe(takeUntil(this.destroy$)) .subscribe(close => { if (close) { if (selectedProfile) { - timer(100).subscribe(() => { - this.store.setFocusOnSelectedProfile(); - }); + if (this.isCopyProfile) { + this.deleteCopy(selectedProfile, profiles); + this.store.setFocusOnCreateButton(); + } else { + timer(100).subscribe(() => { + this.store.setFocusOnSelectedProfile(); + }); + } } else { this.store.setFocusOnCreateButton(); } From 7eeb0b3e896c263338e21bc9fd47adfee7a58a38 Mon Sep 17 00:00:00 2001 From: Olga Mardvilko Date: Fri, 14 Feb 2025 13:00:17 +0300 Subject: [PATCH 2/7] 396366298: (fix) [GM3] prevent corrupting profile if it has long name (#1121) --- .../app/components/device-item/device-item.component.scss | 5 +++++ .../risk-assessment/profile-item/profile-item.component.scss | 5 +---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/ui/src/app/components/device-item/device-item.component.scss b/modules/ui/src/app/components/device-item/device-item.component.scss index e4aa3d37b..717ffa704 100644 --- a/modules/ui/src/app/components/device-item/device-item.component.scss +++ b/modules/ui/src/app/components/device-item/device-item.component.scss @@ -141,6 +141,8 @@ $border-radius: 12px; padding-right: variables.$icon-size; .item-manufacturer-text { + width: 210px; + max-width: 240px; margin: 0; text-overflow: ellipsis; white-space: nowrap; @@ -188,4 +190,7 @@ mat-icon { mat-icon { color: colors.$on-error-container; } + .item-manufacturer-text { + max-width: 150px; + } } diff --git a/modules/ui/src/app/pages/risk-assessment/profile-item/profile-item.component.scss b/modules/ui/src/app/pages/risk-assessment/profile-item/profile-item.component.scss index a005792f6..509ef9d2c 100644 --- a/modules/ui/src/app/pages/risk-assessment/profile-item/profile-item.component.scss +++ b/modules/ui/src/app/pages/risk-assessment/profile-item/profile-item.component.scss @@ -24,10 +24,6 @@ $profile-item-container-gap: 8px; width: 100%; height: 100%; display: grid; - grid-template-columns: minmax(160px, 1fr) repeat( - 2, - $profile-icon-container-size - ); gap: $profile-item-container-gap; box-sizing: border-box; align-items: center; @@ -83,6 +79,7 @@ $profile-item-container-gap: 8px; } .profile-item-name { + max-width: 170px; font-size: 16px; color: colors.$on-surface; line-height: 24px; From 555e8aeeb953e3d482298e665f41caf35902373a Mon Sep 17 00:00:00 2001 From: Olga Mardvilko Date: Fri, 14 Feb 2025 17:05:24 +0300 Subject: [PATCH 3/7] 396579770: (fix) set focus to correct interactive elements after delete discard profile (#1122) --- .../profile-form/profile-form.component.ts | 2 +- .../risk-assessment.component.spec.ts | 33 ++--------- .../risk-assessment.component.ts | 56 ++++++++++++------- 3 files changed, 42 insertions(+), 49 deletions(-) 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 763645cc1..1736f91c0 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 @@ -297,7 +297,7 @@ export class ProfileFormComponent implements OnInit, AfterViewInit { } onDiscardClick() { - this.discard.emit(this.selectedProfile!); + this.discard.emit(); } onDeleteClick(): void { 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 85d8b7650..e60fecd00 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 @@ -415,19 +415,19 @@ describe('RiskAssessmentComponent', () => { openCloseDialogSpy.calls.reset(); }); - describe('with no selected profile', () => { + describe('after dialog closed with discard selected', () => { beforeEach(() => { spyOn( component.form(), 'openCloseDialog' ).and.returnValue(of(true)); - component.discard(null, []); + component.discard(); }); - it('should call setFocusOnCreateButton', () => { + it('should update selected profile', () => { expect( - mockRiskAssessmentStore.setFocusOnCreateButton - ).toHaveBeenCalled(); + mockRiskAssessmentStore.updateSelectedProfile + ).toHaveBeenCalledWith(null); }); it('should close the form', () => { @@ -435,29 +435,6 @@ describe('RiskAssessmentComponent', () => { }); }); - describe('with selected profile', () => { - beforeEach(fakeAsync(() => { - spyOn( - component.form(), - 'openCloseDialog' - ).and.returnValue(of(true)); - component.discard(PROFILE_MOCK, []); - tick(100); - })); - - it('should call setFocusOnCreateButton', fakeAsync(() => { - expect( - mockRiskAssessmentStore.setFocusOnSelectedProfile - ).toHaveBeenCalled(); - })); - - it('should update selected profile', () => { - expect( - mockRiskAssessmentStore.updateSelectedProfile - ).toHaveBeenCalledWith(null); - }); - }); - describe('with selected copy profile', () => { beforeEach(fakeAsync(() => { spyOn( 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 05e63777c..ac2eb0f4f 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 @@ -22,6 +22,7 @@ import { inject, viewChild, ChangeDetectorRef, + ElementRef, } from '@angular/core'; import { RiskAssessmentStore } from './risk-assessment.store'; import { SimpleDialogComponent } from '../../components/simple-dialog/simple-dialog.component'; @@ -93,6 +94,7 @@ export class RiskAssessmentComponent private store = inject(RiskAssessmentStore); private liveAnnouncer = inject(LiveAnnouncer); cd = inject(ChangeDetectorRef); + private elementRef = inject(ElementRef); private destroy$: Subject = new Subject(); dialog = inject(MatDialog); element = inject(ViewContainerRef); @@ -171,7 +173,9 @@ export class RiskAssessmentComponent name: profileName, onDelete: (idx = 0) => { this.closeFormAfterDelete(profileName, profile); - this.setFocus(idx); + timer(100).subscribe(() => { + this.setFocus(idx); + }); }, }); } else { @@ -221,26 +225,37 @@ export class RiskAssessmentComponent .pipe(takeUntil(this.destroy$)) .subscribe(close => { if (close) { - if (selectedProfile) { - if (this.isCopyProfile) { - this.deleteCopy(selectedProfile, profiles); - this.store.setFocusOnCreateButton(); - } else { - timer(100).subscribe(() => { - this.store.setFocusOnSelectedProfile(); - }); - } - } else { - this.store.setFocusOnCreateButton(); + if (selectedProfile && this.isCopyProfile) { + this.deleteCopy(selectedProfile, profiles); } this.isCopyProfile = false; this.isOpenProfileForm = false; this.store.updateSelectedProfile(null); this.cd.markForCheck(); + timer(100).subscribe(() => { + this.focusSelectedButton(); + }); } }); } + private focusSelectedButton() { + const selectedButton = this.elementRef.nativeElement.querySelector( + 'app-profile-item.selected .profile-item-container' + ); + if (selectedButton) { + selectedButton.focus(); + } else { + this.focusAddButton(); + } + } + + private focusAddButton(): void { + const addButton = + this.elementRef.nativeElement.querySelector('.add-entity-button'); + addButton?.focus(); + } + deleteCopy(copyOfProfile: Profile, profiles: Profile[]) { this.isCopyProfile = false; this.store.removeProfile(copyOfProfile.name, profiles); @@ -346,14 +361,15 @@ export class RiskAssessmentComponent } private setFocus(index: number): void { - const nextItem = window.document.querySelector( - `.profile-item-${index + 1}` - ) as HTMLElement; - const firstItem = window.document.querySelector( - `.profile-item-0` - ) as HTMLElement; - - this.store.setFocus({ nextItem, firstItem }); + const nextItem = this.elementRef.nativeElement.querySelectorAll( + 'app-profile-item .profile-item-info' + )[index]; + + if (nextItem) { + nextItem.focus(); + } else { + this.focusAddButton(); + } } private openSaveDialog( From d365f27c01688adb91fc5b1421569cce938845e0 Mon Sep 17 00:00:00 2001 From: kurilova Date: Fri, 14 Feb 2025 16:01:56 +0000 Subject: [PATCH 4/7] Fix after merge --- .../risk-assessment/profile-form/profile-form.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 1736f91c0..20bb9099e 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 @@ -128,7 +128,7 @@ export class ProfileFormComponent implements OnInit, AfterViewInit { @Output() saveProfile = new EventEmitter(); @Output() deleteCopy = new EventEmitter(); - @Output() discard = new EventEmitter(); + @Output() discard = new EventEmitter(); @Output() delete = new EventEmitter(); @Output() copyProfile = new EventEmitter(); ngOnInit() { @@ -297,7 +297,7 @@ export class ProfileFormComponent implements OnInit, AfterViewInit { } onDiscardClick() { - this.discard.emit(); + this.discard.emit(this.selectedProfile!); } onDeleteClick(): void { From 14a5c89c3429a9f0292d85059b6b4245914ab226 Mon Sep 17 00:00:00 2001 From: Olga Mardvilko Date: Fri, 14 Feb 2025 17:05:24 +0300 Subject: [PATCH 5/7] 396579770: (fix) set focus to correct interactive elements after delete discard profile (#1122) --- .../risk-assessment/profile-form/profile-form.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 20bb9099e..a65fa417a 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 @@ -297,7 +297,7 @@ export class ProfileFormComponent implements OnInit, AfterViewInit { } onDiscardClick() { - this.discard.emit(this.selectedProfile!); + this.discard.emit(); } onDeleteClick(): void { From 5f69808e0e04cae1616bb163ac36a6e09f05066f Mon Sep 17 00:00:00 2001 From: Olga Mardvilko Date: Mon, 17 Feb 2025 12:25:43 +0300 Subject: [PATCH 6/7] 395677144: (fix) [GM3] A11Y: move button on the next line to prevent corrupting sticky menu (#1125) --- modules/ui/src/theming/mixins.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ui/src/theming/mixins.scss b/modules/ui/src/theming/mixins.scss index ba402bd1d..5910e5deb 100644 --- a/modules/ui/src/theming/mixins.scss +++ b/modules/ui/src/theming/mixins.scss @@ -95,11 +95,11 @@ left: 32px; bottom: 25px; display: flex; + flex-wrap: wrap; align-items: center; gap: 10px; justify-content: space-between; width: calc(100% - 64px); - height: 80px; padding: 16px; box-sizing: border-box; background: colors.$surface; From 5215b0faf60598a85a571c41c66a7823d53aae8b Mon Sep 17 00:00:00 2001 From: kurilova Date: Mon, 17 Feb 2025 10:20:35 +0000 Subject: [PATCH 7/7] Fix after merge --- .../app/pages/risk-assessment/risk-assessment.component.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 e60fecd00..b2d7b0281 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 @@ -421,7 +421,7 @@ describe('RiskAssessmentComponent', () => { component.form(), 'openCloseDialog' ).and.returnValue(of(true)); - component.discard(); + component.discard(null, []); }); it('should update selected profile', () => {