From c3bcb8d3c0dfedd89a2a20e321f9a512da0b04c7 Mon Sep 17 00:00:00 2001 From: thomas Date: Thu, 22 Dec 2022 11:32:46 +0100 Subject: [PATCH] feat(core): add destroyService --- .../permissions/src/app/has-role.directive.ts | 68 +++++++++++++++++++ libs/shared/utils/src/index.ts | 1 + .../utils/src/lib/destroy-service.service.ts | 39 +++++++++++ 3 files changed, 108 insertions(+) create mode 100644 apps/permissions/src/app/has-role.directive.ts create mode 100644 libs/shared/utils/src/lib/destroy-service.service.ts diff --git a/apps/permissions/src/app/has-role.directive.ts b/apps/permissions/src/app/has-role.directive.ts new file mode 100644 index 0000000..807e8b6 --- /dev/null +++ b/apps/permissions/src/app/has-role.directive.ts @@ -0,0 +1,68 @@ +/* eslint-disable @angular-eslint/directive-selector */ +import { NgIfContext } from '@angular/common'; +import { + Directive, + Input, + OnDestroy, + OnInit, + TemplateRef, + ViewContainerRef, +} from '@angular/core'; +import { Role } from './user.model'; +import { UserStore } from './user.store'; + +@Directive({ + selector: '[hasRole], [hasRoleIsAdmin]', + standalone: true, + providers: [provideDestroyService()], +}) +export class HasRoleDirective implements OnInit, OnDestroy { + @Input('hasRole') role: Role | Role[] | undefined = undefined; + + @Input('hasRoleIsAdmin') isAdmin = false; + + @Input('hasRoleIsAdminElseTemplate') + elseTemplate?: TemplateRef | null; + + constructor( + private templateRef: TemplateRef, + private viewContainer: ViewContainerRef, + private store: UserStore + ) {} + + ngOnDestroy(): void { + console.log('on destroy'); + } + + ngOnInit(): void { + console.log(this.role, this.isAdmin, this.elseTemplate); + if (this.isAdmin) { + this.store.isAdmin$.subscribe((isAdmin) => { + console.log(isAdmin); + isAdmin ? this.addTemplate() : this.addElseTemplate(); + }); + } + // else if (this.role) { + // this.store + // .hasAnyRole(this.role) + // .subscribe((hasPermission) => + // hasPermission ? this.addTemplate() : this.addElseTemplate() + // ); + // } else { + // this.addTemplate(); + // } + } + + private addTemplate() { + console.log('Add'); + this.viewContainer.clear(); + this.viewContainer.createEmbeddedView(this.templateRef); + } + + private addElseTemplate() { + console.log('ici'); + this.viewContainer.clear(); + this.elseTemplate && + this.viewContainer.createEmbeddedView(this.elseTemplate); + } +} diff --git a/libs/shared/utils/src/index.ts b/libs/shared/utils/src/index.ts index 2b1a80f..15f8311 100644 --- a/libs/shared/utils/src/index.ts +++ b/libs/shared/utils/src/index.ts @@ -1 +1,2 @@ +export * from './lib/destroy-service.service'; export * from './lib/random-http-error.utils'; diff --git a/libs/shared/utils/src/lib/destroy-service.service.ts b/libs/shared/utils/src/lib/destroy-service.service.ts new file mode 100644 index 0000000..2a4b103 --- /dev/null +++ b/libs/shared/utils/src/lib/destroy-service.service.ts @@ -0,0 +1,39 @@ +import { ClassProvider, inject, Injectable, OnDestroy } from '@angular/core'; +import { Observable, Subject } from 'rxjs'; + +function describeDestroyService() { + @Injectable() + class DestroyService extends Subject implements OnDestroy { + ngOnDestroy(): void { + this.next(); + this.complete(); + } + } + + function provideDestroyService(): ClassProvider { + return { + provide: DestroyService, + useClass: DestroyService, + }; + } + + function injectDestroyService(): Observable { + const destroy$ = inject(DestroyService, { self: true, optional: true }); + + if (!destroy$) { + throw new Error( + 'It seems that you forgot to provide DestroyService. Add "provideDestroyService()" to your declarable\'s providers.' + ); + } + + return destroy$.asObservable(); + } + + return { + provideDestroyService, + injectDestroyService, + }; +} + +export const { provideDestroyService, injectDestroyService } = + describeDestroyService();