Browse Source

Merge pull request #12048 from abpframework/pr/11960

CmsKit - Filter by User
pull/12111/head
Enis Necipoglu 5 years ago
committed by GitHub
parent
commit
618d8fe33e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostGetListInput.cs
  2. 5
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs
  3. 7
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs
  4. 12
      modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs
  5. 25
      modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs
  6. 9
      modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostGetListInput.cs
  7. 8
      modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs
  8. 15
      modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs
  9. 13
      modules/cms-kit/src/Volo.CmsKit.Public.HttpApi.Client/ClientProxies/BlogPostPublicClientProxy.Generated.cs
  10. 13
      modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs
  11. 4
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml
  12. 41
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/Index.cshtml
  13. 14
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/Index.cshtml.cs
  14. 4
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/index.css
  15. 18
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/index.js
  16. 58
      modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostPublicAppService_Tests.cs
  17. 10
      modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogPostRepository_Test.cs

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 string Filter { get; set; }
public Guid? BlogId { 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

@ -89,9 +89,10 @@ public class BlogPostAdminAppService : CmsKitAppServiceBase, IBlogPostAdminAppSe
{ {
var blogs = (await BlogRepository.GetListAsync()).ToDictionary(x => x.Id); 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 => 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;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Repositories;
using Volo.CmsKit.Users;
namespace Volo.CmsKit.Blogs; namespace Volo.CmsKit.Blogs;
@ -11,11 +12,13 @@ public interface IBlogPostRepository : IBasicRepository<BlogPost, Guid>
Task<int> GetCountAsync( Task<int> GetCountAsync(
string filter = null, string filter = null,
Guid? blogId = null, Guid? blogId = null,
Guid? authorId = null,
CancellationToken cancellationToken = default); CancellationToken cancellationToken = default);
Task<List<BlogPost>> GetListAsync( Task<List<BlogPost>> GetListAsync(
string filter = null, string filter = null,
Guid? blogId = null, Guid? blogId = null,
Guid? authorId = null,
int maxResultCount = int.MaxValue, int maxResultCount = int.MaxValue,
int skipCount = 0, int skipCount = 0,
string sorting = null, string sorting = null,
@ -24,4 +27,6 @@ public interface IBlogPostRepository : IBasicRepository<BlogPost, Guid>
Task<bool> SlugExistsAsync(Guid blogId, string slug, CancellationToken cancellationToken = default); Task<bool> SlugExistsAsync(Guid blogId, string slug, CancellationToken cancellationToken = default);
Task<BlogPost> GetBySlugAsync(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( public virtual async Task<int> GetCountAsync(
string filter = null, string filter = null,
Guid? blogId = null, Guid? blogId = null,
Guid? authorId = null,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
var queryable = (await GetDbSetAsync()) var queryable = (await GetDbSetAsync())
.WhereIf(blogId.HasValue, x => x.BlogId == blogId) .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)); .WhereIf(!string.IsNullOrEmpty(filter), x => x.Title.Contains(filter) || x.Slug.Contains(filter));
var count = await queryable.CountAsync(GetCancellationToken(cancellationToken)); var count = await queryable.CountAsync(GetCancellationToken(cancellationToken));
@ -54,6 +56,7 @@ public class EfCoreBlogPostRepository : EfCoreRepository<CmsKitDbContext, BlogPo
public virtual async Task<List<BlogPost>> GetListAsync( public virtual async Task<List<BlogPost>> GetListAsync(
string filter = null, string filter = null,
Guid? blogId = null, Guid? blogId = null,
Guid? authorId = null,
int maxResultCount = int.MaxValue, int maxResultCount = int.MaxValue,
int skipCount = 0, int skipCount = 0,
string sorting = null, string sorting = null,
@ -66,7 +69,8 @@ public class EfCoreBlogPostRepository : EfCoreRepository<CmsKitDbContext, BlogPo
var queryable = blogPostsDbSet var queryable = blogPostsDbSet
.WhereIf(blogId.HasValue, x => x.BlogId == blogId) .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); 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, return await (await GetDbSetAsync()).AnyAsync(x => x.BlogId == blogId && x.Slug.ToLower() == slug,
GetCancellationToken(cancellationToken)); 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( public virtual async Task<int> GetCountAsync(
string filter = null, string filter = null,
Guid? blogId = null, Guid? blogId = null,
Guid? authorId = null,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
cancellationToken = GetCancellationToken(cancellationToken); cancellationToken = GetCancellationToken(cancellationToken);
@ -49,12 +50,15 @@ public class MongoBlogPostRepository : MongoDbRepository<CmsKitMongoDbContext, B
return await (await GetMongoQueryableAsync(cancellationToken)) 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>>(!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>>(blogId.HasValue, x => x.BlogId == blogId)
.WhereIf<BlogPost, IMongoQueryable<BlogPost>>(authorId.HasValue, x => x.AuthorId == authorId)
.CountAsync(cancellationToken); .CountAsync(cancellationToken);
} }
public virtual async Task<List<BlogPost>> GetListAsync( public virtual async Task<List<BlogPost>> GetListAsync(
string filter = null, string filter = null,
Guid? blogId = null, Guid? blogId = null,
Guid? authorId = null,
int maxResultCount = int.MaxValue, int maxResultCount = int.MaxValue,
int skipCount = 0, int skipCount = 0,
string sorting = null, string sorting = null,
@ -68,7 +72,8 @@ public class MongoBlogPostRepository : MongoDbRepository<CmsKitMongoDbContext, B
var queryable = blogPostQueryable var queryable = blogPostQueryable
.WhereIf(blogId.HasValue, x => x.BlogId == blogId) .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); 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); var queryable = await GetMongoQueryableAsync(cancellationToken);
return await queryable.AnyAsync(x => x.BlogId == blogId && x.Slug.ToLower() == slug, 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 System.Threading.Tasks;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
using Volo.CmsKit.Users;
namespace Volo.CmsKit.Public.Blogs; namespace Volo.CmsKit.Public.Blogs;
public interface IBlogPostPublicAppService : IApplicationService 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<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.Abp.GlobalFeatures;
using Volo.CmsKit.Blogs; using Volo.CmsKit.Blogs;
using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Users;
namespace Volo.CmsKit.Public.Blogs; namespace Volo.CmsKit.Public.Blogs;
@ -14,6 +15,7 @@ public class BlogPostPublicAppService : CmsKitPublicAppServiceBase, IBlogPostPub
protected IBlogRepository BlogRepository { get; } protected IBlogRepository BlogRepository { get; }
protected IBlogPostRepository BlogPostRepository { get; } protected IBlogPostRepository BlogPostRepository { get; }
public BlogPostPublicAppService( public BlogPostPublicAppService(
IBlogRepository blogRepository, IBlogRepository blogRepository,
@ -32,14 +34,21 @@ public class BlogPostPublicAppService : CmsKitPublicAppServiceBase, IBlogPostPub
return ObjectMapper.Map<BlogPost, BlogPostPublicDto>(blogPost); 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 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>( 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)); 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 // This file is automatically generated by ABP framework to use MVC Controllers from CSharp
using System; using System;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.Http.Client; using Volo.Abp.Http.Client;
@ -7,6 +8,7 @@ using Volo.Abp.Http.Modeling;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client.ClientProxying; using Volo.Abp.Http.Client.ClientProxying;
using Volo.CmsKit.Public.Blogs; using Volo.CmsKit.Public.Blogs;
using Volo.CmsKit.Users;
// ReSharper disable once CheckNamespace // ReSharper disable once CheckNamespace
namespace Volo.CmsKit.Public.Blogs.ClientProxies; namespace Volo.CmsKit.Public.Blogs.ClientProxies;
@ -23,13 +25,18 @@ public partial class BlogPostPublicClientProxy : ClientProxyBase<IBlogPostPublic
{ typeof(string), blogPostSlug } { 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 return await RequestAsync<PagedResultDto<BlogPostPublicDto>>(nameof(GetListAsync), new ClientProxyRequestTypeValue
{ {
{ typeof(string), blogSlug }, { 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 Microsoft.AspNetCore.Mvc;
using System; using System;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.Content; using Volo.Abp.Content;
using Volo.Abp.GlobalFeatures; using Volo.Abp.GlobalFeatures;
using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Users;
namespace Volo.CmsKit.Public.Blogs; namespace Volo.CmsKit.Public.Blogs;
@ -31,8 +33,15 @@ public class BlogPostPublicController : CmsKitPublicControllerBase, IBlogPostPub
[HttpGet] [HttpGet]
[Route("{blogSlug}")] [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); 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"> <div class="col-lg-8 col-md-10 mx-auto pb-4">
<h1 class="mt-lg-4 mt-md-3">@Model.BlogPost.Title</h1> <h1 class="mt-lg-4 mt-md-3">@Model.BlogPost.Title</h1>
<p class="mb-lg-5 mb-md-3"> <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> <small style="opacity:.65;">@Model.BlogPost.CreationTime</small>
</p> </p>

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

@ -8,12 +8,40 @@
@model IndexModel @model IndexModel
@section styles{ @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"; 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"> <abp-row id="blogs-container">
@foreach (var blog in Model.Blogs.Items) @foreach (var blog in Model.Blogs.Items)
{ {
@ -21,16 +49,16 @@
<abp-card> <abp-card>
@if (blog.CoverImageMediaId != null) @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 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"> <abp-card-body class="p-4">
<h5>@blog.Title</h5> <h5>@blog.Title</h5>
<p class="mb-2"> <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> <small style="opacity:.65;">@blog.CreationTime</small>
</p> </p>
<p style="min-height: 60px;">@blog.ShortDescription</p> <p style="min-height: 60px;">@blog.ShortDescription</p>
@ -42,11 +70,10 @@
</abp-card-body> </abp-card-body>
</abp-card> </abp-card>
</abp-column> </abp-column>
} }
</abp-row> </abp-row>
<abp-row> <abp-row>
<abp-column> <abp-column>
<abp-paginator model="Model.PagerModel" /> <abp-paginator model="Model.PagerModel"/>
</abp-column> </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.Application.Dtos;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Pagination; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Pagination;
using Volo.CmsKit.Public.Blogs; using Volo.CmsKit.Public.Blogs;
using Volo.CmsKit.Users;
namespace Volo.CmsKit.Public.Web.Pages.Public.CmsKit.Blogs; namespace Volo.CmsKit.Public.Web.Pages.Public.CmsKit.Blogs;
@ -19,10 +20,16 @@ public class IndexModel : CmsKitPublicPageModelBase
[BindProperty(SupportsGet = true)] [BindProperty(SupportsGet = true)]
public int CurrentPage { get; set; } = 1; public int CurrentPage { get; set; } = 1;
[BindProperty(SupportsGet = true)]
public Guid? AuthorId { get; set; }
public PagedResultDto<BlogPostPublicDto> Blogs { get; private set; } public PagedResultDto<BlogPostPublicDto> Blogs { get; private set; }
public PagerModel PagerModel => new PagerModel(Blogs.TotalCount, Blogs.Items.Count, CurrentPage, PageSize, Request.Path.ToString()); 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; } protected IBlogPostPublicAppService BlogPostPublicAppService { get; }
@ -35,10 +42,13 @@ public class IndexModel : CmsKitPublicPageModelBase
{ {
Blogs = await BlogPostPublicAppService.GetListAsync( Blogs = await BlogPostPublicAppService.GetListAsync(
BlogSlug, BlogSlug,
new PagedAndSortedResultRequestDto new BlogPostGetListInput
{ {
SkipCount = PageSize * (CurrentPage - 1), 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 { .popover {
min-width: 276px; 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.Application.Dtos;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.CmsKit.Public.Blogs; using Volo.CmsKit.Public.Blogs;
using Volo.CmsKit.Users;
using Xunit; using Xunit;
namespace Volo.CmsKit.Blogs; namespace Volo.CmsKit.Blogs;
@ -17,16 +18,26 @@ public class BlogPostPublicAppService_Tests : CmsKitApplicationTestBase
private readonly CmsKitTestData cmsKitTestData; private readonly CmsKitTestData cmsKitTestData;
private readonly ICmsUserRepository userRepository;
private readonly IBlogRepository blogRepository;
private readonly IBlogPostRepository blogPostRepository;
private readonly BlogPostManager blogPostManager;
public BlogPostPublicAppService_Tests() public BlogPostPublicAppService_Tests()
{ {
blogPostAppService = GetRequiredService<IBlogPostPublicAppService>(); blogPostAppService = GetRequiredService<IBlogPostPublicAppService>();
cmsKitTestData = GetRequiredService<CmsKitTestData>(); cmsKitTestData = GetRequiredService<CmsKitTestData>();
userRepository = GetRequiredService<ICmsUserRepository>();
blogRepository = GetRequiredService<IBlogRepository>();
blogPostManager = GetRequiredService<BlogPostManager>();
blogPostRepository = GetRequiredService<IBlogPostRepository>();
} }
[Fact] [Fact]
public async Task GetListAsync_ShouldWorkProperly_WithExistingBlog() 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.ShouldNotBeNull();
blogPosts.TotalCount.ShouldBe(2); blogPosts.TotalCount.ShouldBe(2);
@ -62,4 +73,49 @@ public class BlogPostPublicAppService_Tests : CmsKitApplicationTestBase
exception.EntityType.ShouldBe(typeof(Blog)); 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.ShouldNotBeEmpty();
result.Count.ShouldBe(2); 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