From 4852fc9e71723353765338b1ea1ec1875134e3cc Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Thu, 10 Sep 2020 18:00:40 +0800 Subject: [PATCH 1/2] Feature Management Modal improvements --- .../Abp/FeatureManagement/FeatureManager.cs | 12 ++- .../FeatureManagementModal.cshtml | 76 ++++++++++++------- .../feature-management-modal.js | 75 ++++++++++++++++-- 3 files changed, 126 insertions(+), 37 deletions(-) diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManager.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManager.cs index 454ade5476..86a313fb4f 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManager.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManager.cs @@ -6,6 +6,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; using Volo.Abp.Features; +using Volo.Abp.Validation; namespace Volo.Abp.FeatureManagement { @@ -57,7 +58,8 @@ namespace Volo.Abp.FeatureManagement .Select(x => new FeatureNameValue(x.Name, x.Value)).ToList(); } - public async Task GetOrNullWithProviderAsync(string name, string providerName, string providerKey, bool fallback = true) + public async Task GetOrNullWithProviderAsync(string name, + string providerName, string providerKey, bool fallback = true) { Check.NotNull(name, nameof(name)); Check.NotNull(providerName, nameof(providerName)); @@ -65,7 +67,8 @@ namespace Volo.Abp.FeatureManagement return await GetOrNullInternalAsync(name, providerName, providerKey, fallback); } - public async Task> GetAllWithProviderAsync(string providerName, string providerKey, bool fallback = true) + public async Task> GetAllWithProviderAsync(string providerName, + string providerKey, bool fallback = true) { Check.NotNull(providerName, nameof(providerName)); @@ -128,6 +131,11 @@ namespace Volo.Abp.FeatureManagement var feature = FeatureDefinitionManager.Get(name); + if (feature.ValueType.Validator != null && !feature.ValueType.Validator.IsValid(value)) + { + throw new BusinessException($"{feature.Name} value is invalid"); + } + var providers = Enumerable .Reverse(Providers) .SkipWhile(p => p.Name != providerName) diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml index 601926b193..48143b9a5f 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml @@ -14,55 +14,73 @@ @if (Model.FeatureListResultDto != null && Model.FeatureListResultDto.Groups.Any()) { + var featureGroups = Model.FeatureListResultDto.Groups; + - @for (var i = 0; i < Model.FeatureListResultDto.Groups.Count; i++) + @for (var i = 0; i < featureGroups.Count; i++) { - -

@Model.FeatureListResultDto.Groups[i].DisplayName

+ +

@featureGroups[i].DisplayName


- @for (var j = 0; j < Model.FeatureListResultDto.Groups[i].Features.Count; j++) + @for (var j = 0; j < featureGroups[i].Features.Count; j++) { - var feature = Model.FeatureListResultDto.Groups[i].Features[j]; + var feature = featureGroups[i].Features[j]; var disabled = Model.IsDisabled(feature.Provider.Name); -
- - @feature.DisplayName @(disabled ? $"({feature.Provider.Name})" : "") +
+ + @if (feature.ValueType is ToggleStringValueType) + { + + + } + @if (feature.ValueType is FreeTextStringValueType) { - - + } - @if (feature.ValueType is SelectionStringValueType) + + @if (feature.ValueType is SelectionStringValueType selectType) { - - + @foreach (var item in selectType.ItemSource.Items) { - + if (item.Value == feature.Value) + { + + } + else + { + + } } - } - - } - @if (feature.ValueType is ToggleStringValueType) - { - - + +
} + +
}
diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/feature-management-modal.js b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/feature-management-modal.js index 7e4960999c..f9ec7e11fa 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/feature-management-modal.js +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/feature-management-modal.js @@ -3,12 +3,75 @@ abp.modals = abp.modals || {}; abp.modals.FeatureManagement = function () { - $('.FeatureValueCheckbox').change(function () { - if (this.checked) { - $(this).val('true'); - } else { - $(this).val('false'); + function checkParents($tab, $element, className) { + var parentName = $element + .closest(className) + .attr('data-parent-name'); + + if (!parentName) { + return; + } + + $tab.find('.custom-checkbox') + .filter('[data-feature-name="' + parentName + '"]') + .find('input[type="checkbox"]') + .each(function () { + var $parent = $(this); + $parent.prop('checked', true); + checkParents($tab, $parent, className); + }); + } + + function uncheckChildren($tab, $checkBox) { + var featureName = $checkBox + .closest('.custom-checkbox') + .attr('data-feature-name'); + if (!featureName) { + return; } - }); + + $tab.find('.custom-checkbox') + .filter('[data-parent-name="' + featureName + '"]') + .find('input[type="checkbox"]') + .each(function () { + var $child = $(this); + $child.prop('checked', false); + uncheckChildren($tab, $child); + }); + } + + this.initDom = function ($el) { + $el.find('.tab-pane').each(function () { + var $tab = $(this); + $tab.find('input[type="checkbox"]') + .each(function () { + var $checkBox = $(this); + $checkBox.change(function () { + if ($checkBox.is(':checked')) { + checkParents($tab, $checkBox, '.custom-checkbox') + } else { + uncheckChildren($tab, $checkBox); + } + }); + }); + + $tab.find('.form-control') + .each(function () { + var $element = $(this); + $element.change(function () { + checkParents($tab, $element, '.form-group') + }); + }); + }); + + $(function () { + $('.custom-scroll-content').mCustomScrollbar({ + theme: 'minimal-dark', + }); + $('.custom-scroll-container > .col-4').mCustomScrollbar({ + theme: 'minimal-dark', + }); + }); + }; }; })(jQuery); From 450f1a105ed6f7b7f2c234984a66a9c4b2342306 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Thu, 10 Sep 2020 22:12:15 +0800 Subject: [PATCH 2/2] Improved --- .../AbpFeatureManagementDomainSharedModule.cs | 6 ++++++ .../FeatureManagementDomainErrorCodes.cs | 6 ++++-- .../FeatureValueInvalidException.cs | 14 ++++++++++++++ .../FeatureManagement/Localization/Domain/ar.json | 5 +++-- .../FeatureManagement/Localization/Domain/de.json | 5 +++-- .../FeatureManagement/Localization/Domain/en.json | 3 ++- .../FeatureManagement/Localization/Domain/ru.json | 3 ++- .../FeatureManagement/Localization/Domain/tr.json | 3 ++- .../Localization/Domain/zh-Hans.json | 3 ++- .../Localization/Domain/zh-Hant.json | 3 ++- .../Volo/Abp/FeatureManagement/FeatureManager.cs | 11 +++++++---- .../FeatureManagementModal.cshtml | 9 ++++++++- 12 files changed, 55 insertions(+), 16 deletions(-) create mode 100644 modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/FeatureValueInvalidException.cs diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainSharedModule.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainSharedModule.cs index 0c9a2e0f26..04edbfbbc2 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainSharedModule.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainSharedModule.cs @@ -1,5 +1,6 @@ using Volo.Abp.FeatureManagement.Localization; using Volo.Abp.Localization; +using Volo.Abp.Localization.ExceptionHandling; using Volo.Abp.Modularity; using Volo.Abp.Validation; using Volo.Abp.Validation.Localization; @@ -27,6 +28,11 @@ namespace Volo.Abp.FeatureManagement typeof(AbpValidationResource) ).AddVirtualJson("Volo/Abp/FeatureManagement/Localization/Domain"); }); + + Configure(options => + { + options.MapCodeNamespace("Volo.Abp.FeatureManagement", typeof(AbpFeatureManagementResource)); + }); } } } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/FeatureManagementDomainErrorCodes.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/FeatureManagementDomainErrorCodes.cs index 010c64efbb..9bcfd3290e 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/FeatureManagementDomainErrorCodes.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/FeatureManagementDomainErrorCodes.cs @@ -1,7 +1,9 @@ -namespace Volo.Abp.FeatureManagement +using System; + +namespace Volo.Abp.FeatureManagement { public static class FeatureManagementDomainErrorCodes { - + public const string FeatureValueInvalid = "Volo.Abp.FeatureManagement:InvalidFeatureValue"; } } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/FeatureValueInvalidException.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/FeatureValueInvalidException.cs new file mode 100644 index 0000000000..d003295239 --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/FeatureValueInvalidException.cs @@ -0,0 +1,14 @@ +using System; + +namespace Volo.Abp.FeatureManagement +{ + [Serializable] + public class FeatureValueInvalidException : BusinessException + { + public FeatureValueInvalidException(string name) : + base(FeatureManagementDomainErrorCodes.FeatureValueInvalid) + { + WithData("0", name); + } + } +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ar.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ar.json index fcc347b9e3..cc5fae2dff 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ar.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ar.json @@ -2,6 +2,7 @@ "culture": "ar", "texts": { "Features": "المميزات", - "NoFeatureFoundMessage": "لا توجد أي ميزة متاحة." + "NoFeatureFoundMessage": "لا توجد أي ميزة متاحة.", + "Volo.Abp.FeatureManagement:InvalidFeatureValue" : "{0} قيمة الميزة غير صالحة!" } -} \ No newline at end of file +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/de.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/de.json index 12a4e1aef0..c6d4bb1d07 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/de.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/de.json @@ -2,6 +2,7 @@ "culture": "de", "texts": { "Features": "Funktionen", - "NoFeatureFoundMessage": "Es ist keine Funktion verfügbar." + "NoFeatureFoundMessage": "Es ist keine Funktion verfügbar.", + "Volo.Abp.FeatureManagement:InvalidFeatureValue" : "Der {0} -Feature-Wert ist ungültig!" } -} \ No newline at end of file +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/en.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/en.json index 26f5dc736b..c5194de6c7 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/en.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/en.json @@ -4,6 +4,7 @@ "Features": "Features", "NoFeatureFoundMessage": "There isn't any available feature.", "Permission:FeatureManagement": "Feature management", - "Permission:FeatureManagement.ManageHostFeatures": "Manage Host features" + "Permission:FeatureManagement.ManageHostFeatures": "Manage Host features", + "Volo.Abp.FeatureManagement:InvalidFeatureValue" : "{0} feature value is not valid!" } } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ru.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ru.json index 3945762269..d232c20060 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ru.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ru.json @@ -2,6 +2,7 @@ "culture": "ru", "texts": { "Features": "Функциональные возможности", - "NoFeatureFoundMessage": "Нет доступных функциональных возможностей." + "NoFeatureFoundMessage": "Нет доступных функциональных возможностей.", + "Volo.Abp.FeatureManagement:InvalidFeatureValue" : "Недопустимое значение функции {0}!" } } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/tr.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/tr.json index 8233674933..b69674a620 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/tr.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/tr.json @@ -4,6 +4,7 @@ "Features": "Özellikler", "NoFeatureFoundMessage": "Hiç özellik yok.", "Permission:FeatureManagement": "Özellik yönetimi", - "Permission:FeatureManagement.ManageHostFeatures": "Host özelliklerini düzenle" + "Permission:FeatureManagement.ManageHostFeatures": "Host özelliklerini düzenle", + "Volo.Abp.FeatureManagement:InvalidFeatureValue" : "{0} özellik değeri geçerli değil!" } } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hans.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hans.json index 9737a9a59c..473f581b34 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hans.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hans.json @@ -4,6 +4,7 @@ "Features": "功能", "NoFeatureFoundMessage": "没有可用的功能.", "Permission:FeatureManagement": "特性管理", - "Permission:FeatureManagement.ManageHostFeatures": "管理Host特性" + "Permission:FeatureManagement.ManageHostFeatures": "管理Host特性", + "Volo.Abp.FeatureManagement:InvalidFeatureValue" : "{0}功能的值无效!" } } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hant.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hant.json index 7d68fd5bc2..dc84e7c104 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hant.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hant.json @@ -4,6 +4,7 @@ "Features": "功能", "NoFeatureFoundMessage": "沒有可用的功能.", "Permission:FeatureManagement": "功能管理", - "Permission:FeatureManagement.ManageHostFeatures": "管理Host功能" + "Permission:FeatureManagement.ManageHostFeatures": "管理Host功能", + "Volo.Abp.FeatureManagement:InvalidFeatureValue" : "{0}功能的值無效!" } } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManager.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManager.cs index 86a313fb4f..38c61cc743 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManager.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManager.cs @@ -3,10 +3,10 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Localization; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; using Volo.Abp.Features; -using Volo.Abp.Validation; namespace Volo.Abp.FeatureManagement { @@ -15,15 +15,18 @@ namespace Volo.Abp.FeatureManagement protected IFeatureDefinitionManager FeatureDefinitionManager { get; } protected List Providers => _lazyProviders.Value; protected FeatureManagementOptions Options { get; } + protected IStringLocalizerFactory StringLocalizerFactory { get; } private readonly Lazy> _lazyProviders; public FeatureManager( IOptions options, IServiceProvider serviceProvider, - IFeatureDefinitionManager featureDefinitionManager) + IFeatureDefinitionManager featureDefinitionManager, + IStringLocalizerFactory stringLocalizerFactory) { FeatureDefinitionManager = featureDefinitionManager; + StringLocalizerFactory = stringLocalizerFactory; Options = options.Value; //TODO: Instead, use IHybridServiceScopeFactory and create a scope..? @@ -131,9 +134,9 @@ namespace Volo.Abp.FeatureManagement var feature = FeatureDefinitionManager.Get(name); - if (feature.ValueType.Validator != null && !feature.ValueType.Validator.IsValid(value)) + if (!feature.ValueType.Validator.IsValid(value)) { - throw new BusinessException($"{feature.Name} value is invalid"); + throw new FeatureValueInvalidException(feature.DisplayName.Localize(StringLocalizerFactory)); } var providers = Enumerable diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml index 48143b9a5f..a289c3fd9e 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml @@ -51,9 +51,16 @@ @if (feature.ValueType is FreeTextStringValueType) { + var type = "text"; + if(feature.ValueType.Validator is NumericValueValidator) + { + type = "number"; + } + @@ -80,7 +87,7 @@
} - + }