diff --git a/console/src/app/directives/has-role/has-role.directive.ts b/console/src/app/directives/has-role/has-role.directive.ts index 65e6a4fe17..b58e1f3a10 100644 --- a/console/src/app/directives/has-role/has-role.directive.ts +++ b/console/src/app/directives/has-role/has-role.directive.ts @@ -1,25 +1,34 @@ -import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core'; +import { Directive, Input, OnDestroy, TemplateRef, ViewContainerRef } from '@angular/core'; +import { Subject, takeUntil } from 'rxjs'; import { GrpcAuthService } from 'src/app/services/grpc-auth.service'; @Directive({ selector: '[cnslHasRole]', }) -export class HasRoleDirective { +export class HasRoleDirective implements OnDestroy { + private destroy$: Subject = new Subject(); private hasView: boolean = false; @Input() public set hasRole(roles: string[] | RegExp[] | undefined) { if (roles && roles.length > 0) { - this.authService.isAllowed(roles).subscribe((isAllowed) => { - if (isAllowed && !this.hasView) { - this.viewContainerRef.clear(); - this.viewContainerRef.createEmbeddedView(this.templateRef); - } else { - this.viewContainerRef.clear(); - this.hasView = false; - } - }); + this.authService + .isAllowed(roles) + .pipe(takeUntil(this.destroy$)) + .subscribe((isAllowed) => { + if (isAllowed && !this.hasView) { + if (this.viewContainerRef.length !== 0) { + this.viewContainerRef.clear(); + } + this.viewContainerRef.createEmbeddedView(this.templateRef); + } else { + this.viewContainerRef.clear(); + this.hasView = false; + } + }); } else { if (!this.hasView) { - this.viewContainerRef.clear(); + if (this.viewContainerRef.length !== 0) { + this.viewContainerRef.clear(); + } this.viewContainerRef.createEmbeddedView(this.templateRef); } } @@ -30,4 +39,9 @@ export class HasRoleDirective { protected templateRef: TemplateRef, protected viewContainerRef: ViewContainerRef, ) {} + + ngOnDestroy(): void { + this.destroy$.next(); + this.destroy$.complete(); + } }