From 92561484ccd02e0db31bbaa824debf564092e4ed Mon Sep 17 00:00:00 2001 From: Salih Date: Thu, 13 Jul 2023 15:09:36 +0300 Subject: [PATCH] Add Popular Tags View Component --- .../Volo/CmsKit/Tags/ITagAppService.cs | 4 +-- .../Volo/CmsKit/Tags/PopularTagDto.cs | 10 ++++++ ...msKitCommonApplicationAutoMapperProfile.cs | 2 ++ .../Volo/CmsKit/Tags/TagAppService.cs | 12 ++++++- .../Volo/CmsKit/Tags/ITagRepository.cs | 7 +++- .../Volo/CmsKit/Tags/PopularTag.cs | 17 +++++++++ .../Volo/CmsKit/Tags/EfCoreTagRepository.cs | 17 +++++++++ .../CmsKit/MongoDB/Tags/MongoTagRepository.cs | 7 ++++ .../CmsKit/Public/Tags/TagPublicController.cs | 7 ++++ .../Components/PopularTags/Default.cshtml | 29 +++++++++++++++ .../PopularTags/PopularTagsViewComponent.cs | 35 +++++++++++++++++++ .../Tags/TagRepository_Test.cs | 10 ++++++ 12 files changed, 153 insertions(+), 4 deletions(-) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Tags/PopularTagDto.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/PopularTag.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/PopularTags/Default.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/PopularTags/PopularTagsViewComponent.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Tags/ITagAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Tags/ITagAppService.cs index b984d76dc2..5ef4b96b7e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Tags/ITagAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Tags/ITagAppService.cs @@ -1,11 +1,11 @@ using System.Collections.Generic; using System.Threading.Tasks; using Volo.Abp.Application.Services; -using Volo.CmsKit.Tags; namespace Volo.CmsKit.Tags; public interface ITagAppService : IApplicationService { Task> GetAllRelatedTagsAsync(string entityType, string entityId); -} + Task> GetPopularTagsAsync(string entityType, int maxCount); +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Tags/PopularTagDto.cs b/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Tags/PopularTagDto.cs new file mode 100644 index 0000000000..b074aece06 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Tags/PopularTagDto.cs @@ -0,0 +1,10 @@ +using System; + +namespace Volo.CmsKit.Tags; + +public class PopularTagDto +{ + public Guid Id { get; set; } + public string Name { get; set; } + public int Count { get; set; } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/CmsKitCommonApplicationAutoMapperProfile.cs b/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/CmsKitCommonApplicationAutoMapperProfile.cs index 908be3b4d5..099b3e1b10 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/CmsKitCommonApplicationAutoMapperProfile.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/CmsKitCommonApplicationAutoMapperProfile.cs @@ -11,6 +11,8 @@ public class CmsKitCommonApplicationAutoMapperProfile : Profile { CreateMap().MapExtraProperties(); + CreateMap(); + CreateMap().MapExtraProperties(); CreateMap().MapExtraProperties(); diff --git a/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Tags/TagAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Tags/TagAppService.cs index daa8bd5ec8..718b6a318a 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Tags/TagAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Tags/TagAppService.cs @@ -24,4 +24,14 @@ public class TagAppService : CmsKitAppServiceBase, ITagAppService return ObjectMapper.Map, List>(entities); } -} + + public async Task> GetPopularTagsAsync(string entityType, int maxCount) + { + return ObjectMapper.Map, List>( + await TagRepository.GetPopularTagsAsync( + entityType, + maxCount + ) + ); + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/ITagRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/ITagRepository.cs index e74b767078..d00457b53a 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/ITagRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/ITagRepository.cs @@ -36,4 +36,9 @@ public interface ITagRepository : IBasicRepository [NotNull] string entityType, [NotNull] string entityId, CancellationToken cancellationToken = default); -} + + Task> GetPopularTagsAsync( + [NotNull] string entityType, + int maxCount, + CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/PopularTag.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/PopularTag.cs new file mode 100644 index 0000000000..d82d7a0b04 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/PopularTag.cs @@ -0,0 +1,17 @@ +using System; + +namespace Volo.CmsKit.Tags; + +public class PopularTag +{ + public Guid Id { get; set; } + public string Name { get; set; } + public int Count { get; set; } + + public PopularTag(Guid id, string name, int count) + { + Id = id; + Name = name; + Count = count; + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Tags/EfCoreTagRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Tags/EfCoreTagRepository.cs index 9b750eaac5..a82fa1113e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Tags/EfCoreTagRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Tags/EfCoreTagRepository.cs @@ -80,6 +80,23 @@ public class EfCoreTagRepository : EfCoreRepository return await query.ToListAsync(cancellationToken: GetCancellationToken(cancellationToken)); } + public async Task> GetPopularTagsAsync( + [NotNull] string entityType, + int maxCount, + CancellationToken cancellationToken = default) + { + return await (from tag in await GetDbSetAsync() + join entityTag in (await GetDbContextAsync()).Set() on tag.Id equals entityTag.TagId + where tag.EntityType == entityType + select new { tag, entityTag } into tagEntityTag + group tagEntityTag by tagEntityTag.entityTag.TagId + into g + orderby g.Count() descending + select new PopularTag(g.Key, g.First().tag.Name, g.Count())) + .Take(maxCount) + .ToListAsync(cancellationToken: GetCancellationToken(cancellationToken)); + } + public async Task> GetListAsync(string filter, CancellationToken cancellationToken = default) { return await (await GetQueryableByFilterAsync(filter)).ToListAsync(GetCancellationToken(cancellationToken)); diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Tags/MongoTagRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Tags/MongoTagRepository.cs index f8bedebf61..49bf7fad14 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Tags/MongoTagRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Tags/MongoTagRepository.cs @@ -81,6 +81,13 @@ public class MongoTagRepository : MongoDbRepository> GetPopularTagsAsync(string entityType, int maxCount, CancellationToken cancellationToken = default) + { + //TODO: Implement this method + throw new NotImplementedException(); + } + public async Task> GetListAsync(string filter, CancellationToken cancellationToken = default) { diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Tags/TagPublicController.cs b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Tags/TagPublicController.cs index 1620f136da..0aced1bacf 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Tags/TagPublicController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Tags/TagPublicController.cs @@ -30,4 +30,11 @@ public class TagPublicController : CmsKitPublicControllerBase, ITagAppService { return TagAppService.GetAllRelatedTagsAsync(entityType, entityId); } + + [HttpGet] + [Route("popular/{entityType}/{maxCount:int}")] + public Task> GetPopularTagsAsync(string entityType, int maxCount) + { + return TagAppService.GetPopularTagsAsync(entityType, maxCount); + } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/PopularTags/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/PopularTags/Default.cshtml new file mode 100644 index 0000000000..0946744aaa --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/PopularTags/Default.cshtml @@ -0,0 +1,29 @@ +@inject IHtmlLocalizer L +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.CmsKit.Localization +@model Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.PopularTags.PopularTagsViewComponent.PopularTagsViewModel + +@if (Model.Tags != null && Model.Tags.Any()) +{ +

@L["PopularTags"]

+ +
+ @foreach (var tag in Model.Tags) + { + if (Model.UrlFactory == null) + { + + @tag.Name + + } + else + { + + + @tag.Name + + + } + } +
+} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/PopularTags/PopularTagsViewComponent.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/PopularTags/PopularTagsViewComponent.cs new file mode 100644 index 0000000000..465805642b --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/PopularTags/PopularTagsViewComponent.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.Uow; +using Volo.CmsKit.Tags; + +namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.PopularTags; + +public class PopularTagsViewComponent : AbpViewComponent +{ + private readonly ITagAppService _tagAppService; + + public PopularTagsViewComponent(ITagAppService tagAppService) + { + _tagAppService = tagAppService; + } + + public async Task InvokeAsync(string entityType, int maxCount, Func urlFactory = null) + { + var model = new PopularTagsViewModel + { + Tags = await _tagAppService.GetPopularTagsAsync(entityType, maxCount), + UrlFactory = urlFactory + }; + return View("~/Pages/CmsKit/Shared/Components/PopularTags/Default.cshtml", model); + } + + public class PopularTagsViewModel + { + public List Tags { get; set; } + public Func UrlFactory { get; set; } + } +} \ No newline at end of file diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/Tags/TagRepository_Test.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/Tags/TagRepository_Test.cs index 1a061b546a..fabaab6520 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/Tags/TagRepository_Test.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/Tags/TagRepository_Test.cs @@ -129,4 +129,14 @@ public abstract class TagRepository_Test : CmsKitTestBase