diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index 0fdcd10747..36c00e9015 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -400,6 +400,7 @@ "UserDeveloperDescription": "The 'Developers' can write code in the ABP Commercial projects, download the ABP sample projects, and ask questions on the support website. On the other hand, the 'Developers' cannot manage this organization.", "RemoveCurrentUserFromOrganizationWarningMessage": "You are removing yourself from your own organization. You will no longer be able to manage this organization, do you confirm?", "RenewExistingOrganizationOrCreateNewOneMessage": "You can renew the license of your organization(s) by clicking the below \"Extend Now\" button(s) and thus you can extend the license expiration date by 1 year. If you continue to checkout, you will have a new organization. Do you want to continue with a new organization?", + "PurchaseTrialOrganizationOrCreateNewOneMessage": "You have a trial license. To purchase your trial license click Purchase Now button. If you continue to checkout, you will have a new organization. Do you want to continue with a new organization?", "ExtendNow": "Extend Now", "CreateNewOrganization": "Create a new organization", "RenewLicenseEarly": "If I renew my license early, will I get the full year?", diff --git a/docs/en/CLI.md b/docs/en/CLI.md index 57e27c23ec..cc85f0e573 100644 --- a/docs/en/CLI.md +++ b/docs/en/CLI.md @@ -219,7 +219,7 @@ Example: abp add-package Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic ```` -* This example adds the Volo.Abp.MongoDB package to the project. +* This example adds the `Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic` package to the project. #### Options diff --git a/docs/zh-Hans/CLI.md b/docs/zh-Hans/CLI.md index 96d78538ef..f890534795 100644 --- a/docs/zh-Hans/CLI.md +++ b/docs/zh-Hans/CLI.md @@ -190,10 +190,10 @@ abp add-package <包名> [options] 示例: ```` -abp add-package Volo.Abp.MongoDB +abp add-package Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic ```` -* 示例中将Volo.Abp.MongoDB包添加到项目中. +* 示例中将`Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic`包添加到项目中. #### Options @@ -201,6 +201,12 @@ abp add-package Volo.Abp.MongoDB * `--with-source-code`: 下载包的源码到你的解决方案文件夹,而不是NuGet/NPM软件包. * `--add-to-solution-file`: 添加下载/创建的包添加到解决方案文件中,你在IDE中打开解决方案时也会看到包的项目. (仅当 `--with-source-code` 为 `True` 时可用.) +> 当前只有基本主题包([MVC](https://docs.abp.io/zh-Hans/abp/latest/UI/AspNetCore/Basic-Theme) 和 [Blazor](https://docs.abp.io/zh-Hans/abp/latest/UI/Blazor/Basic-Theme)) 可以下载. +> - Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic +> - Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme +> - Volo.Abp.AspNetCore.Components.Web.BasicTheme +> - Volo.Abp.AspNetCore.Components.Server.BasicTheme + ### add-module 通过查找模块的所有包,查找解决方案中的相关项目,并将每个包添加到解决方案中的相应项目,从而将[多包应用程序模块](Modules/Index)添加到解决方案中. diff --git a/docs/zh-Hans/Redis-Cache.md b/docs/zh-Hans/Redis-Cache.md index cb82a640d5..1c6d3caa42 100644 --- a/docs/zh-Hans/Redis-Cache.md +++ b/docs/zh-Hans/Redis-Cache.md @@ -1 +1,45 @@ -TODO... \ No newline at end of file +# Redis 缓存 + +ABP Framework [缓存系统](Caching.md) 拓展了 [ASP.NET Core 分布式缓存](https://docs.microsoft.com/zh-cn/aspnet/core/performance/caching/distributed). 因此, 标准 ASP.NET Core 分布式缓存支持的 **任何提供程序** 都可以在你的应用程序中使用,并且可以像 **微软文档** 那样进行配置. + +不过, ABP为 Redis Cache 还提供了一个集成包: [Volo.Abp.Caching.StackExchangeRedis](https://www.nuget.org/packages/Volo.Abp.Caching.StackExchangeRedis). +为何使用中这个包而不是标准的[Microsoft.Extensions.Caching.StackExchangeRedis](https://www.nuget.org/packages/Microsoft.Extensions.Caching.StackExchangeRedis/)包有两个原因. + +1. 它实现 `SetManyAsync` 和 `GetManyAsync` 方法. 这些都不是 Microsoft 缓存库的标准方法,而是由ABP框架[缓存](Caching.md)系统添加的. 当你需要通过单个方法调用设置/获取多个缓存项时,它们**显著提高了性能**. +2. 它 **简化** 了 Redis 缓存 **配置** (将在下面解释). + +> Volo.Abp.Caching.StackExchangeRedis 已经使用了 Microsoft.Extensions.Caching.StackExchangeRedis 包,但对其进行了扩展和改进. +## 安装 + +> 如果使用Redis,则此软件包已安装在应用程序启动模板中. +在项目`.csproj`的文件夹中打开命令行窗口并输入命令: + +````bash +abp add-package Volo.Abp.Caching.StackExchangeRedis +```` + +## 配置 + +Volo.Abp.Caching.StackExchangeRedis 包自动从`IConfiguration`获取Redis[配置](Configuration.md). 因此,你可以在以下位置设置配置 `appsettings.json`: + +````js +"Redis": { + "IsEnabled": "true", + "Configuration": "127.0.0.1" +} +```` +设置`IsEnabled`为可选的,如果未设置将默认视为`true`. + + +或者,你可以在[模块](Module-Development-Basics.md)的ConfigureServices方法中配置标准的[RedisCacheOptions](https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.extensions.caching.stackexchangeredis.rediscacheoptions)类: + +````csharp +Configure(options => +{ + //... +}); +```` + +## 另请参阅 + +* [缓存](Caching.md) diff --git a/docs/zh-Hans/docs-nav.json b/docs/zh-Hans/docs-nav.json index d66d11b3cf..203000c6c6 100644 --- a/docs/zh-Hans/docs-nav.json +++ b/docs/zh-Hans/docs-nav.json @@ -167,7 +167,13 @@ }, { "text": "缓存", - "path": "Caching.md" + "path": "Caching.md", + "items": [ + { + "text": "Redis 缓存", + "path": "Redis-Cache.md" + } + ] }, { "text": "日志", diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationOptions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationOptions.cs new file mode 100644 index 0000000000..e4e59bc197 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationOptions.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; + +namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; + +public class AbpApplicationConfigurationOptions +{ + public List Contributors { get; } + + public AbpApplicationConfigurationOptions() + { + Contributors = new List(); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationContributorContext.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationContributorContext.cs new file mode 100644 index 0000000000..3831cc1618 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationContributorContext.cs @@ -0,0 +1,17 @@ +using System; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; + +public class ApplicationConfigurationContributorContext : IServiceProviderAccessor +{ + public IServiceProvider ServiceProvider { get; } + + public ApplicationConfigurationDto ApplicationConfiguration { get; } + + public ApplicationConfigurationContributorContext(IServiceProvider serviceProvider, ApplicationConfigurationDto applicationConfiguration) + { + ServiceProvider = serviceProvider; + ApplicationConfiguration = applicationConfiguration; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationDto.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationDto.cs index eb29c5c7cb..61b5ec18db 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationDto.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationDto.cs @@ -1,11 +1,12 @@ using System; using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending; using Volo.Abp.AspNetCore.Mvc.MultiTenancy; +using Volo.Abp.Data; namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; [Serializable] -public class ApplicationConfigurationDto +public class ApplicationConfigurationDto : IHasExtraProperties { public ApplicationLocalizationConfigurationDto Localization { get; set; } @@ -28,4 +29,6 @@ public class ApplicationConfigurationDto public ClockDto Clock { get; set; } public ObjectExtensionsDto ObjectExtensions { get; set; } + + public ExtraPropertyDictionary ExtraProperties { get; set; } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/IApplicationConfigurationContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/IApplicationConfigurationContributor.cs new file mode 100644 index 0000000000..7612ae6fec --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/IApplicationConfigurationContributor.cs @@ -0,0 +1,8 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; + +public interface IApplicationConfigurationContributor +{ + Task ContributeAsync(ApplicationConfigurationContributorContext context); +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs index b80a288e81..528a04583d 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs @@ -13,6 +13,7 @@ using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending; using Volo.Abp.AspNetCore.Mvc.MultiTenancy; using Volo.Abp.Authorization; using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Data; using Volo.Abp.Features; using Volo.Abp.GlobalFeatures; using Volo.Abp.Localization; @@ -41,6 +42,7 @@ public class AbpApplicationConfigurationAppService : ApplicationService, IAbpApp private readonly ITimezoneProvider _timezoneProvider; private readonly AbpClockOptions _abpClockOptions; private readonly ICachedObjectExtensionsDtoService _cachedObjectExtensionsDtoService; + private readonly AbpApplicationConfigurationOptions _options; public AbpApplicationConfigurationAppService( IOptions localizationOptions, @@ -58,7 +60,8 @@ public class AbpApplicationConfigurationAppService : ApplicationService, IAbpApp ILanguageProvider languageProvider, ITimezoneProvider timezoneProvider, IOptions abpClockOptions, - ICachedObjectExtensionsDtoService cachedObjectExtensionsDtoService) + ICachedObjectExtensionsDtoService cachedObjectExtensionsDtoService, + IOptions options) { _serviceProvider = serviceProvider; _abpAuthorizationPolicyProvider = abpAuthorizationPolicyProvider; @@ -74,6 +77,7 @@ public class AbpApplicationConfigurationAppService : ApplicationService, IAbpApp _timezoneProvider = timezoneProvider; _abpClockOptions = abpClockOptions.Value; _cachedObjectExtensionsDtoService = cachedObjectExtensionsDtoService; + _options = options.Value; _localizationOptions = localizationOptions.Value; _multiTenancyOptions = multiTenancyOptions.Value; } @@ -96,9 +100,22 @@ public class AbpApplicationConfigurationAppService : ApplicationService, IAbpApp CurrentTenant = GetCurrentTenant(), Timing = await GetTimingConfigAsync(), Clock = GetClockConfig(), - ObjectExtensions = _cachedObjectExtensionsDtoService.Get() + ObjectExtensions = _cachedObjectExtensionsDtoService.Get(), + ExtraProperties = new ExtraPropertyDictionary() }; + if (_options.Contributors.Any()) + { + using (var scope = _serviceProvider.CreateScope()) + { + var context = new ApplicationConfigurationContributorContext(scope.ServiceProvider, result); + foreach (var contributor in _options.Contributors) + { + await contributor.ContributeAsync(context); + } + } + } + Logger.LogDebug("Executed AbpApplicationConfigurationAppService.GetAsync()."); return result; diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs index 6eb2784bb2..1cffbfe407 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs @@ -16,13 +16,14 @@ using Volo.Abp.Cli.ProjectBuilding.Building; using Volo.Abp.Cli.ProjectModification; using Volo.Abp.Cli.Utils; using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Local; namespace Volo.Abp.Cli.Commands; public class NewCommand : ProjectCreationCommandBase, IConsoleCommand, ITransientDependency { public const string Name = "new"; - + protected TemplateProjectBuilder TemplateProjectBuilder { get; } public ITemplateInfoProvider TemplateInfoProvider { get; } @@ -34,8 +35,9 @@ public class NewCommand : ProjectCreationCommandBase, IConsoleCommand, ITransien IInstallLibsService installLibsService, AngularPwaSupportAdder angularPwaSupportAdder, InitialMigrationCreator initialMigrationCreator, - ThemePackageAdder themePackageAdder) - : base(connectionStringProvider, solutionPackageVersionFinder, cmdHelper, installLibsService, angularPwaSupportAdder, initialMigrationCreator, themePackageAdder) + ThemePackageAdder themePackageAdder, + ILocalEventBus eventBus) + : base(connectionStringProvider, solutionPackageVersionFinder, cmdHelper, installLibsService, angularPwaSupportAdder, initialMigrationCreator, themePackageAdder, eventBus) { TemplateProjectBuilder = templateProjectBuilder; TemplateInfoProvider = templateInfoProvider; @@ -81,10 +83,10 @@ public class NewCommand : ProjectCreationCommandBase, IConsoleCommand, ITransien Logger.LogInformation($"'{projectName}' has been successfully created to '{projectArgs.OutputFolder}'"); ConfigureNpmPackagesForTheme(projectArgs); - RunGraphBuildForMicroserviceServiceTemplate(projectArgs); + await RunGraphBuildForMicroserviceServiceTemplate(projectArgs); await CreateInitialMigrationsAsync(projectArgs); await RunInstallLibsForWebTemplateAsync(projectArgs); - ConfigurePwaSupportForAngular(projectArgs); + await ConfigurePwaSupportForAngular(projectArgs); OpenRelatedWebPage(projectArgs, template, isTiered, commandLineArgs); } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs index 364289f60a..260f752f29 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs @@ -14,10 +14,12 @@ using Volo.Abp.Cli.Commands.Services; using Volo.Abp.Cli.LIbs; using Volo.Abp.Cli.ProjectBuilding; using Volo.Abp.Cli.ProjectBuilding.Building; +using Volo.Abp.Cli.ProjectBuilding.Events; using Volo.Abp.Cli.ProjectBuilding.Templates.App; using Volo.Abp.Cli.ProjectBuilding.Templates.Microservice; using Volo.Abp.Cli.ProjectBuilding.Templates.Module; using Volo.Abp.Cli.Utils; +using Volo.Abp.EventBus.Local; namespace Volo.Abp.Cli.Commands; @@ -29,6 +31,7 @@ public abstract class ProjectCreationCommandBase public IInstallLibsService InstallLibsService { get; } public AngularPwaSupportAdder AngularPwaSupportAdder { get; } public InitialMigrationCreator InitialMigrationCreator { get; } + public ILocalEventBus EventBus { get; } public ILogger Logger { get; set; } public ThemePackageAdder ThemePackageAdder { get; } @@ -40,7 +43,8 @@ public abstract class ProjectCreationCommandBase IInstallLibsService installLibsService, AngularPwaSupportAdder angularPwaSupportAdder, InitialMigrationCreator initialMigrationCreator, - ThemePackageAdder themePackageAdder) + ThemePackageAdder themePackageAdder, + ILocalEventBus eventBus) { ConnectionStringProvider = connectionStringProvider; SolutionPackageVersionFinder = solutionPackageVersionFinder; @@ -48,6 +52,7 @@ public abstract class ProjectCreationCommandBase InstallLibsService = installLibsService; AngularPwaSupportAdder = angularPwaSupportAdder; InitialMigrationCreator = initialMigrationCreator; + EventBus = eventBus; ThemePackageAdder = themePackageAdder; Logger = NullLogger.Instance; @@ -201,6 +206,10 @@ public abstract class ProjectCreationCommandBase protected void ExtractProjectZip(ProjectBuildResult project, string outputFolder) { + EventBus.PublishAsync(new ProjectCreationProgressEvent { + Message = "Extracting the solution archieve" + }, false); + using (var templateFileStream = new MemoryStream(project.ZipContent)) { using (var zipInputStream = new ZipInputStream(templateFileStream)) @@ -332,10 +341,14 @@ public abstract class ProjectCreationCommandBase throw new CliUsageException(ExceptionMessageHelper.GetInvalidArgExceptionMessage("Database Provider")); } - protected virtual void RunGraphBuildForMicroserviceServiceTemplate(ProjectBuildArgs projectArgs) + protected virtual async Task RunGraphBuildForMicroserviceServiceTemplate(ProjectBuildArgs projectArgs) { if (MicroserviceServiceTemplateBase.IsMicroserviceServiceTemplate(projectArgs.TemplateName)) { + await EventBus.PublishAsync(new ProjectCreationProgressEvent { + Message = "Building the microservice solution" + }, false); + CmdHelper.RunCmd("dotnet build /graphbuild", projectArgs.OutputFolder); } } @@ -348,6 +361,11 @@ public abstract class ProjectCreationCommandBase MicroserviceServiceTemplateBase.IsMicroserviceTemplate(projectArgs.TemplateName)) { Logger.LogInformation("Installing client-side packages..."); + + await EventBus.PublishAsync(new ProjectCreationProgressEvent { + Message = "Installing client-side packages" + }, false); + await InstallLibsService.InstallLibsAsync(projectArgs.OutputFolder); } } @@ -384,10 +402,14 @@ public abstract class ProjectCreationCommandBase return; } + await EventBus.PublishAsync(new ProjectCreationProgressEvent { + Message = "Creating the initial DB migration" + }, false); + await InitialMigrationCreator.CreateAsync(Path.GetDirectoryName(efCoreProjectPath), isLayeredTemplate); } - protected void ConfigurePwaSupportForAngular(ProjectBuildArgs projectArgs) + protected async Task ConfigurePwaSupportForAngular(ProjectBuildArgs projectArgs) { var isAngular = projectArgs.UiFramework == UiFramework.Angular; var isPwa = projectArgs.Pwa; @@ -395,6 +417,7 @@ public abstract class ProjectCreationCommandBase if (isAngular && isPwa) { Logger.LogInformation("Adding PWA Support to Angular app."); + AngularPwaSupportAdder.AddPwaSupport(projectArgs.OutputFolder); } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SuiteCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SuiteCommand.cs index 6ee6a74a47..060262eb93 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SuiteCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SuiteCommand.cs @@ -116,6 +116,18 @@ public class SuiteCommand : IConsoleCommand, ITransientDependency return; } + var IsSolutionBuiltResponse = await client.GetAsync( + $"{AbpSuiteHost}/api/abpSuite/solutions/{solutionId.ToString()}/is-built" + ); + + var IsSolutionBuilt = Convert.ToBoolean(await IsSolutionBuiltResponse.Content.ReadAsStringAsync()); + + if (!IsSolutionBuilt) + { + Logger.LogInformation("Building the solution..."); + CmdHelper.RunCmd("dotnet build", Path.GetDirectoryName(solutionFile)); + } + var entityContent = new StringContent( File.ReadAllText(entityFile), Encoding.UTF8, diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangeApplicationIdGuidStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangeApplicationIdGuidStep.cs deleted file mode 100644 index d37b7a67c3..0000000000 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ChangeApplicationIdGuidStep.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Linq; - -namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps; - -public class ChangeApplicationIdGuidStep: ProjectBuildPipelineStep -{ - public override void Execute(ProjectBuildContext context) - { - var projectFile = context.Files.FirstOrDefault(f => f.Name.EndsWith("MyCompanyName.MyProjectName.csproj")); - - projectFile?.SetContent(projectFile.Content.Replace("27317750-B571-4690-B433-B358B2480E01", Guid.NewGuid().ToString())); - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Events/ProjectCreationProgressEvent.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Events/ProjectCreationProgressEvent.cs new file mode 100644 index 0000000000..24c424f4cb --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Events/ProjectCreationProgressEvent.cs @@ -0,0 +1,6 @@ +namespace Volo.Abp.Cli.ProjectBuilding.Events; + +public class ProjectCreationProgressEvent +{ + public string Message { get; set; } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs index 5743a423c0..126e9bdbf9 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs @@ -10,8 +10,10 @@ using Volo.Abp.Cli.Commands; using Volo.Abp.Cli.Licensing; using Volo.Abp.Cli.ProjectBuilding.Analyticses; using Volo.Abp.Cli.ProjectBuilding.Building; +using Volo.Abp.Cli.ProjectBuilding.Events; using Volo.Abp.Cli.ProjectBuilding.Templates.App; using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Local; using Volo.Abp.Json; namespace Volo.Abp.Cli.ProjectBuilding; @@ -26,6 +28,7 @@ public class TemplateProjectBuilder : IProjectBuilder, ITransientDependency protected AbpCliOptions Options { get; } protected IJsonSerializer JsonSerializer { get; } protected IApiKeyService ApiKeyService { get; } + protected ILocalEventBus EventBus { get; } private readonly IConfiguration _configuration; @@ -35,7 +38,8 @@ public class TemplateProjectBuilder : IProjectBuilder, ITransientDependency IOptions options, IJsonSerializer jsonSerializer, IApiKeyService apiKeyService, - IConfiguration configuration) + IConfiguration configuration, + ILocalEventBus eventBus) { SourceCodeStore = sourceCodeStore; TemplateInfoProvider = templateInfoProvider; @@ -43,6 +47,7 @@ public class TemplateProjectBuilder : IProjectBuilder, ITransientDependency Options = options.Value; JsonSerializer = jsonSerializer; ApiKeyService = apiKeyService; + EventBus = eventBus; _configuration = configuration; Logger = NullLogger.Instance; @@ -54,6 +59,10 @@ public class TemplateProjectBuilder : IProjectBuilder, ITransientDependency NormalizeArgs(args, templateInfo); + await EventBus.PublishAsync(new ProjectCreationProgressEvent { + Message = "Downloading the solution template" + }, false); + var templateFile = await SourceCodeStore.GetAsync( args.TemplateName, SourceCodeTypes.Template, @@ -116,7 +125,11 @@ public class TemplateProjectBuilder : IProjectBuilder, ITransientDependency { appTemplateBase.HasDbMigrations = SemanticVersion.Parse(templateFile.Version) < new SemanticVersion(4, 3, 99); } - + + await EventBus.PublishAsync(new ProjectCreationProgressEvent { + Message = "Customizing the solution template" + }, false); + TemplateProjectBuildPipelineBuilder.Build(context).Execute(); if (!templateInfo.DocumentUrl.IsNullOrEmpty()) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs index e1dc2f6018..6b77af00c8 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs @@ -359,6 +359,7 @@ public abstract class AppTemplateBase : TemplateInfo else { steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.HttpApi.Host")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.IdentityServer")); steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.AuthServer")); steps.Add(new TemplateProjectRenameStep("MyCompanyName.MyProjectName.HttpApi.HostWithIds", "MyCompanyName.MyProjectName.HttpApi.Host")); steps.Add(new AppTemplateChangeConsoleTestClientPortSettingsStep("44305")); @@ -398,6 +399,7 @@ public abstract class AppTemplateBase : TemplateInfo { steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Blazor.Server.Tiered")); steps.Add(new TemplateProjectRenameStep("MyCompanyName.MyProjectName.Blazor.Server", "MyCompanyName.MyProjectName.Blazor")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.IdentityServer")); steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.HttpApi.Host")); steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.AuthServer")); steps.Add(new AppTemplateChangeConsoleTestClientPortSettingsStep("44313")); @@ -419,6 +421,7 @@ public abstract class AppTemplateBase : TemplateInfo { steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web.Host")); steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.HttpApi.Host")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.IdentityServer")); steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.AuthServer")); steps.Add(new AppTemplateChangeConsoleTestClientPortSettingsStep("44303")); } @@ -449,6 +452,7 @@ public abstract class AppTemplateBase : TemplateInfo else { steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.HttpApi.Host")); + steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.IdentityServer")); steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.AuthServer")); steps.Add(new TemplateProjectRenameStep("MyCompanyName.MyProjectName.HttpApi.HostWithIds", "MyCompanyName.MyProjectName.HttpApi.Host")); steps.Add(new AppTemplateChangeConsoleTestClientPortSettingsStep("44305")); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Maui/MauiChangeApplicationIdGuidStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Maui/MauiChangeApplicationIdGuidStep.cs new file mode 100644 index 0000000000..9bbaa8b553 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Maui/MauiChangeApplicationIdGuidStep.cs @@ -0,0 +1,34 @@ +using System; +using System.Linq; +using System.Xml; +using Volo.Abp.Cli.ProjectBuilding.Building; +using Volo.Abp.Cli.Utils; + +namespace Volo.Abp.Cli.ProjectBuilding.Templates.Maui; + +public class MauiChangeApplicationIdGuidStep: ProjectBuildPipelineStep +{ + public override void Execute(ProjectBuildContext context) + { + var projectFile = context.Files.FirstOrDefault(f => f.Name.EndsWith("MyCompanyName.MyProjectName.csproj") || f.Name.EndsWith("MyCompanyName.MyProjectName.Maui.csproj")); + + if (projectFile == null) + { + return; + } + + using (var stream = StreamHelper.GenerateStreamFromString(projectFile.Content)) + { + var doc = new XmlDocument { PreserveWhitespace = true }; + doc.Load(stream); + + var node = doc.SelectSingleNode("/Project/PropertyGroup/ApplicationIdGuid"); + if (node != null) + { + node.InnerText = Guid.NewGuid().ToString(); + } + + projectFile.SetContent(doc.OuterXml); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Maui/MauiTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Maui/MauiTemplateBase.cs index 399773ce32..c17d661efa 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Maui/MauiTemplateBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Maui/MauiTemplateBase.cs @@ -16,7 +16,7 @@ public class MauiTemplateBase: TemplateInfo { var steps = new List { - new ChangeApplicationIdGuidStep() + new MauiChangeApplicationIdGuidStep() }; return steps; diff --git a/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpDictionaryExtensions.cs b/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpDictionaryExtensions.cs index 1e6dd0288c..6ac5601f7d 100644 --- a/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpDictionaryExtensions.cs +++ b/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpDictionaryExtensions.cs @@ -1,4 +1,5 @@ using System.Collections.Concurrent; +using System.Dynamic; namespace System.Collections.Generic; @@ -128,4 +129,22 @@ public static class AbpDictionaryExtensions { return dictionary.GetOrAdd(key, k => factory()); } + + /// + /// Converts a dictionary to dynamic object so added and removed at run + /// + /// The collection object + /// If value is correct, return ExpandoObject that represents an object + public static dynamic ConvertToDynamicObject(this Dictionary dictionary) + { + var expandoObject = new ExpandoObject(); + var expendObjectCollection = (ICollection>)expandoObject; + + foreach (var keyValuePair in dictionary) + { + expendObjectCollection.Add(keyValuePair); + } + + return expandoObject; + } } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs index 2a73b72932..741f6f0586 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs @@ -223,7 +223,7 @@ public abstract class AbpApplicationBase : IAbpApplication { if (_configuredServices) { - throw new AbpInitializationException("Services have already been configured! If you call ConfigureServicesAsync method, you must have set AbpApplicationCreationOptions.SkipConfigureServices tu true before."); + throw new AbpInitializationException("Services have already been configured! If you call ConfigureServicesAsync method, you must have set AbpApplicationCreationOptions.SkipConfigureServices to true before."); } } @@ -231,7 +231,7 @@ public abstract class AbpApplicationBase : IAbpApplication public virtual void ConfigureServices() { CheckMultipleConfigureServices(); - + var context = new ServiceConfigurationContext(Services); Services.AddSingleton(context); 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 2e8d8c4689..e303a0fb5d 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 @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; using Volo.Abp.AspNetCore.Mvc.Authorization; using Volo.Abp.AspNetCore.Mvc.GlobalFeatures; using Volo.Abp.AspNetCore.Mvc.Localization; @@ -127,6 +128,11 @@ public class AbpAspNetCoreMvcTestModule : AbpModule options.Maps.Add("SerialNumber", () => ClaimTypes.SerialNumber); options.Maps.Add("DateOfBirth", () => ClaimTypes.DateOfBirth); }); + + Configure(options => + { + options.Contributors.Add(new TestApplicationConfigurationContributor()); + }); } public override void OnApplicationInitialization(ApplicationInitializationContext context) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationBuilder_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationBuilder_Tests.cs index c932e09488..5d3cb09749 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationBuilder_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationBuilder_Tests.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Shouldly; +using Volo.Abp.Data; using Xunit; namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; @@ -15,5 +16,6 @@ public class ApplicationConfigurationBuilder_Tests : AspNetCoreMvcTestBase config.Auth.ShouldNotBeNull(); config.Localization.ShouldNotBeNull(); + config.GetProperty("TestKey").ShouldBe("TestValue"); } } diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/TestApplicationConfigurationContributor.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/TestApplicationConfigurationContributor.cs new file mode 100644 index 0000000000..4ae197d2a0 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/TestApplicationConfigurationContributor.cs @@ -0,0 +1,13 @@ +using System.Threading.Tasks; +using Volo.Abp.Data; + +namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; + +public class TestApplicationConfigurationContributor : IApplicationConfigurationContributor +{ + public Task ContributeAsync(ApplicationConfigurationContributorContext context) + { + context.ApplicationConfiguration.SetProperty("TestKey", "TestValue"); + return Task.CompletedTask; + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/appsettings.json b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/appsettings.json index 3c872decbe..fcf428bab3 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/appsettings.json +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/appsettings.json @@ -1,5 +1,5 @@ { "ConnectionStrings": { - "Default": "Server=(localdb)\\.\\MSSQLLocalDB;Database=CmsKit_Unified;Trusted_Connection=True" + "Default": "Server=(localdb)\\MSSQLLocalDB;Database=CmsKit_Unified;Trusted_Connection=True" } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Contents/ContentConsts.cs b/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Contents/ContentConsts.cs new file mode 100644 index 0000000000..8caaa7a03a --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Contents/ContentConsts.cs @@ -0,0 +1,8 @@ +namespace Volo.CmsKit.Contents; +public static class ContentConsts +{ + public static string Delimeter { get; set; } = "----"; + public static string Widget { get; set; } = "Widget"; + public static string Markdown { get; set; } = "Markdown"; + public static string Content { get; set; } = "Content"; +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Contents/ContentFragment.cs b/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Contents/ContentFragment.cs new file mode 100644 index 0000000000..20574f830c --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Contents/ContentFragment.cs @@ -0,0 +1,10 @@ +using System; +using Volo.Abp.ObjectExtending; + +namespace Volo.CmsKit.Contents; + +[Serializable] +public class ContentFragment : ExtensibleObject +{ + public string Type { get; set; } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Contents/CmsKitContentWidgetOptions.cs b/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Contents/CmsKitContentWidgetOptions.cs new file mode 100644 index 0000000000..1f9dae60ab --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Contents/CmsKitContentWidgetOptions.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; + +namespace Volo.CmsKit.Contents; + +public class CmsKitContentWidgetOptions +{ + public Dictionary WidgetConfigs { get; } + + public CmsKitContentWidgetOptions() + { + WidgetConfigs = new(); + } + + public void AddWidget(string widgetName, string widgetKey) + { + WidgetConfigs.Add(widgetName, new ContentWidgetConfig(widgetKey)); + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Contents/ContentParser.cs b/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Contents/ContentParser.cs new file mode 100644 index 0000000000..7fe9fe5b60 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Contents/ContentParser.cs @@ -0,0 +1,120 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using static Volo.CmsKit.Contents.ContentConsts; + +namespace Volo.CmsKit.Contents; + +public class ContentParser : ITransientDependency +{ + private readonly CmsKitContentWidgetOptions _options; + + public ContentParser(IOptions options) + { + _options = options.Value; + } + + public Task> ParseAsync(string content) + { + if (!_options.WidgetConfigs.Any()) + { + return Task.FromResult(new List + { + new ContentFragment { Type = Markdown }.SetProperty(Content, content), + }); + } + + var parsedList = new List(); + ParseContent(content, parsedList); + + var contentFragments = new List(); + FillContentFragment(content, parsedList, contentFragments); + + return Task.FromResult(contentFragments); + } + + private void ParseContent(string content, List parsedList) + { + var replacedText = Regex.Replace(content, @"\[.*?\]", Delimeter); + if (!replacedText.Contains(Delimeter)) + { + parsedList.Add(replacedText); + } + + while (replacedText.Contains(Delimeter)) + { + //For parsing delimeter + var index = replacedText.IndexOf(Delimeter); + if (index != 0) + { + parsedList.Add(replacedText.Substring(0, index)); + replacedText = replacedText.Substring(index, replacedText.Length - index); + index = 0; + } + + parsedList.Add(replacedText.Substring(index, Delimeter.Length)); + replacedText = replacedText.Substring(Delimeter.Length, replacedText.Length - Delimeter.Length); + + //for parsing the other side + index = replacedText.IndexOf(Delimeter); + if (index != -1) + { + parsedList.Add(replacedText.Substring(0, index)); + replacedText = replacedText.Substring(index, replacedText.Length - index); + } + else if (replacedText.Length > 0) + { + parsedList.Add(replacedText); + } + } + } + + private void FillContentFragment(string content, List parsedList, List contentFragments) + { + content = Regex.Replace(content, @"=\s*""", @"="""); + content = Regex.Replace(content, @"""\s*=", @"""="); + var widgets = Regex.Matches(content, @"(?<=\[Widget)(.*?)(?=\])").Cast().Select(p => p.Value).ToList(); + for (int i = 0, k = 0; i < parsedList.Count; i++) + { + if (parsedList[i] == Delimeter) + { + if (widgets.Count > k) + { + var preparedContent = string.Join("", widgets[k]); + var keys = Regex.Matches(preparedContent, @"(?<=\s)(.*?)(?==\s*"")").Cast() + .Select(p => p.Value).Where(p => p != string.Empty).ToList(); + var values = Regex.Matches(preparedContent, @"(?<=\s*[a-zA-Z]*=\s*"")(.*?)(?="")").Cast() + .Select(p => p.Value).ToList(); + + var widgetTypeIndex = keys.IndexOf("Type"); + if (widgetTypeIndex != -1) + { + var widgetType = values[widgetTypeIndex]; + var name = _options.WidgetConfigs.Where(p => p.Key == widgetType).Select(p => p.Value.Name).FirstOrDefault(); + if (name is not null && widgets.Count > k) + { + values[0] = name; + var contentFragment = new ContentFragment() { Type = Widget }; + contentFragments.Add(contentFragment); + for (int kv = 0; kv < values.Count; kv++) + { + contentFragments.FindLast(p => p == contentFragment) + .SetProperty(keys[kv], values[kv]); + } + } + } + } + k++; + } + else + { + contentFragments.Add(new ContentFragment() { Type = Markdown } + .SetProperty(Content, parsedList[i])); + } + } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Contents/ContentWidgetConfig.cs b/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Contents/ContentWidgetConfig.cs new file mode 100644 index 0000000000..a5eab5930a --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Contents/ContentWidgetConfig.cs @@ -0,0 +1,11 @@ +namespace Volo.CmsKit.Contents; + +public class ContentWidgetConfig +{ + public string Name { get; } + + public ContentWidgetConfig(string widgetName) + { + Name = widgetName; + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs index 94a0456c66..99e6ed5b34 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs @@ -1,6 +1,4 @@ -using Volo.CmsKit.GlobalFeatures; - -namespace Volo.CmsKit.Blogs; +namespace Volo.CmsKit.Blogs; public static class BlogPostConsts { diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostPublicDto.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostPublicDto.cs index 8c6a6a01e9..695f50836e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostPublicDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostPublicDto.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Generic; using Volo.Abp.Application.Dtos; +using Volo.CmsKit.Contents; using Volo.CmsKit.Users; namespace Volo.CmsKit.Public.Blogs; @@ -15,6 +17,8 @@ public class BlogPostPublicDto : AuditedEntityDto public string ShortDescription { get; set; } + public List ContentFragments { get; set; } + public string Content { get; set; } public Guid? CoverImageMediaId { get; set; } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Pages/PageDto.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Pages/PageDto.cs index 64175d0f18..a336844289 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Pages/PageDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Pages/PageDto.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Generic; using Volo.Abp.Application.Dtos; +using Volo.CmsKit.Contents; namespace Volo.CmsKit.Public.Pages; @@ -11,6 +13,8 @@ public class PageDto : EntityDto public string Slug { get; set; } public string Content { get; set; } + + public List ContentFragments { get; set; } public string Script { get; set; } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs index 65e6c6fa20..ebdda3d293 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Volo.Abp.Application.Dtos; using Volo.Abp.GlobalFeatures; using Volo.CmsKit.Blogs; +using Volo.CmsKit.Contents; using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Users; @@ -16,22 +17,29 @@ public class BlogPostPublicAppService : CmsKitPublicAppServiceBase, IBlogPostPub protected IBlogRepository BlogRepository { get; } protected IBlogPostRepository BlogPostRepository { get; } + protected ContentParser ContentParser { get; } public BlogPostPublicAppService( IBlogRepository blogRepository, - IBlogPostRepository blogPostRepository) + IBlogPostRepository blogPostRepository, + ContentParser contentParser) { BlogRepository = blogRepository; BlogPostRepository = blogPostRepository; + ContentParser = contentParser; } - public virtual async Task GetAsync([NotNull] string blogSlug, [NotNull] string blogPostSlug) + public virtual async Task GetAsync( + [NotNull] string blogSlug, [NotNull] string blogPostSlug) { var blog = await BlogRepository.GetBySlugAsync(blogSlug); var blogPost = await BlogPostRepository.GetBySlugAsync(blog.Id, blogPostSlug); - return ObjectMapper.Map(blogPost); + var blogPostDto = ObjectMapper.Map(blogPost); + blogPostDto.ContentFragments = await ContentParser.ParseAsync(blogPost.Content); + + return blogPostDto; } public virtual async Task> GetListAsync([NotNull] string blogSlug, BlogPostGetListInput input) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Pages/PagePublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Pages/PagePublicAppService.cs index 258ef935ed..2bae7c350f 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Pages/PagePublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Pages/PagePublicAppService.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Volo.Abp.GlobalFeatures; +using Volo.CmsKit.Contents; using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Pages; @@ -9,10 +10,12 @@ namespace Volo.CmsKit.Public.Pages; public class PagePublicAppService : CmsKitPublicAppServiceBase, IPagePublicAppService { protected IPageRepository PageRepository { get; } + protected ContentParser ContentParser { get; } - public PagePublicAppService(IPageRepository pageRepository) + public PagePublicAppService(IPageRepository pageRepository, ContentParser contentParser) { PageRepository = pageRepository; + ContentParser = contentParser; } public virtual async Task FindBySlugAsync(string slug) @@ -24,6 +27,8 @@ public class PagePublicAppService : CmsKitPublicAppServiceBase, IPagePublicAppSe return null; } - return ObjectMapper.Map(page); + var pageDto = ObjectMapper.Map(page); + pageDto.ContentFragments = await ContentParser.ParseAsync(page.Content); + return pageDto; } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs index a6b7e497ac..704a03778c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs @@ -30,9 +30,11 @@ public class PublicApplicationAutoMapperProfile : Profile CreateMap(); - CreateMap(); + CreateMap() + .Ignore(x => x.ContentFragments); - CreateMap(MemberList.None); + CreateMap() + .Ignore(x => x.ContentFragments); CreateMap(); diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi.Client/ClientProxies/cms-kit-generate-proxy.json b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi.Client/ClientProxies/cms-kit-generate-proxy.json index d39e795845..626dce7ff2 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi.Client/ClientProxies/cms-kit-generate-proxy.json +++ b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi.Client/ClientProxies/cms-kit-generate-proxy.json @@ -505,6 +505,57 @@ } } }, + "Volo.CmsKit.Public.Polls.PollViewComponentController": { + "controllerName": "PollViewComponent", + "controllerGroupName": "PollViewComponent", + "isRemoteService": true, + "apiVersion": null, + "type": "Volo.CmsKit.Public.Polls.PollViewComponentController", + "interfaces": [ + { + "type": "Volo.CmsKit.Public.Polls.IPollViewComponentAppService" + } + ], + "actions": { + "ParseAsyncByContent": { + "uniqueName": "ParseAsyncByContent", + "name": "ParseAsync", + "httpMethod": "GET", + "url": "api/cms-kit-public/polls/{content}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "content", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "content", + "name": "content", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[Volo.CmsKit.Polls.ContentFragment]" + }, + "allowAnonymous": null, + "implementFrom": "Volo.CmsKit.Public.Polls.IPollViewComponentAppService" + } + } + }, "Volo.CmsKit.Public.Pages.PagesPublicController": { "controllerName": "PagesPublic", "controllerGroupName": "PagesPublic", @@ -989,6 +1040,18 @@ "bindingSourceId": "ModelBinding", "descriptorName": "input" }, + { + "nameOnMethod": "input", + "name": "TagId", + "jsonName": null, + "type": "System.Guid?", + "typeSimple": "string?", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, { "nameOnMethod": "input", "name": "Sorting", diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/Default.cshtml deleted file mode 100644 index 50104515c9..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/Default.cshtml +++ /dev/null @@ -1,17 +0,0 @@ -@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap - -@using Volo.CmsKit.Public.Web.Renderers -@using Volo.Abp.AspNetCore.Mvc.UI.Packages.HighlightJs - -@inject IMarkdownToHtmlRenderer MarkdownRenderer - -@model Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Pages.PageViewModel - - - - @if (!Model.Content.IsNullOrEmpty()) - { - @Html.Raw(await MarkdownRenderer.RenderAsync(Model.Content)) - } - - diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/DefaultPageViewComponent.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/DefaultPageViewComponent.cs deleted file mode 100644 index c5427af114..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Pages/DefaultPageViewComponent.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Volo.Abp.AspNetCore.Mvc; -using Volo.CmsKit.Public.Pages; -using Volo.CmsKit.Public.Web.Renderers; -using Volo.Abp.AspNetCore.Mvc.UI.Packages.HighlightJs; -using Volo.Abp.AspNetCore.Mvc.UI.Widgets; - -namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Pages; - -[Widget( - StyleTypes = new[] - { - typeof(HighlightJsStyleContributor) - }, - ScriptTypes = new[] - { - typeof(HighlightJsScriptContributor) - }, - ScriptFiles = new[] - { - "/Pages/Public/CmsKit/highlightOnLoad.js" - })] -public class DefaultPageViewComponent : AbpViewComponent -{ - protected IPagePublicAppService PagePublicAppService { get; } - - public DefaultPageViewComponent(IPagePublicAppService pagePublicAppService) - { - PagePublicAppService = pagePublicAppService; - } - - public virtual async Task InvokeAsync(Guid pageId, string title, string content) - { - var model = new PageViewModel - { - Id = pageId, - Title = title, - Content = content - }; - - return View("~/Pages/CmsKit/Shared/Components/Pages/Default.cshtml", model); - } -} - -public class PageViewModel -{ - public Guid Id { get; set; } - - public string Title { get; set; } - - public string Content { get; set; } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Tags/TagViewComponent.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Tags/TagViewComponent.cs index a3dc23c61a..0e550a6ade 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Tags/TagViewComponent.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Tags/TagViewComponent.cs @@ -1,9 +1,6 @@ -using Microsoft.AspNetCore.Mvc; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Collections.Generic; using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; using Volo.CmsKit.Tags; diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml index 9d8680e96c..2cff5c9072 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml @@ -1,5 +1,7 @@ @page +@using Volo.Abp.Data +@using Volo.CmsKit.Public.Blogs @using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Blogs.BlogPostComment @using Volo.CmsKit.Public.Web.Pages @using Volo.Abp.GlobalFeatures @@ -9,6 +11,7 @@ @using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Tags @using Volo.CmsKit.Public.Web.Renderers @using Volo.Abp.AspNetCore.Mvc.UI.Packages.HighlightJs +@using Volo.CmsKit.Contents @inherits CmsKitPublicPageBase @@ -23,71 +26,77 @@ } @section styles{ - @if (isScrollIndexEnabled) - { - - - - } + @if (isScrollIndexEnabled) + { + + + + } - - + + } -@section scripts{ + @section scripts{ @if (isScrollIndexEnabled) { - - + + } - - + + } -
-
- - - - -
-

@Model.BlogPost.Title

-

- - @@@Model.BlogPost.Author?.UserName - - @Model.BlogPost.CreationTime -

- @if (!Model.BlogPost.Content.IsNullOrEmpty()) - { - @Html.Raw(await MarkdownRenderer.RenderAsync(Model.BlogPost.Content)) - } - -

- @if (Model.BlogPost.LastModificationTime != null) +

+
+ + + + +
+

@Model.BlogPost.Title

+

+ + @@@Model.BlogPost.Author?.UserName + + @Model.BlogPost.CreationTime +

+ @foreach (var contentFragment in Model.BlogPost.ContentFragments) { - @L["LastModification"].Value : @Model.BlogPost.LastModificationTime + if (contentFragment.Type == ContentConsts.Markdown) + { + @Html.Raw(await MarkdownRenderer.RenderAsync(contentFragment.GetProperty("Content"))) + } + else if (contentFragment.Type == ContentConsts.Widget) + { + @await Component.InvokeAsync(contentFragment.GetProperty("Type"), contentFragment.ExtraProperties.ConvertToDynamicObject()) + } } -

-
+

+ @if (Model.BlogPost.LastModificationTime != null) + { + @L["LastModification"].Value : @Model.BlogPost.LastModificationTime + } +

+
- @if (GlobalFeatureManager.Instance.IsEnabled()) - { - if (Model.TagsFeature?.IsEnabled == true) + @if (GlobalFeatureManager.Instance.IsEnabled()) { - @await Component.InvokeAsync(typeof(TagViewComponent), new + if (Model.TagsFeature?.IsEnabled == true) { - entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, - entityId = Model.BlogPost.Id.ToString(), - urlFormat = $"/blogs/{Model.BlogSlug}?tagId={{TagId}}" - }) + @await Component.InvokeAsync(typeof(TagViewComponent), new + { + entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, + entityId = Model.BlogPost.Id.ToString(), + urlFormat = $"/blogs/{Model.BlogSlug}?tagId={{TagId}}" + }) } }
@@ -100,10 +109,10 @@ if (Model.ReactionsFeature?.IsEnabled == true) { @await Component.InvokeAsync(typeof(ReactionSelectionViewComponent), new - { - entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, - entityId = Model.BlogPost.Id.ToString() - }) + { + entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, + entityId = Model.BlogPost.Id.ToString() + }) } } @@ -113,10 +122,10 @@ if (Model.RatingsFeature?.IsEnabled == true) { @await Component.InvokeAsync(typeof(RatingViewComponent), new - { - entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, - entityId = Model.BlogPost.Id.ToString() - }) + { + entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, + entityId = Model.BlogPost.Id.ToString() + }) } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml.cs index dcefb976a4..6227190ab8 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml.cs @@ -1,11 +1,5 @@ -using Markdig; +using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Cryptography.X509Certificates; -using System.Text; -using System.Threading.Tasks; using Volo.Abp.GlobalFeatures; using Volo.CmsKit.Blogs; using Volo.CmsKit.GlobalFeatures; diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/Index.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/Index.cshtml index a3f1d0c95e..5a92ae2b04 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/Index.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/Index.cshtml @@ -1,31 +1,46 @@ @page -@using Microsoft.AspNetCore.Mvc.Localization -@using Volo.CmsKit.Localization -@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Pages +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap +@using Volo.CmsKit.Contents +@using System.Dynamic +@using Volo.CmsKit.Public.Web.Renderers +@using Volo.Abp.Data +@using Volo.Abp.AspNetCore.Mvc.UI.Packages.HighlightJs; +@using Volo.Abp.AspNetCore.Mvc.UI.Widgets; + +@inject IMarkdownToHtmlRenderer MarkdownRenderer + @model Volo.CmsKit.Public.Web.Pages.Public.CmsKit.Pages.IndexModel -@inject IHtmlLocalizer L @section styles{ } @section scripts{ } -@await Component.InvokeAsync(typeof(DefaultPageViewComponent), - new - { - pageId = Model.Page.Id, - title = Model.Page.Title, - content = Model.Page.Content - }) \ No newline at end of file + + + @foreach (ContentFragment contentFragment in Model.PageDto.ContentFragments) + { + if (contentFragment.Type == ContentConsts.Markdown) + { + @Html.Raw(await MarkdownRenderer.RenderAsync(contentFragment.GetProperty("Content"))) + } + else if (contentFragment.Type == ContentConsts.Widget) + { + @await Component.InvokeAsync(contentFragment.GetProperty("Type"), contentFragment.ExtraProperties.ConvertToDynamicObject()) + } + } + + + diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/Index.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/Index.cshtml.cs index 6eeac638cf..1434eccb4b 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/Index.cshtml.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/Index.cshtml.cs @@ -12,18 +12,18 @@ public class IndexModel : CommonPageModel protected IPagePublicAppService PagePublicAppService { get; } - public PageDto Page; + public PageDto PageDto{ get; private set; } - public IndexModel(IPagePublicAppService pagePublicAppService) +public IndexModel(IPagePublicAppService pagePublicAppService) { PagePublicAppService = pagePublicAppService; } public async Task OnGetAsync() { - Page = await PagePublicAppService.FindBySlugAsync(Slug); + PageDto = await PagePublicAppService.FindBySlugAsync(Slug); - if (Page == null) + if (PageDto == null) { return NotFound(); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/PageViewModel.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/PageViewModel.cs new file mode 100644 index 0000000000..5e5df3e917 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Pages/PageViewModel.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using Volo.CmsKit.Contents; + +namespace Volo.CmsKit.Public.Web.Pages.Public.CmsKit.Pages; + +public class PageViewModel +{ + public Guid Id { get; set; } + + public string Title { get; set; } + + public List ContentFragments { get; set; } +} \ No newline at end of file diff --git a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Contents/ContentParser_Test.cs b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Contents/ContentParser_Test.cs new file mode 100644 index 0000000000..108d883a70 --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Contents/ContentParser_Test.cs @@ -0,0 +1,138 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using Shouldly; +using Xunit; + +namespace Volo.CmsKit.Contents; +public class ContentParser_Test : CmsKitDomainTestBase +{ + private readonly CmsKitTestData testData; + private readonly IOptions _options; + private ContentParser contentParser; + + public ContentParser_Test() + { + testData = GetRequiredService(); + _options = GetRequiredService>(); + } + + [Fact] + public async Task ParseAsync_ShouldWorkWithDifferentWidgetTypes() + { + _options.Value.AddWidget(testData.PollName, testData.WidgetName); + _options.Value.AddWidget("ImageGallery", "ImageGallery"); + contentParser = new ContentParser(_options); + + var content = @"**ABP Framework** is completely open source and developed in a community-driven manner. + [Widget Type=""Poll"" Code=""poll-name""] + Thanks _for_ *your * feedback. + [Widget GalleryName=""Xyz"" Type=""ImageGallery"" Source=""GoogleDrive""]"; + + var widgets = await contentParser.ParseAsync(content); + + widgets.ShouldNotBeNull(); + widgets.Count.ShouldBe(4); + widgets[1].ExtraProperties.Count.ShouldBe(2); + widgets[3].ExtraProperties.Count.ShouldBe(3); + } + + [Fact] + public async Task ParseAsync_ShouldWorkWithoutConfigOptions() + { + var content = @"**ABP Framework** is completely open source and developed in a community-driven manner. + [Widget Type= ""Poll"" Code =""poll-name""] + Thanks _for_ *your * feedback."; + + contentParser = new ContentParser(_options); + var widgets = await contentParser.ParseAsync(content); + + widgets.ShouldNotBeNull(); + widgets.Count.ShouldBe(1);//Ignored Widget + } + + [Fact] + public async Task ParseAsync_ShouldWorkWithWrongConfigOptions() + { + _options.Value.AddWidget(testData.WidgetName, testData.PollName); + contentParser = new ContentParser(_options); + + var content = @"**ABP Framework** is completely open source and developed in a community-driven manner. + [Widget Type= ""Poll"" Code =""poll-name""] + Thanks _for_ *your * feedback."; + + var widgets = await contentParser.ParseAsync(content); + + widgets.ShouldNotBeNull(); + widgets.Count.ShouldBe(2); + } + + [Fact] + public async Task ParseAsync_ShouldWorkWithWrongWidgetType() + { + _options.Value.AddWidget(testData.PollName, testData.WidgetName); + contentParser = new ContentParser(_options); + + var content = @"**ABP Framework** is completely open source and developed in a community-driven manner. + [Widget Wrong Type= ""Poll"" Code =""poll-name""] + Thanks _for_ *your * feedback."; + + var widgets = await contentParser.ParseAsync(content); + + widgets.ShouldNotBeNull(); + widgets.Count.ShouldBe(2); + } + + [Fact] + public async Task ParseAsync_ShouldWorkWithWrongPollName() + { + _options.Value.AddWidget(testData.PollName, testData.WidgetName); + contentParser = new ContentParser(_options); + + var content = @"**ABP Framework** is completely open source and developed in a community-driven manner. + [Widget Type= ""Poll"" PollWrongName =""poll-name""] + Thanks _for_ *your * feedback."; + + var widgets = await contentParser.ParseAsync(content); + + widgets.ShouldNotBeNull(); + widgets.Count.ShouldBe(3); + } + + [Theory] + [MemberData(nameof(ExampleData))] + public async Task ParseAsync_ShouldWorkProperlyWithCorrectInputs(string content, int expectedLine) + { + _options.Value.AddWidget(testData.PollName, testData.WidgetName); + contentParser = new ContentParser(_options); + + var widgets = await contentParser.ParseAsync(content); + + widgets.ShouldNotBeNull(); + widgets.Count.ShouldBe(expectedLine); + } + + public static IEnumerable ExampleData => + new List + { + new object[] { @"**ABP Framework** is completely open source and developed in a community-driven manner. + [Widget Type=""Poll"" Code=""poll-name""] + Thanks _for_ *your * feedback.", 3}, + + new object[] { @"**ABP Framework** is completely open source and developed in a community-driven manner. + [Widget Type=""Poll"" Code=""poll-name""] + Thanks _for_ *your * feedback. + [Widget Type=""Poll"" Code=""poll-name1""]", 4 }, + + new object[] { @"**ABP Framework** is completely open source and developed in a community-driven manner. + Thanks _for_ *your * feedback. + [Widget Type=""Poll"" Code=""poll-name""]", 2 }, + + new object[] { @"[Widget Type=""Poll"" Code=""poll-name""] gg [Widget Type=""Poll"" Code=""poll-name1""]**ABP Framework** is completely open source and developed in a community-driven manner. + Thanks _for_ *your * feedback. + Thanks _for_ *your * feedback.", 4}, + + new object[] { @"Thanks _for_ *your * feedback. + Thanks _for_ *your * feedback.", 1} + }; +} diff --git a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Pages/PageManager_Test.cs b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Pages/PageManager_Test.cs index 92dac10caf..208de3817f 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Pages/PageManager_Test.cs +++ b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Pages/PageManager_Test.cs @@ -1,9 +1,6 @@ -using Shouldly; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Threading.Tasks; +using Shouldly; +using Xunit; namespace Volo.CmsKit.Pages; @@ -20,6 +17,7 @@ public class PageManager_Test : CmsKitDomainTestBase pageRepository = GetRequiredService(); } + [Fact] public async Task CreateAsync_ShouldWorkProperly_WithNonExistingSlug() { var title = "My awesome page"; @@ -34,6 +32,7 @@ public class PageManager_Test : CmsKitDomainTestBase page.Content.ShouldBe(content); } + [Fact] public async Task CreateAsync_ShouldThrowException_WithExistingSlug() { var title = "My awesome page"; @@ -46,6 +45,7 @@ public class PageManager_Test : CmsKitDomainTestBase exception.ShouldNotBeNull(); } + [Fact] public async Task SetSlugAsync_ShouldWorkProperly_WithNonExistingSlug() { var newSlug = "freshly-generated-new-slug"; @@ -56,6 +56,7 @@ public class PageManager_Test : CmsKitDomainTestBase page.Slug.ShouldBe(newSlug); } + [Fact] public async Task SetSlugAsync_ShouldThrowException_WithExistingSlug() { var newSlug = testData.Page_2_Slug; diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs index d47f139560..cfa54d2e55 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs @@ -127,4 +127,8 @@ public class CmsKitTestData : ISingletonDependency public string MenuItem_3_Name { get; } = "Products"; public string MenuItem_3_Url { get; } = "/products"; + + public string PollName { get; } = "Poll"; + + public string WidgetName { get; } = "CmsPollByCode"; } diff --git a/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20220425082215_Initial.Designer.cs b/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20220623064459_Initial.Designer.cs similarity index 99% rename from modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20220425082215_Initial.Designer.cs rename to modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20220623064459_Initial.Designer.cs index be749fd719..db5f69843f 100644 --- a/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20220425082215_Initial.Designer.cs +++ b/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20220623064459_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace OpenIddict.Demo.Server.Migrations { [DbContext(typeof(ServerDbContext))] - [Migration("20220425082215_Initial")] + [Migration("20220623064459_Initial")] partial class Initial { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -21,7 +21,7 @@ namespace OpenIddict.Demo.Server.Migrations #pragma warning disable 612, 618 modelBuilder .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) - .HasAnnotation("ProductVersion", "6.0.0") + .HasAnnotation("ProductVersion", "6.0.5") .HasAnnotation("Relational:MaxIdentifierLength", 128); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); @@ -336,7 +336,8 @@ namespace OpenIddict.Demo.Server.Migrations .HasColumnName("ExtraProperties"); b.Property("IsActive") - .HasColumnType("bit"); + .HasColumnType("bit") + .HasColumnName("IsActive"); b.Property("IsDeleted") .ValueGeneratedOnAdd() @@ -682,6 +683,9 @@ namespace OpenIddict.Demo.Server.Migrations b.Property("ClientSecret") .HasColumnType("nvarchar(max)"); + b.Property("ClientUri") + .HasColumnType("nvarchar(max)"); + b.Property("ConcurrencyStamp") .IsConcurrencyToken() .HasMaxLength(40) @@ -732,6 +736,9 @@ namespace OpenIddict.Demo.Server.Migrations .HasColumnType("uniqueidentifier") .HasColumnName("LastModifierId"); + b.Property("LogoUri") + .HasColumnType("nvarchar(max)"); + b.Property("Permissions") .HasColumnType("nvarchar(max)"); diff --git a/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20220425082215_Initial.cs b/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20220623064459_Initial.cs similarity index 99% rename from modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20220425082215_Initial.cs rename to modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20220623064459_Initial.cs index 5d8df54c6a..823204d341 100644 --- a/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20220425082215_Initial.cs +++ b/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/20220623064459_Initial.cs @@ -237,6 +237,8 @@ namespace OpenIddict.Demo.Server.Migrations RedirectUris = table.Column(type: "nvarchar(max)", nullable: true), Requirements = table.Column(type: "nvarchar(max)", nullable: true), Type = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: true), + ClientUri = table.Column(type: "nvarchar(max)", nullable: true), + LogoUri = table.Column(type: "nvarchar(max)", nullable: true), ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true), CreationTime = table.Column(type: "datetime2", nullable: false), diff --git a/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/ServerDbContextModelSnapshot.cs b/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/ServerDbContextModelSnapshot.cs index 6ec3ed82f7..0ed7013f11 100644 --- a/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/ServerDbContextModelSnapshot.cs +++ b/modules/openiddict/app/OpenIddict.Demo.Server/Migrations/ServerDbContextModelSnapshot.cs @@ -19,7 +19,7 @@ namespace OpenIddict.Demo.Server.Migrations #pragma warning disable 612, 618 modelBuilder .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) - .HasAnnotation("ProductVersion", "6.0.0") + .HasAnnotation("ProductVersion", "6.0.5") .HasAnnotation("Relational:MaxIdentifierLength", 128); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); @@ -334,7 +334,8 @@ namespace OpenIddict.Demo.Server.Migrations .HasColumnName("ExtraProperties"); b.Property("IsActive") - .HasColumnType("bit"); + .HasColumnType("bit") + .HasColumnName("IsActive"); b.Property("IsDeleted") .ValueGeneratedOnAdd() @@ -680,6 +681,9 @@ namespace OpenIddict.Demo.Server.Migrations b.Property("ClientSecret") .HasColumnType("nvarchar(max)"); + b.Property("ClientUri") + .HasColumnType("nvarchar(max)"); + b.Property("ConcurrencyStamp") .IsConcurrencyToken() .HasMaxLength(40) @@ -730,6 +734,9 @@ namespace OpenIddict.Demo.Server.Migrations .HasColumnType("uniqueidentifier") .HasColumnName("LastModifierId"); + b.Property("LogoUri") + .HasColumnType("nvarchar(max)"); + b.Property("Permissions") .HasColumnType("nvarchar(max)"); diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/LogoutController.cs b/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/LogoutController.cs index 404fd0da14..9f92fa7f23 100644 --- a/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/LogoutController.cs +++ b/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/LogoutController.cs @@ -10,21 +10,12 @@ namespace Volo.Abp.OpenIddict.Controllers; public class LogoutController : AbpOpenIdDictControllerBase { [HttpGet] - public virtual Task GetAsync() + public virtual async Task GetAsync() { - return Task.FromResult(View("Logout")); - } - - [HttpPost] - public virtual async Task PostAsync() - { - if (await HasFormValueAsync("accept")) - { - // Ask ASP.NET Core Identity to delete the local and external cookies created - // when the user agent is redirected from the external identity provider - // after a successful authentication flow (e.g Google or Facebook). - await SignInManager.SignOutAsync(); - } + // Ask ASP.NET Core Identity to delete the local and external cookies created + // when the user agent is redirected from the external identity provider + // after a successful authentication flow (e.g Google or Facebook). + await SignInManager.SignOutAsync(); // Returning a SignOutResult will ask OpenIddict to redirect the user agent // to the post_logout_redirect_uri specified by the client application or to diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Views/Logout/Logout.cshtml b/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Views/Logout/Logout.cshtml deleted file mode 100644 index 6838e92ad5..0000000000 --- a/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Views/Logout/Logout.cshtml +++ /dev/null @@ -1,22 +0,0 @@ -@using Microsoft.Extensions.Primitives -@using Volo.Abp.OpenIddict.Localization -@using Microsoft.AspNetCore.Mvc.Localization -@model AuthorizeViewModel -@inject IHtmlLocalizer L - -
-

@L["LogOut"]

-

@L["AreYouSureYouWantToSignOut"]

- -
- @Html.AntiForgeryToken() - @* Flow the request parameters so they can be received by the LogoutPost action: *@ - @foreach (var parameter in Context.Request.HasFormContentType ? (IEnumerable>) Context.Request.Form : Context.Request.Query) - { - - } - - - - -
diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/el.json b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/el.json index de0b8ec150..28dbc2cb6f 100644 --- a/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/el.json +++ b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/el.json @@ -10,8 +10,6 @@ "DoYouWantToGrantAccessToYourData": "Θέλετε να παραχωρήσετε στον χρήστη {0} πρόσβαση στα δεδομένα σας;", "ScopesRequested": "Ζητούνται πεδία εφαρμογής", "Accept": "Αποδοχή", - "Deny": "Άρνηση", - "LogOut": "Αποσύνδεση", - "AreYouSureYouWantToSignOut": "Είστε βέβαιοι ότι θέλετε να αποσυνδεθείτε;" + "Deny": "Άρνηση" } -} \ No newline at end of file +} diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/en.json b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/en.json index 8bd3a92007..9932b3f97e 100644 --- a/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/en.json +++ b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/en.json @@ -10,8 +10,6 @@ "DoYouWantToGrantAccessToYourData": "Do you want to grant {0} access to your data?", "ScopesRequested": "Scopes requested", "Accept": "Accept", - "Deny": "Deny", - "LogOut": "Log out", - "AreYouSureYouWantToSignOut": "Are you sure you want to sign out?" + "Deny": "Deny" } } diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/pt-BR.json b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/pt-BR.json index ebcf57b00e..2952a0352c 100644 --- a/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/pt-BR.json +++ b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/pt-BR.json @@ -10,8 +10,6 @@ "DoYouWantToGrantAccessToYourData": "Deseja permitir {0} acesse seus dados?", "ScopesRequested": "Escopo solicitado", "Accept": "Aceitar", - "Deny": "Negar", - "LogOut": "Sair", - "AreYouSureYouWantToSignOut": "Tem certeza que deseja sair?" + "Deny": "Negar" } -} \ No newline at end of file +} diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/tr.json b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/tr.json index 39e525e27e..5ad9154636 100644 --- a/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/tr.json +++ b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/tr.json @@ -10,8 +10,6 @@ "DoYouWantToGrantAccessToYourData": "Do you want to grant {0} access to your data?", "ScopesRequested": "İstenen kapsamlar", "Accept": "Kabul etmek", - "Deny": "Reddetmek", - "LogOut": "Çıkış Yap", - "AreYouSureYouWantToSignOut": "Çıkış yapmak istediğinden emin misin?" + "Deny": "Reddetmek" } } diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/zh-Hans.json b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/zh-Hans.json index 3c6fd502b3..9c4577d9c0 100644 --- a/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/zh-Hans.json +++ b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/zh-Hans.json @@ -10,8 +10,6 @@ "DoYouWantToGrantAccessToYourData": "是否要授予 {0} 访问你的数据的权限?", "ScopesRequested": "要求的Scope", "Accept": "同意", - "Deny": "拒绝", - "LogOut": "注销", - "AreYouSureYouWantToSignOut": "你确定要退出吗?" + "Deny": "拒绝" } } diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/zh-Hant.json b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/zh-Hant.json index 5d22654a76..8ecebfc676 100644 --- a/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/zh-Hant.json +++ b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/zh-Hant.json @@ -11,8 +11,6 @@ "DoYouWantToGrantAccessToYourData": "是否要授予 {0} 訪問你的數據的權限?", "ScopesRequested": "要求的Scope", "Accept": "接受", - "Deny": "拒絕", - "LogOut": "註銷", - "AreYouSureYouWantToSignOut": "你確定要退出嗎?" + "Deny": "拒絕" } } diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.AuthServer/Pages/Index.cshtml b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.AuthServer/Pages/Index.cshtml index db9f1f100a..48b2d8de02 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.AuthServer/Pages/Index.cshtml +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.AuthServer/Pages/Index.cshtml @@ -1,34 +1,119 @@ @page +@using Microsoft.AspNetCore.Http.Extensions +@using Microsoft.AspNetCore.Mvc.Localization @using MyCompanyName.MyProjectName.Pages +@using MyCompanyName.MyProjectName.Localization @using Volo.Abp.Users +@using Volo.Abp.AspNetCore.Mvc.UI.Theming +@using Volo.Abp.Ui.Branding @model IndexModel +@inject IHtmlLocalizer L @inject ICurrentUser CurrentUser -@if (CurrentUser.IsAuthenticated) -{ -
+@inject IBrandingProvider BrandingProvider +@inject ITheme Theme + +@{ + Layout = Theme.GetEmptyLayout(); +} + +
+
- - - Logout - - -

@CurrentUser.UserName

-
@CurrentUser.Email
-
- Roles: @CurrentUser.Roles.JoinAsString(", ") -
- Claims:
- @Html.Raw(CurrentUser.GetAllClaims().Select(c => $"{c.Type}={c.Value}").JoinAsString("
")) + + -} + + + + +
+ + + +
+
+ +
+
+ @if (CurrentUser.IsAuthenticated) + { + + @L["Welcome"] @CurrentUser.UserName + + @CurrentUser.Email + + } + else + { + @L["Login"] + } +
-@if (!CurrentUser.IsAuthenticated) -{ -
-

- Login +
+ + +
+ + + + @foreach (var language in Model.Languages) + { + @language.DisplayName + } + + +
+
+ + +
+ + + + @foreach (var application in Model.Applications) + { + + + + + @if (!application.LogoUri.IsNullOrEmpty()) + { +
+ +
+ } + +

@application.DisplayName

+ @application.ClientUri + +
+
+
+ } + +
+
+ + + + +
+ +
-} +
\ No newline at end of file diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.AuthServer/Pages/Index.cshtml.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.AuthServer/Pages/Index.cshtml.cs index e8230ee00c..8e31fb91f1 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.AuthServer/Pages/Index.cshtml.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.AuthServer/Pages/Index.cshtml.cs @@ -1,10 +1,36 @@ +using System.Collections.Generic; +using System.Globalization; +using System.Threading; +using System.Threading.Tasks; using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; +using Volo.Abp.Localization; +using Volo.Abp.OpenIddict.Applications; namespace MyCompanyName.MyProjectName.Pages; public class IndexModel : AbpPageModel { - public void OnGet() + public List Applications { get; protected set; } + + public IReadOnlyList Languages { get; protected set; } + + public string CurrentLanguage { get; protected set; } + + protected IOpenIddictApplicationRepository OpenIdApplicationRepository { get; } + + protected ILanguageProvider LanguageProvider { get; } + + public IndexModel(IOpenIddictApplicationRepository openIdApplicationmRepository, ILanguageProvider languageProvider) { + OpenIdApplicationRepository = openIdApplicationmRepository; + LanguageProvider = languageProvider; + } + + public async Task OnGetAsync() + { + Applications = await OpenIdApplicationRepository.GetListAsync(); + + Languages = await LanguageProvider.GetLanguagesAsync(); + CurrentLanguage = CultureInfo.CurrentCulture.DisplayName; } } diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/OpenIddict/OpenIddictDataSeedContributor.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/OpenIddict/OpenIddictDataSeedContributor.cs index add52f7437..9026bfaeaa 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/OpenIddict/OpenIddictDataSeedContributor.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/OpenIddict/OpenIddictDataSeedContributor.cs @@ -10,6 +10,7 @@ using Volo.Abp; using Volo.Abp.Authorization.Permissions; using Volo.Abp.Data; using Volo.Abp.DependencyInjection; +using Volo.Abp.OpenIddict.Applications; using Volo.Abp.PermissionManagement; using Volo.Abp.Uow; @@ -21,14 +22,14 @@ namespace MyCompanyName.MyProjectName.OpenIddict; public class OpenIddictDataSeedContributor : IDataSeedContributor, ITransientDependency { private readonly IConfiguration _configuration; - private readonly IOpenIddictApplicationManager _applicationManager; + private readonly IAbpApplicationManager _applicationManager; private readonly IOpenIddictScopeManager _scopeManager; private readonly IPermissionDataSeeder _permissionDataSeeder; private readonly IStringLocalizer L; public OpenIddictDataSeedContributor( IConfiguration configuration, - IOpenIddictApplicationManager applicationManager, + IAbpApplicationManager applicationManager, IOpenIddictScopeManager scopeManager, IPermissionDataSeeder permissionDataSeeder, IStringLocalizer l) @@ -98,6 +99,7 @@ public class OpenIddictDataSeedContributor : IDataSeedContributor, ITransientDep }, scopes: commonScopes, redirectUri: $"{webClientRootUrl}signin-oidc", + clientUri: webClientRootUrl, postLogoutRedirectUri: $"{webClientRootUrl}signout-callback-oidc" ); } @@ -122,6 +124,7 @@ public class OpenIddictDataSeedContributor : IDataSeedContributor, ITransientDep }, scopes: commonScopes, redirectUri: consoleAndAngularClientRootUrl, + clientUri: consoleAndAngularClientRootUrl, postLogoutRedirectUri: consoleAndAngularClientRootUrl ); } @@ -144,6 +147,7 @@ public class OpenIddictDataSeedContributor : IDataSeedContributor, ITransientDep }, scopes: commonScopes, redirectUri: $"{blazorRootUrl}/authentication/login-callback", + clientUri: blazorRootUrl, postLogoutRedirectUri: $"{blazorRootUrl}/authentication/logout-callback" ); } @@ -167,6 +171,7 @@ public class OpenIddictDataSeedContributor : IDataSeedContributor, ITransientDep }, scopes: commonScopes, redirectUri: $"{blazorServerTieredRootUrl}signin-oidc", + clientUri: blazorServerTieredRootUrl, postLogoutRedirectUri: $"{blazorServerTieredRootUrl}signout-callback-oidc" ); } @@ -188,7 +193,8 @@ public class OpenIddictDataSeedContributor : IDataSeedContributor, ITransientDep OpenIddictConstants.GrantTypes.AuthorizationCode, }, scopes: commonScopes, - redirectUri: $"{swaggerRootUrl}/swagger/oauth2-redirect.html" + redirectUri: $"{swaggerRootUrl}/swagger/oauth2-redirect.html", + clientUri: swaggerRootUrl ); } } @@ -201,6 +207,7 @@ public class OpenIddictDataSeedContributor : IDataSeedContributor, ITransientDep string secret, List grantTypes, List scopes, + string clientUri = null, string redirectUri = null, string postLogoutRedirectUri = null, List permissions = null) @@ -224,13 +231,14 @@ public class OpenIddictDataSeedContributor : IDataSeedContributor, ITransientDep var client = await _applicationManager.FindByClientIdAsync(name); if (client == null) { - var application = new OpenIddictApplicationDescriptor + var application = new AbpApplicationDescriptor { ClientId = name, Type = type, ClientSecret = secret, ConsentType = consentType, - DisplayName = displayName + DisplayName = displayName, + ClientUri = clientUri, }; Check.NotNullOrEmpty(grantTypes, nameof(grantTypes));