diff --git a/docs/en/Tutorials/Part-5.md b/docs/en/Tutorials/Part-5.md index bba99f21df..29374419cb 100644 --- a/docs/en/Tutorials/Part-5.md +++ b/docs/en/Tutorials/Part-5.md @@ -423,13 +423,13 @@ Open the `/src/app/book/book.component.html` file and replace the create button ````html - ```` -* Just added `abpPermission="BookStore.Books.Create"` that hides the button if the current user has no permission. +* Just added `*abpPermission="'BookStore.Books.Create'"` that hides the button if the current user has no permission. ### Hide the Edit and Delete Actions @@ -443,18 +443,18 @@ Open the `/src/app/book/book.component.html` file and replace the edit and delet ````html - - ```` -* Added `abpPermission="BookStore.Books.Edit"` that hides the edit action if the current user has no editing permission. -* Added `abpPermission="BookStore.Books.Delete"` that hides the delete action if the current user has no delete permission. +* Added `*abpPermission="'BookStore.Books.Edit'"` that hides the edit action if the current user has no editing permission. +* Added `*abpPermission="'BookStore.Books.Delete'"` that hides the delete action if the current user has no delete permission. {{else if UI == "Blazor"}} diff --git a/docs/en/UI/Angular/Permission-Management.md b/docs/en/UI/Angular/Permission-Management.md index 1b9d061930..b8125bb2a3 100644 --- a/docs/en/UI/Angular/Permission-Management.md +++ b/docs/en/UI/Angular/Permission-Management.md @@ -54,8 +54,6 @@ You can use the `PermissionDirective` to manage visibility of a DOM Element acco As shown above you can remove elements from DOM with `abpPermission` structural directive. -The directive can also be used as an attribute directive but we recommend to you to use it as a structural directive. - ## Permission Guard You can use `PermissionGuard` if you want to control authenticated user's permission to access to the route during navigation. diff --git a/npm/ng-packs/angular.json b/npm/ng-packs/angular.json index 816cda988c..8aed0992b2 100644 --- a/npm/ng-packs/angular.json +++ b/npm/ng-packs/angular.json @@ -378,7 +378,6 @@ "polyfills": "apps/dev-app/src/polyfills.ts", "tsConfig": "apps/dev-app/tsconfig.dev.json", "aot": true, - "extractCss": true, "allowedCommonJsDependencies": ["chart.js", "js-sha256"], "assets": ["apps/dev-app/src/favicon.ico", "apps/dev-app/src/assets"], "styles": [ @@ -433,7 +432,6 @@ "optimization": true, "outputHashing": "all", "sourceMap": false, - "extractCss": true, "namedChunks": false, "extractLicenses": true, "vendorChunk": false, diff --git a/npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts b/npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts index c24cd9b2d1..2e16cc0f2f 100644 --- a/npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts +++ b/npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts @@ -1,59 +1,64 @@ import { + ChangeDetectorRef, Directive, ElementRef, Input, OnChanges, OnDestroy, - OnInit, Optional, Renderer2, - SimpleChanges, TemplateRef, ViewContainerRef, } from '@angular/core'; import { Subscription } from 'rxjs'; +import { distinctUntilChanged } from 'rxjs/operators'; import { PermissionService } from '../services/permission.service'; @Directive({ selector: '[abpPermission]', }) -export class PermissionDirective implements OnInit, OnDestroy, OnChanges { +export class PermissionDirective implements OnDestroy, OnChanges { @Input('abpPermission') condition: string; subscription: Subscription; constructor( - private elRef: ElementRef, + private elRef: ElementRef, private renderer: Renderer2, @Optional() private templateRef: TemplateRef, private vcRef: ViewContainerRef, private permissionService: PermissionService, + private cdRef: ChangeDetectorRef, ) {} private check() { if (this.subscription) { this.subscription.unsubscribe(); } + this.subscription = this.permissionService .getGrantedPolicy$(this.condition) + .pipe(distinctUntilChanged()) .subscribe(isGranted => { - if (this.templateRef && isGranted) { - this.vcRef.clear(); - this.vcRef.createEmbeddedView(this.templateRef); - } else if (this.templateRef && !isGranted) { - this.vcRef.clear(); - } else if (!isGranted && !this.templateRef) { - this.renderer.removeChild( - (this.elRef.nativeElement as HTMLElement).parentElement, - this.elRef.nativeElement, - ); - } + if (this.templateRef) this.initStructural(isGranted); + else this.initAttribute(isGranted); + + this.cdRef.detectChanges(); }); } - ngOnInit() { - if (this.templateRef && !this.condition) { - this.vcRef.createEmbeddedView(this.templateRef); + private initStructural(isGranted: boolean) { + this.vcRef.clear(); + + if (isGranted) this.vcRef.createEmbeddedView(this.templateRef); + } + + /** + * @deprecated Will be deleted in v5.0 + */ + private initAttribute(isGranted: boolean) { + if (!isGranted) { + this.renderer.removeChild(this.elRef.nativeElement.parentElement, this.elRef.nativeElement); } } @@ -61,9 +66,7 @@ export class PermissionDirective implements OnInit, OnDestroy, OnChanges { if (this.subscription) this.subscription.unsubscribe(); } - ngOnChanges({ condition }: SimpleChanges) { - if ((condition || { currentValue: null }).currentValue) { - this.check(); - } + ngOnChanges() { + this.check(); } } diff --git a/npm/ng-packs/packages/core/src/lib/services/config-state.service.ts b/npm/ng-packs/packages/core/src/lib/services/config-state.service.ts index ed544fec2b..b6d61cec23 100644 --- a/npm/ng-packs/packages/core/src/lib/services/config-state.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/config-state.service.ts @@ -15,7 +15,7 @@ export class ConfigStateService { } setState = (state: ApplicationConfiguration.Response) => { - this.store.patch(state); + this.store.set(state); }; getOne$(key: string) { diff --git a/npm/ng-packs/packages/core/src/lib/services/environment.service.ts b/npm/ng-packs/packages/core/src/lib/services/environment.service.ts index 5cf975ae5f..2062294b7b 100644 --- a/npm/ng-packs/packages/core/src/lib/services/environment.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/environment.service.ts @@ -31,6 +31,6 @@ export class EnvironmentService { } setState(environment: Environment) { - this.store.patch(environment); + this.store.set(environment); } } diff --git a/npm/ng-packs/packages/core/src/lib/services/permission.service.ts b/npm/ng-packs/packages/core/src/lib/services/permission.service.ts index eb06fad098..deb474fa08 100644 --- a/npm/ng-packs/packages/core/src/lib/services/permission.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/permission.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { map } from 'rxjs/operators'; +import { map, tap } from 'rxjs/operators'; import snq from 'snq'; import { ApplicationConfiguration } from '../models/application-configuration'; import { ConfigStateService } from './config-state.service'; @@ -9,7 +9,9 @@ export class PermissionService { constructor(private configState: ConfigStateService) {} getGrantedPolicy$(key: string) { - return this.getStream().pipe(map(policies => this.isPolicyGranted(key, policies))); + return this.getStream().pipe( + map(grantedPolicies => this.isPolicyGranted(key, grantedPolicies)), + ); } getGrantedPolicy(key: string) { @@ -17,7 +19,7 @@ export class PermissionService { return this.isPolicyGranted(key, policies); } - private isPolicyGranted(key: string, policies: ApplicationConfiguration.Policy) { + private isPolicyGranted(key: string, grantedPolicies: ApplicationConfiguration.Policy) { if (!key) return true; const orRegexp = /\|\|/g; @@ -29,16 +31,16 @@ export class PermissionService { if (keys.length < 2) return false; - return keys.some(k => this.getPolicy(k.trim(), policies)); + return keys.some(k => this.getPolicy(k.trim(), grantedPolicies)); } else if (andRegexp.test(key)) { const keys = key.split('&&').filter(Boolean); if (keys.length < 2) return false; - return keys.every(k => this.getPolicy(k.trim(), policies)); + return keys.every(k => this.getPolicy(k.trim(), grantedPolicies)); } - return this.getPolicy(key, policies); + return this.getPolicy(key, grantedPolicies); } private getStream() { @@ -53,7 +55,7 @@ export class PermissionService { return snq(() => applicationConfiguration.auth.grantedPolicies); } - private getPolicy(policy: string, policies: ApplicationConfiguration.Policy) { - return snq(() => policies[policy], false); + private getPolicy(key: string, grantedPolicies: ApplicationConfiguration.Policy) { + return snq(() => grantedPolicies[key], false); } } diff --git a/npm/ng-packs/packages/core/src/lib/utils/internal-store-utils.ts b/npm/ng-packs/packages/core/src/lib/utils/internal-store-utils.ts index 7a481121ee..fbf707c284 100644 --- a/npm/ng-packs/packages/core/src/lib/utils/internal-store-utils.ts +++ b/npm/ng-packs/packages/core/src/lib/utils/internal-store-utils.ts @@ -30,6 +30,11 @@ export class InternalStore { this.update$.next(state); } + set(state: State) { + this.state$.next(state); + this.update$.next(state); + } + reset() { this.patch(this.initialState); } diff --git a/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html b/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html index 85986e20bb..1a49d9cbd6 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html +++ b/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html @@ -51,14 +51,15 @@ > {{ 'AbpIdentity::Permissions' | abpLocalization }} - + + + diff --git a/npm/ng-packs/packages/setting-management/src/lib/components/setting-management.component.html b/npm/ng-packs/packages/setting-management/src/lib/components/setting-management.component.html index c54a581312..345f818890 100644 --- a/npm/ng-packs/packages/setting-management/src/lib/components/setting-management.component.html +++ b/npm/ng-packs/packages/setting-management/src/lib/components/setting-management.component.html @@ -16,20 +16,21 @@
diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/nav-items.component.html b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/nav-items.component.html index d01e6cda38..d781ad90b2 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/nav-items.component.html +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/nav-items.component.html @@ -1,18 +1,16 @@ diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/routes/routes.component.html b/npm/ng-packs/packages/theme-basic/src/lib/components/routes/routes.component.html index cf27990b4e..0e2f67156c 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/routes/routes.component.html +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/routes/routes.component.html @@ -16,37 +16,40 @@ -
- + + + + @@ -74,7 +77,7 @@ #dropdownSubmenu="ngbDropdown" placement="right-top" [autoClose]="true" - [abpPermission]="child.requiredPolicy" + *abpPermission="child.requiredPolicy" >
+
- + @@ -28,11 +24,13 @@ [sortable]="prop.sortable" > - +
diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/grid-actions/grid-actions.component.html b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/grid-actions/grid-actions.component.html index fdf6c19e8b..6172cacd20 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/grid-actions/grid-actions.component.html +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/grid-actions/grid-actions.component.html @@ -24,19 +24,20 @@ >
- + + + diff --git a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/page-toolbar/page-toolbar.component.html b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/page-toolbar/page-toolbar.component.html index 8f97f6aa64..aa1f1703c5 100644 --- a/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/page-toolbar/page-toolbar.component.html +++ b/npm/ng-packs/packages/theme-shared/extensions/src/lib/components/page-toolbar/page-toolbar.component.html @@ -1,18 +1,20 @@
- - - - + + + + + - - - + + + +