Browse Source

Merge branch 'dev' into pr/11962-2

pull/12088/head
Enis Necipoglu 5 years ago
parent
commit
b8d5c0b8e8
  1. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
  2. 14
      framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Microsoft/AspNetCore/Authentication/OAuth/Claims/AbpClaimActionCollectionExtensions.cs
  3. 4
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js
  4. 4
      framework/src/Volo.Abp.Core/Volo/Abp/Localization/CultureHelper.cs
  5. 56
      framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpLocalization_Tests.cs
  6. 12
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs
  7. 2
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostGetListInput.cs
  8. 5
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs
  9. 7
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs
  10. 12
      modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs
  11. 25
      modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs
  12. 9
      modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostGetListInput.cs
  13. 8
      modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs
  14. 15
      modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs
  15. 13
      modules/cms-kit/src/Volo.CmsKit.Public.HttpApi.Client/ClientProxies/BlogPostPublicClientProxy.Generated.cs
  16. 13
      modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs
  17. 4
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml
  18. 41
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/Index.cshtml
  19. 14
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/Index.cshtml.cs
  20. 4
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/index.css
  21. 18
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/index.js
  22. 58
      modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostPublicAppService_Tests.cs
  23. 10
      modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogPostRepository_Test.cs

3
abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json

@ -380,6 +380,7 @@
"PurchaseItems": "Purchase Items",
"SuccessfullyUpdated": "Successfully updated",
"SuccessfullyAdded": "Successfully added",
"PurchaseState": "Purchase State"
"PurchaseState": "Purchase State",
"ShowBetweenDayCount": "Show Between Days"
}
}

14
framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Microsoft/AspNetCore/Authentication/OAuth/Claims/AbpClaimActionCollectionExtensions.cs

@ -13,6 +13,20 @@ public static class AbpClaimActionCollectionExtensions
claimActions.DeleteClaim("name");
claimActions.RemoveDuplicate(AbpClaimTypes.UserName);
}
if (AbpClaimTypes.Name != "given_name")
{
claimActions.MapJsonKey(AbpClaimTypes.Name, "given_name");
claimActions.DeleteClaim("given_name");
claimActions.RemoveDuplicate(AbpClaimTypes.Name);
}
if (AbpClaimTypes.SurName != "family_name")
{
claimActions.MapJsonKey(AbpClaimTypes.SurName, "family_name");
claimActions.DeleteClaim("family_name");
claimActions.RemoveDuplicate(AbpClaimTypes.SurName);
}
if (AbpClaimTypes.Email != "email")
{

4
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js

@ -431,9 +431,7 @@ var abp = abp || {};
configuration.language = datatables.defaultConfigurations.language();
if(configuration.dom){
configuration.dom += datatables.defaultConfigurations.dom;
}else{
if(!configuration.dom){
configuration.dom = datatables.defaultConfigurations.dom;
}

4
framework/src/Volo.Abp.Core/Volo/Abp/Localization/CultureHelper.cs

@ -57,8 +57,6 @@ public static class CultureHelper
public static string GetBaseCultureName(string cultureName)
{
return cultureName.Contains("-")
? cultureName.Left(cultureName.IndexOf("-", StringComparison.Ordinal))
: cultureName;
return new CultureInfo(cultureName).Parent.Name;
}
}

56
framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpLocalization_Tests.cs

@ -1,4 +1,4 @@
using System.Globalization;
using System.Globalization;
using System.Linq;
using Microsoft.Extensions.Localization;
using Shouldly;
@ -183,6 +183,60 @@ public class AbpLocalization_Tests : AbpIntegratedTest<AbpLocalization_Tests.Tes
{
_localizer["CarPlural"].Value.ShouldBe("Autos");
}
using (CultureHelper.Use(CultureInfo.GetCultureInfo("zh-Hans")))
{
_localizer["Car"].Value.ShouldBe("汽车");
}
using (CultureHelper.Use(CultureInfo.GetCultureInfo("zh-Hans")))
{
_localizer["CarPlural"].Value.ShouldBe("汽车");
}
using (CultureHelper.Use(CultureInfo.GetCultureInfo("zh-CN")))
{
_localizer["Car"].Value.ShouldBe("汽车");
}
using (CultureHelper.Use(CultureInfo.GetCultureInfo("zh-CN")))
{
_localizer["CarPlural"].Value.ShouldBe("汽车");
}
using (CultureHelper.Use(CultureInfo.GetCultureInfo("zh-Hans-CN")))
{
_localizer["Car"].Value.ShouldBe("汽车");
}
using (CultureHelper.Use(CultureInfo.GetCultureInfo("zh-Hans-CN")))
{
_localizer["CarPlural"].Value.ShouldBe("汽车");
}
using (CultureHelper.Use(CultureInfo.GetCultureInfo("zh-Hant")))
{
_localizer["Car"].Value.ShouldBe("汽車");
}
using (CultureHelper.Use(CultureInfo.GetCultureInfo("zh-Hant")))
{
_localizer["CarPlural"].Value.ShouldBe("汽車");
}
using (CultureHelper.Use(CultureInfo.GetCultureInfo("zh-TW")))
{
_localizer["Car"].Value.ShouldBe("汽車");
}
using (CultureHelper.Use(CultureInfo.GetCultureInfo("zh-TW")))
{
_localizer["CarPlural"].Value.ShouldBe("汽車");
}
using (CultureHelper.Use(CultureInfo.GetCultureInfo("zh-Hant-TW")))
{
_localizer["Car"].Value.ShouldBe("汽車");
}
using (CultureHelper.Use(CultureInfo.GetCultureInfo("zh-Hant-TW")))
{
_localizer["CarPlural"].Value.ShouldBe("汽車");
}
}
[Fact]

12
modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs

@ -277,6 +277,18 @@ public class LoginModel : AccountPageModel
CheckIdentityErrors(await UserManager.SetEmailAsync(user, emailAddress));
CheckIdentityErrors(await UserManager.AddLoginAsync(user, info));
CheckIdentityErrors(await UserManager.AddDefaultRolesAsync(user));
user.Name = info.Principal.FindFirstValue(AbpClaimTypes.Name);
user.Surname = info.Principal.FindFirstValue(AbpClaimTypes.SurName);
var phoneNumber = info.Principal.FindFirstValue(AbpClaimTypes.PhoneNumber);
if (!phoneNumber.IsNullOrWhiteSpace())
{
var phoneNumberConfirmed = string.Equals(info.Principal.FindFirstValue(AbpClaimTypes.PhoneNumberVerified), "true", StringComparison.InvariantCultureIgnoreCase);
user.SetPhoneNumber(phoneNumber, phoneNumberConfirmed);
}
await UserManager.UpdateAsync(user);
return user;
}

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

@ -8,4 +8,6 @@ public class BlogPostGetListInput : PagedAndSortedResultRequestDto
public string Filter { get; set; }
public Guid? BlogId { get; set; }
public Guid? AuthorId { get; set; }
}

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

@ -94,9 +94,10 @@ public class BlogPostAdminAppService : CmsKitAppServiceBase, IBlogPostAdminAppSe
{
var blogs = (await BlogRepository.GetListAsync()).ToDictionary(x => x.Id);
var blogPosts = await BlogPostRepository.GetListAsync(input.Filter, input.BlogId, input.MaxResultCount, input.SkipCount, input.Sorting);
var blogPosts = await BlogPostRepository.GetListAsync(input.Filter, input.BlogId, input.AuthorId,
input.MaxResultCount, input.SkipCount, input.Sorting);
var count = await BlogPostRepository.GetCountAsync(input.Filter);
var count = await BlogPostRepository.GetCountAsync(input.Filter, input.BlogId, input.AuthorId);
var dtoList = blogPosts.Select(x =>
{

7
modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
using Volo.CmsKit.Users;
namespace Volo.CmsKit.Blogs;
@ -11,11 +12,13 @@ public interface IBlogPostRepository : IBasicRepository<BlogPost, Guid>
Task<int> GetCountAsync(
string filter = null,
Guid? blogId = null,
Guid? authorId = null,
CancellationToken cancellationToken = default);
Task<List<BlogPost>> GetListAsync(
string filter = null,
Guid? blogId = null,
Guid? authorId = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
string sorting = null,
@ -24,4 +27,6 @@ public interface IBlogPostRepository : IBasicRepository<BlogPost, Guid>
Task<bool> SlugExistsAsync(Guid blogId, string slug, CancellationToken cancellationToken = default);
Task<BlogPost> GetBySlugAsync(Guid blogId, string slug, CancellationToken cancellationToken = default);
}
Task<List<CmsUser>> GetAuthorsHasBlogPosts(CancellationToken cancellationToken = default);
}

12
modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs

@ -41,10 +41,12 @@ public class EfCoreBlogPostRepository : EfCoreRepository<CmsKitDbContext, BlogPo
public virtual async Task<int> GetCountAsync(
string filter = null,
Guid? blogId = null,
Guid? authorId = null,
CancellationToken cancellationToken = default)
{
var queryable = (await GetDbSetAsync())
.WhereIf(blogId.HasValue, x => x.BlogId == blogId)
.WhereIf(authorId.HasValue, x => x.AuthorId == authorId)
.WhereIf(!string.IsNullOrEmpty(filter), x => x.Title.Contains(filter) || x.Slug.Contains(filter));
var count = await queryable.CountAsync(GetCancellationToken(cancellationToken));
@ -54,6 +56,7 @@ public class EfCoreBlogPostRepository : EfCoreRepository<CmsKitDbContext, BlogPo
public virtual async Task<List<BlogPost>> GetListAsync(
string filter = null,
Guid? blogId = null,
Guid? authorId = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
string sorting = null,
@ -66,7 +69,8 @@ public class EfCoreBlogPostRepository : EfCoreRepository<CmsKitDbContext, BlogPo
var queryable = blogPostsDbSet
.WhereIf(blogId.HasValue, x => x.BlogId == blogId)
.WhereIf(!string.IsNullOrWhiteSpace(filter), x => x.Title.Contains(filter) || x.Slug.Contains(filter));
.WhereIf(!string.IsNullOrWhiteSpace(filter), x => x.Title.Contains(filter) || x.Slug.Contains(filter))
.WhereIf(authorId.HasValue, x => x.AuthorId == authorId);
queryable = queryable.OrderBy(sorting.IsNullOrEmpty() ? $"{nameof(BlogPost.CreationTime)} desc" : sorting);
@ -95,4 +99,10 @@ public class EfCoreBlogPostRepository : EfCoreRepository<CmsKitDbContext, BlogPo
return await (await GetDbSetAsync()).AnyAsync(x => x.BlogId == blogId && x.Slug.ToLower() == slug,
GetCancellationToken(cancellationToken));
}
public async Task<List<CmsUser>> GetAuthorsHasBlogPosts(CancellationToken cancellationToken = default)
{
return await (await GetDbContextAsync()).BlogPosts.Select(x => x.Author).Distinct()
.ToListAsync(GetCancellationToken(cancellationToken));
}
}

25
modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs

@ -42,6 +42,7 @@ public class MongoBlogPostRepository : MongoDbRepository<CmsKitMongoDbContext, B
public virtual async Task<int> GetCountAsync(
string filter = null,
Guid? blogId = null,
Guid? authorId = null,
CancellationToken cancellationToken = default)
{
cancellationToken = GetCancellationToken(cancellationToken);
@ -49,12 +50,15 @@ public class MongoBlogPostRepository : MongoDbRepository<CmsKitMongoDbContext, B
return await (await GetMongoQueryableAsync(cancellationToken))
.WhereIf<BlogPost, IMongoQueryable<BlogPost>>(!string.IsNullOrWhiteSpace(filter), x => x.Title.Contains(filter) || x.Slug.Contains(filter))
.WhereIf<BlogPost, IMongoQueryable<BlogPost>>(blogId.HasValue, x => x.BlogId == blogId)
.WhereIf<BlogPost, IMongoQueryable<BlogPost>>(authorId.HasValue, x => x.AuthorId == authorId)
.CountAsync(cancellationToken);
}
public virtual async Task<List<BlogPost>> GetListAsync(
string filter = null,
Guid? blogId = null,
Guid? authorId = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
string sorting = null,
@ -68,7 +72,8 @@ public class MongoBlogPostRepository : MongoDbRepository<CmsKitMongoDbContext, B
var queryable = blogPostQueryable
.WhereIf(blogId.HasValue, x => x.BlogId == blogId)
.WhereIf(!string.IsNullOrWhiteSpace(filter), x => x.Title.Contains(filter) || x.Slug.Contains(filter));
.WhereIf(!string.IsNullOrWhiteSpace(filter), x => x.Title.Contains(filter) || x.Slug.Contains(filter))
.WhereIf(authorId.HasValue, x => x.AuthorId == authorId);
queryable = queryable.OrderBy(sorting.IsNullOrEmpty() ? $"{nameof(BlogPost.CreationTime)} desc" : sorting);
@ -99,4 +104,22 @@ public class MongoBlogPostRepository : MongoDbRepository<CmsKitMongoDbContext, B
var queryable = await GetMongoQueryableAsync(cancellationToken);
return await queryable.AnyAsync(x => x.BlogId == blogId && x.Slug.ToLower() == slug, cancellationToken);
}
public async Task<List<CmsUser>> GetAuthorsHasBlogPosts(CancellationToken cancellationToken = default)
{
var blogPostQueryable = (await GetQueryableAsync());
var usersQueryable = (await GetDbContextAsync()).Collection<CmsUser>().AsQueryable();
var queryable = blogPostQueryable
.Join(
usersQueryable,
o => o.AuthorId,
i => i.Id,
(blogPost, user) => new { blogPost, user })
.Select(s => s.user)
.Distinct();
return await AsyncExecuter.ToListAsync(queryable, GetCancellationToken(cancellationToken));
}
}

9
modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostGetListInput.cs

@ -0,0 +1,9 @@
using System;
using Volo.Abp.Application.Dtos;
namespace Volo.CmsKit.Public.Blogs;
public class BlogPostGetListInput : PagedAndSortedResultRequestDto
{
public Guid? AuthorId { get; set; }
}

8
modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs

@ -1,13 +1,17 @@
using JetBrains.Annotations;
using System.Collections.Generic;
using JetBrains.Annotations;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.CmsKit.Users;
namespace Volo.CmsKit.Public.Blogs;
public interface IBlogPostPublicAppService : IApplicationService
{
Task<PagedResultDto<BlogPostPublicDto>> GetListAsync([NotNull] string blogSlug, PagedAndSortedResultRequestDto input);
Task<PagedResultDto<BlogPostPublicDto>> GetListAsync([NotNull] string blogSlug, BlogPostGetListInput input);
Task<BlogPostPublicDto> GetAsync([NotNull] string blogSlug, [NotNull] string blogPostSlug);
Task<List<CmsUserDto>> GetAuthorsHasBlogPostsAsync();
}

15
modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs

@ -5,6 +5,7 @@ using Volo.Abp.Application.Dtos;
using Volo.Abp.GlobalFeatures;
using Volo.CmsKit.Blogs;
using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Users;
namespace Volo.CmsKit.Public.Blogs;
@ -14,6 +15,7 @@ public class BlogPostPublicAppService : CmsKitPublicAppServiceBase, IBlogPostPub
protected IBlogRepository BlogRepository { get; }
protected IBlogPostRepository BlogPostRepository { get; }
public BlogPostPublicAppService(
IBlogRepository blogRepository,
@ -32,14 +34,21 @@ public class BlogPostPublicAppService : CmsKitPublicAppServiceBase, IBlogPostPub
return ObjectMapper.Map<BlogPost, BlogPostPublicDto>(blogPost);
}
public virtual async Task<PagedResultDto<BlogPostPublicDto>> GetListAsync([NotNull] string blogSlug, PagedAndSortedResultRequestDto input)
public virtual async Task<PagedResultDto<BlogPostPublicDto>> GetListAsync([NotNull] string blogSlug, BlogPostGetListInput input)
{
var blog = await BlogRepository.GetBySlugAsync(blogSlug);
var blogPosts = await BlogPostRepository.GetListAsync(null, blog.Id, input.MaxResultCount, input.SkipCount, input.Sorting);
var blogPosts = await BlogPostRepository.GetListAsync(null, blog.Id, input.AuthorId, input.MaxResultCount,
input.SkipCount, input.Sorting);
return new PagedResultDto<BlogPostPublicDto>(
await BlogPostRepository.GetCountAsync(blogId: blog.Id),
await BlogPostRepository.GetCountAsync(blogId: blog.Id, authorId: input.AuthorId),
ObjectMapper.Map<List<BlogPost>, List<BlogPostPublicDto>>(blogPosts));
}
public virtual async Task<List<CmsUserDto>> GetAuthorsHasBlogPostsAsync()
{
var authors = await BlogPostRepository.GetAuthorsHasBlogPosts();
return ObjectMapper.Map<List<CmsUser>, List<CmsUserDto>>(authors);
}
}

13
modules/cms-kit/src/Volo.CmsKit.Public.HttpApi.Client/ClientProxies/BlogPostPublicClientProxy.Generated.cs

@ -1,5 +1,6 @@
// This file is automatically generated by ABP framework to use MVC Controllers from CSharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Http.Client;
@ -7,6 +8,7 @@ using Volo.Abp.Http.Modeling;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client.ClientProxying;
using Volo.CmsKit.Public.Blogs;
using Volo.CmsKit.Users;
// ReSharper disable once CheckNamespace
namespace Volo.CmsKit.Public.Blogs.ClientProxies;
@ -23,13 +25,18 @@ public partial class BlogPostPublicClientProxy : ClientProxyBase<IBlogPostPublic
{ typeof(string), blogPostSlug }
});
}
public virtual async Task<PagedResultDto<BlogPostPublicDto>> GetListAsync(string blogSlug, PagedAndSortedResultRequestDto input)
public virtual async Task<PagedResultDto<BlogPostPublicDto>> GetListAsync(string blogSlug, BlogPostGetListInput input)
{
return await RequestAsync<PagedResultDto<BlogPostPublicDto>>(nameof(GetListAsync), new ClientProxyRequestTypeValue
{
{ typeof(string), blogSlug },
{ typeof(PagedAndSortedResultRequestDto), input }
{ typeof(BlogPostGetListInput), input }
});
}
public virtual async Task<List<CmsUserDto>> GetAuthorsHasBlogPostsAsync()
{
return await RequestAsync<List<CmsUserDto>>(nameof(GetAuthorsHasBlogPostsAsync));
}
}

13
modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs

@ -1,11 +1,13 @@
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Content;
using Volo.Abp.GlobalFeatures;
using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Users;
namespace Volo.CmsKit.Public.Blogs;
@ -31,8 +33,15 @@ public class BlogPostPublicController : CmsKitPublicControllerBase, IBlogPostPub
[HttpGet]
[Route("{blogSlug}")]
public virtual Task<PagedResultDto<BlogPostPublicDto>> GetListAsync(string blogSlug, PagedAndSortedResultRequestDto input)
public virtual Task<PagedResultDto<BlogPostPublicDto>> GetListAsync(string blogSlug, BlogPostGetListInput input)
{
return BlogPostPublicAppService.GetListAsync(blogSlug, input);
}
}
[HttpGet]
[Route("authors")]
public virtual Task<List<CmsUserDto>> GetAuthorsHasBlogPostsAsync()
{
return BlogPostPublicAppService.GetAuthorsHasBlogPostsAsync();
}
}

4
modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml

@ -41,7 +41,9 @@
<div class="col-lg-8 col-md-10 mx-auto pb-4">
<h1 class="mt-lg-4 mt-md-3">@Model.BlogPost.Title</h1>
<p class="mb-lg-5 mb-md-3">
<span class="font-weight-bold">@@@Model.BlogPost.Author?.UserName</span>
<a href="/blogs/@Model.BlogSlug?authorId=@Model.BlogPost.Author.Id">
<span class="font-weight-bold">@@@Model.BlogPost.Author?.UserName</span>
</a>
<small style="opacity:.65;">@Model.BlogPost.CreationTime</small>
</p>

41
modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/Index.cshtml

@ -8,12 +8,40 @@
@model IndexModel
@section styles{
<abp-style src="/Pages/Public/CmsKit/Blogs/index.css" />
<abp-style src="/Pages/Public/CmsKit/Blogs/index.css"/>
}
@section scripts {
<abp-script-bundle>
<abp-script src="/Pages/Public/CmsKit/Blogs/index.js"/>
</abp-script-bundle>
}
@{
const string dummyImageSource = "https://dummyimage.com/320x180/a3a3a3/fff.png";
}
<abp-row id="blogs-filter-area">
<abp-column size="_4">
<div class="mb-3">
<label class="form-label" asp-for="@Model.Authors"></label>
<select id="AuthorSelect" class="form-select">
<option value="">@L["SelectAnAuthor"]</option>
@foreach (var author in Model.Authors)
{
if (author.Id == Model.AuthorId)
{
<option value="@author.Id" selected>@author.Name @author.Surname</option>
}
else
{
<option value="@author.Id">@author.Name @author.Surname</option>
}
}
</select>
</div>
</abp-column>
</abp-row>
<abp-row id="blogs-container">
@foreach (var blog in Model.Blogs.Items)
{
@ -21,16 +49,16 @@
<abp-card>
@if (blog.CoverImageMediaId != null)
{
<img src="/api/cms-kit/media/@blog.CoverImageMediaId" class="card-img-top" onerror="this.src='@dummyImageSource'" />
<img src="/api/cms-kit/media/@blog.CoverImageMediaId" class="card-img-top" onerror="this.src='@dummyImageSource'"/>
}
else
{
<img src="@(dummyImageSource)?text=@blog.Title" class="card-img-top" />
<img src="@(dummyImageSource)?text=@blog.Title" class="card-img-top"/>
}
<abp-card-body class="p-4">
<h5>@blog.Title</h5>
<p class="mb-2">
<span class="font-weight-bold">@@@blog.Author?.UserName</span>
<span class="font-weight-bold author-name-span" data-author-id="@blog.Author.Id">@@@blog.Author?.UserName</span>
<small style="opacity:.65;">@blog.CreationTime</small>
</p>
<p style="min-height: 60px;">@blog.ShortDescription</p>
@ -42,11 +70,10 @@
</abp-card-body>
</abp-card>
</abp-column>
}
</abp-row>
<abp-row>
<abp-column>
<abp-paginator model="Model.PagerModel" />
<abp-paginator model="Model.PagerModel"/>
</abp-column>
</abp-row>
</abp-row>

14
modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/Index.cshtml.cs

@ -7,6 +7,7 @@ using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Pagination;
using Volo.CmsKit.Public.Blogs;
using Volo.CmsKit.Users;
namespace Volo.CmsKit.Public.Web.Pages.Public.CmsKit.Blogs;
@ -19,10 +20,16 @@ public class IndexModel : CmsKitPublicPageModelBase
[BindProperty(SupportsGet = true)]
public int CurrentPage { get; set; } = 1;
[BindProperty(SupportsGet = true)]
public Guid? AuthorId { get; set; }
public PagedResultDto<BlogPostPublicDto> Blogs { get; private set; }
public PagerModel PagerModel => new PagerModel(Blogs.TotalCount, Blogs.Items.Count, CurrentPage, PageSize, Request.Path.ToString());
[BindProperty(SupportsGet = true)]
public List<CmsUserDto> Authors { get; set; }
protected IBlogPostPublicAppService BlogPostPublicAppService { get; }
@ -35,10 +42,13 @@ public class IndexModel : CmsKitPublicPageModelBase
{
Blogs = await BlogPostPublicAppService.GetListAsync(
BlogSlug,
new PagedAndSortedResultRequestDto
new BlogPostGetListInput
{
SkipCount = PageSize * (CurrentPage - 1),
MaxResultCount = PageSize
MaxResultCount = PageSize,
AuthorId = AuthorId
});
Authors = await BlogPostPublicAppService.GetAuthorsHasBlogPostsAsync();
}
}

4
modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/index.css

@ -3,4 +3,8 @@
.popover {
min-width: 276px;
}
.author-name-span{
cursor: pointer;
}

18
modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/index.js

@ -0,0 +1,18 @@
$(function () {
var $selectAuthor = $('#AuthorSelect');
var $authorNameSpan = $('.author-name-span');
$selectAuthor.on('change', function () {
var authorId = $selectAuthor.val();
reloadPageWithQueryString({'authorId': authorId});
});
$authorNameSpan.click(function () {
var authorId = $(this).data('author-id');
reloadPageWithQueryString({'authorId': authorId});
});
function reloadPageWithQueryString(param) {
window.location.href = window.location.pathname + "?" + $.param(param);
}
});

58
modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostPublicAppService_Tests.cs

@ -7,6 +7,7 @@ using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Entities;
using Volo.CmsKit.Public.Blogs;
using Volo.CmsKit.Users;
using Xunit;
namespace Volo.CmsKit.Blogs;
@ -17,16 +18,26 @@ public class BlogPostPublicAppService_Tests : CmsKitApplicationTestBase
private readonly CmsKitTestData cmsKitTestData;
private readonly ICmsUserRepository userRepository;
private readonly IBlogRepository blogRepository;
private readonly IBlogPostRepository blogPostRepository;
private readonly BlogPostManager blogPostManager;
public BlogPostPublicAppService_Tests()
{
blogPostAppService = GetRequiredService<IBlogPostPublicAppService>();
cmsKitTestData = GetRequiredService<CmsKitTestData>();
userRepository = GetRequiredService<ICmsUserRepository>();
blogRepository = GetRequiredService<IBlogRepository>();
blogPostManager = GetRequiredService<BlogPostManager>();
blogPostRepository = GetRequiredService<IBlogPostRepository>();
}
[Fact]
public async Task GetListAsync_ShouldWorkProperly_WithExistingBlog()
{
var blogPosts = await blogPostAppService.GetListAsync(cmsKitTestData.BlogSlug, new PagedAndSortedResultRequestDto { MaxResultCount = 2 });
var blogPosts = await blogPostAppService.GetListAsync(cmsKitTestData.BlogSlug, new BlogPostGetListInput { MaxResultCount = 2 });
blogPosts.ShouldNotBeNull();
blogPosts.TotalCount.ShouldBe(2);
@ -62,4 +73,49 @@ public class BlogPostPublicAppService_Tests : CmsKitApplicationTestBase
exception.EntityType.ShouldBe(typeof(Blog));
}
[Fact]
public async Task GetListAsync_ShouldFilterByUser()
{
var user2 = await userRepository.GetAsync(cmsKitTestData.User2Id);
var blog = await blogRepository.GetAsync(cmsKitTestData.Blog_Id);
var blogPost = await blogPostManager.CreateAsync(
user2,
blog,
cmsKitTestData.BlogPost_1_Title + "by user2",
cmsKitTestData.BlogPost_1_Slug + "by user2",
"Short desc 1",
"Blog Post 1 Content"
);
await blogPostRepository.InsertAsync(blogPost);
//should get all not filtered by user
var blogPosts = await blogPostAppService.GetListAsync(cmsKitTestData.BlogSlug,
new BlogPostGetListInput {});
blogPosts.ShouldNotBeNull();
blogPosts.TotalCount.ShouldBe(3);
blogPosts.Items.ShouldNotBeEmpty();
blogPosts.Items.Count.ShouldBe(3);
//should get only one filtered by user
blogPosts = await blogPostAppService.GetListAsync(cmsKitTestData.BlogSlug,
new BlogPostGetListInput {AuthorId = user2.Id});
blogPosts.ShouldNotBeNull();
blogPosts.TotalCount.ShouldBe(1);
blogPosts.Items.ShouldNotBeEmpty();
blogPosts.Items.Count.ShouldBe(1);
//should get filtered by user1
blogPosts = await blogPostAppService.GetListAsync(cmsKitTestData.BlogSlug,
new BlogPostGetListInput {AuthorId = cmsKitTestData.User1Id});
blogPosts.ShouldNotBeNull();
blogPosts.TotalCount.ShouldBe(2);
blogPosts.Items.ShouldNotBeEmpty();
blogPosts.Items.Count.ShouldBe(2);
}
}

10
modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogPostRepository_Test.cs

@ -145,4 +145,14 @@ public abstract class BlogPostRepository_Test<TStartupModule> : CmsKitTestBase<T
result.ShouldNotBeEmpty();
result.Count.ShouldBe(2);
}
[Fact]
public async Task GetAuthorsHasBlogPosts_ShouldWorkProperly()
{
var authors = await blogPostRepository.GetAuthorsHasBlogPosts();
authors.ShouldNotBeNull();
authors.ShouldNotBeEmpty();
authors.ShouldContain(x => x.Id == testData.User1Id);
}
}

Loading…
Cancel
Save