From 66fcaf9ebf56afec7f9f936b7458bf34c0c92d0c Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Thu, 13 Dec 2018 11:37:47 +0300 Subject: [PATCH 001/368] Resolved #645: Inttroduce IStringEncryptionService --- framework/Volo.Abp.sln | 9 +- .../Encryption/IStringEncryptionService.cs | 31 ++++++ .../Encryption/StringEncryptionOptions.cs | 44 ++++++++ .../Encryption/StringEncryptionService.cs | 103 ++++++++++++++++++ .../Volo.Abp.Security.Tests.csproj | 20 ++++ .../Abp/Security/AbpSecurityTestModule.cs | 13 +++ .../StringEncryptionService_Tests.cs | 26 +++++ 7 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 framework/src/Volo.Abp.Security/Volo/Abp/Security/Encryption/IStringEncryptionService.cs create mode 100644 framework/src/Volo.Abp.Security/Volo/Abp/Security/Encryption/StringEncryptionOptions.cs create mode 100644 framework/src/Volo.Abp.Security/Volo/Abp/Security/Encryption/StringEncryptionService.cs create mode 100644 framework/test/Volo.Abp.Security.Tests/Volo.Abp.Security.Tests.csproj create mode 100644 framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/AbpSecurityTestModule.cs create mode 100644 framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Encryption/StringEncryptionService_Tests.cs diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln index d6518a0af3..7cae777e00 100644 --- a/framework/Volo.Abp.sln +++ b/framework/Volo.Abp.sln @@ -212,7 +212,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Mvc.UI. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.EntityFrameworkCore.PostgreSql", "src\Volo.Abp.EntityFrameworkCore.PostgreSql\Volo.Abp.EntityFrameworkCore.PostgreSql.csproj", "{882E82F1-1A57-4BB9-B126-4CBF700C8F0C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Localization.Abstractions", "src\Volo.Abp.Localization.Abstractions\Volo.Abp.Localization.Abstractions.csproj", "{20513A4E-FAC7-4106-8976-5D79A3BDFED1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Localization.Abstractions", "src\Volo.Abp.Localization.Abstractions\Volo.Abp.Localization.Abstractions.csproj", "{20513A4E-FAC7-4106-8976-5D79A3BDFED1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Security.Tests", "test\Volo.Abp.Security.Tests\Volo.Abp.Security.Tests.csproj", "{7CE07034-7E02-4C78-B981-F1039412CA5E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -604,6 +606,10 @@ Global {20513A4E-FAC7-4106-8976-5D79A3BDFED1}.Debug|Any CPU.Build.0 = Debug|Any CPU {20513A4E-FAC7-4106-8976-5D79A3BDFED1}.Release|Any CPU.ActiveCfg = Release|Any CPU {20513A4E-FAC7-4106-8976-5D79A3BDFED1}.Release|Any CPU.Build.0 = Release|Any CPU + {7CE07034-7E02-4C78-B981-F1039412CA5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7CE07034-7E02-4C78-B981-F1039412CA5E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7CE07034-7E02-4C78-B981-F1039412CA5E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7CE07034-7E02-4C78-B981-F1039412CA5E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -707,6 +713,7 @@ Global {77A621CF-9562-411B-A707-C7C02CC3B8FA} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {882E82F1-1A57-4BB9-B126-4CBF700C8F0C} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {20513A4E-FAC7-4106-8976-5D79A3BDFED1} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} + {7CE07034-7E02-4C78-B981-F1039412CA5E} = {447C8A77-E5F0-4538-8687-7383196D04EA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5} diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Encryption/IStringEncryptionService.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Encryption/IStringEncryptionService.cs new file mode 100644 index 0000000000..bad4e33251 --- /dev/null +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Encryption/IStringEncryptionService.cs @@ -0,0 +1,31 @@ +using JetBrains.Annotations; + +namespace Volo.Abp.Security.Encryption +{ + /// + /// Can be used to simply encrypt/decrypt texts. + /// Use to configure default values. + /// + public interface IStringEncryptionService + { + /// + /// Encrypts a text. + /// + /// The text in plain format + /// A phrase to use as the encryption key (optional, uses default if not provided) + /// Salt value (optional, uses default if not provided) + /// Enrypted text + [CanBeNull] + string Encrypt([CanBeNull] string plainText, string passPhrase = null, byte[] salt = null); + + /// + /// Decrypts a text that is encrypted by the method. + /// + /// The text in encrypted format + /// A phrase to use as the encryption key (optional, uses default if not provided) + /// Salt value (optional, uses default if not provided) + /// Decrypted text + [CanBeNull] + string Decrypt([CanBeNull] string cipherText, string passPhrase = null, byte[] salt = null); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Encryption/StringEncryptionOptions.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Encryption/StringEncryptionOptions.cs new file mode 100644 index 0000000000..91768d37e8 --- /dev/null +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Encryption/StringEncryptionOptions.cs @@ -0,0 +1,44 @@ +using System.Text; + +namespace Volo.Abp.Security.Encryption +{ + /// + /// Options used by . + /// + public class StringEncryptionOptions + { + /// + /// This constant is used to determine the keysize of the encryption algorithm. + /// Default value: 256. + /// + public int Keysize { get; set; } + + /// + /// Default password to encrypt/decrypt texts. + /// It's recommented to set to another value for security. + /// Default value: "gsKnGZ041HLL4IM8" + /// + public string DefaultPassPhrase { get; set; } + + /// + /// This constant string is used as a "salt" value for the PasswordDeriveBytes function calls. + /// This size of the IV (in bytes) must = (keysize / 8). Default keysize is 256, so the IV must be + /// 32 bytes long. Using a 16 character string here gives us 32 bytes when converted to a byte array. + /// Default value: Encoding.ASCII.GetBytes("jkE49230Tf093b42") + /// + public byte[] InitVectorBytes { get; set; } + + /// + /// Default value: Encoding.ASCII.GetBytes("hgt!16kl") + /// + public byte[] DefaultSalt { get; set; } + + public StringEncryptionOptions() + { + Keysize = 256; + DefaultPassPhrase = "gsKnGZ041HLL4IM8"; + InitVectorBytes = Encoding.ASCII.GetBytes("jkE49230Tf093b42"); + DefaultSalt = Encoding.ASCII.GetBytes("hgt!16kl"); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Encryption/StringEncryptionService.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Encryption/StringEncryptionService.cs new file mode 100644 index 0000000000..1d235d1d84 --- /dev/null +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Encryption/StringEncryptionService.cs @@ -0,0 +1,103 @@ +using System; +using System.IO; +using System.Security.Cryptography; +using System.Text; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Security.Encryption +{ + /// + /// Can be used to simply encrypt/decrypt texts. + /// + public class StringEncryptionService : IStringEncryptionService, ITransientDependency + { + protected StringEncryptionOptions Options { get; } + + public StringEncryptionService(IOptions options) + { + Options = options.Value; + } + + public virtual string Encrypt(string plainText, string passPhrase = null, byte[] salt = null) + { + if (plainText == null) + { + return null; + } + + if (passPhrase == null) + { + passPhrase = Options.DefaultPassPhrase; + } + + if (salt == null) + { + salt = Options.DefaultSalt; + } + + var plainTextBytes = Encoding.UTF8.GetBytes(plainText); + using (var password = new Rfc2898DeriveBytes(passPhrase, salt)) + { + var keyBytes = password.GetBytes(Options.Keysize / 8); + using (var symmetricKey = Aes.Create()) + { + symmetricKey.Mode = CipherMode.CBC; + using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, Options.InitVectorBytes)) + { + using (var memoryStream = new MemoryStream()) + { + using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) + { + cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); + cryptoStream.FlushFinalBlock(); + var cipherTextBytes = memoryStream.ToArray(); + return Convert.ToBase64String(cipherTextBytes); + } + } + } + } + } + } + + public virtual string Decrypt(string cipherText, string passPhrase = null, byte[] salt = null) + { + if (string.IsNullOrEmpty(cipherText)) + { + return null; + } + + if (passPhrase == null) + { + passPhrase = Options.DefaultPassPhrase; + } + + if (salt == null) + { + salt = Options.DefaultSalt; + } + + var cipherTextBytes = Convert.FromBase64String(cipherText); + using (var password = new Rfc2898DeriveBytes(passPhrase, salt)) + { + var keyBytes = password.GetBytes(Options.Keysize / 8); + using (var symmetricKey = Aes.Create()) + { + symmetricKey.Mode = CipherMode.CBC; + using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, Options.InitVectorBytes)) + { + using (var memoryStream = new MemoryStream(cipherTextBytes)) + { + using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)) + { + var plainTextBytes = new byte[cipherTextBytes.Length]; + var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); + return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount); + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Security.Tests/Volo.Abp.Security.Tests.csproj b/framework/test/Volo.Abp.Security.Tests/Volo.Abp.Security.Tests.csproj new file mode 100644 index 0000000000..e2f96d8223 --- /dev/null +++ b/framework/test/Volo.Abp.Security.Tests/Volo.Abp.Security.Tests.csproj @@ -0,0 +1,20 @@ + + + + netcoreapp2.1 + Volo.Abp.Security.Tests + Volo.Abp.Security.Tests + true + false + false + false + + + + + + + + + + diff --git a/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/AbpSecurityTestModule.cs b/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/AbpSecurityTestModule.cs new file mode 100644 index 0000000000..b71a0a214a --- /dev/null +++ b/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/AbpSecurityTestModule.cs @@ -0,0 +1,13 @@ +using Volo.Abp.Modularity; + +namespace Volo.Abp.Security +{ + [DependsOn( + typeof(AbpSecurityModule), + typeof(AbpTestBaseModule) + )] + public class AbpSecurityTestModule : AbpModule + { + + } +} diff --git a/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Encryption/StringEncryptionService_Tests.cs b/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Encryption/StringEncryptionService_Tests.cs new file mode 100644 index 0000000000..455e0863bb --- /dev/null +++ b/framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/Encryption/StringEncryptionService_Tests.cs @@ -0,0 +1,26 @@ +using Shouldly; +using Xunit; + +namespace Volo.Abp.Security.Encryption +{ + public class StringEncryptionService_Tests : AbpIntegratedTest + { + private readonly IStringEncryptionService _stringEncryptionService; + + public StringEncryptionService_Tests() + { + _stringEncryptionService = GetRequiredService(); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("This is a plain text!")] + public void Should_Enrypt_And_Decrpyt_With_Default_Options(string plainText) + { + _stringEncryptionService + .Decrypt(_stringEncryptionService.Encrypt(plainText)) + .ShouldBe(plainText); + } + } +} From ac3d7c7c16ea0d24fa818e12345d4d68e929980b Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Thu, 13 Dec 2018 14:10:56 +0300 Subject: [PATCH 002/368] Resolved #203: Encrypt option to settings --- .../Volo.Abp.Settings.csproj | 1 + .../Volo/Abp/Settings/AbpSettingsModule.cs | 4 +- .../Abp/Settings/ISettingEncryptionService.cs | 13 ++ .../Volo/Abp/Settings/SettingDefinition.cs | 10 +- .../Abp/Settings/SettingEncryptionService.cs | 36 +++++ .../Volo/Abp/Settings/SettingManager.cs | 130 +++++++++++------- 6 files changed, 144 insertions(+), 50 deletions(-) create mode 100644 framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingEncryptionService.cs create mode 100644 framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingEncryptionService.cs diff --git a/framework/src/Volo.Abp.Settings/Volo.Abp.Settings.csproj b/framework/src/Volo.Abp.Settings/Volo.Abp.Settings.csproj index 6ba4d46c1f..42ab46d477 100644 --- a/framework/src/Volo.Abp.Settings/Volo.Abp.Settings.csproj +++ b/framework/src/Volo.Abp.Settings/Volo.Abp.Settings.csproj @@ -15,6 +15,7 @@ + diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/AbpSettingsModule.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/AbpSettingsModule.cs index 8900e8e0a3..da871946ae 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/AbpSettingsModule.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/AbpSettingsModule.cs @@ -1,10 +1,12 @@ using Volo.Abp.Localization; using Volo.Abp.Modularity; +using Volo.Abp.Security; namespace Volo.Abp.Settings { [DependsOn( - typeof(AbpLocalizationAbstractionsModule) + typeof(AbpLocalizationAbstractionsModule), + typeof(AbpSecurityModule) )] public class AbpSettingsModule : AbpModule { diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingEncryptionService.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingEncryptionService.cs new file mode 100644 index 0000000000..ffffd7fe97 --- /dev/null +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingEncryptionService.cs @@ -0,0 +1,13 @@ +using JetBrains.Annotations; + +namespace Volo.Abp.Settings +{ + public interface ISettingEncryptionService + { + [CanBeNull] + string Encrypt([NotNull]SettingDefinition settingDefinition, [CanBeNull] string plainValue); + + [CanBeNull] + string Decrypt([NotNull]SettingDefinition settingDefinition, [CanBeNull] string encryptedValue); + } +} diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinition.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinition.cs index 58726492c6..cbbf810f84 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinition.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinition.cs @@ -48,13 +48,20 @@ namespace Volo.Abp.Settings [NotNull] public Dictionary Properties { get; } + /// + /// Is this setting stored as encrypted in the data source. + /// Default: False. + /// + public bool IsEncrypted { get; set; } + public SettingDefinition( string name, string defaultValue = null, ILocalizableString displayName = null, ILocalizableString description = null, bool isVisibleToClients = false, - bool isInherited = true) + bool isInherited = true, + bool isEncrypted = false) { Name = name; DefaultValue = defaultValue; @@ -62,6 +69,7 @@ namespace Volo.Abp.Settings DisplayName = displayName ?? new FixedLocalizableString(name); Description = description; IsInherited = isInherited; + IsEncrypted = isEncrypted; Properties = new Dictionary(); } diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingEncryptionService.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingEncryptionService.cs new file mode 100644 index 0000000000..9fbee47688 --- /dev/null +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingEncryptionService.cs @@ -0,0 +1,36 @@ +using System; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Security.Encryption; + +namespace Volo.Abp.Settings +{ + public class SettingEncryptionService : ISettingEncryptionService, ITransientDependency + { + protected IStringEncryptionService StringEncryptionService { get; } + + public SettingEncryptionService(IStringEncryptionService stringEncryptionService) + { + StringEncryptionService = stringEncryptionService; + } + + public virtual string Encrypt(SettingDefinition settingDefinition, string plainValue) + { + if (plainValue.IsNullOrEmpty()) + { + return plainValue; + } + + return StringEncryptionService.Encrypt(plainValue); + } + + public virtual string Decrypt(SettingDefinition settingDefinition, string encryptedValue) + { + if (encryptedValue.IsNullOrEmpty()) + { + return encryptedValue; + } + + return StringEncryptionService.Decrypt(encryptedValue); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingManager.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingManager.cs index d75eb6ecee..f2d808644d 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingManager.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingManager.cs @@ -11,17 +11,18 @@ namespace Volo.Abp.Settings public class SettingManager : ISettingManager, ISingletonDependency { protected ISettingDefinitionManager SettingDefinitionManager { get; } - + protected ISettingEncryptionService SettingEncryptionService { get; } protected Lazy> Providers { get; } - protected SettingOptions Options { get; } public SettingManager( IOptions options, IServiceProvider serviceProvider, - ISettingDefinitionManager settingDefinitionManager) + ISettingDefinitionManager settingDefinitionManager, + ISettingEncryptionService settingEncryptionService) { SettingDefinitionManager = settingDefinitionManager; + SettingEncryptionService = settingEncryptionService; Options = options.Value; Providers = new Lazy>( @@ -48,34 +49,6 @@ namespace Volo.Abp.Settings return GetOrNullInternalAsync(name, providerName, providerKey, fallback); } - public virtual async Task GetOrNullInternalAsync(string name, string providerName, string providerKey, bool fallback = true) - { - var setting = SettingDefinitionManager.Get(name); - var providers = Enumerable - .Reverse(Providers.Value); - - if (providerName != null) - { - providers = providers.SkipWhile(c => c.Name != providerName); - } - - if (!fallback || !setting.IsInherited) - { - providers = providers.TakeWhile(c => c.Name == providerName); - } - - foreach (var provider in providers) - { - var value = await provider.GetOrNullAsync(setting, providerKey); - if (value != null) - { - return value; - } - } - - return null; - } - public virtual async Task> GetAllAsync() { var settingValues = new Dictionary(); @@ -88,6 +61,11 @@ namespace Volo.Abp.Settings var value = await provider.GetOrNullAsync(setting, null); if (value != null) { + if (setting.IsEncrypted) + { + value = SettingEncryptionService.Decrypt(setting, value); + } + settingValues[setting.Name] = new SettingValue(setting.Name, value); } } @@ -100,7 +78,6 @@ namespace Volo.Abp.Settings { Check.NotNull(providerName, nameof(providerName)); - var settingValues = new Dictionary(); var settingDefinitions = SettingDefinitionManager.GetAll(); var providers = Enumerable.Reverse(Providers.Value) .SkipWhile(c => c.Name != providerName); @@ -112,29 +89,39 @@ namespace Volo.Abp.Settings var providerList = providers.Reverse().ToList(); - if (providerList.Any()) + if (!providerList.Any()) { - foreach (var setting in settingDefinitions) + return new List(); + } + + var settingValues = new Dictionary(); + + foreach (var setting in settingDefinitions) + { + string value = null; + + if (setting.IsInherited) { - if (setting.IsInherited) + foreach (var provider in providerList) { - foreach (var provider in providerList) + var providerValue = await provider.GetOrNullAsync(setting, providerKey); + if (providerValue != null) { - var value = await provider.GetOrNullAsync(setting, providerKey); - if (value != null) - { - settingValues[setting.Name] = new SettingValue(setting.Name, value); - } + value = providerValue; } } - else - { - settingValues[setting.Name] = new SettingValue( - setting.Name, - await providerList[0].GetOrNullAsync(setting, providerKey) - ); - } } + else + { + value = await providerList[0].GetOrNullAsync(setting, providerKey); + } + + if (setting.IsEncrypted) + { + value = SettingEncryptionService.Decrypt(setting, value); + } + + settingValues[setting.Name] = new SettingValue(setting.Name, value); } return settingValues.Values.ToList(); @@ -157,6 +144,11 @@ namespace Volo.Abp.Settings return; } + if (setting.IsEncrypted) + { + value = SettingEncryptionService.Encrypt(setting, value); + } + if (providers.Count > 1 && !forceToSet && setting.IsInherited && value != null) { //Clear the value if it's same as it's fallback value @@ -186,5 +178,47 @@ namespace Volo.Abp.Settings } } } + + protected virtual async Task GetOrNullInternalAsync(string name, string providerName, string providerKey, bool fallback = true) + { + var setting = SettingDefinitionManager.Get(name); + var providers = Enumerable + .Reverse(Providers.Value); + + if (providerName != null) + { + providers = providers.SkipWhile(c => c.Name != providerName); + } + + if (!fallback || !setting.IsInherited) + { + providers = providers.TakeWhile(c => c.Name == providerName); + } + + var value = await GetOrNullValueFromProvidersAsync(providerKey, providers, setting); + if (setting.IsEncrypted) + { + value = SettingEncryptionService.Decrypt(setting, value); + } + + return value; + } + + protected virtual async Task GetOrNullValueFromProvidersAsync( + string providerKey, + IEnumerable providers, + SettingDefinition setting) + { + foreach (var provider in providers) + { + var value = await provider.GetOrNullAsync(setting, providerKey); + if (value != null) + { + return value; + } + } + + return null; + } } } \ No newline at end of file From 9803016be7bd6ced8811f50217a3dc79f955deee Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Thu, 13 Dec 2018 14:13:50 +0300 Subject: [PATCH 003/368] Added Volo.Abp.Localization.Abstractions to nuget package list --- nupkg/common.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/nupkg/common.ps1 b/nupkg/common.ps1 index 3dcccf7d81..3871b73a1e 100644 --- a/nupkg/common.ps1 +++ b/nupkg/common.ps1 @@ -65,6 +65,7 @@ $projects = ( "framework/src/Volo.Abp.Http.Client", "framework/src/Volo.Abp.Json", "framework/src/Volo.Abp.Localization", + "framework/src/Volo.Abp.Localization.Abstractions", "framework/src/Volo.Abp.MemoryDb", "framework/src/Volo.Abp.MongoDB", "framework/src/Volo.Abp.MultiTenancy.Abstractions", From 404c975aaf44f2f8455b23245196146098f06072 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Thu, 13 Dec 2018 14:44:25 +0300 Subject: [PATCH 004/368] Added tests for settings package --- framework/Volo.Abp.sln | 7 +++ .../Volo.Abp.Settings.Tests.csproj | 21 ++++++++ .../Abp/Settings/AbpSettingsTestModule.cs | 20 ++++++++ .../Volo/Abp/Settings/SettingManager_Tests.cs | 49 +++++++++++++++++++ .../Settings/TestSettingDefinitionProvider.cs | 14 ++++++ .../Volo/Abp/Settings/TestSettingNames.cs | 9 ++++ .../Abp/Settings/TestSettingValueProvider.cs | 37 ++++++++++++++ 7 files changed, 157 insertions(+) create mode 100644 framework/test/Volo.Abp.Settings.Tests/Volo.Abp.Settings.Tests.csproj create mode 100644 framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/AbpSettingsTestModule.cs create mode 100644 framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingManager_Tests.cs create mode 100644 framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingDefinitionProvider.cs create mode 100644 framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingNames.cs create mode 100644 framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingValueProvider.cs diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln index 7cae777e00..9916c2a8e8 100644 --- a/framework/Volo.Abp.sln +++ b/framework/Volo.Abp.sln @@ -216,6 +216,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Localization.Abstr EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Security.Tests", "test\Volo.Abp.Security.Tests\Volo.Abp.Security.Tests.csproj", "{7CE07034-7E02-4C78-B981-F1039412CA5E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Settings.Tests", "test\Volo.Abp.Settings.Tests\Volo.Abp.Settings.Tests.csproj", "{5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -610,6 +612,10 @@ Global {7CE07034-7E02-4C78-B981-F1039412CA5E}.Debug|Any CPU.Build.0 = Debug|Any CPU {7CE07034-7E02-4C78-B981-F1039412CA5E}.Release|Any CPU.ActiveCfg = Release|Any CPU {7CE07034-7E02-4C78-B981-F1039412CA5E}.Release|Any CPU.Build.0 = Release|Any CPU + {5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -714,6 +720,7 @@ Global {882E82F1-1A57-4BB9-B126-4CBF700C8F0C} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {20513A4E-FAC7-4106-8976-5D79A3BDFED1} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {7CE07034-7E02-4C78-B981-F1039412CA5E} = {447C8A77-E5F0-4538-8687-7383196D04EA} + {5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403} = {447C8A77-E5F0-4538-8687-7383196D04EA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5} diff --git a/framework/test/Volo.Abp.Settings.Tests/Volo.Abp.Settings.Tests.csproj b/framework/test/Volo.Abp.Settings.Tests/Volo.Abp.Settings.Tests.csproj new file mode 100644 index 0000000000..7b4eda07c9 --- /dev/null +++ b/framework/test/Volo.Abp.Settings.Tests/Volo.Abp.Settings.Tests.csproj @@ -0,0 +1,21 @@ + + + + netcoreapp2.1 + latest + Volo.Abp.Settings.Tests + Volo.Abp.Settings.Tests + true + false + false + false + + + + + + + + + + diff --git a/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/AbpSettingsTestModule.cs b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/AbpSettingsTestModule.cs new file mode 100644 index 0000000000..dc4ab057a0 --- /dev/null +++ b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/AbpSettingsTestModule.cs @@ -0,0 +1,20 @@ +using Volo.Abp.Modularity; + +namespace Volo.Abp.Settings +{ + [DependsOn( + typeof(AbpSettingsModule), + typeof(AbpTestBaseModule) + )] + public class AbpSettingsTestModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.ValueProviders.Add(); + options.DefinitionProviders.Add(); + }); + } + } +} diff --git a/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingManager_Tests.cs b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingManager_Tests.cs new file mode 100644 index 0000000000..be039451f2 --- /dev/null +++ b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingManager_Tests.cs @@ -0,0 +1,49 @@ +using System.Threading.Tasks; +using Shouldly; +using Xunit; + +namespace Volo.Abp.Settings +{ + public class SettingManager_Tests : AbpIntegratedTest + { + private readonly ISettingManager _settingManager; + + public SettingManager_Tests() + { + _settingManager = GetRequiredService(); + } + + [Fact] + public async Task Should_Get_Null_If_No_Value_Provided_And_No_Default_Value() + { + (await _settingManager.GetOrNullAsync(TestSettingNames.TestSettingWithoutDefaultValue)) + .ShouldBeNull(); + } + + [Fact] + public async Task Should_Get_Default_Value_If_No_Value_Provided_And_There_Is_A_Default_Value() + { + (await _settingManager.GetOrNullAsync(TestSettingNames.TestSettingWithDefaultValue)) + .ShouldBe("default-value"); + } + + [Fact] + public async Task Should_Set_And_Get_Encrypted_Values() + { + (await _settingManager.GetOrNullAsync(TestSettingNames.TestSettingEncrypted)) + .ShouldBeNull(); + + await _settingManager.SetAsync( + TestSettingNames.TestSettingEncrypted, + "abc", + TestSettingValueProvider.ProviderName, + null + ); + + (await _settingManager.GetOrNullAsync(TestSettingNames.TestSettingEncrypted)) + .ShouldBe("abc"); + } + + //TODO: Needs more tests with more advanced scenarios. + } +} diff --git a/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingDefinitionProvider.cs b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingDefinitionProvider.cs new file mode 100644 index 0000000000..1cbe860963 --- /dev/null +++ b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingDefinitionProvider.cs @@ -0,0 +1,14 @@ +namespace Volo.Abp.Settings +{ + public class TestSettingDefinitionProvider : SettingDefinitionProvider + { + public override void Define(ISettingDefinitionContext context) + { + context.Add( + new SettingDefinition(TestSettingNames.TestSettingWithoutDefaultValue), + new SettingDefinition(TestSettingNames.TestSettingWithDefaultValue, "default-value"), + new SettingDefinition(TestSettingNames.TestSettingEncrypted, isEncrypted: true) + ); + } + } +} diff --git a/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingNames.cs b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingNames.cs new file mode 100644 index 0000000000..b10267e69d --- /dev/null +++ b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingNames.cs @@ -0,0 +1,9 @@ +namespace Volo.Abp.Settings +{ + public static class TestSettingNames + { + public const string TestSettingWithoutDefaultValue = "TestSettingWithoutDefaultValue"; + public const string TestSettingWithDefaultValue = "TestSettingWithDefaultValue"; + public const string TestSettingEncrypted = "TestSettingEncrypted"; + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingValueProvider.cs b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingValueProvider.cs new file mode 100644 index 0000000000..e8f5cbc559 --- /dev/null +++ b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingValueProvider.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Settings +{ + public class TestSettingValueProvider : ISettingValueProvider, ITransientDependency + { + public const string ProviderName = "Test"; + + private readonly Dictionary _values; + + public string Name => ProviderName; + + public TestSettingValueProvider() + { + _values = new Dictionary(); + } + + public Task GetOrNullAsync(SettingDefinition setting, string providerKey) + { + return Task.FromResult(_values.GetOrDefault(setting.Name)); + } + + public Task SetAsync(SettingDefinition setting, string value, string providerKey) + { + _values[setting.Name] = value; + return Task.CompletedTask; + } + + public Task ClearAsync(SettingDefinition setting, string providerKey) + { + _values.Remove(setting.Name); + return Task.CompletedTask; + } + } +} From 92b191908bbcad870cec9bee14ff837282e6711b Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Thu, 13 Dec 2018 14:46:16 +0300 Subject: [PATCH 005/368] Resolved #648: SMTP password settings should be stored as encrypted in the database. --- .../Volo.Abp.Emailing/Volo/Abp/Emailing/EmailSettingProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/EmailSettingProvider.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/EmailSettingProvider.cs index 97be614a03..382b2eb6cc 100644 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/EmailSettingProvider.cs +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/EmailSettingProvider.cs @@ -14,7 +14,7 @@ namespace Volo.Abp.Emailing new SettingDefinition(EmailSettingNames.Smtp.Host, "127.0.0.1"), new SettingDefinition(EmailSettingNames.Smtp.Port, "25"), new SettingDefinition(EmailSettingNames.Smtp.UserName), - new SettingDefinition(EmailSettingNames.Smtp.Password), + new SettingDefinition(EmailSettingNames.Smtp.Password, isEncrypted: true), new SettingDefinition(EmailSettingNames.Smtp.Domain), new SettingDefinition(EmailSettingNames.Smtp.EnableSsl, "false"), new SettingDefinition(EmailSettingNames.Smtp.UseDefaultCredentials, "true"), From f9bf0960ec61662302a0501c35de862ce5d61ab9 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 13 Dec 2018 14:50:37 +0300 Subject: [PATCH 006/368] Added abp-button-group tag helper --- .../Button/AbpButtonGroupDirection.cs | 13 +++++ .../TagHelpers/Button/AbpButtonGroupSize.cs | 10 ++++ .../Button/AbpButtonGroupTagHelper.cs | 15 +++++ .../Button/AbpButtonGroupTagHelperService.cs | 55 +++++++++++++++++++ .../Pages/Components/Buttons.cshtml | 47 ++++++++++++++++ 5 files changed, 140 insertions(+) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonGroupDirection.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonGroupSize.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonGroupTagHelper.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonGroupTagHelperService.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonGroupDirection.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonGroupDirection.cs new file mode 100644 index 0000000000..53f3c3b6f9 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonGroupDirection.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button +{ + public enum AbpButtonGroupDirection + { + Horizontal, + Vertical + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonGroupSize.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonGroupSize.cs new file mode 100644 index 0000000000..42635dd232 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonGroupSize.cs @@ -0,0 +1,10 @@ +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button +{ + public enum AbpButtonGroupSize + { + Default, + Small, + Medium, + Large + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonGroupTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonGroupTagHelper.cs new file mode 100644 index 0000000000..b1958fc8af --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonGroupTagHelper.cs @@ -0,0 +1,15 @@ +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button +{ + public class AbpButtonGroupTagHelper : AbpTagHelper + { + public AbpButtonGroupDirection Direction { get; set; } = AbpButtonGroupDirection.Horizontal; + + public AbpButtonGroupSize Size { get; set; } = AbpButtonGroupSize.Default; + + public AbpButtonGroupTagHelper(AbpButtonGroupTagHelperService tagHelperService) + : base(tagHelperService) + { + + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonGroupTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonGroupTagHelperService.cs new file mode 100644 index 0000000000..602e956e1e --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonGroupTagHelperService.cs @@ -0,0 +1,55 @@ +using System; +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button +{ + public class AbpButtonGroupTagHelperService : AbpTagHelperService + { + public override void Process(TagHelperContext context, TagHelperOutput output) + { + AddButtonGroupClass(context, output); + AddSizeClass(context, output); + AddAttributes(context, output); + } + + protected virtual void AddSizeClass(TagHelperContext context, TagHelperOutput output) + { + switch (TagHelper.Size) + { + case AbpButtonGroupSize.Default: + break; + case AbpButtonGroupSize.Small: + output.Attributes.AddClass("btn-group-sm"); + break; + case AbpButtonGroupSize.Medium: + output.Attributes.AddClass("btn-group-md"); + break; + case AbpButtonGroupSize.Large: + output.Attributes.AddClass("btn-group-lg"); + break; + } + } + + protected virtual void AddButtonGroupClass(TagHelperContext context, TagHelperOutput output) + { + switch (TagHelper.Direction) + { + case AbpButtonGroupDirection.Horizontal: + output.Attributes.AddClass("btn-group"); + break; + case AbpButtonGroupDirection.Vertical: + output.Attributes.AddClass("btn-group-vertical"); + break; + default: + output.Attributes.AddClass("btn-group"); + break; + } + } + + protected virtual void AddAttributes(TagHelperContext context, TagHelperOutput output) + { + output.Attributes.Add("role", "group"); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Buttons.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Buttons.cshtml index 0525029462..dc34aa32a9 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Buttons.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Buttons.cshtml @@ -121,6 +121,53 @@
 <abp-button text="Busy" busy-text="Saving..."/>
+
+
+ + +

# Group Examples

+ +
+
+ + + Left + Middle + Right + + + + Primary + Secondary + Success + + + + Top + Middle + Bottom + +
+
+
+
+<abp-button-group>
+    <abp-button> Left </abp-button>
+    <abp-button> Middle </abp-button>
+    <abp-button> Right </abp-button>
+</abp-button-group>
+
+<abp-button-group size="Large">
+    <abp-button button-type="Primary"> Primary </abp-button>
+    <abp-button button-type="Secondary"> Secondary </abp-button>
+    <abp-button button-type="Success"> Success </abp-button>
+</abp-button-group>
+
+<abp-button-group direction="Vertical" size="Small">
+    <abp-button button-type="Primary"> Top </abp-button>
+    <abp-button button-type="Warning"> Middle </abp-button>
+    <abp-button button-type="Danger"> Bottom </abp-button>
+</abp-button-group>
 
\ No newline at end of file From ecde9207642c5a23dc531478be5d774d7a5c361f Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Thu, 13 Dec 2018 15:05:30 +0300 Subject: [PATCH 007/368] Improve SettingManager_Tests.Should_Set_And_Get_Encrypted_Values. --- .../Volo/Abp/Settings/SettingManager_Tests.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingManager_Tests.cs b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingManager_Tests.cs index be039451f2..82231b8318 100644 --- a/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingManager_Tests.cs +++ b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingManager_Tests.cs @@ -27,21 +27,25 @@ namespace Volo.Abp.Settings .ShouldBe("default-value"); } - [Fact] - public async Task Should_Set_And_Get_Encrypted_Values() + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("abc")] + [InlineData("This is a relatively long text... This is a relatively long text... This is a relatively long text... ")] + public async Task Should_Set_And_Get_Encrypted_Values(string plainValue) { (await _settingManager.GetOrNullAsync(TestSettingNames.TestSettingEncrypted)) .ShouldBeNull(); await _settingManager.SetAsync( TestSettingNames.TestSettingEncrypted, - "abc", + plainValue, TestSettingValueProvider.ProviderName, null ); (await _settingManager.GetOrNullAsync(TestSettingNames.TestSettingEncrypted)) - .ShouldBe("abc"); + .ShouldBe(plainValue); } //TODO: Needs more tests with more advanced scenarios. From 8ea6fa6a85552f9581be1c9697f2afc51441fdf3 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Thu, 13 Dec 2018 15:06:01 +0300 Subject: [PATCH 008/368] Volo.Abp.Authorization should depend on Volo.Abp.Localization.Abstractions instead of Volo.Abp.Localization. --- .../src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj | 2 +- .../Volo/Abp/Authorization/AbpAuthorizationModule.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj b/framework/src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj index 6690121309..230422beef 100644 --- a/framework/src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj +++ b/framework/src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj @@ -18,7 +18,7 @@ - + diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs index 5649503563..fbcf905b0a 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs @@ -9,7 +9,7 @@ namespace Volo.Abp.Authorization { [DependsOn( typeof(AbpSecurityModule), - typeof(AbpLocalizationModule) + typeof(AbpLocalizationAbstractionsModule) )] public class AbpAuthorizationModule : AbpModule { From 0f4d118069e0030a8de698d9a07ed95f31d8700e Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Fri, 14 Dec 2018 11:30:42 +0300 Subject: [PATCH 009/368] added outline option for abp-button tag helper --- .../TagHelpers/Button/AbpButtonTagHelper.cs | 1 + .../Button/AbpButtonTagHelperServiceBase.cs | 2 +- .../TagHelpers/Button/AbpButtonType.cs | 8 ++++++ .../Pages/Components/Buttons.cshtml | 27 +++++++++++++++++++ 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelper.cs index 1be9524800..afd718da8f 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelper.cs @@ -26,3 +26,4 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button } } } + diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelperServiceBase.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelperServiceBase.cs index 3d8a3bf4e8..b6f2e8f3d1 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelperServiceBase.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelperServiceBase.cs @@ -26,7 +26,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button if (TagHelper.ButtonType != AbpButtonType.Default) { - output.Attributes.AddClass("btn-" + TagHelper.ButtonType.ToString().ToLowerInvariant()); + output.Attributes.AddClass("btn-" + TagHelper.ButtonType.ToString().ToLowerInvariant().Replace("_","-")); } if (TagHelper.Size != AbpButtonSize.Default) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonType.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonType.cs index 07d7e0a50b..a6ced457e0 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonType.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonType.cs @@ -11,6 +11,14 @@ Info, Light, Dark, + Outline_Primary, + Outline_Secondary, + Outline_Success, + Outline_Danger, + Outline_Warning, + Outline_Info, + Outline_Light, + Outline_Dark, Link } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Buttons.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Buttons.cshtml index dc34aa32a9..6fe8f26395 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Buttons.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Buttons.cshtml @@ -47,6 +47,33 @@

# Example

+
+
+ Primary + Secondary + Success + Danger + Warning + Info + Light + Dark +
+
+
+<abp-button button-type="Outline_Primary">Primary</abp-button>
+<abp-button button-type="Outline_Secondary">Secondary</abp-button>
+<abp-button button-type="Outline_Success">Success</abp-button>
+<abp-button button-type="Outline_Danger">Danger</abp-button>
+<abp-button button-type="Outline_Warning">Warning</abp-button>
+<abp-button button-type="Outline_Info">Info</abp-button>
+<abp-button button-type="Outline_Light">Light</abp-button>
+<abp-button button-type="Outline_Dark">Dark</abp-button>
+
+
+
+ +

# Example

+
Link From da066da522cd890365e178b8a439e57c6752d7f0 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Fri, 14 Dec 2018 11:32:10 +0300 Subject: [PATCH 010/368] Remove abp-alert-link attribute at the end of process --- .../TagHelpers/Alert/AbpAlertLinkTagHelperService.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Alert/AbpAlertLinkTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Alert/AbpAlertLinkTagHelperService.cs index eed121566f..79372688c3 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Alert/AbpAlertLinkTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Alert/AbpAlertLinkTagHelperService.cs @@ -8,6 +8,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Alert public override void Process(TagHelperContext context, TagHelperOutput output) { output.Attributes.AddClass("alert-link"); + output.Attributes.RemoveAll("abp-alert-link"); } } } \ No newline at end of file From 9544acb8ace57630f43d52cb9b556cd40c9a189b Mon Sep 17 00:00:00 2001 From: Nokecy Date: Fri, 14 Dec 2018 21:24:07 +0800 Subject: [PATCH 011/368] =?UTF-8?q?fix=20Duplicate=20key=20(AuditLogId?= =?UTF-8?q?=E3=80=81AuditLogId1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AbpAuditLoggingtDbContextModelBuilderExtensions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingtDbContextModelBuilderExtensions.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingtDbContextModelBuilderExtensions.cs index 820d098951..9a39a06dc2 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingtDbContextModelBuilderExtensions.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingtDbContextModelBuilderExtensions.cs @@ -39,8 +39,8 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore b.Property(x => x.UserName).HasMaxLength(AuditLogConsts.MaxUserNameLength).HasColumnName(nameof(AuditLog.UserName)); b.Property(x => x.TenantId).HasColumnName(nameof(AuditLog.TenantId)); - b.HasMany().WithOne().HasForeignKey(x => x.AuditLogId); - b.HasMany().WithOne().HasForeignKey(x => x.AuditLogId); + b.HasMany(a => a.Actions).WithOne().HasForeignKey(x => x.AuditLogId).IsRequired(); + b.HasMany(a => a.EntityChanges).WithOne().HasForeignKey(x => x.AuditLogId).IsRequired(); b.HasIndex(x => new { x.TenantId, x.ExecutionTime }); b.HasIndex(x => new { x.TenantId, x.UserId, x.ExecutionTime }); From 390403b9dac3ed011c697b640206460f30e5b976 Mon Sep 17 00:00:00 2001 From: Mostafa F Date: Sun, 16 Dec 2018 21:24:53 +0330 Subject: [PATCH 012/368] Update code sample for Entity composite key --- docs/en/Entities.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Entities.md b/docs/en/Entities.md index 89688d58c8..a90b95d100 100644 --- a/docs/en/Entities.md +++ b/docs/en/Entities.md @@ -41,7 +41,7 @@ public class UserRole : Entity public DateTime CreationTime { get; set; } - public Phone() + public UserRole() { } From ef65984e342c4021cf521a0e322165929a099b66 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 17 Dec 2018 10:35:34 +0300 Subject: [PATCH 013/368] Added highlight.js --- .../Pages/Components/highlightCode.js | 5 + .../abp.resourcemapping.js | 2 +- .../package.json | 8 +- .../wwwroot/libs/highlight.js/README.md | 186 + .../wwwroot/libs/highlight.js/docs/api.rst | 120 + .../highlight.js/docs/building-testing.rst | 88 + .../docs/css-classes-reference.rst | 460 +++ .../wwwroot/libs/highlight.js/docs/index.rst | 44 + .../docs/language-contribution.rst | 77 + .../libs/highlight.js/docs/language-guide.rst | 264 ++ .../highlight.js/docs/language-requests.rst | 17 + .../libs/highlight.js/docs/line-numbers.rst | 39 + .../highlight.js/docs/maintainers-guide.rst | 34 + .../libs/highlight.js/docs/reference.rst | 360 ++ .../libs/highlight.js/docs/style-guide.rst | 106 + .../libs/highlight.js/lib/highlight.js | 834 +++++ .../wwwroot/libs/highlight.js/lib/index.js | 189 + .../libs/highlight.js/lib/languages/1c.js | 509 +++ .../libs/highlight.js/lib/languages/abnf.js | 70 + .../highlight.js/lib/languages/accesslog.js | 37 + .../lib/languages/actionscript.js | 73 + .../libs/highlight.js/lib/languages/ada.js | 172 + .../highlight.js/lib/languages/angelscript.js | 106 + .../libs/highlight.js/lib/languages/apache.js | 45 + .../highlight.js/lib/languages/applescript.js | 85 + .../libs/highlight.js/lib/languages/arcade.js | 136 + .../highlight.js/lib/languages/arduino.js | 99 + .../libs/highlight.js/lib/languages/armasm.js | 91 + .../highlight.js/lib/languages/asciidoc.js | 187 + .../highlight.js/lib/languages/aspectj.js | 144 + .../highlight.js/lib/languages/autohotkey.js | 58 + .../libs/highlight.js/lib/languages/autoit.js | 135 + .../libs/highlight.js/lib/languages/avrasm.js | 61 + .../libs/highlight.js/lib/languages/awk.js | 52 + .../libs/highlight.js/lib/languages/axapta.js | 30 + .../libs/highlight.js/lib/languages/bash.js | 74 + .../libs/highlight.js/lib/languages/basic.js | 50 + .../libs/highlight.js/lib/languages/bnf.js | 28 + .../highlight.js/lib/languages/brainfuck.js | 36 + .../libs/highlight.js/lib/languages/cal.js | 79 + .../highlight.js/lib/languages/capnproto.js | 48 + .../libs/highlight.js/lib/languages/ceylon.js | 66 + .../libs/highlight.js/lib/languages/clean.js | 24 + .../lib/languages/clojure-repl.js | 14 + .../highlight.js/lib/languages/clojure.js | 95 + .../libs/highlight.js/lib/languages/cmake.js | 52 + .../lib/languages/coffeescript.js | 145 + .../libs/highlight.js/lib/languages/coq.js | 66 + .../libs/highlight.js/lib/languages/cos.js | 123 + .../libs/highlight.js/lib/languages/cpp.js | 191 + .../libs/highlight.js/lib/languages/crmsh.js | 93 + .../highlight.js/lib/languages/crystal.js | 193 + .../libs/highlight.js/lib/languages/cs.js | 184 + .../libs/highlight.js/lib/languages/csp.js | 21 + .../libs/highlight.js/lib/languages/css.js | 104 + .../libs/highlight.js/lib/languages/d.js | 257 ++ .../libs/highlight.js/lib/languages/dart.js | 103 + .../libs/highlight.js/lib/languages/delphi.js | 68 + .../libs/highlight.js/lib/languages/diff.js | 39 + .../libs/highlight.js/lib/languages/django.js | 63 + .../libs/highlight.js/lib/languages/dns.js | 28 + .../highlight.js/lib/languages/dockerfile.js | 21 + .../libs/highlight.js/lib/languages/dos.js | 51 + .../highlight.js/lib/languages/dsconfig.js | 46 + .../libs/highlight.js/lib/languages/dts.js | 123 + .../libs/highlight.js/lib/languages/dust.js | 31 + .../libs/highlight.js/lib/languages/ebnf.js | 32 + .../libs/highlight.js/lib/languages/elixir.js | 99 + .../libs/highlight.js/lib/languages/elm.js | 89 + .../libs/highlight.js/lib/languages/erb.js | 14 + .../highlight.js/lib/languages/erlang-repl.js | 45 + .../libs/highlight.js/lib/languages/erlang.js | 145 + .../libs/highlight.js/lib/languages/excel.js | 47 + .../libs/highlight.js/lib/languages/fix.js | 28 + .../libs/highlight.js/lib/languages/flix.js | 44 + .../highlight.js/lib/languages/fortran.js | 70 + .../libs/highlight.js/lib/languages/fsharp.js | 58 + .../libs/highlight.js/lib/languages/gams.js | 153 + .../libs/highlight.js/lib/languages/gauss.js | 223 ++ .../libs/highlight.js/lib/languages/gcode.js | 66 + .../highlight.js/lib/languages/gherkin.js | 36 + .../libs/highlight.js/lib/languages/glsl.js | 116 + .../libs/highlight.js/lib/languages/gml.js | 872 +++++ .../libs/highlight.js/lib/languages/go.js | 53 + .../libs/highlight.js/lib/languages/golo.js | 22 + .../libs/highlight.js/lib/languages/gradle.js | 34 + .../libs/highlight.js/lib/languages/groovy.js | 93 + .../libs/highlight.js/lib/languages/haml.js | 106 + .../highlight.js/lib/languages/handlebars.js | 33 + .../highlight.js/lib/languages/haskell.js | 121 + .../libs/highlight.js/lib/languages/haxe.js | 111 + .../libs/highlight.js/lib/languages/hsp.js | 45 + .../highlight.js/lib/languages/htmlbars.js | 70 + .../libs/highlight.js/lib/languages/http.js | 40 + .../libs/highlight.js/lib/languages/hy.js | 101 + .../highlight.js/lib/languages/inform7.js | 56 + .../libs/highlight.js/lib/languages/ini.js | 65 + .../libs/highlight.js/lib/languages/irpf90.js | 75 + .../libs/highlight.js/lib/languages/isbl.js | 3172 +++++++++++++++++ .../libs/highlight.js/lib/languages/java.js | 107 + .../highlight.js/lib/languages/javascript.js | 170 + .../highlight.js/lib/languages/jboss-cli.js | 46 + .../libs/highlight.js/lib/languages/json.js | 36 + .../highlight.js/lib/languages/julia-repl.js | 23 + .../libs/highlight.js/lib/languages/julia.js | 161 + .../libs/highlight.js/lib/languages/kotlin.js | 198 + .../libs/highlight.js/lib/languages/lasso.js | 162 + .../libs/highlight.js/lib/languages/ldif.js | 22 + .../libs/highlight.js/lib/languages/leaf.js | 39 + .../libs/highlight.js/lib/languages/less.js | 139 + .../libs/highlight.js/lib/languages/lisp.js | 102 + .../lib/languages/livecodeserver.js | 156 + .../highlight.js/lib/languages/livescript.js | 148 + .../libs/highlight.js/lib/languages/llvm.js | 88 + .../libs/highlight.js/lib/languages/lsl.js | 82 + .../libs/highlight.js/lib/languages/lua.js | 65 + .../highlight.js/lib/languages/makefile.js | 80 + .../highlight.js/lib/languages/markdown.js | 107 + .../highlight.js/lib/languages/mathematica.js | 57 + .../libs/highlight.js/lib/languages/matlab.js | 95 + .../libs/highlight.js/lib/languages/maxima.js | 405 +++ .../libs/highlight.js/lib/languages/mel.js | 224 ++ .../highlight.js/lib/languages/mercury.js | 81 + .../highlight.js/lib/languages/mipsasm.js | 85 + .../libs/highlight.js/lib/languages/mizar.js | 18 + .../highlight.js/lib/languages/mojolicious.js | 24 + .../libs/highlight.js/lib/languages/monkey.js | 74 + .../highlight.js/lib/languages/moonscript.js | 111 + .../libs/highlight.js/lib/languages/n1ql.js | 68 + .../libs/highlight.js/lib/languages/nginx.js | 92 + .../libs/highlight.js/lib/languages/nimrod.js | 54 + .../libs/highlight.js/lib/languages/nix.js | 48 + .../libs/highlight.js/lib/languages/nsis.js | 105 + .../highlight.js/lib/languages/objectivec.js | 90 + .../libs/highlight.js/lib/languages/ocaml.js | 70 + .../highlight.js/lib/languages/openscad.js | 56 + .../highlight.js/lib/languages/oxygene.js | 69 + .../highlight.js/lib/languages/parser3.js | 47 + .../libs/highlight.js/lib/languages/perl.js | 156 + .../libs/highlight.js/lib/languages/pf.js | 51 + .../libs/highlight.js/lib/languages/pgsql.js | 487 +++ .../libs/highlight.js/lib/languages/php.js | 126 + .../highlight.js/lib/languages/plaintext.js | 5 + .../libs/highlight.js/lib/languages/pony.js | 90 + .../highlight.js/lib/languages/powershell.js | 80 + .../highlight.js/lib/languages/processing.js | 47 + .../highlight.js/lib/languages/profile.js | 29 + .../libs/highlight.js/lib/languages/prolog.js | 87 + .../highlight.js/lib/languages/properties.js | 69 + .../highlight.js/lib/languages/protobuf.js | 35 + .../libs/highlight.js/lib/languages/puppet.js | 114 + .../highlight.js/lib/languages/purebasic.js | 57 + .../libs/highlight.js/lib/languages/python.js | 115 + .../libs/highlight.js/lib/languages/q.js | 22 + .../libs/highlight.js/lib/languages/qml.js | 168 + .../libs/highlight.js/lib/languages/r.js | 69 + .../highlight.js/lib/languages/reasonml.js | 299 ++ .../libs/highlight.js/lib/languages/rib.js | 26 + .../highlight.js/lib/languages/roboconf.js | 66 + .../highlight.js/lib/languages/routeros.js | 158 + .../libs/highlight.js/lib/languages/rsl.js | 35 + .../libs/highlight.js/lib/languages/ruby.js | 176 + .../lib/languages/ruleslanguage.js | 60 + .../libs/highlight.js/lib/languages/rust.js | 107 + .../libs/highlight.js/lib/languages/sas.js | 125 + .../libs/highlight.js/lib/languages/scala.js | 114 + .../libs/highlight.js/lib/languages/scheme.js | 143 + .../libs/highlight.js/lib/languages/scilab.js | 53 + .../libs/highlight.js/lib/languages/scss.js | 97 + .../libs/highlight.js/lib/languages/shell.js | 14 + .../libs/highlight.js/lib/languages/smali.js | 55 + .../highlight.js/lib/languages/smalltalk.js | 49 + .../libs/highlight.js/lib/languages/sml.js | 65 + .../libs/highlight.js/lib/languages/sqf.js | 404 +++ .../libs/highlight.js/lib/languages/sql.js | 161 + .../libs/highlight.js/lib/languages/stan.js | 82 + .../libs/highlight.js/lib/languages/stata.js | 37 + .../libs/highlight.js/lib/languages/step21.js | 46 + .../libs/highlight.js/lib/languages/stylus.js | 453 +++ .../highlight.js/lib/languages/subunit.js | 33 + .../libs/highlight.js/lib/languages/swift.js | 123 + .../lib/languages/taggerscript.js | 43 + .../libs/highlight.js/lib/languages/tap.js | 35 + .../libs/highlight.js/lib/languages/tcl.js | 60 + .../libs/highlight.js/lib/languages/tex.js | 61 + .../libs/highlight.js/lib/languages/thrift.js | 34 + .../libs/highlight.js/lib/languages/tp.js | 83 + .../libs/highlight.js/lib/languages/twig.js | 65 + .../highlight.js/lib/languages/typescript.js | 165 + .../libs/highlight.js/lib/languages/vala.js | 49 + .../libs/highlight.js/lib/languages/vbnet.js | 55 + .../lib/languages/vbscript-html.js | 11 + .../highlight.js/lib/languages/vbscript.js | 38 + .../highlight.js/lib/languages/verilog.js | 98 + .../libs/highlight.js/lib/languages/vhdl.js | 60 + .../libs/highlight.js/lib/languages/vim.js | 109 + .../libs/highlight.js/lib/languages/x86asm.js | 135 + .../libs/highlight.js/lib/languages/xl.js | 72 + .../libs/highlight.js/lib/languages/xml.js | 107 + .../libs/highlight.js/lib/languages/xquery.js | 70 + .../libs/highlight.js/lib/languages/yaml.js | 91 + .../libs/highlight.js/lib/languages/zephir.js | 106 + .../wwwroot/libs/highlight.js/package.json | 1095 ++++++ .../libs/highlight.js/styles/a11y-dark.css | 99 + .../libs/highlight.js/styles/a11y-light.css | 99 + .../libs/highlight.js/styles/agate.css | 108 + .../libs/highlight.js/styles/an-old-hope.css | 89 + .../highlight.js/styles/androidstudio.css | 66 + .../highlight.js/styles/arduino-light.css | 88 + .../wwwroot/libs/highlight.js/styles/arta.css | 73 + .../libs/highlight.js/styles/ascetic.css | 45 + .../highlight.js/styles/atelier-cave-dark.css | 83 + .../styles/atelier-cave-light.css | 85 + .../highlight.js/styles/atelier-dune-dark.css | 69 + .../styles/atelier-dune-light.css | 69 + .../styles/atelier-estuary-dark.css | 84 + .../styles/atelier-estuary-light.css | 84 + .../styles/atelier-forest-dark.css | 69 + .../styles/atelier-forest-light.css | 69 + .../styles/atelier-heath-dark.css | 69 + .../styles/atelier-heath-light.css | 69 + .../styles/atelier-lakeside-dark.css | 69 + .../styles/atelier-lakeside-light.css | 69 + .../styles/atelier-plateau-dark.css | 84 + .../styles/atelier-plateau-light.css | 84 + .../styles/atelier-savanna-dark.css | 84 + .../styles/atelier-savanna-light.css | 84 + .../styles/atelier-seaside-dark.css | 69 + .../styles/atelier-seaside-light.css | 69 + .../styles/atelier-sulphurpool-dark.css | 69 + .../styles/atelier-sulphurpool-light.css | 69 + .../styles/atom-one-dark-reasonable.css | 77 + .../highlight.js/styles/atom-one-dark.css | 96 + .../highlight.js/styles/atom-one-light.css | 96 + .../libs/highlight.js/styles/brown-paper.css | 64 + .../highlight.js/styles/brown-papersq.png | Bin 0 -> 18198 bytes .../highlight.js/styles/codepen-embed.css | 60 + .../libs/highlight.js/styles/color-brewer.css | 71 + .../libs/highlight.js/styles/darcula.css | 77 + .../wwwroot/libs/highlight.js/styles/dark.css | 63 + .../libs/highlight.js/styles/darkula.css | 6 + .../libs/highlight.js/styles/default.css | 99 + .../libs/highlight.js/styles/docco.css | 97 + .../libs/highlight.js/styles/dracula.css | 76 + .../wwwroot/libs/highlight.js/styles/far.css | 71 + .../libs/highlight.js/styles/foundation.css | 88 + .../libs/highlight.js/styles/github-gist.css | 71 + .../libs/highlight.js/styles/github.css | 99 + .../wwwroot/libs/highlight.js/styles/gml.css | 78 + .../libs/highlight.js/styles/googlecode.css | 89 + .../libs/highlight.js/styles/grayscale.css | 101 + .../libs/highlight.js/styles/gruvbox-dark.css | 108 + .../highlight.js/styles/gruvbox-light.css | 108 + .../libs/highlight.js/styles/hopscotch.css | 83 + .../libs/highlight.js/styles/hybrid.css | 102 + .../wwwroot/libs/highlight.js/styles/idea.css | 97 + .../libs/highlight.js/styles/ir-black.css | 73 + .../highlight.js/styles/isbl-editor-dark.css | 112 + .../highlight.js/styles/isbl-editor-light.css | 112 + .../libs/highlight.js/styles/kimbie.dark.css | 74 + .../libs/highlight.js/styles/kimbie.light.css | 74 + .../libs/highlight.js/styles/lightfair.css | 87 + .../libs/highlight.js/styles/magula.css | 70 + .../libs/highlight.js/styles/mono-blue.css | 59 + .../highlight.js/styles/monokai-sublime.css | 83 + .../libs/highlight.js/styles/monokai.css | 70 + .../wwwroot/libs/highlight.js/styles/nord.css | 309 ++ .../libs/highlight.js/styles/obsidian.css | 88 + .../libs/highlight.js/styles/ocean.css | 74 + .../libs/highlight.js/styles/paraiso-dark.css | 72 + .../highlight.js/styles/paraiso-light.css | 72 + .../libs/highlight.js/styles/pojoaque.css | 83 + .../libs/highlight.js/styles/pojoaque.jpg | Bin 0 -> 1186 bytes .../libs/highlight.js/styles/purebasic.css | 96 + .../highlight.js/styles/qtcreator_dark.css | 83 + .../highlight.js/styles/qtcreator_light.css | 83 + .../libs/highlight.js/styles/railscasts.css | 106 + .../libs/highlight.js/styles/rainbow.css | 85 + .../libs/highlight.js/styles/routeros.css | 108 + .../libs/highlight.js/styles/school-book.css | 72 + .../libs/highlight.js/styles/school-book.png | Bin 0 -> 486 bytes .../highlight.js/styles/shades-of-purple.css | 97 + .../highlight.js/styles/solarized-dark.css | 84 + .../highlight.js/styles/solarized-light.css | 84 + .../libs/highlight.js/styles/sunburst.css | 102 + .../styles/tomorrow-night-blue.css | 75 + .../styles/tomorrow-night-bright.css | 74 + .../styles/tomorrow-night-eighties.css | 74 + .../highlight.js/styles/tomorrow-night.css | 75 + .../libs/highlight.js/styles/tomorrow.css | 72 + .../wwwroot/libs/highlight.js/styles/vs.css | 68 + .../libs/highlight.js/styles/vs2015.css | 115 + .../libs/highlight.js/styles/xcode.css | 104 + .../libs/highlight.js/styles/xt256.css | 92 + .../libs/highlight.js/styles/zenburn.css | 80 + .../yarn.lock | 152 +- 296 files changed, 32565 insertions(+), 79 deletions(-) create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/highlightCode.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/README.md create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/api.rst create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/building-testing.rst create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/css-classes-reference.rst create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/index.rst create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/language-contribution.rst create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/language-guide.rst create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/language-requests.rst create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/line-numbers.rst create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/maintainers-guide.rst create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/reference.rst create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/style-guide.rst create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/highlight.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/index.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/1c.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/abnf.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/accesslog.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/actionscript.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/ada.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/angelscript.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/apache.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/applescript.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/arcade.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/arduino.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/armasm.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/asciidoc.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/aspectj.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/autohotkey.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/autoit.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/avrasm.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/awk.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/axapta.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/bash.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/basic.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/bnf.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/brainfuck.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/cal.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/capnproto.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/ceylon.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/clean.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/clojure-repl.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/clojure.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/cmake.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/coffeescript.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/coq.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/cos.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/cpp.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/crmsh.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/crystal.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/cs.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/csp.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/css.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/d.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/dart.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/delphi.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/diff.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/django.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/dns.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/dockerfile.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/dos.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/dsconfig.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/dts.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/dust.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/ebnf.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/elixir.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/elm.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/erb.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/erlang-repl.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/erlang.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/excel.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/fix.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/flix.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/fortran.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/fsharp.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/gams.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/gauss.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/gcode.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/gherkin.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/glsl.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/gml.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/go.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/golo.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/gradle.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/groovy.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/haml.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/handlebars.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/haskell.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/haxe.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/hsp.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/htmlbars.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/http.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/hy.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/inform7.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/ini.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/irpf90.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/isbl.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/java.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/javascript.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/jboss-cli.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/json.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/julia-repl.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/julia.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/kotlin.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/lasso.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/ldif.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/leaf.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/less.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/lisp.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/livecodeserver.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/livescript.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/llvm.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/lsl.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/lua.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/makefile.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/markdown.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/mathematica.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/matlab.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/maxima.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/mel.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/mercury.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/mipsasm.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/mizar.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/mojolicious.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/monkey.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/moonscript.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/n1ql.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/nginx.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/nimrod.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/nix.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/nsis.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/objectivec.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/ocaml.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/openscad.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/oxygene.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/parser3.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/perl.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/pf.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/pgsql.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/php.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/plaintext.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/pony.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/powershell.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/processing.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/profile.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/prolog.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/properties.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/protobuf.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/puppet.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/purebasic.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/python.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/q.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/qml.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/r.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/reasonml.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/rib.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/roboconf.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/routeros.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/rsl.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/ruby.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/ruleslanguage.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/rust.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/sas.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/scala.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/scheme.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/scilab.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/scss.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/shell.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/smali.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/smalltalk.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/sml.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/sqf.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/sql.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/stan.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/stata.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/step21.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/stylus.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/subunit.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/swift.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/taggerscript.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/tap.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/tcl.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/tex.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/thrift.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/tp.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/twig.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/typescript.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/vala.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/vbnet.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/vbscript-html.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/vbscript.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/verilog.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/vhdl.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/vim.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/x86asm.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/xl.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/xml.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/xquery.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/yaml.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/lib/languages/zephir.js create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/package.json create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/a11y-dark.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/a11y-light.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/agate.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/an-old-hope.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/androidstudio.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/arduino-light.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/arta.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/ascetic.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atelier-cave-dark.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atelier-cave-light.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atelier-dune-dark.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atelier-dune-light.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atelier-estuary-dark.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atelier-estuary-light.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atelier-forest-dark.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atelier-forest-light.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atelier-heath-dark.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atelier-heath-light.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atelier-lakeside-dark.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atelier-lakeside-light.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atelier-plateau-dark.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atelier-plateau-light.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atelier-savanna-dark.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atelier-savanna-light.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atelier-seaside-dark.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atelier-seaside-light.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atelier-sulphurpool-dark.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atelier-sulphurpool-light.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atom-one-dark-reasonable.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atom-one-dark.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/atom-one-light.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/brown-paper.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/brown-papersq.png create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/codepen-embed.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/color-brewer.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/darcula.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/dark.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/darkula.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/default.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/docco.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/dracula.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/far.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/foundation.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/github-gist.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/github.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/gml.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/googlecode.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/grayscale.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/gruvbox-dark.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/gruvbox-light.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/hopscotch.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/hybrid.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/idea.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/ir-black.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/isbl-editor-dark.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/isbl-editor-light.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/kimbie.dark.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/kimbie.light.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/lightfair.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/magula.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/mono-blue.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/monokai-sublime.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/monokai.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/nord.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/obsidian.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/ocean.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/paraiso-dark.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/paraiso-light.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/pojoaque.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/pojoaque.jpg create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/purebasic.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/qtcreator_dark.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/qtcreator_light.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/railscasts.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/rainbow.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/routeros.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/school-book.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/school-book.png create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/shades-of-purple.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/solarized-dark.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/solarized-light.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/sunburst.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/tomorrow-night-blue.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/tomorrow-night-bright.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/tomorrow-night-eighties.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/tomorrow-night.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/tomorrow.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/vs.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/vs2015.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/xcode.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/xt256.css create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/styles/zenburn.css diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/highlightCode.js b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/highlightCode.js new file mode 100644 index 0000000000..a20784d518 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/highlightCode.js @@ -0,0 +1,5 @@ +$(document).ready(function () { + $('pre code').each(function (i, block) { + hljs.highlightBlock(block); + }); +}); \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/abp.resourcemapping.js b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/abp.resourcemapping.js index 8f527171c0..d4d18c1f07 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/abp.resourcemapping.js +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/abp.resourcemapping.js @@ -7,6 +7,6 @@ "@libs" ], mappings: { - + "@node_modules/highlight.js/**/*.*": "@libs/highlight.js/" } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json index 8e2fcccc97..29e8cca7cb 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json @@ -3,8 +3,8 @@ "name": "asp.net", "private": true, "dependencies": { - "@abp/aspnetcore.mvc.ui.theme.shared": "^0.4.3" + "@abp/aspnetcore.mvc.ui.theme.shared": "^0.4.3", + "highlight.js": "^9.13.1" }, - "devDependencies": { - } -} \ No newline at end of file + "devDependencies": {} +} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/README.md b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/README.md new file mode 100644 index 0000000000..6cf523594c --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/README.md @@ -0,0 +1,186 @@ +# Highlight.js + +[![Build Status](https://travis-ci.org/highlightjs/highlight.js.svg?branch=master)](https://travis-ci.org/highlightjs/highlight.js) + +Highlight.js is a syntax highlighter written in JavaScript. It works in +the browser as well as on the server. It works with pretty much any +markup, doesn’t depend on any framework, and has automatic language +detection. + +## Getting Started + +The bare minimum for using highlight.js on a web page is linking to the +library along with one of the styles and calling +[`initHighlightingOnLoad`][1]: + +```html + + + +``` + +This will find and highlight code inside of `
` tags; it tries
+to detect the language automatically. If automatic detection doesn’t
+work for you, you can specify the language in the `class` attribute:
+
+```html
+
...
+``` + +The list of supported language classes is available in the [class +reference][2]. Classes can also be prefixed with either `language-` or +`lang-`. + +To make arbitrary text look like code, but without highlighting, use the +`plaintext` class: + +```html +
...
+``` + +To disable highlighting altogether use the `nohighlight` class: + +```html +
...
+``` + +## Custom Initialization + +When you need a bit more control over the initialization of +highlight.js, you can use the [`highlightBlock`][3] and [`configure`][4] +functions. This allows you to control *what* to highlight and *when*. + +Here’s an equivalent way to calling [`initHighlightingOnLoad`][1] using +jQuery: + +```javascript +$(document).ready(function() { + $('pre code').each(function(i, block) { + hljs.highlightBlock(block); + }); +}); +``` + +You can use any tags instead of `
` to mark up your code. If
+you don't use a container that preserves line breaks you will need to
+configure highlight.js to use the `
` tag: + +```javascript +hljs.configure({useBR: true}); + +$('div.code').each(function(i, block) { + hljs.highlightBlock(block); +}); +``` + +For other options refer to the documentation for [`configure`][4]. + + +## Web Workers + +You can run highlighting inside a web worker to avoid freezing the browser +window while dealing with very big chunks of code. + +In your main script: + +```javascript +addEventListener('load', function() { + var code = document.querySelector('#code'); + var worker = new Worker('worker.js'); + worker.onmessage = function(event) { code.innerHTML = event.data; } + worker.postMessage(code.textContent); +}) +``` + +In worker.js: + +```javascript +onmessage = function(event) { + importScripts('/highlight.pack.js'); + var result = self.hljs.highlightAuto(event.data); + postMessage(result.value); +} +``` + + +## Getting the Library + +You can get highlight.js as a hosted, or custom-build, browser script or +as a server module. Right out of the box the browser script supports +both AMD and CommonJS, so if you wish you can use RequireJS or +Browserify without having to build from source. The server module also +works perfectly fine with Browserify, but there is the option to use a +build specific to browsers rather than something meant for a server. +Head over to the [download page][5] for all the options. + +**Don't link to GitHub directly.** The library is not supposed to work straight +from the source, it requires building. If none of the pre-packaged options +work for you refer to the [building documentation][6]. + +**The CDN-hosted package doesn't have all the languages.** Otherwise it'd be +too big. If you don't see the language you need in the ["Common" section][5], +it can be added manually: + +```html + +``` + +**On Almond.** You need to use the optimizer to give the module a name. For +example: + +``` +r.js -o name=hljs paths.hljs=/path/to/highlight out=highlight.js +``` + + +### CommonJS + +You can import Highlight.js as a CommonJS-module: + +```bash +npm install highlight.js --save +``` + +In your application: + +```javascript +import hljs from 'highlight.js'; +``` + +The default import imports all languages! Therefore it is likely to be more efficient to import only the library and the languages you need: + +```javascript +import hljs from 'highlight.js/lib/highlight'; +import javascript from 'highlight.js/lib/languages/javascript'; +hljs.registerLanguage('javascript', javascript); +``` + +To set the syntax highlighting style, if your build tool processes CSS from your JavaScript entry point, you can import the stylesheet directly into your CommonJS-module: + +```javascript +import hljs from 'highlight.js/lib/highlight'; +import 'highlight.js/styles/github.css' +``` + +## License + +Highlight.js is released under the BSD License. See [LICENSE][7] file +for details. + +## Links + +The official site for the library is at . + +Further in-depth documentation for the API and other topics is at +. + +Authors and contributors are listed in the [AUTHORS.en.txt][8] file. + +[1]: http://highlightjs.readthedocs.io/en/latest/api.html#inithighlightingonload +[2]: http://highlightjs.readthedocs.io/en/latest/css-classes-reference.html +[3]: http://highlightjs.readthedocs.io/en/latest/api.html#highlightblock-block +[4]: http://highlightjs.readthedocs.io/en/latest/api.html#configure-options +[5]: https://highlightjs.org/download/ +[6]: http://highlightjs.readthedocs.io/en/latest/building-testing.html +[7]: https://github.com/highlightjs/highlight.js/blob/master/LICENSE +[8]: https://github.com/highlightjs/highlight.js/blob/master/AUTHORS.en.txt diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/api.rst b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/api.rst new file mode 100644 index 0000000000..d8039539d3 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/api.rst @@ -0,0 +1,120 @@ +Library API +=========== + +Highlight.js exports a few functions as methods of the ``hljs`` object. + + +``highlight(name, value, ignore_illegals, continuation)`` +--------------------------------------------------------- + +Core highlighting function. +Accepts a language name, or an alias, and a string with the code to highlight. +The ``ignore_illegals`` parameter, when present and evaluates to a true value, +forces highlighting to finish even in case of detecting illegal syntax for the +language instead of throwing an exception. +The ``continuation`` is an optional mode stack representing unfinished parsing. +When present, the function will restart parsing from this state instead of +initializing a new one. +Returns an object with the following properties: + +* ``language``: language name, same as the one passed into a function, returned for consistency with ``highlightAuto`` +* ``relevance``: integer value +* ``value``: HTML string with highlighting markup +* ``top``: top of the current mode stack + + +``highlightAuto(value, languageSubset)`` +---------------------------------------- + +Highlighting with language detection. +Accepts a string with the code to highlight and an optional array of language names and aliases restricting detection to only those languages. The subset can also be set with ``configure``, but the local parameter overrides the option if set. +Returns an object with the following properties: + +* ``language``: detected language +* ``relevance``: integer value +* ``value``: HTML string with highlighting markup +* ``second_best``: object with the same structure for second-best heuristically detected language, may be absent + + +``fixMarkup(value)`` +-------------------- + +Post-processing of the highlighted markup. Currently consists of replacing indentation TAB characters and using ``
`` tags instead of new-line characters. Options are set globally with ``configure``. + +Accepts a string with the highlighted markup. + + +``highlightBlock(block)`` +------------------------- + +Applies highlighting to a DOM node containing code. + +This function is the one to use to apply highlighting dynamically after page load +or within initialization code of third-party Javascript frameworks. + +The function uses language detection by default but you can specify the language +in the ``class`` attribute of the DOM node. See the :doc:`class reference +` for all available language names and aliases. + + +``configure(options)`` +---------------------- + +Configures global options: + +* ``tabReplace``: a string used to replace TAB characters in indentation. +* ``useBR``: a flag to generate ``
`` tags instead of new-line characters in the output, useful when code is marked up using a non-``
`` container.
+* ``classPrefix``: a string prefix added before class names in the generated markup, used for backwards compatibility with stylesheets.
+* ``languages``: an array of language names and aliases restricting auto detection to only these languages.
+
+Accepts an object representing options with the values to updated. Other options don't change
+::
+
+  hljs.configure({
+    tabReplace: '    ', // 4 spaces
+    classPrefix: ''     // don't append class prefix
+                        // … other options aren't changed
+  })
+  hljs.initHighlighting();
+
+
+``initHighlighting()``
+----------------------
+
+Applies highlighting to all ``
..
`` blocks on a page. + + + +``initHighlightingOnLoad()`` +---------------------------- + +Attaches highlighting to the page load event. + + +``registerLanguage(name, language)`` +------------------------------------ + +Adds new language to the library under the specified name. Used mostly internally. + +* ``name``: a string with the name of the language being registered +* ``language``: a function that returns an object which represents the + language definition. The function is passed the ``hljs`` object to be able + to use common regular expressions defined within it. + + +``listLanguages()`` +---------------------------- + +Returns the languages names list. + + + +.. _getLanguage: + + +``getLanguage(name)`` +--------------------- + +Looks up a language by name or alias. + +Returns the language object if found, ``undefined`` otherwise. diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/building-testing.rst b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/building-testing.rst new file mode 100644 index 0000000000..16292cb84a --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/building-testing.rst @@ -0,0 +1,88 @@ +Building and testing +==================== + +To actually run highlight.js it is necessary to build it for the environment +where you're going to run it: a browser, the node.js server, etc. + + +Building +-------- + +The build tool is written in JavaScript using node.js. Before running the +script, make sure to have node installed and run ``npm install`` to get the +dependencies. + +The tool is located in ``tools/build.js``. A few useful examples: + +* Build for a browser using only common languages:: + + node tools/build.js :common + +* Build for node.js including all available languages:: + + node tools/build.js -t node + +* Build two specific languages for debugging, skipping compression in this case:: + + node tools/build.js -n python ruby + +On some systems the node binary is named ``nodejs``; simply replace ``node`` +with ``nodejs`` in the examples above if that is the case. + +The full option reference is available with the usual ``--help`` option. + +The build result will be in the ``build/`` directory. + +.. _basic-testing: + +Basic testing +------------- + +The usual approach to debugging and testing a language is first doing it +visually. You need to build highlight.js with only the language you're working +on (without compression, to have readable code in browser error messages) and +then use the Developer tool in ``tools/developer.html`` to see how it highlights +a test snippet in that language. + +A test snippet should be short and give the idea of the overall look of the +language. It shouldn't include every possible syntactic element and shouldn't +even make practical sense. + +After you satisfied with the result you need to make sure that language +detection still works with your language definition included in the whole suite. + +Testing is done using `Mocha `_ and the +files are found in the ``test/`` directory. You can use the node build to +run the tests in the command line with ``npm test`` after installing the +dependencies with ``npm install``. + +**Note**: for Debian-based machine, like Ubuntu, you might need to create an +alias or symbolic link for nodejs to node. The reason for this is the +dependencies that are requires to test highlight.js has a reference to +"node". + +Place the snippet you used inside the browser in +``test/detect//default.txt``, build the package with all the languages +for node and run the test suite. If your language breaks auto-detection, it +should be fixed by :ref:`improving relevance `, which is a black art +in and of itself. When in doubt, please refer to the discussion group! + + +Testing markup +-------------- + +You can also provide additional markup tests for the language to test isolated +cases of various syntactic construct. If your language has 19 different string +literals or complicated heuristics for telling division (``/``) apart from +regexes (``/ .. /``) -- this is the place. + +A test case consists of two files: + +* ``test/markup//.txt``: test code +* ``test/markup//.expect.txt``: reference rendering + +To generate reference rendering use the Developer tool located at +``tools/developer.html``. Make sure to explicitly select your language in the +drop-down menu, as automatic detection is unlikely to work in this case. + + diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/css-classes-reference.rst b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/css-classes-reference.rst new file mode 100644 index 0000000000..1975f235b8 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/css-classes-reference.rst @@ -0,0 +1,460 @@ +CSS classes reference +===================== + + +Stylable classes +---------------- + ++------------------------------------------------------------------------------+ +| **General-purpose** | ++--------------------------+---------------------------------------------------+ +| keyword | keyword in a regular Algol-style language | ++--------------------------+---------------------------------------------------+ +| built_in | built-in or library object (constant, class, | +| | function) | ++--------------------------+---------------------------------------------------+ +| type | user-defined type in a language with first-class | +| | syntactically significant types, like Haskell | ++--------------------------+---------------------------------------------------+ +| literal | special identifier for a built-in value ("true", | +| | "false", "null") | ++--------------------------+---------------------------------------------------+ +| number | number, including units and modifiers, if any. | ++--------------------------+---------------------------------------------------+ +| regexp | literal regular expression | ++--------------------------+---------------------------------------------------+ +| string | literal string, character | ++--------------------------+---------------------------------------------------+ +| subst | parsed section inside a literal string | ++--------------------------+---------------------------------------------------+ +| symbol | symbolic constant, interned string, goto label | ++--------------------------+---------------------------------------------------+ +| class | class or class-level declaration (interfaces, | +| | traits, modules, etc) | ++--------------------------+---------------------------------------------------+ +| function | function or method declaration | ++--------------------------+---------------------------------------------------+ +| title | name of a class or a function at the place of | +| | declaration | ++--------------------------+---------------------------------------------------+ +| params | block of function arguments (parameters) at the | +| | place of declaration | ++--------------------------+---------------------------------------------------+ +| **Meta** | ++--------------------------+---------------------------------------------------+ +| comment | comment | ++--------------------------+---------------------------------------------------+ +| doctag | documentation markup within comments | ++--------------------------+---------------------------------------------------+ +| meta | flags, modifiers, annotations, processing | +| | instructions, preprocessor directive, etc | ++--------------------------+---------------------------------------------------+ +| meta-keyword | keyword or built-in within meta construct | ++--------------------------+---------------------------------------------------+ +| meta-string | string within meta construct | ++--------------------------+---------------------------------------------------+ +| **Tags, attributes, configs** | ++--------------------------+---------------------------------------------------+ +| section | heading of a section in a config file, heading in | +| | text markup | ++--------------------------+---------------------------------------------------+ +| tag | XML/HTML tag | ++--------------------------+---------------------------------------------------+ +| name | name of an XML tag, the first word in an | +| | s-expression | ++--------------------------+---------------------------------------------------+ +| builtin-name | s-expression name from the language standard | +| | library | ++--------------------------+---------------------------------------------------+ +| attr | name of an attribute with no language defined | +| | semantics (keys in JSON, setting names in .ini), | +| | also sub-attribute within another highlighted | +| | object, like XML tag | ++--------------------------+---------------------------------------------------+ +| attribute | name of an attribute followed by a structured | +| | value part, like CSS properties | ++--------------------------+---------------------------------------------------+ +| variable | variable in a config or a template file, | +| | environment var expansion in a script | ++--------------------------+---------------------------------------------------+ +| **Markup** | ++--------------------------+---------------------------------------------------+ +| bullet | list item bullet in text markup | ++--------------------------+---------------------------------------------------+ +| code | code block in text markup | ++--------------------------+---------------------------------------------------+ +| emphasis | emphasis in text markup | ++--------------------------+---------------------------------------------------+ +| strong | strong emphasis in text markup | ++--------------------------+---------------------------------------------------+ +| formula | mathematical formula in text markup | ++--------------------------+---------------------------------------------------+ +| link | hyperlink in text markup | ++--------------------------+---------------------------------------------------+ +| quote | quotation in text markup | ++--------------------------+---------------------------------------------------+ +| **CSS** | ++--------------------------+---------------------------------------------------+ +| selector-tag | tag selector in CSS | ++--------------------------+---------------------------------------------------+ +| selector-id | #id selector in CSS | ++--------------------------+---------------------------------------------------+ +| selector-class | .class selector in CSS | ++--------------------------+---------------------------------------------------+ +| selector-attr | [attr] selector in CSS | ++--------------------------+---------------------------------------------------+ +| selector-pseudo | :pseudo selector in CSS | ++--------------------------+---------------------------------------------------+ +| **Templates** | ++--------------------------+---------------------------------------------------+ +| template-tag | tag of a template language | ++--------------------------+---------------------------------------------------+ +| template-variable | variable in a template language | ++--------------------------+---------------------------------------------------+ +| **diff** | ++--------------------------+---------------------------------------------------+ +| addition | added or changed line in a diff | ++--------------------------+---------------------------------------------------+ +| deletion | deleted line in a diff | ++--------------------------+---------------------------------------------------+ +| **ReasonML** | ++--------------------------+---------------------------------------------------+ +| operator | reasonml operator such as pipe | ++--------------------------+---------------------------------------------------+ +| pattern-match | reasonml pattern matching matchers | ++--------------------------+---------------------------------------------------+ +| typing | type signatures on function parameters | ++--------------------------+---------------------------------------------------+ +| constructor | type constructors | ++--------------------------+---------------------------------------------------+ +| module-access | scope access into a ReasonML module | ++--------------------------+---------------------------------------------------+ +| module | ReasonML module reference within scope access | ++--------------------------+---------------------------------------------------+ + + +Language names and aliases +-------------------------- + ++-------------------------+---------------------------------------------------+ +| 1C | 1c | ++-------------------------+---------------------------------------------------+ +| ABNF | abnf | ++-------------------------+---------------------------------------------------+ +| Access logs | accesslog | ++-------------------------+---------------------------------------------------+ +| Ada | ada | ++-------------------------+---------------------------------------------------+ +| ARM assembler | armasm, arm | ++-------------------------+---------------------------------------------------+ +| AVR assembler | avrasm | ++-------------------------+---------------------------------------------------+ +| ActionScript | actionscript, as | ++-------------------------+---------------------------------------------------+ +| AngelScript | angelscript, asc | ++-------------------------+---------------------------------------------------+ +| Apache | apache, apacheconf | ++-------------------------+---------------------------------------------------+ +| AppleScript | applescript, osascript | ++-------------------------+---------------------------------------------------+ +| Arcade | arcade | ++-------------------------+---------------------------------------------------+ +| AsciiDoc | asciidoc, adoc | ++-------------------------+---------------------------------------------------+ +| AspectJ | aspectj | ++-------------------------+---------------------------------------------------+ +| AutoHotkey | autohotkey | ++-------------------------+---------------------------------------------------+ +| AutoIt | autoit | ++-------------------------+---------------------------------------------------+ +| Awk | awk, mawk, nawk, gawk | ++-------------------------+---------------------------------------------------+ +| Axapta | axapta | ++-------------------------+---------------------------------------------------+ +| Bash | bash, sh, zsh | ++-------------------------+---------------------------------------------------+ +| Basic | basic | ++-------------------------+---------------------------------------------------+ +| BNF | bnf | ++-------------------------+---------------------------------------------------+ +| Brainfuck | brainfuck, bf | ++-------------------------+---------------------------------------------------+ +| C# | cs, csharp | ++-------------------------+---------------------------------------------------+ +| C++ | cpp, c, cc, h, c++, h++, hpp | ++-------------------------+---------------------------------------------------+ +| C/AL | cal | ++-------------------------+---------------------------------------------------+ +| Cache Object Script | cos, cls | ++-------------------------+---------------------------------------------------+ +| CMake | cmake, cmake.in | ++-------------------------+---------------------------------------------------+ +| Coq | coq | ++-------------------------+---------------------------------------------------+ +| CSP | csp | ++-------------------------+---------------------------------------------------+ +| CSS | css | ++-------------------------+---------------------------------------------------+ +| Cap’n Proto | capnproto, capnp | ++-------------------------+---------------------------------------------------+ +| Clojure | clojure, clj | ++-------------------------+---------------------------------------------------+ +| CoffeeScript | coffeescript, coffee, cson, iced | ++-------------------------+---------------------------------------------------+ +| Crmsh | crmsh, crm, pcmk | ++-------------------------+---------------------------------------------------+ +| Crystal | crystal, cr | ++-------------------------+---------------------------------------------------+ +| D | d | ++-------------------------+---------------------------------------------------+ +| DNS Zone file | dns, zone, bind | ++-------------------------+---------------------------------------------------+ +| DOS | dos, bat, cmd | ++-------------------------+---------------------------------------------------+ +| Dart | dart | ++-------------------------+---------------------------------------------------+ +| Delphi | delphi, dpr, dfm, pas, pascal, freepascal, | +| | lazarus, lpr, lfm | ++-------------------------+---------------------------------------------------+ +| Diff | diff, patch | ++-------------------------+---------------------------------------------------+ +| Django | django, jinja | ++-------------------------+---------------------------------------------------+ +| Dockerfile | dockerfile, docker | ++-------------------------+---------------------------------------------------+ +| dsconfig | dsconfig | ++-------------------------+---------------------------------------------------+ +| DTS (Device Tree) | dts | ++-------------------------+---------------------------------------------------+ +| Dust | dust, dst | ++-------------------------+---------------------------------------------------+ +| EBNF | ebnf | ++-------------------------+---------------------------------------------------+ +| Elixir | elixir | ++-------------------------+---------------------------------------------------+ +| Elm | elm | ++-------------------------+---------------------------------------------------+ +| Erlang | erlang, erl | ++-------------------------+---------------------------------------------------+ +| Excel | excel, xls, xlsx | ++-------------------------+---------------------------------------------------+ +| F# | fsharp, fs | ++-------------------------+---------------------------------------------------+ +| FIX | fix | ++-------------------------+---------------------------------------------------+ +| Fortran | fortran, f90, f95 | ++-------------------------+---------------------------------------------------+ +| G-Code | gcode, nc | ++-------------------------+---------------------------------------------------+ +| Gams | gams, gms | ++-------------------------+---------------------------------------------------+ +| GAUSS | gauss, gss | ++-------------------------+---------------------------------------------------+ +| Gherkin | gherkin | ++-------------------------+---------------------------------------------------+ +| Go | go, golang | ++-------------------------+---------------------------------------------------+ +| Golo | golo, gololang | ++-------------------------+---------------------------------------------------+ +| Gradle | gradle | ++-------------------------+---------------------------------------------------+ +| Groovy | groovy | ++-------------------------+---------------------------------------------------+ +| HTML, XML | xml, html, xhtml, rss, atom, xjb, xsd, xsl, plist | ++-------------------------+---------------------------------------------------+ +| HTTP | http, https | ++-------------------------+---------------------------------------------------+ +| Haml | haml | ++-------------------------+---------------------------------------------------+ +| Handlebars | handlebars, hbs, html.hbs, html.handlebars | ++-------------------------+---------------------------------------------------+ +| Haskell | haskell, hs | ++-------------------------+---------------------------------------------------+ +| Haxe | haxe, hx | ++-------------------------+---------------------------------------------------+ +| Hy | hy, hylang | ++-------------------------+---------------------------------------------------+ +| Ini, TOML | ini, toml | ++-------------------------+---------------------------------------------------+ +| Inform7 | inform7, i7 | ++-------------------------+---------------------------------------------------+ +| IRPF90 | irpf90 | ++-------------------------+---------------------------------------------------+ +| JSON | json | ++-------------------------+---------------------------------------------------+ +| Java | java, jsp | ++-------------------------+---------------------------------------------------+ +| JavaScript | javascript, js, jsx | ++-------------------------+---------------------------------------------------+ +| Leaf | leaf | ++-------------------------+---------------------------------------------------+ +| Lasso | lasso, ls, lassoscript | ++-------------------------+---------------------------------------------------+ +| Less | less | ++-------------------------+---------------------------------------------------+ +| LDIF | ldif | ++-------------------------+---------------------------------------------------+ +| Lisp | lisp | ++-------------------------+---------------------------------------------------+ +| LiveCode Server | livecodeserver | ++-------------------------+---------------------------------------------------+ +| LiveScript | livescript, ls | ++-------------------------+---------------------------------------------------+ +| Lua | lua | ++-------------------------+---------------------------------------------------+ +| Makefile | makefile, mk, mak | ++-------------------------+---------------------------------------------------+ +| Markdown | markdown, md, mkdown, mkd | ++-------------------------+---------------------------------------------------+ +| Mathematica | mathematica, mma | ++-------------------------+---------------------------------------------------+ +| Matlab | matlab | ++-------------------------+---------------------------------------------------+ +| Maxima | maxima | ++-------------------------+---------------------------------------------------+ +| Maya Embedded Language | mel | ++-------------------------+---------------------------------------------------+ +| Mercury | mercury | ++-------------------------+---------------------------------------------------+ +| Mizar | mizar | ++-------------------------+---------------------------------------------------+ +| Mojolicious | mojolicious | ++-------------------------+---------------------------------------------------+ +| Monkey | monkey | ++-------------------------+---------------------------------------------------+ +| Moonscript | moonscript, moon | ++-------------------------+---------------------------------------------------+ +| N1QL | n1ql | ++-------------------------+---------------------------------------------------+ +| NSIS | nsis | ++-------------------------+---------------------------------------------------+ +| Nginx | nginx, nginxconf | ++-------------------------+---------------------------------------------------+ +| Nimrod | nimrod, nim | ++-------------------------+---------------------------------------------------+ +| Nix | nix | ++-------------------------+---------------------------------------------------+ +| OCaml | ocaml, ml | ++-------------------------+---------------------------------------------------+ +| Objective C | objectivec, mm, objc, obj-c | ++-------------------------+---------------------------------------------------+ +| OpenGL Shading Language | glsl | ++-------------------------+---------------------------------------------------+ +| OpenSCAD | openscad, scad | ++-------------------------+---------------------------------------------------+ +| Oracle Rules Language | ruleslanguage | ++-------------------------+---------------------------------------------------+ +| Oxygene | oxygene | ++-------------------------+---------------------------------------------------+ +| PF | pf, pf.conf | ++-------------------------+---------------------------------------------------+ +| PHP | php, php3, php4, php5, php6 | ++-------------------------+---------------------------------------------------+ +| Parser3 | parser3 | ++-------------------------+---------------------------------------------------+ +| Perl | perl, pl, pm | ++-------------------------+---------------------------------------------------+ +| Plaintext: no highlight | plaintext | ++-------------------------+---------------------------------------------------+ +| Pony | pony | ++-------------------------+---------------------------------------------------+ +| PostgreSQL & PL/pgSQL | pgsql, postgres, postgresql | ++-------------------------+---------------------------------------------------+ +| PowerShell | powershell, ps | ++-------------------------+---------------------------------------------------+ +| Processing | processing | ++-------------------------+---------------------------------------------------+ +| Prolog | prolog | ++-------------------------+---------------------------------------------------+ +| Properties | properties | ++-------------------------+---------------------------------------------------+ +| Protocol Buffers | protobuf | ++-------------------------+---------------------------------------------------+ +| Puppet | puppet, pp | ++-------------------------+---------------------------------------------------+ +| Python | python, py, gyp | ++-------------------------+---------------------------------------------------+ +| Python profiler results | profile | ++-------------------------+---------------------------------------------------+ +| Q | k, kdb | ++-------------------------+---------------------------------------------------+ +| QML | qml | ++-------------------------+---------------------------------------------------+ +| R | r | ++-------------------------+---------------------------------------------------+ +| ReasonML | reasonml, re | ++-------------------------+---------------------------------------------------+ +| RenderMan RIB | rib | ++-------------------------+---------------------------------------------------+ +| RenderMan RSL | rsl | ++-------------------------+---------------------------------------------------+ +| Roboconf | graph, instances | ++-------------------------+---------------------------------------------------+ +| Ruby | ruby, rb, gemspec, podspec, thor, irb | ++-------------------------+---------------------------------------------------+ +| Rust | rust, rs | ++-------------------------+---------------------------------------------------+ +| SCSS | scss | ++-------------------------+---------------------------------------------------+ +| SQL | sql | ++-------------------------+---------------------------------------------------+ +| STEP Part 21 | p21, step, stp | ++-------------------------+---------------------------------------------------+ +| Scala | scala | ++-------------------------+---------------------------------------------------+ +| Scheme | scheme | ++-------------------------+---------------------------------------------------+ +| Scilab | scilab, sci | ++-------------------------+---------------------------------------------------+ +| Shell | shell, console | ++-------------------------+---------------------------------------------------+ +| Smali | smali | ++-------------------------+---------------------------------------------------+ +| Smalltalk | smalltalk, st | ++-------------------------+---------------------------------------------------+ +| Stan | stan | ++-------------------------+---------------------------------------------------+ +| Stata | stata | ++-------------------------+---------------------------------------------------+ +| SAS | SAS, sas | ++-------------------------+---------------------------------------------------+ +| Stylus | stylus, styl | ++-------------------------+---------------------------------------------------+ +| SubUnit | subunit | ++-------------------------+---------------------------------------------------+ +| Swift | swift | ++-------------------------+---------------------------------------------------+ +| Test Anything Protocol | tap | ++-------------------------+---------------------------------------------------+ +| Tcl | tcl, tk | ++-------------------------+---------------------------------------------------+ +| TeX | tex | ++-------------------------+---------------------------------------------------+ +| Thrift | thrift | ++-------------------------+---------------------------------------------------+ +| TP | tp | ++-------------------------+---------------------------------------------------+ +| Twig | twig, craftcms | ++-------------------------+---------------------------------------------------+ +| TypeScript | typescript, ts | ++-------------------------+---------------------------------------------------+ +| VB.Net | vbnet, vb | ++-------------------------+---------------------------------------------------+ +| VBScript | vbscript, vbs | ++-------------------------+---------------------------------------------------+ +| VHDL | vhdl | ++-------------------------+---------------------------------------------------+ +| Vala | vala | ++-------------------------+---------------------------------------------------+ +| Verilog | verilog, v | ++-------------------------+---------------------------------------------------+ +| Vim Script | vim | ++-------------------------+---------------------------------------------------+ +| x86 Assembly | x86asm | ++-------------------------+---------------------------------------------------+ +| XL | xl, tao | ++-------------------------+---------------------------------------------------+ +| XQuery | xpath, xq | ++-------------------------+---------------------------------------------------+ +| Zephir | zephir, zep | ++-------------------------+---------------------------------------------------+ diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/index.rst b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/index.rst new file mode 100644 index 0000000000..3288758bb5 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/index.rst @@ -0,0 +1,44 @@ +.. highlight.js documentation master file, created by + sphinx-quickstart on Wed Sep 12 23:48:27 2012. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +``highlight.js`` developer documentation +========================================== + +Contents: + +.. toctree:: + :maxdepth: 1 + + api + language-guide + reference + css-classes-reference + style-guide + language-contribution + building-testing + maintainers-guide + +Miscellaneous: + +.. toctree:: + :maxdepth: 1 + + line-numbers + language-requests + +Links: + +- Code: https://github.com/highlightjs/highlight.js +- Discussion: http://groups.google.com/group/highlightjs +- Bug tracking: https://github.com/highlightjs/highlight.js/issues + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/language-contribution.rst b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/language-contribution.rst new file mode 100644 index 0000000000..614e816339 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/language-contribution.rst @@ -0,0 +1,77 @@ +Language contributor checklist +============================== + +1. Put language definition into a .js file +------------------------------------------ + +The file defines a function accepting a reference to the library and returning a language object. +The library parameter is useful to access common modes and regexps. You should not immediately call this function, +this is done during the build process and details differ for different build targets. + +:: + + function(hljs) { + return { + keywords: 'foo bar', + contains: [ ..., hljs.NUMBER_MODE, ... ] + } + } + +The name of the file is used as a short language identifier and should be usable as a class name in HTML and CSS. + + +2. Provide meta data +-------------------- + +At the top of the file there is a specially formatted comment with meta data processed by a build system. +Meta data format is simply key-value pairs each occupying its own line: + +:: + + /* + Language: Superlanguage + Requires: java.js, sql.js + Author: John Smith + Contributors: Mike Johnson <...@...>, Matt Wilson <...@...> + Description: Some cool language definition + */ + +``Language`` — the only required header giving a human-readable language name. + +``Requires`` — a list of other language files required for this language to work. +This make it possible to describe languages that extend definitions of other ones. +Required files aren't processed in any special way. +The build system just makes sure that they will be in the final package in +``LANGUAGES`` object. + +The meaning of the other headers is pretty obvious. + + +3. Create a code example +------------------------ + +The code example is used both to test language detection and for the demo page +on https://highlightjs.org/. Put it in ``test/detect//default.txt``. + +Take inspiration from other languages in ``test/detect/`` and read +:ref:`testing instructions ` for more details. + + +4. Write class reference +------------------------ + +Class reference lives in the :doc:`CSS classes reference `.. +Describe shortly names of all meaningful modes used in your language definition. + + +5. Add yourself to AUTHORS.*.txt and CHANGES.md +----------------------------------------------- + +If you're a new contributor add yourself to the authors list. +Also it will be good to update CHANGES.md. + + +6. Create a pull request +------------------------ + +Send your contribution as a pull request on GitHub. diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/language-guide.rst b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/language-guide.rst new file mode 100644 index 0000000000..a3cf8d806a --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/language-guide.rst @@ -0,0 +1,264 @@ +Language definition guide +========================= + +Highlighting overview +--------------------- + +Programming language code consists of parts with different rules of parsing: keywords like ``for`` or ``if`` +don't make sense inside strings, strings may contain backslash-escaped symbols like ``\"`` +and comments usually don't contain anything interesting except the end of the comment. + +In highlight.js such parts are called "modes". + +Each mode consists of: + +* starting condition +* ending condition +* list of contained sub-modes +* lexing rules and keywords +* …exotic stuff like another language inside a language + +The parser's work is to look for modes and their keywords. +Upon finding, it wraps them into the markup ``...`` +and puts the name of the mode ("string", "comment", "number") +or a keyword group name ("keyword", "literal", "built-in") as the span's class name. + + +General syntax +-------------- + +A language definition is a JavaScript object describing the default parsing mode for the language. +This default mode contains sub-modes which in turn contain other sub-modes, effectively making the language definition a tree of modes. + +Here's an example: + +:: + + { + case_insensitive: true, // language is case-insensitive + keywords: 'for if while', + contains: [ + { + className: 'string', + begin: '"', end: '"' + }, + hljs.COMMENT( + '/\\*', // begin + '\\*/', // end + { + contains: [ + { + className: 'doc', begin: '@\\w+' + } + ] + } + ) + ] + } + +Usually the default mode accounts for the majority of the code and describes all language keywords. +A notable exception here is XML in which a default mode is just a user text that doesn't contain any keywords, +and most interesting parsing happens inside tags. + + +Keywords +-------- + +In the simple case language keywords are defined in a string, separated by space: + +:: + + { + keywords: 'else for if while' + } + +Some languages have different kinds of "keywords" that might not be called as such by the language spec +but are very close to them from the point of view of a syntax highlighter. These are all sorts of "literals", "built-ins", "symbols" and such. +To define such keyword groups the attribute ``keywords`` becomes an object each property of which defines its own group of keywords: + +:: + + { + keywords: { + keyword: 'else for if while', + literal: 'false true null' + } + } + +The group name becomes then a class name in a generated markup enabling different styling for different kinds of keywords. + +To detect keywords highlight.js breaks the processed chunk of code into separate words — a process called lexing. +The "word" here is defined by the regexp ``[a-zA-Z][a-zA-Z0-9_]*`` that works for keywords in most languages. +Different lexing rules can be defined by the ``lexemes`` attribute: + +:: + + { + lexemes: '-[a-z]+', + keywords: '-import -export' + } + + +Sub-modes +--------- + +Sub-modes are listed in the ``contains`` attribute: + +:: + + { + keywords: '...', + contains: [ + hljs.QUOTE_STRING_MODE, + hljs.C_LINE_COMMENT, + { ... custom mode definition ... } + ] + } + +A mode can reference itself in the ``contains`` array by using a special keyword ``'self``'. +This is commonly used to define nested modes: + +:: + + { + className: 'object', + begin: '{', end: '}', + contains: [hljs.QUOTE_STRING_MODE, 'self'] + } + + +Comments +-------- + +To define custom comments it is recommended to use a built-in helper function ``hljs.COMMENT`` instead of describing the mode directly, as it also defines a few default sub-modes that improve language detection and do other nice things. + +Parameters for the function are: + +:: + + hljs.COMMENT( + begin, // begin regex + end, // end regex + extra // optional object with extra attributes to override defaults + // (for example {relevance: 0}) + ) + + +Markup generation +----------------- + +Modes usually generate actual highlighting markup — ```` elements with specific class names that are defined by the ``className`` attribute: + +:: + + { + contains: [ + { + className: 'string', + // ... other attributes + }, + { + className: 'number', + // ... + } + ] + } + +Names are not required to be unique, it's quite common to have several definitions with the same name. +For example, many languages have various syntaxes for strings, comments, etc… + +Sometimes modes are defined only to support specific parsing rules and aren't needed in the final markup. +A classic example is an escaping sequence inside strings allowing them to contain an ending quote. + +:: + + { + className: 'string', + begin: '"', end: '"', + contains: [{begin: '\\\\.'}], + } + +For such modes ``className`` attribute should be omitted so they won't generate excessive markup. + + +Mode attributes +--------------- + +Other useful attributes are defined in the :doc:`mode reference `. + + +.. _relevance: + +Relevance +--------- + +Highlight.js tries to automatically detect the language of a code fragment. +The heuristics is essentially simple: it tries to highlight a fragment with all the language definitions +and the one that yields most specific modes and keywords wins. The job of a language definition +is to help this heuristics by hinting relative relevance (or irrelevance) of modes. + +This is best illustrated by example. Python has special kinds of strings defined by prefix letters before the quotes: +``r"..."``, ``u"..."``. If a code fragment contains such strings there is a good chance that it's in Python. +So these string modes are given high relevance: + +:: + + { + className: 'string', + begin: 'r"', end: '"', + relevance: 10 + } + +On the other hand, conventional strings in plain single or double quotes aren't specific to any language +and it makes sense to bring their relevance to zero to lessen statistical noise: + +:: + + { + className: 'string', + begin: '"', end: '"', + relevance: 0 + } + +The default value for relevance is 1. When setting an explicit value it's recommended to use either 10 or 0. + +Keywords also influence relevance. Each of them usually has a relevance of 1, but there are some unique names +that aren't likely to be found outside of their languages, even in the form of variable names. +For example just having ``reinterpret_cast`` somewhere in the code is a good indicator that we're looking at C++. +It's worth to set relevance of such keywords a bit higher. This is done with a pipe: + +:: + + { + keywords: 'for if reinterpret_cast|10' + } + + +Illegal symbols +--------------- + +Another way to improve language detection is to define illegal symbols for a mode. +For example in Python first line of class definition (``class MyClass(object):``) cannot contain symbol "{" or a newline. +Presence of these symbols clearly shows that the language is not Python and the parser can drop this attempt early. + +Illegal symbols are defined as a a single regular expression: + +:: + + { + className: 'class', + illegal: '[${]' + } + + +Pre-defined modes and regular expressions +----------------------------------------- + +Many languages share common modes and regular expressions. Such expressions are defined in core highlight.js code +at the end under "Common regexps" and "Common modes" titles. Use them when possible. + + +Contributing +------------ + +Follow the :doc:`contributor checklist `. diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/language-requests.rst b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/language-requests.rst new file mode 100644 index 0000000000..4e4c2f0b61 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/language-requests.rst @@ -0,0 +1,17 @@ +On requesting new languages +=========================== + +This is a general answer to requests for adding new languages that appear from +time to time in the highlight.js issue tracker and discussion group. + + Highlight.js doesn't have a fundamental plan for implementing languages, + instead the project works by accepting language definitions from + interested contributors. There are also no rules at the moment forbidding + any languages from being added to the library, no matter how obscure or + weird. + + This means that there's no point in requesting a new language without + providing an implementation for it. If you want to see a particular language + included in highlight.js but cannot implement it, the best way to make it + happen is to get another developer interested in doing so. Here's our + :doc:`language-guide`. diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/line-numbers.rst b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/line-numbers.rst new file mode 100644 index 0000000000..674542d4ed --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/line-numbers.rst @@ -0,0 +1,39 @@ +Line numbers +============ + +Highlight.js' notable lack of line numbers support is not an oversight but a +feature. Following is the explanation of this policy from the current project +maintainer (hey guys!): + + One of the defining design principles for highlight.js from the start was + simplicity. Not the simplicity of code (in fact, it's quite complex) but + the simplicity of usage and of the actual look of highlighted snippets on + HTML pages. Many highlighters, in my opinion, are overdoing it with such + things as separate colors for every single type of lexemes, striped + backgrounds, fancy buttons around code blocks and — yes — line numbers. + The more fancy stuff resides around the code the more it distracts a + reader from understanding it. + + This is why it's not a straightforward decision: this new feature will not + just make highlight.js better, it might actually make it worse simply by + making it look more bloated in blog posts around the Internet. This is why + I'm asking people to show that it's worth it. + + The only real use-case that ever was brought up in support of line numbers + is referencing code from the descriptive text around it. On my own blog I + was always solving this either with comments within the code itself or by + breaking the larger snippets into smaller ones and describing each small + part separately. I'm not saying that my solution is better. But I don't + see how line numbers are better either. And the only way to show that they + are better is to set up some usability research on the subject. I doubt + anyone would bother to do it. + + Then there's maintenance. So far the core code of highlight.js is + maintained by only one person — yours truly. Inclusion of any new code in + highlight.js means that from that moment I will have to fix bugs in it, + improve it further, make it work together with the rest of the code, + defend its design. And I don't want to do all this for the feature that I + consider "evil" and probably will never use myself. + +This position is `subject to discuss `_. +Also it doesn't stop anyone from forking the code and maintaining line-numbers implementation separately. diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/maintainers-guide.rst b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/maintainers-guide.rst new file mode 100644 index 0000000000..21bfc52396 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/maintainers-guide.rst @@ -0,0 +1,34 @@ +Maintainer's guide +================== + + +Commit policy +------------- + +* Pull requests from outside contributors require a review from a maintainer. + +* Maintainers should avoid working on a master branch directly and create branches for everything. A code review from another maintainer is recommended but not required, use your best judgment. + + + +Release process +--------------- + +Releases happen on a 6-week schedule. Currently due to a long break the date of the next release is not set. + +* Update CHANGES.md with everything interesting since the last update. + +* Update version numbers using the three-part x.y.z notation everywhere: + + * The header in CHANGES.md (this is where the site looks for the latest version number) + * ``"version"`` attribute in package.json + * ``"version"`` attribute in package-lock.json (run `npm install`) + * Two places in docs/conf.py (``version`` and ``release``) + +* Commit the version changes and tag the commit with the plain version number (no "v." or anything like that) + +* Push the commit and the tags to master (``git push && git push --tags``) + +Pushing the tag triggers the update process which can be monitored at http://highlightjs.org/api/release/ + +When something didn't work *and* it's fixable in code (version numbers mismatch, last minute patches, etc), simply make another release incrementing the third (revision) part of the version number. diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/reference.rst b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/reference.rst new file mode 100644 index 0000000000..de240fd48f --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/libs/highlight.js/docs/reference.rst @@ -0,0 +1,360 @@ +Mode reference +============== + +Types +----- + +Types of attributes values in this reference: + ++------------+-------------------------------------------------------------------------------------+ +| identifier | String suitable to be used as a Javascript variable and CSS class name | +| | (i.e. mostly ``/[A-Za-z0-9_]+/``) | ++------------+-------------------------------------------------------------------------------------+ +| regexp | String representing a Javascript regexp. | +| | Note that since it's not a literal regexp all back-slashes should be repeated twice | ++------------+-------------------------------------------------------------------------------------+ +| boolean | Javascript boolean: ``true`` or ``false`` | ++------------+-------------------------------------------------------------------------------------+ +| number | Javascript number | ++------------+-------------------------------------------------------------------------------------+ +| object | Javascript object: ``{ ... }`` | ++------------+-------------------------------------------------------------------------------------+ +| array | Javascript array: ``[ ... ]`` | ++------------+-------------------------------------------------------------------------------------+ + + +Attributes +---------- + +case_insensitive +^^^^^^^^^^^^^^^^ + +**type**: boolean + +Case insensitivity of language keywords and regexps. Used only on the top-level mode. + + +aliases +^^^^^^^ + +**type**: array + +A list of additional names (besides the canonical one given by the filename) that can be used to identify a language in HTML classes and in a call to :ref:`getLanguage `. + + +className +^^^^^^^^^ + +**type**: identifier + +The name of the mode. It is used as a class name in HTML markup. + +Multiple modes can have the same name. This is useful when a language has multiple variants of syntax +for one thing like string in single or double quotes. + + +begin +^^^^^ + +**type**: regexp + +Regular expression starting a mode. For example a single quote for strings or two forward slashes for C-style comments. +If absent, ``begin`` defaults to a regexp that matches anything, so the mode starts immediately. + + +end +^^^ + +**type**: regexp + +Regular expression ending a mode. For example a single quote for strings or "$" (end of line) for one-line comments. + +It's often the case that a beginning regular expression defines the entire mode and doesn't need any special ending. +For example a number can be defined with ``begin: "\\b\\d+"`` which spans all the digits. + +If absent, ``end`` defaults to a regexp that matches anything, so the mode ends immediately. + +Sometimes a mode can end not by itself but implicitly with its containing (parent) mode. +This is achieved with :ref:`endsWithParent ` attribute. + + +beginKeywords +^^^^^^^^^^^^^^^^ + +**type**: string + +Used instead of ``begin`` for modes starting with keywords to avoid needless repetition: + +:: + + { + begin: '\\b(extends|implements) ', + keywords: 'extends implements' + } + +… becomes: + +:: + + { + beginKeywords: 'extends implements' + } + +Unlike the :ref:`keywords ` attribute, this one allows only a simple list of space separated keywords. +If you do need additional features of ``keywords`` or you just need more keywords for this mode you may include ``keywords`` along with ``beginKeywords``. + + +.. _endsWithParent: + +endsWithParent +^^^^^^^^^^^^^^ + +**type**: boolean + +A flag showing that a mode ends when its parent ends. + +This is best demonstrated by example. In CSS syntax a selector has a set of rules contained within symbols "{" and "}". +Individual rules separated by ";" but the last one in a set can omit the terminating semicolon: + +:: + + p { + width: 100%; color: red + } + +This is when ``endsWithParent`` comes into play: + +:: + + { + className: 'rules', begin: '{', end: '}', + contains: [ + {className: 'rule', /* ... */ end: ';', endsWithParent: true} + ] + } + +.. _endsParent: + +endsParent +^^^^^^^^^^^^^^ + +**type**: boolean + +Forces closing of the parent mode right after the current mode is closed. + +This is used for modes that don't have an easily expressible ending lexeme but +instead could be closed after the last interesting sub-mode is found. + +Here's an example with two ways of defining functions in Elixir, one using a +keyword ``do`` and another using a comma: + +:: + + def foo :clear, list do + :ok + end + + def foo, do: IO.puts "hello world" + +Note that in the first case the parameter list after the function title may also +include a comma. And iIf we're only interested in highlighting a title we can +tell it to end the function definition after itself: + +:: + + { + className: 'function', + beginKeywords: 'def', end: /\B\b/, + contains: [ + { + className: 'title', + begin: hljs.IDENT_RE, endsParent: true + } + ] + } + +(The ``end: /\B\b/`` regex tells function to never end by itself.) + +.. _endSameAsBegin: + +endSameAsBegin +^^^^^^^^^^^^^^ + +**type**: boolean + +Acts as ``end`` matching exactly the same string that was found by the +corresponding ``begin`` regexp. + +For example, in PostgreSQL string constants can uee "dollar quotes", +consisting of a dollar sign, an optional tag of zero or more characters, +and another dollar sign. String constant must be ended with the same +construct using the same tag. It is possible to nest dollar-quoted string +constants by choosing different tags at each nesting level: + +:: + + $foo$ + ... + $bar$ nested $bar$ + ... + $foo$ + +In this case you can't simply specify the same regexp for ``begin`` and +``end`` (say, ``"\\$[a-z]\\$"``), but you can use ``begin: "\\$[a-z]\\$"`` +and ``endSameAsBegin: true``. + +.. _lexemes: + +lexemes +^^^^^^^ + +**type**: regexp + +A regular expression that extracts individual lexemes from language text to find :ref:`keywords ` among them. +Default value is ``hljs.IDENT_RE`` which works for most languages. + + +.. _keywords: + +keywords +^^^^^^^^ + +**type**: object + +Keyword definition comes in two forms: + +* ``'for while if else weird_voodoo|10 ... '`` -- a string of space-separated keywords with an optional relevance over a pipe +* ``{'keyword': ' ... ', 'literal': ' ... '}`` -- an object whose keys are names of different kinds of keywords and values are keyword definition strings in the first form + +For detailed explanation see :doc:`Language definition guide `. + + +illegal +^^^^^^^ + +**type**: regexp + +A regular expression that defines symbols illegal for the mode. +When the parser finds a match for illegal expression it immediately drops parsing the whole language altogether. + + +excludeBegin, excludeEnd +^^^^^^^^^^^^^^^^^^^^^^^^ + +**type**: boolean + +Exclude beginning or ending lexemes out of mode's generated markup. For example in CSS syntax a rule ends with a semicolon. +However visually it's better not to color it as the rule contents. Having ``excludeEnd: true`` forces a ```` element for the rule to close before the semicolon. + + +returnBegin +^^^^^^^^^^^ + +**type**: boolean + +Returns just found beginning lexeme back into parser. This is used when beginning of a sub-mode is a complex expression +that should not only be found within a parent mode but also parsed according to the rules of a sub-mode. + +Since the parser is effectively goes back it's quite possible to create a infinite loop here so use with caution! + + +returnEnd +^^^^^^^^^ + +**type**: boolean + +Returns just found ending lexeme back into parser. This is used for example to parse Javascript embedded into HTML. +A Javascript block ends with the HTML closing tag ```` that cannot be parsed with Javascript rules. +So it is returned back into its parent HTML mode that knows what to do with it. + +Since the parser is effectively goes back it's quite possible to create a infinite loop here so use with caution! + + +contains +^^^^^^^^ + +**type**: array + +The list of sub-modes that can be found inside the mode. For detailed explanation see :doc:`Language definition guide `. + + +starts +^^^^^^ + +**type**: identifier + +The name of the mode that will start right after the current mode ends. The new mode won't be contained within the current one. + +Currently this attribute is used to highlight Javascript and CSS contained within HTML. +Tags `` + +

Buttons

Based on Bootstrap button.

-

# Example

+

Examples

- Primary + Secondary Success Danger @@ -30,22 +43,76 @@ Link
-
-<abp-button text="Default"/>
-<abp-button button-type="Primary">Primary</abp-button>
-<abp-button button-type="Secondary">Secondary</abp-button>
-<abp-button button-type="Success">Success</abp-button>
-<abp-button button-type="Danger">Danger</abp-button>
-<abp-button button-type="Warning">Warning</abp-button>
-<abp-button button-type="Info">Info</abp-button>
-<abp-button button-type="Light">Light</abp-button>
-<abp-button button-type="Dark">Dark</abp-button>
-<abp-button button-type="Link">Link</abp-button>
-
+ + +

+<abp-button> Default </abp-button>
+<abp-button button-type="Primary">Primary</abp-button>
+<abp-button button-type="Secondary">Secondary</abp-button>
+<abp-button button-type="Success">Success</abp-button>
+<abp-button button-type="Danger">Danger</abp-button>
+<abp-button button-type="Warning">Warning</abp-button>
+<abp-button button-type="Info">Info</abp-button>
+<abp-button button-type="Light">Light</abp-button>
+<abp-button button-type="Dark">Dark</abp-button>
+
+<abp-button button-type="Link">Link</abp-button>
+
+
+ +

+<button type="button" class="btn">Default</button>
+<button type="button" class="btn btn-primary">Primary</button>
+<button type="button" class="btn btn-secondary">Secondary</button>
+<button type="button" class="btn btn-success">Success</button>
+<button type="button" class="btn btn-danger">Danger</button>
+<button type="button" class="btn btn-warning">Warning</button>
+<button type="button" class="btn btn-info">Info</button>
+<button type="button" class="btn btn-light">Light</button>
+<button type="button" class="btn btn-dark">Dark</button>
+
+<button type="button" class="btn btn-link">Link</button>
+
+
+
+
+
+ +

Button tags

+ +
+
+ Link + + + + +
+
+ + +

+<a abp-button="Primary" href="#">Link</a>
+<abp-button button-type="Primary" type="submit" text="Button"/>
+<input abp-button="Primary" value="Input" />
+<input abp-button="Primary" type="submit" value="Submit" />
+<input abp-button="Primary" type="reset" value="Reset" />
+
+
+ +

+<a class="btn btn-primary" href="#" role="button">Link</a>
+<button class="btn btn-primary" type="submit">Button</button>
+<input class="btn btn-primary" type="button" value="Input">
+<input class="btn btn-primary" type="submit" value="Submit">
+<input class="btn btn-primary" type="reset" value="Reset">
+
+
+
-

# Example

+

Outline buttons

@@ -59,7 +126,9 @@ Dark
-
+        
+            
+                

 <abp-button button-type="Outline_Primary">Primary</abp-button>
 <abp-button button-type="Outline_Secondary">Secondary</abp-button>
 <abp-button button-type="Outline_Success">Success</abp-button>
@@ -68,133 +137,211 @@
 <abp-button button-type="Outline_Info">Info</abp-button>
 <abp-button button-type="Outline_Light">Light</abp-button>
 <abp-button button-type="Outline_Dark">Dark</abp-button>
-
+
+ + +

+<button type="button" class="btn btn-outline-primary">Primary</button>
+<button type="button" class="btn btn-outline-secondary">Secondary</button>
+<button type="button" class="btn btn-outline-success">Success</button>
+<button type="button" class="btn btn-outline-danger">Danger</button>
+<button type="button" class="btn btn-outline-warning">Warning</button>
+<button type="button" class="btn btn-outline-info">Info</button>
+<button type="button" class="btn btn-outline-light">Light</button>
+<button type="button" class="btn btn-outline-dark">Dark</button>
+
+
+
-

# Example

+

Sizes

-
- Link - - - - +
+ +
-
-<a abp-button="Primary" href="#">Link</a>
-<abp-button button-type="Primary" type="submit" text="Button"/>
-<input abp-button="Primary" value="Input" />
-<input abp-button="Primary" type="submit" value="Submit" />
-<input abp-button="Primary" type="reset" value="Reset" />
-
+ + +

+<abp-button size="Large" button-type="Primary" text="Large button" />
+<abp-button size="Large" button-type="Secondary" text="Large button" />
+
+
+ +

+<button type="button" class="btn btn-primary btn-lg">Large button</button>
+<button type="button" class="btn btn-secondary btn-lg">Large button</button>
+
+
+
-

# Example

- - - - + +
-
-<abp-button size="Default" text="Default" />
-<abp-button size="Small" text="Small" />
-<abp-button size="Medium" text="Medium" />
-<abp-button size="Large" text="Large" />
-
+ + +

+<abp-button size="Small" button-type="Primary" text="Small button" />
+<abp-button size="Small" button-type="Secondary" text="Small button" />
+
+
+ +

+<button type="button" class="btn btn-primary btn-sm">Small button</button>
+<button type="button" class="btn btn-secondary btn-sm">Small button</button>
+
+
+
-

# Example

-
- + +
-
-<abp-button block="true" text="Block" />
-
+ + +

+<abp-button size="Block" button-type="Primary" text="Block level button" />
+<abp-button size="Block" button-type="Secondary" text="Block level button" />
+
+
+ +

+<button type="button" class="btn btn-primary btn-lg btn-block">Block level button</button>
+<button type="button" class="btn btn-secondary btn-lg btn-block">Block level button</button>
+
+
+
-

# Example

+ +

Icon

+
+
-
+        
+            
+                

+<abp-button icon="pencil" text="With Icon"/>
 <abp-button icon-type="FontAwesome" icon="info" text="With Icon"/>
-
+
+ + +

+<button class="btn" type="button"><i class="fa fa-pencil"></i> <span>With Icon</span></button>
+<button class="btn" type="button"><i class="fa fa-info"></i> <span>With Icon</span></button>
+
+
+ +
+ +
+
    +
  • + icon-type: Formats the icon attribute. Default value is FontAwesome. +
  • +
  • + icon: Sets icon to button. +
  • +
-

# Example

+ +

Busy Text Example

+
+
- +
-
+        
+            
+                

 <abp-button text="Busy" busy-text="Saving..."/>
-
+
+ + +

+<button class="btn" type="button" data-busy-text="Saving..."><span>Busy</span></button>
+
+
+ +
+ +
+
    +
  • + busy-text: Sets "data-busy-text" attribute. Default value is localization of "ProcessingWithThreeDot" string. +
  • +
-

# Group Examples

+@*

# Group Examples

-
-
+
+
- - Left - Middle - Right - + + Left + Middle + Right + - - Primary - Secondary - Success - + + Primary + Secondary + Success + - - Top - Middle - Bottom - -
-
-
-
-<abp-button-group>
-    <abp-button> Left </abp-button>
-    <abp-button> Middle </abp-button>
-    <abp-button> Right </abp-button>
-</abp-button-group>
-
-<abp-button-group size="Large">
-    <abp-button button-type="Primary"> Primary </abp-button>
-    <abp-button button-type="Secondary"> Secondary </abp-button>
-    <abp-button button-type="Success"> Success </abp-button>
-</abp-button-group>
-
-<abp-button-group direction="Vertical" size="Small">
-    <abp-button button-type="Primary"> Top </abp-button>
-    <abp-button button-type="Warning"> Middle </abp-button>
-    <abp-button button-type="Danger"> Bottom </abp-button>
-</abp-button-group>
-
-
-
\ No newline at end of file + + Top + Middle + Bottom + +
+
+

+
+    <abp-button-group>
+        <abp-button> Left </abp-button>
+        <abp-button> Middle </abp-button>
+        <abp-button> Right </abp-button>
+    </abp-button-group>
+
+    <abp-button-group size="Large">
+        <abp-button button-type="Primary"> Primary </abp-button>
+        <abp-button button-type="Secondary"> Secondary </abp-button>
+        <abp-button button-type="Success"> Success </abp-button>
+    </abp-button-group>
+
+    <abp-button-group direction="Vertical" size="Small">
+        <abp-button button-type="Primary"> Top </abp-button>
+        <abp-button button-type="Warning"> Middle </abp-button>
+        <abp-button button-type="Danger"> Bottom </abp-button>
+    </abp-button-group>
+    
+
+
*@ \ No newline at end of file From 9d61cc03d71d16995d5b13766be0f48140b529d1 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 17 Dec 2018 10:38:51 +0300 Subject: [PATCH 016/368] Breadcrumb doc --- .../Pages/Components/Breadcrumbs.cshtml | 76 ++++++++++++++++--- 1 file changed, 67 insertions(+), 9 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Breadcrumbs.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Breadcrumbs.cshtml index e3ab71b246..8ede105b97 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Breadcrumbs.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Breadcrumbs.cshtml @@ -10,29 +10,87 @@ } +@section scripts { + + @* + *@ + +} + + + + +

Breadcrumbs

Based on Bootstrap Breadcrumb.

-

# Breadcrumb Examples

+

Example

+ + + + - - + + + + + +
-
+        
+            
+                

+
 <abp-breadcrumb>
-   <abp-breadcrumb-item href="#" title="Home"/>
-   <abp-breadcrumb-item href="#" title="Library"/>
-   <abp-breadcrumb-item title="Page"/>
+    <abp-breadcrumb-item title="Home" />
 </abp-breadcrumb>
-
+ +<abp-breadcrumb> + <abp-breadcrumb-item href="#" title="Home" /> + <abp-breadcrumb-item title="Library" /> +</abp-breadcrumb> + +<abp-breadcrumb> + <abp-breadcrumb-item href="#" title="Home" /> + <abp-breadcrumb-item href="#" title="Library"/> + <abp-breadcrumb-item title="Page"/> +</abp-breadcrumb> +
+ + +

+<nav aria-label="breadcrumb">
+  <ol class="breadcrumb">
+    <li class="breadcrumb-item active" aria-current="page">Home</li>
+  </ol>
+</nav>
+
+<nav aria-label="breadcrumb">
+  <ol class="breadcrumb">
+    <li class="breadcrumb-item"><a href="#">Home</a></li>
+    <li class="breadcrumb-item active" aria-current="page">Library</li>
+  </ol>
+</nav>
+
+<nav aria-label="breadcrumb">
+  <ol class="breadcrumb">
+    <li class="breadcrumb-item"><a href="#">Home</a></li>
+    <li class="breadcrumb-item"><a href="#">Library</a></li>
+    <li class="breadcrumb-item active" aria-current="page">Data</li>
+  </ol>
+</nav>
+
+
+
-
+
\ No newline at end of file From ea0a6edccc1bacfc2e08270546104b4a26398ca1 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 17 Dec 2018 10:39:09 +0300 Subject: [PATCH 017/368] badges doc --- .../Pages/Components/Badges.cshtml | 207 +++++++++++++++++- 1 file changed, 196 insertions(+), 11 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Badges.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Badges.cshtml index d5352312a7..becb85d9cd 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Badges.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Badges.cshtml @@ -10,30 +10,215 @@ } +@section scripts { + + @* + *@ + +} + + + + +

Badges

Based on Bootstrap Badge.

-

# Badges Examples

+

Example

- I'm an abp badge! - I'm an abp pill badge! - I'm an abp badge link! - I'm an abp pill badge link! +

Example heading New

+

Example heading New

+

Example heading New

+

Example heading New

+
Example heading New
+
Example heading New
+
+
+ + +

+<h1>Example heading <span abp-badge="Secondary">New</span></h1>
+<h2>Example heading <span abp-badge="Secondary">New</span></h2>
+<h3>Example heading <span abp-badge="Secondary">New</span></h3>
+<h4>Example heading <span abp-badge="Secondary">New</span></h4>
+<h5>Example heading <span abp-badge="Secondary">New</span></h5>
+<h6>Example heading <span abp-badge="Secondary">New</span></h6>
+
+
+ +

+<h1>Example heading <span class="badge badge-secondary">New</span></h1>
+<h2>Example heading <span class="badge badge-secondary">New</span></h2>
+<h3>Example heading <span class="badge badge-secondary">New</span></h3>
+<h4>Example heading <span class="badge badge-secondary">New</span></h4>
+<h5>Example heading <span class="badge badge-secondary">New</span></h5>
+<h6>Example heading <span class="badge badge-secondary">New</span></h6>
+
+
+
+
+
+
+
+ + + Notifications 4 +
-
-<span abp-badge="Primary" >I'm an abp badge!</span>
+        
+            
+                

+<abp-button button-type="Primary">
+    Notifications <span abp-badge="Light">4</span>
+</abp-button>
+
+
+ +

+<button type="button" class="btn btn-primary">
+  Notifications <span class="badge badge-light">4</span>
+</button>
+
+
+
+
+
-<span abp-badge-pill="Warning" >I'm an abp pill badge!</span> +

Contextual variations

-<a abp-badge="Danger" href="#" >I'm an abp badge link!</a> +
+
-<a abp-badge-pill="Success" href="#" >I'm an abp pill badge link!</a> -
+ Primary + Secondary + Success + Danger + Warning + Info + Light + Dark +
+
+ + +

+<span abp-badge="Primary">Primary</span>
+<span abp-badge="Secondary">Secondary</span>
+<span abp-badge="Success">Success</span>
+<span abp-badge="Danger">Danger</span>
+<span abp-badge="Warning">Warning</span>
+<span abp-badge="Info">Info</span>
+<span abp-badge="Light">Light</span>
+<span abp-badge="Dark">Dark</span>
+
+
+ +

+<span class="badge badge-primary">Primary</span>
+<span class="badge badge-secondary">Secondary</span>
+<span class="badge badge-success">Success</span>
+<span class="badge badge-danger">Danger</span>
+<span class="badge badge-warning">Warning</span>
+<span class="badge badge-info">Info</span>
+<span class="badge badge-light">Light</span>
+<span class="badge badge-dark">Dark</span>
+
+
+
+ +

Pill badges

+ +
+
+ + Primary + Secondary + Success + Danger + Warning + Info + Light + Dark +
+
+ + +

+<span abp-badge-pill="Primary">Primary</span>
+<span abp-badge-pill="Secondary">Secondary</span>
+<span abp-badge-pill="Success">Success</span>
+<span abp-badge-pill="Danger">Danger</span>
+<span abp-badge-pill="Warning">Warning</span>
+<span abp-badge-pill="Info">Info</span>
+<span abp-badge-pill="Light">Light</span>
+<span abp-badge-pill="Dark">Dark</span>
+
+
+ +

+<span class="badge badge-pill badge-primary">Primary</span>
+<span class="badge badge-pill badge-secondary">Secondary</span>
+<span class="badge badge-pill badge-success">Success</span>
+<span class="badge badge-pill badge-danger">Danger</span>
+<span class="badge badge-pill badge-warning">Warning</span>
+<span class="badge badge-pill badge-info">Info</span>
+<span class="badge badge-pill badge-light">Light</span>
+<span class="badge badge-pill badge-dark">Dark</span>
+
+
+
+
+
+ +

Links

+ +
+ +
+ + +

+<a href="#" abp-badge="Primary">Primary</a>
+<a href="#" abp-badge="Secondary">Secondary</a>
+<a href="#" abp-badge="Success">Success</a>
+<a href="#" abp-badge="Danger">Danger</a>
+<a href="#" abp-badge="Warning">Warning</a>
+<a href="#" abp-badge="Info">Info</a>
+<a href="#" abp-badge="Light">Light</a>
+<a href="#" abp-badge="Dark">Dark</a>
+
+
+ +

+<a href="#" class="badge badge-primary">Primary</a>
+<a href="#" class="badge badge-secondary">Secondary</a>
+<a href="#" class="badge badge-success">Success</a>
+<a href="#" class="badge badge-danger">Danger</a>
+<a href="#" class="badge badge-warning">Warning</a>
+<a href="#" class="badge badge-info">Info</a>
+<a href="#" class="badge badge-light">Light</a>
+<a href="#" class="badge badge-dark">Dark</a>
+
+
+
+
+
\ No newline at end of file From d29846e031bb1bdb47c099d08af67bee4383276f Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 17 Dec 2018 10:39:19 +0300 Subject: [PATCH 018/368] Alerts doc --- .../Pages/Components/Alerts.cshtml | 255 +++++++++++++++--- 1 file changed, 220 insertions(+), 35 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Alerts.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Alerts.cshtml index d2356bf771..2081e091e5 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Alerts.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Alerts.cshtml @@ -10,84 +10,269 @@ } +@section scripts { + + @* + *@ + +} + + + + +

Alerts

Based on Bootstrap Alert.

-

# Alert Example

+

Examples

- + + A simple primary alert—check it out! + + + A simple secondary alert—check it out! + + + A simple success alert—check it out! + - I'm an abp alert! + A simple danger alert—check it out! + + + A simple warning alert—check it out! + + + A simple info alert—check it out! + + + A simple light alert—check it out! + + + A simple dark alert—check it out! -
-
+        
+            
+                

+<abp-alert alert-type="Primary">
+    A simple primary alert—check it out!
+</abp-alert>
+<abp-alert alert-type="Secondary">
+    A simple secondary  alert—check it out!
+</abp-alert>
+<abp-alert alert-type="Success">
+    A simple success  alert—check it out!
+</abp-alert>
 <abp-alert alert-type="Danger">
-     I'm an abp alert!
+    A simple danger  alert—check it out!
+</abp-alert>
+<abp-alert alert-type="Warning">
+    A simple warning  alert—check it out!
+</abp-alert>
+<abp-alert alert-type="Info">
+    A simple info  alert—check it out!
 </abp-alert>
-
+<abp-alert alert-type="Light"> + A simple light alert—check it out! +</abp-alert> +<abp-alert alert-type="Dark"> + A simple dark alert—check it out! +</abp-alert> +
+ + +

+<div class="alert alert-primary" role="alert">
+    A simple primary alert—check it out!
+</div>
+<div class="alert alert-secondary" role="alert">
+    A simple secondary alert—check it out!
+</div>
+<div class="alert alert-success" role="alert">
+    A simple success alert—check it out!
+</div>
+<div class="alert alert-danger" role="alert">
+    A simple danger alert—check it out!
+</div>
+<div class="alert alert-warning" role="alert">
+    A simple warning alert—check it out!
+</div>
+<div class="alert alert-info" role="alert">
+    A simple info alert—check it out!
+</div>
+<div class="alert alert-light" role="alert">
+    A simple light alert—check it out!
+</div>
+<div class="alert alert-dark" role="alert">
+    A simple dark alert—check it out!
+</div>
+
+
+
-

# Dismissible Alert Example

+

Link color

- - - I'm a dismissible abp alert! + + A simple primary alert with an example link. Give it a click if you like. + + + A simple secondary alert with an example link. Give it a click if you like. + + + A simple success alert with an example link. Give it a click if you like. + + + A simple danger alert with an example link. Give it a click if you like. + + + A simple warning alert with an example link. Give it a click if you like. + + + A simple info alert with an example link. Give it a click if you like. + + + A simple light alert with an example link. Give it a click if you like. + + + A simple dark alert with an example link. Give it a click if you like. -
-
-<abp-alert alert-type="Warning" dismissible="true">
-     I'm a dismissible abp alert!
+        
+            
+                

+<abp-alert alert-type="Primary">
+    A simple primary alert with <a abp-alert-link href="#">an example link</a>. Give it a click if you like.
+</abp-alert>
+<abp-alert alert-type="Secondary">
+    A simple secondary alert with <a abp-alert-link href="#">an example link</a>. Give it a click if you like.
+</abp-alert>
+<abp-alert alert-type="Success">
+    A simple success alert with <a abp-alert-link href="#">an example link</a>. Give it a click if you like.
+</abp-alert>
+<abp-alert alert-type="Danger">
+    A simple danger alert with <a abp-alert-link href="#">an example link</a>. Give it a click if you like.
 </abp-alert>
-
+<abp-alert alert-type="Warning"> + A simple warning alert with <a abp-alert-link href="#">an example link</a>. Give it a click if you like. +</abp-alert> +<abp-alert alert-type="Info"> + A simple info alert with <a abp-alert-link href="#">an example link</a>. Give it a click if you like. +</abp-alert> +<abp-alert alert-type="Light"> + A simple light alert with <a abp-alert-link href="#">an example link</a>. Give it a click if you like. +</abp-alert> +<abp-alert alert-type="Dark"> + A simple dark alert with <a abp-alert-link href="#">an example link</a>. Give it a click if you like. +</abp-alert> +
+ + +

+<div class="alert alert-primary" role="alert">
+    A simple primary alert with <a href="#" class="alert-link">an example link</a>. Give it a click if you like.
+</div>
+<div class="alert alert-secondary" role="alert">
+    A simple secondary alert with <a href="#" class="alert-link">an example link</a>. Give it a click if you like.
+</div>
+<div class="alert alert-success" role="alert">
+    A simple success alert with <a href="#" class="alert-link">an example link</a>. Give it a click if you like.
+</div>
+<div class="alert alert-danger" role="alert">
+    A simple danger alert with <a href="#" class="alert-link">an example link</a>. Give it a click if you like.
+</div>
+<div class="alert alert-warning" role="alert">
+    A simple warning alert with <a href="#" class="alert-link">an example link</a>. Give it a click if you like.
+</div>
+<div class="alert alert-info" role="alert">
+    A simple info alert with <a href="#" class="alert-link">an example link</a>. Give it a click if you like.
+</div>
+<div class="alert alert-light" role="alert">
+    A simple light alert with <a href="#" class="alert-link">an example link</a>. Give it a click if you like.
+</div>
+<div class="alert alert-dark" role="alert">
+    A simple dark alert with <a href="#" class="alert-link">an example link</a>. Give it a click if you like.
+</div>
+
+
+
-

# Alert With Link Example

+

Additional content

- - - I'm an abp alert with Link! + +

Well done!

+

Aww yeah, you successfully read this important alert message. This example text is going to run a bit longer so that you can see how spacing within an alert works with this kind of content.

+
+

Whenever you need to, be sure to use margin utilities to keep things nice and tidy.

-
-
-<abp-alert alert-type="Info">
-      I'm an abp alert with <a abp-alert-link href="#">Link</a>!
+        
+            
+                

+<abp-alert alert-type="Success">
+    <h4>Well done!</h4>
+    <p>Aww yeah, you successfully read this important alert message. This example text is going to run a bit longer so that you can see how spacing within an alert works with this kind of content.</p>
+    <hr>
+    <p class="mb-0">Whenever you need to, be sure to use margin utilities to keep things nice and tidy.</p>
 </abp-alert>
-
+
+ + +

+<div class="alert alert-success" role="alert">
+    <h4 class="alert-heading">Well done!</h4>
+    <p>Aww yeah, you successfully read this important alert message. This example text is going to run a bit longer so that you can see how spacing within an alert works with this kind of content.</p>
+    <hr>
+    <p class="mb-0">Whenever you need to, be sure to use margin utilities to keep things nice and tidy.</p>
+</div>
+
+
+
-

# Alert With Header Example

+

Dismissing

- -

Header

- I'm an abp alert! + + Holy guacamole! You should check in on some of those fields below. -
-
-<abp-alert alert-type="Primary">
-    <h4>Header</h4>
-    I'm an abp alert!
+        
+            
+                

+<abp-alert alert-type="Warning" dismissible="true">
+    Holy guacamole! You should check in on some of those fields below.
 </abp-alert>
-
+
+ + +

+<div class="alert alert-warning alert-dismissible fade show" role="alert">
+  Holy guacamole! You should check in on some of those fields below.
+  <button type="button" class="close" data-dismiss="alert" aria-label="Close">
+    <span aria-hidden="true">&times;</span>
+  </button>
+</div>
+
+
+
\ No newline at end of file From 43f0211ddebbcb0a524582e5b57842c52c34fae7 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 17 Dec 2018 11:20:37 +0300 Subject: [PATCH 019/368] added abp-button-toolbar tag helper --- .../TagHelpers/Button/AbpButtonToolbarTagHelper.cs | 11 +++++++++++ .../Button/AbpButtonToolbarTagHelperService.cs | 14 ++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonToolbarTagHelper.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonToolbarTagHelperService.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonToolbarTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonToolbarTagHelper.cs new file mode 100644 index 0000000000..7c716b88f8 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonToolbarTagHelper.cs @@ -0,0 +1,11 @@ +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button +{ + public class AbpButtonToolbarTagHelper : AbpTagHelper + { + public AbpButtonToolbarTagHelper(AbpButtonToolbarTagHelperService tagHelperService) + : base(tagHelperService) + { + + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonToolbarTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonToolbarTagHelperService.cs new file mode 100644 index 0000000000..87b378e559 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonToolbarTagHelperService.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button +{ + public class AbpButtonToolbarTagHelperService : AbpTagHelperService + { + public override void Process(TagHelperContext context, TagHelperOutput output) + { + output.Attributes.AddClass("btn-toolbar"); + output.Attributes.Add("role","toolbar"); + } + } +} \ No newline at end of file From 7a9b5913fcebf0831bfd47a6b0db63c72761756c Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 17 Dec 2018 11:21:31 +0300 Subject: [PATCH 020/368] added button groups doc --- .../Pages/Components/ButtonGroups.cshtml | 288 ++++++++++++++++++ .../Pages/Components/ButtonGroups.cshtml.cs | 17 ++ 2 files changed, 305 insertions(+) create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ButtonGroups.cshtml create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ButtonGroups.cshtml.cs diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ButtonGroups.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ButtonGroups.cshtml new file mode 100644 index 0000000000..25322444db --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ButtonGroups.cshtml @@ -0,0 +1,288 @@ +@page +@model Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components.ButtonGroupsModel +@{ + ViewData["Title"] = "ButtonGroups"; +} + +@section styles { + + + +} + +@section scripts { + + @* + *@ + +} + + + + + +

Button groups

+ +

Based on Bootstrap Button group.

+ +

Basic example

+ +
+
+ + + Left + Middle + Right + +
+
+ + +

+<abp-button-group>
+    <abp-button button-type="Secondary">Left</abp-button>
+    <abp-button button-type="Secondary">Middle</abp-button>
+    <abp-button button-type="Secondary">Right</abp-button>
+</abp-button-group>
+
+
+ +

+<div class="btn-group" role="group">
+  <button type="button" class="btn btn-secondary">Left</button>
+  <button type="button" class="btn btn-secondary">Middle</button>
+  <button type="button" class="btn btn-secondary">Right</button>
+</div>
+
+
+
+
+
+ +

Button toolbar

+ +
+
+ + + 1 + 2 + 3 + 4 + + + 5 + 6 + 7 + + + 8 + + +
+
+ + +

+    <abp-button-toolbar>
+    <abp-button-group class="mr-2">
+    <abp-button button-type="Secondary">1</abp-button>
+    <abp-button button-type="Secondary">2</abp-button>
+    <abp-button button-type="Secondary">3</abp-button>
+    <abp-button button-type="Secondary">4</abp-button>
+    </abp-button-group>
+    <abp-button-group class="mr-2">
+    <abp-button button-type="Secondary">5</abp-button>
+    <abp-button button-type="Secondary">6</abp-button>
+    <abp-button button-type="Secondary">7</abp-button>
+    </abp-button-group>
+    <abp-button-group>
+    <abp-button button-type="Secondary">8</abp-button>
+    </abp-button-group>
+    </abp-button-toolbar>
+
+
+ +

+<div class="btn-toolbar" role="toolbar">
+  <div class="btn-group mr-2" role="group">
+    <button type="button" class="btn btn-secondary">1</button>
+    <button type="button" class="btn btn-secondary">2</button>
+    <button type="button" class="btn btn-secondary">3</button>
+    <button type="button" class="btn btn-secondary">4</button>
+  </div>
+  <div class="btn-group mr-2" role="group">
+    <button type="button" class="btn btn-secondary">5</button>
+    <button type="button" class="btn btn-secondary">6</button>
+    <button type="button" class="btn btn-secondary">7</button>
+  </div>
+  <div class="btn-group" role="group">
+    <button type="button" class="btn btn-secondary">8</button>
+  </div>
+</div>
+
+
+
+
+
+ +

Sizing

+ +
+
+ + Left + Middle + Right + +

+ + Left + Middle + Right + +

+ + Left + Middle + Right + +
+
+ + +

+<abp-button-group size="Large">
+    ...
+</abp-button-group>
+
+<abp-button-group>
+    ...
+</abp-button-group>
+
+<abp-button-group size="Small">
+    ...
+</abp-button-group>
+
+
+ +

+<div class="btn-group btn-group-lg" role="group">
+    ...
+</div>
+
+<div class="btn-group" role="group">
+    ...
+</div>
+
+<div class="btn-group btn-group-sm" role="group">
+    ...
+</div>
+
+
+
+
+
+ +

Vertical variation

+ +
+
+ + 1 + 2 + + + + Dropdown link + Dropdown link + + + +
+
+ + +

+<abp-button-group>
+    <abp-button button-type="Secondary">1</abp-button>
+    <abp-button button-type="Secondary">2</abp-button>
+    <abp-dropdown>
+        <abp-dropdown-button button-type="Secondary" text="Dropdown" />
+        <abp-dropdown-menu>
+            <abp-dropdown-item href="#"> Dropdown link </abp-dropdown-item>
+            <abp-dropdown-item href="#"> Dropdown link </abp-dropdown-item>
+        </abp-dropdown-menu>
+    </abp-dropdown>
+</abp-button-group>
+
+
+ +

+<div class="btn-group" role="group" aria-label="Button group with nested dropdown">
+  <button type="button" class="btn btn-secondary">1</button>
+  <button type="button" class="btn btn-secondary">2</button>
+
+  <div class="btn-group" role="group">
+    <button id="btnGroupDrop1" type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+      Dropdown
+    </button>
+    <div class="dropdown-menu" aria-labelledby="btnGroupDrop1">
+      <a class="dropdown-item" href="#">Dropdown link</a>
+      <a class="dropdown-item" href="#">Dropdown link</a>
+    </div>
+  </div>
+</div>
+
+
+
+
+
+ +

Nesting

+ +
+
+ + button + button + + + + Dropdown link + Dropdown link + + + button + button + + + + Dropdown link + Dropdown link + + + button + +
+
+ + +

+<abp-button-group direction="Vertical">
+    ...
+</abp-button-group>
+
+
+ +

+<div class="btn-group-vertical">
+  ...
+</div>
+
+
+
+
+
\ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ButtonGroups.cshtml.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ButtonGroups.cshtml.cs new file mode 100644 index 0000000000..dc9ac3c2eb --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ButtonGroups.cshtml.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components +{ + public class ButtonGroupsModel : PageModel + { + public void OnGet() + { + + } + } +} \ No newline at end of file From aae7a38f222ee8b6899590df9675fe2a2edc3a91 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Mon, 17 Dec 2018 14:46:20 +0300 Subject: [PATCH 021/368] Extract RabbitMqMessageConsumer. --- .../RabbitMQ/JobQueueConfiguration.cs | 2 +- .../RabbitMq/RabbitMqDistributedEventBus.cs | 59 +++++-------- .../RabbitMQ/ExchangeDeclareConfiguration.cs | 30 +++++++ .../Abp/RabbitMQ/IRabbitMqMessageConsumer.cs | 12 +++ .../IRabbitMqMessageConsumerFactory.cs | 11 +++ ...ration.cs => QueueDeclareConfiguration.cs} | 4 +- .../Abp/RabbitMQ/RabbitMqMessageConsumer.cs | 86 +++++++++++++++++++ .../RabbitMqMessageConsumerFactory.cs | 27 ++++++ 8 files changed, 189 insertions(+), 42 deletions(-) create mode 100644 framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/ExchangeDeclareConfiguration.cs create mode 100644 framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/IRabbitMqMessageConsumer.cs create mode 100644 framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/IRabbitMqMessageConsumerFactory.cs rename framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/{QueueConfiguration.cs => QueueDeclareConfiguration.cs} (92%) create mode 100644 framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs create mode 100644 framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumerFactory.cs diff --git a/framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/JobQueueConfiguration.cs b/framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/JobQueueConfiguration.cs index 91cd5b4a1b..959952de22 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/JobQueueConfiguration.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/JobQueueConfiguration.cs @@ -3,7 +3,7 @@ using Volo.Abp.RabbitMQ; namespace Volo.Abp.BackgroundJobs.RabbitMQ { - public class JobQueueConfiguration : QueueConfiguration + public class JobQueueConfiguration : QueueDeclareConfiguration { public Type JobArgsType { get; } diff --git a/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs index 99173ee333..a717cb8d5b 100644 --- a/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs +++ b/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs @@ -10,7 +10,6 @@ using Volo.Abp.RabbitMQ; using RabbitMQ.Client; using RabbitMQ.Client.Events; using Volo.Abp.Collections; -using Volo.Abp.EventBus.Local; using Volo.Abp.Threading; namespace Volo.Abp.EventBus.Distributed.RabbitMq @@ -29,27 +28,44 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq protected IRabbitMqSerializer Serializer { get; } protected ConcurrentDictionary> HandlerFactories { get; } //TODO: Accessing to the List may not be thread-safe! protected ConcurrentDictionary EventTypes { get; } - protected IModel ConsumerChannel; protected IHybridServiceScopeFactory ServiceScopeFactory { get; } + protected IRabbitMqMessageConsumerFactory MessageConsumerFactory { get; } + protected IRabbitMqMessageConsumer Consumer { get; } public RabbitMqDistributedEventBus( IOptions options, IConnectionPool connectionPool, IRabbitMqSerializer serializer, IHybridServiceScopeFactory serviceScopeFactory, - IOptions distributedEventBusOptions) + IOptions distributedEventBusOptions, + IRabbitMqMessageConsumerFactory messageConsumerFactory) { ConnectionPool = connectionPool; Serializer = serializer; ServiceScopeFactory = serviceScopeFactory; + MessageConsumerFactory = messageConsumerFactory; DistributedEventBusOptions = distributedEventBusOptions.Value; RabbitMqDistributedEventBusOptions = options.Value; HandlerFactories = new ConcurrentDictionary>(); EventTypes = new ConcurrentDictionary(); - ConsumerChannel = CreateConsumerChannel(); Subscribe(DistributedEventBusOptions.Handlers); + + Consumer = MessageConsumerFactory.Create( + new ExchangeDeclareConfiguration( + RabbitMqDistributedEventBusOptions.ExchangeName, + type: "direct" + ), + new QueueDeclareConfiguration( + RabbitMqDistributedEventBusOptions.ClientName, + durable: true, + exclusive: false, + autoDelete: false + ) + ); + + Consumer.OnMessageReceived(ProcessEventAsync); } protected virtual void Subscribe(ITypeList handlers) @@ -73,41 +89,6 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq } } - private IModel CreateConsumerChannel() - { - //TODO: Support multiple connection (and consumer)? - var channel = ConnectionPool.Get().CreateModel(); - channel.ExchangeDeclare( - exchange: RabbitMqDistributedEventBusOptions.ExchangeName, - type: "direct" - ); - - channel.QueueDeclare( - queue: RabbitMqDistributedEventBusOptions.ClientName, - durable: true, - exclusive: false, - autoDelete: false, - arguments: null - ); - - var consumer = new EventingBasicConsumer(channel); - consumer.Received += async (model, ea) => { await ProcessEventAsync(channel, ea); }; - - channel.BasicConsume( - queue: RabbitMqDistributedEventBusOptions.ClientName, - autoAck: false, - consumer: consumer - ); - - channel.CallbackException += (sender, ea) => - { - ConsumerChannel.Dispose(); - ConsumerChannel = CreateConsumerChannel(); - }; - - return channel; - } - private async Task ProcessEventAsync(IModel channel, BasicDeliverEventArgs ea) { var eventName = ea.RoutingKey; diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/ExchangeDeclareConfiguration.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/ExchangeDeclareConfiguration.cs new file mode 100644 index 0000000000..67f234aec4 --- /dev/null +++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/ExchangeDeclareConfiguration.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; + +namespace Volo.Abp.RabbitMQ +{ + public class ExchangeDeclareConfiguration + { + public string ExchangeName { get; } + + public string Type { get; } + + public bool Durable { get; set; } + + public bool AutoDelete { get; set; } + + public IDictionary Arguments { get; } + + public ExchangeDeclareConfiguration( + string exchangeName, + string type, + bool durable = false, + bool autoDelete = false) + { + ExchangeName = exchangeName; + Type = type; + Durable = durable; + AutoDelete = autoDelete; + Arguments = new Dictionary(); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/IRabbitMqMessageConsumer.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/IRabbitMqMessageConsumer.cs new file mode 100644 index 0000000000..097c5cec35 --- /dev/null +++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/IRabbitMqMessageConsumer.cs @@ -0,0 +1,12 @@ +using System; +using System.Threading.Tasks; +using RabbitMQ.Client; +using RabbitMQ.Client.Events; + +namespace Volo.Abp.RabbitMQ +{ + public interface IRabbitMqMessageConsumer + { + void OnMessageReceived(Func callback); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/IRabbitMqMessageConsumerFactory.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/IRabbitMqMessageConsumerFactory.cs new file mode 100644 index 0000000000..e2a5125f68 --- /dev/null +++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/IRabbitMqMessageConsumerFactory.cs @@ -0,0 +1,11 @@ +namespace Volo.Abp.RabbitMQ +{ + public interface IRabbitMqMessageConsumerFactory + { + IRabbitMqMessageConsumer Create( + ExchangeDeclareConfiguration exchange, + QueueDeclareConfiguration queue, + string connectionName = null + ); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/QueueConfiguration.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/QueueDeclareConfiguration.cs similarity index 92% rename from framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/QueueConfiguration.cs rename to framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/QueueDeclareConfiguration.cs index 3d74a6708e..8cc07b7bb9 100644 --- a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/QueueConfiguration.cs +++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/QueueDeclareConfiguration.cs @@ -4,7 +4,7 @@ using RabbitMQ.Client; namespace Volo.Abp.RabbitMQ { - public class QueueConfiguration + public class QueueDeclareConfiguration { [NotNull] public string QueueName { get; } @@ -17,7 +17,7 @@ namespace Volo.Abp.RabbitMQ public IDictionary Arguments { get; } - public QueueConfiguration( + public QueueDeclareConfiguration( [NotNull] string queueName, bool durable = true, bool exclusive = false, diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs new file mode 100644 index 0000000000..be5358ed45 --- /dev/null +++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Concurrent; +using System.Threading.Tasks; +using RabbitMQ.Client; +using RabbitMQ.Client.Events; + +namespace Volo.Abp.RabbitMQ +{ + public class RabbitMqMessageConsumer : IRabbitMqMessageConsumer + { + protected IConnectionPool ConnectionPool { get; } + protected ExchangeDeclareConfiguration Exchange { get; } + protected QueueDeclareConfiguration Queue { get; } + protected string ConnectionName { get; } + protected IModel ConsumerChannel { get; set; } + protected ConcurrentBag> Callbacks { get; } + + public RabbitMqMessageConsumer( + IConnectionPool connectionPool, + ExchangeDeclareConfiguration exchange, + QueueDeclareConfiguration queue, + string connectionName = null) + { + ConnectionPool = connectionPool; + Exchange = exchange; + Queue = queue; + ConnectionName = connectionName; + Callbacks = new ConcurrentBag>(); + ConsumerChannel = CreateConsumerChannel(); + } + + public void OnMessageReceived(Func callback) + { + Callbacks.Add(callback); + } + + private IModel CreateConsumerChannel() + { + var channel = ConnectionPool + .Get(ConnectionName) + .CreateModel(); + + channel.ExchangeDeclare( + exchange: Exchange.ExchangeName, + type: Exchange.Type + ); + + channel.QueueDeclare( + queue: Queue.QueueName, + durable: Queue.Durable, + exclusive: Queue.Exclusive, + autoDelete: Queue.AutoDelete, + arguments: Queue.Arguments + ); + + var consumer = new EventingBasicConsumer(channel); + consumer.Received += async (model, basicDeliverEventArgs) => + { + { + foreach (var callback in Callbacks) + { + await callback(channel, basicDeliverEventArgs); + } + } + }; + + channel.BasicConsume( + queue: Queue.QueueName, + autoAck: false, + consumer: consumer + ); + + //TODO: Instead of creating a new customer immediately without exception handling, + //create a timer that constantly checks connection health and re-connect if needed. + //As similar. Do not connect on constructor! + + channel.CallbackException += (sender, ea) => + { + ConsumerChannel.Dispose(); + ConsumerChannel = CreateConsumerChannel(); + }; + + return channel; + } + } +} diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumerFactory.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumerFactory.cs new file mode 100644 index 0000000000..1787633ac3 --- /dev/null +++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumerFactory.cs @@ -0,0 +1,27 @@ +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.RabbitMQ +{ + public class RabbitMqMessageConsumerFactory : IRabbitMqMessageConsumerFactory, ISingletonDependency + { + protected IConnectionPool ConnectionPool { get; } + + public RabbitMqMessageConsumerFactory(IConnectionPool connectionPool) + { + ConnectionPool = connectionPool; + } + + public IRabbitMqMessageConsumer Create( + ExchangeDeclareConfiguration exchange, + QueueDeclareConfiguration queue, + string connectionName = null) + { + return new RabbitMqMessageConsumer( + ConnectionPool, + exchange, + queue, + connectionName + ); + } + } +} \ No newline at end of file From f32fc5a0f35aef80dbcc0bef36191b12e67f9909 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 17 Dec 2018 15:07:22 +0300 Subject: [PATCH 022/368] Card Tag Helper improvements --- .../Card/AbpCardBackgroundTagHelper.cs | 19 +++++++++++++++ .../Card/AbpCardBackgroundTagHelperService.cs | 23 +++++++++++++++++++ .../TagHelpers/Card/AbpCardBackgroundType.cs | 15 ++++++++++++ .../TagHelpers/Card/AbpCardBorderColorType.cs | 15 ++++++++++++ .../TagHelpers/Card/AbpCardFooterTagHelper.cs | 11 +++++++++ .../Card/AbpCardFooterTagHelperService.cs | 14 +++++++++++ .../TagHelpers/Card/AbpCardImageTagHelper.cs | 1 + .../TagHelpers/Card/AbpCardTagHelper.cs | 2 ++ .../Card/AbpCardTagHelperService.cs | 11 +++++++++ .../Card/AbpCardTextColorTagHelper.cs | 19 +++++++++++++++ .../Card/AbpCardTextColorTagHelperService.cs | 23 +++++++++++++++++++ .../TagHelpers/Card/AbpCardTextColorType.cs | 16 +++++++++++++ 12 files changed, 169 insertions(+) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundTagHelper.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundTagHelperService.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundType.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBorderColorType.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardFooterTagHelper.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardFooterTagHelperService.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorTagHelper.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorTagHelperService.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorType.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundTagHelper.cs new file mode 100644 index 0000000000..5e95e8bf87 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundTagHelper.cs @@ -0,0 +1,19 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card +{ + [HtmlTargetElement("abp-card", Attributes = "background")] + [HtmlTargetElement("abp-card-header", Attributes = "background")] + [HtmlTargetElement("abp-card-body", Attributes = "background")] + [HtmlTargetElement("abp-card-footer", Attributes = "background")] + public class AbpCardBackgroundTagHelper : AbpTagHelper + { + public AbpCardBackgroundType Background { get; set; } = AbpCardBackgroundType.Default; + + public AbpCardBackgroundTagHelper(AbpCardBackgroundTagHelperService tagHelperService) + : base(tagHelperService) + { + + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundTagHelperService.cs new file mode 100644 index 0000000000..248d737648 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundTagHelperService.cs @@ -0,0 +1,23 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card +{ + public class AbpCardBackgroundTagHelperService : AbpTagHelperService + { + public override void Process(TagHelperContext context, TagHelperOutput output) + { + SetBackground(context, output); + } + + protected virtual void SetBackground(TagHelperContext context, TagHelperOutput output) + { + if (TagHelper.Background == AbpCardBackgroundType.Default) + { + return; + } + + output.Attributes.AddClass("bg-" + TagHelper.Background.ToString().ToLowerInvariant()); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundType.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundType.cs new file mode 100644 index 0000000000..2eb9732ce8 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBackgroundType.cs @@ -0,0 +1,15 @@ +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card +{ + public enum AbpCardBackgroundType + { + Default, + Primary, + Secondary, + Success, + Danger, + Warning, + Info, + Light, + Dark, + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBorderColorType.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBorderColorType.cs new file mode 100644 index 0000000000..0f5ccc3363 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardBorderColorType.cs @@ -0,0 +1,15 @@ +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card +{ + public enum AbpCardBorderColorType + { + Default, + Primary, + Secondary, + Success, + Danger, + Warning, + Info, + Light, + Dark, + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardFooterTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardFooterTagHelper.cs new file mode 100644 index 0000000000..44b8588576 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardFooterTagHelper.cs @@ -0,0 +1,11 @@ +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card +{ + public class AbpCardFooterTagHelper : AbpTagHelper + { + public AbpCardFooterTagHelper(AbpCardFooterTagHelperService tagHelperService) + : base(tagHelperService) + { + + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardFooterTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardFooterTagHelperService.cs new file mode 100644 index 0000000000..2a127a495b --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardFooterTagHelperService.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card +{ + public class AbpCardFooterTagHelperService : AbpTagHelperService + { + public override void Process(TagHelperContext context, TagHelperOutput output) + { + output.Attributes.AddClass("card-footer"); + output.TagName = "div"; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardImageTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardImageTagHelper.cs index 6bafed3376..4a173968d0 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardImageTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardImageTagHelper.cs @@ -3,6 +3,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card { [HtmlTargetElement("img", Attributes = "abp-card-image", TagStructure = TagStructure.WithoutEndTag)] + [HtmlTargetElement("abp-image", Attributes = "abp-card-image", TagStructure = TagStructure.WithoutEndTag)] public class AbpCardImageTagHelper : AbpTagHelper { [HtmlAttributeName("abp-card-image")] diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTagHelper.cs index 4dcf439e01..c186e8857c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTagHelper.cs @@ -2,6 +2,8 @@ { public class AbpCardTagHelper : AbpTagHelper { + public AbpCardBorderColorType Border { get; set; } = AbpCardBorderColorType.Default; + public AbpCardTagHelper(AbpCardTagHelperService tagHelperService) : base(tagHelperService) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTagHelperService.cs index 4eb0c286f8..29a462797d 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTagHelperService.cs @@ -9,6 +9,17 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card { output.TagName = "div"; output.Attributes.AddClass("card"); + + SetBorder(context, output); + } + protected virtual void SetBorder(TagHelperContext context, TagHelperOutput output) + { + if (TagHelper.Border == AbpCardBorderColorType.Default) + { + return; + } + + output.Attributes.AddClass("border-" + TagHelper.Border.ToString().ToLowerInvariant()); } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorTagHelper.cs new file mode 100644 index 0000000000..f9787b1f18 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorTagHelper.cs @@ -0,0 +1,19 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card +{ + [HtmlTargetElement("abp-card", Attributes = "text-color")] + [HtmlTargetElement("abp-card-header", Attributes = "text-color")] + [HtmlTargetElement("abp-card-body", Attributes = "text-color")] + [HtmlTargetElement("abp-card-footer", Attributes = "text-color")] + public class AbpCardTextColorTagHelper : AbpTagHelper + { + public AbpCardTextColorType TextColor { get; set; } = AbpCardTextColorType.Default; + + public AbpCardTextColorTagHelper(AbpCardTextColorTagHelperService tagHelperService) + : base(tagHelperService) + { + + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorTagHelperService.cs new file mode 100644 index 0000000000..36484a33f8 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorTagHelperService.cs @@ -0,0 +1,23 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card +{ + public class AbpCardTextColorTagHelperService : AbpTagHelperService + { + public override void Process(TagHelperContext context, TagHelperOutput output) + { + SetTextColor(context, output); + } + + protected virtual void SetTextColor(TagHelperContext context, TagHelperOutput output) + { + if (TagHelper.TextColor == AbpCardTextColorType.Default) + { + return; + } + + output.Attributes.AddClass("text-" + TagHelper.TextColor.ToString().ToLowerInvariant()); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorType.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorType.cs new file mode 100644 index 0000000000..eb415945b0 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Card/AbpCardTextColorType.cs @@ -0,0 +1,16 @@ +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card +{ + public enum AbpCardTextColorType + { + Default, + White, + Primary, + Secondary, + Success, + Danger, + Warning, + Info, + Light, + Dark + } +} From 8d23b96490ab2de9255b176884f914c1200f1ec7 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 17 Dec 2018 15:07:45 +0300 Subject: [PATCH 023/368] card docs --- .../Pages/Components/Cards.cshtml | 608 +++++++++++++++--- 1 file changed, 535 insertions(+), 73 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Cards.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Cards.cshtml index feefc2c04a..0d51658b5f 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Cards.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Cards.cshtml @@ -10,135 +10,597 @@ } +@section scripts { + + @* + *@ + +} + + + + +

Cards

Based on Bootstrap card.

-

# Example

+

Example

- - Card header - Card body + + + + + Card Title + Some quick example text to build on the card title and make up the bulk of the card's content. + Go somewhere + +
-
<abp-card>
-    <abp-card-header>Card header</abp-card-header>
-    <abp-card-body>Card body</abp-card-body>
-</abp-card>
+ + +

+<abp-card style="width: 18rem;">
+  <img abp-card-image="Top" src="~/imgs/demo/300x200.png"/>
+  <abp-card-body>
+    <abp-card-title>Card Title</abp-card-title>
+    <abp-card-text>Some quick example text to build on the card title and make up the bulk of the card's content.</abp-card-text>
+    <a abp-button="Primary" href="#"> Go somewhere</a>
+  </abp-card-body>
+</abp-card>
+
+
+ +

+<div class="card" style="width: 18rem;">
+  <img class="card-img-top" src=".../100px180/" alt="Card image cap">
+  <div class="card-body">
+    <h5 class="card-title">Card title</h5>
+    <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
+    <a href="#" class="btn btn-primary">Go somewhere</a>
+  </div>
+</div>
+
+
+
-

# Example

+

Titles, text, and links

+ - - - This is a sample card component built by - ABP bootstrap card tag helper. - + + Card title + Card subtitle + Some quick example text to build on the card title and make up the bulk of the card's content. Card link Another link +
-
-<abp-card style="width: 18rem;">
-    <abp-card-body title="Card title" subtitle="Card subtitle">
-        <abp-card-text>Some quick example text to build on the card title and make up the bulk of the card's content.</abp-card-text>
-        <a abp-card-link href="#">Card link</a>
-        <a abp-card-link href="#">Another link</a>
+        
+            
+                

+<abp-card style="width: 18rem;">
+    <abp-card-body>
+<abp-card-title>Card title</abp-card-title>
+<abp-card-subtitle class="mb-2 text-muted">Card subtitle</abp-card-subtitle>
+<abp-card-text>Some quick example text to build on the card title and make up the bulk of the card's content.</abp-card-text>
+<a abp-card-link href="#">Card link</a>
+<a abp-card-link href="#">Another link</a>
     </abp-card-body>
 </abp-card>
-
+
+ + +

+<div class="card" style="width: 18rem;">
+  <div class="card-body">
+    <h5 class="card-title">Card title</h5>
+    <h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
+    <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
+    <a href="#" class="card-link">Card link</a>
+    <a href="#" class="card-link">Another link</a>
+  </div>
+</div>
+
+
+
-

# Example

+

List groups

+ + + + Cras justo odio + Dapibus ac facilisis in + Vestibulum at eros + + + +
+
+ + +

+<abp-card style="width: 18rem;">
+    <abp-list-group flush="true">
+<abp-list-group-item>Cras justo odio</abp-list-group-item>
+<abp-list-group-item>Dapibus ac facilisis in</abp-list-group-item>
+<abp-list-group-item>Vestibulum at eros</abp-list-group-item>
+    </abp-list-group>
+</abp-card>
+
+
+ +

+<div class="card" style="width: 18rem;">
+  <ul class="list-group list-group-flush">
+    <li class="list-group-item">Cras justo odio</li>
+    <li class="list-group-item">Dapibus ac facilisis in</li>
+    <li class="list-group-item">Vestibulum at eros</li>
+  </ul>
+</div>
+
+
+
+
+
+ +
+
+ + + Featured + + Cras justo odio + Dapibus ac facilisis in + Vestibulum at eros + + + +
+
+ + +

+<abp-card style="width: 18rem;">
+    <abp-card-header>Featured</abp-card-header>
+    <abp-list-group flush="true">
+<abp-list-group-item>Cras justo odio</abp-list-group-item>
+<abp-list-group-item>Dapibus ac facilisis in</abp-list-group-item>
+<abp-list-group-item>Vestibulum at eros</abp-list-group-item>
+    </abp-list-group>
+</abp-card>
+
+
+ +

+<div class="card" style="width: 18rem;">
+  <div class="card-header">
+    Featured
+  </div>
+  <ul class="list-group list-group-flush">
+    <li class="list-group-item">Cras justo odio</li>
+    <li class="list-group-item">Dapibus ac facilisis in</li>
+    <li class="list-group-item">Vestibulum at eros</li>
+  </ul>
+</div>
+
+
+
+
+
+ +

Kitchen sink

+ +
+
+ - + - Card title - - This is a sample card component built by - ABP bootstrap card tag helper. - - Go somewhere → + Card Title + Some quick example text to build on the card title and make up the bulk of the card's content. + + + Cras justo odio + Dapibus ac facilisis in + Vestibulum at eros + + + Card link + Another link +
-
-<abp-card style="width: 18rem;">
-    <img abp-card-image="Top" src="~/imgs/demo/300x200.png" alt="Card image cap">
+        
+            
+                

+<abp-card style="width: 18rem;">
+    <img abp-card-image="Top" src="~/imgs/demo/300x200.png" />
     <abp-card-body>
-        <abp-card-title>Card title</abp-card-title>
-        <abp-card-text>Some quick example text to build on the card title and make up the bulk of the card's content.</abp-card-text>
-        <a href="#" class="btn btn-primary">Go somewhere</a>
+<abp-card-title>Card Title</abp-card-title>
+<abp-card-text>Some quick example text to build on the card title and make up the bulk of the card's content.</abp-card-text>
+    </abp-card-body>
+    <abp-list-group flush="true">
+<abp-list-group-item>Cras justo odio</abp-list-group-item>
+<abp-list-group-item>Dapibus ac facilisis in</abp-list-group-item>
+<abp-list-group-item>Vestibulum at eros</abp-list-group-item>
+    </abp-list-group>
+    <abp-card-body>
+<a abp-card-link href="#">Card link</a>
+<a abp-card-link href="#">Another link</a>
     </abp-card-body>
 </abp-card>
-
+
+ + +

+<div class="card" style="width: 18rem;">
+  <img class="card-img-top" src=".../100px180/?text=Image cap" alt="Card image cap">
+  <div class="card-body">
+    <h5 class="card-title">Card title</h5>
+    <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
+  </div>
+  <ul class="list-group list-group-flush">
+    <li class="list-group-item">Cras justo odio</li>
+    <li class="list-group-item">Dapibus ac facilisis in</li>
+    <li class="list-group-item">Vestibulum at eros</li>
+  </ul>
+  <div class="card-body">
+    <a href="#" class="card-link">Card link</a>
+    <a href="#" class="card-link">Another link</a>
+  </div>
+</div>
+
+
+
-

# Example

+

Header and footer

+ +
+
+ + + Featured + + Special title treatment + With supporting text below as a natural lead-in to additional content. + Go somewhere + + + +
+
+ + +

+<abp-card style="width: 18rem;">
+    <abp-card-header>Featured</abp-card-header>
+    <abp-card-body>
+<abp-card-title> Special title treatment</abp-card-title>
+<abp-card-text>With supporting text below as a natural lead-in to additional content.</abp-card-text>
+<a abp-button="Primary" href="#"> Go somewhere</a>
+    </abp-card-body>
+</abp-card>
+
+
+ +

+<div class="card">
+  <div class="card-header">
+    Featured
+  </div>
+  <div class="card-body">
+    <h5 class="card-title">Special title treatment</h5>
+    <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
+    <a href="#" class="btn btn-primary">Go somewhere</a>
+  </div>
+</div>
+
+
+
+
+
+ +
+
+ + + Quote + + +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.

+
Someone famous in Source Title
+
+
+
+ +
+
+ + +

+<abp-card>
+    <abp-card-header>Quote</abp-card-header>
+    <abp-card-body>
+<abp-blockquote>
+    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
+    <footer>Someone famous in Source Title</footer>
+</abp-blockquote>
+    </abp-card-body>
+</abp-card>
+
+
+ +

+<div class="card">
+  <div class="card-header">
+    Quote
+  </div>
+  <div class="card-body">
+    <blockquote class="blockquote mb-0">
+      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
+      <footer class="blockquote-footer">Someone famous in Source Titl</footer>
+    </blockquote>
+  </div>
+</div>
+
+
+
+
+
+ - - - - + Featured + + Special title treatment With supporting text below as a natural lead-in to additional content. - Go somewhere + Go somewhere + 2 days ago +
-
-<abp-card class="text-center">
-    <abp-card-header>
-        <ul class="nav nav-tabs card-header-tabs">
-            <li class="nav-item">
-                <a class="nav-link active" href="#">Active</a>
-            </li>
-            <li class="nav-item">
-                <a class="nav-link" href="#link">Link</a>
-            </li>
-            <li class="nav-item">
-                <a class="nav-link disabled" href="#disabledlink">Disabled</a>
-            </li>
-        </ul>
-    </abp-card-header>
-    <abp-card-body title="Special title treatment">
-        <abp-card-text>With supporting text below as a natural lead-in to additional content.</abp-card-text>
-        <a href="#" class="btn btn-primary">Go somewhere</a>
+        
+            
+                

+<abp-card class="text-center">
+    <abp-card-header>Featured</abp-card-header>
+    <abp-card-body>
+<abp-card-title> Special title treatment</abp-card-title>
+<abp-card-text>With supporting text below as a natural lead-in to additional content.</abp-card-text>
+<a abp-button="Primary" href="#"> Go somewhere</a>
     </abp-card-body>
+    <abp-card-footer class="text-muted"> 2 days ago</abp-card-footer>
 </abp-card>
-
+
+ + +

+<div class="card text-center">
+  <div class="card-header">
+    Featured
+  </div>
+  <div class="card-body">
+    <h5 class="card-title">Special title treatment</h5>
+    <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
+    <a href="#" class="btn btn-primary">Go somewhere</a>
+  </div>
+  <div class="card-footer text-muted">
+    2 days ago
+  </div>
+</div>
+
+
+
-
+

Card styles

+ +
Background and color
-< back \ No newline at end of file +
+
+ + + Featured + + Special title treatment + With supporting text below as a natural lead-in to additional content. + + + + Featured + + Special title treatment + With supporting text below as a natural lead-in to additional content. + + + + Featured + + Special title treatment + With supporting text below as a natural lead-in to additional content. + + + + Featured + + Special title treatment + With supporting text below as a natural lead-in to additional content. + + + + Featured + + Special title treatment + With supporting text below as a natural lead-in to additional content. + + + + + Featured + + Special title treatment + With supporting text below as a natural lead-in to additional content. + + + + + Featured + + Special title treatment + With supporting text below as a natural lead-in to additional content. + + + +
+
+ + +

+<abp-card background="Primary" class="mb-3" style="max-width: 18rem;">
+    <abp-card-header>Featured</abp-card-header>
+    <abp-card-body>
+        <abp-card-title> Special title treatment</abp-card-title>
+        <abp-card-text>With supporting text below as a natural lead-in to additional content.</abp-card-text>
+    </abp-card-body>
+</abp-card>
+
+<abp-card background="Success" text-color="Danger" border="Dark" class="mb-3" style="max-width: 18rem;">
+    <abp-card-header>Featured</abp-card-header>
+    <abp-card-body>
+        <abp-card-title> Special title treatment</abp-card-title>
+        <abp-card-text>With supporting text below as a natural lead-in to additional content.</abp-card-text>
+    </abp-card-body>
+</abp-card>
+
+<abp-card background="Warning" text-color="Secondary" class="mb-3" style="max-width: 18rem;">
+    <abp-card-header>Featured</abp-card-header>
+    <abp-card-body>
+        <abp-card-title> Special title treatment</abp-card-title>
+        <abp-card-text>With supporting text below as a natural lead-in to additional content.</abp-card-text>
+    </abp-card-body>
+</abp-card>
+
+<abp-card background="Light" text-color="Dark" border="Success" class="mb-3"  style="max-width: 18rem;">
+    <abp-card-header>Featured</abp-card-header>
+    <abp-card-body>
+        <abp-card-title> Special title treatment</abp-card-title>
+        <abp-card-text>With supporting text below as a natural lead-in to additional content.</abp-card-text>
+    </abp-card-body>
+</abp-card>
+
+<abp-card background="Dark" text-color="White" border="Danger" class="mb-3" style="max-width: 18rem;">
+    <abp-card-header>Featured</abp-card-header>
+    <abp-card-body>
+        <abp-card-title> Special title treatment</abp-card-title>
+        <abp-card-text>With supporting text below as a natural lead-in to additional content.</abp-card-text>
+    </abp-card-body>
+</abp-card>
+
+<abp-card background="Danger" class="mb-3" style="max-width: 18rem;">
+    <abp-card-header text-color="Primary">Featured</abp-card-header>
+    <abp-card-body>
+        <abp-card-title> Special title treatment</abp-card-title>
+        <abp-card-text>With supporting text below as a natural lead-in to additional content.</abp-card-text>
+    </abp-card-body>
+</abp-card>
+
+<abp-card background="Info" border="Danger" class="mb-3" style="max-width: 18rem;">
+    <abp-card-header>Featured</abp-card-header>
+    <abp-card-body text-color="Danger">
+        <abp-card-title> Special title treatment</abp-card-title>
+        <abp-card-text>With supporting text below as a natural lead-in to additional content.</abp-card-text>
+    </abp-card-body>
+</abp-card>
+
+
+ +

+<div class="card bg-primary mb-3" style="max-width: 18rem;">
+  <div class="card-header">Featured</div>
+  <div class="card-body">
+    <h5 class="card-title"> Special title treatment</h5>
+    <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
+  </div>
+</div>
+
+<div class="card text-danger bg-success border-dark mb-3" style="max-width: 18rem;">
+  <div class="card-header">Featured</div>
+  <div class="card-body">
+    <h5 class="card-title"> Special title treatment</h5>
+    <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
+  </div>
+</div>
+
+<div class="card text-secondary bg-warning mb-3" style="max-width: 18rem;">
+  <div class="card-header">Featured</div>
+  <div class="card-body">
+    <h5 class="card-title"> Special title treatment</h5>
+    <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
+  </div>
+</div>
+
+<div class="card text-dark bg-light border-success mb-3" style="max-width: 18rem;">
+  <div class="card-header">Featured</div>
+  <div class="card-body">
+    <h5 class="card-title"> Special title treatment</h5>
+    <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
+  </div>
+</div>
+
+<div class="card text-white bg-dark border-danger mb-3" style="max-width: 18rem;">
+  <div class="card-header">Featured</div>
+  <div class="card-body">
+    <h5 class="card-title"> Special title treatment</h5>
+    <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
+  </div>
+</div>
+
+<div class="card bg-danger mb-3" style="max-width: 18rem;">
+  <div class="card-header text-primary">Featured</div>
+  <div class="card-body">
+    <h5 class="card-title"> Special title treatment</h5>
+    <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
+  </div>
+</div>
+
+<div class="card bg-info border-danger mb-3" style="max-width: 18rem;">
+  <div class="card-header">Featured</div>
+  <div class="card-body text-danger">
+    <h5 class="card-title"> Special title treatment</h5>
+    <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
+  </div>
+</div>
+
+
+
+
+
\ No newline at end of file From b415ed63797927e59febe5b54798feb6349cc3b1 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Mon, 17 Dec 2018 15:32:41 +0300 Subject: [PATCH 024/368] Implemented reconnect for RabbitMqMessageConsumer --- .../RabbitMq/RabbitMqDistributedEventBus.cs | 7 +- .../RabbitMqDistributedEventBusOptions.cs | 2 + .../Volo.Abp.RabbitMQ.csproj | 1 + .../Volo/Abp/RabbitMQ/AbpRabbitMqModule.cs | 4 +- .../IRabbitMqMessageConsumerFactory.cs | 9 + .../Abp/RabbitMQ/RabbitMqMessageConsumer.cs | 171 ++++++++++++------ .../RabbitMqMessageConsumerFactory.cs | 26 +-- 7 files changed, 151 insertions(+), 69 deletions(-) diff --git a/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs index a717cb8d5b..02a9823d84 100644 --- a/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs +++ b/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs @@ -62,7 +62,8 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq durable: true, exclusive: false, autoDelete: false - ) + ), + RabbitMqDistributedEventBusOptions.ConnectionName ); Consumer.OnMessageReceived(ProcessEventAsync); @@ -101,8 +102,6 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq var eventData = Serializer.Deserialize(ea.Body, eventType); await TriggerHandlersAsync(eventType, eventData); - - channel.BasicAck(ea.DeliveryTag, multiple: false); } public IDisposable Subscribe(IDistributedEventHandler handler) where TEvent : class @@ -120,7 +119,7 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq { var eventName = EventNameAttribute.GetNameOrDefault(eventType); - using (var channel = ConnectionPool.Get().CreateModel()) //TODO: Connection name per event! + using (var channel = ConnectionPool.Get(RabbitMqDistributedEventBusOptions.ConnectionName).CreateModel()) { channel.QueueBind( queue: RabbitMqDistributedEventBusOptions.ClientName, diff --git a/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBusOptions.cs b/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBusOptions.cs index fe277f8599..dbcf916b0c 100644 --- a/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBusOptions.cs +++ b/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBusOptions.cs @@ -2,6 +2,8 @@ { public class RabbitMqDistributedEventBusOptions { + public string ConnectionName { get; set; } + public string ClientName { get; set; } public string ExchangeName { get; set; } diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo.Abp.RabbitMQ.csproj b/framework/src/Volo.Abp.RabbitMQ/Volo.Abp.RabbitMQ.csproj index 5173519237..7194a29ee3 100644 --- a/framework/src/Volo.Abp.RabbitMQ/Volo.Abp.RabbitMQ.csproj +++ b/framework/src/Volo.Abp.RabbitMQ/Volo.Abp.RabbitMQ.csproj @@ -16,6 +16,7 @@ + diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/AbpRabbitMqModule.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/AbpRabbitMqModule.cs index ffaa0c00a7..b030e2f5c2 100644 --- a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/AbpRabbitMqModule.cs +++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/AbpRabbitMqModule.cs @@ -1,11 +1,13 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Json; using Volo.Abp.Modularity; +using Volo.Abp.Threading; namespace Volo.Abp.RabbitMQ { [DependsOn( - typeof(AbpJsonModule) + typeof(AbpJsonModule), + typeof(AbpThreadingModule) )] public class AbpRabbitMqModule : AbpModule { diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/IRabbitMqMessageConsumerFactory.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/IRabbitMqMessageConsumerFactory.cs index e2a5125f68..6e5688b2e1 100644 --- a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/IRabbitMqMessageConsumerFactory.cs +++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/IRabbitMqMessageConsumerFactory.cs @@ -2,6 +2,15 @@ { public interface IRabbitMqMessageConsumerFactory { + /// + /// Creates a new . + /// Avoid to create too many consumers since they are + /// not disposed until end of the application. + /// + /// + /// + /// + /// IRabbitMqMessageConsumer Create( ExchangeDeclareConfiguration exchange, QueueDeclareConfiguration queue, diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs index be5358ed45..4c749fe365 100644 --- a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs +++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs @@ -1,32 +1,56 @@ -using System; -using System.Collections.Concurrent; -using System.Threading.Tasks; +using JetBrains.Annotations; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using RabbitMQ.Client; using RabbitMQ.Client.Events; +using System; +using System.Collections.Concurrent; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Threading; namespace Volo.Abp.RabbitMQ { - public class RabbitMqMessageConsumer : IRabbitMqMessageConsumer + public class RabbitMqMessageConsumer : IRabbitMqMessageConsumer, ITransientDependency, IDisposable { + public ILogger Logger { get; set; } + protected IConnectionPool ConnectionPool { get; } - protected ExchangeDeclareConfiguration Exchange { get; } - protected QueueDeclareConfiguration Queue { get; } - protected string ConnectionName { get; } - protected IModel ConsumerChannel { get; set; } + + protected AbpTimer Timer { get; } + + protected ExchangeDeclareConfiguration Exchange { get; private set; } + + protected QueueDeclareConfiguration Queue { get; private set; } + + protected string ConnectionName { get; private set; } + protected ConcurrentBag> Callbacks { get; } + protected IModel Channel { get; private set; } + public RabbitMqMessageConsumer( IConnectionPool connectionPool, - ExchangeDeclareConfiguration exchange, - QueueDeclareConfiguration queue, - string connectionName = null) + AbpTimer timer) { ConnectionPool = connectionPool; - Exchange = exchange; - Queue = queue; - ConnectionName = connectionName; + Timer = timer; + Logger = NullLogger.Instance; + Callbacks = new ConcurrentBag>(); - ConsumerChannel = CreateConsumerChannel(); + + Timer.Period = 5000; //5 sec. + Timer.Elapsed += Timer_Elapsed; + } + + public void Initialize( + [NotNull] ExchangeDeclareConfiguration exchange, + [NotNull] QueueDeclareConfiguration queue, + string connectionName = null) + { + Exchange = Check.NotNull(exchange, nameof(exchange)); + Queue = Check.NotNull(queue, nameof(queue)); + ConnectionName = connectionName; } public void OnMessageReceived(Func callback) @@ -34,53 +58,94 @@ namespace Volo.Abp.RabbitMQ Callbacks.Add(callback); } - private IModel CreateConsumerChannel() + protected virtual void Timer_Elapsed(object sender, EventArgs e) { - var channel = ConnectionPool - .Get(ConnectionName) - .CreateModel(); - - channel.ExchangeDeclare( - exchange: Exchange.ExchangeName, - type: Exchange.Type - ); - - channel.QueueDeclare( - queue: Queue.QueueName, - durable: Queue.Durable, - exclusive: Queue.Exclusive, - autoDelete: Queue.AutoDelete, - arguments: Queue.Arguments - ); - - var consumer = new EventingBasicConsumer(channel); - consumer.Received += async (model, basicDeliverEventArgs) => + if (Channel == null || Channel.IsOpen == false) { + TryCreateChannel(); + } + } + + private void TryCreateChannel() + { + DisposeChannel(); + + try + { + var channel = ConnectionPool + .Get(ConnectionName) + .CreateModel(); + + channel.ExchangeDeclare( + exchange: Exchange.ExchangeName, + type: Exchange.Type + ); + + channel.QueueDeclare( + queue: Queue.QueueName, + durable: Queue.Durable, + exclusive: Queue.Exclusive, + autoDelete: Queue.AutoDelete, + arguments: Queue.Arguments + ); + + var consumer = new EventingBasicConsumer(channel); + consumer.Received += async (model, basicDeliverEventArgs) => { - foreach (var callback in Callbacks) - { - await callback(channel, basicDeliverEventArgs); - } + await HandleIncomingMessage(channel, basicDeliverEventArgs); + }; + + channel.BasicConsume( + queue: Queue.QueueName, + autoAck: false, + consumer: consumer + ); + + Channel = channel; + } + catch (Exception ex) + { + Logger.LogException(ex, LogLevel.Warning); + } + } + + protected virtual async Task HandleIncomingMessage(IModel channel, BasicDeliverEventArgs basicDeliverEventArgs) + { + try + { + foreach (var callback in Callbacks) + { + await callback(channel, basicDeliverEventArgs); } - }; - channel.BasicConsume( - queue: Queue.QueueName, - autoAck: false, - consumer: consumer - ); + channel.BasicAck(basicDeliverEventArgs.DeliveryTag, multiple: false); + } + catch (Exception ex) + { + Logger.LogException(ex); + } + } - //TODO: Instead of creating a new customer immediately without exception handling, - //create a timer that constantly checks connection health and re-connect if needed. - //As similar. Do not connect on constructor! + protected virtual void DisposeChannel() + { + if (Channel == null) + { + return; + } - channel.CallbackException += (sender, ea) => + try + { + Channel.Dispose(); + } + catch (Exception ex) { - ConsumerChannel.Dispose(); - ConsumerChannel = CreateConsumerChannel(); - }; + Logger.LogException(ex, LogLevel.Warning); + } + } - return channel; + public virtual void Dispose() + { + DisposeChannel(); } } } diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumerFactory.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumerFactory.cs index 1787633ac3..b4abd19860 100644 --- a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumerFactory.cs +++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumerFactory.cs @@ -1,14 +1,16 @@ -using Volo.Abp.DependencyInjection; +using System; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.DependencyInjection; namespace Volo.Abp.RabbitMQ { - public class RabbitMqMessageConsumerFactory : IRabbitMqMessageConsumerFactory, ISingletonDependency + public class RabbitMqMessageConsumerFactory : IRabbitMqMessageConsumerFactory, ISingletonDependency, IDisposable { - protected IConnectionPool ConnectionPool { get; } + protected IServiceScope ServiceScope { get; } - public RabbitMqMessageConsumerFactory(IConnectionPool connectionPool) + public RabbitMqMessageConsumerFactory(IServiceScopeFactory serviceScopeFactory) { - ConnectionPool = connectionPool; + ServiceScope = serviceScopeFactory.CreateScope(); } public IRabbitMqMessageConsumer Create( @@ -16,12 +18,14 @@ namespace Volo.Abp.RabbitMQ QueueDeclareConfiguration queue, string connectionName = null) { - return new RabbitMqMessageConsumer( - ConnectionPool, - exchange, - queue, - connectionName - ); + var consumer = ServiceScope.ServiceProvider.GetRequiredService(); + consumer.Initialize(exchange, queue, connectionName); + return consumer; + } + + public void Dispose() + { + ServiceScope?.Dispose(); } } } \ No newline at end of file From 1ed1c994c7d01a56e8ecda55eb521aca9403974f Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Mon, 17 Dec 2018 15:59:04 +0300 Subject: [PATCH 025/368] Added BindAsync and UnbindAsync methods to IRabbitMqMessageConsumer --- .../RabbitMq/RabbitMqDistributedEventBus.cs | 11 +-- .../Abp/RabbitMQ/IRabbitMqMessageConsumer.cs | 4 + .../Volo/Abp/RabbitMQ/QueueBindType.cs | 4 + .../Abp/RabbitMQ/RabbitMqMessageConsumer.cs | 85 +++++++++++++++++++ 4 files changed, 95 insertions(+), 9 deletions(-) create mode 100644 framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/QueueBindType.cs diff --git a/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs index 02a9823d84..2007a69bf5 100644 --- a/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs +++ b/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs @@ -119,14 +119,7 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq { var eventName = EventNameAttribute.GetNameOrDefault(eventType); - using (var channel = ConnectionPool.Get(RabbitMqDistributedEventBusOptions.ConnectionName).CreateModel()) - { - channel.QueueBind( - queue: RabbitMqDistributedEventBusOptions.ClientName, - exchange: RabbitMqDistributedEventBusOptions.ExchangeName, - routingKey: eventName - ); - } + Consumer.BindAsync(eventName); } return new EventHandlerFactoryUnregistrar(this, eventType, factory); @@ -191,7 +184,7 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq var eventName = EventNameAttribute.GetNameOrDefault(eventType); var body = Serializer.Serialize(eventData); - using (var channel = ConnectionPool.Get().CreateModel()) //TODO: Connection name per event! + using (var channel = ConnectionPool.Get(RabbitMqDistributedEventBusOptions.ConnectionName).CreateModel()) { //TODO: Other properties like durable? channel.ExchangeDeclare(RabbitMqDistributedEventBusOptions.ExchangeName, ""); diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/IRabbitMqMessageConsumer.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/IRabbitMqMessageConsumer.cs index 097c5cec35..d600677ec7 100644 --- a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/IRabbitMqMessageConsumer.cs +++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/IRabbitMqMessageConsumer.cs @@ -7,6 +7,10 @@ namespace Volo.Abp.RabbitMQ { public interface IRabbitMqMessageConsumer { + Task BindAsync(string routingKey); + + Task UnbindAsync(string routingKey); + void OnMessageReceived(Func callback); } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/QueueBindType.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/QueueBindType.cs new file mode 100644 index 0000000000..2ff06260a6 --- /dev/null +++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/QueueBindType.cs @@ -0,0 +1,4 @@ +namespace Volo.Abp.RabbitMQ +{ + +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs index 4c749fe365..25ba3a2aa4 100644 --- a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs +++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs @@ -29,6 +29,10 @@ namespace Volo.Abp.RabbitMQ protected IModel Channel { get; private set; } + protected ConcurrentQueue QueueBindCommands { get; } + + protected object ChannelSendSyncLock { get; } = new object(); + public RabbitMqMessageConsumer( IConnectionPool connectionPool, AbpTimer timer) @@ -37,6 +41,7 @@ namespace Volo.Abp.RabbitMQ Timer = timer; Logger = NullLogger.Instance; + QueueBindCommands = new ConcurrentQueue(); Callbacks = new ConcurrentBag>(); Timer.Period = 5000; //5 sec. @@ -51,6 +56,66 @@ namespace Volo.Abp.RabbitMQ Exchange = Check.NotNull(exchange, nameof(exchange)); Queue = Check.NotNull(queue, nameof(queue)); ConnectionName = connectionName; + Timer.Start(); + } + + public async Task BindAsync(string routingKey) + { + QueueBindCommands.Enqueue(new QueueBindCommand(QueueBindType.Bind, routingKey)); + await TrySendQueueBindCommandsAsync(); + } + + public async Task UnbindAsync(string routingKey) + { + QueueBindCommands.Enqueue(new QueueBindCommand(QueueBindType.Unbind, routingKey)); + await TrySendQueueBindCommandsAsync(); + } + + protected Task TrySendQueueBindCommandsAsync() + { + try + { + while (!QueueBindCommands.IsEmpty) + { + if (Channel == null || Channel.IsClosed) + { + return Task.CompletedTask; + } + + lock (ChannelSendSyncLock) + { + QueueBindCommands.TryPeek(out var command); + + switch (command.Type) + { + case QueueBindType.Bind: + Channel.QueueBind( + queue: Queue.QueueName, + exchange: Exchange.ExchangeName, + routingKey: command.RoutingKey + ); + break; + case QueueBindType.Unbind: + Channel.QueueUnbind( + queue: Queue.QueueName, + exchange: Exchange.ExchangeName, + routingKey: command.RoutingKey + ); + break; + default: + throw new AbpException($"Unknown {nameof(QueueBindType)}: {command.Type}"); + } + + QueueBindCommands.TryDequeue(out command); + } + } + } + catch (Exception ex) + { + Logger.LogException(ex, LogLevel.Warning); + } + + return Task.CompletedTask; } public void OnMessageReceived(Func callback) @@ -63,6 +128,7 @@ namespace Volo.Abp.RabbitMQ if (Channel == null || Channel.IsOpen == false) { TryCreateChannel(); + AsyncHelper.RunSync(TrySendQueueBindCommandsAsync); } } @@ -147,5 +213,24 @@ namespace Volo.Abp.RabbitMQ { DisposeChannel(); } + + public class QueueBindCommand + { + public QueueBindType Type { get; } + + public string RoutingKey { get; } + + public QueueBindCommand(QueueBindType type, string routingKey) + { + Type = type; + RoutingKey = routingKey; + } + } + + public enum QueueBindType + { + Bind, + Unbind + } } } From 1ebe284f4105e1f09d4dfec5a3e62cf617660047 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Mon, 17 Dec 2018 16:06:38 +0300 Subject: [PATCH 026/368] Connect to rabbitmq on startup. make methods virtual. --- .../Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs index 25ba3a2aa4..a41054a45f 100644 --- a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs +++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs @@ -46,6 +46,7 @@ namespace Volo.Abp.RabbitMQ Timer.Period = 5000; //5 sec. Timer.Elapsed += Timer_Elapsed; + Timer.RunOnStart = true; } public void Initialize( @@ -59,19 +60,19 @@ namespace Volo.Abp.RabbitMQ Timer.Start(); } - public async Task BindAsync(string routingKey) + public virtual async Task BindAsync(string routingKey) { QueueBindCommands.Enqueue(new QueueBindCommand(QueueBindType.Bind, routingKey)); await TrySendQueueBindCommandsAsync(); } - public async Task UnbindAsync(string routingKey) + public virtual async Task UnbindAsync(string routingKey) { QueueBindCommands.Enqueue(new QueueBindCommand(QueueBindType.Unbind, routingKey)); await TrySendQueueBindCommandsAsync(); } - protected Task TrySendQueueBindCommandsAsync() + protected virtual Task TrySendQueueBindCommandsAsync() { try { @@ -118,7 +119,7 @@ namespace Volo.Abp.RabbitMQ return Task.CompletedTask; } - public void OnMessageReceived(Func callback) + public virtual void OnMessageReceived(Func callback) { Callbacks.Add(callback); } @@ -132,7 +133,7 @@ namespace Volo.Abp.RabbitMQ } } - private void TryCreateChannel() + protected virtual void TryCreateChannel() { DisposeChannel(); @@ -214,7 +215,7 @@ namespace Volo.Abp.RabbitMQ DisposeChannel(); } - public class QueueBindCommand + protected class QueueBindCommand { public QueueBindType Type { get; } @@ -227,7 +228,7 @@ namespace Volo.Abp.RabbitMQ } } - public enum QueueBindType + protected enum QueueBindType { Bind, Unbind From 9322bf03b35bd6be782ce8107796d9d33a5c2de4 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Mon, 17 Dec 2018 16:24:48 +0300 Subject: [PATCH 027/368] Refactor rabbitmq eventbus --- .../RabbitMq/RabbitMqDistributedEventBus.cs | 39 ++++++------------- .../Volo/Abp/EventBus/EventBusBase.cs | 30 ++++++++++++++ .../Volo/Abp/EventBus/Local/LocalEventBus.cs | 29 +------------- .../Volo/Abp/RabbitMQ/RabbitMqConsts.cs | 12 ++++++ 4 files changed, 55 insertions(+), 55 deletions(-) create mode 100644 framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqConsts.cs diff --git a/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs index 2007a69bf5..297ac33df5 100644 --- a/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs +++ b/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs @@ -26,9 +26,10 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq protected DistributedEventBusOptions DistributedEventBusOptions { get; } protected IConnectionPool ConnectionPool { get; } protected IRabbitMqSerializer Serializer { get; } - protected ConcurrentDictionary> HandlerFactories { get; } //TODO: Accessing to the List may not be thread-safe! + + //TODO: Accessing to the List may not be thread-safe! + protected ConcurrentDictionary> HandlerFactories { get; } protected ConcurrentDictionary EventTypes { get; } - protected IHybridServiceScopeFactory ServiceScopeFactory { get; } protected IRabbitMqMessageConsumerFactory MessageConsumerFactory { get; } protected IRabbitMqMessageConsumer Consumer { get; } @@ -39,10 +40,10 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq IHybridServiceScopeFactory serviceScopeFactory, IOptions distributedEventBusOptions, IRabbitMqMessageConsumerFactory messageConsumerFactory) + : base(serviceScopeFactory) { ConnectionPool = connectionPool; Serializer = serializer; - ServiceScopeFactory = serviceScopeFactory; MessageConsumerFactory = messageConsumerFactory; DistributedEventBusOptions = distributedEventBusOptions.Value; RabbitMqDistributedEventBusOptions = options.Value; @@ -50,8 +51,6 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq HandlerFactories = new ConcurrentDictionary>(); EventTypes = new ConcurrentDictionary(); - Subscribe(DistributedEventBusOptions.Handlers); - Consumer = MessageConsumerFactory.Create( new ExchangeDeclareConfiguration( RabbitMqDistributedEventBusOptions.ExchangeName, @@ -67,27 +66,8 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq ); Consumer.OnMessageReceived(ProcessEventAsync); - } - protected virtual void Subscribe(ITypeList handlers) - { - foreach (var handler in handlers) - { - var interfaces = handler.GetInterfaces(); - foreach (var @interface in interfaces) - { - if (!typeof(IEventHandler).GetTypeInfo().IsAssignableFrom(@interface)) - { - continue; - } - - var genericArgs = @interface.GetGenericArguments(); - if (genericArgs.Length == 1) - { - Subscribe(genericArgs[0], new IocEventHandlerFactory(ServiceScopeFactory, handler)); - } - } - } + SubscribeHandlers(DistributedEventBusOptions.Handlers); } private async Task ProcessEventAsync(IModel channel, BasicDeliverEventArgs ea) @@ -186,11 +166,14 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq using (var channel = ConnectionPool.Get(RabbitMqDistributedEventBusOptions.ConnectionName).CreateModel()) { - //TODO: Other properties like durable? - channel.ExchangeDeclare(RabbitMqDistributedEventBusOptions.ExchangeName, ""); + channel.ExchangeDeclare( + RabbitMqDistributedEventBusOptions.ExchangeName, + "direct" + //TODO: Other properties like durable? + ); var properties = channel.CreateBasicProperties(); - properties.DeliveryMode = 2; //persistent + properties.DeliveryMode = RabbitMqConsts.DeliveryModes.Persistent; channel.BasicPublish( exchange: RabbitMqDistributedEventBusOptions.ExchangeName, diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusBase.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusBase.cs index c700f46532..3b2da52a96 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusBase.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusBase.cs @@ -5,6 +5,8 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; +using Volo.Abp.Collections; +using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus.Distributed; using Volo.Abp.Reflection; @@ -12,6 +14,13 @@ namespace Volo.Abp.EventBus { public abstract class EventBusBase : IEventBus { + protected IHybridServiceScopeFactory ServiceScopeFactory { get; } + + protected EventBusBase(IHybridServiceScopeFactory serviceScopeFactory) + { + ServiceScopeFactory = serviceScopeFactory; + } + /// public virtual IDisposable Subscribe(Func action) where TEvent : class { @@ -122,6 +131,27 @@ namespace Volo.Abp.EventBus } } + protected virtual void SubscribeHandlers(ITypeList handlers) + { + foreach (var handler in handlers) + { + var interfaces = handler.GetInterfaces(); + foreach (var @interface in interfaces) + { + if (!typeof(IEventHandler).GetTypeInfo().IsAssignableFrom(@interface)) + { + continue; + } + + var genericArgs = @interface.GetGenericArguments(); + if (genericArgs.Length == 1) + { + Subscribe(genericArgs[0], new IocEventHandlerFactory(ServiceScopeFactory, handler)); + } + } + } + } + protected abstract IEnumerable GetHandlerFactories(Type eventType); protected virtual async Task TriggerHandlerAsync(IEventHandlerFactory asyncHandlerFactory, Type eventType, object eventData, List exceptions) diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs index ae1041c9e2..e8786073a7 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs @@ -5,9 +5,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using System.Reflection; using System.Threading.Tasks; -using Volo.Abp.Collections; using Volo.Abp.DependencyInjection; using Volo.Abp.Threading; @@ -28,39 +26,16 @@ namespace Volo.Abp.EventBus.Local protected ConcurrentDictionary> HandlerFactories { get; } - protected IHybridServiceScopeFactory ServiceScopeFactory { get; } - public LocalEventBus( IOptions options, IHybridServiceScopeFactory serviceScopeFactory) + : base(serviceScopeFactory) { - ServiceScopeFactory = serviceScopeFactory; Options = options.Value; Logger = NullLogger.Instance; HandlerFactories = new ConcurrentDictionary>(); - Subscribe(Options.Handlers); - } - - public virtual void Subscribe(ITypeList handlers) - { - foreach (var handler in handlers) - { - var interfaces = handler.GetInterfaces(); - foreach (var @interface in interfaces) - { - if (!typeof(IEventHandler).GetTypeInfo().IsAssignableFrom(@interface)) - { - continue; - } - - var genericArgs = @interface.GetGenericArguments(); - if (genericArgs.Length == 1) - { - Subscribe(genericArgs[0], new IocEventHandlerFactory(ServiceScopeFactory, handler)); - } - } - } + SubscribeHandlers(Options.Handlers); } /// diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqConsts.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqConsts.cs new file mode 100644 index 0000000000..0869dfd3b9 --- /dev/null +++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqConsts.cs @@ -0,0 +1,12 @@ +namespace Volo.Abp.RabbitMQ +{ + public static class RabbitMqConsts + { + public static class DeliveryModes + { + public const int NonPersistent = 1; + + public const int Persistent = 2; + } + } +} From bfc50b5fc1c3973befcb2fad996175ab090a35c6 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Mon, 17 Dec 2018 16:42:23 +0300 Subject: [PATCH 028/368] Add link to DI document --- docs/en/Getting-Started-Console-Application.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/Getting-Started-Console-Application.md b/docs/en/Getting-Started-Console-Application.md index 00c3d1e0a2..4200bb6ca7 100644 --- a/docs/en/Getting-Started-Console-Application.md +++ b/docs/en/Getting-Started-Console-Application.md @@ -117,8 +117,8 @@ namespace AbpConsoleDemo } ```` -While it's enough for this simple code example, it's always suggested to create scopes in case of directly resolving dependencies from ``IServiceProvider`` (TODO: see DI documentation). +While it's enough for this simple code example, it's always suggested to create scopes in case of directly resolving dependencies from ``IServiceProvider`` (see the [Dependency Injection documentation](Dependency-Injection.md)). ### Source Code -Get source code of the sample project created in this tutorial from [here](https://github.com/abpframework/abp/tree/master/samples/BasicConsoleApplication. +Get source code of the sample project created in this tutorial from [here](https://github.com/abpframework/abp/tree/master/samples/BasicConsoleApplication). From 7759d3244f0d16988359188e8b2cd351221a831a Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Mon, 17 Dec 2018 16:52:16 +0300 Subject: [PATCH 029/368] Move Volo.Abp.EventBus.Distributed.RabbitMQ to Volo.Abp.EventBus.RabbitMQ --- framework/Volo.Abp.sln | 2 +- .../Volo.Abp.EventBus.RabbitMQ.csproj | 0 .../EventBus/Distributed/RabbitMq/AbpEventBusRabbitMqModule.cs | 0 .../Distributed/RabbitMq/RabbitMqDistributedEventBus.cs | 2 -- .../Distributed/RabbitMq/RabbitMqDistributedEventBusOptions.cs | 0 5 files changed, 1 insertion(+), 3 deletions(-) rename framework/src/{Volo.Abp.EventBus.Distributed.RabbitMQ => Volo.Abp.EventBus.RabbitMQ}/Volo.Abp.EventBus.RabbitMQ.csproj (100%) rename framework/src/{Volo.Abp.EventBus.Distributed.RabbitMQ => Volo.Abp.EventBus.RabbitMQ}/Volo/Abp/EventBus/Distributed/RabbitMq/AbpEventBusRabbitMqModule.cs (100%) rename framework/src/{Volo.Abp.EventBus.Distributed.RabbitMQ => Volo.Abp.EventBus.RabbitMQ}/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs (99%) rename framework/src/{Volo.Abp.EventBus.Distributed.RabbitMQ => Volo.Abp.EventBus.RabbitMQ}/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBusOptions.cs (100%) diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln index 9916c2a8e8..92c46299f4 100644 --- a/framework/Volo.Abp.sln +++ b/framework/Volo.Abp.sln @@ -168,7 +168,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.MongoDB.Tests", "t EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.EntityFrameworkCore.SqlServer", "src\Volo.Abp.EntityFrameworkCore.SqlServer\Volo.Abp.EntityFrameworkCore.SqlServer.csproj", "{6EABA98D-0B71-4ED7-A939-AFDA106D1151}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.EventBus.RabbitMQ", "src\Volo.Abp.EventBus.Distributed.RabbitMQ\Volo.Abp.EventBus.RabbitMQ.csproj", "{468C3DCB-8C00-40E7-AE51-0738EAAB312A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.EventBus.RabbitMQ", "src\Volo.Abp.EventBus.RabbitMQ\Volo.Abp.EventBus.RabbitMQ.csproj", "{468C3DCB-8C00-40E7-AE51-0738EAAB312A}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic", "src\Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic\Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.csproj", "{2F5EE6D9-511B-4998-BD62-0B9F03E02432}" EndProject diff --git a/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo.Abp.EventBus.RabbitMQ.csproj b/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo.Abp.EventBus.RabbitMQ.csproj similarity index 100% rename from framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo.Abp.EventBus.RabbitMQ.csproj rename to framework/src/Volo.Abp.EventBus.RabbitMQ/Volo.Abp.EventBus.RabbitMQ.csproj diff --git a/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/AbpEventBusRabbitMqModule.cs b/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/AbpEventBusRabbitMqModule.cs similarity index 100% rename from framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/AbpEventBusRabbitMqModule.cs rename to framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/AbpEventBusRabbitMqModule.cs diff --git a/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs similarity index 99% rename from framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs rename to framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs index 297ac33df5..4de808defa 100644 --- a/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs +++ b/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs @@ -2,14 +2,12 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using System.Reflection; using System.Threading.Tasks; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; using Volo.Abp.RabbitMQ; using RabbitMQ.Client; using RabbitMQ.Client.Events; -using Volo.Abp.Collections; using Volo.Abp.Threading; namespace Volo.Abp.EventBus.Distributed.RabbitMq diff --git a/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBusOptions.cs b/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBusOptions.cs similarity index 100% rename from framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBusOptions.cs rename to framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBusOptions.cs From 07a1ad9b065f9ff195505136f0c5a747fb35d292 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 17 Dec 2018 17:10:27 +0300 Subject: [PATCH 030/368] Collapse tag helper improvements --- .../Collapse/AbpCollapseBodyTagHelper.cs | 2 + .../AbpCollapseBodyTagHelperService.cs | 14 +++--- .../Collapse/AbpCollapseButtonTagHelper.cs | 9 ++-- .../AbpCollapseButtonTagHelperService.cs | 46 +++++++++++++++---- 4 files changed, 51 insertions(+), 20 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseBodyTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseBodyTagHelper.cs index 0d4aecab31..a50907addb 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseBodyTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseBodyTagHelper.cs @@ -4,6 +4,8 @@ { public string Id { get; set; } + public bool? Multi { get; set; } + public bool? Show { get; set; } public AbpCollapseBodyTagHelper(AbpCollapseBodyTagHelperService tagHelperService) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseBodyTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseBodyTagHelperService.cs index 56b04df63d..10e49b92a7 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseBodyTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseBodyTagHelperService.cs @@ -17,16 +17,14 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Collapse output.Attributes.AddClass("show"); } - var innerContent = (await output.GetChildContentAsync()).GetContent(); - - var body = GetBody(context, output, innerContent); + if (TagHelper.Multi ?? false) + { + output.Attributes.AddClass("multi-collapse"); + } - output.Content.SetHtmlContent(body); - } + var innerContent = (await output.GetChildContentAsync()).GetContent(); - protected virtual string GetBody(TagHelperContext context, TagHelperOutput output, string innerContent) - { - return "
" + innerContent + "
"; + output.Content.SetHtmlContent(innerContent); } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseButtonTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseButtonTagHelper.cs index 2e6da81cf0..6b8fc8c30b 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseButtonTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseButtonTagHelper.cs @@ -1,11 +1,14 @@ -using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button; +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Collapse { + + [HtmlTargetElement("abp-button", Attributes = "abp-collapse-id")] + [HtmlTargetElement("a", Attributes = "abp-collapse-id")] public class AbpCollapseButtonTagHelper : AbpTagHelper { - public AbpButtonType ButonType { get; set; } = AbpButtonType.Default; - + [HtmlAttributeName("abp-collapse-id")] public string BodyId { get; set; } public AbpCollapseButtonTagHelper(AbpCollapseButtonTagHelperService tagHelperService) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseButtonTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseButtonTagHelperService.cs index c2221035c1..6b7d74b866 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseButtonTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Collapse/AbpCollapseButtonTagHelperService.cs @@ -8,20 +8,48 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Collapse { public override void Process(TagHelperContext context, TagHelperOutput output) { - output.TagName = "button"; - output.Attributes.AddClass("btn"); - output.Attributes.Add("data-toggle","collapse"); - output.Attributes.Add("aria-expanded","false"); - output.Attributes.Add("type","button"); - output.Attributes.Add("data-target", "#" +TagHelper.BodyId); + + + AddCommonAttributes(context, output); + + if (output.TagName == "abp-button" || output.TagName == "button") + { + AddButtonAttributes(context,output); + } + else if (output.TagName == "a") + { + AddLinkAttributes(context, output); + } + } + + protected virtual void AddCommonAttributes(TagHelperContext context, TagHelperOutput output) + { + output.Attributes.Add("data-toggle", "collapse"); + output.Attributes.Add("aria-expanded", "false"); output.Attributes.Add("aria-controls", TagHelper.BodyId); + } + protected virtual void AddButtonAttributes(TagHelperContext context, TagHelperOutput output) + { + if (TagHelper.BodyId.Trim().Split(' ').Length > 1) + { + output.Attributes.Add("data-target", ".multi-collapse"); + return; + } - if (TagHelper.ButonType != AbpButtonType.Default) + output.Attributes.Add("data-target", "#" + TagHelper.BodyId); + } + + protected virtual void AddLinkAttributes(TagHelperContext context, TagHelperOutput output) + { + if (TagHelper.BodyId.Trim().Split(' ').Length > 1) { - output.Attributes.AddClass("btn-" + TagHelper.ButonType.ToString().ToLowerInvariant()); + output.Attributes.Add("href", ".multi-collapse"); + return; } + + output.Attributes.Add("href", "#" + TagHelper.BodyId); } - + } } \ No newline at end of file From faf05b04d114b1f9817c5c430251df7d86aab1d4 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 17 Dec 2018 17:10:37 +0300 Subject: [PATCH 031/368] collapse tag helper demo --- .../Pages/Components/Collapse.cshtml | 228 ++++++++++++++---- 1 file changed, 183 insertions(+), 45 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Collapse.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Collapse.cshtml index adbe35a3fa..fa0fd4d815 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Collapse.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Collapse.cshtml @@ -15,68 +15,206 @@

Based on Bootstrap Collapse.

-

# Accordion Example

+ +

Example

- - - 1Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry rtat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. - - - 2Anim pariatur cliche reprehenderit,, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. - - - 3Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. - - + Link with href + + + 3Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. +
-
-<abp-accordion>
-    <abp-accordion-item title="header1">
-       1Anim pariatur cliche reprehenderit, enim eiusmod high life acc
-    </abp-accordion-item>
-    <abp-accordion-item title="header2">
-       2Anim pariatur cliche reprehenderit,, enim eiusmod high life
-    </abp-accordion-item>
-    <abp-accordion-item title="header3">
-       3Anim pariatur  wolf moon tempor,,, sunt aliqua put a bird on i
-    </abp-accordion-item>
-</abp-accordion>
-
+ + +

+<abp-button button-type="Primary" abp-collapse-id="collapseExample" text="Button with data-target" />
+<a abp-button="Primary" abp-collapse-id="collapseExample"> Link with href </a>
+
+<abp-collapse-body id="collapseExample">
+            ...
+</abp-collapse-body>
+
+
+ +

+<p>
+  <a class="btn btn-primary" data-toggle="collapse" href="#collapseExample" role="button" aria-expanded="false" aria-controls="collapseExample">
+    Link with href
+  </a>
+  <button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample">
+    Button with data-target
+  </button>
+</p>
+<div class="collapse" id="collapseExample">
+  <div class="card card-body">
+    Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident.
+  </div>
+</div>
+
+
+
-

# Collapse With Button Example

+

Multiple targets

-

- - Toggle - -

- - - 3Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. - - + Toggle first element + + + + + + + 3Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. + + + + + 3Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. + + +
-
+        
+            
+                

+
+<a abp-button="Primary" abp-collapse-id="FirstCollapseExample"> Toggle first element </a>
+<abp-button button-type="Primary" abp-collapse-id="SecondCollapseExample" text="Toggle second element" />
+<abp-button button-type="Primary" abp-collapse-id="FirstCollapseExample SecondCollapseExample" text="Toggle both elements" />
+        
+<abp-row class="mt-3">
+    <abp-column size-sm="_6">
+        <abp-collapse-body id="FirstCollapseExample" multi="true">
+                        3Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
+        </abp-collapse-body>
+    </abp-column>
+    <abp-column size-sm="_6">
+        <abp-collapse-body id="SecondCollapseExample" multi="true">
+                    3Anim pariatur  wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
+        </abp-collapse-body>
+    </abp-column>
+</abp-row>
+
+
+ +

 <p>
-   <abp-collapse-button buton-type="Success" body-id="collapseExample">
-       Toggle
-   </abp-collapse-button>
+  <a class="btn btn-primary" data-toggle="collapse" href="#multiCollapseExample1" role="button" aria-expanded="false" aria-controls="multiCollapseExample1">Toggle first element</a>
+  <button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#multiCollapseExample2" aria-expanded="false" aria-controls="multiCollapseExample2">Toggle second element</button>
+  <button class="btn btn-primary" type="button" data-toggle="collapse" data-target=".multi-collapse" aria-expanded="false" aria-controls="multiCollapseExample1 multiCollapseExample2">Toggle both elements</button>
 </p>
-        
-<abp-collapse-body id="collapseExample" show="true">
-   3Anim pariatur  wolf moon tempor,,, sunt aliqua put a bir
-</abp-collapse-body>
-
+<div class="row"> + <div class="col"> + <div class="collapse multi-collapse" id="multiCollapseExample1"> + Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. + </div> + </div> + <div class="col"> + <div class="collapse multi-collapse" id="multiCollapseExample2"> + Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. + </div> + </div> +</div> +
+ + +
+
+ +

Accordion example

+ +
+
+ + + + Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry rtat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. + + + Anim pariatur cliche reprehenderit,, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. + + + Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. + + +
+
+ + +

+
+<abp-accordion>
+    <abp-accordion-item title="Collapsible Group Item #1">
+                Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry rtat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
+    </abp-accordion-item>
+    <abp-accordion-item title="Collapsible Group Item #2">
+                Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
+    </abp-accordion-item>
+    <abp-accordion-item title="Collapsible Group Item #3">
+                Anim pariatur  wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
+    </abp-accordion-item>
+</abp-accordion>
+
+
+ +

+<div class="accordion" id="accordionExample">
+  <div class="card">
+    <div class="card-header" id="headingOne">
+      <h5 class="mb-0">
+        <button class="btn btn-link" type="button" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
+          Collapsible Group Item #1
+        </button>
+      </h5>
+    </div>
+
+    <div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#accordionExample">
+      <div class="card-body">
+        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
+      </div>
+    </div>
+  </div>
+  <div class="card">
+    <div class="card-header" id="headingTwo">
+      <h5 class="mb-0">
+        <button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
+          Collapsible Group Item #2
+        </button>
+      </h5>
+    </div>
+    <div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordionExample">
+      <div class="card-body">
+        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
+      </div>
+    </div>
+  </div>
+  <div class="card">
+    <div class="card-header" id="headingThree">
+      <h5 class="mb-0">
+        <button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
+          Collapsible Group Item #3
+        </button>
+      </h5>
+    </div>
+    <div id="collapseThree" class="collapse" aria-labelledby="headingThree" data-parent="#accordionExample">
+      <div class="card-body">
+        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
+      </div>
+    </div>
+  </div>
+</div>
+
+
+
From eb3b69b6148fd9c932260a9c270ed56d1649f4f7 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 17 Dec 2018 17:10:50 +0300 Subject: [PATCH 032/368] carousel tag helper demo --- .../Pages/Components/Carousel.cshtml | 253 ++++++++++++++++-- 1 file changed, 232 insertions(+), 21 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Carousel.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Carousel.cshtml index 2ea6fa3f60..712fc37882 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Carousel.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Carousel.cshtml @@ -14,44 +14,255 @@

Based on Bootstrap Carousel.

-

# Carousel Examples

+

Slides only

+ + + + + + +
+
+ + +

+<abp-carousel indicators="false" controls="false">
+    <abp-carousel-item src="..."></abp-carousel-item>
+    <abp-carousel-item src="..."></abp-carousel-item>
+    <abp-carousel-item src="..."></abp-carousel-item>
+</abp-carousel>
+
+
+ +

+<div id="carouselExampleSlidesOnly" class="carousel slide" data-ride="carousel">
+  <div class="carousel-inner">
+    <div class="carousel-item active">
+      <img class="d-block w-100" src="..." alt="First slide">
+    </div>
+    <div class="carousel-item">
+      <img class="d-block w-100" src="..." alt="Second slide">
+    </div>
+    <div class="carousel-item">
+      <img class="d-block w-100" src="..." alt="Third slide">
+    </div>
+  </div>
+</div>
+
+
+
+
+
+ +

With controls

+ +
+
+ + + + + + +
+
+ + +

+<abp-carousel indicators="false">
+    <abp-carousel-item src="..."></abp-carousel-item>
+    <abp-carousel-item src="..."></abp-carousel-item>
+    <abp-carousel-item src="..."></abp-carousel-item>
+</abp-carousel>
+
+
+ +

+<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
+  <div class="carousel-inner">
+    <div class="carousel-item active">
+      <img class="d-block w-100" src=".../800x400?auto=yes&bg=777&fg=555&text=First slide" alt="First slide">
+    </div>
+    <div class="carousel-item">
+      <img class="d-block w-100" src=".../800x400?auto=yes&bg=666&fg=444&text=Second slide" alt="Second slide">
+    </div>
+    <div class="carousel-item">
+      <img class="d-block w-100" src=".../800x400?auto=yes&bg=555&fg=333&text=Third slide" alt="Third slide">
+    </div>
+  </div>
+  <a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
+    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
+    <span class="sr-only">Previous</span>
+  </a>
+  <a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
+    <span class="carousel-control-next-icon" aria-hidden="true"></span>
+    <span class="sr-only">Next</span>
+  </a>
+</div>
+
+
+
+
+
+ +

With indicators

+ +
+
+ + + + + + +
+
+ + +

+<abp-carousel>
+    <abp-carousel-item src="..."></abp-carousel-item>
+    <abp-carousel-item src="..."></abp-carousel-item>
+    <abp-carousel-item src="..."></abp-carousel-item>
+</abp-carousel>
+
+
+ +

+<div id="carouselExampleIndicators" class="carousel slide" data-ride="carousel">
+  <ol class="carousel-indicators">
+    <li data-target="#carouselExampleIndicators" data-slide-to="0" class="active"></li>
+    <li data-target="#carouselExampleIndicators" data-slide-to="1"></li>
+    <li data-target="#carouselExampleIndicators" data-slide-to="2"></li>
+  </ol>
+  <div class="carousel-inner">
+    <div class="carousel-item active">
+      <img class="d-block w-100" src=".../800x400?auto=yes&bg=777&fg=555&text=First slide" alt="First slide">
+    </div>
+    <div class="carousel-item">
+      <img class="d-block w-100" src=".../800x400?auto=yes&bg=666&fg=444&text=Second slide" alt="Second slide">
+    </div>
+    <div class="carousel-item">
+      <img class="d-block w-100" src=".../800x400?auto=yes&bg=555&fg=333&text=Third slide" alt="Third slide">
+    </div>
+  </div>
+  <a class="carousel-control-prev" href="#carouselExampleIndicators" role="button" data-slide="prev">
+    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
+    <span class="sr-only">Previous</span>
+  </a>
+  <a class="carousel-control-next" href="#carouselExampleIndicators" role="button" data-slide="next">
+    <span class="carousel-control-next-icon" aria-hidden="true"></span>
+    <span class="sr-only">Next</span>
+  </a>
+</div>
+
+
+
+
+
+ +

With captions

+ +
+
+ - - - +
-
+        
+            
+                

 <abp-carousel>
-   <abp-carousel-item src="..."  alt="Carousel Item 1" caption="Caption" caption-title="title"></abp-carousel-item>
-   <abp-carousel-item src="..." alt="Carousel Item 2" caption="Caption2" caption-title="title2"></abp-carousel-item>
-   <abp-carousel-item src="..." alt="Carousel Item 3" caption="Caption3" caption-title="title3"></abp-carousel-item>
+    <abp-carousel-item caption-title="Second slide label" caption="Lorem ipsum dolor sit amet, consectetur adipiscing elit." src="..."></abp-carousel-item>
 </abp-carousel>
-
+
+ + +

+<div id="carouselExampleIndicators" class="carousel slide" data-ride="carousel">
+  <ol class="carousel-indicators">
+    <li data-target="#carouselExampleIndicators" data-slide-to="0" class="active"></li>
+    <li data-target="#carouselExampleIndicators" data-slide-to="1"></li>
+    <li data-target="#carouselExampleIndicators" data-slide-to="2"></li>
+  </ol>
+  <div class="carousel-inner">
+    <div class="carousel-item active">
+      <img class="d-block w-100" src=".../800x400?auto=yes&bg=777&fg=555&text=First slide" alt="First slide">
+        <div class="carousel-caption d-none d-md-block">
+            <h5>Second slide label</h5>
+            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
+        </div>
+    </div>
+  </div>
+  <a class="carousel-control-prev" href="#carouselExampleIndicators" role="button" data-slide="prev">
+    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
+    <span class="sr-only">Previous</span>
+  </a>
+  <a class="carousel-control-next" href="#carouselExampleIndicators" role="button" data-slide="next">
+    <span class="carousel-control-next-icon" aria-hidden="true"></span>
+    <span class="sr-only">Next</span>
+  </a>
+</div>
+
+
+
-

# Carousel Examples

+ +

Crossfade

- - - - + + + + +
-
-<abp-carousel controls="true" indicators="false" crossfade="true">
-   <abp-carousel-item src="..."  alt="Carousel Item 1"></abp-carousel-item>
-   <abp-carousel-item src="..." alt="Carousel Item 2" caption="Caption2" caption-title="title2"></abp-carousel-item>
-   <abp-carousel-item src="..." alt="Carousel Item 3"></abp-carousel-item>
+        
+            
+                

+<abp-carousel indicators="false" crossfade="true">
+    <abp-carousel-item src="..."></abp-carousel-item>
+    <abp-carousel-item src="..."></abp-carousel-item>
+    <abp-carousel-item src="..."></abp-carousel-item>
 </abp-carousel>
-
+
+ + +

+<div id="carouselExampleFade" class="carousel slide carousel-fade" data-ride="carousel">
+  <div class="carousel-inner">
+    <div class="carousel-item active">
+      <img class="d-block w-100" src="..." alt="First slide">
+    </div>
+    <div class="carousel-item">
+      <img class="d-block w-100" src="...e" alt="Second slide">
+    </div>
+    <div class="carousel-item">
+      <img class="d-block w-100" src="..." alt="Third slide">
+    </div>
+  </div>
+  <a class="carousel-control-prev" href="#carouselExampleFade" role="button" data-slide="prev">
+    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
+    <span class="sr-only">Previous</span>
+  </a>
+  <a class="carousel-control-next" href="#carouselExampleFade" role="button" data-slide="next">
+    <span class="carousel-control-next-icon" aria-hidden="true"></span>
+    <span class="sr-only">Next</span>
+  </a>
+</div>
+
+
+
-
\ No newline at end of file + + From 55981f714c20027092f89b0bea5069974f478898 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Mon, 17 Dec 2018 17:18:09 +0300 Subject: [PATCH 033/368] Created sample rabbitmq messaging application --- .../Volo/Abp/EventBus/EventBusExtensions.cs | 36 +++++++++++++++++ .../Volo/Abp/EventBus/IEventBus.cs | 4 +- samples/RabbitMqEventBus/App1/App1.csproj | 13 ++++++ .../App1/App1MessagingService.cs | 40 +++++++++++++++++++ samples/RabbitMqEventBus/App1/App1Module.cs | 20 ++++++++++ .../App1/App1TextEventHandler.cs | 34 ++++++++++++++++ .../App1/App1TextReceivedEventHandler.cs | 18 +++++++++ samples/RabbitMqEventBus/App1/Program.cs | 24 +++++++++++ samples/RabbitMqEventBus/App2/App2.csproj | 13 ++++++ .../App2/App2MessagingService.cs | 40 +++++++++++++++++++ samples/RabbitMqEventBus/App2/App2Module.cs | 20 ++++++++++ .../App2/App2TextEventHandler.cs | 34 ++++++++++++++++ .../App2/App2TextReceivedEventHandler.cs | 18 +++++++++ samples/RabbitMqEventBus/App2/Program.cs | 24 +++++++++++ samples/RabbitMqEventBus/RabbitMqEventBus.sln | 37 +++++++++++++++++ .../SharedModule/SharedModule.csproj | 7 ++++ .../SharedModule/TextEventData.cs | 7 ++++ .../SharedModule/TextReceivedEventData.cs | 7 ++++ 18 files changed, 394 insertions(+), 2 deletions(-) create mode 100644 framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusExtensions.cs create mode 100644 samples/RabbitMqEventBus/App1/App1.csproj create mode 100644 samples/RabbitMqEventBus/App1/App1MessagingService.cs create mode 100644 samples/RabbitMqEventBus/App1/App1Module.cs create mode 100644 samples/RabbitMqEventBus/App1/App1TextEventHandler.cs create mode 100644 samples/RabbitMqEventBus/App1/App1TextReceivedEventHandler.cs create mode 100644 samples/RabbitMqEventBus/App1/Program.cs create mode 100644 samples/RabbitMqEventBus/App2/App2.csproj create mode 100644 samples/RabbitMqEventBus/App2/App2MessagingService.cs create mode 100644 samples/RabbitMqEventBus/App2/App2Module.cs create mode 100644 samples/RabbitMqEventBus/App2/App2TextEventHandler.cs create mode 100644 samples/RabbitMqEventBus/App2/App2TextReceivedEventHandler.cs create mode 100644 samples/RabbitMqEventBus/App2/Program.cs create mode 100644 samples/RabbitMqEventBus/RabbitMqEventBus.sln create mode 100644 samples/RabbitMqEventBus/SharedModule/SharedModule.csproj create mode 100644 samples/RabbitMqEventBus/SharedModule/TextEventData.cs create mode 100644 samples/RabbitMqEventBus/SharedModule/TextReceivedEventData.cs diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusExtensions.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusExtensions.cs new file mode 100644 index 0000000000..5139e1cbcb --- /dev/null +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusExtensions.cs @@ -0,0 +1,36 @@ +using System; +using JetBrains.Annotations; +using Volo.Abp.Threading; + +namespace Volo.Abp.EventBus +{ + public static class EventBusExtensions + { + /// + /// Triggers an event. + /// + /// Event type + /// Event bus instance + /// Related data for the event + public static void Publish([NotNull] this IEventBus eventBus, [NotNull] TEvent eventData) + where TEvent : class + { + Check.NotNull(eventBus, nameof(eventBus)); + + AsyncHelper.RunSync(() => eventBus.PublishAsync(eventData)); + } + + /// + /// Triggers an event. + /// + /// Event bus instance + /// Event type + /// Related data for the event + public static void Publish([NotNull] this IEventBus eventBus, [NotNull] Type eventType, [NotNull] object eventData) + { + Check.NotNull(eventBus, nameof(eventBus)); + + AsyncHelper.RunSync(() => eventBus.PublishAsync(eventType, eventData)); + } + } +} diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs index 4526c1f3b4..1d93c05580 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs @@ -6,7 +6,7 @@ namespace Volo.Abp.EventBus public interface IEventBus { /// - /// Triggers an event asynchronously. + /// Triggers an event. /// /// Event type /// Related data for the event @@ -15,7 +15,7 @@ namespace Volo.Abp.EventBus where TEvent : class; /// - /// Triggers an event asynchronously. + /// Triggers an event. /// /// Event type /// Related data for the event diff --git a/samples/RabbitMqEventBus/App1/App1.csproj b/samples/RabbitMqEventBus/App1/App1.csproj new file mode 100644 index 0000000000..1d59d978ec --- /dev/null +++ b/samples/RabbitMqEventBus/App1/App1.csproj @@ -0,0 +1,13 @@ + + + + Exe + netcoreapp2.1 + + + + + + + + diff --git a/samples/RabbitMqEventBus/App1/App1MessagingService.cs b/samples/RabbitMqEventBus/App1/App1MessagingService.cs new file mode 100644 index 0000000000..718a0b76de --- /dev/null +++ b/samples/RabbitMqEventBus/App1/App1MessagingService.cs @@ -0,0 +1,40 @@ +using System; +using SharedModule; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus; +using Volo.Abp.EventBus.Distributed; + +namespace App2 +{ + public class App1MessagingService : ITransientDependency + { + private readonly IDistributedEventBus _distributedEventBus; + + public App1MessagingService(IDistributedEventBus distributedEventBus) + { + _distributedEventBus = distributedEventBus; + } + + public void Run() + { + Console.WriteLine("Press ENTER (without writing a message) to stop application..."); + Console.WriteLine(); + + string message; + do + { + message = Console.ReadLine(); + + if (!message.IsNullOrEmpty()) + { + _distributedEventBus.Publish(new TextEventData { TextMessage = message }); + } + else + { + _distributedEventBus.Publish(new TextEventData { TextMessage = "App1 is exiting. Bye bye...!" }); + } + + } while (!message.IsNullOrEmpty()); + } + } +} \ No newline at end of file diff --git a/samples/RabbitMqEventBus/App1/App1Module.cs b/samples/RabbitMqEventBus/App1/App1Module.cs new file mode 100644 index 0000000000..6eb1280dab --- /dev/null +++ b/samples/RabbitMqEventBus/App1/App1Module.cs @@ -0,0 +1,20 @@ +using Volo.Abp.EventBus.Distributed.RabbitMq; +using Volo.Abp.Modularity; + +namespace App2 +{ + [DependsOn( + typeof(AbpEventBusRabbitMqModule) + )] + public class App1Module : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.ClientName = "TestApp1"; + options.ExchangeName = "TestMessages"; + }); + } + } +} \ No newline at end of file diff --git a/samples/RabbitMqEventBus/App1/App1TextEventHandler.cs b/samples/RabbitMqEventBus/App1/App1TextEventHandler.cs new file mode 100644 index 0000000000..5ee9d2f406 --- /dev/null +++ b/samples/RabbitMqEventBus/App1/App1TextEventHandler.cs @@ -0,0 +1,34 @@ +using System; +using System.Threading.Tasks; +using SharedModule; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; + +namespace App2 +{ + public class App1TextEventHandler : IDistributedEventHandler, ITransientDependency + { + private readonly IDistributedEventBus _distributedEventBus; + + public App1TextEventHandler(IDistributedEventBus distributedEventBus) + { + _distributedEventBus = distributedEventBus; + } + + public Task HandleEventAsync(TextEventData eventData) + { + Console.WriteLine("************************ INCOMING MESSAGE ****************************"); + Console.WriteLine(eventData.TextMessage); + Console.WriteLine("**********************************************************************"); + + _distributedEventBus.PublishAsync( + new TextReceivedEventData + { + ReceivedText = eventData.TextMessage + } + ); + + return Task.CompletedTask; + } + } +} diff --git a/samples/RabbitMqEventBus/App1/App1TextReceivedEventHandler.cs b/samples/RabbitMqEventBus/App1/App1TextReceivedEventHandler.cs new file mode 100644 index 0000000000..6fe1b45eaa --- /dev/null +++ b/samples/RabbitMqEventBus/App1/App1TextReceivedEventHandler.cs @@ -0,0 +1,18 @@ +using System; +using System.Threading.Tasks; +using SharedModule; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; + +namespace App2 +{ + public class App1TextReceivedEventHandler : IDistributedEventHandler, ITransientDependency + { + public Task HandleEventAsync(TextReceivedEventData eventData) + { + Console.WriteLine("--------> App2 has received the message: " + eventData.ReceivedText.TruncateWithPostfix(32)); + + return Task.CompletedTask; + } + } +} diff --git a/samples/RabbitMqEventBus/App1/Program.cs b/samples/RabbitMqEventBus/App1/Program.cs new file mode 100644 index 0000000000..38583283c2 --- /dev/null +++ b/samples/RabbitMqEventBus/App1/Program.cs @@ -0,0 +1,24 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; + +namespace App2 +{ + internal class Program + { + private static void Main(string[] args) + { + using (var application = AbpApplicationFactory.Create()) + { + application.Initialize(); + + var messagingService = application + .ServiceProvider + .GetRequiredService(); + + messagingService.Run(); + + application.Shutdown(); + } + } + } +} diff --git a/samples/RabbitMqEventBus/App2/App2.csproj b/samples/RabbitMqEventBus/App2/App2.csproj new file mode 100644 index 0000000000..1d59d978ec --- /dev/null +++ b/samples/RabbitMqEventBus/App2/App2.csproj @@ -0,0 +1,13 @@ + + + + Exe + netcoreapp2.1 + + + + + + + + diff --git a/samples/RabbitMqEventBus/App2/App2MessagingService.cs b/samples/RabbitMqEventBus/App2/App2MessagingService.cs new file mode 100644 index 0000000000..03ee9fe071 --- /dev/null +++ b/samples/RabbitMqEventBus/App2/App2MessagingService.cs @@ -0,0 +1,40 @@ +using System; +using SharedModule; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus; +using Volo.Abp.EventBus.Distributed; + +namespace App2 +{ + public class App2MessagingService : ITransientDependency + { + private readonly IDistributedEventBus _distributedEventBus; + + public App2MessagingService(IDistributedEventBus distributedEventBus) + { + _distributedEventBus = distributedEventBus; + } + + public void Run() + { + Console.WriteLine("Press ENTER (without writing a message) to stop application..."); + Console.WriteLine(); + + string message; + do + { + message = Console.ReadLine(); + + if (!message.IsNullOrEmpty()) + { + _distributedEventBus.Publish(new TextEventData { TextMessage = message }); + } + else + { + _distributedEventBus.Publish(new TextEventData { TextMessage = "App2 is exiting. Bye bye...!" }); + } + + } while (!message.IsNullOrEmpty()); + } + } +} \ No newline at end of file diff --git a/samples/RabbitMqEventBus/App2/App2Module.cs b/samples/RabbitMqEventBus/App2/App2Module.cs new file mode 100644 index 0000000000..c2a4959f2c --- /dev/null +++ b/samples/RabbitMqEventBus/App2/App2Module.cs @@ -0,0 +1,20 @@ +using Volo.Abp.EventBus.Distributed.RabbitMq; +using Volo.Abp.Modularity; + +namespace App2 +{ + [DependsOn( + typeof(AbpEventBusRabbitMqModule) + )] + public class App2Module : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.ClientName = "TestApp2"; + options.ExchangeName = "TestMessages"; + }); + } + } +} \ No newline at end of file diff --git a/samples/RabbitMqEventBus/App2/App2TextEventHandler.cs b/samples/RabbitMqEventBus/App2/App2TextEventHandler.cs new file mode 100644 index 0000000000..16eeaf945d --- /dev/null +++ b/samples/RabbitMqEventBus/App2/App2TextEventHandler.cs @@ -0,0 +1,34 @@ +using System; +using System.Threading.Tasks; +using SharedModule; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; + +namespace App2 +{ + public class App2TextEventHandler : IDistributedEventHandler, ITransientDependency + { + private readonly IDistributedEventBus _distributedEventBus; + + public App2TextEventHandler(IDistributedEventBus distributedEventBus) + { + _distributedEventBus = distributedEventBus; + } + + public Task HandleEventAsync(TextEventData eventData) + { + Console.WriteLine("************************ INCOMING MESSAGE ****************************"); + Console.WriteLine(eventData.TextMessage); + Console.WriteLine("**********************************************************************"); + + _distributedEventBus.PublishAsync( + new TextReceivedEventData + { + ReceivedText = eventData.TextMessage + } + ); + + return Task.CompletedTask; + } + } +} diff --git a/samples/RabbitMqEventBus/App2/App2TextReceivedEventHandler.cs b/samples/RabbitMqEventBus/App2/App2TextReceivedEventHandler.cs new file mode 100644 index 0000000000..308cedf7d8 --- /dev/null +++ b/samples/RabbitMqEventBus/App2/App2TextReceivedEventHandler.cs @@ -0,0 +1,18 @@ +using System; +using System.Threading.Tasks; +using SharedModule; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; + +namespace App2 +{ + public class App2TextReceivedEventHandler : IDistributedEventHandler, ITransientDependency + { + public Task HandleEventAsync(TextReceivedEventData eventData) + { + Console.WriteLine("--------> App1 has received the message: " + eventData.ReceivedText.TruncateWithPostfix(32)); + + return Task.CompletedTask; + } + } +} diff --git a/samples/RabbitMqEventBus/App2/Program.cs b/samples/RabbitMqEventBus/App2/Program.cs new file mode 100644 index 0000000000..c13d9a1dee --- /dev/null +++ b/samples/RabbitMqEventBus/App2/Program.cs @@ -0,0 +1,24 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; + +namespace App2 +{ + internal class Program + { + private static void Main(string[] args) + { + using (var application = AbpApplicationFactory.Create()) + { + application.Initialize(); + + var messagingService = application + .ServiceProvider + .GetRequiredService(); + + messagingService.Run(); + + application.Shutdown(); + } + } + } +} diff --git a/samples/RabbitMqEventBus/RabbitMqEventBus.sln b/samples/RabbitMqEventBus/RabbitMqEventBus.sln new file mode 100644 index 0000000000..fae44b73bb --- /dev/null +++ b/samples/RabbitMqEventBus/RabbitMqEventBus.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28010.2016 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "App1", "App1\App1.csproj", "{2C93AFEF-1677-4591-8245-35D5E0F99B03}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharedModule", "SharedModule\SharedModule.csproj", "{D6F948FB-699B-45D7-8B79-F9D43B627B68}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "App2", "App2\App2.csproj", "{A5FE0CEF-C472-47DD-9F2B-DFFFA33B8523}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2C93AFEF-1677-4591-8245-35D5E0F99B03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2C93AFEF-1677-4591-8245-35D5E0F99B03}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2C93AFEF-1677-4591-8245-35D5E0F99B03}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2C93AFEF-1677-4591-8245-35D5E0F99B03}.Release|Any CPU.Build.0 = Release|Any CPU + {D6F948FB-699B-45D7-8B79-F9D43B627B68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D6F948FB-699B-45D7-8B79-F9D43B627B68}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D6F948FB-699B-45D7-8B79-F9D43B627B68}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D6F948FB-699B-45D7-8B79-F9D43B627B68}.Release|Any CPU.Build.0 = Release|Any CPU + {A5FE0CEF-C472-47DD-9F2B-DFFFA33B8523}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A5FE0CEF-C472-47DD-9F2B-DFFFA33B8523}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A5FE0CEF-C472-47DD-9F2B-DFFFA33B8523}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A5FE0CEF-C472-47DD-9F2B-DFFFA33B8523}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {44A91B65-F109-4FD0-B6C0-63C052A5BEEB} + EndGlobalSection +EndGlobal diff --git a/samples/RabbitMqEventBus/SharedModule/SharedModule.csproj b/samples/RabbitMqEventBus/SharedModule/SharedModule.csproj new file mode 100644 index 0000000000..dbdcea46b6 --- /dev/null +++ b/samples/RabbitMqEventBus/SharedModule/SharedModule.csproj @@ -0,0 +1,7 @@ + + + + netstandard2.0 + + + diff --git a/samples/RabbitMqEventBus/SharedModule/TextEventData.cs b/samples/RabbitMqEventBus/SharedModule/TextEventData.cs new file mode 100644 index 0000000000..4b88a9e7bd --- /dev/null +++ b/samples/RabbitMqEventBus/SharedModule/TextEventData.cs @@ -0,0 +1,7 @@ +namespace SharedModule +{ + public class TextEventData + { + public string TextMessage { get; set; } + } +} diff --git a/samples/RabbitMqEventBus/SharedModule/TextReceivedEventData.cs b/samples/RabbitMqEventBus/SharedModule/TextReceivedEventData.cs new file mode 100644 index 0000000000..825fb19aac --- /dev/null +++ b/samples/RabbitMqEventBus/SharedModule/TextReceivedEventData.cs @@ -0,0 +1,7 @@ +namespace SharedModule +{ + public class TextReceivedEventData + { + public string ReceivedText { get; set; } + } +} From 1c2751510694e5350260aacc9a619c8dd4277d43 Mon Sep 17 00:00:00 2001 From: Nokecy Date: Tue, 18 Dec 2018 11:21:21 +0800 Subject: [PATCH 034/368] Add Get methods to find and modify a permission or group --- .../Permissions/IPermissionDefinitionContext.cs | 1 + .../Permissions/PermissionDefinitionContext.cs | 13 +++++++++++++ .../Volo/Abp/Authorization/Authorization_Tests.cs | 13 +++++++++++-- ...AuthorizationTestPermissionDefinitionProvider.cs | 7 ++++++- 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionDefinitionContext.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionDefinitionContext.cs index 11888b47c6..00680e0398 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionDefinitionContext.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionDefinitionContext.cs @@ -6,6 +6,7 @@ namespace Volo.Abp.Authorization.Permissions public interface IPermissionDefinitionContext { //TODO: Add Get methods to find and modify a permission or group. + PermissionGroupDefinition GetGroupOrNull(string name); PermissionGroupDefinition AddGroup([NotNull] string name, ILocalizableString displayName = null); } diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionContext.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionContext.cs index 68ce925c0d..59be1c2ad5 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionContext.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinitionContext.cs @@ -23,5 +23,18 @@ namespace Volo.Abp.Authorization.Permissions return Groups[name] = new PermissionGroupDefinition(name, displayName); } + + public virtual PermissionGroupDefinition GetGroupOrNull(string name) + { + Check.NotNull(name, nameof(name)); + + if (!Groups.ContainsKey(name)) + { + return null; + } + + return Groups[name]; + } + } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs index dbd42f17ca..7c04a9cf1b 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs @@ -1,5 +1,6 @@ -using System.Threading.Tasks; -using Shouldly; +using Shouldly; +using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.Authorization.TestServices; using Xunit; @@ -8,10 +9,12 @@ namespace Volo.Abp.Authorization public class Authorization_Tests : AuthorizationTestBase { private readonly IMyAuthorizedService1 _myAuthorizedService1; + private readonly IPermissionDefinitionManager _permissionDefinitionManager; public Authorization_Tests() { _myAuthorizedService1 = GetRequiredService(); + _permissionDefinitionManager = GetRequiredService(); } [Fact] @@ -43,5 +46,11 @@ namespace Volo.Abp.Authorization { (await _myAuthorizedService1.AnonymousAsync()).ShouldBe(42); } + + [Fact] + public void Should_Permission_Definition_GetGroup() + { + _permissionDefinitionManager.GetGroups().Count.ShouldBe(2); + } } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/AuthorizationTestPermissionDefinitionProvider.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/AuthorizationTestPermissionDefinitionProvider.cs index 5775c5466c..fdfd77b986 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/AuthorizationTestPermissionDefinitionProvider.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/AuthorizationTestPermissionDefinitionProvider.cs @@ -6,7 +6,12 @@ namespace Volo.Abp.Authorization.TestServices { public override void Define(IPermissionDefinitionContext context) { - var group = context.AddGroup("TestGroup"); + PermissionGroupDefinition getGroup = context.GetGroupOrNull("TestGetGroup"); + if (getGroup == null) + { + getGroup = context.AddGroup("TestGetGroup"); + } + PermissionGroupDefinition group = context.AddGroup("TestGroup"); group.AddPermission("MyAuthorizedService1"); } } From c44b2aa64ec640ae9b4b89139be500fe9b11ec69 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 18 Dec 2018 09:38:56 +0300 Subject: [PATCH 035/368] abp border tag helper docs --- .../Pages/Components/Borders.cshtml | 223 +++++++++++++++--- 1 file changed, 193 insertions(+), 30 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Borders.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Borders.cshtml index 9b683f8924..76c14746af 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Borders.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Borders.cshtml @@ -10,43 +10,206 @@ } +@section scripts { + + @* + *@ + +} + + + + + + +

Borders

Based on Bootstrap Border.

-

# Borders Examples

+

Border

+ +
Additive
-
- aaa - bbb - ccc - ddd - eee - fff - ggg - hhh - iii - jjj - kkk - lll - mmm +
+ + + + +
-
-<span abp-border="Default">aaa</span>
-<span abp-border="Top">bbb</span>
-<span abp-border="Right">ccc</span>
-<span abp-border="Left">ddd</span>
-<span abp-border="Bottom">eee</span>
-<span abp-border="Top_0">fff</span>
-<span abp-border="Right_0">ggg</span>
-<span abp-border="Left_0">hhh</span>
-<span abp-border="Bottom_0">iii</span>
-<span abp-border="Top_Primary">jjj</span>
-<span abp-border="Warning_0">kkk</span>
-<span abp-border="Bottom_Primary_0">lll</span>
-<span abp-border="Left_Danger">mmm</span>
-
+ + +

+<span abp-border="Default"></span>
+<span abp-border="Top"></span>
+<span abp-border="Right"></span>
+<span abp-border="Bottom"></span>
+<span abp-border="Left"></span>
+
+
+ +

+<span class="border"></span>
+<span class="border-top"></span>
+<span class="border-right"></span>
+<span class="border-bottom"></span>
+<span class="border-left"></span>
+
+
+
+ +
Subtractive
+ +
+
+ + + + + +
+
+ + +

+<span abp-border="_0"></span>
+<span abp-border="Top_0"></span>
+<span abp-border="Right_0"></span>
+<span abp-border="Bottom_0"></span>
+<span abp-border="Left_0"></span>
+
+
+ +

+<span class="borde-0"></span>
+<span class="border-top-0"></span>
+<span class="border-right-0"></span>
+<span class="border-bottom-0"></span>
+<span class="border-left-0"></span>
+
+
+
+
+
+ +

Border color

+ +
+
+ + + + + + + + +
+ + + + + + + + +
+
+ + +

+<span abp-border="Primary"></span>
+<span abp-border="Secondary"></span>
+<span abp-border="Success"></span>
+<span abp-border="Danger"></span>
+<span abp-border="Info"></span>
+<span abp-border="Light"></span>
+<span abp-border="Dark"></span>
+<span abp-border="White"></span>
+<br/>
+<span abp-border="Left_Primary"></span>
+<span abp-border="Top_Secondary"></span>
+<span abp-border="Right_Success"></span>
+<span abp-border="Bottom_Danger"></span>
+<span abp-border="bottom_Warning"></span>
+<span abp-border="Left_Info"></span>
+<span abp-border="Top_Light"></span>
+<span abp-border="Right_Dark"></span>
+
+
+ +

+<span class="border border-primary"></span>
+<span class="border border-secondary"></span>
+<span class="border border-success"></span>
+<span class="border border-danger"></span>
+<span class="border border-warning"></span>
+<span class="border border-info"></span>
+<span class="border border-light"></span>
+<span class="border border-dark"></span>
+<span class="border border-white"></span>
+<br/>
+<span class="border border-left border-primary"></span>
+<span class="border border-top border-secondary"></span>
+<span class="border border-right border-success"></span>
+<span class="border border-bottom border-danger"></span>
+<span class="border border-bottom border-warning"></span>
+<span class="border border-left border-info"></span>
+<span class="border border-top border-light"></span>
+<span class="border border-right border-dark"></span>
+
+
+
+
+
+ +

Border-radius

+ +
+
+ + + + + + +
+
+ + +

+<span abp-border="Primary" abp-rounded="Default"></span>
+<span abp-border="Primary" abp-rounded="_0"></span>
+<span abp-border="Primary" abp-rounded="Top"></span>
+<span abp-border="Primary" abp-rounded="Left"></span>
+<span abp-border="Primary" abp-rounded="Bottom"></span>
+<span abp-border="Primary" abp-rounded="Right"></span>
+
+
+ +

+<span class="border border-primary rounded"></span>
+<span class="border border-primary rounded-0"></span>
+<span class="border border-primary rounded-top"></span>
+<span class="border border-primary rounded-left"></span>
+<span class="border border-primary rounded-bottom"></span>
+<span class="border border-primary rounded-right"></span>
+
+
+
+
+
\ No newline at end of file From 40fa063c69635fae6a4650bb5d565951b451cf99 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Tue, 18 Dec 2018 10:16:29 +0300 Subject: [PATCH 036/368] Finalized RabbitMqEventBus sample. --- .../Volo.Abp.EventBus.RabbitMQ.csproj | 4 ++-- .../RabbitMq/RabbitMqDistributedEventBus.cs | 10 ++++---- .../Abp/RabbitMQ/RabbitMqMessageConsumer.cs | 6 ++++- samples/RabbitMqEventBus/App1/App1.csproj | 1 + .../App1/App1MessagingService.cs | 14 +++++++---- samples/RabbitMqEventBus/App1/App1Module.cs | 8 ++++--- .../App1/App1TextEventHandler.cs | 16 ++++++------- .../App1/App1TextReceivedEventHandler.cs | 9 +++++--- samples/RabbitMqEventBus/App1/Program.cs | 9 ++++++-- samples/RabbitMqEventBus/App2/App2.csproj | 1 + .../App2/App2MessagingService.cs | 12 ++++++---- samples/RabbitMqEventBus/App2/App2Module.cs | 6 +++-- .../App2/App2TextEventHandler.cs | 14 +++++------ .../App2/App2TextReceivedEventHandler.cs | 7 ++++-- samples/RabbitMqEventBus/App2/Program.cs | 5 +++- .../SharedModule/App1TextReceivedEventData.cs | 23 +++++++++++++++++++ .../SharedModule/App1ToApp2TextEventData.cs | 23 +++++++++++++++++++ .../SharedModule/App2TextReceivedEventData.cs | 23 +++++++++++++++++++ .../SharedModule/App2ToApp1TextEventData.cs | 23 +++++++++++++++++++ .../SharedModule/SharedModule.csproj | 4 ++++ .../SharedModule/TextEventData.cs | 7 ------ .../SharedModule/TextReceivedEventData.cs | 7 ------ 22 files changed, 171 insertions(+), 61 deletions(-) create mode 100644 samples/RabbitMqEventBus/SharedModule/App1TextReceivedEventData.cs create mode 100644 samples/RabbitMqEventBus/SharedModule/App1ToApp2TextEventData.cs create mode 100644 samples/RabbitMqEventBus/SharedModule/App2TextReceivedEventData.cs create mode 100644 samples/RabbitMqEventBus/SharedModule/App2ToApp1TextEventData.cs delete mode 100644 samples/RabbitMqEventBus/SharedModule/TextEventData.cs delete mode 100644 samples/RabbitMqEventBus/SharedModule/TextReceivedEventData.cs diff --git a/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo.Abp.EventBus.RabbitMQ.csproj b/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo.Abp.EventBus.RabbitMQ.csproj index 04d57417e1..c9bab15898 100644 --- a/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo.Abp.EventBus.RabbitMQ.csproj +++ b/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo.Abp.EventBus.RabbitMQ.csproj @@ -4,8 +4,8 @@ netstandard2.0 - Volo.Abp.EventBus.Distributed.RabbitMQ - Volo.Abp.EventBus.Distributed.RabbitMQ + Volo.Abp.EventBus.RabbitMQ + Volo.Abp.EventBus.RabbitMQ $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; false false diff --git a/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs index 4de808defa..223ea4225f 100644 --- a/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs +++ b/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs @@ -38,7 +38,7 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq IHybridServiceScopeFactory serviceScopeFactory, IOptions distributedEventBusOptions, IRabbitMqMessageConsumerFactory messageConsumerFactory) - : base(serviceScopeFactory) + : base(serviceScopeFactory) { ConnectionPool = connectionPool; Serializer = serializer; @@ -52,7 +52,8 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq Consumer = MessageConsumerFactory.Create( new ExchangeDeclareConfiguration( RabbitMqDistributedEventBusOptions.ExchangeName, - type: "direct" + type: "direct", + durable: true ), new QueueDeclareConfiguration( RabbitMqDistributedEventBusOptions.ClientName, @@ -96,7 +97,6 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq if (handlerFactories.Count == 1) //TODO: Multi-threading! { var eventName = EventNameAttribute.GetNameOrDefault(eventType); - Consumer.BindAsync(eventName); } @@ -166,8 +166,8 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq { channel.ExchangeDeclare( RabbitMqDistributedEventBusOptions.ExchangeName, - "direct" - //TODO: Other properties like durable? + "direct", + durable: true ); var properties = channel.CreateBasicProperties(); diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs index a41054a45f..a56fc2491a 100644 --- a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs +++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs @@ -145,7 +145,10 @@ namespace Volo.Abp.RabbitMQ channel.ExchangeDeclare( exchange: Exchange.ExchangeName, - type: Exchange.Type + type: Exchange.Type, + durable: Exchange.Durable, + autoDelete: Exchange.AutoDelete, + arguments: Exchange.Arguments ); channel.QueueDeclare( @@ -212,6 +215,7 @@ namespace Volo.Abp.RabbitMQ public virtual void Dispose() { + Timer.Stop(); DisposeChannel(); } diff --git a/samples/RabbitMqEventBus/App1/App1.csproj b/samples/RabbitMqEventBus/App1/App1.csproj index 1d59d978ec..7bc8ca1c21 100644 --- a/samples/RabbitMqEventBus/App1/App1.csproj +++ b/samples/RabbitMqEventBus/App1/App1.csproj @@ -6,6 +6,7 @@ + diff --git a/samples/RabbitMqEventBus/App1/App1MessagingService.cs b/samples/RabbitMqEventBus/App1/App1MessagingService.cs index 718a0b76de..89f2bab336 100644 --- a/samples/RabbitMqEventBus/App1/App1MessagingService.cs +++ b/samples/RabbitMqEventBus/App1/App1MessagingService.cs @@ -4,7 +4,7 @@ using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus; using Volo.Abp.EventBus.Distributed; -namespace App2 +namespace App1 { public class App1MessagingService : ITransientDependency { @@ -17,21 +17,25 @@ namespace App2 public void Run() { - Console.WriteLine("Press ENTER (without writing a message) to stop application..."); - Console.WriteLine(); + Console.WriteLine("*** Started the APPLICATION 1 ***"); + Console.WriteLine("Write a message and press ENTER to send to the App2."); + Console.WriteLine("Press ENTER (without writing a message) to stop the application."); string message; do { + Console.WriteLine(); + Console.WriteLine("Send message to App2: "); + message = Console.ReadLine(); if (!message.IsNullOrEmpty()) { - _distributedEventBus.Publish(new TextEventData { TextMessage = message }); + _distributedEventBus.Publish(new App1ToApp2TextEventData(message)); } else { - _distributedEventBus.Publish(new TextEventData { TextMessage = "App1 is exiting. Bye bye...!" }); + _distributedEventBus.Publish(new App1ToApp2TextEventData("App1 is exiting. Bye bye...!")); } } while (!message.IsNullOrEmpty()); diff --git a/samples/RabbitMqEventBus/App1/App1Module.cs b/samples/RabbitMqEventBus/App1/App1Module.cs index 6eb1280dab..6f608da57e 100644 --- a/samples/RabbitMqEventBus/App1/App1Module.cs +++ b/samples/RabbitMqEventBus/App1/App1Module.cs @@ -1,10 +1,12 @@ -using Volo.Abp.EventBus.Distributed.RabbitMq; +using Volo.Abp.Autofac; +using Volo.Abp.EventBus.Distributed.RabbitMq; using Volo.Abp.Modularity; -namespace App2 +namespace App1 { [DependsOn( - typeof(AbpEventBusRabbitMqModule) + typeof(AbpEventBusRabbitMqModule), + typeof(AbpAutofacModule) )] public class App1Module : AbpModule { diff --git a/samples/RabbitMqEventBus/App1/App1TextEventHandler.cs b/samples/RabbitMqEventBus/App1/App1TextEventHandler.cs index 5ee9d2f406..48add1d986 100644 --- a/samples/RabbitMqEventBus/App1/App1TextEventHandler.cs +++ b/samples/RabbitMqEventBus/App1/App1TextEventHandler.cs @@ -4,9 +4,12 @@ using SharedModule; using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus.Distributed; -namespace App2 +namespace App1 { - public class App1TextEventHandler : IDistributedEventHandler, ITransientDependency + /// + /// Used to listen messages sent to App2 by App1. + /// + public class App1TextEventHandler : IDistributedEventHandler, ITransientDependency { private readonly IDistributedEventBus _distributedEventBus; @@ -15,18 +18,13 @@ namespace App2 _distributedEventBus = distributedEventBus; } - public Task HandleEventAsync(TextEventData eventData) + public Task HandleEventAsync(App2ToApp1TextEventData eventData) { Console.WriteLine("************************ INCOMING MESSAGE ****************************"); Console.WriteLine(eventData.TextMessage); Console.WriteLine("**********************************************************************"); - _distributedEventBus.PublishAsync( - new TextReceivedEventData - { - ReceivedText = eventData.TextMessage - } - ); + _distributedEventBus.PublishAsync(new App1TextReceivedEventData(eventData.TextMessage)); return Task.CompletedTask; } diff --git a/samples/RabbitMqEventBus/App1/App1TextReceivedEventHandler.cs b/samples/RabbitMqEventBus/App1/App1TextReceivedEventHandler.cs index 6fe1b45eaa..2e0d22df5a 100644 --- a/samples/RabbitMqEventBus/App1/App1TextReceivedEventHandler.cs +++ b/samples/RabbitMqEventBus/App1/App1TextReceivedEventHandler.cs @@ -4,11 +4,14 @@ using SharedModule; using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus.Distributed; -namespace App2 +namespace App1 { - public class App1TextReceivedEventHandler : IDistributedEventHandler, ITransientDependency + /// + /// Used to know when App2 has received a message sent by App1. + /// + public class App1TextReceivedEventHandler : IDistributedEventHandler, ITransientDependency { - public Task HandleEventAsync(TextReceivedEventData eventData) + public Task HandleEventAsync(App2TextReceivedEventData eventData) { Console.WriteLine("--------> App2 has received the message: " + eventData.ReceivedText.TruncateWithPostfix(32)); diff --git a/samples/RabbitMqEventBus/App1/Program.cs b/samples/RabbitMqEventBus/App1/Program.cs index 38583283c2..aab454523a 100644 --- a/samples/RabbitMqEventBus/App1/Program.cs +++ b/samples/RabbitMqEventBus/App1/Program.cs @@ -1,16 +1,21 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp; -namespace App2 +namespace App1 { internal class Program { private static void Main(string[] args) { - using (var application = AbpApplicationFactory.Create()) + using (var application = AbpApplicationFactory.Create(options => + { + options.UseAutofac(); + })) { application.Initialize(); + var x = application.ServiceProvider.GetRequiredService(); + var messagingService = application .ServiceProvider .GetRequiredService(); diff --git a/samples/RabbitMqEventBus/App2/App2.csproj b/samples/RabbitMqEventBus/App2/App2.csproj index 1d59d978ec..7bc8ca1c21 100644 --- a/samples/RabbitMqEventBus/App2/App2.csproj +++ b/samples/RabbitMqEventBus/App2/App2.csproj @@ -6,6 +6,7 @@ + diff --git a/samples/RabbitMqEventBus/App2/App2MessagingService.cs b/samples/RabbitMqEventBus/App2/App2MessagingService.cs index 03ee9fe071..22157342f2 100644 --- a/samples/RabbitMqEventBus/App2/App2MessagingService.cs +++ b/samples/RabbitMqEventBus/App2/App2MessagingService.cs @@ -17,21 +17,25 @@ namespace App2 public void Run() { - Console.WriteLine("Press ENTER (without writing a message) to stop application..."); - Console.WriteLine(); + Console.WriteLine("*** Started the APPLICATION 2 ***"); + Console.WriteLine("Write a message and press ENTER to send to the App1."); + Console.WriteLine("Press ENTER (without writing a message) to stop the application..."); string message; do { + Console.WriteLine(); + Console.WriteLine("Send message to App1: "); + message = Console.ReadLine(); if (!message.IsNullOrEmpty()) { - _distributedEventBus.Publish(new TextEventData { TextMessage = message }); + _distributedEventBus.Publish(new App2ToApp1TextEventData(message)); } else { - _distributedEventBus.Publish(new TextEventData { TextMessage = "App2 is exiting. Bye bye...!" }); + _distributedEventBus.Publish(new App2ToApp1TextEventData("App2 is exiting. Bye bye...!")); } } while (!message.IsNullOrEmpty()); diff --git a/samples/RabbitMqEventBus/App2/App2Module.cs b/samples/RabbitMqEventBus/App2/App2Module.cs index c2a4959f2c..9f81aa2d4c 100644 --- a/samples/RabbitMqEventBus/App2/App2Module.cs +++ b/samples/RabbitMqEventBus/App2/App2Module.cs @@ -1,10 +1,12 @@ -using Volo.Abp.EventBus.Distributed.RabbitMq; +using Volo.Abp.Autofac; +using Volo.Abp.EventBus.Distributed.RabbitMq; using Volo.Abp.Modularity; namespace App2 { [DependsOn( - typeof(AbpEventBusRabbitMqModule) + typeof(AbpEventBusRabbitMqModule), + typeof(AbpAutofacModule) )] public class App2Module : AbpModule { diff --git a/samples/RabbitMqEventBus/App2/App2TextEventHandler.cs b/samples/RabbitMqEventBus/App2/App2TextEventHandler.cs index 16eeaf945d..ac26dd187b 100644 --- a/samples/RabbitMqEventBus/App2/App2TextEventHandler.cs +++ b/samples/RabbitMqEventBus/App2/App2TextEventHandler.cs @@ -6,7 +6,10 @@ using Volo.Abp.EventBus.Distributed; namespace App2 { - public class App2TextEventHandler : IDistributedEventHandler, ITransientDependency + /// + /// Used to listen messages sent to App2 by App1. + /// + public class App2TextEventHandler : IDistributedEventHandler, ITransientDependency { private readonly IDistributedEventBus _distributedEventBus; @@ -15,18 +18,13 @@ namespace App2 _distributedEventBus = distributedEventBus; } - public Task HandleEventAsync(TextEventData eventData) + public Task HandleEventAsync(App1ToApp2TextEventData eventData) { Console.WriteLine("************************ INCOMING MESSAGE ****************************"); Console.WriteLine(eventData.TextMessage); Console.WriteLine("**********************************************************************"); - _distributedEventBus.PublishAsync( - new TextReceivedEventData - { - ReceivedText = eventData.TextMessage - } - ); + _distributedEventBus.PublishAsync(new App2TextReceivedEventData(eventData.TextMessage)); return Task.CompletedTask; } diff --git a/samples/RabbitMqEventBus/App2/App2TextReceivedEventHandler.cs b/samples/RabbitMqEventBus/App2/App2TextReceivedEventHandler.cs index 308cedf7d8..fde68aa615 100644 --- a/samples/RabbitMqEventBus/App2/App2TextReceivedEventHandler.cs +++ b/samples/RabbitMqEventBus/App2/App2TextReceivedEventHandler.cs @@ -6,9 +6,12 @@ using Volo.Abp.EventBus.Distributed; namespace App2 { - public class App2TextReceivedEventHandler : IDistributedEventHandler, ITransientDependency + /// + /// Used to know when App1 has received a message sent by App2. + /// + public class App2TextReceivedEventHandler : IDistributedEventHandler, ITransientDependency { - public Task HandleEventAsync(TextReceivedEventData eventData) + public Task HandleEventAsync(App1TextReceivedEventData eventData) { Console.WriteLine("--------> App1 has received the message: " + eventData.ReceivedText.TruncateWithPostfix(32)); diff --git a/samples/RabbitMqEventBus/App2/Program.cs b/samples/RabbitMqEventBus/App2/Program.cs index c13d9a1dee..2686c54e8f 100644 --- a/samples/RabbitMqEventBus/App2/Program.cs +++ b/samples/RabbitMqEventBus/App2/Program.cs @@ -7,7 +7,10 @@ namespace App2 { private static void Main(string[] args) { - using (var application = AbpApplicationFactory.Create()) + using (var application = AbpApplicationFactory.Create(options => + { + options.UseAutofac(); + })) { application.Initialize(); diff --git a/samples/RabbitMqEventBus/SharedModule/App1TextReceivedEventData.cs b/samples/RabbitMqEventBus/SharedModule/App1TextReceivedEventData.cs new file mode 100644 index 0000000000..0e01f74b84 --- /dev/null +++ b/samples/RabbitMqEventBus/SharedModule/App1TextReceivedEventData.cs @@ -0,0 +1,23 @@ +using Volo.Abp.EventBus; + +namespace SharedModule +{ + /// + /// Used to indicate that App2 has received a text message. + /// + [EventName("Test.App1TextReceived")] //Optional event name + public class App1TextReceivedEventData + { + public string ReceivedText { get; set; } + + public App1TextReceivedEventData() + { + + } + + public App1TextReceivedEventData(string receivedText) + { + ReceivedText = receivedText; + } + } +} diff --git a/samples/RabbitMqEventBus/SharedModule/App1ToApp2TextEventData.cs b/samples/RabbitMqEventBus/SharedModule/App1ToApp2TextEventData.cs new file mode 100644 index 0000000000..56d2c31186 --- /dev/null +++ b/samples/RabbitMqEventBus/SharedModule/App1ToApp2TextEventData.cs @@ -0,0 +1,23 @@ +using Volo.Abp.EventBus; + +namespace SharedModule +{ + /// + /// Used to send a text message from App1 to App2. + /// + [EventName("Test.App1ToApp2Text")] //Optional event name + public class App1ToApp2TextEventData + { + public string TextMessage { get; set; } + + public App1ToApp2TextEventData() + { + + } + + public App1ToApp2TextEventData(string textMessage) + { + TextMessage = textMessage; + } + } +} diff --git a/samples/RabbitMqEventBus/SharedModule/App2TextReceivedEventData.cs b/samples/RabbitMqEventBus/SharedModule/App2TextReceivedEventData.cs new file mode 100644 index 0000000000..c3ac4bf9bb --- /dev/null +++ b/samples/RabbitMqEventBus/SharedModule/App2TextReceivedEventData.cs @@ -0,0 +1,23 @@ +using Volo.Abp.EventBus; + +namespace SharedModule +{ + /// + /// Used to indicate that App2 has received a text message. + /// + [EventName("Test.App2TextReceived")] //Optional event name + public class App2TextReceivedEventData + { + public string ReceivedText { get; set; } + + public App2TextReceivedEventData() + { + + } + + public App2TextReceivedEventData(string receivedText) + { + ReceivedText = receivedText; + } + } +} \ No newline at end of file diff --git a/samples/RabbitMqEventBus/SharedModule/App2ToApp1TextEventData.cs b/samples/RabbitMqEventBus/SharedModule/App2ToApp1TextEventData.cs new file mode 100644 index 0000000000..2943661f7d --- /dev/null +++ b/samples/RabbitMqEventBus/SharedModule/App2ToApp1TextEventData.cs @@ -0,0 +1,23 @@ +using Volo.Abp.EventBus; + +namespace SharedModule +{ + /// + /// Used to send a text message from App2 to App1. + /// + [EventName("Test.App2ToApp1Text")] //Optional event name + public class App2ToApp1TextEventData + { + public string TextMessage { get; set; } + + public App2ToApp1TextEventData() + { + + } + + public App2ToApp1TextEventData(string textMessage) + { + TextMessage = textMessage; + } + } +} \ No newline at end of file diff --git a/samples/RabbitMqEventBus/SharedModule/SharedModule.csproj b/samples/RabbitMqEventBus/SharedModule/SharedModule.csproj index dbdcea46b6..c659ddff0b 100644 --- a/samples/RabbitMqEventBus/SharedModule/SharedModule.csproj +++ b/samples/RabbitMqEventBus/SharedModule/SharedModule.csproj @@ -4,4 +4,8 @@ netstandard2.0 + + + + diff --git a/samples/RabbitMqEventBus/SharedModule/TextEventData.cs b/samples/RabbitMqEventBus/SharedModule/TextEventData.cs deleted file mode 100644 index 4b88a9e7bd..0000000000 --- a/samples/RabbitMqEventBus/SharedModule/TextEventData.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace SharedModule -{ - public class TextEventData - { - public string TextMessage { get; set; } - } -} diff --git a/samples/RabbitMqEventBus/SharedModule/TextReceivedEventData.cs b/samples/RabbitMqEventBus/SharedModule/TextReceivedEventData.cs deleted file mode 100644 index 825fb19aac..0000000000 --- a/samples/RabbitMqEventBus/SharedModule/TextReceivedEventData.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace SharedModule -{ - public class TextReceivedEventData - { - public string ReceivedText { get; set; } - } -} From f5b8b184b682115bd8fc07206cebf632d1771730 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Tue, 18 Dec 2018 10:17:42 +0300 Subject: [PATCH 037/368] Add spaces between messages --- samples/RabbitMqEventBus/App1/App1MessagingService.cs | 1 - samples/RabbitMqEventBus/App1/App1TextEventHandler.cs | 1 + samples/RabbitMqEventBus/App1/App1TextReceivedEventHandler.cs | 3 ++- samples/RabbitMqEventBus/App2/App2MessagingService.cs | 1 - samples/RabbitMqEventBus/App2/App2TextEventHandler.cs | 1 + samples/RabbitMqEventBus/App2/App2TextReceivedEventHandler.cs | 3 ++- 6 files changed, 6 insertions(+), 4 deletions(-) diff --git a/samples/RabbitMqEventBus/App1/App1MessagingService.cs b/samples/RabbitMqEventBus/App1/App1MessagingService.cs index 89f2bab336..b8123d84d4 100644 --- a/samples/RabbitMqEventBus/App1/App1MessagingService.cs +++ b/samples/RabbitMqEventBus/App1/App1MessagingService.cs @@ -25,7 +25,6 @@ namespace App1 do { Console.WriteLine(); - Console.WriteLine("Send message to App2: "); message = Console.ReadLine(); diff --git a/samples/RabbitMqEventBus/App1/App1TextEventHandler.cs b/samples/RabbitMqEventBus/App1/App1TextEventHandler.cs index 48add1d986..046eda56b1 100644 --- a/samples/RabbitMqEventBus/App1/App1TextEventHandler.cs +++ b/samples/RabbitMqEventBus/App1/App1TextEventHandler.cs @@ -23,6 +23,7 @@ namespace App1 Console.WriteLine("************************ INCOMING MESSAGE ****************************"); Console.WriteLine(eventData.TextMessage); Console.WriteLine("**********************************************************************"); + Console.WriteLine(); _distributedEventBus.PublishAsync(new App1TextReceivedEventData(eventData.TextMessage)); diff --git a/samples/RabbitMqEventBus/App1/App1TextReceivedEventHandler.cs b/samples/RabbitMqEventBus/App1/App1TextReceivedEventHandler.cs index 2e0d22df5a..f9d6525e49 100644 --- a/samples/RabbitMqEventBus/App1/App1TextReceivedEventHandler.cs +++ b/samples/RabbitMqEventBus/App1/App1TextReceivedEventHandler.cs @@ -14,7 +14,8 @@ namespace App1 public Task HandleEventAsync(App2TextReceivedEventData eventData) { Console.WriteLine("--------> App2 has received the message: " + eventData.ReceivedText.TruncateWithPostfix(32)); - + Console.WriteLine(); + return Task.CompletedTask; } } diff --git a/samples/RabbitMqEventBus/App2/App2MessagingService.cs b/samples/RabbitMqEventBus/App2/App2MessagingService.cs index 22157342f2..b89e9dd960 100644 --- a/samples/RabbitMqEventBus/App2/App2MessagingService.cs +++ b/samples/RabbitMqEventBus/App2/App2MessagingService.cs @@ -25,7 +25,6 @@ namespace App2 do { Console.WriteLine(); - Console.WriteLine("Send message to App1: "); message = Console.ReadLine(); diff --git a/samples/RabbitMqEventBus/App2/App2TextEventHandler.cs b/samples/RabbitMqEventBus/App2/App2TextEventHandler.cs index ac26dd187b..8cf9ef65ae 100644 --- a/samples/RabbitMqEventBus/App2/App2TextEventHandler.cs +++ b/samples/RabbitMqEventBus/App2/App2TextEventHandler.cs @@ -23,6 +23,7 @@ namespace App2 Console.WriteLine("************************ INCOMING MESSAGE ****************************"); Console.WriteLine(eventData.TextMessage); Console.WriteLine("**********************************************************************"); + Console.WriteLine(); _distributedEventBus.PublishAsync(new App2TextReceivedEventData(eventData.TextMessage)); diff --git a/samples/RabbitMqEventBus/App2/App2TextReceivedEventHandler.cs b/samples/RabbitMqEventBus/App2/App2TextReceivedEventHandler.cs index fde68aa615..d53bac48b4 100644 --- a/samples/RabbitMqEventBus/App2/App2TextReceivedEventHandler.cs +++ b/samples/RabbitMqEventBus/App2/App2TextReceivedEventHandler.cs @@ -14,7 +14,8 @@ namespace App2 public Task HandleEventAsync(App1TextReceivedEventData eventData) { Console.WriteLine("--------> App1 has received the message: " + eventData.ReceivedText.TruncateWithPostfix(32)); - + Console.WriteLine(); + return Task.CompletedTask; } } From 92f9f76663fc1238e5b0bd3c7b948608b9f9af22 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 18 Dec 2018 11:14:28 +0300 Subject: [PATCH 038/368] dropdown tag helper improvements --- .../Dropdown/AbpDropdownButtonTagHelperService.cs | 1 + .../Dropdown/AbpDropdownItemTextTagHelper.cs | 11 +++++++++++ .../AbpDropdownItemTextTagHelperService.cs | 14 ++++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownItemTextTagHelper.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownItemTextTagHelperService.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownButtonTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownButtonTagHelperService.cs index 60a34a71f1..8b01781602 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownButtonTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownButtonTagHelperService.cs @@ -125,6 +125,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown buttonTag.TagName = "a"; buttonTag.Attributes.RemoveAll("type"); buttonTag.Attributes.Add("roles", "button"); + buttonTag.Attributes.Add("href", "#"); if (TagHelper.NavLink??false) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownItemTextTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownItemTextTagHelper.cs new file mode 100644 index 0000000000..4c5e82fac7 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownItemTextTagHelper.cs @@ -0,0 +1,11 @@ +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown +{ + public class AbpDropdownItemTextTagHelper : AbpTagHelper + { + public AbpDropdownItemTextTagHelper(AbpDropdownItemTextTagHelperService tagHelperService) + : base(tagHelperService) + { + + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownItemTextTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownItemTextTagHelperService.cs new file mode 100644 index 0000000000..8cd84eade6 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownItemTextTagHelperService.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown +{ + public class AbpDropdownItemTextTagHelperService : AbpTagHelperService + { + public override void Process(TagHelperContext context, TagHelperOutput output) + { + output.Attributes.AddClass("dropdown-item-text"); + output.TagName = "span"; + } + } +} \ No newline at end of file From a933bb705ba71a18404c4b91af519010808050c1 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 18 Dec 2018 11:14:48 +0300 Subject: [PATCH 039/368] dropdown tag helper docs --- .../Pages/Components/Dropdowns.cshtml | 741 ++++++++++++++++-- .../Pages/Components/Dropdowns.cshtml.cs | 15 + 2 files changed, 705 insertions(+), 51 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Dropdowns.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Dropdowns.cshtml index 7604f18abc..4a8ddba9d6 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Dropdowns.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Dropdowns.cshtml @@ -10,111 +10,750 @@ } +@section scripts { + + @* + *@ + +} + + + + +

Dropdowns

Based on Bootstrap button.

-

# Dropdown Example

+

Single button

+ +
+
+ + + + + Action + Another action + Something else here + + +
+
+ + +

+<abp-dropdown>
+    <abp-dropdown-button text="Dropdown button" />
+    <abp-dropdown-menu>
+<abp-dropdown-item href="#">Action</abp-dropdown-item>
+<abp-dropdown-item href="#">Another action</abp-dropdown-item>
+<abp-dropdown-item href="#">Something else here</abp-dropdown-item>
+    </abp-dropdown-menu>
+</abp-dropdown>
+
+
+ +

+<div class="dropdown">
+  <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+    Dropdown button
+  </button>
+  <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
+    <a class="dropdown-item" href="#">Action</a>
+    <a class="dropdown-item" href="#">Another action</a>
+    <a class="dropdown-item" href="#">Something else here</a>
+  </div>
+</div>
+
+
+
+
+
+ +
+
+ + + + + Action + Another action + Something else here + + +
+
+ + +

+<abp-dropdown>
+    <abp-dropdown-button button-type="Secondary" link="true" text="Dropdown button" />
+    <abp-dropdown-menu>
+<abp-dropdown-item href="#">Action</abp-dropdown-item>
+<abp-dropdown-item href="#">Another action</abp-dropdown-item>
+<abp-dropdown-item href="#">Something else here</abp-dropdown-item>
+    </abp-dropdown-menu>
+</abp-dropdown>
+
+
+ +

+<div class="dropdown">
+  <a class="btn btn-secondary dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+    Dropdown link
+  </a>
+
+  <div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
+    <a class="dropdown-item" href="#">Action</a>
+    <a class="dropdown-item" href="#">Another action</a>
+    <a class="dropdown-item" href="#">Something else here</a>
+  </div>
+</div>
+
+
+
+
+
- + - Dropdown header - Action - Another disabled action + Action + Another action + Something else here + + Separated link + + + + + + Action + Another action + Something else here + + Separated link + + + + + + Action + Another action + Something else here + + Separated link + + + + + + Action + Another action Something else here Separated link -
-
+        
+            
+                

+<!-- Example single danger button -->
+
 <abp-dropdown>
-    <abp-dropdown-button button-type="Primary" text="Dropdown"/>
-       <abp-dropdown-menu>
-       <abp-dropdown-header>Dropdown header</abp-dropdown-header>
-       <abp-dropdown-item href="#" active="true">Action</abp-dropdown-item>
-       <abp-dropdown-item href="#" disabled="true">Another disabled action</abp-dropdown-item>
-       <abp-dropdown-item href="#">Something else here</abp-dropdown-item>
-       <abp-dropdown-divider/>
-       <abp-dropdown-item href="#">Separated link</abp-dropdown-item>
+    <abp-dropdown-button button-type="Danger" text="Dropdown button" />
+    <abp-dropdown-menu>
+<abp-dropdown-item href="#">Action</abp-dropdown-item>
+<abp-dropdown-item href="#">Another action</abp-dropdown-item>
+<abp-dropdown-item href="#">Something else here</abp-dropdown-item>
+<abp-dropdown-divider />
+<abp-dropdown-item href="#">Separated link</abp-dropdown-item>
     </abp-dropdown-menu>
 </abp-dropdown>
-
+
+ + +

+<!-- Example single danger button -->
+
+<div class="btn-group">
+  <button type="button" class="btn btn-danger dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+    Action
+  </button>
+  <div class="dropdown-menu">
+    <a class="dropdown-item" href="#">Action</a>
+    <a class="dropdown-item" href="#">Another action</a>
+    <a class="dropdown-item" href="#">Something else here</a>
+    <div class="dropdown-divider"></div>
+    <a class="dropdown-item" href="#">Separated link</a>
+  </div>
+</div>
+
+
+
-

# Split Dropdown Example

+

Split button

- - + + - Dropdown header - Action - Another disabled action + Action + Another action + Something else here + + Separated link + + + + + + Action + Another action + Something else here + + Separated link + + + + + + Action + Another action + Something else here + + Separated link + + + + + + Action + Another action Something else here Separated link -
-
-<abp-dropdown direction="Right">
-    <abp-dropdown-button dropdown-style="Split" button-type="Danger" text="Dropdown"/>
-       <abp-dropdown-menu>
-       <abp-dropdown-header>Dropdown header</abp-dropdown-header>
-       <abp-dropdown-item href="#" active="true">Action</abp-dropdown-item>
-       <abp-dropdown-item href="#" disabled="true">Another disabled action</abp-dropdown-item>
-       <abp-dropdown-item href="#">Something else here</abp-dropdown-item>
-       <abp-dropdown-divider/>
-       <abp-dropdown-item href="#">Separated link</abp-dropdown-item>
+        
+            
+                

+<!-- Example single danger button -->
+
+<abp-dropdown>
+    <abp-dropdown-button button-type="Danger" dropdown-style="Split" text="Dropdown button" />
+    <abp-dropdown-menu>
+<abp-dropdown-item href="#">Action</abp-dropdown-item>
+<abp-dropdown-item href="#">Another action</abp-dropdown-item>
+<abp-dropdown-item href="#">Something else here</abp-dropdown-item>
+<abp-dropdown-divider />
+<abp-dropdown-item href="#">Separated link</abp-dropdown-item>
     </abp-dropdown-menu>
 </abp-dropdown>
-
+
+ + +

+<!-- Example single danger button -->
+
+<div class="btn-group">
+  <button type="button" class="btn btn-danger">Action</button>
+  <button type="button" class="btn btn-danger dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+    <span class="sr-only">Toggle Dropdown</span>
+  </button>
+  <div class="dropdown-menu">
+    <a class="dropdown-item" href="#">Action</a>
+    <a class="dropdown-item" href="#">Another action</a>
+    <a class="dropdown-item" href="#">Something else here</a>
+    <div class="dropdown-divider"></div>
+    <a class="dropdown-item" href="#">Separated link</a>
+  </div>
+</div>
+
+
+
-

# Link Dropdown Example

+ +

Split button

- - - - Dropdown header - Action - Another disabled action + + + + Action + Another action Something else here Separated link + + + + Action + Another action + Something else here + + Separated link + + + + + + Action + Another action + Something else here + + Separated link + + + + + + Action + Another action + Something else here + + Separated link + + +
+
+ + +

+<!-- Example single danger button -->
+
+<abp-dropdown>
+    <abp-dropdown-button size="Large" button-type="Secondary" text="Large button" />
+    <abp-dropdown-menu>
+        ...
+    </abp-dropdown-menu>
+</abp-dropdown>
+<abp-dropdown>
+    <abp-dropdown-button size="Large" button-type="Secondary" dropdown-style="Split" text="Large split button" />
+    <abp-dropdown-menu>
+        ...
+    </abp-dropdown-menu>
+</abp-dropdown>
+<abp-dropdown>
+    <abp-dropdown-button size="Small" button-type="Secondary" text="Small button" />
+    <abp-dropdown-menu>
+        ...
+    </abp-dropdown-menu>
+</abp-dropdown>
+<abp-dropdown>
+    <abp-dropdown-button size="Small" button-type="Secondary" dropdown-style="Split" text="Small split button" />
+    <abp-dropdown-menu>
+        ...
+    </abp-dropdown-menu>
+</abp-dropdown>
+
+
+ +

+<!-- Large button groups (default and split) -->
+<div class="btn-group">
+  <button class="btn btn-secondary btn-lg dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+    Large button
+  </button>
+  <div class="dropdown-menu">
+    ...
+  </div>
+</div>
+<div class="btn-group">
+  <button class="btn btn-secondary btn-lg" type="button">
+    Large split button
+  </button>
+  <button type="button" class="btn btn-lg btn-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+    <span class="sr-only">Toggle Dropdown</span>
+  </button>
+  <div class="dropdown-menu">
+    ...
+  </div>
+</div>
 
+<!-- Small button groups (default and split) -->
+<div class="btn-group">
+  <button class="btn btn-secondary btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+    Small button
+  </button>
+  <div class="dropdown-menu">
+    ...
+  </div>
+</div>
+<div class="btn-group">
+  <button class="btn btn-secondary btn-sm" type="button">
+    Small split button
+  </button>
+  <button type="button" class="btn btn-sm btn-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+    <span class="sr-only">Toggle Dropdown</span>
+  </button>
+  <div class="dropdown-menu">
+    ...
+  </div>
+</div>
+
+
+
+
+
+ + +

Directions

+ +
+
+ + + + Action + Another action + Something else here + + + + + + Action + Another action + Something else here + + + + + + Action + Another action + Something else here + +
-
+        
+            
+                

 <abp-dropdown direction="Up">
-    <abp-dropdown-button Link="true" button-type="Primary" text="Dropdown"/>
-       <abp-dropdown-menu align="Right">
-       <abp-dropdown-header>Dropdown header</abp-dropdown-header>
-       <abp-dropdown-item href="#" active="true">Action</abp-dropdown-item>
-       <abp-dropdown-item href="#" disabled="true">Another disabled action</abp-dropdown-item>
-       <abp-dropdown-item href="#">Something else here</abp-dropdown-item>
-       <abp-dropdown-divider/>
-       <abp-dropdown-item href="#">Separated link</abp-dropdown-item>
+    <abp-dropdown-button button-type="Secondary" text="Dropup" />
+    <abp-dropdown-menu>
+        ...
+    </abp-dropdown-menu>
+</abp-dropdown>
+<abp-dropdown direction="Right">
+    <abp-dropdown-button button-type="Secondary" text="dropright" />
+    <abp-dropdown-menu>
+        ...
+    </abp-dropdown-menu>
+</abp-dropdown>
+<abp-dropdown direction="Right">
+    <abp-dropdown-button button-type="Secondary" dropdown-style="Split" text="Split right" />
+    <abp-dropdown-menu>
+        ...
+    </abp-dropdown-menu>
+</abp-dropdown>
+
+
+ +

+<div class="btn-group dropup">
+  <button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+    Dropup
+  </button>
+  <div class="dropdown-menu">
+    <!-- Dropdown menu links -->
+  </div>
+</div>
+<div class="btn-group dropright">
+  <button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+    dropright
+  </button>
+  <div class="dropdown-menu">
+    <!-- Dropdown menu links -->
+  </div>
+</div>
+<div class="btn-group dropright">
+  <button type="button" class="btn btn-danger">Action</button>
+  <button type="button" class="btn btn-danger dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+    <span class="sr-only">Split right</span>
+  </button>
+  <div class="dropdown-menu">
+    <!-- Dropdown menu links -->
+  </div>
+</div>
+
+
+
+
+
+ + +

Menu Items

+ +
+
+ + + + Dropdown Header + Action + Active action + Disabled action + + Dropdown Item Text + Something else here + + +
+
+ + +

+<abp-dropdown>
+    <abp-dropdown-button button-type="Secondary" text="Dropdown"/>
+    <abp-dropdown-menu>
+        <abp-dropdown-header>Dropdown Header</abp-dropdown-header>
+        <abp-dropdown-item href="#">Action</abp-dropdown-item>
+        <abp-dropdown-item active="true" href="#">Active action</abp-dropdown-item>
+        <abp-dropdown-item disabled="true" href="#">Disabled action</abp-dropdown-item>
+        <abp-dropdown-divider/>
+        <abp-dropdown-item-text>Dropdown Item Text</abp-dropdown-item-text>
+        <abp-dropdown-item href="#">Something else here</abp-dropdown-item>
+    </abp-dropdown-menu>
+</abp-dropdown>
+
+
+ +

+<div class="dropdown">
+  <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+    Dropdown button
+  </button>
+  <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
+      <h6 class="dropdown-header">Dropdown Header</h6>
+      <a class="dropdown-item" href="#">Action</a>
+      <a class="dropdown-item active" href="#">Active action</a>
+      <a class="dropdown-item disabled" href="#">Disabled action</a>
+      <div class="dropdown-divider"></div>
+      <span class="dropdown-item-text">Dropdown item text</span>
+      <a class="dropdown-item" href="#">Something else here</a>
+  </div>
+</div>
+
+
+
+
+
+ + +

Menu alignment

+ +
+
+ + + + Action + Active action + Disabled action + + +
+
+ + +

+<abp-dropdown>
+    <abp-dropdown-button button-type="Secondary" text="Right-aligned"/>
+    <abp-dropdown-menu align="Right">
+        <abp-dropdown-item href="#">Action</abp-dropdown-item>
+        <abp-dropdown-item active="true" href="#">Active action</abp-dropdown-item>
+        <abp-dropdown-item disabled="true" href="#">Disabled action</abp-dropdown-item>
     </abp-dropdown-menu>
 </abp-dropdown>
-
+ +
+ +

+<div class="btn-group">
+  <button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+    Right-aligned
+  </button>
+  <div class="dropdown-menu dropdown-menu-right">
+    <button class="dropdown-item" type="button">Action</button>
+    <button class="dropdown-item" type="button">Another action</button>
+    <button class="dropdown-item" type="button">Something else here</button>
+  </div>
+</div>
+
+
+
+ +

Custom Content

+ +
+
+ + + +

+ Some example text that's free-flowing within the dropdown menu. +

+

+ And this is more example text. +

+
+
+
+
+ + +

+<abp-dropdown>
+    <abp-dropdown-button button-type="Secondary" text="Dropdown With Only Text" />
+    <abp-dropdown-menu class="p-4" style="max-width: 200px;">
+        <p>
+             Some example text that's free-flowing within the dropdown menu.
+        </p>
+        <p class="mb-0">
+             And this is more example text.
+        </p>
+    </abp-dropdown-menu>
+</abp-dropdown>
+
+
+ +

+<div class="btn-group">
+  <button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+    Dropdown With Only Text
+  </button>
+    <div class="dropdown-menu p-4" style="max-width: 200px;">
+      <p>
+        Some example text that's free-flowing within the dropdown menu.
+      </p>
+      <p class="mb-0">
+        And this is more example text.
+      </p>
+  </div>
+</div>
+
+
+
+
+
+ +
+
+ + + +
+ + + + + + + New around here? Sign up + Forgot password? +
+
+
+
+ + +

+    public class DropdownsModel : PageModel
+    {
+        [Required]
+        [DataType(DataType.EmailAddress)]
+        [Display(Name = "Email Address")]
+        public string EmailAddress { get; set; }
+
+        [Required]
+        [DataType(DataType.Password)]
+        [Display(Name = "Password")]
+        public string Password{ get; set; }
+
+        [Display(Name = "Remember Me")]
+        public bool RememberMe{ get; set; }
+
+
+        public void OnGet()
+        {
+
+        }
+    }
+
+
+ +

+<abp-dropdown >
+    <abp-dropdown-button button-type="Secondary" text="Dropdown With Form"/>
+    <abp-dropdown-menu>
+        <form class="px-4 py-3">
+            <abp-input asp-for="EmailAddress"></abp-input>
+            <abp-input asp-for="Password"></abp-input>
+            <abp-input asp-for="RememberMe"></abp-input>
+            <abp-button button-type="Primary" text="Sign In" type="submit" />
+        </form>
+        <abp-dropdown-divider></abp-dropdown-divider>
+        <abp-dropdown-item href="#">New around here? Sign up</abp-dropdown-item>
+        <abp-dropdown-item href="#">Forgot password?</abp-dropdown-item>
+    </abp-dropdown-menu>
+</abp-dropdown>
+
+
+ +

+<div class="btn-group">
+    <button class="dropdown-toggle btn btn-secondary" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" type="button" data-busy-text="Processing..."><span>Dropdown With Form</span></button>
+    <div></div>
+    <div class="dropdown-menu" x-placement="bottom-start" style="position: absolute; will-change: transform; top: 0px; left: 0px; transform: translate3d(0px, 38px, 0px);">
+        <form class="px-4 py-3" novalidate="novalidate">
+            <div class="form-group">
+                <label for="EmailAddress">Email Address</label>
+                <input type="email" data-val="true" data-val-required="The Email Address field is required." id="EmailAddress" name="EmailAddress" value="" class="form-control input-validation-error" aria-describedby="EmailAddress-error">
+                <span class="text-danger field-validation-error" data-valmsg-for="EmailAddress" data-valmsg-replace="true"><span id="EmailAddress-error" class="">The Email Address field is required.</span></span>
+            </div>
+            <div class="form-group">
+                <label for="Password">Password</label>
+                <input type="password" data-val="true" data-val-required="The Password field is required." id="Password" name="Password" class="form-control input-validation-error" aria-describedby="Password-error">
+                <span class="text-danger field-validation-error" data-valmsg-for="Password" data-valmsg-replace="true"><span id="Password-error" class="">The Password field is required.</span></span>
+            </div>
+            <div class="form-check">
+                <input type="checkbox" data-val="true" data-val-required="The Remember Me field is required." id="RememberMe" name="RememberMe" value="true" class="form-check-input valid" aria-describedby="RememberMe-error">
+                <label class="form-check-label" for="RememberMe">Remember Me</label>
+            </div>
+            <button type="submit" class="btn btn-primary" data-busy-text="Processing..."><span>Sign In</span></button>
+            <input name="RememberMe" type="hidden" value="false">
+        </form>
+        <div class="dropdown-divider"></div>
+        <a href="#" class="dropdown-item">New around here? Sign up</a>
+        <a href="#" class="dropdown-item">Forgot password?</a>
+    </div>
+</div>
+
+
+
+
+
\ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Dropdowns.cshtml.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Dropdowns.cshtml.cs index ab95ad6e60..1b1cf6c4f2 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Dropdowns.cshtml.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Dropdowns.cshtml.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; @@ -9,6 +10,20 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components { public class DropdownsModel : PageModel { + [Required] + [DataType(DataType.EmailAddress)] + [Display(Name = "Email Address")] + public string EmailAddress { get; set; } + + [Required] + [DataType(DataType.Password)] + [Display(Name = "Password")] + public string Password{ get; set; } + + [Display(Name = "Remember Me")] + public bool RememberMe{ get; set; } + + public void OnGet() { From eaf2f44eabf7137428eb89232c28fc61e3d3bbb7 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Tue, 18 Dec 2018 11:24:47 +0300 Subject: [PATCH 040/368] Create common.DotSettings and use by framework\Volo.Abp.sln.DotSettings --- common.DotSettings | 23 +++++++++++++++++++++++ framework/Volo.Abp.sln.DotSettings | 8 +++++++- 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 common.DotSettings diff --git a/common.DotSettings b/common.DotSettings new file mode 100644 index 0000000000..cb0b2c919f --- /dev/null +++ b/common.DotSettings @@ -0,0 +1,23 @@ + + True + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + Required + Required + Required + Required + False + True + False + False + True + False + False + SQL + \ No newline at end of file diff --git a/framework/Volo.Abp.sln.DotSettings b/framework/Volo.Abp.sln.DotSettings index b8ca469cfe..b1de84b369 100644 --- a/framework/Volo.Abp.sln.DotSettings +++ b/framework/Volo.Abp.sln.DotSettings @@ -1,2 +1,8 @@  - SQL \ No newline at end of file + SQL + True + D:\Github\abp\common.DotSettings + ..\..\common.DotSettings + True + 1 + \ No newline at end of file From 72390552369a4cf53321246764c83cd23df5941c Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Tue, 18 Dec 2018 11:29:30 +0300 Subject: [PATCH 041/368] Create Volo.Abp.Identity.sln.DotSettings --- modules/identity/Volo.Abp.Identity.sln.DotSettings | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 modules/identity/Volo.Abp.Identity.sln.DotSettings diff --git a/modules/identity/Volo.Abp.Identity.sln.DotSettings b/modules/identity/Volo.Abp.Identity.sln.DotSettings new file mode 100644 index 0000000000..4e545ca3c3 --- /dev/null +++ b/modules/identity/Volo.Abp.Identity.sln.DotSettings @@ -0,0 +1,6 @@ + + D:\Github\abp\common.DotSettings + ..\..\..\common.DotSettings + True + True + 1 \ No newline at end of file From fd72d7a61fe2e7d85e2b0a67cba5738d50218bad Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Tue, 18 Dec 2018 11:41:18 +0300 Subject: [PATCH 042/368] UseAbpRequestLocalization --- .../Volo.AbpWebSite.Web/AbpWebSiteWebModule.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/abp_io/src/Volo.AbpWebSite.Web/AbpWebSiteWebModule.cs b/abp_io/src/Volo.AbpWebSite.Web/AbpWebSiteWebModule.cs index a66d7bb11a..d0f5369ff2 100644 --- a/abp_io/src/Volo.AbpWebSite.Web/AbpWebSiteWebModule.cs +++ b/abp_io/src/Volo.AbpWebSite.Web/AbpWebSiteWebModule.cs @@ -62,12 +62,21 @@ namespace Volo.AbpWebSite var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = context.Services.GetConfiguration(); + ConfigureLanguages(context.Services); ConfigureDatabaseServices(context.Services, configuration); ConfigureVirtualFileSystem(context.Services, hostingEnvironment); ConfigureBundles(context.Services); ConfigureTheme(context.Services); } + private static void ConfigureLanguages(IServiceCollection services) + { + services.Configure(options => + { + options.Languages.Add(new LanguageInfo("en-US", "en-US", "English")); + }); + } + private static void ConfigureBundles(IServiceCollection services) { services.Configure(options => @@ -138,12 +147,7 @@ namespace Volo.AbpWebSite var app = context.GetApplicationBuilder(); var env = context.GetEnvironment(); - app.UseRequestLocalization(options => - { - options.DefaultRequestCulture = new RequestCulture("en-US", "en-US"); - options.AddSupportedCultures("en-US"); - options.AddSupportedUICultures("en-US"); - }); + app.UseAbpRequestLocalization(); if (env.IsDevelopment()) { From ed51dea6c99be705d9b05b4f61a46675268e5ad5 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Tue, 18 Dec 2018 11:52:33 +0300 Subject: [PATCH 043/368] Added empty autofac integration document. --- docs/en/Autofac-Integration.md | 3 +++ docs/en/Index.md | 4 +--- docs/en/docs-nav.json | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 docs/en/Autofac-Integration.md diff --git a/docs/en/Autofac-Integration.md b/docs/en/Autofac-Integration.md new file mode 100644 index 0000000000..355313235f --- /dev/null +++ b/docs/en/Autofac-Integration.md @@ -0,0 +1,3 @@ +## Autofac Integration + +TODO \ No newline at end of file diff --git a/docs/en/Index.md b/docs/en/Index.md index 443579e40e..18df429102 100644 --- a/docs/en/Index.md +++ b/docs/en/Index.md @@ -1,7 +1,5 @@ # ABP Documentation -## Table of Contents - * Getting Started * From Startup Templates * [ASP.NET Core MVC Template](Getting-Started-AspNetCore-MVC-Template.md) @@ -13,7 +11,7 @@ * [With ASP.NET Core MVC](Tutorials/AspNetCore-Mvc/Part-I.md) * Fundamentals * [Dependency Injection](Dependency-Injection.md) - * AutoFac Integration + * [AutoFac Integration](Autofac-Integration.md) * [Virtual File System](Virtual-File-System.md) * [Localization](Localization.md) * [Exception Handling](Exception-Handling.md) diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index fa8ec3552e..1060a715fc 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -49,7 +49,8 @@ "path": "Dependency-Injection.md", "items": [ { - "text": "AutoFac Integration" + "text": "AutoFac Integration", + "path": "Autofac-Integration.md" } ] }, From a249b172779350a7791900d9c4092a80bd02aa52 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 18 Dec 2018 13:41:56 +0300 Subject: [PATCH 044/368] removed images tag helper --- .../TagHelpers/Image/AbpImagePosition.cs | 10 --- .../TagHelpers/Image/AbpImageTagHelper.cs | 23 ------- .../Image/AbpImageTagHelperService.cs | 68 ------------------- .../Pages/Components/Images.cshtml | 54 --------------- .../Pages/Components/Images.cshtml.cs | 17 ----- 5 files changed, 172 deletions(-) delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Image/AbpImagePosition.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Image/AbpImageTagHelper.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Image/AbpImageTagHelperService.cs delete mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Images.cshtml delete mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Images.cshtml.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Image/AbpImagePosition.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Image/AbpImagePosition.cs deleted file mode 100644 index 4a2f1cb622..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Image/AbpImagePosition.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Image -{ - public enum AbpImagePosition - { - Default, - Right, - Left, - Center - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Image/AbpImageTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Image/AbpImageTagHelper.cs deleted file mode 100644 index afc36f660c..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Image/AbpImageTagHelper.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Image -{ - public class AbpImageTagHelper : AbpTagHelper - { - public bool? Responsive { get; set; } - - public bool? Thumbnail { get; set; } - - public bool? Rounded { get; set; } - - public AbpImagePosition Position { get; set; } = AbpImagePosition.Default; - - public string Alt { get; set; } - - public string Src { get; set; } - - public AbpImageTagHelper(AbpImageTagHelperService tagHelperService) - : base(tagHelperService) - { - - } - } -} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Image/AbpImageTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Image/AbpImageTagHelperService.cs deleted file mode 100644 index c03eee480e..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Image/AbpImageTagHelperService.cs +++ /dev/null @@ -1,68 +0,0 @@ -using Microsoft.AspNetCore.Razor.TagHelpers; -using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; - -namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Image -{ - public class AbpImageTagHelperService : AbpTagHelperService - { - public override void Process(TagHelperContext context, TagHelperOutput output) - { - output.TagName = "img"; - SetSourceFile(context,output); - SetPosition(context,output); - SetResponsive(context,output); - SetThumbnail(context,output); - SetRounded(context,output); - SetAlt(context,output); - } - - protected virtual void SetSourceFile(TagHelperContext context, TagHelperOutput output) { - output.Attributes.Add("src",TagHelper.Src); - } - - protected virtual void SetPosition(TagHelperContext context, TagHelperOutput output) - { - if (TagHelper.Position == default) - { - return; - } - if (TagHelper.Position == AbpImagePosition.Left || TagHelper.Position == AbpImagePosition.Right) - { - output.Attributes.AddClass("float-" + TagHelper.Position.ToString().ToLowerInvariant()); - } - if (TagHelper.Position == AbpImagePosition.Center) - { - output.PreElement.SetHtmlContent("
"); - output.PostElement.SetHtmlContent("
"); - } - } - - protected virtual void SetResponsive(TagHelperContext context, TagHelperOutput output) { - if (TagHelper.Responsive ?? false) - { - output.Attributes.AddClass("img-fluid"); - } - } - - protected virtual void SetThumbnail(TagHelperContext context, TagHelperOutput output) - { - if (TagHelper.Thumbnail ?? false) - { - output.Attributes.AddClass("img-thumbnail"); - } - } - - protected virtual void SetRounded(TagHelperContext context, TagHelperOutput output) - { - if (TagHelper.Rounded ?? false) - { - output.Attributes.AddClass("rounded"); - } - } - - protected virtual void SetAlt(TagHelperContext context, TagHelperOutput output) - { - output.Attributes.Add("alt",TagHelper.Alt); - } - } -} \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Images.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Images.cshtml deleted file mode 100644 index 9ec4f0106e..0000000000 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Images.cshtml +++ /dev/null @@ -1,54 +0,0 @@ -@page -@model Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components.ImagesModel -@{ - ViewData["Title"] = "Images"; -} - -@section styles { - - - -} - -

Images

- -

Based on Bootstrap Images.

- -

# Image Examples

- -
-
- -
-
-
-<abp-image src="..." responsive="true"></abp-image>
-
-
-
- -
-
- -
-
-
-<abp-image src="..." thumbnail="true" rounded="true"></abp-image>
-
-
-
- -
-
- - - -
-
-
-<abp-image src="..." rounded="true" position="Left"></abp-image>
-<abp-image src="..." rounded="true" position="Center"></abp-image>
-<abp-image src="..." rounded="true" position="Right"></abp-image>
-
-
-
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Images.cshtml.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Images.cshtml.cs deleted file mode 100644 index 34130a050e..0000000000 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Images.cshtml.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.RazorPages; - -namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components -{ - public class ImagesModel : PageModel - { - public void OnGet() - { - - } - } -} \ No newline at end of file From 7f6552f22ffe72f89a8bf0c00c90fe539af66037 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Tue, 18 Dec 2018 14:00:09 +0300 Subject: [PATCH 045/368] Resolved #486: AutoFac integration document. --- docs/en/Autofac-Integration.md | 85 ++++++++++++++++++- docs/en/Dependency-Injection.md | 44 ++++++---- .../Getting-Started-AspNetCore-Application.md | 18 ++-- .../en/Getting-Started-Console-Application.md | 71 ++++++++++++++-- .../AbpConsoleDemo/AbpConsoleDemo.csproj | 2 +- .../AbpConsoleDemo/AppModule.cs | 2 + .../AbpConsoleDemo/Program.cs | 9 +- 7 files changed, 193 insertions(+), 38 deletions(-) diff --git a/docs/en/Autofac-Integration.md b/docs/en/Autofac-Integration.md index 355313235f..b3aced3e94 100644 --- a/docs/en/Autofac-Integration.md +++ b/docs/en/Autofac-Integration.md @@ -1,3 +1,84 @@ -## Autofac Integration +# Autofac Integration + +Autofac is one of the most used dependency injection frameworks for .Net. It provides some advanced features compared to .Net Core standard DI library, like dynamic proxying and property injection. + +## Install Autofac Integration + +> All startup templates and samples are Autofac integrated. So, most of the time you don't need to manually install this package. + +Install [Volo.Abp.Autofac](https://www.nuget.org/packages/Volo.Abp.Autofac) nuget package to your project (for a multi-projects application, it's suggested to add to the executable/web project.) + +```` +Install-Package Volo.Abp.Autofac +```` + +Then add `AbpAutofacModule` dependency to your module: + +```csharp +using Volo.Abp.Modularity; +using Volo.Abp.Autofac; + +namespace MyCompany.MyProject +{ + [DependsOn(typeof(AbpAutofacModule))] + public class MyModule : AbpModule + { + //... + } +} +``` + +Finally, configure `AbpApplicationCreationOptions` to replace default dependency injection services by Autofac. It depends on the application type. + +### ASP.NET Core Application + +Call `UseAutofac()` in the **Startup.cs** file as shown below: + +````csharp +public class Startup +{ + public IServiceProvider ConfigureServices(IServiceCollection services) + { + services.AddApplication(options => + { + //Integrate Autofac! + options.UseAutofac(); + }); + + return services.BuildServiceProviderFromFactory(); + } + + public void Configure(IApplicationBuilder app) + { + app.InitializeApplication(); + } +} +```` + +### Console Application + +Call `UseAutofac()` method in the `AbpApplicationFactory.Create` options as shown below: + +````csharp +using System; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; + +namespace AbpConsoleDemo +{ + class Program + { + static void Main(string[] args) + { + using (var application = AbpApplicationFactory.Create(options => + { + options.UseAutofac(); //Autofac integration + })) + { + //... + } + } + } +} +```` -TODO \ No newline at end of file diff --git a/docs/en/Dependency-Injection.md b/docs/en/Dependency-Injection.md index a001d52ec9..5186f29717 100644 --- a/docs/en/Dependency-Injection.md +++ b/docs/en/Dependency-Injection.md @@ -1,8 +1,10 @@ -## Dependency Injection +# Dependency Injection ABP's Dependency Injection system is developed based on Microsoft's [dependency injection extension](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection) library (Microsoft.Extensions.DependencyInjection nuget package). So, it's documentation is valid in ABP too. -### Modularity +> While ABP has no core dependency to any 3rd-party DI provider, it's required to use a provider that supports dynamic proxying and some other advanced features to make some ABP features properly work. Startup templates come with Autofac installed. See [Autofac integration](Autofac-Integration.md) document for more information. + +## Modularity Since ABP is a modular framework, every module defines it's own services and registers via dependency injection in it's own seperate [module class](Module-Development-Basics.md). Example: @@ -16,7 +18,7 @@ public class BlogModule : AbpModule } ```` -### Conventional Registration +## Conventional Registration ABP introduces conventional service registration. You need not do anything to register a service by convention. It's automatically done. If you want to disable it, you can set `SkipAutoServiceRegistration` to `true` by overriding the `PreConfigureServices` method. @@ -49,7 +51,7 @@ public class BlogModule : AbpModule The section below explains the conventions and configurations. -#### Inherently Registered Types +### Inherently Registered Types Some specific types are registered to dependency injection by default. Examples: @@ -71,7 +73,7 @@ public class BlogPostAppService : ApplicationService ``BlogPostAppService`` is automatically registered with transient lifetime since it's derived from a known base class. -#### Dependency Interfaces +### Dependency Interfaces If you implement these interfaces, your class is registered to dependency injection automatically: @@ -89,7 +91,7 @@ public class TaxCalculator : ITransientDependency ``TaxCalculator`` is automatically registered with a transient lifetime since it implements ``ITransientDependency``. -#### Dependency Attribute +### Dependency Attribute Another way of configuring a service for dependency injection is to use ``DependencyAttribute``. It has the following properties: @@ -110,7 +112,7 @@ public class TaxCalculator ``Dependency`` attribute has a higher priority than other dependency interfaces if it defines the ``Lifetime`` property. -#### ExposeServices Attribute +### ExposeServices Attribute ``ExposeServicesAttribute`` is used to control which services are provided by the related class. Example: @@ -124,14 +126,14 @@ public class TaxCalculator: ICalculator, ITaxCalculator, ICanCalculate, ITransie ``TaxCalculator`` class only exposes ``ITaxCalculator`` interface. That means you can only inject ``ITaxCalculator``, but can not inject ``TaxCalculator`` or ``ICalculator`` in your application. -#### Exposed Services by Convention +### Exposed Services by Convention If you do not specify which services to expose, ABP expose services by convention. So taking the ``TaxCalculator`` defined above: * The class itself is exposed by default. That means you can inject it by ``TaxCalculator`` class. * Default interfaces are exposed by default. Default interfaces are determined by naming convention. In this example, ``ICalculator`` and ``ITaxCalculator`` are default interfaces of ``TaxCalculator``, but ``ICanCalculate`` is not. -#### Combining All Together +### Combining All Together Combining attributes and interfaces is possible as long as it's meaningful. @@ -144,7 +146,7 @@ public class TaxCalculator : ITaxCalculator, ITransientDependency } ```` -#### Manually Registering +### Manually Registering In some cases, you may need to register a service to the `IServiceCollection` manually, especially if you need to use custom factory methods or singleton instances. In that case, you can directly add services just as [Microsoft documentation](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection) describes. Example: @@ -157,16 +159,18 @@ public class BlogModule : AbpModule context.Services.AddSingleton(new TaxCalculator(taxRatio: 0.18)); //Register a factory method that resolves from IServiceProvider - context.Services.AddScoped(sp => sp.GetRequiredService()); + context.Services.AddScoped( + sp => sp.GetRequiredService() + ); } } ```` -### Injecting Dependencies +## Injecting Dependencies There are three common ways of using a service that has already been registered. -#### Contructor Injection +### Contructor Injection This is the most common way of injecting a service into a class. For example: @@ -191,7 +195,7 @@ public class TaxAppService : ApplicationService Constructor injection is preffered way of injecting dependencies to a class. In that way, the class can not be constructed unless all constructor-injected dependencies are provided. Thus, the class explicitly declares it's required services. -#### Property Injection +### Property Injection Property injection is not supported by Microsoft Dependency Injection library. However, ABP can integrate with 3rd-party DI providers ([Autofac](https://autofac.org/), for example) to make property injection possible. Example: @@ -222,7 +226,7 @@ One restriction of property injection is that you cannot use the dependency in y Property injection is also useful when you want to design a base class that has some common services injected by default. If you're going to use constructor injection, all derived classes should also inject depended services into their own constructors which makes development harder. However, be very careful using property injection for non-optional services as it makes it harder to clearly see the requirements of a class. -#### Resolve Service from IServiceProvider +### Resolve Service from IServiceProvider You may want to resolve a service directly from ``IServiceProvider``. In that case, you can inject IServiceProvider into your class and use ``GetService`` method as shown below: @@ -244,7 +248,7 @@ public class MyService : ITransientDependency } ```` -#### Releasing/Disposing Services +### Releasing/Disposing Services If you used a constructor or property injection, you don't need to be concerned about releasing the service's resources. However, if you have resolved a service from ``IServiceProvider``, you might, in some cases, need to take care about releasing the service resources. @@ -266,6 +270,12 @@ using (var scope = _serviceProvider.CreateScope()) Both services are released when the created scope is disposed (at the end of the using block). -### See Also +## 3rd-Party Providers + +While ABP has no core dependency to any 3rd-party DI provider, it's required to use a provider that supports dynamic proxying and some other advanced features to make some ABP features properly work. + +Startup templates come with Autofac installed. See [Autofac integration](Autofac-Integration.md) document for more information. + +## See Also * [ASP.NET Core Dependency Injection Best Practices, Tips & Tricks](https://medium.com/volosoft/asp-net-core-dependency-injection-best-practices-tips-tricks-c6e9c67f9d96) diff --git a/docs/en/Getting-Started-AspNetCore-Application.md b/docs/en/Getting-Started-AspNetCore-Application.md index f242f8cd46..8c0d03b6bb 100644 --- a/docs/en/Getting-Started-AspNetCore-Application.md +++ b/docs/en/Getting-Started-AspNetCore-Application.md @@ -1,8 +1,8 @@ -## Getting Started ABP With AspNet Core MVC Web Application +# Getting Started ABP With AspNet Core MVC Web Application This tutorial explains how to start ABP from scratch with minimal dependencies. You generally want to start with a **[startup template](https://abp.io/Templates)**. -### Create A New Project +## Create A New Project 1. Create a new empty AspNet Core Web Application from Visual Studio: @@ -14,7 +14,7 @@ This tutorial explains how to start ABP from scratch with minimal dependencies. You could select another template, but I want to show it from a clear project. -### Install Volo.Abp.AspNetCore.Mvc Package +## Install Volo.Abp.AspNetCore.Mvc Package Volo.Abp.AspNetCore.Mvc is AspNet Core MVC integration package for ABP. So, install it to your project: @@ -22,7 +22,7 @@ Volo.Abp.AspNetCore.Mvc is AspNet Core MVC integration package for ABP. So, inst Install-Package Volo.Abp.AspNetCore.Mvc ```` -### Create First ABP Module +## Create First ABP Module ABP is a modular framework and it requires a **startup (root) module** class derived from ``AbpModule``: @@ -62,7 +62,7 @@ ABP packages define module classes and a module can depend on another module. In Instead of Startup class, we are configuring ASP.NET Core pipeline in this module class. -### The Startup Class +## The Startup Class Next step is to modify Startup class to integrate to ABP module system: @@ -95,7 +95,7 @@ Changed ``ConfigureServices`` method to return ``IServiceProvider`` instead of ` ``app.InitializeApplication()`` call in ``Configure`` method initializes and starts the application. -### Hello World! +## Hello World! The application above does nothing. Let's create an MVC controller does something: @@ -120,13 +120,13 @@ If you run the application, you will see a "Hello World!" message on the page. Derived ``HomeController`` from ``AbpController`` instead of standard ``Controller`` class. This is not required, but ``AbpController`` class has useful base properties and methods to make your development easier. -### Using Autofac as the Dependency Injection Framework +## Using Autofac as the Dependency Injection Framework While AspNet Core's Dependency Injection (DI) system is fine for basic requirements, Autofac provides advanced features like Property Injection and Method Interception which are required by ABP to perform advanced application framework features. Replacing AspNet Core's DI system by Autofac and integrating to ABP is pretty easy. -1. Install Volo.Abp.Autofac package +1. Install [Volo.Abp.Autofac](https://www.nuget.org/packages/Volo.Abp.Autofac) package ```` Install-Package Volo.Abp.Autofac @@ -152,6 +152,6 @@ services.AddApplication(options => }); ```` -### Source Code +## Source Code Get source code of the sample project created in this tutorial from [here](https://github.com/abpframework/abp/tree/master/samples/BasicAspNetCoreApplication). diff --git a/docs/en/Getting-Started-Console-Application.md b/docs/en/Getting-Started-Console-Application.md index 4200bb6ca7..f6ba588ac7 100644 --- a/docs/en/Getting-Started-Console-Application.md +++ b/docs/en/Getting-Started-Console-Application.md @@ -1,14 +1,14 @@ -## Getting Started ABP With Console Application +# Getting Started ABP With Console Application This tutorial explains how to start ABP from scratch with minimal dependencies. You generally want to start with a **[startup template](https://abp.io/Templates)**. -### Create A New Project +## Create A New Project Create a new Regular .Net Core Console Application from Visual Studio: ![](images/create-new-net-core-console-application.png) -### Install Volo.Abp Package +## Install Volo.Abp Package Volo.Abp.Core is the core nuget package to create ABP based applications. So, install it to your project: @@ -16,7 +16,7 @@ Volo.Abp.Core is the core nuget package to create ABP based applications. So, in Install-Package Volo.Abp.Core ```` -### Create First ABP Module +## Create First ABP Module ABP is a modular framework and it requires a **startup (root) module** class derived from ``AbpModule``: @@ -35,7 +35,7 @@ namespace AbpConsoleDemo ``AppModule`` is a good name for the startup module for an application. -### Initialize The Application +## Initialize The Application The next step is to bootstrap the application using the startup module created above: @@ -64,7 +64,7 @@ namespace AbpConsoleDemo ``AbpApplicationFactory`` is used to create the application and load all modules taking ``AppModule`` as the startup module. ``Initialize()`` method starts the application. -### Hello World! +## Hello World! The application above does nothing. Let's create a service that does something: @@ -119,6 +119,63 @@ namespace AbpConsoleDemo While it's enough for this simple code example, it's always suggested to create scopes in case of directly resolving dependencies from ``IServiceProvider`` (see the [Dependency Injection documentation](Dependency-Injection.md)). -### Source Code +## Using Autofac as the Dependency Injection Framework + +While AspNet Core's Dependency Injection (DI) system is fine for basic requirements, Autofac provides advanced features like Property Injection and Method Interception which are required by ABP to perform advanced application framework features. + +Replacing AspNet Core's DI system by Autofac and integrating to ABP is pretty easy. + +1. Install [Volo.Abp.Autofac](https://www.nuget.org/packages/Volo.Abp.Autofac) package + +``` +Install-Package Volo.Abp.Autofac +``` + +1. Add ``AbpAutofacModule`` Dependency + +```c# +[DependsOn(typeof(AbpAutofacModule))] //Add dependency to ABP Autofac module +public class AppModule : AbpModule +{ + ... +} +``` + +1. Change ``Program.cs`` file as shown below: + +```c# +using System; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; + +namespace AbpConsoleDemo +{ + class Program + { + static void Main(string[] args) + { + using (var application = AbpApplicationFactory.Create(options => + { + options.UseAutofac(); //Autofac integration + })) + { + application.Initialize(); + + //Resolve a service and use it + var helloWorldService = + application.ServiceProvider.GetService(); + helloWorldService.SayHello(); + + Console.WriteLine("Press ENTER to stop application..."); + Console.ReadLine(); + } + } + } +} +``` + +Just called `options.UseAutofac()` method in the `AbpApplicationFactory.Create` options. + +## Source Code Get source code of the sample project created in this tutorial from [here](https://github.com/abpframework/abp/tree/master/samples/BasicConsoleApplication). diff --git a/samples/BasicConsoleApplication/AbpConsoleDemo/AbpConsoleDemo.csproj b/samples/BasicConsoleApplication/AbpConsoleDemo/AbpConsoleDemo.csproj index 04d1557392..a08c8bd0b9 100644 --- a/samples/BasicConsoleApplication/AbpConsoleDemo/AbpConsoleDemo.csproj +++ b/samples/BasicConsoleApplication/AbpConsoleDemo/AbpConsoleDemo.csproj @@ -6,7 +6,7 @@ - + diff --git a/samples/BasicConsoleApplication/AbpConsoleDemo/AppModule.cs b/samples/BasicConsoleApplication/AbpConsoleDemo/AppModule.cs index 0449d84b99..07b4fa3ec3 100644 --- a/samples/BasicConsoleApplication/AbpConsoleDemo/AppModule.cs +++ b/samples/BasicConsoleApplication/AbpConsoleDemo/AppModule.cs @@ -1,8 +1,10 @@ using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Autofac; using Volo.Abp.Modularity; namespace AbpConsoleDemo { + [DependsOn(typeof(AbpAutofacModule))] public class AppModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) diff --git a/samples/BasicConsoleApplication/AbpConsoleDemo/Program.cs b/samples/BasicConsoleApplication/AbpConsoleDemo/Program.cs index 5f0dc68d36..651fda3c4f 100644 --- a/samples/BasicConsoleApplication/AbpConsoleDemo/Program.cs +++ b/samples/BasicConsoleApplication/AbpConsoleDemo/Program.cs @@ -8,11 +8,16 @@ namespace AbpConsoleDemo { static void Main(string[] args) { - using (var application = AbpApplicationFactory.Create()) + using (var application = AbpApplicationFactory.Create(options => + { + options.UseAutofac(); //Autofac integration + })) { application.Initialize(); - var helloWorldService = application.ServiceProvider.GetService(); + //Resolve a service and use it + var helloWorldService = + application.ServiceProvider.GetService(); helloWorldService.SayHello(); Console.WriteLine("Press ENTER to stop application..."); From 3c7b40618cec526740ca4a5ba01bafb7ad3d4cc1 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Tue, 18 Dec 2018 14:14:38 +0300 Subject: [PATCH 046/368] Added IServiceCollection.OnRegistred Event section. --- docs/en/Dependency-Injection.md | 42 ++++++++++++++++++++++++ docs/en/Dynamic-Proxying-Interceptors.md | 3 ++ 2 files changed, 45 insertions(+) create mode 100644 docs/en/Dynamic-Proxying-Interceptors.md diff --git a/docs/en/Dependency-Injection.md b/docs/en/Dependency-Injection.md index 5186f29717..d1ca14950c 100644 --- a/docs/en/Dependency-Injection.md +++ b/docs/en/Dependency-Injection.md @@ -270,6 +270,48 @@ using (var scope = _serviceProvider.CreateScope()) Both services are released when the created scope is disposed (at the end of the using block). +## Advanced Features + +### IServiceCollection.OnRegistred Event + +You may want to perform an action for every service registered to the dependency injection. In the `PreConfigureServices` method of your module, register a callback using the `OnRegistred` method as shown below: + +````csharp +public class AppModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + context.Services.OnRegistred(ctx => + { + var type = ctx.ImplementationType; + //... + }); + } +} +```` + +`ImplementationType` provides the service type. This callback is generally used to add interceptor to a service. Example: + +````csharp +public class AppModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + context.Services.OnRegistred(ctx => + { + if (ctx.ImplementationType.IsDefined(typeof(MyLogAttribute), true)) + { + ctx.Interceptors.TryAdd(); + } + }); + } +} +```` + +This example simply checks if the service class has `MyLogAttribute` attribute and adds `MyLogInterceptor` to the interceptor list if so. + +> Notice that `OnRegistred` callback might be called multiple times for the same service class if it exposes more than one service/interface. So, it's safe to use `Interceptors.TryAdd` method instead of `Interceptors.Add` method. See [the documentation](Dynamic-Proxying-Interceptors.md) of dynamic proxying / interceptors. + ## 3rd-Party Providers While ABP has no core dependency to any 3rd-party DI provider, it's required to use a provider that supports dynamic proxying and some other advanced features to make some ABP features properly work. diff --git a/docs/en/Dynamic-Proxying-Interceptors.md b/docs/en/Dynamic-Proxying-Interceptors.md new file mode 100644 index 0000000000..76a23daa8f --- /dev/null +++ b/docs/en/Dynamic-Proxying-Interceptors.md @@ -0,0 +1,3 @@ +## Dynamic Proxying / Interceptors + +TODO \ No newline at end of file From 7e6fe07003e1053bae9c08eab85aafc8d656a3b3 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Tue, 18 Dec 2018 14:15:53 +0300 Subject: [PATCH 047/368] Remove unncessary context.Services.AddAssemblyOf --- docs/en/Getting-Started-Console-Application.md | 4 ++-- .../BasicConsoleApplication/AbpConsoleDemo/AppModule.cs | 8 ++------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/docs/en/Getting-Started-Console-Application.md b/docs/en/Getting-Started-Console-Application.md index f6ba588ac7..faaa8cd376 100644 --- a/docs/en/Getting-Started-Console-Application.md +++ b/docs/en/Getting-Started-Console-Application.md @@ -134,10 +134,10 @@ Install-Package Volo.Abp.Autofac 1. Add ``AbpAutofacModule`` Dependency ```c# -[DependsOn(typeof(AbpAutofacModule))] //Add dependency to ABP Autofac module +[DependsOn(typeof(AbpAutofacModule))] //Add dependency to the AbpAutofacModule public class AppModule : AbpModule { - ... + } ``` diff --git a/samples/BasicConsoleApplication/AbpConsoleDemo/AppModule.cs b/samples/BasicConsoleApplication/AbpConsoleDemo/AppModule.cs index 07b4fa3ec3..85d1d6b816 100644 --- a/samples/BasicConsoleApplication/AbpConsoleDemo/AppModule.cs +++ b/samples/BasicConsoleApplication/AbpConsoleDemo/AppModule.cs @@ -1,5 +1,4 @@ -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.Autofac; +using Volo.Abp.Autofac; using Volo.Abp.Modularity; namespace AbpConsoleDemo @@ -7,9 +6,6 @@ namespace AbpConsoleDemo [DependsOn(typeof(AbpAutofacModule))] public class AppModule : AbpModule { - public override void ConfigureServices(ServiceConfigurationContext context) - { - context.Services.AddAssemblyOf(); - } + } } From 8efecb3841090747621165d4bd7220daa8c00a92 Mon Sep 17 00:00:00 2001 From: personball Date: Tue, 18 Dec 2018 19:44:56 +0800 Subject: [PATCH 048/368] translate zh-Hans/Autofac-Integration.md --- docs/zh-Hans/Autofac-Integration.md | 84 +++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 docs/zh-Hans/Autofac-Integration.md diff --git a/docs/zh-Hans/Autofac-Integration.md b/docs/zh-Hans/Autofac-Integration.md new file mode 100644 index 0000000000..dfba1218f2 --- /dev/null +++ b/docs/zh-Hans/Autofac-Integration.md @@ -0,0 +1,84 @@ +# 集成 Autofac + +Autofac 是.Net世界中最常用的依赖注入框架之一. 相比.Net Core标准的依赖注入库, 它提供了更多高级特性, 比如动态代理和属性注入. + +## 安装 Autofac + +> 所有的启动模板和示例都已经集成了 Autofac. 所以, 多数时候你无需手动安装这个包. + +安装 [Volo.Abp.Autofac](https://www.nuget.org/packages/Volo.Abp.Autofac) nuget 包到你的项目 (对于一个多项目应用程序, 建议安装到可执行项目或者Web项目中.) + +```` +Install-Package Volo.Abp.Autofac +```` + +然后为你的模块添加 `AbpAutofacModule` 依赖: + +```csharp +using Volo.Abp.Modularity; +using Volo.Abp.Autofac; + +namespace MyCompany.MyProject +{ + [DependsOn(typeof(AbpAutofacModule))] + public class MyModule : AbpModule + { + //... + } +} +``` + +最后, 配置 `AbpApplicationCreationOptions` 用 Autofac 替换默认的依赖注入服务. 根据应用程序类型,情况有所不同. + +### ASP.NET Core 应用程序 + +如下所示,在 **Startup.cs** 文件中调用 `UseAutofac()`: + +````csharp +public class Startup +{ + public IServiceProvider ConfigureServices(IServiceCollection services) + { + services.AddApplication(options => + { + //Integrate Autofac! + options.UseAutofac(); + }); + + return services.BuildServiceProviderFromFactory(); + } + + public void Configure(IApplicationBuilder app) + { + app.InitializeApplication(); + } +} +```` + +### 控制台应用程序 + +如下所示,在 `AbpApplicationFactory.Create` 中用options调用 `UseAutofac()` 方法: + +````csharp +using System; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; + +namespace AbpConsoleDemo +{ + class Program + { + static void Main(string[] args) + { + using (var application = AbpApplicationFactory.Create(options => + { + options.UseAutofac(); //Autofac integration + })) + { + //... + } + } + } +} +```` + From 7737acbe743709ce6e52bb7ccf2c9fe70ae92d2b Mon Sep 17 00:00:00 2001 From: personball Date: Tue, 18 Dec 2018 19:52:52 +0800 Subject: [PATCH 049/368] fix comma --- docs/zh-Hans/Autofac-Integration.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/zh-Hans/Autofac-Integration.md b/docs/zh-Hans/Autofac-Integration.md index dfba1218f2..9b1d249e4e 100644 --- a/docs/zh-Hans/Autofac-Integration.md +++ b/docs/zh-Hans/Autofac-Integration.md @@ -28,11 +28,11 @@ namespace MyCompany.MyProject } ``` -最后, 配置 `AbpApplicationCreationOptions` 用 Autofac 替换默认的依赖注入服务. 根据应用程序类型,情况有所不同. +最后, 配置 `AbpApplicationCreationOptions` 用 Autofac 替换默认的依赖注入服务. 根据应用程序类型, 情况有所不同. ### ASP.NET Core 应用程序 -如下所示,在 **Startup.cs** 文件中调用 `UseAutofac()`: +如下所示, 在 **Startup.cs** 文件中调用 `UseAutofac()`: ````csharp public class Startup @@ -57,7 +57,7 @@ public class Startup ### 控制台应用程序 -如下所示,在 `AbpApplicationFactory.Create` 中用options调用 `UseAutofac()` 方法: +如下所示, 在 `AbpApplicationFactory.Create` 中用options调用 `UseAutofac()` 方法: ````csharp using System; From 849179e40d6c2913b889876385fd9440da9a8b7d Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 18 Dec 2018 15:09:36 +0300 Subject: [PATCH 050/368] list group tag helper docs --- .../Pages/Components/ListGroup.cshtml | 313 +++++++++++++++--- 1 file changed, 269 insertions(+), 44 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ListGroup.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ListGroup.cshtml index 90097a3c4d..40a5cb5c65 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ListGroup.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ListGroup.cshtml @@ -10,11 +10,23 @@ } +@section scripts { + + @* + *@ + +} + + + + +

List Groups

Based on Bootstrap List Group.

-

# List Group Example

+

Basic example

@@ -25,116 +37,329 @@ Morbi leo risus Vestibulum at eros -
-
+        
+            
+                

 <abp-list-group>
-    <abp-list-group-item active="true">Cras justo odio</abp-list-group-item>
+    <abp-list-group-item>Cras justo odio</abp-list-group-item>
     <abp-list-group-item>Dapibus ac facilisis in</abp-list-group-item>
     <abp-list-group-item>Morbi leo risus</abp-list-group-item>
-    <abp-list-group-item disabled="true">Vestibulum at eros</abp-list-group-item>
+    <abp-list-group-item>Vestibulum at eros</abp-list-group-item>
 </abp-list-group>
-
+
+ + +

+<ul class="list-group">
+  <li class="list-group-item">Cras justo odio</li>
+  <li class="list-group-item">Dapibus ac facilisis in</li>
+  <li class="list-group-item">Morbi leo risus</li>
+  <li class="list-group-item">Porta ac consectetur ac</li>
+</ul>
+
+
+
-

# List Group Flush Example

+

Active & disabled items

- + Cras justo odio - Dapibus ac facilisis in + Dapibus ac facilisis in Morbi leo risus - Vestibulum at eros + Vestibulum at eros -
-
-<abp-list-group flush="true">
+        
+            
+                

+<abp-list-group>
     <abp-list-group-item>Cras justo odio</abp-list-group-item>
-    <abp-list-group-item>Dapibus ac facilisis in</abp-list-group-item>
+    <abp-list-group-item active="true">Dapibus ac facilisis in</abp-list-group-item>
     <abp-list-group-item>Morbi leo risus</abp-list-group-item>
-    <abp-list-group-item>Vestibulum at eros</abp-list-group-item>
+    <abp-list-group-item disabled="true">Vestibulum at eros</abp-list-group-item>
 </abp-list-group>
-
+
+ + +

+<ul class="list-group">
+  <li class="list-group-item active">Cras justo odio</li>
+  <li class="list-group-item">Dapibus ac facilisis in</li>
+  <li class="list-group-item">Morbi leo risus</li>
+  <li class="list-group-item disabled">Porta ac consectetur ac</li>
+</ul>
+
+
+
-

# List Group Link Example

+

Links and buttons

- Cras justo odio + Cras justo odio Dapibus ac facilisis in Morbi leo risus - Vestibulum at eros + Vestibulum at eros -
-
+        
+            
+                

 <abp-list-group>
-    <abp-list-group-item href="#">Cras justo odio</abp-list-group-item>
+    <abp-list-group-item href="#" active="true">Cras justo odio</abp-list-group-item>
     <abp-list-group-item href="#">Dapibus ac facilisis in</abp-list-group-item>
     <abp-list-group-item href="#">Morbi leo risus</abp-list-group-item>
-    <abp-list-group-item href="#">Vestibulum at eros</abp-list-group-item>
+    <abp-list-group-item href="#" disabled="true">Vestibulum at eros</abp-list-group-item>
 </abp-list-group>
-
+
+ + +

+<div class="list-group">
+  <a href="#" class="list-group-item list-group-item-action active">Cras justo odio</a>
+  <a href="#" class="list-group-item list-group-item-action">Dapibus ac facilisis in</a>
+  <a href="#" class="list-group-item list-group-item-action">Morbi leo risus</a>
+  <a href="#" class="list-group-item list-group-item-action disabled">Vestibulum at eros</a>
+</div>
+
+
+
-

# List Group Button Example

-
- Cras justo odio + Cras justo odio Dapibus ac facilisis in Morbi leo risus Vestibulum at eros -
-
-<abp-list-group flush="true">
-    <abp-list-group-item tag-type="Button">Cras justo odio</abp-list-group-item>
+        
+            
+                

+<abp-list-group>
+    <abp-list-group-item tag-type="Button" active="true">Cras justo odio</abp-list-group-item>
     <abp-list-group-item tag-type="Button">Dapibus ac facilisis in</abp-list-group-item>
     <abp-list-group-item tag-type="Button">Morbi leo risus</abp-list-group-item>
     <abp-list-group-item tag-type="Button">Vestibulum at eros</abp-list-group-item>
 </abp-list-group>
-
+
+ + +

+<div class="list-group">
+  <button type="button" class="list-group-item list-group-item-action active">
+    Cras justo odio
+  </button>
+  <button type="button" class="list-group-item list-group-item-action">Morbi leo risus</button>
+  <button type="button" class="list-group-item list-group-item-action">Porta ac consectetur ac</button>
+  <button type="button" class="list-group-item list-group-item-action" disabled>Vestibulum at eros</button>
+</div>
+
+
+
-

# List Group style Contextual classes Example

+

Flush

+ +
+
+ + + Cras justo odio + Dapibus ac facilisis in + Morbi leo risus + Vestibulum at eros + +
+
+ + +

+<abp-list-group flush="true">
+    <abp-list-group-item>Cras justo odio</abp-list-group-item>
+    <abp-list-group-item>Dapibus ac facilisis in</abp-list-group-item>
+    <abp-list-group-item>Morbi leo risus</abp-list-group-item>
+    <abp-list-group-item>Vestibulum at eros</abp-list-group-item>
+</abp-list-group>
+
+
+ +

+<ul class="list-group list-group-flush">
+  <li class="list-group-item">Cras justo odio</li>
+  <li class="list-group-item">Dapibus ac facilisis in</li>
+  <li class="list-group-item">Morbi leo risus</li>
+  <li class="list-group-item">Vestibulum at eros</li>
+</ul>
+
+
+
+
+
+ +

Contextual classes

- Cras justo odio - Dapibus ac facilisis in - Morbi leo risus 42 - Vestibulum at eros 5 + Cras justo odio + A simple Primary list group item + A simple Secondary list group item + A simple Success list group item + A simple Danger list group item + A simple Warning list group item + A simple Info list group item + A simple Light list group item + A simple Dark list group item +
+
+ + +

+<abp-list-group>
+    <abp-list-group-item>Cras justo odio</abp-list-group-item>
+    <abp-list-group-item type="Primary">A simple Primary list group item</abp-list-group-item>
+    <abp-list-group-item type="Secondary">A simple Secondary list group item</abp-list-group-item>
+    <abp-list-group-item type="Success">A simple Success list group item</abp-list-group-item>
+    <abp-list-group-item type="Danger">A simple Danger list group item</abp-list-group-item>
+    <abp-list-group-item type="Warning">A simple Warning list group item</abp-list-group-item>
+    <abp-list-group-item type="Info">A simple Info list group item</abp-list-group-item>
+    <abp-list-group-item type="Light">A simple Light list group item</abp-list-group-item>
+    <abp-list-group-item type="Dark">A simple Dark list group item</abp-list-group-item>
+</abp-list-group>
+
+
+ +

+<ul class="list-group">
+  <li class="list-group-item">Dapibus ac facilisis in</li>
+  <li class="list-group-item list-group-item-primary">A simple primary list group item</li>
+  <li class="list-group-item list-group-item-secondary">A simple secondary list group item</li>
+  <li class="list-group-item list-group-item-success">A simple success list group item</li>
+  <li class="list-group-item list-group-item-danger">A simple danger list group item</li>
+  <li class="list-group-item list-group-item-warning">A simple warning list group item</li>
+  <li class="list-group-item list-group-item-info">A simple info list group item</li>
+  <li class="list-group-item list-group-item-light">A simple light list group item</li>
+  <li class="list-group-item list-group-item-dark">A simple dark list group item</li>
+</ul>
+
+
+
+
+
+
+
+ + + Cras justo odio + A simple Primary list group item + A simple Secondary list group item + A simple Success list group item + A simple Danger list group item + A simple Warning list group item + A simple Info list group item + A simple Light list group item + A simple Dark list group item +
-
-<abp-list-group flush="true">
-    <abp-list-group-item type="Warning">Cras justo odio</abp-list-group-item>
-    <abp-list-group-item type="Danger">Dapibus ac facilisis in</abp-list-group-item>
-    <abp-list-group-item type="Success">Morbi leo risus <span abp-badge-pill="Success">42</span></abp-list-group-item>
-    <abp-list-group-item type="Secondary">Vestibulum at eros <span abp-badge-pill="Warning">5</span></abp-list-group-item>
+        
+            
+                

+<abp-list-group>
+    <abp-list-group-item href="#">Cras justo odio</abp-list-group-item>
+    <abp-list-group-item href="#" type="Primary">A simple Primary list group item</abp-list-group-item>
+    <abp-list-group-item href="#" type="Secondary">A simple Secondary list group item</abp-list-group-item>
+    <abp-list-group-item href="#" type="Success">A simple Success list group item</abp-list-group-item>
+    <abp-list-group-item href="#" type="Danger">A simple Danger list group item</abp-list-group-item>
+    <abp-list-group-item href="#" type="Warning">A simple Warning list group item</abp-list-group-item>
+    <abp-list-group-item href="#" type="Info">A simple Info list group item</abp-list-group-item>
+    <abp-list-group-item href="#" type="Light">A simple Light list group item</abp-list-group-item>
+    <abp-list-group-item href="#" type="Dark">A simple Dark list group item</abp-list-group-item>
+</abp-list-group>
+
+
+ +

+<div class="list-group">
+  <a href="#" class="list-group-item list-group-item-action">Dapibus ac facilisis in</a>
+  <a href="#" class="list-group-item list-group-item-action list-group-item-primary">A simple primary list group item</a>
+  <a href="#" class="list-group-item list-group-item-action list-group-item-secondary">A simple secondary list group item</a>
+  <a href="#" class="list-group-item list-group-item-action list-group-item-success">A simple success list group item</a>
+  <a href="#" class="list-group-item list-group-item-action list-group-item-danger">A simple danger list group item</a>
+  <a href="#" class="list-group-item list-group-item-action list-group-item-warning">A simple warning list group item</a>
+  <a href="#" class="list-group-item list-group-item-action list-group-item-info">A simple info list group item</a>
+  <a href="#" class="list-group-item list-group-item-action list-group-item-light">A simple light list group item</a>
+  <a href="#" class="list-group-item list-group-item-action list-group-item-dark">A simple dark list group item</a>
+</div>
+
+
+
+
+
+ +

With badges

+ +
+
+ + + Cras justo odio 14 + Dapibus ac facilisis in 2 + Morbi leo risus 1 + +
+
+ + +

+<abp-list-group>
+    <abp-list-group-item>Cras justo odio <span abp-badge-pill="Primary">14</span></abp-list-group-item>
+    <abp-list-group-item>Dapibus ac facilisis in <span abp-badge-pill="Primary">2</span></abp-list-group-item>
+    <abp-list-group-item>Morbi leo risus <span abp-badge-pill="Primary">1</span></abp-list-group-item>
 </abp-list-group>
-
+ +
+ +

+<ul class="list-group">
+  <li class="list-group-item">
+    Cras justo odio
+    <span class="badge badge-primary badge-pill">14</span>
+  </li>
+  <li class="list-group-item">
+    Dapibus ac facilisis in
+    <span class="badge badge-primary badge-pill">2</span>
+  </li>
+  <li class="list-group-item">
+    Morbi leo risus
+    <span class="badge badge-primary badge-pill">1</span>
+  </li>
+</ul>
+
+
+
From a2a660e876b405737d337dd8a46bf3263ebc1dd2 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 18 Dec 2018 15:09:51 +0300 Subject: [PATCH 051/368] abp-modal tag helper improvements --- .../TagHelpers/Modal/AbpModalTagHelper.cs | 2 ++ .../TagHelpers/Modal/AbpModalTagHelperService.cs | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalTagHelper.cs index 5524f221ff..aa61832ab9 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalTagHelper.cs @@ -4,6 +4,8 @@ { public AbpModalSize Size { get; set; } = AbpModalSize.Default; + public bool? Centered { get; set; } = false; + public AbpModalTagHelper(AbpModalTagHelperService tagHelperService) : base(tagHelperService) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalTagHelperService.cs index 23453df1d0..8106db4661 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalTagHelperService.cs @@ -36,6 +36,12 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal { var classNames = new StringBuilder("modal-dialog"); + if (TagHelper.Centered ?? false) + { + classNames.Append(" "); + classNames.Append("modal-dialog-centered"); + } + if (TagHelper.Size != AbpModalSize.Default) { classNames.Append(" "); From 61cd8bd061018bdf276e33069f7c52a2065a3597 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 18 Dec 2018 15:10:01 +0300 Subject: [PATCH 052/368] modal tag helper docs --- .../Pages/Components/Modals.cshtml | 60 ++++++++++++++----- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Modals.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Modals.cshtml index 0a3aa3d8b9..b70e7faa26 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Modals.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Modals.cshtml @@ -15,34 +15,64 @@

Based on Bootstrap Modal.

-

# Modal Example

+

Example

- Launch modal - - - - + Launch modal + + - Body + Woohoo, you're reading this text in a modal! - - -
-
-<abp-modal id="myModal">
-   <abp-modal-header title="Header"></abp-modal-header>
+        
+            
+                

+<abp-button button-type="Primary" data-toggle="modal" data-target="#myModal">Launch modal</abp-button>
+
+<abp-modal centered="true" size="Large" id="myModal">
+   <abp-modal-header title="Modal title"></abp-modal-header>
    <abp-modal-body>
-       Body
+       Woohoo, you're reading this text in a modal!
    </abp-modal-body>
    <abp-modal-footer buttons="(AbpModalButtons.Save|AbpModalButtons.Close)"></abp-modal-footer>
 </abp-modal>
-
+
+ + +

+<!-- Button trigger modal -->
+<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
+  Launch demo modal
+</button>
+
+<!-- Modal -->
+<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
+  <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
+    <div class="modal-content">
+      <div class="modal-header">
+        <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
+        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+          <span aria-hidden="true">&times;</span>
+        </button>
+      </div>
+      <div class="modal-body">
+        ...
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
+        <button type="button" class="btn btn-primary">Save</button>
+      </div>
+    </div>
+  </div>
+</div>
+
+
+
From c8539e2a3cae3366db09d05536ad708dd9d682bb Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Tue, 18 Dec 2018 15:23:29 +0300 Subject: [PATCH 053/368] Added Application Modules document --- docs/en/Module-Development-Basics.md | 33 +++++++++++++++++----------- docs/en/Modules/Docs.md | 9 ++++++++ docs/en/Modules/Index.md | 26 ++++++++++++++++++++++ docs/en/docs-nav.json | 4 ++++ 4 files changed, 59 insertions(+), 13 deletions(-) create mode 100644 docs/en/Modules/Docs.md create mode 100644 docs/en/Modules/Index.md diff --git a/docs/en/Module-Development-Basics.md b/docs/en/Module-Development-Basics.md index 6e1c724669..6a0561a0c5 100644 --- a/docs/en/Module-Development-Basics.md +++ b/docs/en/Module-Development-Basics.md @@ -1,10 +1,10 @@ -## Module Development +# Module Development -### Introduction +## Introduction -ABP is itself a modular framework. It also provides an infrastructure and architectural model to develop your own modules. +ABP is a **modular application framework** which consists of dozens of **nuget packages**. It also provides a complete infrastructure to build your own application modules which may have entities, services, database integration, APIs, UI components and so on. -### Module Class +## Module Class Every module should define a module class. The simplest way of defining a module class is to create a class derived from ``AbpModule`` as shown below: @@ -16,9 +16,9 @@ public class BlogModule : AbpModule ```` -#### Configuring Dependency Injection & Other Modules +### Configuring Dependency Injection & Other Modules -##### ConfigureServices Method +#### ConfigureServices Method ``ConfigureServices`` is the main method to add your services to the dependency injection system and configure other modules. Example: @@ -52,15 +52,15 @@ public class BlogModule : AbpModule See Configuration (TODO: link) document for more about the configuration system. -##### Pre & Post Configure Services +#### Pre & Post Configure Services ``AbpModule`` class also defines ``PreConfigureServices`` and ``PostConfigureServices`` methods to override and write your code just before and just after ``ConfigureServices``. Notice that the code you have written into these methods will be executed before/after the ``ConfigureServices`` methods of all other modules. -#### Application Initialization +### Application Initialization Once all the services of all modules are configured, the application starts by initializing all modules. In this phase, you can resolve services from ``IServiceProvider`` since it's ready and available. -##### OnApplicationInitialization Method +#### OnApplicationInitialization Method You can override ``OnApplicationInitialization`` method to execute code while application is being started. Example: @@ -102,15 +102,15 @@ public class AppModule : AbpModule You can also perform startup logic if your module requires it -##### Pre & Post Application Initialization +#### Pre & Post Application Initialization ``AbpModule`` class also defines ``OnPreApplicationInitialization`` and ``OnPostApplicationInitialization`` methods to override and write your code just before and just after ``OnApplicationInitialization``. Notice that the code you have written into these methods will be executed before/after the ``OnApplicationInitialization`` methods of all other modules. -#### Application Shutdown +### Application Shutdown -Lastly, you can override ``OnApplicationShutdown`` method if you want to execute some code while application is beign shutdown. +Lastly, you can override ``OnApplicationShutdown`` method if you want to execute some code while application is being shutdown. -### Module Dependencies +## Module Dependencies In a modular application, it's not unusual for one module to depend upon another module(s). An Abp module must declare ``[DependsOn]`` attribute if it does have a dependcy upon another module, as shown below: @@ -126,3 +126,10 @@ public class BlogModule You can use multiple ``DependsOn`` attribute or pass multiple module types to a single ``DependsOn`` attribute depending on your preference. A depended module may depend on another module, but you only need to define your direct dependencies. ABP investigates the dependency graph for the application at startup and initializes/shutdowns modules in the correct order. + +## Framework Modules vs Application Modules + +There are **two types of modules.** They don't have any structural difference but categorized by functionality and purpose: + +- **Framework modules**: These are **core modules of the framework** like caching, emailing, theming, security, serialization, validation, EF Core integration, MongoDB integration... etc. They do not have application/business functionalities but makes your daily development easier by providing common infrastructure, integration and abstractions. +- **Application modules**: These modules implement **specific application/business functionalities** like blogging, document management, identity management, tenant management... etc. They generally have their own entities, services, APIs and UI components. See [pre-built application modules](Modules/Index.md). \ No newline at end of file diff --git a/docs/en/Modules/Docs.md b/docs/en/Modules/Docs.md new file mode 100644 index 0000000000..adfcd15453 --- /dev/null +++ b/docs/en/Modules/Docs.md @@ -0,0 +1,9 @@ +# Docs Module + +Docs module is used to create technical documentation pages. ABP's [own documentation](https://abp.io/documents/) already using this module. + +> Docs module follows the [module architecture best practices](../Best-Practices/Module-Architecture.md) guide. + +## Installation + +TODO... \ No newline at end of file diff --git a/docs/en/Modules/Index.md b/docs/en/Modules/Index.md new file mode 100644 index 0000000000..9dc5da7a99 --- /dev/null +++ b/docs/en/Modules/Index.md @@ -0,0 +1,26 @@ +# Application Modules + +ABP is a **modular application framework** which consists of dozens of **nuget packages**. It also provides a complete infrastructure to build your own application modules which may have entities, services, database integration, APIs, UI components and so on. + +There are **two types of modules.** They don't have any structural difference but categorized by functionality and purpose: + +* [**Framework modules**](https://github.com/abpframework/abp/tree/master/framework/src): These are **core modules of the framework** like caching, emailing, theming, security, serialization, validation, EF Core integration, MongoDB integration... etc. They do not have application/business functionalities but makes your daily development easier by providing common infrastructure, integration and abstractions. +* [**Application modules**](https://github.com/abpframework/abp/tree/master/modules): These modules implement specific application/business functionalities like blogging, document management, identity management, tenant management... etc. They generally have their own entities, services, APIs and UI components. + +## Open Source Application Modules + +There are some **free and open source** application modules developed and maintained by the ABP community: + +* **Account**: Used to make user login/register to the application. +* **Audit Logging**: Used to persist audit logs to a database. +* **Background Jobs**: Used to persist background jobs when using default background job manager. +* **Blogging**: Used to create fancy blogs. ABP's [own blog](https://abp.io/blog/abp/) already using this module. +* [**Docs**](Docs.md): Used to create technical documentation pages. ABP's [own documentation](https://abp.io/documents/) already using this module. +* **Identity**: Used to manage roles, users and their permissions. +* **Identity Server**: Integrates to IdentityServer4. +* **Permission Management**: Used to persist permissions. +* **Setting Management**: Used to persist settings. +* **Tenant Management**: Used to manage tenants for a [multi-tenant](../Multi-Tenancy.md) application. +* **Users**: Used the abstract users, so other modules can depend on this instead of the Identity module. + +Documenting the modules is in the progress. See [this repository](https://github.com/abpframework/abp/tree/master/modules) for source code of all modules. \ No newline at end of file diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 1060a715fc..ff05d3934a 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -246,6 +246,10 @@ } ] }, + { + "text": "Application Modules", + "path": "Modules/Index.md" + }, { "text": "Testing" }, From fa8aa1fe0675a20b4daf9613f9de72aaff2a45f9 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 18 Dec 2018 15:28:34 +0300 Subject: [PATCH 054/368] abp nav tag helper improvements --- .../TagHelpers/Nav/AbpNavItemTagHelper.cs | 2 -- .../TagHelpers/Nav/AbpNavItemTagHelperService.cs | 9 --------- .../TagHelpers/Nav/AbpNavLinkTagHelper.cs | 2 -- .../TagHelpers/Nav/AbpNavLinkTagHelperService.cs | 5 ----- 4 files changed, 18 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Nav/AbpNavItemTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Nav/AbpNavItemTagHelper.cs index e7655c6073..40f25951fe 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Nav/AbpNavItemTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Nav/AbpNavItemTagHelper.cs @@ -2,8 +2,6 @@ { public class AbpNavItemTagHelper : AbpTagHelper { - public bool? Active { get; set; } - public bool? Dropdown { get; set; } public AbpNavItemTagHelper(AbpNavItemTagHelperService tagHelperService) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Nav/AbpNavItemTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Nav/AbpNavItemTagHelperService.cs index b4e8575ac8..ced733272c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Nav/AbpNavItemTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Nav/AbpNavItemTagHelperService.cs @@ -11,7 +11,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Nav output.Attributes.AddClass("nav-item"); SetDropdownClass(context, output); - SetActiveClass(context, output); } protected virtual void SetDropdownClass(TagHelperContext context, TagHelperOutput output) @@ -21,13 +20,5 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Nav output.Attributes.AddClass("dropdown"); } } - - protected virtual void SetActiveClass(TagHelperContext context, TagHelperOutput output) - { - if (TagHelper.Active ?? false) - { - output.Attributes.AddClass("active"); - } - } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Nav/AbpNavLinkTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Nav/AbpNavLinkTagHelper.cs index 7809adc98b..1a534b5efb 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Nav/AbpNavLinkTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Nav/AbpNavLinkTagHelper.cs @@ -8,8 +8,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Nav public bool? Active { get; set; } public bool? Disabled { get; set; } - - public string Href { get; set; } public AbpNavLinkTagHelper(AbpNavLinkTagHelperService tagHelperService) : base(tagHelperService) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Nav/AbpNavLinkTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Nav/AbpNavLinkTagHelperService.cs index 48f4867662..75f4285530 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Nav/AbpNavLinkTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Nav/AbpNavLinkTagHelperService.cs @@ -13,11 +13,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Nav output.TagName = "a"; output.TagMode = TagMode.StartTagAndEndTag; SetClasses(context, output); - - if (!string.IsNullOrWhiteSpace(TagHelper.Href)) - { - output.Attributes.Add("href", TagHelper.Href); - } } protected virtual void SetClasses(TagHelperContext context, TagHelperOutput output) From 535e8b62c2b64fa3973d4304bd0b68fffe264ea1 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 18 Dec 2018 15:28:44 +0300 Subject: [PATCH 055/368] abp nav tag helper docs --- .../Pages/Components/Navs.cshtml | 171 ++++++++++++------ 1 file changed, 118 insertions(+), 53 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Navs.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Navs.cshtml index d351878652..47e1715932 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Navs.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Navs.cshtml @@ -14,14 +14,14 @@

Based on Bootstrap Navs.

-

# Navs Examples

+

Base nav

- Active + Active Longer nav link @@ -33,29 +33,51 @@ disabled -
-
-        <abp-nav nav-style="Pill" align="Center">
-            <abp-nav-item>
-                <a abp-nav-link Active="true" href="#">Active</a>
-            </abp-nav-item>
-            <abp-nav-item >
-                <a abp-nav-link  href="#">Longer nav link</a>
-            </abp-nav-item>
-            <abp-nav-item >
-                <a abp-nav-link  href="#">link</a>
-            </abp-nav-item>
-            <abp-nav-item >
-                <a abp-nav-link disabled="true" href="#">disabled</a>
-            </abp-nav-item>
-        </abp-nav>
-
+ + +

+
+<abp-nav nav-style="Pill" align="Center">
+    <abp-nav-item>
+<a abp-nav-link active="true" href="#">Active</a>
+    </abp-nav-item>
+    <abp-nav-item>
+<a abp-nav-link href="#">Longer nav link</a>
+    </abp-nav-item>
+    <abp-nav-item>
+<a abp-nav-link href="#">link</a>
+    </abp-nav-item>
+    <abp-nav-item>
+<a abp-nav-link disabled="true" href="#">disabled</a>
+    </abp-nav-item>
+</abp-nav>
+
+
+ +

+<ul class="nav justify-content-center nav-pills">
+   <li class="nav-item">
+       <a href="#" class="nav-link active">Active</a>
+   </li>
+   <li class="nav-item">
+       <a href="#" class="nav-link">Longer nav link</a>
+   </li>
+   <li class="nav-item">
+       <a href="#" class="nav-link">link</a>
+   </li>
+   <li class="nav-item">
+       <a href="#" class="nav-link disabled">disabled</a>
+   </li>
+</ul>
+
+
+
-

# Navs Examples

+

Base nav

@@ -92,42 +114,85 @@ -
-
-        <abp-nav-bar size="Lg" navbar-style="Dark_Warning">
-            <a abp-navbar-brand href="#">Navbar</a>
-            <abp-navbar-toggle>
-                <abp-navbar-nav>
-                    <abp-nav-item active="true">
-                        <a abp-nav-link href="#">Home <span class="sr-only">(current)</span></a>
-                    </abp-nav-item>
-                    <abp-nav-item>
-                        <a abp-nav-link href="#">Link</a>
-                    </abp-nav-item>
-                    <abp-nav-item dropdown="true">
-                        <abp-dropdown>
-                            <abp-dropdown-button nav-link="true" text="Dropdown" />
-                            <abp-dropdown-menu>
-                                <abp-dropdown-header>Dropdown header</abp-dropdown-header>
-                                <abp-dropdown-item href="#" active="true">Action</abp-dropdown-item>
-                                <abp-dropdown-item href="#" disabled="true">Another disabled action</abp-dropdown-item>
-                                <abp-dropdown-item href="#">Something else here</abp-dropdown-item>
-                                <abp-dropdown-divider />
-                                <abp-dropdown-item href="#">Separated link</abp-dropdown-item>
-                            </abp-dropdown-menu>
-                        </abp-dropdown>
-                    </abp-nav-item>
-                    <abp-nav-item>
-                        <a abp-nav-link disabled="true" href="#">Disabled</a>
-                    </abp-nav-item>
-                </abp-navbar-nav>            
-            <span abp-navbar-text>
+        
+            
+                

+
+<abp-nav-bar size="Lg" navbar-style="Dark_Warning">
+    <a abp-navbar-brand href="#">Navbar</a>
+    <abp-navbar-toggle>
+        <abp-navbar-nav>
+            <abp-nav-item active="true">
+                <a abp-nav-link href="#">Home <span class="sr-only">(current)</span></a>
+            </abp-nav-item>
+            <abp-nav-item>
+                <a abp-nav-link href="#">Link</a>
+            </abp-nav-item>
+            <abp-nav-item dropdown="true">
+                <abp-dropdown>
+                    <abp-dropdown-button nav-link="true" text="Dropdown" />
+                    <abp-dropdown-menu>
+                        <abp-dropdown-header>Dropdown header</abp-dropdown-header>
+                        <abp-dropdown-item href="#" active="true">Action</abp-dropdown-item>
+                        <abp-dropdown-item href="#" disabled="true">Another disabled action</abp-dropdown-item>
+                        <abp-dropdown-item href="#">Something else here</abp-dropdown-item>
+                        <abp-dropdown-divider />
+                        <abp-dropdown-item href="#">Separated link</abp-dropdown-item>
+                    </abp-dropdown-menu>
+                </abp-dropdown>
+            </abp-nav-item>
+            <abp-nav-item>
+                <a abp-nav-link disabled="true" href="#">Disabled</a>
+            </abp-nav-item>
+        </abp-navbar-nav>            
+        <span abp-navbar-text>
+          Sample Text
+        </span>
+    </abp-navbar-toggle>
+</abp-nav-bar>
+
+
+ +

+<nav class="navbar navbar-expand-lg navbar-dark bg-warning">
+    <a href="#" class="navbar-brand">Navbar</a>
+    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#13da550319ec478099dd4c9c3efb3d09" aria-controls="13da550319ec478099dd4c9c3efb3d09" aria-expanded="false" aria-label="Toggle navigation">
+    <span class="navbar-toggler-icon"></span>
+    </button><div class="collapse navbar-collapse" id="13da550319ec478099dd4c9c3efb3d09">
+        <ul class="navbar-nav">
+            <li active="true" class="nav-item">
+                <a href="#" class="nav-link">Home <span class="sr-only">(current)</span></a>
+            </li>
+            <li class="nav-item">
+                <a href="#" class="nav-link">Link</a>
+            </li>
+            <li class="nav-item dropdown">
+                <div class="btn-group">
+                    <a class="dropdown-toggle btn nav-link" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-busy-text="Processing..." roles="button" href="#"><span>Dropdown</span></a>
+                    <div></div>
+                    <div class="dropdown-menu">
+                        <h6 class="dropdown-header">Dropdown header</h6>
+                        <a href="#" class="dropdown-item active">Action</a>
+                        <a href="#" class="dropdown-item disabled">Another disabled action</a>
+                        <a href="#" class="dropdown-item">Something else here</a>
+                        <div class="dropdown-divider"></div>
+                        <a href="#" class="dropdown-item">Separated link</a>
+                    </div>
+                </div>
+            </li>
+            <li class="nav-item">
+                <a href="#" class="nav-link disabled">Disabled</a>
+            </li>
+            <span class="navbar-text">
                  Sample Text
             </span>
-            </abp-navbar-toggle>
-        </abp-nav-bar>
-
+ </ul> + </div> +</nav> +
+ +
From de0cb6b8ccc6eb300e8465d7bbe7a54f56f46afb Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Tue, 18 Dec 2018 15:41:49 +0300 Subject: [PATCH 056/368] Create intro document --- .../Getting-Started-AspNetCore-Application.md | 2 +- ...Getting-Started-AspNetCore-MVC-Template.md | 2 + docs/en/Index.md | 90 ++++++------------- 3 files changed, 31 insertions(+), 63 deletions(-) diff --git a/docs/en/Getting-Started-AspNetCore-Application.md b/docs/en/Getting-Started-AspNetCore-Application.md index 8c0d03b6bb..fe1ff3450b 100644 --- a/docs/en/Getting-Started-AspNetCore-Application.md +++ b/docs/en/Getting-Started-AspNetCore-Application.md @@ -1,6 +1,6 @@ # Getting Started ABP With AspNet Core MVC Web Application -This tutorial explains how to start ABP from scratch with minimal dependencies. You generally want to start with a **[startup template](https://abp.io/Templates)**. +This tutorial explains how to start ABP from scratch with minimal dependencies. You generally want to start with the **[startup template](Getting-Started-AspNetCore-MVC-Template.md)**. ## Create A New Project diff --git a/docs/en/Getting-Started-AspNetCore-MVC-Template.md b/docs/en/Getting-Started-AspNetCore-MVC-Template.md index 665cec98b1..de9a5b09cb 100644 --- a/docs/en/Getting-Started-AspNetCore-MVC-Template.md +++ b/docs/en/Getting-Started-AspNetCore-MVC-Template.md @@ -1,5 +1,7 @@ ## ASP.NET Core MVC Template +This tutorials explains how to create a new ASP.NET Core MVC web application using the startup template, configure and run it. + ### Creating a new project Go to [the template creation page](https://abp.io/Templates), enter a project name and create your project as shown below: diff --git a/docs/en/Index.md b/docs/en/Index.md index 18df429102..df0cab524a 100644 --- a/docs/en/Index.md +++ b/docs/en/Index.md @@ -1,64 +1,30 @@ # ABP Documentation -* Getting Started - * From Startup Templates - * [ASP.NET Core MVC Template](Getting-Started-AspNetCore-MVC-Template.md) - * From Empty Projects - * [With Console Application](Getting-Started-Console-Application.md) - * [With ASP.NET Core Web Application](Getting-Started-AspNetCore-Application.md) -* Tutorials - * Application Development - * [With ASP.NET Core MVC](Tutorials/AspNetCore-Mvc/Part-I.md) -* Fundamentals - * [Dependency Injection](Dependency-Injection.md) - * [AutoFac Integration](Autofac-Integration.md) - * [Virtual File System](Virtual-File-System.md) - * [Localization](Localization.md) - * [Exception Handling](Exception-Handling.md) - * Validation - * Authorization - * Caching - * Auditing - * Setting Management - * Object to Object Mapping - * AutoMapper Integration -* Events - * Event Bus (local) - * Distributed Event Bus - * RabbitMQ Integration -* Services - * Object Serialization - * JSON Serialization - * Emailing - * GUIDs - * Threading - * Timing -* [Multi Tenancy](Multi-Tenancy.md) -* Module Development - * [Basics](Module-Development-Basics.md) - * Plug-In Modules - * [Best Practices](Best-Practices/Index.md) -* Domain Driven Design - * Domain Layer - * [Entities & Aggregate Roots](Entities.md) - * Value Objects - * [Repositories](Repositories.md) - * Domain Services - * Specifications - * Application Layer - * Application Services - * Data Transfer Objects - * Unit Of Work -* ASP.NET Core MVC - * API Versioning - * User Interface - * [Client Side Package Management](AspNetCore/Client-Side-Package-Management.md) - * [Bundling & Minification](AspNetCore/Bundling-Minification.md) - * [Tag Helpers](Tag-Helpers.md) - * [Theming](AspNetCore/Theming.md) -* Data Access - * [Entity Framework Core Integration](Entity-Framework-Core.md) - * [MongoDB Integration](MongoDB.md) -* Background - * [Background Jobs](Background-Jobs.md) -* Testing +ABP is an **open source application framework** focused on ASP.NET Core based web application development, but also supports developing other types of applications. + +Explore the left navigation menu to deep dive in the documentation. + +## Project Status + +ABP is the **next generation** of the open source [ASP.NET Boilerplate](https://aspnetboilerplate.com/) framework. It's currently in early preview stage and not ready to use in production. The documentation is in progress and currently is very incomplete. + +For short-term and production applications, it's suggested to use the [ASP.NET Boilerplate](https://aspnetboilerplate.com/) framework which is feature rich, mature, maintained and up-to-date. + +## Getting Started + +Easiest way to start a new project with ABP is to use the Startup templates: + +* [ASP.NET Core MVC Template](Getting-Started-AspNetCore-MVC-Template.md) + +If you want to start from scratch (with an empty project) then manually install the ABP framework, use following tutorials: + +* [Console Application](Getting-Started-Console-Application.md) +* [ASP.NET Core Web Application](Getting-Started-AspNetCore-Application.md) + +## Source Code + +ABP is being developed on GitHub. See [the source code](https://github.com/abpframework/abp). + +## Want to Contribute? + +ABP is a community-driven open source project. See [the contribution guide](Contribution/Index.md) if you want to be a part of this project. \ No newline at end of file From eac22841e9e6862f989b34399529c438fd808e5e Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 18 Dec 2018 15:41:56 +0300 Subject: [PATCH 057/368] tag helper demos added missin css and js --- .../Pages/Components/Carousel.cshtml | 15 ++++++++++++++- .../Pages/Components/Collapse.cshtml | 17 +++++++++++++++-- .../Pages/Components/Modals.cshtml | 13 +++++++++++++ .../Pages/Components/Navs.cshtml | 13 +++++++++++++ 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Carousel.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Carousel.cshtml index 712fc37882..d8b0e9d486 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Carousel.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Carousel.cshtml @@ -10,6 +10,19 @@ } +@section scripts { + + @* + *@ + +} + + + + + +

Carousels

Based on Bootstrap Carousel.

@@ -20,7 +33,7 @@
- + diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Collapse.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Collapse.cshtml index fa0fd4d815..6a9aeb90ca 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Collapse.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Collapse.cshtml @@ -11,6 +11,19 @@ } + +@section scripts { + + @* + *@ + +} + + + + +

Collapse

Based on Bootstrap Collapse.

@@ -69,11 +82,11 @@ Toggle first element - + - 3Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. + 3Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Modals.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Modals.cshtml index b70e7faa26..74116488ad 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Modals.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Modals.cshtml @@ -11,6 +11,19 @@ } +@section scripts { + + @* + *@ + +} + + + + + +

Modals

Based on Bootstrap Modal.

diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Navs.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Navs.cshtml index 47e1715932..80a0b24c31 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Navs.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Navs.cshtml @@ -10,6 +10,19 @@ } +@section scripts { + + @* + *@ + +} + + + + + +

Navs

Based on Bootstrap Navs.

From bf0c311361d9771f630f48994615fee4fea47244 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 18 Dec 2018 15:42:11 +0300 Subject: [PATCH 058/368] Paginator tag helper demo --- .../Pages/Components/Paginator.cshtml | 107 ++++++++++++++---- .../Pages/Components/Paginator.cshtml.cs | 7 +- 2 files changed, 87 insertions(+), 27 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Paginator.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Paginator.cshtml index bcf117945c..b7a567beae 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Paginator.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Paginator.cshtml @@ -10,34 +10,99 @@ } -

Paginator

+@section scripts { + + @* + *@ + +} -

# Paginator Examples

+ + + -
-
- +

Paginator

+ + +

Example

-
-
-
-<abp-paginator model="Model.PagerModel"/>
-
-
-
-
-
-
- -
-
-<abp-paginator model="Model.PagerModel" show-info="true"/>
-
+ + +

+using Microsoft.AspNetCore.Mvc.RazorPages;
+using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Pagination;
+
+namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components
+{
+    public class PaginatorModel : PageModel
+    {
+        public PagerModel PagerModel { get; set; }
+
+        public void OnGet(int currentPage, string sort)
+        {
+            PagerModel = new PagerModel(100, 10, currentPage, 10, "Paginator", sort);
+        }
+    }
+}
+
+
+ +

+<abp-paginator model="Model.PagerModel" show-info="true" />
+
+
+ +

+<div class="row mt-3">    
+    <div class="col-sm-12 col-md-5">
+        Showing 80 to 90 of 100 entries.
+    </div>
+    <div class="col-sm-12 col-md-7">
+        <nav aria-label="Page navigation">
+            <ul class="pagination justify-localizationKey-end">
+                <li class="page-item ">
+                    <a tabindex="-1" class="page-link" href="/Components/Paginator?currentPage=7">Previous</a>
+                </li>
+                <li class="page-item ">
+                    <a tabindex="-1" class="page-link" href="/Components/Paginator?currentPage=1">1</a>
+                </li>
+                <li class="page-item ">
+                    <a tabindex="-1" class="page-link" href="/Components/Paginator?currentPage=2">2</a>
+                </li>
+                <li class="page-item ">
+                    <span class="page-link gap">…</span>
+                </li>
+                <li class="page-item ">
+                    <a tabindex="-1" class="page-link" href="/Components/Paginator?currentPage=7">7</a>
+                </li>
+                <li class="page-item active">
+                     <span class="page-link">
+                        8
+                        <span class="sr-only">(current)</span>
+                     </span>
+                </li>
+                <li class="page-item ">
+                    <a tabindex="-1" class="page-link" href="/Components/Paginator?currentPage=9">9</a>
+                </li>
+                <li class="page-item ">
+                    <a tabindex="-1" class="page-link" href="/Components/Paginator?currentPage=10">10</a>
+                </li>
+                <li class="page-item ">
+                    <a tabindex="-1" class="page-link" href="/Components/Paginator?currentPage=9">Next</a>
+                </li>
+            </ul>
+         <!-- nav-->
+    </nav></div>
+</div>
+
+
+
-
+
\ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Paginator.cshtml.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Paginator.cshtml.cs index 40afff2016..15b31db6da 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Paginator.cshtml.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Paginator.cshtml.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.AspNetCore.Mvc.RazorPages; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Pagination; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components From 25def1ee76dbacdae6010188b00e1e61b72b3ca7 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 18 Dec 2018 15:54:04 +0300 Subject: [PATCH 059/368] Popover tag helper docs --- .../Pages/Components/Popovers.cshtml | 60 ++++++++++++++----- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Popovers.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Popovers.cshtml index f9563a5c8b..7f43407831 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Popovers.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Popovers.cshtml @@ -1,7 +1,7 @@ @page @model Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components.PopoversModel @{ - ViewData["Title"] = "Badges"; + ViewData["Title"] = "Popovers"; } @section styles { @@ -10,11 +10,25 @@ } +@section scripts { + + @* + *@ + +} + + + + + +

Popovers

Based on Bootstrap Popovers.

-

# Popovers Examples

+ +

Example

@@ -31,23 +45,41 @@ Disabled Popover -
-
-<abp-button abp-popover="Hi, i'm popover content!">
-   Popover Default
+        
+            
+                

+<abp-button abp-popover="Hi, i'm popover content!">
+       Popover Default
 </abp-button>
-<abp-button abp-popover-top="Hi, i'm popover content!" title="Popover Title">
-   Popover With Title
+<abp-button abp-popover-top="Hi, i'm popover content!" title="Popover Title">
+       Popover With Title
 </abp-button>
-<abp-button abp-popover-right="Hi, i'm popover content!" title="Popover Title" dismissible="true">
-   Dismissible Popover
+<abp-button abp-popover-right="Hi, i'm popover content!" title="Popover Title" dismissible="true">
+       Dismissible Popover
 </abp-button>
-<abp-button abp-popover-left="Hi, i'm popover content!" title="Popover Title" disabled="true">
-   Disabled Popover
+<abp-button abp-popover-left="Hi, i'm popover content!" title="Popover Title" disabled="true">
+       Disabled Popover
 </abp-button>
-
+
+ + +

+<button class="btn" type="button" data-busy-text="Processing..." data-toggle="popover" data-placement="bottom" data-content="Hi, i'm popover content!" data-original-title="" title="">
+      Popover Default
+</button>
+<button title="" class="btn" type="button" data-busy-text="Processing..." data-toggle="popover" data-placement="top" data-content="Hi, i'm popover content!" data-original-title="Popover Title">
+      Popover With Title
+</button>
+<button title="" class="btn" type="button" data-busy-text="Processing..." data-toggle="popover" data-placement="right" data-content="Hi, i'm popover content!" data-trigger="focus" data-original-title="Popover Title">
+      Dismissible Popover
+</button>
+<span class="d-inline-block" title="" data-placement="left" data-toggle="popover" data-content="Hi, i'm popover content!" data-original-title="Popover Title"><button title="Popover Title" class="btn" type="button" data-busy-text="Processing..." style="pointer-events: none;">
+      Disabled Popover
+</button></span>
+
+
+
- From b4f5559fc91ee75ac7e83dc6a6ce3f27f4d1446c Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Tue, 18 Dec 2018 16:54:40 +0300 Subject: [PATCH 060/368] Fix migrations on startup templates for AuditLogId duplication (see #652). --- ....cs => 20181218134206_Initial.Designer.cs} | 2 +- ...4_Initial.cs => 20181218134206_Initial.cs} | 0 ...MyCompanyName.MyProjectName.DemoApp.csproj | 4 +++ ....cs => 20181218134025_Initial.Designer.cs} | 22 ++----------- ...6_Initial.cs => 20181218134025_Initial.cs} | 32 +++---------------- .../MyProjectNameDbContextModelSnapshot.cs | 20 ++---------- ...e.MyProjectName.EntityFrameworkCore.csproj | 2 ++ .../IdentityServerHost.csproj | 4 +++ ....cs => 20181218135354_Initial.Designer.cs} | 2 +- ...4_Initial.cs => 20181218135354_Initial.cs} | 0 ....cs => 20181218135310_Initial.Designer.cs} | 22 ++----------- ...2_Initial.cs => 20181218135310_Initial.cs} | 28 ++-------------- .../DemoAppDbContextModelSnapshot.cs | 20 ++---------- .../MyCompanyName.MyProjectName.Host.csproj | 4 +++ 14 files changed, 32 insertions(+), 130 deletions(-) rename templates/module/app/MyCompanyName.MyProjectName.DemoApp/Migrations/{20181212114934_Initial.Designer.cs => 20181218134206_Initial.Designer.cs} (99%) rename templates/module/app/MyCompanyName.MyProjectName.DemoApp/Migrations/{20181212114934_Initial.cs => 20181218134206_Initial.cs} (100%) rename templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/{20181212113826_Initial.Designer.cs => 20181218134025_Initial.Designer.cs} (97%) rename templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/{20181212113826_Initial.cs => 20181218134025_Initial.cs} (95%) rename templates/service/host/IdentityServerHost/Migrations/{20181212121034_Initial.Designer.cs => 20181218135354_Initial.Designer.cs} (99%) rename templates/service/host/IdentityServerHost/Migrations/{20181212121034_Initial.cs => 20181218135354_Initial.cs} (100%) rename templates/service/host/MyCompanyName.MyProjectName.Host/Migrations/{20181212121232_Initial.Designer.cs => 20181218135310_Initial.Designer.cs} (94%) rename templates/service/host/MyCompanyName.MyProjectName.Host/Migrations/{20181212121232_Initial.cs => 20181218135310_Initial.cs} (89%) diff --git a/templates/module/app/MyCompanyName.MyProjectName.DemoApp/Migrations/20181212114934_Initial.Designer.cs b/templates/module/app/MyCompanyName.MyProjectName.DemoApp/Migrations/20181218134206_Initial.Designer.cs similarity index 99% rename from templates/module/app/MyCompanyName.MyProjectName.DemoApp/Migrations/20181212114934_Initial.Designer.cs rename to templates/module/app/MyCompanyName.MyProjectName.DemoApp/Migrations/20181218134206_Initial.Designer.cs index 9f8a2b4adf..3ab0c0721f 100644 --- a/templates/module/app/MyCompanyName.MyProjectName.DemoApp/Migrations/20181212114934_Initial.Designer.cs +++ b/templates/module/app/MyCompanyName.MyProjectName.DemoApp/Migrations/20181218134206_Initial.Designer.cs @@ -10,7 +10,7 @@ using MyCompanyName.MyProjectName.DemoApp; namespace MyCompanyName.MyProjectName.DemoApp.Migrations { [DbContext(typeof(DemoAppDbContext))] - [Migration("20181212114934_Initial")] + [Migration("20181218134206_Initial")] partial class Initial { protected override void BuildTargetModel(ModelBuilder modelBuilder) diff --git a/templates/module/app/MyCompanyName.MyProjectName.DemoApp/Migrations/20181212114934_Initial.cs b/templates/module/app/MyCompanyName.MyProjectName.DemoApp/Migrations/20181218134206_Initial.cs similarity index 100% rename from templates/module/app/MyCompanyName.MyProjectName.DemoApp/Migrations/20181212114934_Initial.cs rename to templates/module/app/MyCompanyName.MyProjectName.DemoApp/Migrations/20181218134206_Initial.cs diff --git a/templates/module/app/MyCompanyName.MyProjectName.DemoApp/MyCompanyName.MyProjectName.DemoApp.csproj b/templates/module/app/MyCompanyName.MyProjectName.DemoApp/MyCompanyName.MyProjectName.DemoApp.csproj index c42f5f663c..2ec0453f90 100644 --- a/templates/module/app/MyCompanyName.MyProjectName.DemoApp/MyCompanyName.MyProjectName.DemoApp.csproj +++ b/templates/module/app/MyCompanyName.MyProjectName.DemoApp/MyCompanyName.MyProjectName.DemoApp.csproj @@ -33,4 +33,8 @@ + + + + diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20181212113826_Initial.Designer.cs b/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20181218134025_Initial.Designer.cs similarity index 97% rename from templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20181212113826_Initial.Designer.cs rename to templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20181218134025_Initial.Designer.cs index 8afbe89363..7821feff86 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20181212113826_Initial.Designer.cs +++ b/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20181218134025_Initial.Designer.cs @@ -11,7 +11,7 @@ using Volo.Abp.BackgroundJobs; namespace MyCompanyName.MyProjectName.Migrations { [DbContext(typeof(MyProjectNameDbContext))] - [Migration("20181212113826_Initial")] + [Migration("20181218134025_Initial")] partial class Initial { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -101,8 +101,6 @@ namespace MyCompanyName.MyProjectName.Migrations b.Property("AuditLogId") .HasColumnName("AuditLogId"); - b.Property("AuditLogId1"); - b.Property("ExecutionDuration") .HasColumnName("ExecutionDuration"); @@ -130,8 +128,6 @@ namespace MyCompanyName.MyProjectName.Migrations b.HasIndex("AuditLogId"); - b.HasIndex("AuditLogId1"); - b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime"); b.ToTable("AbpAuditLogActions"); @@ -145,8 +141,6 @@ namespace MyCompanyName.MyProjectName.Migrations b.Property("AuditLogId") .HasColumnName("AuditLogId"); - b.Property("AuditLogId1"); - b.Property("ChangeTime") .HasColumnName("ChangeTime"); @@ -173,8 +167,6 @@ namespace MyCompanyName.MyProjectName.Migrations b.HasIndex("AuditLogId"); - b.HasIndex("AuditLogId1"); - b.HasIndex("TenantId", "EntityTypeFullName", "EntityId"); b.ToTable("AbpEntityChanges"); @@ -608,25 +600,17 @@ namespace MyCompanyName.MyProjectName.Migrations modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => { b.HasOne("Volo.Abp.AuditLogging.AuditLog") - .WithMany() + .WithMany("Actions") .HasForeignKey("AuditLogId") .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("Volo.Abp.AuditLogging.AuditLog") - .WithMany("Actions") - .HasForeignKey("AuditLogId1"); }); modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => { b.HasOne("Volo.Abp.AuditLogging.AuditLog") - .WithMany() + .WithMany("EntityChanges") .HasForeignKey("AuditLogId") .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("Volo.Abp.AuditLogging.AuditLog") - .WithMany("EntityChanges") - .HasForeignKey("AuditLogId1"); }); modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20181212113826_Initial.cs b/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20181218134025_Initial.cs similarity index 95% rename from templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20181212113826_Initial.cs rename to templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20181218134025_Initial.cs index 5dd6559191..1f76a505a8 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20181212113826_Initial.cs +++ b/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20181218134025_Initial.cs @@ -12,6 +12,7 @@ namespace MyCompanyName.MyProjectName.Migrations columns: table => new { Id = table.Column(nullable: false), + ExtraProperties = table.Column(nullable: true), ConcurrencyStamp = table.Column(nullable: true), UserId = table.Column(nullable: true), UserName = table.Column(maxLength: 256, nullable: true), @@ -27,8 +28,7 @@ namespace MyCompanyName.MyProjectName.Migrations Url = table.Column(maxLength: 256, nullable: true), Exceptions = table.Column(maxLength: 4000, nullable: true), Comments = table.Column(maxLength: 256, nullable: true), - HttpStatusCode = table.Column(nullable: true), - ExtraProperties = table.Column(nullable: true) + HttpStatusCode = table.Column(nullable: true) }, constraints: table => { @@ -173,8 +173,7 @@ namespace MyCompanyName.MyProjectName.Migrations Parameters = table.Column(maxLength: 2000, nullable: true), ExecutionTime = table.Column(nullable: false), ExecutionDuration = table.Column(nullable: false), - ExtraProperties = table.Column(nullable: true), - AuditLogId1 = table.Column(nullable: true) + ExtraProperties = table.Column(nullable: true) }, constraints: table => { @@ -185,12 +184,6 @@ namespace MyCompanyName.MyProjectName.Migrations principalTable: "AbpAuditLogs", principalColumn: "Id", onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_AbpAuditLogActions_AbpAuditLogs_AuditLogId1", - column: x => x.AuditLogId1, - principalTable: "AbpAuditLogs", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); }); migrationBuilder.CreateTable( @@ -204,8 +197,7 @@ namespace MyCompanyName.MyProjectName.Migrations ChangeType = table.Column(nullable: false), EntityId = table.Column(maxLength: 128, nullable: false), EntityTypeFullName = table.Column(maxLength: 128, nullable: false), - ExtraProperties = table.Column(nullable: true), - AuditLogId1 = table.Column(nullable: true) + ExtraProperties = table.Column(nullable: true) }, constraints: table => { @@ -216,12 +208,6 @@ namespace MyCompanyName.MyProjectName.Migrations principalTable: "AbpAuditLogs", principalColumn: "Id", onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_AbpEntityChanges_AbpAuditLogs_AuditLogId1", - column: x => x.AuditLogId1, - principalTable: "AbpAuditLogs", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); }); migrationBuilder.CreateTable( @@ -368,11 +354,6 @@ namespace MyCompanyName.MyProjectName.Migrations table: "AbpAuditLogActions", column: "AuditLogId"); - migrationBuilder.CreateIndex( - name: "IX_AbpAuditLogActions_AuditLogId1", - table: "AbpAuditLogActions", - column: "AuditLogId1"); - migrationBuilder.CreateIndex( name: "IX_AbpAuditLogActions_TenantId_ServiceName_MethodName_ExecutionTime", table: "AbpAuditLogActions", @@ -398,11 +379,6 @@ namespace MyCompanyName.MyProjectName.Migrations table: "AbpEntityChanges", column: "AuditLogId"); - migrationBuilder.CreateIndex( - name: "IX_AbpEntityChanges_AuditLogId1", - table: "AbpEntityChanges", - column: "AuditLogId1"); - migrationBuilder.CreateIndex( name: "IX_AbpEntityChanges_TenantId_EntityTypeFullName_EntityId", table: "AbpEntityChanges", diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/MyProjectNameDbContextModelSnapshot.cs b/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/MyProjectNameDbContextModelSnapshot.cs index 8a05ab5bc3..2ff93f8fde 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/MyProjectNameDbContextModelSnapshot.cs +++ b/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/MyProjectNameDbContextModelSnapshot.cs @@ -99,8 +99,6 @@ namespace MyCompanyName.MyProjectName.Migrations b.Property("AuditLogId") .HasColumnName("AuditLogId"); - b.Property("AuditLogId1"); - b.Property("ExecutionDuration") .HasColumnName("ExecutionDuration"); @@ -128,8 +126,6 @@ namespace MyCompanyName.MyProjectName.Migrations b.HasIndex("AuditLogId"); - b.HasIndex("AuditLogId1"); - b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime"); b.ToTable("AbpAuditLogActions"); @@ -143,8 +139,6 @@ namespace MyCompanyName.MyProjectName.Migrations b.Property("AuditLogId") .HasColumnName("AuditLogId"); - b.Property("AuditLogId1"); - b.Property("ChangeTime") .HasColumnName("ChangeTime"); @@ -171,8 +165,6 @@ namespace MyCompanyName.MyProjectName.Migrations b.HasIndex("AuditLogId"); - b.HasIndex("AuditLogId1"); - b.HasIndex("TenantId", "EntityTypeFullName", "EntityId"); b.ToTable("AbpEntityChanges"); @@ -606,25 +598,17 @@ namespace MyCompanyName.MyProjectName.Migrations modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => { b.HasOne("Volo.Abp.AuditLogging.AuditLog") - .WithMany() + .WithMany("Actions") .HasForeignKey("AuditLogId") .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("Volo.Abp.AuditLogging.AuditLog") - .WithMany("Actions") - .HasForeignKey("AuditLogId1"); }); modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => { b.HasOne("Volo.Abp.AuditLogging.AuditLog") - .WithMany() + .WithMany("EntityChanges") .HasForeignKey("AuditLogId") .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("Volo.Abp.AuditLogging.AuditLog") - .WithMany("EntityChanges") - .HasForeignKey("AuditLogId1"); }); modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/MyCompanyName.MyProjectName.EntityFrameworkCore.csproj b/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/MyCompanyName.MyProjectName.EntityFrameworkCore.csproj index c393a58161..877987ae14 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/MyCompanyName.MyProjectName.EntityFrameworkCore.csproj +++ b/templates/mvc/src/MyCompanyName.MyProjectName.EntityFrameworkCore/MyCompanyName.MyProjectName.EntityFrameworkCore.csproj @@ -7,6 +7,8 @@ + + diff --git a/templates/service/host/IdentityServerHost/IdentityServerHost.csproj b/templates/service/host/IdentityServerHost/IdentityServerHost.csproj index 5dc44682e9..f2b60aba11 100644 --- a/templates/service/host/IdentityServerHost/IdentityServerHost.csproj +++ b/templates/service/host/IdentityServerHost/IdentityServerHost.csproj @@ -25,4 +25,8 @@ + + + + diff --git a/templates/service/host/IdentityServerHost/Migrations/20181212121034_Initial.Designer.cs b/templates/service/host/IdentityServerHost/Migrations/20181218135354_Initial.Designer.cs similarity index 99% rename from templates/service/host/IdentityServerHost/Migrations/20181212121034_Initial.Designer.cs rename to templates/service/host/IdentityServerHost/Migrations/20181218135354_Initial.Designer.cs index 63b2af58a7..757aa9d169 100644 --- a/templates/service/host/IdentityServerHost/Migrations/20181212121034_Initial.Designer.cs +++ b/templates/service/host/IdentityServerHost/Migrations/20181218135354_Initial.Designer.cs @@ -10,7 +10,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace IdentityServerHost.Migrations { [DbContext(typeof(DemoAppDbContext))] - [Migration("20181212121034_Initial")] + [Migration("20181218135354_Initial")] partial class Initial { protected override void BuildTargetModel(ModelBuilder modelBuilder) diff --git a/templates/service/host/IdentityServerHost/Migrations/20181212121034_Initial.cs b/templates/service/host/IdentityServerHost/Migrations/20181218135354_Initial.cs similarity index 100% rename from templates/service/host/IdentityServerHost/Migrations/20181212121034_Initial.cs rename to templates/service/host/IdentityServerHost/Migrations/20181218135354_Initial.cs diff --git a/templates/service/host/MyCompanyName.MyProjectName.Host/Migrations/20181212121232_Initial.Designer.cs b/templates/service/host/MyCompanyName.MyProjectName.Host/Migrations/20181218135310_Initial.Designer.cs similarity index 94% rename from templates/service/host/MyCompanyName.MyProjectName.Host/Migrations/20181212121232_Initial.Designer.cs rename to templates/service/host/MyCompanyName.MyProjectName.Host/Migrations/20181218135310_Initial.Designer.cs index 1644e14900..67977b2f6a 100644 --- a/templates/service/host/MyCompanyName.MyProjectName.Host/Migrations/20181212121232_Initial.Designer.cs +++ b/templates/service/host/MyCompanyName.MyProjectName.Host/Migrations/20181218135310_Initial.Designer.cs @@ -10,7 +10,7 @@ using MyCompanyName.MyProjectName.Host; namespace MyCompanyName.MyProjectName.Host.Migrations { [DbContext(typeof(DemoAppDbContext))] - [Migration("20181212121232_Initial")] + [Migration("20181218135310_Initial")] partial class Initial { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -100,8 +100,6 @@ namespace MyCompanyName.MyProjectName.Host.Migrations b.Property("AuditLogId") .HasColumnName("AuditLogId"); - b.Property("AuditLogId1"); - b.Property("ExecutionDuration") .HasColumnName("ExecutionDuration"); @@ -129,8 +127,6 @@ namespace MyCompanyName.MyProjectName.Host.Migrations b.HasIndex("AuditLogId"); - b.HasIndex("AuditLogId1"); - b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime"); b.ToTable("AbpAuditLogActions"); @@ -144,8 +140,6 @@ namespace MyCompanyName.MyProjectName.Host.Migrations b.Property("AuditLogId") .HasColumnName("AuditLogId"); - b.Property("AuditLogId1"); - b.Property("ChangeTime") .HasColumnName("ChangeTime"); @@ -172,8 +166,6 @@ namespace MyCompanyName.MyProjectName.Host.Migrations b.HasIndex("AuditLogId"); - b.HasIndex("AuditLogId1"); - b.HasIndex("TenantId", "EntityTypeFullName", "EntityId"); b.ToTable("AbpEntityChanges"); @@ -272,25 +264,17 @@ namespace MyCompanyName.MyProjectName.Host.Migrations modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => { b.HasOne("Volo.Abp.AuditLogging.AuditLog") - .WithMany() + .WithMany("Actions") .HasForeignKey("AuditLogId") .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("Volo.Abp.AuditLogging.AuditLog") - .WithMany("Actions") - .HasForeignKey("AuditLogId1"); }); modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => { b.HasOne("Volo.Abp.AuditLogging.AuditLog") - .WithMany() + .WithMany("EntityChanges") .HasForeignKey("AuditLogId") .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("Volo.Abp.AuditLogging.AuditLog") - .WithMany("EntityChanges") - .HasForeignKey("AuditLogId1"); }); modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => diff --git a/templates/service/host/MyCompanyName.MyProjectName.Host/Migrations/20181212121232_Initial.cs b/templates/service/host/MyCompanyName.MyProjectName.Host/Migrations/20181218135310_Initial.cs similarity index 89% rename from templates/service/host/MyCompanyName.MyProjectName.Host/Migrations/20181212121232_Initial.cs rename to templates/service/host/MyCompanyName.MyProjectName.Host/Migrations/20181218135310_Initial.cs index c191391cc9..fd1c985c5d 100644 --- a/templates/service/host/MyCompanyName.MyProjectName.Host/Migrations/20181212121232_Initial.cs +++ b/templates/service/host/MyCompanyName.MyProjectName.Host/Migrations/20181218135310_Initial.cs @@ -77,8 +77,7 @@ namespace MyCompanyName.MyProjectName.Host.Migrations Parameters = table.Column(maxLength: 2000, nullable: true), ExecutionTime = table.Column(nullable: false), ExecutionDuration = table.Column(nullable: false), - ExtraProperties = table.Column(nullable: true), - AuditLogId1 = table.Column(nullable: true) + ExtraProperties = table.Column(nullable: true) }, constraints: table => { @@ -89,12 +88,6 @@ namespace MyCompanyName.MyProjectName.Host.Migrations principalTable: "AbpAuditLogs", principalColumn: "Id", onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_AbpAuditLogActions_AbpAuditLogs_AuditLogId1", - column: x => x.AuditLogId1, - principalTable: "AbpAuditLogs", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); }); migrationBuilder.CreateTable( @@ -108,8 +101,7 @@ namespace MyCompanyName.MyProjectName.Host.Migrations ChangeType = table.Column(nullable: false), EntityId = table.Column(maxLength: 128, nullable: false), EntityTypeFullName = table.Column(maxLength: 128, nullable: false), - ExtraProperties = table.Column(nullable: true), - AuditLogId1 = table.Column(nullable: true) + ExtraProperties = table.Column(nullable: true) }, constraints: table => { @@ -120,12 +112,6 @@ namespace MyCompanyName.MyProjectName.Host.Migrations principalTable: "AbpAuditLogs", principalColumn: "Id", onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_AbpEntityChanges_AbpAuditLogs_AuditLogId1", - column: x => x.AuditLogId1, - principalTable: "AbpAuditLogs", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); }); migrationBuilder.CreateTable( @@ -163,11 +149,6 @@ namespace MyCompanyName.MyProjectName.Host.Migrations table: "AbpAuditLogActions", column: "AuditLogId"); - migrationBuilder.CreateIndex( - name: "IX_AbpAuditLogActions_AuditLogId1", - table: "AbpAuditLogActions", - column: "AuditLogId1"); - migrationBuilder.CreateIndex( name: "IX_AbpAuditLogActions_TenantId_ServiceName_MethodName_ExecutionTime", table: "AbpAuditLogActions", @@ -188,11 +169,6 @@ namespace MyCompanyName.MyProjectName.Host.Migrations table: "AbpEntityChanges", column: "AuditLogId"); - migrationBuilder.CreateIndex( - name: "IX_AbpEntityChanges_AuditLogId1", - table: "AbpEntityChanges", - column: "AuditLogId1"); - migrationBuilder.CreateIndex( name: "IX_AbpEntityChanges_TenantId_EntityTypeFullName_EntityId", table: "AbpEntityChanges", diff --git a/templates/service/host/MyCompanyName.MyProjectName.Host/Migrations/DemoAppDbContextModelSnapshot.cs b/templates/service/host/MyCompanyName.MyProjectName.Host/Migrations/DemoAppDbContextModelSnapshot.cs index 69e2cc0ae2..c5e59b55fd 100644 --- a/templates/service/host/MyCompanyName.MyProjectName.Host/Migrations/DemoAppDbContextModelSnapshot.cs +++ b/templates/service/host/MyCompanyName.MyProjectName.Host/Migrations/DemoAppDbContextModelSnapshot.cs @@ -98,8 +98,6 @@ namespace MyCompanyName.MyProjectName.Host.Migrations b.Property("AuditLogId") .HasColumnName("AuditLogId"); - b.Property("AuditLogId1"); - b.Property("ExecutionDuration") .HasColumnName("ExecutionDuration"); @@ -127,8 +125,6 @@ namespace MyCompanyName.MyProjectName.Host.Migrations b.HasIndex("AuditLogId"); - b.HasIndex("AuditLogId1"); - b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime"); b.ToTable("AbpAuditLogActions"); @@ -142,8 +138,6 @@ namespace MyCompanyName.MyProjectName.Host.Migrations b.Property("AuditLogId") .HasColumnName("AuditLogId"); - b.Property("AuditLogId1"); - b.Property("ChangeTime") .HasColumnName("ChangeTime"); @@ -170,8 +164,6 @@ namespace MyCompanyName.MyProjectName.Host.Migrations b.HasIndex("AuditLogId"); - b.HasIndex("AuditLogId1"); - b.HasIndex("TenantId", "EntityTypeFullName", "EntityId"); b.ToTable("AbpEntityChanges"); @@ -270,25 +262,17 @@ namespace MyCompanyName.MyProjectName.Host.Migrations modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => { b.HasOne("Volo.Abp.AuditLogging.AuditLog") - .WithMany() + .WithMany("Actions") .HasForeignKey("AuditLogId") .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("Volo.Abp.AuditLogging.AuditLog") - .WithMany("Actions") - .HasForeignKey("AuditLogId1"); }); modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => { b.HasOne("Volo.Abp.AuditLogging.AuditLog") - .WithMany() + .WithMany("EntityChanges") .HasForeignKey("AuditLogId") .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("Volo.Abp.AuditLogging.AuditLog") - .WithMany("EntityChanges") - .HasForeignKey("AuditLogId1"); }); modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => diff --git a/templates/service/host/MyCompanyName.MyProjectName.Host/MyCompanyName.MyProjectName.Host.csproj b/templates/service/host/MyCompanyName.MyProjectName.Host/MyCompanyName.MyProjectName.Host.csproj index 979261471c..fb6d365ca6 100644 --- a/templates/service/host/MyCompanyName.MyProjectName.Host/MyCompanyName.MyProjectName.Host.csproj +++ b/templates/service/host/MyCompanyName.MyProjectName.Host/MyCompanyName.MyProjectName.Host.csproj @@ -30,4 +30,8 @@ + + + + From f0a133f9ac9392657c4f92d73e04689b05c2e69c Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 18 Dec 2018 17:03:53 +0300 Subject: [PATCH 061/368] abp button tag helper improvements --- .../TagHelpers/Button/AbpButtonTagHelper.cs | 2 ++ .../TagHelpers/Button/AbpButtonTagHelperServiceBase.cs | 9 +++++++++ .../TagHelpers/Button/AbpLinkButtonTagHelper.cs | 2 ++ .../TagHelpers/Button/IButtonTagHelperBase.cs | 2 ++ 4 files changed, 15 insertions(+) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelper.cs index b26984fde4..56143ea059 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelper.cs @@ -15,6 +15,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button public string Icon { get; set; } + public bool? Disabled { get; set; } + public FontIconType IconType { get; set; } = FontIconType.FontAwesome; public AbpButtonTagHelper(AbpButtonTagHelperService service) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelperServiceBase.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelperServiceBase.cs index 23365deb48..419aff7c08 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelperServiceBase.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpButtonTagHelperServiceBase.cs @@ -13,6 +13,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button AddClasses(context, output); AddIcon(context, output); AddText(context, output); + AddDisabled(context, output); } protected virtual void NormalizeTagMode(TagHelperContext context, TagHelperOutput output) @@ -65,5 +66,13 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button output.Content.AppendHtml($"{TagHelper.Text}"); } + + protected virtual void AddDisabled(TagHelperContext context, TagHelperOutput output) + { + if (TagHelper.Disabled ?? false) + { + output.Attributes.Add("disabled", "disabled"); + } + } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpLinkButtonTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpLinkButtonTagHelper.cs index 08b2ecd41c..9a553a1be5 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpLinkButtonTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/AbpLinkButtonTagHelper.cs @@ -15,6 +15,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button public string Icon { get; set; } + public bool? Disabled { get; set; } + public FontIconType IconType { get; } = FontIconType.FontAwesome; public AbpLinkButtonTagHelper(AbpLinkButtonTagHelperService service) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/IButtonTagHelperBase.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/IButtonTagHelperBase.cs index a0e34b039c..ee88c4d294 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/IButtonTagHelperBase.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Button/IButtonTagHelperBase.cs @@ -10,6 +10,8 @@ string Icon { get; } + bool? Disabled { get; } + FontIconType IconType { get; } } } \ No newline at end of file From 06ecd14b7af3c34849ecb43cde1ffb9f8571a917 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 18 Dec 2018 17:04:17 +0300 Subject: [PATCH 062/368] progress bar tag helper improvments --- .../ProgressBar/AbpProgressBarTagHelper.cs | 6 +++++- .../AbpProgressBarTagHelperService.cs | 16 +++++++++++++++- .../ProgressBar/AbpProgressGroupTagHelper.cs | 11 +++++++++++ ...ce.cs => AbpProgressGroupTagHelperService.cs} | 2 +- .../ProgressBar/AbpProgressTagHelper.cs | 11 ----------- 5 files changed, 32 insertions(+), 14 deletions(-) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressGroupTagHelper.cs rename framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/{AbpProgressTagHelperService.cs => AbpProgressGroupTagHelperService.cs} (80%) delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressTagHelper.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressBarTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressBarTagHelper.cs index 72fb77a333..69e2f78467 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressBarTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressBarTagHelper.cs @@ -1,5 +1,9 @@ -namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.ProgressBar +using Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.ProgressBar { + [HtmlTargetElement("abp-progress-bar")] + [HtmlTargetElement("abp-progress-part")] public class AbpProgressBarTagHelper : AbpTagHelper { public double Value { get; set; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressBarTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressBarTagHelperService.cs index a27deff44d..66c7e7d2c8 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressBarTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressBarTagHelperService.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Razor.TagHelpers; +using System; +using Microsoft.AspNetCore.Razor.TagHelpers; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.ProgressBar @@ -7,6 +8,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.ProgressBar { public override void Process(TagHelperContext context, TagHelperOutput output) { + SetParentElement(context, output); + output.Attributes.AddClass("progress-bar"); output.Attributes.Add("role","progressbar"); @@ -51,6 +54,17 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.ProgressBar } } + protected virtual void SetParentElement(TagHelperContext context, TagHelperOutput output) + { + if (output.TagName == "abp-progress-part") + { + return; + } + + output.PreElement.SetHtmlContent("
" + Environment.NewLine); + output.PostElement.SetHtmlContent(Environment.NewLine + "
"); + } + protected virtual int CalculateStyleWidth() { return (int)((TagHelper.Value - TagHelper.MinValue) * (100 / (TagHelper.MaxValue - TagHelper.MinValue))); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressGroupTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressGroupTagHelper.cs new file mode 100644 index 0000000000..10a0ee4bb4 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressGroupTagHelper.cs @@ -0,0 +1,11 @@ +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.ProgressBar +{ + public class AbpProgressGroupTagHelper : AbpTagHelper + { + public AbpProgressGroupTagHelper(AbpProgressGroupTagHelperService groupTagHelperService) + : base(groupTagHelperService) + { + + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressGroupTagHelperService.cs similarity index 80% rename from framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressTagHelperService.cs rename to framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressGroupTagHelperService.cs index 4f70af2600..5dd4b8aded 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressGroupTagHelperService.cs @@ -3,7 +3,7 @@ using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.ProgressBar { - public class AbpProgressTagHelperService : AbpTagHelperService + public class AbpProgressGroupTagHelperService : AbpTagHelperService { public override void Process(TagHelperContext context, TagHelperOutput output) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressTagHelper.cs deleted file mode 100644 index c74700fcd8..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/ProgressBar/AbpProgressTagHelper.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.ProgressBar -{ - public class AbpProgressTagHelper : AbpTagHelper - { - public AbpProgressTagHelper(AbpProgressTagHelperService tagHelperService) - : base(tagHelperService) - { - - } - } -} From e4a81c6fa2158d620ff20f3617c771505e5c87ae Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 18 Dec 2018 17:04:29 +0300 Subject: [PATCH 063/368] tooltip tag helper improvements --- .../Tooltip/AbpTooltipTagHelperService.cs | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Tooltip/AbpTooltipTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Tooltip/AbpTooltipTagHelperService.cs index 006ccbc856..f95a0097cd 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Tooltip/AbpTooltipTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Tooltip/AbpTooltipTagHelperService.cs @@ -1,4 +1,6 @@ -using Microsoft.AspNetCore.Razor.TagHelpers; +using System; +using System.Linq; +using Microsoft.AspNetCore.Razor.TagHelpers; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Tooltip { @@ -6,19 +8,40 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Tooltip { public override void Process(TagHelperContext context, TagHelperOutput output) { + if (IsButtonDisabled(context, output)) + { + SetParentElementWithTooltip(context, output); + return; + } + SetDataToggle(context, output); SetDataPlacement(context, output); SetTooltipTitle(context, output); } + protected virtual void SetParentElementWithTooltip(TagHelperContext context, TagHelperOutput output) + { + var directory = GetDirectory() != TooltipDirectory.Default ? GetDirectory() : TooltipDirectory.Top; + output.Attributes.Add("data-placement", directory.ToString().ToLowerInvariant()); + + output.PreElement.SetHtmlContent( + "" + Environment.NewLine); + + output.PostElement.SetHtmlContent(Environment.NewLine + ""); + + output.Attributes.Add("style", "pointer-events: none;"); + } + protected virtual void SetDataToggle(TagHelperContext context, TagHelperOutput output) { - output.Attributes.Add("data-toggle","tooltip"); + output.Attributes.Add("data-toggle", "tooltip"); } protected virtual void SetDataPlacement(TagHelperContext context, TagHelperOutput output) { - var directory = GetDirectory() != TooltipDirectory.Default ? GetDirectory() : TooltipDirectory.Bottom; + var directory = GetDirectory() != TooltipDirectory.Default ? GetDirectory() : TooltipDirectory.Top; output.Attributes.Add("data-placement", directory.ToString().ToLowerInvariant()); } @@ -65,5 +88,10 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Tooltip return TooltipDirectory.Default; } + + protected virtual bool IsButtonDisabled(TagHelperContext context, TagHelperOutput output) + { + return output.Attributes.Any(a => a.Name == "disabled"); + } } } \ No newline at end of file From c3083d5168946271165b40f92e93a41b2a93d120 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 18 Dec 2018 17:04:51 +0300 Subject: [PATCH 064/368] progress bar tag helper docs --- .../Pages/Components/ProgressBars.cshtml | 97 ++++++++++--------- 1 file changed, 51 insertions(+), 46 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ProgressBars.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ProgressBars.cshtml index 3e3e1e28e7..25f7f5b96e 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ProgressBars.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ProgressBars.cshtml @@ -14,65 +14,70 @@

Based on Bootstrap Progress Bars.

-

# Progress Bar Examples

+ +

Example

- - - +
- - - %25 - - + %25
- - - - +
- - - %50 - - + %50
- - - - - %10 - - - - + + + %10 + +
-
-<abp-progress>
-  <abp-progress-bar value="70"/>
-</abp-progress>
+        
+            
+                

+<abp-progress-bar value="70" />
+
+<abp-progress-bar type="Warning" value="25"> %25 </abp-progress-bar>
+
+<abp-progress-bar type="Success" value="40" strip="true"/>
+
+<abp-progress-bar type="Dark" value="10" min-value="5" max-value="15" strip="true"> %50 </abp-progress-bar>
+
+<abp-progress-group>
+    <abp-progress-part type="Success" value="25"/>
+    <abp-progress-part type="Danger" value="10" strip="true"> %10 </abp-progress-part>
+    <abp-progress-part type="Primary" value="50" animation="true" strip="true" />
+</abp-progress-group>
+
+
+ +

+<div class="progress">
+    <div class="progress-bar" role="progressbar" style="width: 70%" aria-valuenow="70" aria-valuemin="0" aria-valuemax="100"></div>
+</div>
 
-<abp-progress>
-  <abp-progress-bar type="Warning" value="25">%25</abp-progress-bar>
-</abp-progress>
+<div class="progress">
+    <div class="progress-bar bg-warning" role="progressbar" style="width: 25%" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"> %25 </div>
+</div>
 
-<abp-progress>
-  <abp-progress-bar type="Success" value="40" strip="true"/>
-</abp-progress>
+<div class="progress">
+    <div class="progress-bar progress-bar-striped bg-success" role="progressbar" style="width: 40%" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100"></div>
+</div>
 
-<abp-progress>
-  <abp-progress-bar type="Dark" value="10" min-value="5" max-value="15"  strip="true">%50</abp-progress-bar>
-</abp-progress>
+<div class="progress">
+    <div class="progress-bar progress-bar-striped bg-dark" role="progressbar" style="width: 50%" aria-valuenow="10" aria-valuemin="5" aria-valuemax="15"> %50 </div>
+</div>
 
-<abp-progress>
-  <abp-progress-bar type="Success" value="25"/>
-  <abp-progress-bar type="Danger" value="10" strip="true">%10</abp-progress-bar>
-  <abp-progress-bar type="Primary" value="50" animation="true" strip="true"/>
-</abp-progress>
-
+<div class="progress"> + <div class="progress-bar bg-success" role="progressbar" style="width: 25%" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div> + <div class="progress-bar progress-bar-striped bg-danger" role="progressbar" style="width: 10%" aria-valuenow="10" aria-valuemin="0" aria-valuemax="100"> %10 </div> + <div class="progress-bar progress-bar-animated progress-bar-striped bg-primary" role="progressbar" style="width: 50%" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100"></div> +</div> +
+ +
From d28e35a251040a51b2d1ea0714127eea7b17ba93 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 18 Dec 2018 17:05:02 +0300 Subject: [PATCH 065/368] tooltip tag helper docs --- .../Pages/Components/Tooltips.cshtml | 75 +++++++++++++------ 1 file changed, 53 insertions(+), 22 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tooltips.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tooltips.cshtml index fe0aeebae4..a5bc9f27db 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tooltips.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tooltips.cshtml @@ -1,7 +1,7 @@ @page @model Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components.TooltipsModel @{ - ViewData["Title"] = "Badges"; + ViewData["Title"] = "Tooltips"; } @section styles { @@ -14,46 +14,77 @@

Based on Bootstrap Tooltips.

-

# Tooltips Examples

+

Example

- + Tooltip Default - + Tooltip on top - + Tooltip on right - + Tooltip on bottom - - Tooltip on left + + Disabled button Tooltip -
-
-<abp-button  abp-tooltip="Tooltip Default">
-  Tooltip Default
+        
+            
+                

+<abp-button abp-tooltip="Tooltip">
+      Tooltip Default
 </abp-button>
-<abp-button abp-tooltip-top="Tooltip on top">
-   Tooltip on top
+
+<abp-button abp-tooltip-top="Tooltip">
+      Tooltip on top
 </abp-button>
-<abp-button abp-tooltip-right="Tooltip on right">
-  Tooltip on right
+
+<abp-button abp-tooltip-right="Tooltip">
+      Tooltip on right
 </abp-button>
-<abp-button abp-tooltip-bottom="Tooltip on bottom">
-  Tooltip on bottom
+
+<abp-button abp-tooltip-bottom="Tooltip">
+      Tooltip on bottom
 </abp-button>
-<abp-button abp-tooltip-left="Tooltip on left">
-  Tooltip on left
+
+<abp-button disabled="true" abp-tooltip="Tooltip">
+      Disabled button Tooltip
 </abp-button>
-
+
+ + +

+<button class="btn" type="button" data-busy-text="Processing..." data-toggle="tooltip" data-placement="top" title="" data-original-title="Tooltip">
+    Tooltip Default
+</button>
+
+<button class="btn" type="button" data-busy-text="Processing..." data-toggle="tooltip" data-placement="top" title="" data-original-title="Tooltip">
+    Tooltip on top
+</button>
+
+<button class="btn" type="button" data-busy-text="Processing..." data-toggle="tooltip" data-placement="right" title="" data-original-title="Tooltip">
+     Tooltip on right
+</button>
+
+<button class="btn" type="button" data-busy-text="Processing..." data-toggle="tooltip" data-placement="bottom" title="" data-original-title="Tooltip">
+    Tooltip on bottom
+</button>
+
+<span class="d-inline-block" tabindex="0" data-toggle="tooltip" data-placement="top" title="" data-original-title="Tooltip">
+    <button class="btn" disabled="disabled" type="button" data-busy-text="Processing..." data-placement="top" style="pointer-events: none;">
+        Disabled button Tooltip
+    </button>
+</span>
+
+
+
- From 40754f7f7984b23e2d58fdf88e29ac1c7dca9687 Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 19 Dec 2018 10:05:49 +0800 Subject: [PATCH 066/368] Update docs-nav.json --- docs/zh-Hans/docs-nav.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/zh-Hans/docs-nav.json b/docs/zh-Hans/docs-nav.json index 362e6fbc65..6d66e651ec 100644 --- a/docs/zh-Hans/docs-nav.json +++ b/docs/zh-Hans/docs-nav.json @@ -49,7 +49,8 @@ "path": "Dependency-Injection.md", "items": [ { - "text": "AutoFac 集成" + "text": "AutoFac 集成", + "path": "Autofac-Integration.md" } ] }, @@ -251,4 +252,4 @@ "path": "Contribution/Index.md" } ] -} \ No newline at end of file +} From 5247cf6328e83ebd05a9f77a1f1f9e960965068d Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 19 Dec 2018 10:01:24 +0300 Subject: [PATCH 067/368] Removed redundant code --- .../TagHelpers/Table/AbpTableStyleTagHelper.cs | 4 +--- .../Table/AbpTableStyleTagHelperService.cs | 12 ++---------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Table/AbpTableStyleTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Table/AbpTableStyleTagHelper.cs index dadb22af1c..53452e9c68 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Table/AbpTableStyleTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Table/AbpTableStyleTagHelper.cs @@ -6,9 +6,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Table [HtmlTargetElement("td")] public class AbpTableStyleTagHelper : AbpTagHelper { - public AbpTableStyle AbpTableStyle { get; set; } = AbpTableStyle.Default; - - public AbpTableStyle AbpDarkTableStyle { get; set; } = AbpTableStyle.Default; + public AbpTableStyle TableStyle { get; set; } = AbpTableStyle.Default; public AbpTableStyleTagHelper(AbpTableStyleTagHelperService tagHelperService) : base(tagHelperService) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Table/AbpTableStyleTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Table/AbpTableStyleTagHelperService.cs index 716233b888..fe93d7273e 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Table/AbpTableStyleTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Table/AbpTableStyleTagHelperService.cs @@ -12,17 +12,9 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Table protected virtual void SetStyle(TagHelperContext context, TagHelperOutput output) { - if (TagHelper.AbpTableStyle != AbpTableStyle.Default) + if (TagHelper.TableStyle != AbpTableStyle.Default) { - output.Attributes.AddClass("table-" + TagHelper.AbpTableStyle.ToString().ToLowerInvariant()); - } - } - - protected virtual void SetDarkTableStyle(TagHelperContext context, TagHelperOutput output) - { - if (TagHelper.AbpDarkTableStyle != AbpTableStyle.Default) - { - output.Attributes.AddClass("bg-" + TagHelper.AbpDarkTableStyle.ToString().ToLowerInvariant()); + output.Attributes.AddClass("table-" + TagHelper.TableStyle.ToString().ToLowerInvariant()); } } } From 586a8d47ac180c0226b28c36a8b193f72b0af47c Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 19 Dec 2018 10:01:47 +0300 Subject: [PATCH 068/368] removed commented code --- .../Pages/Components/Buttons.cshtml | 49 +------------------ 1 file changed, 1 insertion(+), 48 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Buttons.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Buttons.cshtml index 9e746b0fe7..0274cd4d69 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Buttons.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Buttons.cshtml @@ -297,51 +297,4 @@
- - -@*

# Group Examples

- -
-
- - - Left - Middle - Right - - - - Primary - Secondary - Success - - - - Top - Middle - Bottom - -
-
-

-
-    <abp-button-group>
-        <abp-button> Left </abp-button>
-        <abp-button> Middle </abp-button>
-        <abp-button> Right </abp-button>
-    </abp-button-group>
-
-    <abp-button-group size="Large">
-        <abp-button button-type="Primary"> Primary </abp-button>
-        <abp-button button-type="Secondary"> Secondary </abp-button>
-        <abp-button button-type="Success"> Success </abp-button>
-    </abp-button-group>
-
-    <abp-button-group direction="Vertical" size="Small">
-        <abp-button button-type="Primary"> Top </abp-button>
-        <abp-button button-type="Warning"> Middle </abp-button>
-        <abp-button button-type="Danger"> Bottom </abp-button>
-    </abp-button-group>
-    
-
-
*@ \ No newline at end of file + \ No newline at end of file From ffc123406a8d17ed2b44373000b3de2f453329bd Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 19 Dec 2018 10:02:00 +0300 Subject: [PATCH 069/368] tabs tag helper demo --- .../Pages/Components/Tabs.cshtml | 209 +++++++++++++++--- 1 file changed, 181 insertions(+), 28 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tabs.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tabs.cshtml index c2c17a389d..367fe710b2 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tabs.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tabs.cshtml @@ -10,19 +10,33 @@ } +@section scripts { + + @* + *@ + +} + + + + + +

Tabs

Based on Bootstrap tab.

-

# Most Simple Tabs Example

+

Example

+ Content_Home - + Content_Profile @@ -37,14 +51,16 @@
-
-<abp-tabs name="TabId">
+        
+            
+                

+<abp-tabs>
     <abp-tab title="Home">
-        Content_Home
-    </abp-tab>   
-    <abp-tab-link title="Link" name="LinkId" href="#"/>
+             Content_Home
+    </abp-tab>
+    <abp-tab-link title="Link" href="#" />
     <abp-tab title="profile">
-        Content_Profile
+            Content_Profile
     </abp-tab>
     <abp-tab-dropdown title="Contact" name="ContactDropdown">
         <abp-tab title="Contact 1" parent-dropdown-name="ContactDropdown">
@@ -55,11 +71,44 @@
         </abp-tab>
     </abp-tab-dropdown>
 </abp-tabs>
-
+
+ + +

+<div>
+    <ul class="nav nav-tabs" id="48c14227782f4edab7f153b413ac1429" role="tablist">
+        <li class="nav-item"><a class="nav-link active" id="48c14227782f4edab7f153b413ac1429_0-tab" data-toggle="tab" href="#48c14227782f4edab7f153b413ac1429_0" role="tab" aria-controls="48c14227782f4edab7f153b413ac1429_0" aria-selected="true">Home</a></li>
+        <li class="nav-item"><a class="nav-link" id="LinkId-tab" href="#">Link</a></li>
+        <li class="nav-item"><a class="nav-link" id="48c14227782f4edab7f153b413ac1429_2-tab" data-toggle="tab" href="#48c14227782f4edab7f153b413ac1429_2" role="tab" aria-controls="48c14227782f4edab7f153b413ac1429_2" aria-selected="false">profile</a></li>
+        <li class="nav-item dropdown">
+            <a class="nav-link dropdown-toggle" id="ContactDropdown-tab" data-toggle="dropdown" href="#ContactDropdown" role="button" aria-haspopup="true" aria-expanded="false">Contact</a><div class="dropdown-menu">
+                <a class="dropdown-item" id="48c14227782f4edab7f153b413ac1429_3-tab" href="#48c14227782f4edab7f153b413ac1429_3" data-toggle="tab" role="tab" aria-controls="48c14227782f4edab7f153b413ac1429_3" aria-selected="false">Contact 1</a>
+                <a class="dropdown-item" id="48c14227782f4edab7f153b413ac1429_4-tab" href="#48c14227782f4edab7f153b413ac1429_4" data-toggle="tab" role="tab" aria-controls="48c14227782f4edab7f153b413ac1429_4" aria-selected="false">Contact 2</a>
+            </div>
+        </li>
+    </ul>
+    <div class="tab-content" id="48c14227782f4edab7f153b413ac1429Content">
+        <div class="tab-pane fade show active" id="48c14227782f4edab7f153b413ac1429_0" role="tabpanel" aria-labelledby="48c14227782f4edab7f153b413ac1429_0-tab">
+              Content_Home
+        </div>
+        <div class="tab-pane fade" id="48c14227782f4edab7f153b413ac1429_2" role="tabpanel" aria-labelledby="48c14227782f4edab7f153b413ac1429_2-tab">
+              Content_Profile
+        </div>
+        <div class="tab-pane fade" id="48c14227782f4edab7f153b413ac1429_3" role="tabpanel" aria-labelledby="48c14227782f4edab7f153b413ac1429_3-tab">
+              Content_1_Content
+        </div>
+        <div class="tab-pane fade" id="48c14227782f4edab7f153b413ac1429_4" role="tabpanel" aria-labelledby="48c14227782f4edab7f153b413ac1429_4-tab">
+              Content_2_Content
+        </div>
+    </div>
+</div>
+
+
+
-

# Tabs With Name Attiribute Example

+

Tab attributes

@@ -76,7 +125,9 @@
-
+        
+            
+                

 <abp-tabs name="TabId">
     <abp-tab name="nav-home" title="Home">
         Content_Home
@@ -88,16 +139,50 @@
         Content_Contact
     </abp-tab>
 </abp-tabs>
-
+
+ + +

+<div>
+    <ul class="nav nav-tabs" id="TabId" role="tablist">
+        <li class="nav-item"><a class="nav-link" id="nav-home-tab" data-toggle="tab" href="#nav-home" role="tab" aria-controls="nav-home" aria-selected="false">Home</a></li>
+        <li class="nav-item"><a class="nav-link" id="nav-profile-tab" data-toggle="tab" href="#nav-profile" role="tab" aria-controls="nav-profile" aria-selected="false">profile</a></li>
+        <li class="nav-item"><a class="nav-link active show" id="nav-contact-tab" data-toggle="tab" href="#nav-contact" role="tab" aria-controls="nav-contact" aria-selected="true">Contact</a></li>
+    </ul>
+    <div class="tab-content" id="TabIdContent">
+        <div class="tab-pane fade" id="nav-home" role="tabpanel" aria-labelledby="nav-home-tab">
+             Content_Home
+        </div>
+        <div class="tab-pane fade" id="nav-profile" role="tabpanel" aria-labelledby="nav-profile-tab">
+             Content_Profile
+        </div>
+        <div class="tab-pane fade active show" id="nav-contact" role="tabpanel" aria-labelledby="nav-contact-tab">
+             Content_Contact
+        </div>
+    </div>
+</div>
+
+
+ +
+
+
    +
  • + name: Sets "id" attribute of generated elements. Default value is a Guid. Not needed unless tabs are changed or modified with Jquery. +
  • +
  • + active: Sets the active tab. +
  • +
-

# Pill Example

+

Pill Example

- + Content_Home @@ -109,28 +194,56 @@
-
-<abp-tabs tab-style="Pill" >
-    <abp-tab active="true" title="Home">
-        Content_Home
-    </abp-tab>   
+        
+            
+                

+<abp-tabs tab-style="Pill">
+    <abp-tab title="Home">
+         Content_Home
+    </abp-tab>
     <abp-tab title="profile">
-        Content_Profile
+         Content_Profile
     </abp-tab>
     <abp-tab title="Contact">
-        Content_Contact
+         Content_Contact
     </abp-tab>
 </abp-tabs>
-
+ +
+ + +

+<div>
+    <ul class="nav nav-pills" id="2eaad131e42c4a90962fcb3c4e55c946" role="tablist">
+        <li class="nav-item"><a class="nav-link active" id="2eaad131e42c4a90962fcb3c4e55c946_0-tab" data-toggle="pill" href="#2eaad131e42c4a90962fcb3c4e55c946_0" role="tab" aria-controls="2eaad131e42c4a90962fcb3c4e55c946_0" aria-selected="true">Home</a></li>
+        <li class="nav-item"><a class="nav-link" id="2eaad131e42c4a90962fcb3c4e55c946_1-tab" data-toggle="pill" href="#2eaad131e42c4a90962fcb3c4e55c946_1" role="tab" aria-controls="2eaad131e42c4a90962fcb3c4e55c946_1" aria-selected="false">profile</a></li>
+        <li class="nav-item"><a class="nav-link" id="2eaad131e42c4a90962fcb3c4e55c946_2-tab" data-toggle="pill" href="#2eaad131e42c4a90962fcb3c4e55c946_2" role="tab" aria-controls="2eaad131e42c4a90962fcb3c4e55c946_2" aria-selected="false">Contact</a></li>
+    </ul>
+    <div class="tab-content" id="2eaad131e42c4a90962fcb3c4e55c946Content">
+        <div class="tab-pane fade show active" id="2eaad131e42c4a90962fcb3c4e55c946_0" role="tabpanel" aria-labelledby="2eaad131e42c4a90962fcb3c4e55c946_0-tab">
+               Content_Home
+        </div>
+        <div class="tab-pane fade" id="2eaad131e42c4a90962fcb3c4e55c946_1" role="tabpanel" aria-labelledby="2eaad131e42c4a90962fcb3c4e55c946_1-tab">
+               Content_Profile
+        </div>
+        <div class="tab-pane fade" id="2eaad131e42c4a90962fcb3c4e55c946_2" role="tabpanel" aria-labelledby="2eaad131e42c4a90962fcb3c4e55c946_2-tab">
+               Content_Contact
+        </div>
+    </div>
+</div>
+
+
+
+
-

# Vertical Example

+

Vertical Example

- + Content_Home @@ -142,8 +255,10 @@
-
-<abp-tabs name="TabId"  tab-style="Pill" vertical-header-size="_2" >
+        
+            
+                

+<abp-tabs tab-style="PillVertical" vertical-header-size="_2" >
     <abp-tab active="true" title="Home">
         Content_Home
     </abp-tab>   
@@ -154,6 +269,44 @@
         Content_Contact
     </abp-tab>
 </abp-tabs>
-
+ +
+ + +

+<div class="row">
+    <div class="col-2">
+        <ul class="nav flex-column  nav-pills" id="2f347a2276af424ebbd67f85653edf1f" role="tablist">
+            <li class="nav-item"><a class="nav-link active" id="2f347a2276af424ebbd67f85653edf1f_0-tab" data-toggle="pill" href="#2f347a2276af424ebbd67f85653edf1f_0" role="tab" aria-controls="2f347a2276af424ebbd67f85653edf1f_0" aria-selected="true">Home</a></li>
+            <li class="nav-item"><a class="nav-link" id="2f347a2276af424ebbd67f85653edf1f_1-tab" data-toggle="pill" href="#2f347a2276af424ebbd67f85653edf1f_1" role="tab" aria-controls="2f347a2276af424ebbd67f85653edf1f_1" aria-selected="false">profile</a></li>
+            <li class="nav-item"><a class="nav-link" id="2f347a2276af424ebbd67f85653edf1f_2-tab" data-toggle="pill" href="#2f347a2276af424ebbd67f85653edf1f_2" role="tab" aria-controls="2f347a2276af424ebbd67f85653edf1f_2" aria-selected="false">Contact</a></li>
+        </ul>
+    </div>
+    <div class="col-10">
+        <div class="tab-content" id="2f347a2276af424ebbd67f85653edf1fContent">
+            <div class="tab-pane fade show active" id="2f347a2276af424ebbd67f85653edf1f_0" role="tabpanel" aria-labelledby="2f347a2276af424ebbd67f85653edf1f_0-tab">
+                 Content_Home
+            </div>
+            <div class="tab-pane fade" id="2f347a2276af424ebbd67f85653edf1f_1" role="tabpanel" aria-labelledby="2f347a2276af424ebbd67f85653edf1f_1-tab">
+                 Content_Profile
+            </div>
+            <div class="tab-pane fade" id="2f347a2276af424ebbd67f85653edf1f_2" role="tabpanel" aria-labelledby="2f347a2276af424ebbd67f85653edf1f_2-tab">
+                 Content_Contact
+            </div>
+        </div>
+    </div>
+</div>
+
+
+
+
-
+ +
+
    +
  • + vertical-header-size: Sets the column width of tab headers. +
  • +
+
+ \ No newline at end of file From b1c516e7763ea376153a6a62c7a1a3acb4710563 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 19 Dec 2018 10:02:11 +0300 Subject: [PATCH 070/368] tables tag helper demo --- .../Pages/Components/Tables.cshtml | 424 +++++++++++++++++- 1 file changed, 402 insertions(+), 22 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tables.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tables.cshtml index 127cd61715..b77606f148 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tables.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Tables.cshtml @@ -10,17 +10,30 @@ } +@section scripts { + + @* + *@ + +} + + + + + +

Tables

Based on Bootstrap Tables.

-

# Tables Examples

+

Examples

- - + + # First @@ -33,9 +46,9 @@ 1 Mark Otto - mdo + mdo - + 2 Jacob Thornton @@ -43,46 +56,413 @@ 3 - Larry + Larry the Bird twitter -
-
-        <abp-table striped-rows="true" small="true" hoverable-rows="true" responsive-sm="true">
-            <thead theme="Dark">
+        
+            
+                

+<abp-table hoverable-rows="true" responsive-sm="true">
+    <thead>
+    <tr>
+        <th scope="Column">#</th>
+        <th scope="Column">First</th>
+        <th scope="Column">Last</th>
+        <th scope="Column">Handle</th>
+    </tr>
+    </thead>
+    <tbody>
+    <tr>
+        <th scope="Row">1</th>
+        <td>Mark</td>
+        <td>Otto</td>
+        <td table-style="Danger">mdo</td>
+    </tr>
+    <tr table-style="Warning">
+        <th scope="Row">2</th>
+        <td>Jacob</td>
+        <td>Thornton</td>
+        <td>fat</td>
+    </tr>
+    <tr>
+        <th scope="Row">3</th>
+        <td table-style="Success">Larry</td>
+        <td>the Bird</td>
+        <td>twitter</td>
+    </tr>
+    </tbody>
+</abp-table>
+
+
+ +

+<div class="table-responsive-sm">
+       <table class="table table-hover">
+            <thead>
             <tr>
-                <th scope="Column">#</th>
-                <th scope="Column">First</th>
-                <th scope="Column">Last</th>
-                <th scope="Column">Handle</th>
+                <th scope="col">#</th>
+                <th scope="col">First</th>
+                <th scope="col">Last</th>
+                <th scope="col">Handle</th>
             </tr>
             </thead>
             <tbody>
             <tr>
-                <th scope="Row">1</th>
+                <th scope="row">1</th>
                 <td>Mark</td>
                 <td>Otto</td>
-                <td  abp-table-style="Danger">mdo</td>
+                <td class="table-danger">mdo</td>
             </tr>
-            <tr abp-table-style="Warning">
-                <th scope="Row">2</th>
+            <tr class="table-warning">
+                <th scope="row">2</th>
                 <td>Jacob</td>
                 <td>Thornton</td>
                 <td>fat</td>
             </tr>
             <tr>
-                <th scope="Row">3</th>
-                <td abp-table-style="Success">Larry</td>
+                <th scope="row">3</th>
+                <td class="table-success">Larry</td>
                 <td>the Bird</td>
                 <td>twitter</td>
             </tr>
             </tbody>
-        </abp-table>
-
+ </table> +</div> +
+ + +
+
+ +
+
+ + + + + # + First + Last + Handle + + + + + 1 + Mark + Otto + mdo + + + 2 + Jacob + Thornton + fat + + + 3 + Larry + the Bird + twitter + + + +
+
+ + +

+<abp-table small="true" striped-rows="true" border-style="Bordered">
+    <thead Theme="Dark">
+        <tr>
+            <th scope="Column">#</th>
+            <th scope="Column">First</th>
+            <th scope="Column">Last</th>
+            <th scope="Column">Handle</th>
+        </tr>
+    </thead>
+    <tbody>
+        <tr>
+            <th scope="Row">1</th>
+            <td>Mark</td>
+            <td>Otto</td>
+            <td>mdo</td>
+        </tr>
+        <tr>
+            <th scope="Row">2</th>
+            <td>Jacob</td>
+            <td>Thornton</td>
+            <td>fat</td>
+        </tr>
+        <tr>
+            <th scope="Row">3</th>
+            <td>Larry</td>
+            <td>the Bird</td>
+            <td>twitter</td>
+        </tr>
+    </tbody>
+</abp-table>
+
+
+ +

+<table class="table table-sm table-striped table-bordered">
+    <thead class="thead-dark">
+        <tr>
+            <th scope="col">#</th>
+            <th scope="col">First</th>
+            <th scope="col">Last</th>
+            <th scope="col">Handle</th>
+        </tr>
+    </thead>
+    <tbody>
+        <tr>
+            <th scope="row">1</th>
+            <td>Mark</td>
+            <td>Otto</td>
+            <td>mdo</td>
+        </tr>
+        <tr>
+            <th scope="row">2</th>
+            <td>Jacob</td>
+            <td>Thornton</td>
+            <td>fat</td>
+        </tr>
+        <tr>
+            <th scope="row">3</th>
+            <td>Larry</td>
+            <td>the Bird</td>
+            <td>twitter</td>
+        </tr>
+    </tbody>
+</table>
+
+
+
+
+
+ +
+
+ + + List of users + + + # + First + Last + Handle + + + + + 1 + Mark + Otto + mdo + + + 2 + Jacob + Thornton + fat + + + 3 + Larry + the Bird + twitter + + + +
+
+ + +

+<abp-table striped-rows="true" dark-theme="true">
+    <caption>List of users</caption>
+    <thead>
+        <tr>
+            <th scope="Column">#</th>
+            <th scope="Column">First</th>
+            <th scope="Column">Last</th>
+            <th scope="Column">Handle</th>
+        </tr>
+    </thead>
+    <tbody>
+        <tr>
+            <th scope="Row">1</th>
+            <td>Mark</td>
+            <td>Otto</td>
+            <td>mdo</td>
+        </tr>
+        <tr>
+            <th scope="Row">2</th>
+            <td>Jacob</td>
+            <td>Thornton</td>
+            <td>fat</td>
+        </tr>
+        <tr>
+            <th scope="Row">3</th>
+            <td>Larry</td>
+            <td>the Bird</td>
+            <td>twitter</td>
+        </tr>
+    </tbody>
+</abp-table>
+
+
+ +

+<table class="table table-dark table-striped">
+    <caption>List of users</caption>
+    <thead>
+        <tr>
+            <th scope="col">#</th>
+            <th scope="col">First</th>
+            <th scope="col">Last</th>
+            <th scope="col">Handle</th>
+        </tr>
+    </thead>
+    <tbody>
+        <tr>
+            <th scope="row">1</th>
+            <td>Mark</td>
+            <td>Otto</td>
+            <td>mdo</td>
+        </tr>
+        <tr>
+            <th scope="row">2</th>
+            <td>Jacob</td>
+            <td>Thornton</td>
+            <td>fat</td>
+        </tr>
+        <tr>
+            <th scope="row">3</th>
+            <td>Larry</td>
+            <td>the Bird</td>
+            <td>twitter</td>
+        </tr>
+    </tbody>
+</table>
+
+
+
+
+
+ + +
+
+ + + + + # + First + Last + Handle + + + + + 1 + Mark + Otto + mdo + + + 2 + Jacob + Thornton + fat + + + 3 + Larry + the Bird + twitter + + + +
+
+ + +

+<abp-table border-style="Borderless">
+    <thead>
+        <tr>
+            <th scope="Column">#</th>
+            <th scope="Column">First</th>
+            <th scope="Column">Last</th>
+            <th scope="Column">Handle</th>
+        </tr>
+    </thead>
+    <tbody>
+        <tr>
+            <th scope="Row">1</th>
+            <td>Mark</td>
+            <td>Otto</td>
+            <td>mdo</td>
+        </tr>
+        <tr>
+            <th scope="Row">2</th>
+            <td>Jacob</td>
+            <td>Thornton</td>
+            <td>fat</td>
+        </tr>
+        <tr>
+            <th scope="Row">3</th>
+            <td>Larry</td>
+            <td>the Bird</td>
+            <td>twitter</td>
+        </tr>
+    </tbody>
+</abp-table>
+
+
+ +

+<table class="table table-borderless">
+    <thead>
+        <tr>
+            <th scope="col">#</th>
+            <th scope="col">First</th>
+            <th scope="col">Last</th>
+            <th scope="col">Handle</th>
+        </tr>
+    </thead>
+    <tbody>
+        <tr>
+            <th scope="row">1</th>
+            <td>Mark</td>
+            <td>Otto</td>
+            <td>mdo</td>
+        </tr>
+        <tr>
+            <th scope="row">2</th>
+            <td>Jacob</td>
+            <td>Thornton</td>
+            <td>fat</td>
+        </tr>
+        <tr>
+            <th scope="row">3</th>
+            <td>Larry</td>
+            <td>the Bird</td>
+            <td>twitter</td>
+        </tr>
+    </tbody>
+</table>
+
+
+
From 147c0dce6f0b836c3c07c18f1340cb4cad6596cd Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 19 Dec 2018 10:43:43 +0300 Subject: [PATCH 071/368] navs doc improvements --- .../Pages/Components/Navs.cshtml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Navs.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Navs.cshtml index 80a0b24c31..8adeabf964 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Navs.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Navs.cshtml @@ -88,6 +88,14 @@ + +
+
    +
  • + For vertical nav, set nav-style "PillVertical". +
  • +
+

Base nav

From cf3f8e6042a7fa423f2d2c48ce227e3ae1bc4974 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 19 Dec 2018 10:54:33 +0300 Subject: [PATCH 072/368] added size for input tag helpers --- .../TagHelpers/Form/AbpFormControlSize.cs | 15 +++++++++++ .../TagHelpers/Form/AbpInputTagHelper.cs | 2 ++ .../Form/AbpInputTagHelperService.cs | 24 +++++++++++++++++- .../TagHelpers/Form/AbpSelectTagHelper.cs | 2 ++ .../Form/AbpSelectTagHelperService.cs | 25 ++++++++++++++++++- .../TagHelpers/Form/FormControlSize.cs | 18 +++++++++++++ 6 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormControlSize.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/FormControlSize.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormControlSize.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormControlSize.cs new file mode 100644 index 0000000000..97acb45822 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormControlSize.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +{ + public enum AbpFormControlSize + { + Default, + Small, + Medium, + Large + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs index de93ff4b1d..30a6a11d39 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs @@ -18,6 +18,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form public bool AutoFocus { get; set; } + public AbpFormControlSize Size { get; set; } = AbpFormControlSize.Default; + [HtmlAttributeNotBound] [ViewContext] public ViewContext ViewContext { get; set; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs index b5abe780ae..e31a2c8100 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -124,7 +124,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form AddReadOnlyAttribute(inputTagHelperOutput); AddAutoFocusAttribute(inputTagHelperOutput); isCheckbox = IsInputCheckbox(context, output, inputTagHelperOutput.Attributes); - inputTagHelperOutput.Attributes.AddClass(isCheckbox ? "form-check-input" : "form-control"); + inputTagHelperOutput.Attributes.AddClass(isCheckbox ? "form-check-input" : "form-control" + " " + GetSize(context,output)); return inputTagHelperOutput; } @@ -254,5 +254,27 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form output.Attributes.Add(newAttritube); } } + + protected virtual string GetSize(TagHelperContext context, TagHelperOutput output) + { + var attribute = GetAttribute(TagHelper.AspFor.ModelExplorer); + + if (attribute != null) + { + TagHelper.Size = attribute.Size; + } + + switch (TagHelper.Size) + { + case AbpFormControlSize.Small: + return "form-control-sm"; + case AbpFormControlSize.Medium: + return "form-control-md"; + case AbpFormControlSize.Large: + return "form-control-lg"; + } + + return ""; + } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs index 889fe4208d..3cb2fd4667 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs @@ -13,6 +13,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form public IEnumerable AspItems { get; set; } + public AbpFormControlSize Size { get; set; } = AbpFormControlSize.Default; + [HtmlAttributeNotBound] [ViewContext] public ViewContext ViewContext { get; set; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs index 8607348fff..ad5b4c62cf 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs @@ -70,7 +70,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form var inputTagHelperOutput = GetInnerTagHelper(new TagHelperAttributeList(), context, selectTagHelper, "select", TagMode.StartTagAndEndTag); - inputTagHelperOutput.Attributes.Add("class", "form-control"); + inputTagHelperOutput.Attributes.AddClass("form-control"); + inputTagHelperOutput.Attributes.AddClass(GetSize(context,output)); AddDisabledAttribute(inputTagHelperOutput); return inputTagHelperOutput; @@ -170,5 +171,27 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form return RenderTagHelper(new TagHelperAttributeList(), context, labelTagHelper, _encoder, "label", TagMode.StartTagAndEndTag, true); } + + protected virtual string GetSize(TagHelperContext context, TagHelperOutput output) + { + var attribute = GetAttribute(TagHelper.AspFor.ModelExplorer); + + if (attribute != null) + { + TagHelper.Size = attribute.Size; + } + + switch (TagHelper.Size) + { + case AbpFormControlSize.Small: + return "form-control-sm"; + case AbpFormControlSize.Medium: + return "form-control-md"; + case AbpFormControlSize.Large: + return "form-control-lg"; + } + + return ""; + } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/FormControlSize.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/FormControlSize.cs new file mode 100644 index 0000000000..19a5edd0af --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/FormControlSize.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +{ + [AttributeUsage(AttributeTargets.Property)] + public class FormControlSize : Attribute + { + public AbpFormControlSize Size { get; set; } + + public FormControlSize(AbpFormControlSize size) + { + Size = size; + } + } +} From c3be3c30043d101f58a0a0eee24545f51c4479dd Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 19 Dec 2018 11:39:53 +0300 Subject: [PATCH 073/368] abp input readonly improvements --- .../TagHelpers/Form/AbpInputTagHelper.cs | 2 +- .../Form/AbpInputTagHelperService.cs | 35 ++++++++++++------- .../TagHelpers/Form/AbpReadonlyInputType.cs | 9 +++++ .../TagHelpers/Form/ReadOnlyInput.cs | 7 ++++ 4 files changed, 40 insertions(+), 13 deletions(-) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpReadonlyInputType.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs index 30a6a11d39..4545024d6d 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs @@ -14,7 +14,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form public bool IsDisabled { get; set; } = false; [HtmlAttributeName("readonly")] - public bool IsReadonly { get; set; } = false; + public AbpReadonlyInputType IsReadonly { get; set; } = AbpReadonlyInputType.False; public bool AutoFocus { get; set; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs index e31a2c8100..e38bd4e97a 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -121,14 +121,31 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form ConvertToTextAreaIfTextArea(inputTagHelperOutput); AddDisabledAttribute(inputTagHelperOutput); - AddReadOnlyAttribute(inputTagHelperOutput); AddAutoFocusAttribute(inputTagHelperOutput); isCheckbox = IsInputCheckbox(context, output, inputTagHelperOutput.Attributes); - inputTagHelperOutput.Attributes.AddClass(isCheckbox ? "form-check-input" : "form-control" + " " + GetSize(context,output)); + AddFormControlClass(context, output, isCheckbox, inputTagHelperOutput); + AddReadOnlyAttribute(inputTagHelperOutput); return inputTagHelperOutput; } + private void AddFormControlClass(TagHelperContext context, TagHelperOutput output, bool isCheckbox, TagHelperOutput inputTagHelperOutput) + { + var className = "form-control"; + var readonlyAttribute = GetAttribute(TagHelper.AspFor.ModelExplorer); + + if (isCheckbox) + { + className = "form-check-input"; + } + else if (TagHelper.IsReadonly == AbpReadonlyInputType.True_PlainText || (readonlyAttribute != null && readonlyAttribute.PlainText)) + { + className = "form-control-plaintext"; + } + + inputTagHelperOutput.Attributes.AddClass(className + " " + GetSize(context, output)); + } + protected virtual void AddAutoFocusAttribute(TagHelperOutput inputTagHelperOutput) { if (TagHelper.AutoFocus && !inputTagHelperOutput.Attributes.ContainsName("data-auto-focus")) @@ -139,11 +156,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form protected virtual void AddDisabledAttribute(TagHelperOutput inputTagHelperOutput) { - if (inputTagHelperOutput.Attributes.ContainsName("disabled")) - { - return; - } - else if (TagHelper.IsDisabled || GetAttribute(TagHelper.AspFor.ModelExplorer) != null) + if (inputTagHelperOutput.Attributes.ContainsName("disabled") == false && + (TagHelper.IsDisabled || GetAttribute(TagHelper.AspFor.ModelExplorer) != null)) { inputTagHelperOutput.Attributes.Add("disabled", ""); } @@ -151,11 +165,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form protected virtual void AddReadOnlyAttribute(TagHelperOutput inputTagHelperOutput) { - if (inputTagHelperOutput.Attributes.ContainsName("readonly")) - { - return; - } - else if (TagHelper.IsReadonly || GetAttribute(TagHelper.AspFor.ModelExplorer) != null) + if (inputTagHelperOutput.Attributes.ContainsName("readonly") == false && + (TagHelper.IsReadonly != AbpReadonlyInputType.False || GetAttribute(TagHelper.AspFor.ModelExplorer) != null)) { inputTagHelperOutput.Attributes.Add("readonly", ""); } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpReadonlyInputType.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpReadonlyInputType.cs new file mode 100644 index 0000000000..415abf2ef7 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpReadonlyInputType.cs @@ -0,0 +1,9 @@ +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +{ + public enum AbpReadonlyInputType + { + False, + True, + True_PlainText + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/ReadOnlyInput.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/ReadOnlyInput.cs index 6cef8594b3..c63cd6d88c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/ReadOnlyInput.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/ReadOnlyInput.cs @@ -8,8 +8,15 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form [AttributeUsage(AttributeTargets.Property)] public class ReadOnlyInput : Attribute { + public bool PlainText { get; set; } + public ReadOnlyInput() { } + + public ReadOnlyInput(bool plainText) + { + PlainText = plainText; + } } } From 5bcccd4866fffc40cb1d6da166d2824222515cd9 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 19 Dec 2018 14:05:04 +0300 Subject: [PATCH 074/368] abp select tag helper fixes --- .../TagHelpers/AbpTagHelperService.cs | 2 + .../Form/AbpSelectTagHelperService.cs | 73 +++++++++---------- 2 files changed, 36 insertions(+), 39 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs index 332210271b..ce47163be0 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs @@ -66,6 +66,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers var innerContext = new TagHelperContext(attributeList, context.Items, Guid.NewGuid().ToString()); + tagHelper.Init(context); + if (runAsync) { AsyncHelper.RunSync(() => tagHelper.ProcessAsync(innerContext, innerOutput)); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs index ad5b4c62cf..7caf61b47e 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -38,6 +39,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { output.TagName = "div"; output.Attributes.AddClass("form-group"); + LeaveOnlyGroupAttributes(context, output); output.TagMode = TagMode.StartTagAndEndTag; output.Content.SetHtmlContent(innerHtml); } @@ -59,16 +61,14 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form protected virtual TagHelperOutput GetSelectTag(TagHelperContext context, TagHelperOutput output) { - var selectItems = GetSelectItems(context, output); - var selectTagHelper = new SelectTagHelper(_generator) { For = TagHelper.AspFor, - Items = selectItems, + Items = GetSelectItems(context, output), ViewContext = TagHelper.ViewContext }; - var inputTagHelperOutput = GetInnerTagHelper(new TagHelperAttributeList(), context, selectTagHelper, "select", TagMode.StartTagAndEndTag); + var inputTagHelperOutput = GetInnerTagHelper(GetInputAttributes(context, output), context, selectTagHelper, "select", TagMode.StartTagAndEndTag); inputTagHelperOutput.Attributes.AddClass("form-control"); inputTagHelperOutput.Attributes.AddClass(GetSize(context,output)); @@ -98,8 +98,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form throw new Exception("No items provided for select attribute."); } - SetSelectedValue(context, output, selectItems); - return selectItems; } @@ -128,39 +126,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form return selectItems != null; } - protected virtual void SetSelectedValue(TagHelperContext context, TagHelperOutput output, List selectItems) - { - if (!selectItems.Any(si => si.Selected)) - { - var selectedValue = GetSelectedValue(context, output); - - var itemToBeSelected = selectItems.FirstOrDefault(si => si.Value.ToString() == selectedValue); - - if (itemToBeSelected != null) - { - itemToBeSelected.Selected = true; - } - } - } - - protected virtual string GetSelectedValue(TagHelperContext context, TagHelperOutput output) - { - var modelExplorer = TagHelper.AspFor.ModelExplorer; - - if (modelExplorer.Metadata.IsEnum) - { - var baseType = modelExplorer.Model?.GetType().GetEnumUnderlyingType(); - - if (baseType == null) { return null; } - - return Convert.ChangeType(modelExplorer.Model, baseType)?.ToString() ?? ""; - } - else - { - return modelExplorer.Model?.ToString(); - } - } - protected virtual string GetLabelAsHtmlUsingTagHelper(TagHelperContext context, TagHelperOutput output) { var labelTagHelper = new LabelTagHelper(_generator) @@ -193,5 +158,35 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form return ""; } + + protected virtual TagHelperAttributeList GetInputAttributes(TagHelperContext context, TagHelperOutput output) + { + var groupPrefix = "group-"; + + var tagHelperAttributes = output.Attributes.Where(a => !a.Name.StartsWith(groupPrefix)).ToList(); + var attrList = new TagHelperAttributeList(); + + foreach (var tagHelperAttribute in tagHelperAttributes) + { + attrList.Add(tagHelperAttribute); + } + + return attrList; + } + + protected virtual void LeaveOnlyGroupAttributes(TagHelperContext context, TagHelperOutput output) + { + var groupPrefix = "group-"; + var tagHelperAttributes = output.Attributes.Where(a => a.Name.StartsWith(groupPrefix)).ToList(); + + output.Attributes.Clear(); + + foreach (var tagHelperAttribute in tagHelperAttributes) + { + var nameWithoutPrefix = tagHelperAttribute.Name.Substring(groupPrefix.Length); + var newAttritube = new TagHelperAttribute(nameWithoutPrefix, tagHelperAttribute.Value); + output.Attributes.Add(newAttritube); + } + } } } \ No newline at end of file From d5a69b1f9cfe12e23c87223af82c687b5060b34e Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 19 Dec 2018 16:22:33 +0300 Subject: [PATCH 075/368] Abp Select Tag Helper bug fix --- .../TagHelpers/Form/AbpSelectTagHelperService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs index 7caf61b47e..4ed0c70356 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs @@ -38,8 +38,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form else { output.TagName = "div"; - output.Attributes.AddClass("form-group"); LeaveOnlyGroupAttributes(context, output); + output.Attributes.AddClass("form-group"); output.TagMode = TagMode.StartTagAndEndTag; output.Content.SetHtmlContent(innerHtml); } From edb70e054be79fbc4665033418d8ffb2ed3e3703 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 19 Dec 2018 16:25:58 +0300 Subject: [PATCH 076/368] added fom element tag helper docs --- .../Pages/Components/FormElements.cshtml | 465 ++++++++++++++++++ .../Pages/Components/FormElements.cshtml.cs | 81 +++ 2 files changed, 546 insertions(+) create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/FormElements.cshtml create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/FormElements.cshtml.cs diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/FormElements.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/FormElements.cshtml new file mode 100644 index 0000000000..82b9bee992 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/FormElements.cshtml @@ -0,0 +1,465 @@ +@page +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components +@model FormElementsModel + +@{ + ViewData["Title"] = "Form Elements"; +} + +@section styles { + + + +} + +@section scripts { + + @* + *@ + +} + + + + + + + +

Form Elements

+ +

Example

+ +
+
+ + + +
+
+ + +

+ public class FormElementsModel : PageModel
+    {
+        public SampleModel MyModel { get; set; }
+
+        public void OnGet()
+        {
+            MyModel = new SampleModel();
+        }
+
+        public class SampleModel
+        {
+            [Required]
+            public string Name { get; set; }
+
+            [Required]
+            [DataType(DataType.Password)]
+            public string Password { get; set; }
+
+            public bool CheckMeOut { get; set; }
+        }
+    }
+
+
+ +

+<abp-input asp-for="@@Model.MyModel.Name" label="Name"/>
+<abp-input asp-for="@@Model.MyModel.Password" label="Password" />
+<abp-input asp-for="@@Model.MyModel.CheckMeOut" label="Check Me Out" />
+
+
+ +

+<div class="form-group">
+<label for="MyModel_Name">Name</label>
+<input type="text" data-val="true" data-val-required="The Name field is required." id="MyModel_Name" name="MyModel.Name" value="" class="form-control ">
+<span class="text-danger field-validation-valid" data-valmsg-for="MyModel.Name" data-valmsg-replace="true"></span>
+</div>
+<div class="form-group">
+<label for="MyModel_Password">Password</label>
+<input type="password" data-val="true" data-val-required="The Password field is required." id="MyModel_Password" name="MyModel.Password" class="form-control ">
+<span class="text-danger field-validation-valid" data-valmsg-for="MyModel.Password" data-valmsg-replace="true"></span>
+</div>
+<div class="form-check">
+<input type="checkbox" data-val="true" data-val-required="The CheckMeOut field is required." id="MyModel_CheckMeOut" name="MyModel.CheckMeOut" value="true" class="form-check-input "><input name="MyModel.CheckMeOut" type="hidden" value="false">
+<label class="form-check-label" for="MyModel_CheckMeOut">Check Me Out</label>
+</div>
+
+
+
+
+
+ +

Form controls

+ +
+
+ + + + +
+
+ + +

+ public class FormElementsModel : PageModel
+    {
+        public SampleModel MyModel { get; set; }
+                    
+        public List<SelectListItem> CityList { get; set; } = new List<SelectListItem>
+        {
+            new SelectListItem { Value = "NY", Text = "New York"},
+            new SelectListItem { Value = "LDN", Text = "London"},
+            new SelectListItem { Value = "IST", Text = "Istanbul"},
+            new SelectListItem { Value = "MOS", Text = "Moscow"}
+        };
+
+        public void OnGet()
+        {
+            MyModel = new SampleModel();
+        }
+
+        public class SampleModel
+        {
+            [Required]
+            public string EmailAddress { get; set; }
+
+            public string City { get; set; }
+
+            public List<string> Cities { get; set; }
+
+            [TextArea]
+            public string Description { get; set; }
+        }
+    }
+
+
+ +

+<abp-input asp-for="@@Model.MyModel.EmailAddress" label="Email Address" placeholder="name@example.com" />
+<abp-select asp-for="@@Model.MyModel.City" asp-items="@@Model.CityList" label="City" />
+<abp-select asp-for="@@Model.MyModel.Cities" asp-items="@@Model.CityList" label="Cities" />
+<abp-input asp-for="@@Model.MyModel.Description" label="Description" />
+
+
+ +

+<div class="form-group">
+<label for="MyModel_EmailAddress">Email Address</label>
+<input placeholder="name@example.com" type="text" data-val="true" data-val-required="The EmailAddress field is required." id="MyModel_EmailAddress" name="MyModel.EmailAddress" value="" class="form-control ">
+<span class="text-danger field-validation-valid" data-valmsg-for="MyModel.EmailAddress" data-valmsg-replace="true"></span>
+</div>
+<div class="form-group">
+<label for="MyModel_City">City</label>
+<select id="MyModel_City" name="MyModel.City" class="form-control">
+<option value="NY">New York</option>
+<option value="LDN">London</option>
+<option value="IST">Istanbul</option>
+<option value="MOS">Moscow</option>
+</select>
+</div>
+<div class="form-group">
+<label for="MyModel_Cities">Cities</label>
+<select id="MyModel_Cities" multiple="multiple" name="MyModel.Cities" class="form-control">
+<option value="NY">New York</option>
+<option value="LDN">London</option>
+<option value="IST">Istanbul</option>
+<option value="MOS">Moscow</option>
+</select>
+</div>
+<div class="form-group">
+<label for="MyModel_Description">Description</label>
+<textarea id="MyModel_Description" name="MyModel.Description" class="form-control "></textarea>
+<span class="text-danger field-validation-valid" data-valmsg-for="MyModel.Description" data-valmsg-replace="true"></span>
+</div>
+
+
+
+
+
+ +

Sizing

+ +
+
+ + +
+
+ + +

+ public class FormElementsModel : PageModel
+    {
+        public SampleModel MyModel { get; set; }
+
+        public void OnGet()
+        {
+            MyModel = new SampleModel();
+        }
+
+        public class SampleModel
+        {
+            public string LargeInput { get; set; }
+
+            public string SmallInput { get; set; }
+        }
+    }
+
+
+ +

+<abp-input asp-for="@@Model.MyModel.LargeInput" size="Large" />
+<abp-input asp-for="@@Model.MyModel.SmallInput" size="Small" />
+
+
+ +

+<div class="form-group">
+<label for="MyModel_LargeInput">LargeInput</label>
+<input type="text" id="MyModel_LargeInput" name="MyModel.LargeInput" value="" class="form-control form-control-lg">
+<span class="text-danger field-validation-valid" data-valmsg-for="MyModel.LargeInput" data-valmsg-replace="true"></span>
+</div>
+<div class="form-group">
+<label for="MyModel_SmallInput">SmallInput</label>
+<input type="text" id="MyModel_SmallInput" name="MyModel.SmallInput" value="" class="form-control form-control-sm">
+<span class="text-danger field-validation-valid" data-valmsg-for="MyModel.SmallInput" data-valmsg-replace="true"></span>
+</div>
+
+
+
+
+
+ +

Disabled And ReadOnly

+ +
+
+ + + +
+
+ + +

+ public class FormElementsModel : PageModel
+    {
+        public SampleModel MyModel { get; set; }
+
+        public void OnGet()
+        {
+            MyModel = new SampleModel();
+            MyModel.SampleInput0 = "This is a disabled input.";
+            MyModel.SampleInput0 = "This is a disabled input.";
+            MyModel.SampleInput1 = "This is a readonly input.";
+            MyModel.SampleInput2 = "This is a readonly plain-text.";
+        }
+
+        public class SampleModel
+        {
+            public string SampleInput0 { get; set; }
+                    
+            public string SampleInput1 { get; set; }
+
+            public string SampleInput2 { get; set; }
+        }
+    }
+
+
+ +

+<abp-input asp-for="@@Model.MyModel.SampleInput0" disabled="true" />
+<abp-input asp-for="@@Model.MyModel.SampleInput1" readonly="True" />
+<abp-input asp-for="@@Model.MyModel.SampleInput2" readonly="True_PlainText"/>
+
+
+ +

+<div class="form-group">
+    <label for="MyModel_SampleInput0">SampleInput0</label>
+    <input type="text" id="MyModel_SampleInput0" name="MyModel.SampleInput0" value="This is a disabled input." disabled="" class="form-control ">
+    <span class="text-danger field-validation-valid" data-valmsg-for="MyModel.SampleInput0" data-valmsg-replace="true"></span>
+</div>
+<div class="form-group">
+    <label for="MyModel_SampleInput1">SampleInput1</label>
+    <input type="text" id="MyModel_SampleInput1" name="MyModel.SampleInput1" value="This is a readonly input." class="form-control " readonly="">
+    <span class="text-danger field-validation-valid" data-valmsg-for="MyModel.SampleInput1" data-valmsg-replace="true"></span>
+</div>
+<div class="form-group">
+    <label for="MyModel_SampleInput2">SampleInput2</label>
+    <input type="text" id="MyModel_SampleInput2" name="MyModel.SampleInput2" value="This is a readonly plain-text." class="form-control-plaintext " readonly="">
+    <span class="text-danger field-validation-valid" data-valmsg-for="MyModel.SampleInput2" data-valmsg-replace="true"></span>
+</div>
+
+
+
+
+
+ +

Checkboxes and radios

+ +
+
+ + +
+
+ + +

+ public class FormElementsModel : PageModel
+    {
+        public SampleModel MyModel { get; set; }
+
+        public void OnGet()
+        {
+            MyModel = new SampleModel();
+        }
+
+        public class SampleModel
+        {
+            public bool DefaultCheckbox { get; set; }
+
+            public bool DisabledCheckbox { get; set; }
+        }
+    }
+
+
+ +

+<abp-input asp-for="@@Model.MyModel.DefaultCheckbox"/>
+<abp-input asp-for="@@Model.MyModel.DisabledCheckbox" disabled="true"/>
+
+
+ +

+<div class="form-check">
+    <input type="checkbox" data-val="true" data-val-required="The DefaultCheckbox field is required." id="MyModel_DefaultCheckbox" name="MyModel.DefaultCheckbox" value="true" class="form-check-input "><input name="MyModel.DefaultCheckbox" type="hidden" value="false">
+    <label class="form-check-label" for="MyModel_DefaultCheckbox">DefaultCheckbox</label>
+</div>
+<div class="form-check">
+    <input type="checkbox" data-val="true" data-val-required="The DisabledCheckbox field is required." id="MyModel_DisabledCheckbox" name="MyModel.DisabledCheckbox" value="true" disabled="" class="form-check-input "><input name="MyModel.DisabledCheckbox" type="hidden" value="false">
+    <label class="form-check-label" for="MyModel_DisabledCheckbox">DisabledCheckbox</label>
+</div>
+
+
+
+
+
+ +
+
+ +
+
+ + +

+ public class FormElementsModel : PageModel
+    {
+        public SampleModel MyModel { get; set; }
+
+        public void OnGet()
+        {
+            MyModel = new SampleModel();
+            MyModel.CityRadio = "IST";
+        }
+
+        public class SampleModel
+        {
+            [Display(Name="City")]
+            public string CityRadio { get; set; }
+        }
+    }
+
+
+ +

+<abp-radio asp-for="@@Model.MyModel.CityRadio" asp-items="@@Model.CityList" inline="true"/>
+
+
+ +

+<div>
+    <div class="custom-control custom-radio custom-control-inline">
+        <input type="radio" id="MyModel.CityRadioRadioNY" name="MyModel.CityRadio" value="NY" class="custom-control-input">
+        <label class="custom-control-label" for="MyModel.CityRadioRadioNY">New York</label>
+    </div>
+    <div class="custom-control custom-radio custom-control-inline">
+        <input type="radio" id="MyModel.CityRadioRadioLDN" name="MyModel.CityRadio" value="LDN" class="custom-control-input">
+        <label class="custom-control-label" for="MyModel.CityRadioRadioLDN">London</label>
+    </div>
+    <div class="custom-control custom-radio custom-control-inline">
+        <input type="radio" id="MyModel.CityRadioRadioIST" name="MyModel.CityRadio" value="IST" checked="checked" class="custom-control-input">
+        <label class="custom-control-label" for="MyModel.CityRadioRadioIST">Istanbul</label>
+    </div>
+    <div class="custom-control custom-radio custom-control-inline">
+        <input type="radio" id="MyModel.CityRadioRadioMOS" name="MyModel.CityRadio" value="MOS" class="custom-control-input">
+        <label class="custom-control-label" for="MyModel.CityRadioRadioMOS">Moscow</label>
+    </div>
+</div>
+
+
+
+
+
+ +

Enum

+ +
+
+ +
+
+ + +

+ public class FormElementsModel : PageModel
+    {
+        public SampleModel MyModel { get; set; }
+
+        public void OnGet()
+        {
+            MyModel = new SampleModel();
+        }
+
+        public class SampleModel
+        {
+            public CarType CarType { get; set; }
+        }
+
+        public enum CarType
+        {
+            Sedan,
+            Hatchback,
+            StationWagon,
+            Coupe
+        }
+    }
+
+
+ +

+<abp-select asp-for="@Model.MyModel.CarType"/>
+
+
+ +

+ <div class="form-group">
+     <label for="MyModel_CarType">CarType</label>
+     <select data-val="true" data-val-required="The CarType field is required." id="MyModel_CarType" name="MyModel.CarType" class="form-control">
+         <option selected="selected" value="0">Sedan</option>
+         <option value="1">Hatchback</option>
+         <option value="2">StationWagon</option>
+         <option value="3">Coupe</option>
+     </select>
+ </div>
+
+
+
+
+
\ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/FormElements.cshtml.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/FormElements.cshtml.cs new file mode 100644 index 0000000000..6a3f432220 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/FormElements.cshtml.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.AspNetCore.Mvc.Rendering; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components +{ + public class FormElementsModel : PageModel + { + [BindProperty] + public SampleModel MyModel { get; set; } + + public List CityList { get; set; } = new List + { + new SelectListItem { Value = "NY", Text = "New York"}, + new SelectListItem { Value = "LDN", Text = "London"}, + new SelectListItem { Value = "IST", Text = "Istanbul"}, + new SelectListItem { Value = "MOS", Text = "Moscow"} + }; + + public void OnGet() + { + MyModel = new SampleModel(); + MyModel.SampleInput0 = "This is a disabled input."; + MyModel.SampleInput1 = "This is a readonly input."; + MyModel.SampleInput2 = "This is a readonly plain-text."; + MyModel.CityRadio = "IST"; + } + + public class SampleModel + { + public string Name { get; set; } + + public string SampleInput0 { get; set; } + + public string SampleInput1 { get; set; } + + public string SampleInput2 { get; set; } + + public string LargeInput { get; set; } + + public string SmallInput { get; set; } + + [TextArea] + public string Description { get; set; } + + public string EmailAddress { get; set; } + + [Required] + [DataType(DataType.Password)] + public string Password { get; set; } + + public bool CheckMeOut { get; set; } + + public bool DefaultCheckbox { get; set; } + + public bool DisabledCheckbox { get; set; } + + public CarType CarType { get; set; } + + public string City { get; set; } + + [Display(Name="City")] + public string CityRadio { get; set; } + + public List Cities { get; set; } + } + + public enum CarType + { + Sedan, + Hatchback, + StationWagon, + Coupe + } + } +} \ No newline at end of file From c38fdd2cf433a037b55cdcb3731007630e38a3da Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Wed, 19 Dec 2018 16:29:32 +0300 Subject: [PATCH 077/368] Resolved #654: Use async methods in FileSystemDocumentStore. --- .../Volo.Abp.Core/Volo/Abp/IO/FileHelper.cs | 35 ++++++++++++++++++- .../Documents/FileSystemDocumentStore.cs | 5 +-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/IO/FileHelper.cs b/framework/src/Volo.Abp.Core/Volo/Abp/IO/FileHelper.cs index 0f4514a066..21ca7c2086 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/IO/FileHelper.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/IO/FileHelper.cs @@ -1,4 +1,7 @@ -using System.IO; +using System; +using System.IO; +using System.Text; +using System.Threading.Tasks; using JetBrains.Annotations; namespace Volo.Abp.IO @@ -41,5 +44,35 @@ namespace Volo.Abp.IO return fileNameWithExtension.Substring(lastDotIndex + 1); } + + /// + /// Opens a text file, reads all lines of the file, and then closes the file. + /// + /// The file to open for reading. + /// A string containing all lines of the file. + public static async Task ReadAllTextAsync(string path) + { + using (var reader = File.OpenText(path)) + { + return await reader.ReadToEndAsync(); + } + } + + /// + /// Opens a text file, reads all lines of the file, and then closes the file. + /// + /// The file to open for reading. + /// A string containing all lines of the file. + public static async Task ReadAllBytesAsync(string path) + { + using (var stream = File.Open(path, FileMode.Open)) + { + var result = new byte[stream.Length]; + await stream.ReadAsync(result, 0, (int)stream.Length); + return result; + } + } + + //TODO: ReadAllLinesAsync } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Documents/FileSystemDocumentStore.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Documents/FileSystemDocumentStore.cs index a0a341fa04..dccc99fc75 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Documents/FileSystemDocumentStore.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Documents/FileSystemDocumentStore.cs @@ -2,6 +2,7 @@ using System.IO; using System.Threading.Tasks; using Volo.Abp.Domain.Services; +using Volo.Abp.IO; using Volo.Docs.Documents; using Volo.Docs.FileSystem.Projects; using Volo.Docs.Projects; @@ -15,7 +16,7 @@ namespace Volo.Docs.FileSystem.Documents public async Task GetDocument(Project project, string documentName, string version) { var path = Path.Combine(project.GetFileSystemPath(), documentName); - var content = File.ReadAllText(path); //TODO: async! + var content = await FileHelper.ReadAllTextAsync(path); var localDirectory = ""; if (documentName.Contains("/")) @@ -43,7 +44,7 @@ namespace Volo.Docs.FileSystem.Documents public async Task GetResource(Project project, string resourceName, string version) { var path = Path.Combine(project.GetFileSystemPath(), resourceName); - return new DocumentResource(File.ReadAllBytes(path)); + return new DocumentResource(await FileHelper.ReadAllBytesAsync(path)); } } } From bf47922e33bcfafa847280e62ffd7aa66a6358a9 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Wed, 19 Dec 2018 17:00:57 +0300 Subject: [PATCH 078/368] Check directory path for security. --- .../DefaultHttpExceptionStatusCodeFinder.cs | 4 ++- .../Volo/Abp/IO/DirectoryHelper.cs | 35 ++++++++++++++++--- .../Documents/FileSystemDocumentStore.cs | 24 +++++++++++-- .../Documents/DocumentResourceController.cs | 1 - 4 files changed, 56 insertions(+), 8 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/DefaultHttpExceptionStatusCodeFinder.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/DefaultHttpExceptionStatusCodeFinder.cs index c188e5dc40..7625fa1d63 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/DefaultHttpExceptionStatusCodeFinder.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ExceptionHandling/DefaultHttpExceptionStatusCodeFinder.cs @@ -39,6 +39,8 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling : HttpStatusCode.Unauthorized; } + //TODO: Handle SecurityException..? + if (exception is AbpValidationException) { return HttpStatusCode.BadRequest; @@ -58,7 +60,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling { return HttpStatusCode.Forbidden; } - + return HttpStatusCode.InternalServerError; } } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/IO/DirectoryHelper.cs b/framework/src/Volo.Abp.Core/Volo/Abp/IO/DirectoryHelper.cs index 93afea9264..c4185cbbed 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/IO/DirectoryHelper.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/IO/DirectoryHelper.cs @@ -1,4 +1,5 @@ using System.IO; +using JetBrains.Annotations; namespace Volo.Abp.IO { @@ -7,10 +8,6 @@ namespace Volo.Abp.IO /// public static class DirectoryHelper { - /// - /// Creates a new directory if it does not exists. - /// - /// Directory to create public static void CreateIfNotExists(string directory) { if (!Directory.Exists(directory)) @@ -18,5 +15,35 @@ namespace Volo.Abp.IO Directory.CreateDirectory(directory); } } + + public static bool IsSubDirectoryOf([NotNull] string parentDirectoryPath, [NotNull] string childDirectoryPath) + { + Check.NotNull(parentDirectoryPath, nameof(parentDirectoryPath)); + Check.NotNull(childDirectoryPath, nameof(childDirectoryPath)); + + return IsSubDirectoryOf( + new DirectoryInfo(parentDirectoryPath), + new DirectoryInfo(childDirectoryPath) + ); + } + + public static bool IsSubDirectoryOf([NotNull] DirectoryInfo parentDirectory, [NotNull] DirectoryInfo childDirectory) + { + Check.NotNull(parentDirectory, nameof(parentDirectory)); + Check.NotNull(childDirectory, nameof(childDirectory)); + + if (parentDirectory.FullName == childDirectory.FullName) + { + return true; + } + + var parentOfChild = childDirectory.Parent; + if (parentOfChild == null) + { + return false; + } + + return IsSubDirectoryOf(parentDirectory, parentOfChild); + } } } diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Documents/FileSystemDocumentStore.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Documents/FileSystemDocumentStore.cs index dccc99fc75..a8366554dc 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Documents/FileSystemDocumentStore.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Documents/FileSystemDocumentStore.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.IO; +using System.Security; using System.Threading.Tasks; using Volo.Abp.Domain.Services; using Volo.Abp.IO; @@ -15,7 +16,11 @@ namespace Volo.Docs.FileSystem.Documents public async Task GetDocument(Project project, string documentName, string version) { - var path = Path.Combine(project.GetFileSystemPath(), documentName); + var projectFolder = project.GetFileSystemPath(); + var path = Path.Combine(projectFolder, documentName); + + CheckDirectorySecurity(projectFolder, path); + var content = await FileHelper.ReadAllTextAsync(path); var localDirectory = ""; @@ -43,8 +48,23 @@ namespace Volo.Docs.FileSystem.Documents public async Task GetResource(Project project, string resourceName, string version) { - var path = Path.Combine(project.GetFileSystemPath(), resourceName); + var projectFolder = project.GetFileSystemPath(); + var path = Path.Combine(projectFolder, resourceName); + + if (!DirectoryHelper.IsSubDirectoryOf(projectFolder, path)) + { + throw new SecurityException("Can not get a resource file out of the project folder!"); + } + return new DocumentResource(await FileHelper.ReadAllBytesAsync(path)); } + + private static void CheckDirectorySecurity(string projectFolder, string path) + { + if (!DirectoryHelper.IsSubDirectoryOf(projectFolder, path)) + { + throw new SecurityException("Can not get a resource file out of the project folder!"); + } + } } } diff --git a/modules/docs/src/Volo.Docs.Web/Areas/Documents/DocumentResourceController.cs b/modules/docs/src/Volo.Docs.Web/Areas/Documents/DocumentResourceController.cs index 0061c6e999..b5cec70a5b 100644 --- a/modules/docs/src/Volo.Docs.Web/Areas/Documents/DocumentResourceController.cs +++ b/modules/docs/src/Volo.Docs.Web/Areas/Documents/DocumentResourceController.cs @@ -24,7 +24,6 @@ namespace Volo.Docs.Areas.Documents [HttpGet] [Route("")] - //[Produces(MimeTypes.Image.Jpeg, MimeTypes.Image.Png, MimeTypes.Image.Gif)] public async Task GetResource(GetDocumentResourceInput input) { input.Name = input.Name.RemovePreFix("/"); From 0eb355e2e61d3a69e547b56821b1f7764fe73d5b Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 19 Dec 2018 17:49:15 +0300 Subject: [PATCH 079/368] dynamic form tag helper docs --- .../Pages/Components/DynamicForms.cshtml | 526 +++++++++++++----- .../Pages/Components/DynamicForms.cshtml.cs | 133 +++-- 2 files changed, 496 insertions(+), 163 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml index b259d071ca..026c8c4339 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml @@ -12,166 +12,444 @@ } +@section scripts { + + @* + *@ + +} + + + + +

Dynamic Forms

-

# Dynamic Form Example

+

Dynamic Form Example

- -
-
Posted Values:
-
- Name: @Model.PersonInput.Name
- City: @Model.PersonInput.City
- Phone.Name: @Model.PersonInput.Phone.Name
- Phone.Number: @Model.PersonInput.Phone.Number
- Day: @Model.PersonInput.Day.ToString("yyyy-MM-dd")
- Country: @Model.PersonInput.Country
- IsActive: @Model.PersonInput.IsActive
-
+
-
-<abp-dynamic-form abp-model="Model.PersonInput"/>
-
-
-
+ + +

+public class DynamicFormsModel : PageModel
+    {
+        [BindProperty]
+        public DetailedModel MyDetailedModel { get; set; }
 
-

# Override an input Example

+ public List<SelectListItem> CountryList { get; set; } = new List<SelectListItem> + { + new SelectListItem { Value = "CA", Text = "Canada"}, + new SelectListItem { Value = "US", Text = "USA"}, + new SelectListItem { Value = "UK", Text = "United Kingdom"}, + new SelectListItem { Value = "RU", Text = "Russia"} + }; -
-
- - - - - -
-
Posted Values:
-
- Name: @Model.PersonInput.Name
- Surname: @Model.PersonInput.Surname
- City: @Model.PersonInput.City
- Phone.Name: @Model.PersonInput.Phone.Name
- Phone.Number: @Model.PersonInput.Phone.Number
- Day: @Model.PersonInput.Day.ToString("yyyy-MM-dd")
- Country: @Model.PersonInput.Country
- IsActive: @Model.PersonInput.IsActive
-
-
-
-
-<abp-dynamic-form abp-model="Model.PersonInput">
-    <abp-input asp-for="Model.PersonInput.Name" label="Overrided name" />
-    <abp-input asp-for="Model.PersonInput.Phone.Number" label="Overrided number" />
-    <abp-button button-type="Primary" type="submit" text="submit" />
-</abp-dynamic-form>
-
+ public void OnGet() + { + MyDetailedModel = new DetailedModel + { + Name = "John Surname", + Description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + IsActive = true, + Age = 65, + Day = DateTime.Now, + MyCarType = CarType.Coupe, + YourCarType = CarType.Sedan, + Country = "RU", + NeighborCountries = new List<string>() { "UK", "CA" } + }; + } + + public class DetailedModel + { + [Required] + [Display(Name = "Name")] + public string Name { get; set; } + + [TextArea(Rows = 4)] + [Display(Name = "Description")] + public string Description { get; set; } + + [Required] + [DataType(DataType.Password)] + [Display(Name = "Password")] + public string Password { get; set; } + + [Display(Name = "Is Active")] + public bool IsActive { get; set; } + + [Required] + [Display(Name = "Age")] + public int Age { get; set; } + + [Required] + [Display(Name = "My Car Type")] + public CarType MyCarType { get; set; } + + [Required] + [AbpRadioButton(Inline = true)] + [Display(Name = "Your Car Type")] + public CarType YourCarType { get; set; } + + [DataType(DataType.Date)] + [Display(Name = "Day")] + public DateTime Day { get; set; } + + [SelectItems(nameof(CountryList))] + [Display(Name = "Country")] + public string Country { get; set; } + + [SelectItems(nameof(CountryList))] + [Display(Name = "Neighbor Countries")] + public List<string> NeighborCountries { get; set; } + } + + public enum CarType + { + Sedan, + Hatchback, + StationWagon, + Coupe + } + } +
+
+ +

+<abp-dynamic-form abp-model="@Model.MyDetailedModel" submit-button="true" />
+
+
+ +

+<form method="post" novalidate="novalidate">
+    <div class="form-group">
+<label for="MyDetailedModel_Name">Name</label>
+<input type="text" data-val="true" data-val-required="The Name field is required." id="MyDetailedModel_Name" name="MyDetailedModel.Name" value="John Surname" class="form-control ">
+<span class="text-danger field-validation-valid" data-valmsg-for="MyDetailedModel.Name" data-valmsg-replace="true"></span>
+    </div>
+    <div class="form-group">
+<label for="MyDetailedModel_Description">Description</label>
+<textarea id="MyDetailedModel_Description" name="MyDetailedModel.Description" rows="4" class="form-control ">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</textarea>
+<span class="text-danger field-validation-valid" data-valmsg-for="MyDetailedModel.Description" data-valmsg-replace="true"></span>
+    </div>
+    <div class="form-group">
+<label for="MyDetailedModel_Password">Password</label>
+<input type="password" data-val="true" data-val-required="The Password field is required." id="MyDetailedModel_Password" name="MyDetailedModel.Password" class="form-control ">
+<span class="text-danger field-validation-valid" data-valmsg-for="MyDetailedModel.Password" data-valmsg-replace="true"></span>
+    </div>
+    <div class="form-check">
+<input type="checkbox" checked="checked" data-val="true" data-val-required="The Is Active field is required." id="MyDetailedModel_IsActive" name="MyDetailedModel.IsActive" value="true" class="form-check-input "><input name="MyDetailedModel.IsActive" type="hidden" value="false">
+<label class="form-check-label" for="MyDetailedModel_IsActive">Is Active</label>
+    </div>
+    <div class="form-group">
+<label for="MyDetailedModel_Age">Age</label>
+<input type="number" data-val="true" data-val-required="The Age field is required." id="MyDetailedModel_Age" name="MyDetailedModel.Age" value="65" class="form-control ">
+<span class="text-danger field-validation-valid" data-valmsg-for="MyDetailedModel.Age" data-valmsg-replace="true"></span>
+    </div>
+    <div class="form-group">
+<label for="MyDetailedModel_MyCarType">My Car Type</label>
+<select data-val="true" data-val-required="The My Car Type field is required." id="MyDetailedModel_MyCarType" name="MyDetailedModel.MyCarType" class="form-control valid" aria-describedby="MyDetailedModel_MyCarType-error" aria-invalid="false">
+    <option value="0">Sedan</option>
+    <option value="1">Hatchback</option>
+    <option value="2">StationWagon</option>
+    <option selected="selected" value="3">Coupe</option>
+</select>
+    </div>
+    <div class="custom-control custom-radio custom-control-inline">
+<input type="radio" id="MyDetailedModel.YourCarTypeRadio0" name="MyDetailedModel.YourCarType" value="0" checked="checked" class="custom-control-input">
+<label class="custom-control-label" for="MyDetailedModel.YourCarTypeRadio0">Sedan</label>
+    </div>
+    <div class="custom-control custom-radio custom-control-inline">
+<input type="radio" id="MyDetailedModel.YourCarTypeRadio1" name="MyDetailedModel.YourCarType" value="1" class="custom-control-input">
+<label class="custom-control-label" for="MyDetailedModel.YourCarTypeRadio1">Hatchback</label>
+    </div>
+    <div class="custom-control custom-radio custom-control-inline">
+<input type="radio" id="MyDetailedModel.YourCarTypeRadio2" name="MyDetailedModel.YourCarType" value="2" class="custom-control-input">
+<label class="custom-control-label" for="MyDetailedModel.YourCarTypeRadio2">StationWagon</label>
+    </div>
+    <div class="custom-control custom-radio custom-control-inline">
+<input type="radio" id="MyDetailedModel.YourCarTypeRadio3" name="MyDetailedModel.YourCarType" value="3" class="custom-control-input">
+<label class="custom-control-label" for="MyDetailedModel.YourCarTypeRadio3">Coupe</label>
+    </div>
+    <div class="form-group">
+<label for="MyDetailedModel_Day">Day</label>
+<input type="date" data-val="true" data-val-required="The Day field is required." id="MyDetailedModel_Day" name="MyDetailedModel.Day" value="2018-12-19" class="form-control ">
+<span class="text-danger field-validation-valid" data-valmsg-for="MyDetailedModel.Day" data-valmsg-replace="true"></span>
+    </div>
+    <div class="form-group">
+<label for="MyDetailedModel_Country">Country</label>
+<select id="MyDetailedModel_Country" name="MyDetailedModel.Country" class="form-control">
+    <option value="CA">Canada</option>
+    <option value="US">USA</option>
+    <option value="UK">United Kingdom</option>
+    <option selected="selected" value="RU">Russia</option>
+</select>
+    </div>
+    <div class="form-group">
+<label for="MyDetailedModel_NeighborCountries">Neighbor Countries</label>
+<select id="MyDetailedModel_NeighborCountries" multiple="multiple" name="MyDetailedModel.NeighborCountries" class="form-control">
+    <option selected="selected" value="CA">Canada</option>
+    <option value="US">USA</option>
+    <option selected="selected" value="UK">United Kingdom</option>
+    <option value="RU">Russia</option>
+</select>
+    </div>
+    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Kbwu8pRBWJCh6KUtTDoAuTDS8evmWgc2dNZYWkzjZ1xFcA9ptyCgQBCTgA9NMoh_FXGRBDVunA7fx0TF1df1_OxaxerJvuWRCwFBhy8KbPcgXrVtmtSp6Z28gpFpO0Z1TSO1pdgdTwEXj43DBWq0Hc">
+    <button type="submit" class="btn btn-primary" data-busy-text="Processing..."><span>Submit</span></button>
+</form>
+
+
+
-

# Form with Button Example

+

Order Attribute Example

- -
-
Posted Values:
-
- Name: @Model.PersonInput.Name
- Surname: @Model.PersonInput.Surname
- City: @Model.PersonInput.City
- Phone.Name: @Model.PersonInput.Phone.Name
- Phone.Number: @Model.PersonInput.Phone.Number
- Day: @Model.PersonInput.Day.ToString("yyyy-MM-dd")
- Country: @Model.PersonInput.Country
- IsActive: @Model.PersonInput.IsActive
-
+
-
-<abp-dynamic-form abp-model="Model.PersonInput" submit-button="true"/>
-
+ + +

+public class DynamicFormsModel : PageModel
+    {
+        public OrderExampleModel MyOrderExampleModel { get; set; }
+
+        public void OnGet()
+        {
+            MyOrderExampleModel = new OrderExampleModel();
+        }
+
+        public class OrderExampleModel
+        {
+            [DisplayOrder(10005)]
+            public string Surname{ get; set; }
+
+            //Default 10000
+            public string EmailAddress { get; set; }
+
+            [DisplayOrder(10003)]
+            public string Name { get; set; }
+
+            [DisplayOrder(9999)]
+            public string City { get; set; }
+        }
+    }
+
+
+ +

+    <abp-dynamic-form abp-model="Model.MyOrderExampleModel"/>
+
+
+ +

+<form method="post">
+    <div class="form-group">
+<label for="MyOrderExampleModel_City">City</label>
+<input type="text" id="MyOrderExampleModel_City" name="MyOrderExampleModel.City" value="" class="form-control ">
+<span class="text-danger field-validation-valid" data-valmsg-for="MyOrderExampleModel.City" data-valmsg-replace="true"></span>
+    </div>
+    <div class="form-group">
+<label for="MyOrderExampleModel_EmailAddress">EmailAddress</label>
+<input type="text" id="MyOrderExampleModel_EmailAddress" name="MyOrderExampleModel.EmailAddress" value="" class="form-control ">
+<span class="text-danger field-validation-valid" data-valmsg-for="MyOrderExampleModel.EmailAddress" data-valmsg-replace="true"></span>
+    </div>
+    <div class="form-group">
+<label for="MyOrderExampleModel_Name">Name</label>
+<input type="text" id="MyOrderExampleModel_Name" name="MyOrderExampleModel.Name" value="" class="form-control ">
+<span class="text-danger field-validation-valid" data-valmsg-for="MyOrderExampleModel.Name" data-valmsg-replace="true"></span>
+    </div>
+    <div class="form-group">
+<label for="MyOrderExampleModel_Surname">Surname</label>
+<input type="text" id="MyOrderExampleModel_Surname" name="MyOrderExampleModel.Surname" value="" class="form-control ">
+<span class="text-danger field-validation-valid" data-valmsg-for="MyOrderExampleModel.Surname" data-valmsg-replace="true"></span>
+    </div>
+    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Kbwu8pRBWJCh6KUtTDoAuQICDXiCEgWpOHc7uIzSQ2dKiezdDkWplt2D8XLsCX39Z8B_GnplHrAfZgZ5GkNZN-tkEgKlMtyjoWv9MADyYb2MmWw-LuW8wfUXI9YSza5lo_8P03Vff4NxmrV3boG0xQ">
+</form>
+
+
+
-

# Non-dynamic Form

+

Attribute Examples

-
- - - - - - - - - - - -
-
Posted Values:
-
- Name: @Model.PersonInput.Name
- Surname: @Model.PersonInput.Surname
- Age: @Model.PersonInput.Age
- Is Active: @Model.PersonInput.IsActive
- Day: @Model.PersonInput.Day
- City: @Model.PersonInput.City
- Country: @Model.PersonInput.Country
- Phone.Number: @Model.PersonInput.Phone.Number
- Phone.Name: @Model.PersonInput.Phone.Name
-
+
-
+        
+            
+                

+public class DynamicFormsModel : PageModel
+    {
+        public AttributeExamplesModel MyAttributeExamplesModel { get; set; }
+
+        public void OnGet()
+        {
+            MyAttributeExamplesModel = new AttributeExamplesModel();
+            MyAttributeExamplesModel.DisabledInput = "Disabled Input";
+            MyAttributeExamplesModel.ReadonlyInput = "Readonly Input";
+            MyAttributeExamplesModel.ReadonlyPlainTextInput = "Readonly Plain Text Input";
+            MyAttributeExamplesModel.LargeInput = "Large Input";
+            MyAttributeExamplesModel.SmallInput = "Small Input";
+        }
+
+        public class AttributeExamplesModel
+        {
+            [HiddenInput]
+            public string HiddenInput { get; set; }
+
+            [DisabledInput]
+            public string DisabledInput{ get; set; }
+
+            [ReadOnlyInput]
+            public string ReadonlyInput { get; set; }
+
+            [ReadOnlyInput(PlainText = true)]
+            public string ReadonlyPlainTextInput { get; set; }
+
+            [FormControlSize(AbpFormControlSize.Large)]
+            public string LargeInput { get; set; }
+
+            [FormControlSize(AbpFormControlSize.Small)]
+            public string SmallInput { get; set; }
+        }
+    }
+
+
+ +

+    <abp-dynamic-form abp-model="Model.MyAttributeExamplesModel"/>
+
+
+ +

 <form method="post">
-    <abp-input asp-for="Model.PersonInput.Name" />
-    <abp-input asp-for="Model.PersonInput.Surname" />
-    <abp-input asp-for="Model.PersonInput.Age" />
-    <abp-input asp-for="Model.PersonInput.IsActive" />
-    <abp-input asp-for="Model.PersonInput.Day" />
-    <abp-select asp-for="Model.PersonInput.City" />
-    <abp-select asp-for="Model.PersonInput.Country" />
-    <abp-input asp-for="Model.PersonInput.Phone.Number" />
-    <abp-input asp-for="Model.PersonInput.Phone.Name" />
-    <abp-button type="submit" button-type="Primary" text="Submit" />
+    <div class="form-group">
+<input type="hidden" id="MyAttributeExamplesModel_HiddenInput" name="MyAttributeExamplesModel.HiddenInput" value="" class="form-control ">
+    </div>
+    <div class="form-group">
+<label for="MyAttributeExamplesModel_DisabledInput">DisabledInput</label>
+<input type="text" id="MyAttributeExamplesModel_DisabledInput" name="MyAttributeExamplesModel.DisabledInput" value="Disabled Input" disabled="" class="form-control ">
+<span class="text-danger field-validation-valid" data-valmsg-for="MyAttributeExamplesModel.DisabledInput" data-valmsg-replace="true"></span>
+    </div>
+    <div class="form-group">
+<label for="MyAttributeExamplesModel_ReadonlyInput">ReadonlyInput</label>
+<input type="text" id="MyAttributeExamplesModel_ReadonlyInput" name="MyAttributeExamplesModel.ReadonlyInput" value="Readonly Input" class="form-control " readonly="">
+<span class="text-danger field-validation-valid" data-valmsg-for="MyAttributeExamplesModel.ReadonlyInput" data-valmsg-replace="true"></span>
+    </div>
+    <div class="form-group">
+<label for="MyAttributeExamplesModel_ReadonlyPlainTextInput">ReadonlyPlainTextInput</label>
+<input type="text" id="MyAttributeExamplesModel_ReadonlyPlainTextInput" name="MyAttributeExamplesModel.ReadonlyPlainTextInput" value="Readonly Plain Text Input" class="form-control-plaintext " readonly="">
+<span class="text-danger field-validation-valid" data-valmsg-for="MyAttributeExamplesModel.ReadonlyPlainTextInput" data-valmsg-replace="true"></span>
+    </div>
+    <div class="form-group">
+<label for="MyAttributeExamplesModel_LargeInput">LargeInput</label>
+<input type="text" id="MyAttributeExamplesModel_LargeInput" name="MyAttributeExamplesModel.LargeInput" value="Large Input" class="form-control form-control-lg">
+<span class="text-danger field-validation-valid" data-valmsg-for="MyAttributeExamplesModel.LargeInput" data-valmsg-replace="true"></span>
+    </div>
+    <div class="form-group">
+<label for="MyAttributeExamplesModel_SmallInput">SmallInput</label>
+<input type="text" id="MyAttributeExamplesModel_SmallInput" name="MyAttributeExamplesModel.SmallInput" value="Small Input" class="form-control form-control-sm">
+<span class="text-danger field-validation-valid" data-valmsg-for="MyAttributeExamplesModel.SmallInput" data-valmsg-replace="true"></span>
+    </div>
+    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Kbwu8pRBWJCh6KUtTDoAuSUKLRRJ2JhujqxKEZfzYxIDYQtg1knqOh9zyG1DjaXRnoavm1876JtbePc4El_6aDqwMUKuXshQhXIunS_hrygXH5v-Tm6Qw_zL-JEJnSmd6Q4EwCtwDBwGX0in4-swG8">
 </form>
-
+
+ +
-

# Form Content Placement

+

Form Content Placement

- + +
+ First Div!
+ --------- +
+ - + +
+ ---------
+ Second Div! +
-
-
Posted Values:
-
- Name: @Model.PersonInput.Name
- Name: @Model.PersonInput.Surname
- City: @Model.PersonInput.City
- Phone.Name: @Model.PersonInput.Phone.Name
- Phone.Number: @Model.PersonInput.Phone.Number
- Day: @Model.PersonInput.Day.ToString("yyyy-MM-dd")
- Country: @Model.PersonInput.Country
- IsActive: @Model.PersonInput.IsActive
-
-
-<abp-dynamic-form abp-model="@Model.PersonInput">
-     <abp-form-content />
-     <abp-button button-type="Primary" type="submit" text="submit" />
+        
+            
+                

+public class DynamicFormsModel : PageModel
+    {
+        public FormContentExampleModel MyFormContentExampleModel { get; set; }
+
+        public void OnGet()
+        {
+            MyFormContentExampleModel = new FormContentExampleModel();
+        }
+
+        public class FormContentExampleModel
+        {
+            public string SampleInput { get; set; }
+        }
+    }
+
+
+ +

+<abp-dynamic-form abp-model="@@Model.MyFormContentExampleModel">
+    <div>
+        First Div!  <br />
+        ---------
+    </div>
+
+    <abp-form-content />
+
+    <div>
+        ---------  <br />
+        Second Div!
+    </div>
 </abp-dynamic-form>
-
-
-
+ + + +

+<form method="post">
+    <div>
+        First Div!  <br />
+        ---------
+    </div>
+
+    <div>
+        <div class="form-group">
+            <label for="MyFormContentExampleModel_SampleInput">SampleInput</label>
+            <input type="text" id="MyFormContentExampleModel_SampleInput" name="MyFormContentExampleModel.SampleInput" value="" class="form-control ">
+            <span class="text-danger field-validation-valid" data-valmsg-for="MyFormContentExampleModel.SampleInput" data-valmsg-replace="true"></span>
+        </div>
+    </div>
 
+    <div>
+        ---------  <br />
+        Second Div!
+    </div>
+    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Kbwu8pRBWJCh6KUtTDoAuS4l6PkkSnj6NFFQcJPBjnUn13wQKxp0lm1Dw84zvR-1QrE4byCemr2_qENxB-Ob_YEc6yw3bvQcqN6VQ0ZPN4Sv6DvX5okAWE52wRXmNcHlTliFOPdjLcKcv3qBFXXlVk">
+</form>
+
+
+ + + \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml.cs index 27075bf09a..6bfbfe2d0b 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml.cs @@ -12,9 +12,15 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components public class DynamicFormsModel : PageModel { [BindProperty] - public PersonModel PersonInput { get; set; } + public DetailedModel MyDetailedModel { get; set; } - public List Countries { get; set; } = new List + public OrderExampleModel MyOrderExampleModel { get; set; } + + public AttributeExamplesModel MyAttributeExamplesModel { get; set; } + + public FormContentExampleModel MyFormContentExampleModel { get; set; } + + public List CountryList { get; set; } = new List { new SelectListItem { Value = "CA", Text = "Canada"}, new SelectListItem { Value = "US", Text = "USA"}, @@ -24,72 +30,121 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components public void OnGet() { - if (PersonInput == null) - { - PersonInput = new PersonModel + MyDetailedModel = new DetailedModel { - Name = "John", + Name = "John Surname", + Description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + IsActive = true, Age = 65, - Country = "CA", Day = DateTime.Now, - City = Cities.NewJersey, - Phone = new PhoneModel { Number = "326346231", Name = "MyPhone" } + MyCarType = CarType.Coupe, + YourCarType = CarType.Sedan, + Country = "RU", + NeighborCountries = new List() { "UK", "CA" } }; - } + + MyFormContentExampleModel = new FormContentExampleModel(); + + MyOrderExampleModel = new OrderExampleModel(); + MyAttributeExamplesModel = new AttributeExamplesModel(); + MyAttributeExamplesModel.DisabledInput = "Disabled Input"; + MyAttributeExamplesModel.ReadonlyInput = "Readonly Input"; + MyAttributeExamplesModel.ReadonlyPlainTextInput = "Readonly Plain Text Input"; + MyAttributeExamplesModel.LargeInput = "Large Input"; + MyAttributeExamplesModel.SmallInput = "Small Input"; } - public void OnPost() + public class FormContentExampleModel { + public string SampleInput { get; set; } + } + + public class AttributeExamplesModel + { + [HiddenInput] + public string HiddenInput { get; set; } + + [DisabledInput] + public string DisabledInput{ get; set; } + + [ReadOnlyInput] + public string ReadonlyInput { get; set; } + + [ReadOnlyInput(PlainText = true)] + public string ReadonlyPlainTextInput { get; set; } + + [FormControlSize(AbpFormControlSize.Large)] + public string LargeInput { get; set; } + + [FormControlSize(AbpFormControlSize.Small)] + public string SmallInput { get; set; } + } + + public class OrderExampleModel + { + [DisplayOrder(10005)] + public string Surname{ get; set; } + + //Default 10000 + public string EmailAddress { get; set; } + + [DisplayOrder(10003)] + public string Name { get; set; } + [DisplayOrder(9999)] + public string City { get; set; } } - public class PersonModel + public class DetailedModel { [Required] + [Display(Name = "Name")] public string Name { get; set; } [TextArea(Rows = 4)] - public string Surname { get; set; } + [Display(Name = "Description")] + public string Description { get; set; } + + [Required] + [DataType(DataType.Password)] + [Display(Name = "Password")] + public string Password { get; set; } + + [Display(Name = "Is Active")] + public bool IsActive { get; set; } [Required] - [Range(1, 100)] + [Display(Name = "Age")] public int Age { get; set; } [Required] - public Cities City { get; set; } + [Display(Name = "My Car Type")] + public CarType MyCarType { get; set; } - public PhoneModel Phone { get; set; } + [Required] + [AbpRadioButton(Inline = true)] + [Display(Name = "Your Car Type")] + public CarType YourCarType { get; set; } [DataType(DataType.Date)] - [DisplayOrder(10003)] + [Display(Name = "Day")] public DateTime Day { get; set; } - public bool IsActive { get; set; } - - [AbpRadioButton(Inline = true)] - [SelectItems(nameof(Countries))] + [SelectItems(nameof(CountryList))] + [Display(Name = "Country")] public string Country { get; set; } + + [SelectItems(nameof(CountryList))] + [Display(Name = "Neighbor Countries")] + public List NeighborCountries { get; set; } } - public class PhoneModel - { - [Required] - [DisplayOrder(10002)] - public string Number { get; set; } - - [Required] - [DisplayOrder(10001)] - [DisplayName("PhoneName")] - public string Name { get; set; } - } - - public enum Cities + public enum CarType { - NewJersey, - Moscow, - Istanbul, - London, - Beijing + Sedan, + Hatchback, + StationWagon, + Coupe } } } \ No newline at end of file From 15e319f4a01bf2b3d1c8dec98dd2c8da4ad536a5 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Wed, 19 Dec 2018 17:54:10 +0300 Subject: [PATCH 080/368] Create PrismjsScriptBundleContributor --- .../ClipboardScriptBundleContributor.cs | 4 +--- .../Prismjs/PrismjsScriptBundleContributor.cs | 16 ++++++++++++++++ .../Pages/Documents/Project/Index.cshtml | 3 ++- 3 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Prismjs/PrismjsScriptBundleContributor.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Clipboard/ClipboardScriptBundleContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Clipboard/ClipboardScriptBundleContributor.cs index 4a0cc30100..416fe4afd0 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Clipboard/ClipboardScriptBundleContributor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Clipboard/ClipboardScriptBundleContributor.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Collections.Generic; using Volo.Abp.AspNetCore.Mvc.UI.Bundling; namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Clipboard diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Prismjs/PrismjsScriptBundleContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Prismjs/PrismjsScriptBundleContributor.cs new file mode 100644 index 0000000000..a5dc51610b --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Prismjs/PrismjsScriptBundleContributor.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Clipboard; +using Volo.Abp.Modularity; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs +{ + [DependsOn(typeof(ClipboardScriptBundleContributor))] + public class PrismjsScriptBundleContributor : BundleContributor + { + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files.AddIfNotContains("/libs/prismjs/prism.js"); + } + } +} diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml index 29a6b786a6..b43611e406 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml @@ -4,6 +4,7 @@ @using Volo.Abp.AspNetCore.Mvc.UI.Packages.Clipboard @using Volo.Abp.AspNetCore.Mvc.UI.Packages.MalihuCustomScrollbar @using Volo.Abp.AspNetCore.Mvc.UI.Packages.Popper +@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs @using Volo.Abp.AspNetCore.Mvc.UI.Theming @using Volo.Docs @using Volo.Docs.Localization @@ -30,7 +31,7 @@ - + From edbbec9294cb625968f1be9b6df3d984ad78cc5f Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Wed, 19 Dec 2018 17:54:29 +0300 Subject: [PATCH 081/368] Format fix for Bundling-Minification document --- docs/en/AspNetCore/Bundling-Minification.md | 39 ++++++++++----------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/docs/en/AspNetCore/Bundling-Minification.md b/docs/en/AspNetCore/Bundling-Minification.md index b8d70d8624..85d7f10a11 100644 --- a/docs/en/AspNetCore/Bundling-Minification.md +++ b/docs/en/AspNetCore/Bundling-Minification.md @@ -1,5 +1,5 @@ -## ASP.NET Core MVC Bundling & Minification +# ASP.NET Core MVC Bundling & Minification There are many ways of bundling & minification of client side resources (JavaScript and CSS files). Most common ways are: @@ -8,7 +8,7 @@ There are many ways of bundling & minification of client side resources (JavaScr ABP offers a simple, dynamic, powerful, modular and built-in way. -### Volo.Abp.AspNetCore.Mvc.UI.Bundling Package +## Volo.Abp.AspNetCore.Mvc.UI.Bundling Package > This package is already installed by default with the startup templates. So, most of the time, you don't need to install it manually. @@ -34,7 +34,7 @@ namespace MyCompany.MyProject } ```` -### Razor Bundling Tag Helpers +## Razor Bundling Tag Helpers The simplest way of creating a bundle is to use `abp-script-bundle` or `abp-style-bundle` tag helpers. Example: @@ -54,7 +54,7 @@ This bundle defines a style bundle with a **unique name**: `MyGlobalBundle`. It' * The bundle files may be **physical** files or [**virtual/embedded** files](../Virtual-File-System.md). * ABP automatically adds **version query string** to the bundle file URL to prevent browsers from caching when the bundle is being updated. (like ?_v=67872834243042 - generated from last change date of the related files). The versioning works even if the bundle files are individually added to the page (on the development environment). -#### Importing The Bundling Tag Helpers +### Importing The Bundling Tag Helpers > This is already imported by default with the startup templates. So, most of the time, you don't need to add it manually. @@ -64,7 +64,7 @@ In order to use bundle tag helpers, you need to add it into your `_ViewImports.c @addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling ```` -#### Unnamed Bundles +### Unnamed Bundles The `name` is **optional** for the razor bundle tag helpers. If you don't define a name, it's automatically **calculated** based on the used bundle file names (they are **concatenated** and **hashed**). Example: @@ -90,7 +90,7 @@ Advantages of **named** bundles: * Other **modules can contribute** to the bundle by its name (see the sections below). -#### Single File +### Single File If you need to just add a single file to the page, you can use the `abp-script` or `abp-style` tag without a wrapping in the `abp-script-bundle` or `abp-style-bundle` tag. Example: @@ -100,11 +100,11 @@ If you need to just add a single file to the page, you can use the `abp-script` The bundle name will be *scripts.my-scripts* for the example above ("/" is replaced by "."). All bundling features are work as expected for single file bundles too. -### Bundling Options +## Bundling Options If you need to use same bundle in **multiple pages** or want to use some more **powerful features**, you can configure bundles **by code** in your [module](../Module-Development-Basics.md) class. -#### Creating A New Bundle +### Creating A New Bundle Example usage: @@ -141,7 +141,7 @@ After defining such a bundle, it can be included into a page using the same tag This time, no file defined in the tag helper definition because the bundle files are defined by the code. -#### Configuring An Existing Bundle +### Configuring An Existing Bundle ABP supports [modularity](../Module-Development-Basics.md) for bundling as well. A module can modify an existing bundle that is created by a dependant module. Example: @@ -168,7 +168,7 @@ public class MyWebExtensionModule : AbpModule > It's not possible to configure unnamed bundle tag helpers by code, because their name are not known at the development time. It's suggested to always use a name for a bundle tag helper. -### Bundle Contributors +## Bundle Contributors Adding files to an existing bundle seems useful. What if you need to **replace** a file in the bundle or you want to **conditionally** add files? Defining a bundle contributor provides extra power for such cases. @@ -200,8 +200,7 @@ services.Configure(options => }); ```` -Contributors can also be used in the bundle tag helpers. -Example: +Contributors can also be used in the bundle tag helpers. Example: ````xml @@ -213,7 +212,7 @@ Example: `abp-style` and `abp-script` tags can get `type` attributes (instead of `src` attributes) as shown in this sample. When you add a bundle contributor, its dependencies are also automatically added to the bundle. -#### Contributor Dependencies +### Contributor Dependencies A bundle contributor can have one or more dependencies to other contributors. Example: @@ -230,11 +229,11 @@ When a bundle contributor is added, its dependencies are **automatically and rec Creating contributors and defining dependencies is a way of organizing bundle creation across different modules. -#### Accessing to the IServiceProvider +### Accessing to the IServiceProvider While it is rarely needed, `BundleConfigurationContext` has a `ServiceProvider` property that you can resolve service dependencies inside the `ConfigureBundle` method. -#### Standard Package Contributors +### Standard Package Contributors Adding a specific NPM package resource (js, css files) into a bundle is pretty straight forward for that package. For example you always add the `bootstrap.css` file for the bootstrap NPM package. @@ -255,7 +254,7 @@ Using the built-in contributors for standard packages; * Prevents multiple modules adding the **duplicate the files**. * Manages **dependencies recursively** (adds dependencies of dependencies, if necessary). -##### Volo.Abp.AspNetCore.Mvc.UI.Packages Package +#### Volo.Abp.AspNetCore.Mvc.UI.Packages Package > This package is already installed by default in the startup templates. So, most of the time, you don't need to install it manually. @@ -282,7 +281,7 @@ namespace MyCompany.MyProject } ```` -#### Bundle Inheritance +### Bundle Inheritance In some specific cases, it may be needed to create a **new** bundle **inherited** from other bundle(s). Inheriting from a bundle (recursively) inherits all files/contributors of that bundle. Then the derived bundle can add or modify files/contributors **without modifying** the original bundle. Example: @@ -302,11 +301,11 @@ services.Configure(options => }); ```` -### Themes +## Themes Themes uses the standard package contributors to add library resources to page layouts. Themes may also define some standard/global bundles, so any module can contribute to these standard/global bundles. See the [theming documentation](Theming.md) for more. -### Best Practices & Suggestions +## Best Practices & Suggestions It's suggested to define multiple bundles for an application, each one is used for different purposes. @@ -317,7 +316,7 @@ It's suggested to define multiple bundles for an application, each one is used f Establish a balance between performance, network bandwidth usage and count of many bundles. -### See Also +## See Also * [Client Side Package Management](Client-Side-Package-Management.md) * [Theming](Theming.md) From 23a57fa89721f42939705751b656426a13eb287f Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 20 Dec 2018 09:13:33 +0300 Subject: [PATCH 082/368] added placeholder attribute to input tag helper --- .../Form/AbpInputTagHelperService.cs | 16 ++++++++++++++++ .../TagHelpers/Form/Placeholder.cs | 18 ++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/Placeholder.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs index e38bd4e97a..7077dfef8d 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -125,6 +125,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form isCheckbox = IsInputCheckbox(context, output, inputTagHelperOutput.Attributes); AddFormControlClass(context, output, isCheckbox, inputTagHelperOutput); AddReadOnlyAttribute(inputTagHelperOutput); + AddPlaceholderAttribute(inputTagHelperOutput); return inputTagHelperOutput; } @@ -172,6 +173,21 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form } } + protected virtual void AddPlaceholderAttribute(TagHelperOutput inputTagHelperOutput) + { + if (inputTagHelperOutput.Attributes.ContainsName("placeholder")) + { + return; + } + + var attribute = GetAttribute(TagHelper.AspFor.ModelExplorer); + + if (attribute != null) + { + inputTagHelperOutput.Attributes.Add("placeholder", attribute.Value); + } + } + protected virtual bool IsInputCheckbox(TagHelperContext context, TagHelperOutput output, TagHelperAttributeList attributes) { return attributes.Any(a => a.Value != null && a.Name == "type" && a.Value.ToString() == "checkbox"); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/Placeholder.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/Placeholder.cs new file mode 100644 index 0000000000..042efb67c2 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/Placeholder.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +{ + [AttributeUsage(AttributeTargets.Property)] + public class Placeholder : Attribute + { + public string Value { get; set; } + + public Placeholder(string value) + { + Value = value; + } + } +} From 20fb9b52c6a9c6fbc0f06040792091450482de61 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 20 Dec 2018 09:49:10 +0300 Subject: [PATCH 083/368] dynamic-form docs improvements --- .../Pages/Components/DynamicForms.cshtml | 153 +++++++++--------- .../Pages/Components/DynamicForms.cshtml.cs | 19 ++- 2 files changed, 89 insertions(+), 83 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml index 026c8c4339..8fd08e3a94 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml @@ -53,7 +53,7 @@ public class DynamicFormsModel : PageModel { MyDetailedModel = new DetailedModel { - Name = "John Surname", + Name = "", Description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", IsActive = true, Age = 65, @@ -68,6 +68,7 @@ public class DynamicFormsModel : PageModel public class DetailedModel { [Required] + [Placeholder("Enter your name...")] [Display(Name = "Name")] public string Name { get; set; } @@ -121,83 +122,83 @@ public class DynamicFormsModel : PageModel

-<abp-dynamic-form abp-model="@Model.MyDetailedModel" submit-button="true" />
+<abp-dynamic-form abp-model="@@Model.MyDetailedModel" submit-button="true" />
 

 <form method="post" novalidate="novalidate">
     <div class="form-group">
-<label for="MyDetailedModel_Name">Name</label>
-<input type="text" data-val="true" data-val-required="The Name field is required." id="MyDetailedModel_Name" name="MyDetailedModel.Name" value="John Surname" class="form-control ">
-<span class="text-danger field-validation-valid" data-valmsg-for="MyDetailedModel.Name" data-valmsg-replace="true"></span>
+        <label for="MyDetailedModel_Name">Name</label>
+        <input type="text" data-val="true" data-val-required="The Name field is required." id="MyDetailedModel_Name" name="MyDetailedModel.Name" value="" class="form-control " placeholder="Enter your name...">
+        <span class="text-danger field-validation-valid" data-valmsg-for="MyDetailedModel.Name" data-valmsg-replace="true"></span>
     </div>
     <div class="form-group">
-<label for="MyDetailedModel_Description">Description</label>
-<textarea id="MyDetailedModel_Description" name="MyDetailedModel.Description" rows="4" class="form-control ">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</textarea>
-<span class="text-danger field-validation-valid" data-valmsg-for="MyDetailedModel.Description" data-valmsg-replace="true"></span>
+        <label for="MyDetailedModel_Description">Description</label>
+        <textarea id="MyDetailedModel_Description" name="MyDetailedModel.Description" rows="4" class="form-control ">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</textarea>
+        <span class="text-danger field-validation-valid" data-valmsg-for="MyDetailedModel.Description" data-valmsg-replace="true"></span>
     </div>
     <div class="form-group">
-<label for="MyDetailedModel_Password">Password</label>
-<input type="password" data-val="true" data-val-required="The Password field is required." id="MyDetailedModel_Password" name="MyDetailedModel.Password" class="form-control ">
-<span class="text-danger field-validation-valid" data-valmsg-for="MyDetailedModel.Password" data-valmsg-replace="true"></span>
+        <label for="MyDetailedModel_Password">Password</label>
+        <input type="password" data-val="true" data-val-required="The Password field is required." id="MyDetailedModel_Password" name="MyDetailedModel.Password" class="form-control ">
+        <span class="text-danger field-validation-valid" data-valmsg-for="MyDetailedModel.Password" data-valmsg-replace="true"></span>
     </div>
     <div class="form-check">
-<input type="checkbox" checked="checked" data-val="true" data-val-required="The Is Active field is required." id="MyDetailedModel_IsActive" name="MyDetailedModel.IsActive" value="true" class="form-check-input "><input name="MyDetailedModel.IsActive" type="hidden" value="false">
-<label class="form-check-label" for="MyDetailedModel_IsActive">Is Active</label>
+        <input type="checkbox" checked="checked" data-val="true" data-val-required="The Is Active field is required." id="MyDetailedModel_IsActive" name="MyDetailedModel.IsActive" value="true" class="form-check-input "><input name="MyDetailedModel.IsActive" type="hidden" value="false">
+        <label class="form-check-label" for="MyDetailedModel_IsActive">Is Active</label>
     </div>
     <div class="form-group">
-<label for="MyDetailedModel_Age">Age</label>
-<input type="number" data-val="true" data-val-required="The Age field is required." id="MyDetailedModel_Age" name="MyDetailedModel.Age" value="65" class="form-control ">
-<span class="text-danger field-validation-valid" data-valmsg-for="MyDetailedModel.Age" data-valmsg-replace="true"></span>
+        <label for="MyDetailedModel_Age">Age</label>
+        <input type="number" data-val="true" data-val-required="The Age field is required." id="MyDetailedModel_Age" name="MyDetailedModel.Age" value="65" class="form-control ">
+        <span class="text-danger field-validation-valid" data-valmsg-for="MyDetailedModel.Age" data-valmsg-replace="true"></span>
     </div>
     <div class="form-group">
-<label for="MyDetailedModel_MyCarType">My Car Type</label>
-<select data-val="true" data-val-required="The My Car Type field is required." id="MyDetailedModel_MyCarType" name="MyDetailedModel.MyCarType" class="form-control valid" aria-describedby="MyDetailedModel_MyCarType-error" aria-invalid="false">
-    <option value="0">Sedan</option>
-    <option value="1">Hatchback</option>
-    <option value="2">StationWagon</option>
-    <option selected="selected" value="3">Coupe</option>
-</select>
+        <label for="MyDetailedModel_MyCarType">My Car Type</label>
+        <select data-val="true" data-val-required="The My Car Type field is required." id="MyDetailedModel_MyCarType" name="MyDetailedModel.MyCarType" class="form-control valid" aria-describedby="MyDetailedModel_MyCarType-error" aria-invalid="false">
+            <option value="0">Sedan</option>
+            <option value="1">Hatchback</option>
+            <option value="2">StationWagon</option>
+            <option selected="selected" value="3">Coupe</option>
+        </select>
     </div>
     <div class="custom-control custom-radio custom-control-inline">
-<input type="radio" id="MyDetailedModel.YourCarTypeRadio0" name="MyDetailedModel.YourCarType" value="0" checked="checked" class="custom-control-input">
-<label class="custom-control-label" for="MyDetailedModel.YourCarTypeRadio0">Sedan</label>
+        <input type="radio" id="MyDetailedModel.YourCarTypeRadio0" name="MyDetailedModel.YourCarType" value="0" checked="checked" class="custom-control-input">
+        <label class="custom-control-label" for="MyDetailedModel.YourCarTypeRadio0">Sedan</label>
     </div>
     <div class="custom-control custom-radio custom-control-inline">
-<input type="radio" id="MyDetailedModel.YourCarTypeRadio1" name="MyDetailedModel.YourCarType" value="1" class="custom-control-input">
-<label class="custom-control-label" for="MyDetailedModel.YourCarTypeRadio1">Hatchback</label>
+        <input type="radio" id="MyDetailedModel.YourCarTypeRadio1" name="MyDetailedModel.YourCarType" value="1" class="custom-control-input">
+        <label class="custom-control-label" for="MyDetailedModel.YourCarTypeRadio1">Hatchback</label>
     </div>
     <div class="custom-control custom-radio custom-control-inline">
-<input type="radio" id="MyDetailedModel.YourCarTypeRadio2" name="MyDetailedModel.YourCarType" value="2" class="custom-control-input">
-<label class="custom-control-label" for="MyDetailedModel.YourCarTypeRadio2">StationWagon</label>
+        <input type="radio" id="MyDetailedModel.YourCarTypeRadio2" name="MyDetailedModel.YourCarType" value="2" class="custom-control-input">
+        <label class="custom-control-label" for="MyDetailedModel.YourCarTypeRadio2">StationWagon</label>
     </div>
     <div class="custom-control custom-radio custom-control-inline">
-<input type="radio" id="MyDetailedModel.YourCarTypeRadio3" name="MyDetailedModel.YourCarType" value="3" class="custom-control-input">
-<label class="custom-control-label" for="MyDetailedModel.YourCarTypeRadio3">Coupe</label>
+        <input type="radio" id="MyDetailedModel.YourCarTypeRadio3" name="MyDetailedModel.YourCarType" value="3" class="custom-control-input">
+        <label class="custom-control-label" for="MyDetailedModel.YourCarTypeRadio3">Coupe</label>
     </div>
     <div class="form-group">
-<label for="MyDetailedModel_Day">Day</label>
-<input type="date" data-val="true" data-val-required="The Day field is required." id="MyDetailedModel_Day" name="MyDetailedModel.Day" value="2018-12-19" class="form-control ">
-<span class="text-danger field-validation-valid" data-valmsg-for="MyDetailedModel.Day" data-valmsg-replace="true"></span>
+        <label for="MyDetailedModel_Day">Day</label>
+        <input type="date" data-val="true" data-val-required="The Day field is required." id="MyDetailedModel_Day" name="MyDetailedModel.Day" value="2018-12-19" class="form-control ">
+        <span class="text-danger field-validation-valid" data-valmsg-for="MyDetailedModel.Day" data-valmsg-replace="true"></span>
     </div>
     <div class="form-group">
-<label for="MyDetailedModel_Country">Country</label>
-<select id="MyDetailedModel_Country" name="MyDetailedModel.Country" class="form-control">
-    <option value="CA">Canada</option>
-    <option value="US">USA</option>
-    <option value="UK">United Kingdom</option>
-    <option selected="selected" value="RU">Russia</option>
-</select>
+        <label for="MyDetailedModel_Country">Country</label>
+        <select id="MyDetailedModel_Country" name="MyDetailedModel.Country" class="form-control">
+            <option value="CA">Canada</option>
+            <option value="US">USA</option>
+            <option value="UK">United Kingdom</option>
+            <option selected="selected" value="RU">Russia</option>
+        </select>
     </div>
     <div class="form-group">
-<label for="MyDetailedModel_NeighborCountries">Neighbor Countries</label>
-<select id="MyDetailedModel_NeighborCountries" multiple="multiple" name="MyDetailedModel.NeighborCountries" class="form-control">
-    <option selected="selected" value="CA">Canada</option>
-    <option value="US">USA</option>
-    <option selected="selected" value="UK">United Kingdom</option>
-    <option value="RU">Russia</option>
-</select>
+        <label for="MyDetailedModel_NeighborCountries">Neighbor Countries</label>
+        <select id="MyDetailedModel_NeighborCountries" multiple="multiple" name="MyDetailedModel.NeighborCountries" class="form-control">
+            <option selected="selected" value="CA">Canada</option>
+            <option value="US">USA</option>
+            <option selected="selected" value="UK">United Kingdom</option>
+            <option value="RU">Russia</option>
+        </select>
     </div>
     <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Kbwu8pRBWJCh6KUtTDoAuTDS8evmWgc2dNZYWkzjZ1xFcA9ptyCgQBCTgA9NMoh_FXGRBDVunA7fx0TF1df1_OxaxerJvuWRCwFBhy8KbPcgXrVtmtSp6Z28gpFpO0Z1TSO1pdgdTwEXj43DBWq0Hc">
     <button type="submit" class="btn btn-primary" data-busy-text="Processing..."><span>Submit</span></button>
@@ -253,24 +254,24 @@ public class DynamicFormsModel : PageModel
                 

 <form method="post">
     <div class="form-group">
-<label for="MyOrderExampleModel_City">City</label>
-<input type="text" id="MyOrderExampleModel_City" name="MyOrderExampleModel.City" value="" class="form-control ">
-<span class="text-danger field-validation-valid" data-valmsg-for="MyOrderExampleModel.City" data-valmsg-replace="true"></span>
+        <label for="MyOrderExampleModel_City">City</label>
+        <input type="text" id="MyOrderExampleModel_City" name="MyOrderExampleModel.City" value="" class="form-control ">
+        <span class="text-danger field-validation-valid" data-valmsg-for="MyOrderExampleModel.City" data-valmsg-replace="true"></span>
     </div>
     <div class="form-group">
-<label for="MyOrderExampleModel_EmailAddress">EmailAddress</label>
-<input type="text" id="MyOrderExampleModel_EmailAddress" name="MyOrderExampleModel.EmailAddress" value="" class="form-control ">
-<span class="text-danger field-validation-valid" data-valmsg-for="MyOrderExampleModel.EmailAddress" data-valmsg-replace="true"></span>
+        <label for="MyOrderExampleModel_EmailAddress">EmailAddress</label>
+        <input type="text" id="MyOrderExampleModel_EmailAddress" name="MyOrderExampleModel.EmailAddress" value="" class="form-control ">
+        <span class="text-danger field-validation-valid" data-valmsg-for="MyOrderExampleModel.EmailAddress" data-valmsg-replace="true"></span>
     </div>
     <div class="form-group">
-<label for="MyOrderExampleModel_Name">Name</label>
-<input type="text" id="MyOrderExampleModel_Name" name="MyOrderExampleModel.Name" value="" class="form-control ">
-<span class="text-danger field-validation-valid" data-valmsg-for="MyOrderExampleModel.Name" data-valmsg-replace="true"></span>
+        <label for="MyOrderExampleModel_Name">Name</label>
+        <input type="text" id="MyOrderExampleModel_Name" name="MyOrderExampleModel.Name" value="" class="form-control ">
+        <span class="text-danger field-validation-valid" data-valmsg-for="MyOrderExampleModel.Name" data-valmsg-replace="true"></span>
     </div>
     <div class="form-group">
-<label for="MyOrderExampleModel_Surname">Surname</label>
-<input type="text" id="MyOrderExampleModel_Surname" name="MyOrderExampleModel.Surname" value="" class="form-control ">
-<span class="text-danger field-validation-valid" data-valmsg-for="MyOrderExampleModel.Surname" data-valmsg-replace="true"></span>
+        <label for="MyOrderExampleModel_Surname">Surname</label>
+        <input type="text" id="MyOrderExampleModel_Surname" name="MyOrderExampleModel.Surname" value="" class="form-control ">
+        <span class="text-danger field-validation-valid" data-valmsg-for="MyOrderExampleModel.Surname" data-valmsg-replace="true"></span>
     </div>
     <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Kbwu8pRBWJCh6KUtTDoAuQICDXiCEgWpOHc7uIzSQ2dKiezdDkWplt2D8XLsCX39Z8B_GnplHrAfZgZ5GkNZN-tkEgKlMtyjoWv9MADyYb2MmWw-LuW8wfUXI9YSza5lo_8P03Vff4NxmrV3boG0xQ">
 </form>
@@ -336,32 +337,32 @@ public class DynamicFormsModel : PageModel
                 

 <form method="post">
     <div class="form-group">
-<input type="hidden" id="MyAttributeExamplesModel_HiddenInput" name="MyAttributeExamplesModel.HiddenInput" value="" class="form-control ">
+        <input type="hidden" id="MyAttributeExamplesModel_HiddenInput" name="MyAttributeExamplesModel.HiddenInput" value="" class="form-control ">
     </div>
     <div class="form-group">
-<label for="MyAttributeExamplesModel_DisabledInput">DisabledInput</label>
-<input type="text" id="MyAttributeExamplesModel_DisabledInput" name="MyAttributeExamplesModel.DisabledInput" value="Disabled Input" disabled="" class="form-control ">
-<span class="text-danger field-validation-valid" data-valmsg-for="MyAttributeExamplesModel.DisabledInput" data-valmsg-replace="true"></span>
+        <label for="MyAttributeExamplesModel_DisabledInput">DisabledInput</label>
+        <input type="text" id="MyAttributeExamplesModel_DisabledInput" name="MyAttributeExamplesModel.DisabledInput" value="Disabled Input" disabled="" class="form-control ">
+        <span class="text-danger field-validation-valid" data-valmsg-for="MyAttributeExamplesModel.DisabledInput" data-valmsg-replace="true"></span>
     </div>
     <div class="form-group">
-<label for="MyAttributeExamplesModel_ReadonlyInput">ReadonlyInput</label>
-<input type="text" id="MyAttributeExamplesModel_ReadonlyInput" name="MyAttributeExamplesModel.ReadonlyInput" value="Readonly Input" class="form-control " readonly="">
-<span class="text-danger field-validation-valid" data-valmsg-for="MyAttributeExamplesModel.ReadonlyInput" data-valmsg-replace="true"></span>
+        <label for="MyAttributeExamplesModel_ReadonlyInput">ReadonlyInput</label>
+        <input type="text" id="MyAttributeExamplesModel_ReadonlyInput" name="MyAttributeExamplesModel.ReadonlyInput" value="Readonly Input" class="form-control " readonly="">
+        <span class="text-danger field-validation-valid" data-valmsg-for="MyAttributeExamplesModel.ReadonlyInput" data-valmsg-replace="true"></span>
     </div>
     <div class="form-group">
-<label for="MyAttributeExamplesModel_ReadonlyPlainTextInput">ReadonlyPlainTextInput</label>
-<input type="text" id="MyAttributeExamplesModel_ReadonlyPlainTextInput" name="MyAttributeExamplesModel.ReadonlyPlainTextInput" value="Readonly Plain Text Input" class="form-control-plaintext " readonly="">
-<span class="text-danger field-validation-valid" data-valmsg-for="MyAttributeExamplesModel.ReadonlyPlainTextInput" data-valmsg-replace="true"></span>
+        <label for="MyAttributeExamplesModel_ReadonlyPlainTextInput">ReadonlyPlainTextInput</label>
+        <input type="text" id="MyAttributeExamplesModel_ReadonlyPlainTextInput" name="MyAttributeExamplesModel.ReadonlyPlainTextInput" value="Readonly Plain Text Input" class="form-control-plaintext " readonly="">
+        <span class="text-danger field-validation-valid" data-valmsg-for="MyAttributeExamplesModel.ReadonlyPlainTextInput" data-valmsg-replace="true"></span>
     </div>
     <div class="form-group">
-<label for="MyAttributeExamplesModel_LargeInput">LargeInput</label>
-<input type="text" id="MyAttributeExamplesModel_LargeInput" name="MyAttributeExamplesModel.LargeInput" value="Large Input" class="form-control form-control-lg">
-<span class="text-danger field-validation-valid" data-valmsg-for="MyAttributeExamplesModel.LargeInput" data-valmsg-replace="true"></span>
+        <label for="MyAttributeExamplesModel_LargeInput">LargeInput</label>
+        <input type="text" id="MyAttributeExamplesModel_LargeInput" name="MyAttributeExamplesModel.LargeInput" value="Large Input" class="form-control form-control-lg">
+        <span class="text-danger field-validation-valid" data-valmsg-for="MyAttributeExamplesModel.LargeInput" data-valmsg-replace="true"></span>
     </div>
     <div class="form-group">
-<label for="MyAttributeExamplesModel_SmallInput">SmallInput</label>
-<input type="text" id="MyAttributeExamplesModel_SmallInput" name="MyAttributeExamplesModel.SmallInput" value="Small Input" class="form-control form-control-sm">
-<span class="text-danger field-validation-valid" data-valmsg-for="MyAttributeExamplesModel.SmallInput" data-valmsg-replace="true"></span>
+        <label for="MyAttributeExamplesModel_SmallInput">SmallInput</label>
+        <input type="text" id="MyAttributeExamplesModel_SmallInput" name="MyAttributeExamplesModel.SmallInput" value="Small Input" class="form-control form-control-sm">
+        <span class="text-danger field-validation-valid" data-valmsg-for="MyAttributeExamplesModel.SmallInput" data-valmsg-replace="true"></span>
     </div>
     <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Kbwu8pRBWJCh6KUtTDoAuSUKLRRJ2JhujqxKEZfzYxIDYQtg1knqOh9zyG1DjaXRnoavm1876JtbePc4El_6aDqwMUKuXshQhXIunS_hrygXH5v-Tm6Qw_zL-JEJnSmd6Q4EwCtwDBwGX0in4-swG8">
 </form>
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml.cs
index 6bfbfe2d0b..753a76d3be 100644
--- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml.cs
+++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml.cs
@@ -32,7 +32,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components
         {
                 MyDetailedModel = new DetailedModel
                 {
-                    Name = "John Surname",
+                    Name = "",
                     Description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
                     IsActive = true,
                     Age = 65,
@@ -46,12 +46,16 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components
             MyFormContentExampleModel = new FormContentExampleModel();
 
             MyOrderExampleModel = new OrderExampleModel();
-            MyAttributeExamplesModel = new AttributeExamplesModel();
-            MyAttributeExamplesModel.DisabledInput = "Disabled Input";
-            MyAttributeExamplesModel.ReadonlyInput = "Readonly Input";
-            MyAttributeExamplesModel.ReadonlyPlainTextInput = "Readonly Plain Text Input";
-            MyAttributeExamplesModel.LargeInput = "Large Input";
-            MyAttributeExamplesModel.SmallInput = "Small Input";
+
+            MyAttributeExamplesModel = new AttributeExamplesModel
+            {
+                DisabledInput = "Disabled Input",
+                ReadonlyInput = "Readonly Input",
+                ReadonlyPlainTextInput = "Readonly Plain Text Input",
+                LargeInput = "Large Input",
+                SmallInput = "Small Input"
+            };
+
         }
 
         public class FormContentExampleModel
@@ -98,6 +102,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components
         public class DetailedModel
         {
             [Required]
+            [Placeholder("Enter your name...")]
             [Display(Name = "Name")]
             public string Name { get; set; }
             

From 740bcc5d727acec19bea909f79161863888562c9 Mon Sep 17 00:00:00 2001
From: Halil ibrahim Kalkan 
Date: Thu, 20 Dec 2018 10:26:27 +0300
Subject: [PATCH 084/368] Added contributor extension system and used for the
 docs module

---
 docs/en/AspNetCore/Bundling-Minification.md   | 36 +++++++++++++++++--
 .../UI/Bundling/BundleContributorOptions.cs   | 31 ++++++++++++++++
 .../Mvc/UI/Bundling/BundleManager.cs          | 17 ++++++++-
 .../Prismjs/PrismjsStyleBundleContributor.cs  | 13 +++++++
 ...mjsScriptBundleContributorDocsExtension.cs | 17 +++++++++
 ...smjsStyleBundleContributorDocsExtension.cs | 14 ++++++++
 .../docs/src/Volo.Docs.Web/DocsWebModule.cs   | 14 ++++++++
 .../Pages/Documents/Project/Index.cshtml      | 19 ++++------
 8 files changed, 144 insertions(+), 17 deletions(-)
 create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleContributorOptions.cs
 create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Prismjs/PrismjsStyleBundleContributor.cs
 create mode 100644 modules/docs/src/Volo.Docs.Web/Bundling/PrismjsScriptBundleContributorDocsExtension.cs
 create mode 100644 modules/docs/src/Volo.Docs.Web/Bundling/PrismjsStyleBundleContributorDocsExtension.cs

diff --git a/docs/en/AspNetCore/Bundling-Minification.md b/docs/en/AspNetCore/Bundling-Minification.md
index 85d7f10a11..7170690ef3 100644
--- a/docs/en/AspNetCore/Bundling-Minification.md
+++ b/docs/en/AspNetCore/Bundling-Minification.md
@@ -143,8 +143,7 @@ This time, no file defined in the tag helper definition because the bundle files
 
 ### Configuring An Existing Bundle
 
-ABP supports [modularity](../Module-Development-Basics.md) for bundling as well. A module can modify an existing bundle that is created by a dependant module. 
-Example:
+ABP supports [modularity](../Module-Development-Basics.md) for bundling as well. A module can modify an existing bundle that is created by a dependant module. Example:
 
 ````C#
 [DependsOn(typeof(MyWebModule))]
@@ -187,7 +186,7 @@ public class MyExtensionGlobalStyleContributor : BundleContributor
 }
 ````
 
-Then you can use this contributor as below:
+Then you can use this contributor as like below:
 
 ````C#
 services.Configure(options =>
@@ -200,6 +199,8 @@ services.Configure(options =>
 });
 ````
 
+> You can also add contributors while creating a new bundle.
+
 Contributors can also be used in the bundle tag helpers. Example:
 
 ````xml
@@ -229,6 +230,35 @@ When a bundle contributor is added, its dependencies are **automatically and rec
 
 Creating contributors and defining dependencies is a way of organizing bundle creation across different modules.
 
+### Contributor Extensions
+
+In some advanced scenarios, you may want to do some additional configuration whenever a bundle contributor is used. Contributor extensions works seamlessly when the extended contributor is used.
+
+The example below adds some styles for prism.js library:
+
+````csharp
+public class MyPrismjsStyleExtension : BundleContributor
+{
+    public override void ConfigureBundle(BundleConfigurationContext context)
+    {
+        context.Files.AddIfNotContains("/libs/prismjs/plugins/toolbar/prism-toolbar.css");
+    }
+}
+````
+
+Then you can configure `BundleContributorOptions` to extend existing `PrismjsStyleBundleContributor`.
+
+````csharp
+Configure(options =>
+{
+    options
+        .Extensions()
+        .Add();
+});
+````
+
+Whenever `PrismjsStyleBundleContributor` is added into a bundle, `MyPrismjsStyleExtension` will also be automatically added.
+
 ### Accessing to the IServiceProvider
 
 While it is rarely needed, `BundleConfigurationContext` has a `ServiceProvider` property that you can resolve service dependencies inside the `ConfigureBundle` method.
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleContributorOptions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleContributorOptions.cs
new file mode 100644
index 0000000000..1e7d15bf23
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleContributorOptions.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Concurrent;
+using JetBrains.Annotations;
+
+namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
+{
+    public class BundleContributorOptions
+    {
+        public ConcurrentDictionary AllExtensions { get; }
+
+        public BundleContributorOptions()
+        {
+            AllExtensions = new ConcurrentDictionary();
+        }
+
+        public BundleContributorCollection Extensions()
+        {
+            return Extensions(typeof(TContributor));
+        }
+
+        public BundleContributorCollection Extensions([NotNull] Type contributorType)
+        {
+            Check.NotNull(contributorType, nameof(contributorType));
+
+            return AllExtensions.GetOrAdd(
+                contributorType,
+                _ => new BundleContributorCollection()
+            );
+        }
+    }
+}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleManager.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleManager.cs
index ca5e914754..3f99614aa9 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleManager.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleManager.cs
@@ -21,6 +21,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
         public ILogger Logger { get; set; }
 
         protected readonly BundlingOptions Options;
+        protected readonly BundleContributorOptions ContributorOptions;
         protected readonly IWebContentFileProvider WebContentFileProvider;
         protected readonly IHostingEnvironment HostingEnvironment;
         protected readonly IScriptBundler ScriptBundler;
@@ -32,6 +33,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
 
         public BundleManager(
             IOptions options,
+            IOptions contributorOptions,
             IScriptBundler scriptBundler,
             IStyleBundler styleBundler,
             IHostingEnvironment hostingEnvironment,
@@ -41,6 +43,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
             IWebContentFileProvider webContentFileProvider,
             IWebRequestResources requestResources)
         {
+            Options = options.Value;
+            ContributorOptions = contributorOptions.Value;
             HostingEnvironment = hostingEnvironment;
             ScriptBundler = scriptBundler;
             ServiceProvider = serviceProvider;
@@ -49,7 +53,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
             WebContentFileProvider = webContentFileProvider;
             RequestResources = requestResources;
             StyleBundler = styleBundler;
-            Options = options.Value;
 
             Logger = NullLogger.Instance;
         }
@@ -202,7 +205,19 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
         protected virtual List GetContributors(BundleConfigurationCollection bundles, string bundleName)
         {
             var contributors = new List();
+
             AddContributorsWithBaseBundles(contributors, bundles, bundleName);
+
+            for (var i = 0; i < contributors.Count; ++i)
+            {
+                var extensions = ContributorOptions.Extensions(contributors[i].GetType()).GetAll();
+                if (extensions.Count > 0)
+                {
+                    contributors.InsertRange(i + 1, extensions);
+                    i += extensions.Count;
+                }
+            }
+
             return contributors;
         }
 
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Prismjs/PrismjsStyleBundleContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Prismjs/PrismjsStyleBundleContributor.cs
new file mode 100644
index 0000000000..00713df1f1
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Prismjs/PrismjsStyleBundleContributor.cs
@@ -0,0 +1,13 @@
+using System.Collections.Generic;
+using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
+
+namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs
+{
+    public class PrismjsStyleBundleContributor : BundleContributor
+    {
+        public override void ConfigureBundle(BundleConfigurationContext context)
+        {
+            context.Files.AddIfNotContains("/libs/prismjs/themes/prism-okaidia.css");
+        }
+    }
+}
\ No newline at end of file
diff --git a/modules/docs/src/Volo.Docs.Web/Bundling/PrismjsScriptBundleContributorDocsExtension.cs b/modules/docs/src/Volo.Docs.Web/Bundling/PrismjsScriptBundleContributorDocsExtension.cs
new file mode 100644
index 0000000000..f096b3e9d7
--- /dev/null
+++ b/modules/docs/src/Volo.Docs.Web/Bundling/PrismjsScriptBundleContributorDocsExtension.cs
@@ -0,0 +1,17 @@
+using System.Collections.Generic;
+using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
+
+namespace Volo.Docs.Bundling
+{
+    public class PrismjsScriptBundleContributorDocsExtension : BundleContributor
+    {
+        public override void ConfigureBundle(BundleConfigurationContext context)
+        {
+            context.Files.AddIfNotContains("/libs/prismjs/plugins/toolbar/prism-toolbar.js");
+            context.Files.AddIfNotContains("/libs/prismjs/plugins/show-language/prism-show-language.js");
+            context.Files.AddIfNotContains("/libs/prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard.js");
+            context.Files.AddIfNotContains("/libs/prismjs/plugins/line-highlight/prism-line-highlight.js");
+            context.Files.AddIfNotContains("/libs/prismjs/components/prism-csharp.js");
+        }
+    }
+}
diff --git a/modules/docs/src/Volo.Docs.Web/Bundling/PrismjsStyleBundleContributorDocsExtension.cs b/modules/docs/src/Volo.Docs.Web/Bundling/PrismjsStyleBundleContributorDocsExtension.cs
new file mode 100644
index 0000000000..9cbe1bd04c
--- /dev/null
+++ b/modules/docs/src/Volo.Docs.Web/Bundling/PrismjsStyleBundleContributorDocsExtension.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
+
+namespace Volo.Docs.Bundling
+{
+    public class PrismjsStyleBundleContributorDocsExtension : BundleContributor
+    {
+        public override void ConfigureBundle(BundleConfigurationContext context)
+        {
+            context.Files.AddIfNotContains("/libs/prismjs/plugins/line-highlight/prism-line-highlight.css");
+            context.Files.AddIfNotContains("/libs/prismjs/plugins/toolbar/prism-toolbar.css");
+        }
+    }
+}
\ No newline at end of file
diff --git a/modules/docs/src/Volo.Docs.Web/DocsWebModule.cs b/modules/docs/src/Volo.Docs.Web/DocsWebModule.cs
index 1791463fb3..689b9ec929 100644
--- a/modules/docs/src/Volo.Docs.Web/DocsWebModule.cs
+++ b/modules/docs/src/Volo.Docs.Web/DocsWebModule.cs
@@ -2,9 +2,12 @@
 using Microsoft.Extensions.DependencyInjection;
 using Volo.Abp.AspNetCore.Mvc.Localization;
 using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap;
+using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
+using Volo.Abp.AspNetCore.Mvc.UI.Packages.Prismjs;
 using Volo.Abp.AutoMapper;
 using Volo.Abp.Modularity;
 using Volo.Abp.VirtualFileSystem;
+using Volo.Docs.Bundling;
 using Volo.Docs.HtmlConverting;
 using Volo.Docs.Localization;
 using Volo.Docs.Markdown;
@@ -47,6 +50,17 @@ namespace Volo.Docs
             {
                 options.Converters[MarkdownDocumentToHtmlConverter.Type] = typeof(MarkdownDocumentToHtmlConverter);
             });
+
+            Configure(options =>
+            {
+                options
+                    .Extensions()
+                    .Add();
+
+                options
+                    .Extensions()
+                    .Add();
+            });
         }
     }
 }
diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml
index b43611e406..55e6196201 100644
--- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml
+++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml
@@ -17,14 +17,12 @@
     Layout = ThemeManager.CurrentTheme.GetEmptyLayout();
 }
 @section styles {
-    
-        
-        
-        
-        
-        
-        
-    
+
+    
+    
+    
+    
+
 }
 @section scripts {
     
@@ -32,11 +30,6 @@
         
         
         
-        
-        
-        
-        
-        
         
         
         

From 7dd2a9accacb726b5807d0c8f42f85f240e0b3dd Mon Sep 17 00:00:00 2001
From: Halil ibrahim Kalkan 
Date: Thu, 20 Dec 2018 10:44:50 +0300
Subject: [PATCH 085/368] Register
 IOptions

---
 .../Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs     | 12 ++++++++++--
 .../Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs |  1 -
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs
index df5d127d98..cac53d4611 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs
@@ -75,14 +75,22 @@ namespace Volo.Abp.AspNetCore.Mvc
             var mvcCoreBuilder = context.Services.AddMvcCore();
             context.Services.ExecutePreConfiguredActions(mvcCoreBuilder);
 
+            var abpMvcDataAnnotationsLocalizationOptions = context.Services.ExecutePreConfiguredActions(new AbpMvcDataAnnotationsLocalizationOptions());
+
+            context.Services
+                .AddSingleton>(
+                    new OptionsWrapper(
+                        abpMvcDataAnnotationsLocalizationOptions
+                    )
+                );
+
             var mvcBuilder = context.Services.AddMvc()
                 .AddDataAnnotationsLocalization(options =>
                 {
-                    var assemblyResources = context.Services.ExecutePreConfiguredActions(new AbpMvcDataAnnotationsLocalizationOptions()).AssemblyResources;
 
                     options.DataAnnotationLocalizerProvider = (type, factory) =>
                     {
-                        var resourceType = assemblyResources.GetOrDefault(type.Assembly);
+                        var resourceType = abpMvcDataAnnotationsLocalizationOptions.AssemblyResources.GetOrDefault(type.Assembly);
                         return factory.Create(resourceType ?? type);
                     };
                 })
diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs
index 94e020a365..6ffd7ebf54 100644
--- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs
+++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs
@@ -14,7 +14,6 @@ using Volo.Abp.Localization.Resources.AbpValidation;
 using Volo.Abp.MemoryDb;
 using Volo.Abp.Modularity;
 using Volo.Abp.TestApp;
-using Volo.Abp.UI;
 using Volo.Abp.VirtualFileSystem;
 
 namespace Volo.Abp.AspNetCore.Mvc

From 632e207658189f61c6cc74937b702f67382920e6 Mon Sep 17 00:00:00 2001
From: Yunus Emre Kalkan 
Date: Thu, 20 Dec 2018 10:45:23 +0300
Subject: [PATCH 086/368] abp column break tag helper rename

---
 .../TagHelpers/Grid/AbpColBreakTagHelper.cs           | 11 -----------
 .../TagHelpers/Grid/AbpColumnBreakerTagHelper.cs      | 11 +++++++++++
 ...Service.cs => AbpColumnBreakerTagHelperService.cs} |  2 +-
 3 files changed, 12 insertions(+), 12 deletions(-)
 delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColBreakTagHelper.cs
 create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColumnBreakerTagHelper.cs
 rename framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/{AbpColBreakTagHelperService.cs => AbpColumnBreakerTagHelperService.cs} (82%)

diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColBreakTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColBreakTagHelper.cs
deleted file mode 100644
index fdd6b973a4..0000000000
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColBreakTagHelper.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid
-{
-    public class AbpColBreakTagHelper : AbpTagHelper
-    {
-        public AbpColBreakTagHelper(AbpColBreakTagHelperService tagHelperService)
-            : base(tagHelperService)
-        {
-
-        }
-    }
-}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColumnBreakerTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColumnBreakerTagHelper.cs
new file mode 100644
index 0000000000..492a16ff21
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColumnBreakerTagHelper.cs
@@ -0,0 +1,11 @@
+namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid
+{
+    public class AbpColumnBreakerTagHelper : AbpTagHelper
+    {
+        public AbpColumnBreakerTagHelper(AbpColumnBreakerTagHelperService tagHelperService)
+            : base(tagHelperService)
+        {
+
+        }
+    }
+}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColBreakTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColumnBreakerTagHelperService.cs
similarity index 82%
rename from framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColBreakTagHelperService.cs
rename to framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColumnBreakerTagHelperService.cs
index b483f275b2..f6190f2332 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColBreakTagHelperService.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColumnBreakerTagHelperService.cs
@@ -3,7 +3,7 @@ using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers
 
 namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid
 {
-    public class AbpColBreakTagHelperService : AbpTagHelperService
+    public class AbpColumnBreakerTagHelperService : AbpTagHelperService
     {
         public override void Process(TagHelperContext context, TagHelperOutput output)
         {

From 475b9820c7ced5bc2115681174c66151b8ec321c Mon Sep 17 00:00:00 2001
From: Yunus Emre Kalkan 
Date: Thu, 20 Dec 2018 11:15:41 +0300
Subject: [PATCH 087/368] abp-row tag helper gutters

---
 .../TagHelpers/Grid/AbpRowTagHelper.cs                |  2 ++
 .../TagHelpers/Grid/AbpRowTagHelperService.cs         | 11 +++++++++++
 2 files changed, 13 insertions(+)

diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpRowTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpRowTagHelper.cs
index 900b72fe25..ead3367ac7 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpRowTagHelper.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpRowTagHelper.cs
@@ -6,6 +6,8 @@
 
         public HorizontalAlign HAlign { get; set; } = HorizontalAlign.Default;
 
+        public bool? Gutters { get; set; } = true;
+
         public AbpRowTagHelper(AbpRowTagHelperService tagHelperService)
             : base(tagHelperService)
         {
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpRowTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpRowTagHelperService.cs
index 12609600d7..ecbe5db97e 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpRowTagHelperService.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpRowTagHelperService.cs
@@ -12,6 +12,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid
 
             ProcessVerticalAlign(output);
             ProcessHorizontalAlign(output);
+            ProcessGutters(output);
         }
 
         protected virtual void ProcessVerticalAlign(TagHelperOutput output)
@@ -33,5 +34,15 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid
 
             output.Attributes.AddClass("justify-content-" + TagHelper.HAlign.ToString().ToLowerInvariant());
         }
+
+        protected virtual void ProcessGutters(TagHelperOutput output)
+        {
+            if (TagHelper.Gutters ?? true)
+            {
+                return;
+            }
+
+            output.Attributes.AddClass("no-gutters");
+        }
     }
 }
\ No newline at end of file

From a9ef9552b0264446d9912126a4d9961c6815b87d Mon Sep 17 00:00:00 2001
From: Yunus Emre Kalkan 
Date: Thu, 20 Dec 2018 11:16:18 +0300
Subject: [PATCH 088/368] Abp-Dynamic-Form input Placeholder and enum
 DisplayName attribute localization #667

---
 .../Form/AbpInputTagHelperService.cs          | 25 ++++++++++++--
 .../Form/AbpRadioInputTagHelperService.cs     | 34 ++++++++++++++++++-
 .../Form/AbpSelectTagHelperService.cs         | 31 +++++++++++++++--
 3 files changed, 85 insertions(+), 5 deletions(-)

diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs
index 7077dfef8d..3699c26709 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs
@@ -1,9 +1,13 @@
 using System;
+using System.Collections.Generic;
 using System.Linq;
 using System.Text.Encodings.Web;
 using Microsoft.AspNetCore.Mvc.TagHelpers;
 using Microsoft.AspNetCore.Mvc.ViewFeatures;
 using Microsoft.AspNetCore.Razor.TagHelpers;
+using Microsoft.Extensions.Localization;
+using Microsoft.Extensions.Options;
+using Volo.Abp.AspNetCore.Mvc.Localization;
 using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers;
 
 namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
@@ -12,11 +16,15 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
     {
         private readonly IHtmlGenerator _generator;
         private readonly HtmlEncoder _encoder;
+        private readonly IStringLocalizerFactory _stringLocalizerFactory;
+        private readonly AbpMvcDataAnnotationsLocalizationOptions _options;
 
-        public AbpInputTagHelperService(IHtmlGenerator generator, HtmlEncoder encoder)
+        public AbpInputTagHelperService(IHtmlGenerator generator, HtmlEncoder encoder, IOptions options, IStringLocalizerFactory stringLocalizerFactory)
         {
             _generator = generator;
             _encoder = encoder;
+            _stringLocalizerFactory = stringLocalizerFactory;
+            _options = options.Value;
         }
 
         public override void Process(TagHelperContext context, TagHelperOutput output)
@@ -184,10 +192,23 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
 
             if (attribute != null)
             {
-                inputTagHelperOutput.Attributes.Add("placeholder", attribute.Value);
+                inputTagHelperOutput.Attributes.Add("placeholder", LocalizeText(attribute.Value));
             }
         }
 
+        protected virtual string LocalizeText(string text)
+        {
+            IStringLocalizer localizer = null;
+            var resourceType = _options.AssemblyResources.GetOrDefault(TagHelper.AspFor.ModelExplorer.ModelType.Assembly);
+
+            if (resourceType != null)
+            {
+               localizer = _stringLocalizerFactory.Create(resourceType);
+            }
+
+            return localizer == null? text: localizer[text].Value;
+        }
+
         protected virtual bool IsInputCheckbox(TagHelperContext context, TagHelperOutput output, TagHelperAttributeList attributes)
         {
             return attributes.Any(a => a.Value != null && a.Name == "type" && a.Value.ToString() == "checkbox");
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpRadioInputTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpRadioInputTagHelperService.cs
index 13b3d29cf7..6dee6c1371 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpRadioInputTagHelperService.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpRadioInputTagHelperService.cs
@@ -6,11 +6,23 @@ using System.Text;
 using Microsoft.AspNetCore.Mvc.Rendering;
 using Microsoft.AspNetCore.Mvc.ViewFeatures;
 using Microsoft.AspNetCore.Razor.TagHelpers;
+using Microsoft.Extensions.Localization;
+using Microsoft.Extensions.Options;
+using Volo.Abp.AspNetCore.Mvc.Localization;
 
 namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
 {
     public class AbpRadioInputTagHelperService : AbpTagHelperService
     {
+        private readonly AbpMvcDataAnnotationsLocalizationOptions _options;
+        private readonly IStringLocalizerFactory _stringLocalizerFactory;
+
+        public AbpRadioInputTagHelperService(IOptions options, IStringLocalizerFactory stringLocalizerFactory)
+        {
+            _options = options.Value;
+            _stringLocalizerFactory = stringLocalizerFactory;
+        }
+
         public override void Process(TagHelperContext context, TagHelperOutput output)
         {
             var selectItems = GetSelectItems(context,output);
@@ -76,12 +88,32 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
 
         protected virtual bool GetSelectItemsIfProvidedByEnum(TagHelperContext context, TagHelperOutput output, ModelExplorer explorer, out List selectItems)
         {
+            IStringLocalizer localizer = null;
+            var resourceType = _options.AssemblyResources.GetOrDefault(explorer.ModelType.Assembly);
+
+            if (resourceType != null)
+            {
+                localizer = _stringLocalizerFactory.Create(resourceType);
+            }
+
             selectItems = explorer.Metadata.IsEnum ? explorer.ModelType.GetTypeInfo().GetMembers(BindingFlags.Public | BindingFlags.Static)
-                .Select((t, i) => new SelectListItem { Value = i.ToString(), Text = t.Name }).ToList() : null;
+                .Select((t, i) => new SelectListItem { Value = i.ToString(), Text = GetLocalizedPropertyName(localizer, explorer.ModelType, t.Name) }).ToList() : null;
 
             return selectItems != null;
         }
 
+        protected virtual string GetLocalizedPropertyName(IStringLocalizer localizer, Type enumType, string propertyName)
+        {
+            if (localizer == null)
+            {
+                return propertyName;
+            }
+
+            var localizedString = localizer[enumType.Name + "." + propertyName];
+
+            return !localizedString.ResourceNotFound ? localizedString.Value : localizer[propertyName].Value;
+        }
+
         protected virtual bool GetSelectItemsIfProvidedFromAttribute(TagHelperContext context, TagHelperOutput output, ModelExplorer explorer, out List selectItems)
         {
             selectItems = GetAttribute(explorer)?.GetItems(explorer)?.ToList();
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs
index 4ed0c70356..355234ba82 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs
@@ -8,6 +8,9 @@ using Microsoft.AspNetCore.Mvc.Rendering;
 using Microsoft.AspNetCore.Mvc.TagHelpers;
 using Microsoft.AspNetCore.Mvc.ViewFeatures;
 using Microsoft.AspNetCore.Razor.TagHelpers;
+using Microsoft.Extensions.Localization;
+using Microsoft.Extensions.Options;
+using Volo.Abp.AspNetCore.Mvc.Localization;
 using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers;
 
 namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
@@ -16,11 +19,15 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
     {
         private readonly IHtmlGenerator _generator;
         private readonly HtmlEncoder _encoder;
+        private readonly IStringLocalizerFactory _stringLocalizerFactory;
+        private readonly AbpMvcDataAnnotationsLocalizationOptions _options;
 
-        public AbpSelectTagHelperService(IHtmlGenerator generator, HtmlEncoder encoder)
+        public AbpSelectTagHelperService(IHtmlGenerator generator, HtmlEncoder encoder, IOptions options, IStringLocalizerFactory stringLocalizerFactory)
         {
             _generator = generator;
             _encoder = encoder;
+            _stringLocalizerFactory = stringLocalizerFactory;
+            _options = options.Value;
         }
 
         public override void Process(TagHelperContext context, TagHelperOutput output)
@@ -113,12 +120,32 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
 
         protected virtual bool GetSelectItemsIfProvidedByEnum(TagHelperContext context, TagHelperOutput output, ModelExplorer explorer, out List selectItems)
         {
+            IStringLocalizer localizer = null;
+            var resourceType = _options.AssemblyResources.GetOrDefault(explorer.ModelType.Assembly);
+
+            if (resourceType != null)
+            {
+                localizer = _stringLocalizerFactory.Create(resourceType);
+            }
+
             selectItems = explorer.Metadata.IsEnum ? explorer.ModelType.GetTypeInfo().GetMembers(BindingFlags.Public | BindingFlags.Static)
-                .Select((t, i) => new SelectListItem { Value = i.ToString(), Text = t.Name }).ToList() : null;
+                .Select((t, i) => new SelectListItem { Value = i.ToString(), Text = GetLocalizedPropertyName(localizer, explorer.ModelType, t.Name) }).ToList() : null;
 
             return selectItems != null;
         }
 
+        protected virtual string GetLocalizedPropertyName(IStringLocalizer localizer, Type enumType, string propertyName)
+        {
+            if (localizer == null)
+            {
+                return propertyName;
+            }
+
+            var localizedString = localizer[enumType.Name + "." + propertyName];
+
+            return !localizedString.ResourceNotFound ? localizedString.Value : localizer[propertyName].Value;
+        }
+
         protected virtual bool GetSelectItemsIfProvidedFromAttribute(TagHelperContext context, TagHelperOutput output, ModelExplorer explorer, out List selectItems)
         {
             selectItems = GetAttribute(explorer)?.GetItems(explorer)?.ToList();

From a6baf08ec89b6d780da8bf295cc8a45ea8f6faa7 Mon Sep 17 00:00:00 2001
From: Yunus Emre Kalkan 
Date: Thu, 20 Dec 2018 11:53:28 +0300
Subject: [PATCH 089/368] Grid tag helper doc

---
 .../Pages/Components/Grids.cshtml             | 910 ++++++++++++++----
 1 file changed, 744 insertions(+), 166 deletions(-)

diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Grids.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Grids.cshtml
index 4957fd3636..097b670e70 100644
--- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Grids.cshtml
+++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Grids.cshtml
@@ -10,260 +10,838 @@
     
 }
 
+@section scripts {
+    
+        @*
+            *@
+    
+}
+
+
+
+
+
 

Grids

Based on Bootstrap grid.

-

# Example

+

Equal-width

-
+
- One of two columns - One of two columns + 1 of 2 + 2 of 2 + + + 1 of 3 + 2 of 3 + 3 of 3 + +
+
+ + +

+        <abp-container>
+            <abp-row>
+                <abp-column>1 of 2</abp-column>
+                <abp-column>2 of 2</abp-column>
+            </abp-row>
+            <abp-row>
+                <abp-column>1 of 3</abp-column>
+                <abp-column>2 of 3</abp-column>
+                <abp-column>3 of 3</abp-column>
+            </abp-row>
+        </abp-container>
+
+
+ +

+        <div class="container">
+            <div class="row">
+                <div class="col">1 of 2</div>
+                <div class="col">2 of 2</div>
+            </div>
+            <div class="row">
+                <div class="col">1 of 3</div>
+                <div class="col">2 of 3</div>
+                <div class="col">3 of 3</div>
+            </div>
+        </div>
+
+
+
+
+
+ +

Column Breaker

+ +
+
+ - One of three columns - One of three columns - One of three columns + column + column + + column + column
-
-<abp-container>
-     <abp-row>
-         <abp-column size-sm="C6">One of two columns</abp-column>
-         <abp-column size-sm="C6">One of two columns</abp-column>
-     </abp-row>
-     <abp-row>
-         <abp-column size-sm="C4">One of three columns</abp-column>
-         <abp-column size-sm="C4">One of three columns</abp-column>
-         <abp-column size-sm="C4">One of three columns</abp-column>
-     </abp-row>
-</abp-container>
-
+ + +

+        <abp-container>
+            <abp-row>
+                <abp-column>column</abp-column>
+                <abp-column>column</abp-column>
+                <abp-column-breaker/>
+                <abp-column>column</abp-column>
+                <abp-column>column</abp-column>
+            </abp-row>
+        </abp-container>
+
+
+ +

+        <div class="container">
+            <div class="row">
+                <div class="col">column</div>
+                <div class="col">column</div>
+                <div class="w-100"></div>
+                <div class="col">column</div>
+                <div class="col">column</div>
+            </div>
+        </div>
+
+
+
-

# Break Column Example

+

Setting one column width

-
+
- One of three columns - One of three columns - @* TODO: abp-column-break *@ - One of three columns + 1 of 3 + 2 of 3 (wider) + 3 of 3 + + + 1 of 3 + 2 of 3 (wider) + 3 of 3
-
- <abp-container>
-     <abp-row>
-         <abp-column>One of three columns</abp-column>
-         <abp-column>One of three columns</abp-column>
-         <abp-col-break /> @* TODO: abp-column-break *@
-         <abp-column>One of three columns</abp-column>
-     </abp-row>
- </abp-container>
-
+ + +

+        <abp-container>
+            <abp-row>
+                <abp-column>1 of 3</abp-column>
+                <abp-column size="_6">2 of 3 (wider)</abp-column>
+                <abp-column>3 of 3</abp-column>
+            </abp-row>
+            <abp-row>
+                <abp-column>1 of 3</abp-column>
+                <abp-column size="_5">2 of 3 (wider)</abp-column>
+                <abp-column>3 of 3</abp-column>
+            </abp-row>
+        </abp-container>
+
+
+ +

+        <div class="container">
+            <div class="row">
+                <div class="col">1 of 3</div>
+                <div class="col col-6">2 of 3 (wider)</div>
+                <div class="col">3 of 3</div>
+            </div>
+            <div class="row">
+                <div class="col">1 of 3</div>
+                <div class="col col-5">2 of 3 (wider)</div>
+                <div class="col">3 of 3</div>
+            </div>
+        </div>
+
+
+
-

# Vertical alignment Example

+

Variable width content

-
+
+ + + 1 of 3 + Variable width content + 3 of 3 + + + 1 of 3 + Variable width content + 3 of 3 + + +
+
+ + +

+        <abp-container>
+            <abp-row h-align="Center">
+                <abp-column size-lg="_2">1 of 3</abp-column>
+                <abp-column size-md="Auto">Variable width content</abp-column>
+                <abp-column size-lg="_2">3 of 3</abp-column>
+            </abp-row>
+            <abp-row>
+                <abp-column>1 of 3</abp-column>
+                <abp-column size-md="Auto">Variable width content</abp-column>
+                <abp-column size-lg="_2">3 of 3</abp-column>
+            </abp-row>
+        </abp-container>
+
+
+ +

+        <div class="container">
+            <div class="row justify-content-center">
+                <div class="col col-lg-2">1 of 3</div>
+                <div class="col col-md-auto">Variable width content</div>
+                <div class="col col-lg-2">3 of 3</div>
+            </div>
+            <div class="row">
+                <div class="col">1 of 3</div>
+                <div class="col col-md-auto">Variable width content</div>
+                <div class="col col-lg-2">3 of 3</div>
+            </div>
+        </div>
+
+
+
+
+
+ +

Responsive classes

+ +
All breakpoints
+ +
+
+ + col + col + col + col + + + col-8 + col-4 + +
+
+ + +

+            <abp-row>
+                <abp-column>col</abp-column>
+                <abp-column>col</abp-column>
+                <abp-column>col</abp-column>
+                <abp-column>col</abp-column>
+            </abp-row>
+            <abp-row>
+                <abp-column size="_8">col-8</abp-column>
+                <abp-column size="_4">col-4</abp-column>
+            </abp-row>
+
+
+ +

+            <div class="row">
+                <div class="col">col</div>
+                <div class="col">col</div>
+                <div class="col">col</div>
+                <div class="col">col</div>
+            </div>
+            <div class="row">
+                <div class="col col-8">col-8</div>
+                <div class="col col-4">col-4</div>
+            </div>
+
+
+
+
+
+ +
All breakpoints
+ +
+
+ + col-sm-8 + col-sm-4 + + + col-sm + col-sm + col-sm + col-sm + +
+
+ + +

+        <abp-row>
+            <abp-column size-sm="_8">col-sm-8</abp-column>
+            <abp-column size-sm="_4">col-sm-4</abp-column>
+        </abp-row>
+        <abp-row>
+            <abp-column size-sm="_">col-sm</abp-column>
+            <abp-column size-sm="_">col-sm</abp-column>
+            <abp-column size-sm="_">col-sm</abp-column>
+            <abp-column size-sm="_">col-sm</abp-column>
+        </abp-row>
+
+
+ +

+         <div class="row">
+            <div class="col col-sm-8">col-sm-8</div>
+            <div class="col col-sm-4">col-sm-4</div>
+        </div>
+        <div class="row">
+            <div class="col col-sm">col-sm</div>
+            <div class="col col-sm">col-sm</div>
+            <div class="col col-sm">col-sm</div>
+            <div class="col col-sm">col-sm</div>
+        </div>
+
+
+
+
+
+ +
Mix and match
+ +
+
+ + .col-12 .col-md-8 + .col-6 .col-md-4 + + + .col-6 .col-md-4 + .col-6 .col-md-4 + .col-6 .col-md-4 + + + .col-6 + .col-6 + +
+
+ + +

+        <!-- Stack the columns on mobile by making one full-width and the other half-width -->
+        <abp-row>
+            <abp-column size="_12" size-md="_8">.col-12 .col-md-8</abp-column>
+            <abp-column size="_6" size-md="_4">.col-6 .col-md-4</abp-column>
+        </abp-row>
+
+        <!-- Columns start at 50% wide on mobile and bump up to 33.3% wide on desktop -->
+        <abp-row>
+            <abp-column size="_6" size-md="_4">.col-6 .col-md-4</abp-column>
+            <abp-column size="_6" size-md="_4">.col-6 .col-md-4</abp-column>
+            <abp-column size="_6" size-md="_4">.col-6 .col-md-4</abp-column>
+        </abp-row>
+
+        <!-- Columns are always 50% wide, on mobile and desktop -->
+        <abp-row>
+            <abp-column size="_6">.col-6</abp-column>
+            <abp-column size="_6">.col-6</abp-column>
+        </abp-row>
+
+
+ +

+        <div class="row">
+            <div class="col col-12 col-md-8">.col-12 .col-md-8</div>
+            <div class="col col-6 col-md-4">.col-6 .col-md-4</div>
+        </div>
+        <div class="row">
+            <div class="col col-6 col-md-4">.col-6 .col-md-4</div>
+            <div class="col col-6 col-md-4">.col-6 .col-md-4</div>
+            <div class="col col-6 col-md-4">.col-6 .col-md-4</div>
+        </div>
+        <div class="row">
+            <div class="col col-6">.col-6</div>
+            <div class="col col-6">.col-6</div>
+        </div>
+
+
+
+
+
+ +

Alignment

+ +
Vertical Alignment
+ +
+
- One of three columns - One of three columns - One of three columns + column + column + column - One of three columns - One of three columns - One of three columns + column + column + column - One of three columns - One of three columns - One of three columns + column + column + column
-
-<abp-container>
-     <abp-row v-align="Start">
-        <abp-column>One of three columns</abp-column>
-        <abp-column>One of three columns</abp-column>
-        <abp-column>One of three columns</abp-column>
-     </abp-row>
-     <abp-row v-align="Center">
-         <abp-column>One of three columns</abp-column>
-         <abp-column>One of three columns</abp-column>
-         <abp-column>One of three columns</abp-column>
-     </abp-row>
-     <abp-row v-align="End">
-         <abp-column>One of three columns</abp-column>
-         <abp-column>One of three columns</abp-column>
-         <abp-column>One of three columns</abp-column>
-     </abp-row>
- </abp-container>
-
+ + +

+        <abp-container>
+            <abp-row v-align="Start">
+                <abp-column>column</abp-column>
+                <abp-column>column</abp-column>
+                <abp-column>column</abp-column>
+            </abp-row>
+            <abp-row v-align="Center">
+                <abp-column>column</abp-column>
+                <abp-column>column</abp-column>
+                <abp-column>column</abp-column>
+            </abp-row>
+            <abp-row v-align="End">
+                <abp-column>column</abp-column>
+                <abp-column>column</abp-column>
+                <abp-column>column</abp-column>
+            </abp-row>
+        </abp-container>
+
+
+ +

+        <div class="container">
+            <div class="row align-items-start">
+                <div class="col">column</div>
+                <div class="col">column</div>
+                <div class="col">column</div>
+            </div>
+            <div class="row align-items-center">
+                <div class="col">column</div>
+                <div class="col">column</div>
+                <div class="col">column</div>
+            </div>
+            <div class="row align-items-end">
+                <div class="col">column</div>
+                <div class="col">column</div>
+                <div class="col">column</div>
+            </div>
+        </div>
+
+
+
-

# Vertical alignment Example 2

-
-
+
- - One of three columns - One of three columns - One of three columns + + column + column + column
-
- <abp-container>
-    <abp-row>
-        <abp-column v-align="Start">One of three columns</abp-column>
-        <abp-column v-align="Center">One of three columns</abp-column>
-        <abp-column v-align="End">One of three columns</abp-column>
-     </abp-row>
- </abp-container>
-
+ + +

+        <abp-container>
+            <abp-row v-align="Start">
+                <abp-column v-align="Start">column</abp-column>
+                <abp-column v-align="Center">column</abp-column>
+                <abp-column v-align="End">column</abp-column>
+            </abp-row>
+        </abp-container>
+
+
+ +

+        <div class="container">
+            <div class="row align-items-start">
+                <div class="col align-self-start">column</div>
+                <div class="col align-self-center">column</div>
+                <div class="col align-self-end">column</div>
+            </div>
+        </div>
+
+
+
-

# Horizontal alignment Example

+
Horizontal alignment
-
+
- One of three columns - One of three columns + One of two columns + One of two columns - One of three columns - One of three columns + One of two columns + One of two columns - One of three columns - One of three columns + One of two columns + One of two columns - One of three columns - One of three columns + One of two columns + One of two columns - One of three columns - One of three columns + One of two columns + One of two columns + + +
+
+ + +

+        <abp-container>
+            <abp-row h-align="Start">
+                <abp-column size="_4">One of two columns</abp-column>
+                <abp-column size="_4">One of two columns</abp-column>
+            </abp-row>
+            <abp-row h-align="Center">
+                <abp-column size="_4">One of two columns</abp-column>
+                <abp-column size="_4">One of two columns</abp-column>
+            </abp-row>
+            <abp-row h-align="End">
+                <abp-column size="_4">One of two columns</abp-column>
+                <abp-column size="_4">One of two columns</abp-column>
+            </abp-row>
+            <abp-row h-align="Around">
+                <abp-column size="_4">One of two columns</abp-column>
+                <abp-column size="_4">One of two columns</abp-column>
+            </abp-row>
+            <abp-row h-align="Between">
+                <abp-column size="_4">One of two columns</abp-column>
+                <abp-column size="_4">One of two columns</abp-column>
+            </abp-row>
+        </abp-container>
+
+
+ +

+        <div class="container">
+            <div class="row justify-content-start">
+                <div class="col col-4">One of two columns</div>
+                <div class="col col-4">One of two columns</div>
+            </div>
+            <div class="row justify-content-center">
+                <div class="col col-4">One of two columns</div>
+                <div class="col col-4">One of two columns</div>
+            </div>
+            <div class="row justify-content-end">
+                <div class="col col-4">One of two columns</div>
+                <div class="col col-4">One of two columns</div>
+            </div>
+            <div class="row justify-content-around">
+                <div class="col col-4">One of two columns</div>
+                <div class="col col-4">One of two columns</div>
+            </div>
+            <div class="row justify-content-between">
+                <div class="col col-4">One of two columns</div>
+                <div class="col col-4">One of two columns</div>
+            </div>
+        </div>
+
+
+
+
+
+ +
No gutters
+ +
+
+ + One of two columns + One of two columns + +
+
+ + +

+            <abp-row gutters="false">
+                <abp-column size="_8">One of two columns</abp-column>
+                <abp-column size="_4">One of two columns</abp-column>
+            </abp-row>
+
+
+ +

+            <div class="row no-gutters">
+                <div class="col col-8">One of two columns</div>
+                <div class="col col-4">One of two columns</div>
+            </div>
+
+
+
+
+
+ +
Column wrapping
+ +
+
+ + .col-9 + .col-4
Since 9 + 4 = 13 > 12, this 4-column-wide div gets wrapped onto a new line as one contiguous unit.
+ .col-6
Subsequent columns continue along the new line.s
+
+
+
+ + +

+            <abp-row>
+                <abp-column size="_9">.col-9</abp-column>
+                <abp-column size="_4">.col-4<br>Since 9 + 4 = 13 &gt; 12, this 4-column-wide div gets wrapped onto a new line as one contiguous unit.</abp-column>
+                <abp-column size="_6">.col-6<br>Subsequent columns continue along the new line.s</abp-column>
+            </abp-row>
+
+
+ +

+            <div class="row">
+                <div class="col col-9">.col-9</div>
+                <div class="col col-4">.col-4<br>Since 9 + 4 = 13 &gt; 12, this 4-column-wide div gets wrapped onto a new line as one contiguous unit.</div>
+                <div class="col col-6">.col-6<br>Subsequent columns continue along the new line.s</div>
+            </div>
+
+
+
+
+
+ +

Reordering

+ +
Order classes
+ +
+
+ + + First, but Last + Second, but unordered + Third, but Second + + +
+
+ + +

+        <abp-container>
+            <abp-row>
+                <abp-column order="_12">First, but Last</abp-column>
+                <abp-column>Second, but unordered</abp-column>
+                <abp-column order="_6">Third, but Second</abp-column>
+            </abp-row>
+        </abp-container>
+
+
+ +

+        <div class="container">
+            <div class="row">
+                <div class="col order-12">First, but Last</div>
+                <div class="col">Second, but unordered</div>
+                <div class="col order-6">Third, but Second</div>
+            </div>
+        </div>
+
+
+
+
+
+ +
+
+ + + First, but Last + Second, but unordered + Third, but First
-
- <abp-container>
-    <abp-row h-align="Start">
-        <abp-column size="C4">One of three columns</abp-column>
-        <abp-column size="C4">One of three columns</abp-column>
-    </abp-row>
-    <abp-row h-align="Center">
-        <abp-column size="C4">One of three columns</abp-column>
-        <abp-column size="C4">One of three columns</abp-column>
-    </abp-row>
-    <abp-row h-align="End">
-        <abp-column size="C4">One of three columns</abp-column>
-        <abp-column size="C4">One of three columns</abp-column>
-    </abp-row>
-        <abp-row h-align="Around">
-        <abp-column size="C4">One of three columns</abp-column>
-        <abp-column size="C4">One of three columns</abp-column>
-    </abp-row>
-    <abp-row h-align="Between">
-        <abp-column size="C4">One of three columns</abp-column>
-        <abp-column size="C4">One of three columns</abp-column>
-    </abp-row>
- </abp-container>
-
+ + +

+        <abp-container>
+            <abp-row>
+                <abp-column order="Last">First, but Last</abp-column>
+                <abp-column>Second, but unordered</abp-column>
+                <abp-column order="First">Third, but First</abp-column>
+            </abp-row>
+        </abp-container>
+
+
+ +

+        <div class="container">
+            <div class="row">
+                <div class="col order-last">First, but Last</div>
+                <div class="col">Second, but unordered</div>
+                <div class="col order-first">Third, but First</div>
+            </div>
+        </div>
+
+
+
-

# Order Example

+

Offsetting columns

+ +
Offset classes
-
+
- First, but unordered - Second, but last - Third, but first + .col-md-4 + .col-md-4 .offset-md-4 + + + .col-md-3 .offset-md-3 + .col-md-3 .offset-md-3 - First, but unordered - Second, but last - Third, but first + .col-md-6 .offset-md-3
-
- <abp-container>
-    <abp-row>
-        <abp-column> First, but unordered</abp-column>
-        <abp-column order="C12">Second, but last</abp-column>
-        <abp-column order="C1">Third, but first</abp-column>
-    </abp-row>
-    <abp-row>
-        <abp-column> First, but unordered</abp-column>
-        <abp-column order="Last">Second, but last</abp-column>
-        <abp-column order="First">Third, but first</abp-column>
-    </abp-row>
- </abp-container>
-
+ + +

+        <abp-container>
+            <abp-row>
+                <abp-column size-md="_4">.col-md-4</abp-column>
+                <abp-column size-md="_4" offset-md="_4">.col-md-4 .offset-md-4</abp-column>
+            </abp-row>
+            <abp-row>
+                <abp-column size-md="_3" offset-md="_3">.col-md-3 .offset-md-3</abp-column>
+                <abp-column size-md="_3" offset-md="_3">.col-md-3 .offset-md-3</abp-column>
+            </abp-row>
+            <abp-row>
+                <abp-column size-md="_6" offset-md="_3">.col-md-6 .offset-md-3</abp-column>
+            </abp-row>
+        </abp-container>
+
+
+ +

+        <div class="container">
+            <div class="row">
+                <div class="col col-md-4">.col-md-4</div>
+                <div class="col col-md-4 offset-md-4">.col-md-4 .offset-md-4</div>
+            </div>
+            <div class="row">
+                <div class="col col-md-3 offset-md-3">.col-md-3 .offset-md-3</div>
+                <div class="col col-md-3 offset-md-3">.col-md-3 .offset-md-3</div>
+            </div>
+            <div class="row">
+                <div class="col col-md-6 offset-md-3">.col-md-6 .offset-md-3</div>
+            </div>
+        </div>
+
+
+
-

# Offset Example

-
- - .col-md-4 - .col-md-4 .offset-md-4 - - - .col-md-3 .offset-md-3 - .col-md-3 .offset-md-3 - - - .col-md-6 .offset-md-3 - +
+ + + .col-sm-5 .col-md-6 + .col-sm-5 .offset-sm-2 .col-md-6 .offset-md-0 + + + col-sm-6 .col-md-5 .col-lg-6 + .col-sm-6 .col-md-5 .offset-md-2 .col-lg-6 .offset-lg-0 + +
-
- <abp-row>
-    <abp-column> .col-md-4</abp-column>
-    <abp-column size-md="C4" offset-md="C4">.col-md-4 .offset-md-4</abp-column>
- </abp-row>
- <abp-row>
-    <abp-column size-md="C3" offset-md="C3">.col-md-3 .offset-md-3</abp-column>
-    <abp-column size-md="C3" offset-md="C3">.col-md-3 .offset-md-3</abp-column>
- </abp-row>
- <abp-row>
-    <abp-column size-md="C6" offset-md="C3">.col-md-6 .offset-md-3</abp-column>
- </abp-row>
-
+ + +

+        <abp-container>
+            <abp-row>
+                <abp-column size-sm="_5" size-md="_6">.col-sm-5 .col-md-6</abp-column>
+                <abp-column size-sm="_5" offset-sm="_2" size-md="_6" offset-md="_">.col-sm-5 .offset-sm-2 .col-md-6 .offset-md-0</abp-column>
+            </abp-row>
+            <abp-row>
+                <abp-column size-sm="_6" size-md="_5" size-lg="_6">col-sm-6 .col-md-5 .col-lg-6</abp-column>
+                <abp-column size-sm="_6" size-md="_5" offset-md="_2" size-lg="_6" offset-lg="_">.col-sm-6 .col-md-5 .offset-md-2 .col-lg-6 .offset-lg-0</abp-column>
+            </abp-row>
+        </abp-container>
+
+
+ +

+        <div class="container">
+            <div class="row">
+                <div class="col col-sm-5 col-md-6">.col-sm-5 .col-md-6</div>
+                <div class="col col-sm-5 col-md-6 offset-sm-2 offset-md-0">col-sm-5 .offset-sm-2 .col-md-6 .offset-md-0</div>
+            </div>
+            <div class="row">
+                <div class="col col-sm-6 col-md-5 col-lg-6">col-sm-6 .col-md-5 .col-lg-6</div>
+                <div class="col col-sm-6 col-md-5 col-lg-6 offset-md-2 offset-lg-0">.col-sm-6 .col-md-5 .offset-md-2 .col-lg-6 .offset-lg-0</div>
+            </div>
+        </div>
+
+
+
From 21891982f90cb51be07275caff8e1483705af19d Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 20 Dec 2018 11:53:56 +0300 Subject: [PATCH 090/368] update demo.css in tag helper docs --- .../wwwroot/css/demo.css | 23 ++++++++++--------- .../wwwroot/css/demo.min.css | 2 +- .../wwwroot/css/demo.scss | 11 +++++++++ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/css/demo.css b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/css/demo.css index f5d133afc9..297eea1679 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/css/demo.css +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/css/demo.css @@ -1,17 +1,18 @@ .demo-with-code { padding-bottom: 10px; - margin-bottom: 10px; - margin-top: 20px; } - .demo-with-code .attribute-area { - padding: 10px; - } + margin-bottom: 10px; } .demo-with-code .demo-area { - border: 1px solid #ddd; - padding: 20px; - } + margin-top: 20px; + margin-bottom: 1em; } + .demo-with-code .grid .col { + background: #ffc9c9; + border: 1.5px solid #000000; } + .demo-with-code .large-row .row { + min-height: 10rem; + background: #fcdede; + margin-top: 1rem; } .demo-with-code .code-area { border: 1px solid #ddd; padding: 10px; - font-size: 0.9em; - } - + margin-top: 10px; + font-size: 0.9em; } diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/css/demo.min.css b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/css/demo.min.css index 6721b78939..87e8a549a8 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/css/demo.min.css +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/css/demo.min.css @@ -1 +1 @@ -.demo-with-code{padding-bottom:10px;margin-bottom:10px;}.demo-with-code .demo-area{margin-bottom:1em;}.demo-with-code .code-area{border:1px solid #ddd;padding:10px;font-size:.9em;} \ No newline at end of file +.demo-with-code{padding-bottom:10px;margin-bottom:10px;}.demo-with-code .demo-area{margin-top:20px;margin-bottom:1em;}.demo-with-code .grid .col{background:#ffc9c9;border:1.5px solid #000;}.demo-with-code .large-row .row{min-height:10rem;background:#fcdede;margin-top:1rem;}.demo-with-code .code-area{border:1px solid #ddd;padding:10px;margin-top:10px;font-size:.9em;} \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/css/demo.scss b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/css/demo.scss index c9c78fa28b..04e085f22e 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/css/demo.scss +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/wwwroot/css/demo.scss @@ -7,6 +7,17 @@ margin-bottom: 1em; } + .grid .col { + background: #ffc9c9; + border: 1.5px solid #000000; + } + + .large-row .row { + min-height: 10rem; + background: #fcdede; + margin-top: 1rem; + } + .code-area { border: 1px solid #ddd; padding: 10px; From 24bc860401a5999edb12e81933635305022e65ac Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 20 Dec 2018 11:54:15 +0300 Subject: [PATCH 091/368] lining fix in formElements doc --- .../Pages/Components/FormElements.cshtml | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/FormElements.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/FormElements.cshtml index 82b9bee992..b62c610fbc 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/FormElements.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/FormElements.cshtml @@ -147,34 +147,34 @@

-<div class="form-group">
-<label for="MyModel_EmailAddress">Email Address</label>
-<input placeholder="name@example.com" type="text" data-val="true" data-val-required="The EmailAddress field is required." id="MyModel_EmailAddress" name="MyModel.EmailAddress" value="" class="form-control ">
-<span class="text-danger field-validation-valid" data-valmsg-for="MyModel.EmailAddress" data-valmsg-replace="true"></span>
-</div>
-<div class="form-group">
-<label for="MyModel_City">City</label>
-<select id="MyModel_City" name="MyModel.City" class="form-control">
-<option value="NY">New York</option>
-<option value="LDN">London</option>
-<option value="IST">Istanbul</option>
-<option value="MOS">Moscow</option>
-</select>
-</div>
-<div class="form-group">
-<label for="MyModel_Cities">Cities</label>
-<select id="MyModel_Cities" multiple="multiple" name="MyModel.Cities" class="form-control">
-<option value="NY">New York</option>
-<option value="LDN">London</option>
-<option value="IST">Istanbul</option>
-<option value="MOS">Moscow</option>
-</select>
-</div>
-<div class="form-group">
-<label for="MyModel_Description">Description</label>
-<textarea id="MyModel_Description" name="MyModel.Description" class="form-control "></textarea>
-<span class="text-danger field-validation-valid" data-valmsg-for="MyModel.Description" data-valmsg-replace="true"></span>
-</div>
+    <div class="form-group">
+        <label for="MyModel_EmailAddress">Email Address</label>
+        <input placeholder="name@example.com" type="text" data-val="true" data-val-required="The EmailAddress field is required." id="MyModel_EmailAddress" name="MyModel.EmailAddress" value="" class="form-control ">
+        <span class="text-danger field-validation-valid" data-valmsg-for="MyModel.EmailAddress" data-valmsg-replace="true"></span>
+    </div>
+    <div class="form-group">
+        <label for="MyModel_City">City</label>
+        <select id="MyModel_City" name="MyModel.City" class="form-control">
+            <option value="NY">New York</option>
+            <option value="LDN">London</option>
+            <option value="IST">Istanbul</option>
+            <option value="MOS">Moscow</option>
+        </select>
+    </div>
+    <div class="form-group">
+        <label for="MyModel_Cities">Cities</label>
+        <select id="MyModel_Cities" multiple="multiple" name="MyModel.Cities" class="form-control">
+            <option value="NY">New York</option>
+            <option value="LDN">London</option>
+            <option value="IST">Istanbul</option>
+            <option value="MOS">Moscow</option>
+        </select>
+    </div>
+    <div class="form-group">
+        <label for="MyModel_Description">Description</label>
+        <textarea id="MyModel_Description" name="MyModel.Description" class="form-control "></textarea>
+        <span class="text-danger field-validation-valid" data-valmsg-for="MyModel.Description" data-valmsg-replace="true"></span>
+    </div>
 
@@ -219,14 +219,14 @@

 <div class="form-group">
-<label for="MyModel_LargeInput">LargeInput</label>
-<input type="text" id="MyModel_LargeInput" name="MyModel.LargeInput" value="" class="form-control form-control-lg">
-<span class="text-danger field-validation-valid" data-valmsg-for="MyModel.LargeInput" data-valmsg-replace="true"></span>
+    <label for="MyModel_LargeInput">LargeInput</label>
+    <input type="text" id="MyModel_LargeInput" name="MyModel.LargeInput" value="" class="form-control form-control-lg">
+    <span class="text-danger field-validation-valid" data-valmsg-for="MyModel.LargeInput" data-valmsg-replace="true"></span>
 </div>
 <div class="form-group">
-<label for="MyModel_SmallInput">SmallInput</label>
-<input type="text" id="MyModel_SmallInput" name="MyModel.SmallInput" value="" class="form-control form-control-sm">
-<span class="text-danger field-validation-valid" data-valmsg-for="MyModel.SmallInput" data-valmsg-replace="true"></span>
+    <label for="MyModel_SmallInput">SmallInput</label>
+    <input type="text" id="MyModel_SmallInput" name="MyModel.SmallInput" value="" class="form-control form-control-sm">
+    <span class="text-danger field-validation-valid" data-valmsg-for="MyModel.SmallInput" data-valmsg-replace="true"></span>
 </div>
 
From 07c2d5ff096731e159aa3c9f5d7b5aa314d5fe5e Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 20 Dec 2018 11:55:56 +0300 Subject: [PATCH 092/368] tag helper demo index page reorder list --- .../Pages/Index.cshtml | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Index.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Index.cshtml index 9164ee5d87..39c62bfb96 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Index.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Index.cshtml @@ -7,27 +7,28 @@

Components

From 2aa2448b44e200b725adf5381e55624647f84c3f Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 20 Dec 2018 14:08:54 +0300 Subject: [PATCH 093/368] Added Info text to abp-input tag helper --- .../Form/AbpInputTagHelperService.cs | 52 +++++++++++++++++-- .../TagHelpers/Form/InputInfoText.cs | 18 +++++++ .../Pages/Components/DynamicForms.cshtml | 1 + .../Pages/Components/DynamicForms.cshtml.cs | 1 + 4 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/InputInfoText.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs index 3699c26709..13ab0f9159 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -60,10 +60,11 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form var inputTag = GetInputTagHelperOutput(context, output, out isCheckbox); var inputHtml = RenderTagHelperOutput(inputTag, _encoder); var label = GetLabelAsHtml(context, output, inputTag, isCheckbox); + var info = GetInfoAsHtml(context, output, inputTag, isCheckbox); var validation = isCheckbox ? "" : GetValidationAsHtml(context, output, inputTag); - return GetContent(context, output, label, inputHtml, validation, isCheckbox); + return GetContent(context, output, label, inputHtml, validation, info, isCheckbox); } protected virtual string GetValidationAsHtml(TagHelperContext context, TagHelperOutput output, TagHelperOutput inputTag) @@ -84,14 +85,14 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form return RenderTagHelper(attributeList, context, validationMessageTagHelper, _encoder, "span", TagMode.StartTagAndEndTag, true); } - protected virtual string GetContent(TagHelperContext context, TagHelperOutput output, string label, string inputHtml, string validation, bool isCheckbox) + protected virtual string GetContent(TagHelperContext context, TagHelperOutput output, string label, string inputHtml, string validation, string infoHtml, bool isCheckbox) { var innerContent = isCheckbox ? inputHtml + Environment.NewLine + label : label + Environment.NewLine + inputHtml; return Environment.NewLine + innerContent + Environment.NewLine + - Environment.NewLine + validation + Environment.NewLine; + Environment.NewLine + validation + Environment.NewLine + infoHtml; } protected virtual string SurroundInnerHtmlAndGet(TagHelperContext context, TagHelperOutput output, string innerHtml, bool isCheckbox) @@ -134,6 +135,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form AddFormControlClass(context, output, isCheckbox, inputTagHelperOutput); AddReadOnlyAttribute(inputTagHelperOutput); AddPlaceholderAttribute(inputTagHelperOutput); + AddInfoTextId(inputTagHelperOutput); return inputTagHelperOutput; } @@ -196,6 +198,23 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form } } + protected virtual void AddInfoTextId(TagHelperOutput inputTagHelperOutput) + { + if (GetAttribute(TagHelper.AspFor.ModelExplorer) == null) + { + return; + } + + var idAttr = inputTagHelperOutput.Attributes.FirstOrDefault(a => a.Name == "id"); + + if (idAttr == null) + { + return; + } + + inputTagHelperOutput.Attributes.Add("aria-describedby", LocalizeText(idAttr.Value + "InfoText")); + } + protected virtual string LocalizeText(string text) { IStringLocalizer localizer = null; @@ -233,6 +252,33 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form ""; } + protected virtual string GetInfoAsHtml(TagHelperContext context, TagHelperOutput output, TagHelperOutput inputTag, bool isCheckbox) + { + if (isCheckbox) + { + return ""; + } + + var infoAttribute = GetAttribute(TagHelper.AspFor.ModelExplorer); + if (infoAttribute == null) + { + return ""; + } + + var idAttr = inputTag.Attributes.FirstOrDefault(a => a.Name == "id"); + + if (idAttr == null) + { + return ""; + } + + var id = idAttr.Value + "InfoText"; + + return "" + + LocalizeText(infoAttribute.Text) + + ""; + } + protected virtual string GetLabelAsHtmlUsingTagHelper(TagHelperContext context, TagHelperOutput output, bool isCheckbox) { var labelTagHelper = new LabelTagHelper(_generator) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/InputInfoText.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/InputInfoText.cs new file mode 100644 index 0000000000..237ca7c92d --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/InputInfoText.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +{ + [AttributeUsage(AttributeTargets.Property)] + public class InputInfoText : Attribute + { + public string Text { get; set; } + + public InputInfoText(string text) + { + Text = text; + } + } +} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml index 8fd08e3a94..7e710d1956 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml @@ -74,6 +74,7 @@ public class DynamicFormsModel : PageModel [TextArea(Rows = 4)] [Display(Name = "Description")] + [InputInfoText("Describe Yourself")] public string Description { get; set; } [Required] diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml.cs index 753a76d3be..7854da4920 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/DynamicForms.cshtml.cs @@ -108,6 +108,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components [TextArea(Rows = 4)] [Display(Name = "Description")] + [InputInfoText("Describe Yourself")] public string Description { get; set; } [Required] From 24c5597bf70aed666048001d8a629cf398a639e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arma=C4=9Fan=20=C3=9Cnl=C3=BC?= <36102404+armgnunlu@users.noreply.github.com> Date: Thu, 20 Dec 2018 14:31:29 +0300 Subject: [PATCH 094/368] Responsive menu problem #132 - Fixed --- .../Volo.AbpWebSite.Web/Pages/Index.cshtml | 40 +++++++++---------- .../Shared/Components/Header/Default.cshtml | 3 +- .../Volo.AbpWebSite.Web/wwwroot/scss/vs.css | 2 +- .../wwwroot/scss/vs.min.css | 2 +- .../Volo.AbpWebSite.Web/wwwroot/scss/vs.scss | 2 +- 5 files changed, 24 insertions(+), 25 deletions(-) diff --git a/abp_io/src/Volo.AbpWebSite.Web/Pages/Index.cshtml b/abp_io/src/Volo.AbpWebSite.Web/Pages/Index.cshtml index bf74126618..010209c690 100644 --- a/abp_io/src/Volo.AbpWebSite.Web/Pages/Index.cshtml +++ b/abp_io/src/Volo.AbpWebSite.Web/Pages/Index.cshtml @@ -195,34 +195,34 @@

-
+
 
                     
-<abp-card>
-    <img abp-card-image="Top" src="~/images/my-dog.png" />
-    <abp-card-body>
-        <abp-card-title>Card title</abp-card-title>
-        <abp-card-text>
-            <p>
-                This is a sample card component built by ABP bootstrap
-                card tag helper. ABP has tag helper wrappers for most of 
-                the bootstrap components.
-            </p>
-        </abp-card-text>
-        <a abp-button="Primary" href="#">Go somewhere &rarr;</a>
-    </abp-card-body>
-</abp-card>
+                    <abp-card>
+                        <img abp-card-image="Top" src="~/images/my-dog.png" />
+                        <abp-card-body>
+                            <abp-card-title>Card title</abp-card-title>
+                            <abp-card-text>
+                                <p>
+                                    This is a sample card component built by ABP bootstrap
+                                    card tag helper. ABP has tag helper wrappers for most of 
+                                    the bootstrap components.
+                                </p>
+                            </abp-card-text>
+                            <a abp-button="Primary" href="#">Go somewhere &rarr;</a>
+                        </abp-card-body>
+                    </abp-card>
                         
                     
-
+
-
+
@@ -265,7 +265,7 @@
-
+
 
                     
@@ -300,12 +300,12 @@ public class PersonModel
                     
-
+
-
+
diff --git a/abp_io/src/Volo.AbpWebSite.Web/Pages/Shared/Components/Header/Default.cshtml b/abp_io/src/Volo.AbpWebSite.Web/Pages/Shared/Components/Header/Default.cshtml index c3d877b425..8c25d6592b 100644 --- a/abp_io/src/Volo.AbpWebSite.Web/Pages/Shared/Components/Header/Default.cshtml +++ b/abp_io/src/Volo.AbpWebSite.Web/Pages/Shared/Components/Header/Default.cshtml @@ -26,8 +26,7 @@ Github
  • -
  • diff --git a/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.css b/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.css index 36bfe30a55..ad4f5adca0 100644 --- a/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.css +++ b/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.css @@ -600,7 +600,7 @@ span.code-arrow { .docs-page .docs-page-index { display: none; } } -@media (max-width: 767px) { +@media (max-width: 992px) { body { font-size: 14px; } .for-mobile { diff --git a/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.min.css b/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.min.css index b8f9189bf2..524731f0ff 100644 --- a/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.min.css +++ b/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.min.css @@ -1 +1 @@ -body{position:relative;font-family:'PT Sans',sans-serif;background:url(../assets/tools/bg.jpg) center center no-repeat;background-attachment:fixed;}h1,h2,h3,h4,h5,h6{font-family:'PT Sans Caption',sans-serif;}h1{font-size:2.25em;margin:1.5rem 0 .75rem;}h2{font-size:1.75em;margin:1.5rem 0 .75rem;}h3{font-size:1.5em;margin:1.5rem 0 .75rem;}h4{font-size:1.25em;margin:1.5rem 0 .75rem;}h5{font-size:1em;margin:1.5rem 0 .75rem;}h6{font-size:1em;margin:1.5rem 0 .75rem;}img{max-width:100%;}.navbar{padding:1.75rem 2rem;}.nav-link{padding-left:1rem !important;padding-right:1rem !important;}.navbar-dark .navbar-nav .nav-link{color:#fff;}.text-success{color:#e90052 !important;}a.text-success:hover,a.text-success:focus{color:#e90052 !important;}.bg-success,.btn-success,.badge-success{background-color:#e90052 !important;border-color:#e90052 !important;}.bg-success{background-color:rgba(233,0,82,.8) !important;}.bg-blue,.btn-blue,.badge-blue{background-color:#03abed !important;border-color:#03abed !important;color:#fff;}.bg-blue:hover,.btn-blue:hover,.badge-blue:hover{background-color:#0095d0 !important;border-color:#0095d0 !important;color:#fff !important;}.btn:focus,.btn:active,.btn:visited,a:focus,a:active,a:visited{outline:none !important;box-shadow:none;}.text-primary{color:#38003c !important;}.bg-primary,.btn-primary,.badge-primary{background-color:#38003c !important;border-color:#38003c !important;}.bg-primary{background-color:rgba(56,0,60,.9) !important;}.btn-outline-primary{color:#38003c !important;border-color:#38003c !important;}.btn-outline-primary:hover{background-color:#38003c !important;color:#fff !important;}.dropdown-menu{padding:1rem 0;border-radius:.15rem;border:none;box-shadow:5px 5px 40px rgba(0,0,0,.3);}.dropdown-menu .dropdown-item{padding:.75rem 1.5rem;}#index-video{position:fixed;right:0;bottom:0;min-width:100%;min-height:100%;z-index:-1;}.bg-gradient-horizontal{background:#fff;}@media(min-width:480px){.bg-gradient-horizontal{background:#fff;background:-moz-linear-gradient(left,#fff 50%,#f2f2f2 50%);background:-webkit-linear-gradient(left,#fff 50%,#f2f2f2 50%);background:linear-gradient(to right,#fff 50%,#f2f2f2 50%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',endColorstr='#f2f2f2',GradientType=1);}}.bg-transparency{background:rgba(255,255,255,.9);}.bg-light{background:#eee;}.for-mobile{display:none;}.for-desktop{display:inline-block;}.breadcrumb{background:none;font-size:.85em;border-radius:0;border-bottom:1px solid #f5f5f5;margin:0 -15px;padding:.5rem 0;text-align:center;display:block;}.breadcrumb .breadcrumb-item+.breadcrumb-item{padding-left:.2rem;}.breadcrumb .breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.4rem;color:#eee;content:"|";}.breadcrumb .breadcrumb-item{color:#eee;display:inline-block;}.breadcrumb .breadcrumb-item a{color:#aaa;}.close{font-weight:300;}hr{margin-top:2rem;margin-bottom:2.5rem;border-top:1px solid rgba(0,0,0,.05);}span.with-br-name{font-size:.75em;}span.br-name{display:block;font-size:1.25em;}span.br-name-1{display:block;font-size:1em;}.btn-fifty{display:flex;}.btn-fifty .btn{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%;}.p-responsive{padding:120px 0;}.global-header{display:none;}.global-header .navbar{background:rgba(255,255,255,.2);}.global-header .navbar .products-link{border:1px solid rgba(255,255,255,.75);border-radius:.2rem;margin:0 10px;padding-top:.36rem;padding-bottom:.36rem;}.global-header .navbar .search-item{position:relative;}.global-header .navbar .search-item input.form-control{background:none;border:1px solid rgba(255,255,255,.25);border-radius:.2rem;color:#fff;padding-left:2.5rem;min-width:280px;}.global-header .navbar .search-item input.form-control::-webkit-input-placeholder{color:rgba(255,255,255,.25) !important;}.global-header .navbar .search-item input.form-control:-moz-placeholder{color:rgba(255,255,255,.25) !important;}.global-header .navbar .search-item input.form-control::-moz-placeholder{color:rgba(255,255,255,.25) !important;}.global-header .navbar .search-item input.form-control:-ms-input-placeholder{color:rgba(255,255,255,.25) !important;}.global-header .navbar .search-item .btn-search{position:absolute;top:-2px;left:-1px;background:none;}header .btn{background:#fff;}header .btn.btn-login,header .btn.btn-logout{border:2px solid #fff;color:#fff;background:transparent;margin-right:6px;}header .btn.btn-login:hover,header .btn.btn-logout:hover{background:#fff;color:#e90052;}.product-header{font-size:1.1rem;}.product-header .navbar-brand{font-size:1.75rem;}.home-logo{width:120px;}.jumbotron-logo{width:240px;margin-bottom:40px;}.forkme{position:fixed;bottom:0;right:0;}.footer-logo{width:140px;}.jumbotron{background:#006bf0;background:-moz-linear-gradient(left,#006bf0 0%,#40ffb0 100%);background:-webkit-linear-gradient(left,#006bf0 0%,#40ffb0 100%);background:linear-gradient(to right,rgba(56,0,60,.9) 0%,rgba(185,0,74,.78) 100%);margin-top:-120px;border-radius:0;margin-bottom:0;height:90vh;}.jumbotron.jumbocover{padding:120px 0 20px;height:auto;}.jumbotron>.row{height:calc(90vh - 120px);}.jumbotron .abp-version{position:absolute;font-size:11px;right:1px;top:-2px;padding:1px 4px 0;display:inline-block;color:#fff;background:rgba(233,3,82,.7);border-radius:3px;opacity:.8;}.jumbotron .desc-span{font-size:1.4em;font-style:italic;opacity:.7;}.section-with-logos img{margin:25px;max-height:50px;transition:.4s;opacity:.6;-webkit-filter:grayscale(60%);filter:grayscale(60%);}.section-with-logos img:hover{opacity:1;-webkit-filter:grayscale(0%);filter:grayscale(0%);}img.subsection-icon{width:64px;height:64px;}.toggle-row{display:none;}.btn-toggle .lessText{display:none;}.btn-toggle .moreText{display:block;}.btn-toggle.less .lessText{display:block;}.btn-toggle.less .moreText{display:none;}.abp-browser{margin:3rem 0 1rem;text-align:left;border-radius:6px;overflow:hidden;}.abp-browser .browser-container{border:1px solid #eee;}.abp-browser .browser-row{padding:4px 10px;background:#e5e5e5;}.abp-browser .browser-row:after{content:"";display:table;clear:both;}.abp-browser .browser-dot{margin-top:2px;margin-right:2px;height:12px;width:12px;background-color:#bbb;border-radius:50%;display:inline-block;}.abp-browser .abp-browser input[type=text]{width:100%;border-radius:3px;border:none;background-color:#fff;margin-top:-8px;height:25px;color:#666;padding:5px;}.abp-browser .browser-bar{width:17px;height:3px;background-color:#aaa;margin:3px 0;display:block;}.abp-browser .browser-content{padding:2rem;background:#f5f5f5;}.abp-browser .bg-primary,.abp-browser .btn-primary,.abp-browser .badge-primary{background-color:#007bff !important;border-color:#007bff !important;}.abp-browser .btn-outline-primary{color:#007bff !important;border-color:#007bff !important;}.abp-browser .btn-outline-primary:hover{background-color:#007bff !important;color:#fff !important;}span.code-arrow{padding:52px 0 18px;display:block;font-size:40px;}.docs-page{background:#f5f7f9;}.docs-page .docs-sidebar{background:#f5f7f9;padding-right:1.5rem;position:relative;width:270px;}.docs-page .docs-sidebar .docs-sidebar-wrapper{width:270px;top:0;position:fixed;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{height:calc(100vh - 190px);overflow:hidden;overflow-y:auto;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-search{position:relative;padding:0 0 1.25rem 1.5rem;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-search input.form-control{background:none;border-radius:.2rem;padding-left:2.5rem;width:100%;background:#eeeff2;border:0;font-size:.85em;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-search .btn-search{position:absolute;top:-5px;left:22px;background:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul{font-size:.913em;list-style:none;padding:0 0 0 20px;margin:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li{margin-left:0;padding-left:24px;display:block;width:100%;position:relative;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li label{margin:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li label.tree-toggle{transition:.3s;display:inline-block;width:18px;height:18px;text-align:center;padding:0;line-height:normal;border-radius:50%;margin-right:4px;position:absolute;left:0;top:8px;cursor:pointer;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li label.tree-toggle img{width:14px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li label.tree-toggle:not(.last-link).opened{transform:rotate(180deg);}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a{color:#101010;font-weight:700;padding:7px 0;display:block;border-bottom:1px solid #eeeff3;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li label.tree-toggle{top:6px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li a{font-weight:400;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul li a{font-weight:300;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a{color:#38003c;font-weight:bold;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:2rem;font-weight:700;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand .docs-logo{width:130px;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand strong{font-weight:300;font-size:1.2rem;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:.85em;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc strong{display:block;}.docs-page .docs-content .docs-text-field{padding:3rem;}.docs-page .docs-page-index{position:relative;}.docs-page .docs-page-index .docs-inner-anchors{position:fixed;top:0;max-width:270px;padding:10px;font-size:.9em;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills{font-size:.95em;margin-left:18px;border-left:1px solid #e5e5e5;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link{padding:.2rem 0 .2rem 1rem;color:#aaa;line-height:1.1;position:relative;border-left:3px solid transparent;border-radius:0;margin-left:-2px;margin-top:2px;margin-bottom:2px;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link.active{background:none;color:#38003b;border-color:#38003b;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-link.active{color:#38003b;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-pills .nav-link.active{color:#38003b;}.docs-page .docs-page-index .docs-inner-anchors>.navbar{margin-left:-18px;}.docs-page .docs-page-index .docs-inner-anchors .docs-anchors-wrapper{max-width:300px;float:left;}.docs-page .docs-page-index .docs-inner-anchors .inner-title{padding-left:18px;}.docs-page .docs-page-index .scroll-top-btn{display:none;font-size:.85em;color:#aaa;text-decoration:underline;padding-left:18px;}.docs-page .docs-page-index .scroll-top-btn.showup{display:block;}@media(min-width:1200px){.container{max-width:1180px;}}@media(min-width:1366px){.container{max-width:1340px;}}@media(min-width:1440px){.container{max-width:1400px;}}@media(max-width:767px){.docs-page{background:#f5f7f9;}.docs-page>.container-fluid{display:block;}.docs-page>.container-fluid>.row{display:block;}.docs-page .docs-sidebar{position:fixed;max-width:100%;width:100%;display:block;padding:0 !important;top:0;left:0;z-index:100;right:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper{max-width:100%;width:100%;top:0;position:relative;margin:0 !important;height:72px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{padding:.5rem 1.5rem 2rem 1.5rem;height:calc(100vh - 72px);overflow:hidden;overflow-y:auto;position:fixed;top:72px;font-size:17px;left:0;width:100%;z-index:100;background:#f5f7f9;display:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-search{position:relative;padding:0 0 1rem !important;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-search .btn-search{top:-14px;left:-2px;}.docs-page .docs-sidebar .docs-top .navbar-logo{padding:0;padding-top:.3rem;display:block;text-align:center;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:2rem;font-weight:700;display:block;margin-right:0;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand .docs-logo{width:110px;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:1em;display:none;}.docs-page .docs-sidebar .docs-top .open-dmenu{position:absolute;top:10px;left:20px;}.docs-page .docs-content{padding-top:72px;max-width:100%;display:block !important;}.docs-page .docs-content .docs-text-field{padding:1rem 1.5rem;}.docs-page .docs-page-index{display:none;}}@media(max-width:767px){body{font-size:14px;}.for-mobile{display:inline-block;}.for-desktop{display:none;}.close-mmenu,.close-dmenu{position:absolute;top:-78px;left:25px;color:#fff;font-size:68px;background:#fff;opacity:0;}.navbar{padding:.5rem 1.75rem;}.navbar .navbar-collapse{background:#38003d;position:fixed;top:86px;left:0;width:100%;height:100vh;height:calc(100vh - 86px);z-index:100 !important;}.navbar .navbar-collapse .navbar-nav{height:100vh;padding:20px 30px;overflow:auto;}.navbar .navbar-collapse .navbar-nav .nav-link{padding:1.2rem !important;}.navbar .navbar-toggler{padding:.5rem .75rem;font-size:1.5rem;line-height:1;background-color:transparent;border:0;border-radius:.25rem;color:#fff !important;margin-left:-1rem;}.jumbotron .btn,footer .btn{display:block;margin-bottom:10px;}.multi-tenancy{text-align:center !important;}.section-with-logos img{margin:15px;opacity:1;-webkit-filter:grayscale(0%);filter:grayscale(0%);}.jumbotron{padding-top:160px;margin-top:-160px;border-radius:0;padding-bottom:40px;margin-bottom:0;font-size:.85em;padding-left:45px;padding-right:45px;}span.code-arrow{padding:0 0 0;display:block;transform:rotate(90deg);font-size:2em;}.mb-5,.my-5{margin-bottom:2rem !important;}.jumbotron{height:calc(100vh + 120px);}.jumbotron.jumbocover{height:auto;padding:160px 0 20px;}.jumbotron hr{display:none;}.jumbotron .btn{margin-bottom:0 !important;}.jumbotron .jumbotron-logo{margin-bottom:0;width:180px;height:62px;margin-top:-30px;}.jumbotron .jlogo-wrapper{height:62px;}}.vs-blog{margin-top:-88px !important;}.abp-account-container{max-width:400px;margin:0 auto;margin-top:-88px !important;}body{background-size:cover;} \ No newline at end of file +body{position:relative;font-family:'PT Sans',sans-serif;background:url(../assets/tools/bg.jpg) center center no-repeat;background-attachment:fixed;}h1,h2,h3,h4,h5,h6{font-family:'PT Sans Caption',sans-serif;}h1{font-size:2.25em;margin:1.5rem 0 .75rem;}h2{font-size:1.75em;margin:1.5rem 0 .75rem;}h3{font-size:1.5em;margin:1.5rem 0 .75rem;}h4{font-size:1.25em;margin:1.5rem 0 .75rem;}h5{font-size:1em;margin:1.5rem 0 .75rem;}h6{font-size:1em;margin:1.5rem 0 .75rem;}img{max-width:100%;}.navbar{padding:1.75rem 2rem;}.nav-link{padding-left:1rem !important;padding-right:1rem !important;}.navbar-dark .navbar-nav .nav-link{color:#fff;}.text-success{color:#e90052 !important;}a.text-success:hover,a.text-success:focus{color:#e90052 !important;}.bg-success,.btn-success,.badge-success{background-color:#e90052 !important;border-color:#e90052 !important;}.bg-success{background-color:rgba(233,0,82,.8) !important;}.bg-blue,.btn-blue,.badge-blue{background-color:#03abed !important;border-color:#03abed !important;color:#fff;}.bg-blue:hover,.btn-blue:hover,.badge-blue:hover{background-color:#0095d0 !important;border-color:#0095d0 !important;color:#fff !important;}.btn:focus,.btn:active,.btn:visited,a:focus,a:active,a:visited{outline:none !important;box-shadow:none;}.text-primary{color:#38003c !important;}.bg-primary,.btn-primary,.badge-primary{background-color:#38003c !important;border-color:#38003c !important;}.bg-primary{background-color:rgba(56,0,60,.9) !important;}.btn-outline-primary{color:#38003c !important;border-color:#38003c !important;}.btn-outline-primary:hover{background-color:#38003c !important;color:#fff !important;}.dropdown-menu{padding:1rem 0;border-radius:.15rem;border:none;box-shadow:5px 5px 40px rgba(0,0,0,.3);}.dropdown-menu .dropdown-item{padding:.75rem 1.5rem;}#index-video{position:fixed;right:0;bottom:0;min-width:100%;min-height:100%;z-index:-1;}.bg-gradient-horizontal{background:#fff;}@media(min-width:480px){.bg-gradient-horizontal{background:#fff;background:-moz-linear-gradient(left,#fff 50%,#f2f2f2 50%);background:-webkit-linear-gradient(left,#fff 50%,#f2f2f2 50%);background:linear-gradient(to right,#fff 50%,#f2f2f2 50%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',endColorstr='#f2f2f2',GradientType=1);}}.bg-transparency{background:rgba(255,255,255,.9);}.bg-light{background:#eee;}.for-mobile{display:none;}.for-desktop{display:inline-block;}.breadcrumb{background:none;font-size:.85em;border-radius:0;border-bottom:1px solid #f5f5f5;margin:0 -15px;padding:.5rem 0;text-align:center;display:block;}.breadcrumb .breadcrumb-item+.breadcrumb-item{padding-left:.2rem;}.breadcrumb .breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.4rem;color:#eee;content:"|";}.breadcrumb .breadcrumb-item{color:#eee;display:inline-block;}.breadcrumb .breadcrumb-item a{color:#aaa;}.close{font-weight:300;}hr{margin-top:2rem;margin-bottom:2.5rem;border-top:1px solid rgba(0,0,0,.05);}span.with-br-name{font-size:.75em;}span.br-name{display:block;font-size:1.25em;}span.br-name-1{display:block;font-size:1em;}.btn-fifty{display:flex;}.btn-fifty .btn{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%;}.p-responsive{padding:120px 0;}.global-header{display:none;}.global-header .navbar{background:rgba(255,255,255,.2);}.global-header .navbar .products-link{border:1px solid rgba(255,255,255,.75);border-radius:.2rem;margin:0 10px;padding-top:.36rem;padding-bottom:.36rem;}.global-header .navbar .search-item{position:relative;}.global-header .navbar .search-item input.form-control{background:none;border:1px solid rgba(255,255,255,.25);border-radius:.2rem;color:#fff;padding-left:2.5rem;min-width:280px;}.global-header .navbar .search-item input.form-control::-webkit-input-placeholder{color:rgba(255,255,255,.25) !important;}.global-header .navbar .search-item input.form-control:-moz-placeholder{color:rgba(255,255,255,.25) !important;}.global-header .navbar .search-item input.form-control::-moz-placeholder{color:rgba(255,255,255,.25) !important;}.global-header .navbar .search-item input.form-control:-ms-input-placeholder{color:rgba(255,255,255,.25) !important;}.global-header .navbar .search-item .btn-search{position:absolute;top:-2px;left:-1px;background:none;}header .btn{background:#fff;}header .btn.btn-login,header .btn.btn-logout{border:2px solid #fff;color:#fff;background:transparent;margin-right:6px;}header .btn.btn-login:hover,header .btn.btn-logout:hover{background:#fff;color:#e90052;}.product-header{font-size:1.1rem;}.product-header .navbar-brand{font-size:1.75rem;}.home-logo{width:120px;}.jumbotron-logo{width:240px;margin-bottom:40px;}.forkme{position:fixed;bottom:0;right:0;}.footer-logo{width:140px;}.jumbotron{background:#006bf0;background:-moz-linear-gradient(left,#006bf0 0%,#40ffb0 100%);background:-webkit-linear-gradient(left,#006bf0 0%,#40ffb0 100%);background:linear-gradient(to right,rgba(56,0,60,.9) 0%,rgba(185,0,74,.78) 100%);margin-top:-120px;border-radius:0;margin-bottom:0;height:90vh;}.jumbotron.jumbocover{padding:120px 0 20px;height:auto;}.jumbotron>.row{height:calc(90vh - 120px);}.jumbotron .abp-version{position:absolute;font-size:11px;right:1px;top:-2px;padding:1px 4px 0;display:inline-block;color:#fff;background:rgba(233,3,82,.7);border-radius:3px;opacity:.8;}.jumbotron .desc-span{font-size:1.4em;font-style:italic;opacity:.7;}.section-with-logos img{margin:25px;max-height:50px;transition:.4s;opacity:.6;-webkit-filter:grayscale(60%);filter:grayscale(60%);}.section-with-logos img:hover{opacity:1;-webkit-filter:grayscale(0%);filter:grayscale(0%);}img.subsection-icon{width:64px;height:64px;}.toggle-row{display:none;}.btn-toggle .lessText{display:none;}.btn-toggle .moreText{display:block;}.btn-toggle.less .lessText{display:block;}.btn-toggle.less .moreText{display:none;}.abp-browser{margin:3rem 0 1rem;text-align:left;border-radius:6px;overflow:hidden;}.abp-browser .browser-container{border:1px solid #eee;}.abp-browser .browser-row{padding:4px 10px;background:#e5e5e5;}.abp-browser .browser-row:after{content:"";display:table;clear:both;}.abp-browser .browser-dot{margin-top:2px;margin-right:2px;height:12px;width:12px;background-color:#bbb;border-radius:50%;display:inline-block;}.abp-browser .abp-browser input[type=text]{width:100%;border-radius:3px;border:none;background-color:#fff;margin-top:-8px;height:25px;color:#666;padding:5px;}.abp-browser .browser-bar{width:17px;height:3px;background-color:#aaa;margin:3px 0;display:block;}.abp-browser .browser-content{padding:2rem;background:#f5f5f5;}.abp-browser .bg-primary,.abp-browser .btn-primary,.abp-browser .badge-primary{background-color:#007bff !important;border-color:#007bff !important;}.abp-browser .btn-outline-primary{color:#007bff !important;border-color:#007bff !important;}.abp-browser .btn-outline-primary:hover{background-color:#007bff !important;color:#fff !important;}span.code-arrow{padding:52px 0 18px;display:block;font-size:40px;}.docs-page{background:#f5f7f9;}.docs-page .docs-sidebar{background:#f5f7f9;padding-right:1.5rem;position:relative;width:270px;}.docs-page .docs-sidebar .docs-sidebar-wrapper{width:270px;top:0;position:fixed;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{height:calc(100vh - 190px);overflow:hidden;overflow-y:auto;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-search{position:relative;padding:0 0 1.25rem 1.5rem;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-search input.form-control{background:none;border-radius:.2rem;padding-left:2.5rem;width:100%;background:#eeeff2;border:0;font-size:.85em;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-search .btn-search{position:absolute;top:-5px;left:22px;background:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul{font-size:.913em;list-style:none;padding:0 0 0 20px;margin:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li{margin-left:0;padding-left:24px;display:block;width:100%;position:relative;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li label{margin:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li label.tree-toggle{transition:.3s;display:inline-block;width:18px;height:18px;text-align:center;padding:0;line-height:normal;border-radius:50%;margin-right:4px;position:absolute;left:0;top:8px;cursor:pointer;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li label.tree-toggle img{width:14px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li label.tree-toggle:not(.last-link).opened{transform:rotate(180deg);}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a{color:#101010;font-weight:700;padding:7px 0;display:block;border-bottom:1px solid #eeeff3;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li label.tree-toggle{top:6px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li a{font-weight:400;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul li a{font-weight:300;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a{color:#38003c;font-weight:bold;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:2rem;font-weight:700;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand .docs-logo{width:130px;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand strong{font-weight:300;font-size:1.2rem;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:.85em;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc strong{display:block;}.docs-page .docs-content .docs-text-field{padding:3rem;}.docs-page .docs-page-index{position:relative;}.docs-page .docs-page-index .docs-inner-anchors{position:fixed;top:0;max-width:270px;padding:10px;font-size:.9em;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills{font-size:.95em;margin-left:18px;border-left:1px solid #e5e5e5;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link{padding:.2rem 0 .2rem 1rem;color:#aaa;line-height:1.1;position:relative;border-left:3px solid transparent;border-radius:0;margin-left:-2px;margin-top:2px;margin-bottom:2px;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link.active{background:none;color:#38003b;border-color:#38003b;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-link.active{color:#38003b;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-pills .nav-link.active{color:#38003b;}.docs-page .docs-page-index .docs-inner-anchors>.navbar{margin-left:-18px;}.docs-page .docs-page-index .docs-inner-anchors .docs-anchors-wrapper{max-width:300px;float:left;}.docs-page .docs-page-index .docs-inner-anchors .inner-title{padding-left:18px;}.docs-page .docs-page-index .scroll-top-btn{display:none;font-size:.85em;color:#aaa;text-decoration:underline;padding-left:18px;}.docs-page .docs-page-index .scroll-top-btn.showup{display:block;}@media(min-width:1200px){.container{max-width:1180px;}}@media(min-width:1366px){.container{max-width:1340px;}}@media(min-width:1440px){.container{max-width:1400px;}}@media(max-width:767px){.docs-page{background:#f5f7f9;}.docs-page>.container-fluid{display:block;}.docs-page>.container-fluid>.row{display:block;}.docs-page .docs-sidebar{position:fixed;max-width:100%;width:100%;display:block;padding:0 !important;top:0;left:0;z-index:100;right:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper{max-width:100%;width:100%;top:0;position:relative;margin:0 !important;height:72px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{padding:.5rem 1.5rem 2rem 1.5rem;height:calc(100vh - 72px);overflow:hidden;overflow-y:auto;position:fixed;top:72px;font-size:17px;left:0;width:100%;z-index:100;background:#f5f7f9;display:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-search{position:relative;padding:0 0 1rem !important;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-search .btn-search{top:-14px;left:-2px;}.docs-page .docs-sidebar .docs-top .navbar-logo{padding:0;padding-top:.3rem;display:block;text-align:center;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:2rem;font-weight:700;display:block;margin-right:0;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand .docs-logo{width:110px;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:1em;display:none;}.docs-page .docs-sidebar .docs-top .open-dmenu{position:absolute;top:10px;left:20px;}.docs-page .docs-content{padding-top:72px;max-width:100%;display:block !important;}.docs-page .docs-content .docs-text-field{padding:1rem 1.5rem;}.docs-page .docs-page-index{display:none;}}@media(max-width:992px){body{font-size:14px;}.for-mobile{display:inline-block;}.for-desktop{display:none;}.close-mmenu,.close-dmenu{position:absolute;top:-78px;left:25px;color:#fff;font-size:68px;background:#fff;opacity:0;}.navbar{padding:.5rem 1.75rem;}.navbar .navbar-collapse{background:#38003d;position:fixed;top:86px;left:0;width:100%;height:100vh;height:calc(100vh - 86px);z-index:100 !important;}.navbar .navbar-collapse .navbar-nav{height:100vh;padding:20px 30px;overflow:auto;}.navbar .navbar-collapse .navbar-nav .nav-link{padding:1.2rem !important;}.navbar .navbar-toggler{padding:.5rem .75rem;font-size:1.5rem;line-height:1;background-color:transparent;border:0;border-radius:.25rem;color:#fff !important;margin-left:-1rem;}.jumbotron .btn,footer .btn{display:block;margin-bottom:10px;}.multi-tenancy{text-align:center !important;}.section-with-logos img{margin:15px;opacity:1;-webkit-filter:grayscale(0%);filter:grayscale(0%);}.jumbotron{padding-top:160px;margin-top:-160px;border-radius:0;padding-bottom:40px;margin-bottom:0;font-size:.85em;padding-left:45px;padding-right:45px;}span.code-arrow{padding:0 0 0;display:block;transform:rotate(90deg);font-size:2em;}.mb-5,.my-5{margin-bottom:2rem !important;}.jumbotron{height:calc(100vh + 120px);}.jumbotron.jumbocover{height:auto;padding:160px 0 20px;}.jumbotron hr{display:none;}.jumbotron .btn{margin-bottom:0 !important;}.jumbotron .jumbotron-logo{margin-bottom:0;width:180px;height:62px;margin-top:-30px;}.jumbotron .jlogo-wrapper{height:62px;}}.vs-blog{margin-top:-88px !important;}.abp-account-container{max-width:400px;margin:0 auto;margin-top:-88px !important;}body{background-size:cover;} \ No newline at end of file diff --git a/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.scss b/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.scss index 07bfa1b354..4d9cb4a995 100644 --- a/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.scss +++ b/abp_io/src/Volo.AbpWebSite.Web/wwwroot/scss/vs.scss @@ -3,7 +3,7 @@ @import "footer.scss"; @import "home.scss"; @import "docs.scss"; -@media (max-width: 767px) { +@media (max-width: 992px) { @import "responsive.scss"; } From 7f97c12e61c2a2d53a8bc77c3c65cb2d5734fb35 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 20 Dec 2018 14:41:59 +0300 Subject: [PATCH 095/368] Resharper and Coding Standards... #610 --- modules/account/Volo.Abp.Account.sln.DotSettings | 7 +++++++ .../audit-logging/Volo.Abp.AuditLogging.sln.DotSettings | 7 +++++++ .../Volo.Abp.BackgroundJobs.sln.DotSettings | 7 +++++++ modules/blogging/Volo.Blogging.sln.DotSettings | 7 +++++++ modules/docs/Volo.Docs.sln.DotSettings | 7 +++++++ .../identityserver/Volo.Abp.IdentityServer.sln.DotSettings | 7 +++++++ .../Volo.Abp.PermissionManagement.sln.DotSettings | 7 +++++++ .../Volo.Abp.SettingManagement.sln.DotSettings | 7 +++++++ .../Volo.Abp.TenantManagement.sln.DotSettings | 7 +++++++ modules/users/Volo.Abp.Users.sln.DotSettings | 7 +++++++ .../module/MyCompanyName.MyProjectName.sln.DotSettings | 7 +++++++ templates/mvc/MyCompanyName.MyProjectName.sln.DotSettings | 7 +++++++ .../service/MyCompanyName.MyProjectName.sln.DotSettings | 7 +++++++ 13 files changed, 91 insertions(+) create mode 100644 modules/account/Volo.Abp.Account.sln.DotSettings create mode 100644 modules/audit-logging/Volo.Abp.AuditLogging.sln.DotSettings create mode 100644 modules/background-jobs/Volo.Abp.BackgroundJobs.sln.DotSettings create mode 100644 modules/blogging/Volo.Blogging.sln.DotSettings create mode 100644 modules/docs/Volo.Docs.sln.DotSettings create mode 100644 modules/identityserver/Volo.Abp.IdentityServer.sln.DotSettings create mode 100644 modules/permission-management/Volo.Abp.PermissionManagement.sln.DotSettings create mode 100644 modules/setting-management/Volo.Abp.SettingManagement.sln.DotSettings create mode 100644 modules/tenant-management/Volo.Abp.TenantManagement.sln.DotSettings create mode 100644 modules/users/Volo.Abp.Users.sln.DotSettings create mode 100644 templates/module/MyCompanyName.MyProjectName.sln.DotSettings create mode 100644 templates/mvc/MyCompanyName.MyProjectName.sln.DotSettings create mode 100644 templates/service/MyCompanyName.MyProjectName.sln.DotSettings diff --git a/modules/account/Volo.Abp.Account.sln.DotSettings b/modules/account/Volo.Abp.Account.sln.DotSettings new file mode 100644 index 0000000000..d132bd87f4 --- /dev/null +++ b/modules/account/Volo.Abp.Account.sln.DotSettings @@ -0,0 +1,7 @@ + + True + D:\github\abp\common.DotSettings + ..\..\..\common.DotSettings + True + 1 + \ No newline at end of file diff --git a/modules/audit-logging/Volo.Abp.AuditLogging.sln.DotSettings b/modules/audit-logging/Volo.Abp.AuditLogging.sln.DotSettings new file mode 100644 index 0000000000..9244fc7a65 --- /dev/null +++ b/modules/audit-logging/Volo.Abp.AuditLogging.sln.DotSettings @@ -0,0 +1,7 @@ + + True + D:\github\abp\common.DotSettings + ..\..\..\common.DotSettings + True + 1 + \ No newline at end of file diff --git a/modules/background-jobs/Volo.Abp.BackgroundJobs.sln.DotSettings b/modules/background-jobs/Volo.Abp.BackgroundJobs.sln.DotSettings new file mode 100644 index 0000000000..1561493d47 --- /dev/null +++ b/modules/background-jobs/Volo.Abp.BackgroundJobs.sln.DotSettings @@ -0,0 +1,7 @@ + + True + D:\github\abp\common.DotSettings + ..\..\..\common.DotSettings + True + 1 + \ No newline at end of file diff --git a/modules/blogging/Volo.Blogging.sln.DotSettings b/modules/blogging/Volo.Blogging.sln.DotSettings new file mode 100644 index 0000000000..efc1d95fa5 --- /dev/null +++ b/modules/blogging/Volo.Blogging.sln.DotSettings @@ -0,0 +1,7 @@ + + True + D:\github\abp\common.DotSettings + ..\..\..\common.DotSettings + True + 1 + \ No newline at end of file diff --git a/modules/docs/Volo.Docs.sln.DotSettings b/modules/docs/Volo.Docs.sln.DotSettings new file mode 100644 index 0000000000..df013904be --- /dev/null +++ b/modules/docs/Volo.Docs.sln.DotSettings @@ -0,0 +1,7 @@ + + True + D:\github\abp\common.DotSettings + ..\..\..\common.DotSettings + True + 1 + \ No newline at end of file diff --git a/modules/identityserver/Volo.Abp.IdentityServer.sln.DotSettings b/modules/identityserver/Volo.Abp.IdentityServer.sln.DotSettings new file mode 100644 index 0000000000..39a2d2cfaa --- /dev/null +++ b/modules/identityserver/Volo.Abp.IdentityServer.sln.DotSettings @@ -0,0 +1,7 @@ + + True + D:\github\abp\common.DotSettings + ..\..\..\common.DotSettings + True + 1 + \ No newline at end of file diff --git a/modules/permission-management/Volo.Abp.PermissionManagement.sln.DotSettings b/modules/permission-management/Volo.Abp.PermissionManagement.sln.DotSettings new file mode 100644 index 0000000000..b301a23053 --- /dev/null +++ b/modules/permission-management/Volo.Abp.PermissionManagement.sln.DotSettings @@ -0,0 +1,7 @@ + + True + D:\github\abp\common.DotSettings + ..\..\..\common.DotSettings + True + 1 + \ No newline at end of file diff --git a/modules/setting-management/Volo.Abp.SettingManagement.sln.DotSettings b/modules/setting-management/Volo.Abp.SettingManagement.sln.DotSettings new file mode 100644 index 0000000000..c01a440181 --- /dev/null +++ b/modules/setting-management/Volo.Abp.SettingManagement.sln.DotSettings @@ -0,0 +1,7 @@ + + True + D:\github\abp\common.DotSettings + ..\..\..\common.DotSettings + True + 1 + \ No newline at end of file diff --git a/modules/tenant-management/Volo.Abp.TenantManagement.sln.DotSettings b/modules/tenant-management/Volo.Abp.TenantManagement.sln.DotSettings new file mode 100644 index 0000000000..47d731a6fd --- /dev/null +++ b/modules/tenant-management/Volo.Abp.TenantManagement.sln.DotSettings @@ -0,0 +1,7 @@ + + True + D:\github\abp\common.DotSettings + ..\..\..\common.DotSettings + True + 1 + \ No newline at end of file diff --git a/modules/users/Volo.Abp.Users.sln.DotSettings b/modules/users/Volo.Abp.Users.sln.DotSettings new file mode 100644 index 0000000000..05bef5f511 --- /dev/null +++ b/modules/users/Volo.Abp.Users.sln.DotSettings @@ -0,0 +1,7 @@ + + True + D:\github\abp\common.DotSettings + ..\..\..\common.DotSettings + True + 1 + \ No newline at end of file diff --git a/templates/module/MyCompanyName.MyProjectName.sln.DotSettings b/templates/module/MyCompanyName.MyProjectName.sln.DotSettings new file mode 100644 index 0000000000..836e6ed4da --- /dev/null +++ b/templates/module/MyCompanyName.MyProjectName.sln.DotSettings @@ -0,0 +1,7 @@ + + True + D:\github\abp\common.DotSettings + ..\..\..\common.DotSettings + True + 1 + \ No newline at end of file diff --git a/templates/mvc/MyCompanyName.MyProjectName.sln.DotSettings b/templates/mvc/MyCompanyName.MyProjectName.sln.DotSettings new file mode 100644 index 0000000000..b89df7b544 --- /dev/null +++ b/templates/mvc/MyCompanyName.MyProjectName.sln.DotSettings @@ -0,0 +1,7 @@ + + True + D:\github\abp\common.DotSettings + ..\..\..\common.DotSettings + True + 1 + \ No newline at end of file diff --git a/templates/service/MyCompanyName.MyProjectName.sln.DotSettings b/templates/service/MyCompanyName.MyProjectName.sln.DotSettings new file mode 100644 index 0000000000..eaa1dba027 --- /dev/null +++ b/templates/service/MyCompanyName.MyProjectName.sln.DotSettings @@ -0,0 +1,7 @@ + + True + D:\github\abp\common.DotSettings + ..\..\..\common.DotSettings + True + 1 + \ No newline at end of file From b0cf0352ac1d2f6dba931b267ddc0a28244f9f29 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Thu, 20 Dec 2018 16:43:41 +0300 Subject: [PATCH 096/368] #418 Caching documents. --- .../Docs/Documents/ContentWithDetailsDto.cs | 2 + .../Docs/Documents/DocumentResourceDto.cs | 3 ++ .../Volo/Docs/Projects/ProjectDto.cs | 1 + .../Volo/Docs/Documents/DocumentAppService.cs | 46 ++++++++++++++++--- .../Volo/Docs/Projects/ProjectAppService.cs | 2 +- .../Volo.Docs.Domain/Volo.Docs.Domain.csproj | 1 + .../GitHub/Documents/GithubDocumentStore.cs | 6 +-- 7 files changed, 50 insertions(+), 11 deletions(-) diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/ContentWithDetailsDto.cs b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/ContentWithDetailsDto.cs index e59bf0e357..67819d6ba2 100644 --- a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/ContentWithDetailsDto.cs +++ b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/ContentWithDetailsDto.cs @@ -1,7 +1,9 @@ +using System; using Volo.Docs.Projects; namespace Volo.Docs.Documents { + [Serializable] public class DocumentWithDetailsDto { public string Title { get; set; } diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/DocumentResourceDto.cs b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/DocumentResourceDto.cs index bd09ba0e25..439409dd09 100644 --- a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/DocumentResourceDto.cs +++ b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/DocumentResourceDto.cs @@ -1,5 +1,8 @@ +using System; + namespace Volo.Docs.Documents { + [Serializable] public class DocumentResourceDto { public byte[] Content { get; set; } diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/ProjectDto.cs b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/ProjectDto.cs index 2f12ecc2e6..a29ea840b3 100644 --- a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/ProjectDto.cs +++ b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/ProjectDto.cs @@ -3,6 +3,7 @@ using Volo.Abp.Application.Dtos; namespace Volo.Docs.Projects { + [Serializable] public class ProjectDto : EntityDto { public string Name { get; set; } diff --git a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs index 4b12777fdb..3e68004b87 100644 --- a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs +++ b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs @@ -1,5 +1,8 @@ +using System; using System.Threading.Tasks; +using Microsoft.Extensions.Caching.Distributed; using Volo.Abp.Application.Services; +using Volo.Abp.Caching; using Volo.Docs.Projects; namespace Volo.Docs.Documents @@ -8,13 +11,19 @@ namespace Volo.Docs.Documents { private readonly IProjectRepository _projectRepository; private readonly IDocumentStoreFactory _documentStoreFactory; + protected IDistributedCache DocumentCache { get; } + protected IDistributedCache ResourceCache { get; } public DocumentAppService( IProjectRepository projectRepository, - IDocumentStoreFactory documentStoreFactory) + IDocumentStoreFactory documentStoreFactory, + IDistributedCache documentCache, + IDistributedCache resourceCache) { _projectRepository = projectRepository; _documentStoreFactory = documentStoreFactory; + DocumentCache = documentCache; + ResourceCache = resourceCache; } public virtual async Task GetAsync(GetDocumentInput input) @@ -53,11 +62,22 @@ namespace Volo.Docs.Documents public async Task GetResourceAsync(GetDocumentResourceInput input) { var project = await _projectRepository.GetAsync(input.ProjectId); - var store = _documentStoreFactory.Create(project.DocumentStoreType); + var cacheKey = $"Resource@{project.ShortName}#{input.Name}#{input.Version}"; - var documentResource = await store.GetResource(project, input.Name, input.Version); + return await ResourceCache.GetOrAddAsync( + cacheKey, + async () => + { + var store = _documentStoreFactory.Create(project.DocumentStoreType); + var documentResource = await store.GetResource(project, input.Name, input.Version); - return ObjectMapper.Map(documentResource); + return ObjectMapper.Map(documentResource); + }, + () => new DistributedCacheEntryOptions + { + SlidingExpiration = TimeSpan.FromMinutes(30) //TODO: Configurable? + } + ); } protected virtual async Task GetDocumentWithDetailsDto( @@ -65,10 +85,22 @@ namespace Volo.Docs.Documents string documentName, string version) { - var store = _documentStoreFactory.Create(project.DocumentStoreType); - var document = await store.GetDocument(project, documentName, version); + var cacheKey = $"Document@{project.ShortName}#{documentName}#{version}"; + + return await DocumentCache.GetOrAddAsync( + cacheKey, + async () => + { + var store = _documentStoreFactory.Create(project.DocumentStoreType); + var document = await store.GetDocument(project, documentName, version); - return CreateDocumentWithDetailsDto(project, document); + return CreateDocumentWithDetailsDto(project, document); + }, + () => new DistributedCacheEntryOptions + { + SlidingExpiration = TimeSpan.FromMinutes(30) //TODO: Configurable? + } + ); } protected virtual DocumentWithDetailsDto CreateDocumentWithDetailsDto(Project project, Document document) diff --git a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs index dd8cdae909..34f5956980 100644 --- a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs +++ b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs @@ -51,7 +51,7 @@ namespace Volo.Docs.Projects () => GetVersionsAsync(project), () => new DistributedCacheEntryOptions { - SlidingExpiration = TimeSpan.FromSeconds(2) + SlidingExpiration = TimeSpan.FromMinutes(60) //TODO: Configurable? } ); diff --git a/modules/docs/src/Volo.Docs.Domain/Volo.Docs.Domain.csproj b/modules/docs/src/Volo.Docs.Domain/Volo.Docs.Domain.csproj index ac37f6eebc..f8143caa2f 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo.Docs.Domain.csproj +++ b/modules/docs/src/Volo.Docs.Domain/Volo.Docs.Domain.csproj @@ -24,6 +24,7 @@ + diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentStore.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentStore.cs index 6742c5adb5..04b6f0278b 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentStore.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentStore.cs @@ -15,7 +15,7 @@ using Project = Volo.Docs.Projects.Project; namespace Volo.Docs.GitHub.Documents { - //TODO: Needs refactoring + //TODO: Needs more refactoring public class GithubDocumentStore : DomainService, IDocumentStore { @@ -46,7 +46,7 @@ namespace Volo.Docs.GitHub.Documents LocalDirectory = localDirectory, FileName = fileName, Version = version, - Content = await DownloadWebContentAsync(rawDocumentUrl, project.GetGitHubAccessTokenOrNull()) + Content = await DownloadWebContentAsStringAsync(rawDocumentUrl, project.GetGitHubAccessTokenOrNull()) }; } @@ -136,7 +136,7 @@ namespace Volo.Docs.GitHub.Documents } } - private async Task DownloadWebContentAsync(string rawUrl, string token) + private async Task DownloadWebContentAsStringAsync(string rawUrl, string token) { try { From c07870317bd53ff39c781e807cdbfdbe4826017f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arma=C4=9Fan=20=C3=9Cnl=C3=BC?= <36102404+armgnunlu@users.noreply.github.com> Date: Thu, 20 Dec 2018 16:45:45 +0300 Subject: [PATCH 097/368] Avoiding break of style on pages with big texts #646 - Fixed (merged) --- .../Pages/Documents/Shared/Scripts/vs.js | 19 ++++++++++++++++--- .../Pages/Documents/Shared/Styles/vs.css | 2 +- .../Pages/Documents/Shared/Styles/vs.min.css | 2 +- .../Pages/Documents/Shared/Styles/vs.scss | 2 +- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Scripts/vs.js b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Scripts/vs.js index 482e50700d..473326d3b8 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Scripts/vs.js +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Scripts/vs.js @@ -35,6 +35,8 @@ }); $(document).ready(function () { + handleCustomScrolls(); + var $myNav = $("#docs-sticky-index"); Toc.init($myNav); $("body").scrollspy({ @@ -57,7 +59,6 @@ $(".toggle-row").slideToggle(400); $(this).toggleClass("less"); }); - $(".close-mmenu").on("click", function () { $(".navbar-collapse").removeClass("show"); }); @@ -65,7 +66,15 @@ $(".open-dmenu").on("click", function () { $(".docs-tree-list").slideToggle(); }); + }); + $(window).resize(function () { + handleCustomScrolls(); + }); + }); + function handleCustomScrolls() { + var wWidth = $(window).width(); + if (wWidth > 766) { $("#sidebar-scroll").mCustomScrollbar({ theme: "minimal" }); @@ -73,9 +82,13 @@ $("#scroll-index").mCustomScrollbar({ theme: "minimal-dark" }); - }); - }); + //$(".docs-text-field").mCustomScrollbar({ + // axis: "xy", + // theme: "minimal" + //}); + } + } window.Toc.helpers.createNavList = function () { return $(''); }; diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.css b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.css index 1ef27ea55e..b4a1abdb40 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.css +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.css @@ -171,7 +171,7 @@ .docs-page .docs-content .docs-text-field { padding: 2rem; } .docs-page .docs-content article.docs-body h1 { - padding-top: 2rem; + padding-top: 1rem; font-size: 2.25rem; padding-bottom: 10px; } .docs-page .docs-content article.docs-body h2 { diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.min.css b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.min.css index b766e165d1..225d720609 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.min.css +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.min.css @@ -1 +1 @@ -body{position:relative;}.docs-page{background:#f5f7f9;}.docs-page .anchorjs-link{transition:all .25s linear;}.docs-page *:hover>.anchorjs-link{margin-left:-1.125em !important;transition:color .25s linear;color:#808080;}.docs-page .anchorjs-link:hover{color:#007bff;text-decoration:none;}.docs-page .docs-sidebar{background:#f5f7f9;padding-right:1rem;position:relative;top:0;left:0;position:fixed;}.docs-page .docs-sidebar .docs-sidebar-wrapper{width:270px;float:right;}.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control{background:none;padding-left:36px;width:100%;background:#e9ecef;border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:focus,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:active,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:hover,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:visited{box-shadow:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version{position:relative;padding:0 1rem;margin:.5rem 0 1rem;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select{border-radius:8px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select .input-group-text{border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control{line-height:1;border-top-left-radius:0;border-bottom-left-radius:0;padding:.3em .5em .5em;border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:focus,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:active,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:hover,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:visited{box-shadow:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter{position:relative;padding:0 1rem;margin:.5rem 0;font-size:.9em;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon{position:absolute;top:0;padding:8px 10px;line-height:1;left:16px;background:none;padding:.375rem .75rem;font-size:1rem;line-height:1.5;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon i.fa{color:#ddd;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{height:100vh;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list>ul{display:block;height:calc(100vh - 210px);}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul{font-size:.935em;list-style:none;padding:0 1rem;margin:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li{margin-left:0;padding-left:24px;display:block;width:100%;position:relative;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a{color:#999;font-weight:700;padding:7px 0;display:block;border-bottom:1px solid #eeeff3;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a:hover{color:#000;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a.last-link{top:11px;color:#aaa;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li span.tree-toggle{color:#999;padding:7px 0;display:block;border-bottom:1px solid #eeeff3;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon{font-size:.85em;transition:.3s;width:18px;height:18px;text-align:center;padding:0;line-height:1;border-radius:50%;margin-right:4px;position:absolute;left:2px;top:11px;color:#aaa;cursor:default;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon .fa-long-arrow-right.no-link{color:#555;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon .fa-chevron-right{cursor:pointer;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li a{font-weight:400;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul li a{font-weight:300;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a{color:#000;transition:.4s;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>span .fa{transform:rotate(90deg);color:#007bff;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree.last-link>span .fa{transform:rotate(0deg);}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:1.5rem;color:#000;font-weight:700;padding:20px 0 10px;line-height:1;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand strong{font-weight:300;text-transform:uppercase;font-size:.9rem;opacity:.6;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site{color:#000;opacity:.15;transition:.4s;font-size:.75rem;font-weight:300;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site:hover{text-decoration:none;opacity:.5;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:.85em;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc strong{display:block;}.docs-page .docs-content{overflow-x:scroll;}.docs-page .docs-content .docs-link-btns{border-bottom:1px solid #f4f5f7;background:#fdfdfd;padding:10px 20px;margin:0 -15px;text-align:right;font-size:.8em;}.docs-page .docs-content .docs-link-btns a{color:#999;}.docs-page .docs-content .docs-link-btns a:hover{color:#444;text-decoration:none;}.docs-page .docs-content .docs-text-field{padding:2rem;}.docs-page .docs-content article.docs-body h1{padding-top:2rem;font-size:2.25rem;padding-bottom:10px;}.docs-page .docs-content article.docs-body h2{padding-top:2rem;padding-bottom:10px;font-size:2rem;}.docs-page .docs-content article.docs-body h3,.docs-page .docs-content article.docs-body h4,.docs-page .docs-content article.docs-body h5,.docs-page .docs-content article.docs-body h6{padding-top:20px;padding-bottom:5px;font-size:1.5rem;}.docs-page .docs-content article.docs-body h1,.docs-page .docs-content article.docs-body h2,.docs-page .docs-content article.docs-body h3,.docs-page .docs-content article.docs-body h4,.docs-page .docs-content article.docs-body h5,.docs-page .docs-content article.docs-body h6{position:relative;}.docs-page .docs-content article.docs-body h1 .anchor,.docs-page .docs-content article.docs-body h2 .anchor,.docs-page .docs-content article.docs-body h3 .anchor,.docs-page .docs-content article.docs-body h4 .anchor,.docs-page .docs-content article.docs-body h5 .anchor,.docs-page .docs-content article.docs-body h6 .anchor{position:absolute;right:-26px;font-size:18px;bottom:5px;color:#999;opacity:0;transition:.5s;}.docs-page .docs-content article.docs-body h1:hover .anchor,.docs-page .docs-content article.docs-body h2:hover .anchor,.docs-page .docs-content article.docs-body h3:hover .anchor,.docs-page .docs-content article.docs-body h4:hover .anchor,.docs-page .docs-content article.docs-body h5:hover .anchor,.docs-page .docs-content article.docs-body h6:hover .anchor{opacity:1;}.docs-page .docs-content article.docs-body img{max-width:100%;border:1px solid #f4f5f7;margin:15px 0 25px;box-shadow:0 0 45px #f8f9fa;border-radius:6px;}.docs-page .docs-page-index{min-height:100vh;}.docs-page .docs-page-index #scroll-index{max-height:100vh;}.docs-page .docs-page-index .docs-inner-anchors{position:fixed;top:0;padding:10px;font-size:.9em;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills{font-size:.92em;margin-left:15px;border-left:1px solid #eee;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link{padding:3px 14px 4px;color:#aaa;line-height:1.2;position:relative;border-left:1px solid #eee;border-radius:0;margin-left:-1px;margin-top:1px;margin-bottom:1px;transition:.2s;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link.active{border-left:2px solid #007bff;background:none;color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-link.active{color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-pills .nav-link.active{color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .index-scroll{margin-left:-30px;}.docs-page .docs-page-index .docs-inner-anchors .docs-anchors-wrapper{max-width:300px;float:left;}.docs-page .docs-page-index .scroll-top-btn{display:none;font-size:.85em;color:#aaa;text-decoration:none;padding-left:18px;}.docs-page .docs-page-index .scroll-top-btn.showup{display:block;}@media(min-width:1100px){.container{max-width:1080px;}.docs-page .docs-sidebar.dark-sidebar{background:#191919;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control{background:#333;border-color:#333;color:#999;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-version .version-select label{background:#444;border-color:#444;color:#ddd;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter .form-control{background:#333;color:#999;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter select{border:0;border-radius:6px;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon i.fa{color:#aaa;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a{color:#aaa;border-bottom:1px solid #333;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a:hover{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon{font-size:.85em;transition:.3s;width:18px;height:18px;text-align:center;padding:0;line-height:1;border-radius:50%;margin-right:4px;position:absolute;left:2px;top:11px;color:#aaa;cursor:default;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon .fa-long-arrow-right.no-link{color:#555;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon .fa-chevron-right{cursor:pointer;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon.last-link{top:11px;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li span.tree-toggle{color:#555;padding:7px 0;display:block;border-bottom:1px solid #333;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a{color:#fff;transition:.4s;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a span .fa{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a span:not(.last-link) .fa{transform:rotate(90deg);color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .navbar-brand{color:#fff;text-transform:uppercase;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .go-back-site{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .navbar-logo-desc{color:#ddd;}}@media(min-width:1366px){.container{max-width:1340px;}}@media(min-width:1440px){.container{max-width:1400px;}}@media(max-width:767px){.docs-page .docs-content article.docs-body h1{padding-top:1.5rem;}.docs-page{background:#f5f7f9;}.docs-page>.container-fluid{display:block;}.docs-page>.container-fluid>.row{display:block;}.docs-page .docs-sidebar{position:fixed;max-width:100%;width:100%;display:block;padding:0 !important;top:0;left:0;z-index:100;right:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper{max-width:100%;width:100%;top:0;position:relative;margin:0 !important;height:72px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{padding:.5rem 1.5rem 2rem 1.5rem;position:fixed;top:70px;font-size:17px;left:0;width:100%;z-index:100;background:#f5f7f9;display:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-filter{position:relative;padding:0 0 1rem !important;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-filter .filter-icon{left:0;}.docs-page .docs-sidebar .docs-top .navbar-logo{padding:0;padding-top:.3rem;display:block;text-align:center;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:1.5rem;font-weight:700;display:block;margin-right:0;padding:7px 0 10px;text-transform:uppercase;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand .docs-logo{width:110px;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site{display:none;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:1em;display:none;}.docs-page .docs-sidebar .docs-top .open-dmenu{position:absolute;top:10px;left:20px;}.docs-page .docs-content{padding-top:72px;max-width:100%;display:block !important;}.docs-page .docs-content .docs-text-field{padding:1rem 1.5rem;}.docs-page .docs-page-index{display:none;}}.for-mobile{display:none;}.for-desktop{display:inline-block;}pre[class*="language-"]{padding:1.4em 2em !important;margin:15px 0 25px !important;border-radius:6px;}code{padding:.2em .4em;margin:0;font-size:82%;background-color:#f0f1f3;border-radius:3px;color:#28a745;}pre code{padding:0;}pre .token.keyword{color:#569cd6;}pre .token.atrule,pre .token.attr-value,pre .token.function,pre .token.class-name{color:#d69d85;}:not(pre)>code[class*="language-"],pre[class*="language-"]{background:#191919 !important;}div.code-toolbar>.toolbar span{cursor:default;}div.code-toolbar>.toolbar a{cursor:copy;}@media(max-width:767px){body{font-size:14px;}.for-mobile{display:inline-block;}.for-desktop{display:none;}.close-mmenu,.close-dmenu{position:absolute;top:-78px;left:25px;color:#fff;font-size:68px;background:#fff;opacity:0;}.navbar{padding:.5rem 1.75rem;}.navbar .navbar-collapse{background:#38003d;position:fixed;top:86px;left:0;width:100%;height:100vh;height:calc(100vh - 86px);z-index:100 !important;}.navbar .navbar-collapse .navbar-nav{height:100vh;padding:20px 30px;overflow:auto;}.navbar .navbar-collapse .navbar-nav .nav-link{padding:1.2rem !important;}.navbar .navbar-toggler{padding:.5rem .75rem;font-size:1.5rem;line-height:1;background-color:transparent;border:0;border-radius:.25rem;color:#fff !important;margin-left:-1rem;}.section-with-logos img{margin:15px;opacity:1;-webkit-filter:grayscale(0%);filter:grayscale(0%);}span.code-arrow{padding:0 0 0;display:block;transform:rotate(90deg);font-size:2em;}.mb-5,.my-5{margin-bottom:2rem !important;}} \ No newline at end of file +body{position:relative;}.docs-page{background:#f5f7f9;}.docs-page .anchorjs-link{transition:all .25s linear;}.docs-page *:hover>.anchorjs-link{margin-left:-1.125em !important;transition:color .25s linear;color:#808080;}.docs-page .anchorjs-link:hover{color:#007bff;text-decoration:none;}.docs-page .docs-sidebar{background:#f5f7f9;padding-right:1rem;position:relative;top:0;left:0;position:fixed;}.docs-page .docs-sidebar .docs-sidebar-wrapper{width:270px;float:right;}.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control{background:none;padding-left:36px;width:100%;background:#e9ecef;border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:focus,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:active,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:hover,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:visited{box-shadow:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version{position:relative;padding:0 1rem;margin:.5rem 0 1rem;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select{border-radius:8px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select .input-group-text{border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control{line-height:1;border-top-left-radius:0;border-bottom-left-radius:0;padding:.3em .5em .5em;border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:focus,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:active,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:hover,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:visited{box-shadow:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter{position:relative;padding:0 1rem;margin:.5rem 0;font-size:.9em;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon{position:absolute;top:0;padding:8px 10px;line-height:1;left:16px;background:none;padding:.375rem .75rem;font-size:1rem;line-height:1.5;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon i.fa{color:#ddd;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{height:100vh;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list>ul{display:block;height:calc(100vh - 210px);}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul{font-size:.935em;list-style:none;padding:0 1rem;margin:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li{margin-left:0;padding-left:24px;display:block;width:100%;position:relative;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a{color:#999;font-weight:700;padding:7px 0;display:block;border-bottom:1px solid #eeeff3;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a:hover{color:#000;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a.last-link{top:11px;color:#aaa;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li span.tree-toggle{color:#999;padding:7px 0;display:block;border-bottom:1px solid #eeeff3;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon{font-size:.85em;transition:.3s;width:18px;height:18px;text-align:center;padding:0;line-height:1;border-radius:50%;margin-right:4px;position:absolute;left:2px;top:11px;color:#aaa;cursor:default;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon .fa-long-arrow-right.no-link{color:#555;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon .fa-chevron-right{cursor:pointer;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li a{font-weight:400;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul li a{font-weight:300;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a{color:#000;transition:.4s;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>span .fa{transform:rotate(90deg);color:#007bff;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree.last-link>span .fa{transform:rotate(0deg);}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:1.5rem;color:#000;font-weight:700;padding:20px 0 10px;line-height:1;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand strong{font-weight:300;text-transform:uppercase;font-size:.9rem;opacity:.6;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site{color:#000;opacity:.15;transition:.4s;font-size:.75rem;font-weight:300;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site:hover{text-decoration:none;opacity:.5;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:.85em;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc strong{display:block;}.docs-page .docs-content{overflow-x:scroll;}.docs-page .docs-content .docs-link-btns{border-bottom:1px solid #f4f5f7;background:#fdfdfd;padding:10px 20px;margin:0 -15px;text-align:right;font-size:.8em;}.docs-page .docs-content .docs-link-btns a{color:#999;}.docs-page .docs-content .docs-link-btns a:hover{color:#444;text-decoration:none;}.docs-page .docs-content .docs-text-field{padding:2rem;}.docs-page .docs-content article.docs-body h1{padding-top:1rem;font-size:2.25rem;padding-bottom:10px;}.docs-page .docs-content article.docs-body h2{padding-top:2rem;padding-bottom:10px;font-size:2rem;}.docs-page .docs-content article.docs-body h3,.docs-page .docs-content article.docs-body h4,.docs-page .docs-content article.docs-body h5,.docs-page .docs-content article.docs-body h6{padding-top:20px;padding-bottom:5px;font-size:1.5rem;}.docs-page .docs-content article.docs-body h1,.docs-page .docs-content article.docs-body h2,.docs-page .docs-content article.docs-body h3,.docs-page .docs-content article.docs-body h4,.docs-page .docs-content article.docs-body h5,.docs-page .docs-content article.docs-body h6{position:relative;}.docs-page .docs-content article.docs-body h1 .anchor,.docs-page .docs-content article.docs-body h2 .anchor,.docs-page .docs-content article.docs-body h3 .anchor,.docs-page .docs-content article.docs-body h4 .anchor,.docs-page .docs-content article.docs-body h5 .anchor,.docs-page .docs-content article.docs-body h6 .anchor{position:absolute;right:-26px;font-size:18px;bottom:5px;color:#999;opacity:0;transition:.5s;}.docs-page .docs-content article.docs-body h1:hover .anchor,.docs-page .docs-content article.docs-body h2:hover .anchor,.docs-page .docs-content article.docs-body h3:hover .anchor,.docs-page .docs-content article.docs-body h4:hover .anchor,.docs-page .docs-content article.docs-body h5:hover .anchor,.docs-page .docs-content article.docs-body h6:hover .anchor{opacity:1;}.docs-page .docs-content article.docs-body img{max-width:100%;border:1px solid #f4f5f7;margin:15px 0 25px;box-shadow:0 0 45px #f8f9fa;border-radius:6px;}.docs-page .docs-page-index{min-height:100vh;}.docs-page .docs-page-index #scroll-index{max-height:100vh;}.docs-page .docs-page-index .docs-inner-anchors{position:fixed;top:0;padding:10px;font-size:.9em;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills{font-size:.92em;margin-left:15px;border-left:1px solid #eee;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link{padding:3px 14px 4px;color:#aaa;line-height:1.2;position:relative;border-left:1px solid #eee;border-radius:0;margin-left:-1px;margin-top:1px;margin-bottom:1px;transition:.2s;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link.active{border-left:2px solid #007bff;background:none;color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-link.active{color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-pills .nav-link.active{color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .index-scroll{margin-left:-30px;}.docs-page .docs-page-index .docs-inner-anchors .docs-anchors-wrapper{max-width:300px;float:left;}.docs-page .docs-page-index .scroll-top-btn{display:none;font-size:.85em;color:#aaa;text-decoration:none;padding-left:18px;}.docs-page .docs-page-index .scroll-top-btn.showup{display:block;}@media(min-width:1100px){.container{max-width:1080px;}.docs-page .docs-sidebar.dark-sidebar{background:#191919;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control{background:#333;border-color:#333;color:#999;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-version .version-select label{background:#444;border-color:#444;color:#ddd;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter .form-control{background:#333;color:#999;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter select{border:0;border-radius:6px;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon i.fa{color:#aaa;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a{color:#aaa;border-bottom:1px solid #333;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a:hover{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon{font-size:.85em;transition:.3s;width:18px;height:18px;text-align:center;padding:0;line-height:1;border-radius:50%;margin-right:4px;position:absolute;left:2px;top:11px;color:#aaa;cursor:default;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon .fa-long-arrow-right.no-link{color:#555;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon .fa-chevron-right{cursor:pointer;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon.last-link{top:11px;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li span.tree-toggle{color:#555;padding:7px 0;display:block;border-bottom:1px solid #333;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a{color:#fff;transition:.4s;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a span .fa{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a span:not(.last-link) .fa{transform:rotate(90deg);color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .navbar-brand{color:#fff;text-transform:uppercase;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .go-back-site{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .navbar-logo-desc{color:#ddd;}}@media(min-width:1366px){.container{max-width:1340px;}}@media(min-width:1440px){.container{max-width:1400px;}}@media(max-width:767px){.docs-page .docs-content article.docs-body h1{padding-top:1.5rem;}.docs-page{background:#f5f7f9;}.docs-page>.container-fluid{display:block;}.docs-page>.container-fluid>.row{display:block;}.docs-page .docs-sidebar{position:fixed;max-width:100%;width:100%;display:block;padding:0 !important;top:0;left:0;z-index:100;right:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper{max-width:100%;width:100%;top:0;position:relative;margin:0 !important;height:72px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{padding:.5rem 1.5rem 2rem 1.5rem;position:fixed;top:70px;font-size:17px;left:0;width:100%;z-index:100;background:#f5f7f9;display:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-filter{position:relative;padding:0 0 1rem !important;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-filter .filter-icon{left:0;}.docs-page .docs-sidebar .docs-top .navbar-logo{padding:0;padding-top:.3rem;display:block;text-align:center;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:1.5rem;font-weight:700;display:block;margin-right:0;padding:7px 0 10px;text-transform:uppercase;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand .docs-logo{width:110px;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site{display:none;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:1em;display:none;}.docs-page .docs-sidebar .docs-top .open-dmenu{position:absolute;top:10px;left:20px;}.docs-page .docs-content{padding-top:72px;max-width:100%;display:block !important;}.docs-page .docs-content .docs-text-field{padding:1rem 1.5rem;}.docs-page .docs-page-index{display:none;}}.for-mobile{display:none;}.for-desktop{display:inline-block;}pre[class*="language-"]{padding:1.4em 2em !important;margin:15px 0 25px !important;border-radius:6px;}code{padding:.2em .4em;margin:0;font-size:82%;background-color:#f0f1f3;border-radius:3px;color:#28a745;}pre code{padding:0;}pre .token.keyword{color:#569cd6;}pre .token.atrule,pre .token.attr-value,pre .token.function,pre .token.class-name{color:#d69d85;}:not(pre)>code[class*="language-"],pre[class*="language-"]{background:#191919 !important;}div.code-toolbar>.toolbar span{cursor:default;}div.code-toolbar>.toolbar a{cursor:copy;}@media(max-width:767px){body{font-size:14px;}.for-mobile{display:inline-block;}.for-desktop{display:none;}.close-mmenu,.close-dmenu{position:absolute;top:-78px;left:25px;color:#fff;font-size:68px;background:#fff;opacity:0;}.navbar{padding:.5rem 1.75rem;}.navbar .navbar-collapse{background:#38003d;position:fixed;top:86px;left:0;width:100%;height:100vh;height:calc(100vh - 86px);z-index:100 !important;}.navbar .navbar-collapse .navbar-nav{height:100vh;padding:20px 30px;overflow:auto;}.navbar .navbar-collapse .navbar-nav .nav-link{padding:1.2rem !important;}.navbar .navbar-toggler{padding:.5rem .75rem;font-size:1.5rem;line-height:1;background-color:transparent;border:0;border-radius:.25rem;color:#fff !important;margin-left:-1rem;}.section-with-logos img{margin:15px;opacity:1;-webkit-filter:grayscale(0%);filter:grayscale(0%);}span.code-arrow{padding:0 0 0;display:block;transform:rotate(90deg);font-size:2em;}.mb-5,.my-5{margin-bottom:2rem !important;}} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.scss b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.scss index 498ab9f249..5d6ba28c87 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.scss +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.scss @@ -285,7 +285,7 @@ body { article.docs-body { h1 { - padding-top: 2rem; + padding-top: 1rem; font-size: 2.25rem; padding-bottom: 10px; } From 0a7975eef13413ed24e60c48699d495b5d9c304e Mon Sep 17 00:00:00 2001 From: Nokecy Date: Thu, 20 Dec 2018 21:53:02 +0800 Subject: [PATCH 098/368] ProfileController Should inherit AbpController --- .../Volo/Abp/Identity/ProfileController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/ProfileController.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/ProfileController.cs index 449383956b..30f356cac4 100644 --- a/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/ProfileController.cs +++ b/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/ProfileController.cs @@ -9,7 +9,7 @@ namespace Volo.Abp.Identity [RemoteService] [Area("identity")] [ControllerName("Profile")] - public class ProfileController : IProfileAppService + public class ProfileController : AbpController, IProfileAppService { private readonly IProfileAppService _profileAppService; From 0540f9d3a84d701aa9199550f70d2b8f77972c28 Mon Sep 17 00:00:00 2001 From: Nokecy Date: Thu, 20 Dec 2018 21:55:34 +0800 Subject: [PATCH 099/368] Update ProfileController.cs --- .../Volo/Abp/Identity/ProfileController.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/ProfileController.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/ProfileController.cs index 30f356cac4..b1bb8a744c 100644 --- a/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/ProfileController.cs +++ b/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/ProfileController.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; namespace Volo.Abp.Identity { From d7e9916f17805a9add2c7409475460ed82c2674c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arma=C4=9Fan=20=C3=9Cnl=C3=BC?= <36102404+armgnunlu@users.noreply.github.com> Date: Thu, 20 Dec 2018 17:06:17 +0300 Subject: [PATCH 100/368] Docs mobile scroll bug - Fixed --- .../src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.css | 3 ++- .../Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.min.css | 2 +- .../Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.scss | 7 ++++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.css b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.css index b4a1abdb40..37241a8388 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.css +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.css @@ -67,7 +67,8 @@ height: 100vh; } .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list > ul { display: block; - height: calc(100vh - 210px); } + height: calc(100vh - 220px); + overflow-y: auto; } .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul { font-size: .935em; list-style: none; diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.min.css b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.min.css index 225d720609..9386497044 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.min.css +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.min.css @@ -1 +1 @@ -body{position:relative;}.docs-page{background:#f5f7f9;}.docs-page .anchorjs-link{transition:all .25s linear;}.docs-page *:hover>.anchorjs-link{margin-left:-1.125em !important;transition:color .25s linear;color:#808080;}.docs-page .anchorjs-link:hover{color:#007bff;text-decoration:none;}.docs-page .docs-sidebar{background:#f5f7f9;padding-right:1rem;position:relative;top:0;left:0;position:fixed;}.docs-page .docs-sidebar .docs-sidebar-wrapper{width:270px;float:right;}.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control{background:none;padding-left:36px;width:100%;background:#e9ecef;border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:focus,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:active,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:hover,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:visited{box-shadow:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version{position:relative;padding:0 1rem;margin:.5rem 0 1rem;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select{border-radius:8px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select .input-group-text{border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control{line-height:1;border-top-left-radius:0;border-bottom-left-radius:0;padding:.3em .5em .5em;border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:focus,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:active,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:hover,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:visited{box-shadow:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter{position:relative;padding:0 1rem;margin:.5rem 0;font-size:.9em;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon{position:absolute;top:0;padding:8px 10px;line-height:1;left:16px;background:none;padding:.375rem .75rem;font-size:1rem;line-height:1.5;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon i.fa{color:#ddd;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{height:100vh;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list>ul{display:block;height:calc(100vh - 210px);}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul{font-size:.935em;list-style:none;padding:0 1rem;margin:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li{margin-left:0;padding-left:24px;display:block;width:100%;position:relative;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a{color:#999;font-weight:700;padding:7px 0;display:block;border-bottom:1px solid #eeeff3;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a:hover{color:#000;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a.last-link{top:11px;color:#aaa;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li span.tree-toggle{color:#999;padding:7px 0;display:block;border-bottom:1px solid #eeeff3;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon{font-size:.85em;transition:.3s;width:18px;height:18px;text-align:center;padding:0;line-height:1;border-radius:50%;margin-right:4px;position:absolute;left:2px;top:11px;color:#aaa;cursor:default;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon .fa-long-arrow-right.no-link{color:#555;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon .fa-chevron-right{cursor:pointer;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li a{font-weight:400;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul li a{font-weight:300;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a{color:#000;transition:.4s;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>span .fa{transform:rotate(90deg);color:#007bff;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree.last-link>span .fa{transform:rotate(0deg);}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:1.5rem;color:#000;font-weight:700;padding:20px 0 10px;line-height:1;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand strong{font-weight:300;text-transform:uppercase;font-size:.9rem;opacity:.6;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site{color:#000;opacity:.15;transition:.4s;font-size:.75rem;font-weight:300;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site:hover{text-decoration:none;opacity:.5;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:.85em;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc strong{display:block;}.docs-page .docs-content{overflow-x:scroll;}.docs-page .docs-content .docs-link-btns{border-bottom:1px solid #f4f5f7;background:#fdfdfd;padding:10px 20px;margin:0 -15px;text-align:right;font-size:.8em;}.docs-page .docs-content .docs-link-btns a{color:#999;}.docs-page .docs-content .docs-link-btns a:hover{color:#444;text-decoration:none;}.docs-page .docs-content .docs-text-field{padding:2rem;}.docs-page .docs-content article.docs-body h1{padding-top:1rem;font-size:2.25rem;padding-bottom:10px;}.docs-page .docs-content article.docs-body h2{padding-top:2rem;padding-bottom:10px;font-size:2rem;}.docs-page .docs-content article.docs-body h3,.docs-page .docs-content article.docs-body h4,.docs-page .docs-content article.docs-body h5,.docs-page .docs-content article.docs-body h6{padding-top:20px;padding-bottom:5px;font-size:1.5rem;}.docs-page .docs-content article.docs-body h1,.docs-page .docs-content article.docs-body h2,.docs-page .docs-content article.docs-body h3,.docs-page .docs-content article.docs-body h4,.docs-page .docs-content article.docs-body h5,.docs-page .docs-content article.docs-body h6{position:relative;}.docs-page .docs-content article.docs-body h1 .anchor,.docs-page .docs-content article.docs-body h2 .anchor,.docs-page .docs-content article.docs-body h3 .anchor,.docs-page .docs-content article.docs-body h4 .anchor,.docs-page .docs-content article.docs-body h5 .anchor,.docs-page .docs-content article.docs-body h6 .anchor{position:absolute;right:-26px;font-size:18px;bottom:5px;color:#999;opacity:0;transition:.5s;}.docs-page .docs-content article.docs-body h1:hover .anchor,.docs-page .docs-content article.docs-body h2:hover .anchor,.docs-page .docs-content article.docs-body h3:hover .anchor,.docs-page .docs-content article.docs-body h4:hover .anchor,.docs-page .docs-content article.docs-body h5:hover .anchor,.docs-page .docs-content article.docs-body h6:hover .anchor{opacity:1;}.docs-page .docs-content article.docs-body img{max-width:100%;border:1px solid #f4f5f7;margin:15px 0 25px;box-shadow:0 0 45px #f8f9fa;border-radius:6px;}.docs-page .docs-page-index{min-height:100vh;}.docs-page .docs-page-index #scroll-index{max-height:100vh;}.docs-page .docs-page-index .docs-inner-anchors{position:fixed;top:0;padding:10px;font-size:.9em;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills{font-size:.92em;margin-left:15px;border-left:1px solid #eee;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link{padding:3px 14px 4px;color:#aaa;line-height:1.2;position:relative;border-left:1px solid #eee;border-radius:0;margin-left:-1px;margin-top:1px;margin-bottom:1px;transition:.2s;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link.active{border-left:2px solid #007bff;background:none;color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-link.active{color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-pills .nav-link.active{color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .index-scroll{margin-left:-30px;}.docs-page .docs-page-index .docs-inner-anchors .docs-anchors-wrapper{max-width:300px;float:left;}.docs-page .docs-page-index .scroll-top-btn{display:none;font-size:.85em;color:#aaa;text-decoration:none;padding-left:18px;}.docs-page .docs-page-index .scroll-top-btn.showup{display:block;}@media(min-width:1100px){.container{max-width:1080px;}.docs-page .docs-sidebar.dark-sidebar{background:#191919;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control{background:#333;border-color:#333;color:#999;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-version .version-select label{background:#444;border-color:#444;color:#ddd;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter .form-control{background:#333;color:#999;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter select{border:0;border-radius:6px;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon i.fa{color:#aaa;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a{color:#aaa;border-bottom:1px solid #333;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a:hover{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon{font-size:.85em;transition:.3s;width:18px;height:18px;text-align:center;padding:0;line-height:1;border-radius:50%;margin-right:4px;position:absolute;left:2px;top:11px;color:#aaa;cursor:default;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon .fa-long-arrow-right.no-link{color:#555;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon .fa-chevron-right{cursor:pointer;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon.last-link{top:11px;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li span.tree-toggle{color:#555;padding:7px 0;display:block;border-bottom:1px solid #333;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a{color:#fff;transition:.4s;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a span .fa{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a span:not(.last-link) .fa{transform:rotate(90deg);color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .navbar-brand{color:#fff;text-transform:uppercase;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .go-back-site{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .navbar-logo-desc{color:#ddd;}}@media(min-width:1366px){.container{max-width:1340px;}}@media(min-width:1440px){.container{max-width:1400px;}}@media(max-width:767px){.docs-page .docs-content article.docs-body h1{padding-top:1.5rem;}.docs-page{background:#f5f7f9;}.docs-page>.container-fluid{display:block;}.docs-page>.container-fluid>.row{display:block;}.docs-page .docs-sidebar{position:fixed;max-width:100%;width:100%;display:block;padding:0 !important;top:0;left:0;z-index:100;right:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper{max-width:100%;width:100%;top:0;position:relative;margin:0 !important;height:72px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{padding:.5rem 1.5rem 2rem 1.5rem;position:fixed;top:70px;font-size:17px;left:0;width:100%;z-index:100;background:#f5f7f9;display:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-filter{position:relative;padding:0 0 1rem !important;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-filter .filter-icon{left:0;}.docs-page .docs-sidebar .docs-top .navbar-logo{padding:0;padding-top:.3rem;display:block;text-align:center;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:1.5rem;font-weight:700;display:block;margin-right:0;padding:7px 0 10px;text-transform:uppercase;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand .docs-logo{width:110px;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site{display:none;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:1em;display:none;}.docs-page .docs-sidebar .docs-top .open-dmenu{position:absolute;top:10px;left:20px;}.docs-page .docs-content{padding-top:72px;max-width:100%;display:block !important;}.docs-page .docs-content .docs-text-field{padding:1rem 1.5rem;}.docs-page .docs-page-index{display:none;}}.for-mobile{display:none;}.for-desktop{display:inline-block;}pre[class*="language-"]{padding:1.4em 2em !important;margin:15px 0 25px !important;border-radius:6px;}code{padding:.2em .4em;margin:0;font-size:82%;background-color:#f0f1f3;border-radius:3px;color:#28a745;}pre code{padding:0;}pre .token.keyword{color:#569cd6;}pre .token.atrule,pre .token.attr-value,pre .token.function,pre .token.class-name{color:#d69d85;}:not(pre)>code[class*="language-"],pre[class*="language-"]{background:#191919 !important;}div.code-toolbar>.toolbar span{cursor:default;}div.code-toolbar>.toolbar a{cursor:copy;}@media(max-width:767px){body{font-size:14px;}.for-mobile{display:inline-block;}.for-desktop{display:none;}.close-mmenu,.close-dmenu{position:absolute;top:-78px;left:25px;color:#fff;font-size:68px;background:#fff;opacity:0;}.navbar{padding:.5rem 1.75rem;}.navbar .navbar-collapse{background:#38003d;position:fixed;top:86px;left:0;width:100%;height:100vh;height:calc(100vh - 86px);z-index:100 !important;}.navbar .navbar-collapse .navbar-nav{height:100vh;padding:20px 30px;overflow:auto;}.navbar .navbar-collapse .navbar-nav .nav-link{padding:1.2rem !important;}.navbar .navbar-toggler{padding:.5rem .75rem;font-size:1.5rem;line-height:1;background-color:transparent;border:0;border-radius:.25rem;color:#fff !important;margin-left:-1rem;}.section-with-logos img{margin:15px;opacity:1;-webkit-filter:grayscale(0%);filter:grayscale(0%);}span.code-arrow{padding:0 0 0;display:block;transform:rotate(90deg);font-size:2em;}.mb-5,.my-5{margin-bottom:2rem !important;}} \ No newline at end of file +body{position:relative;}.docs-page{background:#f5f7f9;}.docs-page .anchorjs-link{transition:all .25s linear;}.docs-page *:hover>.anchorjs-link{margin-left:-1.125em !important;transition:color .25s linear;color:#808080;}.docs-page .anchorjs-link:hover{color:#007bff;text-decoration:none;}.docs-page .docs-sidebar{background:#f5f7f9;padding-right:1rem;position:relative;top:0;left:0;position:fixed;}.docs-page .docs-sidebar .docs-sidebar-wrapper{width:270px;float:right;}.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control{background:none;padding-left:36px;width:100%;background:#e9ecef;border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:focus,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:active,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:hover,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:visited{box-shadow:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version{position:relative;padding:0 1rem;margin:.5rem 0 1rem;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select{border-radius:8px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select .input-group-text{border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control{line-height:1;border-top-left-radius:0;border-bottom-left-radius:0;padding:.3em .5em .5em;border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:focus,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:active,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:hover,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:visited{box-shadow:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter{position:relative;padding:0 1rem;margin:.5rem 0;font-size:.9em;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon{position:absolute;top:0;padding:8px 10px;line-height:1;left:16px;background:none;padding:.375rem .75rem;font-size:1rem;line-height:1.5;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon i.fa{color:#ddd;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{height:100vh;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list>ul{display:block;height:calc(100vh - 220px);overflow-y:auto;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul{font-size:.935em;list-style:none;padding:0 1rem;margin:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li{margin-left:0;padding-left:24px;display:block;width:100%;position:relative;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a{color:#999;font-weight:700;padding:7px 0;display:block;border-bottom:1px solid #eeeff3;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a:hover{color:#000;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a.last-link{top:11px;color:#aaa;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li span.tree-toggle{color:#999;padding:7px 0;display:block;border-bottom:1px solid #eeeff3;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon{font-size:.85em;transition:.3s;width:18px;height:18px;text-align:center;padding:0;line-height:1;border-radius:50%;margin-right:4px;position:absolute;left:2px;top:11px;color:#aaa;cursor:default;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon .fa-long-arrow-right.no-link{color:#555;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon .fa-chevron-right{cursor:pointer;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li a{font-weight:400;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul li a{font-weight:300;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a{color:#000;transition:.4s;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>span .fa{transform:rotate(90deg);color:#007bff;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree.last-link>span .fa{transform:rotate(0deg);}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:1.5rem;color:#000;font-weight:700;padding:20px 0 10px;line-height:1;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand strong{font-weight:300;text-transform:uppercase;font-size:.9rem;opacity:.6;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site{color:#000;opacity:.15;transition:.4s;font-size:.75rem;font-weight:300;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site:hover{text-decoration:none;opacity:.5;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:.85em;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc strong{display:block;}.docs-page .docs-content{overflow-x:scroll;}.docs-page .docs-content .docs-link-btns{border-bottom:1px solid #f4f5f7;background:#fdfdfd;padding:10px 20px;margin:0 -15px;text-align:right;font-size:.8em;}.docs-page .docs-content .docs-link-btns a{color:#999;}.docs-page .docs-content .docs-link-btns a:hover{color:#444;text-decoration:none;}.docs-page .docs-content .docs-text-field{padding:2rem;}.docs-page .docs-content article.docs-body h1{padding-top:1rem;font-size:2.25rem;padding-bottom:10px;}.docs-page .docs-content article.docs-body h2{padding-top:2rem;padding-bottom:10px;font-size:2rem;}.docs-page .docs-content article.docs-body h3,.docs-page .docs-content article.docs-body h4,.docs-page .docs-content article.docs-body h5,.docs-page .docs-content article.docs-body h6{padding-top:20px;padding-bottom:5px;font-size:1.5rem;}.docs-page .docs-content article.docs-body h1,.docs-page .docs-content article.docs-body h2,.docs-page .docs-content article.docs-body h3,.docs-page .docs-content article.docs-body h4,.docs-page .docs-content article.docs-body h5,.docs-page .docs-content article.docs-body h6{position:relative;}.docs-page .docs-content article.docs-body h1 .anchor,.docs-page .docs-content article.docs-body h2 .anchor,.docs-page .docs-content article.docs-body h3 .anchor,.docs-page .docs-content article.docs-body h4 .anchor,.docs-page .docs-content article.docs-body h5 .anchor,.docs-page .docs-content article.docs-body h6 .anchor{position:absolute;right:-26px;font-size:18px;bottom:5px;color:#999;opacity:0;transition:.5s;}.docs-page .docs-content article.docs-body h1:hover .anchor,.docs-page .docs-content article.docs-body h2:hover .anchor,.docs-page .docs-content article.docs-body h3:hover .anchor,.docs-page .docs-content article.docs-body h4:hover .anchor,.docs-page .docs-content article.docs-body h5:hover .anchor,.docs-page .docs-content article.docs-body h6:hover .anchor{opacity:1;}.docs-page .docs-content article.docs-body img{max-width:100%;border:1px solid #f4f5f7;margin:15px 0 25px;box-shadow:0 0 45px #f8f9fa;border-radius:6px;}.docs-page .docs-page-index{min-height:100vh;}.docs-page .docs-page-index #scroll-index{max-height:100vh;}.docs-page .docs-page-index .docs-inner-anchors{position:fixed;top:0;padding:10px;font-size:.9em;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills{font-size:.92em;margin-left:15px;border-left:1px solid #eee;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link{padding:3px 14px 4px;color:#aaa;line-height:1.2;position:relative;border-left:1px solid #eee;border-radius:0;margin-left:-1px;margin-top:1px;margin-bottom:1px;transition:.2s;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link.active{border-left:2px solid #007bff;background:none;color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-link.active{color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-pills .nav-link.active{color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .index-scroll{margin-left:-30px;}.docs-page .docs-page-index .docs-inner-anchors .docs-anchors-wrapper{max-width:300px;float:left;}.docs-page .docs-page-index .scroll-top-btn{display:none;font-size:.85em;color:#aaa;text-decoration:none;padding-left:18px;}.docs-page .docs-page-index .scroll-top-btn.showup{display:block;}@media(min-width:1100px){.container{max-width:1080px;}.docs-page .docs-sidebar.dark-sidebar{background:#191919;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control{background:#333;border-color:#333;color:#999;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-version .version-select label{background:#444;border-color:#444;color:#ddd;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter .form-control{background:#333;color:#999;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter select{border:0;border-radius:6px;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon i.fa{color:#aaa;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a{color:#aaa;border-bottom:1px solid #333;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a:hover{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon{font-size:.85em;transition:.3s;width:18px;height:18px;text-align:center;padding:0;line-height:1;border-radius:50%;margin-right:4px;position:absolute;left:2px;top:11px;color:#aaa;cursor:default;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon .fa-long-arrow-right.no-link{color:#555;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon .fa-chevron-right{cursor:pointer;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon.last-link{top:11px;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li span.tree-toggle{color:#555;padding:7px 0;display:block;border-bottom:1px solid #333;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a{color:#fff;transition:.4s;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a span .fa{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a span:not(.last-link) .fa{transform:rotate(90deg);color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .navbar-brand{color:#fff;text-transform:uppercase;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .go-back-site{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .navbar-logo-desc{color:#ddd;}}@media(min-width:1366px){.container{max-width:1340px;}}@media(min-width:1440px){.container{max-width:1400px;}}@media(max-width:767px){.docs-page .docs-content article.docs-body h1{padding-top:1.5rem;}.docs-page{background:#f5f7f9;}.docs-page>.container-fluid{display:block;}.docs-page>.container-fluid>.row{display:block;}.docs-page .docs-sidebar{position:fixed;max-width:100%;width:100%;display:block;padding:0 !important;top:0;left:0;z-index:100;right:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper{max-width:100%;width:100%;top:0;position:relative;margin:0 !important;height:72px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{padding:.5rem 1.5rem 2rem 1.5rem;position:fixed;top:70px;font-size:17px;left:0;width:100%;z-index:100;background:#f5f7f9;display:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-filter{position:relative;padding:0 0 1rem !important;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-filter .filter-icon{left:0;}.docs-page .docs-sidebar .docs-top .navbar-logo{padding:0;padding-top:.3rem;display:block;text-align:center;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:1.5rem;font-weight:700;display:block;margin-right:0;padding:7px 0 10px;text-transform:uppercase;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand .docs-logo{width:110px;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site{display:none;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:1em;display:none;}.docs-page .docs-sidebar .docs-top .open-dmenu{position:absolute;top:10px;left:20px;}.docs-page .docs-content{padding-top:72px;max-width:100%;display:block !important;}.docs-page .docs-content .docs-text-field{padding:1rem 1.5rem;}.docs-page .docs-page-index{display:none;}}.for-mobile{display:none;}.for-desktop{display:inline-block;}pre[class*="language-"]{padding:1.4em 2em !important;margin:15px 0 25px !important;border-radius:6px;}code{padding:.2em .4em;margin:0;font-size:82%;background-color:#f0f1f3;border-radius:3px;color:#28a745;}pre code{padding:0;}pre .token.keyword{color:#569cd6;}pre .token.atrule,pre .token.attr-value,pre .token.function,pre .token.class-name{color:#d69d85;}:not(pre)>code[class*="language-"],pre[class*="language-"]{background:#191919 !important;}div.code-toolbar>.toolbar span{cursor:default;}div.code-toolbar>.toolbar a{cursor:copy;}@media(max-width:767px){body{font-size:14px;}.for-mobile{display:inline-block;}.for-desktop{display:none;}.close-mmenu,.close-dmenu{position:absolute;top:-78px;left:25px;color:#fff;font-size:68px;background:#fff;opacity:0;}.navbar{padding:.5rem 1.75rem;}.navbar .navbar-collapse{background:#38003d;position:fixed;top:86px;left:0;width:100%;height:100vh;height:calc(100vh - 86px);z-index:100 !important;}.navbar .navbar-collapse .navbar-nav{height:100vh;padding:20px 30px;overflow:auto;}.navbar .navbar-collapse .navbar-nav .nav-link{padding:1.2rem !important;}.navbar .navbar-toggler{padding:.5rem .75rem;font-size:1.5rem;line-height:1;background-color:transparent;border:0;border-radius:.25rem;color:#fff !important;margin-left:-1rem;}.section-with-logos img{margin:15px;opacity:1;-webkit-filter:grayscale(0%);filter:grayscale(0%);}span.code-arrow{padding:0 0 0;display:block;transform:rotate(90deg);font-size:2em;}.mb-5,.my-5{margin-bottom:2rem !important;}} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.scss b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.scss index 5d6ba28c87..9219592bb4 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.scss +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.scss @@ -101,8 +101,9 @@ body { height: 100vh; > ul { - display: block; - height: calc(100vh - 210px); + display: block; + height: calc(100vh - 220px); + overflow-y: auto; } ul { @@ -259,7 +260,7 @@ body { } .docs-content { - overflow-x:scroll; + overflow-x: scroll; .docs-link-btns { border-bottom: 1px solid #f4f5f7; From a9e923339b94d82e11836e05703dbda074c31b5b Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Thu, 20 Dec 2018 17:16:31 +0300 Subject: [PATCH 101/368] Change cache config --- .../Volo/Docs/Documents/DocumentAppService.cs | 8 ++++++-- .../Volo/Docs/Projects/ProjectAppService.cs | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs index 3e68004b87..264f3f5474 100644 --- a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs +++ b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs @@ -75,7 +75,9 @@ namespace Volo.Docs.Documents }, () => new DistributedCacheEntryOptions { - SlidingExpiration = TimeSpan.FromMinutes(30) //TODO: Configurable? + //TODO: Configurable? + AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(6), + SlidingExpiration = TimeSpan.FromMinutes(30) } ); } @@ -98,7 +100,9 @@ namespace Volo.Docs.Documents }, () => new DistributedCacheEntryOptions { - SlidingExpiration = TimeSpan.FromMinutes(30) //TODO: Configurable? + //TODO: Configurable? + AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(6), + SlidingExpiration = TimeSpan.FromMinutes(30) } ); } diff --git a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs index 34f5956980..7afefee4f1 100644 --- a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs +++ b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs @@ -51,7 +51,9 @@ namespace Volo.Docs.Projects () => GetVersionsAsync(project), () => new DistributedCacheEntryOptions { - SlidingExpiration = TimeSpan.FromMinutes(60) //TODO: Configurable? + //TODO: Configurable? + AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(12), + SlidingExpiration = TimeSpan.FromMinutes(60) } ); From 6c3ba85c49d7e7e09d80d34f076874f5f58fcec5 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Fri, 21 Dec 2018 09:08:52 +0300 Subject: [PATCH 102/368] Resolved #658 --- .../Form/AbpSelectTagHelperService.cs | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs index 355234ba82..ca1c2e51ff 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs @@ -57,8 +57,9 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form var selectTag = GetSelectTag(context, output); var selectAsHtml = RenderTagHelperOutput(selectTag, _encoder); var label = GetLabelAsHtml(context, output, selectTag); + var validation = GetValidationAsHtml(context, output, selectTag); - return label + Environment.NewLine + selectAsHtml; + return label + Environment.NewLine + selectAsHtml + Environment.NewLine + validation; } protected virtual string SurroundInnerHtmlAndGet(TagHelperContext context, TagHelperOutput output, string innerHtml) @@ -164,6 +165,24 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form return RenderTagHelper(new TagHelperAttributeList(), context, labelTagHelper, _encoder, "label", TagMode.StartTagAndEndTag, true); } + protected virtual string GetValidationAsHtml(TagHelperContext context, TagHelperOutput output, TagHelperOutput inputTag) + { + if (inputTag.Attributes.Any(a => a.Name.ToLowerInvariant() == "type" && a.Value.ToString().ToLowerInvariant() == "hidden")) + { + return ""; + } + + var validationMessageTagHelper = new ValidationMessageTagHelper(_generator) + { + For = TagHelper.AspFor, + ViewContext = TagHelper.ViewContext + }; + + var attributeList = new TagHelperAttributeList { { "class", "text-danger" } }; + + return RenderTagHelper(attributeList, context, validationMessageTagHelper, _encoder, "span", TagMode.StartTagAndEndTag, true); + } + protected virtual string GetSize(TagHelperContext context, TagHelperOutput output) { var attribute = GetAttribute(TagHelper.AspFor.ModelExplorer); From 77d1ffccde94083f8264128ca6cbb760e1b0a982 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Fri, 21 Dec 2018 09:45:27 +0300 Subject: [PATCH 103/368] Seelct Tag helper info text --- .../TagHelpers/Form/AbpInputTagHelper.cs | 3 + .../Form/AbpInputTagHelperService.cs | 37 +++++----- .../Form/AbpRadioInputTagHelperService.cs | 1 - .../TagHelpers/Form/AbpSelectTagHelper.cs | 3 + .../Form/AbpSelectTagHelperService.cs | 72 +++++++++++++++++-- 5 files changed, 93 insertions(+), 23 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs index 4545024d6d..8bd4021458 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs @@ -10,6 +10,9 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form public string Label { get; set; } + [HtmlAttributeName("info")] + public string InfoText { get; set; } + [HtmlAttributeName("disabled")] public bool IsDisabled { get; set; } = false; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs index 13ab0f9159..a4a0193e97 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -58,10 +58,10 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form protected virtual string GetFormInputGroupAsHtml(TagHelperContext context, TagHelperOutput output, out bool isCheckbox) { var inputTag = GetInputTagHelperOutput(context, output, out isCheckbox); + var inputHtml = RenderTagHelperOutput(inputTag, _encoder); var label = GetLabelAsHtml(context, output, inputTag, isCheckbox); var info = GetInfoAsHtml(context, output, inputTag, isCheckbox); - var validation = isCheckbox ? "" : GetValidationAsHtml(context, output, inputTag); return GetContent(context, output, label, inputHtml, validation, info, isCheckbox); @@ -88,11 +88,10 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form protected virtual string GetContent(TagHelperContext context, TagHelperOutput output, string label, string inputHtml, string validation, string infoHtml, bool isCheckbox) { var innerContent = isCheckbox ? - inputHtml + Environment.NewLine + label : - label + Environment.NewLine + inputHtml; + inputHtml + label : + label + inputHtml; - return Environment.NewLine + innerContent + Environment.NewLine + - Environment.NewLine + validation + Environment.NewLine + infoHtml; + return innerContent + infoHtml + validation; } protected virtual string SurroundInnerHtmlAndGet(TagHelperContext context, TagHelperOutput output, string innerHtml, bool isCheckbox) @@ -259,23 +258,29 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form return ""; } - var infoAttribute = GetAttribute(TagHelper.AspFor.ModelExplorer); - if (infoAttribute == null) + string text = ""; + + if (!string.IsNullOrEmpty(TagHelper.InfoText)) { - return ""; + text = TagHelper.InfoText; } - - var idAttr = inputTag.Attributes.FirstOrDefault(a => a.Name == "id"); - - if (idAttr == null) + else { - return ""; + var infoAttribute = GetAttribute(TagHelper.AspFor.ModelExplorer); + if (infoAttribute != null) + { + text = infoAttribute.Text; + } + else + { + return ""; + } } - var id = idAttr.Value + "InfoText"; + var idAttr = inputTag.Attributes.FirstOrDefault(a => a.Name == "id"); - return "" + - LocalizeText(infoAttribute.Text) + + return "" + + LocalizeText(text) + ""; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpRadioInputTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpRadioInputTagHelperService.cs index 6dee6c1371..13585eeaf2 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpRadioInputTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpRadioInputTagHelperService.cs @@ -31,7 +31,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form var html = GetHtml(context, output, selectItems); - AddGroupToFormGroupContents(context, TagHelper.AspFor.Name, html, order, out var surpress); if (surpress) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs index 3cb2fd4667..8a1890f4dc 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs @@ -15,6 +15,9 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form public AbpFormControlSize Size { get; set; } = AbpFormControlSize.Default; + [HtmlAttributeName("info")] + public string InfoText { get; set; } + [HtmlAttributeNotBound] [ViewContext] public ViewContext ViewContext { get; set; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs index ca1c2e51ff..fa3d987135 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs @@ -58,8 +58,9 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form var selectAsHtml = RenderTagHelperOutput(selectTag, _encoder); var label = GetLabelAsHtml(context, output, selectTag); var validation = GetValidationAsHtml(context, output, selectTag); + var infoText = GetInfoAsHtml(context, output, selectTag); - return label + Environment.NewLine + selectAsHtml + Environment.NewLine + validation; + return label + Environment.NewLine + selectAsHtml + Environment.NewLine + infoText+ Environment.NewLine + validation; } protected virtual string SurroundInnerHtmlAndGet(TagHelperContext context, TagHelperOutput output, string innerHtml) @@ -76,13 +77,14 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form ViewContext = TagHelper.ViewContext }; - var inputTagHelperOutput = GetInnerTagHelper(GetInputAttributes(context, output), context, selectTagHelper, "select", TagMode.StartTagAndEndTag); + var selectTagHelperOutput = GetInnerTagHelper(GetInputAttributes(context, output), context, selectTagHelper, "select", TagMode.StartTagAndEndTag); - inputTagHelperOutput.Attributes.AddClass("form-control"); - inputTagHelperOutput.Attributes.AddClass(GetSize(context,output)); - AddDisabledAttribute(inputTagHelperOutput); + selectTagHelperOutput.Attributes.AddClass("form-control"); + selectTagHelperOutput.Attributes.AddClass(GetSize(context,output)); + AddDisabledAttribute(selectTagHelperOutput); + AddInfoTextId(selectTagHelperOutput); - return inputTagHelperOutput; + return selectTagHelperOutput; } protected virtual void AddDisabledAttribute(TagHelperOutput inputTagHelperOutput) @@ -119,6 +121,64 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form return GetLabelAsHtmlUsingTagHelper(context, output); } + protected virtual void AddInfoTextId(TagHelperOutput inputTagHelperOutput) + { + if (GetAttribute(TagHelper.AspFor.ModelExplorer) == null) + { + return; + } + + var idAttr = inputTagHelperOutput.Attributes.FirstOrDefault(a => a.Name == "id"); + + if (idAttr == null) + { + return; + } + + inputTagHelperOutput.Attributes.Add("aria-describedby", LocalizeText(idAttr.Value + "InfoText")); + } + + protected virtual string GetInfoAsHtml(TagHelperContext context, TagHelperOutput output, TagHelperOutput inputTag) + { + string text = ""; + + if (!string.IsNullOrEmpty(TagHelper.InfoText)) + { + text = TagHelper.InfoText; + } + else + { + var infoAttribute = GetAttribute(TagHelper.AspFor.ModelExplorer); + if (infoAttribute != null) + { + text = infoAttribute.Text; + } + else + { + return ""; + } + } + + var idAttr = inputTag.Attributes.FirstOrDefault(a => a.Name == "id"); + + return "" + + LocalizeText(text) + + ""; + } + + protected virtual string LocalizeText(string text) + { + IStringLocalizer localizer = null; + var resourceType = _options.AssemblyResources.GetOrDefault(TagHelper.AspFor.ModelExplorer.ModelType.Assembly); + + if (resourceType != null) + { + localizer = _stringLocalizerFactory.Create(resourceType); + } + + return localizer == null ? text : localizer[text].Value; + } + protected virtual bool GetSelectItemsIfProvidedByEnum(TagHelperContext context, TagHelperOutput output, ModelExplorer explorer, out List selectItems) { IStringLocalizer localizer = null; From 35bcf455f911395e2c142112afcbb21470ee577a Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Fri, 21 Dec 2018 10:23:14 +0300 Subject: [PATCH 104/368] Update AbpSelectTagHelperService.cs --- .../Form/AbpSelectTagHelperService.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs index fa3d987135..5437cf0bc8 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs @@ -167,6 +167,13 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form } protected virtual string LocalizeText(string text) + { + var localizer = GetLocalizer(); + + return localizer == null ? text : localizer[text].Value; + } + + protected virtual IStringLocalizer GetLocalizer() { IStringLocalizer localizer = null; var resourceType = _options.AssemblyResources.GetOrDefault(TagHelper.AspFor.ModelExplorer.ModelType.Assembly); @@ -176,18 +183,12 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form localizer = _stringLocalizerFactory.Create(resourceType); } - return localizer == null ? text : localizer[text].Value; + return localizer; } protected virtual bool GetSelectItemsIfProvidedByEnum(TagHelperContext context, TagHelperOutput output, ModelExplorer explorer, out List selectItems) { - IStringLocalizer localizer = null; - var resourceType = _options.AssemblyResources.GetOrDefault(explorer.ModelType.Assembly); - - if (resourceType != null) - { - localizer = _stringLocalizerFactory.Create(resourceType); - } + var localizer = GetLocalizer(); selectItems = explorer.Metadata.IsEnum ? explorer.ModelType.GetTypeInfo().GetMembers(BindingFlags.Public | BindingFlags.Static) .Select((t, i) => new SelectListItem { Value = i.ToString(), Text = GetLocalizedPropertyName(localizer, explorer.ModelType, t.Name) }).ToList() : null; From e8bd3d2aa24ec3f1f6a4c0f668cee267097c0143 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Fri, 21 Dec 2018 11:01:47 +0300 Subject: [PATCH 105/368] Update Index.cshtml --- .../Pages/Index.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Index.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Index.cshtml index 39c62bfb96..6888267210 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Index.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Index.cshtml @@ -20,7 +20,7 @@
  • Dropdowns
  • Dynamic Forms
  • Form Elements
  • -
  • > Grids
  • +
  • Grids
  • List Groups
  • Modals
  • Navs
  • From 2a2f3c267d180c38ab91d984b1c74f6aaf82c290 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Fri, 21 Dec 2018 11:06:51 +0300 Subject: [PATCH 106/368] Fixed #674: Argument check error --- .../System/Collections/Generic/AbpCollectionExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpCollectionExtensions.cs b/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpCollectionExtensions.cs index 69b4d795e0..0d5e4260f6 100644 --- a/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpCollectionExtensions.cs +++ b/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpCollectionExtensions.cs @@ -75,7 +75,7 @@ namespace System.Collections.Generic public static bool AddIfNotContains([NotNull] this ICollection source, [NotNull] Func predicate, [NotNull] Func itemFactory) { Check.NotNull(source, nameof(source)); - Check.NotNull(source, nameof(predicate)); + Check.NotNull(predicate, nameof(predicate)); Check.NotNull(itemFactory, nameof(itemFactory)); if (source.Any(predicate)) From 2be6c2d23d6606aab145fd378aee02a49c90f51e Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Fri, 21 Dec 2018 11:34:36 +0300 Subject: [PATCH 107/368] Add summary to IEntity.GetKeys method. --- .../Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/IEntity.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/IEntity.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/IEntity.cs index 8afbabb26e..58e607b120 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/IEntity.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/IEntity.cs @@ -6,6 +6,10 @@ /// public interface IEntity { + /// + /// Returns an array of ordered keys for this entity. + /// + /// object[] GetKeys(); } From 79a6c1ef7641385ab4dace074a48235ce9c3ff46 Mon Sep 17 00:00:00 2001 From: Nokecy Date: Fri, 21 Dec 2018 16:40:23 +0800 Subject: [PATCH 108/368] Fix Localization problem on My Profile modal --- .../Pages/Identity/Shared/PersonalSettingsModal.cshtml.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Shared/PersonalSettingsModal.cshtml.cs b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Shared/PersonalSettingsModal.cshtml.cs index 140abcacf6..7306e63b22 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Shared/PersonalSettingsModal.cshtml.cs +++ b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Shared/PersonalSettingsModal.cshtml.cs @@ -45,7 +45,7 @@ namespace Volo.Abp.Identity.Web.Pages.Identity.Shared [Required] [StringLength(IdentityUserConsts.MaxEmailLength)] - [Display(Name = "DisplayName:Email")] + [Display(Name = "DisplayName:EmailAddress")] public string Email { get; set; } [StringLength(IdentityUserConsts.MaxNameLength)] @@ -60,4 +60,4 @@ namespace Volo.Abp.Identity.Web.Pages.Identity.Shared [Display(Name = "DisplayName:PhoneNumber")] public string PhoneNumber { get; set; } } -} \ No newline at end of file +} From a8e38ffa57550adeca3b1a0b66032faa2181bbf3 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Fri, 21 Dec 2018 15:04:42 +0300 Subject: [PATCH 109/368] Resolved #650: Document how to create API controllers from application services conventionally. --- docs/en/AspNetCore/Auto-API-Controllers.md | 138 ++++++++++++++++++ docs/en/Index.md | 2 +- docs/en/Tutorials/AspNetCore-Mvc/Part-I.md | 2 +- docs/en/docs-nav.json | 8 +- docs/en/images/bookstore-apis.png | Bin 0 -> 17154 bytes .../Mvc/Conventions/AbpServiceConvention.cs | 4 +- .../ConventionalControllerSetting.cs | 13 +- 7 files changed, 155 insertions(+), 12 deletions(-) create mode 100644 docs/en/AspNetCore/Auto-API-Controllers.md create mode 100644 docs/en/images/bookstore-apis.png diff --git a/docs/en/AspNetCore/Auto-API-Controllers.md b/docs/en/AspNetCore/Auto-API-Controllers.md new file mode 100644 index 0000000000..48567b6919 --- /dev/null +++ b/docs/en/AspNetCore/Auto-API-Controllers.md @@ -0,0 +1,138 @@ +# Auto API Controllers + +Once you create an [application service](Application-Services.md), you generally want to create an API controller to expose this service as an HTTP (REST) API endpoint. A typical API controller does nothing but redirects method calls to the application service and configures the REST API using attributes like [HttpGet], [HttpPost], [Route]... etc. + +ABP can **automagically** configures your application services as MVC API Controllers by convention. Most of time you don't care about its detailed configuration, but it's possible fully customize it. + +## Configuration + +Basic configuration is simple. Just configure `AbpAspNetCoreMvcOptions` and use `ConventionalControllers.Create` method as shown below: + +````csharp +[DependsOn(BookStoreApplicationModule)] +public class BookStoreWebModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.ConventionalControllers.Create(typeof(BookStoreApplicationModule).Assembly); + }); + } +} +```` + +This example code configures all the application services in the assembly containing the class `BookStoreApplicationModule`. The figure below shows the resulting API on the [Swagger UI](https://swagger.io/tools/swagger-ui/). + +![bookstore-apis](../images/bookstore-apis.png) + +### Examples + +Some example method names and the corresponding routes calculated by convention: + +| Service Method Name | HTTP Method | Route | +| ----------------------------------------------------- | ----------- | -------------------------- | +| GetAsync(Guid id) | GET | /api/app/book/{id} | +| GetListAsync() | GET | /api/app/book | +| CreateAsync(CreateBookDto input) | POST | /api/app/book | +| UpdateAsync(Guid id, UpdateBookDto input) | PUT | /api/app/book/{id} | +| DeleteAsync(Guid id) | DELETE | /api/app/book/{id} | +| GetEditorsAsync(Guid id) | GET | /api/app/book/{id}/editors | +| CreateEditorAsync(Guid id, BookEditorCreateDto input) | POST | /api/app/book/{id}/editor | + +### HTTP Method + +ABP uses a naming convention while determining the HTTP method for a service method (action): + +- **Get**: Used if the method name starts with 'GetList', 'GetAll' or 'Get'. +- **Put**: Used if the method name starts with 'Put' or 'Update'. +- **Delete**: Used if the method name starts with 'Delete' or 'Remove'. +- **Post**: Used if the method name starts with 'Create', 'Add', 'Insert' or 'Post'. +- **Patch**: Used if the method name starts with 'Patch'. +- Otherwise, **Post** is used **by default**. + +If you need to customize HTTP method for a particular method, then you can use one of the standard ASP.NET Core attributes ([HttpPost], [HttpGet], [HttpPut]... etc.). This requires to add [Microsoft.AspNetCore.Mvc.Core](https://www.nuget.org/packages/Microsoft.AspNetCore.Mvc.Core) nuget package to your project that contains the service. + +### Route + +Route is calculated based on some conventions: + +* It always starts with '**/api**'. +* Continues with a **route path**. Default value is '**/app**' and can be configured as like below: + +````csharp +Configure(options => +{ + options.ConventionalControllers + .Create(typeof(BookStoreApplicationModule).Assembly, opts => + { + opts.RootPath = "volosoft/book-store"; + }); +}); +```` + +Then the route for getting a book will be '**/api/volosoft/book-store/book/{id}**'. This sample uses two-level root path, but you generally use a single level depth. + +* Continues with the **normalized controller/service name**. Normalization removes 'AppService', 'ApplicationService' and 'Service' postfixes and converts it to **camelCase**. If your application service class name is 'BookAppService' then it becomes only '/book'. + * If you want to customize naming, then set the `UrlControllerNameNormalizer` option. It's a func delegate which allows you to determine the name per controller/service. +* If the method has an '**id**' parameter then it adds '**/{id}**' ro the route. +* Then it adds the action name if necessary. Action name is obtained from the method name on the service and normalized by; + * Removing '**Async**' postfix. If the method name is 'GetPhonesAsync' then it becomes 'GetPhones'. + * Removing **HTTP method prefix**. 'GetList', 'GetAll', 'Get', 'Put', 'Update', 'Delete', 'Remove', 'Create', 'Add', 'Insert', 'Post' and 'Patch' prefixes are removed based on the selected HTTP method. So, 'GetPhones' becomes 'Phones' since 'Get' prefix is a duplicate for a GET request. + * Converting the result to **camelCase**. + * If the resulting action name is **empty** then it's not added to the route. If it's not empty, it's added to the route (like '/phones'). For 'GetAllAsync' method name it will be empty, for 'GetPhonesAsync' method name is will be 'phones'. + * Normalization can be customized by setting the `UrlActionNameNormalizer` option. It's an action delegate that is called for every method. +* If there is another parameter with 'Id' postfix, then it's also added to the route as the final route segment (like '/phoneId'). + +## Service Selection + +Creating conventional HTTP API controllers are not unique to application services actually. + +### IRemoteService Interface + +If a class implements the `IRemoteService` interface then it's automatically selected to be a conventional API controller. Since application services inherently implement it, they are considered as natural API controllers. + +### RemoteService Attribute + +`RemoteService` attribute can be used to mark a class as a remote service or disable for a particular class that inherently implements the `IRemoteService` interface. Example: + +````csharp +[RemoteService(IsEnabled = false)] //or simply [RemoteService(false)] +public class PersonAppService : ApplicationService +{ + +} +```` + +### TypePredicate Option + +You can further filter classes to become an API controller by providing the `TypePedicate` option: + +````csharp +services.Configure(options => +{ + options.ConventionalControllers + .Create(typeof(BookStoreApplicationModule).Assembly, opts => + { + opts.TypePredicate = type => { return true; }; + }); +}); +```` + +Instead of returning `true` for every type, you can check it and return `false` if you don't want to expose this type as an API controller. + +## API Explorer + +API Exploring a service that makes possible to investigate API structure by the clients. Swagger uses it to create a documentation and test UI for an endpoint. + +API Explorer is automatically enabled for conventional HTTP API controllers by default. Use `RemoteService` attribute to control it per class or method level. Example: + +````csharp +[RemoteService(IsMetadataEnabled = false)] +public class PersonAppService : ApplicationService +{ + +} +```` + +Disabled `IsMetadataEnabled` which hides this service from API explorer and it will not be discoverable. However, it still can be usable for the clients know the exact API path/route. \ No newline at end of file diff --git a/docs/en/Index.md b/docs/en/Index.md index df0cab524a..bd65ed5c7f 100644 --- a/docs/en/Index.md +++ b/docs/en/Index.md @@ -16,7 +16,7 @@ Easiest way to start a new project with ABP is to use the Startup templates: * [ASP.NET Core MVC Template](Getting-Started-AspNetCore-MVC-Template.md) -If you want to start from scratch (with an empty project) then manually install the ABP framework, use following tutorials: +If you want to start from scratch (with an empty project) then manually install the ABP framework, use the following tutorials: * [Console Application](Getting-Started-Console-Application.md) * [ASP.NET Core Web Application](Getting-Started-AspNetCore-Application.md) diff --git a/docs/en/Tutorials/AspNetCore-Mvc/Part-I.md b/docs/en/Tutorials/AspNetCore-Mvc/Part-I.md index 9a48022e27..9f766ae3b0 100644 --- a/docs/en/Tutorials/AspNetCore-Mvc/Part-I.md +++ b/docs/en/Tutorials/AspNetCore-Mvc/Part-I.md @@ -236,7 +236,7 @@ namespace Acme.BookStore You normally create **Controllers** to expose application services as **HTTP API** endpoints. Thus allowing browser or 3rd-party clients to call them via AJAX. -ABP can **automagically** configures your application services as MVC API Controllers by convention. +ABP can [**automagically**](../../AspNetCore/Auto-API-Controllers.md) configures your application services as MVC API Controllers by convention. #### Swagger UI diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index ff05d3934a..3d16381f01 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -189,7 +189,13 @@ "text": "ASP.NET Core MVC", "items": [ { - "text": "API Versioning" + "text": "API", + "items": [ + { + "text": "Auto API Controllers", + "path": "AspNetCore/Auto-API-Controllers.md" + } + ] }, { "text": "User Interface", diff --git a/docs/en/images/bookstore-apis.png b/docs/en/images/bookstore-apis.png new file mode 100644 index 0000000000000000000000000000000000000000..aedd79c7f1d9bd6732e7c71ea432c4e3c06e034c GIT binary patch literal 17154 zcmdtKbyQS;+wVW5fFdmoN=u4#D-=%nVy!*S%-;Kx*M42^>+OUpDM(^skYIp7AWUf~aTO2yPRqX~bp_C+k z0LRs|7H1Y8E?mYDF4{b9o4MS(kd;0z{dJgJtinV@$Ko>Gn$(vO#bBk?_}edpF4yn% zaN;qgIjUKZBdUaXQ1yw2@Ga7o*VeFSpU774_L*=xbxmE}mynPUDWsk>RzKjyKty8z zaH#q6KXMTDRUK^Bg$N9hPwK0Osx7R744b4s1H z`NRE1d+Sxb?7as96%`evYcy3rv*i8wNawe2-E}8fKN`=H?c@-iWblzjFZE?VJ@5j@(Zo!I4px+a{{DwJ0zlx#eY}`X^D{KD;00Zd}%$hB2VzOTD11)ZUxI4CMIhFV=hJHI`;Ly5Sm0e0> z*24f(j2HHT@;v1C@Wp~Gtl1wfZwS-D>f3I=RR+Vygkfop3<$qwboDMAF4DvHGqxtm zzPOGJh&;W$7TbM73v@7S!=lRf;l8Iwyk1O*Lgsh#b#!01&ck}k5}D)Onz`f{Hv;Hp z`N#QL6vPkWy29E{^+3dKeADWx@T3rCIJ-JVy6BhZZ+B}t_7yyWhAMZwNg10S=97(U zPX7(P@H#!K)ts#!L6eDl0Husa?C6& z-@bkg;1)#(MpS#0;-$#`#oXnw0c>gvbx_3jMoY{8cCzC5V5eTagk0Qr|! z$$`nRR9C)agu!>oci^+(AOm{DH$TUM%*Vz=kTM3H4xanmOe&OnTlO1(h3FrM&N?1$ z-hGW+!NtK*wwrc;EBQDR`F{BrIy_3?%W#Vb`qY{?$}B>}m1(lVV73%+JSb9|a-W6U zps%OO_8`n)FWO(Q*grS>C27pZei%xd!<2q}KQwf#J~$+N7d=6d3If*fUNo7!Fzlc@ zk;5Fmn1MUAC9@GHCEYdG;6TQ}Da=>CzBdC)sJhoRhG%73eAWJn>FpMjL=?CyrzMr$ z#(usv4>#A>XA#PoquHqahz3k;9}hdBZ1oS2yWrRPj_ANfD@a~2m#3npuEhpsO_wT2 zB7)2^eTIk+0`4hSEMqM|`K4iUPbPITUhL*_F|aC&m5YTjV2y)=14RYaG)JNw$hQ6N zBCQPNWRX8YVcTPEyc>1V*Q#k|>hxsrj5U64iTh)MiCXwsL3piIIUcu}?F@Bc_NLRc z%SP*Aa2eQb99TZyzYgocWl>6qzIybxme=$V1jMNdSkK*Z*cI;YAeG&R^Q+;CLkHo! zH_BjH&=*PXv6UK+!E?)ghDml9Rm94bQ2j;JXX;}GdH1y_OR)_D(x)wYpZYG3|3s25 z&3#@>0Y}0gdqA+Y26NYe73_ZZpqn5ViguBY(@tZ8+U6VSU;_QlT@ISeT}KU`{2;k2 zqucM7d#oUfxq1)xn00<5SSmvIaTB%lX)oTkpu={*HC8>yhTawb;c|%{pN)Bb3;wm}#a>r__?Std(s zF4lfOs^r-_S@IY@BIe33>U5||MM%dvYtoV5uqQDXL{dvf_Zl}YP2E89qg?yvZ9{8% zFV;Vx17BZm7@7^h!|X~c@1gg(vKa=ob{b;8yWF?KcL){Ka=5#Jx+(-p28MCiMIoxc z0#1NBJhJLpIL-;~=R|q*$TjV?a+|{Y2s#61!0Yb%1Na4&1cs+RGhv}g-g zI-1o0FH7{#3=NozLM<%)7oeONjREn2R+N(ju6VmEsD;?* z)*QAi&b=2C7vEqDGs@n-(@!NYc!o7~eqXxJW`Or}3JpXg58MxNu=%@vP8pA4Oaq_F zEDVnbxM-f+<+SIuHsw!R78@Zw1RxqxcE5x_fG04vaR2jzLD5fNDj{g-NWZsp+s_fL zvkBF0mXUHbatA@*!fgZ}r6dkEA!p~pTiL-qR>l_gm6Vy>G?)If_`FeB#nkvTemm#T zHPx-$?E?*w;@edLg++UA%KHagoG5|gi_FXPlguuYdLuuw7@Cx3i$!nT?eze2iN*-) z-bFLP*F}?O<#TBwBq97l3wmnrgL@=7`eAzk+g2kWL+*4WTztvcXK@Ma?AD(l%I&;q z1|Pn#vzVIw)}NsM;UV)_cDQe2sRiW}W2~^G6a_SuR*o2p>h#*DvndPZ&E{4~N>|IR z_~s-o&iKfLI4kipw%b*1WC5Yqj9nV;D!i1e-@+VH$1N)*xG|2f5dEgk97SjeOgmx+ ztG!(Nw3xyL(`{TE(WO#|211lfZ-&1n)bxPpUPP+x+0$T|q9?j9zP8(##x*uUP&B8b z%1X`()qU+t^TnuG$dPZ`aEM3aO@4TIn1wj+h5)9%?dW|v9Zcy(&D$!obX$}!uYI_m zzYs6F-I$p1=$OG`?aX@=8>iWkkdkz8`ySqO(du=cd=YRlBz=IDEJ>ZSQqWm7(d(7X zG(W5+c)wcrX(MAHgP5FllB`Q1FoDe#qo+D@+DAhX*U8JpsyvC48m6oA{eGcZ@0iS8 z^dg4@UMJ#j2aGyTrCjYqs4LKtj~OKC86TaaJC$ibZ4eo>Qtv$i_ZLrfBOUx0MiS%A z9d4FO)wU5r2Q7c*V&gVEzmnM)wLq>cZ)9gHjAfM z;t8@Q4#J)wm)V65&h;T2b zF|`|yXR9h{CLB(<8LPcR?V8Q4!T$&zXbZJ7gD1O+csexR<^zRE*8qpSHEL=d7G&cnUq*u=X~qh zP`s4F#Wsd-Qf>}$-?rGHav>tL4+*&yM{1;bkAe7$Q5S9IF~kM|MHxF4BmCEc@ZkNi zt#ZI~jI1&fzYIL_)aU0Xm?*^%5oR&DtRX8=pigxX=zbfqoYaOzpA^tlDe4t9hvj6s z5lsbBRYf&7+A!j20HhL6_z)}Q85AI z*FK_zz1YZ?vy-VVajTVwV}km&uaWwU$ic_m!NlY?E$Vq=!+ztuOQmTGj&ET77OeW( z?~NqnwBwA^3yp;?)GJ;_+AU^&*HlxVp6;%tc*mh>lk6_&Yq{4Vn6Lf{$TA2HH*gc7 z2ee+`f=EAgtMs8pC)(^C0ni(ZlMV*GF@k&*FkzZ`*5#o;t!LDW^bXebBUJ>#!)~;(2q$OKE?=>1=tj<~A%F^0+mIz1DH`)@ z9UNy`&Qq;s*OwY5QrzA1fPJ-?AO)<0w@CZEwG%wJ*o<@mh#e8_I;>5Y*rMI2eLKjwGVU=;9Kd16;qqI^_bz?r!B>#%)&WQ)I{T*$pB-%%hu+OgJb zF8Et|ibYK@X@BRL+1zZ}8lIi&aB9JgnvL*> zbju^47#I6v2weLk`AlYbIW-KV24mb{GwIjuJ-uxijiKEdlY@*$PrHvElIzW6PmNC4 zYj}#G%Q$lXKu|r3H-Cxy`qgXE3_rQ8k#0HESZo)3pNn zP%e4;Ff_XEg#|o@pRkmyBOl*v{45oTNZ@@#hJ*43WLUdUR!@1n!-k+;5~V$$GOAY3 zk_ar_u=82jDpgq!(WJ&^UTdP>&TC@~#tBs(1f?d#8Ki09$i!j_7R6ng zgVaW=WcG*9kB!=qv*<&|#RpJ#+5H2PrUi*!Sequzhb=Lj!lz!z*AZ{ zCs3Dahq;rj-M5npt^NWJq43^#QJr0o*TJt0viLPpN4IYe7JMFwjqt{!@OMk@h#?WS z&Cd8Vd9IBtS+r(Toqk)3$>)8)K_=G{h!f-rB{dCk4A?R{m8DD$p7#|~EjCQk`iiv_ zwKk$DE7=RrK3$}${CL^^*6Ds{X(ir6$VJb_Z_CH0S95ns+yTiR0I`;gKwU(%w?QG9 zsL5)JW=P0J8ANmM)=b}$7ls5y3-I_m;#!Qp{G2|s>_*T_#@4(M9IP|H zl43i>!NJnVuqdpx`8v?izkIGuKvzzil_!&)3PNZD?6T(<=d3jPOe6DZ&wk6#%W7<+ z@S_hN(&7Es4)Az$xp&H|xXuMm`xX+ShE`fyYKtWu{h{)GQgU+oJ?~Ag=RyjW5Hu>z z;p;0f!wuw$r0AMP_Ho_2xeG95n#EsGo6e^~9}!lw=fux8V=t~ewGX|FY=Ycx8z6(18|< zOA*)Wk>kD~dV<>f5^qx%QIfOr@01)(lU#~rqb~}yR+y%|@9&^IHDj-K$rhy}x1l=s zk()2}RT7YnN7XNsw?$2c-ukaeDZ+}-pB_fOivRO|N_D{YH>swT<677@a964(;+B~p zU_k!+Qd8Ex_jJmo+on%B(4q|%@WCY`_?cvz3FUDluua5y`W{{OuigcO0&13~?VeB9 zACjM_?fb53x67u90ruJ4{sMehz*8NF`2$tn;{I*klrJ)<*MbUA!(4pwXr!No=R)^- z?;kx|pHW-@rqJrR*-r|M0&@^O$=dO``zFd7MK4=s&`xn- zSw)`p$&d$_)x!7{Nxa?53!ii_Dif_VbfUgL5KI0K{ zz5hOKrGB8JK0+H!gFXU9Bi-AE0Ao|Y#vaf;k>er+++mfr6W(1-DCjh@n*I$bW*GE#>u#o{j@TF;H+7dC!~7EmwR%+-LI+!B%v1X9b0d?iT_6PuywR) z&s()%RA?cOthjg%ivCJ{dE<(RsYP^dVLlU(cmYd8#0Z$9|0d1z$367t)QH#$t`?uA zt~7kGR9To9zMU)*Q^5b=LGk-hZ=-C?1SD+JKnBuOaMI`Is2%UIkjgM1r;`+0$NAD` zw+Od4pIQFra=wqob+>Cu-TFu2+XrAET~`jpjtT39=_4pi9~!5>p5;yqMjE1^nub2S zCIH*UKW)PTg%BQVh5jzLq5Md2q!nsdU+opF7$+5vsO?4%t0Uxke){>{x|efT6A1@M zZFUABn?Mqu@TgqkHVoybZdj+rmI&LPwE zJ$g+=##CG+;nWxVPvFlcEH$X#k#L0^4+b{Z&o(=5=NpI(;WzVDSRGEBKJtU5Ev=V5iX zDV{$~o=iXPhdea2FnGK(x?Qbt#XlDFvp9P$rL@M;-|K0Iy3q6wSvx5 z9Vdw+O0qK^m_}}^PRva*!Q37Zc6-(mh;5HpByszriCVgR@Uo0E#dls7u||9#_EC?V$Ip>uYb(5~ zy)8XFhzDT{Yk6B(57eqEv*c$jlqe|Pz7}7#9sFE#T!C&ML(l8Io3_%hQ5#ABU}m@4 z)Ec;d!5R_l{@@TF6jW4esqXr$Y*DAd_8nDGxV~e}+pqdHKB>1Qnkv~sEgw#!7>U;N z`Mqf=haT1;kSom%O=hp(tehW5Tr67(SUqf5US9yGCkwDVRkx1EC);nLpr?=U{-}|F zSH!vy$t>BK=PGa`Dg%kGx}=8kTzCw_;svd8Q&r>?*ZXf@5?+mvrdpu+KZ%baC(hT6 z=w;X!1$?J6MSPTp_=2PN_xJuG_fbPuT|4jgXPxChG~gH`WI6TGm#byH7rSAxHJ0`r zotOV4di2Nl74;^f#y9?j<8P*ow%v?U%2p~&frpal zz@Tikt5lp{>`X>WOKHO;Fzcuoq->hA?@NV)bNwB4#{NSmy75{J8u{b(PZ{&tzEZ(8 zX=Q~l1xiLcKl=r>z=&DzVlpP`w6Eb52x^{Z(G)j=OPWk-J-rf0m_Pet_jeTpWQWnH zpO0~-@Lp6Bzmn*$r6j{4-?ms6($G-H?CI@mm{wIqs`33=OKEDRsZPyLEn7LJR!IS4 zoYM=RJyaiHDvFrq>Hv8D<@~-15R&p(^!95oB*ewrvJ$VOeL}nDf&-&sko|kL?;M6g zXVO>)NFi2T-nQUWNMPPEg`Ah+pVif_d{q!ct$NIsOvFO{cIm_MQeK@Epl)9)DJ2jnPM9FR2 z75TMnH7_rdMzTZQqIK1szElv;gA(MG2syFf)hH zR&VIkZ^Q22*l&@QTKgR^(O{Ll=E+xQ_0H{X;`E4MFRR^M8G)#JmfdqbE>;g@{w>sq zO}oP-N%xZhVNl2JH+NWZvj71?!G-#OL0?2;7#@msI6uo|Lh;iGrDkusr+;cvNeBwP^E}fUHM|`E=N$a|>aB#;;{dJtnT{Z@vZ3p^3vfoBF zi^E|ZE1yM=DgDD~Qwo6iDYdTRZ_O^OrT-wl{GdKz{6qhyLoEgH*ay#cV#;#-6Y+sC zbpM&8Kc6rjh@YY5&iV2HPkTurHRjxQCf(saX`1^~-|-?~*3{sBEMMo**V#wiGv|S| zy|@IcvHEK1L`pJ?alACM#qS=2(BLvM=qQo=#Tk@P|{$6OZCQ!y1cW_Z_fSq zXEzI4)2xK776W)&C2LuJ9|+_!s`~iv+>ST4vOzr#nifDKcei2XRb{G>=FbfPMCt!} z!^*y6Ozj*diJZ#&$Iz|YPWbE@AM8ESugTPe(kOOQS&3DmY1H= zD+_PvUo!L3r*8c2pf3Ih!BH_zxbWOW3~*XwJ0LzQ5{{x-xs1#iv0|9{?yTMXEJ4csK?!OrEI{@hl4x4GT!dA=U9I;qSv2H6+xC&eIo-@CbIN@VzWZqYu(pW zMcY?_bjSXuIA44Rj(mxRwT=#;ga4ozG^@UD{{XaiFK}a;C{-bUcHfylb%8%(@1E8n zJk$##d4w()SK?1fq5+%cao~>vbo5jeD&{cFd=fNNVw|F7DE`w$PT^=Ex=)bU(DY#qoU#=o6*-r4^}rjQ@W zP3aY6GR)7y&kyV09=BwRxZ|3S-PG&DJF}dXoqKg}x* zjs*=JMq=V$%db3_h#N?xrZ@4MUDy4wywoCtxHy0NV|@f=139enb9Z;&6mQtAN+9}n3e=9l&^&vJ>T3-Gy!5-WNLxr^T6O?V%nptx2H)ZIoJE)n+6vp$5~yZ>m!zWdzP*ao?ExT`&!ax)f$J& zUNRaJNv(V4KSaFxEd@rmx*rUvs2sMJh0l3twAx?DfA{@(*LQJEYzc0jI6Vd#o{Qeu z<)g9sKN#t?Xv^qZO2H`Zl`XXN*4(^mjzoNzE*y!in7jsEB4Pd=1iQHpHn3jQ~@$4!3Hj)dQ!)9CwFd!US_vZqAZyjgCuZB}1(PAlLFe`D)!hBY&A z3~odGxm0f2njWmkB(J^dq7xlsjL)(DjSk+SA+w6f(B$ltDauClCA+ztubwfNP=qhFNH9$poPGnHM> z<1;6e10Q{st?R5<=GVCTJd|B0>yIF^9WA8(=yNk2-SyE|X+9mG5^%hl-H~(kMk2sO zvbczy#zX}a^Ieh=${QVA#U4Jh#nKd|Now*HK`=ED&=+Jt4xwJn9pz=L!;OeU6Y0cG zV20KFGiNsP3Pf&DynMW7i_eH~10Nz7d<@>_HetAVF`@21Ixh(hI%IQIq6_?`(E@OIp0q~KpMea=H_e-n@xbH z5i9O4*JV2dI%`;CY`kcokmS~n)!qx;P%YMA-NQoukQc<&dR0Tf8q#aq|FT~Hf_O}D zKcRiT*~;hb$bl(S#WcI&QW%S@N>f??COJ8O5ih;ktnyh-qi4DkkTr$ zX7LR-!hu%$`3(AO{dyzCCP=x3&brib$(d=|y(4Fr_^+}7N=bW;yziFWMj}V%!{xL! z=9`mOI$7%>PD1CyiBhokrssEbh; z`sYm@cJ%3HeP z&Dg4ERqO2x?{q*bIS>Xz_=ug&R46NWyt-p#2vGiyB_X10)3k_7(hvP3U zJm|PTswWeMhHg;D`w{+5&{=;IPmmA(8gA~Xtx z&uDk;KdE_8MYtu9#ozuy|1xU-o*s?=t%a|wakTfRf%dV9m+8OEBU-B;o(J6ym~t5n zXVtosGRHzt zAajWzWS=}7VKAXg5kN0ktp7)jGU}JyFi-4YoN#hd)9kmWM@fLxQTVM{5wyOwAQF(1 z61eV%hvHzx2j9%EER%$+hTm5i<9>2#_te}4BGiA)Qapthw6}G~goxQ0sr4T4LPG|E z5i26rCBDZ<_A|DS4}3!mcU- zzy4*JL&;aS*W4b+N{1t|9y@2B3`&)72sw}&GQ8v((~fGYd%jv2y!kVO&*}Kf?lRc< zN5}g-4=mKVun8wmH`!)YO;8s^`kEqNr;8|mdqLc;a=@Wp(%**RGTYVCisAlly7C6K zVJ4elbFd{gW|3ptywq76g_?@W0Nsm~m_-8A@bPYmoy+0Wm*famZwA7?A%23BMkmKw zC+G|gY)A6bHxHR{Ptifpeh{oZat8SoM2^E8&7}0@-|t)iLyK3*!`|TfjiJE0;NOcB zRY^ChR)nyISwMx)%IZ8=HC|{!#hMfyg{n~sA%K7`qJMP|a!}m=^DJ;F){Asp51ai^ zD#UNw8z)Ey)PjA{uI_2=t9vs+ZDO#?xaa3s7-8tZAB0Q>gvOsL__|<73Gog7q5mDJ z%z-Llss`T1{1=7PA3qhir#h0EtYcw}3grAA2+Q{ZZB0jrOS5T$)02&<@1*tQ$q%~w z6t0xN3N6hgk`@^mcqYAixx((6rLQ=At{JQ2*i>TvwK6;u%M~w30;uDte{KbZg%l{F zzh@;jo2%$NiSNp&S8?W_6MpcthNYk4WMh(Y^WK*pFj!2bWUQ_I`ExzLpqmF)eO=^I zhT_p0Z7)rJ=VM9Ox*o!(k2({(%~l`J(VT`c$vn-iw+EyB2_UYAh2QKBijR)ekTVuE zU-%LWY%wa>8Z5e3<&^Dx_i`G$sr^S;V{}~U%NiF75bezdtMN^qjW_@)&x*Po-@jEg zRDMqc?^mXg8rgxWX0xvzOtOHi5jD*eOInPvG&kEjr zy~e6WJHiIaa6&10ROC(ZQgKvBu-$O~OiKp=2=|+byVmL8?blRvOx0I1;x+X!dRE3bKG|Bzu=jY^_j!ef3pCB z?Wap6fl~NUhH59vKbG}30hB#8-3TpA$s6VJ^u^6{w&usSbAO&2i~m{xN!;u%{b;Aa zvnQP>)cV^U_Tk46{wQXfG3@A**z2@ax^r>yd)%vidygOR6#}G6ur#POQfk143m`(; zL5i2nn=~W)-AT%?FFpbyuBe5LGZ;-hnkKw=Vrhwt&$X<=Ci(2eVv9RMN$K|As~>gl zXC#j?y1Kfap!zd3>3+dG*@x@oA!`3y2y{!7&B|`3n6wTEzH~wXIN3WqzLAD~98iiU zYApYTk?>4O)GQCP;}PXmKG6soR{zFe7ZTRF6ZxML99VIXr&$&Qhvhz)-IP+m@fYv^ zoGRgve+xowj|Vgvac@agysqwd$_GbY=%BaQfGvkhn1U`Qy%>mlS#2L4d|nFc=TEv< zMo@=k>6hENAFwZOjkLB8{Q$aym{EuhyId5$`t2bRq+hO?@>;pUjuMnSVpglo@+V{H ze1IA>K^!=_P;&mHKe=69AE_nln04q#zWu+NDGmMDR~elDRo>1qrN5dA7zsjl`rZZ3 z0hOiukK&WRd~pA@1hVO%x<8aIu|jU%Ogr&xF){}340Bos%ti{FXr67j=~t`u>`3SE zGTL%^yE33he;9=B&w}{~C#P) z3zEr(Ea6@uNTPsoPEoi=@pRE#eNmDujdYWjd*>dV@_ zK z4ZOM`vMLtXZ`%#xqm$-!1$sg=+K)c=)q#9AtbWApgIfN!L8Xu{C$_UkO>;rT)6ht> zh|6j8vFRj)j*r5RXc!_GSeV&OjAsxxvwiFZ+Xs+Mw0{nFw9){nA3@RpZTDKB$WoAD zzNEyvIYvc{?e1J<OQFNQ%O2NyipD{l=Vw-J*mHi)iLu`qHZ)+Fy5F1CC zZEDi-35d!@>Q!5rNthRSL&%WAQUnHyB` zJ{$fzH-n-WYzug_`g#Tx44UAbkqa$`yNZ-+Z2H&nj93Rp=MT?g!&;`o2LITNhGYU7 zUzt0H-n#woyhZu{i?_%E83B~=*b#Cv7m;Nn;1KhzU|{HH`5sV!=pT|d3*>v@xEeg* zfd6q}YMfA|ieIQ1*%ELO0EQ-2fxUlm7fHKbd;PMHo@FwW8)Y$OctN$d$@yLOOYU<} zX;+|O>vQlkC2W-O!V0vzh0)!4-M;=A}=vM?mi*SL{D6zvUA0?nPe4!x^K5Ve@=_+yD% zctU$o7_LxE3inF*kaHLF3;b>#>G)Hyg(<5uew7uP>(X0*KQsN7v zb$WV|!__|flNMs2Dsa`a_*YdR#_@-aBcNEiPP}0q*BWA*2c6Q35Zv?1KYVl;Fsw(w zX)@14zwlKJj1p4HGKbXBrc(7@8A$*vthU)c572Ij?tNM5Qi`VWUnsmCg-sd`i2v)? z?y2;$!|90|*|f!HDT@M4C6a}yx$7l>!XLZ!kr63xiEYe==EKVIl+u^wVgpwzo+wh? z1yY&Vy~_5KR_KQqQA$=|=2^Ah_oJ^s2Y=}JlCj(S@ls*e_3T7e0NSm2PhI;x zH>J>4=e70bI>Byv{D=HF(5t-CpYom@&A&{0@YQniZ4rNO5>x=3%b_Wx4FsK6p8799 zCJwf?4*GTb@s0KtHY+Vo|DfE2nx)Xq!ZXN5j9{CMsi&cgexr%o{lr0v)AhIJy7E!o z+L43@@jBho{{4W>OZAJJmR#q(SzJ88WGw=itfvoONJle2lXY}Fo1~O%cT-G0%gh&s zC`MG)YA3PkAg|8&P(7bE_}I)C^homQFD+Ic15112!ehz_5m976?jct~W*gLQKMQ}b zhU?NwTNd03R;zEoLgnhy;1%d<0Qd`M_gle(CYO6t@}`W0bx!Jve|)HON2St$Xz6}F zC3!>WGll)^nb|8M@p03pw~xRD4!u92+OS=_f(d z$Shjkq$8S))#SMqU+E|<7RE}CUer1=2ciho!^A{V$YLMO!xO-n<-AbWGbW?4U3lq! z6})7dRbc~2kx_P*CghUEP1O-_V}|}|Ma0<{C*ND(bt~z=_-y{>y7?cm+n{|}z&mP| zkDi44dB!nSpO9j3P(paI#^L7a9kYT!%uNDfxF!56Mx|a`-yiv2cyc00Nl5&ku(`|< zHG_va3`d>~4#~Y98gj%sM;2;6r+5d1%>%FiyqjX3|A(EDG%>C{@DbVgCWbPPx9md)fl z{msR-0oQ}|yT2In>i0cwOZqEdw6A~4FDt%(O8YE)Q$W_Sb8}3=pjpZLj#Py3kIFu8 zDAtqkE3=*G)eCMKTt8z@9BmyP0TESr(gKkmaxLC-86)F$k(;Y%`2P7b1E6Mxcoc@m z6-$<@5$fGC)4N=pRDAw--kjwj3watLMJ~v$gaY^IuwB;M6&2~UY2kXie){xj8*noL z`_aOoDfhk%0gNRT1x&#d{gTjcSUUIg`%;bGHuY&;D(Q)LL(`o>Xd?0ODe{&|U@e$m zDEg;F{|{Ndw?DbG^c|syz_eG}jkaBzpn1g$W0m%X;2^pSrx(Dvt#QV4J09(t=DG33 z_ZRX%BKOA2fIdJLKl}|ok0Kp2PG#Zcrblf;lasW6rQH`m?gNQ5}wIYHFv$;I3drij&js{K%Rxk*mA84FP|CIyZ^n;HlXZ za$?~F*pWG*$Qg`Osj9i^NkTMlx2t)|sahp~vV7X8a?)rY#Cfl!bBV=NA87rgfwgt> zmEtFD1;U$sO?SzA7;o1RMY6Dn!*98Da(9COLBZ#u!NuvR3ssPV>x`X8`sw(Tcu^J1 z2Lnkyc)mn5S=U!pV!lE~2u^o)p=dTws=Pk!yeE2fUl&}38pxx6a{?AAM<~I3D|8Yk zBmaX)c>P{$G*bP}{WK}dF#;SkHZcFnml^bXBbiC_kf^GGch%x&+-r~@``w`C;Uq=b zm;>L2m8&UnP~LqPZF7p3<7N>#6gV%htzv=Qw|cubmSyXlp0a;20s%cd+*hC)ZoG*a z%mD=RMdh>D>*KqX!kl%TIHA`5rCq!o-O{~9&Jw$;;!Rk&BHf)k1xjhTTDh$wqs|&8%nReBox@i z(1F-7+wEQcg#jarK_VasvBK-JF#`+L(B@|1Iiery&d`h*2Y_e@Uab=4K7C(iyYh~gf1sAR55O}xv=|E=7$^2vt#ZG|dK5j0b z$?V=Z2#0~m;g9?+2*}@k!gV*T05TI_=3}8SM)LQEuX0et%aVvZw7u+T6cR{{aM6lf z8hvf~Y>8-+G77JIuKy?zF~QaAJqAeKm$e8P_o&(zjU!Dv8l=|7mLCV-TL4IzM3Pkd zG`nFaT|{}#o}97_Z78krj|27URu#q4br8tuErbpA{C@v`n*>^&x2+i1Zq#!Kv6`xN%O4N*- z+$%BZYDoy$>@%flO(Yq2CY-(v2fH#HL3ymE@KgoQ!>LVNWP@JJCxQDaE(%q*6|$S& zR-#Hog$AP0Ar<$}5xMV*a(ia$uizJPV;3SD)u$Z(EZrxFD)A^Y<>Z_y@#Ui#d_rc#rejnMDI2k**QB6+Kf9dD`O?_xdS(4BRhxAS+H;x< zVNboj=C1C~b!VFQ2%s#5SrI|Eiq&u?Uk)xLY)qjFZPM!%nZu+w~FBOp_R)c!;V2(Zh+X$yO^T-TLODFIO|A zp^f13T+F7x0ASS*!(R_38fWME1R1Fh=a&zPP24zMC=w}OH2E9K<51%LL3tg0@VI5- zmTs=Ja1$&S^IvrBiS4@BOz%C0`}jfyOxn4#HIIB3yvEMl)=cq23fR!Rj$$3d`6@1s z^6^CW9jybn`0Tjp=7G1)cL2**kk#$C1rn%6i}k2*;XX})E$EUoC-ODwqAPc$HtA6N zTw@`oapdv);wGEHulaFmqgw6e>OUz!edqL!6JY(?ZaCkMO3x#93^5t1!vxLleeTC& zS>7qKF(bb6k{Er=q3^rkoMd$My~+9UHiQ1J{Yr|+#keQ(-YO9|9tpJ(>t&G(D~!^>Qv!qUS{mwQt7&liv6l+r8nZw5sO`YTtQMdMtR|Z@7_4VZi=Z%4+ zR;_K?;w$ytn@lY*mv&C`JCtKr$lRGR@J#vfSf{Bde{U>&7QffUPCg8v%4`&R9y^j# zrT6a>fd7rCM^EHo(I!qvhEHDNB{j95eIsUdPvR%c+~6(zj_?B!K63J5$|1&cv=^(R zxsQ!-I*okFwC2;YO<(0PmD^s0wtUvn^rjFtwL5@sSgMD;Q*~?tNEuD4D;18%$6(xd zxnnlFH8!E?hd!469_hip1BY}Ni*W$rTx(#JuHVM&jPe7E7stJ~n?FKh8_vB2$A77R z|K=b$VU2&nEq+z_6cb|-1?q$jC$(_b#t$m(yl|Xy#k%rQjDG{*UAVP* zDOBLs1%^>mhBS_Sp}*bnt|n% zoObtlx088EX2o5=e>S4ZvITnEi}H>o>|R;!Q%o@TBd!V-%=DdDDfpd7BuBQ zS@;J0`K^bR%@kTeJMjsqPx-P4Av|>&`TfU4{~t-9_aX().FirstOrDefault(); - if (areaAttribute.RouteValue != null) + if (areaAttribute?.RouteValue != null) { return areaAttribute.RouteValue; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalControllerSetting.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalControllerSetting.cs index ac504b6546..fac627d182 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalControllerSetting.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/ConventionalControllerSetting.cs @@ -1,12 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using JetBrains.Annotations; +using JetBrains.Annotations; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.AspNetCore.Mvc.Versioning; -using Volo.Abp.Application.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; using Volo.Abp.Reflection; namespace Volo.Abp.AspNetCore.Mvc.Conventions @@ -17,7 +16,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Conventions public Assembly Assembly { get; } [NotNull] - public HashSet ControllerTypes { get; } + public HashSet ControllerTypes { get; } //TODO: Internal? [NotNull] public string RootPath From 197a11cfb44a3faa78ecdc3c6a0609f45d84a843 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Fri, 21 Dec 2018 15:06:41 +0300 Subject: [PATCH 110/368] Change ASP.NET Core MVC to ASP.NET Core on the nav menu. --- docs/en/docs-nav.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 3d16381f01..01f8fb884b 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -186,7 +186,7 @@ ] }, { - "text": "ASP.NET Core MVC", + "text": "ASP.NET Core", "items": [ { "text": "API", From 1c71c9cc9b42cfd3647e434e674f2d9bdd39493f Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Fri, 21 Dec 2018 15:41:43 +0300 Subject: [PATCH 111/368] Added Acme.BookStore.ConsoleApiClient project --- samples/BookStore/Acme.BookStore.sln | 7 +++++ .../Acme.BookStore.ConsoleApiClient.csproj | 14 +++++++++ .../ApiClientDemoService.cs | 26 ++++++++++++++++ .../ConsoleApiClientModule.cs | 27 +++++++++++++++++ .../Program.cs | 30 +++++++++++++++++++ 5 files changed, 104 insertions(+) create mode 100644 samples/BookStore/test/Acme.BookStore.ConsoleApiClient/Acme.BookStore.ConsoleApiClient.csproj create mode 100644 samples/BookStore/test/Acme.BookStore.ConsoleApiClient/ApiClientDemoService.cs create mode 100644 samples/BookStore/test/Acme.BookStore.ConsoleApiClient/ConsoleApiClientModule.cs create mode 100644 samples/BookStore/test/Acme.BookStore.ConsoleApiClient/Program.cs diff --git a/samples/BookStore/Acme.BookStore.sln b/samples/BookStore/Acme.BookStore.sln index 49f9115781..b0a02d2dde 100644 --- a/samples/BookStore/Acme.BookStore.sln +++ b/samples/BookStore/Acme.BookStore.sln @@ -19,6 +19,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.Application. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.Web.Tests", "test\Acme.BookStore.Web.Tests\Acme.BookStore.Web.Tests.csproj", "{5F1B28C6-8D0C-4155-92D0-252F7EA5F674}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Acme.BookStore.ConsoleApiClient", "test\Acme.BookStore.ConsoleApiClient\Acme.BookStore.ConsoleApiClient.csproj", "{3DED9AA7-1FC4-435D-9934-BCD37B43F744}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -49,6 +51,10 @@ Global {5F1B28C6-8D0C-4155-92D0-252F7EA5F674}.Debug|Any CPU.Build.0 = Debug|Any CPU {5F1B28C6-8D0C-4155-92D0-252F7EA5F674}.Release|Any CPU.ActiveCfg = Release|Any CPU {5F1B28C6-8D0C-4155-92D0-252F7EA5F674}.Release|Any CPU.Build.0 = Release|Any CPU + {3DED9AA7-1FC4-435D-9934-BCD37B43F744}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3DED9AA7-1FC4-435D-9934-BCD37B43F744}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3DED9AA7-1FC4-435D-9934-BCD37B43F744}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3DED9AA7-1FC4-435D-9934-BCD37B43F744}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -60,6 +66,7 @@ Global {068855E8-9240-4F1A-910B-CF825794513B} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} {50B2631D-129C-47B3-A587-029CCD6099BC} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} {5F1B28C6-8D0C-4155-92D0-252F7EA5F674} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} + {3DED9AA7-1FC4-435D-9934-BCD37B43F744} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F} diff --git a/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/Acme.BookStore.ConsoleApiClient.csproj b/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/Acme.BookStore.ConsoleApiClient.csproj new file mode 100644 index 0000000000..0582d6f067 --- /dev/null +++ b/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/Acme.BookStore.ConsoleApiClient.csproj @@ -0,0 +1,14 @@ + + + + Exe + netcoreapp2.1 + + + + + + + + + diff --git a/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/ApiClientDemoService.cs b/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/ApiClientDemoService.cs new file mode 100644 index 0000000000..d16746bdb8 --- /dev/null +++ b/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/ApiClientDemoService.cs @@ -0,0 +1,26 @@ +using System; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.Abp.DependencyInjection; + +namespace Acme.BookStore.ConsoleApiClient +{ + public class ApiClientDemoService : ITransientDependency + { + private readonly IBookAppService _bookAppService; + + public ApiClientDemoService(IBookAppService bookAppService) + { + _bookAppService = bookAppService; + } + + public async Task RunAsync() + { + var output = await _bookAppService.GetListAsync(new PagedAndSortedResultRequestDto()); + foreach (var bookDto in output.Items) + { + Console.WriteLine($"[BOOK {bookDto.Id}] Name={bookDto.Name}, Price={bookDto.Price}"); + } + } + } +} diff --git a/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/ConsoleApiClientModule.cs b/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/ConsoleApiClientModule.cs new file mode 100644 index 0000000000..8bd13aee76 --- /dev/null +++ b/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/ConsoleApiClientModule.cs @@ -0,0 +1,27 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Autofac; +using Volo.Abp.Http.Client; +using Volo.Abp.Modularity; + +namespace Acme.BookStore.ConsoleApiClient +{ + [DependsOn( + typeof(AbpAutofacModule), + typeof(AbpHttpClientModule), + typeof(BookStoreApplicationModule) + )] + public class ConsoleApiClientModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.Configure(options => + { + options.RemoteServices.Default = new RemoteServiceConfiguration("http://localhost:53929/"); + }); + + context.Services.AddHttpClientProxies( + typeof(BookStoreApplicationModule).Assembly + ); + } + } +} diff --git a/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/Program.cs b/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/Program.cs new file mode 100644 index 0000000000..3be13e1281 --- /dev/null +++ b/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/Program.cs @@ -0,0 +1,30 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; +using Volo.Abp.Threading; + +namespace Acme.BookStore.ConsoleApiClient +{ + class Program + { + static void Main(string[] args) + { + using (var application = AbpApplicationFactory.Create(options => + { + options.UseAutofac(); + })) + { + application.Initialize(); + + using (var scope = application.ServiceProvider.CreateScope()) + { + var demoService = scope.ServiceProvider.GetRequiredService(); + AsyncHelper.RunSync(() => demoService.RunAsync()); + } + + Console.WriteLine("Press ENTER to stop application..."); + Console.ReadLine(); + } + } + } +} From 25f47faa3519a39aaf079b83cc97b4e1636d3f2a Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Fri, 21 Dec 2018 15:57:30 +0300 Subject: [PATCH 112/368] tag helper demo fix --- .../Pages/Components/ButtonGroups.cshtml | 36 +++++++++---------- .../Pages/Components/Collapse.cshtml | 17 ++++----- .../Pages/Components/Dropdowns.cshtml | 32 ++++++++--------- 3 files changed, 43 insertions(+), 42 deletions(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ButtonGroups.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ButtonGroups.cshtml index 25322444db..90cd39f7ab 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ButtonGroups.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ButtonGroups.cshtml @@ -86,22 +86,22 @@
    
    -    <abp-button-toolbar>
    -    <abp-button-group class="mr-2">
    -    <abp-button button-type="Secondary">1</abp-button>
    -    <abp-button button-type="Secondary">2</abp-button>
    -    <abp-button button-type="Secondary">3</abp-button>
    -    <abp-button button-type="Secondary">4</abp-button>
    -    </abp-button-group>
    -    <abp-button-group class="mr-2">
    -    <abp-button button-type="Secondary">5</abp-button>
    -    <abp-button button-type="Secondary">6</abp-button>
    -    <abp-button button-type="Secondary">7</abp-button>
    -    </abp-button-group>
    -    <abp-button-group>
    -    <abp-button button-type="Secondary">8</abp-button>
    -    </abp-button-group>
    -    </abp-button-toolbar>
    +        <abp-button-toolbar>
    +            <abp-button-group class="mr-2">
    +                <abp-button button-type="Secondary">1</abp-button>
    +                <abp-button button-type="Secondary">2</abp-button>
    +                <abp-button button-type="Secondary">3</abp-button>
    +                <abp-button button-type="Secondary">4</abp-button>
    +            </abp-button-group>
    +            <abp-button-group class="mr-2">
    +                <abp-button button-type="Secondary">5</abp-button>
    +                <abp-button button-type="Secondary">6</abp-button>
    +                <abp-button button-type="Secondary">7</abp-button>
    +            </abp-button-group>
    +            <abp-button-group>
    +                <abp-button button-type="Secondary">8</abp-button>
    +            </abp-button-group>
    +        </abp-button-toolbar>
     
    @@ -186,7 +186,7 @@
    -

    Vertical variation

    +

    Nesting

    @@ -241,7 +241,7 @@
    -

    Nesting

    +

    Vertical variation

    diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Collapse.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Collapse.cshtml index 6a9aeb90ca..e72e219487 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Collapse.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Collapse.cshtml @@ -38,7 +38,7 @@ - 3Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. + Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
    @@ -49,7 +49,8 @@ <a abp-button="Primary" abp-collapse-id="collapseExample"> Link with href </a> <abp-collapse-body id="collapseExample"> - ... + + Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. </abp-collapse-body>
    @@ -86,12 +87,12 @@ - 3Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. + Curabitur porta porttitor libero eu luctus. Praesent ultrices mattis commodo. Integer sodales massa risus, in molestie enim sagittis blandit - 3Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. + Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. @@ -108,12 +109,12 @@ <abp-row class="mt-3"> <abp-column size-sm="_6"> <abp-collapse-body id="FirstCollapseExample" multi="true"> - 3Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. + Curabitur porta porttitor libero eu luctus. Praesent ultrices mattis commodo. Integer sodales massa risus, in molestie enim sagittis blandit </abp-collapse-body> </abp-column> <abp-column size-sm="_6"> <abp-collapse-body id="SecondCollapseExample" multi="true"> - 3Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. + Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. </abp-collapse-body> </abp-column> </abp-row> @@ -129,12 +130,12 @@ <div class="row"> <div class="col"> <div class="collapse multi-collapse" id="multiCollapseExample1"> - Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. + Curabitur porta porttitor libero eu luctus. Praesent ultrices mattis commodo. Integer sodales massa risus, in molestie enim sagittis blandit </div> </div> <div class="col"> <div class="collapse multi-collapse" id="multiCollapseExample2"> - Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. + Anim pariatur wolf moon tempor,,, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. </div> </div> </div> diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Dropdowns.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Dropdowns.cshtml index 4a8ddba9d6..47d332e134 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Dropdowns.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Dropdowns.cshtml @@ -47,9 +47,9 @@ <abp-dropdown> <abp-dropdown-button text="Dropdown button" /> <abp-dropdown-menu> -<abp-dropdown-item href="#">Action</abp-dropdown-item> -<abp-dropdown-item href="#">Another action</abp-dropdown-item> -<abp-dropdown-item href="#">Something else here</abp-dropdown-item> + <abp-dropdown-item href="#">Action</abp-dropdown-item> + <abp-dropdown-item href="#">Another action</abp-dropdown-item> + <abp-dropdown-item href="#">Something else here</abp-dropdown-item> </abp-dropdown-menu> </abp-dropdown>
    @@ -91,9 +91,9 @@ <abp-dropdown> <abp-dropdown-button button-type="Secondary" link="true" text="Dropdown button" /> <abp-dropdown-menu> -<abp-dropdown-item href="#">Action</abp-dropdown-item> -<abp-dropdown-item href="#">Another action</abp-dropdown-item> -<abp-dropdown-item href="#">Something else here</abp-dropdown-item> + <abp-dropdown-item href="#">Action</abp-dropdown-item> + <abp-dropdown-item href="#">Another action</abp-dropdown-item> + <abp-dropdown-item href="#">Something else here</abp-dropdown-item> </abp-dropdown-menu> </abp-dropdown>
    @@ -170,11 +170,11 @@ <abp-dropdown> <abp-dropdown-button button-type="Danger" text="Dropdown button" /> <abp-dropdown-menu> -<abp-dropdown-item href="#">Action</abp-dropdown-item> -<abp-dropdown-item href="#">Another action</abp-dropdown-item> -<abp-dropdown-item href="#">Something else here</abp-dropdown-item> -<abp-dropdown-divider /> -<abp-dropdown-item href="#">Separated link</abp-dropdown-item> + <abp-dropdown-item href="#">Action</abp-dropdown-item> + <abp-dropdown-item href="#">Another action</abp-dropdown-item> + <abp-dropdown-item href="#">Something else here</abp-dropdown-item> + <abp-dropdown-divider /> + <abp-dropdown-item href="#">Separated link</abp-dropdown-item> </abp-dropdown-menu> </abp-dropdown> @@ -256,11 +256,11 @@ <abp-dropdown> <abp-dropdown-button button-type="Danger" dropdown-style="Split" text="Dropdown button" /> <abp-dropdown-menu> -<abp-dropdown-item href="#">Action</abp-dropdown-item> -<abp-dropdown-item href="#">Another action</abp-dropdown-item> -<abp-dropdown-item href="#">Something else here</abp-dropdown-item> -<abp-dropdown-divider /> -<abp-dropdown-item href="#">Separated link</abp-dropdown-item> + <abp-dropdown-item href="#">Action</abp-dropdown-item> + <abp-dropdown-item href="#">Another action</abp-dropdown-item> + <abp-dropdown-item href="#">Something else here</abp-dropdown-item> + <abp-dropdown-divider /> + <abp-dropdown-item href="#">Separated link</abp-dropdown-item> </abp-dropdown-menu> </abp-dropdown> From 752d2bcc5c68efe8ad9fcc3858b29382b959acd8 Mon Sep 17 00:00:00 2001 From: Alper Ebicoglu Date: Fri, 21 Dec 2018 17:01:14 +0300 Subject: [PATCH 113/368] closes #549 . Added Docs Module documentation. The MongoDB provider will be added later. --- .../src/Volo.AbpWebSite.Web/package-lock.json | 2758 +++++++++++++++++ docs/en/Modules/Docs.md | 470 ++- .../docs-module_download-new-abp-project.png | Bin 0 -> 20225 bytes ...module_download-sample-navigation-menu.png | Bin 0 -> 12396 bytes .../images/docs-module_solution-explorer.png | Bin 0 -> 10828 bytes 5 files changed, 3226 insertions(+), 2 deletions(-) create mode 100644 abp_io/src/Volo.AbpWebSite.Web/package-lock.json create mode 100644 docs/en/images/docs-module_download-new-abp-project.png create mode 100644 docs/en/images/docs-module_download-sample-navigation-menu.png create mode 100644 docs/en/images/docs-module_solution-explorer.png diff --git a/abp_io/src/Volo.AbpWebSite.Web/package-lock.json b/abp_io/src/Volo.AbpWebSite.Web/package-lock.json new file mode 100644 index 0000000000..5e26238da6 --- /dev/null +++ b/abp_io/src/Volo.AbpWebSite.Web/package-lock.json @@ -0,0 +1,2758 @@ +{ + "name": "volo.aspnetzero.support", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@abp/anchor-js": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@abp/anchor-js/-/anchor-js-0.5.1.tgz", + "integrity": "sha512-9N/iPP9tDdq9lKRNFQuqRL+QYSv5fq789KgHHGG1/MqExJ6KTPcqUDHvQ53kz96pUgJA+Fyn3dpwgPqLVYI3Yg==", + "requires": { + "@abp/core": "^0.4.9", + "anchor-js": "^4.1.1" + } + }, + "@abp/aspnetcore.mvc.ui": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-0.4.9.tgz", + "integrity": "sha512-AveMEi6WRQmD1tM9yVNLAe6ffcbtoL3ZGQKTPA95Q+dy5xBXVg4Y8jdhxawNPK64KYArhfrVkQDfa4mq3pW5Qw==", + "requires": { + "ansi-colors": "^1.1.0", + "extend-object": "^1.0.0", + "gulp": "^3.9.1", + "merge-stream": "^1.0.1", + "path": "^0.12.7", + "rimraf": "^2.6.2" + } + }, + "@abp/aspnetcore.mvc.ui.theme.basic": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-0.4.9.tgz", + "integrity": "sha512-g3Zby8x8+vWw3oTJsSPasjm4tv7BG4270PEf7jK9w925+lIyKYHn6UxOcFbSU2pi9mJTnaF+Fk/rScIcdxwZZw==", + "requires": { + "@abp/aspnetcore.mvc.ui.theme.shared": "^0.4.9" + } + }, + "@abp/aspnetcore.mvc.ui.theme.shared": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-0.4.9.tgz", + "integrity": "sha512-Fe4UfQ215Pz2V6D5HUYhDJFeJWjKLcv2gsZfOheWLlOBgYh274pdnUIwceoZ4Btpa9aPECLG+LAH4dTbs8vjRg==", + "requires": { + "@abp/aspnetcore.mvc.ui": "^0.4.9", + "@abp/bootstrap": "^0.4.9", + "@abp/datatables.net-bs4": "^0.4.9", + "@abp/font-awesome": "^0.4.9", + "@abp/jquery-form": "^0.4.9", + "@abp/jquery-validation-unobtrusive": "^0.4.9", + "@abp/lodash": "^0.4.9", + "@abp/select2": "^0.4.9", + "@abp/sweetalert": "^0.4.9", + "@abp/timeago": "^0.4.9", + "@abp/toastr": "^0.4.9" + } + }, + "@abp/blogging": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/blogging/-/blogging-0.4.9.tgz", + "integrity": "sha512-cMFLekebHCM1ZAGPxcli3yzEy0kq1nV8ZuV9JbaczoiC/KDOnBp8CWq61CwLxgnfZpVIO5RTdtDye9pDtBJdmg==", + "requires": { + "@abp/aspnetcore.mvc.ui.theme.shared": "^0.4.9", + "@abp/owl.carousel": "^0.4.9", + "@abp/tui-editor": "^0.4.9" + } + }, + "@abp/bootstrap": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/bootstrap/-/bootstrap-0.4.9.tgz", + "integrity": "sha512-A7lDHo43KnqjINo0xWECx/WzNQe3vqvE3GPv6uXq3KDi+gStQLAFBq3bVcVW/kSxiquDQ/tuCLRpE0qlhoobag==", + "requires": { + "@abp/core": "^0.4.9", + "bootstrap": "^4.1.1" + } + }, + "@abp/clipboard": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@abp/clipboard/-/clipboard-0.5.1.tgz", + "integrity": "sha512-efOPloVL0moRqGpAMA7DU5o+vzzu7ipGOFcG9nOfDD6uGY9AsOztFc71GwIFrtwADvJSiJHD6OfEIfR++dCT0w==", + "requires": { + "@abp/core": "^0.4.9", + "clipboard": "^2.0.4" + } + }, + "@abp/codemirror": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/codemirror/-/codemirror-0.4.9.tgz", + "integrity": "sha512-bjuKZKLHyBzr6lWZ5Fh4Io/6u0OILkwsB9LJAZ3cHnDkmBEIRlnQBmuGxCkQ3D0sXcFWrLoqb2FAB9djLxCnUQ==", + "requires": { + "@abp/core": "^0.4.9", + "codemirror": "^5.38.0" + } + }, + "@abp/core": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/core/-/core-0.4.9.tgz", + "integrity": "sha512-JbibIPDz0w/C9YhexNagMD763qbZCclcHLVlTpKEZUcxzp6rZXwPR6ekh/PnvzD0R7wmHOh+bHl0hs5JSdy3oA==" + }, + "@abp/datatables.net": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/datatables.net/-/datatables.net-0.4.9.tgz", + "integrity": "sha512-URimiGMFBusEMo9aAadLFCossbYyrN2R6+6YrQ+heqxdheCPmm2wupsXSFoUBHBhD0tzF4rY+OL//oOg3Wtg4g==", + "requires": { + "@abp/core": "^0.4.9", + "datatables.net": "^1.10.16" + } + }, + "@abp/datatables.net-bs4": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/datatables.net-bs4/-/datatables.net-bs4-0.4.9.tgz", + "integrity": "sha512-Dsz0fy2haBz3dl2MLXWjW2bhDBzp1cpWXSXj8TEEzYazjhyoqBy6AiFlEnRCqO49KZD6Ps1cONSRxx4c4On9Lg==", + "requires": { + "@abp/datatables.net": "^0.4.9", + "datatables.net-bs4": "^1.10.16" + } + }, + "@abp/docs": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@abp/docs/-/docs-0.5.1.tgz", + "integrity": "sha512-3pGYnxZxm2kYPfu2EwDF0QinsNTym2cWlYAo7mVUBuReTPMhwHYtgrE7AX3nCVv1iAo6ltW+mebonGt1s5yXzA==", + "requires": { + "@abp/anchor-js": "^0.5.1", + "@abp/clipboard": "^0.5.1", + "@abp/malihu-custom-scrollbar-plugin": "^0.5.1", + "@abp/popper.js": "^0.5.1", + "@abp/prismjs": "^0.5.1" + } + }, + "@abp/font-awesome": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/font-awesome/-/font-awesome-0.4.9.tgz", + "integrity": "sha512-H4H/PJeSypoq++jP7eqS3y5jpbPIglUByPymHnho7U84gO06tZBUIoK00zyLACUVLzNztWANhmVqyA6OaHQ6xQ==", + "requires": { + "@abp/core": "^0.4.9", + "font-awesome": "^4.7.0" + } + }, + "@abp/highlight.js": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/highlight.js/-/highlight.js-0.4.9.tgz", + "integrity": "sha512-bsXgtOAJ8O4W3AO9arIxwLCC1JZABlZtoB55Pk5WjGiu8mhWiB4+HCXqWtSBE2qXwSLoDBE2FS5KAtIPfGfn+g==", + "requires": { + "@abp/core": "^0.4.9" + } + }, + "@abp/jquery": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/jquery/-/jquery-0.4.9.tgz", + "integrity": "sha512-Lte2rfDhcVXRA18mJMyPs0oFoiX/7x10F9cwMyX4+8e9QulA0dg+MjJZ4HIbxRoKvaYPz0AdE5VZ511folFeTg==", + "requires": { + "@abp/core": "^0.4.9", + "jquery": "^3.3.1" + } + }, + "@abp/jquery-form": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/jquery-form/-/jquery-form-0.4.9.tgz", + "integrity": "sha512-T1LzHNO+L/ATSfsaSu9H5rq9oUGjjBrwcJBVQhWRuGbB/Nsv1t4CdCPZHqbYBsn3ji/6T9C80FMdL+s4iOfy8A==", + "requires": { + "@abp/jquery": "^0.4.9", + "jquery-form": "^4.2.2" + } + }, + "@abp/jquery-validation": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/jquery-validation/-/jquery-validation-0.4.9.tgz", + "integrity": "sha512-8C58G9BTYszW6E0EO6NYqXLEbABXt/yGlOqAFCkPiLVfUcoC6uARqkgIgNVnE99ZUeSmluNsYeCczP0Qb0yNzg==", + "requires": { + "@abp/jquery": "^0.4.9", + "jquery-validation": "^1.17.0" + } + }, + "@abp/jquery-validation-unobtrusive": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-0.4.9.tgz", + "integrity": "sha512-GR62QEPexX4uLcqF3y72V39nlx/70C7ubeaIxS1ZEq+0wGklwAiyq1p19qpB5Cuj2GJL+vFrIig5w+B79P2iAw==", + "requires": { + "@abp/jquery-validation": "^0.4.9", + "jquery-validation-unobtrusive": "^3.2.9" + } + }, + "@abp/lodash": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/lodash/-/lodash-0.4.9.tgz", + "integrity": "sha512-/itYbXQL145WigKIGpnyWgARml7QGie7xqhC1WZG5iUkdqLx+4YBXesdzGFykthDewiQNz8mB2gPk64d376AAw==", + "requires": { + "@abp/core": "^0.4.9", + "lodash": "^4.17.10" + }, + "dependencies": { + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + } + } + }, + "@abp/malihu-custom-scrollbar-plugin": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-0.5.1.tgz", + "integrity": "sha512-i9XorWsWcqb3tbbiwvE4OQCfXXJO38HlkQgvlwzxshB8xDcS9v/JL5fAAvM/Cr66fB2zybsrCseq9QcBXL+yCQ==", + "requires": { + "@abp/core": "^0.4.9", + "malihu-custom-scrollbar-plugin": "^3.1.5" + } + }, + "@abp/markdown-it": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/markdown-it/-/markdown-it-0.4.9.tgz", + "integrity": "sha512-leaY6Iom4zCW9RcZWIZbiYTM8NTmSYSa2Xiq7FW2MzhDCATXbcqV1+EqNAAFBERHAJoq0Hyz2AkIP510L+hz6Q==", + "requires": { + "@abp/core": "^0.4.9", + "markdown-it": "^8.4.1" + } + }, + "@abp/owl.carousel": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/owl.carousel/-/owl.carousel-0.4.9.tgz", + "integrity": "sha512-pgRcdbN1u6vaN6wOfNN9z6Id70va93kGTCBNVY43fJec1ghIq/evpBNp29ef5x9b0lcfe4DhmNb3CFaLbikr0w==", + "requires": { + "@abp/core": "^0.4.9", + "owl.carousel": "^2.3.4" + } + }, + "@abp/popper.js": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@abp/popper.js/-/popper.js-0.5.1.tgz", + "integrity": "sha512-qS97hQQtG78mVPRvmZZtBb7Vu905NpThl9PN3jPWWDiVbOV2/d+BXCTRhTRbfdup3C5cmGdntjaGxfcxlxHt1Q==", + "requires": { + "@abp/core": "^0.4.9", + "popper.js": "^1.14.6" + } + }, + "@abp/prismjs": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@abp/prismjs/-/prismjs-0.5.1.tgz", + "integrity": "sha512-DxoidAVV8LmtgFonbzGJEfszQDUaHEQc+/bcJtyQCuv5l+uflVnpAH+6W8IAErt5N96a0RJbeV9ZBXjIhqOzpA==", + "requires": { + "@abp/core": "^0.4.9", + "prismjs": "^1.15.0" + } + }, + "@abp/select2": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/select2/-/select2-0.4.9.tgz", + "integrity": "sha512-AaJHWy9fkP/LqVkruZGfvzgdZXyT96/FpnflUpoNPXjuvVRptkJpd/BQiWjpyjS+qzuZ+m3X9dms0d0lAyFKYA==", + "requires": { + "@abp/core": "^0.4.9", + "select2": "^4.0.5" + } + }, + "@abp/sweetalert": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/sweetalert/-/sweetalert-0.4.9.tgz", + "integrity": "sha512-FaxtELo7Um/uasasbOGi1j1XuBtZ819mUo7+6pMSWj2CSAkg2A/RyT9NhYcX8oyGpv188W5CjZfJ1DM0bRH+pQ==", + "requires": { + "@abp/core": "^0.4.9", + "sweetalert": "^2.1.0" + } + }, + "@abp/timeago": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/timeago/-/timeago-0.4.9.tgz", + "integrity": "sha512-RsAyJCl+rEWQL0q0Nx/ijy+iOBYm5IC5Re6y4SQ1jYF/B4n88GM2PFy6kLrE+HHGl5Z5hkWr5OGXmFem50Y3Wg==", + "requires": { + "@abp/jquery": "^0.4.9", + "timeago": "^1.6.3" + } + }, + "@abp/toastr": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/toastr/-/toastr-0.4.9.tgz", + "integrity": "sha512-KjnETa1Og5EIMDw/pIxPoKLTABBcsxBN8BqwIG33ya2+BIRfAI7b0lEMoKK+qmwVwI5dkXZlKFGIUmPtb+zVCw==", + "requires": { + "@abp/jquery": "^0.4.9", + "toastr": "^2.1.4" + } + }, + "@abp/tui-editor": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@abp/tui-editor/-/tui-editor-0.4.9.tgz", + "integrity": "sha512-sIXF/rNX2UyQiDCDmj8pv1FeqtAv9B0NquyBJwWDkaXWQsmJJ3YU/drcJHbzabsYg2tBjzRM/4Bb0+eXYR+Mnw==", + "requires": { + "@abp/codemirror": "^0.4.9", + "@abp/highlight.js": "^0.4.9", + "@abp/jquery": "^0.4.9", + "@abp/markdown-it": "^0.4.9", + "tui-editor": "^1.2.6" + } + }, + "almond": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/almond/-/almond-0.3.3.tgz", + "integrity": "sha1-oOfJWsdiTWQXtElLHmi/9pMWiiA=" + }, + "anchor-js": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/anchor-js/-/anchor-js-4.1.1.tgz", + "integrity": "sha512-c2Wl9F1X0C4jkYKLla1SNE2uI6xJrSKsRC7HCCg4yLNQ5sL5D+tDEWrjRaoTuTlMTqBCnF6kOuR3dx59Erxpvw==" + }, + "ansi-colors": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", + "requires": { + "ansi-wrap": "^0.1.0" + } + }, + "ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=" + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + }, + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=" + }, + "array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=" + }, + "array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==" + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + }, + "babel-polyfill": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", + "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", + "requires": { + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "regenerator-runtime": "^0.10.5" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + } + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "beeper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=" + }, + "bootstrap": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.1.3.tgz", + "integrity": "sha512-rDFIzgXcof0jDyjNosjv4Sno77X4KuPeFxG2XZZv1/Kc8DRVGVADdoQyyOVDwPqL36DDmtCQbrpMCqvpPLJQ0w==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "clipboard": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.4.tgz", + "integrity": "sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ==", + "requires": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=" + }, + "codemirror": { + "version": "5.40.2", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.40.2.tgz", + "integrity": "sha512-yoWuvEiD3v5vTwdoMc/wu/Ld6dh9K/yEiEBTKOPGM+/pN0gTAqFNtrLHv1IJ1UJvzFpNRvMi92XCi3+8/iIaEw==" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + }, + "core-js": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "datatables.net": { + "version": "1.10.19", + "resolved": "https://registry.npmjs.org/datatables.net/-/datatables.net-1.10.19.tgz", + "integrity": "sha512-+ljXcI6Pj3PTGy5pesp3E5Dr3x3AV45EZe0o1r0gKENN2gafBKXodVnk2ypKwl2tTmivjxbkiqoWnipTefyBTA==", + "requires": { + "jquery": ">=1.7" + } + }, + "datatables.net-bs4": { + "version": "1.10.19", + "resolved": "https://registry.npmjs.org/datatables.net-bs4/-/datatables.net-bs4-1.10.19.tgz", + "integrity": "sha512-pgeP17w4aPR7HIxIwuJghfqXULjdg1K6xMUUKDyCERJRSNNK4MRToFfELtIsluLNN555YBK4Kx8nihX5/ZT1Fw==", + "requires": { + "datatables.net": "1.10.19", + "jquery": ">=1.7" + } + }, + "dateformat": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", + "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "requires": { + "clone": "^1.0.2" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "delegate": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==" + }, + "deprecated": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz", + "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=" + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=" + }, + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "requires": { + "readable-stream": "~1.1.9" + } + }, + "end-of-stream": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", + "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=", + "requires": { + "once": "~1.3.0" + } + }, + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=" + }, + "es6-object-assign": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", + "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "eve": { + "version": "git://github.com/adobe-webplatform/eve.git#eef80ed8d188423c2272746fb8ae5cc8dad84cb1", + "from": "git://github.com/adobe-webplatform/eve.git#eef80ed" + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-object": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/extend-object/-/extend-object-1.0.0.tgz", + "integrity": "sha1-QlFPhAFdE1bK9Rh5ad+yvBvaCCM=" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "fancy-log": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.2.tgz", + "integrity": "sha1-9BEl49hPLn2JpD0G2VjI94vha+E=", + "requires": { + "ansi-gray": "^0.1.1", + "color-support": "^1.1.3", + "time-stamp": "^1.0.0" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "find-index": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", + "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=" + }, + "findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "fined": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.0.tgz", + "integrity": "sha1-s33IRLdqL15wgeiE98CuNE8VNHY=", + "requires": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + } + }, + "first-chunk-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", + "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=" + }, + "flagged-respawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.0.tgz", + "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=" + }, + "font-awesome": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz", + "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM=" + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "requires": { + "for-in": "^1.0.1" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "gaze": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", + "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=", + "requires": { + "globule": "~0.1.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + }, + "glob": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", + "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^2.0.1", + "once": "^1.3.0" + } + }, + "glob-stream": { + "version": "3.1.18", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", + "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", + "requires": { + "glob": "^4.3.1", + "glob2base": "^0.0.12", + "minimatch": "^2.0.1", + "ordered-read-streams": "^0.1.0", + "through2": "^0.6.1", + "unique-stream": "^1.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + } + } + }, + "glob-watcher": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz", + "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=", + "requires": { + "gaze": "^0.5.1" + } + }, + "glob2base": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", + "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", + "requires": { + "find-index": "^0.1.1" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globule": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", + "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", + "requires": { + "glob": "~3.1.21", + "lodash": "~1.0.1", + "minimatch": "~0.2.11" + }, + "dependencies": { + "glob": { + "version": "3.1.21", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", + "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", + "requires": { + "graceful-fs": "~1.2.0", + "inherits": "1", + "minimatch": "~0.2.11" + } + }, + "graceful-fs": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", + "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=" + }, + "inherits": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", + "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=" + }, + "minimatch": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", + "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", + "requires": { + "lru-cache": "2", + "sigmund": "~1.0.0" + } + } + } + }, + "glogg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.1.tgz", + "integrity": "sha512-ynYqXLoluBKf9XGR1gA59yEJisIL7YHEH4xr3ZziHB5/yl4qWfaK8Js9jGe6gBGCSCKVqiyO30WnRZADvemUNw==", + "requires": { + "sparkles": "^1.0.0" + } + }, + "good-listener": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", + "requires": { + "delegate": "^3.1.2" + } + }, + "graceful-fs": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz", + "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", + "requires": { + "natives": "^1.1.0" + } + }, + "gulp": { + "version": "3.9.1", + "resolved": "http://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz", + "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=", + "requires": { + "archy": "^1.0.0", + "chalk": "^1.0.0", + "deprecated": "^0.0.1", + "gulp-util": "^3.0.0", + "interpret": "^1.0.0", + "liftoff": "^2.1.0", + "minimist": "^1.1.0", + "orchestrator": "^0.3.0", + "pretty-hrtime": "^1.0.0", + "semver": "^4.1.0", + "tildify": "^1.0.0", + "v8flags": "^2.0.2", + "vinyl-fs": "^0.3.0" + } + }, + "gulp-util": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", + "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", + "requires": { + "array-differ": "^1.0.0", + "array-uniq": "^1.0.2", + "beeper": "^1.0.0", + "chalk": "^1.0.0", + "dateformat": "^2.0.0", + "fancy-log": "^1.1.0", + "gulplog": "^1.0.0", + "has-gulplog": "^0.1.0", + "lodash._reescape": "^3.0.0", + "lodash._reevaluate": "^3.0.0", + "lodash._reinterpolate": "^3.0.0", + "lodash.template": "^3.0.0", + "minimist": "^1.1.0", + "multipipe": "^0.1.2", + "object-assign": "^3.0.0", + "replace-ext": "0.0.1", + "through2": "^2.0.0", + "vinyl": "^0.5.0" + } + }, + "gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "requires": { + "glogg": "^1.0.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "requires": { + "sparkles": "^1.0.0" + } + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "highlight.js": { + "version": "9.13.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.13.1.tgz", + "integrity": "sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A==" + }, + "homedir-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", + "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=" + }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "requires": { + "is-unc-path": "^1.0.0" + } + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "jquery": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz", + "integrity": "sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg==" + }, + "jquery-form": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/jquery-form/-/jquery-form-4.2.2.tgz", + "integrity": "sha512-HJTef7DRBSg8ge/RNUw8rUTTtB3l8ozO0OhD16AzDl+eIXp4skgCqRTd9fYPsOzL+pN6+1B9wvbTLGjgikz8Tg==", + "requires": { + "jquery": ">=1.7.2" + } + }, + "jquery-mousewheel": { + "version": "3.1.13", + "resolved": "https://registry.npmjs.org/jquery-mousewheel/-/jquery-mousewheel-3.1.13.tgz", + "integrity": "sha1-BvAzXxbjU6aV5yBr9QUDy1I6buU=" + }, + "jquery-validation": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/jquery-validation/-/jquery-validation-1.18.0.tgz", + "integrity": "sha512-+MK0pvoegfLrJnwtCU6tx305Vgp9HWevpmdVwDf5TthmINkn0wqqLD0bpa75EERlHsBBjMmza//ppx5ZQPnW3Q==", + "requires": { + "jquery": "^1.7 || ^2.0 || ^3.1" + } + }, + "jquery-validation-unobtrusive": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.2.11.tgz", + "integrity": "sha512-3FQPllaWdD+Aq55zJLGSW39+eXPDz1HhwAvrSwYi8zHQ8DVcu5IJ1HVeTiCl0BnCnrIBvfFU3zEB/DrGdcoRIQ==", + "requires": { + "jquery": ">=1.8", + "jquery-validation": ">=1.16" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + }, + "liftoff": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", + "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", + "requires": { + "extend": "^3.0.0", + "findup-sync": "^2.0.0", + "fined": "^1.0.1", + "flagged-respawn": "^1.0.0", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.0", + "rechoir": "^0.6.2", + "resolve": "^1.1.7" + } + }, + "linkify-it": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.0.3.tgz", + "integrity": "sha1-2UpGSPmxwXnWT6lykSaL22zpQ08=", + "requires": { + "uc.micro": "^1.0.1" + } + }, + "lodash": { + "version": "1.0.2", + "resolved": "http://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", + "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=" + }, + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=" + }, + "lodash._basetostring": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", + "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=" + }, + "lodash._basevalues": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", + "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=" + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=" + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=" + }, + "lodash._reescape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", + "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=" + }, + "lodash._reevaluate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", + "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=" + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + }, + "lodash._root": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=" + }, + "lodash.escape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", + "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", + "requires": { + "lodash._root": "^3.0.0" + } + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "requires": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "lodash.restparam": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=" + }, + "lodash.template": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", + "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", + "requires": { + "lodash._basecopy": "^3.0.0", + "lodash._basetostring": "^3.0.0", + "lodash._basevalues": "^3.0.0", + "lodash._isiterateecall": "^3.0.0", + "lodash._reinterpolate": "^3.0.0", + "lodash.escape": "^3.0.0", + "lodash.keys": "^3.0.0", + "lodash.restparam": "^3.0.0", + "lodash.templatesettings": "^3.0.0" + } + }, + "lodash.templatesettings": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", + "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.escape": "^3.0.0" + } + }, + "lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=" + }, + "make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "requires": { + "kind-of": "^6.0.2" + } + }, + "malihu-custom-scrollbar-plugin": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.5.tgz", + "integrity": "sha1-MQzsxeWUFaHCnp37XStuAdZqKe8=", + "requires": { + "jquery-mousewheel": ">=3.0.6" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "requires": { + "object-visit": "^1.0.0" + } + }, + "markdown-it": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", + "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", + "requires": { + "argparse": "^1.0.7", + "entities": "~1.1.1", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" + }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "requires": { + "readable-stream": "^2.0.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "minimatch": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", + "requires": { + "brace-expansion": "^1.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "multipipe": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "requires": { + "duplexer2": "0.0.2" + } + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natives": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.6.tgz", + "integrity": "sha512-6+TDFewD4yxY14ptjKaS63GVdtKiES1pTPyxn9Jb0rBqPMZ7VcCiooEhPNsr+mqHtMGxa/5c/HhcC4uPEUw/nA==" + }, + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "requires": { + "isobject": "^3.0.0" + } + }, + "object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "requires": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "requires": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", + "requires": { + "wrappy": "1" + } + }, + "orchestrator": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz", + "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=", + "requires": { + "end-of-stream": "~0.1.5", + "sequencify": "~0.0.7", + "stream-consume": "~0.1.0" + } + }, + "ordered-read-streams": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz", + "integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=" + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "owl.carousel": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/owl.carousel/-/owl.carousel-2.3.4.tgz", + "integrity": "sha512-JaDss9+feAvEW8KZppPSpllfposEzQiW+Ytt/Xm5t/3CTJ7YVmkh6RkWixoA2yXk2boIwedYxOvrrppIGzru9A==", + "requires": { + "jquery": ">=1.8.3" + } + }, + "pako": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.3.tgz", + "integrity": "sha1-X1FbDGci4ZgpIK6ABerLC3ynPM8=" + }, + "parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "requires": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + }, + "path": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", + "integrity": "sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=", + "requires": { + "process": "^0.11.1", + "util": "^0.10.3" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "requires": { + "path-root-regex": "^0.1.0" + } + }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=" + }, + "plantuml-encoder": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/plantuml-encoder/-/plantuml-encoder-1.2.5.tgz", + "integrity": "sha512-viV7Sz+BJNX/sC3iyebh2VfLyAZKuu3+JuBs2ISms8+zoTGwPqwk3/WEDw/zROmGAJ/xD4sNd8zsBw/YmTo7ng==", + "requires": { + "pako": "1.0.3", + "utf8-bytes": "0.0.1" + } + }, + "popper.js": { + "version": "1.14.6", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.6.tgz", + "integrity": "sha512-AGwHGQBKumlk/MDfrSOf0JHhJCImdDMcGNoqKmKkU+68GFazv3CQ6q9r7Ja1sKDZmYWTckY/uLyEznheTDycnA==" + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" + }, + "pretty-hrtime": { + "version": "1.0.3", + "resolved": "http://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" + }, + "prismjs": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.15.0.tgz", + "integrity": "sha512-Lf2JrFYx8FanHrjoV5oL8YHCclLQgbJcVZR+gikGGMqz6ub5QVWDTM6YIwm3BuPxM/LOV+rKns3LssXNLIf+DA==", + "requires": { + "clipboard": "^2.0.0" + } + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "promise-polyfill": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.1.0.tgz", + "integrity": "sha1-36lpQ+qcEh/KTem1hoyznTRy4Fc=" + }, + "raphael": { + "version": "git+https://github.com/nhnent/raphael.git#78a6ed3ec269f33b6457b0ec66f8c3d1f2ed70e0", + "from": "git+https://github.com/nhnent/raphael.git#2.2.0-c", + "requires": { + "eve": "git://github.com/adobe-webplatform/eve.git#eef80ed8d188423c2272746fb8ae5cc8dad84cb1" + } + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "requires": { + "resolve": "^1.1.6" + } + }, + "regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=" + }, + "resize-observer-polyfill": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.0.tgz", + "integrity": "sha512-M2AelyJDVR/oLnToJLtuDJRBBWUGUvvGigj1411hXhAdyFWqMaqHp7TixW3FpiLuVaikIcR1QL+zqoJoZlOgpg==" + }, + "resolve": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", + "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "requires": { + "path-parse": "^1.0.5" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "requires": { + "glob": "^7.0.5" + }, + "dependencies": { + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "requires": { + "ret": "~0.1.10" + } + }, + "select": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", + "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=" + }, + "select2": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/select2/-/select2-4.0.5.tgz", + "integrity": "sha1-eqxQaSVhmFs007guxV4ib4lg1Ao=", + "requires": { + "almond": "~0.3.1", + "jquery-mousewheel": "~3.1.13" + } + }, + "semver": { + "version": "4.3.6", + "resolved": "http://registry.npmjs.org/semver/-/semver-4.3.6.tgz", + "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=" + }, + "sequencify": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz", + "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=" + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" + }, + "sparkles": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", + "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==" + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "squire-rte": { + "version": "github:neilj/Squire#306230d0df9b38047cd06204476ddc0582569cfd", + "from": "github:neilj/Squire#306230d0df9b38047cd06204476ddc0582569cfd" + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stream-consume": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.1.tgz", + "integrity": "sha512-tNa3hzgkjEP7XbCkbRXe1jpg+ievoa0O4SCFlMOYEscGSS4JJsckGL8swUyAa/ApGU3Ae4t6Honor4HhL+tRyg==" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz", + "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=", + "requires": { + "first-chunk-stream": "^1.0.0", + "is-utf8": "^0.2.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "sweetalert": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sweetalert/-/sweetalert-2.1.0.tgz", + "integrity": "sha512-9YKj0SvjKyBfRWco50UOsIbXVeifYbxzT9Qda7EsqC01eafHGCSG0IR7g942ufjzt7lnwO8ZZBwr6emXv2fQrg==", + "requires": { + "es6-object-assign": "^1.1.0", + "promise-polyfill": "^6.0.2" + } + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "requires": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "tildify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", + "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", + "requires": { + "os-homedir": "^1.0.0" + } + }, + "time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=" + }, + "timeago": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/timeago/-/timeago-1.6.3.tgz", + "integrity": "sha512-x97d1X1KsNapWJTgCOOAy/59XagYu2WsDTAH/yvPsWi5bqtGbLPaVZBv3HZ3jTpakHR+JGGyrI9qC0yuvIAvnQ==", + "requires": { + "jquery": ">=1.2.3" + } + }, + "tiny-emitter": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.0.2.tgz", + "integrity": "sha512-2NM0auVBGft5tee/OxP4PI3d8WItkDM+fPnaRAVo6xTDI2knbz9eC5ArWGqtGlYqiH3RU5yMpdyTTO7MguC4ow==" + }, + "to-mark": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/to-mark/-/to-mark-1.1.3.tgz", + "integrity": "sha512-Wai0j2IPk5vEsuPHgTBjK/xzGwUAmddUbUVLZgAvOiTZKEJwmVHRdEHO3yTta4LxgY4W9761sP1MkAZbYVXcig==" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "toastr": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/toastr/-/toastr-2.1.4.tgz", + "integrity": "sha1-i0O+ZPudDEFIcURvLbjoyk6V8YE=", + "requires": { + "jquery": ">=1.12.0" + } + }, + "tui-chart": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/tui-chart/-/tui-chart-3.4.0.tgz", + "integrity": "sha512-gPIJ1SsPhISj/SlzysA9fkLJMlnPV1PLaUE+gxUioZaDtfoZ+TxSE+Vs1rOvoXUUmT/v5+qlH2iM2fkaLvDU0A==", + "requires": { + "babel-polyfill": "^6.26.0", + "raphael": "git+https://github.com/nhnent/raphael.git#78a6ed3ec269f33b6457b0ec66f8c3d1f2ed70e0", + "tui-code-snippet": "^1.4.0" + } + }, + "tui-code-snippet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/tui-code-snippet/-/tui-code-snippet-1.4.0.tgz", + "integrity": "sha512-a7XzHRbRDi6Tt4lGcopq6ctQjVrzmnw9JMoTFqur5gczgtw5tmgUqXHjg8D9IonDkzZNq5gYLhkzykx4fmn+GA==" + }, + "tui-color-picker": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tui-color-picker/-/tui-color-picker-2.2.0.tgz", + "integrity": "sha512-oAzMxF19bDExbvv7jVWQBPlrJ8sO3jQe+1rHqKkM4FtpvtGNlJO/ty19LW6pk9CCi1y43cgoG3QUt41ctGmygQ==", + "requires": { + "tui-code-snippet": "^1.3.0" + } + }, + "tui-editor": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/tui-editor/-/tui-editor-1.2.6.tgz", + "integrity": "sha512-sVvs8yx3G1a/+YbR4VxzzfHFxPIPgattai+RDAHaUYeDkRhFPi3LeKN8A89jPyvUhyM8NhZWlhVd8ZTYx9ykNg==", + "requires": { + "codemirror": "^5.33.0", + "highlight.js": "^9.12.0", + "jquery": "^3.3.1", + "markdown-it": "^8.4.0", + "plantuml-encoder": "^1.2.5", + "resize-observer-polyfill": "^1.5.0", + "squire-rte": "github:neilj/Squire#306230d0df9b38047cd06204476ddc0582569cfd", + "to-mark": "^1.1.2", + "tui-chart": "^3.0.1", + "tui-code-snippet": "^1.3.0", + "tui-color-picker": "^2.2.0" + } + }, + "uc.micro": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.5.tgz", + "integrity": "sha512-JoLI4g5zv5qNyT09f4YAvEZIIV1oOjqnewYg5D38dkQljIzpPT296dbIGvKro3digYI1bkb7W6EP1y4uDlmzLg==" + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=" + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unique-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", + "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=" + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + } + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + }, + "user-home": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", + "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=" + }, + "utf8-bytes": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/utf8-bytes/-/utf8-bytes-0.0.1.tgz", + "integrity": "sha1-EWsCVEjJtQAIHN+/H01sbDfYg30=" + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "v8flags": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", + "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", + "requires": { + "user-home": "^1.1.1" + } + }, + "vinyl": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", + "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", + "requires": { + "clone": "^1.0.0", + "clone-stats": "^0.0.1", + "replace-ext": "0.0.1" + } + }, + "vinyl-fs": { + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz", + "integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=", + "requires": { + "defaults": "^1.0.0", + "glob-stream": "^3.1.5", + "glob-watcher": "^0.0.6", + "graceful-fs": "^3.0.0", + "mkdirp": "^0.5.0", + "strip-bom": "^1.0.0", + "through2": "^0.6.1", + "vinyl": "^0.4.0" + }, + "dependencies": { + "clone": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", + "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "vinyl": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", + "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", + "requires": { + "clone": "^0.2.0", + "clone-stats": "^0.0.1" + } + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + } + } +} diff --git a/docs/en/Modules/Docs.md b/docs/en/Modules/Docs.md index adfcd15453..f99e5ca320 100644 --- a/docs/en/Modules/Docs.md +++ b/docs/en/Modules/Docs.md @@ -1,9 +1,475 @@ # Docs Module -Docs module is used to create technical documentation pages. ABP's [own documentation](https://abp.io/documents/) already using this module. +## What is Docs Module? + +Docs module is an application module for ABP framework. It simplifies software documentation. This module is free and open-source. + +### Integration + +Currently docs module provides you to store your docs both on GitHub and file system. + +### Hosting + +Docs module is an application module and does not offer any hosting solution. You can host your docs on-premise or on cloud. + +### Versioning + +When you use GitHub to store your docs, Docs Module supports versioning. If you have multiple versions for your docs, there will be a combo-box on the UI to switch between versions. If you choose file system to store your docs, it does not support multiple versions. + +[The documents](https://abp.io/documents/) for ABP framework is also using this module. > Docs module follows the [module architecture best practices](../Best-Practices/Module-Architecture.md) guide. + + ## Installation -TODO... \ No newline at end of file +### 1- Download + +If you do not have an existing ABP project, this step shows you how to create a new project from [abp.io](https://abp.io) to add the Docs Module. If you already have an ABP project, you can skip this step. + +Navigate to https://abp.io/Templates. Enter your project name as `Acme.MyProject`, select `ASP.NET Core Mvc Application` and select `Entity Framework Core` for the database provider. + +Note that this document covers `Entity Framework Core` provider but you can also select `MongoDB` as your database provider. + +![Create new project](..\images\docs-module_download-new-abp-project.png) + +### 2- Running The Empty Application + +After you download the project, extract the ZIP file and open `Acme.MyProject.sln`. You will see that the solution consists of `Application`, `Domain `, `EntityFrameworkCore` and `Web` projects. Right click on `Acme.MyProject.Web` project and **Set as StartUp Project**. + +![Create a new project](..\images\docs-module_solution-explorer.png) + +The database connection string is located in `appsettings.json` of your `Acme.MyProject.Web` project. If you have a different database configuration, change the connection string. + +```json +{ + "ConnectionStrings": { + "Default": "Server=localhost;Database=MyProject;Trusted_Connection=True;MultipleActiveResultSets=true" + } +} +``` + + + +Open `Package Manager Console` in the Visual Studio and choose `src\Acme.MyProject.EntityFrameworkCore` as the default project. Run `Update-Database` command to create your new database. The database `MyProject` will be created in your database server. + +Now an empty ABP project has been created! You can now run your project and see the empty website. + +To login your website enter `admin` as the username and `1q2w3E*` as the password. + +### 2- Referencing Docs Module Packages + +Docs module packages are hosted on NuGet. There are 4 packages that needs be to installed to your application. Each package has to be installed to the relevant project. + +* [Volo.Docs.Domain](https://www.nuget.org/packages/Volo.Docs.Domain/) needs to be referenced to `Acme.MyProject.Domain` project. + + * Edit `Acme.MyProject.Domain.csproj`file and add the below line to as a reference. Note that you need to change version (v0.9.0) to the latest. + + ```csharp + + ``` +* [Volo.Docs.EntityFrameworkCore](https://www.nuget.org/packages/Volo.Docs.EntityFrameworkCore/) needs to be referenced to `Acme.MyProject.EntityFrameworkCore` project. + + - Edit `Acme.MyProject.EntityFrameworkCore.csproj`file and add the below line to as a reference. Note that you need to change version (v0.9.0) to the latest. + + ```csharp + + ``` +* [Volo.Docs.Application](https://www.nuget.org/packages/Volo.Docs.Application/) needs to be referenced to `Acme.MyProject.Application` project. + + * Edit `Acme.MyProject.Application.csproj`file and add the below line to as a reference. Note that you need to change version (v0.9.0) to the latest. + + ```csharp + + ``` +* [Volo.Docs.Web ](https://www.nuget.org/packages/Volo.Docs.Web/)needs to be referenced to `Acme.MyProject.Web` project. + + - Edit `Acme.MyProject.Web.csproj`file and add the below line to as a reference. Note that you need to change version (v0.9.0) to the latest. + + ```csharp + + ``` + + + +### 3- Adding Module Dependencies + +An ABP module must declare `[DependsOn]` attribute if it has a dependency upon another module. Each module has to be added in`[DependsOn]` attribute to the relevant project. + +* Open `MyProjectDomainModule.cs`and add `typeof(DocsDomainModule)` as shown below; + + ```csharp + [DependsOn( + typeof(DocsDomainModule), + typeof(AbpIdentityDomainModule), + typeof(AbpAuditingModule), + typeof(BackgroundJobsDomainModule), + typeof(AbpAuditLoggingDomainModule) + )] + public class MyProjectDomainModule : AbpModule + { + //... + } + ``` + +* Open `MyProjectEntityFrameworkCoreModule.cs`and add `typeof(DocsEntityFrameworkCoreModule)` as shown below; + + ```csharp + [DependsOn( + typeof(DocsEntityFrameworkCoreModule), + typeof(MyProjectDomainModule), + typeof(AbpIdentityEntityFrameworkCoreModule), + typeof(AbpPermissionManagementEntityFrameworkCoreModule), + typeof(AbpSettingManagementEntityFrameworkCoreModule), + typeof(AbpEntityFrameworkCoreSqlServerModule), + typeof(BackgroundJobsEntityFrameworkCoreModule), + typeof(AbpAuditLoggingEntityFrameworkCoreModule) + )] + public class MyProjectEntityFrameworkCoreModule : AbpModule + { + //... + } + ``` + + +* Open `MyProjectApplicationModule.cs`and add `typeof(DocsApplicationModule)` as shown below; + + ```csharp + [DependsOn( + typeof(DocsApplicationModule), + typeof(MyProjectDomainModule), + typeof(AbpIdentityApplicationModule))] + public class MyProjectApplicationModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.DefinitionProviders.Add(); + }); + + Configure(options => + { + options.AddProfile(); + }); + } + } + ``` + + +* Open `MyProjectWebModule.cs`and add `typeof(DocsWebModule)` as shown below; + + ```csharp + [DependsOn( + typeof(DocsWebModule), + typeof(MyProjectApplicationModule), + typeof(MyProjectEntityFrameworkCoreModule), + typeof(AbpAutofacModule), + typeof(AbpIdentityWebModule), + typeof(AbpAccountWebModule), + typeof(AbpAspNetCoreMvcUiBasicThemeModule) + )] + public class MyProjectWebModule : AbpModule + { + //... + } + ``` + + + +### 4- Database Integration + +#### 4.1- Entity Framework Integration + +If you choose Entity Framework as your database provider, you need to configure the Docs Module in your DbContext. To do this; + +- Open `MyProjectDbContext.cs` and add `modelBuilder.ConfigureDocs()` to the `OnModelCreating()` + + ```csharp + [ConnectionStringName("Default")] + public class MyProjectDbContext : AbpDbContext + { + public MyProjectDbContext(DbContextOptions options) + : base(options) + { + + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + //... + modelBuilder.ConfigureDocs(); + } + } + ``` + +* Open `Package Manager Console` in `Visual Studio` and choose `Acme.MyProject.EntityFrameworkCore` as default project. Then write the below command to add the migration for Docs Module. + + ```csharp + add-migration Added_Docs_Module + ``` + + When the command successfully executes , you will see a new migration file named as `20181221111621_Added_Docs_Module` in the folder `Acme.MyProject.EntityFrameworkCore\Migrations`. + + Now, update the database for Docs module database changes. To do this run the below code on `Package Manager Console` in `Visual Studio`. Be sure `Acme.MyProject.EntityFrameworkCore` is still default project. + + ```csharp + update-database + ``` + + Finally, you can check your database to see the newly created tables. For example you can see `DocsProjects` table must be added to your database. + + +### 5- Linking Docs Module + +The default route for Docs module is; + +``` +/Documents +``` + +To add Docs module link to your application menu; + +* Open `MyProjectMenuContributor.cs` and add the below line to the method `ConfigureMainMenuAsync()`. + + ```csharp + context.Menu.Items.Add(new ApplicationMenuItem("MyProject.Docs", l["Menu:Docs"], "/Documents")); + ``` + + Final look of **MyProjectMenuContributor.cs** + + ```csharp + private async Task ConfigureMainMenuAsync(MenuConfigurationContext context) + { + var l = context.ServiceProvider.GetRequiredService>(); + + context.Menu.Items.Insert(0, new ApplicationMenuItem("MyProject.Home", l["Menu:Home"], "/")); + + context.Menu.Items.Add(new ApplicationMenuItem("MyProject.Docs", l["Menu:Docs"], "/Documents")); + } + ``` + +The `Menu:Docs` keyword is a localization key. To localize the menu text, open `Localization\MyProject\en.json` in the project `Acme.MyProject.Domain`. And add the below line + +```json +"Menu:Docs": "Documents" +``` + +Final look of **en.json** + +```json +{ + "culture": "en", + "texts": { + "Menu:Home": "Home", + "Welcome": "Welcome", + "LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP framework. For more information, visit abp.io.", + "Menu:Docs": "Documents" + } +} +``` + +The new menu item for Docs Module is added to the menu. Run your web application and browse to `http://localhost:YOUR_PORT_NUMBER/documents` URL. + +You will see a warning says; + +``` +There are no projects yet! +``` + +As we have not added any projects yet, this warning is normal. + +### 6- Adding New Docs Project + +Open `DocsProjects` in your database, and insert a new record with the following field information; + +* **Name**: The display name of the document name which will be shown on the web page. +* **ShortName**: A short and URL friendly name that will be used in your docs URL. +* **Format**: The format of the document (for Markdown: `md`, for HTML: `html`) +* **DefaultDocumentName**: The document for the initial page. +* **NavigationDocumentName**: The document to be used for the navigation menu (index). +* **MinimumVersion**: The minimum version to show the docs. Below version will not be listed. +* **DocumentStoreType**: The source of the documents (for GitHub:`GitHub`, for file system`FileSystem`) +* **ExtraProperties**: A serialized `JSON` that stores special configuration for the selected `DocumentStoreType`. +* **MainWebsiteUrl**: The URL when user clicks to the logo of the Docs module page. You can simply set as `/` to link to your website root address. +* **LatestVersionBranchName**: This is a config for GitHub. It's the branch name which to retrieve the docs. You can set it as `master`. + +#### Sample Project Record for "GitHub" + +You can use [ABP Framework](https://github.com/abpframework/abp/) GitHub documents to configure your GitHub document store. + +- Name: `ABP framework (GitHub)` + +- ShortName: `abp` + +- Format: `md` + +- DefaultDocumentName: `Index` + +- NavigationDocumentName: `docs-nav.json` + +- MinimumVersion: `` (no minimum version) + +- DocumentStoreType: `GitHub` + +- ExtraProperties: + + ```json + {"GitHubRootUrl":"https://github.com/abpframework/abp/tree/{version}/docs/en/","GitHubAccessToken":"***"} + ``` + + Note that `GitHubAccessToken` is masked with `***`. It's a private token that you must get it from GitHub. See https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/ + +- MainWebsiteUrl: `/` + +- LatestVersionBranchName: `master` + +For `SQL` databases, you can use the below `T-SQL` command to insert the specified sample into your `DocsProjects` table: + +```mssql +INSERT [dbo].[DocsProjects] ([Id], [Name], [ShortName], [Format], [DefaultDocumentName], [NavigationDocumentName], [MinimumVersion], [DocumentStoreType], [ExtraProperties], [MainWebsiteUrl], [LatestVersionBranchName]) VALUES (N'12f21123-e08e-4f15-bedb-ae0b2d939658', N'ABP framework (GitHub)', N'abp', N'md', N'Index', N'docs-nav.json', NULL, N'GitHub', N'{"GitHubRootUrl":"https://github.com/abpframework/abp/tree/{version}/docs/en/","GitHubAccessToken":"***"}', N'/', N'master') +``` + +Be aware that `GitHubAccessToken` is masked. It's a private token and you must get your own token and replace the `***` string. + +#### Sample Project Record for "FileSystem" + +You can use [ABP Framework](https://github.com/abpframework/abp/) GitHub documents to configure your GitHub document store. + +- Name: `ABP framework (FileSystem)` + +- ShortName: `abp` + +- Format: `md` + +- DefaultDocumentName: `Index` + +- NavigationDocumentName: `docs-nav.json` + +- MinimumVersion: `` (no minimum version) + +- DocumentStoreType: `FileSystem` + +- ExtraProperties: + + ```json + {"Path":"C:\\Github\\abp\\docs\\en"} + ``` + + Note that `Path` must be replaced with your local docs directory. You can fetch the ABP Framework's documents from https://github.com/abpframework/abp/tree/master/docs/en and copy to the directory `C:\\Github\\abp\\docs\\en` to get it work. + +- MainWebsiteUrl: `/` + +- LatestVersionBranchName: `` + +For `SQL` databases, you can use the below `T-SQL` command to insert the specified sample into your `DocsProjects` table: + +```mssql +INSERT [dbo].[DocsProjects] ([Id], [Name], [ShortName], [Format], [DefaultDocumentName], [NavigationDocumentName], [MinimumVersion], [DocumentStoreType], [ExtraProperties], [MainWebsiteUrl], [LatestVersionBranchName]) VALUES (N'12f21123-e08e-4f15-bedb-ae0b2d939659', N'ABP framework (FileSystem)', N'abp', N'md', N'Index', N'docs-nav.json', NULL, N'FileSystem', N'{"Path":"C:\\Github\\abp\\docs\\en"}', N'/', NULL) +``` + + + +Add one of the sample projects above and run the application. In the menu you will see `Documents` link, click the menu link to open the documents page. + +So far, we have created a new application from abp.io website and made it up and ready for Docs module. + +### 7- Creating a New Document + +In the sample Project records, you see that `Format` is specified as `md` which refers to [Mark Down](https://en.wikipedia.org/wiki/Markdown). You can see the mark down cheat sheet following the below link; + +https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet + +ABP Docs Module can render mark down to HTML. + +Now let's have a look a sample document in markdown format. + +~~~markdown +# This is a header + +Welcome to Docs Module. + +## This is a sub header + + [This is a link](https://abp.io) + +![This is an image](https://abp.io/assets/my-image.png) + +## This is a code block + +```csharp +public class Person +{ + public string Name { get; set; } + + public string Address { get; set; } +} +``` +~~~ + + + +As an example you can see ABP Framework documentation: + +https://github.com/abpframework/abp/blob/master/docs/en/ + +### 8- Creating the Navigation Document + +Navigation document is the main menu of the documents page. It is located on the left side of the page. It is a `JSON` file. Take a look at the below sample navigation document to understand the structure. + +```json +{ + "items":[ + { + "text":"Sample Menu Item - 1", + "items":[ + { + "text":"Sample Menu Item - 1.1", + "items":[ + { + "text":"Sample Menu Item - 1.1.1", + "path":"SampleMenuItem_1_1_1.md" + } + ] + }, + { + "text":"Sample Menu Item - 1.2", + "items":[ + { + "text":"Sample Menu Item - 1.2.1", + "path":"SampleMenuItem_1_2_1.md" + }, + { + "text":"Sample Menu Item - 1.2.2", + "path":"SampleMenuItem_1_2_2.md" + } + ] + } + ] + }, + { + "text":"Sample Menu Item - 2", + "items":[ + { + "text":"Sample Menu Item - 2.1", + "items":[ + { + "text":"Sample Menu Item - 2.1.1", + "path":"SampleMenuItem_2_1_1.md" + } + ] + } + ] + } + ] +} +``` + +The upper sample `JSON` file renders the below navigation menu as `HTML`. + +![Create a new project](..\images\docs-module_download-sample-navigation-menu.png) + + + +Finally a new Docs Module is added to your project which is feeded with GitHub. \ No newline at end of file diff --git a/docs/en/images/docs-module_download-new-abp-project.png b/docs/en/images/docs-module_download-new-abp-project.png new file mode 100644 index 0000000000000000000000000000000000000000..0da3b7a67a367c4cbd9272b0488e2e36a5bb9551 GIT binary patch literal 20225 zcmd43c{H1E*FTynO0`u((JCobLrtZInp;CrLrgW35L0Wasu)AH)J##T#u`cyGciZ1 z=6NV${+6ODXrw|Ck&`~}dCofP{Bxf7w|?(g=Z~zc`@WLvzJ|R&d+*QQ*BxhKtb6hN zwetV~;G({swiy6$21EO-Ffr2Z+AR=bEe<-vkL%VoT;z z&u;s3;$F$!*k$^&SMWN~#y8w9FeeRao5{|;e8s^#S<}b01~Fs)TzLP<2qf!Uw53(j zBe_%$O{e$@^O;YNKe;}(X>y}1g;u$%dG1q)xeepQu(9Ayi0R>cC?zQ0y^7Ltv`_%t z;`loWx*%|&*X91Lj)f^6_h;MhbNz?5GsJ>8nAs z+9ZKm4wUfC1{7=y@EJ6$PARhUKm>o{(45mnc%^KAdg?j;A#nDw`}pYswoB?5_mA;;gm@rO=Kb0S zg-{a+{`vCJ$b6tPdDmrwp71JopI0#^Yw0zb&P#Ea1xuV8c|9j`hQf<~+-?phCf(gM zYYuI38SBDl6Sox!AI60WJ5OUan*uoJ*T+Ao6tk*G)fTk$=AO<(2UYj(abl7p)SXu% zOr`hL4x{Fe!#Fvtsw2MTw)2oNQkKS$hJcr}2dNmG#{x${8bBRTIjP&*ZVu_!*?ARA&98ZJs2Couz`t5~qZXhtXhuigTW>z+ zN9i%z`~o&g9X8n9Xs4|r$|d}T9KR#Cr8We#e30i8BX{ySsOCIkPk&?F5$+L6>yLbVG-^d5 z=M~(I2wguKO<_%7TZ&2I?^+EbH&9zc|D4RtEr#z0k9EKVXP-PD>MzB=3tVl3a*wq3M_i_$=5sqHNnzGlSWT|nR({ApZd>6h8=2K?83)C$ z*l~~a*V%q~r`v;EJpx9cb4gf9c-PFWmKi>3O)!M{S6{d#YkDR(wIXzj% zsADHT`wT5+XsWRhnl~a+%7QKR;uYe?q|dUFNu(@^oRs)}dIBPNe{T`m?fs6o;LcV& zYPY4}!d3_072TqswgWzYOSXg*mAWu=hhl(d>joY9rINp|a5iemd5m)hd$l2z-cV98 z$NZ?vb~P%I2^-V}mf;=G|JJ)mJd}SDXk!fDswLi;eF!-N%a3LthW$dKVFz*I>=Te^@D(hD7Nn-%Ke4TEUxjVdxBi2gO4a@+vt!p4zv6&vA^dDw{Ql-SDS8;EJx(OASMOGT zjUTG-`AIITN`nu zO5~)|z8~K@Ycj(xFnLYxyR&9B=#IO23hf_>BdeCE;MzJ6@SodT*!2XMZrHx!x{~K~ zdh31notL^jfW@(HI`V>=er&jhV{*TO4o$(yJ-5bVEZkZUNd2|y~)!s zgI1m&K+d*5-DmwqLe7PJPrY%utU3iYALU3`W?AiPfEK(Ovo?Wf1pQKRpqQrsQ*D92P^L54ekN%a|Cqc#pW(fW!c)jbNtipwf$ATep0)8NW?X|P~1GQC%oTBDmf>j zOMtN0tEd9oFA|LVyWZl5u`NvvnY7<_MN78 zB`{$nkXITRkd)6Y0=3JRUZk4E8-;M%{~V`4_; z=iY&cNZ9+Ul=Tf9D;@l|%YvjQu;h0C&y`Tek{7S;$x)&IG7>a7-b)9kXx1G9pFd^x zlK#c=?orQJPT(cV$Vm#ExPMD=h>osZ9(hqF4KkzKdogm99umUVuC!t5dvxmASi^BU z=UeAQK)2LNL$0Q9tyb5M7khauo5h77Vc#b7(*Ry*qsF9)$z|)8P3}&S^19UCFq!kc z&fsY!X#VmR%9o^tpLTBmoddC9LZ?Mu0&NcJ{uGQfG!NALJV_#wd6$l!17$QQM9>g2Nn=&W;fdZn8bH}1m=Feiy)|_3^|wmReys)z?^l9nPC^OkVH?tCZ`H5z5p;;~HAAnk z!N8D&+A2D`(}BL9(n>Z3Lpi+!9-w*c45&qtLslyVHzu zO4n2MSkL1j;`+R_(jbs;aC5uVeI&Y3_zc9(+7ZI%4!*0AxmJ=n{y{ooodI7Biv(S< z9{yBJonm=hX-{1pmEI`JSq*mj5%{VK9!Om{IaoR7A(w8AY-8l!?wXmmZbTQ2O(BzL zdu4l|+pAvpC^7((H#)Gt5Q6KZj`k(5x&WE#Z-r--3z1Jt4NkN)YVY(YupppQzHF<@ z)IHz+0iO3uH6FLvyfb!KNfWsT5g>wz0SAgUb5q#LG`29> zy7=XwX1k=z`43)keg9@N@%L{5f472VoxpZ%%>`;SusuQT=%1r{C7Pc&pC(;<7R_TP zSPOvISoEBMSp5wOt}saeTxeiwr*rgV6}KwO_;Q(*rque?Jx504RDaU_Nv%!FGbRAx z4$UZ)1~pLw5Y`nMJ(mEX>@+C4+p<4e3i{aw`on+EECPNGKoFw!2S8t-^#}mmr3C{3 zzzBej1pv5n_J63M_9faUtIU_;k1yBYl_G=d9)p!2)Clx-=8FNP-{xgs?UFC~^vo^l zCoaNu*LP;t2jI;g%0NBbwN=+!$E%ahndgTKF%w)tt4ktw%e9};og^6$1G+8 z>C@K~lg!WgvMBlSTIcQDLsaQdR+54}I8-o~wI4Ua4%V!dEbSo_dx6^am?t~lTu!SO zp7ZTlUz+dUnPEO;*KFVv58#ugwaT#y)Hb|Ecf($xeJ;_%@HcAXf*EG1p4^@iI_M1s zPHreT;-9rCVJ)T2^w=(wZXFJu5Z{5B+Y~mh-xZio|u;{vbw2PqVp3nIjB6h-)<+)u` z5L522v2pFK+}z&Fn);*`;fiDUdROKlT=g)(5^<(0(|fh%ou{qcS!Vh0)aQAk3ew7f z=~xy&iR6ntzBc5!$g2#qj6ykCmqlA4>pNLD@XTUd4mxU)PXtL&qBFno$HA5ADrb;2 z{XD%0u)$^JR?U#F4d_OH^N-Uq2I~c2`h!{DE9-;d?^v3D=`L6`#f7sTXOTHR@7Cza z@Z0K6_Nyy6Uoz8ti{$Em7xk8{uklkuQ@(pZa*?-|ztFnb=y+B{vU7g_R(D}adkdx9 z0W30B3G*5dZY?bxp}h0FFWUyoIDYKC;5V^0S5r9=XxeW!q7&cBo-j-LV_0iSX!y2d zR4?7Q?Fd48%lvCP$P1QDn6Nw^)vD7Q2ZGO#OKyaXgt?UWq;K4?kA$z%9jcK^7UbyB z3ZQf3?c->`2&wZ&{yU!rbml=<_;s7 zP8tu{qi-H5j=4^byO3H5t~UtlJD;z#KSw2GwW#k>@zAQQTYvByJS^j;h#V?-Oef|@ z>ALS2s2>x;!ntmn*#vGV+pFZS(IlxWAKfH0od6x$zvA%le!@(^O^P@+APTh+BI%qy z8W72qa-FSfQ+bf|UvsE7kVI7-OG2s2wSsgzu`KN@;X8D(E*!hUUl+fpM5`}r6Oh|1 z?MiWzv)#$2x+B-01g5WbX!s#4kPzf^ZUzDqq~Bm3!Ss=a^m(!L<$%Gk7njw>@oLY}4_97^7rCz*8-eAWVyqx#$_vZ;I&p*DugB%}TwdQTP=;}CF}t`Q># z)=FA-_mw11EVN`V5HXH^L7Ri)i!C*jFA=c=*IGRd%IJ!(Y& zkd(I56l>IMNhwdB44%VYwHGlMTNWZ~8lKzI&)e_Cg3no6K=_D4+fgi(msRgcaV!|& z$$H<`+H+pM_ViBOy4d##eH_yNxCwelpc5x`R#O*IvB2Hv{0T2n5BnhgfNH4y8`8Ih zD>QjgX@xmUU~T<;Z$;tOu08W~9bimIX?hx?$5aG_Cl57QiAcMSZuxnPfX0tQp6e}U zHfbQrWEG~#LvO>A#^9A8_%f^6$fv{tdxJ9?gn^SeeEF!6YUV>e zAJ^fZy{1y#OA&C>=;JNQP?phAaU#6Zp&pdOyIOk1e4_}vCP)&SaF&=et@L$DKuV=u z47N)eo2~ZF6P;0dgsbku!qbq9DtO}Cxev&2ymFKGwO=g;n3^hvDrqIhX!{uR&G2sd z8^cDZmz^msy>MXp@8XH1U`h>#@zk@VvTtbn`o);T;!)CE=qXQwd)@Jor z?@pY8m^U5A$-s__!kgY@?$*!kJrh?Xxvt9Y!4MPuXjM;{St;48Dw38%Z9IG$Y3zna zdG1y{VaEA4P0REg*{<5{UQ5RpJDk-*4f?%r(!kh`rOv+JbdR%+G2aURbM12~u4=&o zXWn4ba-;NJ7K=wsBJ$_b1|Z9=waPZd(7+qy8d5dfH$vL z@1ARCr~(eorfLYPCH3}UbPQvu6_>+-4bkFW28m+^Bu9G}L8OetkGSgw#b+ay z&WPwK^_7s42ddLp>jwqYYnPAdWN%sbn|^E9Wo?^-Yb+?A_cqImRJxYv?c#Dmw{1QP z&Wbs;4_2Fbhvy1=>wU7Ij|v4N9BSUF6BVKhKJBK@6@L8eYv8_k|AI@-^XrO7VyL|n z?@elimxP-iUtqxV)xKF@eYWA`30?K-KZVwn3#6**rUj6<J<84H z_I77l)eV4j^~SNo6W6g0Tnk@FgG0hK?XmUHCl8Jpvd7$66byqj%5^Am`b0YEy;sw{ zX-1CMwd|PU7D~eoHo9xJxt>_*E_~p6Z*3t~_?QKC6w%>pfGz7nizM&Elb~1p5C%$t|Zz}Jr z7F*-kC~}eST525qs6P;L5_i zU&=$Iw>w(ZV33#MX4%K~aM`XB)^g)kslHu_Im-~W4)vX51`V^kknke~7G^~5W$qDp z^8(c2z7E|4S7po3u!8bV4aFC18R=KwvNQ_=wMcgu4vQpCCcG!ObLwxLBm4Zh>vVFN z`Yq7GU4pB3Nz@Pr;?t^T`R@Dc=22BHp0gRnIy38>%dqL8>Gc|X*7GsRg2u8R77 z9sLUUd`RjZcMx#k*@!f!;+f!Ql&DyJE^Y_ZJ==tG_o42pa`HvW3+|(LI(M_e4yYoH z(8w^h!LacgU|D?0rE#wDDrKxjqjqQ&$K%3_`RJZZi^}MjTwNFU` z*sI_ej^A)Mik_X^qC_-hxNp&naMv6D>yMul`TBtA3hIUZ|F!6o?=9Wq^K|lj~dQxZZ)@@uenQLwK$W$mn@1BC3?le?<=N(*Jui!TD zZ1%F!M(}86kVLOFZ<#fSP3GMC&a-PPE18lDA>+b9(&b3x9%MFh4BO*;J>GD_Ud!WT)>f^v&FiPR?4|JQwL#KX8AMojgdE_V!7v z>FuJ;gr&DQ(ayew<0R(=E4oo;pL4f?{UX4;1-DIzLk0!!Ne zfr^oy(5AI&1{Ts{BGVKdTcFVOxSrEfGjA*Fx@H|x9F>88I!+9qzIWDNj%QI%2DR(| zGqg6YpNy`&7ECS-|1C3L z5lmQ*%c_2_zyX%~K&+nev*dRxHO;tOQ+iG)6$`U2$>Wz>7Z@&=2T zv+PuF+R>R6+bqt0{Um(PGV?N~Q}>bjwA4s%R)cR|);(MOr$#)FZnrZ_GLL;B)O>v` z!t^?Px&uC1^t?>8>ThWI@O29BK@RG8|8%ll}$vthg)?Lui>?EjiK^8ZB!n~M{3 z5&x$u!bknkJ!GEx2!Xt6d|i%=tf)!6d9>`7ug(S*rSTuciO+Y_jqH+}@h_Fw!DE_< zy=8kU*I4yvJV?0Oh*!+5kq?$g53JQC4C>9?Xm`u8Yn@8KZw2256msowHc=jckR4`5 zz`l@O8jA$w1WaLrq}kV-7OJy#Ty(sfZYo|Eiaz%H|96Sw}Uq~MV_QDpITr=U{hplYAsj!LsQ^Gd4o$y*7Qocb1_p<_e++Ao>2Ne@=7 zB=w$4mBvGV3p7Y3JwCn(719BLK{LwFca^~hJPOX~EMCPFi^cdLB8sG7i}(>@usgFp z-}YR6_*9eE>3!{ku0cQVsbUh!*hkBiOus7heAlAxSG9=UyMRlzi}RY1SGJ}Y?7kW4 zOB!6Oa}4xz(-(gdRvXJH7I)Ggfkp^=9k0^Sw*fepT%?J}|z$TedJuPTy>3 zXu1kk3KU$K&*}|6qIUPqD%U`B6P$R~U#ju%#=?{r+e1(VD`R4)48xY>^__0;OSQgC zX0L!$%RzJzUjyf$nf+34Ym}w?Pfef1ob;5t+0RZq=fPKVCUkB3Q%r?$POBVGFUVH( z_~7~(*JtyG%S-$Ul5rL6aMy;*7T%7HtyfS_=svvl111H>xY>Dedk<0kIVl$qaT8M1 zh>y9=W)q$`#G*>aMThIo_Rk~a7x671oRRE?a{jZ?Ggw$Ahjj$ou%J|_>H{4)f#0Is zVR|oQ2Zat?rYq8AzB@~EJUVDFtaUgTjoWIw$4OUtES+YlzV|Hb-FoU57Y}9%K|xr9 zw7!dq(Pv)H)Wmk{ z^GT+eWApCE#sU{RDVTG$D-LPgA{B~9coDp;N&imBLZ;9-{JY|W_HB&kVy9q~{%%cT(q?65)`4FR?&^aE z2bI$EUdcz5M^3q_HtwSS`-A;f-prJX%x|;~jkG*9dXe3ioYIG)l%Fr1p)Sj`a+Qv_ zJBa+T8gmctG{jYvwi^2b?fe)qT3(gtH_)buD{&9>UmOMr=wFx{^hnGp7TLu#^9^Ub z8;~nBgo&s$3Y9d8_jzN=li!=Bd=eQmsX5YudLh#KMw3!{2UHd3`t@?TtzSPSiy@zM z-|83NeAF!FYxQTJCu;|OE+zi-&F0-+lgi?el;06ciqU<Z zc(o*&T62HP-O!B-{kW&nQ`}q^55kITY{K7q8riT)ej{*rRn8`aRbg&WQsIy6Zc{m` zeUHlBC%b%W5X9;f4|5srDW3%XBd67;!uI{AO>00jzjF?Q!sWDx+pcsb96GAAO;_2v zO%CeJHETaPg=U~-(>hy?1WbF?z5STQzOk%7W&Q@_WwX}33N%6sed&@Fb5kd;tzD;Y zOo>FK7x0#evGdP2BSgj){W@2>k+&zsiwdVb_OBw1a>|5mlzaG_RWpAY$F?Z!N3I~B zC*BJzZ$T2}OM7&33S|3InNd&P?O2TH`|zUqT^~d)Gs;Cqn_8H@{A8lT1b{rS1VJ)X z{IWDL#AncYn{MOOdvs_w8yW}2zgQP)eW{DQRk!rqB?S`94glDpf9?LQvVxuY?^E{) zEM6p2%4Ut^CveYvHJFoKG$VZ z)Un+TadB!#H;-!SjdDQ)_bdWP+Vd%Sw}7iCl#{4-LworIhm|D13}I0C6SdmNEh0YW zsk@Ly**>i4wyC2cNzrEPFXjh6+xOZ+SNxO2q z&(GIf(Y;<{qb;jN!6B!1#lDksmFF(_hxIy&cv_G9;rTMaor4x4ahSDD)c0_4+%LF} zC&fKO7)}Js8gMUryMe>M6H#TtdxX*ZsUBek=SISFJ|1Xe)3p>~Pki4$>mhdc3%05_ zcRk8ebu8R}_pb3?G*l~zn;S#E^rvn-EyT%vD ze%$4@{#!MZpuM(4sC%)a-_wv?mbjL?5?=3}r{QNTYp3FuSW_7w<%NKcZpoi?{T3Mm z2Obl@I-UO*qzp57~tIEN=9QOt^5Z1B3ITXI9|w9cqBP<|LV%=i0~-zL&=b` ztc*T6+IvOVNLAK_?^BZDMDhwZygJ+O>09gMq3g#qONUhjPW2;t+|I?MvVT2Vo)7OHP$A|$e_nc>}(AUj*m-ug!U zO>v{$)v^q|X_?dxWo_p_$OTm8)O^XUl7&6hI4focVM~L@8U;6fi);Jeqm1SI?mHj$ z7hMeLN)VcSg45$fiTMjd&B+@cN76L5=Dw31$}tg_C|06U%U0}toU7`nh z`K97k58wr%aNY+lsxq88n~7K<5bu_Mrw5z_q1OEaC!hxUOO z@UsoGlyJ9PH??ZNOsPA4HA}9$aLYfH^PBdqUmok<1}h911z1(lH{Py+D*zP4UL<^v`))tXIkYvp#T5 zeC?m{L0nN)9Z=GTs9d#ff!y~~SPbdbopHN*&b7(|Z~jOAOLKl-7y!$zAX0luXCd{L zmYmZrv;SOIbCQ)!FL;{U@pipMCoMz&rsFqw*FrDw7bnGo8Lxg+z7EsKNU2My(|#{9 zmG2Sgrqz99I@5e_by=hquTa%m*Z+u33c6^Bm~S}<@VJ@2d-+g#nKZD;pV%Xc9Oui@vWj-2-xAf+YCd=euR_(^ z2s&nyY0h~c>2N`})T>CzSwD5`yE|If3$YQm@MS9CF;DUNOk|l$cDy~WHycx8E-+Wu zz;A_g60i49?{(ofYa%9#x{Tf|;Teh#{g%F!2Aik;ifvlXOXzQs&(RBzufvkwdzvRC z$ZF{1^w6(L90)%^F4I~vGvX@o`T?mC@f$~RhcN3lPhj%a!F|6OVA+FEq@@9(;s zM-gFj*U6)Ho2!mgzG%%t6VdjHdvJf{tv^0@C4_2y?kN85`*1WeQ)#tsN-KX}em$*N z=5M^OaI>C9IGVpu6s0BIefqcaraN72^dNcJ4gL&(mz^)CRmwt#>))c=+^1>z_|WLl zpZtH5@e}`9-Sn&;1gyvk|L%q-N-ufmt6XKR5)}#eYi`23`EN-xUQi=s)!--UjzbdD z$8%IVskXr*hP!UDkfYf@GvBe{$A`ys0LXr=I^7Qawq44H7?dl6YcB`vaz*=S-mIm= z{pr!}HM+_f4Z`o)IPC26Db;31JOkj)IZwe_cu~IV`=(wYUf}cYve*Qbh^?#A zrw`o;6cT**AMJjEpTyBkjDwmPVRt=<=~V3VzyUNPafMlUNG(H1(Col9$st7C`8G`O6q(eXF?DwG^@T z@u=BScF-`V>2%K>5$@YyE6g6lBSPN3rP_mB6&X*=RImGeQNFg(4IWn&nedX&>)yAa zwy)51=oQyP1|&OwjN$2eoIM9$gkh|)l(sEz3h8IFh_4mlJ2n|*@k%T#Exe!f-LF!# zJ7%E<7M6Wl;n(a^w2%loN0Wol_Zi&Q(tzyGEmLuNdOw~wXB5XhkkropCsw9?iYwC@ z5%zvdTRh2%+3N|YY2D&i^JmJ_es^n#e*`{_*-IvwK9b>O=Wsj=;xuc@99!GR5iG#Z zW^^O_RRh4a-Eql&HBUMl0&_+jcQVi|E`8}+k6y0g^XdxIR9 z?oZL}q~l+{4W7LG$^=W2J@d9`D@#zjmnWH7(<*6W_cBV3#O!^gOHr)094-Z$QhX8^ zl*jUU$wv2#WZ%#ZtwNrobR~CQOXcn(=}Q?uZR7-|U?C4;NrF0K1>@Q! z{08UKKi$g01#KL;G0fgvyZK8F`mSkmQ>(A+bGnZdV_+Kq(4LaPg;5*)37sQO{3V4l z&qg}P{O}1=W=@Hcaz)>19tcm|cg@k|W`(I3P99{m1bvXloD6ah(-Ol}YlkyV8cybxNH!t^J zFjM{)W}2`11xQHzt=YMA>3_6Z=l`W52>pt#-6qF2+k>;7d&mo(ja$!C z4zi0F$;9b)wxtvnoZZw5;~UuFmnVBu$zW#cr6em7n1wpD@|m^~E=UtdZ|m_u3xap& zhvqGyq(Nj-O=w{}+~t+Sp;LKJc!LV&%y-uQ5GU`&{GI@G1Z@ykygr~y^PELEvp>s6 zRbSQ;aQVxw=w6`=STZ4=cP!03jJ&cNubi!CX91+`UX_h8B=4<-4#)ICYQ<^ROd89_ zdT|7>fl;L!XPK8M$!7he3&D+jyLR=28OlnoxlY5ZCRc;i*ODI02&6eJ&~%tEh^&f| zbWfm1@>DJ)8DGIHq|jaM#R}Z?Rv^uw1;|rFS=>oMtllA@(F^9CGVa{O?~V^KOwB=~MM}m0H1GQA~yr@G|3H5v^so?i~9+LbY1^+_X_T zIvvu(3j14CUUr?Cz-rL~){pMd^svea1wxSsAFu9}K+o{z4tjQ>B)@>fl|9Y+7NzPZ8U_MIW}{C^*=_HTPG*!~u+ ztP}W}=0sp&xhqP`cA3%iv*k)ER+wQs;hrD{#7ZUk~*FzB%(;2>MzQ#RI8R|y!x+WMkp5&7= zy~)3KHazD8Ejx@v3KRoxZw(z}rEXe@QY_Sc#h+Ba@k)_-+8bJ_@2|cS^rg%v=~zZ& zWK|P`*;F5qWdulkC7nkY2(5;U2y^EMsR#@|5yFb9N8cfplrSIOp8_$5e9q&vo*6rn z4QpanA=GNC<(2P8>Wh4+UKo4U)3G+1{0YGGC zEg+#^&d1rbLXV1y63l1Z^agAxFX$?7weYcH3Q3bIdGmu0BM)Dd&Tow^=6u>^PYC*o zo2a|B(m*PTWbGSiajSPV~14szz3Hv5AW!12xk+!iu*cJ| z+B`TGC=-X5Oc96D1IcZ!C+SH}K5Zc!YfONzh)?KD{kmHcolJ>)H*5!&CY9gwu`(-w zo=%l!Cf&R+|CsG0uS4q)zEu~e;1(x;Yg0B{ruu_)6E#h!Rz#~H-bAS#uCd&TGD@yV z?@Lzyq5dB35!>pqbf2N1KIBnY-%iwA9_z}AgfWyLjtBN($)8WIK%+=Dz{%C8EB-1K z%7A~4%c#gzuz0Xvzb&E=9Z&y+S@R>asdPQuH0r*-OC-k8027?k$dVdoiITz&7-;2Y z!^GsGG|Q3;b^n;I4A3`1C1tRKV`Q1<1xu|H1)K?wRGl>j)gv59cOG6T<6)8Me~=Yb zP_!GAHxXz6>Bm})C&+)_X{1LU$eWB6qPQx;&!Dd>ks@}RpfyQ|7O3Pb2=aLHs=;rr zRVfz3e3Kuo9gXZCYi|lw$<`6Pd0#2K`Q`cgq3q0)-pa;lvW3t*68P0QHN`4ZRg&MFE@R)bs_jv{;A0>q+nJ>F<;_A$Zilf=*X1rT0+}?3YPr;t z{ni~uR z*s}AJNZ%Dy!8r8)6-KRGr4S3O#w}aW6sdJ=Ld3(dW`w{b#I}bRS`(!b`uOH_8=9x~; zo1Zewgi1V}Gl54`FEv>ZnAj>AW?{vBk3myvnucrlPDATHTztAZSr)?&^BWC>CiK5} zX2gk$3rN68I4>v8vH9VkB_t>zChJg(*R5F#$CM}*}=@w~9`m@~Gw7u^u$AbTdX(fSyL@44nZvR28A z=t%W@$84vyH%sE#7zBfU`Kij3ijdwOO*Y=@yMJCEv~3j&Rd-X1Sr6#;bbv^{Cd}be ze{FeJWW~u;9Gdh#!0=3N(E+%es_0?&9@thyT}ihvd?c$Ba18sZxyfOiX@739L|c@j zrnXo#cr}h0R$hW@Fe761x^v=dA8=di3WuOB#8qmYM@U6gmGEmj7qMQn>ki`ByoUrK zRk`~KIz8?kW3gyu#$Bs52?klu{q^ERwy=G&*m^9QZlu?iSpp4{(SckR0PxU7GMM}g zOd4or<~)rv_2T+(WC$UP^aPCWimX+QV^R$b?_tu$`?-6P!EA+Z_x>g7qp(i13q1pw zyLH6R^BM}X;^z=*EPZ?cfN(=DdL>W}wWsvFfaC37_e|}BD?3G*R^C_q&rUpsb{+&U zGL*@T{oQ(okcPHBNg61U$v#Wl3Wz1mU6Zt(N_PINCaf0l8@YCjdd>S?`EM9VKS{OZWy`T|v&b zg1q9_hxUU+QRo%YICO8E%yaV_0FYL7#k#fOU5%tboI7(XyQ^y=1|$-m_iQMfi?{u< zitdbXyr-MNWmKW=cP$zAt+bz40-$+e7rxv5*24Vb4MH(TdiMyY=*Uag8N;X3XU+g# z3fqa-3f7TJBm=|DdP>k-nyHu9EeAE;vTPn>peVU036k~x3y$4zt%$QIl}2dhn%n)p z2{Tg8_-h|f?X9F@vIR+lUm5`T`Qb6dKdq%iR#Y}lRLG%SuKIR2*Q!-#yI0aOux9ZB z@mFv4)z=s)-WuubtW4}<+a;yK74+vu5!RL z#KU>(koQEB=C75?e2vKs`SN*X{l!3(bZ;R$OTS#?sE+#-CQV2#JeMJ=9>PLzc^yB{ zMl+5zc8#wk{~rG4a$;ey%%A3Xe)%mDU7^wWwuU)RJg(47IX`NWNFR?z z_EaNpCHbRSJf480D%#WpxcqWwlXRU{vsM9sw+*gzI}G<@bpj-qU8R`JOip%G=lf+G z+J){oXzaq)p`Ivur(Zfk9b-H6PV7b26UnAJ0+6^LzOasX{Ts`7zP*xwRn>R0cWFLT zljZs%^;gKQ4KpJ^V?`D!YB7j?_7=`6gt6)@i>|0tIgKJ<=q4OKlFn`#khllCopGm6 z!Qm>ql`hu*3C$mlFi%D4q?uUOantIX1s4w$zlYX-%3|!g9ckoWIDZaM8)IYgHy;D} zi!J{XXDt5zO-30)K-pWUfCl0T_rgXYwCErdwYi;%#c%RSL+T<`LHo zpdw4_f2uX?hO&ODTgn)nD(D1yUBp6YTg$ciz3 zVP0D=hkagCvknd~`pub`cck6r(m8|@a)x&b73F2QIt!*8zT%F)nE<`Y%XZG-TA2oy zmofYe{sUzut1SiPkX`IT{^w*Cd69kYfvYZ3YAWdgxL=0rCII7kG99tF@2}&yRL8X= zR@?mrPJ+{K%jhzKpUyqyW6rqy;p z=j+zOc7%&!3-+M3tMScvgX6-Y5&fLmlXo(rVK~DCHUL)bzyUk4Hxr5G8Vs?Ae614| zHiwm&|B~wwNdm`K)INFguWbC&_rz`bfyK>~=&Uvw<iPh!t|EAU`)vju0NhsgsrXDc}*VgkrMT^81$LST-|cz*~n2ah#m9p zE$}X@tA5+y6kR2sf#A2r#uoH1??#-a#_YIMa$WMWH&-2Be7cwTiI_Jt4w$!Em__m* z%$(Z4kRk@W^eB=WugWv|hbL?l7|;&Ij@n8_vQsj6-~$j1%~S}-MA#BKNRoB_yLgCYas zY95rcP$+=5F3t!>OnD2Ce+6rteIv;)#^z(Ps`w^Rs4(ZjP8GHYL zv92dl9$U>-BNDY+(pjF|%Mnsp27&)aD_0+sbhd`Q+U}%ok`}}6)ndAB=!Ty=eW=9G z-PG&ot!#5vEm@?{)ovJmBqE>;tDBW;?9E)aR&7(uN+WQUL_pLqN?ctn5EY?BCFDaf z6cmxgcK^6D_phC~|DJQ+dC$z5=Xu_F&N;7yex;zKyN+xAD38I4RN~%c{0t+=07#-G z!WgP6263z3W%ion^*L|+Paynd5idApS9ta_lo5dvuT;)X*&##rnTFXZafa2L_Xu@h zR1tax=m@Es@7K@TtaKTmTfuo3>UAgcW}e4bYtuSCpJme@CPXyZUw@RRsnFR}aL9n9 zI`yU>>F@L#3$qQbRTM~(JZ z_YlQWRGd*!zxdjlJ+bZ4P50WY6o+S(ShZuT%#`^OR=l+K+2wE41j?wQ@CC)x2#)pL zYmis4Qw7`F)C!`cj{F>zdq(SlYQv`ggKSWvPq+L~v#%P&pH^D=rsm2oT3SIn^oYzM z{#i!n6JLdC3E*kT>v9bjy*~+SYYu|4)E;Ek67J>UlhtUgm*}pE(r8PSbMQ(&L|rw0s=zzFdc6I61ZK zod{xThUY)Md`RyX@8eoOUNxaNz$utHm9N;0LxjxjjIqlMI@}~Y@lxsLI$(it&w6S- zG}P_1@sj0s2ciY4t*hV;pA)R+A*qWicmjroB)6B_1zS=um5A%T0G70ZvZM{iob; zdz?pIS$pG19~X^KE|eVdEr;FhXHAzN6RE+U7&gTy5sWOrjFX?tIJmW{TVZEY^}u$C zxhl?wOAcT7jx+T>%f^RlQK3HP0|Tw19$P}G*(Qsm>l^qfJ$;U^LikLqKYHU7^$^*k zEHox!J(hT6qUvL!F@)h?EiqH@2Q%=bmnfo88fLo7S$sNXIlbFa+QV*BpCIe1R67nN z@s3?}B?T~TgR+$m2~#I9L;S61>RMx$`v-Ka-XL|C>5cg$=<@J_2B#H|-RhV;eEtOG>FZa>f_e}bu!p;UNlHGB(XC3}`x{E{H?mwJYlvT_N&_&BM!#_p#2;|>F zNtv(6BBi4ZQ(-qx5VhjhCD3&&-vk%5+h^Q1=)%R>%D2$!Sn-}*(GAF&FFDBmmX_VJ zhp8!&HVj=CwddA?iGl<^4gfCvR>Reh`S%(@P8FMV8Vk@2X<{hq@9bg{MsGx!Zti$n za#WAW;>=tUoL!(xpgG2Wsi#!akI|ntsjzA|9Y0BKD2#>Xb`mT%0>DXs;wKq?9CWc1 zupni}Hva;$wQV}!+OR4M1J-%O5z2Je;I=-YdwGj@#P)qKW+7inW{wUD!dfHot}OwE zB*vPDwUxv61bC8_8eI||Hce(Sgk8scLZDC0sZX%4EEZW;*YwqR5}m}EddgYtJtXLV z?+@;po!|e!(e`4}Wp>K@^W@HWVdscfGQ9q5waHjHga7ar>x`iZ8h6i_V}Ei? z{N{LW84@>@spW&`ILe5wxp8#cQtf7NeKp}*$UxPt>&lWXMQ~*aSjm-$ncd+%M^cfw z(*UR#l<1AnlLGp%`oXea0fU0`j;w3CJI@q6fE2H@IV3j3OVnPWnjP6qmm(&1(ek6$ zuT{>B8z2ALhY*s>6XijUt}f4WhOek^XAD?Jmr^yHACZAbEurWBkPgwh6cpB892N)1 zI(E6mcC^GaMm-LD~YU literal 0 HcmV?d00001 diff --git a/docs/en/images/docs-module_download-sample-navigation-menu.png b/docs/en/images/docs-module_download-sample-navigation-menu.png new file mode 100644 index 0000000000000000000000000000000000000000..9a1232f1987f735aafa3eba9f2e050b5e202765b GIT binary patch literal 12396 zcmd6OXIN9+wr*(B1Qax=AWa~Y01AHe-aFC>2%#4>AiW1ckP@UPemS3G03=qZxB1kX~_WqRk4(pRwVc~`D;~(I{-la z?azat+ojkR0C-HGrYL9NW3iJ3jd<9dwWq~&bFz~XWiWjPHC<&Y8+Vg>f%;rr8uX`{f+?}izso+S&`?kB zdlQ}R>I^m}_MZ4V|12v^u}9-_aI%xaLnlA1V?PLbVCg@=F1lXJ;u?0GFV~go`A-U5 zca3{>J-mZl)y+k6PtV(DrhZLSiXP~DW8c~vTI_BsZSBlBrO@}c@BF$D=)dQfq5=2l zKaENC-|XtOeplk(=AYF$%2a&wu3IS_H$ zZz3%@9==`9^f#7>mKy$nIiH_!Dc+*nl4+bN1kp%mZ}N7Eez^pA*}&Q{HDcZ#?a% zPsT7Pt3KuNzJ3d}QW5>t%Gm7v%k~)37oskCL#~bw*T>Lva!yk}&Cqvor$;8R5~7k4 zY3n)wQmroL-Y8p7LLHzB6X=8BiN z|8&&8S)5gK4icQkE>s4+y8+^O&6b$EeQ6kB_TWRSH|z|NC|U6>7?|tN~;z3L|jE8E_e3U}*N_Up8UU*40aU2+T?yaL& z=*sPJYu*`Ah4<`qy`_`O&y-a-ZcUaeub-^?oRVo2;u~|=hK_9~IRN&!n zts2u=`6K7+dKEGoEVJKT6M$_@8;}Jakc%~7j1pugORaVCvM!VYJ};Vm$fhfwkzsxZ zwhhz<#v5El&#NE>d^fs~zrC@NUt5~zqQ;@I#IH{$>Z5SX5MZxs+g3%jB7Dn8q;J8$ z{?jB;(3|_QSwj>fX0vFSU)d_7>_hf>OLO!Jd9y4C40F^`)_{FV_(p#Sl=}mVja~k9U`7R%E%G}+#Q=d$!Rh#Wo@s)YMue7D%4^>fD^8xC!n}wivdFYo=#XwqK znbReNbL{1TdUhh1Mn5IY=UJEbbB~wu1fOOk`W5?=7O)dDG_(?HIyHW6>4CrL9}&s& zNq$5kMK=aD5@BKy} z8^bb_Yh}e%v_rfS#{V4VZKER1LJMj#p}xFRe_2lv9BCKNN4mQ!0MESq1ZLtZqx0g-XW*QZ+->-P;3mk-MA-TP_Plm?=gi3}R|LT}sZa(y$S zPh6v3F@X$*f5~DjRVO9IvFdu=jn>=8*@3o*or&>?X1mr<>E6tNMqlV(nmC*X_=;g;ygWX@sK#<)U%y=bX!hLP;j; z=lWR?M?0U17Hl1p41TVy-V)-*yF>zQ9N5MrAtguz%O2k%g>n&@;1XLT8!bZxmgFGp!S)9dOrzB=8>k&O0-XWK6uV1~(6nrDLQe8crK{Chx?+z#uCP&#O3`1i1kJAR$l|UqyA}avmwmF4g_4zV zZD%Ixl5hKa<)=H&R5xyB0QLCpF=HC) z;f_?zUacQW{jC#UoeR|m)!5xoYq^mUWsPbnO4BbSFLNR0T1UMFNbj9MrPM}o>7ceX1lxK)MwxAlLjCJ z5H{U|>`SrPas5F7sSIxq-4}EqZnk!;L0aT1EjeC+Y02OucV=}#Gu0~sQ~e~fil~u| zv5c#bql>mor|Xc!D_6)NeI|Qyak<{jazuE)^u=Y>Lj9d{6S2hEJbmb0%$D8VLnuXH)fF~h$%+RVM_O`R z$uK69{zEHR!*0E@@K>(|EyU+oMkj?l?;89-HNT&>gdLF|WNjp<0m;97%_OqmbIv^uafchMxgJ>!Uyo! zwa$D63gf_(M0RsS>ER=vZ%g7iGZ? z^=EpdY8UN3a^Jc!|3nQPGj2T2p=*0e&~7cL0J-JC0Uv2$Y#jl!X0RvKjC;NuK<<;5 za+VjFo_a!EQo>xiL8zp8E@Tge;f<1g7jpmX`z8uTw(qAQzcL<~IuZB@qArdi^W3;N z@C)WYA351Z=Gr9m-FVY!e}dc>3Khxt?lTGfT3hN*NvE;bl&x#~@uX@JiiBgq9}5!+ zb>P?OLm!mm!;0V)U+YONtHk7yasB6DIjD>hdyq%z(+}Vmm%g&%EpTT)UWl)>`ko}#}-U`?R2=M?1B!AOsjkmJ@T!0j2ec(y>sSMptn@xw{ z+%+?&2OTIP_eW_*>#BQ0PJ9WfDZk7QXak=r8DGKYS48G?;lju0j0ve7?W6B0Xy4%P z=!n)|uy}gqhCkRila*R76AriDw_a_m**vkdCrAn2=#`he1HKLnz5GpdkPW5P;92eG9EKDQd_-g*us z<~SBLHt8XJbN=KmB$|yPq(9_JV@}~A2bBwmUA+7>xiWyml*v{u$LYRK!xwOklBe7K zAC4Ut1e47Cg4v@1&BtP|Gy*Ab`Pc7U4_(8A9c2_vn7Wj(OR%IE4#1H$5AtjoBmE1KZVlt#98*CApmtMjHY(R5{2iV*a3`e6Vyiaaj)iK zEq%(tlNZR`y+$<8pCk5%Ym?~j^L=F zBis3Pk`!@CP*ewJA&ZtiBBt4g51Tldhg{t08gyYU4hk?g1=`B(jJWL(fIdc&zws5K zgWO8Gm2~rv2A?kbdk65fqzT`DC5QfP?f;|XYmJ}HHTRx_^ild|kgdkGyBVO}TCPz| zjOUtk%BYZya!QPypxsTjQ9R}`zJ*L4=f;?rYI2DB_W?XO6DIaQiCv37(0!E+nyK>dDZb1WkxuU(N+u&H2G2x41+p6LtuG~MLraU$~QE8~m ziremXab57!m_MEN23)f@iH>t)(_%yDIxEmZdRik-e&G80$jaF8Kbw$2E^%Aet(M52 z356D%bQjC3_tZ+Fihu?+fwfGjMkA!K`+KQLx+B!gIzH{aSQ-c;AKpz>w~!`gShLd~ zS>8ZZV78ZO1?c4)PzsJ>w#=;dYhvwfWyBqI)z!*QT$~WC-70M;YyHNBE|D(d!#^)( zL9#rsx?HX;>9PLfYcjJY4gOhzM>4Q=Nco_1oz!Ql4eKbKKRFJaQZeJ8f9GLQvY z`u#J@7oS(#5%B~j{M0+0J;xVb`n;6*2 z{T%Eyin{?okgssAtc&Kc6mn7m+Fua;_ozkxNO`JKME>@|Dx@ZTHH6KaBfX0@2C}4T zTXUpD96uCC4G*4ZNuLFy=`cryJ43JMV7!=qxrmaF=(gN3qQPjps@n$Ox!Sba$)(^*1m;L?qsoQ?=X1$BO$|OQ)!a}N zCAqmo{LtN}ojYt{I$Zg-l5DzIQpHojV3cKw+M-6aHYhVL8az1_ST&ytb7)l&eD*eB z!h6R!^7e(A+9cE4fV_H};*;{@Hkbk@?^XtDWIoufzX?|mQfk{VsE`)vvBtCA#z30$ zODozcGuMXt&&(3dP7xEQ%peI~&l}EY*V0pl6(Q%1YeZS?(2cxK=EuB`QkACRXV2g3 zpXe|miVet1F;H+u6?n?d^y5;&HZQD5q7VYVExWhbS+F(K7-ZKm!UPZ zU0?w0LkpW@e7eJBqnT2$w88$g5!_Vg!@QpMhfP`vxQhUJFH)@ES`wc$^hk1>Kkp0j zLD&oEEvUEr!*$>J>N)>~a4)$b>Uh zb6(BvNkiXT=~?foI?#qYH;V%L)kD6x#H+CyEKR{vWf)}Cc&?5$(g5P)18w@Q9X2}7 zjST?<6IbFoKYrw30I1OQ+LYVrllG7K)_@>C*e;(>w7wRpabIQ1xW$v1Zie#hc&)dS?& zI``?%Z+(aD2l^L>vUhtH?|K=Z(yS$W(e+u29zW8B9!#_lzQ((%{m>Em^|v?E=O?2i zNRt~(jk`=fosHP*g?IkXZg(l@+?>YE$-E9a_E>nBPRG7JnjQik-6{1Vb)GL}MMx%d zt(#W`u6^8;F}Hj{t^m|%&yn$--}N6eRJ9t-E8g10&b9|Ge>$k++le&ZR$z!PTv);wk><7&TA`PEOyd;Is1(&udKPKDK z*igr&Bl zkAbs7N z=0J3UK}U*s$m4YbF3S8 z-}Y<$f}ANwsGgu)nMU-U4E6Slhvf$79}u9_pEK0x(9Gw*Q6dW@FMUKALTU3#cht7B zOLt~nu8cG3j^bHnjp4h~(%HTC9ThB{&Bwr%1pis&`u(kZX z>FrPmr0U#r&|#vCnI6~gA4v7exHMr!d?Q7s390=g`ob;?bjPa*{S>xO99Ss7l>IB) zD`5^W7}c9c;VG1V64HNJe)wzHA`I6``0Cx^3YA2b#4HG3SFdh!lvlac1Wc-+Oo*~8 zp|cP@IpfCgBC9*r&fA&rFmQ76m9$Gk`O(7B0JnC-52{Y@Gbp*a2@jb86g=LKpp<-q7!hOQ`X|S8hv_$GAD$>c-F7 zaF^33)E}Xy=As}!^SL?%g>C%8DEN`I=*b64Zfxu`|>c%~;#GIehXbbV#^|)EvP4v=P2gdUN-9ZU zj03RXz<}1Nz7#tgSacN6fVw+dd8cQQ?BH_i13RG{@QUJes(RPe&j0-dj|qhy^LGiS z1moB71|H-^B=)E>7)ZN@0$McWBmWqYOASk(Iz}TWX}&56HiG+>;@PH;>$NZM!On1U zz)u8_=r9@s8U2Q{C_5w8gJ4?nPtLrWv1l|xm=(3NNW4X;O*K$0?aBuE37>>NI3`W@ zL&FF^Ol?n*d60`!L6W*3*|Dy~X{`FCjMso{=@VmOi6C#@smzQFW!_V`Lj^;|b1m{( zWIUzo%hRH674YR4?0DOFK7h4(A*2=23=WX6QciA1FJO6N9iBset95tdIi`LP+@GWS?BJv&5}2wuOJ`fzfwVlxE3gsGrtSgB{JuQ4pwr%Y^VCD)7oK^ac+ zisb$9^oXvkTlI7?sV6VVn1=%F7Gw|(y3K)`?g6M&rVKj((u9DMCID~|3^oGv5DpOa zSd+W~w@d!B@U_}LHT3{M84fJ{e+jn~DUsLBH>b0kW}_Q7{hv&GqfO0e{Js4yv|u9- zjFX!n?pAYDG+SvgM3{OXCdKCIN&RsMpOFHPS!#vJ&ji9G3Rj0R6%+cdp9p-hGd^9~ zJF=FC+zf}ai`3&muwJHY$?q>9R$Q>9u^{dg zHexXwJJLOl*&$+mQwuooG!Gf;rE3khq?%KBTpw&!i{>yifpXf_z|o|-6P&MSQu0&6 zpvE`+GK$@>K48o#OK4n!`CMsLm=`EM?4-q^>=V;kWPJCR2+5ez-WQV9aUDKRq93^K zISCfksBOrA$PV36Zz&(S5x zCw*1FN|bb?QVp&Cu$3dTihdMD?OQ-*JXv9DCnv{Dk}d}fU|`BOl;`50``+~Z>W&5(lbdq-jQX(CISi>)2v>d9m`JQ@*36y%=h#CPgf_>VHDG((M z=8rpVIa0o0Q8zOkJ|XCzl*C*Sl5ZD{r+eykq7LyI#@GxKLiTuIj97SE)2-yLmpGj_i}LUmp!5h3p(mUe%sFzco` z?31HPZ;UhE(+8TNB<_DaxBWetwe-sFtF7GHu!iLtc#pnv&LiWpp~M=4z7Y1pnbdi) zAntaP?iBPpuQB9!caQl6(|jqf?mH}u2@yzlHBi%5>#uya{kgM3m0^v$Y6~!m-Uz8} zViVrlS-vpfSl8yfe`zvkhDV)}(xqx{8UA?Lj8-ivCwaZY1Kqqa^jcT-2DYu&-rX?k za(35-QNFE4Tw8pcnpVKJ>R1vxRe=gPcYDXXtA5wRcsds9H^mYy-s?}4^!+yBmju;R z%dwX-kxPT>V%m75b16q#IVmII?mc#&3L(ncz*qC(K2}PJrb{>+F_l3zJ<7;v}E-& z%o&3D<%(Dlhd%k>d`36p%fDe?WhZmaMdLd?dIAU|0h6bWjJx$s-KRCZ%6So$KCod; zE`+eyS?hALD5Xy5s?c669=*~Jkz9BQJAAKFGTYV83iJ?)YUaAH?KF)bwS7X9JrzN; zxUKCzcAG$jX1?nKBqC@2vhH$H#ZhH;X)O|~6sb(}2ijJsHl0&H^^3IHnGlimF7d2( z=JSFB#uV@}yiXP=E8ojdSf`j2@oH)-HCC#6zy9Hlbf~D0#O1`>%Q^oD#oQ~z9uAgb zyI|F(sko#afhO-RMa}#?k#d2Y4gDy$^N?nchnDcS?z{!JXQoT;6RhJ&H~|agV;cM- z1Rw!N_~W12%St2qvw{ONnwF*fv&i|M?2j2`E!!ypqVet#IAdr)x)5d%*z{UgU$$z? zq@4XQtqyHFfBESQKH{s_Lax>9TK>-B$M2T+V63UKU%wdxO(VU501(d^8NFkrFCvhV zZv$|1lK1t2$NYNcj>mm1Gh%~AKuw@l!XBP!E@CpA6PfFyO++qFp0j0KrSV^&pe%^0 zeL4RPB>KE-4d$YEN>G>V&+6(CW<{XSA;tmIH#YzH+Yn)1wV8VJ7gji^JAx*Im@Ml@wd#H^H6p!_f249~J9Lh8x}# z-7qm6yjY@ufI&m8bzA(<*35+{lpe{<-P5JiY+?=q4rRwe40 z_R)&jm`V{8=+TPJQ9AR=gG?+E{%@S~nkoDnwOmx#A21E_c%D;pcn^MaW2F+^Gs;;s?p-8G5Y2e;0Z@|1k9ScWjFm znjf~d9r|=7hh=#L>>TFVK3Kg#412r*uYT2MaNR$XEvXb|n_nlGHW9+-phbes|D1-V z|2++LH$lc>e{mz6b%VjH1RO4DQ?$BlNT*7u^vOWSoL3F@*5drmK9uG#XpfaP_(Gud zv>uWW7EXM-Zs9)!;f~^8gRtUC6B#|xn}g^i`2T^D;!DR!j)cxSG;>q_&59RWgQ+bN zS`NG0B^caxquhw1VUky!%i&j=>FnYh5m?YWtg~4O)RBK1C7Sfk`8ov26p>a19-o0q zx=-MG69srYsbX8Un0$7d{P(R2DwNpiczL-IiZ}Fe>#g!r0e&pU3kzBjLp&QJyJTxASLa?V|QW!2@pnw}C2zVmjQD0%l@Z>g^{ z^ip!vW_j&J!2Q(qiyM%n^mACxTOFQ`dvbT~zWa^{iAs*UWBS-Z11(K6Tf+_uw@krN zaqvcK1F^>6>g32+(*kFH7yuhx#{zjVZB90;$hbVR0w)RYGQk46g(ORCjvt!0i;?NI zx|QhZM_t9+&+MrSc;9Qz^QYM*oDG+akb~GCY1DZ^!Dn{p^u73-qsvPebFAV1JGh=+ zT{lb4`p&)2fxI{ubX;%WMIj%ZDr7mu6RSaD+#8w|{@QMD(C~MVNKAai=4(Q=17 z_2o@_)xXE_+^chkQO zs(pNQw)H78MB6z)FCEM!hn6K*d$fr|s@Z*n(G!X|XY8P0MUxdU1=^{b)d z`>%HdSLht|txb&4sJ7qJpzm!5?Btc0} z{5CtRnmr~80z61V6RTZ-@`qD?#-!YHgH%xQeCm~tLG60)-eXDtyRCJl_A1p({Z&K_ z1}AE8?&DRZ=PPo|dlE2o;;~qc&kX#xxH@eCuGHz2S=}jm3Rzs)3WLoN8UmSSQ~A&J zSZh81st$|Ux;i@c-e~_t{6FQ>D7@-J{LjLkvw)A^k@KS)EfKN)(i+(X{`?P;d7vE{nnz})vFOQ=7H z;V@OYca9w7t!ZTt3?^LKPT_u5I2eljJu~BpS`$gSpsKGmV=fAd>y+>N);&CEf7+7p z@?-4SJ?ewB!SpeocCnJjoT@)dgh(L8XycvThKB+-dpgwlOfWu%xFSkTtE{^=_>xPL zE&Aj;ujk!GU>JwZA25vZrwiblV!Agv4(G|zWz1UMD`Q~w6KCbPGTvfaSGYdatl#G{ zyrNoHQE6pvF%%P@ux<5f!Jin~)@1FC-LC76{j;ol=(rtN&lcB7>ozTg>+2MLUD0yX zryXNKE+mle)PBtmSxkAuo_=}ioEzX!ufex znn@#*@jr^HPm51VIu#VpGs|ds*(e2~QsLVbXY(HcO(!ulAKFI8w?JB}Ny6N?HFmj# z-1n8*FXRuFSO51~lvsGqm*L$vdR1&4o(SGnW1!fp8oufwA0_|tW!95$kX88 zwg@ zR455#Y%DKINiUk=lo@aAmEUg5o5EK>Y&4>&;q2=KCbakh6)$($k>DlSI1&@1e?Ab& vdpfG?>Ta~hEA)ra{x`l8Pt-kqO)86c>320kTaEvR06aHgg5T{`TgGKeV@%<&3gERf%cij1@Xuo065ot z@}O&T{_qR{kocve0l)w1@fymqL$J+Luq1qPyF4LgQSA-blHp9x=`vx6#+%0@S5DV> zSTy0cInD3A^M!p(j#GNpAqKTs!=n3m2;+vbBMnnu?KLGpJFz> zB4X|3y7gy@gp9eWeQkGEQx)C4ymwFwC~rbiH@)(nm$z+KYI54uDC61e$GAPL)Ffq?q}+Ke^_U`Au4mM{&ua*Yt<3w?jqk- z;^RscFtbdn0enM*LnCyjnhB$%@Ww=7F?UrRd)uX9l^gP2fI7zXiIcuUMCW9f_EK}K z#nttXJAyZ{d9|bW>Mq986$UD<`qrC zysvLdVDw5U$>jo$%@e-b%JHu{8xoLdY7Z$o4oX7I7+GJ2upcJAr?m(I;f-C|?<*m1 zG>zu-Y{rJ?ZaR}(lZM7WI0t|G{-Vk*0;%uM055dt0K(ZLlEn}$oJ`9$j0}TsSwY>W zlX!49OKwfh@GxT<6h5nBfgdfrD(R##(9>2NBa?zGbon0vQ9tKKhv)1wM*UMA|B#H3 z_2bKq(cMX8le+8u`?uL66kpvlmr)$M&J&TEM}K!!p@IW>G;#Mrr_9JpW0_&J_8W2h z@VM_3XRp4K!VIUvXKJKvM)mnL2CDAnP)qDtAX9R~Gva+U$ZZ!`5ExEdd-;F8e3@oo z0XFTkV}O_`M`rjbxQo0a!_vnYXdsx`K=<#R7Y4Eb<@P31R2x8Mo|ZpoRbs`cqx?ya zAf?M}tjpXdGiOKmO)8iXN8ac!<|?jW10z<1feuL^3=lr1p@vPIJwBYQnExZx;Bq}H z!TGKl7K}*w9t>PsT6iv~YNQuKB@e!r`pA>e6?L!nliie0p~yj+Is+Ox^mD@C^W ziB=onk~8}Eo$Wu-{>sZqs>ew06rV75+_p<4SOs->$8#%rp}<-7x2Y!?sbWO^HcXg7 z5IrLL(m&A;T_Lv7W&#nOZfeWcAS#jAbs}~SSGqM1zYYtzS7ZuhD4VHxlf*wQ;L&=X zvm?=FvEYPMvBKhw$$J((*Ah!$mMEqpnaM}j7CMSgzcU2U2a9oq+W~rSPzu{_L}xsWpOwc&_Shx z2RD;H(Wi5|MLimJPi31ee;nzPitzauVWZbquD4pA_9Dq4EQVVQ6?{>Iq#oObaD*Ta zLkMYUV4X?NVave~*jCoE3fU)G)Tv)qlC1Q@+A0iVD*?}*;|~KxpU;+w6GhbB;Zalt zO4#7RDwG*}?tXDCjh}ipQs%K^#kdFB#g^6?ys|tTVuF<@$e-i_@Prr9X;5Eb;{L>L zCsTp;3Lj@o)e>*+BOBe`WywqV?F5vR7=qg~*#chfsADYH#Rk_^)WudBdBkkaodzvb zJIdx>o*U`p5S=%@8%tjp{*+Feh`;v$| z^a44RS;>8-NU@L3H835euB8oUA)Y0AvvNEcMRwn*N9?}yP-O0VUGoR?>?}Gw-a7(} zTB+AAAgdl0>gXb$y@k-DE;sU=hnT(Zbqpoyx1S$ni`VigERTKam$0fN?vdI*M}kGI z(Svf>(7yw_ym&sUE}Go5e0Vz6Ag_qL}A< zn`V(Yv0pKBV$$Xw-C^r0OEd4e#ue%CAHcm-5wq;F5;N@O$PH7Q8}6utS#(nLogUck z=)29Ud2CX$eR5*&`5swo3}7Jbk-`bVU{5(D*6WwP(*?k_k*%p7hs3kt@d_qb+Efno z0`i@Mpv|$E793R;Q_1W}kgM%(O$`}`m9~WLY(t|^9cjXI?3jU0KloU%Dy6@%Kk%_} z{v&xQeIxU@sd($H?;4b%$BfH5W*z&@gYg4n0m3>nD+@A%) z*3j9B?)4;Sf+4O^e->6{Do zkaAbFDXX+ph^w#bi>G7JXN8yA&Wle7I z7g61OhlH+Cij##UZc|6HsDo=E-R~Tx)@@6``&MU~3@9Ny%;^^M=LR$ne^xb2--g=w z52Byf!FVt;-AzY`JNwFK_NxlXkC}&uyOSyVslJ4Gm>zj8)0Vz#rxEp<2y5Q#dKK;ROj=_2TYg~A~tI7a2flv8| z`i}(%Qj-|HZy7~15N#)t(Pa}xtxN&qQT<;mW%Q23eL_}+&guPlNeWc)@7UGk|6MdC z?-O~%yJ9l1+ge+(ao5LLG(Bc-!!;e7v^s*~b!@{^-0o{X@4q0vesjOHHC(Jl@El1U zME~{l%W5PO_8crZgvo(9?cSaFNZTbD(5IrgOyNed(Zyp|e>Y$}(zmN5I=bpY-{w z_3RCzTx&@lVeew?=Ccl<7|N{Fc~CrgV6?({U)_&U`Q4pr@}5N1>f!!TT_2VMH@3BQN+`A6wdR{tE(Smn!S~wgu;&x})!ncJX$b z%G-G&8+r&{O_{7;+HTxXBmVW%?u>=EUt@_^&tFq-p6u_$m%LP}lBiWqS|^)smib>886y;Z$Vtpz0+ z&*`k{S9t!x&ly`knUODN>-ai+%zGd8K+}fj6vjSEe0!5T!f~pX7((x^hudWX>Ypq9Nw(LTrocP6BKi1hXmIR&=MI91kP0gL9_kPCM1uQPSu1in zAwY-L)D*D3CO)euDPn4#qi`z858%_}^1Y&d~Uk|}>T-OZyceKEISW(_Nr zWVbKNpQ0ZkVP0Q5+LYZ^iid+rl#)-y zb^FDOBXx_Ey!s>O@f~wdq1|0NBJ;wtGMMBj$r9D+u?BL=b1#h`D@v)PU;lVkVRA=B z&MB^@65OyoWS%o3jyS?Ga%5A@$&0E@wV3!6=euU`=`r^i?Uk8=g6in;dH%=)l$rEH zdQ>*0lfgHdw-7VNR8T_vQrxXR_LBM81T0)T3RP0)neAF>(4~i69_<}zN_W2&R=dxg zdmh5|h3m|r$vl#&wo`$WIz&D=m^YJRq8DDTez2RP*&h<+DnhA)l2YFh^N&*X<%o}Y z!dXFt&%VFD216o8BoXT^BPQ2XeNXF!q@*OrDJLJayhS-zTY3$M-}rIs*>P2Ad?2RTjG{TGakT8FBWlKj%vwD<=KwvIs=Xbu=nPUWR$Wl8 zrJf`8qqE$e5TM{~DUr~Z_o9Uj9%g7`MzgVp3)7jk7Oz_81PT7Ko~jeBtdOu>`q=G^)ZRzoOPUt+`QhBOsl#ol%p`w(1I z6y84Qc~`ZPPGs3&>|Xxpj-Q}e9ghAMjxrTVt~WwkMq8AZ5nKUKm-GuH3Po&|oZT&s zA#Iynwv#4}EL7>Y)*`(rTeYE^XQLY?I&y(wEg|14M8=LrN{-NaUrlMO5;p-1CPo1mPCszBD$uKQ^NY4EqjG zRbk)y?_u;a#09Z0jpRL_v2~Q1(xO6m^o?pCUx1+~{ z!W*GE;M0#fHZYZbltty98exhs(hPl4jyiPNPM|bRh9!i6)N3mvt3A$NhF|nJ#pN$B zTVM6@-3B=JPsa%+{Y^V~O%rF%t+g`y%#bS0ImYE!3c8-8WsKhmXMB}3QsY&CWbhRH zf%`)2Ry2emmwg`-JbII=QNvF~$h&DeY~%;rMx__s;1c7^*ntINQ3 zW0GVFN-Z(%r~Af<)kGQ_aXbp0g@q3oK2|hW+3twWKBRFK%0icx1_1TS&(ngCHy`QX zrvO&+|L|Fd8TRq()vo1%zzhYSgI`dES^!{#tK%WIi{SO?_4b~3taw8*bo_Yfk~jd6 zg0aSI9d33jn1}!B$U*Ac!kxby)k$b+FoOV&f`2jhaT+S$we+6w?3}a)2b2ZnhqFTf zBg#_JH1{-Y;U4MB;ldZsg=gAe6arD}KbKjkZ=H|XDPt6CrY?Kn` z=>b+sG$&vjVJn8XWj>f*lxExA%-Wa!oV*ieOA6;8(*v%maC1YXwc45cmbCG+K-nDCkuR-Y$eL+kWgfq(P}*(`(0C)2?z?@Trn!iC`@DE&P@*H?>MbeM zy?QS6K?m~E^wU2B^cnn*%X?LD^ID!Y0RpU`0J7w-Jb6F|eFX<@)6P(Qy8l~7+N%#r z)I|Y(9RNU{p@QQijiRj>pn?v_0(dhDzyJY_j(~sLl-pPU;N96v=OM2dav?AGW{}8G z0PTu#r~5t+KQ_M~kFeOYthShE1`!Hx&GnD>-kbBSF5sLN_>v}#9#ckxEY+)Wa?2A~ z(HGEzC6n>%zDwRq@`VM4@_ccpK@G=V)a_v&&fEtqAOh~zoK-l|J%&6x+9qAuG!be< z`783^zTP=qpb&A9^L-x*N_|{)cI+60a?5?{1|J(8mAIs9jP*J?C@G++onoK7K#tRX z(oG0rO?!OjUx z9|!z-XMttT)d*t<`?k0`TJiFDD;!!i4WT73`aOMs9g`Q^m||1o-?!NUkgS?1t;hn$ zonU5r{)bba<+6&DZfg20+)MK(GBEA8BAd3*Rde5MS4>0^A~!jO_Ht)0vB`0(m67@x z3!=YXtH=`m%OYxH1@F94Ldp4DL>x@gauT!;Z13-tX+LgxT+w|es{N1f!HRCH6fn%? z_Y_=QccCloMN|Y6D=4h9S5$kv3KGtKEOw41_DoP0T_Ix}Y*OZyeNRl#_jRm$DJMIW9=GEm3^p*V{J;f)s#LBTFQcDFbr8>FV`gvh=rKpDxEwT&dJ+$F%X6s~92ib~F+Jav8D zG8}(8y;UA!^n5zJQ3TZ=3mpR!Nv?F(88}O|Bqz+05Ky8Chw<1RG~wYC#c<&)yjWrd zBO<)6-k?_i=Ga}YkpqThI+@a8$MYQyr>qvM94^YWWJwk|Ijg@6JXcdJZ|dO0_mZ>h zrHMVc%Y`IKxcGpym0JrFun+8*p;_kCpT{lf8={JndqDWV+vNTcdj6E;nU^J3LJi)kq?Xx3SKJ*J`$&8XJL^bNTWIld4;9+PV%)W zVMGec|Huj_7s3a&l%o5(g#m!gMjWQn9M7xcqMBPWWw&*4F~9PLTRO{M=~uigR{2DZ z{qF5AL>nIuQ7WjP#uy@+ahMizc>;(A`&jYXQkJ!Ic@nvVbW;7f% z4PCwA6mVAmn3ui>2OzI$7Nb!T9S;(dpbgEdlR1@JaO2og;il;ly>lIUmpzkWPrM0V z<_vj|Rbn97*=_cfwZ3tl#uFm6-*Drykr5u`p#9r_u3X&J zlO#ZczcC3C5%gDqlGO9g1J!ufy4_%8jo8g5H&`1Tl;KS^l}EaPI+Aa7k5xN~>_9N8 zEiJKwjmZQ!ReG}R$B&ZM;#ON)*$Pyvs;Qi$I^|NO4mB*ZJJlM;B`jeeQ^fM_+0Znj zhYGef^>soMSs|e0R7{_vFN}@h9#^KW<6(pZ@Ycfc_IELU3h`igwN0&OB*{}EW!2Z8 z5OfH7_?`>*BxB>iTx}@%C2QI8Ww!V>8adc%iQ&TsPQWRrjorG|$#9MBJ`Wd_9%WA= z{x3MoHcF5=PY(U&+A+TUu#X9UJ4ipPuqDN@adx&!E^a2v7Z<$EBQX*C<%3^k2Bvkoxlt;VtHbN#}ry9`5w?;hag%yF|p# z6|pdb{LFiV)62>r9iM74ad9UHe9lJ^xlGwZm-Pp+y(Tn^Ck<6VyFXUP45>b2GZnaW z9;fIp8++TtO5lEw{pdX7i+3uK4c7H29$srkt#-i}acM(3AzN0ZwA=Xh+>C^fC%NBX zKk5>oZ^`R5?L1Kx*qem+etn5u&MK|gwR_#L@Z1Vvja%Ef#FGhML5O_|H8R6`$-Pp% zcL8>DCYKWs{}qS1e*q#B?$SSH3wr+X(dnUU+yLDtIlv`dZPTcDm5z@NvK!%R6Lvpa=w53DQvd``dTry%3K26>q~Rw!@30G5gw)?%kt> zP?ql~XtBkWNufR9hE=-5Vv}Z$& z-eSJ1vG|4$-16Sq(c4r`=JHjlYQW?l@cbKU_N?=ao9csu0ZlS z>h0)ItX=M9bX0fLCXxl-%3r6%XRKVfDc&?})to=L|Iy!K-z7?Fb~vjIL71>OfdXy# zrxgYjYx~N*Q%)$>rLHPwudb4n7(Mx&>g|%z=;bGrav7UA6q%faMPgQFZ--LyCl@kT zS8kPM;I?mJ-79~x0Ocuy8f!#8GK6K-7)bsSoyNnw)>Ug z>TW9gEB}(Z%N}Vwtsj(>#>%BG@!*WDHLT!Yc|;pRb!7*AAfV%GOty9uIf`bsr1T&C zAytvct9eKeF^!AobWC9#-A*?qWW`c*4kSu+5eKGO7NPk(bSIuD~Y{;N9a#@nZi%VH`h)M2DaF6 zyu2`;peKDpugR=+ox8A{c4Xu-ysnQU@%*2GI^fr>FJIOkJWZgUif8!$bg4LF65RTC z+~`vlK%?^2kKlwOYn+(8Vn+b_t9ROOHc_u(a{5J~J)Qc`y>4Y0jnwYrIe*wNo78(l z#(p^?m4(JD^s6#78aR|Om$+Nraw$apH`~Ck6O0*NtsMF7Zn!Zhu!}e8uD{2Qn~46w z5cXI|LQEGT>s`I|lR2jMZx63>@c ziq;NHMU9VswYoY1y@W3DK-47ejuHI*J@MSQZrGpx=iMfc?f04dcXhW9%y|mJd7x3; z5I$xld*)vfR^5wpW`459@%e5~kkE!~bkx}3-pum(oygbbBn^V0D;*v8i7*(^c;R?= zp+u4Hz>uwB_9%9$heYz-v)SD}H0Sxm$|DoO2@zJiW^ZA}>G7lR8-tbryG4`+92i0} zfw#!7TqmY?i;_PBNosW&vcXmhhjoJDQBL(=2u1##==*HM|E)|HVoD;N*8^?tC)t~L zH+WcV)&J%n5qK92?(O){;vECqtjXXjV_zZ=cE1~b(o2&0Y^`w-^bZ~belhyhJeP}o zvoyLZzo$#Onym8S(5W=fdZs#fM532vJ9PBzW%5p>SF)$)UOEwaK}yNkujY8pXR&a& z6v}Y%o$5be1NZvOenZv}-jjTPEv%Dok-x-ABOKV}Qr>i*`GTh<1)#g=^jxPA9#NKJ zi;29nF=uWL?+z4>KvGrfi?YpQgpaBG3t+$yjd=oW|G6iL4e3rKp^qFrr~a6X%jXhY zh4Ik?k~C6yiAfh`@>&0H4U0o&--%s6HbIiwl8E;eYOgING(PVBNe`d((=S1 zNtRmEJShO6Ju4L4%TF1$^tP<1=0#XZ{aO;C5rsUP9?dZI-WayvL^(Qf#DgHv%bl!A z8t75E*L-m#iv{r%l@R=MWv;}YhbAZDa9;{+jXLlAM1sEg-nZ=J(PF%e>JZ6!dIVORsAFUTOLh#@zN(fKtH@Eo@hYN?NEP zkH6P+*78=4_jNJ4lgvbm=Gp=OvGV`!@k{SwaK|Jw89Kl_rhmD6sj?scYUVxGJ`Z!B z&lPscWA zcI)~tSsTN%cS*&BqXX;gmT9+Uq2t$TrwH#PlSL6Pf3Hn^s@f@*XRmLBe;)pz%B)Xt zzIK(xpk?R~TK1WZTX)yfAWiYIjU99QK!uEuN!Skt2Rpm`cb9csg*il;p2&*W%Zi+& z4X@h$htCSyo0~gOk5UXg0c>Y9R7~@EzbJYpuCExcS(x}s-|OaDsJ#9U!HT#F#|YcQ zV?`i}5X4bI>=A@g;H_MMASg+|o|LQiAGnNn>b^(uIie4`<@>sEK>=F+>aTxC_BTN9 z^E9(0ZYl~Ey8YgeXL(Gy(fOU`0@w~@NId%&?2t%v)KApAgiB+52VfQNAp8CMl%@7Z zZ9zp@M`P!pZo4c+ReGfdH}n1L#}w>N8X+b&L62;Y_3_&I@2{{m7GGYK)ouP#{dlz5 zKv)5W9QDBjhG`_p1>xYmW@TaK{&gGhg6V3~3;dNH#xUYSKrW+Knk{kD=d$To)8qkn zAN60(;iju2agG`pXgb)uV`KUA5@nJE6((r;BYiW>GB`61`U;(h+F`}zUS>%DLHvyc zjdWjD)OHPO{i$a<%frWMcI$t$c4$ket#12NUdqc)2GrSS+eGAH=khUidcnYD5xUmz zDy`Kb4DZup;`y#zGv27jG(43FqD;OeU_P(%*~|EIzDgX~a}xH_^-xo3a(*)e}XG52*N zn0F_AowtRKcL^oyNA;@F8X-GNd%1c^*)uIL_=dRYSw?Nuy*kG29&kLxQXZ0hsO+9O zrvs61f-zN{aY@q_`P2RTqd7K$76^w28Llk7SbHkhToyQK5MCwcmsC+%8HF~tVUXC4 z`=wF8E?yw>wnNVQAIsvh8&gv2t7VDvXz*A$52-Vjhj)iE)su!yGPB^9cd1^4NSvQL z0~y4x5IP8bpcJiPJh>J^cah2Ad;7jIscpC21=;4A3){}s@%O23*8UYz9hd0252|mb z&h^E*2}fEj7*gY>Sfg#Cg`o!St^bt`xgWhJO~cE}&xkh-6b#Ct7W zvvW0SvO}iIn6hfgjHU0+_rzPw>a^dx8eEWPAdV%kiZ=ahF730xFo6=agR^d>R>-6@IvDI$<$ z84z(BPDG?$w0ESCYg`Z4zrt)_<_fEe1+YJ4q1OFErLHvIT zsnc{L;9pKDab%Vq@W#i=_@tNKobn%9FD4NR297JdU*ybLtHx0>j%jIGvCwQK`lomI z?d{aS@r+|)e)4(m=7RGnQ92A^BpXRFT`8F%`WWE;PefON=$Ye8VLWfG)B#XE{H*FO zMALc^RcHaXj_8Dz-FcMBAIA!6fEnw?<7%+XF;k_y9F@Er?!YkmCzrtw83Yeg4!Vg5Q8|-C3N!67+#cr4RTICea6TA)uuug%hwFln1BuTyVUt!*4t9o?YZRdGZP=ohFPn3j1>L^!l4PIs z$RvbZOU-VAO9!S>H9_A6H;-TXHva?Eke3nV5UZ?l{!?l zZ-c8w>9)F3fS;WZ%R|Ap3EULO%0oOazJ5jqd9!PJo@P@XZP(!+@X$?gt06Paq7-AF z2v)4h^8mVg$al?^HvYb10!Wm$wtRt@;J`A7AG_$(n?YKIU19N)z1Cr@3f9N~ literal 0 HcmV?d00001 From 956f8c23b9bb7b760832bd05002f1c20f5d9e392 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Fri, 21 Dec 2018 17:02:32 +0300 Subject: [PATCH 114/368] Get remote endpoint from the configuration. --- .../Acme.BookStore.ConsoleApiClient.csproj | 7 +++++++ .../ApiClientDemoService.cs | 1 + .../ConsoleApiClientModule.cs | 14 +++++++++----- .../Acme.BookStore.ConsoleApiClient/Program.cs | 2 ++ .../appsettings.json | 7 +++++++ 5 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 samples/BookStore/test/Acme.BookStore.ConsoleApiClient/appsettings.json diff --git a/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/Acme.BookStore.ConsoleApiClient.csproj b/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/Acme.BookStore.ConsoleApiClient.csproj index 0582d6f067..bc66bc8ded 100644 --- a/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/Acme.BookStore.ConsoleApiClient.csproj +++ b/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/Acme.BookStore.ConsoleApiClient.csproj @@ -8,7 +8,14 @@ + + + + Always + + + diff --git a/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/ApiClientDemoService.cs b/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/ApiClientDemoService.cs index d16746bdb8..5aa617da5e 100644 --- a/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/ApiClientDemoService.cs +++ b/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/ApiClientDemoService.cs @@ -16,6 +16,7 @@ namespace Acme.BookStore.ConsoleApiClient public async Task RunAsync() { + //While it seems like a regular method call, it actually calls a remote REST API. var output = await _bookAppService.GetListAsync(new PagedAndSortedResultRequestDto()); foreach (var bookDto in output.Items) { diff --git a/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/ConsoleApiClientModule.cs b/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/ConsoleApiClientModule.cs index 8bd13aee76..ed5c08e4f1 100644 --- a/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/ConsoleApiClientModule.cs +++ b/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/ConsoleApiClientModule.cs @@ -1,4 +1,6 @@ -using Microsoft.Extensions.DependencyInjection; +using System.IO; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Autofac; using Volo.Abp.Http.Client; using Volo.Abp.Modularity; @@ -14,10 +16,12 @@ namespace Acme.BookStore.ConsoleApiClient { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => - { - options.RemoteServices.Default = new RemoteServiceConfiguration("http://localhost:53929/"); - }); + var configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .Build(); + + context.Services.Configure(configuration); context.Services.AddHttpClientProxies( typeof(BookStoreApplicationModule).Assembly diff --git a/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/Program.cs b/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/Program.cs index 3be13e1281..2e0ffa25c7 100644 --- a/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/Program.cs +++ b/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/Program.cs @@ -5,6 +5,8 @@ using Volo.Abp.Threading; namespace Acme.BookStore.ConsoleApiClient { + /* Before running this application, ensure that the Acme.BookStore.Web application is running. + */ class Program { static void Main(string[] args) diff --git a/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/appsettings.json b/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/appsettings.json new file mode 100644 index 0000000000..1f3cc219b5 --- /dev/null +++ b/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/appsettings.json @@ -0,0 +1,7 @@ +{ + "RemoteServices": { + "Default": { + "BaseUrl": "http://localhost:53929/" + } + } +} \ No newline at end of file From c82c8ae2db1463484f2254405c3565fd72885255 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Fri, 21 Dec 2018 17:03:05 +0300 Subject: [PATCH 115/368] Resolved #651: Document Dynamic C# API Clients. --- .../AspNetCore/Dynamic-CSharp-API-Clients.md | 153 ++++++++++++++++++ docs/en/docs-nav.json | 4 + 2 files changed, 157 insertions(+) create mode 100644 docs/en/AspNetCore/Dynamic-CSharp-API-Clients.md diff --git a/docs/en/AspNetCore/Dynamic-CSharp-API-Clients.md b/docs/en/AspNetCore/Dynamic-CSharp-API-Clients.md new file mode 100644 index 0000000000..eee2abacc0 --- /dev/null +++ b/docs/en/AspNetCore/Dynamic-CSharp-API-Clients.md @@ -0,0 +1,153 @@ +# Dynamic C# API Clients + +ABP can dynamically create C# API client proxies to call remote HTTP services (REST APIs). In this way, you don't need to deal with `HttpClient` and other low level HTTP features to call remote services and get results. + +## Service Interface + +Your service/controller should implement an interface that is shared between the server and the client. So, first define a service interface in a shared library project. Example: + +````csharp +public interface IBookService : IApplicationService +{ + Task> GetListAsync(); +} +```` + +Your interface should implement the `IRemoteService` interface. Since the `IApplicationService` inherits the `IRemoteService` interface, the `IBookService` above satisfies this condition. + +Implement this class in your service application. You can use [auto API controller system](Auto-API-Controllers.md) to expose the service as a REST API endpoint. + +## Client Proxy Generation + +First, add [Volo.Abp.Http.Client](https://www.nuget.org/packages/Volo.Abp.Http.Client) nuget package to your client project: + +```` +Install-Package Volo.Abp.Http.Client +```` + +Then add `AbpHttpClientModule` dependency to your module: + +````csharp +[DependsOn(typeof(AbpHttpClientModule))] //add the dependency +public class MyClientAppModule : AbpModule +{ +} +```` + +Now, it's ready to create the client proxies. Example: + +````csharp +[DependsOn( + typeof(AbpHttpClientModule), //used to create client proxies + typeof(BookStoreApplicationModule) //contains the application service interfaces + )] +public class MyClientAppModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + //Configure remote end point + context.Services.Configure(options => + { + options.RemoteServices.Default = + new RemoteServiceConfiguration("http://localhost:53929/"); + }); + + //Create dynamic client proxies + context.Services.AddHttpClientProxies( + typeof(BookStoreApplicationModule).Assembly + ); + } +} +```` + +`RemoteServiceOptions` is used to configure endpoints for remote services (This example sets the default endpoint while you can have different service endpoints used by different clients. See the "Multiple Remote Service Endpoint" section). + +`AddHttpClientProxies` method gets an assembly, finds all service interfaces in the given assembly, creates and registers proxy classes. + +## Usage + +It's straightforward to use. Just inject the service interface in the client application code: + +````csharp +public class MyService : ITransientDependency +{ + private readonly IBookService _bookService; + + public MyService(IBookService bookService) + { + _bookService = bookService; + } + + public async Task DoIt() + { + var books = await _bookService.GetListAsync(); + foreach (var book in books) + { + Console.WriteLine($"[BOOK {book.Id}] Name={book.Name}"); + } + } +} +```` + +This sample injects the `IBookService` service interface defined above. The dynamic client proxy implementation makes an HTTP call whenever a service method is called by the client. + +## Configuration Details + +### RemoteServiceOptions + +While you can configure `RemoteServiceOptions` as the example shown above, you can let it to read from your `appsettings.json` file. Add a `RemoteServices` section to your `appsettings.json` file: + +````json +{ + "RemoteServices": { + "Default": { + "BaseUrl": "http://localhost:53929/" + } + } +} +```` + +Then you can pass your `IConfigurationRoot` instance directly to the `Configure()` method as shown below: + +````csharp +var configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .Build(); + +context.Services.Configure(configuration); +```` + +This approach is useful since it's easy to change the configuration later without touching to the code. + +#### Multiple Remote Service Endpoint + +The examples above have configured the "Default" remote service endpoint. You may have different endpoints for different services (as like in a microservice approach where each microservice has different endpoint). In this case, you can add other endpoints to your configuration file: + +````json +{ + "RemoteServices": { + "Default": { + "BaseUrl": "http://localhost:53929/" + }, + "BookStore": { + "BaseUrl": "http://localhost:48392/" + } + } +} +```` + +See the next section to learn how to use this new endpoint. + +### AddHttpClientProxies Method + +`AddHttpClientProxies` method can get an additional parameter for the remote service name. Example: + +````csharp +context.Services.AddHttpClientProxies( + typeof(BookStoreApplicationModule).Assembly, + remoteServiceName: "BookStore" +); +```` + +`remoteServiceName` parameter matches the service endpoint configured via `RemoteServiceOptions`. If the `BookStore` endpoint is not defined then it fallbacks to the `Default` endpoint. \ No newline at end of file diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 01f8fb884b..a3e3355a55 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -194,6 +194,10 @@ { "text": "Auto API Controllers", "path": "AspNetCore/Auto-API-Controllers.md" + }, + { + "text": "Dynamic C# API Clients", + "path": "AspNetCore/Dynamic-CSharp-API-Clients.md" } ] }, From 3e1cce2c914116ee1f9dda76d333a406f5d40232 Mon Sep 17 00:00:00 2001 From: Alper Ebicoglu Date: Fri, 21 Dec 2018 17:03:34 +0300 Subject: [PATCH 116/368] fixed link --- docs/en/Modules/Docs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Modules/Docs.md b/docs/en/Modules/Docs.md index f99e5ca320..ae08f42d92 100644 --- a/docs/en/Modules/Docs.md +++ b/docs/en/Modules/Docs.md @@ -412,7 +412,7 @@ public class Person As an example you can see ABP Framework documentation: -https://github.com/abpframework/abp/blob/master/docs/en/ +[https://github.com/abpframework/abp/blob/master/docs/en/](https://github.com/abpframework/abp/blob/master/docs/en/) ### 8- Creating the Navigation Document From 6072acceef2b9ac1bf281bd84e4b79284386abe4 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Fri, 21 Dec 2018 17:07:37 +0300 Subject: [PATCH 117/368] Increment version to 0.10.0. --- common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.props b/common.props index 15df803252..ab2b655172 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 0.9.0 + 0.10.0 $(NoWarn);CS1591 https://abp.io/assets/abp_nupkg.png https://abp.io From 16120747967281964f19a182ec952855f650c474 Mon Sep 17 00:00:00 2001 From: Alper Ebicoglu Date: Fri, 21 Dec 2018 17:08:35 +0300 Subject: [PATCH 118/368] fixed image links --- docs/en/Modules/Docs.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/Modules/Docs.md b/docs/en/Modules/Docs.md index ae08f42d92..1aa81621f5 100644 --- a/docs/en/Modules/Docs.md +++ b/docs/en/Modules/Docs.md @@ -32,13 +32,13 @@ Navigate to https://abp.io/Templates. Enter your project name as `Acme.MyProject Note that this document covers `Entity Framework Core` provider but you can also select `MongoDB` as your database provider. -![Create new project](..\images\docs-module_download-new-abp-project.png) +![Create new project](../images/docs-module_download-new-abp-project.png) ### 2- Running The Empty Application After you download the project, extract the ZIP file and open `Acme.MyProject.sln`. You will see that the solution consists of `Application`, `Domain `, `EntityFrameworkCore` and `Web` projects. Right click on `Acme.MyProject.Web` project and **Set as StartUp Project**. -![Create a new project](..\images\docs-module_solution-explorer.png) +![Create a new project](../images/docs-module_solution-explorer.png) The database connection string is located in `appsettings.json` of your `Acme.MyProject.Web` project. If you have a different database configuration, change the connection string. @@ -468,7 +468,7 @@ Navigation document is the main menu of the documents page. It is located on the The upper sample `JSON` file renders the below navigation menu as `HTML`. -![Create a new project](..\images\docs-module_download-sample-navigation-menu.png) +![Navigation menu](../images/docs-module_download-sample-navigation-menu.png) From 2ca539763a841057762b9ae76399b475fdc81366 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Fri, 21 Dec 2018 17:14:36 +0300 Subject: [PATCH 119/368] Update ButtonGroups.cshtml --- .../Pages/Components/ButtonGroups.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ButtonGroups.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ButtonGroups.cshtml index 90cd39f7ab..b128174d61 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ButtonGroups.cshtml +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/ButtonGroups.cshtml @@ -244,7 +244,7 @@

    Vertical variation

    -
    +
    button button From 7063f191a589a41e3d981e550c1c5236f09bbbd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E5=A3=AB=E4=BC=9F?= Date: Mon, 24 Dec 2018 09:53:22 +0800 Subject: [PATCH 120/368] Resolved #19: Synchronization module development Chinese document. --- docs/zh-Hans/Module-Development-Basics.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/zh-Hans/Module-Development-Basics.md b/docs/zh-Hans/Module-Development-Basics.md index 044016e17a..9feaa8c7f9 100644 --- a/docs/zh-Hans/Module-Development-Basics.md +++ b/docs/zh-Hans/Module-Development-Basics.md @@ -125,3 +125,10 @@ public class BlogModule 你可以根据需要使用多个``DependsOn``属性或将多个模块类型传递给单个``DependsOn``属性. 依赖模块可能依赖于另一个模块,但你只需要定义直接依赖项.ABP在启动时会调查应用程序的依赖关系,并以正确的顺序初始化/关闭模块. + +## 框架模块 vs 应用程序模块 + +**模块分为两种类型.** 这两种类型并没有任何结构上的区别,只是按功能和用途分类: + +- **框架模块**: 这些是**框架的核心模块** 如缓存, 邮件, 主题, 安全, 序列化, 验证, EF Core集成, MongoDB集成... 等. 它们没有应用/业务功能,它们提供了日常开发经常用到的基础设施,集成和抽象. +- **应用程序模块**: 这些模块实现了 **特定的应用/业务功能** 像博客, 文档管理, 身份管理, 租房管理... 等等. 它们通过有自己的实体,服务,API和UI组件. 请参阅 [预构建的应用程序模块](Modules/Index.md). From 444f7d5412ce35118a4feba946bde8d72c60a5aa Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 24 Dec 2018 13:07:40 +0300 Subject: [PATCH 121/368] project management CRUD AppService #629 --- .../Volo/Docs/Projects/CreateProjectDto.cs | 27 +++++++++ .../Volo/Docs/Projects/IProjectAppService.cs | 7 +++ .../Volo/Docs/Projects/ProjectDto.cs | 13 +++- .../Volo/Docs/Projects/UpdateProjectDto.cs | 25 ++++++++ .../Volo/Docs/Projects/ProjectAppService.cs | 59 ++++++++++++++++++- .../Volo/Docs/Projects/Project.cs | 24 ++++++++ 6 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/CreateProjectDto.cs create mode 100644 modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/UpdateProjectDto.cs diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/CreateProjectDto.cs b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/CreateProjectDto.cs new file mode 100644 index 0000000000..cb02c579a3 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/CreateProjectDto.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; + +namespace Volo.Docs.Projects +{ + public class CreateProjectDto + { + public string Name { get; set; } + + public string ShortName { get; set; } + + public string Format { get; set; } + + public string DefaultDocumentName { get; set; } + + public string NavigationDocumentName { get; set; } + + public string MinimumVersion { get; set; } + + public string MainWebsiteUrl { get; set; } + + public string LatestVersionBranchName { get; set; } + + public string DocumentStoreType { get; set; } + + public Dictionary ExtraProperties { get; set; } + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/IProjectAppService.cs b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/IProjectAppService.cs index 5bfc221e4d..8dba5fa3e1 100644 --- a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/IProjectAppService.cs +++ b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/IProjectAppService.cs @@ -1,3 +1,4 @@ +using System; using System.Threading.Tasks; using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; @@ -9,6 +10,12 @@ namespace Volo.Docs.Projects Task> GetListAsync(); Task GetAsync(string shortName); + + Task CreateAsync(CreateProjectDto input); + + Task UpdateAsync(Guid id, UpdateProjectDto input); + + Task DeleteAsync(Guid id); Task> GetVersionsAsync(string shortName); } diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/ProjectDto.cs b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/ProjectDto.cs index a29ea840b3..91f5c63a22 100644 --- a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/ProjectDto.cs +++ b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/ProjectDto.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Volo.Abp.Application.Dtos; namespace Volo.Docs.Projects @@ -10,12 +11,20 @@ namespace Volo.Docs.Projects public string ShortName { get; set; } + public string Format { get; set; } + public string DefaultDocumentName { get; set; } + public string NavigationDocumentName { get; set; } + + public string MinimumVersion { get; set; } + public string MainWebsiteUrl { get; set; } - public virtual string DocumentStoreType { get; protected set; } + public string LatestVersionBranchName { get; set; } + + public string DocumentStoreType { get; set; } - public virtual string Format { get; protected set; } + public Dictionary ExtraProperties { get; set; } } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/UpdateProjectDto.cs b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/UpdateProjectDto.cs new file mode 100644 index 0000000000..b16f1916e4 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/UpdateProjectDto.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using Volo.Abp.Application.Dtos; + +namespace Volo.Docs.Projects +{ + public class UpdateProjectDto + { + public string Name { get; set; } + + public string Format { get; set; } + + public string DefaultDocumentName { get; set; } + + public string NavigationDocumentName { get; set; } + + public string MinimumVersion { get; set; } + + public string MainWebsiteUrl { get; set; } + + public string LatestVersionBranchName { get; set; } + + public Dictionary ExtraProperties { get; set; } + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs index 7afefee4f1..6a7e8132fc 100644 --- a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs +++ b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs @@ -6,6 +6,7 @@ using Microsoft.Extensions.Caching.Distributed; using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; using Volo.Abp.Caching; +using Volo.Abp.Guids; using Volo.Docs.Documents; namespace Volo.Docs.Projects @@ -15,15 +16,17 @@ namespace Volo.Docs.Projects private readonly IProjectRepository _projectRepository; private readonly IDistributedCache> _versionCache; private readonly IDocumentStoreFactory _documentStoreFactory; + private readonly IGuidGenerator _guidGenerator; public ProjectAppService( IProjectRepository projectRepository, IDistributedCache> versionCache, - IDocumentStoreFactory documentStoreFactory) + IDocumentStoreFactory documentStoreFactory, IGuidGenerator guidGenerator) { _projectRepository = projectRepository; _versionCache = versionCache; _documentStoreFactory = documentStoreFactory; + _guidGenerator = guidGenerator; } public async Task> GetListAsync() @@ -42,6 +45,60 @@ namespace Volo.Docs.Projects return ObjectMapper.Map(project); } + public async Task CreateAsync(CreateProjectDto input) + { + var project = new Project(_guidGenerator.Create(), + input.Name, + input.ShortName, + input.DocumentStoreType, + input.Format, + input.DefaultDocumentName, + input.NavigationDocumentName + ) + { + MinimumVersion = input.MinimumVersion, + MainWebsiteUrl = input.MainWebsiteUrl, + LatestVersionBranchName = input.LatestVersionBranchName + }; + + foreach (var extraProperty in input.ExtraProperties) + { + project.ExtraProperties.Add(extraProperty.Key,extraProperty.Value); + } + + project = await _projectRepository.InsertAsync(project); + + return ObjectMapper.Map(project); + } + + public async Task UpdateAsync(Guid id, UpdateProjectDto input) + { + var project = await _projectRepository.GetAsync(id); + + project.SetName(input.Name); + project.SetFormat(input.Format); + project.SetNavigationDocumentName(input.NavigationDocumentName); + project.SetDefaultDocumentName(input.DefaultDocumentName); + + project.MinimumVersion = input.MinimumVersion; + project.MainWebsiteUrl = input.MainWebsiteUrl; + project.LatestVersionBranchName = input.LatestVersionBranchName; + + foreach (var extraProperty in input.ExtraProperties) + { + project.ExtraProperties[extraProperty.Key] = extraProperty.Value; + } + + project = await _projectRepository.UpdateAsync(project); + + return ObjectMapper.Map(project); + } + + public async Task DeleteAsync(Guid id) + { + await _projectRepository.DeleteAsync(id); + } + public async Task> GetVersionsAsync(string shortName) { var project = await _projectRepository.GetByShortNameAsync(shortName); diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Project.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Project.cs index 7472ace4e3..2a98ea6cff 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Project.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Project.cs @@ -54,6 +54,8 @@ namespace Volo.Docs.Projects Guid id, [NotNull] string name, [NotNull] string shortName, + [NotNull] string documentStoreType, + [NotNull] string format, [NotNull] string defaultDocumentName, [NotNull] string navigationDocumentName) { @@ -61,10 +63,32 @@ namespace Volo.Docs.Projects Name = Check.NotNullOrWhiteSpace(name, nameof(name)); ShortName = Check.NotNullOrWhiteSpace(shortName, nameof(shortName)); + DocumentStoreType = Check.NotNullOrWhiteSpace(documentStoreType, nameof(documentStoreType)); + Format = Check.NotNullOrWhiteSpace(format, nameof(format)); DefaultDocumentName = Check.NotNullOrWhiteSpace(defaultDocumentName, nameof(defaultDocumentName)); NavigationDocumentName = Check.NotNullOrWhiteSpace(navigationDocumentName, nameof(navigationDocumentName)); ExtraProperties = new Dictionary(); } + + public void SetName(string name) + { + Name = Check.NotNullOrWhiteSpace(name, nameof(name)); + } + + public void SetFormat(string format) + { + Format = Check.NotNullOrWhiteSpace(format, nameof(format)); + } + + public void SetNavigationDocumentName(string navigationDocumentName) + { + NavigationDocumentName = Check.NotNullOrWhiteSpace(navigationDocumentName, nameof(navigationDocumentName)); + } + + public void SetDefaultDocumentName(string defaultDocumentName) + { + DefaultDocumentName = Check.NotNullOrWhiteSpace(defaultDocumentName, nameof(defaultDocumentName)); + } } } \ No newline at end of file From 5bee7411bd30203e9e9bd1c9ead973b3c54d4b34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Mon, 24 Dec 2018 14:00:00 +0300 Subject: [PATCH 122/368] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5074216c59..330c30d69f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ABP -[![Build Status](http://vjenkins.dynu.net:5480/job/abp/badge/icon)](http://vjenkins.dynu.net:5480/blue/organizations/jenkins/abp/activity) +[![Build Status](http://vjenkins.dynu.net:5480/job/abp/badge/icon)](http://ci.volosoft.com:5480/blue/organizations/jenkins/abp/activity) This project is the next generation of the [ASP.NET Boilerplate](https://aspnetboilerplate.com/) web application framework. See [the announcement](https://abp.io/blog/abp/Abp-vNext-Announcement). From ec3e904cd8ed01be4e6c232e99a36413d7c59b74 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 24 Dec 2018 15:09:46 +0300 Subject: [PATCH 123/368] Update DocsProjectController.cs --- .../Docs/Projects/DocsProjectController.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Projects/DocsProjectController.cs b/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Projects/DocsProjectController.cs index 773655aab8..180cec622f 100644 --- a/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Projects/DocsProjectController.cs +++ b/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Projects/DocsProjectController.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Volo.Abp; using Volo.Abp.Application.Dtos; @@ -33,6 +34,21 @@ namespace Volo.Docs.Projects return ProjectAppService.GetAsync(shortName); } + public Task CreateAsync(CreateProjectDto input) + { + return ProjectAppService.CreateAsync(input); + } + + public Task UpdateAsync(Guid id, UpdateProjectDto input) + { + return ProjectAppService.UpdateAsync(id, input); + } + + public Task DeleteAsync(Guid id) + { + return ProjectAppService.DeleteAsync(id); + } + [HttpGet] [Route("{shortName}/versions")] public virtual Task> GetVersionsAsync(string shortName) From 089cf8d8a9173c200db98575333381d3581841b2 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 24 Dec 2018 15:28:50 +0300 Subject: [PATCH 124/368] Bookstore App : Upgraded Abp Packages to v0.10.0* https://github.com/abpframework/abp/issues/680 --- .../Acme.BookStore.Application.csproj | 2 +- .../Acme.BookStore.Domain.csproj | 2 +- .../Acme.BookStore.EntityFrameworkCore.csproj | 8 +- .../EntityFrameworkCore/BookStoreDbContext.cs | 5 + ...24122651_Upgreded_ABP_Packages.Designer.cs | 448 ++++++++++++++++++ .../20181224122651_Upgreded_ABP_Packages.cs | 75 +++ .../BookStoreDbContextModelSnapshot.cs | 25 +- .../Acme.BookStore.Web.csproj | 8 +- .../Acme.BookStore.Application.Tests.csproj | 4 +- .../Acme.BookStore.ConsoleApiClient.csproj | 4 +- .../Acme.BookStore.Web.Tests.csproj | 2 +- 11 files changed, 567 insertions(+), 16 deletions(-) create mode 100644 samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/Migrations/20181224122651_Upgreded_ABP_Packages.Designer.cs create mode 100644 samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/Migrations/20181224122651_Upgreded_ABP_Packages.cs diff --git a/samples/BookStore/src/Acme.BookStore.Application/Acme.BookStore.Application.csproj b/samples/BookStore/src/Acme.BookStore.Application/Acme.BookStore.Application.csproj index 7f8acd52f5..3711361b25 100644 --- a/samples/BookStore/src/Acme.BookStore.Application/Acme.BookStore.Application.csproj +++ b/samples/BookStore/src/Acme.BookStore.Application/Acme.BookStore.Application.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/BookStore/src/Acme.BookStore.Domain/Acme.BookStore.Domain.csproj b/samples/BookStore/src/Acme.BookStore.Domain/Acme.BookStore.Domain.csproj index 87a8e297b3..301c88f15f 100644 --- a/samples/BookStore/src/Acme.BookStore.Domain/Acme.BookStore.Domain.csproj +++ b/samples/BookStore/src/Acme.BookStore.Domain/Acme.BookStore.Domain.csproj @@ -6,7 +6,7 @@ - + diff --git a/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/Acme.BookStore.EntityFrameworkCore.csproj b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/Acme.BookStore.EntityFrameworkCore.csproj index 44fb8928f6..00f6e2ac9e 100644 --- a/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/Acme.BookStore.EntityFrameworkCore.csproj +++ b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/Acme.BookStore.EntityFrameworkCore.csproj @@ -17,10 +17,10 @@ - - - - + + + + diff --git a/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContext.cs b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContext.cs index 86d276a6f7..40e8a79dd0 100644 --- a/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContext.cs +++ b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/EntityFrameworkCore/BookStoreDbContext.cs @@ -1,5 +1,6 @@ using Microsoft.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore.Modeling; using Volo.Abp.Identity.EntityFrameworkCore; using Volo.Abp.PermissionManagement.EntityFrameworkCore; using Volo.Abp.SettingManagement.EntityFrameworkCore; @@ -20,6 +21,10 @@ namespace Acme.BookStore.EntityFrameworkCore { base.OnModelCreating(modelBuilder); + modelBuilder.Entity( + b => b.ConfigureExtraProperties() + ); + modelBuilder.ConfigureIdentity(); modelBuilder.ConfigurePermissionManagement(); modelBuilder.ConfigureSettingManagement(); diff --git a/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/Migrations/20181224122651_Upgreded_ABP_Packages.Designer.cs b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/Migrations/20181224122651_Upgreded_ABP_Packages.Designer.cs new file mode 100644 index 0000000000..c3cbd8e6d2 --- /dev/null +++ b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/Migrations/20181224122651_Upgreded_ABP_Packages.Designer.cs @@ -0,0 +1,448 @@ +// +using System; +using Acme.BookStore.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace Acme.BookStore.Migrations +{ + [DbContext(typeof(BookStoreDbContext))] + [Migration("20181224122651_Upgreded_ABP_Packages")] + partial class Upgreded_ABP_Packages + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.1.1-rtm-30846") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Acme.BookStore.Book", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken(); + + b.Property("CreationTime"); + + b.Property("CreatorId"); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties"); + + b.Property("LastModificationTime"); + + b.Property("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128); + + b.Property("Price"); + + b.Property("PublishDate"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.ToTable("Books"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasColumnName("ConcurrencyStamp") + .HasMaxLength(256); + + b.Property("Description") + .HasMaxLength(256); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties"); + + b.Property("IsStatic"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256); + + b.Property("Regex") + .HasMaxLength(512); + + b.Property("RegexDescription") + .HasMaxLength(128); + + b.Property("Required"); + + b.Property("ValueType"); + + b.HasKey("Id"); + + b.ToTable("AbpClaimTypes"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasColumnName("ConcurrencyStamp") + .HasMaxLength(256); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties"); + + b.Property("IsDefault") + .HasColumnName("IsDefault"); + + b.Property("IsPublic") + .HasColumnName("IsPublic"); + + b.Property("IsStatic") + .HasColumnName("IsStatic"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256); + + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(256); + + b.Property("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName"); + + b.ToTable("AbpRoles"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256); + + b.Property("ClaimValue") + .HasMaxLength(1024); + + b.Property("RoleId"); + + b.Property("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AbpRoleClaims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AccessFailedCount") + .ValueGeneratedOnAdd() + .HasColumnName("AccessFailedCount") + .HasDefaultValue(0); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasColumnName("ConcurrencyStamp") + .HasMaxLength(256); + + b.Property("CreationTime"); + + b.Property("CreatorId"); + + b.Property("DeleterId"); + + b.Property("DeletionTime"); + + b.Property("Email") + .HasColumnName("Email") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnName("EmailConfirmed") + .HasDefaultValue(false); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted"); + + b.Property("LastModificationTime"); + + b.Property("LastModifierId"); + + b.Property("LockoutEnabled") + .ValueGeneratedOnAdd() + .HasColumnName("LockoutEnabled") + .HasDefaultValue(false); + + b.Property("LockoutEnd"); + + b.Property("Name") + .HasColumnName("Name") + .HasMaxLength(64); + + b.Property("NormalizedEmail") + .HasColumnName("NormalizedEmail") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .IsRequired() + .HasColumnName("NormalizedUserName") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnName("PasswordHash") + .HasMaxLength(256); + + b.Property("PhoneNumber") + .HasColumnName("PhoneNumber") + .HasMaxLength(16); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnName("PhoneNumberConfirmed") + .HasDefaultValue(false); + + b.Property("SecurityStamp") + .IsRequired() + .HasColumnName("SecurityStamp") + .HasMaxLength(256); + + b.Property("Surname") + .HasColumnName("Surname") + .HasMaxLength(64); + + b.Property("TenantId") + .HasColumnName("TenantId"); + + b.Property("TwoFactorEnabled") + .ValueGeneratedOnAdd() + .HasColumnName("TwoFactorEnabled") + .HasDefaultValue(false); + + b.Property("UserName") + .IsRequired() + .HasColumnName("UserName") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("NormalizedEmail"); + + b.HasIndex("NormalizedUserName"); + + b.HasIndex("UserName"); + + b.ToTable("AbpUsers"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256); + + b.Property("ClaimValue") + .HasMaxLength(1024); + + b.Property("TenantId"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AbpUserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.Property("UserId"); + + b.Property("LoginProvider") + .HasMaxLength(64); + + b.Property("ProviderDisplayName") + .HasMaxLength(128); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(196); + + b.Property("TenantId"); + + b.HasKey("UserId", "LoginProvider"); + + b.HasIndex("LoginProvider", "ProviderKey"); + + b.ToTable("AbpUserLogins"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.Property("UserId"); + + b.Property("RoleId"); + + b.Property("TenantId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId", "UserId"); + + b.ToTable("AbpUserRoles"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.Property("UserId"); + + b.Property("LoginProvider") + .HasMaxLength(64); + + b.Property("Name") + .HasMaxLength(128); + + b.Property("TenantId"); + + b.Property("Value"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AbpUserTokens"); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(64); + + b.Property("ProviderName") + .IsRequired() + .HasMaxLength(64); + + b.Property("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpPermissionGrants"); + }); + + modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128); + + b.Property("ProviderKey") + .HasMaxLength(64); + + b.Property("ProviderName") + .HasMaxLength(64); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2048); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpSettings"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole") + .WithMany("Claims") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser") + .WithMany("Claims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser") + .WithMany("Logins") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Volo.Abp.Identity.IdentityUser") + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser") + .WithMany("Tokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/Migrations/20181224122651_Upgreded_ABP_Packages.cs b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/Migrations/20181224122651_Upgreded_ABP_Packages.cs new file mode 100644 index 0000000000..77545ed9a3 --- /dev/null +++ b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/Migrations/20181224122651_Upgreded_ABP_Packages.cs @@ -0,0 +1,75 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Acme.BookStore.Migrations +{ + public partial class Upgreded_ABP_Packages : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ConcurrencyStamp", + table: "Books", + nullable: true); + + migrationBuilder.AddColumn( + name: "ExtraProperties", + table: "Books", + nullable: true); + + migrationBuilder.AlterColumn( + name: "ConcurrencyStamp", + table: "AbpRoles", + maxLength: 256, + nullable: false, + oldClrType: typeof(string), + oldNullable: true); + + migrationBuilder.AddColumn( + name: "ExtraProperties", + table: "AbpRoles", + nullable: true); + + migrationBuilder.AddColumn( + name: "ConcurrencyStamp", + table: "AbpClaimTypes", + maxLength: 256, + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "ExtraProperties", + table: "AbpClaimTypes", + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "ConcurrencyStamp", + table: "Books"); + + migrationBuilder.DropColumn( + name: "ExtraProperties", + table: "Books"); + + migrationBuilder.DropColumn( + name: "ExtraProperties", + table: "AbpRoles"); + + migrationBuilder.DropColumn( + name: "ConcurrencyStamp", + table: "AbpClaimTypes"); + + migrationBuilder.DropColumn( + name: "ExtraProperties", + table: "AbpClaimTypes"); + + migrationBuilder.AlterColumn( + name: "ConcurrencyStamp", + table: "AbpRoles", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 256); + } + } +} diff --git a/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/Migrations/BookStoreDbContextModelSnapshot.cs b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/Migrations/BookStoreDbContextModelSnapshot.cs index e3bd17d745..a707fa1487 100644 --- a/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/Migrations/BookStoreDbContextModelSnapshot.cs +++ b/samples/BookStore/src/Acme.BookStore.EntityFrameworkCore/Migrations/BookStoreDbContextModelSnapshot.cs @@ -24,10 +24,16 @@ namespace Acme.BookStore.Migrations b.Property("Id") .ValueGeneratedOnAdd(); + b.Property("ConcurrencyStamp") + .IsConcurrencyToken(); + b.Property("CreationTime"); b.Property("CreatorId"); + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties"); + b.Property("LastModificationTime"); b.Property("LastModifierId"); @@ -52,9 +58,18 @@ namespace Acme.BookStore.Migrations b.Property("Id") .ValueGeneratedOnAdd(); + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasColumnName("ConcurrencyStamp") + .HasMaxLength(256); + b.Property("Description") .HasMaxLength(256); + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties"); + b.Property("IsStatic"); b.Property("Name") @@ -81,7 +96,14 @@ namespace Acme.BookStore.Migrations b.Property("Id") .ValueGeneratedOnAdd(); - b.Property("ConcurrencyStamp"); + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasColumnName("ConcurrencyStamp") + .HasMaxLength(256); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties"); b.Property("IsDefault") .HasColumnName("IsDefault"); @@ -143,6 +165,7 @@ namespace Acme.BookStore.Migrations .HasDefaultValue(0); b.Property("ConcurrencyStamp") + .IsConcurrencyToken() .IsRequired() .HasColumnName("ConcurrencyStamp") .HasMaxLength(256); diff --git a/samples/BookStore/src/Acme.BookStore.Web/Acme.BookStore.Web.csproj b/samples/BookStore/src/Acme.BookStore.Web/Acme.BookStore.Web.csproj index 5cfa52f2c8..9c66768d6d 100644 --- a/samples/BookStore/src/Acme.BookStore.Web/Acme.BookStore.Web.csproj +++ b/samples/BookStore/src/Acme.BookStore.Web/Acme.BookStore.Web.csproj @@ -27,10 +27,10 @@ - - - - + + + + diff --git a/samples/BookStore/test/Acme.BookStore.Application.Tests/Acme.BookStore.Application.Tests.csproj b/samples/BookStore/test/Acme.BookStore.Application.Tests/Acme.BookStore.Application.Tests.csproj index fe3b577dc5..4bd65139df 100644 --- a/samples/BookStore/test/Acme.BookStore.Application.Tests/Acme.BookStore.Application.Tests.csproj +++ b/samples/BookStore/test/Acme.BookStore.Application.Tests/Acme.BookStore.Application.Tests.csproj @@ -8,8 +8,8 @@ - - + + diff --git a/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/Acme.BookStore.ConsoleApiClient.csproj b/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/Acme.BookStore.ConsoleApiClient.csproj index bc66bc8ded..4dade97b64 100644 --- a/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/Acme.BookStore.ConsoleApiClient.csproj +++ b/samples/BookStore/test/Acme.BookStore.ConsoleApiClient/Acme.BookStore.ConsoleApiClient.csproj @@ -6,8 +6,8 @@ - - + + diff --git a/samples/BookStore/test/Acme.BookStore.Web.Tests/Acme.BookStore.Web.Tests.csproj b/samples/BookStore/test/Acme.BookStore.Web.Tests/Acme.BookStore.Web.Tests.csproj index c10970a304..5b7141fdc7 100644 --- a/samples/BookStore/test/Acme.BookStore.Web.Tests/Acme.BookStore.Web.Tests.csproj +++ b/samples/BookStore/test/Acme.BookStore.Web.Tests/Acme.BookStore.Web.Tests.csproj @@ -15,7 +15,7 @@ - + From b1fbafff191fed6f9e6da1efb19a088bd42dbf97 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 24 Dec 2018 15:32:51 +0300 Subject: [PATCH 125/368] Resolved : AggregateRoot.ExtraProperties could not be mapped Ef Core #680 --- docs/en/Tutorials/AspNetCore-Mvc/Part-I.md | 24 +++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/docs/en/Tutorials/AspNetCore-Mvc/Part-I.md b/docs/en/Tutorials/AspNetCore-Mvc/Part-I.md index 9f766ae3b0..2afe26e7d2 100644 --- a/docs/en/Tutorials/AspNetCore-Mvc/Part-I.md +++ b/docs/en/Tutorials/AspNetCore-Mvc/Part-I.md @@ -82,11 +82,25 @@ namespace Acme.BookStore EF Core requires you to relate entities with your DbContext. The easiest way to do this is to add a `DbSet` property to the `BookStoreDbContext` class in the `Acme.BookStore.EntityFrameworkCore` project, as shown below: ````C# -public class BookStoreDbContext : AbpDbContext -{ - public DbSet Book { get; set; } - ... -} + public class BookStoreDbContext : AbpDbContext + { + public DbSet Book { get; set; } + + public BookStoreDbContext(DbContextOptions options) + : base(options) + { + + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.Entity( + b => b.ConfigureExtraProperties() + ); + } + } ```` #### Add New Migration & Update the Database From 6401c37bc18e4a7cb7d3072668ebc141683d9fe9 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Mon, 24 Dec 2018 16:29:52 +0300 Subject: [PATCH 126/368] Resolved #682: Automatically configure IHasExtraProperties for entities in EF Core. --- .../Abp/EntityFrameworkCore/AbpDbContext.cs | 69 +++++++++++++------ .../AbpEntityTypeBuilderExtensions.cs | 9 +++ .../TestApp/SecondContext/SecondDbContext.cs | 6 -- .../TestMigrationsDbContext.cs | 21 ------ .../EntityFrameworkCore/TestAppDbContext.cs | 16 ----- .../DocsDbContextModelBuilderExtensions.cs | 2 - 6 files changed, 58 insertions(+), 65 deletions(-) diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs index 6540930405..1f39d94774 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs @@ -11,6 +11,7 @@ using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; +using Newtonsoft.Json; using Volo.Abp.Auditing; using Volo.Abp.Data; using Volo.Abp.DependencyInjection; @@ -49,10 +50,10 @@ namespace Volo.Abp.EntityFrameworkCore public ILogger> Logger { get; set; } - private static readonly MethodInfo ConfigureGlobalFiltersMethodInfo + private static readonly MethodInfo ConfigureBasePropertiesMethodInfo = typeof(AbpDbContext) .GetMethod( - nameof(ConfigureGlobalFilters), + nameof(ConfigureBaseProperties), BindingFlags.Instance | BindingFlags.NonPublic ); @@ -71,9 +72,7 @@ namespace Volo.Abp.EntityFrameworkCore foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { - ConfigureConcurrencyStamp(entityType); - - ConfigureGlobalFiltersMethodInfo + ConfigureBasePropertiesMethodInfo .MakeGenericMethod(entityType.ClrType) .Invoke(this, new object[] { modelBuilder, entityType }); } @@ -155,19 +154,6 @@ namespace Volo.Abp.EntityFrameworkCore } } - protected virtual void ConfigureConcurrencyStamp(IMutableEntityType entityType) - { - if (!typeof(IHasConcurrencyStamp).GetTypeInfo().IsAssignableFrom(entityType.ClrType)) - { - return; - } - - entityType - .GetProperties() - .First(p => p.Name == nameof(IHasConcurrencyStamp.ConcurrencyStamp)) - .IsConcurrencyToken = true; - } - protected virtual EntityChangeReport ApplyAbpConcepts() { var changeReport = new EntityChangeReport(); @@ -326,10 +312,53 @@ namespace Volo.Abp.EntityFrameworkCore AuditPropertySetter.SetDeletionProperties(entry.Entity); } - protected void ConfigureGlobalFilters(ModelBuilder modelBuilder, IMutableEntityType entityType) + protected virtual void ConfigureBaseProperties(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType) + where TEntity : class + { + ConfigureConcurrencyStamp(modelBuilder, mutableEntityType); + ConfigureExtraProperties(modelBuilder, mutableEntityType); + ConfigureGlobalFilters(modelBuilder, mutableEntityType); + } + + protected virtual void ConfigureConcurrencyStamp(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType) + where TEntity : class + { + if (!typeof(IHasConcurrencyStamp).GetTypeInfo().IsAssignableFrom(typeof(TEntity))) + { + return; + } + + modelBuilder.Entity(b => + { + b.Property(x => ((IHasConcurrencyStamp) x).ConcurrencyStamp) + .IsConcurrencyToken() + .HasColumnName(nameof(IHasConcurrencyStamp.ConcurrencyStamp)); + }); + } + + protected virtual void ConfigureExtraProperties(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType) + where TEntity : class + { + if (!typeof(IHasExtraProperties).GetTypeInfo().IsAssignableFrom(typeof(TEntity))) + { + return; + } + + modelBuilder.Entity(b => + { + b.Property(x => ((IHasExtraProperties) x).ExtraProperties) + .HasConversion( + d => JsonConvert.SerializeObject(d, Formatting.None), + s => JsonConvert.DeserializeObject>(s) + ) + .HasColumnName(nameof(IHasExtraProperties.ExtraProperties)); + }); + } + + protected virtual void ConfigureGlobalFilters(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType) where TEntity : class { - if (entityType.BaseType == null && ShouldFilterEntity(entityType)) + if (mutableEntityType.BaseType == null && ShouldFilterEntity(mutableEntityType)) { var filterExpression = CreateFilterExpression(); if (filterExpression != null) diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Modeling/AbpEntityTypeBuilderExtensions.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Modeling/AbpEntityTypeBuilderExtensions.cs index 143dd07e30..200e7a707c 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Modeling/AbpEntityTypeBuilderExtensions.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Modeling/AbpEntityTypeBuilderExtensions.cs @@ -4,12 +4,21 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Newtonsoft.Json; using Volo.Abp.Auditing; using Volo.Abp.Data; +using Volo.Abp.Domain.Entities; using Volo.Abp.MultiTenancy; namespace Volo.Abp.EntityFrameworkCore.Modeling { public static class AbpEntityTypeBuilderExtensions { + public static void ConfigureConcurrencyStamp(this EntityTypeBuilder b) + where T : class, IHasConcurrencyStamp + { + b.Property(x => x.ConcurrencyStamp) + .IsConcurrencyToken() + .HasColumnName(nameof(IHasConcurrencyStamp.ConcurrencyStamp)); + } + public static void ConfigureExtraProperties(this EntityTypeBuilder b) where T : class, IHasExtraProperties { diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/SecondDbContext.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/SecondDbContext.cs index bb2f0504ad..9b584a494c 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/SecondDbContext.cs +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests.SecondContext/Volo/Abp/EntityFrameworkCore/TestApp/SecondContext/SecondDbContext.cs @@ -21,12 +21,6 @@ namespace Volo.Abp.EntityFrameworkCore.TestApp.SecondContext modelBuilder.Entity(b => { b.HasKey(p => new { p.PersonId, p.Number }); - b.ConfigureExtraProperties(); - }); - - modelBuilder.Entity(b => - { - b.ConfigureExtraProperties(); }); } } diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/TestMigrationsDbContext.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/TestMigrationsDbContext.cs index 68e6ac97cb..cb9726d6b4 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/TestMigrationsDbContext.cs +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/TestMigrationsDbContext.cs @@ -1,5 +1,4 @@ using Microsoft.EntityFrameworkCore; -using Volo.Abp.EntityFrameworkCore.Modeling; using Volo.Abp.EntityFrameworkCore.TestApp.SecondContext; using Volo.Abp.EntityFrameworkCore.TestApp.ThirdDbContext; using Volo.Abp.TestApp.Domain; @@ -30,26 +29,6 @@ namespace Volo.Abp.EntityFrameworkCore { b.HasKey(p => new { p.PersonId, p.Number }); }); - - modelBuilder.Entity(b => - { - b.ConfigureExtraProperties(); - }); - - modelBuilder.Entity(b => - { - b.ConfigureExtraProperties(); - }); - - modelBuilder.Entity(b => - { - b.ConfigureExtraProperties(); - }); - - modelBuilder.Entity(b => - { - b.ConfigureExtraProperties(); - }); } } } diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/TestAppDbContext.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/TestAppDbContext.cs index bef7830567..00e052d2dd 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/TestAppDbContext.cs +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/TestAppDbContext.cs @@ -1,6 +1,5 @@ using Microsoft.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; -using Volo.Abp.EntityFrameworkCore.Modeling; using Volo.Abp.EntityFrameworkCore.TestApp.ThirdDbContext; using Volo.Abp.TestApp.Domain; @@ -24,25 +23,10 @@ namespace Volo.Abp.TestApp.EntityFrameworkCore { base.OnModelCreating(modelBuilder); - modelBuilder.Entity(b => - { - b.ConfigureExtraProperties(); - }); - modelBuilder.Entity(b => { b.HasKey(p => new {p.PersonId, p.Number}); }); - - modelBuilder.Entity(b => - { - b.ConfigureExtraProperties(); - }); - - modelBuilder.Entity(b => - { - b.ConfigureExtraProperties(); - }); } } } diff --git a/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsDbContextModelBuilderExtensions.cs b/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsDbContextModelBuilderExtensions.cs index 1235bf5fb2..20e169f279 100644 --- a/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsDbContextModelBuilderExtensions.cs +++ b/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsDbContextModelBuilderExtensions.cs @@ -29,8 +29,6 @@ namespace Volo.Docs.EntityFrameworkCore b.Property(x => x.DefaultDocumentName).IsRequired().HasMaxLength(ProjectConsts.MaxDefaultDocumentNameLength); b.Property(x => x.NavigationDocumentName).IsRequired().HasMaxLength(ProjectConsts.MaxNavigationDocumentNameLength); b.Property(x => x.LatestVersionBranchName).HasMaxLength(ProjectConsts.MaxLatestVersionBranchNameLength); - - b.ConfigureExtraProperties(); }); } } From de5f6e29850f091fd330615d18df3e325bcacd13 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Mon, 24 Dec 2018 16:40:13 +0300 Subject: [PATCH 127/368] Organized folders --- modules/docs/Volo.Docs.sln | 45 +++++++++++-------- .../DocsDbContextModelBuilderExtensions.cs | 1 + 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/modules/docs/Volo.Docs.sln b/modules/docs/Volo.Docs.sln index d59169ddde..8d58433a93 100644 --- a/modules/docs/Volo.Docs.sln +++ b/modules/docs/Volo.Docs.sln @@ -5,27 +5,33 @@ VisualStudioVersion = 15.0.27703.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{42416152-5BAB-4706-93A6-57A19E71FE14}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Docs.Domain.Shared", "src\Volo.Docs.Domain.Shared\Volo.Docs.Domain.Shared.csproj", "{ECE3F02A-3189-4159-A29C-D7C3D146DE36}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Docs.Domain.Shared", "src\Volo.Docs.Domain.Shared\Volo.Docs.Domain.Shared.csproj", "{ECE3F02A-3189-4159-A29C-D7C3D146DE36}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Docs.Domain", "src\Volo.Docs.Domain\Volo.Docs.Domain.csproj", "{AC02A635-260F-4FE9-9173-A7F8D7777263}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Docs.Domain", "src\Volo.Docs.Domain\Volo.Docs.Domain.csproj", "{AC02A635-260F-4FE9-9173-A7F8D7777263}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Docs.Application.Contracts", "src\Volo.Docs.Application.Contracts\Volo.Docs.Application.Contracts.csproj", "{E70D5691-90FF-44BF-BF16-152B161163D0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Docs.Application.Contracts", "src\Volo.Docs.Application.Contracts\Volo.Docs.Application.Contracts.csproj", "{E70D5691-90FF-44BF-BF16-152B161163D0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Docs.Application", "src\Volo.Docs.Application\Volo.Docs.Application.csproj", "{B12622E8-20C7-44DB-8088-33844731469A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Docs.Application", "src\Volo.Docs.Application\Volo.Docs.Application.csproj", "{B12622E8-20C7-44DB-8088-33844731469A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Docs.EntityFrameworkCore", "src\Volo.Docs.EntityFrameworkCore\Volo.Docs.EntityFrameworkCore.csproj", "{2D35B1A4-6D22-454D-8C20-46CA7A74535E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Docs.EntityFrameworkCore", "src\Volo.Docs.EntityFrameworkCore\Volo.Docs.EntityFrameworkCore.csproj", "{2D35B1A4-6D22-454D-8C20-46CA7A74535E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Docs.HttpApi", "src\Volo.Docs.HttpApi\Volo.Docs.HttpApi.csproj", "{30808C64-F590-47F7-AF8A-256F6B6E186B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Docs.HttpApi", "src\Volo.Docs.HttpApi\Volo.Docs.HttpApi.csproj", "{30808C64-F590-47F7-AF8A-256F6B6E186B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Docs.HttpApi.Client", "src\Volo.Docs.HttpApi.Client\Volo.Docs.HttpApi.Client.csproj", "{BF3FDDFF-BED8-422C-82E9-07F181A2D47F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Docs.HttpApi.Client", "src\Volo.Docs.HttpApi.Client\Volo.Docs.HttpApi.Client.csproj", "{BF3FDDFF-BED8-422C-82E9-07F181A2D47F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Docs.Web", "src\Volo.Docs.Web\Volo.Docs.Web.csproj", "{871FB966-C89F-4AF5-BB1D-172625AA571C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Docs.Web", "src\Volo.Docs.Web\Volo.Docs.Web.csproj", "{871FB966-C89F-4AF5-BB1D-172625AA571C}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "app", "app", "{555508AD-F593-43E3-9354-9FA51512F181}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.DocsTestApp", "app\Volo.DocsTestApp\Volo.DocsTestApp.csproj", "{30BC20A3-85CE-4907-8FD0-54153C3F190C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.DocsTestApp", "app\Volo.DocsTestApp\Volo.DocsTestApp.csproj", "{30BC20A3-85CE-4907-8FD0-54153C3F190C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.DocsTestApp.EntityFrameworkCore", "app\Volo.DocsTestApp.EntityFrameworkCore\Volo.DocsTestApp.EntityFrameworkCore.csproj", "{A5F88BCB-6B22-4E2D-AE89-AEF1E3DC727A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.DocsTestApp.EntityFrameworkCore", "app\Volo.DocsTestApp.EntityFrameworkCore\Volo.DocsTestApp.EntityFrameworkCore.csproj", "{A5F88BCB-6B22-4E2D-AE89-AEF1E3DC727A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "domain", "domain", "{A982A58E-1E92-4764-9F56-39E7AABB8556}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "admin-app", "admin-app", "{BCA19441-17E9-43E6-AED1-15344D18F967}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "public-app", "public-app", "{8B0CDFC9-E313-4323-9390-59CFFAAC60B5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -78,16 +84,19 @@ Global HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {ECE3F02A-3189-4159-A29C-D7C3D146DE36} = {42416152-5BAB-4706-93A6-57A19E71FE14} - {AC02A635-260F-4FE9-9173-A7F8D7777263} = {42416152-5BAB-4706-93A6-57A19E71FE14} - {E70D5691-90FF-44BF-BF16-152B161163D0} = {42416152-5BAB-4706-93A6-57A19E71FE14} - {B12622E8-20C7-44DB-8088-33844731469A} = {42416152-5BAB-4706-93A6-57A19E71FE14} - {2D35B1A4-6D22-454D-8C20-46CA7A74535E} = {42416152-5BAB-4706-93A6-57A19E71FE14} - {30808C64-F590-47F7-AF8A-256F6B6E186B} = {42416152-5BAB-4706-93A6-57A19E71FE14} - {BF3FDDFF-BED8-422C-82E9-07F181A2D47F} = {42416152-5BAB-4706-93A6-57A19E71FE14} - {871FB966-C89F-4AF5-BB1D-172625AA571C} = {42416152-5BAB-4706-93A6-57A19E71FE14} + {ECE3F02A-3189-4159-A29C-D7C3D146DE36} = {A982A58E-1E92-4764-9F56-39E7AABB8556} + {AC02A635-260F-4FE9-9173-A7F8D7777263} = {A982A58E-1E92-4764-9F56-39E7AABB8556} + {E70D5691-90FF-44BF-BF16-152B161163D0} = {8B0CDFC9-E313-4323-9390-59CFFAAC60B5} + {B12622E8-20C7-44DB-8088-33844731469A} = {8B0CDFC9-E313-4323-9390-59CFFAAC60B5} + {2D35B1A4-6D22-454D-8C20-46CA7A74535E} = {A982A58E-1E92-4764-9F56-39E7AABB8556} + {30808C64-F590-47F7-AF8A-256F6B6E186B} = {8B0CDFC9-E313-4323-9390-59CFFAAC60B5} + {BF3FDDFF-BED8-422C-82E9-07F181A2D47F} = {8B0CDFC9-E313-4323-9390-59CFFAAC60B5} + {871FB966-C89F-4AF5-BB1D-172625AA571C} = {8B0CDFC9-E313-4323-9390-59CFFAAC60B5} {30BC20A3-85CE-4907-8FD0-54153C3F190C} = {555508AD-F593-43E3-9354-9FA51512F181} {A5F88BCB-6B22-4E2D-AE89-AEF1E3DC727A} = {555508AD-F593-43E3-9354-9FA51512F181} + {A982A58E-1E92-4764-9F56-39E7AABB8556} = {42416152-5BAB-4706-93A6-57A19E71FE14} + {BCA19441-17E9-43E6-AED1-15344D18F967} = {42416152-5BAB-4706-93A6-57A19E71FE14} + {8B0CDFC9-E313-4323-9390-59CFFAAC60B5} = {42416152-5BAB-4706-93A6-57A19E71FE14} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {13691265-2547-4FFF-B757-E8FACB05679D} diff --git a/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsDbContextModelBuilderExtensions.cs b/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsDbContextModelBuilderExtensions.cs index 20e169f279..967938fbae 100644 --- a/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsDbContextModelBuilderExtensions.cs +++ b/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsDbContextModelBuilderExtensions.cs @@ -22,6 +22,7 @@ namespace Volo.Docs.EntityFrameworkCore { b.ToTable(options.TablePrefix + "Projects", options.Schema); + b.ConfigureConcurrencyStamp(); b.ConfigureExtraProperties(); b.Property(x => x.Name).IsRequired().HasMaxLength(ProjectConsts.MaxNameLength); From dff9924e069c696dd8cb9e7f5eec1c42eca3f06e Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 24 Dec 2018 17:32:59 +0300 Subject: [PATCH 128/368] #629 moved admin codes to new projects --- modules/docs/Volo.Docs.sln | 35 +++++++ ...lo.Docs.Admin.Application.Contracts.csproj | 17 ++++ .../DocsAdminApplicationContractsModule.cs | 14 +++ .../Docs/Admin}/Projects/CreateProjectDto.cs | 2 +- .../Admin/Projects/IProjectAdminAppService.cs | 20 ++++ .../Volo/Docs/Admin/Projects/ProjectDto.cs | 30 ++++++ .../Docs/Admin}/Projects/UpdateProjectDto.cs | 4 +- .../Volo.Docs.Admin.Application.csproj | 19 ++++ .../DocsAdminApplicationAutoMapperProfile.cs | 14 +++ .../Docs/Admin/DocsAdminApplicationModule.cs | 22 +++++ .../Admin/Projects/ProjectAdminAppService.cs | 95 +++++++++++++++++++ .../Volo.Docs.Admin.HttpApi.Client.csproj | 16 ++++ .../Docs/Admin/DocsHttpApiClientModule.cs | 11 +++ .../Volo.Docs.Admin.HttpApi.csproj | 17 ++++ .../Volo/Docs/Admin/DocsAdminHttpApiModule.cs | 14 +++ .../Projects/DocsAdminProjectController.cs | 50 ++++++++++ .../DocsAdminWebAutoMapperProfile.cs | 13 +++ .../Volo.Docs.Admin.Web/DocsAdminWebModule.cs | 37 ++++++++ .../Properties/launchSettings.json | 27 ++++++ .../Volo.Docs.Admin.Web.csproj | 55 +++++++++++ .../Volo/Docs/Projects/IProjectAppService.cs | 6 -- .../Volo/Docs/Projects/ProjectAppService.cs | 54 ----------- .../Volo/Docs/Projects/IProjectRepository.cs | 5 + .../Docs/Projects/EfCoreProjectRepository.cs | 17 ++++ .../Docs/Projects/DocsProjectController.cs | 15 --- 25 files changed, 530 insertions(+), 79 deletions(-) create mode 100644 modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo.Docs.Admin.Application.Contracts.csproj create mode 100644 modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/DocsAdminApplicationContractsModule.cs rename modules/docs/src/{Volo.Docs.Application.Contracts/Volo/Docs => Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin}/Projects/CreateProjectDto.cs (94%) create mode 100644 modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/IProjectAdminAppService.cs create mode 100644 modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/ProjectDto.cs rename modules/docs/src/{Volo.Docs.Application.Contracts/Volo/Docs => Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin}/Projects/UpdateProjectDto.cs (87%) create mode 100644 modules/docs/src/Volo.Docs.Admin.Application/Volo.Docs.Admin.Application.csproj create mode 100644 modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/DocsAdminApplicationAutoMapperProfile.cs create mode 100644 modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/DocsAdminApplicationModule.cs create mode 100644 modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Projects/ProjectAdminAppService.cs create mode 100644 modules/docs/src/Volo.Docs.Admin.HttpApi.Client/Volo.Docs.Admin.HttpApi.Client.csproj create mode 100644 modules/docs/src/Volo.Docs.Admin.HttpApi.Client/Volo/Docs/Admin/DocsHttpApiClientModule.cs create mode 100644 modules/docs/src/Volo.Docs.Admin.HttpApi/Volo.Docs.Admin.HttpApi.csproj create mode 100644 modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/DocsAdminHttpApiModule.cs create mode 100644 modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/Projects/DocsAdminProjectController.cs create mode 100644 modules/docs/src/Volo.Docs.Admin.Web/DocsAdminWebAutoMapperProfile.cs create mode 100644 modules/docs/src/Volo.Docs.Admin.Web/DocsAdminWebModule.cs create mode 100644 modules/docs/src/Volo.Docs.Admin.Web/Properties/launchSettings.json create mode 100644 modules/docs/src/Volo.Docs.Admin.Web/Volo.Docs.Admin.Web.csproj diff --git a/modules/docs/Volo.Docs.sln b/modules/docs/Volo.Docs.sln index 8d58433a93..3fe7cc736f 100644 --- a/modules/docs/Volo.Docs.sln +++ b/modules/docs/Volo.Docs.sln @@ -33,6 +33,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "admin-app", "admin-app", "{ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "public-app", "public-app", "{8B0CDFC9-E313-4323-9390-59CFFAAC60B5}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Docs.Admin.Application.Contracts", "src\Volo.Docs.Admin.Application.Contracts\Volo.Docs.Admin.Application.Contracts.csproj", "{37D483C8-400B-4127-A6D0-2EE4E80CB696}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Docs.Admin.Application", "src\Volo.Docs.Admin.Application\Volo.Docs.Admin.Application.csproj", "{823C51A7-40AB-45D8-8FB8-F212AF7E45F2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Docs.Admin.HttpApi", "src\Volo.Docs.Admin.HttpApi\Volo.Docs.Admin.HttpApi.csproj", "{262F38DB-62AF-427F-96E2-C6385C5AB695}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Docs.Admin.HttpApi.Client", "src\Volo.Docs.Admin.HttpApi.Client\Volo.Docs.Admin.HttpApi.Client.csproj", "{81EE378A-0DE1-47BA-86D9-08EF6317BB95}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Docs.Admin.Web", "src\Volo.Docs.Admin.Web\Volo.Docs.Admin.Web.csproj", "{116A6145-9D66-4867-B3EF-A464FAC47946}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -79,6 +89,26 @@ Global {A5F88BCB-6B22-4E2D-AE89-AEF1E3DC727A}.Debug|Any CPU.Build.0 = Debug|Any CPU {A5F88BCB-6B22-4E2D-AE89-AEF1E3DC727A}.Release|Any CPU.ActiveCfg = Release|Any CPU {A5F88BCB-6B22-4E2D-AE89-AEF1E3DC727A}.Release|Any CPU.Build.0 = Release|Any CPU + {37D483C8-400B-4127-A6D0-2EE4E80CB696}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {37D483C8-400B-4127-A6D0-2EE4E80CB696}.Debug|Any CPU.Build.0 = Debug|Any CPU + {37D483C8-400B-4127-A6D0-2EE4E80CB696}.Release|Any CPU.ActiveCfg = Release|Any CPU + {37D483C8-400B-4127-A6D0-2EE4E80CB696}.Release|Any CPU.Build.0 = Release|Any CPU + {823C51A7-40AB-45D8-8FB8-F212AF7E45F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {823C51A7-40AB-45D8-8FB8-F212AF7E45F2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {823C51A7-40AB-45D8-8FB8-F212AF7E45F2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {823C51A7-40AB-45D8-8FB8-F212AF7E45F2}.Release|Any CPU.Build.0 = Release|Any CPU + {262F38DB-62AF-427F-96E2-C6385C5AB695}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {262F38DB-62AF-427F-96E2-C6385C5AB695}.Debug|Any CPU.Build.0 = Debug|Any CPU + {262F38DB-62AF-427F-96E2-C6385C5AB695}.Release|Any CPU.ActiveCfg = Release|Any CPU + {262F38DB-62AF-427F-96E2-C6385C5AB695}.Release|Any CPU.Build.0 = Release|Any CPU + {81EE378A-0DE1-47BA-86D9-08EF6317BB95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {81EE378A-0DE1-47BA-86D9-08EF6317BB95}.Debug|Any CPU.Build.0 = Debug|Any CPU + {81EE378A-0DE1-47BA-86D9-08EF6317BB95}.Release|Any CPU.ActiveCfg = Release|Any CPU + {81EE378A-0DE1-47BA-86D9-08EF6317BB95}.Release|Any CPU.Build.0 = Release|Any CPU + {116A6145-9D66-4867-B3EF-A464FAC47946}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {116A6145-9D66-4867-B3EF-A464FAC47946}.Debug|Any CPU.Build.0 = Debug|Any CPU + {116A6145-9D66-4867-B3EF-A464FAC47946}.Release|Any CPU.ActiveCfg = Release|Any CPU + {116A6145-9D66-4867-B3EF-A464FAC47946}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -97,6 +127,11 @@ Global {A982A58E-1E92-4764-9F56-39E7AABB8556} = {42416152-5BAB-4706-93A6-57A19E71FE14} {BCA19441-17E9-43E6-AED1-15344D18F967} = {42416152-5BAB-4706-93A6-57A19E71FE14} {8B0CDFC9-E313-4323-9390-59CFFAAC60B5} = {42416152-5BAB-4706-93A6-57A19E71FE14} + {37D483C8-400B-4127-A6D0-2EE4E80CB696} = {BCA19441-17E9-43E6-AED1-15344D18F967} + {823C51A7-40AB-45D8-8FB8-F212AF7E45F2} = {BCA19441-17E9-43E6-AED1-15344D18F967} + {262F38DB-62AF-427F-96E2-C6385C5AB695} = {BCA19441-17E9-43E6-AED1-15344D18F967} + {81EE378A-0DE1-47BA-86D9-08EF6317BB95} = {BCA19441-17E9-43E6-AED1-15344D18F967} + {116A6145-9D66-4867-B3EF-A464FAC47946} = {BCA19441-17E9-43E6-AED1-15344D18F967} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {13691265-2547-4FFF-B757-E8FACB05679D} diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo.Docs.Admin.Application.Contracts.csproj b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo.Docs.Admin.Application.Contracts.csproj new file mode 100644 index 0000000000..0835730d57 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo.Docs.Admin.Application.Contracts.csproj @@ -0,0 +1,17 @@ + + + + + + netstandard2.0 + Volo.Docs.Admin.Application.Contracts + Volo.Docs.Admin.Application.Contracts + + + + + + + + + diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/DocsAdminApplicationContractsModule.cs b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/DocsAdminApplicationContractsModule.cs new file mode 100644 index 0000000000..547fb6bf71 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/DocsAdminApplicationContractsModule.cs @@ -0,0 +1,14 @@ +using Volo.Abp.Application; +using Volo.Abp.Modularity; + +namespace Volo.Docs.Admin +{ + [DependsOn( + typeof(DocsDomainSharedModule), + typeof(AbpDddApplicationModule) + )] + public class DocsAdminApplicationContractsModule : AbpModule + { + + } +} diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/CreateProjectDto.cs b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/CreateProjectDto.cs similarity index 94% rename from modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/CreateProjectDto.cs rename to modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/CreateProjectDto.cs index cb02c579a3..2427d2d51f 100644 --- a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/CreateProjectDto.cs +++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/CreateProjectDto.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace Volo.Docs.Projects +namespace Volo.Docs.Admin.Projects { public class CreateProjectDto { diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/IProjectAdminAppService.cs b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/IProjectAdminAppService.cs new file mode 100644 index 0000000000..34b607689c --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/IProjectAdminAppService.cs @@ -0,0 +1,20 @@ +using System; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; + +namespace Volo.Docs.Admin.Projects +{ + public interface IProjectAdminAppService : IApplicationService + { + Task> GetListAsync(PagedAndSortedResultRequestDto input); + + Task GetAsync(Guid id); + + Task CreateAsync(CreateProjectDto input); + + Task UpdateAsync(Guid id, UpdateProjectDto input); + + Task DeleteAsync(Guid id); + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/ProjectDto.cs b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/ProjectDto.cs new file mode 100644 index 0000000000..c5a3bd6eb2 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/ProjectDto.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using Volo.Abp.Application.Dtos; + +namespace Volo.Docs.Admin.Projects +{ + [Serializable] + public class ProjectDto : EntityDto + { + public string Name { get; set; } + + public string ShortName { get; set; } + + public string Format { get; set; } + + public string DefaultDocumentName { get; set; } + + public string NavigationDocumentName { get; set; } + + public string MinimumVersion { get; set; } + + public string MainWebsiteUrl { get; set; } + + public string LatestVersionBranchName { get; set; } + + public string DocumentStoreType { get; set; } + + public Dictionary ExtraProperties { get; set; } + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/UpdateProjectDto.cs b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/UpdateProjectDto.cs similarity index 87% rename from modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/UpdateProjectDto.cs rename to modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/UpdateProjectDto.cs index b16f1916e4..b2ac8472ae 100644 --- a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/UpdateProjectDto.cs +++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/UpdateProjectDto.cs @@ -1,8 +1,6 @@ -using System; using System.Collections.Generic; -using Volo.Abp.Application.Dtos; -namespace Volo.Docs.Projects +namespace Volo.Docs.Admin.Projects { public class UpdateProjectDto { diff --git a/modules/docs/src/Volo.Docs.Admin.Application/Volo.Docs.Admin.Application.csproj b/modules/docs/src/Volo.Docs.Admin.Application/Volo.Docs.Admin.Application.csproj new file mode 100644 index 0000000000..73d2afc26b --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.Application/Volo.Docs.Admin.Application.csproj @@ -0,0 +1,19 @@ + + + + + + netstandard2.0 + Volo.Docs.Admin.Application + Volo.Docs.Admin.Application + + + + + + + + + + + diff --git a/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/DocsAdminApplicationAutoMapperProfile.cs b/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/DocsAdminApplicationAutoMapperProfile.cs new file mode 100644 index 0000000000..e51cce664b --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/DocsAdminApplicationAutoMapperProfile.cs @@ -0,0 +1,14 @@ +using AutoMapper; +using Volo.Docs.Admin.Projects; +using Volo.Docs.Projects; + +namespace Volo.Docs.Admin +{ + public class DocsAdminApplicationAutoMapperProfile : Profile + { + public DocsAdminApplicationAutoMapperProfile() + { + CreateMap(); + } + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/DocsAdminApplicationModule.cs b/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/DocsAdminApplicationModule.cs new file mode 100644 index 0000000000..1771b00cdb --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/DocsAdminApplicationModule.cs @@ -0,0 +1,22 @@ +using Volo.Abp.AutoMapper; +using Volo.Abp.Caching; +using Volo.Abp.Modularity; + +namespace Volo.Docs.Admin +{ + [DependsOn( + typeof(DocsDomainModule), + typeof(DocsAdminApplicationContractsModule), + typeof(AbpCachingModule), + typeof(AbpAutoMapperModule))] + public class DocsAdminApplicationModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.AddProfile(validate: true); + }); + } + } +} diff --git a/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Projects/ProjectAdminAppService.cs b/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Projects/ProjectAdminAppService.cs new file mode 100644 index 0000000000..25e9754140 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Projects/ProjectAdminAppService.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; +using Volo.Abp.Guids; +using Volo.Docs.Projects; + +namespace Volo.Docs.Admin.Projects +{ + public class ProjectAdminAppService : ApplicationService, IProjectAdminAppService + { + private readonly IProjectRepository _projectRepository; + private readonly IGuidGenerator _guidGenerator; + + public ProjectAdminAppService( + IProjectRepository projectRepository, IGuidGenerator guidGenerator) + { + _projectRepository = projectRepository; + _guidGenerator = guidGenerator; + } + + public async Task> GetListAsync(PagedAndSortedResultRequestDto input) + { + var blogs = await _projectRepository.GetListAsync(input.Sorting, input.MaxResultCount, input.SkipCount); + + var totalCount = await _projectRepository.GetTotalProjectCount(); + + var dtos = ObjectMapper.Map, List>(blogs); + + return new PagedResultDto(totalCount, dtos); + } + + public async Task GetAsync(Guid id) + { + var project = await _projectRepository.GetAsync(id); + + return ObjectMapper.Map(project); + } + + public async Task CreateAsync(CreateProjectDto input) + { + var project = new Project(_guidGenerator.Create(), + input.Name, + input.ShortName, + input.DocumentStoreType, + input.Format, + input.DefaultDocumentName, + input.NavigationDocumentName + ) + { + MinimumVersion = input.MinimumVersion, + MainWebsiteUrl = input.MainWebsiteUrl, + LatestVersionBranchName = input.LatestVersionBranchName + }; + + foreach (var extraProperty in input.ExtraProperties) + { + project.ExtraProperties.Add(extraProperty.Key,extraProperty.Value); + } + + project = await _projectRepository.InsertAsync(project); + + return ObjectMapper.Map(project); + } + + public async Task UpdateAsync(Guid id, UpdateProjectDto input) + { + var project = await _projectRepository.GetAsync(id); + + project.SetName(input.Name); + project.SetFormat(input.Format); + project.SetNavigationDocumentName(input.NavigationDocumentName); + project.SetDefaultDocumentName(input.DefaultDocumentName); + + project.MinimumVersion = input.MinimumVersion; + project.MainWebsiteUrl = input.MainWebsiteUrl; + project.LatestVersionBranchName = input.LatestVersionBranchName; + + foreach (var extraProperty in input.ExtraProperties) + { + project.ExtraProperties[extraProperty.Key] = extraProperty.Value; + } + + project = await _projectRepository.UpdateAsync(project); + + return ObjectMapper.Map(project); + } + + public async Task DeleteAsync(Guid id) + { + await _projectRepository.DeleteAsync(id); + } + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/Volo.Docs.Admin.HttpApi.Client.csproj b/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/Volo.Docs.Admin.HttpApi.Client.csproj new file mode 100644 index 0000000000..c76ce2895c --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/Volo.Docs.Admin.HttpApi.Client.csproj @@ -0,0 +1,16 @@ + + + + + + netstandard2.0 + Volo.Docs.Admin.HttpApi.Client + Volo.Docs.Admin.HttpApi.Client + + + + + + + + diff --git a/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/Volo/Docs/Admin/DocsHttpApiClientModule.cs b/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/Volo/Docs/Admin/DocsHttpApiClientModule.cs new file mode 100644 index 0000000000..5a2e66e5ca --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.HttpApi.Client/Volo/Docs/Admin/DocsHttpApiClientModule.cs @@ -0,0 +1,11 @@ +using Volo.Abp.Modularity; + +namespace Volo.Docs.Admin +{ + [DependsOn( + typeof(DocsAdminApplicationContractsModule))] + public class DocsAdminHttpApiClientModule : AbpModule + { + + } +} diff --git a/modules/docs/src/Volo.Docs.Admin.HttpApi/Volo.Docs.Admin.HttpApi.csproj b/modules/docs/src/Volo.Docs.Admin.HttpApi/Volo.Docs.Admin.HttpApi.csproj new file mode 100644 index 0000000000..cea70211b2 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.HttpApi/Volo.Docs.Admin.HttpApi.csproj @@ -0,0 +1,17 @@ + + + + + + netstandard2.0 + Volo.Docs.Admin.HttpApi + Volo.Docs.Admin.HttpApi + + + + + + + + + diff --git a/modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/DocsAdminHttpApiModule.cs b/modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/DocsAdminHttpApiModule.cs new file mode 100644 index 0000000000..46321bbcfc --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/DocsAdminHttpApiModule.cs @@ -0,0 +1,14 @@ +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.Modularity; + +namespace Volo.Docs.Admin +{ + [DependsOn( + typeof(DocsAdminApplicationContractsModule), + typeof(AbpAspNetCoreMvcModule) + )] + public class DocsAdminHttpApiModule : AbpModule + { + + } +} diff --git a/modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/Projects/DocsAdminProjectController.cs b/modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/Projects/DocsAdminProjectController.cs new file mode 100644 index 0000000000..58f3f23758 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/Projects/DocsAdminProjectController.cs @@ -0,0 +1,50 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.AspNetCore.Mvc; + +namespace Volo.Docs.Admin.Projects +{ + [RemoteService] + [Area("docs")] + [ControllerName("Project")] + [Route("api/docs/admin/projects")] + public class DocsAdminProjectController : AbpController, IProjectAdminAppService + { + protected IProjectAdminAppService ProjectAppService { get; } + + public DocsAdminProjectController(IProjectAdminAppService projectAppService) + { + ProjectAppService = projectAppService; + } + + public Task> GetListAsync(PagedAndSortedResultRequestDto input) + { + return ProjectAppService.GetListAsync(input); + } + + [HttpGet] + [Route("{id}")] + public Task GetAsync(Guid id) + { + return ProjectAppService.GetAsync(id); + } + + public Task CreateAsync(CreateProjectDto input) + { + return ProjectAppService.CreateAsync(input); + } + + public Task UpdateAsync(Guid id, UpdateProjectDto input) + { + return ProjectAppService.UpdateAsync(id, input); + } + + public Task DeleteAsync(Guid id) + { + return ProjectAppService.DeleteAsync(id); + } + } +} diff --git a/modules/docs/src/Volo.Docs.Admin.Web/DocsAdminWebAutoMapperProfile.cs b/modules/docs/src/Volo.Docs.Admin.Web/DocsAdminWebAutoMapperProfile.cs new file mode 100644 index 0000000000..0b9d5ebd3b --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.Web/DocsAdminWebAutoMapperProfile.cs @@ -0,0 +1,13 @@ +using AutoMapper; +using Volo.Abp.AutoMapper; + +namespace Volo.Docs.Admin +{ + public class DocsAdminWebAutoMapperProfile : Profile + { + public DocsAdminWebAutoMapperProfile() + { + + } + } +} diff --git a/modules/docs/src/Volo.Docs.Admin.Web/DocsAdminWebModule.cs b/modules/docs/src/Volo.Docs.Admin.Web/DocsAdminWebModule.cs new file mode 100644 index 0000000000..a443865676 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.Web/DocsAdminWebModule.cs @@ -0,0 +1,37 @@ +using Volo.Abp.AspNetCore.Mvc.Localization; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap; +using Volo.Abp.AutoMapper; +using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; +using Volo.Docs.Localization; + +namespace Volo.Docs.Admin +{ + [DependsOn( + typeof(DocsAdminHttpApiModule), + typeof(AbpAspNetCoreMvcUiBootstrapModule) + )] + public class DocsAdminWebModule : AbpModule + { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + PreConfigure(options => + { + options.AddAssemblyResource(typeof(DocsResource), typeof(DocsAdminWebModule).Assembly); + }); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.FileSets.AddEmbedded("Volo.Docs.Admin"); + }); + + Configure(options => + { + options.AddProfile(validate: true); + }); + } + } +} diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Properties/launchSettings.json b/modules/docs/src/Volo.Docs.Admin.Web/Properties/launchSettings.json new file mode 100644 index 0000000000..b0ed7371d0 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.Web/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:51397", + "sslPort": 44346 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Volo.Docs.Admin.Web": { + "commandName": "Project", + "launchBrowser": true, + "applicationUrl": "https://localhost:5001;http://localhost:5000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Volo.Docs.Admin.Web.csproj b/modules/docs/src/Volo.Docs.Admin.Web/Volo.Docs.Admin.Web.csproj new file mode 100644 index 0000000000..b5b4569789 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.Web/Volo.Docs.Admin.Web.csproj @@ -0,0 +1,55 @@ + + + + + + netstandard2.0 + Volo.Docs.Admin.Web + Volo.Docs.Admin.Web + Library + true + Volo.Docs.Admin + 2.8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/IProjectAppService.cs b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/IProjectAppService.cs index 8dba5fa3e1..f06c676079 100644 --- a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/IProjectAppService.cs +++ b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Projects/IProjectAppService.cs @@ -10,12 +10,6 @@ namespace Volo.Docs.Projects Task> GetListAsync(); Task GetAsync(string shortName); - - Task CreateAsync(CreateProjectDto input); - - Task UpdateAsync(Guid id, UpdateProjectDto input); - - Task DeleteAsync(Guid id); Task> GetVersionsAsync(string shortName); } diff --git a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs index 6a7e8132fc..20970ade0d 100644 --- a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs +++ b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs @@ -45,60 +45,6 @@ namespace Volo.Docs.Projects return ObjectMapper.Map(project); } - public async Task CreateAsync(CreateProjectDto input) - { - var project = new Project(_guidGenerator.Create(), - input.Name, - input.ShortName, - input.DocumentStoreType, - input.Format, - input.DefaultDocumentName, - input.NavigationDocumentName - ) - { - MinimumVersion = input.MinimumVersion, - MainWebsiteUrl = input.MainWebsiteUrl, - LatestVersionBranchName = input.LatestVersionBranchName - }; - - foreach (var extraProperty in input.ExtraProperties) - { - project.ExtraProperties.Add(extraProperty.Key,extraProperty.Value); - } - - project = await _projectRepository.InsertAsync(project); - - return ObjectMapper.Map(project); - } - - public async Task UpdateAsync(Guid id, UpdateProjectDto input) - { - var project = await _projectRepository.GetAsync(id); - - project.SetName(input.Name); - project.SetFormat(input.Format); - project.SetNavigationDocumentName(input.NavigationDocumentName); - project.SetDefaultDocumentName(input.DefaultDocumentName); - - project.MinimumVersion = input.MinimumVersion; - project.MainWebsiteUrl = input.MainWebsiteUrl; - project.LatestVersionBranchName = input.LatestVersionBranchName; - - foreach (var extraProperty in input.ExtraProperties) - { - project.ExtraProperties[extraProperty.Key] = extraProperty.Value; - } - - project = await _projectRepository.UpdateAsync(project); - - return ObjectMapper.Map(project); - } - - public async Task DeleteAsync(Guid id) - { - await _projectRepository.DeleteAsync(id); - } - public async Task> GetVersionsAsync(string shortName) { var project = await _projectRepository.GetByShortNameAsync(shortName); diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/IProjectRepository.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/IProjectRepository.cs index fdfe785df4..1872d33cd8 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/IProjectRepository.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/IProjectRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories; @@ -6,6 +7,10 @@ namespace Volo.Docs.Projects { public interface IProjectRepository : IBasicRepository { + Task> GetListAsync(string sorting, int maxResultCount, int skipCount); + + Task GetTotalProjectCount(); + Task GetByShortNameAsync(string shortName); } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/Projects/EfCoreProjectRepository.cs b/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/Projects/EfCoreProjectRepository.cs index e06fea3aba..f9e6ab4fa7 100644 --- a/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/Projects/EfCoreProjectRepository.cs +++ b/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/Projects/EfCoreProjectRepository.cs @@ -1,4 +1,7 @@ using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Dynamic.Core; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Volo.Abp.Domain.Entities; @@ -16,6 +19,20 @@ namespace Volo.Docs.Projects } + public async Task> GetListAsync(string sorting, int maxResultCount, int skipCount) + { + var projects = await DbSet.OrderBy(sorting ?? "creationTime desc") + .PageBy(skipCount, maxResultCount) + .ToListAsync(); + + return projects; + } + + public async Task GetTotalProjectCount() + { + return await DbSet.CountAsync(); + } + public async Task GetByShortNameAsync(string shortName) { var project = await DbSet.FirstOrDefaultAsync(p => p.ShortName == shortName); diff --git a/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Projects/DocsProjectController.cs b/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Projects/DocsProjectController.cs index 180cec622f..e22df620f9 100644 --- a/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Projects/DocsProjectController.cs +++ b/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Projects/DocsProjectController.cs @@ -34,21 +34,6 @@ namespace Volo.Docs.Projects return ProjectAppService.GetAsync(shortName); } - public Task CreateAsync(CreateProjectDto input) - { - return ProjectAppService.CreateAsync(input); - } - - public Task UpdateAsync(Guid id, UpdateProjectDto input) - { - return ProjectAppService.UpdateAsync(id, input); - } - - public Task DeleteAsync(Guid id) - { - return ProjectAppService.DeleteAsync(id); - } - [HttpGet] [Route("{shortName}/versions")] public virtual Task> GetVersionsAsync(string shortName) From 2aa03bc433e54489afb4f7d7f75c71345a5d6b09 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Mon, 24 Dec 2018 19:04:15 +0300 Subject: [PATCH 129/368] Add BreadCrumb.Add method --- .../Volo/Abp/AspNetCore/Mvc/UI/Layout/BreadCrumb.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Layout/BreadCrumb.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Layout/BreadCrumb.cs index c0459fe5a0..10d03554e4 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Layout/BreadCrumb.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Layout/BreadCrumb.cs @@ -20,5 +20,10 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Layout { Items = new List(); } + + public void Add(string text, string url = null, string icon = null) + { + Items.Add(new BreadCrumbItem(text, url, icon)); + } } } \ No newline at end of file From 5e551438e786e50ee397a5eff9725883dff0e760 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Tue, 25 Dec 2018 10:50:10 +0300 Subject: [PATCH 130/368] Fix value of StandardMenus.Shortcut --- .../Mvc/UI/MultiTenancy/Components/TenantSwitch/Default.cshtml | 2 +- .../Mvc/UI/MultiTenancy/Components/_ViewImports.cshtml | 3 +++ .../Volo/Abp/Ui/Navigation/StandardMenus.cs | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Components/_ViewImports.cshtml diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Components/TenantSwitch/Default.cshtml b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Components/TenantSwitch/Default.cshtml index c275048621..33419549f0 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Components/TenantSwitch/Default.cshtml +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Components/TenantSwitch/Default.cshtml @@ -1,7 +1,7 @@ @using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Components.TenantSwitch @model TenantSwitchViewComponent.TenantSwitchViewModel