From 83bea6eaf2d7b04a5a0e0a74fba1f2d74bf2cbb0 Mon Sep 17 00:00:00 2001 From: Musa Demir Date: Tue, 10 May 2022 12:35:55 +0300 Subject: [PATCH] add filter by tag option --- .../Admin/Blogs/BlogPostGetListInput.cs | 2 ++ .../Admin/Blogs/BlogPostAdminAppService.cs | 4 +-- .../Volo/CmsKit/Blogs/IBlogPostRepository.cs | 2 ++ .../Volo/CmsKit/Tags/EntityTagManager.cs | 10 ++++++- .../Volo/CmsKit/Tags/IEntityTagRepository.cs | 6 ++++ .../CmsKit/Blogs/EfCoreBlogPostRepository.cs | 28 +++++++++++++++++-- .../CmsKit/Tags/EfCoreEntityTagRepository.cs | 15 +++++++++- .../MongoDB/Blogs/MongoBlogPostRepository.cs | 23 +++++++++++++-- .../MongoDB/Tags/MongoEntityTagRepository.cs | 13 +++++++++ .../Public/Blogs/BlogPostGetListInput.cs | 4 ++- .../Public/Blogs/BlogPostPublicAppService.cs | 6 ++-- .../Shared/Components/Tags/Default.cshtml | 25 +++++++++++++---- .../Components/Tags/TagViewComponent.cs | 7 +++-- .../Pages/Public/CmsKit/Blogs/BlogPost.cshtml | 3 +- .../Pages/Public/CmsKit/Blogs/Index.cshtml.cs | 6 +++- 15 files changed, 132 insertions(+), 22 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostGetListInput.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostGetListInput.cs index f136fe6562..ddb8ebcbcb 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostGetListInput.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostGetListInput.cs @@ -11,6 +11,8 @@ public class BlogPostGetListInput : PagedAndSortedResultRequestDto public Guid? BlogId { get; set; } public Guid? AuthorId { get; set; } + + public Guid? TagId { get; set; } public BlogPostStatus? Status { get; set; } } \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs index f09a2e4565..9d8fcfd917 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs @@ -101,11 +101,11 @@ public class BlogPostAdminAppService : CmsKitAppServiceBase, IBlogPostAdminAppSe { var blogs = (await BlogRepository.GetListAsync()).ToDictionary(x => x.Id); - var blogPosts = await BlogPostRepository.GetListAsync(input.Filter, input.BlogId, input.AuthorId, + var blogPosts = await BlogPostRepository.GetListAsync(input.Filter, input.BlogId, input.AuthorId, input.TagId, statusFilter: input.Status, input.MaxResultCount, input.SkipCount, input.Sorting); - var count = await BlogPostRepository.GetCountAsync(input.Filter, input.BlogId, input.AuthorId); + var count = await BlogPostRepository.GetCountAsync(input.Filter, input.BlogId, input.AuthorId, tagId: input.TagId); var dtoList = blogPosts.Select(x => { diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs index 2af1036162..404d21dc83 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs @@ -13,6 +13,7 @@ public interface IBlogPostRepository : IBasicRepository string filter = null, Guid? blogId = null, Guid? authorId = null, + Guid? tagId = null, BlogPostStatus? statusFilter = null, CancellationToken cancellationToken = default); @@ -20,6 +21,7 @@ public interface IBlogPostRepository : IBasicRepository string filter = null, Guid? blogId = null, Guid? authorId = null, + Guid? tagId = null, BlogPostStatus? statusFilter = null, int maxResultCount = int.MaxValue, int skipCount = 0, diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/EntityTagManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/EntityTagManager.cs index 4000cc8aec..b33d337a06 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/EntityTagManager.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/EntityTagManager.cs @@ -71,4 +71,12 @@ public class EntityTagManager : DomainService await AddTagToEntityAsync(tag.Id, entityType, entityId, CurrentTenant?.Id); } } -} + + public async Task> GetEntityIdsFilteredByTagAsync( + [NotNull] Guid tagId, + [CanBeNull] Guid? tenantId, + CancellationToken cancellationToken = default) + { + return await EntityTagRepository.GetEntityIdsFilteredByTagAsync(tagId, tenantId, cancellationToken); + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/IEntityTagRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/IEntityTagRepository.cs index 15efdcd433..a96402267d 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/IEntityTagRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/IEntityTagRepository.cs @@ -1,5 +1,6 @@ using JetBrains.Annotations; using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories; @@ -15,4 +16,9 @@ public interface IEntityTagRepository : IBasicRepository CancellationToken cancellationToken = default); Task DeleteManyAsync(Guid[] tagIds, CancellationToken cancellationToken = default); + + Task> GetEntityIdsFilteredByTagAsync( + [NotNull] Guid tagId, + [CanBeNull] Guid? tenantId, + CancellationToken cancellationToken = default); } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs index 0c359debcc..dfe2c6fa19 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs @@ -11,14 +11,20 @@ using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; using Volo.CmsKit.EntityFrameworkCore; +using Volo.CmsKit.Tags; using Volo.CmsKit.Users; namespace Volo.CmsKit.Blogs; public class EfCoreBlogPostRepository : EfCoreRepository, IBlogPostRepository { - public EfCoreBlogPostRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) + private EntityTagManager _entityTagManager; + + public EfCoreBlogPostRepository( + IDbContextProvider dbContextProvider, + EntityTagManager entityTagManager) : base(dbContextProvider) { + _entityTagManager = entityTagManager; } public async Task GetBySlugAsync( @@ -43,10 +49,18 @@ public class EfCoreBlogPostRepository : EfCoreRepository entityIdFilters = null; + if (tagId.HasValue) + { + entityIdFilters = await _entityTagManager.GetEntityIdsFilteredByTagAsync(tagId.Value, CurrentTenant.Id, cancellationToken); + } + var queryable = (await GetDbSetAsync()) + .WhereIf(entityIdFilters != null, x => entityIdFilters.Contains(x.Id.ToString())) .WhereIf(blogId.HasValue, x => x.BlogId == blogId) .WhereIf(authorId.HasValue, x => x.AuthorId == authorId) .WhereIf(statusFilter.HasValue, x => x.Status == statusFilter) @@ -60,6 +74,7 @@ public class EfCoreBlogPostRepository : EfCoreRepository(); var usersDbSet = dbContext.Set(); - var queryable = blogPostsDbSet + List entityIdFilters = null; + if (tagId.HasValue) + { + entityIdFilters = await _entityTagManager.GetEntityIdsFilteredByTagAsync(tagId.Value, CurrentTenant.Id, cancellationToken); + } + + var queryable = (await GetDbSetAsync()) + .WhereIf(entityIdFilters != null, x => entityIdFilters.Contains(x.Id.ToString())) .WhereIf(blogId.HasValue, x => x.BlogId == blogId) .WhereIf(!string.IsNullOrWhiteSpace(filter), x => x.Title.Contains(filter) || x.Slug.Contains(filter)) .WhereIf(authorId.HasValue, x => x.AuthorId == authorId) @@ -138,4 +160,4 @@ public class EfCoreBlogPostRepository : EfCoreRepository x.Status == BlogPostStatus.WaitingForReview, GetCancellationToken(cancellationToken)); } -} +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Tags/EfCoreEntityTagRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Tags/EfCoreEntityTagRepository.cs index 16d648ca61..fe7e622841 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Tags/EfCoreEntityTagRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Tags/EfCoreEntityTagRepository.cs @@ -1,8 +1,10 @@ using JetBrains.Annotations; using System; +using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; using Volo.Abp; using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; @@ -39,4 +41,15 @@ public class EfCoreEntityTagRepository : EfCoreRepository> GetEntityIdsFilteredByTagAsync( + [NotNull] Guid tagId, + [CanBeNull] Guid? tenantId, + CancellationToken cancellationToken = default) + { + return await (await GetDbContextAsync()).Set() + .Where(q => q.TagId == tagId && q.TenantId == tenantId) + .Select(q => q.EntityId) + .ToListAsync(cancellationToken: GetCancellationToken(cancellationToken)); + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs index 129c5e10b7..9358635f5c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs @@ -12,15 +12,18 @@ using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.MongoDB; using Volo.CmsKit.Blogs; +using Volo.CmsKit.Tags; using Volo.CmsKit.Users; namespace Volo.CmsKit.MongoDB.Blogs; public class MongoBlogPostRepository : MongoDbRepository, IBlogPostRepository { - public MongoBlogPostRepository(IMongoDbContextProvider dbContextProvider) : base( + private EntityTagManager _entityTagManager; + public MongoBlogPostRepository(IMongoDbContextProvider dbContextProvider, EntityTagManager entityTagManager) : base( dbContextProvider) { + _entityTagManager = entityTagManager; } public virtual async Task GetBySlugAsync(Guid blogId, [NotNull] string slug, @@ -44,12 +47,20 @@ public class MongoBlogPostRepository : MongoDbRepository entityIdFilters = null; + if (tagId.HasValue) + { + entityIdFilters = await _entityTagManager.GetEntityIdsFilteredByTagAsync(tagId.Value, CurrentTenant.Id, cancellationToken); + } + return await (await GetMongoQueryableAsync(cancellationToken)) + .WhereIf>(entityIdFilters != null, x => entityIdFilters.Contains(x.Id.ToString())) .WhereIf>(!string.IsNullOrWhiteSpace(filter), x => x.Title.Contains(filter) || x.Slug.Contains(filter)) .WhereIf>(blogId.HasValue, x => x.BlogId == blogId) .WhereIf>(authorId.HasValue, x => x.AuthorId == authorId) @@ -61,6 +72,7 @@ public class MongoBlogPostRepository : MongoDbRepository entityIdFilters = null; + if (tagId.HasValue) + { + entityIdFilters = await _entityTagManager.GetEntityIdsFilteredByTagAsync(tagId.Value, CurrentTenant.Id, cancellationToken); + } + var usersQueryable = dbContext.Collection().AsQueryable(); var queryable = blogPostQueryable + .WhereIf(entityIdFilters != null, x => entityIdFilters.Contains(x.Id.ToString())) .WhereIf(blogId.HasValue, x => x.BlogId == blogId) .WhereIf(!string.IsNullOrWhiteSpace(filter), x => x.Title.Contains(filter) || x.Slug.Contains(filter)) .WhereIf(authorId.HasValue, x => x.AuthorId == authorId) diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Tags/MongoEntityTagRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Tags/MongoEntityTagRepository.cs index e4d6143996..82952c9bf5 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Tags/MongoEntityTagRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Tags/MongoEntityTagRepository.cs @@ -2,6 +2,7 @@ using MongoDB.Driver; using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Volo.Abp; @@ -39,4 +40,16 @@ public class MongoEntityTagRepository : MongoDbRepository> GetEntityIdsFilteredByTagAsync( + [NotNull] Guid tagId, + [CanBeNull] Guid? tenantId, + CancellationToken cancellationToken = default) + { + var blogPostQueryable = (await GetQueryableAsync()) + .Where(q => q.TagId == tagId && q.TenantId == tenantId) + .Select(q => q.EntityId); + + return await AsyncExecuter.ToListAsync(blogPostQueryable, GetCancellationToken(cancellationToken)); + } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostGetListInput.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostGetListInput.cs index b471171f3b..5e3ffe9311 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostGetListInput.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostGetListInput.cs @@ -5,5 +5,7 @@ namespace Volo.CmsKit.Public.Blogs; public class BlogPostGetListInput : PagedAndSortedResultRequestDto { - public Guid? AuthorId { get; set; } + public Guid? AuthorId { get; set; } + + public Guid? TagId { get; set; } } \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs index 94847fba11..65e6c6fa20 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs @@ -38,11 +38,13 @@ public class BlogPostPublicAppService : CmsKitPublicAppServiceBase, IBlogPostPub { var blog = await BlogRepository.GetBySlugAsync(blogSlug); - var blogPosts = await BlogPostRepository.GetListAsync(null, blog.Id, input.AuthorId, BlogPostStatus.Published, input.MaxResultCount, + var blogPosts = await BlogPostRepository.GetListAsync(null, blog.Id, input.AuthorId, input.TagId, + BlogPostStatus.Published, input.MaxResultCount, input.SkipCount, input.Sorting); return new PagedResultDto( - await BlogPostRepository.GetCountAsync(blogId: blog.Id, statusFilter: BlogPostStatus.Published, authorId: input.AuthorId), + await BlogPostRepository.GetCountAsync(blogId: blog.Id, tagId: input.TagId, + statusFilter: BlogPostStatus.Published, authorId: input.AuthorId), ObjectMapper.Map, List>(blogPosts)); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Tags/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Tags/Default.cshtml index f86ba0998e..85113c8688 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Tags/Default.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Tags/Default.cshtml @@ -2,16 +2,29 @@ @model TagViewComponent.TagViewModel -
-
- @if (Model.Tags != null) +
+
+ @if (Model.Tags != null) + { + foreach (var tag in Model.Tags) { - foreach (var tag in Model.Tags) + if (Model.UrlFormat.IsNullOrWhiteSpace()) { + @tag.Name } + else + { + var formattedUrl = Model.UrlFormat.Replace("{TagId}", tag.Id.ToString()); + + + @tag.Name + + + } } -
-
\ No newline at end of file + } +
+
\ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Tags/TagViewComponent.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Tags/TagViewComponent.cs index 43fb6ea8cc..a3dc23c61a 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Tags/TagViewComponent.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Tags/TagViewComponent.cs @@ -26,7 +26,8 @@ public class TagViewComponent : AbpViewComponent public virtual async Task InvokeAsync( string entityType, - string entityId) + string entityId, + string urlFormat) { var tagDtos = await TagAppService.GetAllRelatedTagsAsync(entityType, entityId); @@ -34,7 +35,8 @@ public class TagViewComponent : AbpViewComponent { EntityId = entityId, EntityType = entityType, - Tags = tagDtos + Tags = tagDtos, + UrlFormat = urlFormat }; return View("~/Pages/CmsKit/Shared/Components/Tags/Default.cshtml", viewModel); @@ -45,5 +47,6 @@ public class TagViewComponent : AbpViewComponent public List Tags { get; set; } public string EntityId { get; set; } public string EntityType { get; set; } + public string UrlFormat { get; set; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml index 62670a742d..9d8680e96c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/BlogPost.cshtml @@ -85,7 +85,8 @@ @await Component.InvokeAsync(typeof(TagViewComponent), new { entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, - entityId = Model.BlogPost.Id.ToString() + entityId = Model.BlogPost.Id.ToString(), + urlFormat = $"/blogs/{Model.BlogSlug}?tagId={{TagId}}" }) } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/Index.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/Index.cshtml.cs index c7f667382b..f5f2cc2f7a 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/Index.cshtml.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/Public/CmsKit/Blogs/Index.cshtml.cs @@ -24,6 +24,9 @@ public class IndexModel : CmsKitPublicPageModelBase [BindProperty(SupportsGet = true)] public Guid? AuthorId { get; set; } + [BindProperty(SupportsGet = true)] + public Guid? TagId { get; set; } + public PagedResultDto Blogs { get; private set; } public PagerModel PagerModel => new PagerModel(Blogs.TotalCount, Blogs.Items.Count, CurrentPage, PageSize, Request.Path.ToString()); @@ -45,7 +48,8 @@ public class IndexModel : CmsKitPublicPageModelBase { SkipCount = PageSize * (CurrentPage - 1), MaxResultCount = PageSize, - AuthorId = AuthorId + AuthorId = AuthorId, + TagId = TagId }); if (AuthorId != null)