From 52908a7496a7938144ab2f9a8a56225a59987e3b Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 28 Jul 2020 17:48:23 +0300 Subject: [PATCH 01/13] cmskit: commets initial files & backend --- .../Pages/Index.cshtml | 2 + .../Volo/CmsKit/Comments/CommentConsts.cs | 11 +++ .../Volo/CmsKit/Comments/Comment.cs | 50 ++++++++++ .../CmsKit/Comments/ICommentRepository.cs | 15 +++ .../Comments/EfCoreCommentRepository.cs | 50 ++++++++++ .../EntityFrameworkCore/CmsKitDbContext.cs | 3 + .../CmsKitDbContextModelCreatingExtensions.cs | 16 ++++ .../EntityFrameworkCore/ICmsKitDbContext.cs | 3 + .../Volo/CmsKit/Comments/CommentDto.cs | 21 +++++ .../CmsKit/Comments/CommentWithRepliesDto.cs | 22 +++++ .../CmsKit/Comments/CreateCommentInput.cs | 23 +++++ .../Comments/ICommentPublicAppService.cs | 19 ++++ .../CmsKit/Comments/UpdateCommentInput.cs | 13 +++ .../Comments/CommentPublicAppService.cs | 83 +++++++++++++++++ .../PublicApplicationAutoMapperProfile.cs | 7 +- .../Comments/CommentPublicController.cs | 48 ++++++++++ .../CommentingScriptBundleContributor.cs | 15 +++ .../CommentingStyleBundleContributor.cs | 13 +++ .../Commenting/CommentingViewComponent.cs | 92 +++++++++++++++++++ .../Components/Commenting/Default.cshtml | 22 +++++ .../Shared/Components/Commenting/default.css | 13 +++ .../Shared/Components/Commenting/default.js | 76 +++++++++++++++ 22 files changed, 616 insertions(+), 1 deletion(-) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Comments/CommentConsts.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/Comment.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/ICommentRepository.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Comments/EfCoreCommentRepository.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CommentDto.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CommentWithRepliesDto.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CreateCommentInput.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/ICommentPublicAppService.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/UpdateCommentInput.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Comments/CommentPublicAppService.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Comments/CommentPublicController.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingScriptBundleContributor.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingStyleBundleContributor.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingViewComponent.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.css create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.js diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Index.cshtml b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Index.cshtml index 62ef15d4b7..a0d01ae300 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Index.cshtml +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Index.cshtml @@ -2,6 +2,7 @@ @using Localization.Resources.AbpUi @using Microsoft.Extensions.Localization @using Volo.CmsKit.Pages +@using Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting @using Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.ReactionSelection @model IndexModel @inject IStringLocalizer Localizer @@ -23,6 +24,7 @@ @await Component.InvokeAsync(typeof(ReactionSelectionViewComponent), new { entityType = "quote", entityId = "1" }) + @await Component.InvokeAsync(typeof(CommentingViewComponent), new { entityType = "quote", entityId = "1" }) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Comments/CommentConsts.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Comments/CommentConsts.cs new file mode 100644 index 0000000000..9fed054cae --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Comments/CommentConsts.cs @@ -0,0 +1,11 @@ +namespace Volo.CmsKit.Comments +{ + public static class CommentConsts + { + public static int EntityTypeLength { get; set; } = 64; + + public static int EntityIdLength { get; set; } = 64; + + public static int MaxTextLength { get; set; } = 512; + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/Comment.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/Comment.cs new file mode 100644 index 0000000000..fdcdfe37c2 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/Comment.cs @@ -0,0 +1,50 @@ +using System; +using JetBrains.Annotations; +using Volo.Abp; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; + +namespace Volo.CmsKit.Comments +{ + public class Comment: Entity, IAggregateRoot, IHasCreationTime, IMustHaveCreator + { + public virtual string EntityType { get; protected set; } + + public virtual string EntityId { get; protected set; } + + public virtual string Text { get; protected set; } + + public virtual Guid? RepliedCommentId { get; protected set; } + + public virtual Guid CreatorId { get; set; } + + public virtual DateTime CreationTime { get; set; } + + protected Comment() + { + + } + + public Comment( + Guid id, + [NotNull] string entityType, + [NotNull] string entityId, + [NotNull] string text, + Guid? repliedCommentId, + Guid creatorId) + : base(id) + { + EntityType = Check.NotNullOrWhiteSpace(entityType, nameof(entityType), CommentConsts.EntityTypeLength); + EntityId = Check.NotNullOrWhiteSpace(entityId, nameof(entityId), CommentConsts.EntityIdLength); + RepliedCommentId = repliedCommentId; + CreatorId = creatorId; + + SetText(text); + } + + public virtual void SetText(string text) + { + Text = Check.NotNullOrWhiteSpace(text, nameof(text), CommentConsts.MaxTextLength); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/ICommentRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/ICommentRepository.cs new file mode 100644 index 0000000000..a189c8938e --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/ICommentRepository.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Volo.Abp.Domain.Repositories; + +namespace Volo.CmsKit.Comments +{ + public interface ICommentRepository : IBasicRepository + { + Task> GetListAsync( + [NotNull] string entityType, + [NotNull] string entityId); + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Comments/EfCoreCommentRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Comments/EfCoreCommentRepository.cs new file mode 100644 index 0000000000..42e9de4f32 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Comments/EfCoreCommentRepository.cs @@ -0,0 +1,50 @@ +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; +using Volo.CmsKit.EntityFrameworkCore; + +namespace Volo.CmsKit.Comments +{ + public class EfCoreCommentRepository : EfCoreRepository, + ICommentRepository + { + public EfCoreCommentRepository(IDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + } + + public async Task> GetListAsync( + string entityType, + string entityId) + { + Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); + Check.NotNullOrWhiteSpace(entityId, nameof(entityId)); + + return await DbSet + .Where(x => + x.EntityType == entityType && + x.EntityId == entityId) + .ToListAsync(); + } + + public override async Task DeleteAsync(Guid id, bool autoSave = false, CancellationToken cancellationToken = default) + { + var replies = await DbSet + .Where(x => x.RepliedCommentId == id) + .ToListAsync(GetCancellationToken(cancellationToken)); + + foreach (var reply in replies) + { + await base.DeleteAsync(reply.Id, autoSave, GetCancellationToken(cancellationToken)); + } + + await base.DeleteAsync(id, autoSave, GetCancellationToken(cancellationToken)); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs index e90e133d7f..01384a3aa1 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs @@ -1,6 +1,7 @@ using Microsoft.EntityFrameworkCore; using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; +using Volo.CmsKit.Comments; using Volo.CmsKit.Reactions; namespace Volo.CmsKit.EntityFrameworkCore @@ -10,6 +11,8 @@ namespace Volo.CmsKit.EntityFrameworkCore { public DbSet UserReactions { get; set; } + public DbSet Comments { get; set; } + public CmsKitDbContext(DbContextOptions options) : base(options) { diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs index 9eeb191f5b..e551412d5e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs @@ -2,6 +2,7 @@ using Microsoft.EntityFrameworkCore; using Volo.Abp; using Volo.Abp.EntityFrameworkCore.Modeling; +using Volo.CmsKit.Comments; using Volo.CmsKit.Reactions; namespace Volo.CmsKit.EntityFrameworkCore @@ -34,6 +35,21 @@ namespace Volo.CmsKit.EntityFrameworkCore b.HasIndex(x => new { x.EntityType, x.EntityId }); b.HasIndex(x => new { x.CreatorId, x.EntityType, x.EntityId, x.ReactionName }); }); + + builder.Entity(b => + { + b.ToTable(options.TablePrefix + "Comments", options.Schema); + b.ConfigureByConvention(); + + b.Property(x => x.EntityType).IsRequired().HasMaxLength(CommentConsts.EntityTypeLength); + b.Property(x => x.EntityId).IsRequired().HasMaxLength(CommentConsts.EntityIdLength); + b.Property(x => x.Text).IsRequired().HasMaxLength(CommentConsts.MaxTextLength); + b.Property(x => x.RepliedCommentId); + b.Property(x => x.CreationTime); + + b.HasIndex(x => new { x.EntityType, x.EntityId }); + b.HasIndex(x => new { x.RepliedCommentId }); + }); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/ICmsKitDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/ICmsKitDbContext.cs index 9441986b23..ecd807d005 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/ICmsKitDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/ICmsKitDbContext.cs @@ -1,6 +1,7 @@ using Microsoft.EntityFrameworkCore; using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; +using Volo.CmsKit.Comments; using Volo.CmsKit.Reactions; namespace Volo.CmsKit.EntityFrameworkCore @@ -9,5 +10,7 @@ namespace Volo.CmsKit.EntityFrameworkCore public interface ICmsKitDbContext : IEfCoreDbContext { DbSet UserReactions { get; } + + DbSet Comments { get; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CommentDto.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CommentDto.cs new file mode 100644 index 0000000000..0852bab22e --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CommentDto.cs @@ -0,0 +1,21 @@ +using System; + +namespace Volo.CmsKit.Comments +{ + public class CommentDto + { + public Guid Id { get; set; } + + public string EntityType { get; set; } + + public string EntityId { get; set; } + + public string Text { get; set; } + + public Guid? RepliedCommentId { get; set; } + + public Guid CreatorId { get; set; } + + public DateTime CreationTime { get; set; } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CommentWithRepliesDto.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CommentWithRepliesDto.cs new file mode 100644 index 0000000000..a9e682f856 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CommentWithRepliesDto.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; + +namespace Volo.CmsKit.Comments +{ + public class CommentWithRepliesDto + { + public Guid Id { get; set; } + + public string EntityType { get; set; } + + public string EntityId { get; set; } + + public string Text { get; set; } + + public Guid CreatorId { get; set; } + + public DateTime CreationTime { get; set; } + + public List Replies { get; set; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CreateCommentInput.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CreateCommentInput.cs new file mode 100644 index 0000000000..30b86b75f0 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CreateCommentInput.cs @@ -0,0 +1,23 @@ +using System; +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Validation; + +namespace Volo.CmsKit.Comments +{ + public class CreateCommentInput + { + [Required] + [DynamicStringLength(typeof(CommentConsts), nameof(CommentConsts.EntityTypeLength))] + public string EntityType { get; set; } + + [Required] + [DynamicStringLength(typeof(CommentConsts), nameof(CommentConsts.EntityIdLength))] + public string EntityId { get; set; } + + [Required] + [DynamicStringLength(typeof(CommentConsts), nameof(CommentConsts.MaxTextLength))] + public string Text { get; set; } + + public Guid? RepliedCommentId { get; set; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/ICommentPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/ICommentPublicAppService.cs new file mode 100644 index 0000000000..bffe742aca --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/ICommentPublicAppService.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Volo.Abp.Application.Services; + +namespace Volo.CmsKit.Comments +{ + public interface ICommentPublicAppService : IApplicationService + { + Task> GetAllForEntityAsync(string entityType, string entityId); + + Task CreateAsync(CreateCommentInput input); + + Task UpdateAsync(Guid id, UpdateCommentInput input); + + Task DeleteAsync(Guid id); + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/UpdateCommentInput.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/UpdateCommentInput.cs new file mode 100644 index 0000000000..e084914626 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/UpdateCommentInput.cs @@ -0,0 +1,13 @@ +using System; +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Validation; + +namespace Volo.CmsKit.Comments +{ + public class UpdateCommentInput + { + [Required] + [DynamicStringLength(typeof(CommentConsts), nameof(CommentConsts.MaxTextLength))] + public string Text { get; set; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Comments/CommentPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Comments/CommentPublicAppService.cs new file mode 100644 index 0000000000..7833460f0d --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Comments/CommentPublicAppService.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Volo.Abp; +using Volo.Abp.Application.Services; + +namespace Volo.CmsKit.Comments +{ + [Authorize] + public class CommentPublicAppService : ApplicationService, ICommentPublicAppService + { + protected ICommentRepository CommentRepository { get; } + + public CommentPublicAppService(ICommentRepository commentRepository) + { + CommentRepository = commentRepository; + } + + public async Task> GetAllForEntityAsync(string entityType, string entityId) + { + var comments = await CommentRepository.GetListAsync(entityType, entityId); + + return ConvertCommentsToNestedStructure(comments); + } + + public async Task CreateAsync(CreateCommentInput input) + { + var comment = await CommentRepository.InsertAsync(new Comment( + GuidGenerator.Create(), + input.EntityType, + input.EntityId, + input.Text, + input.RepliedCommentId, + CurrentUser.Id.Value + )); + + return ObjectMapper.Map(comment); + } + + public async Task UpdateAsync(Guid id, UpdateCommentInput input) + { + var comment = await CommentRepository.GetAsync(id); + + comment.SetText(input.Text); + + var updatedComment = await CommentRepository.UpdateAsync(comment); + + return ObjectMapper.Map(updatedComment); + } + + public async Task DeleteAsync(Guid id) + { + var comment = await CommentRepository.GetAsync(id); + + if (comment.CreatorId != CurrentUser.Id) + { + throw new BusinessException(); + } + + await CommentRepository.DeleteAsync(id); + } + + private List ConvertCommentsToNestedStructure(List comments) + { + var parentComments = comments + .Where(c=> c.RepliedCommentId == null) + .Select(c=> ObjectMapper.Map(c)) + .ToList(); + + foreach (var parentComment in parentComments) + { + parentComment.Replies = comments + .Where(c => c.RepliedCommentId == parentComment.Id) + .Select(c => ObjectMapper.Map(c)) + .ToList(); + } + + return parentComments; + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/PublicApplicationAutoMapperProfile.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/PublicApplicationAutoMapperProfile.cs index e88dd5c4b3..695bb8376c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/PublicApplicationAutoMapperProfile.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/PublicApplicationAutoMapperProfile.cs @@ -1,4 +1,6 @@ using AutoMapper; +using Volo.Abp.AutoMapper; +using Volo.CmsKit.Comments; namespace Volo.CmsKit { @@ -9,6 +11,9 @@ namespace Volo.CmsKit /* You can configure your AutoMapper mapping configuration here. * Alternatively, you can split your mapping configurations * into multiple profile classes for a better organization. */ + + CreateMap(); + CreateMap().Ignore(x=> x.Replies); } } -} \ No newline at end of file +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Comments/CommentPublicController.cs b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Comments/CommentPublicController.cs new file mode 100644 index 0000000000..cc5cedb309 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Comments/CommentPublicController.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp; + +namespace Volo.CmsKit.Comments +{ + [RemoteService(Name = CmsKitPublicRemoteServiceConsts.RemoteServiceName)] + [Area("cms-kit")] + [Route("api/cms-kit-public/comments")] + public class CommentPublicController : CmsKitPublicControllerBase, ICommentPublicAppService + { + public ICommentPublicAppService CommentPublicAppService { get; } + + public CommentPublicController(ICommentPublicAppService commentPublicAppService) + { + CommentPublicAppService = commentPublicAppService; + } + + [HttpGet] + [Route("{entityType}/{entityId}")] + public Task> GetAllForEntityAsync(string entityType, string entityId) + { + return CommentPublicAppService.GetAllForEntityAsync(entityType, entityId); + } + + [HttpPost] + public Task CreateAsync(CreateCommentInput input) + { + return CommentPublicAppService.CreateAsync(input); + } + + [HttpPost] + [Route("{id}")] + public Task UpdateAsync(Guid id, UpdateCommentInput input) + { + return CommentPublicAppService.UpdateAsync(id, input); + } + + [HttpDelete] + [Route("update")] + public Task DeleteAsync(Guid id) + { + return CommentPublicAppService.DeleteAsync(id); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingScriptBundleContributor.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingScriptBundleContributor.cs new file mode 100644 index 0000000000..8f1b6ad38e --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingScriptBundleContributor.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Bootstrap; +using Volo.Abp.Modularity; + +namespace Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting +{ + public class CommentingScriptBundleContributor : BundleContributor + { + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files.AddIfNotContains("/Pages/CmsKit/Shared/Components/Commenting/default.js"); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingStyleBundleContributor.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingStyleBundleContributor.cs new file mode 100644 index 0000000000..158c8e15d2 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingStyleBundleContributor.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; + +namespace Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting +{ + public class CommentingStyleBundleContributor : BundleContributor + { + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files.AddIfNotContains("/Pages/CmsKit/Shared/Components/Commenting/default.css"); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingViewComponent.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingViewComponent.cs new file mode 100644 index 0000000000..d73174c1dc --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingViewComponent.cs @@ -0,0 +1,92 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Widgets; +using Volo.CmsKit.Reactions; + +namespace Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting +{ + [ViewComponent(Name = "CmsCommenting")] + [Widget( + ScriptTypes = new[] {typeof(CommentingScriptBundleContributor)}, + StyleTypes = new[] {typeof(CommentingStyleBundleContributor)}, + RefreshUrl = "/CmsKitPublicWidgets/Commenting" + )] + public class CommentingViewComponent : AbpViewComponent + { + protected IReactionPublicAppService ReactionPublicAppService { get; } + + protected CmsKitUiOptions Options { get; } + + public CommentingViewComponent( + IReactionPublicAppService reactionPublicAppService, + IOptions options) + { + } + + public virtual async Task InvokeAsync( + string entityType, + string entityId) + { + + return View("~/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml", new CommentingViewModel + { + EntityType = entityType, + EntityId = entityId, + Reactions = new List() + }); + + var result = await ReactionPublicAppService.GetForSelectionAsync(entityType, entityId); + + var viewModel = new CommentingViewModel + { + EntityType = entityType, + EntityId = entityId, + Reactions = new List() + }; + + foreach (var reactionDto in result.Items) + { + viewModel.Reactions.Add( + new CommentViewModel //TODO: AutoMap + { + Name = reactionDto.Reaction.Name, + DisplayName = reactionDto.Reaction.DisplayName, + Icon = Options.ReactionIcons.GetLocalizedIcon(reactionDto.Reaction.Name), + Count = reactionDto.Count, + IsSelectedByCurrentUser = reactionDto.IsSelectedByCurrentUser + }); + } + + return View("~/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml", viewModel); + } + + public class CommentingViewModel + { + public string EntityType { get; set; } + + public string EntityId { get; set; } + + public List Reactions { get; set; } + } + + public class CommentViewModel + { + [NotNull] + public string Name { get; set; } + + [CanBeNull] + public string DisplayName { get; set; } + + [NotNull] + public string Icon { get; set; } + + public int Count { get; set; } + + public bool IsSelectedByCurrentUser { get; set; } + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml new file mode 100644 index 0000000000..af2f1d2fea --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml @@ -0,0 +1,22 @@ +@model Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting.CommentingViewComponent.CommentingViewModel +
+
+
Yunus Emre Kalkan
+

+ Lorem Ipsum is simply dummy text of the printing and typesetting industry. + Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, + when an unknown printer took a galley of type and scrambled it to make a type specimen book. + It has survived not only five centuries, but also the leap into electronic typesetting. +

+
+
+
+
Yunus Emre Kalkan
+

+ Lorem Ipsum is simply dummy text of the printing and typesetting industry. + Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, + when an unknown printer took a galley of type and scrambled it to make a type specimen book. + It has survived not only five centuries, but also the leap into electronic typesetting. +

+
+
diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.css b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.css new file mode 100644 index 0000000000..8e27846c5c --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.css @@ -0,0 +1,13 @@ +.cms-reaction-select-icon +{ + cursor: pointer; +} +.cms-reaction-icon +{ + cursor: pointer; + padding: 3px 5px 5px; +} +.cms-reaction-icon-selected +{ + background-color: #eef; +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.js b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.js new file mode 100644 index 0000000000..543e56e216 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.js @@ -0,0 +1,76 @@ +(function ($) { + + /* + var l = abp.localization.getResource('CmsKit'); + + var myDefaultWhiteList = $.fn.tooltip.Constructor.Default.whiteList; + + if (myDefaultWhiteList.span.indexOf('data-reaction-name') < 0) { + myDefaultWhiteList.span.push('data-reaction-name'); + } + + $(document).ready(function () { + + abp.widgets.CmsReactionSelection = function ($widget) { + var widgetManager = $widget.data('abp-widget-manager'); + var $reactionArea = $widget.find('.cms-reaction-area'); + var $selectIcon = $widget.find('.cms-reaction-select-icon'); + var $popoverContent = $widget.find('.cms-reaction-selection-popover-content'); + + function getFilters() { + return { + entityType: $reactionArea.attr('data-entity-type'), + entityId: $reactionArea.attr('data-entity-id') + }; + } + + function registerClickOfReactionIcons($container) { + $container.find('.cms-reaction-icon').each(function () { + var $icon = $(this); + $icon.click(function () { + var methodName = $icon.hasClass('cms-reaction-icon-selected') ? 'delete' : 'create'; + volo.cmsKit.reactions.reactionPublic[methodName]( + $.extend(getFilters(), { + reactionName: $icon.attr('data-reaction-name') + }) + ).then(function () { + $selectIcon.popover('hide'); + widgetManager.refresh($widget); + }); + }); + }); + } + + function init() { + + $selectIcon.popover({ + placement: 'right', + html: true, + trigger: 'focus', + title: l('PickYourReaction'), + content: $popoverContent.html() + }).on('shown.bs.popover', function () { + var $popover = $('#' + $selectIcon.attr('aria-describedby')); + registerClickOfReactionIcons($popover); + }); + + registerClickOfReactionIcons($widget); + } + + return { + init: init, + getFilters: getFilters + }; + }; + + $('.abp-widget-wrapper[data-widget-name="CmsCommenting"]') + .each(function () { + var widgetManager = new abp.WidgetManager({ + wrapper: $(this), + }); + + widgetManager.init(); + }); + }); + */ +})(jQuery); From 345adb41f86de09cb696e2598a534e3eca276c1b Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 29 Jul 2020 11:18:37 +0300 Subject: [PATCH 02/13] CmsKit: Created CmsUser --- .../Volo.CmsKit.Domain.csproj | 1 + .../Volo/CmsKit/CmsKitDomainModule.cs | 2 + .../Volo/CmsKit/Users/CmsUser.cs | 82 +++++++++++++++++++ .../Volo/CmsKit/Users/CmsUserLookupService.cs | 24 ++++++ .../Volo/CmsKit/Users/CmsUserSynchronizer.cs | 43 ++++++++++ .../CmsKit/Users/ICmsUserLookupService.cs | 9 ++ .../Volo/CmsKit/Users/ICmsUserRepository.cs | 9 ++ .../Volo.CmsKit.EntityFrameworkCore.csproj | 3 +- .../EntityFrameworkCore/CmsKitDbContext.cs | 3 + .../CmsKitDbContextModelCreatingExtensions.cs | 10 +++ .../CmsKitEntityFrameworkCoreModule.cs | 13 ++- .../EntityFrameworkCore/ICmsKitDbContext.cs | 3 + .../CmsKit/Users/EfCoreCmsUserRepository.cs | 14 ++++ 13 files changed, 211 insertions(+), 5 deletions(-) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Users/CmsUser.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Users/CmsUserLookupService.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Users/CmsUserSynchronizer.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Users/ICmsUserLookupService.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Users/ICmsUserRepository.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Users/EfCoreCmsUserRepository.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj index f016bed623..ee064cbedc 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj @@ -11,6 +11,7 @@ + diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs index e67bca57df..7659c40126 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs @@ -1,11 +1,13 @@ using Volo.Abp.Domain; using Volo.Abp.Modularity; +using Volo.Abp.Users; using Volo.CmsKit.Reactions; namespace Volo.CmsKit { [DependsOn( typeof(CmsKitDomainSharedModule), + typeof(AbpUsersDomainModule), typeof(AbpDddDomainModule) )] public class CmsKitDomainModule : AbpModule diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Users/CmsUser.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Users/CmsUser.cs new file mode 100644 index 0000000000..7e66aae6a1 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Users/CmsUser.cs @@ -0,0 +1,82 @@ +using System; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Users; + +namespace Volo.CmsKit.Users +{ + public class CmsUser : AggregateRoot, IUser, IUpdateUserData + { + public virtual Guid? TenantId { get; protected set; } + + public virtual string UserName { get; protected set; } + + public virtual string Email { get; protected set; } + + public virtual string Name { get; set; } + + public virtual string Surname { get; set; } + + public virtual bool EmailConfirmed { get; protected set; } + + public virtual string PhoneNumber { get; protected set; } + + public virtual bool PhoneNumberConfirmed { get; protected set; } + + protected CmsUser() + { + + } + + public CmsUser(IUserData user) + : base(user.Id) + { + TenantId = user.TenantId; + UpdateInternal(user); + } + + public virtual bool Update(IUserData user) + { + if (Id != user.Id) + { + throw new ArgumentException($"Given User's Id '{user.Id}' does not match to this User's Id '{Id}'"); + } + + if (TenantId != user.TenantId) + { + throw new ArgumentException($"Given User's TenantId '{user.TenantId}' does not match to this User's TenantId '{TenantId}'"); + } + + if (Equals(user)) + { + return false; + } + + UpdateInternal(user); + return true; + } + + protected virtual bool Equals(IUserData user) + { + return Id == user.Id && + TenantId == user.TenantId && + UserName == user.UserName && + Name == user.Name && + Surname == user.Surname && + Email == user.Email && + EmailConfirmed == user.EmailConfirmed && + PhoneNumber == user.PhoneNumber && + PhoneNumberConfirmed == user.PhoneNumberConfirmed; + } + + protected virtual void UpdateInternal(IUserData user) + { + Email = user.Email; + Name = user.Name; + Surname = user.Surname; + EmailConfirmed = user.EmailConfirmed; + PhoneNumber = user.PhoneNumber; + PhoneNumberConfirmed = user.PhoneNumberConfirmed; + UserName = user.UserName; + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Users/CmsUserLookupService.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Users/CmsUserLookupService.cs new file mode 100644 index 0000000000..0771140a10 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Users/CmsUserLookupService.cs @@ -0,0 +1,24 @@ +using Volo.Abp.Uow; +using Volo.Abp.Users; + +namespace Volo.CmsKit.Users +{ + public class CmsUserLookupService: UserLookupService, ICmsUserLookupService + { + public CmsUserLookupService( + ICmsUserRepository userRepository, + IUnitOfWorkManager unitOfWorkManager) + : base( + userRepository, + unitOfWorkManager) + { + + } + + protected override CmsUser CreateUser(IUserData externalUser) + { + return new CmsUser(externalUser); + } + + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Users/CmsUserSynchronizer.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Users/CmsUserSynchronizer.cs new file mode 100644 index 0000000000..6fc785ad4a --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Users/CmsUserSynchronizer.cs @@ -0,0 +1,43 @@ +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Users; + +namespace Volo.CmsKit.Users +{ + public class CmsUserSynchronizer : + IDistributedEventHandler>, + ITransientDependency + { + protected ICmsUserRepository UserRepository { get; } + + protected ICmsUserLookupService UserLookupService { get; } + + public CmsUserSynchronizer( + ICmsUserRepository userRepository, + ICmsUserLookupService userLookupService) + { + UserRepository = userRepository; + UserLookupService = userLookupService; + } + + public virtual async Task HandleEventAsync(EntityUpdatedEto eventData) + { + var user = await UserRepository.FindAsync(eventData.Entity.Id); + if (user == null) + { + user = await UserLookupService.FindByIdAsync(eventData.Entity.Id); + if (user == null) + { + return; + } + } + + if (user.Update(eventData.Entity)) + { + await UserRepository.UpdateAsync(user); + } + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Users/ICmsUserLookupService.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Users/ICmsUserLookupService.cs new file mode 100644 index 0000000000..8731a187fc --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Users/ICmsUserLookupService.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Users; + +namespace Volo.CmsKit.Users +{ + public interface ICmsUserLookupService : IUserLookupService + { + + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Users/ICmsUserRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Users/ICmsUserRepository.cs new file mode 100644 index 0000000000..95971911af --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Users/ICmsUserRepository.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Users; + +namespace Volo.CmsKit.Users +{ + public interface ICmsUserRepository: IUserRepository + { + + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo.CmsKit.EntityFrameworkCore.csproj b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo.CmsKit.EntityFrameworkCore.csproj index de174d0afd..ace2e010bd 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo.CmsKit.EntityFrameworkCore.csproj +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo.CmsKit.EntityFrameworkCore.csproj @@ -10,7 +10,8 @@ - + + diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs index 01384a3aa1..8033522f70 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs @@ -3,6 +3,7 @@ using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; using Volo.CmsKit.Comments; using Volo.CmsKit.Reactions; +using Volo.CmsKit.Users; namespace Volo.CmsKit.EntityFrameworkCore { @@ -13,6 +14,8 @@ namespace Volo.CmsKit.EntityFrameworkCore public DbSet Comments { get; set; } + public DbSet CmsUsers { get; set; } + public CmsKitDbContext(DbContextOptions options) : base(options) { diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs index e551412d5e..cb7a7b78d6 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs @@ -4,6 +4,8 @@ using Volo.Abp; using Volo.Abp.EntityFrameworkCore.Modeling; using Volo.CmsKit.Comments; using Volo.CmsKit.Reactions; +using Volo.CmsKit.Users; +using Volo.Abp.Users.EntityFrameworkCore; namespace Volo.CmsKit.EntityFrameworkCore { @@ -22,6 +24,14 @@ namespace Volo.CmsKit.EntityFrameworkCore optionsAction?.Invoke(options); + builder.Entity(b => + { + b.ToTable(options.TablePrefix + "Users", options.Schema); + + b.ConfigureByConvention(); + b.ConfigureAbpUser(); + }); + builder.Entity(b => { b.ToTable(options.TablePrefix + "UserReactions", options.Schema); diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitEntityFrameworkCoreModule.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitEntityFrameworkCoreModule.cs index afad9b56e8..028bc466b2 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitEntityFrameworkCoreModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitEntityFrameworkCoreModule.cs @@ -1,11 +1,16 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.Modularity; +using Volo.Abp.Users.EntityFrameworkCore; +using Volo.CmsKit.Comments; +using Volo.CmsKit.Reactions; +using Volo.CmsKit.Users; namespace Volo.CmsKit.EntityFrameworkCore { [DependsOn( typeof(CmsKitDomainModule), + typeof(AbpUsersEntityFrameworkCoreModule), typeof(AbpEntityFrameworkCoreModule) )] public class CmsKitEntityFrameworkCoreModule : AbpModule @@ -14,10 +19,10 @@ namespace Volo.CmsKit.EntityFrameworkCore { context.Services.AddAbpDbContext(options => { - /* Add custom repositories here. Example: - * options.AddRepository(); - */ + options.AddRepository(); + options.AddRepository(); + options.AddRepository(); }); } } -} \ No newline at end of file +} diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/ICmsKitDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/ICmsKitDbContext.cs index ecd807d005..e63366d5ae 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/ICmsKitDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/ICmsKitDbContext.cs @@ -3,6 +3,7 @@ using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; using Volo.CmsKit.Comments; using Volo.CmsKit.Reactions; +using Volo.CmsKit.Users; namespace Volo.CmsKit.EntityFrameworkCore { @@ -12,5 +13,7 @@ namespace Volo.CmsKit.EntityFrameworkCore DbSet UserReactions { get; } DbSet Comments { get; } + + DbSet CmsUsers { get; set; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Users/EfCoreCmsUserRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Users/EfCoreCmsUserRepository.cs new file mode 100644 index 0000000000..0b6e804be0 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Users/EfCoreCmsUserRepository.cs @@ -0,0 +1,14 @@ +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Users.EntityFrameworkCore; +using Volo.CmsKit.EntityFrameworkCore; + +namespace Volo.CmsKit.Users +{ + public class EfCoreCmsUserRepository: EfCoreUserRepositoryBase, ICmsUserRepository + { + public EfCoreCmsUserRepository(IDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + } + } +} From f7b3f1eb1c65cde2d4279bb9aa28d7addec53a5c Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 29 Jul 2020 17:47:02 +0300 Subject: [PATCH 03/13] Cmskit comment improvements --- .../20200719204212_Added_Reactions.cs | 43 ------- ....cs => 20200729125121_Initial.Designer.cs} | 109 +++++++++++++++++- ...0_Initial.cs => 20200729125121_Initial.cs} | 83 +++++++++++++ .../UnifiedDbContextModelSnapshot.cs | 105 +++++++++++++++++ .../CmsKit/Localization/Resources/en.json | 8 +- .../Volo/CmsKit/Comments/CommentWithAuthor.cs | 11 ++ .../CmsKit/Comments/ICommentRepository.cs | 2 +- .../Comments/EfCoreCommentRepository.cs | 19 ++- .../Volo/CmsKit/Comments/CmsUserDto.cs | 17 +++ .../Volo/CmsKit/Comments/CommentDto.cs | 4 +- ...RepliesDto.cs => CommentWithDetailsDto.cs} | 4 +- .../Comments/ICommentPublicAppService.cs | 3 +- .../Comments/CommentPublicAppService.cs | 43 +++++-- .../PublicApplicationAutoMapperProfile.cs | 6 +- .../Comments/CommentPublicController.cs | 3 +- .../CmsKitPublicWidgetsController.cs | 6 + .../Commenting/CommentingViewComponent.cs | 62 ++-------- .../Components/Commenting/Default.cshtml | 103 ++++++++++++++--- .../Shared/Components/Commenting/default.css | 14 +-- .../Shared/Components/Commenting/default.js | 96 +++++++++------ 20 files changed, 554 insertions(+), 187 deletions(-) delete mode 100644 modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200719204212_Added_Reactions.cs rename modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/{20200719204212_Added_Reactions.Designer.cs => 20200729125121_Initial.Designer.cs} (91%) rename modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/{20200624023340_Initial.cs => 20200729125121_Initial.cs} (88%) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/CommentWithAuthor.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CmsUserDto.cs rename modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/{CommentWithRepliesDto.cs => CommentWithDetailsDto.cs} (82%) diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200719204212_Added_Reactions.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200719204212_Added_Reactions.cs deleted file mode 100644 index c853458396..0000000000 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200719204212_Added_Reactions.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -namespace Volo.CmsKit.Migrations -{ - public partial class Added_Reactions : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "CmsUserReactions", - columns: table => new - { - Id = table.Column(nullable: false), - EntityType = table.Column(maxLength: 64, nullable: false), - EntityId = table.Column(maxLength: 64, nullable: false), - ReactionName = table.Column(maxLength: 32, nullable: false), - CreatorId = table.Column(nullable: false), - CreationTime = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_CmsUserReactions", x => x.Id); - }); - - migrationBuilder.CreateIndex( - name: "IX_CmsUserReactions_EntityType_EntityId", - table: "CmsUserReactions", - columns: new[] { "EntityType", "EntityId" }); - - migrationBuilder.CreateIndex( - name: "IX_CmsUserReactions_CreatorId_EntityType_EntityId_ReactionName", - table: "CmsUserReactions", - columns: new[] { "CreatorId", "EntityType", "EntityId", "ReactionName" }); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "CmsUserReactions"); - } - } -} diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200719204212_Added_Reactions.Designer.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200729125121_Initial.Designer.cs similarity index 91% rename from modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200719204212_Added_Reactions.Designer.cs rename to modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200729125121_Initial.Designer.cs index 71e8e68f91..9d5d5e7c9d 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200719204212_Added_Reactions.Designer.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200729125121_Initial.Designer.cs @@ -11,8 +11,8 @@ using Volo.CmsKit.EntityFrameworkCore; namespace Volo.CmsKit.Migrations { [DbContext(typeof(UnifiedDbContext))] - [Migration("20200719204212_Added_Reactions")] - partial class Added_Reactions + [Migration("20200729125121_Initial")] + partial class Initial { protected override void BuildTargetModel(ModelBuilder modelBuilder) { @@ -914,6 +914,47 @@ namespace Volo.CmsKit.Migrations b.ToTable("AbpTenantConnectionStrings"); }); + modelBuilder.Entity("Volo.CmsKit.Comments.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityId") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("RepliedCommentId") + .HasColumnType("uniqueidentifier"); + + b.Property("Text") + .IsRequired() + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.HasKey("Id"); + + b.HasIndex("RepliedCommentId"); + + b.HasIndex("EntityType", "EntityId"); + + b.ToTable("CmsComments"); + }); + modelBuilder.Entity("Volo.CmsKit.Reactions.UserReaction", b => { b.Property("Id") @@ -952,6 +993,70 @@ namespace Volo.CmsKit.Migrations b.ToTable("CmsUserReactions"); }); + modelBuilder.Entity("Volo.CmsKit.Users.CmsUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("nvarchar(40)") + .HasMaxLength(40); + + b.Property("Email") + .IsRequired() + .HasColumnName("Email") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnName("EmailConfirmed") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnName("Name") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("PhoneNumber") + .HasColumnName("PhoneNumber") + .HasColumnType("nvarchar(16)") + .HasMaxLength(16); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnName("PhoneNumberConfirmed") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("Surname") + .HasColumnName("Surname") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserName") + .IsRequired() + .HasColumnName("UserName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.ToTable("CmsUsers"); + }); + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => { b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200624023340_Initial.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200729125121_Initial.cs similarity index 88% rename from modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200624023340_Initial.cs rename to modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200729125121_Initial.cs index d749beb7b8..6f8b2a069c 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200624023340_Initial.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20200729125121_Initial.cs @@ -195,6 +195,60 @@ namespace Volo.CmsKit.Migrations table.PrimaryKey("PK_AbpUsers", x => x.Id); }); + migrationBuilder.CreateTable( + name: "CmsComments", + columns: table => new + { + Id = table.Column(nullable: false), + EntityType = table.Column(maxLength: 64, nullable: false), + EntityId = table.Column(maxLength: 64, nullable: false), + Text = table.Column(maxLength: 512, nullable: false), + RepliedCommentId = table.Column(nullable: true), + CreatorId = table.Column(nullable: false), + CreationTime = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CmsComments", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "CmsUserReactions", + columns: table => new + { + Id = table.Column(nullable: false), + EntityType = table.Column(maxLength: 64, nullable: false), + EntityId = table.Column(maxLength: 64, nullable: false), + ReactionName = table.Column(maxLength: 32, nullable: false), + CreatorId = table.Column(nullable: false), + CreationTime = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CmsUserReactions", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "CmsUsers", + columns: table => new + { + Id = table.Column(nullable: false), + ExtraProperties = table.Column(nullable: true), + ConcurrencyStamp = table.Column(maxLength: 40, nullable: true), + TenantId = table.Column(nullable: true), + UserName = table.Column(maxLength: 256, nullable: false), + Email = table.Column(maxLength: 256, nullable: false), + Name = table.Column(maxLength: 64, nullable: true), + Surname = table.Column(maxLength: 64, nullable: true), + EmailConfirmed = table.Column(nullable: false, defaultValue: false), + PhoneNumber = table.Column(maxLength: 16, nullable: true), + PhoneNumberConfirmed = table.Column(nullable: false, defaultValue: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CmsUsers", x => x.Id); + }); + migrationBuilder.CreateTable( name: "AbpAuditLogActions", columns: table => new @@ -564,6 +618,26 @@ namespace Volo.CmsKit.Migrations name: "IX_AbpUsers_UserName", table: "AbpUsers", column: "UserName"); + + migrationBuilder.CreateIndex( + name: "IX_CmsComments_RepliedCommentId", + table: "CmsComments", + column: "RepliedCommentId"); + + migrationBuilder.CreateIndex( + name: "IX_CmsComments_EntityType_EntityId", + table: "CmsComments", + columns: new[] { "EntityType", "EntityId" }); + + migrationBuilder.CreateIndex( + name: "IX_CmsUserReactions_EntityType_EntityId", + table: "CmsUserReactions", + columns: new[] { "EntityType", "EntityId" }); + + migrationBuilder.CreateIndex( + name: "IX_CmsUserReactions_CreatorId_EntityType_EntityId_ReactionName", + table: "CmsUserReactions", + columns: new[] { "CreatorId", "EntityType", "EntityId", "ReactionName" }); } protected override void Down(MigrationBuilder migrationBuilder) @@ -607,6 +681,15 @@ namespace Volo.CmsKit.Migrations migrationBuilder.DropTable( name: "AbpUserTokens"); + migrationBuilder.DropTable( + name: "CmsComments"); + + migrationBuilder.DropTable( + name: "CmsUserReactions"); + + migrationBuilder.DropTable( + name: "CmsUsers"); + migrationBuilder.DropTable( name: "AbpEntityChanges"); diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs index 35d92b2cc6..be32e92f05 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs @@ -912,6 +912,47 @@ namespace Volo.CmsKit.Migrations b.ToTable("AbpTenantConnectionStrings"); }); + modelBuilder.Entity("Volo.CmsKit.Comments.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime2"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityId") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("RepliedCommentId") + .HasColumnType("uniqueidentifier"); + + b.Property("Text") + .IsRequired() + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.HasKey("Id"); + + b.HasIndex("RepliedCommentId"); + + b.HasIndex("EntityType", "EntityId"); + + b.ToTable("CmsComments"); + }); + modelBuilder.Entity("Volo.CmsKit.Reactions.UserReaction", b => { b.Property("Id") @@ -950,6 +991,70 @@ namespace Volo.CmsKit.Migrations b.ToTable("CmsUserReactions"); }); + modelBuilder.Entity("Volo.CmsKit.Users.CmsUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("nvarchar(40)") + .HasMaxLength(40); + + b.Property("Email") + .IsRequired() + .HasColumnName("Email") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnName("EmailConfirmed") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnName("Name") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("PhoneNumber") + .HasColumnName("PhoneNumber") + .HasColumnType("nvarchar(16)") + .HasMaxLength(16); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnName("PhoneNumberConfirmed") + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("Surname") + .HasColumnName("Surname") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserName") + .IsRequired() + .HasColumnName("UserName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.ToTable("CmsUsers"); + }); + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => { b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json index e1bdb1b209..4df6575fbf 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json @@ -1,6 +1,12 @@ { "culture": "en", "texts": { - "PickYourReaction": "Pick your reaction" + "PickYourReaction": "Pick your reaction", + "YourComment": "Your comment", + "YourReply": "Your reply", + "Send": "Send", + "Delete": "delete", + "Reply": "reply", + "MessageDeletionConfirmationMessage": "This comment will be deleted completely." } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/CommentWithAuthor.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/CommentWithAuthor.cs new file mode 100644 index 0000000000..3a04a31ee8 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/CommentWithAuthor.cs @@ -0,0 +1,11 @@ +using Volo.CmsKit.Users; + +namespace Volo.CmsKit.Comments +{ + public class CommentWithAuthor + { + public Comment Comment { get; set; } + + public CmsUser Author { get; set; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/ICommentRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/ICommentRepository.cs index a189c8938e..f4839b8c5b 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/ICommentRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/ICommentRepository.cs @@ -8,7 +8,7 @@ namespace Volo.CmsKit.Comments { public interface ICommentRepository : IBasicRepository { - Task> GetListAsync( + Task> GetListAsync( [NotNull] string entityType, [NotNull] string entityId); } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Comments/EfCoreCommentRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Comments/EfCoreCommentRepository.cs index 42e9de4f32..f0a3b9a908 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Comments/EfCoreCommentRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Comments/EfCoreCommentRepository.cs @@ -19,18 +19,24 @@ namespace Volo.CmsKit.Comments { } - public async Task> GetListAsync( + public async Task> GetListAsync( string entityType, string entityId) { Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); Check.NotNullOrWhiteSpace(entityId, nameof(entityId)); - return await DbSet - .Where(x => - x.EntityType == entityType && - x.EntityId == entityId) - .ToListAsync(); + var query = from comment in DbSet + join user in DbContext.CmsUsers on comment.CreatorId equals user.Id + where entityType == comment.EntityType && entityId == comment.EntityId + orderby comment.CreationTime + select new CommentWithAuthor + { + Comment = comment, + Author = user + }; + + return await query.ToListAsync(); } public override async Task DeleteAsync(Guid id, bool autoSave = false, CancellationToken cancellationToken = default) @@ -41,6 +47,7 @@ namespace Volo.CmsKit.Comments foreach (var reply in replies) { + //TODO: Discuss if it is better to mark it as deleted and show in the ui as "This is deleted" instead of deleting it and replies completely await base.DeleteAsync(reply.Id, autoSave, GetCancellationToken(cancellationToken)); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CmsUserDto.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CmsUserDto.cs new file mode 100644 index 0000000000..3446517efd --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CmsUserDto.cs @@ -0,0 +1,17 @@ +using System; + +namespace Volo.CmsKit.Comments +{ + public class CmsUserDto + { + public Guid Id { get; set; } + + public string UserName { get; set; } + + public string Email { get; set; } + + public string Name { get; set; } + + public string Surname { get; set; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CommentDto.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CommentDto.cs index 0852bab22e..1dd2ac4056 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CommentDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CommentDto.cs @@ -17,5 +17,7 @@ namespace Volo.CmsKit.Comments public Guid CreatorId { get; set; } public DateTime CreationTime { get; set; } + + public CmsUserDto Author { get; set; } } -} \ No newline at end of file +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CommentWithRepliesDto.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CommentWithDetailsDto.cs similarity index 82% rename from modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CommentWithRepliesDto.cs rename to modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CommentWithDetailsDto.cs index a9e682f856..5938316b84 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CommentWithRepliesDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/CommentWithDetailsDto.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; namespace Volo.CmsKit.Comments { - public class CommentWithRepliesDto + public class CommentWithDetailsDto { public Guid Id { get; set; } @@ -18,5 +18,7 @@ namespace Volo.CmsKit.Comments public DateTime CreationTime { get; set; } public List Replies { get; set; } + + public CmsUserDto Author { get; set; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/ICommentPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/ICommentPublicAppService.cs index bffe742aca..385a7ea92a 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/ICommentPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Comments/ICommentPublicAppService.cs @@ -2,13 +2,14 @@ using System.Collections.Generic; using System.Threading.Tasks; using JetBrains.Annotations; +using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; namespace Volo.CmsKit.Comments { public interface ICommentPublicAppService : IApplicationService { - Task> GetAllForEntityAsync(string entityType, string entityId); + Task> GetAllForEntityAsync(string entityType, string entityId); Task CreateAsync(CreateCommentInput input); diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Comments/CommentPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Comments/CommentPublicAppService.cs index 7833460f0d..eb09af2afa 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Comments/CommentPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Comments/CommentPublicAppService.cs @@ -4,7 +4,9 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Volo.Abp; +using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; +using Volo.CmsKit.Users; namespace Volo.CmsKit.Comments { @@ -12,21 +14,32 @@ namespace Volo.CmsKit.Comments public class CommentPublicAppService : ApplicationService, ICommentPublicAppService { protected ICommentRepository CommentRepository { get; } + public ICmsUserLookupService CmsUserLookupService { get; } - public CommentPublicAppService(ICommentRepository commentRepository) + public CommentPublicAppService(ICommentRepository commentRepository, ICmsUserLookupService cmsUserLookupService) { CommentRepository = commentRepository; + CmsUserLookupService = cmsUserLookupService; } - public async Task> GetAllForEntityAsync(string entityType, string entityId) + public async Task> GetAllForEntityAsync(string entityType, string entityId) { - var comments = await CommentRepository.GetListAsync(entityType, entityId); + var commentsWithAuthor = await CommentRepository.GetListAsync(entityType, entityId); - return ConvertCommentsToNestedStructure(comments); + return new ListResultDto( + ConvertCommentsToNestedStructure(commentsWithAuthor) + ); } public async Task CreateAsync(CreateCommentInput input) { + var user = await CmsUserLookupService.FindByIdAsync(CurrentUser.Id.Value); + + if (user == null) + { + throw new BusinessException(message: "User Not found!"); + } + var comment = await CommentRepository.InsertAsync(new Comment( GuidGenerator.Create(), input.EntityType, @@ -62,22 +75,34 @@ namespace Volo.CmsKit.Comments await CommentRepository.DeleteAsync(id); } - private List ConvertCommentsToNestedStructure(List comments) + private List ConvertCommentsToNestedStructure(List comments) { var parentComments = comments - .Where(c=> c.RepliedCommentId == null) - .Select(c=> ObjectMapper.Map(c)) + .Where(c=> c.Comment.RepliedCommentId == null) + .Select(c=> ObjectMapper.Map(c.Comment)) .ToList(); foreach (var parentComment in parentComments) { + parentComment.Author = GetAuthorAsDtoFromCommentList(comments, parentComment.Id); + parentComment.Replies = comments - .Where(c => c.RepliedCommentId == parentComment.Id) - .Select(c => ObjectMapper.Map(c)) + .Where(c => c.Comment.RepliedCommentId == parentComment.Id) + .Select(c => ObjectMapper.Map(c.Comment)) .ToList(); + + foreach (var reply in parentComment.Replies) + { + reply.Author = GetAuthorAsDtoFromCommentList(comments, reply.Id); + } } return parentComments; } + + private CmsUserDto GetAuthorAsDtoFromCommentList(List comments, Guid commentId) + { + return ObjectMapper.Map(comments.Single(c => c.Comment.Id == commentId).Author); + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/PublicApplicationAutoMapperProfile.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/PublicApplicationAutoMapperProfile.cs index 695bb8376c..d26814c0c8 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/PublicApplicationAutoMapperProfile.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/PublicApplicationAutoMapperProfile.cs @@ -1,6 +1,7 @@ using AutoMapper; using Volo.Abp.AutoMapper; using Volo.CmsKit.Comments; +using Volo.CmsKit.Users; namespace Volo.CmsKit { @@ -12,8 +13,9 @@ namespace Volo.CmsKit * Alternatively, you can split your mapping configurations * into multiple profile classes for a better organization. */ - CreateMap(); - CreateMap().Ignore(x=> x.Replies); + CreateMap(); + CreateMap().Ignore(x=> x.Author); + CreateMap().Ignore(x=> x.Replies).Ignore(x=> x.Author); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Comments/CommentPublicController.cs b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Comments/CommentPublicController.cs index cc5cedb309..de8e4e0c83 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Comments/CommentPublicController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Comments/CommentPublicController.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Volo.Abp; +using Volo.Abp.Application.Dtos; namespace Volo.CmsKit.Comments { @@ -20,7 +21,7 @@ namespace Volo.CmsKit.Comments [HttpGet] [Route("{entityType}/{entityId}")] - public Task> GetAllForEntityAsync(string entityType, string entityId) + public Task> GetAllForEntityAsync(string entityType, string entityId) { return CommentPublicAppService.GetAllForEntityAsync(entityType, entityId); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/CmsKitPublicWidgetsController.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/CmsKitPublicWidgetsController.cs index 3534811ad3..5988c33f41 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/CmsKitPublicWidgetsController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/CmsKitPublicWidgetsController.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting; using Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.ReactionSelection; namespace Volo.CmsKit.Web.Controllers @@ -11,5 +12,10 @@ namespace Volo.CmsKit.Web.Controllers { return ViewComponent(typeof(ReactionSelectionViewComponent), new {entityType, entityId}); } + + public async Task Commenting(string entityType, string entityId) + { + return ViewComponent(typeof(CommentingViewComponent), new {entityType, entityId}); + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingViewComponent.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingViewComponent.cs index d73174c1dc..9f97619d57 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingViewComponent.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingViewComponent.cs @@ -1,11 +1,10 @@ using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; -using JetBrains.Annotations; using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Options; using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; -using Volo.CmsKit.Reactions; +using Volo.CmsKit.Comments; namespace Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting { @@ -17,50 +16,25 @@ namespace Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting )] public class CommentingViewComponent : AbpViewComponent { - protected IReactionPublicAppService ReactionPublicAppService { get; } - - protected CmsKitUiOptions Options { get; } + public ICommentPublicAppService CommentPublicAppService { get; } public CommentingViewComponent( - IReactionPublicAppService reactionPublicAppService, - IOptions options) + ICommentPublicAppService commentPublicAppService) { + CommentPublicAppService = commentPublicAppService; } - public virtual async Task InvokeAsync( - string entityType, - string entityId) + public virtual async Task InvokeAsync( string entityType,string entityId) { - - return View("~/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml", new CommentingViewModel - { - EntityType = entityType, - EntityId = entityId, - Reactions = new List() - }); - - var result = await ReactionPublicAppService.GetForSelectionAsync(entityType, entityId); + var result = await CommentPublicAppService.GetAllForEntityAsync(entityType, entityId); var viewModel = new CommentingViewModel { - EntityType = entityType, EntityId = entityId, - Reactions = new List() + EntityType = entityType, + Comments = result.Items.ToList() }; - foreach (var reactionDto in result.Items) - { - viewModel.Reactions.Add( - new CommentViewModel //TODO: AutoMap - { - Name = reactionDto.Reaction.Name, - DisplayName = reactionDto.Reaction.DisplayName, - Icon = Options.ReactionIcons.GetLocalizedIcon(reactionDto.Reaction.Name), - Count = reactionDto.Count, - IsSelectedByCurrentUser = reactionDto.IsSelectedByCurrentUser - }); - } - return View("~/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml", viewModel); } @@ -70,23 +44,7 @@ namespace Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting public string EntityId { get; set; } - public List Reactions { get; set; } - } - - public class CommentViewModel - { - [NotNull] - public string Name { get; set; } - - [CanBeNull] - public string DisplayName { get; set; } - - [NotNull] - public string Icon { get; set; } - - public int Count { get; set; } - - public bool IsSelectedByCurrentUser { get; set; } + public List Comments { get; set; } } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml index af2f1d2fea..b590cc8381 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml @@ -1,22 +1,87 @@ -@model Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting.CommentingViewComponent.CommentingViewModel +@using Microsoft.AspNetCore.Html +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.Users +@using Volo.CmsKit.Comments +@using Volo.CmsKit.Localization +@inject ICurrentUser CurrentUser +@inject IHtmlLocalizer L +@model Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting.CommentingViewComponent.CommentingViewModel + +@{ + Func GetCommentAuthorName(CmsUserDto author) => + @ + @((string.IsNullOrWhiteSpace(author.Name) + ? author.UserName + : author.Name + " " + author.Surname).Trim()) + ; +} +@{ + Func GetCommentArea(string repliedCommentIdAsString, bool cancelButton = false) => + @
+
+ +
+ + +
+ @if (cancelButton) + { + @L["Cancel"] + } + @L["Send"] +
+
; +} +
-
-
Yunus Emre Kalkan
-

- Lorem Ipsum is simply dummy text of the printing and typesetting industry. - Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, - when an unknown printer took a galley of type and scrambled it to make a type specimen book. - It has survived not only five centuries, but also the leap into electronic typesetting. -

-
-
-
-
Yunus Emre Kalkan
-

- Lorem Ipsum is simply dummy text of the printing and typesetting industry. - Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, - when an unknown printer took a galley of type and scrambled it to make a type specimen book. - It has survived not only five centuries, but also the leap into electronic typesetting. -

+ + @foreach (var comment in Model.Comments) + { +
+

+ + @GetCommentAuthorName(comment.Author).Invoke(null) +

+

+ @comment.Text +

+ + @if (comment.Author.Id == CurrentUser.Id) + { + + @L["Delete"] + + } + + + @L["Reply"] + + + @foreach (var reply in comment.Replies) + { +
+
+ + @GetCommentAuthorName(reply.Author).Invoke(null) +
+

+ @reply.Text +

+ + @if (reply.Author.Id == CurrentUser.Id) + { + + @L["Delete"] + + } +
+ } + + @GetCommentArea(comment.Id.ToString(), true).Invoke(null) +
+ } +
+ @GetCommentArea("").Invoke(null)
diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.css b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.css index 8e27846c5c..5f282702bb 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.css +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.css @@ -1,13 +1 @@ -.cms-reaction-select-icon -{ - cursor: pointer; -} -.cms-reaction-icon -{ - cursor: pointer; - padding: 3px 5px 5px; -} -.cms-reaction-icon-selected -{ - background-color: #eef; -} + \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.js b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.js index 543e56e216..10dc9c1766 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.js +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.js @@ -1,40 +1,76 @@ (function ($) { - /* var l = abp.localization.getResource('CmsKit'); - var myDefaultWhiteList = $.fn.tooltip.Constructor.Default.whiteList; - - if (myDefaultWhiteList.span.indexOf('data-reaction-name') < 0) { - myDefaultWhiteList.span.push('data-reaction-name'); - } - $(document).ready(function () { - abp.widgets.CmsReactionSelection = function ($widget) { + abp.widgets.CmsCommenting = function ($widget) { var widgetManager = $widget.data('abp-widget-manager'); - var $reactionArea = $widget.find('.cms-reaction-area'); - var $selectIcon = $widget.find('.cms-reaction-select-icon'); - var $popoverContent = $widget.find('.cms-reaction-selection-popover-content'); + var $commentArea = $widget.find('.cms-comment-area'); function getFilters() { return { - entityType: $reactionArea.attr('data-entity-type'), - entityId: $reactionArea.attr('data-entity-id') + entityType: $commentArea.attr('data-entity-type'), + entityId: $commentArea.attr('data-entity-id') }; } - function registerClickOfReactionIcons($container) { - $container.find('.cms-reaction-icon').each(function () { - var $icon = $(this); - $icon.click(function () { - var methodName = $icon.hasClass('cms-reaction-icon-selected') ? 'delete' : 'create'; - volo.cmsKit.reactions.reactionPublic[methodName]( + function registerReplyLinks($container) { + $container.find('.comment-reply-link').each(function () { + var $link = $(this); + $link.on('click', function (e) { + e.preventDefault(); + + var replyCommentId = $link.data('reply-id'); + + var relatedCommentArea = $container.find('.cms-comment-form-area[data-reply-id='+ replyCommentId +']'); + + relatedCommentArea.show(); + }); + }); + $container.find('.reply-cancel-button').each(function () { + var $button = $(this); + $button.on('click', function (e) { + e.preventDefault(); + + var replyCommentId = $button.data('reply-id'); + + var relatedCommentArea = $container.find('.cms-comment-form-area[data-reply-id='+ replyCommentId +']'); + + relatedCommentArea.hide(); + }); + }); + } + + function registerDeleteLinks($container) { + $container.find('.comment-delete-link').each(function () { + var $link = $(this); + $link.on('click', '', function (e) { + e.preventDefault(); + + abp.message.confirm(l("MessageDeletionConfirmationMessage"), function () { + volo.cmsKit.comments.commentPublic.delete($link.data('comment-id') + ).then(function () { + widgetManager.refresh($widget); + }); + }); + }); + }); + } + + function registerSubmissionOfNewComment($container) { + $container.find('.cms-comment-form').each(function () { + var $form = $(this); + $form.submit(function (e) { + e.preventDefault(); + var formAsObject = $form.serializeFormToObject(); + volo.cmsKit.comments.commentPublic.create( $.extend(getFilters(), { - reactionName: $icon.attr('data-reaction-name') + repliedCommentId: formAsObject.repliedCommentId, + text: formAsObject.commentText }) ).then(function () { - $selectIcon.popover('hide'); + $form.find('textarea').val(''); widgetManager.refresh($widget); }); }); @@ -42,19 +78,9 @@ } function init() { - - $selectIcon.popover({ - placement: 'right', - html: true, - trigger: 'focus', - title: l('PickYourReaction'), - content: $popoverContent.html() - }).on('shown.bs.popover', function () { - var $popover = $('#' + $selectIcon.attr('aria-describedby')); - registerClickOfReactionIcons($popover); - }); - - registerClickOfReactionIcons($widget); + registerReplyLinks($widget); + registerDeleteLinks($widget); + registerSubmissionOfNewComment($widget); } return { @@ -72,5 +98,5 @@ widgetManager.init(); }); }); - */ + })(jQuery); From 326d6810b716b175b0c4e8b6596a92dc9b7f2d8a Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 30 Jul 2020 10:24:39 +0300 Subject: [PATCH 04/13] cmskit comment: ui improvements --- .../Pages/Index.cshtml | 1 + .../CmsKit/Localization/Resources/en.json | 6 +- .../Comments/CommentPublicAppService.cs | 5 + .../Components/Commenting/Default.cshtml | 91 +++++++++++++------ .../Shared/Components/Commenting/default.js | 80 ++++++++++++++-- 5 files changed, 141 insertions(+), 42 deletions(-) diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Index.cshtml b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Index.cshtml index a0d01ae300..a8a6b82748 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Index.cshtml +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Index.cshtml @@ -41,4 +41,5 @@ @await Component.InvokeAsync(typeof(ReactionSelectionViewComponent), new { entityType = "quote", entityId = "2" }) + @await Component.InvokeAsync(typeof(CommentingViewComponent), new { entityType = "quote", entityId = "2" }) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json index 4df6575fbf..5749c5f66e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json @@ -5,8 +5,10 @@ "YourComment": "Your comment", "YourReply": "Your reply", "Send": "Send", - "Delete": "delete", - "Reply": "reply", + "Delete": "Delete", + "Reply": "Reply", + "Update": "Update", + "Edit": "Edit", "MessageDeletionConfirmationMessage": "This comment will be deleted completely." } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Comments/CommentPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Comments/CommentPublicAppService.cs index eb09af2afa..06991e6a42 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Comments/CommentPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Comments/CommentPublicAppService.cs @@ -56,6 +56,11 @@ namespace Volo.CmsKit.Comments { var comment = await CommentRepository.GetAsync(id); + if (comment.CreatorId != CurrentUser.Id) + { + throw new BusinessException(); + } + comment.SetText(input.Text); var updatedComment = await CommentRepository.UpdateAsync(comment); diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml index b590cc8381..dc3df1d270 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml @@ -33,52 +33,83 @@
; } +@{ + Func GetCommentContentArea(Guid id, Guid authorId, bool isReply, string text) => + @
+
+

+ @text +

+
+ + @if (!isReply) + { + + @L["Reply"] + + } + @if (authorId == CurrentUser.Id) + { + @if (!isReply) + { + | + } + + + @L["Delete"] + + + | + + + @L["Edit"] + + } + +
; +}
@foreach (var comment in Model.Comments) {
-

+

@GetCommentAuthorName(comment.Author).Invoke(null) -
-

- @comment.Text -

+ - @if (comment.Author.Id == CurrentUser.Id) - { - - @L["Delete"] - - } + @GetCommentContentArea(comment.Id, comment.Author.Id, false, comment.Text).Invoke(null) - - @L["Reply"] - + @GetCommentArea(comment.Id.ToString(), true).Invoke(null) - @foreach (var reply in comment.Replies) + @if (comment.Replies.Any()) { -
-
- - @GetCommentAuthorName(reply.Author).Invoke(null) -
-

- @reply.Text -

+
+ @foreach (var reply in comment.Replies) + { +
+
+ + @GetCommentAuthorName(reply.Author).Invoke(null) +
- @if (reply.Author.Id == CurrentUser.Id) - { - - @L["Delete"] - - } + @GetCommentContentArea(reply.Id, reply.Author.Id, true, reply.Text).Invoke(null) + +
+ }
} - @GetCommentArea(comment.Id.ToString(), true).Invoke(null)
}
diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.js b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.js index 10dc9c1766..29def70797 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.js +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/default.js @@ -15,6 +15,40 @@ }; } + function registerEditLinks($container) { + $container.find('.comment-edit-link').each(function () { + var $link = $(this); + $link.on('click', function (e) { + e.preventDefault(); + + var commentId = $link.data('id'); + + var $relatedCommentContentArea = $container.find('.cms-comment-content-area[data-id='+ commentId +']'); + var $relatedCommentEditFormArea = $container.find('.cms-comment-edit-area[data-id='+ commentId +']'); + + $relatedCommentContentArea.hide(); + $relatedCommentEditFormArea.show(); + $link.removeAttr('href'); + }); + }); + $container.find('.comment-edit-cancel-button').each(function () { + var $button = $(this); + $button.on('click', function (e) { + e.preventDefault(); + + var commentId = $button.data('id'); + + var $relatedCommentContentArea = $container.find('.cms-comment-content-area[data-id='+ commentId +']'); + var $relatedCommentEditFormArea = $container.find('.cms-comment-edit-area[data-id='+ commentId +']'); + var $link = $container.find('.comment-edit-link[data-id='+ commentId +']'); + + $relatedCommentContentArea.show(); + $relatedCommentEditFormArea.hide(); + $link.attr('href','#'); + }); + }); + } + function registerReplyLinks($container) { $container.find('.comment-reply-link').each(function () { var $link = $(this); @@ -23,9 +57,10 @@ var replyCommentId = $link.data('reply-id'); - var relatedCommentArea = $container.find('.cms-comment-form-area[data-reply-id='+ replyCommentId +']'); + var $relatedCommentArea = $container.find('.cms-comment-form-area[data-reply-id='+ replyCommentId +']'); - relatedCommentArea.show(); + $relatedCommentArea.show(); + $link.removeAttr('href'); }); }); $container.find('.reply-cancel-button').each(function () { @@ -35,9 +70,11 @@ var replyCommentId = $button.data('reply-id'); - var relatedCommentArea = $container.find('.cms-comment-form-area[data-reply-id='+ replyCommentId +']'); + var $relatedCommentArea = $container.find('.cms-comment-form-area[data-reply-id='+ replyCommentId +']'); + var $replyLink = $container.find('.comment-reply-link[data-reply-id='+ replyCommentId +']'); - relatedCommentArea.hide(); + $relatedCommentArea.hide(); + $replyLink.attr('href','#'); }); }); } @@ -48,11 +85,31 @@ $link.on('click', '', function (e) { e.preventDefault(); - abp.message.confirm(l("MessageDeletionConfirmationMessage"), function () { - volo.cmsKit.comments.commentPublic.delete($link.data('comment-id') - ).then(function () { - widgetManager.refresh($widget); - }); + abp.message.confirm(l("MessageDeletionConfirmationMessage"), function (ok) { + if (ok){ + volo.cmsKit.comments.commentPublic.delete($link.data('id') + ).then(function () { + widgetManager.refresh($widget); + }); + } + }); + }); + }); + } + + function registerUpdateOfNewComment($container) { + $container.find('.cms-comment-update-form').each(function () { + var $form = $(this); + $form.submit(function (e) { + e.preventDefault(); + var formAsObject = $form.serializeFormToObject(); + volo.cmsKit.comments.commentPublic.update( + formAsObject.id, + { + text: formAsObject.commentText + } + ).then(function () { + widgetManager.refresh($widget); }); }); }); @@ -64,13 +121,13 @@ $form.submit(function (e) { e.preventDefault(); var formAsObject = $form.serializeFormToObject(); + console.log(formAsObject); volo.cmsKit.comments.commentPublic.create( $.extend(getFilters(), { repliedCommentId: formAsObject.repliedCommentId, text: formAsObject.commentText }) ).then(function () { - $form.find('textarea').val(''); widgetManager.refresh($widget); }); }); @@ -79,7 +136,10 @@ function init() { registerReplyLinks($widget); + registerEditLinks($widget); registerDeleteLinks($widget); + + registerUpdateOfNewComment($widget); registerSubmissionOfNewComment($widget); } From 800de78a03bf8a1ce94fa6ec3e26246dbf3d1b52 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 4 Aug 2020 09:54:05 +0300 Subject: [PATCH 05/13] cmskit comments: allow public entitites --- .../CmsKit/Localization/Resources/en.json | 3 +- .../Volo/CmsKit/CmsKitOptions.cs | 7 +++- .../Comments/CommentPublicAppService.cs | 33 +++++++++++++++++-- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json index 5749c5f66e..036ebd7de1 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json @@ -9,6 +9,7 @@ "Reply": "Reply", "Update": "Update", "Edit": "Edit", - "MessageDeletionConfirmationMessage": "This comment will be deleted completely." + "MessageDeletionConfirmationMessage": "This comment will be deleted completely.", + "CommentAuthorizationExceptionMessage": "Those comments are not allowed for public display." } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitOptions.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitOptions.cs index cc69f715ce..8e13acca5c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitOptions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitOptions.cs @@ -1,4 +1,5 @@ -using JetBrains.Annotations; +using System.Collections.Generic; +using JetBrains.Annotations; using Volo.CmsKit.Reactions; namespace Volo.CmsKit @@ -8,9 +9,13 @@ namespace Volo.CmsKit [NotNull] public ReactionDefinitionDictionary Reactions { get; } + [NotNull] + public List PublicCommentEntities { get; } + public CmsKitOptions() { Reactions = new ReactionDefinitionDictionary(); + PublicCommentEntities = new List(); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Comments/CommentPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Comments/CommentPublicAppService.cs index 06991e6a42..5edd0303d1 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Comments/CommentPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Comments/CommentPublicAppService.cs @@ -3,27 +3,35 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; +using Microsoft.Extensions.Options; using Volo.Abp; using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; +using Volo.Abp.Authorization; using Volo.CmsKit.Users; namespace Volo.CmsKit.Comments { - [Authorize] public class CommentPublicAppService : ApplicationService, ICommentPublicAppService { + private readonly CmsKitOptions _cmsKitOptions; protected ICommentRepository CommentRepository { get; } public ICmsUserLookupService CmsUserLookupService { get; } - public CommentPublicAppService(ICommentRepository commentRepository, ICmsUserLookupService cmsUserLookupService) + public CommentPublicAppService( + ICommentRepository commentRepository, + ICmsUserLookupService cmsUserLookupService, + IOptionsSnapshot cmsKitOptions) { + _cmsKitOptions = cmsKitOptions.Value; CommentRepository = commentRepository; CmsUserLookupService = cmsUserLookupService; } public async Task> GetAllForEntityAsync(string entityType, string entityId) { + CheckAuthorizationAsync(entityType); + var commentsWithAuthor = await CommentRepository.GetListAsync(entityType, entityId); return new ListResultDto( @@ -31,6 +39,7 @@ namespace Volo.CmsKit.Comments ); } + [Authorize] public async Task CreateAsync(CreateCommentInput input) { var user = await CmsUserLookupService.FindByIdAsync(CurrentUser.Id.Value); @@ -52,6 +61,7 @@ namespace Volo.CmsKit.Comments return ObjectMapper.Map(comment); } + [Authorize] public async Task UpdateAsync(Guid id, UpdateCommentInput input) { var comment = await CommentRepository.GetAsync(id); @@ -68,6 +78,7 @@ namespace Volo.CmsKit.Comments return ObjectMapper.Map(updatedComment); } + [Authorize] public async Task DeleteAsync(Guid id) { var comment = await CommentRepository.GetAsync(id); @@ -105,6 +116,24 @@ namespace Volo.CmsKit.Comments return parentComments; } + private async Task CheckAuthorizationAsync(string entityType) + { + if (await IsPublicEntity(entityType)) + { + return; + } + + if (!CurrentUser.IsAuthenticated) + { + throw new AbpAuthorizationException(L["CommentAuthorizationExceptionMessage"]); + } + } + + private async Task IsPublicEntity(string entityType) + { + return _cmsKitOptions.PublicCommentEntities.Contains(entityType); + } + private CmsUserDto GetAuthorAsDtoFromCommentList(List comments, Guid commentId) { return ObjectMapper.Map(comments.Single(c => c.Comment.Id == commentId).Author); From e64664e926c2cc04d413a91c5fbb4bb58056fee4 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 4 Aug 2020 12:01:53 +0300 Subject: [PATCH 06/13] cmskit comment: hide new comment form when not authenticated --- .../Components/Commenting/Default.cshtml | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml index dc3df1d270..e24e99fbaa 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml @@ -16,18 +16,18 @@ ; } @{ - Func GetCommentArea(string repliedCommentIdAsString, bool cancelButton = false) => - @
+ Func GetCommentArea(Guid? repliedCommentId, bool cancelButton = false) => + @
- +
- +
@if (cancelButton) { - @L["Cancel"] + @L["Cancel"] } @L["Send"]
@@ -90,29 +90,35 @@ @GetCommentContentArea(comment.Id, comment.Author.Id, false, comment.Text).Invoke(null) - @GetCommentArea(comment.Id.ToString(), true).Invoke(null) + @if (CurrentUser.IsAuthenticated) + { + @GetCommentArea(comment.Id, true).Invoke(null) + } @if (comment.Replies.Any()) {
- @foreach (var reply in comment.Replies) - { -
-
- - @GetCommentAuthorName(reply.Author).Invoke(null) -
+ @foreach (var reply in comment.Replies) + { +
+
+ + @GetCommentAuthorName(reply.Author).Invoke(null) +
- @GetCommentContentArea(reply.Id, reply.Author.Id, true, reply.Text).Invoke(null) + @GetCommentContentArea(reply.Id, reply.Author.Id, true, reply.Text).Invoke(null) -
- } +
+ }
}
}
- @GetCommentArea("").Invoke(null) + @if (CurrentUser.IsAuthenticated) + { + @GetCommentArea(null).Invoke(null) + }
From 9ad272db715fd4dd33ffe8bf52e895dd18d07636 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 4 Aug 2020 12:42:17 +0300 Subject: [PATCH 07/13] cmskit comment login buttons --- .../Volo/CmsKit/Localization/Resources/en.json | 2 ++ .../Commenting/CommentingViewComponent.cs | 5 ++++- .../Shared/Components/Commenting/Default.cshtml | 17 ++++++++++++++--- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json index 036ebd7de1..6d577e080c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json @@ -9,6 +9,8 @@ "Reply": "Reply", "Update": "Update", "Edit": "Edit", + "LoginToAddComment": "Login to add comment", + "LoginToReply": "Login to reply", "MessageDeletionConfirmationMessage": "This comment will be deleted completely.", "CommentAuthorizationExceptionMessage": "Those comments are not allowed for public display." } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingViewComponent.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingViewComponent.cs index 9f97619d57..50f07ab9b1 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingViewComponent.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/CommentingViewComponent.cs @@ -24,7 +24,7 @@ namespace Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting CommentPublicAppService = commentPublicAppService; } - public virtual async Task InvokeAsync( string entityType,string entityId) + public virtual async Task InvokeAsync(string entityType, string entityId, string loginUrl = null) { var result = await CommentPublicAppService.GetAllForEntityAsync(entityType, entityId); @@ -32,6 +32,7 @@ namespace Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting { EntityId = entityId, EntityType = entityType, + LoginUrl = loginUrl, Comments = result.Items.ToList() }; @@ -44,6 +45,8 @@ namespace Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting public string EntityId { get; set; } + public string LoginUrl { get; set; } + public List Comments { get; set; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml index e24e99fbaa..f61ff27e95 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml @@ -44,9 +44,16 @@ @if (!isReply) { - - @L["Reply"] - + @if (CurrentUser.IsAuthenticated) + { + + @L["Reply"] + + } + else + { + @L["LoginToReply"] + } } @if (authorId == CurrentUser.Id) { @@ -120,5 +127,9 @@ { @GetCommentArea(null).Invoke(null) } + else if (!string.IsNullOrWhiteSpace(Model.LoginUrl)) + { + @L["LoginToAddComment"] + }
From 3c5001c8f455e879f1317196ce2cfbcfd4a67b2e Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 4 Aug 2020 14:19:56 +0300 Subject: [PATCH 08/13] cmskit comments: improved demo with public page --- .../CmsKitWebUnifiedModule.cs | 5 +++ .../Pages/Index.cshtml | 2 -- .../Pages/Public.cshtml | 36 +++++++++++++++++++ .../Pages/Public.cshtml.cs | 11 ++++++ .../Volo.CmsKit.Web.Unified.csproj | 10 ++++++ 5 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Public.cshtml create mode 100644 modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Public.cshtml.cs diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs index 183469ce48..32e1b9f905 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/CmsKitWebUnifiedModule.cs @@ -112,6 +112,11 @@ namespace Volo.CmsKit { options.IsEnabled = MultiTenancyConsts.IsEnabled; }); + + Configure(options => + { + options.PublicCommentEntities.Add("publicQuote"); + }); } public override void OnApplicationInitialization(ApplicationInitializationContext context) diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Index.cshtml b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Index.cshtml index a8a6b82748..c54ee474e4 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Index.cshtml +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Index.cshtml @@ -8,8 +8,6 @@ @inject IStringLocalizer Localizer

CMS Kit DEMO

-

Reactions

- diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Public.cshtml b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Public.cshtml new file mode 100644 index 0000000000..006fe83c31 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Public.cshtml @@ -0,0 +1,36 @@ +@page +@using Localization.Resources.AbpUi +@using Microsoft.Extensions.Localization +@using Volo.CmsKit.Pages +@using Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting +@model PublicModel +@inject IStringLocalizer Localizer +

CMS Kit DEMO - Public

+ + + + +

+ Any fool can write code that a computer can understand. Good programmers write code that humans can understand. +

+
+ Martin Fowler +
+
+
+ @await Component.InvokeAsync(typeof(CommentingViewComponent), new { entityType = "publicQuote", entityId = "1", loginUrl="Account/Login?ReturnUrl=%2Fpublic" }) +
+ + + + +

+ Writing code is very simple, but writing simple code is the hardest thing there is! +

+
+ Halil ibrahim Kalkan (inspired from Johan Cruyff) +
+
+
+ @await Component.InvokeAsync(typeof(CommentingViewComponent), new { entityType = "publicQuote", entityId = "2", loginUrl="Account/Login?ReturnUrl=%2Fpublic" }) +
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Public.cshtml.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Public.cshtml.cs new file mode 100644 index 0000000000..3ec2b2020a --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Pages/Public.cshtml.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace Volo.CmsKit.Pages +{ + public class PublicModel : PageModel + { + public void OnGet() + { + } + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Volo.CmsKit.Web.Unified.csproj b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Volo.CmsKit.Web.Unified.csproj index d0237cd54c..ae12fbb510 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Volo.CmsKit.Web.Unified.csproj +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Volo.CmsKit.Web.Unified.csproj @@ -47,6 +47,16 @@ + + true + PreserveNewest + + + public.cshtml + + + Public.cshtml + From a64ec0e77cf234138480716baf665d7617918403 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 4 Aug 2020 14:47:18 +0300 Subject: [PATCH 09/13] Update Default.cshtml --- .../Components/Commenting/Default.cshtml | 58 ++++++++++--------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml index f61ff27e95..ab24b4da70 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml @@ -89,37 +89,41 @@ @foreach (var comment in Model.Comments) { -
-
- - @GetCommentAuthorName(comment.Author).Invoke(null) -
+
+
+
+ + @GetCommentAuthorName(comment.Author).Invoke(null) +
- @GetCommentContentArea(comment.Id, comment.Author.Id, false, comment.Text).Invoke(null) + @GetCommentContentArea(comment.Id, comment.Author.Id, false, comment.Text).Invoke(null) - @if (CurrentUser.IsAuthenticated) - { - @GetCommentArea(comment.Id, true).Invoke(null) - } + @if (CurrentUser.IsAuthenticated) + { + @GetCommentArea(comment.Id, true).Invoke(null) + } - @if (comment.Replies.Any()) - { -
- @foreach (var reply in comment.Replies) - { -
-
- - @GetCommentAuthorName(reply.Author).Invoke(null) -
+ @if (comment.Replies.Any()) + { +
+ @foreach (var reply in comment.Replies) + { +
+
- @GetCommentContentArea(reply.Id, reply.Author.Id, true, reply.Text).Invoke(null) +
+ + @GetCommentAuthorName(reply.Author).Invoke(null) +
-
- } -
- } + @GetCommentContentArea(reply.Id, reply.Author.Id, true, reply.Text).Invoke(null) +
+
+ } +
+ } +
}
@@ -129,7 +133,9 @@ } else if (!string.IsNullOrWhiteSpace(Model.LoginUrl)) { - @L["LoginToAddComment"] + }
From 4ec311624f523b2cc96f63efa475ba509385a5c6 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 4 Aug 2020 15:26:35 +0300 Subject: [PATCH 10/13] Update Default.cshtml --- .../Pages/CmsKit/Shared/Components/Commenting/Default.cshtml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml index ab24b4da70..fd29799f8b 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml @@ -94,6 +94,7 @@
@GetCommentAuthorName(comment.Author).Invoke(null) + @comment.CreationTime.ToString()
@GetCommentContentArea(comment.Id, comment.Author.Id, false, comment.Text).Invoke(null) @@ -114,6 +115,7 @@
@GetCommentAuthorName(reply.Author).Invoke(null) + @comment.CreationTime.ToString()
@GetCommentContentArea(reply.Id, reply.Author.Id, true, reply.Text).Invoke(null) From 769ce3d82c27de35467b884616ef829a02eeaf30 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 4 Aug 2020 15:35:22 +0300 Subject: [PATCH 11/13] Update Default.cshtml --- .../CmsKit/Shared/Components/Commenting/Default.cshtml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml index fd29799f8b..a22f579c7c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml @@ -8,11 +8,12 @@ @model Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting.CommentingViewComponent.CommentingViewModel @{ - Func GetCommentAuthorName(CmsUserDto author) => + Func GetCommentTitle(CmsUserDto author, DateTime creationTime) => @ @((string.IsNullOrWhiteSpace(author.Name) ? author.UserName : author.Name + " " + author.Surname).Trim()) + @creationTime.ToString() ; } @{ @@ -93,8 +94,7 @@
- @GetCommentAuthorName(comment.Author).Invoke(null) - @comment.CreationTime.ToString() + @GetCommentTitle(comment.Author, comment.CreationTime).Invoke(null)
@GetCommentContentArea(comment.Id, comment.Author.Id, false, comment.Text).Invoke(null) @@ -114,8 +114,7 @@
- @GetCommentAuthorName(reply.Author).Invoke(null) - @comment.CreationTime.ToString() + @GetCommentTitle(reply.Author, reply.CreationTime).Invoke(null)
@GetCommentContentArea(reply.Id, reply.Author.Id, true, reply.Text).Invoke(null) From ec5b0caeb630eb4d2bd0a84451585381baf8e898 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 4 Aug 2020 16:31:45 +0300 Subject: [PATCH 12/13] cmskit comment ui improvements --- .../CmsKit/Localization/Resources/en.json | 1 + .../Components/Commenting/Default.cshtml | 87 ++++++++++--------- 2 files changed, 46 insertions(+), 42 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json index 6d577e080c..3e16a17a47 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json @@ -4,6 +4,7 @@ "PickYourReaction": "Pick your reaction", "YourComment": "Your comment", "YourReply": "Your reply", + "Comments": "Comments", "Send": "Send", "Delete": "Delete", "Reply": "Reply", diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml index a22f579c7c..faf3537430 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Commenting/Default.cshtml @@ -88,55 +88,58 @@
- @foreach (var comment in Model.Comments) - { -
-
-
- - @GetCommentTitle(comment.Author, comment.CreationTime).Invoke(null) -
- - @GetCommentContentArea(comment.Id, comment.Author.Id, false, comment.Text).Invoke(null) +
+

+ + @L["Comments"] +

+ @foreach (var comment in Model.Comments) + { +
+
+
+ @GetCommentTitle(comment.Author, comment.CreationTime).Invoke(null) +
- @if (CurrentUser.IsAuthenticated) - { - @GetCommentArea(comment.Id, true).Invoke(null) - } + @GetCommentContentArea(comment.Id, comment.Author.Id, false, comment.Text).Invoke(null) - @if (comment.Replies.Any()) - { -
- @foreach (var reply in comment.Replies) - { -
-
+ @if (CurrentUser.IsAuthenticated) + { + @GetCommentArea(comment.Id, true).Invoke(null) + } -
- - @GetCommentTitle(reply.Author, reply.CreationTime).Invoke(null) -
+ @if (comment.Replies.Any()) + { +
+ @foreach (var reply in comment.Replies) + { +
+
- @GetCommentContentArea(reply.Id, reply.Author.Id, true, reply.Text).Invoke(null) +
+ @GetCommentTitle(reply.Author, reply.CreationTime).Invoke(null) +
+ @GetCommentContentArea(reply.Id, reply.Author.Id, true, reply.Text).Invoke(null) +
-
- } -
- } -
-
- } -
- @if (CurrentUser.IsAuthenticated) - { - @GetCommentArea(null).Invoke(null) - } - else if (!string.IsNullOrWhiteSpace(Model.LoginUrl)) - { - + } +
} +
+ @if (CurrentUser.IsAuthenticated) + { + @GetCommentArea(null).Invoke(null) + } + else if (!string.IsNullOrWhiteSpace(Model.LoginUrl)) + { + + } +
From 16285fabfaa9a008adb2d95edcfcf176d7ba64a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Tue, 4 Aug 2020 21:53:44 +0300 Subject: [PATCH 13/13] Refactor. --- .../Volo/CmsKit/Comments/ICommentRepository.cs | 2 +- .../Volo/CmsKit/Comments/EfCoreCommentRepository.cs | 2 +- .../Volo/CmsKit/Comments/CommentPublicAppService.cs | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/ICommentRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/ICommentRepository.cs index f4839b8c5b..8e5bba3427 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/ICommentRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Comments/ICommentRepository.cs @@ -8,7 +8,7 @@ namespace Volo.CmsKit.Comments { public interface ICommentRepository : IBasicRepository { - Task> GetListAsync( + Task> GetListWithAuthorsAsync( [NotNull] string entityType, [NotNull] string entityId); } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Comments/EfCoreCommentRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Comments/EfCoreCommentRepository.cs index f0a3b9a908..3c39386f03 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Comments/EfCoreCommentRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Comments/EfCoreCommentRepository.cs @@ -19,7 +19,7 @@ namespace Volo.CmsKit.Comments { } - public async Task> GetListAsync( + public async Task> GetListWithAuthorsAsync( string entityType, string entityId) { diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Comments/CommentPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Comments/CommentPublicAppService.cs index 5edd0303d1..73339492f6 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Comments/CommentPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Comments/CommentPublicAppService.cs @@ -14,16 +14,16 @@ namespace Volo.CmsKit.Comments { public class CommentPublicAppService : ApplicationService, ICommentPublicAppService { - private readonly CmsKitOptions _cmsKitOptions; + protected CmsKitOptions CmsKitOptions { get; } protected ICommentRepository CommentRepository { get; } - public ICmsUserLookupService CmsUserLookupService { get; } + protected ICmsUserLookupService CmsUserLookupService { get; } public CommentPublicAppService( ICommentRepository commentRepository, ICmsUserLookupService cmsUserLookupService, - IOptionsSnapshot cmsKitOptions) + IOptions cmsKitOptions) { - _cmsKitOptions = cmsKitOptions.Value; + CmsKitOptions = cmsKitOptions.Value; CommentRepository = commentRepository; CmsUserLookupService = cmsUserLookupService; } @@ -32,7 +32,7 @@ namespace Volo.CmsKit.Comments { CheckAuthorizationAsync(entityType); - var commentsWithAuthor = await CommentRepository.GetListAsync(entityType, entityId); + var commentsWithAuthor = await CommentRepository.GetListWithAuthorsAsync(entityType, entityId); return new ListResultDto( ConvertCommentsToNestedStructure(commentsWithAuthor) @@ -131,7 +131,7 @@ namespace Volo.CmsKit.Comments private async Task IsPublicEntity(string entityType) { - return _cmsKitOptions.PublicCommentEntities.Contains(entityType); + return CmsKitOptions.PublicCommentEntities.Contains(entityType); } private CmsUserDto GetAuthorAsDtoFromCommentList(List comments, Guid commentId)