diff --git a/docs/en/UI/AspNetCore/Navigation-Menu.md b/docs/en/UI/AspNetCore/Navigation-Menu.md index 97e3d1a47d..f0776f47ec 100644 --- a/docs/en/UI/AspNetCore/Navigation-Menu.md +++ b/docs/en/UI/AspNetCore/Navigation-Menu.md @@ -100,7 +100,7 @@ There are more options of a menu item (the constructor of the `ApplicationMenuIt * `url` (`string`): The URL of the menu item. * `icon` (`string`): An icon name. Free [Font Awesome](https://fontawesome.com/) icon classes are supported out of the box. Example: `fa fa-book`. You can use any CSS font icon class as long as you include the necessary CSS files to your application. * `order` (`int`): The order of the menu item. Default value is `1000`. Items are sorted by the adding order unless you specify an order value. -* `customData` (`object`): A custom object that you can associate to the menu item and use it while rendering the menu item. +* `customData` (`Dictionary`): A dictionary that allows storing custom objects that you can associate with the menu item and use it while rendering the menu item. * `target` (`string`): Target of the menu item. Can be `null` (default), "\_*blank*", "\_*self*", "\_*parent*", "\_*top*" or a frame name for web applications. * `elementId` (`string`): Can be used to render the element with a specific HTML `id` attribute. * `cssClass` (`string`): Additional string classes for the menu item. diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenu.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenu.cs index 976552a6ec..1a69de7f2c 100644 --- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenu.cs +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenu.cs @@ -1,4 +1,6 @@ +using System.Collections.Generic; using JetBrains.Annotations; +using Volo.Abp.Data; using Volo.Abp.UI.Navigation; namespace Volo.Abp.UI.Navigation; @@ -31,10 +33,9 @@ public class ApplicationMenu : IHasMenuItems /// /// Can be used to store a custom object related to this menu. - /// TODO: Convert to dictionary! /// - [CanBeNull] - public object CustomData { get; set; } + [NotNull] + public Dictionary CustomData { get; } = new(); public ApplicationMenu( [NotNull] string name, @@ -59,6 +60,16 @@ public class ApplicationMenu : IHasMenuItems return this; } + /// + /// Adds a custom data item to with given key & value. + /// + /// This itself. + public ApplicationMenu WithCustomData(string key, object value) + { + CustomData[key] = value; + return this; + } + public override string ToString() { return $"[ApplicationMenu] Name = {Name}"; diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs index 1f5d26d7bb..32241ba7ac 100644 --- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs @@ -79,7 +79,8 @@ public class ApplicationMenuItem : IHasMenuItems, IHasSimpleStateCheckers /// Can be used to store a custom object related to this menu item. Optional. /// - public object CustomData { get; set; } + [NotNull] + public Dictionary CustomData { get; } = new(); /// /// Can be used to render the element with a specific Id for DOM selections. @@ -97,7 +98,6 @@ public class ApplicationMenuItem : IHasMenuItems, IHasSimpleStateCheckers + /// Adds a custom data item to with given key & value. + /// + /// This itself. + public ApplicationMenuItem WithCustomData(string key, object value) + { + CustomData[key] = value; + return this; + } + private string GetDefaultElementId() { return "MenuItem_" + Name; diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Menus/CmsKitPublicMenuContributor.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Menus/CmsKitPublicMenuContributor.cs index 845db61425..2753816af0 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Menus/CmsKitPublicMenuContributor.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Menus/CmsKitPublicMenuContributor.cs @@ -58,7 +58,6 @@ public class CmsKitPublicMenuContributor : IMenuContributor menuItem.Url, menuItem.Icon, menuItem.Order, - customData: null, menuItem.Target, menuItem.ElementId, menuItem.CssClass diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainModule.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainModule.cs index ba8105cb88..291e947c06 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainModule.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainModule.cs @@ -52,6 +52,7 @@ public class AbpFeatureManagementDomainModule : AbpModule } private readonly CancellationTokenSource _cancellationTokenSource = new(); + private Task _initializeDynamicFeaturesTask; public override void OnApplicationInitialization(ApplicationInitializationContext context) { @@ -70,6 +71,11 @@ public class AbpFeatureManagementDomainModule : AbpModule return Task.CompletedTask; } + public Task GetInitializeDynamicFeaturesTask() + { + return _initializeDynamicFeaturesTask ?? Task.CompletedTask; + } + private void InitializeDynamicFeatures(ApplicationInitializationContext context) { var options = context @@ -84,7 +90,7 @@ public class AbpFeatureManagementDomainModule : AbpModule var rootServiceProvider = context.ServiceProvider.GetRequiredService(); - Task.Run(async () => + _initializeDynamicFeaturesTask = Task.Run(async () => { using var scope = rootServiceProvider.CreateScope(); var applicationLifetime = scope.ServiceProvider.GetService(); diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.EntityFrameworkCore.Tests/Volo/Abp/FeatureManagement/EntityFrameworkCore/AbpFeatureManagementEntityFrameworkCoreTestModule.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.EntityFrameworkCore.Tests/Volo/Abp/FeatureManagement/EntityFrameworkCore/AbpFeatureManagementEntityFrameworkCoreTestModule.cs index 147a4009a9..3329f1dba6 100644 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.EntityFrameworkCore.Tests/Volo/Abp/FeatureManagement/EntityFrameworkCore/AbpFeatureManagementEntityFrameworkCoreTestModule.cs +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.EntityFrameworkCore.Tests/Volo/Abp/FeatureManagement/EntityFrameworkCore/AbpFeatureManagementEntityFrameworkCoreTestModule.cs @@ -1,10 +1,13 @@ -using Microsoft.Data.Sqlite; +using System.Threading.Tasks; +using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore.Sqlite; using Volo.Abp.Modularity; +using Volo.Abp.Threading; using Volo.Abp.Uow; namespace Volo.Abp.FeatureManagement.EntityFrameworkCore; @@ -42,4 +45,18 @@ public class AbpFeatureManagementEntityFrameworkCoreTestModule : AbpModule return connection; } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + var task = context.ServiceProvider.GetRequiredService().GetInitializeDynamicFeaturesTask(); + if (!task.IsCompleted) + { + AsyncHelper.RunSync(() => Awaited(task)); + } + } + + private async static Task Awaited(Task task) + { + await task; + } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/AbpPermissionManagementDomainModule.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/AbpPermissionManagementDomainModule.cs index 71b42a20fb..da96890997 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/AbpPermissionManagementDomainModule.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/AbpPermissionManagementDomainModule.cs @@ -26,7 +26,7 @@ namespace Volo.Abp.PermissionManagement; public class AbpPermissionManagementDomainModule : AbpModule { private readonly CancellationTokenSource _cancellationTokenSource = new(); - + private Task _initializeDynamicPermissionsTask; public override void ConfigureServices(ServiceConfigurationContext context) { if (context.Services.IsDataMigrationEnvironment()) @@ -56,6 +56,11 @@ public class AbpPermissionManagementDomainModule : AbpModule return Task.CompletedTask; } + public Task GetInitializeDynamicPermissionsTask() + { + return _initializeDynamicPermissionsTask ?? Task.CompletedTask; + } + private void InitializeDynamicPermissions(ApplicationInitializationContext context) { var options = context @@ -70,7 +75,7 @@ public class AbpPermissionManagementDomainModule : AbpModule var rootServiceProvider = context.ServiceProvider.GetRequiredService(); - Task.Run(async () => + _initializeDynamicPermissionsTask = Task.Run(async () => { using var scope = rootServiceProvider.CreateScope(); var applicationLifetime = scope.ServiceProvider.GetService(); diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionDefinitionRecordRepository_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionDefinitionRecordRepository_Tests.cs index 20f9f7e21f..d7ca406624 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionDefinitionRecordRepository_Tests.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionDefinitionRecordRepository_Tests.cs @@ -1,10 +1,12 @@ using System.Threading.Tasks; using Shouldly; +using Volo.Abp.Modularity; using Xunit; namespace Volo.Abp.PermissionManagement; -public abstract class PermissionDefinitionRecordRepository_Tests : PermissionTestBase +public abstract class PermissionDefinitionRecordRepository_Tests : PermissionManagementTestBase + where TStartupModule : IAbpModule { protected IPermissionDefinitionRecordRepository PermissionDefinitionRecordRepository { get; set; } diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests/Volo/Abp/PermissionManagement/EntityFrameworkCore/AbpPermissionManagementEntityFrameworkCoreTestModule.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests/Volo/Abp/PermissionManagement/EntityFrameworkCore/AbpPermissionManagementEntityFrameworkCoreTestModule.cs index b7eab38191..a73e5afb86 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests/Volo/Abp/PermissionManagement/EntityFrameworkCore/AbpPermissionManagementEntityFrameworkCoreTestModule.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests/Volo/Abp/PermissionManagement/EntityFrameworkCore/AbpPermissionManagementEntityFrameworkCoreTestModule.cs @@ -1,8 +1,10 @@ using System; +using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.Modularity; +using Volo.Abp.Threading; using Volo.Abp.Uow; namespace Volo.Abp.PermissionManagement.EntityFrameworkCore; @@ -28,4 +30,18 @@ public class AbpPermissionManagementEntityFrameworkCoreTestModule : AbpModule context.Services.AddAlwaysDisableUnitOfWorkTransaction(); } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + var task = context.ServiceProvider.GetRequiredService().GetInitializeDynamicPermissionsTask(); + if (!task.IsCompleted) + { + AsyncHelper.RunSync(() => Awaited(task)); + } + } + + private async static Task Awaited(Task task) + { + await task; + } } diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests/Volo/Abp/PermissionManagement/EntityFrameworkCore/EFCorePermissionDefinitionRecordRepository_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests/Volo/Abp/PermissionManagement/EntityFrameworkCore/EFCorePermissionDefinitionRecordRepository_Tests.cs index 5429d2e772..832c266ba6 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests/Volo/Abp/PermissionManagement/EntityFrameworkCore/EFCorePermissionDefinitionRecordRepository_Tests.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests/Volo/Abp/PermissionManagement/EntityFrameworkCore/EFCorePermissionDefinitionRecordRepository_Tests.cs @@ -1,6 +1,6 @@ namespace Volo.Abp.PermissionManagement.EntityFrameworkCore; -public class EFCorePermissionDefinitionRecordRepository_Tests : PermissionDefinitionRecordRepository_Tests +public class EFCorePermissionDefinitionRecordRepository_Tests : PermissionDefinitionRecordRepository_Tests { }