diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/AbpSettingManagementWebModule.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/AbpSettingManagementWebModule.cs index 61874c0b6b..b544d4a7bf 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/AbpSettingManagementWebModule.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/AbpSettingManagementWebModule.cs @@ -1,7 +1,5 @@ -using Microsoft.AspNetCore.Mvc.RazorPages; -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Mvc.Localization; -using Volo.Abp.AspNetCore.Mvc.UI.Bundling; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; using Volo.Abp.AutoMapper; using Volo.Abp.Http.ProxyScripting.Generators.JQuery; @@ -29,7 +27,7 @@ public class AbpSettingManagementWebModule : AbpModule { options.AddAssemblyResource(typeof(AbpSettingManagementResource), typeof(AbpSettingManagementWebModule).Assembly); }); - + PreConfigure(mvcBuilder => { mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpSettingManagementWebModule).Assembly); @@ -54,21 +52,11 @@ public class AbpSettingManagementWebModule : AbpModule options.FileSets.AddEmbedded(); }); - Configure(options => - { - options.ScriptBundles - .Configure(typeof(IndexModel).FullName, - configuration => - { - configuration.AddFiles("/Pages/SettingManagement/Components/EmailSettingGroup/Default.js"); - }); - }); - Configure(options => { options.DisableModule(SettingManagementRemoteServiceConsts.ModuleName); }); - + context.Services.AddAutoMapperObjectMapper(); Configure(options => { diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Navigation/SettingManagementMainMenuContributor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Navigation/SettingManagementMainMenuContributor.cs index 97eb89b6c6..a5775a8a42 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Navigation/SettingManagementMainMenuContributor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Navigation/SettingManagementMainMenuContributor.cs @@ -1,5 +1,4 @@ using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; using System.Linq; using System.Threading.Tasks; using Volo.Abp.Features; @@ -25,10 +24,8 @@ public class SettingManagementMainMenuContributor : IMenuContributor return; } - var settingManagementPageOptions = context.ServiceProvider.GetRequiredService>().Value; - var settingPageCreationContext = new SettingPageCreationContext(context.ServiceProvider); - if (!settingManagementPageOptions.Contributors.Any() || - !(await CheckAnyOfPagePermissionsGranted(settingManagementPageOptions, settingPageCreationContext))) + var settingPageContributorManager = context.ServiceProvider.GetRequiredService(); + if (!(await settingPageContributorManager.GetAvailableContributors()).Any()) { return; } @@ -46,18 +43,4 @@ public class SettingManagementMainMenuContributor : IMenuContributor ).RequireFeatures(SettingManagementFeatures.Enable) ); } - - protected virtual async Task CheckAnyOfPagePermissionsGranted( - SettingManagementPageOptions settingManagementPageOptions, - SettingPageCreationContext settingPageCreationContext) - { - foreach (var contributor in settingManagementPageOptions.Contributors) - { - if (await contributor.CheckPermissionsAsync(settingPageCreationContext)) - { - return true; - } - } - return false; - } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Components/EmailSettingGroup/Default.cshtml b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Components/EmailSettingGroup/Default.cshtml index caca43c1e1..a5e0275535 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Components/EmailSettingGroup/Default.cshtml +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Components/EmailSettingGroup/Default.cshtml @@ -6,6 +6,8 @@ @inject IPermissionChecker PermissionChecker @model Volo.Abp.SettingManagement.Web.Pages.SettingManagement.Components.EmailSettingGroup.EmailSettingGroupViewComponent.UpdateEmailSettingsViewModel + +
@@ -36,4 +38,4 @@ -
\ No newline at end of file + diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/ISettingPageContributor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/ISettingPageContributor.cs index 4128e9cd05..7bf0653380 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/ISettingPageContributor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/ISettingPageContributor.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; namespace Volo.Abp.SettingManagement.Web.Pages.SettingManagement; @@ -6,5 +7,6 @@ public interface ISettingPageContributor { Task ConfigureAsync(SettingPageCreationContext context); + [Obsolete("Use SettingPageContributorBase as base class and call `RequiredPermissions` or `RequiredFeatures` for better performance.")] Task CheckPermissionsAsync(SettingPageCreationContext context); } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.cshtml b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.cshtml index 6ee1d62299..0ff8e7d0ac 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.cshtml +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.cshtml @@ -21,19 +21,24 @@
- - @foreach (var group in Model.SettingPageCreationContext.Groups) - { - -

@group.DisplayName

-
- @await Component.InvokeAsync(group.ComponentType, new +
+
+ +
+
+
+
+
+
diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.cshtml.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.cshtml.cs index bf0b3e0d6b..1e55bd2f6a 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.cshtml.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.cshtml.cs @@ -1,5 +1,5 @@ +using System.Linq; using System.Threading.Tasks; -using Microsoft.Extensions.Options; using Microsoft.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; @@ -13,25 +13,19 @@ public class IndexModel : AbpPageModel { public SettingPageCreationContext SettingPageCreationContext { get; private set; } + protected SettingPageContributorManager SettingPageContributorManager { get; } + protected ILocalEventBus LocalEventBus { get; } - protected SettingManagementPageOptions Options { get; } - public IndexModel( - IOptions options, - ILocalEventBus localEventBus) + public IndexModel(ILocalEventBus localEventBus, SettingPageContributorManager settingPageContributorManager) { LocalEventBus = localEventBus; - Options = options.Value; + SettingPageContributorManager = settingPageContributorManager; } public virtual async Task OnGetAsync() { - SettingPageCreationContext = new SettingPageCreationContext(ServiceProvider); - - foreach (var contributor in Options.Contributors) - { - await contributor.ConfigureAsync(SettingPageCreationContext); - } + SettingPageCreationContext = await SettingPageContributorManager.ConfigureAsync(); return Page(); } @@ -41,6 +35,19 @@ public class IndexModel : AbpPageModel return Task.FromResult(Page()); } + public virtual async Task OnPostRenderViewAsync(string id) + { + var context = await SettingPageContributorManager.ConfigureAsync(); + + var view = context.Groups.FirstOrDefault(x => x.Id == id); + if (view != null) + { + return ViewComponent(view.ComponentType, view.Parameter); + } + + return NoContent(); + } + public virtual async Task OnPostRefreshConfigurationAsync() { await LocalEventBus.PublishAsync( diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.js b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.js index 8af1bb6715..07b40c2c38 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.js +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.js @@ -1,6 +1,30 @@ (function ($) { var l = abp.localization.getResource('AbpSettingManagement'); + $('#tabs-nav .nav-item .nav-link').click(function () { + var _this = $(this); + if(_this.attr('data-bs-target') !== undefined) { + return; + } + + var id = _this.data("id") + abp.ui.block({ + elm: '#tab-content', + busy: true, + promise: abp.ajax({ + type: 'POST', + url: 'SettingManagement?handler=RenderView&id=' + id, + dataType: "html", + contentType: false, + processData: false + }).done(function (response) { + $('#tab-content').children('.tab-pane').removeClass('show').removeClass('active'); + _this.attr('data-bs-target', '#' + $.escapeSelector($.escapeSelector(id))); + $('#tab-content').append('
' + response + '
'); + }) + }); + }).first().click(); + $(document).on('AbpSettingSaved', function () { abp.notify.success(l('SuccessfullySaved')); diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageContributorBase.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageContributorBase.cs new file mode 100644 index 0000000000..b79c452df9 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageContributorBase.cs @@ -0,0 +1,59 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.SettingManagement.Web.Pages.SettingManagement; + +public abstract class SettingPageContributorBase : ISettingPageContributor +{ + private readonly HashSet _requiredPermissions; + private readonly HashSet _requiredFeatures; + private readonly HashSet _requiredTenantSideFeatures; + + protected SettingPageContributorBase() + { + _requiredPermissions = new HashSet(); + _requiredFeatures = new HashSet(); + _requiredTenantSideFeatures = new HashSet(); + } + + protected virtual SettingPageContributorBase RequiredPermissions(params string[] permissions) + { + Check.NotNullOrEmpty(permissions, nameof(permissions)); + _requiredPermissions.AddIfNotContains(permissions); + return this; + } + + public virtual IReadOnlySet GetRequiredPermissions() + { + return _requiredPermissions; + } + + protected virtual SettingPageContributorBase RequiredFeatures(params string[] features) + { + Check.NotNullOrEmpty(features, nameof(features)); + _requiredFeatures.AddIfNotContains(features); + return this; + } + + protected virtual SettingPageContributorBase RequiredTenantSideFeatures(params string[] features) + { + Check.NotNullOrEmpty(features, nameof(features)); + _requiredTenantSideFeatures.AddIfNotContains(features); + return this; + } + + public virtual IReadOnlySet GetRequiredFeatures(MultiTenancySides? multiTenancySides = null) + { + return multiTenancySides == null || multiTenancySides != MultiTenancySides.Tenant + ? _requiredFeatures + : _requiredTenantSideFeatures; + } + + public abstract Task ConfigureAsync(SettingPageCreationContext context); + + public virtual Task CheckPermissionsAsync(SettingPageCreationContext context) + { + return Task.FromResult(true); + } +} diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageContributorManager.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageContributorManager.cs new file mode 100644 index 0000000000..e1f597b85a --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/SettingPageContributorManager.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Features; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.SettingManagement.Web.Pages.SettingManagement; + +public class SettingPageContributorManager : IScopedDependency +{ + protected IServiceProvider ServiceProvider { get; } + + protected ConcurrentDictionary> CachedAvailableContributors { get; set; } + + public SettingPageContributorManager(IServiceProvider serviceProvider) + { + ServiceProvider = serviceProvider; + CachedAvailableContributors = new ConcurrentDictionary>(); + } + + public virtual async Task> GetAvailableContributors() + { + return CachedAvailableContributors.GetOrAdd(nameof(SettingPageContributorManager), await GetAvailableContributorsInternalAsync()); + } + + public virtual async Task ConfigureAsync() + { + var contributors = CachedAvailableContributors.GetOrAdd(nameof(SettingPageContributorManager), await GetAvailableContributorsInternalAsync()); + var context = new SettingPageCreationContext(ServiceProvider); + foreach (var contributor in contributors) + { + await contributor.ConfigureAsync(context); + } + return context; + } + + protected virtual async Task> GetAvailableContributorsInternalAsync() + { + var contributors = ServiceProvider.GetRequiredService>().Value.Contributors; + var contributorBases = contributors.Where(x => x is SettingPageContributorBase).Cast().ToList(); + + var permissions = new HashSet(); + permissions.AddIfNotContains(contributorBases.SelectMany(x => x.GetRequiredPermissions())); + + var featureChecker = ServiceProvider.GetRequiredService(); + var permissionChecker = ServiceProvider.GetRequiredService(); + var grantResult = await permissionChecker.IsGrantedAsync(permissions.ToArray()); + + var availableContributors = new List(); + foreach (var contributor in contributorBases) + { + var available = true; + + var requiredFeatures = contributor.GetRequiredFeatures(); + if (requiredFeatures.Any() && !await featureChecker.IsEnabledAsync(true, requiredFeatures.ToArray())) + { + available = false; + } + + if (available) + { + var requiredTenantSideFeatures = contributor.GetRequiredFeatures(MultiTenancySides.Tenant); + if (requiredTenantSideFeatures.Any() && !await featureChecker.IsEnabledAsync(true, requiredTenantSideFeatures.ToArray())) + { + available = false; + } + } + + if (available) + { + available = contributor.GetRequiredPermissions().All(x => grantResult.Result.ContainsKey(x) && grantResult.Result[x] == PermissionGrantResult.Granted); + } + + if (available) + { + availableContributors.Add(contributor); + } + } + + var context = new SettingPageCreationContext(ServiceProvider); + foreach (var contributor in contributors.Where(x => x is not SettingPageContributorBase)) + { +#pragma warning disable CS0618 + if (await contributor.CheckPermissionsAsync(context)) +#pragma warning restore CS0618 + { + availableContributors.Add(contributor); + } + } + + return availableContributors; + } +} diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs index 35e6714b9f..773088d140 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs @@ -1,24 +1,22 @@ using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; -using Volo.Abp.Features; -using Volo.Abp.MultiTenancy; using Volo.Abp.SettingManagement.Localization; using Volo.Abp.SettingManagement.Web.Pages.SettingManagement; using Volo.Abp.SettingManagement.Web.Pages.SettingManagement.Components.EmailSettingGroup; namespace Volo.Abp.SettingManagement.Web.Settings; -public class EmailingPageContributor : ISettingPageContributor +public class EmailingPageContributor : SettingPageContributorBase { - public async Task ConfigureAsync(SettingPageCreationContext context) + public EmailingPageContributor() + { + RequiredFeatures(SettingManagementFeatures.Enable); + RequiredTenantSideFeatures(SettingManagementFeatures.AllowTenantsToChangeEmailSettings); + RequiredPermissions(SettingManagementPermissions.Emailing); + } + public override Task ConfigureAsync(SettingPageCreationContext context) { - if (!await CheckPermissionsInternalAsync(context)) - { - return; - } - var l = context.ServiceProvider.GetRequiredService>(); context.Groups.Add( new SettingPageGroup( @@ -27,38 +25,6 @@ public class EmailingPageContributor : ISettingPageContributor typeof(EmailSettingGroupViewComponent) ) ); - } - - public async Task CheckPermissionsAsync(SettingPageCreationContext context) - { - return await CheckPermissionsInternalAsync(context); - } - - private async Task CheckPermissionsInternalAsync(SettingPageCreationContext context) - { - if (!await CheckFeatureAsync(context)) - { - return false; - } - - var authorizationService = context.ServiceProvider.GetRequiredService(); - - return await authorizationService.IsGrantedAsync(SettingManagementPermissions.Emailing); - } - - private async Task CheckFeatureAsync(SettingPageCreationContext context) - { - var featureCheck = context.ServiceProvider.GetRequiredService(); - if (!await featureCheck.IsEnabledAsync(SettingManagementFeatures.Enable)) - { - return false; - } - - if (context.ServiceProvider.GetRequiredService().IsAvailable) - { - return await featureCheck.IsEnabledAsync(SettingManagementFeatures.AllowTenantsToChangeEmailSettings); - } - - return true; + return Task.CompletedTask; } }