pull/926/head
Alper Ebicoglu 6 years ago
commit 77b414967a

@ -14,7 +14,7 @@
@using (Html.BeginForm(FormMethod.Post))
{
<div class="row border">
<div class="col p-5 ">
<div class="col-lg-7 p-5 ">
<h2>
<span class="text-primary">Create</span>
<span class="text-success">New Project</span>
@ -64,7 +64,7 @@
</div>
</div>
<div class="col-md-5 bg-light p-5">
<div class="col-lg-5 bg-light p-5">
<h4>The Startup Project</h4>
<p>See <a href="/documents/abp/latest/Getting-Started-AspNetCore-MVC-Template" target="_blank">the documentation</a> to understand how to run the downloaded project.</p>

@ -37,6 +37,7 @@ namespace Volo.AbpWebSite.Templates
if (context.Request.DatabaseProvider != DatabaseProvider.EntityFrameworkCore)
{
steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.EntityFrameworkCore"));
steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations"));
steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Application.Tests", projectFolderPath: "test/MyCompanyName.MyProjectName.Application.Tests"));
steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web.Tests", projectFolderPath: "test/MyCompanyName.MyProjectName.Web.Tests"));
}

@ -0,0 +1,20 @@
using System;
using System.Linq;
using Volo.Utils.SolutionTemplating.Files;
namespace Volo.Utils.SolutionTemplating.Building
{
public static class ProjectBuildContextExtensions
{
public static FileEntry GetFile(this ProjectBuildContext context, string filePath)
{
var file = context.Files.FirstOrDefault(f => f.Name == filePath);
if (file == null)
{
throw new ApplicationException("Could not find file: " + filePath);
}
return file;
}
}
}

@ -1,22 +1,7 @@
using System;
using System.Linq;
using Volo.Utils.SolutionTemplating.Files;
namespace Volo.Utils.SolutionTemplating.Building
namespace Volo.Utils.SolutionTemplating.Building
{
public abstract class ProjectBuildPipelineStep
{
public abstract void Execute(ProjectBuildContext context);
protected FileEntry GetFile(ProjectBuildContext context, string filePath)
{
var file = context.Files.FirstOrDefault(f => f.Name == filePath);
if (file == null)
{
throw new ApplicationException("Could not find file: " + filePath);
}
return file;
}
}
}

@ -23,7 +23,7 @@ namespace Volo.Utils.SolutionTemplating.Building.Steps
public override void Execute(ProjectBuildContext context)
{
context.Files.RemoveAll(file => file.Name.StartsWith(_projectFolderPath));
var solutionFile = GetFile(context, _solutionFilePath);
var solutionFile = context.GetFile(_solutionFilePath);
solutionFile.NormalizeLineEndings();
solutionFile.SetLines(RemoveProject(solutionFile.GetLines().ToList()));
}

@ -14,7 +14,7 @@ namespace Volo.Utils.SolutionTemplating.Building.Steps
private void ChangeProjectReference(ProjectBuildContext context)
{
var file = GetFile(context, "/src/MyCompanyName.MyProjectName.Web/MyCompanyName.MyProjectName.Web.csproj");
var file = context.GetFile("/src/MyCompanyName.MyProjectName.Web/MyCompanyName.MyProjectName.Web.csproj");
file.NormalizeLineEndings();
@ -29,12 +29,12 @@ namespace Volo.Utils.SolutionTemplating.Building.Steps
}
}
throw new ApplicationException("Could not find the 'Default' connection string in appsettings.json file!");
throw new ApplicationException("Could not find the EntityFrameworkCore reference in the MyCompanyName.MyProjectName.Web.csproj!");
}
private void ChangeWebModuleUsage(ProjectBuildContext context)
{
var file = GetFile(context, "/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs");
var file = context.GetFile("/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs");
file.NormalizeLineEndings();
@ -59,7 +59,7 @@ namespace Volo.Utils.SolutionTemplating.Building.Steps
private void ChangeConnectionString(ProjectBuildContext context)
{
var file = GetFile(context, "/src/MyCompanyName.MyProjectName.Web/appsettings.json");
var file = context.GetFile("/src/MyCompanyName.MyProjectName.Web/appsettings.json");
file.NormalizeLineEndings();

@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Features;

@ -0,0 +1,23 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Localization;
namespace Volo.Abp.AspNetCore.Mvc.Client
{
public class RemoteLanguageProvider : ILanguageProvider, ITransientDependency
{
protected ICachedApplicationConfigurationClient ConfigurationClient { get; }
public RemoteLanguageProvider(ICachedApplicationConfigurationClient configurationClient)
{
ConfigurationClient = configurationClient;
}
public async Task<IReadOnlyList<LanguageInfo>> GetLanguagesAsync()
{
var configuration = await ConfigurationClient.GetAsync();
return configuration.Localization.Languages;
}
}
}

@ -1,9 +1,16 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
{
[Serializable]
public class ApplicationFeatureConfigurationDto
{
public Dictionary<string, string> Values { get; set; }
public ApplicationFeatureConfigurationDto()
{
Values = new Dictionary<string, string>();
}
}
}

@ -1,16 +1,21 @@
using System;
using System.Collections.Generic;
using Volo.Abp.Localization;
namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
{
[Serializable]
public class ApplicationLocalizationConfigurationDto
{
//TODO: Rename to Texts?
public Dictionary<string, Dictionary<string, string>> Values { get; set; }
public List<LanguageInfo> Languages { get; set; }
public ApplicationLocalizationConfigurationDto()
{
Values = new Dictionary<string, Dictionary<string, string>>();
Languages = new List<LanguageInfo>();
}
}
}

@ -1,5 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap

@ -1,5 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Packages;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling;

@ -338,6 +338,23 @@
}
}
configuration.language = {
info: localize("PagerInfo"),
infoFiltered: localize("PagerInfoFiltered"),
infoEmpty: localize("PagerInfoEmpty"),
search: localize("PagerSearch"),
processing: localize("ProcessingWithThreeDot"),
loadingRecords: localize("LoadingWithThreeDot"),
lengthMenu: localize("PagerShowMenuEntries"),
emptyTable: localize("NoDataAvailableInDatatable"),
paginate: {
first: localize("PagerFirst"),
last: localize("PagerLast"),
previous: localize("PagerPrevious"),
next: localize("PagerNext")
}
};
configuration.dom = '<"dataTable_filters"f>rt<"row dataTable_footer"<"col-auto"l><"col-auto"i><"col"p>>';
return configuration;

@ -24,6 +24,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
private readonly ISettingProvider _settingProvider;
private readonly ISettingDefinitionManager _settingDefinitionManager;
private readonly IFeatureDefinitionManager _featureDefinitionManager;
private readonly ILanguageProvider _languageProvider;
public AbpApplicationConfigurationAppService(
IOptions<AbpLocalizationOptions> localizationOptions,
@ -33,7 +34,8 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
ICurrentUser currentUser,
ISettingProvider settingProvider,
SettingDefinitionManager settingDefinitionManager,
IFeatureDefinitionManager featureDefinitionManager)
IFeatureDefinitionManager featureDefinitionManager,
ILanguageProvider languageProvider)
{
_serviceProvider = serviceProvider;
_abpAuthorizationPolicyProvider = abpAuthorizationPolicyProvider;
@ -42,6 +44,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
_settingProvider = settingProvider;
_settingDefinitionManager = settingDefinitionManager;
_featureDefinitionManager = featureDefinitionManager;
_languageProvider = languageProvider;
_localizationOptions = localizationOptions.Value;
}
@ -53,7 +56,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
{
Auth = await GetAuthConfigAsync(),
Features = await GetFeaturesConfigAsync(),
Localization = GetLocalizationConfig(),
Localization = await GetLocalizationConfigAsync(),
CurrentUser = GetCurrentUser(),
Setting = await GetSettingConfigAsync()
};
@ -87,10 +90,12 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
return authConfig;
}
protected virtual ApplicationLocalizationConfigurationDto GetLocalizationConfig()
protected virtual async Task<ApplicationLocalizationConfigurationDto> GetLocalizationConfigAsync()
{
var localizationConfig = new ApplicationLocalizationConfigurationDto();
localizationConfig.Languages.AddRange(await _languageProvider.GetLanguagesAsync());
foreach (var resource in _localizationOptions.Resources.Values)
{
var dictionary = new Dictionary<string, string>();
@ -104,8 +109,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
dictionary[localizedString.Name] = localizedString.Value;
}
var resourceName = LocalizationResourceNameAttribute.GetName(resource.ResourceType);
localizationConfig.Values[resourceName] = dictionary;
localizationConfig.Values[resource.ResourceName] = dictionary;
}
return localizationConfig;
@ -133,10 +137,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
protected virtual async Task<ApplicationFeatureConfigurationDto> GetFeaturesConfigAsync()
{
var result = new ApplicationFeatureConfigurationDto
{
Values = new Dictionary<string, string>()
};
var result = new ApplicationFeatureConfigurationDto();
foreach (var featureDefinition in _featureDefinitionManager.GetAll())
{

@ -10,7 +10,6 @@ namespace Volo.Abp.BackgroundWorkers
)]
public class AbpBackgroundWorkersModule : AbpModule
{
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var options = context.ServiceProvider.GetRequiredService<IOptions<BackgroundWorkerOptions>>().Value;

@ -1,5 +1,4 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
@ -70,11 +69,12 @@ namespace Volo.Abp.Caching
}
catch (Exception ex)
{
if ((bool) hideErrors)
if (hideErrors == true)
{
Logger.LogException(ex, LogLevel.Warning);
return null;
}
throw;
}
@ -94,11 +94,14 @@ namespace Volo.Abp.Caching
try
{
cachedBytes = await Cache.GetAsync(NormalizeKey(key), CancellationTokenProvider.FallbackToProvider(token));
cachedBytes = await Cache.GetAsync(
NormalizeKey(key),
CancellationTokenProvider.FallbackToProvider(token)
);
}
catch (Exception ex)
{
if ((bool)hideErrors)
if (hideErrors == true)
{
Logger.LogException(ex, LogLevel.Warning);
return null;
@ -185,7 +188,7 @@ namespace Volo.Abp.Caching
}
catch (Exception ex)
{
if ((bool) hideErrors)
if (hideErrors == true)
{
Logger.LogException(ex, LogLevel.Warning);
return;
@ -210,7 +213,7 @@ namespace Volo.Abp.Caching
}
catch (Exception ex)
{
if ((bool)hideErrors)
if (hideErrors == true)
{
Logger.LogException(ex, LogLevel.Warning);
return;
@ -230,7 +233,7 @@ namespace Volo.Abp.Caching
}
catch (Exception ex)
{
if ((bool) hideErrors)
if (hideErrors == true)
{
Logger.LogException(ex, LogLevel.Warning);
return;
@ -250,7 +253,7 @@ namespace Volo.Abp.Caching
}
catch (Exception ex)
{
if ((bool)hideErrors)
if (hideErrors == true)
{
Logger.LogException(ex, LogLevel.Warning);
return;
@ -270,7 +273,7 @@ namespace Volo.Abp.Caching
}
catch (Exception ex)
{
if ((bool) hideErrors)
if (hideErrors == true)
{
Logger.LogException(ex, LogLevel.Warning);
}
@ -289,7 +292,7 @@ namespace Volo.Abp.Caching
}
catch (Exception ex)
{
if ((bool)hideErrors)
if (hideErrors == true)
{
Logger.LogException(ex, LogLevel.Warning);
return;

@ -19,6 +19,7 @@
<ProjectReference Include="..\Volo.Abp.Ddd.Domain\Volo.Abp.Ddd.Domain.csproj" />
<ProjectReference Include="..\Volo.Abp.Features\Volo.Abp.Features.csproj" />
<ProjectReference Include="..\Volo.Abp.Http.Abstractions\Volo.Abp.Http.Abstractions.csproj" />
<ProjectReference Include="..\Volo.Abp.Localization\Volo.Abp.Localization.csproj" />
<ProjectReference Include="..\Volo.Abp.ObjectMapping\Volo.Abp.ObjectMapping.csproj" />
<ProjectReference Include="..\Volo.Abp.Security\Volo.Abp.Security.csproj" />
<ProjectReference Include="..\Volo.Abp.Settings\Volo.Abp.Settings.csproj" />

@ -1,16 +1,18 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Aspects;
using Volo.Abp.Auditing;
using Volo.Abp.Authorization;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Features;
using Volo.Abp.Guids;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
using Volo.Abp.ObjectMapping;
using Volo.Abp.Settings;
@ -21,8 +23,8 @@ using Volo.Abp.Validation;
namespace Volo.Abp.Application.Services
{
public abstract class ApplicationService :
IApplicationService,
public abstract class ApplicationService :
IApplicationService,
IAvoidDuplicateCrossCuttingConcerns,
IValidationEnabled,
IUnitOfWorkEnabled,
@ -53,6 +55,22 @@ namespace Volo.Abp.Application.Services
public IFeatureChecker FeatureChecker { get; set; }
public IStringLocalizerFactory StringLocalizerFactory { get; set; }
public IStringLocalizer L => _localizer ?? (_localizer = StringLocalizerFactory.Create(LocalizationResource));
private IStringLocalizer _localizer;
protected Type LocalizationResource
{
get => _localizationResource;
set
{
_localizationResource = value;
_localizer = null;
}
}
private Type _localizationResource = typeof(DefaultResource);
protected IUnitOfWork CurrentUnitOfWork => UnitOfWorkManager?.Current;
protected ILogger Logger => _lazyLogger.Value;

@ -20,7 +20,7 @@ namespace Volo.Abp.Features
public override async Task<string> GetOrNullAsync(FeatureDefinition feature)
{
var editionId = PrincipalAccessor.Principal.FindEditionId();
var editionId = PrincipalAccessor.Principal?.FindEditionId();
if (editionId == null)
{
return null;

@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
@ -210,6 +212,9 @@ namespace Volo.Abp.Http.Client.DynamicProxying
//CorrelationId
requestMessage.Headers.Add(CorrelationIdOptions.HttpHeaderName, CorrelationIdProvider.Get());
//TODO: Is that the way we want? Couldn't send the culture (not ui culture)
requestMessage.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(CultureInfo.CurrentUICulture.Name));
}
private string GetConfiguredApiVersion()

@ -8,7 +8,7 @@ using Microsoft.Extensions.Localization;
namespace Volo.Abp.Localization
{
public class AbpDictionaryBasedStringLocalizer : IStringLocalizer
public class AbpDictionaryBasedStringLocalizer : IStringLocalizer, IStringLocalizerSupportsInheritance
{
public LocalizationResource Resource { get; }
@ -26,7 +26,20 @@ namespace Volo.Abp.Localization
public IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures)
{
return GetAllStrings(CultureInfo.CurrentUICulture.Name, includeParentCultures);
return GetAllStrings(
CultureInfo.CurrentUICulture.Name,
includeParentCultures
);
}
public IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures, bool includeBaseLocalizers)
{
return GetAllStrings(
CultureInfo.CurrentUICulture.Name,
includeParentCultures,
includeBaseLocalizers
);
}
public IStringLocalizer WithCulture(CultureInfo culture)
@ -109,26 +122,32 @@ namespace Volo.Abp.Localization
return null;
}
protected virtual IReadOnlyList<LocalizedString> GetAllStrings(string cultureName, bool includeParentCultures = true)
protected virtual IReadOnlyList<LocalizedString> GetAllStrings(
string cultureName,
bool includeParentCultures = true,
bool includeBaseLocalizers = true)
{
//TODO: Can be optimized (example: if it's already default dictionary, skip overriding)
var allStrings = new Dictionary<string, LocalizedString>();
foreach (var baseLocalizer in BaseLocalizers.Select(l => l.WithCulture(CultureInfo.GetCultureInfo(cultureName))))
if (includeBaseLocalizers)
{
//TODO: Try/catch is a workaround here!
try
foreach (var baseLocalizer in BaseLocalizers.Select(l => l.WithCulture(CultureInfo.GetCultureInfo(cultureName))))
{
var baseLocalizedString = baseLocalizer.GetAllStrings(includeParentCultures);
foreach (var localizedString in baseLocalizedString)
//TODO: Try/catch is a workaround here!
try
{
allStrings[localizedString.Name] = localizedString;
var baseLocalizedString = baseLocalizer.GetAllStrings(includeParentCultures);
foreach (var localizedString in baseLocalizedString)
{
allStrings[localizedString.Name] = localizedString;
}
}
}
catch (MissingManifestResourceException)
{
catch (MissingManifestResourceException)
{
}
}
}
@ -160,7 +179,7 @@ namespace Volo.Abp.Localization
: cultureName;
}
public class CultureWrapperStringLocalizer : IStringLocalizer
public class CultureWrapperStringLocalizer : IStringLocalizer, IStringLocalizerSupportsInheritance
{
private readonly string _cultureName;
private readonly AbpDictionaryBasedStringLocalizer _innerLocalizer;
@ -184,6 +203,11 @@ namespace Volo.Abp.Localization
{
return new CultureWrapperStringLocalizer(culture.Name, _innerLocalizer);
}
public IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures, bool includeBaseLocalizers)
{
return _innerLocalizer.GetAllStrings(_cultureName, includeParentCultures, includeBaseLocalizers);
}
}
}
}

@ -23,9 +23,14 @@ namespace Volo.Abp.Localization
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<AbpValidationResource>("en")
.AddVirtualJson("/Localization/Resources/AbpValidation");
options
.Resources
.Add<DefaultResource>("en");
options
.Resources
.Add<AbpValidationResource>("en")
.AddVirtualJson("/Localization/Resources/AbpValidation");
});
}
}

@ -0,0 +1,58 @@
using System.Collections.Generic;
using System.Reflection;
using JetBrains.Annotations;
using Microsoft.Extensions.Localization;
using Volo.Abp.DynamicProxy;
using Volo.Abp.Reflection;
namespace Volo.Abp.Localization
{
public static class AbpStringLocalizerExtensions
{
[NotNull]
public static IStringLocalizer GetInternalLocalizer(
[NotNull] this IStringLocalizer stringLocalizer)
{
Check.NotNull(stringLocalizer, nameof(stringLocalizer));
var localizerType = stringLocalizer.GetType();
if (!ReflectionHelper.IsAssignableToGenericType(localizerType, typeof(StringLocalizer<>)))
{
return stringLocalizer;
}
var localizerField = localizerType
.GetField(
"_localizer",
BindingFlags.Instance |
BindingFlags.NonPublic
);
if (localizerField == null)
{
throw new AbpException($"Could not find the _localizer field inside the {typeof(StringLocalizer<>).FullName} class. Probably its name has changed. Please report this issue to the ABP framework.");
}
return localizerField.GetValue(stringLocalizer) as IStringLocalizer;
}
public static IEnumerable<LocalizedString> GetAllStrings(
this IStringLocalizer stringLocalizer,
bool includeParentCultures,
bool includeBaseLocalizers)
{
var internalLocalizer = (ProxyHelper.UnProxy(stringLocalizer) as IStringLocalizer).GetInternalLocalizer();
if (internalLocalizer is IStringLocalizerSupportsInheritance stringLocalizerSupportsInheritance)
{
return stringLocalizerSupportsInheritance.GetAllStrings(
includeParentCultures,
includeBaseLocalizers
);
}
return stringLocalizer.GetAllStrings(
includeParentCultures
);
}
}
}

@ -0,0 +1,8 @@
namespace Volo.Abp.Localization
{
[LocalizationResourceName("Default")]
public class DefaultResource
{
}
}

@ -0,0 +1,10 @@
using System.Collections.Generic;
using Microsoft.Extensions.Localization;
namespace Volo.Abp.Localization
{
public interface IStringLocalizerSupportsInheritance
{
IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures, bool includeBaseLocalizers);
}
}

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
@ -13,6 +13,11 @@
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="Volo\Abp\Ui\Navigation\Localization\Resource\*.json" />
<Content Remove="Volo\Abp\Ui\Navigation\Localization\Resource\*.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.UI\Volo.Abp.UI.csproj" />
</ItemGroup>

@ -1,10 +1,32 @@
using Volo.Abp.Modularity;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.Ui.Navigation;
using Volo.Abp.Ui.Navigation.Localization.Resource;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.UI.Navigation
{
[DependsOn(typeof(AbpUiModule))]
public class AbpUiNavigationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<VirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpUiNavigationModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<AbpUiNavigationResource>("en")
.AddVirtualJson("/Volo/Abp/Ui/Navigation/Localization/Resource");
});
Configure<NavigationOptions>(options =>
{
options.MenuContributors.Add(new DefaultMenuContributor());
});
}
}
}

@ -1,5 +1,5 @@
using System.Collections.Generic;
using JetBrains.Annotations;
using Volo.Abp.Ui.Navigation;
namespace Volo.Abp.UI.Navigation
{
@ -29,11 +29,11 @@ namespace Volo.Abp.UI.Navigation
/// <inheritdoc cref="IHasMenuItems.Items"/>
[NotNull]
public IList<ApplicationMenuItem> Items { get; } //TODO: Create a specialized collection (that can contain AddAfter for example)
public ApplicationMenuItemList Items { get; }
/// <summary>
/// Can be used to store a custom object related to this menu.
/// TODO: Conver to dictionary!
/// TODO: Convert to dictionary!
/// </summary>
[CanBeNull]
public object CustomData { get; set; }
@ -47,7 +47,7 @@ namespace Volo.Abp.UI.Navigation
Name = name;
DisplayName = displayName ?? Name;
Items = new List<ApplicationMenuItem>();
Items = new ApplicationMenuItemList();
}
/// <summary>
@ -60,5 +60,10 @@ namespace Volo.Abp.UI.Navigation
Items.Add(menuItem);
return this;
}
public override string ToString()
{
return $"[ApplicationMenu] Name = {Name}";
}
}
}

@ -0,0 +1,59 @@
using JetBrains.Annotations;
using System.Linq;
using Volo.Abp.Ui.Navigation;
namespace Volo.Abp.UI.Navigation
{
public static class ApplicationMenuExtensions
{
[NotNull]
public static ApplicationMenuItem GetAdministration(
[NotNull] this ApplicationMenu applicationMenu)
{
return applicationMenu.GetMenuItem(
DefaultMenuNames.Application.Main.Administration
);
}
[NotNull]
public static ApplicationMenuItem GetMenuItem(
[NotNull] this IHasMenuItems menuWithItems,
string menuItemName)
{
var menuItem = menuWithItems.GetMenuItemOrNull(menuItemName);
if (menuItem == null)
{
throw new AbpException($"Could not find a menu item with given name: {menuItemName}");
}
return menuItem;
}
[CanBeNull]
public static ApplicationMenuItem GetMenuItemOrNull(
[NotNull] this IHasMenuItems menuWithItems,
string menuItemName)
{
Check.NotNull(menuWithItems, nameof(menuWithItems));
return menuWithItems.Items.FirstOrDefault(mi => mi.Name == menuItemName);
}
[NotNull]
public static IHasMenuItems SetSubItemOrder(
[NotNull] this IHasMenuItems menuWithItems,
string menuItemName,
int order)
{
Check.NotNull(menuWithItems, nameof(menuWithItems));
var menuItem = menuWithItems.GetMenuItemOrNull(menuItemName);
if (menuItem != null)
{
menuItem.Order = order;
}
return menuWithItems;
}
}
}

@ -1,5 +1,6 @@
using System.Collections.Generic;
using JetBrains.Annotations;
using Volo.Abp.Ui.Navigation;
namespace Volo.Abp.UI.Navigation
{
@ -68,7 +69,7 @@ namespace Volo.Abp.UI.Navigation
/// <inheritdoc cref="IHasMenuItems.Items"/>
[NotNull]
public IList<ApplicationMenuItem> Items { get; }
public ApplicationMenuItemList Items { get; }
/// <summary>
/// Can be used to store a custom object related to this menu item. Optional.
@ -109,7 +110,7 @@ namespace Volo.Abp.UI.Navigation
ElementId = elementId ?? GetDefaultElementId();
CssClass = cssClass;
Items = new List<ApplicationMenuItem>();
Items = new ApplicationMenuItemList();
}
/// <summary>
@ -127,5 +128,10 @@ namespace Volo.Abp.UI.Navigation
{
return "MenuItem_" + Name;
}
public override string ToString()
{
return $"[ApplicationMenuItem] Name = {Name}";
}
}
}

@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Volo.Abp.UI.Navigation;
namespace Volo.Abp.Ui.Navigation
{
public class ApplicationMenuItemList : List<ApplicationMenuItem>
{
public ApplicationMenuItemList()
{
}
public ApplicationMenuItemList(int capacity)
: base(capacity)
{
}
public ApplicationMenuItemList(IEnumerable<ApplicationMenuItem> collection)
: base(collection)
{
}
public void Normalize()
{
RemoveEmptyItems();
Order();
}
private void RemoveEmptyItems()
{
RemoveAll(item => item.IsLeaf && item.Url.IsNullOrEmpty());
}
private void Order()
{
//TODO: Is there any way that is more performant?
var orderedItems = this.OrderBy(item => item.Order).ToArray();
Clear();
AddRange(orderedItems);
}
}
}

@ -0,0 +1,34 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using System.Threading.Tasks;
using Volo.Abp.Ui.Navigation.Localization.Resource;
using Volo.Abp.UI.Navigation;
namespace Volo.Abp.Ui.Navigation
{
public class DefaultMenuContributor : IMenuContributor
{
public virtual Task ConfigureMenuAsync(MenuConfigurationContext context)
{
Configure(context);
return Task.CompletedTask;
}
protected virtual void Configure(MenuConfigurationContext context)
{
var l = context.ServiceProvider
.GetRequiredService<IStringLocalizer<AbpUiNavigationResource>>();
if (context.Menu.Name == StandardMenus.Main)
{
context.Menu.AddItem(
new ApplicationMenuItem(
DefaultMenuNames.Application.Main.Administration,
l["Menu:Administration"],
icon: "fa fa-wrench"
)
);
}
}
}
}

@ -0,0 +1,13 @@
namespace Volo.Abp.Ui.Navigation
{
public static class DefaultMenuNames
{
public static class Application
{
public static class Main
{
public const string Administration = "Abp.Application.Main.Administration";
}
}
}
}

@ -1,4 +1,4 @@
using System.Collections.Generic;
using Volo.Abp.Ui.Navigation;
namespace Volo.Abp.UI.Navigation
{
@ -7,6 +7,6 @@ namespace Volo.Abp.UI.Navigation
/// <summary>
/// Menu items.
/// </summary>
IList<ApplicationMenuItem> Items { get; }
ApplicationMenuItemList Items { get; }
}
}

@ -0,0 +1,10 @@
using Volo.Abp.Localization;
namespace Volo.Abp.Ui.Navigation.Localization.Resource
{
[LocalizationResourceName("AbpUiNavigation")]
public class AbpUiNavigationResource
{
}
}

@ -0,0 +1,6 @@
{
"culture": "en",
"texts": {
"Menu:Administration": "Administration"
}
}

@ -0,0 +1,6 @@
{
"culture": "tr",
"texts": {
"Menu:Administration": "Yönetim"
}
}

@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
@ -9,26 +9,26 @@ namespace Volo.Abp.UI.Navigation
{
public class MenuManager : IMenuManager, ITransientDependency
{
private readonly NavigationOptions _options;
private readonly IServiceProvider _serviceProvider;
protected NavigationOptions Options { get; }
protected IHybridServiceScopeFactory ServiceScopeFactory { get; }
public MenuManager(
IOptions<NavigationOptions> options,
IServiceProvider serviceProvider)
IHybridServiceScopeFactory serviceScopeFactory)
{
_serviceProvider = serviceProvider;
_options = options.Value;
ServiceScopeFactory = serviceScopeFactory;
Options = options.Value;
}
public async Task<ApplicationMenu> GetAsync(string name)
{
var menu = new ApplicationMenu(name);
using (var scope = _serviceProvider.CreateScope())
using (var scope = ServiceScopeFactory.CreateScope())
{
var context = new MenuConfigurationContext(menu, scope.ServiceProvider);
foreach (var contributor in _options.MenuContributors)
foreach (var contributor in Options.MenuContributors)
{
await contributor.ConfigureMenuAsync(context);
}
@ -39,9 +39,14 @@ namespace Volo.Abp.UI.Navigation
return menu;
}
protected virtual void NormalizeMenu(ApplicationMenu menu)
protected virtual void NormalizeMenu(IHasMenuItems menuWithItems)
{
menu.Items.RemoveAll(item => item.IsLeaf && item.Url.IsNullOrEmpty());
foreach (var menuItem in menuWithItems.Items)
{
NormalizeMenu(menuItem);
}
menuWithItems.Items.Normalize();
}
}
}

@ -2,6 +2,12 @@ namespace Volo.Abp.UI.Navigation
{
public static class StandardMenus
{
/* TODO: Consider to create nested class like
* StandardMenus.Application.Main
* StandardMenus.Application.User
* StandardMenus.Application.Shortcut
*/
public const string Main = "Main";
public const string User = "User";
public const string Shortcut = "Shortcut";

@ -2,6 +2,7 @@
namespace Localization.Resources.AbpUi
{
//TODO: Move to the Volo.Abp.UI.Localization.Resource folder
[LocalizationResourceName("AbpUi")]
public class AbpUiResource
{

@ -25,14 +25,23 @@
"Delete": "Delete",
"Edit": "Edit",
"ProcessingWithThreeDot": "Processing...",
"LoadingWithThreeDot": "Loading...",
"Welcome": "Welcome",
"Login": "Login",
"Register": "Register",
"Logout": "Log out",
"Submit": "Submit",
"Back": "Back",
"PagerSearch": "Search",
"PagerNext": "Next",
"PagerPrevious": "Previous",
"PagerInfo": "Showing {0} to {1} of {2} entries.",
"PagerFirst": "First",
"PagerLast": "Last",
"PagerInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
"PagerInfoEmpty": "Showing 0 to 0 of 0 entries",
"PagerInfoFiltered": "(filtered from _MAX_ total entries)",
"NoDataAvailableInDatatable": "No data available in table",
"PagerShowMenuEntries": "Show _MENU_ entries",
"DatatableActionDropdownDefaultText": "Actions",
"ChangePassword": "Change password",
"PersonalInfo": "My profile"

@ -25,14 +25,23 @@
"Delete": "Sil",
"Edit": "Düzenle",
"ProcessingWithThreeDot": "İşleniyor...",
"LoadingWithThreeDot": "Yükleniyor...",
"Welcome": "Hoşgeldiniz",
"Login": "Giriş",
"Register": "Kaydol",
"Logout": ıkış",
"Submit": "Gönder",
"Back": "Geri",
"PagerSearch": "Ara",
"PagerNext": "Sonraki",
"PagerPrevious": "Önceki",
"PagerInfo": "{2} kayıttan {0} ile {1} arası gösteriliyor.",
"PagerFirst": "İlk",
"PagerLast": "Son",
"PagerInfo": "_TOTAL_ kayıttan _START_ ile _END_ arası gösteriliyor.",
"PagerInfoEmpty": "0 kayıttan 0 ile 0 arası gösteriliyor.",
"PagerInfoFiltered": "(_MAX_ kayıt arasından filtrelendi)",
"NoDataAvailableInDatatable": "Tabloda kayır mevcut değil.",
"PagerShowMenuEntries": "Sayfada _MENU_ kayıt göster.",
"DatatableActionDropdownDefaultText": "İşlemler",
"ChangePassword": "Şifre değiştir",
"PersonalInfo": "Profilim"

@ -25,14 +25,23 @@
"Delete": "删除",
"Edit": "修改",
"ProcessingWithThreeDot": "处理中...",
"LoadingWithThreeDot": "加载中...",
"Welcome": "欢迎",
"Login": "登录",
"Register": "注册",
"Logout": "注销",
"Submit": "提交",
"Back": "返回",
"PagerSearch": "搜索",
"PagerNext": "下一页",
"PagerPrevious": "上一页",
"PagerFirst": "首页",
"PagerLast": "尾页",
"PagerInfo": "显示 {0} 到 {1} 个 {2} 条目.",
"PagerInfoEmpty": "显示0个条目中的0到0",
"PagerInfoFiltered": "(从 _MAX_ 总条目中过滤掉)",
"NoDataAvailableInDatatable": "表中没有数据",
"PagerShowMenuEntries": "显示 _MENU_ 实体",
"DatatableActionDropdownDefaultText": "操作",
"ChangePassword": "修改密码",
"PersonalInfo": "个人信息"

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
@ -15,6 +15,7 @@
<ItemGroup>
<EmbeddedResource Include="Localization\**\*.json" />
<Content Remove="Localization\**\*.json" />
</ItemGroup>
<ItemGroup>

@ -20,7 +20,9 @@ namespace Volo.Abp.UI
Configure<AbpLocalizationOptions>(options =>
{
options.Resources.Add<AbpUiResource>("en").AddVirtualJson("/Localization/Resources/AbpUi");
options.Resources
.Add<AbpUiResource>("en")
.AddVirtualJson("/Localization/Resources/AbpUi");
});
}
}

@ -20,9 +20,9 @@ namespace Volo.Abp.Features
{
_settingRecords = new List<SettingRecord>
{
new SettingRecord("BooleanTestFeature1", TenantFeatureValueProvider.ProviderName, Tenant1Id.ToString(), "true"),
new SettingRecord("BooleanTestFeature2", TenantFeatureValueProvider.ProviderName, Tenant1Id.ToString(), "true"),
new SettingRecord("IntegerTestFeature1", TenantFeatureValueProvider.ProviderName, Tenant2Id.ToString(), "34")
new SettingRecord("BooleanTestFeature1", TenantFeatureValueProvider.ProviderName, Tenant1Id.ToString("N"), "true"),
new SettingRecord("BooleanTestFeature2", TenantFeatureValueProvider.ProviderName, Tenant1Id.ToString("N"), "true"),
new SettingRecord("IntegerTestFeature1", TenantFeatureValueProvider.ProviderName, Tenant2Id.ToString("N"), "34")
};
}

@ -1,4 +1,5 @@
using System.Globalization;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using Shouldly;
@ -14,10 +15,28 @@ namespace Volo.Abp.Localization
public class AbpLocalization_Tests : AbpIntegratedTest<AbpLocalization_Tests.TestModule>
{
private readonly IStringLocalizer<LocalizationTestResource> _localizer;
private readonly IStringLocalizerFactory _localizerFactory;
public AbpLocalization_Tests()
{
_localizer = GetRequiredService<IStringLocalizer<LocalizationTestResource>>();
_localizerFactory = GetRequiredService<IStringLocalizerFactory>();
}
[Fact]
public void AbpStringLocalizerExtensions_GetInternalLocalizer()
{
var internalLocalizer = _localizer.GetInternalLocalizer();
internalLocalizer.ShouldNotBeNull();
internalLocalizer.ShouldBeOfType<AbpDictionaryBasedStringLocalizer>();
}
[Fact]
public void AbpStringLocalizerExtensions_GetInternalLocalizer_Using_LocalizerFactory()
{
var internalLocalizer = _localizerFactory.Create(typeof(LocalizationTestResource)).GetInternalLocalizer();
internalLocalizer.ShouldNotBeNull();
internalLocalizer.ShouldBeOfType<AbpDictionaryBasedStringLocalizer>();
}
[Fact]
@ -104,6 +123,102 @@ namespace Volo.Abp.Localization
_localizer.WithCulture(CultureInfo.GetCultureInfo("tr"))["CarPlural"].Value.ShouldBe("Araba");
}
[Fact]
public void GetAllStrings_With_Parents()
{
using (AbpCultureHelper.Use("tr"))
{
var localizedStrings = _localizer.GetAllStrings(true).ToList();
localizedStrings.ShouldContain(
ls => ls.Name == "FortyTwo" &&
ls.Value == "Forty Two" &&
ls.ResourceNotFound == false
);
localizedStrings.ShouldContain(
ls => ls.Name == "Universe" &&
ls.Value == "Evren" &&
ls.ResourceNotFound == false
);
}
}
[Fact]
public void GetAllStrings_Without_Parents()
{
using (AbpCultureHelper.Use("tr"))
{
var localizedStrings = _localizer.GetAllStrings(false).ToList();
localizedStrings.ShouldNotContain(
ls => ls.Name == "FortyTwo"
);
localizedStrings.ShouldContain(
ls => ls.Name == "Universe" &&
ls.Value == "Evren" &&
ls.ResourceNotFound == false
);
}
}
[Fact]
public void GetAllStrings_With_Inheritance()
{
using (AbpCultureHelper.Use("tr"))
{
var localizedStrings = _localizer
.GetAllStrings(true, includeBaseLocalizers: true)
.ToList();
localizedStrings.ShouldContain(
ls => ls.Name == "USA" &&
ls.Value == "Amerika Birleşik Devletleri" &&
ls.ResourceNotFound == false
);
localizedStrings.ShouldContain(
ls => ls.Name == "Universe" &&
ls.Value == "Evren" &&
ls.ResourceNotFound == false
);
localizedStrings.ShouldContain(
ls => ls.Name == "SeeYou" &&
ls.Value == "See you" &&
ls.ResourceNotFound == false
);
}
}
[Fact]
public void GetAllStrings_Without_Inheritance()
{
using (AbpCultureHelper.Use("tr"))
{
var localizedStrings = _localizer
.GetAllStrings(true, includeBaseLocalizers: false)
.ToList();
localizedStrings.ShouldNotContain(
ls => ls.Name == "USA"
);
localizedStrings.ShouldContain(
ls => ls.Name == "Universe" &&
ls.Value == "Evren" &&
ls.ResourceNotFound == false
);
localizedStrings.ShouldContain(
ls => ls.Name == "SeeYou" &&
ls.Value == "See you" &&
ls.ResourceNotFound == false
);
}
}
[DependsOn(typeof(AbpTestBaseModule))]
[DependsOn(typeof(AbpLocalizationModule))]
public class TestModule : AbpModule
@ -117,10 +232,21 @@ namespace Volo.Abp.Localization
Configure<AbpLocalizationOptions>(options =>
{
options.Resources.Add<LocalizationTestValidationResource>("en").AddVirtualJson("/Volo/Abp/Localization/TestResources/Base/Validation");
options.Resources.Add<LocalizationTestCountryNamesResource>("en").AddVirtualJson("/Volo/Abp/Localization/TestResources/Base/CountryNames");
options.Resources.Add<LocalizationTestResource>("en").AddVirtualJson("/Volo/Abp/Localization/TestResources/Source");
options.Resources.Get<LocalizationTestResource>().AddVirtualJson("/Volo/Abp/Localization/TestResources/SourceExt");
options.Resources
.Add<LocalizationTestValidationResource>("en")
.AddVirtualJson("/Volo/Abp/Localization/TestResources/Base/Validation");
options.Resources
.Add<LocalizationTestCountryNamesResource>("en")
.AddVirtualJson("/Volo/Abp/Localization/TestResources/Base/CountryNames");
options.Resources
.Add<LocalizationTestResource>("en")
.AddVirtualJson("/Volo/Abp/Localization/TestResources/Source");
options.Resources
.Get<LocalizationTestResource>()
.AddVirtualJson("/Volo/Abp/Localization/TestResources/SourceExt");
});
}
}

@ -3,8 +3,10 @@ using Volo.Abp.Localization.TestResources.Base.Validation;
namespace Volo.Abp.Localization.TestResources.Source
{
[InheritResource(typeof(LocalizationTestValidationResource))]
[InheritResource(typeof(LocalizationTestCountryNamesResource))]
[InheritResource(
typeof(LocalizationTestValidationResource),
typeof(LocalizationTestCountryNamesResource)
)]
public sealed class LocalizationTestResource
{

@ -5,6 +5,7 @@
"Car": "Car",
"CarPlural": "Cars",
"MaxLenghtErrorMessage": "This field's length can be maximum of '{0}' chars",
"Universe": "Universe"
"Universe": "Universe",
"FortyTwo": "Forty Two"
}
}

@ -2,7 +2,7 @@
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Volo.Abp.Modularity;
using System.Collections.Generic;
using Volo.Abp.Ui.Navigation;
using Xunit;
namespace Volo.Abp.UI.Navigation
@ -25,10 +25,13 @@ namespace Volo.Abp.UI.Navigation
mainMenu.DisplayName.ShouldBe("Main Menu");
mainMenu.Items.Count.ShouldBe(2);
mainMenu.Items[0].Name.ShouldBe("Dashboard");
mainMenu.Items[1].Name.ShouldBe("Administration");
mainMenu.Items[1].Name.ShouldBe(DefaultMenuNames.Application.Main.Administration);
mainMenu.Items[1].Items[0].Name.ShouldBe("Administration.UserManagement");
mainMenu.Items[1].Items[1].Name.ShouldBe("Administration.RoleManagement");
mainMenu.Items[1].Items[2].Name.ShouldBe("Administration.DashboardSettings");
mainMenu.Items[1].Items[3].Name.ShouldBe("Administration.SubMenu1");
mainMenu.Items[1].Items[3].Items[0].Name.ShouldBe("Administration.SubMenu1.1");
mainMenu.Items[1].Items[3].Items[1].Name.ShouldBe("Administration.SubMenu1.2");
}
[DependsOn(typeof(AbpUiNavigationModule))]
@ -60,10 +63,7 @@ namespace Volo.Abp.UI.Navigation
context.Menu.DisplayName = "Main Menu";
var administration = context.Menu.Items.GetOrAdd(
m => m.Name == "Administration",
() => new ApplicationMenuItem("Administration", "Administration")
);
var administration = context.Menu.GetAdministration();
administration.AddItem(new ApplicationMenuItem("Administration.UserManagement", "User Management", url: "/admin/users"));
administration.AddItem(new ApplicationMenuItem("Administration.RoleManagement", "Role Management", url: "/admin/roles"));
@ -88,13 +88,16 @@ namespace Volo.Abp.UI.Navigation
context.Menu.Items.Insert(0, new ApplicationMenuItem("Dashboard", "Dashboard", url: "/dashboard"));
var administration = context.Menu.Items.GetOrAdd(
m => m.Name == "Administration",
() => new ApplicationMenuItem("Administration", "Administration")
);
var administration = context.Menu.GetAdministration();
administration.AddItem(new ApplicationMenuItem("Administration.DashboardSettings", "Dashboard Settings", url: "/admin/settings/dashboard"));
administration.AddItem(
new ApplicationMenuItem("Administration.SubMenu1", "Sub menu 1")
.AddItem(new ApplicationMenuItem("Administration.SubMenu1.1", "Sub menu 1.1", url: "/submenu1/submenu1_1"))
.AddItem(new ApplicationMenuItem("Administration.SubMenu1.2", "Sub menu 1.2", url: "/submenu1/submenu1_2"))
);
return Task.CompletedTask;
}
}

@ -47,6 +47,12 @@ namespace Volo.Abp.Account.Web.Areas.Account.Controllers
{
ValidateLoginInfo(login);
var identityUser = await _userManager.FindByNameAsync(login.UserNameOrEmailAddress);
if (identityUser == null)
{
return new AbpLoginResult(LoginResultType.InvalidUserNameOrPassword);
}
return GetAbpLoginResult(await _signInManager.CheckPasswordSignInAsync(identityUser, login.Password, true));
}

@ -11,12 +11,12 @@
"InvalidUserNameOrPassword": "用户名或密码错误!",
"LoginIsNotAllowed": "无法登录!你需要验证邮箱地址/手机号.",
"SelfRegistrationDisabledMessage": "应用程序未开放注册,请联系管理员添加新用户.",
"Login": "Login",
"Cancel": "Cancel",
"Register": "Register",
"UseAnotherServiceToLogIn.": "Use another service to log in.",
"InvalidLoginRequest": "Invalid login request",
"ThereAreNoLoginSchemesConfiguredForThisClient": "There are no login schemes configured for this client.",
"LogInUsingYourProviderAccount": "Log in using your {0} account"
"Login": "登录",
"Cancel": "取消",
"Register": "注册",
"UseAnotherServiceToLogIn.": "使用其他服务登录.",
"InvalidLoginRequest": "登录请求无效",
"ThereAreNoLoginSchemesConfiguredForThisClient": "没有为此客户端配置登录方案.",
"LogInUsingYourProviderAccount": "使用您的{0}帐户登录"
}
}

@ -20,6 +20,7 @@ namespace Volo.Abp.AuditLogging
string correlationId = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false,
CancellationToken cancellationToken = default);
@ -32,6 +33,7 @@ namespace Volo.Abp.AuditLogging
string correlationId = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
CancellationToken cancellationToken = default);
}

@ -30,11 +30,12 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
string correlationId = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = GetListQuery(httpMethod, url, userName, applicationName, correlationId, maxExecutionDuration, minExecutionDuration, httpStatusCode, includeDetails);
var query = GetListQuery(httpMethod, url, userName, applicationName, correlationId, maxExecutionDuration, minExecutionDuration, hasException, httpStatusCode, includeDetails);
var auditLogs = await query.OrderBy(sorting ?? "executionTime desc")
.PageBy(skipCount, maxResultCount)
@ -51,10 +52,11 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
string correlationId = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
CancellationToken cancellationToken = default)
{
var query = GetListQuery(httpMethod, url, userName, applicationName, correlationId, maxExecutionDuration, minExecutionDuration, httpStatusCode);
var query = GetListQuery(httpMethod, url, userName, applicationName, correlationId, maxExecutionDuration, minExecutionDuration, hasException, httpStatusCode);
var totalCount = await query.LongCountAsync();
@ -69,11 +71,14 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
string correlationId = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false)
{
return DbSet.AsNoTracking()
.IncludeDetails(includeDetails)
.WhereIf(hasException.HasValue && hasException.Value, auditLog => auditLog.Exceptions != null && auditLog.Exceptions.Length > 0)
.WhereIf(hasException.HasValue && !hasException.Value, auditLog => auditLog.Exceptions == null || auditLog.Exceptions.Length == 0)
.WhereIf(httpMethod != null, auditLog => auditLog.HttpMethod != null && auditLog.HttpMethod.ToLowerInvariant() == httpMethod.ToLowerInvariant())
.WhereIf(url != null, auditLog => auditLog.Url != null && auditLog.Url.ToLowerInvariant().Contains(url.ToLowerInvariant()))
.WhereIf(userName != null, auditLog => auditLog.UserName != null && auditLog.UserName.ToLowerInvariant() == userName.ToLowerInvariant())

@ -31,11 +31,12 @@ namespace Volo.Abp.AuditLogging.MongoDB
string correlationId = null,
int? maxDuration = null,
int? minDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = GetListQuery(httpMethod, url, userName, applicationName, correlationId, maxDuration, minDuration, httpStatusCode, includeDetails);
var query = GetListQuery(httpMethod, url, userName, applicationName, correlationId, maxDuration, minDuration, hasException, httpStatusCode, includeDetails);
return await query.OrderBy(sorting ?? "executionTime desc").As<IMongoQueryable<AuditLog>>()
.PageBy<AuditLog, IMongoQueryable<AuditLog>>(skipCount, maxResultCount)
@ -50,10 +51,11 @@ namespace Volo.Abp.AuditLogging.MongoDB
string correlationId = null,
int? maxDuration = null,
int? minDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
CancellationToken cancellationToken = default)
{
var query = GetListQuery(httpMethod, url, userName, applicationName, correlationId, maxDuration, minDuration, httpStatusCode);
var query = GetListQuery(httpMethod, url, userName, applicationName, correlationId, maxDuration, minDuration, hasException, httpStatusCode);
var count = await query.As<IMongoQueryable<AuditLog>>().LongCountAsync();
@ -68,10 +70,13 @@ namespace Volo.Abp.AuditLogging.MongoDB
string correlationId = null,
int? maxDuration = null,
int? minDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false)
{
return GetMongoQueryable()
.WhereIf(hasException.HasValue && hasException.Value, auditLog => auditLog.Exceptions != null && auditLog.Exceptions.Length > 0)
.WhereIf(hasException.HasValue && !hasException.Value, auditLog => auditLog.Exceptions == null || auditLog.Exceptions.Length == 0)
.WhereIf(httpMethod != null, auditLog => auditLog.HttpMethod != null && auditLog.HttpMethod.ToLowerInvariant() == httpMethod.ToLowerInvariant())
.WhereIf(url != null, auditLog => auditLog.Url != null && auditLog.Url.ToLowerInvariant().Contains(url.ToLowerInvariant()))
.WhereIf(userName != null, auditLog => auditLog.UserName != null && auditLog.UserName.ToLowerInvariant() == userName.ToLowerInvariant())
@ -79,7 +84,7 @@ namespace Volo.Abp.AuditLogging.MongoDB
.WhereIf(correlationId != null, auditLog => auditLog.CorrelationId != null && auditLog.CorrelationId.ToLowerInvariant() == correlationId.ToLowerInvariant())
.WhereIf(httpStatusCode != null && httpStatusCode > 0, auditLog => auditLog.HttpStatusCode == (int?)httpStatusCode)
.WhereIf(maxDuration != null && maxDuration > 0, auditLog => auditLog.ExecutionDuration <= maxDuration)
.WhereIf(minDuration != null && minDuration > 0, auditLog => auditLog.ExecutionDuration >= minDuration); ;
.WhereIf(minDuration != null && minDuration > 0, auditLog => auditLog.ExecutionDuration >= minDuration);
}
}
}

@ -228,8 +228,9 @@ namespace Volo.Blogging.Posts
{
tag.IncreaseUsageCount();
tag = await _tagRepository.UpdateAsync(tag);
post.AddTag(tag.Id);
}
post.AddTag(tag.Id);
}
}

@ -27,7 +27,7 @@ namespace Volo.Blogging.EntityFrameworkCore
{
b.ToTable(options.TablePrefix + "Users", options.Schema);
b.ConfigureAbpUser(options);
b.ConfigureAbpUser();
b.ConfigureExtraProperties();
});

@ -0,0 +1,10 @@
{
"culture": "zh-Hans",
"texts": {
"Permission:DocumentManagement": "文档管理",
"Permission:Projects": "项目",
"Permission:Edit": "编辑",
"Permission:Delete": "删除",
"Permission:Create": "创建"
}
}

@ -0,0 +1,26 @@
{
"culture": "zh-Hans",
"texts": {
"Menu:DocumentManagement": "文档",
"Menu:ProjectManagement": "项目",
"CreateANewProject": "创建新项目",
"Edit": "编辑",
"Create": "创建",
"Projects": "项目",
"Name": "名称",
"ShortName": "简称",
"DocumentStoreType": "文件存储类型",
"Format": "格式",
"ShortNameInfoText": "将用于唯一的URL.",
"DisplayName:Name": "名称",
"DisplayName:ShortName": "简称",
"DisplayName:Format": "格式",
"DisplayName:DefaultDocumentName": "默认文档名称",
"DisplayName:NavigationDocumentName": "导航文档名称",
"DisplayName:MinimumVersion": "最低版本",
"DisplayName:MainWebsiteUrl": "主网站网址",
"DisplayName:LatestVersionBranchName": "最新版本的分支名称",
"DisplayName:GitHubRootUrl": "GitHub根网址",
"DisplayName:GitHubAccessToken": "GitHub访问令牌"
}
}

@ -2,14 +2,17 @@
"culture": "zh-Hans",
"texts": {
"Documents": "文档",
"BackToWebsite": "返回网站",
"BackToWebsite": "返回主网站",
"Contributors": "贡献者",
"ShareOn": "分享到",
"Version": "版本",
"Edit": "编辑",
"InThisDocument": "在这个文档中",
"GoToTop": "返回顶部",
"Delete": "删除",
"InThisDocument": "在本文中",
"GoToTop": "到顶部",
"Projects": "项目",
"NoProjectWarning": "当前并没有项目!",
"DocumentNotFound": "抱歉,您请求的文档不存在!",
"NavigationDocumentNotFound": "此版本并没有导航文档!"
"NoProjectWarning": "没有项目!",
"DocumentNotFound": "找不到请求的文档!",
"NavigationDocumentNotFound": "这个版本没有导航文件!"
}
}

@ -7,6 +7,7 @@ using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement;
using Volo.Abp.Users;
using Volo.Abp.VirtualFileSystem;
using Volo.Abp.Localization.ExceptionHandling;
namespace Volo.Abp.Identity
{
@ -32,6 +33,11 @@ namespace Volo.Abp.Identity
.Get<IdentityResource>()
.AddVirtualJson("/Volo/Abp/Identity/Localization/ApplicationContracts");
});
Configure<ExceptionLocalizationOptions>(options =>
{
options.MapCodeNamespace("Volo.Abp.Identity", typeof(IdentityResource));
});
}
}
}

@ -14,7 +14,5 @@ namespace Volo.Abp.Identity
Task<IdentityUserDto> FindByUsernameAsync(string username);
Task<IdentityUserDto> FindByEmailAsync(string email);
Task ChangePasswordAsync(string currentPassword, string newPassword);
}
}

@ -8,5 +8,7 @@ namespace Volo.Abp.Identity
Task<ProfileDto> GetAsync();
Task<ProfileDto> UpdateAsync(UpdateProfileDto input);
Task ChangePasswordAsync(string currentPassword, string newPassword);
}
}

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Volo.Abp.Identity
{
public static class IdentityErrorCodes
{
public const string UserSelfDeletion = "Volo.Abp.Identity:010001";
}
}

@ -1,6 +1,7 @@
{
"culture": "en",
"texts": {
"Volo.Abp.Identity:010001": "You can not delete your own account!",
"Permission:IdentityManagement": "Identity management",
"Permission:RoleManagement": "Role management",
"Permission:Create": "Create",

@ -1,6 +1,7 @@
{
"culture": "tr",
"texts": {
"Volo.Abp.Identity:010001": "Kendi hesabınızı silemezsiniz!",
"Permission:IdentityManagement": "Kimlik yönetimi",
"Permission:RoleManagement": "Rol yönetimi",
"Permission:Create": "Oluşturma",

@ -1,12 +1,14 @@
{
"culture": "zh-Hans",
"texts": {
"Permission:IdentityManagement": "身份认证管理",
"Volo.Abp.Identity:010001": "您无法删除自己的帐户!",
"Permission:IdentityManagement": "身份标识管理",
"Permission:RoleManagement": "角色管理",
"Permission:Create": "创建",
"Permission:Edit": "编辑",
"Permission:Delete": "删除",
"Permission:ChangePermissions": "更改权限",
"Permission:UserManagement": "用户管理"
"Permission:UserManagement": "用户管理",
"Permission:UserLookup": "用户查询"
}
}

@ -80,6 +80,11 @@ namespace Volo.Abp.Identity
[Authorize(IdentityPermissions.Users.Delete)]
public async Task DeleteAsync(Guid id)
{
if (CurrentUser.Id == id)
{
throw new BusinessException(code: IdentityErrorCodes.UserSelfDeletion);
}
var user = await _userManager.FindByIdAsync(id.ToString());
if (user == null)
{
@ -113,18 +118,6 @@ namespace Volo.Abp.Identity
);
}
//TODO: Move this to the profile service!
public async Task ChangePasswordAsync(string currentPassword, string newPassword)
{
if (!CurrentUser.Id.HasValue)
{
throw new AbpException("Current user Id is null!");
}
var currentUser = await _userManager.GetByIdAsync(CurrentUser.Id.Value);
(await _userManager.ChangePasswordAsync(currentUser, currentPassword, newPassword)).CheckErrors();
}
private async Task UpdateUserByInput(IdentityUser user, IdentityUserCreateOrUpdateDtoBase input)
{
(await _userManager.SetEmailAsync(user, input.Email)).CheckErrors();

@ -49,5 +49,11 @@ namespace Volo.Abp.Identity
return ObjectMapper.Map<IdentityUser, ProfileDto>(user);
}
public async Task ChangePasswordAsync(string currentPassword, string newPassword)
{
var currentUser = await _userManager.GetByIdAsync(CurrentUser.GetId());
(await _userManager.ChangePasswordAsync(currentUser, currentPassword, newPassword)).CheckErrors();
}
}
}

@ -17,6 +17,12 @@
<EmbeddedResource Include="Volo\Abp\Identity\Localization\Domain\*.json" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Volo\Abp\Permissions\**" />
<EmbeddedResource Remove="Volo\Abp\Permissions\**" />
<None Remove="Volo\Abp\Permissions\**" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Identity.Domain.Shared\Volo.Abp.Identity.Domain.Shared.csproj" />
@ -29,8 +35,4 @@
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Volo\Abp\Permissions\" />
</ItemGroup>
</Project>

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Volo.Abp.DependencyInjection;
@ -53,7 +52,7 @@ namespace Volo.Abp.Identity
adminUser = new IdentityUser(_guidGenerator.Create(), adminUserName, "admin@abp.io", tenantId);
adminUser.Name = adminUserName;
CheckIdentityErrors(await _userManager.CreateAsync(adminUser, adminUserPassword));
(await _userManager.CreateAsync(adminUser, adminUserPassword)).CheckErrors();
result.CreatedAdminUser = true;
//"admin" role
@ -65,24 +64,13 @@ namespace Volo.Abp.Identity
adminRole.IsStatic = true;
adminRole.IsPublic = true;
CheckIdentityErrors(await _roleManager.CreateAsync(adminRole));
(await _roleManager.CreateAsync(adminRole)).CheckErrors();
result.CreatedAdminRole = true;
}
CheckIdentityErrors(await _userManager.AddToRoleAsync(adminUser, adminRoleName));
(await _userManager.AddToRoleAsync(adminUser, adminRoleName)).CheckErrors();
return result;
}
protected void CheckIdentityErrors(IdentityResult identityResult) //TODO: This is temporary and duplicate code!
{
if (!identityResult.Succeeded)
{
//TODO: A better exception that can be shown on UI as localized?
throw new AbpException("Operation failed: " + identityResult.Errors.Select(e => $"[{e.Code}] {e.Description}").JoinAsString(", "));
}
//identityResult.CheckErrors(LocalizationManager); //TODO: Get from old Abp
}
}
}

@ -25,7 +25,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
b.ConfigureFullAudited();
b.ConfigureExtraProperties();
b.ConfigureConcurrencyStamp();
b.ConfigureAbpUser(options);
b.ConfigureAbpUser();
b.Property(u => u.NormalizedUserName).IsRequired().HasMaxLength(IdentityUserConsts.MaxNormalizedUserNameLength).HasColumnName(nameof(IdentityUser.NormalizedUserName));
b.Property(u => u.NormalizedEmail).HasMaxLength(IdentityUserConsts.MaxNormalizedEmailLength).HasColumnName(nameof(IdentityUser.NormalizedEmail));

@ -64,10 +64,5 @@ namespace Volo.Abp.Identity
{
return _userAppService.FindByEmailAsync(email);
}
public Task ChangePasswordAsync(string currentPassword, string newPassword)
{
return _userAppService.ChangePasswordAsync(currentPassword, newPassword);
}
}
}

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc;
@ -27,5 +24,10 @@ namespace Volo.Abp.Identity
{
return _profileAppService.UpdateAsync(input);
}
public Task ChangePasswordAsync(string currentPassword, string newPassword)
{
return _profileAppService.ChangePasswordAsync(currentPassword, newPassword);
}
}
}

@ -16,11 +16,13 @@ namespace Volo.Abp.Identity.Web.Navigation
return;
}
var administrationMenu = context.Menu.GetAdministration();
var authorizationService = context.ServiceProvider.GetRequiredService<IAuthorizationService>();
var l = context.ServiceProvider.GetRequiredService<IStringLocalizer<IdentityResource>>();
var identityMenuItem = new ApplicationMenuItem(IdentityMenuNames.GroupName, l["Menu:IdentityManagement"], icon: "fa fa-id-card-o");
context.Menu.AddItem(identityMenuItem);
administrationMenu.AddItem(identityMenuItem);
if (await authorizationService.IsGrantedAsync(IdentityPermissions.Roles.Default))
{

@ -12,13 +12,14 @@ namespace Volo.Abp.Identity.Web.Pages.Identity.Shared
[BindProperty]
public ChangePasswordInfoModel ChangePasswordInfoModel { get; set; }
private readonly IIdentityUserAppService _userAppService;
private readonly IProfileAppService _profileAppService;
private readonly IStringLocalizer<IdentityResource> _localizer;
public ChangePasswordModal(IIdentityUserAppService userAppService,
public ChangePasswordModal(
IProfileAppService profileAppService,
IStringLocalizer<IdentityResource> localizer)
{
_userAppService = userAppService;
_profileAppService = profileAppService;
_localizer = localizer;
}
@ -31,8 +32,10 @@ namespace Volo.Abp.Identity.Web.Pages.Identity.Shared
throw new UserFriendlyException(_localizer.GetString("Identity.PasswordConfirmationFailed").Value);
}
await _userAppService.ChangePasswordAsync(ChangePasswordInfoModel.CurrentPassword,
ChangePasswordInfoModel.NewPassword);
await _profileAppService.ChangePasswordAsync(
ChangePasswordInfoModel.CurrentPassword,
ChangePasswordInfoModel.NewPassword
);
return NoContent();
}

@ -31,7 +31,6 @@
}
</abp-tab>
</abp-tabs>
<div asp-validation-summary="All"></div>
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer>
</abp-modal>

@ -32,7 +32,6 @@
}
</abp-tab>
</abp-tabs>
<div asp-validation-summary="All"></div>
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer>
</abp-modal>

@ -1,6 +1,8 @@
{
"culture": "zh-Hans",
"texts": {
"Permissions": "权限"
"Permissions": "权限",
"OnlyProviderPermissons": "只有这个提供商",
"All": "所有"
}
}

@ -14,23 +14,24 @@
<abp-modal-body>
<input asp-for="@Model.ProviderKey" />
<input asp-for="@Model.ProviderName" />
<abp-tabs tab-style="PillVertical" vertical-header-size="_4">
<abp-tabs name="PermissionsTabs" tab-style="PillVertical" vertical-header-size="_4">
@for (var i = 0; i < Model.Groups.Count; i++)
{
<abp-tab title="@Model.Groups[i].DisplayName" name="v-pills-tab-@Model.Groups[i].GetNormalizedGroupName()">
<h4>@Model.Groups[i].DisplayName</h4>
<hr class="mt-3 mb-4" />
@for (var j = 0; j < Model.Groups[i].Permissions.Count; j++)
{
<abp-input asp-for="@Model.Groups[i].Permissions[j].IsGranted"
label="@Model.Groups[i].Permissions[j].GetShownName(Model.ProviderName)"
disabled="@Model.Groups[i].Permissions[j].IsDisabled(Model.ProviderName)"
group-data-permission-name="@Model.Groups[i].Permissions[j].Name"
group-data-parent-name="@(Model.Groups[i].Permissions[j].ParentName ?? "")"
group-style="margin-left: @(Model.Groups[i].Permissions[j].Depth * 20)px" />
<input asp-for="@Model.Groups[i].Permissions[j].Name" />
}
<div class="pl-1 pt-1" style="height: 450px; overflow: auto;">
@for (var j = 0; j < Model.Groups[i].Permissions.Count; j++)
{
<abp-input asp-for="@Model.Groups[i].Permissions[j].IsGranted"
label="@Model.Groups[i].Permissions[j].GetShownName(Model.ProviderName)"
disabled="@Model.Groups[i].Permissions[j].IsDisabled(Model.ProviderName)"
group-data-permission-name="@Model.Groups[i].Permissions[j].Name"
group-data-parent-name="@(Model.Groups[i].Permissions[j].ParentName ?? "")"
group-style="margin-left: @(Model.Groups[i].Permissions[j].Depth * 20)px" />
<input asp-for="@Model.Groups[i].Permissions[j].Name" />
}
</div>
</abp-tab>
}
</abp-tabs>

@ -1,5 +1,7 @@
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.SettingManagement.Localization;
using Volo.Abp.SettingManagement.Web.Navigation;
using Volo.Abp.UI.Navigation;
using Volo.Abp.VirtualFileSystem;
@ -22,6 +24,19 @@ namespace Volo.Abp.SettingManagement.Web
{
options.FileSets.AddEmbedded<AbpSettingManagementWebModule>("Volo.Abp.SettingManagement.Web");
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<AbpSettingManagementResource>("en");
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<AbpSettingManagementResource>()
.AddVirtualJson("/Localization/Resources/AbpSettingManagement");
});
}
}
}

@ -0,0 +1,10 @@
using Volo.Abp.Localization;
namespace Volo.Abp.SettingManagement.Localization
{
[LocalizationResourceName("AbpSettingManagement")]
public class AbpSettingManagementResource
{
}
}

@ -1,7 +1,9 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.SettingManagement.Localization;
using Volo.Abp.SettingManagement.Web.Pages.SettingManagement;
using Volo.Abp.UI.Navigation;
@ -22,10 +24,18 @@ namespace Volo.Abp.SettingManagement.Web.Navigation
return Task.CompletedTask;
}
//TODO: Localize
//var l = context.ServiceProvider.GetRequiredService<IStringLocalizer<IdentityResource>>();
var l = context.ServiceProvider.GetRequiredService<IStringLocalizer<AbpSettingManagementResource>>();
context.Menu.AddItem(new ApplicationMenuItem(SettingManagementMenuNames.GroupName, "Settings", "/SettingManagement", icon: "fa fa-cog", order: int.MaxValue - 1000));
context.Menu
.GetAdministration()
.AddItem(
new ApplicationMenuItem(
SettingManagementMenuNames.GroupName,
l["Settings"],
"/SettingManagement",
icon: "fa fa-cog"
)
);
return Task.CompletedTask;
}

@ -1,14 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Volo.Abp.SettingManagement.Web.Navigation
namespace Volo.Abp.SettingManagement.Web.Navigation
{
public class SettingManagementMenuNames
{
public const string GroupName = "SettingManagement";
public const string Settings = GroupName + ".Settings";
}
}

@ -1,11 +1,14 @@
@page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Microsoft.AspNetCore.Mvc.Localization
@using Volo.Abp.SettingManagement.Localization
@using Volo.Abp.SettingManagement.Web.Navigation
@using Volo.Abp.SettingManagement.Web.Pages.SettingManagement
@model IndexModel
@inject IHtmlLocalizer<AbpSettingManagementResource> L
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = /*L["Settings"].Value*/ "Settings";
PageLayout.Content.Title = L["Settings"].Value;
PageLayout.Content.MenuItemName = SettingManagementMenuNames.GroupName;
}
@section scripts {
@ -14,21 +17,21 @@
</abp-script-bundle>
}
<div id="SettingManagementWrapper">
<abp-card>
<abp-card-body>
<div id="SettingManagementWrapper">
<abp-card>
<abp-card-body>
<abp-tabs tab-style="PillVertical" vertical-header-size="_3">
@foreach (var group in Model.SettingPageCreationContext.Groups)
{
<abp-tab title="@group.DisplayName">
<abp-tabs tab-style="PillVertical" vertical-header-size="_3">
@foreach (var group in Model.SettingPageCreationContext.Groups)
{
<abp-tab title="@group.DisplayName">
<h2>@group.DisplayName</h2>
<hr class="my-4" />
@await Component.InvokeAsync(group.ComponentType)
</abp-tab>
}
</abp-tabs>
</abp-card-body>
</abp-card>
</div>
<h2>@group.DisplayName</h2>
<hr class="my-4" />
@await Component.InvokeAsync(group.ComponentType)
</abp-tab>
}
</abp-tabs>
</abp-card-body>
</abp-card>
</div>

@ -14,6 +14,7 @@
<ItemGroup>
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared\Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.Localization\Volo.Abp.Localization.csproj" />
</ItemGroup>
<ItemGroup>
@ -25,7 +26,6 @@
<Content Remove="Pages\**\*.cshtml" />
<Content Remove="Pages\**\*.js" />
<Content Remove="Pages\**\*.css" />
<Content Remove="Localization\Resources\**\*.json" />
<Content Remove="Properties\launchSettings.json" />
<None Remove="Pages\Identity\Shared\personal-settings-modal.js" />
<None Include="Properties\launchSettings.json" />

@ -16,11 +16,13 @@ namespace Volo.Abp.TenantManagement.Web.Navigation
return;
}
var administrationMenu = context.Menu.GetAdministration();
var authorizationService = context.ServiceProvider.GetRequiredService<IAuthorizationService>();
var l = context.ServiceProvider.GetRequiredService<IStringLocalizer<AbpTenantManagementResource>>();
var tenantManagementMenuItem = new ApplicationMenuItem(TenantManagementMenuNames.GroupName, l["Menu:TenantManagement"], icon: "fa fa-users");
context.Menu.AddItem(tenantManagementMenuItem);
administrationMenu.AddItem(tenantManagementMenuItem);
if (await authorizationService.IsGrantedAsync(TenantManagementPermissions.Tenants.Default))
{

@ -1,12 +1,11 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Volo.Abp.EntityFrameworkCore.Modeling;
namespace Volo.Abp.Users.EntityFrameworkCore
{
public static class AbpUsersDbContextModelCreatingExtensions
{
public static void ConfigureAbpUser<TUser>(this EntityTypeBuilder<TUser> b, ModelBuilderConfigurationOptions options)
public static void ConfigureAbpUser<TUser>(this EntityTypeBuilder<TUser> b)
where TUser : class, IUser
{
b.Property(u => u.TenantId).HasColumnName(nameof(IUser.TenantId));

@ -1,33 +1,31 @@
apiVersion: extensions/v1beta1
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
io.kompose.service: auth-server
name: auth-server
spec:
selector:
matchLabels:
app: auth-server
replicas: 1
strategy: {}
template:
metadata:
labels:
io.kompose.service: auth-server
app: auth-server
spec:
containers:
- env:
- name: ASPNETCORE_ENVIRONMENT
value: Development
- name: ASPNETCORE_URLS
value: http://0.0.0.0:51511
- name: ConnectionStrings__Default
value: Server=sqlserver;Database=MsDemo_Identity;Trusted_Connection=True;MultipleActiveResultSets=true;User=sa;Password=yourStrong(!)Password;Integrated Security=false
- name: RabbitMQ__Connections__Default__HostName
value: rabbitmq
- name: Redis__Configuration
value: redis
image: volosoft/microservice-demo-auth-server
name: auth-server
ports:
- containerPort: 51511
resources: {}
restartPolicy: Always
status: {}
- name: auth-server
image: "volosoft/microservice-demo-auth-server"
env:
- name: ASPNETCORE_ENVIRONMENT
value: Development
- name: ASPNETCORE_URLS
value: http://0.0.0.0:51511
- name: ConnectionStrings__Default
value: Server=sqlserver;Database=MsDemo_Identity;Trusted_Connection=True;MultipleActiveResultSets=true;User=sa;Password=yourStrong(!)Password;Integrated Security=false
- name: RabbitMQ__Connections__Default__HostName
value: rabbitmq
- name: Redis__Configuration
value: redis
ports:
- name: http
containerPort: 51511

@ -1,14 +1,11 @@
apiVersion: v1
kind: Service
apiVersion: v1
metadata:
labels:
io.kompose.service: auth-server
name: auth-server
spec:
ports:
- port: 51511
targetPort: 51511
selector:
io.kompose.service: auth-server
status:
loadBalancer: {}
app: auth-server
ports:
- protocol: TCP
port: 51511
targetPort: http

@ -1,33 +1,31 @@
apiVersion: extensions/v1beta1
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
io.kompose.service: backend-admin-app
name: backend-admin-app
spec:
selector:
matchLabels:
app: backend-admin-app
replicas: 1
strategy: {}
template:
metadata:
labels:
io.kompose.service: backend-admin-app
app: backend-admin-app
spec:
containers:
- env:
- name: ASPNETCORE_ENVIRONMENT
value: Development
- name: ASPNETCORE_URLS
value: http://0.0.0.0:80
- name: AuthServer__Authority
value: http://auth-server:51511
- name: Redis__Configuration
value: redis
- name: RemoteServices__Default__BaseUrl
value: http://backend-admin-app-gateway/
image: volosoft/microservice-demo-backend-admin-app
name: backend-admin-app
ports:
- containerPort: 80
resources: {}
restartPolicy: Always
status: {}
- name: backend-admin-app
image: "volosoft/microservice-demo-backend-admin-app"
env:
- name: ASPNETCORE_ENVIRONMENT
value: Development
- name: ASPNETCORE_URLS
value: http://0.0.0.0:80
- name: AuthServer__Authority
value: http://auth-server:51511
- name: Redis__Configuration
value: redis
- name: RemoteServices__Default__BaseUrl
value: http://backend-admin-app-gateway/
ports:
- name: http
containerPort: 80

@ -1,45 +1,43 @@
apiVersion: extensions/v1beta1
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
io.kompose.service: backend-admin-app-gateway
name: backend-admin-app-gateway
spec:
selector:
matchLabels:
app: backend-admin-app-gateway
replicas: 1
strategy: {}
template:
metadata:
labels:
io.kompose.service: backend-admin-app-gateway
app: backend-admin-app-gateway
spec:
containers:
- env:
- name: ASPNETCORE_ENVIRONMENT
value: Development
- name: ASPNETCORE_URLS
value: http://0.0.0.0:80
- name: AuthServer__Authority
value: http://auth-server:51511
- name: ConnectionStrings__Default
value: Server=sqlserver;Database=MsDemo_Identity;Trusted_Connection=True;MultipleActiveResultSets=true;User=sa;Password=yourStrong(!)Password;Integrated Security=false
- name: GlobalConfiguration__BaseUrl
value: http://backend-admin-app-gateway
- name: ReRoutes__0__DownstreamHostAndPorts__0__Host
value: identity-service
- name: ReRoutes__0__DownstreamHostAndPorts__0__Port
value: "80"
- name: ReRoutes__1__DownstreamHostAndPorts__0__Host
value: product-service
- name: ReRoutes__1__DownstreamHostAndPorts__0__Port
value: "80"
- name: Redis__Configuration
value: redis
- name: RemoteServices__Default__BaseUrl
value: http://backend-admin-app-gateway/
image: volosoft/microservice-demo-backend-admin-app-gateway
name: backend-admin-app-gateway
ports:
- containerPort: 80
resources: {}
restartPolicy: Always
status: {}
- name: backend-admin-app-gateway
image: "volosoft/microservice-demo-backend-admin-app-gateway"
env:
- name: ASPNETCORE_ENVIRONMENT
value: Development
- name: ASPNETCORE_URLS
value: http://0.0.0.0:80
- name: AuthServer__Authority
value: http://auth-server:51511
- name: ConnectionStrings__Default
value: Server=sqlserver;Database=MsDemo_Identity;Trusted_Connection=True;MultipleActiveResultSets=true;User=sa;Password=yourStrong(!)Password;Integrated Security=false
- name: GlobalConfiguration__BaseUrl
value: http://backend-admin-app-gateway
- name: ReRoutes__0__DownstreamHostAndPorts__0__Host
value: identity-service
- name: ReRoutes__0__DownstreamHostAndPorts__0__Port
value: "80"
- name: ReRoutes__1__DownstreamHostAndPorts__0__Host
value: product-service
- name: ReRoutes__1__DownstreamHostAndPorts__0__Port
value: "80"
- name: Redis__Configuration
value: redis
- name: RemoteServices__Default__BaseUrl
value: http://backend-admin-app-gateway/
ports:
- name: http
containerPort: 80

@ -1,14 +1,11 @@
apiVersion: v1
kind: Service
apiVersion: v1
metadata:
labels:
io.kompose.service: backend-admin-app-gateway
name: backend-admin-app-gateway
spec:
ports:
- port: 80
targetPort: 80
selector:
io.kompose.service: backend-admin-app-gateway
status:
loadBalancer: {}
app: backend-admin-app-gateway
ports:
- protocol: TCP
port: 80
targetPort: http

@ -1,14 +1,11 @@
apiVersion: v1
kind: Service
apiVersion: v1
metadata:
labels:
io.kompose.service: backend-admin-app
name: backend-admin-app
spec:
ports:
- port: 80
targetPort: 80
selector:
io.kompose.service: backend-admin-app
status:
loadBalancer: {}
app: backend-admin-app
ports:
- protocol: TCP
port: 80
targetPort: http

@ -1,39 +1,37 @@
apiVersion: extensions/v1beta1
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
io.kompose.service: blogging-service
name: blogging-service
spec:
selector:
matchLabels:
app: blogging-service
replicas: 1
strategy: {}
template:
metadata:
labels:
io.kompose.service: blogging-service
app: blogging-service
spec:
containers:
- env:
- name: ASPNETCORE_ENVIRONMENT
value: Development
- name: ASPNETCORE_URLS
value: http://0.0.0.0:80
- name: AuthServer__Authority
value: http://auth-server:51511
- name: ConnectionStrings__Blogging
value: mongodb://mongodb|MsDemo_Blogging
- name: ConnectionStrings__Default
value: Server=sqlserver;Database=MsDemo_Identity;Trusted_Connection=True;MultipleActiveResultSets=true;User=sa;Password=yourStrong(!)Password;Integrated Security=false
- name: RabbitMQ__Connections__Default__HostName
value: rabbitmq
- name: Redis__Configuration
value: redis
- name: RemoteServices__Default__BaseUrl
value: http://internal-gateway/
image: volosoft/microservice-demo-blogging-service
name: blogging-service
ports:
- containerPort: 80
resources: {}
restartPolicy: Always
status: {}
- name: blogging-service
image: "volosoft/microservice-demo-blogging-service"
env:
- name: ASPNETCORE_ENVIRONMENT
value: Development
- name: ASPNETCORE_URLS
value: http://0.0.0.0:80
- name: AuthServer__Authority
value: http://auth-server:51511
- name: ConnectionStrings__Blogging
value: mongodb://mongodb|MsDemo_Blogging
- name: ConnectionStrings__Default
value: Server=sqlserver;Database=MsDemo_Identity;Trusted_Connection=True;MultipleActiveResultSets=true;User=sa;Password=yourStrong(!)Password;Integrated Security=false
- name: RabbitMQ__Connections__Default__HostName
value: rabbitmq
- name: Redis__Configuration
value: redis
- name: RemoteServices__Default__BaseUrl
value: http://internal-gateway/
ports:
- name: http
containerPort: 80

@ -1,14 +1,11 @@
apiVersion: v1
kind: Service
apiVersion: v1
metadata:
labels:
io.kompose.service: blogging-service
name: blogging-service
spec:
ports:
- port: 80
targetPort: 80
selector:
io.kompose.service: blogging-service
status:
loadBalancer: {}
app: blogging-service
ports:
- protocol: TCP
port: 80
targetPort: http

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save