Skip to content

Commit

Permalink
refactor: update auth directives to use signals
Browse files Browse the repository at this point in the history
  • Loading branch information
jrassa committed May 9, 2024
1 parent 4c64400 commit 6db6b70
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 135 deletions.
43 changes: 11 additions & 32 deletions src/app/core/auth/directives/has-every-role.directive.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { NgIf } from '@angular/common';
import { DestroyRef, Directive, Input, inject } from '@angular/core';
import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
import { Directive, effect, inject, input } from '@angular/core';

import { APP_SESSION } from '../../tokens';
import { Role } from '../role.model';
Expand All @@ -16,42 +15,22 @@ import { Role } from '../role.model';
standalone: true
})
export class HasEveryRoleDirective {
roles: Array<string | Role>;
andCondition = true;
orCondition = false;

private destroyRef = inject(DestroyRef);
private ngIfDirective = inject(NgIf);
#ngIfDirective = inject(NgIf);
#session = inject(APP_SESSION);

@Input({ required: true })
set hasEveryRole(roles: Array<string | Role>) {
this.roles = roles;
this.updateNgIf();
}

@Input()
set hasEveryRoleAnd(condition: boolean) {
this.andCondition = condition;
this.updateNgIf();
}

@Input()
set hasEveryRoleOr(condition: boolean) {
this.orCondition = condition;
this.updateNgIf();
}
roles = input.required<Array<string | Role>>({ alias: 'hasEveryRole' });
andCondition = input(true, { alias: 'hasEveryRoleAnd' });
orCondition = input(false, { alias: 'hasEveryRoleOr' });

constructor() {
toObservable(this.#session)
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(() => {
this.updateNgIf();
});
effect(() => {
this.updateNgIf();
});
}

private updateNgIf() {
this.ngIfDirective.ngIf =
this.orCondition || (this.andCondition && this.#session().hasEveryRole(this.roles));
this.#ngIfDirective.ngIf =
this.orCondition() ||
(this.andCondition() && this.#session().hasEveryRole(this.roles()));
}
}
42 changes: 10 additions & 32 deletions src/app/core/auth/directives/has-role.directive.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { NgIf } from '@angular/common';
import { DestroyRef, Directive, Input, inject } from '@angular/core';
import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
import { Directive, effect, inject, input } from '@angular/core';

import { APP_SESSION } from '../../tokens';
import { Role } from '../role.model';
Expand All @@ -16,42 +15,21 @@ import { Role } from '../role.model';
standalone: true
})
export class HasRoleDirective {
role: string | Role;
andCondition = true;
orCondition = false;

private destroyRef = inject(DestroyRef);
private ngIfDirective = inject(NgIf);
#ngIfDirective = inject(NgIf);
#session = inject(APP_SESSION);

@Input({ required: true })
set hasRole(role: string | Role) {
this.role = role;
this.updateNgIf();
}

@Input()
set hasRoleAnd(condition: boolean) {
this.andCondition = condition;
this.updateNgIf();
}

@Input()
set hasRoleOr(condition: boolean) {
this.orCondition = condition;
this.updateNgIf();
}
role = input.required<string | Role>({ alias: 'hasRole' });
andCondition = input(true, { alias: 'hasRoleAnd' });
orCondition = input(false, { alias: 'hasRoleOr' });

constructor() {
toObservable(this.#session)
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(() => {
this.updateNgIf();
});
effect(() => {
this.updateNgIf();
});
}

private updateNgIf() {
this.ngIfDirective.ngIf =
this.orCondition || (this.andCondition && this.#session().hasRole(this.role));
this.#ngIfDirective.ngIf =
this.orCondition() || (this.andCondition() && this.#session().hasRole(this.role()));
}
}
42 changes: 11 additions & 31 deletions src/app/core/auth/directives/has-some-roles.directive.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NgIf } from '@angular/common';
import { DestroyRef, Directive, Input, inject } from '@angular/core';
import { DestroyRef, Directive, Input, effect, inject, input } from '@angular/core';

Check warning on line 2 in src/app/core/auth/directives/has-some-roles.directive.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

'DestroyRef' is defined but never used

Check warning on line 2 in src/app/core/auth/directives/has-some-roles.directive.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

'Input' is defined but never used

Check warning on line 2 in src/app/core/auth/directives/has-some-roles.directive.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

'DestroyRef' is defined but never used

Check warning on line 2 in src/app/core/auth/directives/has-some-roles.directive.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

'Input' is defined but never used
import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';

Check warning on line 3 in src/app/core/auth/directives/has-some-roles.directive.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

'takeUntilDestroyed' is defined but never used

Check warning on line 3 in src/app/core/auth/directives/has-some-roles.directive.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

'toObservable' is defined but never used

Check warning on line 3 in src/app/core/auth/directives/has-some-roles.directive.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

'takeUntilDestroyed' is defined but never used

Check warning on line 3 in src/app/core/auth/directives/has-some-roles.directive.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

'toObservable' is defined but never used

import { APP_SESSION } from '../../tokens';
Expand All @@ -16,42 +16,22 @@ import { Role } from '../role.model';
standalone: true
})
export class HasSomeRolesDirective {
roles: Array<string | Role>;
andCondition = true;
orCondition = false;

private destroyRef = inject(DestroyRef);
private ngIfDirective = inject(NgIf);
#ngIfDirective = inject(NgIf);
#session = inject(APP_SESSION);

@Input({ required: true })
set hasSomeRoles(roles: Array<string | Role>) {
this.roles = roles;
this.updateNgIf();
}

@Input()
set hasSomeRolesAnd(condition: boolean) {
this.andCondition = condition;
this.updateNgIf();
}

@Input()
set hasSomeRolesOr(condition: boolean) {
this.orCondition = condition;
this.updateNgIf();
}
roles = input.required<Array<string | Role>>({ alias: 'hasSomeRoles' });
andCondition = input(true, { alias: 'hasSomeRolesAnd' });
orCondition = input(false, { alias: 'hasSomeRolesOr' });

constructor() {
toObservable(this.#session)
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(() => {
this.updateNgIf();
});
effect(() => {
this.updateNgIf();
});
}

private updateNgIf() {
this.ngIfDirective.ngIf =
this.orCondition || (this.andCondition && this.#session().hasSomeRoles(this.roles));
this.#ngIfDirective.ngIf =
this.orCondition() ||
(this.andCondition() && this.#session().hasSomeRoles(this.roles()));
}
}
44 changes: 10 additions & 34 deletions src/app/core/auth/directives/is-authenticated.directive.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';
import { NgIf } from '@angular/common';
import { DestroyRef, Directive, Input, inject } from '@angular/core';
import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
import { Directive, booleanAttribute, effect, inject, input } from '@angular/core';

import { APP_SESSION } from '../../tokens';

Expand All @@ -16,42 +14,20 @@ import { APP_SESSION } from '../../tokens';
standalone: true
})
export class IsAuthenticatedDirective {
private _isAuthenticated = true;
andCondition = true;
orCondition = false;

private destroyRef = inject(DestroyRef);
private ngIfDirective = inject(NgIf);
#ngIfDirective = inject(NgIf);
#session = inject(APP_SESSION);

@Input()
set isAuthenticated(isAuthenticated: BooleanInput) {
this._isAuthenticated = coerceBooleanProperty(isAuthenticated);
this.updateNgIf();
}

@Input()
set isAuthenticatedAnd(condition: boolean) {
this.andCondition = condition;
this.updateNgIf();
}

@Input()
set isAuthenticatedOr(condition: boolean) {
this.orCondition = condition;
this.updateNgIf();
}
isAuthenticated = input(true, { transform: booleanAttribute });
andCondition = input(true, { alias: 'isAuthenticatedAnd' });
orCondition = input(false, { alias: 'isAuthenticatedOr' });

constructor() {
toObservable(this.#session)
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(() => {
this.updateNgIf();
});
effect(() => {
this.updateNgIf();
});
}

private updateNgIf() {
this.ngIfDirective.ngIf =
this.orCondition || (this.andCondition && this.#session().isAuthenticated());
this.#ngIfDirective.ngIf =
this.orCondition() || (this.andCondition() && this.#session().isAuthenticated());
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DestroyRef, Directive, OnInit, SimpleChange, inject } from '@angular/core';
import { Directive, OnInit, SimpleChange, inject } from '@angular/core';

import { NgSelectComponent } from '@ng-select/ng-select';

Expand All @@ -9,17 +9,16 @@ import { APP_SESSION } from '../../tokens';
standalone: true
})
export class UserExternalRolesSelectDirective implements OnInit {
private destroyRef = inject(DestroyRef);
private select = inject(NgSelectComponent);
#select = inject(NgSelectComponent);
#session = inject(APP_SESSION);

ngOnInit() {
const externalRoles = this.#session().user?.externalRoles ?? [];

const change = new SimpleChange(this.select.items, externalRoles, false);
this.select.items = externalRoles;
const change = new SimpleChange(this.#select.items, externalRoles, false);
this.#select.items = externalRoles;
// change detection doesn't work properly when setting input programmatically
// tslint:disable-next-line:no-lifecycle-call
this.select.ngOnChanges({ items: change });
this.#select.ngOnChanges({ items: change });
}
}

0 comments on commit 6db6b70

Please sign in to comment.