Skip to content

Commit 7c86678

Browse files
committed
feat: add a permission directive for manage all sections to view
1 parent 5b1e1f7 commit 7c86678

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { PermissionDirective } from './permission.directive';
2+
3+
describe('PermissionDirective', () => {
4+
it('should create an instance', () => {
5+
const directive = new PermissionDirective();
6+
expect(directive).toBeTruthy();
7+
});
8+
});
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import {
2+
Directive,
3+
EmbeddedViewRef,
4+
inject,
5+
input,
6+
OnInit,
7+
TemplateRef,
8+
ViewContainerRef,
9+
ViewRef,
10+
} from '@angular/core';
11+
import { Role, User } from '../user.model';
12+
import { UserStore } from '../user.store';
13+
14+
@Directive({
15+
selector: '[appHasRole],[appHasRoleSuperAdmin]',
16+
standalone: true,
17+
})
18+
export class PermissionDirective implements OnInit {
19+
private readonly templateRef = inject(TemplateRef);
20+
private readonly viewContainerRef = inject(ViewContainerRef);
21+
private readonly userStore = inject(UserStore);
22+
23+
appHasRole = input<string | string[] | null>(null);
24+
appHasRoleSuperAdmin = input<boolean | string>(true);
25+
26+
private currentEmbeddedView: EmbeddedViewRef<ViewRef> | null = null;
27+
28+
ngOnInit() {
29+
this.manageSubscriptions();
30+
}
31+
32+
private manageSubscriptions(): void {
33+
this.userStore.user$.subscribe({
34+
next: (user) => {
35+
if (!user) {
36+
this.viewContainerRef.clear();
37+
return;
38+
}
39+
const renderView = this.canSectionBeVisible(user);
40+
if (renderView) {
41+
this.createView();
42+
} else {
43+
this.clearView();
44+
}
45+
},
46+
error: () => {
47+
// addition error handling goes here
48+
this.clearView();
49+
},
50+
});
51+
}
52+
53+
private createView(): void {
54+
this.currentEmbeddedView ??= this.viewContainerRef.createEmbeddedView(
55+
this.templateRef,
56+
);
57+
}
58+
59+
private clearView(): void {
60+
this.viewContainerRef.clear();
61+
this.currentEmbeddedView = null;
62+
}
63+
64+
private canSectionBeVisible(activeUser: User): boolean {
65+
const { roles } = activeUser;
66+
const hasRole = this.appHasRole();
67+
const isSuperAdmin = this.appHasRoleSuperAdmin();
68+
69+
if (Array.isArray(hasRole) && hasRole.length > 0) {
70+
return hasRole.some((rolName: string) => roles.includes(rolName as Role));
71+
}
72+
73+
if (typeof hasRole === 'string') {
74+
return roles.includes(hasRole as Role);
75+
}
76+
77+
return activeUser.isAdmin === !!isSuperAdmin;
78+
}
79+
}

0 commit comments

Comments
 (0)