Browse Source

Merge branch 'rel-10.4' into maliming/suite-mudblazor-docs

pull/25448/head
maliming 5 months ago
parent
commit
72b1616308
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 10
      .github/workflows/auto-pr.yml
  2. 17
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApiExploring/AbpRemoteServiceApiDescriptionProvider.cs
  3. 151
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ApiExploring/AbpRemoteServiceApiDescriptionProvider_Tests.cs
  4. 2
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/EntityChange.cs
  5. 2
      modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityUserAppService.cs
  6. 8
      modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs
  7. 22
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserManager.cs
  8. 8
      modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserClientProxy.Generated.cs
  9. 54
      modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/identity-generate-proxy.json
  10. 7
      modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/IdentityUserController.cs
  11. 4
      modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/EditModal.cshtml.cs
  12. 7
      modules/identity/src/Volo.Abp.Identity.Web/wwwroot/client-proxies/identity-proxy.js
  13. 31
      modules/identity/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/IdentityUserAppService_Tests.cs
  14. 47
      modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/IdentityUserManager_Tests.cs
  15. 7
      modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/SettingManagement.razor
  16. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/ar.json
  17. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/cs.json
  18. 3
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/de-DE.json
  19. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/de.json
  20. 3
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/el.json
  21. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/en-GB.json
  22. 3
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/en.json
  23. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/es.json
  24. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/fa.json
  25. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/fi.json
  26. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/fr.json
  27. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/hi.json
  28. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/hr.json
  29. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/hu.json
  30. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/is.json
  31. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/it.json
  32. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/nl.json
  33. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/pl-PL.json
  34. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/pt-BR.json
  35. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/ro-RO.json
  36. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/ru.json
  37. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/sk.json
  38. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/sl.json
  39. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/sv.json
  40. 3
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/tr.json
  41. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/vi.json
  42. 5
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/zh-Hans.json
  43. 3
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/zh-Hant.json
  44. 42
      modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.cshtml
  45. 39
      npm/ng-packs/packages/setting-management/src/lib/components/setting-management.component.html

10
.github/workflows/auto-pr.yml

@ -1,4 +1,4 @@
name: Merge branch dev with rel-10.4
name: Merge branch rel-10.5 with rel-10.4
on:
push:
branches:
@ -7,7 +7,7 @@ permissions:
contents: read
jobs:
merge-dev-with-rel-10-4:
merge-rel-10-5-with-rel-10-4:
permissions:
contents: write # for peter-evans/create-pull-request to create branch
pull-requests: write # for peter-evans/create-pull-request to create a PR
@ -15,7 +15,7 @@ jobs:
steps:
- uses: actions/checkout@v2
with:
ref: dev
ref: rel-10.5
- name: Reset promotion branch
run: |
git fetch origin rel-10.4:rel-10.4
@ -24,8 +24,8 @@ jobs:
uses: peter-evans/create-pull-request@v3
with:
branch: auto-merge/rel-10-4/${{github.run_number}}
title: Merge branch dev with rel-10.4
body: This PR generated automatically to merge dev with rel-10.4. Please review the changed files before merging to prevent any errors that may occur.
title: Merge branch rel-10.5 with rel-10.4
body: This PR generated automatically to merge rel-10.5 with rel-10.4. Please review the changed files before merging to prevent any errors that may occur.
draft: true
token: ${{ github.token }}
- name: Merge Pull Request

17
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApiExploring/AbpRemoteServiceApiDescriptionProvider.cs

@ -59,13 +59,20 @@ public class AbpRemoteServiceApiDescriptionProvider : IApiDescriptionProvider, I
protected virtual IEnumerable<ApiResponseType> GetApiResponseTypes()
{
foreach (var apiResponse in _options.SupportedResponseTypes)
foreach (var template in _options.SupportedResponseTypes)
{
apiResponse.ModelMetadata = _modelMetadataProvider.GetMetadataForType(apiResponse.Type!);
var apiResponse = new ApiResponseType
{
Type = template.Type,
StatusCode = template.StatusCode,
Description = template.Description,
IsDefaultResponse = template.IsDefaultResponse,
ModelMetadata = _modelMetadataProvider.GetMetadataForType(template.Type!)
};
foreach (var responseTypeMetadataProvider in _mvcOptions.OutputFormatters.OfType<IApiResponseTypeMetadataProvider>())
{
var formatterSupportedContentTypes = responseTypeMetadataProvider.GetSupportedContentTypes(null!, apiResponse.Type!);
var formatterSupportedContentTypes = responseTypeMetadataProvider.GetSupportedContentTypes(null!, template.Type!);
if (formatterSupportedContentTypes == null)
{
continue;
@ -80,8 +87,8 @@ public class AbpRemoteServiceApiDescriptionProvider : IApiDescriptionProvider, I
});
}
}
}
return _options.SupportedResponseTypes;
yield return apiResponse;
}
}
}

151
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ApiExploring/AbpRemoteServiceApiDescriptionProvider_Tests.cs

@ -0,0 +1,151 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.Extensions.Options;
using Shouldly;
using Xunit;
namespace Volo.Abp.AspNetCore.Mvc.ApiExploring;
public class AbpRemoteServiceApiDescriptionProvider_Tests
{
private static (AbpRemoteServiceApiDescriptionProvider provider,
AbpRemoteServiceApiDescriptionProviderOptions options)
CreateProvider()
{
var options = new AbpRemoteServiceApiDescriptionProviderOptions();
options.SupportedResponseTypes.Add(new ApiResponseType
{
Type = typeof(string),
StatusCode = 400
});
options.SupportedResponseTypes.Add(new ApiResponseType
{
Type = typeof(string),
StatusCode = 500
});
var mvcOptions = new MvcOptions();
mvcOptions.OutputFormatters.Add(new FakeOutputFormatter());
var provider = new AbpRemoteServiceApiDescriptionProvider(
new EmptyModelMetadataProvider(),
new OptionsWrapper<MvcOptions>(mvcOptions),
new OptionsWrapper<AbpRemoteServiceApiDescriptionProviderOptions>(options));
return (provider, options);
}
private static ApiDescriptionProviderContext CreateContext()
{
var actionDescriptor = new ControllerActionDescriptor
{
ControllerName = "Fake",
ActionName = "Get",
ControllerTypeInfo = typeof(FakeRemoteController).GetTypeInfo(),
MethodInfo = typeof(FakeRemoteController).GetMethod(nameof(FakeRemoteController.Get))!,
AttributeRouteInfo = new AttributeRouteInfo { Template = "api/fake" }
};
var description = new ApiDescription
{
ActionDescriptor = actionDescriptor,
HttpMethod = "GET",
RelativePath = "api/fake"
};
return new ApiDescriptionProviderContext(new[] { actionDescriptor })
{
Results = { description }
};
}
[Fact]
public void Should_Not_Mutate_Shared_Options_On_Repeated_Calls()
{
var (provider, options) = CreateProvider();
provider.OnProvidersExecuting(CreateContext());
provider.OnProvidersExecuting(CreateContext());
provider.OnProvidersExecuting(CreateContext());
foreach (var template in options.SupportedResponseTypes)
{
template.ApiResponseFormats.ShouldBeEmpty();
}
}
[Fact]
public void Should_Add_Response_Types_With_Preserved_Template_Fields_And_Formats()
{
var options = new AbpRemoteServiceApiDescriptionProviderOptions();
options.SupportedResponseTypes.Add(new ApiResponseType
{
Type = typeof(string),
StatusCode = 418,
Description = "I'm a teapot",
IsDefaultResponse = true
});
var mvcOptions = new MvcOptions();
mvcOptions.OutputFormatters.Add(new FakeOutputFormatter());
var provider = new AbpRemoteServiceApiDescriptionProvider(
new EmptyModelMetadataProvider(),
new OptionsWrapper<MvcOptions>(mvcOptions),
new OptionsWrapper<AbpRemoteServiceApiDescriptionProviderOptions>(options));
var context = CreateContext();
provider.OnProvidersExecuting(context);
var result = context.Results.Single();
var added = result.SupportedResponseTypes.ShouldHaveSingleItem();
added.StatusCode.ShouldBe(418);
added.Type.ShouldBe(typeof(string));
added.Description.ShouldBe("I'm a teapot");
added.IsDefaultResponse.ShouldBeTrue();
added.ModelMetadata.ShouldNotBeNull();
added.ApiResponseFormats.Select(x => x.MediaType)
.ShouldBe(new[] { "application/json", "text/json" });
}
[Fact]
public void Should_Not_Throw_Under_Concurrent_Calls()
{
var (provider, _) = CreateProvider();
var exception = Record.Exception(() =>
Parallel.For(0, 8, _ =>
{
for (var i = 0; i < 500; i++)
{
provider.OnProvidersExecuting(CreateContext());
}
}));
exception.ShouldBeNull();
}
private sealed class FakeRemoteController : IRemoteService
{
public string Get() => string.Empty;
}
private sealed class FakeOutputFormatter : IOutputFormatter, IApiResponseTypeMetadataProvider
{
public bool CanWriteResult(OutputFormatterCanWriteContext context) => true;
public Task WriteAsync(OutputFormatterWriteContext context) => Task.CompletedTask;
public IReadOnlyList<string> GetSupportedContentTypes(string? contentType, Type objectType)
=> new[] { "application/json", "text/json" };
}
}

2
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/EntityChange.cs

@ -47,7 +47,7 @@ public class EntityChange : Entity<Guid>, IMultiTenant, IHasExtraProperties
ChangeTime = entityChangeInfo.ChangeTime;
ChangeType = entityChangeInfo.ChangeType;
EntityTenantId = entityChangeInfo.EntityTenantId;
EntityId = entityChangeInfo.EntityId.Truncate(EntityChangeConsts.MaxEntityTypeFullNameLength);
EntityId = entityChangeInfo.EntityId.Truncate(EntityChangeConsts.MaxEntityIdLength);
EntityTypeFullName = entityChangeInfo.EntityTypeFullName.TruncateFromBeginning(EntityChangeConsts.MaxEntityTypeFullNameLength);
PropertyChanges = entityChangeInfo

2
modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityUserAppService.cs

@ -22,4 +22,6 @@ public interface IIdentityUserAppService
Task<IdentityUserDto> FindByUsernameAsync(string userName);
Task<IdentityUserDto> FindByEmailAsync(string email);
Task<IdentityUserDto> FindByIdAsync(Guid id);
}

8
modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs

@ -180,6 +180,14 @@ public class IdentityUserAppService : IdentityAppServiceBase, IIdentityUserAppSe
);
}
[Authorize(IdentityPermissions.Users.Default)]
public virtual async Task<IdentityUserDto> FindByIdAsync(Guid id)
{
return ObjectMapper.Map<IdentityUser, IdentityUserDto>(
await UserManager.FindByIdAsync(id.ToString())
);
}
protected virtual async Task UpdateUserByInput(IdentityUser user, IdentityUserCreateOrUpdateDtoBase input)
{
if (!string.Equals(user.Email, input.Email, StringComparison.InvariantCultureIgnoreCase))

22
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserManager.cs

@ -555,22 +555,18 @@ public class IdentityUserManager : UserManager<IdentityUser>, IDomainService
}
else if (Options.User.AllowedUserNameCharacters.Where(char.IsDigit).Distinct().Count() >= 4)
{
// The AllowedUserNameCharacters includes 4 numbers. So, we are generating 4 random numbers and appending to the username.
var numbers = Options.User.AllowedUserNameCharacters.Where(char.IsDigit).OrderBy(x => Guid.NewGuid()).Take(4).ToArray();
var minArray = numbers.OrderBy(x => x).ToArray();
if (minArray[0] == '0')
{
var secondItem = minArray[1];
minArray[0] = secondItem;
minArray[1] = '0';
}
var min = int.Parse(new string(minArray));
var max = int.Parse(new string(numbers.OrderByDescending(x => x).ToArray()));
// The AllowedUserNameCharacters includes at least 4 distinct digits. So, we are picking 4 random digits from them and appending to the username.
var allowedDigits = Options.User.AllowedUserNameCharacters.Where(char.IsDigit).Distinct().ToArray();
tryCount = 0;
do
{
var randomUserName = userName + RandomHelper.GetRandom(min, max);
if ( await ValidateUserNameAsync(randomUserName))
var randomDigits = new char[4];
for (var i = 0; i < randomDigits.Length; i++)
{
randomDigits[i] = allowedDigits[RandomHelper.GetRandom(0, allowedDigits.Length)];
}
var randomUserName = userName + new string(randomDigits);
if (await ValidateUserNameAsync(randomUserName))
{
return randomUserName;
}

8
modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/IdentityUserClientProxy.Generated.cs

@ -58,6 +58,14 @@ public partial class IdentityUserClientProxy : ClientProxyBase<IIdentityUserAppS
});
}
public virtual async Task<IdentityUserDto> FindByIdAsync(Guid id)
{
return await RequestAsync<IdentityUserDto>(nameof(FindByIdAsync), new ClientProxyRequestTypeValue
{
{ typeof(Guid), id }
});
}
public virtual async Task<ListResultDto<IdentityRoleDto>> GetRolesAsync(Guid id)
{
return await RequestAsync<ListResultDto<IdentityRoleDto>>(nameof(GetRolesAsync), new ClientProxyRequestTypeValue

54
modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/identity-generate-proxy.json

@ -487,6 +487,23 @@
"typeSimple": "Volo.Abp.Identity.IdentityUserDto"
}
},
{
"name": "FindByIdAsync",
"parametersOnMethod": [
{
"name": "id",
"typeAsString": "System.Guid, System.Private.CoreLib",
"type": "System.Guid",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null
}
],
"returnValue": {
"type": "Volo.Abp.Identity.IdentityUserDto",
"typeSimple": "Volo.Abp.Identity.IdentityUserDto"
}
},
{
"name": "GetAsync",
"parametersOnMethod": [
@ -1019,6 +1036,43 @@
},
"allowAnonymous": null,
"implementFrom": "Volo.Abp.Identity.IIdentityUserAppService"
},
"FindByIdAsyncById": {
"uniqueName": "FindByIdAsyncById",
"name": "FindByIdAsync",
"httpMethod": "GET",
"url": "api/identity/users/by-id/{id}",
"supportedVersions": [],
"parametersOnMethod": [
{
"name": "id",
"typeAsString": "System.Guid, System.Private.CoreLib",
"type": "System.Guid",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null
}
],
"parameters": [
{
"nameOnMethod": "id",
"name": "id",
"jsonName": null,
"type": "System.Guid",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": [],
"bindingSourceId": "Path",
"descriptorName": ""
}
],
"returnValue": {
"type": "Volo.Abp.Identity.IdentityUserDto",
"typeSimple": "Volo.Abp.Identity.IdentityUserDto"
},
"allowAnonymous": null,
"implementFrom": "Volo.Abp.Identity.IIdentityUserAppService"
}
}
},

7
modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/IdentityUserController.cs

@ -53,6 +53,13 @@ public class IdentityUserController : AbpControllerBase, IIdentityUserAppService
return UserAppService.DeleteAsync(id);
}
[HttpGet]
[Route("by-id/{id}")]
public virtual Task<IdentityUserDto> FindByIdAsync(Guid id)
{
return UserAppService.FindByIdAsync(id);
}
[HttpGet]
[Route("{id}/roles")]
public virtual Task<ListResultDto<IdentityRoleDto>> GetRolesAsync(Guid id)

4
modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/EditModal.cshtml.cs

@ -83,8 +83,8 @@ public class EditModalModel : IdentityPageModel
return null;
}
var user = await IdentityUserAppService.GetAsync(userId.Value);
return user.UserName;
var user = await IdentityUserAppService.FindByIdAsync(userId.Value);
return user?.UserName;
}
public virtual async Task<IActionResult> OnPostAsync()

7
modules/identity/src/Volo.Abp.Identity.Web/wwwroot/client-proxies/identity-proxy.js

@ -102,6 +102,13 @@
}, ajaxParams));
};
volo.abp.identity.identityUser.findById = function(id, ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/identity/users/by-id/' + id + '',
type: 'GET'
}, ajaxParams));
};
volo.abp.identity.identityUser.getRoles = function(id, ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/identity/users/' + id + '/roles',

31
modules/identity/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/IdentityUserAppService_Tests.cs

@ -51,6 +51,37 @@ public class IdentityUserAppService_Tests : AbpIdentityApplicationTestBase
result.PhoneNumber.ShouldBe(johnNash.PhoneNumber);
}
[Fact]
public async Task FindByIdAsync_Should_Return_User_When_Exists()
{
var johnNash = GetUser("john.nash");
var result = await _userAppService.FindByIdAsync(johnNash.Id);
result.ShouldNotBeNull();
result.Id.ShouldBe(johnNash.Id);
result.UserName.ShouldBe(johnNash.UserName);
}
[Fact]
public async Task FindByIdAsync_Should_Return_Null_When_User_Does_Not_Exist()
{
var result = await _userAppService.FindByIdAsync(Guid.NewGuid());
result.ShouldBeNull();
}
[Fact]
public async Task FindByIdAsync_Should_Return_Null_When_User_Is_Soft_Deleted()
{
var johnNash = GetUser("john.nash");
await _userAppService.DeleteAsync(johnNash.Id);
var result = await _userAppService.FindByIdAsync(johnNash.Id);
result.ShouldBeNull();
}
[Fact]
public async Task GetListAsync()
{

47
modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/IdentityUserManager_Tests.cs

@ -441,7 +441,7 @@ public class IdentityUserManager_Tests : AbpIdentityDomainTestBase
username = await _identityUserManager.GetUserNameFromEmailAsync("admin@abp.io");
username.Length.ShouldBe(9); //admin and random 4 numbers
username.ShouldContain("admin");
Regex.IsMatch(username, @"[0-4]{3}$").ShouldBeTrue();
Regex.IsMatch(username, @"[0-4]{4}$").ShouldBeTrue();
_identityUserManager.Options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyz";
username = await _identityUserManager.GetUserNameFromEmailAsync("admin@abp.io");
@ -462,6 +462,51 @@ public class IdentityUserManager_Tests : AbpIdentityDomainTestBase
Regex.IsMatch(username, @"[0-9]{4}$").ShouldBeTrue();
}
[Fact]
public async Task GetUserNameFromEmailAsync_Should_Only_Use_Allowed_Digits_When_AllowedUserNameCharacters_Has_Partial_Digits()
{
_identityUserManager.Options.User.AllowedUserNameCharacters = "admin01234";
for (var i = 0; i < 200; i++)
{
var username = await _identityUserManager.GetUserNameFromEmailAsync("admin@abp.io");
username.Length.ShouldBe(9);
username.ShouldStartWith("admin");
username.All(c => "admin01234".Contains(c)).ShouldBeTrue($"username '{username}' contains chars outside AllowedUserNameCharacters");
}
}
[Fact]
public async Task GetUserNameFromEmailAsync_Should_Only_Use_Allowed_Digits_With_Exact_Four_Digits()
{
_identityUserManager.Options.User.AllowedUserNameCharacters = "admin1234";
for (var i = 0; i < 200; i++)
{
var username = await _identityUserManager.GetUserNameFromEmailAsync("admin@abp.io");
username.Length.ShouldBe(9);
username.ShouldStartWith("admin");
username.Substring(5).All(c => "1234".Contains(c)).ShouldBeTrue($"suffix of '{username}' contains chars outside the allowed digits");
}
}
[Fact]
public async Task GetUserNameFromEmailAsync_Should_Allow_Leading_Zero_In_Random_Digits()
{
_identityUserManager.Options.User.AllowedUserNameCharacters = "admin0123";
var sawLeadingZero = false;
for (var i = 0; i < 100; i++)
{
var username = await _identityUserManager.GetUserNameFromEmailAsync("admin@abp.io");
username.Length.ShouldBe(9);
username.ShouldStartWith("admin");
username.Substring(5).All(c => "0123".Contains(c)).ShouldBeTrue($"suffix of '{username}' contains chars outside the allowed digits");
if (username[5] == '0')
{
sawLeadingZero = true;
}
}
sawLeadingZero.ShouldBeTrue("expected at least one username with leading-zero random suffix across 100 runs");
}
private async Task CreateRandomDefaultRoleAsync()
{
await _identityRoleRepository.InsertAsync(

7
modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/SettingManagement.razor

@ -44,5 +44,12 @@
</Content>
</Tabs>
}
else
{
<div class="text-center text-muted py-5">
<i class="bi bi-gear-fill" style="font-size: 3rem; opacity: 0.4;" aria-hidden="true"></i>
<p class="mt-3 mb-0">@L["NoSettingsAvailable"]</p>
</div>
}
</CardBody>
</Card>

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/ar.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "تفعيل إعداد نظام الإدارة في التطبيق.",
"Feature:AllowChangingEmailSettings": "السماح لتغيير إعدادات البريد الإلكتروني",
"Feature:AllowChangingEmailSettingsDescription": "السماح لتغيير إعدادات البريد الإلكتروني.",
"SmtpPasswordPlaceholder": "أدخل قيمة لتحديث كلمة المرور"
"SmtpPasswordPlaceholder": "أدخل قيمة لتحديث كلمة المرور",
"NoSettingsAvailable": "لا توجد إعدادات لعرضها."
}
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/cs.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "Povolit systém správy nastavení v aplikaci.",
"Feature:AllowChangingEmailSettings": "Povolit změnu nastavení e-mailu",
"Feature:AllowChangingEmailSettingsDescription": "Povolit změnu nastavení e-mailu.",
"SmtpPasswordPlaceholder": "Zadejte hodnotu pro aktualizaci hesla"
"SmtpPasswordPlaceholder": "Zadejte hodnotu pro aktualizaci hesla",
"NoSettingsAvailable": "Nejsou k dispozici žádná nastavení."
}
}
}

3
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/de-DE.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "Aktivieren Sie das Einstellungsverwaltungssystem in der Anwendung.",
"Feature:AllowChangingEmailSettings": "Änderung der E-Mail-Einstellungen zulassen",
"Feature:AllowChangingEmailSettingsDescription": "Änderung der E-Mail-Einstellungen zulassen.",
"SmtpPasswordPlaceholder": "Geben Sie einen Wert ein, um das Passwort zu aktualisieren"
"SmtpPasswordPlaceholder": "Geben Sie einen Wert ein, um das Passwort zu aktualisieren",
"NoSettingsAvailable": "Es sind keine Einstellungen anzuzeigen."
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/de.json

@ -38,6 +38,7 @@
"Feature:SettingManagementEnableDescription": "Aktivieren Sie das Einstellungsverwaltungssystem in der Anwendung.",
"Feature:AllowChangingEmailSettings": "Erlauben Sie das Ändern der E-Mail-Einstellungen",
"Feature:AllowChangingEmailSettingsDescription": "Erlauben Sie das Ändern der E-Mail-Einstellungen.",
"SmtpPasswordPlaceholder": "Geben Sie einen Wert ein, um das Passwort zu aktualisieren"
"SmtpPasswordPlaceholder": "Geben Sie einen Wert ein, um das Passwort zu aktualisieren",
"NoSettingsAvailable": "Es sind keine Einstellungen anzuzeigen."
}
}
}

3
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/el.json

@ -33,6 +33,7 @@
"Feature:SettingManagementEnableDescription": "Ενεργοποίηση συστήματος διαχείρισης ρυθμίσεων στην εφαρμογή.",
"Feature:AllowChangingEmailSettings": "Επιτρέψτε την αλλαγή των ρυθμίσεων email",
"Feature:AllowChangingEmailSettingsDescription": "Επιτρέψτε την αλλαγή των ρυθμίσεων email.",
"SmtpPasswordPlaceholder": "Εισαγάγετε μια τιμή για ενημέρωση κωδικού πρόσβασης"
"SmtpPasswordPlaceholder": "Εισαγάγετε μια τιμή για ενημέρωση κωδικού πρόσβασης",
"NoSettingsAvailable": "Δεν υπάρχουν ρυθμίσεις για εμφάνιση."
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/en-GB.json

@ -2,6 +2,7 @@
"culture": "en-GB",
"texts": {
"Settings": "Settings",
"SavedSuccessfully": "Saved successfully"
"SavedSuccessfully": "Saved successfully",
"NoSettingsAvailable": "There are no settings to display."
}
}
}

3
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/en.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "Enable setting management system in the application.",
"Feature:AllowChangingEmailSettings": "Allow changing email settings",
"Feature:AllowChangingEmailSettingsDescription": "Allow changing email settings.",
"SmtpPasswordPlaceholder": "Enter a value to update password"
"SmtpPasswordPlaceholder": "Enter a value to update password",
"NoSettingsAvailable": "There are no settings to display."
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/es.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "Habilite el sistema de gestión de la configuración en la aplicación.",
"Feature:AllowChangingEmailSettings": "Permitir cambiar la configuración de correo electrónico",
"Feature:AllowChangingEmailSettingsDescription": "Permitir cambiar la configuración de correo electrónico.",
"SmtpPasswordPlaceholder": "Ingrese un valor para actualizar la contraseña"
"SmtpPasswordPlaceholder": "Ingrese un valor para actualizar la contraseña",
"NoSettingsAvailable": "No hay ajustes para mostrar."
}
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/fa.json

@ -18,6 +18,7 @@
"DefaultFromDisplayName": "نام نمایشی ارسال کننده پیش فرض",
"Feature:SettingManagementGroup": "تنظیمات مدیریت",
"Feature:SettingManagementEnable": "فعال کردن مدیریت تنظیمات",
"Feature:SettingManagementEnableDescription": "سیستم مدیریت تنظیمات را در برنامه فعال کنید."
"Feature:SettingManagementEnableDescription": "سیستم مدیریت تنظیمات را در برنامه فعال کنید.",
"NoSettingsAvailable": "تنظیماتی برای نمایش وجود ندارد."
}
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/fi.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "Ota asetustenhallintajärjestelmä käyttöön sovelluksessa.",
"Feature:AllowChangingEmailSettings": "Salli sähköpostiasetusten muuttaminen",
"Feature:AllowChangingEmailSettingsDescription": "Salli sähköpostiasetusten muuttaminen.",
"SmtpPasswordPlaceholder": "Syötä arvo päivittääksesi salasana"
"SmtpPasswordPlaceholder": "Syötä arvo päivittääksesi salasana",
"NoSettingsAvailable": "Näytettäviä asetuksia ei ole."
}
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/fr.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "Activer le système de gestion des paramètres dans l'application.",
"Feature:AllowChangingEmailSettings": "Autoriser la modification des paramètres de messagerie",
"Feature:AllowChangingEmailSettingsDescription": "Autoriser la modification des paramètres de messagerie.",
"SmtpPasswordPlaceholder": "Entrez une valeur pour mettre à jour le mot de passe"
"SmtpPasswordPlaceholder": "Entrez une valeur pour mettre à jour le mot de passe",
"NoSettingsAvailable": "Aucun paramètre à afficher."
}
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/hi.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "एप्लिकेशन में सेटिंग प्रबंधन प्रणाली सक्षम करें।",
"Feature:AllowChangingEmailSettings": "ईमेल सेटिंग्स बदलने की अनुमति दें।",
"Feature:AllowChangingEmailSettingsDescription": "ईमेल सेटिंग्स बदलने की अनुमति दें।",
"SmtpPasswordPlaceholder": "पासवर्ड अपडेट करने के लिए एक मान दर्ज करें"
"SmtpPasswordPlaceholder": "पासवर्ड अपडेट करने के लिए एक मान दर्ज करें",
"NoSettingsAvailable": "दिखाने के लिए कोई सेटिंग नहीं है।"
}
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/hr.json

@ -38,6 +38,7 @@
"Feature:SettingManagementEnableDescription": "Omogućite sustav upravljanja postavkama u aplikaciji.",
"Feature:AllowChangingEmailSettings": "Dopusti promjenu postavki e-pošte",
"Feature:AllowChangingEmailSettingsDescription": "Dopusti promjenu postavki e-pošte.",
"SmtpPasswordPlaceholder": "Unesite vrijednost za ažuriranje lozinke"
"SmtpPasswordPlaceholder": "Unesite vrijednost za ažuriranje lozinke",
"NoSettingsAvailable": "Nema postavki za prikaz."
}
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/hu.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "A beállításkezelő rendszer engedélyezése az alkalmazásban.",
"Feature:AllowChangingEmailSettings": "Az e-mail beállítások módosításának engedélyezése",
"Feature:AllowChangingEmailSettingsDescription": "Az e-mail beállítások módosításának engedélyezése.",
"SmtpPasswordPlaceholder": "Adjon meg egy értéket a jelszó frissítéséhez"
"SmtpPasswordPlaceholder": "Adjon meg egy értéket a jelszó frissítéséhez",
"NoSettingsAvailable": "Nincs megjeleníthető beállítás."
}
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/is.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "Virkja stillingar í forritinu.",
"Feature:AllowChangingEmailSettings": "Leyfa að breyta stillingum tölvupósts",
"Feature:AllowChangingEmailSettingsDescription": "Leyfa að breyta stillingum tölvupósts.",
"SmtpPasswordPlaceholder": "Sláðu inn gildi til að uppfæra lykilorð"
"SmtpPasswordPlaceholder": "Sláðu inn gildi til að uppfæra lykilorð",
"NoSettingsAvailable": "Engar stillingar til að sýna."
}
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/it.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "Abilita sistema gestione impostazioni nell'applicazione",
"Feature:AllowChangingEmailSettings": "Consenti di modificare le loro impostazioni e-mail",
"Feature:AllowChangingEmailSettingsDescription": "Consenti di modificare le loro impostazioni e-mail.",
"SmtpPasswordPlaceholder": "Inserisci un valore per aggiornare la password"
"SmtpPasswordPlaceholder": "Inserisci un valore per aggiornare la password",
"NoSettingsAvailable": "Non ci sono impostazioni da visualizzare."
}
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/nl.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "Schakel het instellingsbeheersysteem in de toepassing in.",
"Feature:AllowChangingEmailSettings": "Toestaan om e-mailinstellingen te wijzigen",
"Feature:AllowChangingEmailSettingsDescription": "Toestaan om e-mailinstellingen te wijzigen.",
"SmtpPasswordPlaceholder": "Voer een waarde in om het wachtwoord bij te werken"
"SmtpPasswordPlaceholder": "Voer een waarde in om het wachtwoord bij te werken",
"NoSettingsAvailable": "Er zijn geen instellingen om weer te geven."
}
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/pl-PL.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "Włącz system zarządzania ustawieniami w aplikacji.",
"Feature:AllowChangingEmailSettings": "Zezwól na zmianę ustawień poczty e-mail",
"Feature:AllowChangingEmailSettingsDescription": "Zezwól na zmianę ustawień poczty e-mail.",
"SmtpPasswordPlaceholder": "Wprowadź wartość, aby zaktualizować hasło"
"SmtpPasswordPlaceholder": "Wprowadź wartość, aby zaktualizować hasło",
"NoSettingsAvailable": "Brak ustawień do wyświetlenia."
}
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/pt-BR.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "Habilite o sistema de gerenciamento de configuração no aplicativo.",
"Feature:AllowChangingEmailSettings": "Permitir alterar as configurações de e-mail",
"Feature:AllowChangingEmailSettingsDescription": "Permitir alterar as configurações de e-mail.",
"SmtpPasswordPlaceholder": "Digite um valor para atualizar a senha"
"SmtpPasswordPlaceholder": "Digite um valor para atualizar a senha",
"NoSettingsAvailable": "Não há configurações para exibir."
}
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/ro-RO.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "Activează sistemul de administrare a setărilor în aplicaţie.",
"Feature:AllowChangingEmailSettings": "Permiteți modificarea setărilor de e-mail",
"Feature:AllowChangingEmailSettingsDescription": "Permiteți modificarea setărilor de e-mail.",
"SmtpPasswordPlaceholder": "Introduceți o valoare pentru a actualiza parola"
"SmtpPasswordPlaceholder": "Introduceți o valoare pentru a actualiza parola",
"NoSettingsAvailable": "Nu există setări de afișat."
}
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/ru.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "Включите систему управления настройками в приложении.",
"Feature:AllowChangingEmailSettings": "Разрешить изменение настроек электронной почты",
"Feature:AllowChangingEmailSettingsDescription": "Разрешить изменение настроек электронной почты.",
"SmtpPasswordPlaceholder": "Введите значение для обновления пароля"
"SmtpPasswordPlaceholder": "Введите значение для обновления пароля",
"NoSettingsAvailable": "Нет настроек для отображения."
}
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/sk.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "Povoliť systém správy nastavení v aplikácii.",
"Feature:AllowChangingEmailSettings": "Povoliť zmenu nastavení e-mailu",
"Feature:AllowChangingEmailSettingsDescription": "Povoliť zmenu nastavení e-mailu.",
"SmtpPasswordPlaceholder": "Zadajte hodnotu pre aktualizáciu hesla"
"SmtpPasswordPlaceholder": "Zadajte hodnotu pre aktualizáciu hesla",
"NoSettingsAvailable": "Nie sú k dispozícii žiadne nastavenia."
}
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/sl.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "Omogočite nastavitev sistema upravljanja v aplikaciji.",
"Feature:AllowChangingEmailSettings": "Dovoli spreminjanje e-poštnih nastavitev",
"Feature:AllowChangingEmailSettingsDescription": "Dovoli spreminjanje e-poštnih nastavitev.",
"SmtpPasswordPlaceholder": "Vnesite vrednost za posodobitev gesla"
"SmtpPasswordPlaceholder": "Vnesite vrednost za posodobitev gesla",
"NoSettingsAvailable": "Ni nastavitev za prikaz."
}
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/sv.json

@ -36,6 +36,7 @@
"Feature:SettingManagementEnableDescription": "Aktivera inställningshanteringssystem i applikationen.",
"Feature:AllowChangingEmailSettings": "Tillåt ändring av e-postinställningar",
"Feature:AllowChangingEmailSettingsDescription": "Tillåt ändring av e-postinställningar.",
"SmtpPasswordPlaceholder": "Ange ett värde för att uppdatera lösenordet"
"SmtpPasswordPlaceholder": "Ange ett värde för att uppdatera lösenordet",
"NoSettingsAvailable": "Det finns inga inställningar att visa."
}
}
}

3
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/tr.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "Uygulamada ayar yönetim sistemini etkinleştirin.",
"Feature:AllowChangingEmailSettings": "E-posta ayarlarını değiştirmeye izin verin",
"Feature:AllowChangingEmailSettingsDescription": "E-posta ayarlarını değiştirmeye izin verin.",
"SmtpPasswordPlaceholder": "Şifreyi güncellemek için bir değer girin"
"SmtpPasswordPlaceholder": "Şifreyi güncellemek için bir değer girin",
"NoSettingsAvailable": "Görüntülenecek ayar yok."
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/vi.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "Bật cài đặt hệ thống quản lý trong ứng dụng.",
"Feature:AllowChangingEmailSettings": "Cho phép thay đổi cài đặt email",
"Feature:AllowChangingEmailSettingsDescription": "Cho phép thay đổi cài đặt email.",
"SmtpPasswordPlaceholder": "Nhập một giá trị để cập nhật mật khẩu"
"SmtpPasswordPlaceholder": "Nhập một giá trị để cập nhật mật khẩu",
"NoSettingsAvailable": "Không có cài đặt nào để hiển thị."
}
}
}

5
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/zh-Hans.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "在应用程序中启用设置管理系统。",
"Feature:AllowChangingEmailSettings": "允许更改邮件设置",
"Feature:AllowChangingEmailSettingsDescription": "允许更改邮件设置。",
"SmtpPasswordPlaceholder": "输入一个值以更新密码"
"SmtpPasswordPlaceholder": "输入一个值以更新密码",
"NoSettingsAvailable": "没有可显示的设置。"
}
}
}

3
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/zh-Hant.json

@ -37,6 +37,7 @@
"Feature:SettingManagementEnableDescription": "在應用程序中啟用設定管理系統.",
"Feature:AllowChangingEmailSettings": "允許更改電子郵件設置",
"Feature:AllowChangingEmailSettingsDescription": "允許更改電子郵件設置。",
"SmtpPasswordPlaceholder": "輸入一個值以更新密碼"
"SmtpPasswordPlaceholder": "輸入一個值以更新密碼",
"NoSettingsAvailable": "沒有可顯示的設定。"
}
}

42
modules/setting-management/src/Volo.Abp.SettingManagement.Web/Pages/SettingManagement/Index.cshtml

@ -25,24 +25,34 @@
<div id="SettingManagementWrapper">
<abp-card>
<abp-card-body>
<div class="row">
<div class="col-md-3">
<ul class="nav flex-column nav-pills" id="tabs-nav" role="tablist">
@for (var i = 0; i < Model.SettingPageCreationContext.Groups.Count; i++)
{
var group = Model.SettingPageCreationContext.Groups[i];
var active = i == 0 ? "active" : string.Empty;
<li class="nav-item">
<a href="javascript:;" class="nav-link @active" data-id="@group.Id" data-bs-toggle="pill" role="tab">@group.DisplayName</a>
</li>
}
</ul>
</div>
<div class="col-md-9">
<div class="tab-content pt-0" id="tab-content">
@if (Model.SettingPageCreationContext.Groups.Count > 0)
{
<div class="row">
<div class="col-md-3">
<ul class="nav flex-column nav-pills" id="tabs-nav" role="tablist">
@for (var i = 0; i < Model.SettingPageCreationContext.Groups.Count; i++)
{
var group = Model.SettingPageCreationContext.Groups[i];
var active = i == 0 ? "active" : string.Empty;
<li class="nav-item">
<a href="javascript:;" class="nav-link @active" data-id="@group.Id" data-bs-toggle="pill" role="tab">@group.DisplayName</a>
</li>
}
</ul>
</div>
<div class="col-md-9">
<div class="tab-content pt-0" id="tab-content">
</div>
</div>
</div>
</div>
}
else
{
<div class="text-center text-muted py-5">
<i class="bi bi-gear-fill" style="font-size: 3rem; opacity: 0.4;" aria-hidden="true"></i>
<p class="mt-3 mb-0">@L["NoSettingsAvailable"]</p>
</div>
}
</abp-card-body>
</abp-card>
</div>

39
npm/ng-packs/packages/setting-management/src/lib/components/setting-management.component.html

@ -2,28 +2,33 @@
<div id="SettingManagementWrapper">
<div class="card">
<div class="card-body">
<div class="row" ngTabs>
<div class="col-12 col-md-3 mb-2 mb-md-0">
<div class="nav flex-column nav-pills" id="nav-tab" ngTabList orientation="vertical"
[selectedTab]="selected?.name">
@if (settings.length) {
<div class="row" ngTabs>
<div class="col-12 col-md-3 mb-2 mb-md-0">
<div class="nav flex-column nav-pills" id="nav-tab" ngTabList orientation="vertical"
[selectedTab]="selected?.name">
<ng-container *abpFor="let setting of settings; trackBy: trackByFn">
<button ngTab #tab="ngTab" [value]="setting.name" (click)="selected = setting"
class="nav-link text-start" [class.active]="tab.selected()" *abpPermission="setting.requiredPolicy">
{{ setting.name | abpLocalization }}
</button>
</ng-container>
</div>
</div>
<div class="col-12 col-md-9">
<ng-container *abpFor="let setting of settings; trackBy: trackByFn">
<button ngTab #tab="ngTab" [value]="setting.name" (click)="selected = setting"
class="nav-link text-start" [class.active]="tab.selected()" *abpPermission="setting.requiredPolicy">
{{ setting.name | abpLocalization }}
</button>
<div ngTabPanel [value]="setting.name" class="tab-pane" *abpPermission="setting.requiredPolicy">
<ng-container *ngComponentOutlet="setting.component" />
</div>
</ng-container>
</div>
</div>
<div class="col-12 col-md-9">
@if (settings.length) {
<ng-container *abpFor="let setting of settings; trackBy: trackByFn">
<div ngTabPanel [value]="setting.name" class="tab-pane" *abpPermission="setting.requiredPolicy">
<ng-container *ngComponentOutlet="setting.component" />
</div>
</ng-container>
}
} @else {
<div class="text-center text-muted py-5">
<i class="bi bi-gear-fill" style="font-size: 3rem; opacity: 0.4;" aria-hidden="true"></i>
<p class="mt-3 mb-0">{{ 'AbpSettingManagement::NoSettingsAvailable' | abpLocalization }}</p>
</div>
</div>
}
</div>
</div>
</div>

Loading…
Cancel
Save