diff --git a/docs/en/release-info/migration-guides/abp-8-2.md b/docs/en/release-info/migration-guides/abp-8-2.md index 0a70af9796..cd904f052e 100644 --- a/docs/en/release-info/migration-guides/abp-8-2.md +++ b/docs/en/release-info/migration-guides/abp-8-2.md @@ -51,8 +51,13 @@ If the flag icon has been specified while defining the localization languages, t In this version, ABP Framework provides a new UI option called **Blazor Full-Stack WebApp**. We have already created an introduction/migration guide for you to check it: [Migrating to Blazor Web App](abp-8-2-blazor-web-app.md) > Please read the documentation carefully if you are considering migrating your existing **Blazor** project to **Blazor WebApp**. + +## Angular UI + +In this version, the Angular UI has been updated to use the Angular version 17.3.0 and Nx version to 19.0.0. See the PR for more information: [#19915](https://github.com/abpframework/abp/pull/19915/) + ## Session Management Infrastructure The **Session Management** feature allows you to prevent concurrent login and manage user sessions. -In this version, a new entity called `IdentitySession` has been added to the framework and you should create a new migration and apply it to your database. +In this version, a new entity called `IdentitySession` has been added to the framework and you should create a new migration and apply it to your database. \ No newline at end of file diff --git a/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts b/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts index 8503a2bd81..8ad2fd2320 100644 --- a/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts +++ b/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts @@ -171,58 +171,74 @@ export class PermissionManagementComponent } onClickCheckbox(clickedPermission: PermissionGrantInfoDto) { - if ( - clickedPermission.isGranted && - this.isGrantedByOtherProviderName(clickedPermission.grantedProviders) - ) + const { isGranted, grantedProviders } = clickedPermission; + if (isGranted && this.isGrantedByOtherProviderName(grantedProviders)) { return; + } + this.setSelectedGroup(this.selectedGroup); setTimeout(() => { - this.permissions = this.permissions.map(per => { - if (clickedPermission.name === per.name) { - return { ...per, isGranted: !per.isGranted }; - } else if (clickedPermission.name === per.parentName && clickedPermission.isGranted) { - return { ...per, isGranted: false }; - } else if (clickedPermission.parentName === per.name && !clickedPermission.isGranted) { - return { ...per, isGranted: true }; - } - return per; - }); + this.updatePermissionStatus(clickedPermission); this.updateSelectedGroupPermissions(clickedPermission); + this.setParentClicked(clickedPermission); this.setTabCheckboxState(); this.setGrantCheckboxState(); - this.setParentClicked(clickedPermission); }, 0); } - setParentClicked(clickedPermissions: PermissionGrantInfoDto) { - let childPermissionGrantedCount = 0; - let parentPermission: PermissionGrantInfoDto; + updatePermissionStatus(clickedPermission: PermissionGrantInfoDto) { + this.permissions = this.permissions.map(permission => { + const isExactMatch = clickedPermission.name == permission.name; + const isParentOfPermission = clickedPermission.parentName === permission.name; + const isChildOfPermission = clickedPermission.name === permission.parentName; + + if (isExactMatch) { + return { ...permission, isGranted: !permission.isGranted }; + } + + if (isChildOfPermission && permission.isGranted) { + return { ...permission, isGranted: false }; + } + + if (isParentOfPermission && !permission.isGranted) { + return { ...permission, isGranted: true }; + } + + return permission; + }); + } + + setParentClicked(clickedPermission: PermissionGrantInfoDto) { + if (clickedPermission.parentName) { + const parentPermissions = findParentPermissions(this.permissions, clickedPermission); + if (parentPermissions.length > 0) { + const parentNames = new Set(parentPermissions.map(parent => parent.name)); - if (clickedPermissions.parentName) { - this.permissions.forEach(per => { - if (per.name === clickedPermissions.parentName) { - parentPermission = per; - } - }); - this.permissions.forEach(per => { - if (parentPermission.name === per.parentName) { - per.isGranted && childPermissionGrantedCount++; - } - }); - if (childPermissionGrantedCount === 1 && !parentPermission.isGranted) { this.permissions = this.permissions.map(per => { - if (per.name === parentPermission.name) { - per.isGranted = true; + let updatedIsGranted = per.isGranted; + + if (per.parentName === clickedPermission.name && !clickedPermission.isGranted) { + updatedIsGranted = false; + } + + if (parentNames.has(per.name)) { + updatedIsGranted = true; } - return per; + + return { ...per, isGranted: updatedIsGranted }; }); } return; } + this.permissions = this.permissions.map(per => { - if (per.parentName === clickedPermissions.name) { - per.isGranted = false; + const parents = findParentPermissions(this.permissions, per); + if (parents.length > 0) { + const rootParent = parents[parents.length - 1]; + + if (rootParent.name === clickedPermission.name && !rootParent.isGranted) { + return { ...per, isGranted: false }; + } } return per; }); @@ -238,13 +254,13 @@ export class PermissionManagementComponent } setTabCheckboxState() { - const selectableGroupPermissions = this.selectedGroupPermissions.filter(per => + const selectablePermissions = this.permissions.filter(per => per.grantedProviders.every(p => p.providerName === this.providerName), ); - const selectedPermissions = selectableGroupPermissions.filter(per => per.isGranted); + const selectedPermissions = selectablePermissions.filter(per => per.isGranted); const element = document.querySelector('#select-all-in-this-tabs') as any; - if (selectedPermissions.length === selectableGroupPermissions.length) { + if (selectedPermissions.length === selectablePermissions.length) { element.indeterminate = false; this.selectThisTab = true; } else if (selectedPermissions.length === 0) { @@ -387,6 +403,26 @@ export class PermissionManagementComponent } } +function findParentPermissions( + permissions: PermissionGrantInfoDto[], + permission: PermissionGrantInfoDto, +): PermissionGrantInfoDto[] { + const permissionMap = new Map(permissions.map(p => [p.name, p])); + let currentPermission = permissionMap.get(permission.name) ?? null; + const parentPermissions: PermissionGrantInfoDto[] = []; + + while (currentPermission && currentPermission.parentName) { + const parentPermission = permissionMap.get(currentPermission.parentName); + if (!parentPermission) { + break; + } + parentPermissions.push(parentPermission); + currentPermission = parentPermission; + } + + return parentPermissions; +} + function findMargin( permissions: PermissionGrantInfoDto[], permission: PermissionGrantInfoDto,