From 64b68b04f59df5968642c6bf75e4cc99ef188765 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enis=20Necipo=C4=9Flu?= Date: Wed, 9 Jun 2021 16:46:10 +0300 Subject: [PATCH] CmsKit - Main Menu Implementation --- ....cs => 20210609132819_Initial.Designer.cs} | 5 ++- ...0_Initial.cs => 20210609132819_Initial.cs} | 1 + .../UnifiedDbContextModelSnapshot.cs | 3 ++ .../Admin/Menus/IMenuAdminAppService.cs | 3 ++ .../Volo/CmsKit/Admin/Menus/MenuDto.cs | 1 + .../CmsKit/Admin/Menus/UpdateMainMenuInput.cs | 7 ++++ .../CmsKit/Admin/Menus/MenuAdminAppService.cs | 12 ++++++ .../CmsKit/Admin/Menus/MenuAdminController.cs | 10 +++++ .../Menus/MenuItems/UpdateModal.cshtml.cs | 1 + .../Pages/CmsKit/Menus/index.js | 42 ++++++++++++++++++- .../Volo/CmsKit}/Menus/MenuItemDto.cs | 2 +- .../Volo/CmsKit}/Menus/MenuWithDetailsDto.cs | 3 +- .../CmsKit/Localization/Resources/en.json | 2 + .../CmsKit/Localization/Resources/tr.json | 2 + .../Volo/CmsKit/Menus/IMenuRepository.cs | 4 +- .../Volo/CmsKit/Menus/Menu.cs | 2 + .../Volo/CmsKit/Menus/MenuManager.cs | 29 +++++++++++-- .../Volo/CmsKit/Menus/EfCoreMenuRepository.cs | 7 ++++ .../MongoDB/Menus/MongoMenuRepository.cs | 7 ++++ .../Public/Menus/IMenuPublicAppService.cs | 11 +++++ .../Public/Menus/MenuPublicAppService.cs | 30 +++++++++++++ .../PublicApplicationAutoMapperProfile.cs | 5 +++ .../Public/Menus/MenuPublicController.cs | 30 +++++++++++++ .../Menus/MenuRepository_Test.cs | 9 ++++ .../MongoDB/Menus/MenuRepository_Test.cs | 11 +++++ .../CmsKitDataSeedContributor.cs | 9 +++- .../Volo.CmsKit.TestBase/CmsKitTestData.cs | 5 +++ .../Menus/MenuRepository_Test.cs | 41 ++++++++++++++++++ 28 files changed, 284 insertions(+), 10 deletions(-) rename modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/{20210609081350_Initial.Designer.cs => 20210609132819_Initial.Designer.cs} (99%) rename modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/{20210609081350_Initial.cs => 20210609132819_Initial.cs} (99%) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/UpdateMainMenuInput.cs rename modules/cms-kit/src/{Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin => Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit}/Menus/MenuItemDto.cs (95%) rename modules/cms-kit/src/{Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin => Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit}/Menus/MenuWithDetailsDto.cs (81%) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Menus/IMenuPublicAppService.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Menus/MenuPublicAppService.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Menus/MenuPublicController.cs create mode 100644 modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Menus/MenuRepository_Test.cs create mode 100644 modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Menus/MenuRepository_Test.cs create mode 100644 modules/cms-kit/test/Volo.CmsKit.TestBase/Menus/MenuRepository_Test.cs diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210609081350_Initial.Designer.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210609132819_Initial.Designer.cs similarity index 99% rename from modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210609081350_Initial.Designer.cs rename to modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210609132819_Initial.Designer.cs index 2284726bdc..3b2029f349 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210609081350_Initial.Designer.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210609132819_Initial.Designer.cs @@ -11,7 +11,7 @@ using Volo.CmsKit.EntityFrameworkCore; namespace Volo.CmsKit.Migrations { [DbContext(typeof(UnifiedDbContext))] - [Migration("20210609081350_Initial")] + [Migration("20210609132819_Initial")] partial class Initial { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -1496,6 +1496,9 @@ namespace Volo.CmsKit.Migrations .HasDefaultValue(false) .HasColumnName("IsDeleted"); + b.Property("IsMainMenu") + .HasColumnType("bit"); + b.Property("LastModificationTime") .HasColumnType("datetime2") .HasColumnName("LastModificationTime"); diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210609081350_Initial.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210609132819_Initial.cs similarity index 99% rename from modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210609081350_Initial.cs rename to modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210609132819_Initial.cs index 9d533d6a48..8c9cca8a66 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210609081350_Initial.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210609132819_Initial.cs @@ -374,6 +374,7 @@ namespace Volo.CmsKit.Migrations { Id = table.Column(type: "uniqueidentifier", nullable: false), Name = table.Column(type: "nvarchar(max)", nullable: true), + IsMainMenu = table.Column(type: "bit", nullable: false), TenantId = table.Column(type: "uniqueidentifier", nullable: true), ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true), 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 00e961ad2b..51f7abf3b7 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 @@ -1494,6 +1494,9 @@ namespace Volo.CmsKit.Migrations .HasDefaultValue(false) .HasColumnName("IsDeleted"); + b.Property("IsMainMenu") + .HasColumnType("bit"); + b.Property("LastModificationTime") .HasColumnType("datetime2") .HasColumnName("LastModificationTime"); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/IMenuAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/IMenuAdminAppService.cs index b80ca454ef..0e8beaccee 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/IMenuAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/IMenuAdminAppService.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; +using Volo.CmsKit.Menus; namespace Volo.CmsKit.Admin.Menus { @@ -28,5 +29,7 @@ namespace Volo.CmsKit.Admin.Menus Task DeleteMenuItemAsync(Guid menuId, Guid menuItemId); Task MoveMenuItemAsync(Guid menuId, Guid menuItemId, MenuItemMoveInput input); + + Task UpdateMainMenuAsync(Guid menuId, UpdateMainMenuInput input); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuDto.cs index 2a8bfbd420..23c245449e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuDto.cs @@ -10,5 +10,6 @@ namespace Volo.CmsKit.Admin.Menus public class MenuDto : EntityDto { public string Name { get; set; } + public bool IsMainMenu { get; set; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/UpdateMainMenuInput.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/UpdateMainMenuInput.cs new file mode 100644 index 0000000000..eb04610146 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/UpdateMainMenuInput.cs @@ -0,0 +1,7 @@ +namespace Volo.CmsKit.Admin.Menus +{ + public class UpdateMainMenuInput + { + public bool IsMainMenu { get; set; } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Menus/MenuAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Menus/MenuAdminAppService.cs index 8833d9973e..4952645b73 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Menus/MenuAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Menus/MenuAdminAppService.cs @@ -175,5 +175,17 @@ namespace Volo.CmsKit.Admin.Menus { return MenuManager.MoveAsync(menuId, menuItemId, input.NewParentId, input.Position); } + + public virtual async Task UpdateMainMenuAsync(Guid menuId, UpdateMainMenuInput input) + { + if (input.IsMainMenu) + { + await MenuManager.SetMainMenuAsync(menuId); + } + else + { + await MenuManager.UnSetMainMenuAsync(menuId); + } + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Menus/MenuAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Menus/MenuAdminController.cs index 413bae1ec9..a3a66a7a04 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Menus/MenuAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Menus/MenuAdminController.cs @@ -8,7 +8,9 @@ using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.Application.Dtos; using Volo.Abp.GlobalFeatures; +using Volo.Abp.UI.Navigation; using Volo.CmsKit.GlobalFeatures; +using Volo.CmsKit.Menus; using Volo.CmsKit.Permissions; namespace Volo.CmsKit.Admin.Menus @@ -93,6 +95,14 @@ namespace Volo.CmsKit.Admin.Menus { return MenuAdminAppService.MoveMenuItemAsync(menuId, menuItemId, input); } + + [Route("{menuId}/main-menu")] + [HttpPut] + [Authorize(CmsKitAdminPermissions.Menus.Update)] + public Task UpdateMainMenuAsync(Guid menuId, UpdateMainMenuInput input) + { + return MenuAdminAppService.UpdateMainMenuAsync(menuId, input); + } [Route("{menuId}")] [HttpPut] diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/UpdateModal.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/UpdateModal.cshtml.cs index b7661e2582..1ab02f429d 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/UpdateModal.cshtml.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/UpdateModal.cshtml.cs @@ -5,6 +5,7 @@ using AutoMapper; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Volo.CmsKit.Admin.Menus; +using Volo.CmsKit.Menus; namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems { diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/index.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/index.js index 28f66a4626..adcb18b812 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/index.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/index.js @@ -29,6 +29,32 @@ location.href = "/Cms/Menus/" + data.record.id + "/menu-items" } }, + { + text: l('MakeMainMenu'), + visible: function(data){ + return abp.auth.isGranted('CmsKit.Menus.Update') && !data.isMainMenu + }, + action: function (data) { + menusService + .updateMainMenu(data.record.id, { isMainMenu: true}) + .then(function () { + dataTable.ajax.reload(); + }); + } + }, + { + text: l('UnMakeMainMenu'), + visible: function(data){ + return abp.auth.isGranted('CmsKit.Menus.Update') && data.isMainMenu + }, + action: function (data) { + menusService + .updateMainMenu(data.record.id, { isMainMenu: false}) + .then(function () { + dataTable.ajax.reload(); + }); + } + }, { text: l('Edit'), visible: abp.auth.isGranted('CmsKit.Menus.Update'), @@ -56,7 +82,21 @@ { title: l("Name"), orderable: true, - data: "name" + data: "name", + render: function (data, val ,record) { + + if (record.isMainMenu) { + return ( + '' + + + data + + + '' + ); + } else { + return data; + } + } } ] })); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuItemDto.cs b/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Menus/MenuItemDto.cs similarity index 95% rename from modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuItemDto.cs rename to modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Menus/MenuItemDto.cs index df5601b439..c000b6760e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuItemDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Menus/MenuItemDto.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using Volo.Abp.Application.Dtos; -namespace Volo.CmsKit.Admin.Menus +namespace Volo.CmsKit.Menus { public class MenuItemDto : AuditedEntityDto { diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuWithDetailsDto.cs b/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Menus/MenuWithDetailsDto.cs similarity index 81% rename from modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuWithDetailsDto.cs rename to modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Menus/MenuWithDetailsDto.cs index 8436f46473..bd15a68d61 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuWithDetailsDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Menus/MenuWithDetailsDto.cs @@ -5,11 +5,12 @@ using System.Text; using System.Threading.Tasks; using Volo.Abp.Application.Dtos; -namespace Volo.CmsKit.Admin.Menus +namespace Volo.CmsKit.Menus { public class MenuWithDetailsDto : FullAuditedEntityDto { public string Name { get; set; } + public bool IsMainMenu { get; set; } public List Items { get; set; } } } 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 b6553f678e..a80e9197dc 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 @@ -54,6 +54,7 @@ "LoginToRate": "Login to rate", "LoginToReact": "Login to react", "LoginToReply": "Login to reply", + "MakeMainMenu": "Make Main Menu", "Menu:CMS": "CMS", "Menu:Menus": "Menus", "MenuDeletionConfirmationMessage": "The menu '{0}' will be deleted. Are you sure?", @@ -149,6 +150,7 @@ "Update": "Update", "UpdatePreferenceSuccessMessage": "Your preferences have been saved.", "UpdateYourEmailPreferences": "Update your email preferences", + "UnMakeMainMenu": "Unmake Main Menu", "UploadFailedMessage": "Upload failed.", "UserId": "User Id", "Username": "Username", diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json index e418132f26..2bc10b359b 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json @@ -53,6 +53,7 @@ "LoginToRate": "Oylamak için giriş yapın", "LoginToReact": "Reaksiyon vermek için giriş yap", "LoginToReply": "Cevap vermek için giriş yap", + "MakeMainMenu": "Ana Menü Yap", "Menu:CMS": "CMS", "Menu:Menus": "Menüler", "MenuDeletionConfirmationMessage": "'{0}' isimli menü silinecek. Emin misiniz?", @@ -140,6 +141,7 @@ "UpdatePreference": "Tercihleri Güncelle", "UpdatePreferenceSuccessMessage": "Tercihleriniz kaydedilmiştir.", "UpdateYourEmailPreferences": "E-posta tercihlerinizi güncelleyin", + "UnMakeMainMenu": "Ana Menü Atamasını Kaldır", "UploadFailedMessage": "Karşıya yükleme işlemi başarısız oldu.", "UserId": "Kullanıcı Id", "Username": "Kullanıcı adı", diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/IMenuRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/IMenuRepository.cs index e72cc9c08c..25ed98b3f1 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/IMenuRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/IMenuRepository.cs @@ -1,10 +1,12 @@ using System; +using System.Threading; +using System.Threading.Tasks; using Volo.Abp.Domain.Repositories; namespace Volo.CmsKit.Menus { public interface IMenuRepository : IBasicRepository { - + Task FindMainMenuAsync(bool includeDetails = true, CancellationToken cancellationToken = default); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/Menu.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/Menu.cs index ed5ae7ff69..e5d6479869 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/Menu.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/Menu.cs @@ -12,6 +12,8 @@ namespace Volo.CmsKit.Menus { public string Name { get; protected set; } + public bool IsMainMenu { get; internal set; } + public Guid? TenantId { get; protected set; } public ICollection Items { get; protected set; } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/MenuManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/MenuManager.cs index 571360e596..7f1843d7af 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/MenuManager.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/MenuManager.cs @@ -31,7 +31,7 @@ namespace Volo.CmsKit.Menus var menu = await MenuRepository.GetAsync(menuId, includeDetails: true); var menuItem = menu.Items.FirstOrDefault(x => x.Id == menuItemId) - ?? throw new EntityNotFoundException(typeof(MenuItem), menuItemId); + ?? throw new EntityNotFoundException(typeof(MenuItem), menuItemId); if (newParentId.HasValue && !menu.Items.Any(a => a.Id == newParentId.Value)) { @@ -40,7 +40,7 @@ namespace Volo.CmsKit.Menus menuItem.ParentId = newParentId; menuItem.Order = position; - + OrganizeTreeOrderForMenuItem(menu, menuItem); await MenuRepository.UpdateAsync(menu); @@ -51,7 +51,7 @@ namespace Volo.CmsKit.Menus var sameTree = menu.Items.Where(x => x.ParentId == menuItem.ParentId).OrderBy(x => x.Order).ToList(); sameTree.Remove(menuItem); // Remove if exists - + sameTree.Insert(menuItem.Order, menuItem); for (int i = 0; i < sameTree.Count; i++) @@ -59,5 +59,26 @@ namespace Volo.CmsKit.Menus sameTree[i].Order = i; } } + + public virtual async Task SetMainMenuAsync(Guid menuId) + { + var menus = await MenuRepository.GetListAsync(includeDetails: false); + + foreach (var menu in menus) + { + menu.IsMainMenu = menuId == menu.Id; + } + + await MenuRepository.UpdateManyAsync(menus); + } + + public virtual async Task UnSetMainMenuAsync(Guid menuId) + { + var menu = await MenuRepository.GetAsync(menuId, includeDetails: false); + + menu.IsMainMenu = false; + + await MenuRepository.UpdateAsync(menu); + } } -} +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Menus/EfCoreMenuRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Menus/EfCoreMenuRepository.cs index 987650490a..c4fc6e2b4c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Menus/EfCoreMenuRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Menus/EfCoreMenuRepository.cs @@ -1,6 +1,7 @@ using Microsoft.EntityFrameworkCore; using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; @@ -18,5 +19,11 @@ namespace Volo.CmsKit.Menus { return (await base.WithDetailsAsync()).Include(i => i.Items); } + + public async Task FindMainMenuAsync(bool includeDetails = true, CancellationToken cancellationToken = default) + { + return await (includeDetails ? await WithDetailsAsync() : await GetQueryableAsync()) + .FirstOrDefaultAsync(x => x.IsMainMenu, GetCancellationToken(cancellationToken)); + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Menus/MongoMenuRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Menus/MongoMenuRepository.cs index 91850a8eda..f7cc583658 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Menus/MongoMenuRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Menus/MongoMenuRepository.cs @@ -2,7 +2,9 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; +using MongoDB.Driver.Linq; using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.MongoDB; using Volo.CmsKit.Menus; @@ -14,5 +16,10 @@ namespace Volo.CmsKit.MongoDB.Menus public MongoMenuRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) { } + + public async Task FindMainMenuAsync(bool includeDetails = true, CancellationToken cancellationToken = default) + { + return await (await GetMongoQueryableAsync()).FirstOrDefaultAsync(x => x.IsMainMenu); + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Menus/IMenuPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Menus/IMenuPublicAppService.cs new file mode 100644 index 0000000000..ee544f5505 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Menus/IMenuPublicAppService.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; +using Volo.Abp.Application.Services; +using Volo.CmsKit.Menus; + +namespace Volo.CmsKit.Public.Menus +{ + public interface IMenuPublicAppService : IApplicationService + { + Task GetMainMenuAsync(); + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Menus/MenuPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Menus/MenuPublicAppService.cs new file mode 100644 index 0000000000..7e6989d0d6 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Menus/MenuPublicAppService.cs @@ -0,0 +1,30 @@ +using System.Threading.Tasks; +using Volo.Abp.GlobalFeatures; +using Volo.CmsKit.GlobalFeatures; +using Volo.CmsKit.Menus; + +namespace Volo.CmsKit.Public.Menus +{ + [RequiresGlobalFeature(typeof(MenuFeature))] + public class MenuPublicAppService : CmsKitPublicAppServiceBase, IMenuPublicAppService + { + protected IMenuRepository MenuRepository { get; } + + public MenuPublicAppService(IMenuRepository menuRepository) + { + MenuRepository = menuRepository; + } + + public async Task GetMainMenuAsync() + { + var menu = await MenuRepository.FindMainMenuAsync(includeDetails: true); + + if (menu == null) + { + return null; + } + + return ObjectMapper.Map(menu); + } + } +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs index b8684f2463..72a9dae9b2 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs @@ -2,6 +2,7 @@ using Volo.Abp.AutoMapper; using Volo.CmsKit.Blogs; using Volo.CmsKit.Comments; +using Volo.CmsKit.Menus; using Volo.CmsKit.Pages; using Volo.CmsKit.Public.Blogs; using Volo.CmsKit.Public.Comments; @@ -30,6 +31,10 @@ namespace Volo.CmsKit.Public CreateMap(); CreateMap(MemberList.None); + + CreateMap(); + + CreateMap(); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Menus/MenuPublicController.cs b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Menus/MenuPublicController.cs new file mode 100644 index 0000000000..14d4c621ed --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Menus/MenuPublicController.cs @@ -0,0 +1,30 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp; +using Volo.Abp.GlobalFeatures; +using Volo.CmsKit.GlobalFeatures; +using Volo.CmsKit.Menus; + +namespace Volo.CmsKit.Public.Menus +{ + [RequiresGlobalFeature(typeof(BlogsFeature))] + [RemoteService(Name = CmsKitPublicRemoteServiceConsts.RemoteServiceName)] + [Area("cms-kit")] + [Route("api/cms-kit-public/menus")] + public class MenuPublicController : CmsKitPublicControllerBase, IMenuPublicAppService + { + protected IMenuPublicAppService MenuPublicAppService { get; } + + public MenuPublicController(IMenuPublicAppService menuPublicAppService) + { + MenuPublicAppService = menuPublicAppService; + } + + [Route("main-menu")] + [HttpGet] + public Task GetMainMenuAsync() + { + return MenuPublicAppService.GetMainMenuAsync(); + } + } +} \ No newline at end of file diff --git a/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Menus/MenuRepository_Test.cs b/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Menus/MenuRepository_Test.cs new file mode 100644 index 0000000000..f4ba77618c --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Menus/MenuRepository_Test.cs @@ -0,0 +1,9 @@ +using Volo.CmsKit.Menus; + +namespace Volo.CmsKit.EntityFrameworkCore.Menus +{ + public class MenuRepository_Test : MenuRepository_Test + { + + } +} \ No newline at end of file diff --git a/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Menus/MenuRepository_Test.cs b/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Menus/MenuRepository_Test.cs new file mode 100644 index 0000000000..8daf56f569 --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Menus/MenuRepository_Test.cs @@ -0,0 +1,11 @@ +using Xunit; +using Volo.CmsKit.Menus; + +namespace Volo.CmsKit.MongoDB.Menus +{ + [Collection(MongoTestCollection.Name)] + public class MenuRepository_Test : MenuRepository_Test + { + + } +} \ No newline at end of file diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs index 81fa265f95..57a1c9505b 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs @@ -416,7 +416,8 @@ namespace Volo.CmsKit private async Task SeedMenusAsync() { var menu = new Menu(_cmsKitTestData.Menu_1_Id, null, _cmsKitTestData.Menu_1_Name); - + menu.IsMainMenu = true; + menu.Items.Add( new MenuItem( _cmsKitTestData.MenuItem_1_Id, @@ -432,6 +433,12 @@ namespace Volo.CmsKit _cmsKitTestData.MenuItem_2_Url)); await _menuRepository.InsertAsync(menu); + + await _menuRepository.InsertAsync( + new Menu( + _cmsKitTestData.Menu_2_Id, + null, + _cmsKitTestData.Menu_2_Name)); } } } diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs index 09dc8184ef..f9c40a6793 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs @@ -123,5 +123,10 @@ namespace Volo.CmsKit public string MenuItem_2_Name { get; } = "Our Team"; public string MenuItem_2_Url { get; } = "/team"; + + + public Guid Menu_2_Id { get; } = Guid.NewGuid(); + + public string Menu_2_Name { get; } = "DraftMenu"; } } diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/Menus/MenuRepository_Test.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/Menus/MenuRepository_Test.cs new file mode 100644 index 0000000000..4ec0fc8052 --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/Menus/MenuRepository_Test.cs @@ -0,0 +1,41 @@ +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Modularity; +using Xunit; + +namespace Volo.CmsKit.Menus +{ + public abstract class MenuRepository_Test : CmsKitTestBase + where TStartupModule : IAbpModule + { + + private readonly CmsKitTestData testData; + private readonly IMenuRepository menuRepository; + + public MenuRepository_Test() + { + testData = GetRequiredService(); + menuRepository = GetRequiredService(); + } + + [Fact] + public async Task GetMainMenuAsync_ShouldWorkProperly() + { + var mainMenu = await menuRepository.FindMainMenuAsync(); + + mainMenu.ShouldNotBeNull(); + mainMenu.Id.ShouldBe(testData.Menu_1_Id); + } + + [Fact] + public async Task GetMainMenuAsync_ShouldWorkProperly_WithIncludeDetails() + { + var mainMenu = await menuRepository.FindMainMenuAsync(includeDetails: true); + + mainMenu.ShouldNotBeNull(); + mainMenu.Id.ShouldBe(testData.Menu_1_Id); + mainMenu.Items.ShouldNotBeEmpty(); + mainMenu.Items.Count.ShouldBe(2); + } + } +} \ No newline at end of file