Correct method to display/hide interface according to profiles/rules/credentials with Angular 2+

Asked

Viewed 207 times

0

I need, for the current system I develop, a way to hide or display components according to profiles, for example:

Profile: Master

View View, Create, Edit, and Remove Registrations button

Profile: Internal Controls

Display only the View Entries button

For this case, what I thought was the following: Create a checker component, which asks for the profile and the required permission to view its content, as shown in the code below:

import { Component, OnInit, Input } from '@angular/core';
import { RuleCheckService } from 'src/app/core/services/rule-check/rule-check.service';

@Component({
    selector: 'app-rule-check',
    template: `
    <ng-template [ngIf]="canShowContent">
        <ng-content></ng-content>
    </ng-template>
    `,
    styleUrls: []
})
export class RuleCheckComponent implements OnInit {

    @Input()
    public ruleGroup: string; // Grupo de regras ao qual o perfil deve se encaixar
    @Input()
    public permissionCheck: any; // Permissão necessária para exibição do conteúdo, podendo ser string ou array de string

    public canShowContent = false; // Verifica se deve ou não exibir o conteúdo do componente, de acordo com as regras verificadas

    constructor(
        private ruleCheckService: RuleCheckService // Serviço que puxa o usuário logado, obtendo suas permissões
    ) { }

    ngOnInit(): void {
        this.checkPermission();
    }

    checkPermission() { // Método que fará a verificação e alterará para visível ou não
        if ( this.ruleGroup === null || this.permissionCheck === null ) {
            this.canShowContent = false;
            return;
        }

        const $check = this.ruleCheckService.check( this.ruleGroup, this.permissionCheck )
        $check.subscribe( permission => {
            this.canShowContent = permission;
        });
    }
}

Have some more practical and/or intelligent way to use this situation?

1 answer

0

Yes, with the async pipe.

Instead of signing to the observable, insert it directly into the HTML.

In HTML:

<ng-template *ngIf="check$ | async">
        <ng-content></ng-content>
</ng-template>

In TS:

ngOnInit(): void {
        this.check$ = this.ruleCheckService.check(this.ruleGroup, this.permissionCheck).pipe(take(1));
}

The condition !this.ruleGroup || ! this.permissionCheck must be inserted within the service.

I inserted the $ at the end because it is the standard for variables Observables. The asyncPipe is the value of the observable every time it undergoes some change, without the need to make a subscribe.

Another note: Use HTML in HTML and ng-template files when you have a second condition in HTML. Example:

<div *ngIf="check$ | async; else outraCoisa"> Uma coisa </div>
<ng-template #outraCoisa>
            Outra coisa
</ng-template>

In this example, ng-template becomes a Else and the div major one if.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.