diff --git a/Directory.Packages.props b/Directory.Packages.props index c860d010c0..7a0067896d 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -111,10 +111,10 @@ - - - - + + + + @@ -126,11 +126,11 @@ - - - - - + + + + + diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json index d53323c3a2..2a9c936794 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json @@ -688,6 +688,8 @@ "Permission:UserCleanUp": "User Clean Up", "AllowPrivateQuestion": "Allow Private Question", "Permission:Campaigns": "Campaigns", - "Permission:Licenses": "License Settings" + "Permission:Licenses": "License Settings", + "BlockUserPolicy": "Block User Policy", + "Permission:BlockUserPolicy": "Block User Policy" } } diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json index 4890226d9a..31f6186258 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json @@ -252,6 +252,7 @@ "DoYouAgreePrivacyPolicy": "By clicking Subscribe button you agree to the Terms & Conditions and Privacy Policy.", "AbpConferenceDescription": "ABP Conference is a virtual event for .NET developers to learn and connect with the community.", "Mobile": "Mobile", - "MetaTwitterCard": "summary_large_image" + "MetaTwitterCard": "summary_large_image", + "IPAddress": "IP Address" } } \ No newline at end of file diff --git a/docs/en/cli/index.md b/docs/en/cli/index.md index e9b4e5c42a..940c8acccd 100644 --- a/docs/en/cli/index.md +++ b/docs/en/cli/index.md @@ -44,7 +44,7 @@ Here, is the list of all available commands before explaining their details: * **`add-package-ref`**: Adds package to given project. * **`install-module`**: Adds a [multi-package application module](../modules/index.md) to a given module. * **`install-local-module`**: Installs a local module to given module. -* **`list-modules`**: Lists names of open-source application modules. +* **`list-modules`**: Lists names of application modules. * **`list-templates`**: Lists the names of available templates to create a solution. * **`get-source`**: Downloads the source code of a module. * **`add-source-code`**: Downloads the source code and replaces package references with project references. diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 87b3d56e88..03640f506c 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -130,7 +130,7 @@ { "text": "Book Store Application (with ABP Suite)", "isLazyExpandable": true, - "path": "tutorials/book-store-with-abp-suite/index.md", + "path": "tutorials/book-store-with-abp-suite", "items": [ { "text": "Overview", @@ -162,11 +162,11 @@ { "text": "Modular Monolith Application", "isLazyExpandable": true, - "path": "tutorials/modular-crm/index.md", + "path": "tutorials/modular-crm", "items": [ { "text": "Overview", - "path": "tutorials/modular-crm/index.md", + "path": "tutorials/modular-crm", "isIndex": true }, { @@ -206,11 +206,11 @@ { "text": "Microservice Solution", "isLazyExpandable": true, - "path": "tutorials/microservice/index.md", + "path": "tutorials/microservice", "items": [ { "text": "Overview", - "path": "tutorials/microservice/index.md", + "path": "tutorials/microservice", "isIndex": true }, { @@ -246,19 +246,19 @@ { "text": "Mobile Application Development", "isLazyExpandable": true, - "path": "tutorials/mobile/index.md", + "path": "tutorials/mobile", "items": [ { "text": "Overview", - "path": "tutorials/mobile/index.md" + "path": "tutorials/mobile" }, { "text": "MAUI", - "path": "tutorials/mobile/maui/index.md" + "path": "tutorials/mobile/maui" }, { "text": "React Native", - "path": "tutorials/mobile/react-native/index.md" + "path": "tutorials/mobile/react-native" } ] }, @@ -2689,7 +2689,7 @@ }, { "text": "Knowledge Base", - "path": "kb/index.md" + "path": "kb" }, { "text": "Penetration Test Report", diff --git a/docs/en/release-info/migration-guides/abp-9-0.md b/docs/en/release-info/migration-guides/abp-9-0.md index 5158b1722d..d211c9db55 100644 --- a/docs/en/release-info/migration-guides/abp-9-0.md +++ b/docs/en/release-info/migration-guides/abp-9-0.md @@ -2,7 +2,7 @@ This document is a guide for upgrading ABP v8.x solutions to ABP v9.0. There are some changes in this version that may affect your applications, please read it carefully and apply the necessary changes to your application. -> ABP upgraded to .NET 9.0, so you need to move your solutions to .NET 9.0 if you want to use the ABP 9.0. You can check the [Migrate from ASP.NET Core 8.0 to 9.0](https://learn.microsoft.com/en-us/aspnet/core/migration/80-90) documentation. +> ABP has upgraded to .NET 9.0, so if you plan to use ABP 9.0, you’ll need to migrate your solutions to .NET 9.0. You can refer to the [Migrate from ASP.NET Core 8.0 to 9.0](https://learn.microsoft.com/en-us/aspnet/core/migration/80-90) documentation for guidance. However, ABP’s NuGet packages are compatible with both .NET 8 and .NET 9, allowing developers to continue using .NET 8 while still enjoying the latest features and improvements of the ABP Framework without upgrading their SDK. ## Open-Source (Framework) diff --git a/docs/en/release-info/release-notes.md b/docs/en/release-info/release-notes.md index f89e2383d7..f0e91ec4a8 100644 --- a/docs/en/release-info/release-notes.md +++ b/docs/en/release-info/release-notes.md @@ -18,6 +18,8 @@ This is currently a RC (release-candidate) and you can see the detailed **[blog See the detailed **[blog post / announcement](https://abp.io/blog/abp-9-0-stable-release-with-dotnet-9-0)** for the v9.0 release. +> **Note**: ABP has upgraded to .NET 9.0, so if you plan to use ABP 9.0, you’ll need to migrate your solutions to .NET 9.0. You can refer to the [Migrate from ASP.NET Core 8.0 to 9.0](https://learn.microsoft.com/en-us/aspnet/core/migration/80-90) documentation for guidance. However, ABP’s NuGet packages are compatible with both .NET 8 and .NET 9, allowing developers to continue using .NET 8 while still enjoying the latest features and improvements of the ABP Framework without upgrading their SDK. + * Upgraded to .NET 9.0 * Introducing the `Extension Property Policy` * Google Cloud Storage BLOB Provider diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/toast/abp-toast.css b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/toast/abp-toast.css index b6edbb0d6f..9ff4555d0c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/toast/abp-toast.css +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/toast/abp-toast.css @@ -9,9 +9,11 @@ z-index: 1900; right: 30px; bottom: 30px; + pointer-events: none; } .abp-toast { + pointer-events: auto; display: grid; grid-template-columns: 35px 1fr; gap: 5px; diff --git a/latest-versions.json b/latest-versions.json index 7cf305971d..2e5e6b0d81 100644 --- a/latest-versions.json +++ b/latest-versions.json @@ -1,4 +1,13 @@ [ + { + "version": "9.0.5", + "releaseDate": "", + "type": "stable", + "message": "", + "leptonx": { + "version": "4.0.6" + } + }, { "version": "9.0.4", "releaseDate": "", diff --git a/modules/docs/src/Volo.Docs.Web/DocsUiOptions.cs b/modules/docs/src/Volo.Docs.Web/DocsUiOptions.cs index 702536c31d..a6b06768c3 100644 --- a/modules/docs/src/Volo.Docs.Web/DocsUiOptions.cs +++ b/modules/docs/src/Volo.Docs.Web/DocsUiOptions.cs @@ -38,6 +38,31 @@ namespace Volo.Docs public SingleProjectModeOptions SingleProjectMode { get; } = new (); public bool EnableEnlargeImage { get; set; } = true; + + public Func DocumentLinksNormalizer { get; set; } = link => + { + if (!link.EndsWith("/Index", StringComparison.OrdinalIgnoreCase)) + { + return link; + + } + return link.Substring(0, link.LastIndexOf("/Index", StringComparison.OrdinalIgnoreCase)); + }; + + public Func RedirectUrlResolver { get; set; } = url => + { + if (!url.EndsWith("/Index", StringComparison.OrdinalIgnoreCase)) + { + return null; + + } + return url.Substring(0, url.LastIndexOf("/Index", StringComparison.OrdinalIgnoreCase)); + }; + + public string? GetRedirectUrlIfNeeded(string url) + { + return RedirectUrlResolver.Invoke(url); + } private string GetFormattedRoutePrefix() { diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs index d6acd8c262..2bb7c82c21 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs @@ -131,6 +131,12 @@ namespace Volo.Docs.Pages.Documents.Project return Redirect(decodedUrl); } + var redirectUrl = _uiOptions.GetRedirectUrlIfNeeded(displayUrl); + if (redirectUrl != null) + { + return RedirectPermanent(redirectUrl); + } + return await SetPageAsync(); } diff --git a/modules/docs/src/Volo.Docs.Web/Utils/DefaultDocsLinkGenerator.cs b/modules/docs/src/Volo.Docs.Web/Utils/DefaultDocsLinkGenerator.cs index bc91e17848..c3934ec16f 100644 --- a/modules/docs/src/Volo.Docs.Web/Utils/DefaultDocsLinkGenerator.cs +++ b/modules/docs/src/Volo.Docs.Web/Utils/DefaultDocsLinkGenerator.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Net; using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; using Volo.Docs.Pages.Documents.Project; @@ -9,10 +10,13 @@ namespace Volo.Docs.Utils; public class DefaultDocsLinkGenerator : IDocsLinkGenerator, ITransientDependency { protected LinkGenerator LinkGenerator { get; } + + protected IOptions DocsUiOptions { get; } - public DefaultDocsLinkGenerator(LinkGenerator linkGenerator) + public DefaultDocsLinkGenerator(LinkGenerator linkGenerator, IOptions docsUiOptions) { LinkGenerator = linkGenerator; + DocsUiOptions = docsUiOptions; } @@ -26,6 +30,7 @@ public class DefaultDocsLinkGenerator : IDocsLinkGenerator, ITransientDependency }; var encodedUrl = LinkGenerator.GetPathByPage("/Documents/Project/Index", values: routeValues); - return encodedUrl?.Replace("%2F", "/"); //Document name can contain path separator(/), so we need to decode it. + var url = encodedUrl?.Replace("%2F", "/"); //Document name can contain path separator(/), so we need to decode it. + return DocsUiOptions.Value.DocumentLinksNormalizer?.Invoke(url); } } \ No newline at end of file diff --git a/modules/openiddict/app/OpenIddict.Demo.Server/EntityFrameworkCore/ServerDataSeedContributor.cs b/modules/openiddict/app/OpenIddict.Demo.Server/EntityFrameworkCore/ServerDataSeedContributor.cs index 148685c1bd..c67b2977ef 100644 --- a/modules/openiddict/app/OpenIddict.Demo.Server/EntityFrameworkCore/ServerDataSeedContributor.cs +++ b/modules/openiddict/app/OpenIddict.Demo.Server/EntityFrameworkCore/ServerDataSeedContributor.cs @@ -71,6 +71,7 @@ public class ServerDataSeedContributor : IDataSeedContributor, ITransientDepende OpenIddictConstants.Permissions.Endpoints.Introspection, OpenIddictConstants.Permissions.Endpoints.Revocation, OpenIddictConstants.Permissions.Endpoints.EndSession, + OpenIddictConstants.Permissions.Endpoints.PushedAuthorization, OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, OpenIddictConstants.Permissions.GrantTypes.Implicit, diff --git a/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20241005085943_Initial.Designer.cs b/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20250215074649_Initial.Designer.cs similarity index 99% rename from modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20241005085943_Initial.Designer.cs rename to modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20250215074649_Initial.Designer.cs index 7fffd314e8..fec1a9f143 100644 --- a/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20241005085943_Initial.Designer.cs +++ b/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20250215074649_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace OpenIddict.Demo.Server.Migrations { [DbContext(typeof(ServerDbContext))] - [Migration("20241005085943_Initial")] + [Migration("20250215074649_Initial")] partial class Initial { /// @@ -22,7 +22,7 @@ namespace OpenIddict.Demo.Server.Migrations #pragma warning disable 612, 618 modelBuilder .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) - .HasAnnotation("ProductVersion", "9.0.0-rc.1.24451.1") + .HasAnnotation("ProductVersion", "9.0.0") .HasAnnotation("Relational:MaxIdentifierLength", 128); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); @@ -162,6 +162,10 @@ namespace OpenIddict.Demo.Server.Migrations .HasColumnType("nvarchar(40)") .HasColumnName("ConcurrencyStamp"); + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + b.Property("Description") .HasMaxLength(256) .HasColumnType("nvarchar(256)"); @@ -238,6 +242,10 @@ namespace OpenIddict.Demo.Server.Migrations .HasColumnType("nvarchar(40)") .HasColumnName("ConcurrencyStamp"); + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + b.Property("EntityVersion") .HasColumnType("int"); @@ -394,13 +402,6 @@ namespace OpenIddict.Demo.Server.Migrations .HasMaxLength(64) .HasColumnType("nvarchar(64)"); - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .IsRequired() - .HasMaxLength(40) - .HasColumnType("nvarchar(40)") - .HasColumnName("ConcurrencyStamp"); - b.Property("Device") .IsRequired() .HasMaxLength(64) @@ -411,7 +412,6 @@ namespace OpenIddict.Demo.Server.Migrations .HasColumnType("nvarchar(64)"); b.Property("ExtraProperties") - .IsRequired() .HasColumnType("nvarchar(max)") .HasColumnName("ExtraProperties"); diff --git a/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20241005085943_Initial.cs b/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20250215074649_Initial.cs similarity index 99% rename from modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20241005085943_Initial.cs rename to modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20250215074649_Initial.cs index 62b23276c4..fdf8dac987 100644 --- a/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20241005085943_Initial.cs +++ b/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20250215074649_Initial.cs @@ -23,6 +23,7 @@ namespace OpenIddict.Demo.Server.Migrations RegexDescription = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), Description = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), ValueType = table.Column(type: "int", nullable: false), + CreationTime = table.Column(type: "datetime2", nullable: false), ExtraProperties = table.Column(type: "nvarchar(max)", nullable: false), ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: false) }, @@ -188,6 +189,7 @@ namespace OpenIddict.Demo.Server.Migrations IsStatic = table.Column(type: "bit", nullable: false), IsPublic = table.Column(type: "bit", nullable: false), EntityVersion = table.Column(type: "int", nullable: false), + CreationTime = table.Column(type: "datetime2", nullable: false), ExtraProperties = table.Column(type: "nvarchar(max)", nullable: false), ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: false) }, @@ -235,8 +237,7 @@ namespace OpenIddict.Demo.Server.Migrations IpAddresses = table.Column(type: "nvarchar(2048)", maxLength: 2048, nullable: true), SignedIn = table.Column(type: "datetime2", nullable: false), LastAccessed = table.Column(type: "datetime2", nullable: true), - ExtraProperties = table.Column(type: "nvarchar(max)", nullable: false), - ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: false) + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true) }, constraints: table => { diff --git a/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/ServerDbContextModelSnapshot.cs b/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/ServerDbContextModelSnapshot.cs index fbaf0bc710..4099fccc43 100644 --- a/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/ServerDbContextModelSnapshot.cs +++ b/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/ServerDbContextModelSnapshot.cs @@ -19,7 +19,7 @@ namespace OpenIddict.Demo.Server.Migrations #pragma warning disable 612, 618 modelBuilder .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) - .HasAnnotation("ProductVersion", "9.0.0-rc.1.24451.1") + .HasAnnotation("ProductVersion", "9.0.0") .HasAnnotation("Relational:MaxIdentifierLength", 128); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); @@ -159,6 +159,10 @@ namespace OpenIddict.Demo.Server.Migrations .HasColumnType("nvarchar(40)") .HasColumnName("ConcurrencyStamp"); + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + b.Property("Description") .HasMaxLength(256) .HasColumnType("nvarchar(256)"); @@ -235,6 +239,10 @@ namespace OpenIddict.Demo.Server.Migrations .HasColumnType("nvarchar(40)") .HasColumnName("ConcurrencyStamp"); + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + b.Property("EntityVersion") .HasColumnType("int"); @@ -391,13 +399,6 @@ namespace OpenIddict.Demo.Server.Migrations .HasMaxLength(64) .HasColumnType("nvarchar(64)"); - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .IsRequired() - .HasMaxLength(40) - .HasColumnType("nvarchar(40)") - .HasColumnName("ConcurrencyStamp"); - b.Property("Device") .IsRequired() .HasMaxLength(64) @@ -408,7 +409,6 @@ namespace OpenIddict.Demo.Server.Migrations .HasColumnType("nvarchar(64)"); b.Property("ExtraProperties") - .IsRequired() .HasColumnType("nvarchar(max)") .HasColumnName("ExtraProperties"); diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/AbpOpenIddictAspNetCoreModule.cs b/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/AbpOpenIddictAspNetCoreModule.cs index 6ebb66cb6a..dddc89d515 100644 --- a/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/AbpOpenIddictAspNetCoreModule.cs +++ b/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/AbpOpenIddictAspNetCoreModule.cs @@ -65,6 +65,7 @@ public class AbpOpenIddictAspNetCoreModule : AbpModule .SetDeviceAuthorizationEndpointUris("device") .SetIntrospectionEndpointUris("connect/introspect") .SetEndSessionEndpointUris("connect/endsession") + .SetPushedAuthorizationEndpointUris("connect/par") .SetRevocationEndpointUris("connect/revocat") .SetTokenEndpointUris("connect/token") .SetUserInfoEndpointUris("connect/userinfo") diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor index 2d89ff866d..fc9884bf4e 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor @@ -24,7 +24,7 @@ - + @L["SelectAllInAllTabs"] diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs index b2c998eb4f..d2c2e092d5 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs @@ -38,43 +38,7 @@ public partial class PermissionManagementModal protected string _permissionGroupSearchText; - protected bool GrantAll { - get { - if (_notGrantedPermissionCount == 0) - { - return true; - } - - return false; - } - set { - if (_groups == null) - { - return; - } - - _grantedPermissionCount = 0; - _notGrantedPermissionCount = 0; - Task.Run(()=>OnPermissionGroupSearchTextChangedAsync(null)); - - foreach (var permission in _allGroups.SelectMany(x => x.Permissions)) - { - if (!IsDisabledPermission(permission)) - { - permission.IsGranted = value; - - if (value) - { - _grantedPermissionCount++; - } - else - { - _notGrantedPermissionCount++; - } - } - } - } - } + protected bool GrantAll { get; set; } protected Dictionary _permissionDepths = new Dictionary(); @@ -98,6 +62,8 @@ public partial class PermissionManagementModal _groups = _allGroups.ToList(); NormalizePermissionGroup(); + + GrantAll = _notGrantedPermissionCount == 0; await InvokeAsync(_modal.Show); } @@ -106,17 +72,57 @@ public partial class PermissionManagementModal await HandleErrorAsync(ex); } } + + protected virtual async Task GrantAllAsync(bool grantAll) + { + GrantAll = grantAll; + + if (_allGroups == null) + { + return; + } + + _grantedPermissionCount = 0; + _notGrantedPermissionCount = 0; + + await OnPermissionGroupSearchTextChangedAsync(string.Empty); + + foreach (var permission in _allGroups.SelectMany(x => x.Permissions)) + { + if (IsDisabledPermission(permission)) + { + continue; + } + + permission.IsGranted = grantAll; + + if (grantAll) + { + _grantedPermissionCount++; + } + else + { + _notGrantedPermissionCount++; + } + } + + await InvokeAsync(StateHasChanged); + } - protected void NormalizePermissionGroup() + protected virtual void NormalizePermissionGroup(bool checkDisabledPermissions = true) { _selectAllDisabled = _groups.All(IsPermissionGroupDisabled); _grantedPermissionCount = 0; _notGrantedPermissionCount = 0; - _disabledPermissions.Clear(); + if (checkDisabledPermissions) + { + _disabledPermissions.Clear(); + } + foreach (var permission in _groups.SelectMany(x => x.Permissions)) { - if (permission.IsGranted && permission.GrantedProviders.All(x => x.ProviderName != _providerName)) + if (checkDisabledPermissions && permission.IsGranted && permission.GrantedProviders.All(x => x.ProviderName != _providerName)) { _disabledPermissions.Add(permission); continue; @@ -269,19 +275,19 @@ public partial class PermissionManagementModal permission.IsGranted = value; } - protected PermissionGrantInfoDto GetParentPermission(PermissionGroupDto permissionGroup, PermissionGrantInfoDto permission) + protected virtual PermissionGrantInfoDto GetParentPermission(PermissionGroupDto permissionGroup, PermissionGrantInfoDto permission) { return permissionGroup.Permissions.First(x => x.Name == permission.ParentName); } - protected List GetChildPermissions(PermissionGroupDto permissionGroup, PermissionGrantInfoDto permission) + protected virtual List GetChildPermissions(PermissionGroupDto permissionGroup, PermissionGrantInfoDto permission) { var childPermissions = new List(); GetChildPermissions(childPermissions, permissionGroup.Permissions, permission); return childPermissions; } - protected void GetChildPermissions(List allChildPermissions, List permissions, PermissionGrantInfoDto permission) + protected virtual void GetChildPermissions(List allChildPermissions, List permissions, PermissionGrantInfoDto permission) { var childPermissions = permissions.Where(x => x.ParentName == permission.Name).ToList(); if (childPermissions.Count == 0) @@ -297,7 +303,7 @@ public partial class PermissionManagementModal } } - protected bool IsDisabledPermission(PermissionGrantInfoDto permissionGrantInfo) + protected virtual bool IsDisabledPermission(PermissionGrantInfoDto permissionGrantInfo) { return _disabledPermissions.Any(x => x == permissionGrantInfo); } @@ -341,9 +347,9 @@ public partial class PermissionManagementModal } _permissionGroupSearchText = value; - _groups = _permissionGroupSearchText.IsNullOrWhiteSpace() ? _allGroups : _allGroups.Where(x => x.DisplayName.Contains(_permissionGroupSearchText, StringComparison.OrdinalIgnoreCase) || x.Permissions.Any(permission => permission.DisplayName.Contains(_permissionGroupSearchText, StringComparison.OrdinalIgnoreCase))).ToList(); + _groups = _permissionGroupSearchText.IsNullOrWhiteSpace() ? _allGroups.ToList() : _allGroups.Where(x => x.DisplayName.Contains(_permissionGroupSearchText, StringComparison.OrdinalIgnoreCase) || x.Permissions.Any(permission => permission.DisplayName.Contains(_permissionGroupSearchText, StringComparison.OrdinalIgnoreCase))).ToList(); - NormalizePermissionGroup(); + NormalizePermissionGroup(false); await InvokeAsync(StateHasChanged); } diff --git a/npm/ng-packs/package.json b/npm/ng-packs/package.json index 21f88272b4..d63e69590f 100644 --- a/npm/ng-packs/package.json +++ b/npm/ng-packs/package.json @@ -112,7 +112,7 @@ "lerna": "^4.0.0", "lint-staged": "^13.0.0", "ng-packagr": "~19.1.0", - "ng-zorro-antd": "^19.0.0-beta.0", + "ng-zorro-antd": "~19.0.0", "nx": "~20.3.0", "postcss": "^8.0.0", "postcss-import": "14.1.0", diff --git a/npm/ng-packs/packages/components/package.json b/npm/ng-packs/packages/components/package.json index 18b76419e9..28394bdd71 100644 --- a/npm/ng-packs/packages/components/package.json +++ b/npm/ng-packs/packages/components/package.json @@ -12,7 +12,7 @@ }, "dependencies": { "chart.js": "^3.5.1", - "ng-zorro-antd": "^19.0.0-beta.0", + "ng-zorro-antd": "~19.0.0", "@ctrl/tinycolor": "^4.0.0", "tslib": "^2.0.0" }, diff --git a/npm/ng-packs/packages/components/tree/src/lib/components/tree.component.html b/npm/ng-packs/packages/components/tree/src/lib/components/tree.component.html index b670b0ed48..82b3048868 100644 --- a/npm/ng-packs/packages/components/tree/src/lib/components/tree.component.html +++ b/npm/ng-packs/packages/components/tree/src/lib/components/tree.component.html @@ -9,18 +9,18 @@ [nzExpandedKeys]="expandedKeys" [nzExpandedIcon]="expandedIconTemplate?.template || defaultIconTemplate" (nzExpandChange)="onExpandedKeysChange($event)" - (nzCheckBoxChange)="onCheckboxChange($event)" + (nzCheckboxChange)="onCheckboxChange($event)" (nzOnDrop)="onDrop($event)" [nzNoAnimation]="noAnimation" (nzContextMenu)="dropdowns[$event.node?.key]?.toggle()" -> +/>
- +
@@ -29,7 +29,7 @@ customNodeTemplate ? customNodeTemplate?.template : defaultNodeTemplate; context: { $implicit: node } " - > + />
@if (menu) { @@ -48,7 +48,7 @@ aria-hidden="true" >
- +
} @@ -62,8 +62,8 @@ + diff --git a/npm/ng-packs/packages/components/tree/src/lib/components/tree.component.ts b/npm/ng-packs/packages/components/tree/src/lib/components/tree.component.ts index 51e4eb9eae..2d227787ca 100644 --- a/npm/ng-packs/packages/components/tree/src/lib/components/tree.component.ts +++ b/npm/ng-packs/packages/components/tree/src/lib/components/tree.component.ts @@ -4,21 +4,20 @@ import { Component, ContentChild, EventEmitter, - Inject, + inject, Input, OnInit, - Optional, Output, TemplateRef, ViewEncapsulation, } from '@angular/core'; +import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap'; import { NzFormatBeforeDropEvent, NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd/tree'; +import { LazyLoadService, LOADING_STRATEGY, SubscriptionService } from '@abp/ng.core'; import { of } from 'rxjs'; +import { DISABLE_TREE_STYLE_LOADING_TOKEN } from '../disable-tree-style-loading.token'; import { TreeNodeTemplateDirective } from '../templates/tree-node-template.directive'; import { ExpandedIconTemplateDirective } from '../templates/expanded-icon-template.directive'; -import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap'; -import { LazyLoadService, LOADING_STRATEGY, SubscriptionService } from '@abp/ng.core'; -import { DISABLE_TREE_STYLE_LOADING_TOKEN } from '../disable-tree-style-loading.token'; export type DropEvent = NzFormatEmitEvent & { pos: number }; @@ -32,19 +31,15 @@ export type DropEvent = NzFormatEmitEvent & { pos: number }; changeDetection: ChangeDetectionStrategy.OnPush, }) export class TreeComponent implements OnInit { + private lazyLoadService = inject(LazyLoadService); + private subscriptionService = inject(SubscriptionService); + private cdr = inject(ChangeDetectorRef); + private disableTreeStyleLoading = inject(DISABLE_TREE_STYLE_LOADING_TOKEN, { optional: true }); + dropPosition: number; dropdowns = {} as { [key: string]: NgbDropdown }; - constructor( - private lazyLoadService: LazyLoadService, - private subscriptionService: SubscriptionService, - @Optional() - @Inject(DISABLE_TREE_STYLE_LOADING_TOKEN) - private disableTreeStyleLoading: boolean | undefined, - private cdr: ChangeDetectorRef, - ) {} - @ContentChild('menu') menu: TemplateRef; @ContentChild(TreeNodeTemplateDirective) customNodeTemplate: TreeNodeTemplateDirective; @ContentChild(ExpandedIconTemplateDirective) expandedIconTemplate: ExpandedIconTemplateDirective; @@ -88,7 +83,7 @@ export class TreeComponent implements OnInit { return node; } if (node.children) { - let res = this.findNode(target, node.children); + const res = this.findNode(target, node.children); if (res) { return res; } @@ -138,7 +133,7 @@ export class TreeComponent implements OnInit { } setSelectedNode(node: any) { - let newSelectedNode = this.findNode(node, this.nodes); + const newSelectedNode = this.findNode(node, this.nodes); this.selectedNode = { ...newSelectedNode }; this.cdr.markForCheck(); } diff --git a/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html b/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html index 7470c3e772..32fe44e488 100644 --- a/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html +++ b/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html @@ -40,7 +40,9 @@
- {{ 'AbpPermissionManagement::PermissionGroup' | abpLocalization }} + + {{ 'AbpPermissionManagement::PermissionGroup' | abpLocalization }} +
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 a5a912e3eb..2742cedcee 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 @@ -164,6 +164,7 @@ export class PermissionManagementComponent let groups = this.permissionGroupSignal(); if (!search) { + this.setSelectedGroup(groups[0]); return groups; } @@ -176,9 +177,7 @@ export class PermissionManagementComponent if (groups.length) { this.setSelectedGroup(groups[0]); - this.disabledSelectAllInAllTabs = false; } else { - this.disabledSelectAllInAllTabs = true; this.selectedGroupPermissions = []; } @@ -323,6 +322,9 @@ export class PermissionManagementComponent ); const selectedPermissions = selectablePermissions.filter(per => per.isGranted); const element = document.querySelector('#select-all-in-this-tabs') as any; + if (!element) { + return; + } if (selectedPermissions.length === selectablePermissions.length) { element.indeterminate = false; @@ -373,7 +375,7 @@ export class PermissionManagementComponent onClickSelectAll() { if (this.filter()) { this.filter.set(''); - } + } this.permissions = this.permissions.map(permission => ({ ...permission,