mirror of https://github.com/abpframework/abp.git
committed by
GitHub
28 changed files with 404 additions and 26 deletions
@ -0,0 +1,20 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using Volo.Abp.Validation.StringValues; |
||||
|
|
||||
|
namespace Volo.Abp.FeatureManagement |
||||
|
{ |
||||
|
public class FeatureDto |
||||
|
{ |
||||
|
public string Name { get; set; } |
||||
|
|
||||
|
public string Value { get; set; } |
||||
|
|
||||
|
public string Description { get; set; } |
||||
|
|
||||
|
public IStringValueType ValueType { get; set; } |
||||
|
|
||||
|
public int Depth { get; set; } |
||||
|
|
||||
|
public string ParentName { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Volo.Abp.FeatureManagement |
||||
|
{ |
||||
|
public class FeatureListDto |
||||
|
{ |
||||
|
public List<FeatureDto> Features { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
using JetBrains.Annotations; |
||||
|
using Volo.Abp.Application.Services; |
||||
|
|
||||
|
namespace Volo.Abp.FeatureManagement |
||||
|
{ |
||||
|
public interface IFeatureAppService : IApplicationService |
||||
|
{ |
||||
|
Task<FeatureListDto> GetAsync([NotNull] string providerName, [NotNull] string providerKey); |
||||
|
|
||||
|
Task UpdateAsync([NotNull] string providerName, [NotNull] string providerKey, UpdateFeaturesDto input); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Text; |
||||
|
|
||||
|
namespace Volo.Abp.FeatureManagement |
||||
|
{ |
||||
|
public class UpdateFeatureDto |
||||
|
{ |
||||
|
public string Name { get; set; } |
||||
|
|
||||
|
public string Value { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Volo.Abp.FeatureManagement |
||||
|
{ |
||||
|
public class UpdateFeaturesDto |
||||
|
{ |
||||
|
public List<UpdateFeatureDto> Features { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,93 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
using JetBrains.Annotations; |
||||
|
using Microsoft.AspNetCore.Authorization; |
||||
|
using Microsoft.Extensions.Localization; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.Application.Services; |
||||
|
using Volo.Abp.Features; |
||||
|
|
||||
|
namespace Volo.Abp.FeatureManagement |
||||
|
{ |
||||
|
[Authorize] |
||||
|
public class FeatureAppService : ApplicationService, IFeatureAppService |
||||
|
{ |
||||
|
protected FeatureManagementOptions Options { get; } |
||||
|
|
||||
|
private readonly IFeatureManager _featureManager; |
||||
|
private readonly IFeatureDefinitionManager _featureDefinitionManager; |
||||
|
private readonly IStringLocalizerFactory _stringLocalizerFactory; |
||||
|
|
||||
|
public FeatureAppService(IFeatureManager featureManager, |
||||
|
IFeatureDefinitionManager featureDefinitionManager, |
||||
|
IStringLocalizerFactory stringLocalizerFactory, |
||||
|
IOptions<FeatureManagementOptions> options) |
||||
|
{ |
||||
|
_featureManager = featureManager; |
||||
|
_featureDefinitionManager = featureDefinitionManager; |
||||
|
_stringLocalizerFactory = stringLocalizerFactory; |
||||
|
Options = options.Value; |
||||
|
} |
||||
|
|
||||
|
public async Task<FeatureListDto> GetAsync([NotNull] string providerName, [NotNull] string providerKey) |
||||
|
{ |
||||
|
await CheckProviderPolicy(providerName); |
||||
|
|
||||
|
var featureDefinitions = _featureDefinitionManager.GetAll(); |
||||
|
var features = new List<FeatureDto>(); |
||||
|
|
||||
|
foreach (var featureDefinition in featureDefinitions) |
||||
|
{ |
||||
|
features.Add(new FeatureDto |
||||
|
{ |
||||
|
Name = featureDefinition.Name, |
||||
|
ValueType = featureDefinition.ValueType, |
||||
|
Description = featureDefinition.Description.Localize(_stringLocalizerFactory), |
||||
|
ParentName = featureDefinition.Parent?.Name, |
||||
|
Value = await _featureManager.GetOrNullAsync(featureDefinition.Name, providerName, providerKey) |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
SetFeatureDepth(features, providerName, providerKey); |
||||
|
|
||||
|
return new FeatureListDto { Features = features }; |
||||
|
} |
||||
|
|
||||
|
public async Task UpdateAsync([NotNull] string providerName, [NotNull] string providerKey, UpdateFeaturesDto input) |
||||
|
{ |
||||
|
await CheckProviderPolicy(providerName); |
||||
|
|
||||
|
foreach (var feature in input.Features) |
||||
|
{ |
||||
|
await _featureManager.SetAsync(feature.Name, feature.Value, providerName, providerKey); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void SetFeatureDepth(List<FeatureDto> features, string providerName, string providerKey, |
||||
|
FeatureDto parentFeature = null, int depth = 0) |
||||
|
{ |
||||
|
foreach (var feature in features) |
||||
|
{ |
||||
|
if ((parentFeature == null && feature.ParentName == null) || (parentFeature != null && parentFeature.Name == feature.ParentName)) |
||||
|
{ |
||||
|
feature.Depth = depth; |
||||
|
SetFeatureDepth(features, providerName, providerKey, feature, depth + 1); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task CheckProviderPolicy(string providerName) |
||||
|
{ |
||||
|
var policyName = Options.ProviderPolicies.GetOrDefault(providerName); |
||||
|
if (policyName.IsNullOrEmpty()) |
||||
|
{ |
||||
|
throw new AbpException($"No policy defined to get/set permissions for the provider '{policyName}'. Use {nameof(FeatureManagementOptions)} to map the policy."); |
||||
|
} |
||||
|
|
||||
|
await AuthorizationService.CheckAsync(policyName); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,60 @@ |
|||||
|
@page |
||||
|
@using Microsoft.AspNetCore.Mvc.Localization |
||||
|
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal |
||||
|
@using Volo.Abp.FeatureManagement.Localization |
||||
|
@using Volo.Abp.Validation.StringValues |
||||
|
@using Volo.Abp.FeatureManagement.Web.Pages.FeatureManagement |
||||
|
@model FeatureManagementModal |
||||
|
@inject IHtmlLocalizer<AbpFeatureManagementResource> L |
||||
|
@{ |
||||
|
Layout = null; |
||||
|
} |
||||
|
<form method="post" asp-page="/FeatureManagement/FeatureManagementModal" data-script-class="abp.modals.FeatureManagement"> |
||||
|
<abp-modal size="Large"> |
||||
|
<abp-modal-header title="@(L["Features"].Value)"></abp-modal-header> |
||||
|
<abp-modal-body class="ml-4"> |
||||
|
<input asp-for="@Model.ProviderKey" /> |
||||
|
<input asp-for="@Model.ProviderName" /> |
||||
|
@for (var i = 0; i < Model.FeatureListDto.Features.Count; i++) |
||||
|
{ |
||||
|
var feature = Model.FeatureListDto.Features[i]; |
||||
|
<div class="mt-2" style="padding-left: @(feature.Depth * 20)px"> |
||||
|
|
||||
|
<spam class="mr-2">@feature.Name</spam> |
||||
|
|
||||
|
<input type="text" name="Features[@i].Type" value="@feature.ValueType.Name" hidden /> |
||||
|
@if (feature.ValueType is FreeTextStringValueType) |
||||
|
{ |
||||
|
<input type="text" name="Features[@i].Name" value="@feature.Name" hidden /> |
||||
|
<input type="text" name="Features[@i].Value" value="@feature.Value" /> |
||||
|
} |
||||
|
@if (feature.ValueType is SelectionStringValueType) |
||||
|
{ |
||||
|
<input type="text" name="Features[@i].Name" value="@feature.Name" hidden /> |
||||
|
<select name="Features[@i].Value"> |
||||
|
@foreach (var item in (feature.ValueType as SelectionStringValueType).ItemSource.Items) |
||||
|
{ |
||||
|
if (item.Value == feature.Value) |
||||
|
{ |
||||
|
<option value="@item.Value" selected="selected"> @L.GetString(item.DisplayText.Name) </option> |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
<option value="@item.Value"> @L.GetString(item.DisplayText.Name) </option> |
||||
|
} |
||||
|
} |
||||
|
</select> |
||||
|
} |
||||
|
@if (feature.ValueType is ToggleStringValueType) |
||||
|
{ |
||||
|
<input type="text" name="Features[@i].Name" value="@feature.Name" hidden /> |
||||
|
<input type="checkbox" class="FeatureValueCheckbox" name="Features[@i].BoolValue" value="@feature.Value" |
||||
|
@Html.Raw(feature.Value == "True" ? "checked" : "") /> |
||||
|
} |
||||
|
</div> |
||||
|
} |
||||
|
</abp-modal-body> |
||||
|
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer> |
||||
|
</abp-modal> |
||||
|
</form> |
||||
|
|
||||
@ -0,0 +1,75 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; |
||||
|
using Volo.Abp.Validation.StringValues; |
||||
|
|
||||
|
namespace Volo.Abp.FeatureManagement.Web.Pages.FeatureManagement |
||||
|
{ |
||||
|
public class FeatureManagementModal : AbpPageModel |
||||
|
{ |
||||
|
[Required] |
||||
|
[HiddenInput] |
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public string ProviderName { get; set; } |
||||
|
|
||||
|
[Required] |
||||
|
[HiddenInput] |
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public string ProviderKey { get; set; } |
||||
|
|
||||
|
[BindProperty] |
||||
|
public List<FeatureViewModel> Features { get; set; } |
||||
|
|
||||
|
public FeatureListDto FeatureListDto { get; set; } |
||||
|
|
||||
|
private readonly IFeatureAppService _featureAppService; |
||||
|
|
||||
|
public FeatureManagementModal(IFeatureAppService featureAppService) |
||||
|
{ |
||||
|
_featureAppService = featureAppService; |
||||
|
} |
||||
|
|
||||
|
public async Task OnGetAsync() |
||||
|
{ |
||||
|
FeatureListDto = await _featureAppService.GetAsync(ProviderName, ProviderKey); |
||||
|
} |
||||
|
|
||||
|
public async Task<IActionResult> OnPostAsync() |
||||
|
{ |
||||
|
var features = new UpdateFeaturesDto |
||||
|
{ |
||||
|
Features = Features.Select(f => new UpdateFeatureDto |
||||
|
{ |
||||
|
Name = f.Name, |
||||
|
Value = f.Type == nameof(ToggleStringValueType) ? f.BoolValue.ToString() : f.Value |
||||
|
}).ToList() |
||||
|
}; |
||||
|
|
||||
|
await _featureAppService.UpdateAsync(ProviderName, ProviderKey, features); |
||||
|
|
||||
|
return NoContent(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public class ProviderInfoViewModel |
||||
|
{ |
||||
|
public string ProviderName { get; set; } |
||||
|
|
||||
|
public string ProviderKey { get; set; } |
||||
|
} |
||||
|
|
||||
|
public class FeatureViewModel |
||||
|
{ |
||||
|
public string Name { get; set; } |
||||
|
|
||||
|
public string Value { get; set; } |
||||
|
|
||||
|
public bool BoolValue { get; set; } |
||||
|
|
||||
|
public string Type { get; set; } |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
var abp = abp || {}; |
||||
|
(function ($) { |
||||
|
abp.modals = abp.modals || {}; |
||||
|
|
||||
|
abp.modals.FeatureManagement = function () { |
||||
|
|
||||
|
$('.FeatureValueCheckbox').change(function () { |
||||
|
if (this.checked) { |
||||
|
$(this).val("true"); |
||||
|
} |
||||
|
else { |
||||
|
$(this).val("false"); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
}; |
||||
|
})(jQuery); |
||||
@ -0,0 +1,12 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netcoreapp2.2</TargetFramework> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.TenantManagement.Domain.Shared\Volo.Abp.TenantManagement.Domain.Shared.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\feature-management\src\Volo.Abp.FeatureManagement.Domain\Volo.Abp.FeatureManagement.Domain.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,18 @@ |
|||||
|
using Volo.Abp.Features; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.FeatureManagement.TenantManagement |
||||
|
{ |
||||
|
public class AbpFeatureManagementDomainTenantManagementModule : AbpModule |
||||
|
{ |
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
Configure<FeatureManagementOptions>(options => |
||||
|
{ |
||||
|
options.Providers.Add<TenantFeatureManagementProvider>(); |
||||
|
|
||||
|
options.ProviderPolicies[TenantFeatureValueProvider.ProviderName] = "AbpTenantManagement.Tenants.ManageFeatures"; |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue