mirror of
https://github.com/Raghu-Ch/angular-challenges.git
synced 2026-02-11 05:13:02 -05:00
feat(doc): move permissions
This commit is contained in:
11
apps/angular/permissions/src/app/app.component.ts
Normal file
11
apps/angular/permissions/src/app/app.component.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
imports: [RouterOutlet],
|
||||
selector: 'app-root',
|
||||
template: ` <router-outlet></router-outlet> `,
|
||||
styles: [],
|
||||
})
|
||||
export class AppComponent {}
|
||||
6
apps/angular/permissions/src/app/app.config.ts
Normal file
6
apps/angular/permissions/src/app/app.config.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { ApplicationConfig } from '@angular/core';
|
||||
import { provideRouter } from '@angular/router';
|
||||
import { APP_ROUTES } from './routes';
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [provideRouter(APP_ROUTES)],
|
||||
};
|
||||
13
apps/angular/permissions/src/app/button.component.ts
Normal file
13
apps/angular/permissions/src/app/button.component.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'button[app-button]',
|
||||
template: `<ng-content></ng-content>`,
|
||||
host: {
|
||||
class: 'border border-blue-700 bg-blue-400 p-2 rounded-sm text-white',
|
||||
},
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ButtonComponent {}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { RouterLink } from '@angular/router';
|
||||
import { ButtonComponent } from '../button.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dashboard',
|
||||
standalone: true,
|
||||
imports: [RouterLink, ButtonComponent],
|
||||
template: `
|
||||
<p>dashboard for Admin works!</p>
|
||||
<button app-button routerLink="/">Logout</button>
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class AdminDashboardComponent {}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { RouterLink } from '@angular/router';
|
||||
import { ButtonComponent } from '../button.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dashboard',
|
||||
standalone: true,
|
||||
imports: [RouterLink, ButtonComponent],
|
||||
template: `
|
||||
<p>dashboard for Manager works!</p>
|
||||
<button app-button routerLink="/">Logout</button>
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ManagerDashboardComponent {}
|
||||
68
apps/angular/permissions/src/app/has-role.directive.ts
Normal file
68
apps/angular/permissions/src/app/has-role.directive.ts
Normal file
@@ -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<NgIfContext> | null;
|
||||
|
||||
constructor(
|
||||
private templateRef: TemplateRef<unknown>,
|
||||
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);
|
||||
}
|
||||
}
|
||||
24
apps/angular/permissions/src/app/information.component.ts
Normal file
24
apps/angular/permissions/src/app/information.component.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { UserStore } from './user.store';
|
||||
|
||||
@Component({
|
||||
selector: 'app-information',
|
||||
standalone: true,
|
||||
imports: [CommonModule],
|
||||
template: `
|
||||
<h2 class="mt-10 text-xl">Information Panel</h2>
|
||||
<!-- admin can see everything -->
|
||||
<div>visible only for super admin</div>
|
||||
<div>visible if manager</div>
|
||||
<div>visible if manager and/or reader</div>
|
||||
<div>visible if manager and/or writer</div>
|
||||
<div>visible if client</div>
|
||||
<div>visible for everyone</div>
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class InformationComponent {
|
||||
user$ = this.userStore.user$;
|
||||
constructor(private userStore: UserStore) {}
|
||||
}
|
||||
63
apps/angular/permissions/src/app/login.component.ts
Normal file
63
apps/angular/permissions/src/app/login.component.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { RouterLink } from '@angular/router';
|
||||
import { ButtonComponent } from './button.component';
|
||||
import { InformationComponent } from './information.component';
|
||||
import {
|
||||
admin,
|
||||
client,
|
||||
everyone,
|
||||
manager,
|
||||
reader,
|
||||
readerAndWriter,
|
||||
writer,
|
||||
} from './user.model';
|
||||
import { UserStore } from './user.store';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
imports: [InformationComponent, RouterLink, ButtonComponent],
|
||||
selector: 'app-login',
|
||||
template: `
|
||||
<header class="flex gap-3 items-center">
|
||||
Log as :
|
||||
<button app-button (click)="admin()">Admin</button>
|
||||
<button app-button (click)="manager()">Manager</button>
|
||||
<button app-button (click)="reader()">Reader</button>
|
||||
<button app-button (click)="writer()">Writer</button>
|
||||
<button app-button (click)="readerWriter()">Reader and Writer</button>
|
||||
<button app-button (click)="client()">Client</button>
|
||||
<button app-button (click)="everyone()">Client</button>
|
||||
</header>
|
||||
|
||||
<app-information></app-information>
|
||||
|
||||
<button app-button class=" mt-10" routerLink="enter">
|
||||
Enter application
|
||||
</button>
|
||||
`,
|
||||
})
|
||||
export class LoginComponent {
|
||||
constructor(private userStore: UserStore) {}
|
||||
|
||||
admin() {
|
||||
this.userStore.add(admin);
|
||||
}
|
||||
manager() {
|
||||
this.userStore.add(manager);
|
||||
}
|
||||
reader() {
|
||||
this.userStore.add(reader);
|
||||
}
|
||||
writer() {
|
||||
this.userStore.add(writer);
|
||||
}
|
||||
readerWriter() {
|
||||
this.userStore.add(readerAndWriter);
|
||||
}
|
||||
client() {
|
||||
this.userStore.add(client);
|
||||
}
|
||||
everyone() {
|
||||
this.userStore.add(everyone);
|
||||
}
|
||||
}
|
||||
14
apps/angular/permissions/src/app/routes.ts
Normal file
14
apps/angular/permissions/src/app/routes.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
export const APP_ROUTES = [
|
||||
{
|
||||
path: '',
|
||||
loadComponent: () =>
|
||||
import('./login.component').then((m) => m.LoginComponent),
|
||||
},
|
||||
{
|
||||
path: 'enter',
|
||||
loadComponent: () =>
|
||||
import('./dashboard/admin.component').then(
|
||||
(m) => m.AdminDashboardComponent
|
||||
),
|
||||
},
|
||||
];
|
||||
49
apps/angular/permissions/src/app/user.model.ts
Normal file
49
apps/angular/permissions/src/app/user.model.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
export type Role = 'MANAGER' | 'WRITER' | 'READER' | 'CLIENT';
|
||||
|
||||
export interface User {
|
||||
name: string;
|
||||
isAdmin: boolean;
|
||||
roles: Role[];
|
||||
}
|
||||
|
||||
export const admin: User = {
|
||||
name: 'admin',
|
||||
isAdmin: true,
|
||||
roles: [],
|
||||
};
|
||||
|
||||
export const manager: User = {
|
||||
name: 'manager',
|
||||
isAdmin: false,
|
||||
roles: ['MANAGER'],
|
||||
};
|
||||
|
||||
export const writer: User = {
|
||||
name: 'writer',
|
||||
isAdmin: false,
|
||||
roles: ['WRITER'],
|
||||
};
|
||||
|
||||
export const reader: User = {
|
||||
name: 'reader',
|
||||
isAdmin: false,
|
||||
roles: ['READER'],
|
||||
};
|
||||
|
||||
export const readerAndWriter: User = {
|
||||
name: 'reader',
|
||||
isAdmin: false,
|
||||
roles: ['READER', 'WRITER'],
|
||||
};
|
||||
|
||||
export const client: User = {
|
||||
name: 'client',
|
||||
isAdmin: false,
|
||||
roles: ['CLIENT'],
|
||||
};
|
||||
|
||||
export const everyone: User = {
|
||||
name: 'client',
|
||||
isAdmin: false,
|
||||
roles: [],
|
||||
};
|
||||
15
apps/angular/permissions/src/app/user.store.ts
Normal file
15
apps/angular/permissions/src/app/user.store.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { User } from './user.model';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class UserStore {
|
||||
private user = new BehaviorSubject<User | undefined>(undefined);
|
||||
user$ = this.user.asObservable();
|
||||
|
||||
add(user: User) {
|
||||
this.user.next(user);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user