Browse Source

Feature Management Modal improvements

pull/5361/head
liangshiwei 6 years ago
parent
commit
4852fc9e71
  1. 12
      modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManager.cs
  2. 76
      modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml
  3. 75
      modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/feature-management-modal.js

12
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<FeatureNameValueWithGrantedProvider> GetOrNullWithProviderAsync(string name, string providerName, string providerKey, bool fallback = true)
public async Task<FeatureNameValueWithGrantedProvider> 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<List<FeatureNameValueWithGrantedProvider>> GetAllWithProviderAsync(string providerName, string providerKey, bool fallback = true)
public async Task<List<FeatureNameValueWithGrantedProvider>> 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)

76
modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml

@ -14,55 +14,73 @@
<abp-modal-header title="@(L["Features"].Value)"></abp-modal-header>
@if (Model.FeatureListResultDto != null && Model.FeatureListResultDto.Groups.Any())
{
var featureGroups = Model.FeatureListResultDto.Groups;
<abp-modal-body class="ml-4">
<input asp-for="@Model.ProviderKey"/>
<input asp-for="@Model.ProviderName"/>
<abp-tabs name="FeaturesTabs" tab-style="PillVertical" vertical-header-size="_4" class="custom-scroll-container">
@for (var i = 0; i < Model.FeatureListResultDto.Groups.Count; i++)
@for (var i = 0; i < featureGroups.Count; i++)
{
<abp-tab title="@Model.FeatureListResultDto.Groups[i].DisplayName" name="v-pills-tab-@Model.FeatureListResultDto.Groups[i].GetNormalizedGroupName()">
<h4>@Model.FeatureListResultDto.Groups[i].DisplayName</h4>
<abp-tab title="@featureGroups[i].DisplayName" name="v-pills-tab-@featureGroups[i].GetNormalizedGroupName()">
<h4>@featureGroups[i].DisplayName</h4>
<hr class="mt-2 mb-3"/>
<div class="custom-scroll-content">
<div class="pl-1 pt-1">
@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);
<div class="mt-2" style="padding-left: @(feature.Depth * 20)px">
<spam class="mr-2">@feature.DisplayName @(disabled ? $"({feature.Provider.Name})" : "")</spam>
<div class="mt-2">
<input type="text" name="FeatureGroups[@i].Features[@j].ProviderName" value="@feature.Provider.Name" hidden/>
<input type="text" name="FeatureGroups[@i].Features[@j].Type" value="@feature.ValueType?.Name" hidden/>
@if (feature.ValueType is ToggleStringValueType)
{
<abp-input asp-for="@featureGroups[i].Features[j].Value"
type="checkbox"
name="FeatureGroups[@i].Features[@j].BoolValue"
label="@feature.DisplayName"
disabled="@disabled"
group-data-feature-name="@feature.Name"
group-data-parent-name="@(feature.ParentName ?? "")"
group-style="margin-left: @(feature.Depth * 20)px"/>
}
@if (feature.ValueType is FreeTextStringValueType)
{
<input type="text" name="FeatureGroups[@i].Features[@j].Name" value="@feature.Name" hidden/>
<input disabled="@disabled" type="text" name="FeatureGroups[@i].Features[@j].Value" value="@feature.Value"/>
<abp-input asp-for="@featureGroups[i].Features[j].Value"
label="@feature.DisplayName"
disabled="@disabled"
group-data-feature-name="@feature.Name"
group-data-parent-name="@(feature.ParentName ?? "")"
group-style="margin-left: @(feature.Depth * 25)px"/>
}
@if (feature.ValueType is SelectionStringValueType)
@if (feature.ValueType is SelectionStringValueType selectType)
{
<input type="text" name="FeatureGroups[@i].Features[@j].Name" value="@feature.Name" hidden/>
<select disabled="@disabled" name="FeatureGroups[@i].Features[@j].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
<div data-feature-name="@feature.Name" data-parent-name="@(feature.ParentName ?? "")" style="margin-left: @(feature.Depth * 25)px" class="form-group">
<label for="@feature.Name">@feature.DisplayName</label>
<select id="@feature.Name" name="FeatureGroups[@i].Features[@j].Value" class="custom-select form-control">
@foreach (var item in selectType.ItemSource.Items)
{
<option value="@item.Value"> @L.GetString(item.DisplayText.Name) </option>
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="FeatureGroups[@i].Features[@j].Name" value="@feature.Name" hidden/>
<input disabled="@disabled" type="checkbox" class="FeatureValueCheckbox" name="FeatureGroups[@i].Features[@j].BoolValue" value="@feature.Value"
@Html.Raw(feature.Value == "True" ? "checked" : "")/>
</select>
</div>
}
<input value="@feature.Name" name="FeatureGroups[@i].Features[@j].Name" hidden=""/>
</div>
}
</div>

75
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);

Loading…
Cancel
Save