[ACS-9266][ACS-9234] Make notification and user menu accessible with keyboard (#10647)

* [ACS-9266][ACS-9234] Make notification and user menu accessible with keyboard

* [ACS-9266] cr fix

* [ACS-9266] cr fixes

* [ACS-9266] fix eslint

* [ACS-9266] fix circular dependency

* [ACS-9266] cr fix
This commit is contained in:
Mykyta Maliarchuk
2025-02-17 10:52:27 +01:00
committed by GitHub
parent c8aa27a87b
commit e4feb68381
11 changed files with 263 additions and 176 deletions

View File

@@ -19,10 +19,11 @@
import { Component, Input, OnChanges, SimpleChange } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DynamicExtensionComponent } from './dynamic.component';
import { ComponentRegisterService } from '../../services/component-register.service';
import { HttpClientModule } from '@angular/common/http';
import { MatMenuItem } from '@angular/material/menu';
import { By } from '@angular/platform-browser';
@Component({
selector: 'test-component',
@@ -71,9 +72,10 @@ describe('DynamicExtensionComponent', () => {
TestBed.resetTestingModule();
});
const getInnerElement = () => fixture.debugElement.query(By.css('[data-automation-id="found-me"]'));
it('should load the TestComponent', () => {
const innerElement = fixture.debugElement.query(By.css('[data-automation-id="found-me"]'));
expect(innerElement).not.toBeNull();
expect(getInnerElement()).not.toBeNull();
});
it('should pass through the data', () => {
@@ -90,6 +92,12 @@ describe('DynamicExtensionComponent', () => {
const testComponent = fixture.debugElement.query(By.css('test-component')).componentInstance;
expect(testComponent.data).toBe(data);
});
it('should assign menuItem from dynamically generated component in ngAfterViewInit', () => {
getInnerElement().componentInstance.menuItem = new MatMenuItem(null, null, null, null, null);
component.ngAfterViewInit();
expect(component.menuItem).toBeInstanceOf(MatMenuItem);
});
});
describe('Angular life-cycle methods in sub-component', () => {

View File

@@ -15,9 +15,10 @@
* limitations under the License.
*/
import { Component, Input, ComponentRef, ViewChild, ViewContainerRef, OnDestroy, OnChanges, SimpleChanges } from '@angular/core';
import { Component, Input, ComponentRef, ViewChild, ViewContainerRef, OnDestroy, OnChanges, SimpleChanges, AfterViewInit } from '@angular/core';
import { ExtensionService } from '../../services/extension.service';
import { ExtensionComponent } from '../../services/component-register.service';
import { MatMenuItem } from '@angular/material/menu';
// cSpell:words lifecycle
@Component({
@@ -25,7 +26,7 @@ import { ExtensionComponent } from '../../services/component-register.service';
standalone: true,
template: `<div #content></div>`
})
export class DynamicExtensionComponent implements OnChanges, OnDestroy {
export class DynamicExtensionComponent implements OnChanges, OnDestroy, AfterViewInit {
@ViewChild('content', { read: ViewContainerRef, static: true })
content: ViewContainerRef;
@@ -35,6 +36,9 @@ export class DynamicExtensionComponent implements OnChanges, OnDestroy {
/** Data for the dynamically-loaded component instance. */
@Input() data: any;
/** Provides the menu item of dynamically-loaded component instance. */
menuItem: MatMenuItem;
private componentRef: ComponentRef<ExtensionComponent>;
private loaded: boolean = false;
@@ -61,6 +65,10 @@ export class DynamicExtensionComponent implements OnChanges, OnDestroy {
}
}
ngAfterViewInit() {
this.menuItem = this.componentRef?.instance?.menuItem;
}
private loadComponent() {
const componentType = this.extensions.getComponentById<ExtensionComponent>(this.id);
if (componentType) {

View File

@@ -16,9 +16,11 @@
*/
import { Injectable, Type } from '@angular/core';
import { MatMenuItem } from '@angular/material/menu';
export interface ExtensionComponent {
data: any;
menuItem?: MatMenuItem;
}
@Injectable({ providedIn: 'root' })