src/modules/app-menu/components/app-menu-item.component.ts
Component to display app-menu-item based on the options passed as parameters.
OnInit
AfterViewInit
OnDestroy
changeDetection | ChangeDetectionStrategy.OnPush |
encapsulation | ViewEncapsulation.None |
host | { |
selector | stark-app-menu-item |
templateUrl | ./app-menu-item.component.html |
Properties |
|
Methods |
|
Inputs |
Outputs |
Accessors |
Public
constructor(logger: StarkLoggingService, routingService: StarkRoutingService, renderer: Renderer2, elementRef: ElementRef, cdRef: ChangeDetectorRef)
|
||||||||||||||||||||||||
Class constructor
Parameters :
|
level | |
Type : number
|
|
Default value : 0
|
|
Current menu level |
menuGroup | |
Type : StarkMenuGroup
|
|
Default value : DEFAULT_MENU_GROUP
|
|
Data source of the component |
color | |
Type : string
|
|
Inherited from
AbstractStarkUiComponent
|
|
Defined in
AbstractStarkUiComponent:16
|
|
Color theme |
activated | |
Type : EventEmitter
|
|
Event to emit when the component is activated |
deactivated | |
Type : EventEmitter
|
|
Event to emit when the component is deactivated |
Public isCurrentState |
isCurrentState()
|
Utility function to check if the component targetState is the current state
Returns :
boolean
|
Public ngAfterViewInit |
ngAfterViewInit()
|
Component AfterViewInit lifecycle hook
Returns :
void
|
Public ngOnDestroy |
ngOnDestroy()
|
Component OnDestroy lifecycle hook
Returns :
void
|
Public ngOnInit |
ngOnInit()
|
Inherited from
AbstractStarkUiComponent
|
Defined in
AbstractStarkUiComponent:143
|
Component OnInit lifecycle hook
Returns :
void
|
Public onActivate |
onActivate()
|
Activate event handler
Returns :
void
|
Public onClick |
onClick()
|
Click event handler
Returns :
void
|
Public onDeactivate |
onDeactivate()
|
Deactivate event handler
Returns :
void
|
Private _isActive |
Default value : false
|
Active status of the component |
Public logger |
Type : StarkLoggingService
|
Decorators :
@Inject(STARK_LOGGING_SERVICE)
|
- The `StarkLoggingService` instance of the application.
|
Public menuGroupsPanel |
Type : MatExpansionPanel
|
Decorators :
@ViewChild('menuGroupsPanel', {static: false})
|
ViewChild catching the extension panel in order to open/close it programmatically |
Public routingService |
Type : StarkRoutingService
|
Decorators :
@Inject(STARK_ROUTING_SERVICE)
|
- The `StarkRoutingService` instance of the application.
|
Private Optional routingTransitionFinishCallback |
Type : Function
|
Routing transition finish callback |
Private Optional routingTransitionSuccessCallback |
Type : Function
|
Routing transition success callback |
isActive | ||||||
getisActive()
|
||||||
setisActive(isActive: boolean)
|
||||||
Parameters :
Returns :
void
|
import {
AfterViewInit,
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ElementRef,
EventEmitter,
Inject,
Input,
OnDestroy,
OnInit,
Output,
Renderer2,
ViewChild,
ViewEncapsulation
} from "@angular/core";
import { MatExpansionPanel } from "@angular/material/expansion";
import {
STARK_LOGGING_SERVICE,
STARK_ROUTING_SERVICE,
StarkLoggingService,
StarkRoutingService,
StarkRoutingTransitionHook
} from "@nationalbankbelgium/stark-core";
import { AbstractStarkUiComponent } from "@nationalbankbelgium/stark-ui/src/internal-common";
import { StarkMenuGroup } from "./app-menu-group.intf";
/**
* @ignore
*/
const componentName = "stark-app-menu-item";
/**
*
* Default value for MenuGroup
*/
const DEFAULT_MENU_GROUP: StarkMenuGroup = {
id: "",
label: "",
isVisible: false,
isEnabled: false
};
/**
* Component to display app-menu-item based on the options passed as parameters.
*/
@Component({
selector: "stark-app-menu-item",
templateUrl: "./app-menu-item.component.html",
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
// We need to use host instead of @HostBinding: https://github.com/NationalBankBelgium/stark/issues/664
host: {
class: componentName
}
})
export class StarkAppMenuItemComponent extends AbstractStarkUiComponent implements OnInit, AfterViewInit, OnDestroy {
/**
* Current menu level
*/
@Input()
public level = 0;
/**
* Data source of the component
*/
@Input()
public menuGroup: StarkMenuGroup = DEFAULT_MENU_GROUP;
/**
* Event to emit when the component is activated
*/
@Output()
public readonly activated = new EventEmitter<void>();
/**
* Event to emit when the component is deactivated
*/
@Output()
public readonly deactivated = new EventEmitter<void>();
/**
* ViewChild catching the extension panel in order to open/close it programmatically
*/
@ViewChild("menuGroupsPanel", { static: false })
public menuGroupsPanel!: MatExpansionPanel;
/**
* Active status of the component
*/
private _isActive = false;
public set isActive(isActive: boolean) {
this._isActive = isActive;
if (isActive && this.menuGroup.entries) {
this.menuGroupsPanel.open();
}
if (isActive) {
this.cdRef.detectChanges(); // needed due to ChangeDetectionStrategy.OnPush in order to refresh the CSS classes
this.activated.emit();
} else {
this.cdRef.detectChanges(); // needed due to ChangeDetectionStrategy.OnPush in order to refresh the CSS classes
this.deactivated.emit();
}
}
public get isActive(): boolean {
return this._isActive;
}
/**
* Routing transition finish callback
*/
private routingTransitionFinishCallback?: Function;
/**
* Routing transition success callback
*/
private routingTransitionSuccessCallback?: Function;
/**
* Class constructor
* @param logger - The `StarkLoggingService` instance of the application.
* @param routingService - The `StarkRoutingService` instance of the application.
* @param renderer - Angular `Renderer2` wrapper for DOM manipulations.
* @param elementRef - Reference to the DOM element where this component is attached to.
* @param cdRef - Reference to the change detector attached to this component.
*/
public constructor(
@Inject(STARK_LOGGING_SERVICE) public logger: StarkLoggingService,
@Inject(STARK_ROUTING_SERVICE) public routingService: StarkRoutingService,
renderer: Renderer2,
elementRef: ElementRef,
protected cdRef: ChangeDetectorRef
) {
super(renderer, elementRef);
}
/**
* Component OnInit lifecycle hook
*/
public override ngOnInit(): void {
super.ngOnInit();
this.logger.debug(componentName + ": component initialized");
}
/**
* Component AfterViewInit lifecycle hook
*/
public ngAfterViewInit(): void {
this.routingTransitionSuccessCallback = this.routingService.addTransitionHook(StarkRoutingTransitionHook.ON_SUCCESS, {}, () => {
if (this.isCurrentState()) {
this.isActive = true;
}
});
this.routingTransitionFinishCallback = this.routingService.addTransitionHook(StarkRoutingTransitionHook.ON_FINISH, {}, () => {
this.isActive = false;
});
}
/**
* Component OnDestroy lifecycle hook
*/
public ngOnDestroy(): void {
if (this.routingTransitionFinishCallback) {
this.routingTransitionFinishCallback();
}
if (this.routingTransitionSuccessCallback) {
this.routingTransitionSuccessCallback();
}
}
/**
* Click event handler
*/
public onClick(): void {
if (this.menuGroup.isEnabled) {
if (this.menuGroup.targetState) {
this.routingService.navigateTo(this.menuGroup.targetState, this.menuGroup.targetStateParams);
} else if (this.menuGroup.entries) {
this.menuGroupsPanel.toggle();
}
}
}
/**
* Activate event handler
*/
public onActivate(): void {
this.isActive = true;
}
/**
* Deactivate event handler
*/
public onDeactivate(): void {
this.isActive = false;
}
/**
* Utility function to check if the component targetState is the current state
*/
public isCurrentState(): boolean {
if (!this.menuGroup.entries) {
return this.menuGroup.targetState ? this.routingService.isCurrentUiStateIncludedIn(this.menuGroup.targetState) : false;
}
return this.menuGroup.targetState ? this.routingService.isCurrentUiState(this.menuGroup.targetState) : false;
}
/**
* @ignore
*/
public trackMenuItem(index: number, _menuGroup: StarkMenuGroup): number {
return index;
}
}
<mat-list-item
*ngIf="menuGroup.isVisible"
[id]="menuGroup.id"
[ngClass]="'stark-app-menu-item-level-' + level.toString()"
[class.active]="isActive"
[class.stark-disabled]="!menuGroup.isEnabled"
[disableRipple]="!menuGroup.isEnabled"
(click)="onClick()"
>
<mat-icon *ngIf="menuGroup.icon" [color]="isActive ? 'primary' : ''" [svgIcon]="menuGroup.icon" class="stark-small-icon"></mat-icon>
<span matLine translate>{{ menuGroup.label }}</span>
</mat-list-item>
<mat-expansion-panel *ngIf="menuGroup.entries" #menuGroupsPanel>
<mat-nav-list>
<stark-app-menu-item
*ngFor="let entry of menuGroup.entries; trackBy: trackMenuItem"
[level]="level + 1"
[menuGroup]="entry"
(activated)="onActivate()"
(deactivated)="onDeactivate()"
></stark-app-menu-item>
</mat-nav-list>
</mat-expansion-panel>