Browse Source

Merge branch 'dev' into update-nx-angular-16

pull/16546/head
Masum ULU 3 years ago
committed by GitHub
parent
commit
03957e7a19
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      docs/en/Startup-Templates/Application.md
  2. 4
      docs/en/docs-nav.json
  3. BIN
      docs/en/images/layered-project-dependencies-blazor-server.png
  4. BIN
      docs/en/images/layered-project-dependencies-blazor-wasm.png
  5. 76
      framework/src/Volo.Abp.Core/Volo/Abp/Threading/SemaphoreSlimExtensions.cs
  6. 28
      framework/test/Volo.Abp.Core.Tests/Volo/Abp/Threading/SemaphoreSlimExtensions_Tests.cs
  7. 2
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogDto.cs
  8. 2
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs
  9. 2
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostListDto.cs
  10. 4
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateBlogDto.cs
  11. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateBlogPostDto.cs
  12. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/UpdateBlogDto.cs
  13. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/UpdateBlogPostDto.cs
  14. 77
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/CmsKitAdminApplicationContractsModule.cs
  15. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Comments/CmsUserDto.cs
  16. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Comments/CommentDto.cs
  17. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Comments/CommentWithAuthorDto.cs
  18. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/GlobalResources/GlobalResourcesDto.cs
  19. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/GlobalResources/GlobalResourcesUpdateDto.cs
  20. 2
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorDto.cs
  21. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuCreateInput.cs
  22. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuItemCreateInput.cs
  23. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuItemUpdateInput.cs
  24. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuUpdateInput.cs
  25. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/CreatePageInputDto.cs
  26. 2
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/PageDto.cs
  27. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/UpdatePageInputDto.cs
  28. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/TagCreateDto.cs
  29. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/TagUpdateDto.cs
  30. 6
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs
  31. 6
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs
  32. 26
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs
  33. 5
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Menus/MenuItemAdminAppService.cs
  34. 4
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs
  35. 4
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/TagAdminAppService.cs
  36. 56
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebAutoMapperProfile.cs
  37. 52
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs
  38. 48
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml
  39. 4
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml.cs
  40. 50
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml
  41. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml.cs
  42. 48
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/CreateModal.cshtml
  43. 9
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/CreateModal.cshtml.cs
  44. 51
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/UpdateModal.cshtml
  45. 7
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/UpdateModal.cshtml.cs
  46. 40
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/CreateModal.cshtml
  47. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/CreateModal.cshtml.cs
  48. 40
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/UpdateModal.cshtml
  49. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/UpdateModal.cshtml.cs
  50. 43
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml
  51. 4
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml.cs
  52. 44
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml
  53. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml.cs
  54. 48
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/CreateModal.cshtml
  55. 4
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/CreateModal.cshtml.cs
  56. 48
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/EditModal.cshtml
  57. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/EditModal.cshtml.cs
  58. 3
      modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Blogs/BlogFeatureCacheItem.cs
  59. 2
      modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Blogs/BlogFeatureDto.cs
  60. 44
      modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/CmsKitCommonApplicationContractsModule.cs
  61. 2
      modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Contents/BlogPostCommonDto.cs
  62. 2
      modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Contents/PageDto.cs
  63. 2
      modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Menus/MenuItemDto.cs
  64. 2
      modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Tags/TagDto.cs
  65. 2
      modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Users/CmsUserDto.cs
  66. 13
      modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/CmsKitCommonApplicationAutoMapperProfile.cs
  67. 97
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/Abp/ObjectExtending/CmsKitModuleExtensionConfiguration.cs
  68. 17
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/Abp/ObjectExtending/CmsKitModuleExtensionConfigurationDictionaryExtensions.cs
  69. 29
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/Abp/ObjectExtending/CmsKitModuleExtensionConsts.cs
  70. 69
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs
  71. 3
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/PageCacheItem.cs
  72. 25
      modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/CmsKitPublicApplicationContractsModule.cs
  73. 3
      modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Comments/CmsUserDto.cs
  74. 3
      modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Comments/CommentDto.cs
  75. 3
      modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Comments/CommentWithDetailsDto.cs
  76. 3
      modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Comments/CreateCommentInput.cs
  77. 3
      modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Comments/UpdateCommentInput.cs
  78. 2
      modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/GlobalResources/GlobalResourceDto.cs
  79. 19
      modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs
  80. 10
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserManager.cs
  81. 15
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs
  82. 10
      npm/ng-packs/packages/oauth/src/lib/guards/oauth.guard.ts
  83. 5
      npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts
  84. 37
      npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts
  85. 19
      npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts

13
docs/en/Startup-Templates/Application.md

@ -261,6 +261,19 @@ You should run the application with the given order:
* Then run the `.HttpApi.Host` since it is used by the `.Web` application. * Then run the `.HttpApi.Host` since it is used by the `.Web` application.
* Finally, you can run the `.Web` project and login to the application (using `admin` as the username and `1q2w3E*` as the password). * Finally, you can run the `.Web` project and login to the application (using `admin` as the username and `1q2w3E*` as the password).
### Blazor UI
If you choose `Blazor` as the UI Framework (using the `-u blazor` or `-u blazor-server` option), the solution will have a project named `.Blazor`. This project contains the Blazor UI application. According to your choice, it will be a Blazor WebAssembly or Blazor Server application. If Blazor WebAssembly is selected, the solution will also have a `.HttpApi.Host`. This project is an ASP.NET Core application that hosts the backend application for the Blazor single page application.
#### .Blazor Project (Server)
The Blazor Server project is similar to the ASP.NET Core MVC project. It replaces `.Web` project with `.Blazor` in the solution structure above. It has the same folder structure and the same application flow. Since it's an ASP.NET Core application, it can contain **.cshtml** files and **.razor** components at the same time. If routing matches a razor component, the Blazor UI will be used. Otherwise, the request will be handled by the MVC framework.
![abp solution structure blazor server](../images/layered-project-dependencies-blazor-server.png)
#### .Blazor Project (WebAssembly)
The Blazor WebAssembly project is a single page application that runs on the browser. You'll see it as `.Blazor` project in the solution. It uses the `.HttpApi.Host` project to communicate with the backend. It can't be used without the backend application. It contains only **.razor** components. It's a pure client-side application. It doesn't have any server-side code. Everything in this layer will be for the client side.
![abp solution structure blazor wasm](../images/layered-project-dependencies-blazor-wasm.png)
### Angular UI ### Angular UI
If you choose `Angular` as the UI framework (using the `-u angular` option), the solution is being separated into two folders: If you choose `Angular` as the UI framework (using the `-u angular` option), the solution is being separated into two folders:

4
docs/en/docs-nav.json

@ -1351,6 +1351,10 @@
"text": "Deployment", "text": "Deployment",
"path": "Deployment/Index.md", "path": "Deployment/Index.md",
"items": [ "items": [
{
"text": "Configuring OpenIddict",
"path": "Deployment/Configuring-OpenIddict.md"
},
{ {
"text": "Configuring for Production", "text": "Configuring for Production",
"path": "Deployment/Configuring-Production.md" "path": "Deployment/Configuring-Production.md"

BIN
docs/en/images/layered-project-dependencies-blazor-server.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

BIN
docs/en/images/layered-project-dependencies-blazor-wasm.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

76
framework/src/Volo.Abp.Core/Volo/Abp/Threading/SemaphoreSlimExtensions.cs

@ -6,40 +6,56 @@ namespace Volo.Abp.Threading;
public static class SemaphoreSlimExtensions public static class SemaphoreSlimExtensions
{ {
public static async Task<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim) public async static Task<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim)
{ {
await semaphoreSlim.WaitAsync(); await semaphoreSlim.WaitAsync();
return GetDispose(semaphoreSlim); return GetDispose(semaphoreSlim);
} }
public static async Task<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim, CancellationToken cancellationToken) public async static Task<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim, CancellationToken cancellationToken)
{ {
await semaphoreSlim.WaitAsync(cancellationToken); await semaphoreSlim.WaitAsync(cancellationToken);
return GetDispose(semaphoreSlim); return GetDispose(semaphoreSlim);
} }
public static async Task<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout) public async static Task<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout)
{ {
await semaphoreSlim.WaitAsync(millisecondsTimeout); if (await semaphoreSlim.WaitAsync(millisecondsTimeout))
return GetDispose(semaphoreSlim); {
return GetDispose(semaphoreSlim);
}
throw new TimeoutException();
} }
public static async Task<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout, CancellationToken cancellationToken) public async static Task<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout, CancellationToken cancellationToken)
{ {
await semaphoreSlim.WaitAsync(millisecondsTimeout, cancellationToken); if (await semaphoreSlim.WaitAsync(millisecondsTimeout, cancellationToken))
return GetDispose(semaphoreSlim); {
return GetDispose(semaphoreSlim);
}
throw new TimeoutException();
} }
public static async Task<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim, TimeSpan timeout) public async static Task<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim, TimeSpan timeout)
{ {
await semaphoreSlim.WaitAsync(timeout); if (await semaphoreSlim.WaitAsync(timeout))
return GetDispose(semaphoreSlim); {
return GetDispose(semaphoreSlim);
}
throw new TimeoutException();
} }
public static async Task<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim, TimeSpan timeout, CancellationToken cancellationToken) public async static Task<IDisposable> LockAsync(this SemaphoreSlim semaphoreSlim, TimeSpan timeout, CancellationToken cancellationToken)
{ {
await semaphoreSlim.WaitAsync(timeout, cancellationToken); if (await semaphoreSlim.WaitAsync(timeout, cancellationToken))
return GetDispose(semaphoreSlim); {
return GetDispose(semaphoreSlim);
}
throw new TimeoutException();
} }
public static IDisposable Lock(this SemaphoreSlim semaphoreSlim) public static IDisposable Lock(this SemaphoreSlim semaphoreSlim)
@ -56,26 +72,42 @@ public static class SemaphoreSlimExtensions
public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout) public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout)
{ {
semaphoreSlim.Wait(millisecondsTimeout); if (semaphoreSlim.Wait(millisecondsTimeout))
return GetDispose(semaphoreSlim); {
return GetDispose(semaphoreSlim);
}
throw new TimeoutException();
} }
public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout, CancellationToken cancellationToken) public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, int millisecondsTimeout, CancellationToken cancellationToken)
{ {
semaphoreSlim.Wait(millisecondsTimeout, cancellationToken); if (semaphoreSlim.Wait(millisecondsTimeout, cancellationToken))
return GetDispose(semaphoreSlim); {
return GetDispose(semaphoreSlim);
}
throw new TimeoutException();
} }
public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, TimeSpan timeout) public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, TimeSpan timeout)
{ {
semaphoreSlim.Wait(timeout); if (semaphoreSlim.Wait(timeout))
return GetDispose(semaphoreSlim); {
return GetDispose(semaphoreSlim);
}
throw new TimeoutException();
} }
public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, TimeSpan timeout, CancellationToken cancellationToken) public static IDisposable Lock(this SemaphoreSlim semaphoreSlim, TimeSpan timeout, CancellationToken cancellationToken)
{ {
semaphoreSlim.Wait(timeout, cancellationToken); if (semaphoreSlim.Wait(timeout, cancellationToken))
return GetDispose(semaphoreSlim); {
return GetDispose(semaphoreSlim);
}
throw new TimeoutException();
} }
private static IDisposable GetDispose(this SemaphoreSlim semaphoreSlim) private static IDisposable GetDispose(this SemaphoreSlim semaphoreSlim)

28
framework/test/Volo.Abp.Core.Tests/Volo/Abp/Threading/SemaphoreSlimExtensions_Tests.cs

@ -0,0 +1,28 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Shouldly;
using Xunit;
namespace Volo.Abp.Threading;
public class SemaphoreSlimExtensions_Tests
{
[Fact]
public async Task LockAsync_Test()
{
var semaphore = new SemaphoreSlim(0, 1);
await Assert.ThrowsAsync<TimeoutException>(async () =>
{
await semaphore.LockAsync(10);
});
semaphore = new SemaphoreSlim(1, 1);
using (await semaphore.LockAsync())
{
semaphore.CurrentCount.ShouldBe(0);
}
semaphore.CurrentCount.ShouldBe(1);
}
}

2
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogDto.cs

@ -5,7 +5,7 @@ using Volo.Abp.Domain.Entities;
namespace Volo.CmsKit.Admin.Blogs; namespace Volo.CmsKit.Admin.Blogs;
[Serializable] [Serializable]
public class BlogDto : EntityDto<Guid>, IHasConcurrencyStamp public class BlogDto : ExtensibleEntityDto<Guid>, IHasConcurrencyStamp
{ {
public string Name { get; set; } public string Name { get; set; }

2
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs

@ -7,7 +7,7 @@ using Volo.CmsKit.Blogs;
namespace Volo.CmsKit.Admin.Blogs; namespace Volo.CmsKit.Admin.Blogs;
[Serializable] [Serializable]
public class BlogPostDto : EntityDto<Guid>, IHasCreationTime, IHasModificationTime, IHasConcurrencyStamp public class BlogPostDto : ExtensibleEntityDto<Guid>, IHasCreationTime, IHasModificationTime, IHasConcurrencyStamp
{ {
public Guid BlogId { get; set; } public Guid BlogId { get; set; }

2
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostListDto.cs

@ -6,7 +6,7 @@ using Volo.CmsKit.Blogs;
namespace Volo.CmsKit.Admin.Blogs; namespace Volo.CmsKit.Admin.Blogs;
[Serializable] [Serializable]
public class BlogPostListDto : EntityDto<Guid>, IHasCreationTime, IHasModificationTime public class BlogPostListDto : ExtensibleEntityDto<Guid>, IHasCreationTime, IHasModificationTime
{ {
public Guid BlogId { get; set; } public Guid BlogId { get; set; }

4
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateBlogDto.cs

@ -1,12 +1,14 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Volo.Abp.Application.Dtos;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation; using Volo.Abp.Validation;
using Volo.CmsKit.Blogs; using Volo.CmsKit.Blogs;
namespace Volo.CmsKit.Admin.Blogs; namespace Volo.CmsKit.Admin.Blogs;
[Serializable] [Serializable]
public class CreateBlogDto public class CreateBlogDto : ExtensibleObject
{ {
[Required] [Required]
[DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxNameLength))] [DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxNameLength))]

3
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateBlogPostDto.cs

@ -1,12 +1,13 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation; using Volo.Abp.Validation;
using Volo.CmsKit.Blogs; using Volo.CmsKit.Blogs;
namespace Volo.CmsKit.Admin.Blogs; namespace Volo.CmsKit.Admin.Blogs;
[Serializable] [Serializable]
public class CreateBlogPostDto public class CreateBlogPostDto: ExtensibleObject
{ {
[Required] [Required]
public Guid BlogId { get; set; } public Guid BlogId { get; set; }

3
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/UpdateBlogDto.cs

@ -1,13 +1,14 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation; using Volo.Abp.Validation;
using Volo.CmsKit.Blogs; using Volo.CmsKit.Blogs;
namespace Volo.CmsKit.Admin.Blogs; namespace Volo.CmsKit.Admin.Blogs;
[Serializable] [Serializable]
public class UpdateBlogDto : IHasConcurrencyStamp public class UpdateBlogDto : ExtensibleObject, IHasConcurrencyStamp
{ {
[Required] [Required]
[DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxNameLength))] [DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxNameLength))]

3
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/UpdateBlogPostDto.cs

@ -1,13 +1,14 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation; using Volo.Abp.Validation;
using Volo.CmsKit.Blogs; using Volo.CmsKit.Blogs;
namespace Volo.CmsKit.Admin.Blogs; namespace Volo.CmsKit.Admin.Blogs;
[Serializable] [Serializable]
public class UpdateBlogPostDto : IHasConcurrencyStamp public class UpdateBlogPostDto : ExtensibleObject, IHasConcurrencyStamp
{ {
[Required] [Required]
[DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxTitleLength))] [DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxTitleLength))]

77
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/CmsKitAdminApplicationContractsModule.cs

@ -1,11 +1,84 @@
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.ObjectExtending;
using Volo.Abp.ObjectExtending.Modularity;
using Volo.Abp.Threading;
using Volo.CmsKit.Admin.Blogs;
using Volo.CmsKit.Admin.Comments;
using Volo.CmsKit.Admin.GlobalResources;
using Volo.CmsKit.Admin.MediaDescriptors;
using Volo.CmsKit.Admin.Menus;
using Volo.CmsKit.Admin.Pages;
using Volo.CmsKit.Admin.Tags;
namespace Volo.CmsKit.Admin; namespace Volo.CmsKit.Admin;
[DependsOn( [DependsOn(
typeof(CmsKitCommonApplicationContractsModule) typeof(CmsKitCommonApplicationContractsModule)
)] )]
public class CmsKitAdminApplicationContractsModule : AbpModule public class CmsKitAdminApplicationContractsModule : AbpModule
{ {
private readonly static OneTimeRunner OneTimeRunner = new OneTimeRunner();
} public override void PostConfigureServices(ServiceConfigurationContext context)
{
OneTimeRunner.Run(() =>
{
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.Blog,
getApiTypes: new[] { typeof(BlogDto) },
createApiTypes: new[] { typeof(CreateBlogDto) },
updateApiTypes: new[] { typeof(UpdateBlogDto) }
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.BlogPost,
getApiTypes: new[] { typeof(BlogPostDto), typeof(BlogPostListDto) },
createApiTypes: new[] { typeof(CreateBlogPostDto) },
updateApiTypes: new[] { typeof(UpdateBlogPostDto) }
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.Comment,
getApiTypes: new[] { typeof(CommentDto), typeof(CommentWithAuthorDto) }
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.GlobalResource,
getApiTypes: new[] { typeof(GlobalResourcesDto) },
updateApiTypes: new[] { typeof(GlobalResourcesUpdateDto) }
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.MediaDescriptor,
getApiTypes: new[] { typeof(MediaDescriptorDto) }
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.MenuItem,
createApiTypes: new[] { typeof(MenuCreateInput) , typeof(MenuItemCreateInput)},
updateApiTypes: new[] { typeof(MenuUpdateInput) , typeof(MenuItemUpdateInput)}
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.Page,
getApiTypes: new[] { typeof(PageDto) },
createApiTypes: new[] { typeof(CreatePageInputDto) },
updateApiTypes: new[] { typeof(UpdatePageInputDto) }
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.Tag,
createApiTypes: new[] { typeof(TagCreateDto) },
updateApiTypes: new[] { typeof(TagUpdateDto) }
);
});
}
}

3
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Comments/CmsUserDto.cs

@ -1,9 +1,10 @@
using System; using System;
using Volo.Abp.ObjectExtending;
namespace Volo.CmsKit.Admin.Comments; namespace Volo.CmsKit.Admin.Comments;
[Serializable] [Serializable]
public class CmsUserDto public class CmsUserDto : ExtensibleObject
{ {
public Guid Id { get; set; } public Guid Id { get; set; }

3
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Comments/CommentDto.cs

@ -1,9 +1,10 @@
using System; using System;
using Volo.Abp.ObjectExtending;
namespace Volo.CmsKit.Admin.Comments; namespace Volo.CmsKit.Admin.Comments;
[Serializable] [Serializable]
public class CommentDto public class CommentDto : ExtensibleObject
{ {
public Guid Id { get; set; } public Guid Id { get; set; }

3
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Comments/CommentWithAuthorDto.cs

@ -1,9 +1,10 @@
using System; using System;
using Volo.Abp.ObjectExtending;
namespace Volo.CmsKit.Admin.Comments; namespace Volo.CmsKit.Admin.Comments;
[Serializable] [Serializable]
public class CommentWithAuthorDto public class CommentWithAuthorDto : ExtensibleObject
{ {
public Guid Id { get; set; } public Guid Id { get; set; }

3
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/GlobalResources/GlobalResourcesDto.cs

@ -1,9 +1,10 @@
using System; using System;
using Volo.Abp.ObjectExtending;
namespace Volo.CmsKit.Admin.GlobalResources; namespace Volo.CmsKit.Admin.GlobalResources;
[Serializable] [Serializable]
public class GlobalResourcesDto public class GlobalResourcesDto : ExtensibleObject
{ {
public string StyleContent { get; set; } public string StyleContent { get; set; }

3
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/GlobalResources/GlobalResourcesUpdateDto.cs

@ -1,9 +1,10 @@
using System; using System;
using Volo.Abp.ObjectExtending;
namespace Volo.CmsKit.Admin.GlobalResources; namespace Volo.CmsKit.Admin.GlobalResources;
[Serializable] [Serializable]
public class GlobalResourcesUpdateDto public class GlobalResourcesUpdateDto : ExtensibleObject
{ {
public string Style { get; set; } public string Style { get; set; }

2
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorDto.cs

@ -4,7 +4,7 @@ using Volo.Abp.Application.Dtos;
namespace Volo.CmsKit.Admin.MediaDescriptors; namespace Volo.CmsKit.Admin.MediaDescriptors;
[Serializable] [Serializable]
public class MediaDescriptorDto : EntityDto<Guid> public class MediaDescriptorDto : ExtensibleEntityDto<Guid>
{ {
public string Name { get; set; } public string Name { get; set; }

3
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuCreateInput.cs

@ -3,11 +3,12 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.ObjectExtending;
namespace Volo.CmsKit.Admin.Menus; namespace Volo.CmsKit.Admin.Menus;
[Serializable] [Serializable]
public class MenuCreateInput public class MenuCreateInput : ExtensibleObject
{ {
public string Name { get; set; } public string Name { get; set; }
} }

3
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuItemCreateInput.cs

@ -1,10 +1,11 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Volo.Abp.ObjectExtending;
namespace Volo.CmsKit.Admin.Menus; namespace Volo.CmsKit.Admin.Menus;
[Serializable] [Serializable]
public class MenuItemCreateInput public class MenuItemCreateInput : ExtensibleObject
{ {
public Guid? ParentId { get; set; } public Guid? ParentId { get; set; }

3
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuItemUpdateInput.cs

@ -1,11 +1,12 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.ObjectExtending;
namespace Volo.CmsKit.Admin.Menus; namespace Volo.CmsKit.Admin.Menus;
[Serializable] [Serializable]
public class MenuItemUpdateInput : IHasConcurrencyStamp public class MenuItemUpdateInput : ExtensibleObject, IHasConcurrencyStamp
{ {
[Required] [Required]
public string DisplayName { get; set; } public string DisplayName { get; set; }

3
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuUpdateInput.cs

@ -3,11 +3,12 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.ObjectExtending;
namespace Volo.CmsKit.Admin.Menus; namespace Volo.CmsKit.Admin.Menus;
[Serializable] [Serializable]
public class MenuUpdateInput public class MenuUpdateInput : ExtensibleObject
{ {
public string Name { get; set; } public string Name { get; set; }
} }

3
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/CreatePageInputDto.cs

@ -1,12 +1,13 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation; using Volo.Abp.Validation;
using Volo.CmsKit.Pages; using Volo.CmsKit.Pages;
namespace Volo.CmsKit.Admin.Pages; namespace Volo.CmsKit.Admin.Pages;
[Serializable] [Serializable]
public class CreatePageInputDto public class CreatePageInputDto: ExtensibleObject
{ {
[Required] [Required]
[DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxTitleLength))] [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxTitleLength))]

2
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/PageDto.cs

@ -5,7 +5,7 @@ using Volo.Abp.Domain.Entities;
namespace Volo.CmsKit.Admin.Pages; namespace Volo.CmsKit.Admin.Pages;
[Serializable] [Serializable]
public class PageDto : AuditedEntityDto<Guid>, IHasConcurrencyStamp public class PageDto : ExtensibleAuditedEntityDto<Guid>, IHasConcurrencyStamp
{ {
public string Title { get; set; } public string Title { get; set; }

3
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/UpdatePageInputDto.cs

@ -1,13 +1,14 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation; using Volo.Abp.Validation;
using Volo.CmsKit.Pages; using Volo.CmsKit.Pages;
namespace Volo.CmsKit.Admin.Pages; namespace Volo.CmsKit.Admin.Pages;
[Serializable] [Serializable]
public class UpdatePageInputDto : IHasConcurrencyStamp public class UpdatePageInputDto : ExtensibleObject, IHasConcurrencyStamp
{ {
[Required] [Required]
[DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxTitleLength))] [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxTitleLength))]

3
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/TagCreateDto.cs

@ -1,12 +1,13 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation; using Volo.Abp.Validation;
using Volo.CmsKit.Tags; using Volo.CmsKit.Tags;
namespace Volo.CmsKit.Admin.Tags; namespace Volo.CmsKit.Admin.Tags;
[Serializable] [Serializable]
public class TagCreateDto public class TagCreateDto : ExtensibleObject
{ {
[Required] [Required]
[DynamicMaxLength(typeof(TagConsts), nameof(TagConsts.MaxEntityTypeLength))] [DynamicMaxLength(typeof(TagConsts), nameof(TagConsts.MaxEntityTypeLength))]

3
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/TagUpdateDto.cs

@ -1,13 +1,14 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation; using Volo.Abp.Validation;
using Volo.CmsKit.Tags; using Volo.CmsKit.Tags;
namespace Volo.CmsKit.Admin.Tags; namespace Volo.CmsKit.Admin.Tags;
[Serializable] [Serializable]
public class TagUpdateDto : IHasConcurrencyStamp public class TagUpdateDto : ExtensibleObject, IHasConcurrencyStamp
{ {
[Required] [Required]
[DynamicMaxLength(typeof(TagConsts), nameof(TagConsts.MaxNameLength))] [DynamicMaxLength(typeof(TagConsts), nameof(TagConsts.MaxNameLength))]

6
modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs

@ -6,6 +6,7 @@ using Volo.Abp.Application.Dtos;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.Features; using Volo.Abp.Features;
using Volo.Abp.GlobalFeatures; using Volo.Abp.GlobalFeatures;
using Volo.Abp.ObjectExtending;
using Volo.CmsKit.Blogs; using Volo.CmsKit.Blogs;
using Volo.CmsKit.Features; using Volo.CmsKit.Features;
using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.GlobalFeatures;
@ -56,7 +57,8 @@ public class BlogAdminAppService : CmsKitAdminAppServiceBase, IBlogAdminAppServi
public virtual async Task<BlogDto> CreateAsync(CreateBlogDto input) public virtual async Task<BlogDto> CreateAsync(CreateBlogDto input)
{ {
var blog = await BlogManager.CreateAsync(input.Name, input.Slug); var blog = await BlogManager.CreateAsync(input.Name, input.Slug);
input.MapExtraPropertiesTo(blog);
await BlogRepository.InsertAsync(blog, autoSave: true); await BlogRepository.InsertAsync(blog, autoSave: true);
await BlogFeatureManager.SetDefaultsAsync(blog.Id); await BlogFeatureManager.SetDefaultsAsync(blog.Id);
@ -70,7 +72,7 @@ public class BlogAdminAppService : CmsKitAdminAppServiceBase, IBlogAdminAppServi
var blog = await BlogRepository.GetAsync(id); var blog = await BlogRepository.GetAsync(id);
blog = await BlogManager.UpdateAsync(blog, input.Name, input.Slug); blog = await BlogManager.UpdateAsync(blog, input.Name, input.Slug);
input.MapExtraPropertiesTo(blog);
blog.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp); blog.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp);
await BlogRepository.UpdateAsync(blog); await BlogRepository.UpdateAsync(blog);

6
modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs

@ -6,6 +6,7 @@ using Volo.Abp.Application.Dtos;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.Features; using Volo.Abp.Features;
using Volo.Abp.GlobalFeatures; using Volo.Abp.GlobalFeatures;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Users; using Volo.Abp.Users;
using Volo.CmsKit.Admin.MediaDescriptors; using Volo.CmsKit.Admin.MediaDescriptors;
using Volo.CmsKit.Blogs; using Volo.CmsKit.Blogs;
@ -59,7 +60,7 @@ public class BlogPostAdminAppService : CmsKitAppServiceBase, IBlogPostAdminAppSe
input.Content, input.Content,
input.CoverImageMediaId input.CoverImageMediaId
); );
input.MapExtraPropertiesTo(blogPost);
await BlogPostRepository.InsertAsync(blogPost); await BlogPostRepository.InsertAsync(blogPost);
return ObjectMapper.Map<BlogPost, BlogPostDto>(blogPost); return ObjectMapper.Map<BlogPost, BlogPostDto>(blogPost);
@ -85,7 +86,8 @@ public class BlogPostAdminAppService : CmsKitAppServiceBase, IBlogPostAdminAppSe
{ {
await BlogPostManager.SetSlugUrlAsync(blogPost, input.Slug); await BlogPostManager.SetSlugUrlAsync(blogPost, input.Slug);
} }
input.MapExtraPropertiesTo(blogPost);
await BlogPostRepository.UpdateAsync(blogPost); await BlogPostRepository.UpdateAsync(blogPost);
return ObjectMapper.Map<BlogPost, BlogPostDto>(blogPost); return ObjectMapper.Map<BlogPost, BlogPostDto>(blogPost);

26
modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs

@ -20,29 +20,31 @@ public class CmsKitAdminApplicationAutoMapperProfile : Profile
{ {
public CmsKitAdminApplicationAutoMapperProfile() public CmsKitAdminApplicationAutoMapperProfile()
{ {
CreateMap<CmsUser, Comments.CmsUserDto>(); CreateMap<CmsUser, Comments.CmsUserDto>().MapExtraProperties();
CreateMap<Comment, CommentDto>(); CreateMap<Comment, CommentDto>().MapExtraProperties();
CreateMap<Comment, CommentWithAuthorDto>() CreateMap<Comment, CommentWithAuthorDto>()
.Ignore(x => x.Author); .Ignore(x => x.Author)
.MapExtraProperties();
CreateMap<Page, PageDto>(); CreateMap<Page, PageDto>().MapExtraProperties();
CreateMap<Page, PageLookupDto>(); CreateMap<Page, PageLookupDto>();
CreateMap<BlogPost, BlogPostDto>(MemberList.Destination); CreateMap<BlogPost, BlogPostDto>(MemberList.Destination).MapExtraProperties();
CreateMap<BlogPost, BlogPostListDto>() CreateMap<BlogPost, BlogPostListDto>()
.Ignore(d => d.BlogName); .Ignore(d => d.BlogName)
CreateMap<CreateBlogPostDto, BlogPost>(MemberList.Source); .MapExtraProperties();
CreateMap<UpdateBlogPostDto, BlogPost>(MemberList.Source); CreateMap<CreateBlogPostDto, BlogPost>(MemberList.Source).MapExtraProperties();
CreateMap<UpdateBlogPostDto, BlogPost>(MemberList.Source).MapExtraProperties();
CreateMap<Blog, BlogDto>(); CreateMap<Blog, BlogDto>().MapExtraProperties();
CreateMap<TagEntityTypeDefiniton, TagDefinitionDto>(MemberList.Destination); CreateMap<TagEntityTypeDefiniton, TagDefinitionDto>(MemberList.Destination);
CreateMap<Tag, TagDto>(); CreateMap<Tag, TagDto>().MapExtraProperties();
CreateMap<MediaDescriptor, MediaDescriptorDto>(); CreateMap<MediaDescriptor, MediaDescriptorDto>().MapExtraProperties();
CreateMap<MenuItem, MenuItemDto>(); CreateMap<MenuItem, MenuItemDto>().MapExtraProperties();
} }
} }

5
modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Menus/MenuItemAdminAppService.cs

@ -6,6 +6,7 @@ using Volo.Abp.Application.Dtos;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.Features; using Volo.Abp.Features;
using Volo.Abp.GlobalFeatures; using Volo.Abp.GlobalFeatures;
using Volo.Abp.ObjectExtending;
using Volo.CmsKit.Features; using Volo.CmsKit.Features;
using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Menus; using Volo.CmsKit.Menus;
@ -69,7 +70,7 @@ public class MenuItemAdminAppService : CmsKitAdminAppServiceBase, IMenuItemAdmin
{ {
MenuManager.SetPageUrl(menuItem, await PageRepository.GetAsync(input.PageId.Value)); MenuManager.SetPageUrl(menuItem, await PageRepository.GetAsync(input.PageId.Value));
} }
input.MapExtraPropertiesTo(menuItem);
await MenuItemRepository.InsertAsync(menuItem); await MenuItemRepository.InsertAsync(menuItem);
return ObjectMapper.Map<MenuItem, MenuItemDto>(menuItem); return ObjectMapper.Map<MenuItem, MenuItemDto>(menuItem);
@ -96,7 +97,7 @@ public class MenuItemAdminAppService : CmsKitAdminAppServiceBase, IMenuItemAdmin
menuItem.ElementId = input.ElementId; menuItem.ElementId = input.ElementId;
menuItem.CssClass = input.CssClass; menuItem.CssClass = input.CssClass;
menuItem.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp); menuItem.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp);
input.MapExtraPropertiesTo(menuItem);
await MenuItemRepository.UpdateAsync(menuItem); await MenuItemRepository.UpdateAsync(menuItem);
return ObjectMapper.Map<MenuItem, MenuItemDto>(menuItem); return ObjectMapper.Map<MenuItem, MenuItemDto>(menuItem);

4
modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs

@ -7,6 +7,7 @@ using Volo.Abp.Caching;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.Features; using Volo.Abp.Features;
using Volo.Abp.GlobalFeatures; using Volo.Abp.GlobalFeatures;
using Volo.Abp.ObjectExtending;
using Volo.CmsKit.Features; using Volo.CmsKit.Features;
using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Pages; using Volo.CmsKit.Pages;
@ -62,7 +63,7 @@ public class PageAdminAppService : CmsKitAdminAppServiceBase, IPageAdminAppServi
public virtual async Task<PageDto> CreateAsync(CreatePageInputDto input) public virtual async Task<PageDto> CreateAsync(CreatePageInputDto input)
{ {
var page = await PageManager.CreateAsync(input.Title, input.Slug, input.Content, input.Script, input.Style); var page = await PageManager.CreateAsync(input.Title, input.Slug, input.Content, input.Script, input.Style);
input.MapExtraPropertiesTo(page);
await PageRepository.InsertAsync(page); await PageRepository.InsertAsync(page);
return ObjectMapper.Map<Page, PageDto>(page); return ObjectMapper.Map<Page, PageDto>(page);
@ -84,6 +85,7 @@ public class PageAdminAppService : CmsKitAdminAppServiceBase, IPageAdminAppServi
page.SetScript(input.Script); page.SetScript(input.Script);
page.SetStyle(input.Style); page.SetStyle(input.Style);
page.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp); page.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp);
input.MapExtraPropertiesTo(page);
await PageRepository.UpdateAsync(page); await PageRepository.UpdateAsync(page);

4
modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/TagAdminAppService.cs

@ -8,6 +8,7 @@ using Volo.Abp.Application.Dtos;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.Features; using Volo.Abp.Features;
using Volo.Abp.GlobalFeatures; using Volo.Abp.GlobalFeatures;
using Volo.Abp.ObjectExtending;
using Volo.CmsKit.Features; using Volo.CmsKit.Features;
using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Permissions; using Volo.CmsKit.Permissions;
@ -44,7 +45,7 @@ public class TagAdminAppService : CmsKitAppServiceBase, ITagAdminAppService
GuidGenerator.Create(), GuidGenerator.Create(),
input.EntityType, input.EntityType,
input.Name); input.Name);
input.MapExtraPropertiesTo(tag);
await Repository.InsertAsync(tag); await Repository.InsertAsync(tag);
return ObjectMapper.Map<Tag, TagDto>(tag); return ObjectMapper.Map<Tag, TagDto>(tag);
@ -56,6 +57,7 @@ public class TagAdminAppService : CmsKitAppServiceBase, ITagAdminAppService
var tag = await TagManager.UpdateAsync( var tag = await TagManager.UpdateAsync(
id, id,
input.Name); input.Name);
input.MapExtraPropertiesTo(tag);
tag.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp); tag.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp);

56
modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebAutoMapperProfile.cs

@ -0,0 +1,56 @@
using AutoMapper;
using Volo.CmsKit.Admin.Blogs;
using Volo.CmsKit.Admin.Menus;
using Volo.CmsKit.Admin.Pages;
using Volo.CmsKit.Admin.Tags;
using Volo.CmsKit.Menus;
using Volo.CmsKit.Tags;
namespace Volo.CmsKit.Admin.Web;
public class CmsKitAdminWebAutoMapperProfile : Profile
{
public CmsKitAdminWebAutoMapperProfile()
{
CreateBlogPostMappings();
CreateBlogMappings();
CreateMenuMappings();
CreatePageMappings();
CreateTagMappings();
}
protected virtual void CreateBlogPostMappings()
{
CreateMap<Volo.CmsKit.Admin.Web.Pages.CmsKit.BlogPosts.CreateModel.CreateBlogPostViewModel, CreateBlogPostDto>().MapExtraProperties();
CreateMap<Volo.CmsKit.Admin.Web.Pages.CmsKit.BlogPosts.UpdateModel.UpdateBlogPostViewModel, UpdateBlogPostDto>().MapExtraProperties();
CreateMap<BlogPostDto, Volo.CmsKit.Admin.Web.Pages.CmsKit.BlogPosts.UpdateModel.UpdateBlogPostViewModel>().MapExtraProperties();
}
protected virtual void CreateBlogMappings()
{
CreateMap<Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs.CreateModalModel.CreateBlogViewModel, CreateBlogDto>().MapExtraProperties();
CreateMap<Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs.UpdateModalModel.UpdateBlogViewModel, UpdateBlogDto>().MapExtraProperties();
CreateMap<BlogDto, Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs.UpdateModalModel.UpdateBlogViewModel>().MapExtraProperties();
}
protected virtual void CreateMenuMappings()
{
CreateMap<Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems.CreateModalModel.MenuItemCreateViewModel, MenuItemCreateInput>().MapExtraProperties();
CreateMap<Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems.UpdateModalModel.MenuItemUpdateViewModel, MenuItemUpdateInput>().MapExtraProperties();
CreateMap<MenuItemDto, Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems.UpdateModalModel.MenuItemUpdateViewModel>().MapExtraProperties();
}
protected virtual void CreatePageMappings()
{
CreateMap<Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages.CreateModel.CreatePageViewModel, CreatePageInputDto>().MapExtraProperties();
CreateMap<Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages.UpdateModel.UpdatePageViewModel, UpdatePageInputDto>().MapExtraProperties();
CreateMap<PageDto, Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages.UpdateModel.UpdatePageViewModel>().MapExtraProperties();
}
protected virtual void CreateTagMappings()
{
CreateMap<Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags.CreateModalModel.TagCreateViewModel, TagCreateDto>().MapExtraProperties();
CreateMap<Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags.EditModalModel.TagEditViewModel, TagUpdateDto>().MapExtraProperties();
CreateMap<TagDto, Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags.EditModalModel.TagEditViewModel>().MapExtraProperties();
}
}

52
modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs

@ -7,6 +7,9 @@ using Volo.Abp.AutoMapper;
using Volo.Abp.Http.ProxyScripting.Generators.JQuery; using Volo.Abp.Http.ProxyScripting.Generators.JQuery;
using Volo.Abp.Localization; using Volo.Abp.Localization;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.ObjectExtending;
using Volo.Abp.ObjectExtending.Modularity;
using Volo.Abp.Threading;
using Volo.Abp.UI.Navigation; using Volo.Abp.UI.Navigation;
using Volo.Abp.VirtualFileSystem; using Volo.Abp.VirtualFileSystem;
using Volo.CmsKit.Admin.MediaDescriptors; using Volo.CmsKit.Admin.MediaDescriptors;
@ -23,6 +26,8 @@ namespace Volo.CmsKit.Admin.Web;
)] )]
public class CmsKitAdminWebModule : AbpModule public class CmsKitAdminWebModule : AbpModule
{ {
private readonly static OneTimeRunner OneTimeRunner = new OneTimeRunner();
public override void PreConfigureServices(ServiceConfigurationContext context) public override void PreConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options => context.Services.PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options =>
@ -169,4 +174,51 @@ public class CmsKitAdminWebModule : AbpModule
options.ConventionalControllers.FormBodyBindingIgnoredTypes.Add(typeof(CreateMediaInputWithStream)); options.ConventionalControllers.FormBodyBindingIgnoredTypes.Add(typeof(CreateMediaInputWithStream));
}); });
} }
public override void PostConfigureServices(ServiceConfigurationContext context)
{
OneTimeRunner.Run(() =>
{
ModuleExtensionConfigurationHelper
.ApplyEntityConfigurationToUi(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.Blog,
createFormTypes: new[] { typeof(Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs.CreateModalModel.CreateBlogViewModel) },
editFormTypes: new[] { typeof(Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs.UpdateModalModel.UpdateBlogViewModel) }
);
ModuleExtensionConfigurationHelper
.ApplyEntityConfigurationToUi(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.BlogPost,
createFormTypes: new[] { typeof(Volo.CmsKit.Admin.Web.Pages.CmsKit.BlogPosts.CreateModel.CreateBlogPostViewModel) },
editFormTypes: new[] { typeof(Volo.CmsKit.Admin.Web.Pages.CmsKit.BlogPosts.UpdateModel.UpdateBlogPostViewModel) }
);
ModuleExtensionConfigurationHelper
.ApplyEntityConfigurationToUi(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.MenuItem,
createFormTypes: new[] { typeof(Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems.CreateModalModel.MenuItemCreateViewModel) },
editFormTypes: new[] { typeof(Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems.UpdateModalModel.MenuItemUpdateViewModel) }
);
ModuleExtensionConfigurationHelper
.ApplyEntityConfigurationToUi(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.Page,
createFormTypes: new[] { typeof(Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages.CreateModel.CreatePageViewModel) },
editFormTypes: new[] { typeof(Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages.UpdateModel.UpdatePageViewModel) }
);
ModuleExtensionConfigurationHelper
.ApplyEntityConfigurationToUi(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.Tag,
createFormTypes: new[] { typeof(Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags.CreateModalModel.TagCreateViewModel) },
editFormTypes: new[] { typeof(Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags.EditModalModel.TagEditViewModel) }
);
});
}
} }

48
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml

@ -2,6 +2,12 @@
@using System.Globalization @using System.Globalization
@using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Mvc.TagHelpers
@using Microsoft.Extensions.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
@using Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers
@using Volo.Abp.AspNetCore.Mvc.UI.Packages.TuiEditor @using Volo.Abp.AspNetCore.Mvc.UI.Packages.TuiEditor
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageToolbar @using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageToolbar
@using Volo.CmsKit.Admin.Web.Pages @using Volo.CmsKit.Admin.Web.Pages
@ -11,10 +17,14 @@
@using Volo.CmsKit.Blogs @using Volo.CmsKit.Blogs
@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Uppy @using Volo.Abp.AspNetCore.Mvc.UI.Packages.Uppy
@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Slugify @using Volo.Abp.AspNetCore.Mvc.UI.Packages.Slugify
@using Volo.Abp.Data
@using Volo.Abp.Localization
@using Volo.Abp.ObjectExtending
@using Volo.CmsKit.Permissions @using Volo.CmsKit.Permissions
@inherits CmsKitAdminPageBase @inherits CmsKitAdminPageBase
@inject IAuthorizationService AuthorizationService @inject IAuthorizationService AuthorizationService
@inject IStringLocalizerFactory StringLocalizerFactory
@model CreateModel @model CreateModel
@{ @{
@ -54,7 +64,7 @@
<input type="file" id="BlogPostCoverImage" class="form-control" /> <input type="file" id="BlogPostCoverImage" class="form-control" />
</div> </div>
<abp-dynamic-form abp-model="ViewModel" asp-page="/CmsKit/BlogPosts/Create" id="form-blog-post-create"> <form asp-page="/CmsKit/BlogPosts/Create" id="form-blog-post-create">
<div class="mb-3"> <div class="mb-3">
<label class="form-label" asp-for="ViewModel.BlogId"></label> <label class="form-label" asp-for="ViewModel.BlogId"></label>
<select asp-for="ViewModel.BlogId" id="BlogSelectionSelect" class="form-control"></select> <select asp-for="ViewModel.BlogId" id="BlogSelectionSelect" class="form-control"></select>
@ -64,8 +74,8 @@
<abp-input asp-for="ViewModel.Title" /> <abp-input asp-for="ViewModel.Title" />
<abp-input asp-for="ViewModel.Slug" /> <abp-input asp-for="ViewModel.Slug" />
<abp-form-content /> <abp-input asp-for="ViewModel.ShortDescription" />
<div class="content-editor cms-kit-editor" <div class="content-editor cms-kit-editor"
id="ContentEditor" id="ContentEditor"
@ -73,7 +83,37 @@
data-language="@(CultureInfo.CurrentUICulture.TwoLetterISOLanguageName)"> data-language="@(CultureInfo.CurrentUICulture.TwoLetterISOLanguageName)">
</div> </div>
<input type="hidden" id="ViewModel_Status" name="ViewModel.Status" value="" class="form-control "> <input type="hidden" id="ViewModel_Status" name="ViewModel.Status" value="" class="form-control ">
</abp-dynamic-form> @foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties<CreateModel.CreateBlogPostViewModel>())
{
if (!propertyInfo.Name.EndsWith("_Text"))
{
if (propertyInfo.Type.IsEnum || !propertyInfo.Lookup.Url.IsNullOrEmpty())
{
if (propertyInfo.Type.IsEnum)
{
Model.ViewModel.ExtraProperties.ToEnum(propertyInfo.Name, propertyInfo.Type);
}
<abp-select asp-for="ViewModel.ExtraProperties[propertyInfo.Name]"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
autocomplete-api-url="@propertyInfo.Lookup.Url"
autocomplete-selected-item-name="@Model.ViewModel.GetProperty(propertyInfo.Name+"_Text")"
autocomplete-selected-item-value="@Model.ViewModel.GetProperty(propertyInfo.Name)"
autocomplete-filter-param-name="@propertyInfo.Lookup.FilterParamName"
autocomplete-items-property-name="@propertyInfo.Lookup.ResultListPropertyName"
autocomplete-display-property-name="@propertyInfo.Lookup.DisplayPropertyName"
autocomplete-value-property-name="@propertyInfo.Lookup.ValuePropertyName"></abp-select>
}
else
{
<abp-input type="@propertyInfo.GetInputType()"
asp-for="ViewModel.ExtraProperties[propertyInfo.Name]"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
asp-format="@propertyInfo.GetInputFormatOrNull()"
value="@propertyInfo.GetInputValueOrNull(Model.ViewModel.GetProperty(propertyInfo.Name))" />
}
}
}
</form>
<div id="blog-post-tags-wrapper"> <div id="blog-post-tags-wrapper">

4
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Create.cshtml.cs

@ -8,6 +8,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation; using Volo.Abp.Validation;
using Volo.CmsKit.Admin.Blogs; using Volo.CmsKit.Admin.Blogs;
using Volo.CmsKit.Blogs; using Volo.CmsKit.Blogs;
@ -25,6 +26,7 @@ public class CreateModel : CmsKitAdminPageModel
IBlogPostAdminAppService blogPostAdminAppService) IBlogPostAdminAppService blogPostAdminAppService)
{ {
BlogPostAdminAppService = blogPostAdminAppService; BlogPostAdminAppService = blogPostAdminAppService;
ViewModel = new CreateBlogPostViewModel();
} }
public async Task<IActionResult> OnPostAsync() public async Task<IActionResult> OnPostAsync()
@ -49,7 +51,7 @@ public class CreateModel : CmsKitAdminPageModel
} }
[AutoMap(typeof(CreateBlogPostDto), ReverseMap = true)] [AutoMap(typeof(CreateBlogPostDto), ReverseMap = true)]
public class CreateBlogPostViewModel public class CreateBlogPostViewModel : ExtensibleObject
{ {
[Required] [Required]
[DynamicFormIgnore] [DynamicFormIgnore]

50
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml

@ -1,6 +1,12 @@
@page "{Id}" @page "{Id}"
@using System.Globalization @using System.Globalization
@using Microsoft.AspNetCore.Mvc.TagHelpers
@using Microsoft.Extensions.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
@using Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers
@using Volo.Abp.AspNetCore.Mvc.UI.Packages.TuiEditor @using Volo.Abp.AspNetCore.Mvc.UI.Packages.TuiEditor
@using Volo.CmsKit.Blogs @using Volo.CmsKit.Blogs
@using Volo.CmsKit.Admin.Web.Pages @using Volo.CmsKit.Admin.Web.Pages
@ -10,6 +16,10 @@
@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags.Components.TagEditor @using Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags.Components.TagEditor
@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Uppy @using Volo.Abp.AspNetCore.Mvc.UI.Packages.Uppy
@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Slugify @using Volo.Abp.AspNetCore.Mvc.UI.Packages.Slugify
@using Volo.Abp.Data
@using Volo.Abp.Localization
@using Volo.Abp.ObjectExtending
@inject IStringLocalizerFactory StringLocalizerFactory
@inherits CmsKitAdminPageBase @inherits CmsKitAdminPageBase
@ -62,14 +72,15 @@
<input type="file" id="BlogPostCoverImage" class="form-control"/> <input type="file" id="BlogPostCoverImage" class="form-control"/>
</div> </div>
<abp-dynamic-form abp-model="ViewModel" asp-page="/CmsKit/BlogPosts/Update" id="form-blog-post-update"> <form asp-page="/CmsKit/BlogPosts/Update" id="form-blog-post-update">
<abp-input asp-for="Id" /> <abp-input asp-for="Id" />
<abp-input asp-for="ViewModel.ConcurrencyStamp" hidden />
<abp-input asp-for="ViewModel.Title" /> <abp-input asp-for="ViewModel.Title" />
<abp-input asp-for="ViewModel.Slug" /> <abp-input asp-for="ViewModel.Slug" />
<abp-form-content /> <abp-input asp-for="ViewModel.ShortDescription" />
<div class="content-editor cms-kit-editor" <div class="content-editor cms-kit-editor"
id="ContentEditor" id="ContentEditor"
@ -77,7 +88,38 @@
data-language="@(CultureInfo.CurrentUICulture.TwoLetterISOLanguageName)"> data-language="@(CultureInfo.CurrentUICulture.TwoLetterISOLanguageName)">
</div> </div>
</abp-dynamic-form> @foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties<UpdateModel.UpdateBlogPostViewModel>())
{
if (!propertyInfo.Name.EndsWith("_Text"))
{
if (propertyInfo.Type.IsEnum || !propertyInfo.Lookup.Url.IsNullOrEmpty())
{
if (propertyInfo.Type.IsEnum)
{
Model.ViewModel.ExtraProperties.ToEnum(propertyInfo.Name, propertyInfo.Type);
}
<abp-select asp-for="ViewModel.ExtraProperties[propertyInfo.Name]"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
autocomplete-api-url="@propertyInfo.Lookup.Url"
autocomplete-selected-item-name="@Model.ViewModel.GetProperty(propertyInfo.Name+"_Text")"
autocomplete-selected-item-value="@Model.ViewModel.GetProperty(propertyInfo.Name)"
autocomplete-filter-param-name="@propertyInfo.Lookup.FilterParamName"
autocomplete-items-property-name="@propertyInfo.Lookup.ResultListPropertyName"
autocomplete-display-property-name="@propertyInfo.Lookup.DisplayPropertyName"
autocomplete-value-property-name="@propertyInfo.Lookup.ValuePropertyName"></abp-select>
}
else
{
<abp-input type="@propertyInfo.GetInputType()"
asp-for="ViewModel.ExtraProperties[propertyInfo.Name]"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
asp-format="@propertyInfo.GetInputFormatOrNull()"
value="@propertyInfo.GetInputValueOrNull(Model.ViewModel.GetProperty(propertyInfo.Name))" />
}
}
}
</form>
@if (Model.TagsFeature?.IsEnabled == true) @if (Model.TagsFeature?.IsEnabled == true)
{ {

3
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/BlogPosts/Update.cshtml.cs

@ -9,6 +9,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation; using Volo.Abp.Validation;
using Volo.CmsKit.Admin.Blogs; using Volo.CmsKit.Admin.Blogs;
using Volo.CmsKit.Blogs; using Volo.CmsKit.Blogs;
@ -57,7 +58,7 @@ public class UpdateModel : CmsKitAdminPageModel
[AutoMap(typeof(BlogPostDto))] [AutoMap(typeof(BlogPostDto))]
[AutoMap(typeof(UpdateBlogPostDto), ReverseMap = true)] [AutoMap(typeof(UpdateBlogPostDto), ReverseMap = true)]
public class UpdateBlogPostViewModel : IHasConcurrencyStamp public class UpdateBlogPostViewModel : ExtensibleObject, IHasConcurrencyStamp
{ {
[DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxTitleLength))] [DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxTitleLength))]
[Required] [Required]

48
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/CreateModal.cshtml

@ -1,8 +1,15 @@
@page @page
@using Microsoft.AspNetCore.Mvc.TagHelpers
@using Microsoft.Extensions.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs @using Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs
@using Volo.CmsKit.Admin.Web.Pages @using Volo.CmsKit.Admin.Web.Pages
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal @using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@using Volo.Abp.Data
@using Volo.Abp.Localization
@using Volo.Abp.ObjectExtending
@inject IStringLocalizerFactory StringLocalizerFactory
@inherits CmsKitAdminPageBase @inherits CmsKitAdminPageBase
@ -12,12 +19,45 @@
Layout = null; Layout = null;
} }
<abp-dynamic-form abp-model="ViewModel" asp-page="/CmsKit/Blogs/CreateModal"> <form asp-page="/CmsKit/Blogs/CreateModal">
<abp-modal> <abp-modal>
<abp-modal-header title="@L["New"].Value"></abp-modal-header> <abp-modal-header title="@L["New"].Value"></abp-modal-header>
<abp-modal-body> <abp-modal-body>
<abp-form-content /> <abp-input asp-for="ViewModel.Name" />
<abp-input asp-for="ViewModel.Slug" />
@foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties<CreateModalModel.CreateBlogViewModel>())
{
if (!propertyInfo.Name.EndsWith("_Text"))
{
if (propertyInfo.Type.IsEnum || !propertyInfo.Lookup.Url.IsNullOrEmpty())
{
if (propertyInfo.Type.IsEnum)
{
Model.ViewModel.ExtraProperties.ToEnum(propertyInfo.Name, propertyInfo.Type);
}
<abp-select asp-for="ViewModel.ExtraProperties[propertyInfo.Name]"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
autocomplete-api-url="@propertyInfo.Lookup.Url"
autocomplete-selected-item-name="@Model.ViewModel.GetProperty(propertyInfo.Name+"_Text")"
autocomplete-selected-item-value="@Model.ViewModel.GetProperty(propertyInfo.Name)"
autocomplete-filter-param-name="@propertyInfo.Lookup.FilterParamName"
autocomplete-items-property-name="@propertyInfo.Lookup.ResultListPropertyName"
autocomplete-display-property-name="@propertyInfo.Lookup.DisplayPropertyName"
autocomplete-value-property-name="@propertyInfo.Lookup.ValuePropertyName"></abp-select>
}
else
{
<abp-input type="@propertyInfo.GetInputType()"
asp-for="ViewModel.ExtraProperties[propertyInfo.Name]"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
asp-format="@propertyInfo.GetInputFormatOrNull()"
value="@propertyInfo.GetInputValueOrNull(Model.ViewModel.GetProperty(propertyInfo.Name))" />
}
}
}
</abp-modal-body> </abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel | AbpModalButtons.Save)"></abp-modal-footer> <abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer>
</abp-modal> </abp-modal>
</abp-dynamic-form> </form>

9
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/CreateModal.cshtml.cs

@ -2,6 +2,7 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation; using Volo.Abp.Validation;
using Volo.CmsKit.Admin.Blogs; using Volo.CmsKit.Admin.Blogs;
using Volo.CmsKit.Blogs; using Volo.CmsKit.Blogs;
@ -18,9 +19,10 @@ public class CreateModalModel : CmsKitAdminPageModel
public CreateModalModel(IBlogAdminAppService blogAdminAppService) public CreateModalModel(IBlogAdminAppService blogAdminAppService)
{ {
BlogAdminAppService = blogAdminAppService; BlogAdminAppService = blogAdminAppService;
ViewModel = new CreateBlogViewModel();
} }
public async Task<IActionResult> OnPostAsync() public virtual async Task<IActionResult> OnPostAsync()
{ {
var dto = ObjectMapper.Map<CreateBlogViewModel, CreateBlogDto>(ViewModel); var dto = ObjectMapper.Map<CreateBlogViewModel, CreateBlogDto>(ViewModel);
@ -28,9 +30,8 @@ public class CreateModalModel : CmsKitAdminPageModel
return NoContent(); return NoContent();
} }
[AutoMap(typeof(CreateBlogDto), ReverseMap = true)] public class CreateBlogViewModel : ExtensibleObject
public class CreateBlogViewModel
{ {
[Required] [Required]
[DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxNameLength))] [DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxNameLength))]

51
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/UpdateModal.cshtml

@ -1,8 +1,14 @@
@page @page
@using Microsoft.AspNetCore.Mvc.TagHelpers
@using Microsoft.Extensions.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
@using Volo.CmsKit.Admin.Web.Pages @using Volo.CmsKit.Admin.Web.Pages
@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs @using Volo.CmsKit.Admin.Web.Pages.CmsKit.Blogs
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal @using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@using Volo.Abp.Data
@using Volo.Abp.Localization
@using Volo.Abp.ObjectExtending
@inject IStringLocalizerFactory StringLocalizerFactory
@inherits CmsKitAdminPageBase @inherits CmsKitAdminPageBase
@model UpdateModalModel @model UpdateModalModel
@ -11,13 +17,48 @@
Layout = null; Layout = null;
} }
<abp-dynamic-form abp-model="ViewModel" asp-page="/CmsKit/Blogs/UpdateModal"> <form asp-page="/CmsKit/Blogs/UpdateModal">
<abp-modal> <abp-modal>
<abp-modal-header title="@L["Edit"].Value"></abp-modal-header> <abp-modal-header title="@L["Edit"].Value"></abp-modal-header>
<abp-modal-body> <abp-modal-body>
<abp-input asp-for="Id" /> <abp-input asp-for="Id" hidden />
<abp-form-content /> <abp-input asp-for="ViewModel.ConcurrencyStamp" hidden />
<abp-input asp-for="ViewModel.Name" />
<abp-input asp-for="ViewModel.Slug" />
@foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties<UpdateModalModel.UpdateBlogViewModel>())
{
if (!propertyInfo.Name.EndsWith("_Text"))
{
if (propertyInfo.Type.IsEnum || !propertyInfo.Lookup.Url.IsNullOrEmpty())
{
if (propertyInfo.Type.IsEnum)
{
Model.ViewModel.ExtraProperties.ToEnum(propertyInfo.Name, propertyInfo.Type);
}
<abp-select asp-for="ViewModel.ExtraProperties[propertyInfo.Name]"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
autocomplete-api-url="@propertyInfo.Lookup.Url"
autocomplete-selected-item-name="@Model.ViewModel.GetProperty(propertyInfo.Name+"_Text")"
autocomplete-selected-item-value="@Model.ViewModel.GetProperty(propertyInfo.Name)"
autocomplete-filter-param-name="@propertyInfo.Lookup.FilterParamName"
autocomplete-items-property-name="@propertyInfo.Lookup.ResultListPropertyName"
autocomplete-display-property-name="@propertyInfo.Lookup.DisplayPropertyName"
autocomplete-value-property-name="@propertyInfo.Lookup.ValuePropertyName"></abp-select>
}
else
{
<abp-input type="@propertyInfo.GetInputType()"
asp-for="ViewModel.ExtraProperties[propertyInfo.Name]"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
asp-format="@propertyInfo.GetInputFormatOrNull()"
value="@propertyInfo.GetInputValueOrNull(Model.ViewModel.GetProperty(propertyInfo.Name))" />
}
}
}
</abp-modal-body> </abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer> <abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer>
</abp-modal> </abp-modal>
</abp-dynamic-form> </form>

7
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/UpdateModal.cshtml.cs

@ -4,6 +4,7 @@ using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation; using Volo.Abp.Validation;
using Volo.CmsKit.Admin.Blogs; using Volo.CmsKit.Admin.Blogs;
using Volo.CmsKit.Blogs; using Volo.CmsKit.Blogs;
@ -41,10 +42,8 @@ public class UpdateModalModel : CmsKitAdminPageModel
return NoContent(); return NoContent();
} }
[AutoMap(typeof(BlogDto))] public class UpdateBlogViewModel : ExtensibleObject, IHasConcurrencyStamp
[AutoMap(typeof(UpdateBlogDto), ReverseMap = true)]
public class UpdateBlogViewModel : IHasConcurrencyStamp
{ {
[Required] [Required]
[DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxNameLength))] [DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxNameLength))]

40
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/CreateModal.cshtml

@ -1,9 +1,16 @@
@page @page
@using Microsoft.AspNetCore.Mvc.TagHelpers
@using Microsoft.Extensions.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems @using Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems
@using Volo.CmsKit.Admin.Web.Pages @using Volo.CmsKit.Admin.Web.Pages
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal @using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Tab
@using Volo.Abp.Data
@using Volo.Abp.Localization
@using Volo.Abp.ObjectExtending
@inject IStringLocalizerFactory StringLocalizerFactory
@inherits CmsKitAdminPageBase @inherits CmsKitAdminPageBase
@model CreateModalModel @model CreateModalModel
@ -42,6 +49,37 @@
<abp-input asp-for="ViewModel.Target"/> <abp-input asp-for="ViewModel.Target"/>
<abp-input asp-for="ViewModel.ElementId"/> <abp-input asp-for="ViewModel.ElementId"/>
<abp-input asp-for="ViewModel.CssClass"/> <abp-input asp-for="ViewModel.CssClass"/>
@foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties<CreateModalModel.MenuItemCreateViewModel>())
{
if (!propertyInfo.Name.EndsWith("_Text"))
{
if (propertyInfo.Type.IsEnum || !propertyInfo.Lookup.Url.IsNullOrEmpty())
{
if (propertyInfo.Type.IsEnum)
{
Model.ViewModel.ExtraProperties.ToEnum(propertyInfo.Name, propertyInfo.Type);
}
<abp-select asp-for="ViewModel.ExtraProperties[propertyInfo.Name]"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
autocomplete-api-url="@propertyInfo.Lookup.Url"
autocomplete-selected-item-name="@Model.ViewModel.GetProperty(propertyInfo.Name+"_Text")"
autocomplete-selected-item-value="@Model.ViewModel.GetProperty(propertyInfo.Name)"
autocomplete-filter-param-name="@propertyInfo.Lookup.FilterParamName"
autocomplete-items-property-name="@propertyInfo.Lookup.ResultListPropertyName"
autocomplete-display-property-name="@propertyInfo.Lookup.DisplayPropertyName"
autocomplete-value-property-name="@propertyInfo.Lookup.ValuePropertyName"></abp-select>
}
else
{
<abp-input type="@propertyInfo.GetInputType()"
asp-for="ViewModel.ExtraProperties[propertyInfo.Name]"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
asp-format="@propertyInfo.GetInputFormatOrNull()"
value="@propertyInfo.GetInputValueOrNull(Model.ViewModel.GetProperty(propertyInfo.Name))" />
}
}
}
</abp-modal-body> </abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel | AbpModalButtons.Save)"></abp-modal-footer> <abp-modal-footer buttons="@(AbpModalButtons.Cancel | AbpModalButtons.Save)"></abp-modal-footer>
</abp-modal> </abp-modal>

3
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/CreateModal.cshtml.cs

@ -7,6 +7,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form;
using Volo.Abp.ObjectExtending;
using Volo.CmsKit.Admin.Menus; using Volo.CmsKit.Admin.Menus;
namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems; namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems;
@ -41,7 +42,7 @@ public class CreateModalModel : CmsKitAdminPageModel
} }
[AutoMap(typeof(MenuItemCreateInput), ReverseMap = true)] [AutoMap(typeof(MenuItemCreateInput), ReverseMap = true)]
public class MenuItemCreateViewModel public class MenuItemCreateViewModel : ExtensibleObject
{ {
[HiddenInput] [HiddenInput]
public Guid? ParentId { get; set; } public Guid? ParentId { get; set; }

40
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/UpdateModal.cshtml

@ -1,9 +1,16 @@
@page @page
@using Microsoft.AspNetCore.Mvc.TagHelpers
@using Microsoft.Extensions.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems @using Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems
@using Volo.CmsKit.Admin.Web.Pages @using Volo.CmsKit.Admin.Web.Pages
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal @using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Tab
@using Volo.Abp.Data
@using Volo.Abp.Localization
@using Volo.Abp.ObjectExtending
@inject IStringLocalizerFactory StringLocalizerFactory
@inherits CmsKitAdminPageBase @inherits CmsKitAdminPageBase
@model UpdateModalModel @model UpdateModalModel
@ -41,6 +48,37 @@
<abp-input asp-for="ViewModel.Target"/> <abp-input asp-for="ViewModel.Target"/>
<abp-input asp-for="ViewModel.ElementId"/> <abp-input asp-for="ViewModel.ElementId"/>
<abp-input asp-for="ViewModel.CssClass"/> <abp-input asp-for="ViewModel.CssClass"/>
@foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties<UpdateModalModel.MenuItemUpdateViewModel>())
{
if (!propertyInfo.Name.EndsWith("_Text"))
{
if (propertyInfo.Type.IsEnum || !propertyInfo.Lookup.Url.IsNullOrEmpty())
{
if (propertyInfo.Type.IsEnum)
{
Model.ViewModel.ExtraProperties.ToEnum(propertyInfo.Name, propertyInfo.Type);
}
<abp-select asp-for="ViewModel.ExtraProperties[propertyInfo.Name]"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
autocomplete-api-url="@propertyInfo.Lookup.Url"
autocomplete-selected-item-name="@Model.ViewModel.GetProperty(propertyInfo.Name+"_Text")"
autocomplete-selected-item-value="@Model.ViewModel.GetProperty(propertyInfo.Name)"
autocomplete-filter-param-name="@propertyInfo.Lookup.FilterParamName"
autocomplete-items-property-name="@propertyInfo.Lookup.ResultListPropertyName"
autocomplete-display-property-name="@propertyInfo.Lookup.DisplayPropertyName"
autocomplete-value-property-name="@propertyInfo.Lookup.ValuePropertyName"></abp-select>
}
else
{
<abp-input type="@propertyInfo.GetInputType()"
asp-for="ViewModel.ExtraProperties[propertyInfo.Name]"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
asp-format="@propertyInfo.GetInputFormatOrNull()"
value="@propertyInfo.GetInputValueOrNull(Model.ViewModel.GetProperty(propertyInfo.Name))" />
}
}
}
</abp-modal-body> </abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel | AbpModalButtons.Save)"></abp-modal-footer> <abp-modal-footer buttons="@(AbpModalButtons.Cancel | AbpModalButtons.Save)"></abp-modal-footer>
</abp-modal> </abp-modal>

3
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/UpdateModal.cshtml.cs

@ -5,6 +5,7 @@ using AutoMapper;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.RazorPages;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.ObjectExtending;
using Volo.CmsKit.Admin.Menus; using Volo.CmsKit.Admin.Menus;
using Volo.CmsKit.Menus; using Volo.CmsKit.Menus;
@ -44,7 +45,7 @@ public class UpdateModalModel : CmsKitAdminPageModel
[AutoMap(typeof(MenuItemDto))] [AutoMap(typeof(MenuItemDto))]
[AutoMap(typeof(MenuItemUpdateInput), ReverseMap = true)] [AutoMap(typeof(MenuItemUpdateInput), ReverseMap = true)]
public class MenuItemUpdateViewModel : IHasConcurrencyStamp public class MenuItemUpdateViewModel : ExtensibleObject, IHasConcurrencyStamp
{ {
[Required] [Required]
public string DisplayName { get; set; } public string DisplayName { get; set; }

43
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml

@ -1,12 +1,24 @@
@page @page
@using System.Globalization @using System.Globalization
@using Microsoft.AspNetCore.Mvc.TagHelpers
@using Microsoft.Extensions.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Tab
@using Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers
@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Codemirror @using Volo.Abp.AspNetCore.Mvc.UI.Packages.Codemirror
@using Volo.Abp.AspNetCore.Mvc.UI.Packages.TuiEditor @using Volo.Abp.AspNetCore.Mvc.UI.Packages.TuiEditor
@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Uppy @using Volo.Abp.AspNetCore.Mvc.UI.Packages.Uppy
@using Volo.CmsKit.Admin.Web.Pages @using Volo.CmsKit.Admin.Web.Pages
@using Volo.CmsKit.Admin.Web.Menus @using Volo.CmsKit.Admin.Web.Menus
@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Slugify @using Volo.Abp.AspNetCore.Mvc.UI.Packages.Slugify
@using Volo.Abp.Data
@using Volo.Abp.Localization
@using Volo.Abp.ObjectExtending
@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages
@inject IStringLocalizerFactory StringLocalizerFactory
@inherits CmsKitAdminPageBase @inherits CmsKitAdminPageBase
@ -70,6 +82,37 @@
</abp-tab> </abp-tab>
</abp-tabs> </abp-tabs>
@foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties<CreateModel.CreatePageViewModel>())
{
if (!propertyInfo.Name.EndsWith("_Text"))
{
if (propertyInfo.Type.IsEnum || !propertyInfo.Lookup.Url.IsNullOrEmpty())
{
if (propertyInfo.Type.IsEnum)
{
Model.ViewModel.ExtraProperties.ToEnum(propertyInfo.Name, propertyInfo.Type);
}
<abp-select asp-for="ViewModel.ExtraProperties[propertyInfo.Name]"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
autocomplete-api-url="@propertyInfo.Lookup.Url"
autocomplete-selected-item-name="@Model.ViewModel.GetProperty(propertyInfo.Name+"_Text")"
autocomplete-selected-item-value="@Model.ViewModel.GetProperty(propertyInfo.Name)"
autocomplete-filter-param-name="@propertyInfo.Lookup.FilterParamName"
autocomplete-items-property-name="@propertyInfo.Lookup.ResultListPropertyName"
autocomplete-display-property-name="@propertyInfo.Lookup.DisplayPropertyName"
autocomplete-value-property-name="@propertyInfo.Lookup.ValuePropertyName"></abp-select>
}
else
{
<abp-input type="@propertyInfo.GetInputType()"
asp-for="ViewModel.ExtraProperties[propertyInfo.Name]"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
asp-format="@propertyInfo.GetInputFormatOrNull()"
value="@propertyInfo.GetInputValueOrNull(Model.ViewModel.GetProperty(propertyInfo.Name))" />
}
}
}
</form> </form>
</abp-card-body> </abp-card-body>
<abp-card-footer> <abp-card-footer>

4
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Create.cshtml.cs

@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation; using Volo.Abp.Validation;
using Volo.CmsKit.Admin.Pages; using Volo.CmsKit.Admin.Pages;
using Volo.CmsKit.Pages; using Volo.CmsKit.Pages;
@ -19,6 +20,7 @@ public class CreateModel : CmsKitAdminPageModel
public CreateModel(IPageAdminAppService pageAdminAppService) public CreateModel(IPageAdminAppService pageAdminAppService)
{ {
this.pageAdminAppService = pageAdminAppService; this.pageAdminAppService = pageAdminAppService;
ViewModel = new CreatePageViewModel();
} }
public async Task<IActionResult> OnPostAsync() public async Task<IActionResult> OnPostAsync()
@ -31,7 +33,7 @@ public class CreateModel : CmsKitAdminPageModel
} }
[AutoMap(typeof(CreatePageInputDto), ReverseMap = true)] [AutoMap(typeof(CreatePageInputDto), ReverseMap = true)]
public class CreatePageViewModel public class CreatePageViewModel : ExtensibleObject
{ {
[Required] [Required]
[DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxTitleLength))] [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxTitleLength))]

44
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml

@ -1,12 +1,24 @@
@page "{Id}" @page "{Id}"
@using System.Globalization @using System.Globalization
@using Microsoft.AspNetCore.Mvc.TagHelpers
@using Microsoft.Extensions.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Tab
@using Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers
@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Codemirror @using Volo.Abp.AspNetCore.Mvc.UI.Packages.Codemirror
@using Volo.Abp.AspNetCore.Mvc.UI.Packages.TuiEditor @using Volo.Abp.AspNetCore.Mvc.UI.Packages.TuiEditor
@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Uppy @using Volo.Abp.AspNetCore.Mvc.UI.Packages.Uppy
@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Slugify @using Volo.Abp.AspNetCore.Mvc.UI.Packages.Slugify
@using Volo.Abp.Data
@using Volo.Abp.Localization
@using Volo.Abp.ObjectExtending
@using Volo.CmsKit.Admin.Web.Menus @using Volo.CmsKit.Admin.Web.Menus
@using Volo.CmsKit.Admin.Web.Pages @using Volo.CmsKit.Admin.Web.Pages
@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Pages
@inject IStringLocalizerFactory StringLocalizerFactory
@inherits CmsKitAdminPageBase @inherits CmsKitAdminPageBase
@ -56,7 +68,6 @@
<abp-input asp-for="@Model.ViewModel.Content" /> <abp-input asp-for="@Model.ViewModel.Content" />
<abp-tabs tab-style="Tab"> <abp-tabs tab-style="Tab">
<abp-tab title="@L["Content"]"> <abp-tab title="@L["Content"]">
@ -76,6 +87,37 @@
</abp-tab> </abp-tab>
</abp-tabs> </abp-tabs>
@foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties<UpdateModel.UpdatePageViewModel>())
{
if (!propertyInfo.Name.EndsWith("_Text"))
{
if (propertyInfo.Type.IsEnum || !propertyInfo.Lookup.Url.IsNullOrEmpty())
{
if (propertyInfo.Type.IsEnum)
{
Model.ViewModel.ExtraProperties.ToEnum(propertyInfo.Name, propertyInfo.Type);
}
<abp-select asp-for="ViewModel.ExtraProperties[propertyInfo.Name]"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
autocomplete-api-url="@propertyInfo.Lookup.Url"
autocomplete-selected-item-name="@Model.ViewModel.GetProperty(propertyInfo.Name+"_Text")"
autocomplete-selected-item-value="@Model.ViewModel.GetProperty(propertyInfo.Name)"
autocomplete-filter-param-name="@propertyInfo.Lookup.FilterParamName"
autocomplete-items-property-name="@propertyInfo.Lookup.ResultListPropertyName"
autocomplete-display-property-name="@propertyInfo.Lookup.DisplayPropertyName"
autocomplete-value-property-name="@propertyInfo.Lookup.ValuePropertyName"></abp-select>
}
else
{
<abp-input type="@propertyInfo.GetInputType()"
asp-for="ViewModel.ExtraProperties[propertyInfo.Name]"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
asp-format="@propertyInfo.GetInputFormatOrNull()"
value="@propertyInfo.GetInputValueOrNull(Model.ViewModel.GetProperty(propertyInfo.Name))" />
}
}
}
</form> </form>
</abp-card-body> </abp-card-body>

3
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Pages/Update.cshtml.cs

@ -5,6 +5,7 @@ using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation; using Volo.Abp.Validation;
using Volo.CmsKit.Admin.Pages; using Volo.CmsKit.Admin.Pages;
using Volo.CmsKit.Pages; using Volo.CmsKit.Pages;
@ -45,7 +46,7 @@ public class UpdateModel : CmsKitAdminPageModel
[AutoMap(typeof(PageDto))] [AutoMap(typeof(PageDto))]
[AutoMap(typeof(UpdatePageInputDto), ReverseMap = true)] [AutoMap(typeof(UpdatePageInputDto), ReverseMap = true)]
public class UpdatePageViewModel : IHasConcurrencyStamp public class UpdatePageViewModel : ExtensibleObject, IHasConcurrencyStamp
{ {
[Required] [Required]
[DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxTitleLength))] [DynamicMaxLength(typeof(PageConsts), nameof(PageConsts.MaxTitleLength))]

48
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/CreateModal.cshtml

@ -1,8 +1,15 @@
@page @page
@using Microsoft.AspNetCore.Mvc.Localization @using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.AspNetCore.Mvc.TagHelpers
@using Microsoft.Extensions.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags @using Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal @using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@using Volo.Abp.Data
@using Volo.Abp.Localization
@using Volo.Abp.ObjectExtending
@using Volo.CmsKit.Localization @using Volo.CmsKit.Localization
@inject IStringLocalizerFactory StringLocalizerFactory
@inject IHtmlLocalizer<CmsKitResource> L @inject IHtmlLocalizer<CmsKitResource> L
@ -12,12 +19,45 @@
Layout = null; Layout = null;
} }
<abp-dynamic-form abp-model="ViewModel" asp-page="/CmsKit/Tags/CreateModal"> <form asp-page="/CmsKit/Tags/CreateModal">
<abp-modal> <abp-modal>
<abp-modal-header title="@L["New"].Value"></abp-modal-header> <abp-modal-header title="@L["New"].Value"></abp-modal-header>
<abp-modal-body> <abp-modal-body>
<abp-form-content/> <abp-input asp-for="ViewModel.EntityType" />
<abp-input asp-for="ViewModel.Name" />
@foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties<CreateModalModel.TagCreateViewModel>())
{
if (!propertyInfo.Name.EndsWith("_Text"))
{
if (propertyInfo.Type.IsEnum || !propertyInfo.Lookup.Url.IsNullOrEmpty())
{
if (propertyInfo.Type.IsEnum)
{
Model.ViewModel.ExtraProperties.ToEnum(propertyInfo.Name, propertyInfo.Type);
}
<abp-select asp-for="ViewModel.ExtraProperties[propertyInfo.Name]"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
autocomplete-api-url="@propertyInfo.Lookup.Url"
autocomplete-selected-item-name="@Model.ViewModel.GetProperty(propertyInfo.Name+"_Text")"
autocomplete-selected-item-value="@Model.ViewModel.GetProperty(propertyInfo.Name)"
autocomplete-filter-param-name="@propertyInfo.Lookup.FilterParamName"
autocomplete-items-property-name="@propertyInfo.Lookup.ResultListPropertyName"
autocomplete-display-property-name="@propertyInfo.Lookup.DisplayPropertyName"
autocomplete-value-property-name="@propertyInfo.Lookup.ValuePropertyName"></abp-select>
}
else
{
<abp-input type="@propertyInfo.GetInputType()"
asp-for="ViewModel.ExtraProperties[propertyInfo.Name]"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
asp-format="@propertyInfo.GetInputFormatOrNull()"
value="@propertyInfo.GetInputValueOrNull(Model.ViewModel.GetProperty(propertyInfo.Name))" />
}
}
}
</abp-modal-body> </abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel | AbpModalButtons.Save)"></abp-modal-footer> <abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer>
</abp-modal> </abp-modal>
</abp-dynamic-form> </form>

4
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/CreateModal.cshtml.cs

@ -6,6 +6,7 @@ using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation; using Volo.Abp.Validation;
using Volo.CmsKit.Admin.Tags; using Volo.CmsKit.Admin.Tags;
using Volo.CmsKit.Tags; using Volo.CmsKit.Tags;
@ -24,6 +25,7 @@ public class CreateModalModel : CmsKitAdminPageModel
public CreateModalModel(ITagAdminAppService tagAdminAppService) public CreateModalModel(ITagAdminAppService tagAdminAppService)
{ {
TagAdminAppService = tagAdminAppService; TagAdminAppService = tagAdminAppService;
ViewModel = new TagCreateViewModel();
} }
public async Task OnGetAsync() public async Task OnGetAsync()
@ -43,7 +45,7 @@ public class CreateModalModel : CmsKitAdminPageModel
} }
[AutoMap(typeof(TagCreateDto), ReverseMap = true)] [AutoMap(typeof(TagCreateDto), ReverseMap = true)]
public class TagCreateViewModel public class TagCreateViewModel : ExtensibleObject
{ {
[DynamicMaxLength(typeof(TagConsts), nameof(TagConsts.MaxEntityTypeLength))] [DynamicMaxLength(typeof(TagConsts), nameof(TagConsts.MaxEntityTypeLength))]
[Required] [Required]

48
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/EditModal.cshtml

@ -1,24 +1,62 @@
@page @page
@using Microsoft.AspNetCore.Mvc.Localization @using Microsoft.AspNetCore.Mvc.Localization
@using Volo.CmsKit.Admin.Web.Pages @using Microsoft.AspNetCore.Mvc.TagHelpers
@using Microsoft.Extensions.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags @using Volo.CmsKit.Admin.Web.Pages.CmsKit.Tags
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal @using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@using Volo.Abp.Data
@using Volo.Abp.Localization
@using Volo.Abp.ObjectExtending
@using Volo.CmsKit.Localization @using Volo.CmsKit.Localization
@inject IHtmlLocalizer<CmsKitResource> L @inject IHtmlLocalizer<CmsKitResource> L
@inject IStringLocalizerFactory StringLocalizerFactory
@model EditModalModel @model EditModalModel
@{ @{
Layout = null; Layout = null;
} }
<abp-dynamic-form abp-model="ViewModel" asp-page="/CmsKit/Tags/EditModal"> <form asp-page="/CmsKit/Tags/EditModal">
<abp-modal> <abp-modal>
<abp-modal-header title="@L["Edit"].Value"></abp-modal-header> <abp-modal-header title="@L["Edit"].Value"></abp-modal-header>
<abp-modal-body> <abp-modal-body>
<abp-input asp-for="Id" /> <abp-input asp-for="Id"/>
<abp-form-content />
<abp-input asp-for="ViewModel.Name" />
@foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties<EditModalModel.TagEditViewModel>())
{
if (!propertyInfo.Name.EndsWith("_Text"))
{
if (propertyInfo.Type.IsEnum || !propertyInfo.Lookup.Url.IsNullOrEmpty())
{
if (propertyInfo.Type.IsEnum)
{
Model.ViewModel.ExtraProperties.ToEnum(propertyInfo.Name, propertyInfo.Type);
}
<abp-select asp-for="ViewModel.ExtraProperties[propertyInfo.Name]"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
autocomplete-api-url="@propertyInfo.Lookup.Url"
autocomplete-selected-item-name="@Model.ViewModel.GetProperty(propertyInfo.Name+"_Text")"
autocomplete-selected-item-value="@Model.ViewModel.GetProperty(propertyInfo.Name)"
autocomplete-filter-param-name="@propertyInfo.Lookup.FilterParamName"
autocomplete-items-property-name="@propertyInfo.Lookup.ResultListPropertyName"
autocomplete-display-property-name="@propertyInfo.Lookup.DisplayPropertyName"
autocomplete-value-property-name="@propertyInfo.Lookup.ValuePropertyName"></abp-select>
}
else
{
<abp-input type="@propertyInfo.GetInputType()"
asp-for="ViewModel.ExtraProperties[propertyInfo.Name]"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
asp-format="@propertyInfo.GetInputFormatOrNull()"
value="@propertyInfo.GetInputValueOrNull(Model.ViewModel.GetProperty(propertyInfo.Name))" />
}
}
}
</abp-modal-body> </abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer> <abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer>
</abp-modal> </abp-modal>
</abp-dynamic-form> </form>

3
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Tags/EditModal.cshtml.cs

@ -7,6 +7,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation; using Volo.Abp.Validation;
using Volo.CmsKit.Admin.Tags; using Volo.CmsKit.Admin.Tags;
using Volo.CmsKit.Tags; using Volo.CmsKit.Tags;
@ -45,7 +46,7 @@ public class EditModalModel : CmsKitAdminPageModel
[AutoMap(typeof(TagDto))] [AutoMap(typeof(TagDto))]
[AutoMap(typeof(TagUpdateDto), ReverseMap = true)] [AutoMap(typeof(TagUpdateDto), ReverseMap = true)]
public class TagEditViewModel : IHasConcurrencyStamp public class TagEditViewModel : ExtensibleObject, IHasConcurrencyStamp
{ {
[Required] [Required]
[DynamicMaxLength(typeof(TagConsts), nameof(TagConsts.MaxNameLength))] [DynamicMaxLength(typeof(TagConsts), nameof(TagConsts.MaxNameLength))]

3
modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Blogs/BlogFeatureCacheItem.cs

@ -1,9 +1,10 @@
using System; using System;
using Volo.Abp.ObjectExtending;
namespace Volo.CmsKit.Blogs; namespace Volo.CmsKit.Blogs;
[Serializable] [Serializable]
public class BlogFeatureCacheItem public class BlogFeatureCacheItem : ExtensibleObject
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public string FeatureName { get; set; } public string FeatureName { get; set; }

2
modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Blogs/BlogFeatureDto.cs

@ -4,7 +4,7 @@ using Volo.Abp.Application.Dtos;
namespace Volo.CmsKit.Blogs; namespace Volo.CmsKit.Blogs;
[Serializable] [Serializable]
public class BlogFeatureDto : EntityDto<Guid> public class BlogFeatureDto : ExtensibleEntityDto<Guid>
{ {
public string FeatureName { get; set; } public string FeatureName { get; set; }
public bool IsEnabled { get; set; } public bool IsEnabled { get; set; }

44
modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/CmsKitCommonApplicationContractsModule.cs

@ -2,6 +2,14 @@
using Volo.Abp.Authorization; using Volo.Abp.Authorization;
using Volo.Abp.Caching; using Volo.Abp.Caching;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.ObjectExtending;
using Volo.Abp.ObjectExtending.Modularity;
using Volo.Abp.Threading;
using Volo.CmsKit.Blogs;
using Volo.CmsKit.Contents;
using Volo.CmsKit.Menus;
using Volo.CmsKit.Tags;
using Volo.CmsKit.Users;
namespace Volo.CmsKit; namespace Volo.CmsKit;
@ -13,5 +21,41 @@ namespace Volo.CmsKit;
)] )]
public class CmsKitCommonApplicationContractsModule : AbpModule public class CmsKitCommonApplicationContractsModule : AbpModule
{ {
private readonly static OneTimeRunner OneTimeRunner = new OneTimeRunner();
public override void PostConfigureServices(ServiceConfigurationContext context)
{
OneTimeRunner.Run(() =>
{
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.BlogFeature,
getApiTypes: new[] { typeof(BlogFeatureDto) }
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.BlogPost,
getApiTypes: new[] { typeof(BlogPostCommonDto) }
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.MenuItem,
getApiTypes: new[] { typeof(MenuItemDto) }
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.Tag,
getApiTypes: new[] { typeof(TagDto) }
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.CmsUser,
getApiTypes: new[] { typeof(CmsUserDto) }
);
});
}
} }

2
modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Contents/BlogPostCommonDto.cs

@ -5,7 +5,7 @@ using Volo.CmsKit.Users;
namespace Volo.CmsKit.Contents; namespace Volo.CmsKit.Contents;
[Serializable] [Serializable]
public class BlogPostCommonDto : AuditedEntityDto<Guid> public class BlogPostCommonDto : ExtensibleAuditedEntityDto<Guid>
{ {
public Guid BlogId { get; set; } public Guid BlogId { get; set; }

2
modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Contents/PageDto.cs

@ -3,7 +3,7 @@ using Volo.Abp.Application.Dtos;
namespace Volo.CmsKit.Contents; namespace Volo.CmsKit.Contents;
public class PageDto : EntityDto<Guid> public class PageDto : ExtensibleEntityDto<Guid>
{ {
public string Title { get; set; } public string Title { get; set; }

2
modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Menus/MenuItemDto.cs

@ -5,7 +5,7 @@ using Volo.Abp.Domain.Entities;
namespace Volo.CmsKit.Menus; namespace Volo.CmsKit.Menus;
[Serializable] [Serializable]
public class MenuItemDto : AuditedEntityDto<Guid>, IHasConcurrencyStamp public class MenuItemDto : ExtensibleAuditedEntityDto<Guid>, IHasConcurrencyStamp
{ {
public Guid? ParentId { get; set; } public Guid? ParentId { get; set; }

2
modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Tags/TagDto.cs

@ -5,7 +5,7 @@ using Volo.Abp.Domain.Entities;
namespace Volo.CmsKit.Tags; namespace Volo.CmsKit.Tags;
[Serializable] [Serializable]
public class TagDto : EntityDto<Guid>, IHasConcurrencyStamp public class TagDto : ExtensibleEntityDto<Guid>, IHasConcurrencyStamp
{ {
public string EntityType { get; set; } public string EntityType { get; set; }

2
modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Users/CmsUserDto.cs

@ -4,7 +4,7 @@ using Volo.Abp.Application.Dtos;
namespace Volo.CmsKit.Users; namespace Volo.CmsKit.Users;
[Serializable] [Serializable]
public class CmsUserDto : EntityDto<Guid> public class CmsUserDto : ExtensibleEntityDto<Guid>
{ {
public virtual Guid? TenantId { get; protected set; } public virtual Guid? TenantId { get; protected set; }

13
modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/CmsKitCommonApplicationAutoMapperProfile.cs

@ -9,12 +9,15 @@ public class CmsKitCommonApplicationAutoMapperProfile : Profile
{ {
public CmsKitCommonApplicationAutoMapperProfile() public CmsKitCommonApplicationAutoMapperProfile()
{ {
CreateMap<Tag, TagDto>(); CreateMap<Tag, TagDto>().MapExtraProperties();
CreateMap<CmsUser, CmsUserDto>(); CreateMap<CmsUser, CmsUserDto>().MapExtraProperties();
CreateMap<BlogFeature, BlogFeatureCacheItem>(); CreateMap<BlogFeature, BlogFeatureCacheItem>().MapExtraProperties();
CreateMap<BlogFeature, BlogFeatureDto>(); CreateMap<BlogFeature, BlogFeatureDto>().MapExtraProperties();
CreateMap<BlogFeatureCacheItem, BlogFeatureDto>().ReverseMap(); CreateMap<BlogFeatureCacheItem, BlogFeatureDto>()
.MapExtraProperties()
.ReverseMap()
.MapExtraProperties();
} }
} }

97
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/Abp/ObjectExtending/CmsKitModuleExtensionConfiguration.cs

@ -0,0 +1,97 @@
using System;
using Volo.Abp.ObjectExtending.Modularity;
namespace Volo.Abp.ObjectExtending;
public class CmsKitModuleExtensionConfiguration : ModuleExtensionConfiguration
{
public CmsKitModuleExtensionConfiguration ConfigureBlog(
Action<EntityExtensionConfiguration> configureAction)
{
return this.ConfigureEntity(
CmsKitModuleExtensionConsts.EntityNames.Blog,
configureAction
);
}
public CmsKitModuleExtensionConfiguration ConfigureBlogPost(
Action<EntityExtensionConfiguration> configureAction)
{
return this.ConfigureEntity(
CmsKitModuleExtensionConsts.EntityNames.BlogPost,
configureAction
);
}
public CmsKitModuleExtensionConfiguration ConfigureBlogFeature(
Action<EntityExtensionConfiguration> configureAction)
{
return this.ConfigureEntity(
CmsKitModuleExtensionConsts.EntityNames.BlogFeature,
configureAction
);
}
public CmsKitModuleExtensionConfiguration ConfigureMediaDescriptor(
Action<EntityExtensionConfiguration> configureAction)
{
return this.ConfigureEntity(
CmsKitModuleExtensionConsts.EntityNames.MediaDescriptor,
configureAction
);
}
public CmsKitModuleExtensionConfiguration ConfigurePage(
Action<EntityExtensionConfiguration> configureAction)
{
return this.ConfigureEntity(
CmsKitModuleExtensionConsts.EntityNames.Page,
configureAction
);
}
public CmsKitModuleExtensionConfiguration ConfigureTag(
Action<EntityExtensionConfiguration> configureAction)
{
return this.ConfigureEntity(
CmsKitModuleExtensionConsts.EntityNames.Tag,
configureAction
);
}
public CmsKitModuleExtensionConfiguration ConfigureComment(
Action<EntityExtensionConfiguration> configureAction)
{
return this.ConfigureEntity(
CmsKitModuleExtensionConsts.EntityNames.Comment,
configureAction
);
}
public CmsKitModuleExtensionConfiguration ConfigureMenuItem(
Action<EntityExtensionConfiguration> configureAction)
{
return this.ConfigureEntity(
CmsKitModuleExtensionConsts.EntityNames.MenuItem,
configureAction
);
}
public CmsKitModuleExtensionConfiguration ConfigureCmsUser(
Action<EntityExtensionConfiguration> configureAction)
{
return this.ConfigureEntity(
CmsKitModuleExtensionConsts.EntityNames.CmsUser,
configureAction
);
}
public CmsKitModuleExtensionConfiguration ConfigureGlobalResource(
Action<EntityExtensionConfiguration> configureAction)
{
return this.ConfigureEntity(
CmsKitModuleExtensionConsts.EntityNames.GlobalResource,
configureAction
);
}
}

17
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/Abp/ObjectExtending/CmsKitModuleExtensionConfigurationDictionaryExtensions.cs

@ -0,0 +1,17 @@
using System;
using Volo.Abp.ObjectExtending.Modularity;
namespace Volo.Abp.ObjectExtending;
public static class CmsKitModuleExtensionConfigurationDictionaryExtensions
{
public static ModuleExtensionConfigurationDictionary ConfigureCmsKit(
this ModuleExtensionConfigurationDictionary modules,
Action<CmsKitModuleExtensionConfiguration> configureAction)
{
return modules.ConfigureModule(
CmsKitModuleExtensionConsts.ModuleName,
configureAction
);
}
}

29
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/Abp/ObjectExtending/CmsKitModuleExtensionConsts.cs

@ -0,0 +1,29 @@
namespace Volo.Abp.ObjectExtending;
public static class CmsKitModuleExtensionConsts
{
public const string ModuleName = "CmsKit";
public static class EntityNames
{
public const string Blog = "Blog";
public const string BlogPost = "BlogPost";
public const string BlogFeature = "BlogFeature";
public const string MediaDescriptor = "MediaDescriptor";
public const string Page = "Page";
public const string Tag = "Tag";
public const string Comment = "Comment";
public const string MenuItem = "MenuItem";
public const string CmsUser = "CmsUser";
public const string GlobalResource = "GlobalResource";
}
}

69
modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs

@ -3,13 +3,21 @@ using Volo.Abp.Domain;
using Volo.Abp.GlobalFeatures; using Volo.Abp.GlobalFeatures;
using Volo.Abp.Localization; using Volo.Abp.Localization;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.ObjectExtending;
using Volo.Abp.ObjectExtending.Modularity;
using Volo.Abp.Threading;
using Volo.Abp.Users; using Volo.Abp.Users;
using Volo.CmsKit.Blogs; using Volo.CmsKit.Blogs;
using Volo.CmsKit.Comments; using Volo.CmsKit.Comments;
using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Localization; using Volo.CmsKit.Localization;
using Volo.CmsKit.MediaDescriptors;
using Volo.CmsKit.Menus;
using Volo.CmsKit.Pages;
using Volo.CmsKit.Ratings; using Volo.CmsKit.Ratings;
using Volo.CmsKit.Reactions; using Volo.CmsKit.Reactions;
using Volo.CmsKit.Tags;
using Volo.CmsKit.Users;
namespace Volo.CmsKit; namespace Volo.CmsKit;
@ -21,6 +29,7 @@ namespace Volo.CmsKit;
)] )]
public class CmsKitDomainModule : AbpModule public class CmsKitDomainModule : AbpModule
{ {
private readonly static OneTimeRunner OneTimeRunner = new OneTimeRunner();
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
if (GlobalFeatureManager.Instance.IsEnabled<ReactionsFeature>()) if (GlobalFeatureManager.Instance.IsEnabled<ReactionsFeature>())
@ -81,6 +90,66 @@ public class CmsKitDomainModule : AbpModule
// TODO: Configure TagEntityTypes here... // TODO: Configure TagEntityTypes here...
} }
} }
public override void PostConfigureServices(ServiceConfigurationContext context)
{
OneTimeRunner.Run(() =>
{
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.Blog,
typeof(Blog)
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.BlogPost,
typeof(BlogPost)
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.BlogFeature,
typeof(BlogFeature)
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.MediaDescriptor,
typeof(MediaDescriptor)
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.Page,
typeof(Page)
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.Tag,
typeof(Tag)
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.Comment,
typeof(Comment)
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.MenuItem,
typeof(MenuItem)
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.CmsUser,
typeof(CmsUser)
);
});
}
private static LocalizableString L(string name) private static LocalizableString L(string name)
{ {

3
modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/PageCacheItem.cs

@ -1,8 +1,9 @@
using System; using System;
using Volo.Abp.ObjectExtending;
namespace Volo.CmsKit.Pages; namespace Volo.CmsKit.Pages;
public class PageCacheItem public class PageCacheItem : ExtensibleObject
{ {
public Guid Id { get; set; } public Guid Id { get; set; }

25
modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/CmsKitPublicApplicationContractsModule.cs

@ -1,5 +1,10 @@
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.EventBus; using Volo.Abp.EventBus;
using Volo.Abp.ObjectExtending;
using Volo.Abp.ObjectExtending.Modularity;
using Volo.Abp.Threading;
using Volo.CmsKit.Public.Comments;
using Volo.CmsKit.Public.GlobalResources;
namespace Volo.CmsKit.Public; namespace Volo.CmsKit.Public;
@ -9,5 +14,25 @@ namespace Volo.CmsKit.Public;
)] )]
public class CmsKitPublicApplicationContractsModule : AbpModule public class CmsKitPublicApplicationContractsModule : AbpModule
{ {
private readonly static OneTimeRunner OneTimeRunner = new OneTimeRunner();
public override void PostConfigureServices(ServiceConfigurationContext context)
{
OneTimeRunner.Run(() =>
{
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.Comment,
getApiTypes: new[] { typeof(CommentDto) , typeof(CommentWithDetailsDto) },
createApiTypes: new []{ typeof(CreateCommentInput) },
updateApiTypes: new []{ typeof(UpdateCommentInput) }
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToApi(
CmsKitModuleExtensionConsts.ModuleName,
CmsKitModuleExtensionConsts.EntityNames.GlobalResource,
getApiTypes: new[] { typeof(GlobalResourceDto) }
);
});
}
} }

3
modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Comments/CmsUserDto.cs

@ -1,9 +1,10 @@
using System; using System;
using Volo.Abp.ObjectExtending;
namespace Volo.CmsKit.Public.Comments; namespace Volo.CmsKit.Public.Comments;
[Serializable] [Serializable]
public class CmsUserDto public class CmsUserDto : ExtensibleObject
{ {
public Guid Id { get; set; } public Guid Id { get; set; }

3
modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Comments/CommentDto.cs

@ -1,10 +1,11 @@
using System; using System;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.ObjectExtending;
namespace Volo.CmsKit.Public.Comments; namespace Volo.CmsKit.Public.Comments;
[Serializable] [Serializable]
public class CommentDto : IHasConcurrencyStamp public class CommentDto : ExtensibleObject, IHasConcurrencyStamp
{ {
public Guid Id { get; set; } public Guid Id { get; set; }

3
modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Comments/CommentWithDetailsDto.cs

@ -1,11 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.ObjectExtending;
namespace Volo.CmsKit.Public.Comments; namespace Volo.CmsKit.Public.Comments;
[Serializable] [Serializable]
public class CommentWithDetailsDto : IHasConcurrencyStamp public class CommentWithDetailsDto : ExtensibleObject, IHasConcurrencyStamp
{ {
public Guid Id { get; set; } public Guid Id { get; set; }

3
modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Comments/CreateCommentInput.cs

@ -1,12 +1,13 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation; using Volo.Abp.Validation;
using Volo.CmsKit.Comments; using Volo.CmsKit.Comments;
namespace Volo.CmsKit.Public.Comments; namespace Volo.CmsKit.Public.Comments;
[Serializable] [Serializable]
public class CreateCommentInput public class CreateCommentInput: ExtensibleObject
{ {
[Required] [Required]
[DynamicStringLength(typeof(CommentConsts), nameof(CommentConsts.MaxTextLength))] [DynamicStringLength(typeof(CommentConsts), nameof(CommentConsts.MaxTextLength))]

3
modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Comments/UpdateCommentInput.cs

@ -1,13 +1,14 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation; using Volo.Abp.Validation;
using Volo.CmsKit.Comments; using Volo.CmsKit.Comments;
namespace Volo.CmsKit.Public.Comments; namespace Volo.CmsKit.Public.Comments;
[Serializable] [Serializable]
public class UpdateCommentInput : IHasConcurrencyStamp public class UpdateCommentInput : ExtensibleObject, IHasConcurrencyStamp
{ {
[Required] [Required]
[DynamicStringLength(typeof(CommentConsts), nameof(CommentConsts.MaxTextLength))] [DynamicStringLength(typeof(CommentConsts), nameof(CommentConsts.MaxTextLength))]

2
modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/GlobalResources/GlobalResourceDto.cs

@ -4,7 +4,7 @@ using Volo.Abp.Application.Dtos;
namespace Volo.CmsKit.Public.GlobalResources; namespace Volo.CmsKit.Public.GlobalResources;
[Serializable] [Serializable]
public class GlobalResourceDto : AuditedEntityDto public class GlobalResourceDto : ExtensibleAuditedEntityDto
{ {
public string Name { get; set; } public string Name { get; set; }

19
modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs

@ -19,27 +19,28 @@ public class PublicApplicationAutoMapperProfile : Profile
{ {
public PublicApplicationAutoMapperProfile() public PublicApplicationAutoMapperProfile()
{ {
CreateMap<CmsUser, Comments.CmsUserDto>(); CreateMap<CmsUser, Comments.CmsUserDto>().MapExtraProperties();
CreateMap<Comment, CommentDto>() CreateMap<Comment, CommentDto>()
.Ignore(x => x.Author); .Ignore(x => x.Author).MapExtraProperties();
CreateMap<Comment, CommentWithDetailsDto>() CreateMap<Comment, CommentWithDetailsDto>()
.Ignore(x => x.Replies) .Ignore(x => x.Replies)
.Ignore(x => x.Author); .Ignore(x => x.Author)
.MapExtraProperties();
CreateMap<Rating, RatingDto>(); CreateMap<Rating, RatingDto>();
CreateMap<Page, PageCacheItem>(); CreateMap<Page, PageCacheItem>().MapExtraProperties();
CreateMap<PageCacheItem, PageDto>(); CreateMap<PageCacheItem, PageDto>().MapExtraProperties();
CreateMap<Page, PageDto>(); CreateMap<Page, PageDto>().MapExtraProperties();
CreateMap<BlogPost, BlogPostCommonDto>(); CreateMap<BlogPost, BlogPostCommonDto>().MapExtraProperties();
CreateMap<MenuItem, MenuItemDto>(); CreateMap<MenuItem, MenuItemDto>().MapExtraProperties();
CreateMap<GlobalResource, GlobalResourceDto>(); CreateMap<GlobalResource, GlobalResourceDto>().MapExtraProperties();
} }
} }

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

@ -275,4 +275,14 @@ public class IdentityUserManager : UserManager<IdentityUser>, IDomainService
return passwordChangePeriodDays > 0 && lastPasswordChangeTime.AddDays(passwordChangePeriodDays) < DateTime.UtcNow; return passwordChangePeriodDays > 0 && lastPasswordChangeTime.AddDays(passwordChangePeriodDays) < DateTime.UtcNow;
} }
public virtual async Task ResetRecoveryCodesAsync(IdentityUser user)
{
if (!(Store is IdentityUserStore identityUserStore))
{
throw new AbpException($"Store is not an instance of {typeof(IdentityUserStore).AssemblyQualifiedName}");
}
await identityUserStore.SetTokenAsync(user, await identityUserStore.GetInternalLoginProviderAsync(), await identityUserStore.GetRecoveryCodeTokenNameAsync(), string.Empty, CancellationToken);
}
} }

15
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs

@ -1108,6 +1108,21 @@ public class IdentityUserStore :
return false; return false;
} }
public virtual Task<string> GetInternalLoginProviderAsync()
{
return Task.FromResult(InternalLoginProvider);
}
public virtual Task<string> GetAuthenticatorKeyTokenNameAsync()
{
return Task.FromResult(AuthenticatorKeyTokenName);
}
public virtual Task<string> GetRecoveryCodeTokenNameAsync()
{
return Task.FromResult(RecoveryCodeTokenName);
}
public virtual void Dispose() public virtual void Dispose()
{ {

10
npm/ng-packs/packages/oauth/src/lib/guards/oauth.guard.ts

@ -1,5 +1,5 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { UrlTree } from '@angular/router'; import { CanActivate, UrlTree, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { OAuthService } from 'angular-oauth2-oidc'; import { OAuthService } from 'angular-oauth2-oidc';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { AuthService, IAuthGuard } from '@abp/ng.core'; import { AuthService, IAuthGuard } from '@abp/ng.core';
@ -10,13 +10,17 @@ import { AuthService, IAuthGuard } from '@abp/ng.core';
export class AbpOAuthGuard implements IAuthGuard { export class AbpOAuthGuard implements IAuthGuard {
constructor(private oauthService: OAuthService, private authService: AuthService) {} constructor(private oauthService: OAuthService, private authService: AuthService) {}
canActivate(): Observable<boolean> | boolean | UrlTree { canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
): Observable<boolean> | boolean | UrlTree {
const hasValidAccessToken = this.oauthService.hasValidAccessToken(); const hasValidAccessToken = this.oauthService.hasValidAccessToken();
if (hasValidAccessToken) { if (hasValidAccessToken) {
return true; return true;
} }
this.authService.navigateToLogin(); const params = { returnUrl: state.url };
this.authService.navigateToLogin(params);
return false; return false;
} }
} }

5
npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts

@ -14,7 +14,10 @@ export class AuthCodeFlowStrategy extends AuthFlowStrategy {
} }
navigateToLogin(queryParams?: Params) { navigateToLogin(queryParams?: Params) {
this.oAuthService.initCodeFlow('', this.getCultureParams(queryParams)); const additionalState = queryParams.returnUrl;
const cultureParams = this.getCultureParams(queryParams);
this.oAuthService.initCodeFlow(additionalState, cultureParams);
} }
checkIfInternalAuth(queryParams?: Params) { checkIfInternalAuth(queryParams?: Params) {

37
npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts

@ -1,5 +1,5 @@
import { Injector } from '@angular/core'; import { Injector } from '@angular/core';
import { Params } from '@angular/router'; import { Params, Router } from '@angular/router';
import { import {
AuthConfig, AuthConfig,
OAuthErrorEvent, OAuthErrorEvent,
@ -7,7 +7,7 @@ import {
OAuthStorage, OAuthStorage,
} from 'angular-oauth2-oidc'; } from 'angular-oauth2-oidc';
import { Observable, of } from 'rxjs'; import { Observable, of } from 'rxjs';
import { filter, switchMap, tap } from 'rxjs/operators'; import { filter, map, switchMap, take, tap } from 'rxjs/operators';
import { import {
AbpLocalStorageService, AbpLocalStorageService,
ConfigStateService, ConfigStateService,
@ -32,13 +32,11 @@ export abstract class AuthFlowStrategy {
protected sessionState: SessionStateService; protected sessionState: SessionStateService;
protected localStorageService: AbpLocalStorageService; protected localStorageService: AbpLocalStorageService;
protected tenantKey: string; protected tenantKey: string;
protected router: Router;
abstract checkIfInternalAuth(queryParams?: Params): boolean; abstract checkIfInternalAuth(queryParams?: Params): boolean;
abstract navigateToLogin(queryParams?: Params): void; abstract navigateToLogin(queryParams?: Params): void;
abstract logout(queryParams?: Params): Observable<any>; abstract logout(queryParams?: Params): Observable<any>;
abstract login(params?: LoginParams | Params): Observable<any>; abstract login(params?: LoginParams | Params): Observable<any>;
private catchError = (err: HttpErrorResponse) => { private catchError = (err: HttpErrorResponse) => {
@ -55,6 +53,7 @@ export abstract class AuthFlowStrategy {
this.localStorageService = injector.get(AbpLocalStorageService); this.localStorageService = injector.get(AbpLocalStorageService);
this.oAuthConfig = this.environment.getEnvironment().oAuthConfig || {}; this.oAuthConfig = this.environment.getEnvironment().oAuthConfig || {};
this.tenantKey = injector.get(TENANT_KEY); this.tenantKey = injector.get(TENANT_KEY);
this.router = injector.get(Router);
this.listenToOauthErrors(); this.listenToOauthErrors();
} }
@ -71,6 +70,8 @@ export abstract class AuthFlowStrategy {
.pipe(filter(event => event.type === 'token_refresh_error')) .pipe(filter(event => event.type === 'token_refresh_error'))
.subscribe(() => this.navigateToLogin()); .subscribe(() => this.navigateToLogin());
this.navigateToPreviousUrl();
return this.oAuthService return this.oAuthService
.loadDiscoveryDocument() .loadDiscoveryDocument()
.then(() => { .then(() => {
@ -83,6 +84,32 @@ export abstract class AuthFlowStrategy {
.catch(this.catchError); .catch(this.catchError);
} }
protected navigateToPreviousUrl(): void {
const { responseType } = this.oAuthConfig;
if (responseType === 'code') {
this.oAuthService.events
.pipe(
filter(event => event.type === 'token_received' && !!this.oAuthService.state),
take(1),
map(() => {
const redirect_uri = decodeURIComponent(this.oAuthService.state);
if (redirect_uri && redirect_uri !== '/') {
return redirect_uri;
}
return '/';
}),
switchMap(redirectUri =>
this.configState.getOne$('currentUser').pipe(
filter(user => !!user?.isAuthenticated),
tap(() => this.router.navigate([redirectUri])),
),
),
)
.subscribe();
}
}
protected refreshToken() { protected refreshToken() {
return this.oAuthService.refreshToken().catch(() => clearOAuthStorage()); return this.oAuthService.refreshToken().catch(() => clearOAuthStorage());
} }

19
npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts

@ -123,9 +123,11 @@ export class ErrorHandler {
} }
private executeErrorHandler = (error: any) => { private executeErrorHandler = (error: any) => {
const returnValue = this.httpErrorHandler(this.injector, error); const errHandler = this.httpErrorHandler(this.injector, error);
const isObservable = errHandler instanceof Observable;
const response = isObservable ? errHandler : of(null);
return (returnValue instanceof Observable ? returnValue : of(null)).pipe( return response.pipe(
catchError(err => { catchError(err => {
this.handleError(err); this.handleError(err);
return of(null); return of(null);
@ -139,6 +141,11 @@ export class ErrorHandler {
defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title, defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title,
}; };
if (err instanceof HttpErrorResponse && err.headers.get('Abp-Tenant-Resolve-Error')) {
this.authService.logout().subscribe();
return;
}
if (err instanceof HttpErrorResponse && err.headers.get('_AbpErrorFormat')) { if (err instanceof HttpErrorResponse && err.headers.get('_AbpErrorFormat')) {
const confirmation$ = this.showErrorWithRequestBody(body); const confirmation$ = this.showErrorWithRequestBody(body);
@ -147,8 +154,6 @@ export class ErrorHandler {
this.navigateToLogin(); this.navigateToLogin();
}); });
} }
} if(err instanceof HttpErrorResponse && err.headers.get('Abp-Tenant-Resolve-Error')){
this.authService.logout().subscribe();
} else { } else {
switch (err.status) { switch (err.status) {
case 401: case 401:
@ -178,7 +183,7 @@ export class ErrorHandler {
status: 403, status: 403,
}); });
break; break;
case 404:{ case 404:
this.canCreateCustomError(404) this.canCreateCustomError(404)
? this.show404Page() ? this.show404Page()
: this.showError( : this.showError(
@ -191,9 +196,7 @@ export class ErrorHandler {
defaultValue: DEFAULT_ERROR_MESSAGES.defaultError404.title, defaultValue: DEFAULT_ERROR_MESSAGES.defaultError404.title,
}, },
); );
break; break;
}
case 500: case 500:
this.createErrorComponent({ this.createErrorComponent({
title: { title: {

Loading…
Cancel
Save