Browse Source

CmsKit - Remove Menu AggregateRoot & use directly MenuItems

pull/9396/head
enisn 5 years ago
parent
commit
24c0eeb108
  1. 36
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/IMenuAdminAppService.cs
  2. 25
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/IMenuItemAdminAppService.cs
  3. 2
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuItemCreateInput.cs
  4. 1
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs
  5. 207
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Menus/MenuAdminAppService.cs
  6. 125
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Menus/MenuItemAdminAppService.cs
  7. 98
      modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Menus/MenuAdminController.cs
  8. 19
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs
  9. 4
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenuContributor.cs
  10. 23
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/CreateModal.cshtml
  11. 44
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/CreateModal.cshtml.cs
  12. 34
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/Index.cshtml
  13. 13
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/Index.cshtml.cs
  14. 1
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/CreateModal.cshtml
  15. 12
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/CreateModal.cshtml.cs
  16. 7
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/Index.cshtml
  17. 16
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/Index.cshtml.cs
  18. 1
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/UpdateModal.cshtml
  19. 12
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/UpdateModal.cshtml.cs
  20. 2
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/createModal.js
  21. 14
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/index.js
  22. 2
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/updateModal.js
  23. 23
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/UpdateModal.cshtml
  24. 53
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/UpdateModal.cshtml.cs
  25. 1
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/createModal.js
  26. 118
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/index.js
  27. 1
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/updateModal.js
  28. 1
      modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Menus/MenuItemDto.cs
  29. 20
      modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Menus/MenuWithDetailsDto.cs
  30. 19
      modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Menus/MenuChangedHandler.cs
  31. 9
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/IMenuItemRepository.cs
  32. 18
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/IMenuRepository.cs
  33. 33
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/Menu.cs
  34. 11
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/MenuItem.cs
  35. 63
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/MenuItemManager.cs
  36. 109
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/MenuManager.cs
  37. 21
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/PageChangedHandler.cs
  38. 1
      modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs
  39. 10
      modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs
  40. 2
      modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/ICmsKitDbContext.cs
  41. 13
      modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Menus/EfCoreMenuExtensions.cs
  42. 14
      modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Menus/EfCoreMenuItemRepository.cs
  43. 40
      modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Menus/EfCoreMenuRepository.cs
  44. 2
      modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs
  45. 6
      modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs
  46. 3
      modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbModule.cs
  47. 2
      modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs
  48. 21
      modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Menus/MongoMenuItemRepository.cs
  49. 35
      modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Menus/MongoMenuRepository.cs
  50. 12
      modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Menus/IMenuItemPublicAppService.cs
  51. 11
      modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Menus/IMenuPublicAppService.cs
  52. 43
      modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Menus/MenuItemPublicAppService.cs
  53. 45
      modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Menus/MenuPublicAppService.cs
  54. 2
      modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs
  55. 14
      modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Menus/MenuItemPublicController.cs
  56. 10
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Menus/CmsKitPublicMenuContributor.cs
  57. 8
      modules/cms-kit/test/Volo.CmsKit.Application.Tests/Menus/MenuAdminAppService_Tests.cs
  58. 73
      modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Menus/MenuManager_Test.cs
  59. 2
      modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Menus/MenuRepository_Test.cs
  60. 2
      modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Menus/MenuRepository_Test.cs
  61. 39
      modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs
  62. 9
      modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs
  63. 21
      modules/cms-kit/test/Volo.CmsKit.TestBase/Menus/MenuItemRepository_Test.cs
  64. 51
      modules/cms-kit/test/Volo.CmsKit.TestBase/Menus/MenuRepository_Test.cs

36
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/IMenuAdminAppService.cs

@ -1,36 +0,0 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.CmsKit.Menus;
namespace Volo.CmsKit.Admin.Menus
{
public interface IMenuAdminAppService : IApplicationService
{
Task<PagedResultDto<MenuWithDetailsDto>> GetListAsync(PagedAndSortedResultRequestDto input);
Task<MenuWithDetailsDto> GetAsync(Guid id);
Task<MenuWithDetailsDto> CreateAsync(MenuCreateInput input);
Task<MenuWithDetailsDto> UpdateAsync(Guid menuId, MenuUpdateInput input);
Task DeleteAsync(Guid menuId);
Task<MenuItemDto> GetMenuItemAsync(Guid menuId, Guid menuItemId);
Task<MenuItemDto> CreateMenuItemAsync(Guid menuId, MenuItemCreateInput input);
Task<MenuItemDto> UpdateMenuItemAsync(Guid menuId, Guid menuItemId, MenuItemUpdateInput input);
Task DeleteMenuItemAsync(Guid menuId, Guid menuItemId);
Task MoveMenuItemAsync(Guid menuId, Guid menuItemId, MenuItemMoveInput input);
Task UpdateMainMenuAsync(Guid menuId, UpdateMainMenuInput input);
Task<PagedResultDto<PageLookupDto>> GetPageLookupAsync(PageLookupInputDto input);
}
}

25
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/IMenuItemAdminAppService.cs

@ -0,0 +1,25 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.CmsKit.Menus;
namespace Volo.CmsKit.Admin.Menus
{
public interface IMenuItemAdminAppService : IApplicationService
{
Task<ListResultDto<MenuItemDto>> GetListAsync();
Task<MenuItemDto> GetAsync(Guid id);
Task<MenuItemDto> CreateAsync(MenuItemCreateInput input);
Task<MenuItemDto> UpdateAsync(Guid id, MenuItemUpdateInput input);
Task DeleteAsync(Guid id);
Task MoveMenuItemAsync(Guid id, MenuItemMoveInput input);
Task<PagedResultDto<PageLookupDto>> GetPageLookupAsync(PageLookupInputDto input);
}
}

2
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/MenuItemCreateInput.cs

@ -6,8 +6,6 @@ namespace Volo.CmsKit.Admin.Menus
[Serializable] [Serializable]
public class MenuItemCreateInput public class MenuItemCreateInput
{ {
public Guid MenuId { get; set; }
public Guid? ParentId { get; set; } public Guid? ParentId { get; set; }
[Required] [Required]

1
modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs

@ -43,7 +43,6 @@ namespace Volo.CmsKit.Admin
CreateMap<MediaDescriptor, MediaDescriptorDto>(); CreateMap<MediaDescriptor, MediaDescriptorDto>();
CreateMap<Menu, MenuWithDetailsDto>();
CreateMap<MenuItem, MenuItemDto>(); CreateMap<MenuItem, MenuItemDto>();
} }
} }

207
modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Menus/MenuAdminAppService.cs

@ -1,207 +0,0 @@
using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Entities;
using Volo.Abp.GlobalFeatures;
using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Menus;
using Volo.CmsKit.Pages;
using Volo.CmsKit.Permissions;
namespace Volo.CmsKit.Admin.Menus
{
[RequiresGlobalFeature(typeof(MenuFeature))]
[Authorize(CmsKitAdminPermissions.Menus.Default)]
public class MenuAdminAppService : CmsKitAdminAppServiceBase, IMenuAdminAppService
{
protected MenuManager MenuManager { get; }
protected IMenuRepository MenuRepository { get; }
protected IPageRepository PageRepository { get; }
public MenuAdminAppService(
MenuManager menuManager,
IMenuRepository menuRepository,
IPageRepository pageRepository)
{
MenuManager = menuManager;
MenuRepository = menuRepository;
PageRepository = pageRepository;
}
public async Task<PagedResultDto<MenuWithDetailsDto>> GetListAsync(PagedAndSortedResultRequestDto input)
{
var menus = await MenuRepository.GetPagedListAsync(input.SkipCount, input.MaxResultCount, input.Sorting);
return new PagedResultDto<MenuWithDetailsDto>(
await MenuRepository.GetCountAsync(),
ObjectMapper.Map<List<Menu>, List<MenuWithDetailsDto>>(menus)
);
}
public async Task<MenuWithDetailsDto> GetAsync(Guid id)
{
var menu = await MenuRepository.GetAsync(id, includeDetails: true);
return ObjectMapper.Map<Menu, MenuWithDetailsDto>(menu);
}
public async Task<MenuWithDetailsDto> GetSimpleAsync(Guid id)
{
var menu = await MenuRepository.GetAsync(id, includeDetails: false);
return ObjectMapper.Map<Menu, MenuWithDetailsDto>(menu);
}
[Authorize(CmsKitAdminPermissions.Menus.Create)]
public async Task<MenuWithDetailsDto> CreateAsync(MenuCreateInput input)
{
var menu = await MenuManager.CreateAsync(CurrentTenant.Id, input.Name);
await MenuRepository.InsertAsync(menu);
return ObjectMapper.Map<Menu, MenuWithDetailsDto>(menu);
}
[Authorize(CmsKitAdminPermissions.Menus.Update)]
public async Task<MenuWithDetailsDto> UpdateAsync(Guid menuId, MenuUpdateInput input)
{
var menu = await MenuRepository.GetAsync(menuId);
menu.SetName(input.Name);
await MenuRepository.UpdateAsync(menu);
return ObjectMapper.Map<Menu, MenuWithDetailsDto>(menu);
}
[Authorize(CmsKitAdminPermissions.Menus.Delete)]
public virtual Task DeleteAsync(Guid menuId)
{
return MenuRepository.DeleteAsync(menuId);
}
public async Task<MenuItemDto> GetMenuItemAsync(Guid menuId, Guid menuItemId)
{
var menu = await MenuRepository.GetAsync(menuId);
var menuItem = menu.Items.FirstOrDefault(x => x.Id == menuItemId)
?? throw new EntityNotFoundException(typeof(MenuItem), menuItemId);
return ObjectMapper.Map<MenuItem, MenuItemDto>(menuItem);
}
[Authorize(CmsKitAdminPermissions.Menus.Update)]
public virtual async Task<MenuItemDto> CreateMenuItemAsync(Guid menuId, MenuItemCreateInput input)
{
var menu = await MenuRepository.GetAsync(menuId, includeDetails: true);
var menuItem =
new MenuItem(
GuidGenerator.Create(),
menuId,
input.DisplayName,
input.Url.IsNullOrEmpty() ? "#" : input.Url,
input.IsActive,
input.ParentId,
input.Icon,
input.Order,
input.Target,
input.ElementId,
input.CssClass);
if (input.PageId.HasValue)
{
var page = await PageRepository.GetAsync(input.PageId.Value);
MenuManager.SetPageUrl(menuItem, page);
}
menu.Items.Add(menuItem);
MenuManager.OrganizeTreeOrderForMenuItem(menu, menuItem);
await MenuRepository.UpdateAsync(menu);
return ObjectMapper.Map<MenuItem, MenuItemDto>(menuItem);
}
[Authorize(CmsKitAdminPermissions.Menus.Update)]
public virtual async Task<MenuItemDto> UpdateMenuItemAsync(Guid menuId, Guid menuItemId,
MenuItemUpdateInput input)
{
var menu = await MenuRepository.GetAsync(menuId, includeDetails: true);
var menuItem = menu.Items.FirstOrDefault(x => x.Id == menuItemId)
?? throw new EntityNotFoundException(typeof(MenuItem), menuItemId);
if (input.PageId.HasValue)
{
MenuManager.SetPageUrl(menuItem, await PageRepository.GetAsync(input.PageId.Value));
}
else
{
menuItem.SetUrl(input.Url);
}
menuItem.SetDisplayName(input.DisplayName);
menuItem.IsActive = input.IsActive;
menuItem.Icon = input.Icon;
menuItem.Target = input.Target;
menuItem.ElementId = input.ElementId;
menuItem.CssClass = input.CssClass;
await MenuRepository.UpdateAsync(menu);
return ObjectMapper.Map<MenuItem, MenuItemDto>(menuItem);
}
[Authorize(CmsKitAdminPermissions.Menus.Update)]
public virtual async Task DeleteMenuItemAsync(Guid menuId, Guid menuItemId)
{
var menu = await MenuRepository.GetAsync(menuId, includeDetails: true);
var menuItem = menu.Items.FirstOrDefault(x => x.Id == menuItemId)
?? throw new EntityNotFoundException(typeof(MenuItem), menuItemId);
menu.Items.Remove(menuItem);
await MenuRepository.UpdateAsync(menu);
}
[Authorize(CmsKitAdminPermissions.Menus.Update)]
public virtual Task MoveMenuItemAsync(Guid menuId, Guid menuItemId, MenuItemMoveInput input)
{
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);
}
}
public virtual async Task<PagedResultDto<PageLookupDto>> GetPageLookupAsync(PageLookupInputDto input)
{
var count = await PageRepository.GetCountAsync(input.Filter);
var pages = await PageRepository.GetListAsync(
input.Filter,
input.MaxResultCount,
input.SkipCount,
input.Sorting
);
return new PagedResultDto<PageLookupDto>(
count,
ObjectMapper.Map<List<Page>, List<PageLookupDto>>(pages)
);
}
}
}

125
modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Menus/MenuItemAdminAppService.cs

@ -0,0 +1,125 @@
using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.GlobalFeatures;
using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Menus;
using Volo.CmsKit.Pages;
using Volo.CmsKit.Permissions;
namespace Volo.CmsKit.Admin.Menus
{
[RequiresGlobalFeature(typeof(MenuFeature))]
[Authorize(CmsKitAdminPermissions.Menus.Default)]
public class MenuItemAdminAppService : CmsKitAdminAppServiceBase, IMenuItemAdminAppService
{
protected MenuItemManager MenuManager { get; }
protected IMenuItemRepository MenuItemRepository { get; }
protected IPageRepository PageRepository { get; }
public MenuItemAdminAppService(
MenuItemManager menuManager,
IMenuItemRepository menuRepository,
IPageRepository pageRepository)
{
MenuManager = menuManager;
MenuItemRepository = menuRepository;
PageRepository = pageRepository;
}
public virtual async Task<ListResultDto<MenuItemDto>> GetListAsync()
{
var menuItems = await MenuItemRepository.GetListAsync();
return new ListResultDto<MenuItemDto>(
ObjectMapper.Map<List<MenuItem>, List<MenuItemDto>>(menuItems)
);
}
public virtual async Task<MenuItemDto> GetAsync(Guid id)
{
var menu = await MenuItemRepository.GetAsync(id);
return ObjectMapper.Map<MenuItem, MenuItemDto>(menu);
}
[Authorize(CmsKitAdminPermissions.Menus.Create)]
public virtual async Task<MenuItemDto> CreateAsync(MenuItemCreateInput input)
{
var menuItem = new MenuItem(
GuidGenerator.Create(),
input.DisplayName,
input.Url.IsNullOrEmpty() ? "#" : input.Url,
input.IsActive,
input.ParentId,
input.Icon,
input.Order,
input.Target,
input.ElementId,
input.CssClass
);
await MenuItemRepository.InsertAsync(menuItem);
return ObjectMapper.Map<MenuItem, MenuItemDto>(menuItem);
}
[Authorize(CmsKitAdminPermissions.Menus.Update)]
public virtual async Task<MenuItemDto> UpdateAsync(Guid id, MenuItemUpdateInput input)
{
var menuItem = await MenuItemRepository.GetAsync(id);
if (input.PageId.HasValue)
{
MenuManager.SetPageUrl(menuItem, await PageRepository.GetAsync(input.PageId.Value));
}
else
{
menuItem.SetUrl(input.Url);
}
menuItem.SetDisplayName(input.DisplayName);
menuItem.IsActive = input.IsActive;
menuItem.Icon = input.Icon;
menuItem.Target = input.Target;
menuItem.ElementId = input.ElementId;
menuItem.CssClass = input.CssClass;
await MenuItemRepository.UpdateAsync(menuItem);
return ObjectMapper.Map<MenuItem, MenuItemDto>(menuItem);
}
[Authorize(CmsKitAdminPermissions.Menus.Delete)]
public virtual Task DeleteAsync(Guid id)
{
return MenuItemRepository.DeleteAsync(id);
}
[Authorize(CmsKitAdminPermissions.Menus.Update)]
public virtual Task MoveMenuItemAsync(Guid id, MenuItemMoveInput input)
{
return MenuManager.MoveAsync(id, input.NewParentId, input.Position);
}
public virtual async Task<PagedResultDto<PageLookupDto>> GetPageLookupAsync(PageLookupInputDto input)
{
var count = await PageRepository.GetCountAsync(input.Filter);
var pages = await PageRepository.GetListAsync(
input.Filter,
input.MaxResultCount,
input.SkipCount,
input.Sorting
);
return new PagedResultDto<PageLookupDto>(
count,
ObjectMapper.Map<List<Page>, List<PageLookupDto>>(pages)
);
}
}
}

98
modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Menus/MenuAdminController.cs

@ -1,14 +1,10 @@
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.GlobalFeatures; using Volo.Abp.GlobalFeatures;
using Volo.Abp.UI.Navigation;
using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Menus; using Volo.CmsKit.Menus;
using Volo.CmsKit.Permissions; using Volo.CmsKit.Permissions;
@ -19,105 +15,65 @@ namespace Volo.CmsKit.Admin.Menus
[RemoteService(Name = CmsKitAdminRemoteServiceConsts.RemoteServiceName)] [RemoteService(Name = CmsKitAdminRemoteServiceConsts.RemoteServiceName)]
[Area("cms-kit")] [Area("cms-kit")]
[Authorize(CmsKitAdminPermissions.Menus.Default)] [Authorize(CmsKitAdminPermissions.Menus.Default)]
[Route("api/cms-kit-admin/menus")] [Route("api/cms-kit-admin/menu-items")]
public class MenuAdminController : CmsKitAdminController, IMenuAdminAppService public class MenuAdminController : CmsKitAdminController, IMenuItemAdminAppService
{ {
protected IMenuAdminAppService MenuAdminAppService { get; } protected IMenuItemAdminAppService MenuItemAdminAppService { get; }
public MenuAdminController(IMenuAdminAppService menuAdminAppService) public MenuAdminController(IMenuItemAdminAppService menuAdminAppService)
{ {
MenuAdminAppService = menuAdminAppService; MenuItemAdminAppService = menuAdminAppService;
} }
[HttpPost]
[Authorize(CmsKitAdminPermissions.Menus.Create)]
public Task<MenuWithDetailsDto> CreateAsync(MenuCreateInput input)
{
return MenuAdminAppService.CreateAsync(input);
}
[Route("{menuId}/menu-items/{menuItemId}")]
[Authorize(CmsKitAdminPermissions.Menus.Update)]
[HttpGet] [HttpGet]
public Task<MenuItemDto> GetMenuItemAsync(Guid menuId, Guid menuItemId) public virtual Task<ListResultDto<MenuItemDto>> GetListAsync()
{
return MenuAdminAppService.GetMenuItemAsync(menuId, menuItemId);
}
[Route("{menuId}/menu-items")]
[HttpPost]
[Authorize(CmsKitAdminPermissions.Menus.Update)]
public Task<MenuItemDto> CreateMenuItemAsync(Guid menuId, MenuItemCreateInput input)
{
return MenuAdminAppService.CreateMenuItemAsync(menuId, input);
}
[Route("{menuId}")]
[HttpDelete]
[Authorize(CmsKitAdminPermissions.Menus.Delete)]
public Task DeleteAsync(Guid menuId)
{ {
return MenuAdminAppService.DeleteAsync(menuId); return MenuItemAdminAppService.GetListAsync();
} }
[Route("{menuId}/menu-items/{menuItemId}")]
[HttpDelete]
[Authorize(CmsKitAdminPermissions.Menus.Update)]
public Task DeleteMenuItemAsync(Guid menuId, Guid menuItemId)
{
return MenuAdminAppService.DeleteMenuItemAsync(menuId, menuItemId);
}
[Route("{menuId}")]
[HttpGet] [HttpGet]
public Task<MenuWithDetailsDto> GetAsync(Guid menuId) [Route("{id}")]
public virtual Task<MenuItemDto> GetAsync(Guid id)
{ {
return MenuAdminAppService.GetAsync(menuId); return MenuItemAdminAppService.GetAsync(id);
} }
[HttpGet] [HttpPost]
public Task<PagedResultDto<MenuWithDetailsDto>> GetListAsync(PagedAndSortedResultRequestDto input) [Authorize(CmsKitAdminPermissions.Menus.Create)]
public virtual Task<MenuItemDto> CreateAsync(MenuItemCreateInput input)
{ {
return MenuAdminAppService.GetListAsync(input); return MenuItemAdminAppService.CreateAsync(input);
} }
[Route("{menuId}/menu-items/{menuItemId}/move")]
[HttpPut] [HttpPut]
[Route("{id}")]
[Authorize(CmsKitAdminPermissions.Menus.Update)] [Authorize(CmsKitAdminPermissions.Menus.Update)]
public Task MoveMenuItemAsync(Guid menuId, Guid menuItemId, MenuItemMoveInput input) public virtual Task<MenuItemDto> UpdateAsync(Guid id, MenuItemUpdateInput input)
{ {
return MenuAdminAppService.MoveMenuItemAsync(menuId, menuItemId, input); return MenuItemAdminAppService.UpdateAsync(id, input);
}
[Route("{menuId}/main-menu")]
[HttpPut]
[Authorize(CmsKitAdminPermissions.Menus.Update)]
public Task UpdateMainMenuAsync(Guid menuId, UpdateMainMenuInput input)
{
return MenuAdminAppService.UpdateMainMenuAsync(menuId, input);
} }
[Route("{menuId}")] [HttpDelete]
[HttpPut] [Route("{id}")]
[Authorize(CmsKitAdminPermissions.Menus.Update)] [Authorize(CmsKitAdminPermissions.Menus.Delete)]
public Task<MenuWithDetailsDto> UpdateAsync(Guid menuId, MenuUpdateInput input) public virtual Task DeleteAsync(Guid id)
{ {
return MenuAdminAppService.UpdateAsync(menuId, input); return MenuItemAdminAppService.DeleteAsync(id);
} }
[Route("{menuId}/menu-items/{menuItemId}")]
[HttpPut] [HttpPut]
[Route("{id}/move")]
[Authorize(CmsKitAdminPermissions.Menus.Update)] [Authorize(CmsKitAdminPermissions.Menus.Update)]
public Task<MenuItemDto> UpdateMenuItemAsync(Guid menuId, Guid menuItemId, MenuItemUpdateInput input) public virtual Task MoveMenuItemAsync(Guid id, MenuItemMoveInput input)
{ {
return MenuAdminAppService.UpdateMenuItemAsync(menuId, menuItemId, input); return MenuItemAdminAppService.MoveMenuItemAsync(id, input);
} }
[HttpGet] [HttpGet]
[Route("lookup/pages")] [Route("lookup/pages")]
public virtual Task<PagedResultDto<PageLookupDto>> GetPageLookupAsync([FromQuery]PageLookupInputDto input) public virtual Task<PagedResultDto<PageLookupDto>> GetPageLookupAsync(PageLookupInputDto input)
{ {
return MenuAdminAppService.GetPageLookupAsync(input); return MenuItemAdminAppService.GetPageLookupAsync(input);
} }
} }
} }

19
modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs

@ -70,8 +70,8 @@ namespace Volo.CmsKit.Admin.Web
options.Conventions.AuthorizeFolder("/CmsKit/Comments/", CmsKitAdminPermissions.Comments.Default); options.Conventions.AuthorizeFolder("/CmsKit/Comments/", CmsKitAdminPermissions.Comments.Default);
options.Conventions.AuthorizeFolder("/CmsKit/Comments/Details", CmsKitAdminPermissions.Comments.Default); options.Conventions.AuthorizeFolder("/CmsKit/Comments/Details", CmsKitAdminPermissions.Comments.Default);
options.Conventions.AuthorizeFolder("/CmsKit/Menus", CmsKitAdminPermissions.Menus.Default); options.Conventions.AuthorizeFolder("/CmsKit/Menus", CmsKitAdminPermissions.Menus.Default);
options.Conventions.AuthorizePage("/CmsKit/Menus/CreateModal", CmsKitAdminPermissions.Menus.Create); options.Conventions.AuthorizePage("/CmsKit/Menus/MenuItems/CreateModal", CmsKitAdminPermissions.Menus.Create);
options.Conventions.AuthorizePage("/CmsKit/Menus/UpdateModal", CmsKitAdminPermissions.Menus.Update); options.Conventions.AuthorizePage("/CmsKit/Menus/MenuItems/UpdateModal", CmsKitAdminPermissions.Menus.Update);
options.Conventions.AuthorizeFolder("/CmsKit/Menus/MenuItems", CmsKitAdminPermissions.Menus.Update); options.Conventions.AuthorizeFolder("/CmsKit/Menus/MenuItems", CmsKitAdminPermissions.Menus.Update);
}); });
@ -87,8 +87,7 @@ namespace Volo.CmsKit.Admin.Web
options.Conventions.AddPageRoute("/CmsKit/BlogPosts/Update", "/Cms/BlogPosts/Update/{Id}"); options.Conventions.AddPageRoute("/CmsKit/BlogPosts/Update", "/Cms/BlogPosts/Update/{Id}");
options.Conventions.AddPageRoute("/CmsKit/Comments/Index", "/Cms/Comments"); options.Conventions.AddPageRoute("/CmsKit/Comments/Index", "/Cms/Comments");
options.Conventions.AddPageRoute("/CmsKit/Comments/Details", "/Cms/Comments/{Id}"); options.Conventions.AddPageRoute("/CmsKit/Comments/Details", "/Cms/Comments/{Id}");
options.Conventions.AddPageRoute("/CmsKit/Menus/Index", "/Cms/Menus"); options.Conventions.AddPageRoute("/CmsKit/Menus/MenuItems/Index", "/Cms/Menus/Items");
options.Conventions.AddPageRoute("/CmsKit/Menus/MenuItems/Index", "/Cms/Menus/{Id}/menu-items");
}); });
Configure<AbpPageToolbarOptions>(options => Configure<AbpPageToolbarOptions>(options =>
@ -141,18 +140,6 @@ namespace Volo.CmsKit.Admin.Web
); );
}); });
options.Configure<Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.IndexModel>(
toolbar =>
{
toolbar.AddButton(
LocalizableString.Create<CmsKitResource>("NewMenu"),
icon: "plus",
name: "CreateMenu",
id: "CreateMenu",
requiredPolicyName: CmsKitAdminPermissions.Menus.Create
);
});
options.Configure<Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems.IndexModel>( options.Configure<Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems.IndexModel>(
toolbar => toolbar =>
{ {

4
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenuContributor.cs

@ -74,8 +74,8 @@ namespace Volo.CmsKit.Admin.Web.Menus
cmsMenus.Add(new ApplicationMenuItem( cmsMenus.Add(new ApplicationMenuItem(
CmsKitAdminMenus.Menus.MenusMenu, CmsKitAdminMenus.Menus.MenusMenu,
l["Menus"], l["Menus"],
"/Cms/Menus", "/Cms/Menus/Items",
"fa fa-bars") "fa fa-stream")
.RequireGlobalFeatures(typeof(MenuFeature)) .RequireGlobalFeatures(typeof(MenuFeature))
.RequirePermissions(CmsKitAdminPermissions.Menus.Default)); .RequirePermissions(CmsKitAdminPermissions.Menus.Default));

23
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/CreateModal.cshtml

@ -1,23 +0,0 @@
@page
@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus
@using Volo.CmsKit.Admin.Web.Pages
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@inherits CmsKitAdminPageBase
@model CreateModalModel
@{
Layout = null;
}
<abp-dynamic-form abp-model="ViewModel" asp-page="/CmsKit/Menus/CreateModal">
<abp-modal>
<abp-modal-header title="@L["New"].Value"></abp-modal-header>
<abp-modal-body>
<abp-form-content />
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel | AbpModalButtons.Save)"></abp-modal-footer>
</abp-modal>
</abp-dynamic-form>

44
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/CreateModal.cshtml.cs

@ -1,44 +0,0 @@
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Validation;
using Volo.CmsKit.Admin.Menus;
using Volo.CmsKit.Menus;
namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus
{
public class CreateModalModel : CmsKitAdminPageModel
{
protected IMenuAdminAppService MenuAdminAppService { get; }
[BindProperty]
public CreateMenuViewModel ViewModel { get; set; }
public CreateModalModel(IMenuAdminAppService menuAdminAppService)
{
MenuAdminAppService = menuAdminAppService;
}
public async Task<IActionResult> OnPostAsync()
{
var input = ObjectMapper.Map<CreateMenuViewModel, MenuCreateInput>(ViewModel);
await MenuAdminAppService.CreateAsync(input);
return NoContent();
}
[AutoMap(typeof(MenuCreateInput), ReverseMap = true)]
public class CreateMenuViewModel
{
[Required]
[DynamicMaxLength(typeof(MenuConsts), nameof(MenuConsts.MaxNameLength))]
public string Name { get; set; }
}
}
}

34
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/Index.cshtml

@ -1,34 +0,0 @@
@page
@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus
@using Volo.CmsKit.Admin.Web.Pages
@using Volo.CmsKit.Admin.Web.Menus
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageToolbar
@inherits CmsKitAdminPageBase
@model IndexModel
@{
PageLayout.Content.Title = L["Menus"].Value;
PageLayout.Content.BreadCrumb.Add(L["Menu:CMS"].Value);
PageLayout.Content.MenuItemName = CmsKitAdminMenus.Menus.MenusMenu;
}
@section scripts {
<abp-script-bundle>
<abp-script src="/Pages/CmsKit/Menus/index.js" />
</abp-script-bundle>
}
@section content_toolbar {
@await Component.InvokeAsync(typeof(AbpPageToolbarViewComponent), new { pageName = typeof(IndexModel).FullName })
}
<div id="CmsKitMenusWrapper">
<abp-card>
<abp-card-body>
<abp-table striped-rows="true" id="MenusTable" class="nowrap"></abp-table>
</abp-card-body>
</abp-card>
</div>

13
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/Index.cshtml.cs

@ -1,13 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus
{
public class IndexModel
{
}
}

1
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/CreateModal.cshtml

@ -34,7 +34,6 @@
</abp-tabs> </abp-tabs>
<hr/> <hr/>
<abp-input asp-for="ViewModel.MenuId"/>
<abp-input asp-for="ViewModel.ParentId"/> <abp-input asp-for="ViewModel.ParentId"/>
<abp-input asp-for="ViewModel.DisplayName"/> <abp-input asp-for="ViewModel.DisplayName"/>
<abp-input asp-for="ViewModel.IsActive"/> <abp-input asp-for="ViewModel.IsActive"/>

12
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/CreateModal.cshtml.cs

@ -13,20 +13,19 @@ namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems
{ {
public class CreateModalModel : CmsKitAdminPageModel public class CreateModalModel : CmsKitAdminPageModel
{ {
protected IMenuAdminAppService MenuAdminAppService { get; } protected IMenuItemAdminAppService MenuAdminAppService { get; }
[BindProperty] [BindProperty]
public MenuItemCreateViewModel ViewModel { get; set; } public MenuItemCreateViewModel ViewModel { get; set; }
public CreateModalModel(IMenuAdminAppService menuAdminAppService) public CreateModalModel(IMenuItemAdminAppService menuAdminAppService)
{ {
MenuAdminAppService = menuAdminAppService; MenuAdminAppService = menuAdminAppService;
ViewModel = new MenuItemCreateViewModel(); ViewModel = new MenuItemCreateViewModel();
} }
public virtual Task OnGetAsync(Guid menuId, Guid? parentId) public virtual Task OnGetAsync(Guid? parentId)
{ {
ViewModel.MenuId = menuId;
ViewModel.ParentId = parentId; ViewModel.ParentId = parentId;
return Task.CompletedTask; return Task.CompletedTask;
@ -36,7 +35,7 @@ namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems
{ {
var input = ObjectMapper.Map<MenuItemCreateViewModel, MenuItemCreateInput>(ViewModel); var input = ObjectMapper.Map<MenuItemCreateViewModel, MenuItemCreateInput>(ViewModel);
var dto = await MenuAdminAppService.CreateMenuItemAsync(ViewModel.MenuId, input); var dto = await MenuAdminAppService.CreateAsync(input);
return new OkObjectResult(dto); return new OkObjectResult(dto);
} }
@ -44,9 +43,6 @@ namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems
[AutoMap(typeof(MenuItemCreateInput), ReverseMap = true)] [AutoMap(typeof(MenuItemCreateInput), ReverseMap = true)]
public class MenuItemCreateViewModel public class MenuItemCreateViewModel
{ {
[HiddenInput]
public Guid MenuId { get; set; }
[HiddenInput] [HiddenInput]
public Guid? ParentId { get; set; } public Guid? ParentId { get; set; }

7
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/Index.cshtml

@ -11,9 +11,8 @@
@model IndexModel @model IndexModel
@{ @{
PageLayout.Content.Title = @Model.Menu.Name + " - " + L["MenuItems"].Value; PageLayout.Content.Title = L["MenuItems"].Value;
PageLayout.Content.BreadCrumb.Add(L["Menu:CMS"].Value); PageLayout.Content.BreadCrumb.Add(L["Menu:CMS"].Value);
PageLayout.Content.BreadCrumb.Add(L["Menus"].Value, "/Cms/Menus");
PageLayout.Content.MenuItemName = CmsKitAdminMenus.Menus.MenusMenu; PageLayout.Content.MenuItemName = CmsKitAdminMenus.Menus.MenusMenu;
} }
@ -37,11 +36,11 @@
@await Component.InvokeAsync(typeof(AbpPageToolbarViewComponent), new {pageName = typeof(IndexModel).FullName}) @await Component.InvokeAsync(typeof(AbpPageToolbarViewComponent), new {pageName = typeof(IndexModel).FullName})
} }
<div id="CmsKitMenuItemsWrapper" data-menu-id="@Model.Id"> <div id="CmsKitMenuItemsWrapper">
<abp-card> <abp-card>
<abp-card-body> <abp-card-body>
<abp-card-title> <abp-card-title>
@Model.Menu.Name @L["MenuItems"].Value
</abp-card-title> </abp-card-title>
<div id="MenuItemsEditTree"></div> <div id="MenuItemsEditTree"></div>

16
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/Index.cshtml.cs

@ -11,21 +11,5 @@ namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems
{ {
public class IndexModel : CmsKitAdminPageModel public class IndexModel : CmsKitAdminPageModel
{ {
protected IMenuAdminAppService MenuAdminAppService { get; }
[BindProperty(SupportsGet = true)]
public Guid Id { get; set; }
public MenuWithDetailsDto Menu { get; protected set; }
public IndexModel(IMenuAdminAppService menuAdminAppService)
{
MenuAdminAppService = menuAdminAppService;
}
public async Task OnGetAsync()
{
Menu = await MenuAdminAppService.GetAsync(Id);
}
} }
} }

1
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/UpdateModal.cshtml

@ -16,7 +16,6 @@
<abp-modal> <abp-modal>
<abp-modal-header title="@L["New"].Value"></abp-modal-header> <abp-modal-header title="@L["New"].Value"></abp-modal-header>
<abp-modal-body> <abp-modal-body>
<abp-input asp-for="MenuId"/>
<abp-input asp-for="Id"/> <abp-input asp-for="Id"/>
<abp-tabs tab-style="Tab"> <abp-tabs tab-style="Tab">

12
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/UpdateModal.cshtml.cs

@ -11,27 +11,23 @@ namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems
{ {
public class UpdateModalModel : CmsKitAdminPageModel public class UpdateModalModel : CmsKitAdminPageModel
{ {
protected IMenuAdminAppService MenuAdminAppService { get; } protected IMenuItemAdminAppService MenuAdminAppService { get; }
[BindProperty] [BindProperty]
public MenuItemUpdateViewModel ViewModel { get; set; } public MenuItemUpdateViewModel ViewModel { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public Guid MenuId { get; set; }
[HiddenInput] [HiddenInput]
[BindProperty(SupportsGet = true)] [BindProperty(SupportsGet = true)]
public Guid Id { get; set; } public Guid Id { get; set; }
public UpdateModalModel(IMenuAdminAppService menuAdminAppService) public UpdateModalModel(IMenuItemAdminAppService menuAdminAppService)
{ {
MenuAdminAppService = menuAdminAppService; MenuAdminAppService = menuAdminAppService;
} }
public async Task OnGetAsync() public async Task OnGetAsync()
{ {
var menuItemDto = await MenuAdminAppService.GetMenuItemAsync(MenuId, Id); var menuItemDto = await MenuAdminAppService.GetAsync(Id);
ViewModel = ObjectMapper.Map<MenuItemDto, MenuItemUpdateViewModel>(menuItemDto); ViewModel = ObjectMapper.Map<MenuItemDto, MenuItemUpdateViewModel>(menuItemDto);
} }
@ -40,7 +36,7 @@ namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems
{ {
var input = ObjectMapper.Map<MenuItemUpdateViewModel, MenuItemUpdateInput>(ViewModel); var input = ObjectMapper.Map<MenuItemUpdateViewModel, MenuItemUpdateInput>(ViewModel);
var result = await MenuAdminAppService.UpdateMenuItemAsync(MenuId, Id, input); var result = await MenuAdminAppService.UpdateAsync(Id, input);
return new OkObjectResult(result); return new OkObjectResult(result);
} }

2
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/createModal.js

@ -28,7 +28,7 @@ $(function () {
}) })
function initSelectPageId() { function initSelectPageId() {
$pageId.data('autocompleteApiUrl', '/api/cms-kit-admin/menus/lookup/pages'); $pageId.data('autocompleteApiUrl', '/api/cms-kit-admin/menu-items/lookup/pages');
$pageId.data('autocompleteDisplayProperty', 'title'); $pageId.data('autocompleteDisplayProperty', 'title');
$pageId.data('autocompleteValueProperty', 'id'); $pageId.data('autocompleteValueProperty', 'id');
$pageId.data('autocompleteItemsProperty', 'items'); $pageId.data('autocompleteItemsProperty', 'items');

14
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/index.js

@ -2,8 +2,6 @@
$(function () { $(function () {
var l = abp.localization.getResource("CmsKit"); var l = abp.localization.getResource("CmsKit");
var menuId = $('#CmsKitMenuItemsWrapper').data('menu-id');
var menuService = volo.cmsKit.admin.menus.menuAdmin; var menuService = volo.cmsKit.admin.menus.menuAdmin;
var createModal = new abp.ModalManager({ viewUrl: abp.appPath + 'CmsKit/Menus/MenuItems/CreateModal', modalClass: 'createMenuItem' }); var createModal = new abp.ModalManager({ viewUrl: abp.appPath + 'CmsKit/Menus/MenuItems/CreateModal', modalClass: 'createMenuItem' });
@ -96,8 +94,7 @@ $(function () {
var instance = $.jstree.reference(data.reference); var instance = $.jstree.reference(data.reference);
updateModal.open({ updateModal.open({
id: node.id, id: node.id
menuId: menuId
}) })
} }
}, },
@ -124,7 +121,7 @@ $(function () {
function (isConfirmed) { function (isConfirmed) {
if (isConfirmed) { if (isConfirmed) {
menuService menuService
.deleteMenuItem(menuId, node.id) .delete(node.id)
.done(function () { .done(function () {
instance.delete_node(node); instance.delete_node(node);
menuTree.refreshItemCount(); menuTree.refreshItemCount();
@ -147,7 +144,6 @@ $(function () {
var instance = $.jstree.reference(menuTree.$tree); var instance = $.jstree.reference(menuTree.$tree);
createModal.open({ createModal.open({
menuId: menuId,
parentId: parentId, parentId: parentId,
}, function (newMenuItem) { }, function (newMenuItem) {
instance.create_node( instance.create_node(
@ -182,7 +178,7 @@ $(function () {
}, },
getTreeDataFromServer: function (callback) { getTreeDataFromServer: function (callback) {
menuService.get(menuId).done(function (result) { menuService.getList().done(function (result) {
var treeData = _.map(result.items, function (item) { var treeData = _.map(result.items, function (item) {
return { return {
id: item.id, id: item.id,
@ -233,7 +229,7 @@ $(function () {
function (isConfirmed) { function (isConfirmed) {
if (isConfirmed) { if (isConfirmed) {
menuService menuService
.moveMenuItem(menuId, data.node.id, { .moveMenuItem(data.node.id, {
newParentId: data.parent === '#' ? null : data.parent, newParentId: data.parent === '#' ? null : data.parent,
position: data.position position: data.position
}) })
@ -285,7 +281,7 @@ $(function () {
$('button[name=CreateMenuItem]').click(function (e) { $('button[name=CreateMenuItem]').click(function (e) {
e.preventDefault(); e.preventDefault();
createModal.open({menuId: menuId}); createModal.open();
}); });
createModal.onResult(function () { createModal.onResult(function () {

2
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/updateModal.js

@ -29,7 +29,7 @@ $(function () {
}); });
function initSelectPageId() { function initSelectPageId() {
$pageId.data('autocompleteApiUrl', '/api/cms-kit-admin/menus/lookup/pages'); $pageId.data('autocompleteApiUrl', '/api/cms-kit-admin/menu-items/lookup/pages');
$pageId.data('autocompleteDisplayProperty', 'title'); $pageId.data('autocompleteDisplayProperty', 'title');
$pageId.data('autocompleteValueProperty', 'id'); $pageId.data('autocompleteValueProperty', 'id');
$pageId.data('autocompleteItemsProperty', 'items'); $pageId.data('autocompleteItemsProperty', 'items');

23
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/UpdateModal.cshtml

@ -1,23 +0,0 @@
@page
@using Volo.CmsKit.Admin.Web.Pages
@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@inherits CmsKitAdminPageBase
@model UpdateModalModel
@{
Layout = null;
}
<abp-dynamic-form abp-model="ViewModel" asp-page="/CmsKit/Menus/UpdateModal">
<abp-modal>
<abp-modal-header title="@L["Edit"].Value"></abp-modal-header>
<abp-modal-body>
<abp-input asp-for="Id" />
<abp-form-content />
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer>
</abp-modal>
</abp-dynamic-form>

53
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/UpdateModal.cshtml.cs

@ -1,53 +0,0 @@
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using System;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using Volo.Abp.Validation;
using Volo.CmsKit.Admin.Menus;
using Volo.CmsKit.Menus;
namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus
{
public class UpdateModalModel : CmsKitAdminPageModel
{
protected IMenuAdminAppService MenuAdminAppService { get; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public Guid Id { get; set; }
[BindProperty]
public UpdateMenuViewModel ViewModel { get; set; }
public UpdateModalModel(IMenuAdminAppService menuAdminAppService)
{
MenuAdminAppService = menuAdminAppService;
}
public async Task OnGetAsync()
{
var menu = await MenuAdminAppService.GetAsync(Id);
ViewModel = ObjectMapper.Map<MenuWithDetailsDto, UpdateMenuViewModel>(menu);
}
public async Task<IActionResult> OnPostAsync()
{
var input = ObjectMapper.Map<UpdateMenuViewModel, MenuUpdateInput>(ViewModel);
await MenuAdminAppService.UpdateAsync(Id, input);
return NoContent();
}
[AutoMap(typeof(MenuWithDetailsDto))]
[AutoMap(typeof(MenuUpdateInput), ReverseMap = true)]
public class UpdateMenuViewModel
{
[Required]
[DynamicMaxLength(typeof(MenuConsts), nameof(MenuConsts.MaxNameLength))]
public string Name { get; set; }
}
}
}

1
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/createModal.js

@ -1 +0,0 @@


118
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/index.js

@ -1,118 +0,0 @@
$(function () {
var l = abp.localization.getResource("CmsKit");
var createModal = new abp.ModalManager(abp.appPath + "CmsKit/Menus/CreateModal");
var updateModal = new abp.ModalManager(abp.appPath + "CmsKit/Menus/UpdateModal");
var menusService = volo.cmsKit.admin.menus.menuAdmin;
var dataTable = $("#MenusTable").DataTable(abp.libs.datatables.normalizeConfiguration({
processing: true,
serverSide: true,
paging: true,
searching: false,
scrollCollapse: true,
scrollX: true,
ordering: true,
order: [[1, "desc"]],
ajax: abp.libs.datatables.createAjax(menusService.getList),
columnDefs: [
{
title: l("Details"),
targets: 0,
rowAction: {
items: [
{
text: l('MenuItems'),
visible: abp.auth.isGranted('CmsKit.Menus.Update'),
action: function (data) {
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'),
action: function (data) {
updateModal.open({id: data.record.id});
}
},
{
text: l('Delete'),
visible: abp.auth.isGranted('CmsKit.Menus.Delete'),
confirmMessage: function (data) {
return l("MenuDeletionConfirmationMessage", data.record.name)
},
action: function (data) {
menusService
.delete(data.record.id)
.then(function () {
dataTable.ajax.reload();
});
}
}
]
}
},
{
title: l("Name"),
orderable: true,
data: "name",
render: function (data, val, record) {
if (record.isMainMenu) {
return (
data
+
'<span class="badge badge-pill badge-info ml-1">'
+
l("MainMenu")
+
'</span>'
);
} else {
return data;
}
}
}
]
}));
$('#AbpContentToolbar button[name=CreateMenu]').on('click', function (e) {
e.preventDefault();
createModal.open();
});
createModal.onResult(function () {
dataTable.ajax.reload();
});
updateModal.onResult(function () {
dataTable.ajax.reload();
});
});

1
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/updateModal.js

@ -1 +0,0 @@


1
modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Menus/MenuItemDto.cs

@ -7,7 +7,6 @@ namespace Volo.CmsKit.Menus
[Serializable] [Serializable]
public class MenuItemDto : AuditedEntityDto<Guid> public class MenuItemDto : AuditedEntityDto<Guid>
{ {
public Guid MenuId { get; set; }
public Guid? ParentId { get; set; } public Guid? ParentId { get; set; }
public string DisplayName { get; set; } public string DisplayName { get; set; }
public bool IsActive { get; set; } public bool IsActive { get; set; }

20
modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Menus/MenuWithDetailsDto.cs

@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
namespace Volo.CmsKit.Menus
{
[Serializable]
public class MenuWithDetailsDto : FullAuditedEntityDto<Guid>
{
public string Name { get; set; }
public bool IsMainMenu { get; set; }
public List<MenuItemDto> Items { get; set; }
}
}

19
modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Menus/MenuChangedHandler.cs

@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Caching; using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
@ -7,23 +8,29 @@ using Volo.Abp.EventBus;
namespace Volo.CmsKit.Menus namespace Volo.CmsKit.Menus
{ {
public class MenuChangedHandler : public class MenuChangedHandler :
ILocalEventHandler<EntityUpdatedEventData<Menu>>, ILocalEventHandler<EntityUpdatedEventData<MenuItem>>,
ILocalEventHandler<EntityDeletedEventData<Menu>>, ILocalEventHandler<EntityDeletedEventData<MenuItem>>,
ILocalEventHandler<EntityCreatedEventData<MenuItem>>,
ITransientDependency ITransientDependency
{ {
protected IDistributedCache<MenuWithDetailsDto> DistributedCache { get; } protected IDistributedCache<List<MenuItemDto>> DistributedCache { get; }
public MenuChangedHandler(IDistributedCache<MenuWithDetailsDto> distributedCache) public MenuChangedHandler(IDistributedCache<List<MenuItemDto>> distributedCache)
{ {
DistributedCache = distributedCache; DistributedCache = distributedCache;
} }
public Task HandleEventAsync(EntityUpdatedEventData<Menu> eventData) public Task HandleEventAsync(EntityUpdatedEventData<MenuItem> eventData)
{ {
return DistributedCache.RemoveAsync(MenuApplicationConsts.MainMenuCacheKey); return DistributedCache.RemoveAsync(MenuApplicationConsts.MainMenuCacheKey);
} }
public Task HandleEventAsync(EntityDeletedEventData<Menu> eventData) public Task HandleEventAsync(EntityDeletedEventData<MenuItem> eventData)
{
return DistributedCache.RemoveAsync(MenuApplicationConsts.MainMenuCacheKey);
}
public Task HandleEventAsync(EntityCreatedEventData<MenuItem> eventData)
{ {
return DistributedCache.RemoveAsync(MenuApplicationConsts.MainMenuCacheKey); return DistributedCache.RemoveAsync(MenuApplicationConsts.MainMenuCacheKey);
} }

9
modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/IMenuItemRepository.cs

@ -0,0 +1,9 @@
using System;
using Volo.Abp.Domain.Repositories;
namespace Volo.CmsKit.Menus
{
public interface IMenuItemRepository : IBasicRepository<MenuItem, Guid>
{
}
}

18
modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/IMenuRepository.cs

@ -1,18 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace Volo.CmsKit.Menus
{
public interface IMenuRepository : IBasicRepository<Menu, Guid>
{
Task<Menu> FindMainMenuAsync(bool includeDetails = true, CancellationToken cancellationToken = default);
Task<List<Menu>> GetCurrentAndNextMainMenusAsync(
Guid nextMainMenuId,
bool includeDetails = true,
CancellationToken cancellationToken = default);
}
}

33
modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/Menu.cs

@ -1,33 +0,0 @@
using JetBrains.Annotations;
using System;
using System.Collections;
using System.Collections.Generic;
using Volo.Abp;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace Volo.CmsKit.Menus
{
public class Menu : FullAuditedAggregateRoot<Guid>, IMultiTenant
{
public string Name { get; protected set; }
public bool IsMainMenu { get; internal set; }
public Guid? TenantId { get; protected set; }
public ICollection<MenuItem> Items { get; protected set; }
internal Menu(Guid id, Guid? tenantId, [NotNull] string name) : base(id)
{
TenantId = tenantId;
SetName(name);
Items = new HashSet<MenuItem>();
}
public void SetName([NotNull] string name)
{
Name = Check.NotNullOrEmpty(name, nameof(name), MenuConsts.MaxNameLength);
}
}
}

11
modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/MenuItem.cs

@ -7,16 +7,12 @@ using System.Threading.Tasks;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Authorization.Permissions; using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace Volo.CmsKit.Menus namespace Volo.CmsKit.Menus
{ {
public class MenuItem : AuditedEntity<Guid> public class MenuItem : AuditedAggregateRoot<Guid>, IMultiTenant
{ {
/// <summary>
/// Parent <see cref="Menu"/> Id.
/// </summary>
public Guid MenuId { get; set; }
/// <summary> /// <summary>
/// Presents another <see cref="MenuItem"/> Id. /// Presents another <see cref="MenuItem"/> Id.
/// If it's <see langword="null"/>, then it's a root menu item. /// If it's <see langword="null"/>, then it's a root menu item.
@ -43,9 +39,9 @@ namespace Volo.CmsKit.Menus
public Guid? PageId { get; protected set; } public Guid? PageId { get; protected set; }
public Guid? TenantId { get; }
public MenuItem(Guid id, public MenuItem(Guid id,
Guid menuId,
[NotNull] string displayName, [NotNull] string displayName,
[NotNull] string url, [NotNull] string url,
bool isActive = true, bool isActive = true,
@ -57,7 +53,6 @@ namespace Volo.CmsKit.Menus
[CanBeNull] string cssClass = null) [CanBeNull] string cssClass = null)
:base(id) :base(id)
{ {
MenuId = menuId;
SetDisplayName(displayName); SetDisplayName(displayName);
IsActive = isActive; IsActive = isActive;
ParentId = parentId; ParentId = parentId;

63
modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/MenuItemManager.cs

@ -0,0 +1,63 @@
using JetBrains.Annotations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Uow;
using Volo.CmsKit.Pages;
namespace Volo.CmsKit.Menus
{
public class MenuItemManager : CmsKitDomainServiceBase
{
protected IMenuItemRepository MenuItemRepository { get; }
public MenuItemManager(IMenuItemRepository menuRepository)
{
MenuItemRepository = menuRepository;
}
public virtual void SetPageUrl(MenuItem menuItem, Page page)
{
menuItem.SetPageId(page.Id);
menuItem.SetUrl(PageConsts.UrlPrefix + page.Slug);
}
[UnitOfWork]
public virtual async Task MoveAsync(Guid menuItemId, Guid? newParentMenuItemId, int position = 0)
{
var menuItems = await MenuItemRepository.GetListAsync();
var movedMenuItem = menuItems.FirstOrDefault(x => x.Id == menuItemId)
?? throw new EntityNotFoundException(typeof(MenuItem), menuItemId);
if (newParentMenuItemId.HasValue && !menuItems.Any(a => a.Id == newParentMenuItemId.Value))
{
throw new EntityNotFoundException(typeof(MenuItem), newParentMenuItemId);
}
movedMenuItem.ParentId = newParentMenuItemId;
movedMenuItem.Order = position;
OrganizeTreeOrderForMenuItem(menuItems, movedMenuItem);
await MenuItemRepository.UpdateManyAsync(menuItems);
}
public virtual void OrganizeTreeOrderForMenuItem(List<MenuItem> items, MenuItem menuItem)
{
var sameTree = items.Where(x => x.ParentId == menuItem.ParentId).OrderBy(x => x.Order).ToList();
sameTree.Remove(menuItem); // Remove if exists to prevent misordering with same order number
sameTree.Insert(menuItem.Order, menuItem);
for (int i = 0; i < sameTree.Count; i++)
{
sameTree[i].Order = i;
}
}
}
}

109
modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/MenuManager.cs

@ -1,109 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Volo.Abp;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Services;
using Volo.Abp.Uow;
using Volo.CmsKit.Pages;
namespace Volo.CmsKit.Menus
{
public class MenuManager : CmsKitDomainServiceBase
{
protected IMenuRepository MenuRepository { get; }
public MenuManager(IMenuRepository menuRepository)
{
MenuRepository = menuRepository;
}
/// <summary>
/// Creates a new instance of <see cref="Menu"/> without inserting into database.
/// </summary>
/// <param name="tenantId">Tenant Id of Menu.</param>
/// <param name="name">Name of Menu.</param>
/// <returns>Created instance.</returns>
public virtual async Task<Menu> CreateAsync(Guid? tenantId, [NotNull] string name)
{
var menu = new Menu(
GuidGenerator.Create(),
tenantId,
Check.NotNullOrEmpty(name, nameof(name), MenuConsts.MaxNameLength));
var existingMenuCount = await MenuRepository.GetCountAsync();
if (existingMenuCount == 0)
{
menu.IsMainMenu = true;
}
return menu;
}
public virtual void SetPageUrl(MenuItem menuItem, Page page)
{
menuItem.SetPageId(page.Id);
menuItem.SetUrl(PageConsts.UrlPrefix + page.Slug);
}
[UnitOfWork]
public virtual async Task MoveAsync(Guid menuId, Guid menuItemId, Guid? newParentId, int position = 0)
{
var menu = await MenuRepository.GetAsync(menuId, includeDetails: true);
var menuItem = menu.Items.FirstOrDefault(x => x.Id == menuItemId)
?? throw new EntityNotFoundException(typeof(MenuItem), menuItemId);
if (newParentId.HasValue && !menu.Items.Any(a => a.Id == newParentId.Value))
{
throw new EntityNotFoundException(typeof(MenuItem), newParentId);
}
menuItem.ParentId = newParentId;
menuItem.Order = position;
OrganizeTreeOrderForMenuItem(menu, menuItem);
await MenuRepository.UpdateAsync(menu);
}
public virtual void OrganizeTreeOrderForMenuItem(Menu menu, MenuItem menuItem)
{
var sameTree = menu.Items.Where(x => x.ParentId == menuItem.ParentId).OrderBy(x => x.Order).ToList();
sameTree.Remove(menuItem); // Remove if exists to prevent misordering with same order number
sameTree.Insert(menuItem.Order, menuItem);
for (int i = 0; i < sameTree.Count; i++)
{
sameTree[i].Order = i;
}
}
public virtual async Task SetMainMenuAsync(Guid menuId)
{
var menus = await MenuRepository.GetCurrentAndNextMainMenusAsync(menuId ,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);
}
}
}

21
modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/PageChangedHandler.cs

@ -11,12 +11,12 @@ namespace Volo.CmsKit.Menus
public class PageChangedHandler: ILocalEventHandler<EntityUpdatedEventData<Page>>, public class PageChangedHandler: ILocalEventHandler<EntityUpdatedEventData<Page>>,
ITransientDependency ITransientDependency
{ {
protected IMenuRepository MenuRepository { get; } protected IMenuItemRepository MenuRepository { get; }
protected MenuManager MenuManager { get; } protected MenuItemManager MenuManager { get; }
public PageChangedHandler( public PageChangedHandler(
IMenuRepository menuRepository, IMenuItemRepository menuRepository,
MenuManager menuManager) MenuItemManager menuManager)
{ {
MenuRepository = menuRepository; MenuRepository = menuRepository;
MenuManager = menuManager; MenuManager = menuManager;
@ -25,21 +25,18 @@ namespace Volo.CmsKit.Menus
public async Task HandleEventAsync(EntityUpdatedEventData<Page> eventData) public async Task HandleEventAsync(EntityUpdatedEventData<Page> eventData)
{ {
// TODO: Write a repository query. // TODO: Write a repository query.
var allMenus = await MenuRepository.GetListAsync(includeDetails: true); var allMenuItems = await MenuRepository.GetListAsync();
var affectedMenus = allMenus var affectedMenuItems = allMenuItems
.Where(menu => menu.Items.Any(x => x.PageId == eventData.Entity.Id)) .Where(x => x.PageId == eventData.Entity.Id)
.ToArray(); .ToArray();
var affectedMenuItems =
affectedMenus.SelectMany(sm => sm.Items).Where(mItem => mItem.PageId == eventData.Entity.Id);
foreach (var menuItem in affectedMenuItems) foreach (var menuItem in affectedMenuItems)
{ {
MenuManager.SetPageUrl(menuItem, eventData.Entity); MenuManager.SetPageUrl(menuItem, eventData.Entity);
} }
await MenuRepository.UpdateManyAsync(affectedMenus); await MenuRepository.UpdateManyAsync(affectedMenuItems);
} }
} }
} }

1
modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs

@ -27,7 +27,6 @@ namespace Volo.CmsKit.EntityFrameworkCore
public DbSet<BlogPost> BlogPosts { get; set; } public DbSet<BlogPost> BlogPosts { get; set; }
public DbSet<BlogFeature> BlogFeatures { get; set; } public DbSet<BlogFeature> BlogFeatures { get; set; }
public DbSet<MediaDescriptor> MediaDescriptors { get; set; } public DbSet<MediaDescriptor> MediaDescriptors { get; set; }
public DbSet<Menu> Menus { get; set; }
public DbSet<MenuItem> MenuItems { get; set; } public DbSet<MenuItem> MenuItems { get; set; }
public CmsKitDbContext(DbContextOptions<CmsKitDbContext> options) public CmsKitDbContext(DbContextOptions<CmsKitDbContext> options)

10
modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs

@ -258,15 +258,6 @@ namespace Volo.CmsKit.EntityFrameworkCore
if (GlobalFeatureManager.Instance.IsEnabled<MenuFeature>()) if (GlobalFeatureManager.Instance.IsEnabled<MenuFeature>())
{ {
builder.Entity<Menu>(b =>
{
b.ToTable(options.TablePrefix + "Menus", options.Schema);
b.ConfigureByConvention();
b.HasMany(x => x.Items).WithOne().HasForeignKey(fk => fk.MenuId);
});
builder.Entity<MenuItem>(b => builder.Entity<MenuItem>(b =>
{ {
b.ToTable(options.TablePrefix + "MenuItems", options.Schema); b.ToTable(options.TablePrefix + "MenuItems", options.Schema);
@ -280,7 +271,6 @@ namespace Volo.CmsKit.EntityFrameworkCore
} }
else else
{ {
builder.Ignore<Menu>();
builder.Ignore<MenuItem>(); builder.Ignore<MenuItem>();
} }

2
modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/ICmsKitDbContext.cs

@ -4,6 +4,7 @@ using Volo.Abp.EntityFrameworkCore;
using Volo.CmsKit.Blogs; using Volo.CmsKit.Blogs;
using Volo.CmsKit.Comments; using Volo.CmsKit.Comments;
using Volo.CmsKit.MediaDescriptors; using Volo.CmsKit.MediaDescriptors;
using Volo.CmsKit.Menus;
using Volo.CmsKit.Pages; using Volo.CmsKit.Pages;
using Volo.CmsKit.Ratings; using Volo.CmsKit.Ratings;
using Volo.CmsKit.Reactions; using Volo.CmsKit.Reactions;
@ -25,5 +26,6 @@ namespace Volo.CmsKit.EntityFrameworkCore
DbSet<Blog> Blogs { get; } DbSet<Blog> Blogs { get; }
DbSet<BlogPost> BlogPosts { get; } DbSet<BlogPost> BlogPosts { get; }
DbSet<MediaDescriptor> MediaDescriptors { get; } DbSet<MediaDescriptor> MediaDescriptors { get; }
DbSet<MenuItem> MenuItems { get; }
} }
} }

13
modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Menus/EfCoreMenuExtensions.cs

@ -1,13 +0,0 @@
using System.Linq;
using Microsoft.EntityFrameworkCore;
namespace Volo.CmsKit.Menus
{
public static class EfCoreMenuExtensions
{
public static IQueryable<Menu> IncludeDetails(this IQueryable<Menu> source)
{
return source.Include(i => i.Items);
}
}
}

14
modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Menus/EfCoreMenuItemRepository.cs

@ -0,0 +1,14 @@
using System;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
using Volo.CmsKit.EntityFrameworkCore;
namespace Volo.CmsKit.Menus
{
public class EfCoreMenuItemRepository : EfCoreRepository<ICmsKitDbContext, MenuItem, Guid>, IMenuItemRepository
{
public EfCoreMenuItemRepository(IDbContextProvider<ICmsKitDbContext> dbContextProvider) : base(dbContextProvider)
{
}
}
}

40
modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Menus/EfCoreMenuRepository.cs

@ -1,40 +0,0 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
using Volo.CmsKit.EntityFrameworkCore;
namespace Volo.CmsKit.Menus
{
public class EfCoreMenuRepository : EfCoreRepository<ICmsKitDbContext, Menu, Guid>, IMenuRepository
{
public EfCoreMenuRepository(IDbContextProvider<ICmsKitDbContext> dbContextProvider) : base(dbContextProvider)
{
}
public override async Task<IQueryable<Menu>> WithDetailsAsync()
{
return (await base.WithDetailsAsync()).IncludeDetails();
}
public virtual async Task<Menu> FindMainMenuAsync(bool includeDetails = true, CancellationToken cancellationToken = default)
{
return await (includeDetails ? await WithDetailsAsync() : await GetQueryableAsync())
.FirstOrDefaultAsync(x => x.IsMainMenu, GetCancellationToken(cancellationToken));
}
public virtual async Task<List<Menu>> GetCurrentAndNextMainMenusAsync(
Guid nextMainMenuId,
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return await (includeDetails ? await WithDetailsAsync() : await GetQueryableAsync())
.Where(x => x.IsMainMenu || x.Id == nextMainMenuId)
.ToListAsync(GetCancellationToken(cancellationToken));
}
}
}

2
modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs

@ -39,7 +39,7 @@ namespace Volo.CmsKit.MongoDB
public IMongoCollection<MediaDescriptor> MediaDescriptors => Collection<MediaDescriptor>(); public IMongoCollection<MediaDescriptor> MediaDescriptors => Collection<MediaDescriptor>();
public IMongoCollection<Menu> Menus => Collection<Menu>(); public IMongoCollection<MenuItem> Menus => Collection<MenuItem>();
protected override void CreateModel(IMongoModelBuilder modelBuilder) protected override void CreateModel(IMongoModelBuilder modelBuilder)
{ {

6
modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs

@ -4,6 +4,7 @@ using Volo.Abp.MongoDB;
using Volo.CmsKit.Blogs; using Volo.CmsKit.Blogs;
using Volo.CmsKit.Comments; using Volo.CmsKit.Comments;
using Volo.CmsKit.MediaDescriptors; using Volo.CmsKit.MediaDescriptors;
using Volo.CmsKit.Menus;
using Volo.CmsKit.Pages; using Volo.CmsKit.Pages;
using Volo.CmsKit.Ratings; using Volo.CmsKit.Ratings;
using Volo.CmsKit.Reactions; using Volo.CmsKit.Reactions;
@ -80,6 +81,11 @@ namespace Volo.CmsKit.MongoDB
{ {
x.CollectionName = CmsKitDbProperties.DbTablePrefix + "MediaDescriptors"; x.CollectionName = CmsKitDbProperties.DbTablePrefix + "MediaDescriptors";
}); });
builder.Entity<MenuItem>(x =>
{
x.CollectionName = CmsKitDbProperties.DbTablePrefix + "MenuItems";
});
} }
} }
} }

3
modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbModule.cs

@ -5,9 +5,11 @@ using Volo.Abp.Users.MongoDB;
using Volo.CmsKit.Blogs; using Volo.CmsKit.Blogs;
using Volo.CmsKit.Comments; using Volo.CmsKit.Comments;
using Volo.CmsKit.MediaDescriptors; using Volo.CmsKit.MediaDescriptors;
using Volo.CmsKit.Menus;
using Volo.CmsKit.MongoDB.Blogs; using Volo.CmsKit.MongoDB.Blogs;
using Volo.CmsKit.MongoDB.Comments; using Volo.CmsKit.MongoDB.Comments;
using Volo.CmsKit.MongoDB.MediaDescriptors; using Volo.CmsKit.MongoDB.MediaDescriptors;
using Volo.CmsKit.MongoDB.Menus;
using Volo.CmsKit.MongoDB.Pages; using Volo.CmsKit.MongoDB.Pages;
using Volo.CmsKit.MongoDB.Ratings; using Volo.CmsKit.MongoDB.Ratings;
using Volo.CmsKit.MongoDB.Reactions; using Volo.CmsKit.MongoDB.Reactions;
@ -42,6 +44,7 @@ namespace Volo.CmsKit.MongoDB
options.AddRepository<Blog, MongoBlogRepository>(); options.AddRepository<Blog, MongoBlogRepository>();
options.AddRepository<BlogPost, MongoBlogPostRepository>(); options.AddRepository<BlogPost, MongoBlogPostRepository>();
options.AddRepository<MediaDescriptor, MongoMediaDescriptorRepository>(); options.AddRepository<MediaDescriptor, MongoMediaDescriptorRepository>();
options.AddRepository<MenuItem, MongoMenuItemRepository>();
}); });
} }
} }

2
modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs

@ -39,6 +39,6 @@ namespace Volo.CmsKit.MongoDB
IMongoCollection<MediaDescriptor> MediaDescriptors { get; } IMongoCollection<MediaDescriptor> MediaDescriptors { get; }
IMongoCollection<Menu> Menus { get; } IMongoCollection<MenuItem> Menus { get; }
} }
} }

21
modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Menus/MongoMenuItemRepository.cs

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using Volo.Abp.Domain.Repositories.MongoDB;
using Volo.Abp.MongoDB;
using Volo.CmsKit.Menus;
namespace Volo.CmsKit.MongoDB.Menus
{
public class MongoMenuItemRepository : MongoDbRepository<ICmsKitMongoDbContext, MenuItem, Guid>, IMenuItemRepository
{
public MongoMenuItemRepository(IMongoDbContextProvider<ICmsKitMongoDbContext> dbContextProvider) : base(dbContextProvider)
{
}
}
}

35
modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Menus/MongoMenuRepository.cs

@ -1,35 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using Volo.Abp.Domain.Repositories.MongoDB;
using Volo.Abp.MongoDB;
using Volo.CmsKit.Menus;
namespace Volo.CmsKit.MongoDB.Menus
{
public class MongoMenuRepository : MongoDbRepository<ICmsKitMongoDbContext, Menu, Guid>, IMenuRepository
{
public MongoMenuRepository(IMongoDbContextProvider<ICmsKitMongoDbContext> dbContextProvider) : base(dbContextProvider)
{
}
public virtual async Task<Menu> FindMainMenuAsync(bool includeDetails = true, CancellationToken cancellationToken = default)
{
return await (await GetMongoQueryableAsync(GetCancellationToken(cancellationToken)))
.FirstOrDefaultAsync(x => x.IsMainMenu, GetCancellationToken(cancellationToken));
}
public virtual async Task<List<Menu>> GetCurrentAndNextMainMenusAsync(Guid nextMainMenuId, bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return await (await GetMongoQueryableAsync(GetCancellationToken(cancellationToken)))
.Where(x => x.IsMainMenu || x.Id == nextMainMenuId)
.ToListAsync(GetCancellationToken(cancellationToken));
}
}
}

12
modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Menus/IMenuItemPublicAppService.cs

@ -0,0 +1,12 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.CmsKit.Menus;
namespace Volo.CmsKit.Public.Menus
{
public interface IMenuItemPublicAppService : IApplicationService
{
Task<List<MenuItemDto>> GetMenuItemsAsync();
}
}

11
modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Menus/IMenuPublicAppService.cs

@ -1,11 +0,0 @@
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.CmsKit.Menus;
namespace Volo.CmsKit.Public.Menus
{
public interface IMenuPublicAppService : IApplicationService
{
Task<MenuWithDetailsDto> GetMainMenuAsync();
}
}

43
modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Menus/MenuItemPublicAppService.cs

@ -0,0 +1,43 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Caching;
using Volo.Abp.GlobalFeatures;
using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Menus;
namespace Volo.CmsKit.Public.Menus
{
[RequiresGlobalFeature(typeof(MenuFeature))]
public class MenuItemPublicAppService : CmsKitPublicAppServiceBase, IMenuItemPublicAppService
{
protected IMenuItemRepository MenuItemRepository { get; }
protected IDistributedCache<List<MenuItemDto>> DistributedCache { get; }
public MenuItemPublicAppService(
IMenuItemRepository menuRepository,
IDistributedCache<List<MenuItemDto>> distributedCache)
{
MenuItemRepository = menuRepository;
DistributedCache = distributedCache;
}
public async Task<List<MenuItemDto>> GetMenuItemsAsync()
{
var cachedMenu = await DistributedCache.GetOrAddAsync(
MenuApplicationConsts.MainMenuCacheKey,
async () =>
{
var menuItems = await MenuItemRepository.GetListAsync();
if (menuItems == null)
{
return new();
}
return ObjectMapper.Map<List<MenuItem>, List<MenuItemDto>>(menuItems);
});
return cachedMenu;
}
}
}

45
modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Menus/MenuPublicAppService.cs

@ -1,45 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Caching;
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; }
protected IDistributedCache<MenuWithDetailsDto> DistributedCache { get; }
public MenuPublicAppService(
IMenuRepository menuRepository,
IDistributedCache<MenuWithDetailsDto> distributedCache)
{
MenuRepository = menuRepository;
DistributedCache = distributedCache;
}
public async Task<MenuWithDetailsDto> GetMainMenuAsync()
{
var cachedMenu = await DistributedCache.GetOrAddAsync(
MenuApplicationConsts.MainMenuCacheKey,
async () =>
{
var menu = await MenuRepository.FindMainMenuAsync(includeDetails: true);
if (menu == null)
{
return new MenuWithDetailsDto();
}
return ObjectMapper.Map<Menu, MenuWithDetailsDto>(menu);
});
return cachedMenu;
}
}
}

2
modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs

@ -33,8 +33,6 @@ namespace Volo.CmsKit.Public
CreateMap<BlogPost, BlogPostPublicDto>(MemberList.None); CreateMap<BlogPost, BlogPostPublicDto>(MemberList.None);
CreateMap<MenuItem, MenuItemDto>(); CreateMap<MenuItem, MenuItemDto>();
CreateMap<Menu, MenuWithDetailsDto>();
} }
} }
} }

14
modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Menus/MenuPublicController.cs → modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Menus/MenuItemPublicController.cs

@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Volo.Abp; using Volo.Abp;
@ -10,21 +11,20 @@ namespace Volo.CmsKit.Public.Menus
[RequiresGlobalFeature(typeof(BlogsFeature))] [RequiresGlobalFeature(typeof(BlogsFeature))]
[RemoteService(Name = CmsKitPublicRemoteServiceConsts.RemoteServiceName)] [RemoteService(Name = CmsKitPublicRemoteServiceConsts.RemoteServiceName)]
[Area("cms-kit")] [Area("cms-kit")]
[Route("api/cms-kit-public/menus")] [Route("api/cms-kit-public/menus/items")]
public class MenuPublicController : CmsKitPublicControllerBase, IMenuPublicAppService public class MenuItemPublicController : CmsKitPublicControllerBase, IMenuItemPublicAppService
{ {
protected IMenuPublicAppService MenuPublicAppService { get; } protected IMenuItemPublicAppService MenuPublicAppService { get; }
public MenuPublicController(IMenuPublicAppService menuPublicAppService) public MenuItemPublicController(IMenuItemPublicAppService menuPublicAppService)
{ {
MenuPublicAppService = menuPublicAppService; MenuPublicAppService = menuPublicAppService;
} }
[Route("main-menu")]
[HttpGet] [HttpGet]
public Task<MenuWithDetailsDto> GetMainMenuAsync() public Task<List<MenuItemDto>> GetMenuItemsAsync()
{ {
return MenuPublicAppService.GetMainMenuAsync(); return MenuPublicAppService.GetMenuItemsAsync();
} }
} }
} }

10
modules/cms-kit/src/Volo.CmsKit.Public.Web/Menus/CmsKitPublicMenuContributor.cs

@ -24,15 +24,15 @@ namespace Volo.CmsKit.Public.Web.Menus
{ {
if (GlobalFeatureManager.Instance.IsEnabled<MenuFeature>()) if (GlobalFeatureManager.Instance.IsEnabled<MenuFeature>())
{ {
var menuAppService = context.ServiceProvider.GetRequiredService<IMenuPublicAppService>(); var menuAppService = context.ServiceProvider.GetRequiredService<IMenuItemPublicAppService>();
var mainMenu = await menuAppService.GetMainMenuAsync(); var menuItems = await menuAppService.GetMenuItemsAsync();
if (mainMenu != null) if (!menuItems.IsNullOrEmpty())
{ {
foreach (var menuItemDto in mainMenu.Items.Where(x => x.ParentId == null && x.IsActive)) foreach (var menuItemDto in menuItems.Where(x => x.ParentId == null && x.IsActive))
{ {
AddChildItems(menuItemDto, mainMenu.Items, context.Menu); AddChildItems(menuItemDto, menuItems, context.Menu);
} }
} }
} }

8
modules/cms-kit/test/Volo.CmsKit.Application.Tests/Menus/MenuAdminAppService_Tests.cs

@ -13,15 +13,15 @@ namespace Volo.CmsKit.Menus
{ {
public class MenuAdminAppService_Tests : CmsKitApplicationTestBase public class MenuAdminAppService_Tests : CmsKitApplicationTestBase
{ {
protected IMenuAdminAppService MenuAdminAppService { get; } protected IMenuItemAdminAppService MenuAdminAppService { get; }
protected CmsKitTestData TestData { get; } protected CmsKitTestData TestData { get; }
protected IMenuRepository MenuRepository { get; } protected IMenuItemRepository MenuRepository { get; }
public MenuAdminAppService_Tests() public MenuAdminAppService_Tests()
{ {
MenuAdminAppService = GetRequiredService<IMenuAdminAppService>(); MenuAdminAppService = GetRequiredService<IMenuItemAdminAppService>();
TestData = GetRequiredService<CmsKitTestData>(); TestData = GetRequiredService<CmsKitTestData>();
MenuRepository = GetRequiredService<IMenuRepository>(); MenuRepository = GetRequiredService<IMenuItemRepository>();
} }
[Fact] [Fact]

73
modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Menus/MenuManager_Test.cs

@ -1,8 +1,7 @@
using Shouldly;
using System; using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Nito.AsyncEx;
using Shouldly;
using Volo.CmsKit.Pages; using Volo.CmsKit.Pages;
using Xunit; using Xunit;
@ -10,16 +9,16 @@ namespace Volo.CmsKit.Menus
{ {
public class MenuManager_Test : CmsKitDomainTestBase public class MenuManager_Test : CmsKitDomainTestBase
{ {
private readonly MenuManager menuManager; private readonly MenuItemManager menuManager;
private readonly CmsKitTestData testData; private readonly CmsKitTestData testData;
private readonly IMenuRepository menuRepository; private readonly IMenuItemRepository menuItemRepository;
private readonly IPageRepository pageRepository; private readonly IPageRepository pageRepository;
public MenuManager_Test() public MenuManager_Test()
{ {
menuManager = GetRequiredService<MenuManager>(); menuManager = GetRequiredService<MenuItemManager>();
testData = GetRequiredService<CmsKitTestData>(); testData = GetRequiredService<CmsKitTestData>();
menuRepository = GetRequiredService<IMenuRepository>(); menuItemRepository = GetRequiredService<IMenuItemRepository>();
pageRepository = GetRequiredService<IPageRepository>(); pageRepository = GetRequiredService<IPageRepository>();
} }
@ -27,8 +26,8 @@ namespace Volo.CmsKit.Menus
public async Task SetPageUrl_ShouldSetUrlSameWithPage_WithExistingPage() public async Task SetPageUrl_ShouldSetUrlSameWithPage_WithExistingPage()
{ {
var page = await pageRepository.GetAsync(testData.Page_1_Id); var page = await pageRepository.GetAsync(testData.Page_1_Id);
var menu = await menuRepository.GetAsync(testData.Menu_1_Id);
var menuItem = menu.Items.First(); var menuItem = await menuItemRepository.GetAsync(testData.MenuItem_1_Id);
menuManager.SetPageUrl(menuItem, page); menuManager.SetPageUrl(menuItem, page);
@ -39,24 +38,22 @@ namespace Volo.CmsKit.Menus
[Fact] [Fact]
public async Task MoveAsync_ShouldMoveCorrectly_UnderAnotherMenu() public async Task MoveAsync_ShouldMoveCorrectly_UnderAnotherMenu()
{ {
await menuManager.MoveAsync(testData.Menu_1_Id, testData.MenuItem_2_Id, testData.MenuItem_1_Id); await menuManager.MoveAsync(testData.MenuItem_3_Id, testData.MenuItem_1_Id);
var menu = await menuRepository.GetAsync(testData.Menu_1_Id); var menu = await menuItemRepository.GetAsync(testData.MenuItem_3_Id);
menu.Items.ShouldContain( menu.ParentId.ShouldBe(testData.MenuItem_1_Id);
x => x.ParentId == testData.MenuItem_1_Id
&& x.Id == testData.MenuItem_2_Id);
} }
[Fact] [Fact]
public async Task MoveAsync_ShouldChangePositionCorrectly_UnderSameParent() public async Task MoveAsync_ShouldChangePositionCorrectly_UnderRoot()
{ {
await menuManager.MoveAsync(testData.Menu_1_Id, testData.MenuItem_2_Id, null, 0); await menuManager.MoveAsync(testData.MenuItem_2_Id, null, 0);
var menu = await menuRepository.GetAsync(testData.Menu_1_Id); var menuItems = await menuItemRepository.GetListAsync();
var menuItem1 = menu.Items.First(x => x.Id == testData.MenuItem_1_Id); var menuItem1 = menuItems.First(x => x.Id == testData.MenuItem_1_Id);
var menuItem2 = menu.Items.First(x => x.Id == testData.MenuItem_2_Id); var menuItem2 = menuItems.First(x => x.Id == testData.MenuItem_2_Id);
menuItem1.Order.ShouldBeGreaterThan(menuItem2.Order); menuItem1.Order.ShouldBeGreaterThan(menuItem2.Order);
} }
@ -65,45 +62,21 @@ namespace Volo.CmsKit.Menus
public async Task OrganizeTreeOrderForMenuItem_ShouldWorkProperly_WithNewMenuItem() public async Task OrganizeTreeOrderForMenuItem_ShouldWorkProperly_WithNewMenuItem()
{ {
var menu3Id = Guid.NewGuid(); var menu3Id = Guid.NewGuid();
var menu = await menuRepository.GetAsync(testData.Menu_1_Id);
var menuItem1 = menu.Items.First(x => x.Id == testData.MenuItem_1_Id);
var menuItem2 = menu.Items.First(x => x.Id == testData.MenuItem_2_Id);
var menuItem3 = new MenuItem(menu3Id, menu.Id, "Menu 3", "#");
menu.Items.Add(menuItem3); var menuItems = await menuItemRepository.GetListAsync();
var menuItem1 = menuItems.First(x => x.Id == testData.MenuItem_1_Id);
var menuItem2 = menuItems.First(x => x.Id == testData.MenuItem_2_Id);
var menuItem3 = new MenuItem(menu3Id, "Menu 3", "#");
menuItems.Add(menuItem3);
menuItem3.Order = 0; menuItem3.Order = 0;
menuManager.OrganizeTreeOrderForMenuItem(menu, menuItem3); menuManager.OrganizeTreeOrderForMenuItem(menuItems, menuItem3);
menuItem3.Order.ShouldBeLessThan(menuItem1.Order); menuItem3.Order.ShouldBeLessThan(menuItem1.Order);
menuItem3.Order.ShouldBeLessThan(menuItem2.Order); menuItem3.Order.ShouldBeLessThan(menuItem2.Order);
} }
[Fact]
public async Task SetMainMenuAsync_ShouldSetOnlyOneMainMenu()
{
await menuManager.SetMainMenuAsync(testData.Menu_2_Id);
var menuList = await menuRepository.GetListAsync();
var isMainMenuTrueCount = menuList.Count(menu => menu.IsMainMenu);
isMainMenuTrueCount.ShouldBe(1);
menuList.ShouldContain(menu => menu.IsMainMenu && menu.Id == testData.Menu_2_Id);
}
[Fact]
public async Task UnSetMainMenuAsync_ShouldUnsetProperly()
{
await menuManager.UnSetMainMenuAsync(testData.Menu_1_Id);
var menuList = await menuRepository.GetListAsync();
var isMainMenuTrueCount = menuList.Count(menu => menu.IsMainMenu);
isMainMenuTrueCount.ShouldBe(0);
menuList.ShouldNotContain(menu => menu.IsMainMenu && menu.Id == testData.Menu_1_Id);
}
} }
} }

2
modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Menus/MenuRepository_Test.cs

@ -2,7 +2,7 @@ using Volo.CmsKit.Menus;
namespace Volo.CmsKit.EntityFrameworkCore.Menus namespace Volo.CmsKit.EntityFrameworkCore.Menus
{ {
public class MenuRepository_Test : MenuRepository_Test<CmsKitEntityFrameworkCoreTestModule> public class MenuRepository_Test : MenuItemRepository_Test<CmsKitEntityFrameworkCoreTestModule>
{ {
} }

2
modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Menus/MenuRepository_Test.cs

@ -4,7 +4,7 @@ using Volo.CmsKit.Menus;
namespace Volo.CmsKit.MongoDB.Menus namespace Volo.CmsKit.MongoDB.Menus
{ {
[Collection(MongoTestCollection.Name)] [Collection(MongoTestCollection.Name)]
public class MenuRepository_Test : MenuRepository_Test<CmsKitMongoDbTestModule> public class MenuRepository_Test : MenuItemRepository_Test<CmsKitMongoDbTestModule>
{ {
} }

39
modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs

@ -1,5 +1,4 @@
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;
@ -48,7 +47,7 @@ namespace Volo.CmsKit
private readonly IOptions<CmsKitMediaOptions> _mediaOptions; private readonly IOptions<CmsKitMediaOptions> _mediaOptions;
private readonly IOptions<CmsKitCommentOptions> _commentsOptions; private readonly IOptions<CmsKitCommentOptions> _commentsOptions;
private readonly IOptions<CmsKitRatingOptions> _ratingOptions; private readonly IOptions<CmsKitRatingOptions> _ratingOptions;
private readonly IMenuRepository _menuRepository; private readonly IMenuItemRepository _menuItemRepository;
public CmsKitDataSeedContributor( public CmsKitDataSeedContributor(
IGuidGenerator guidGenerator, IGuidGenerator guidGenerator,
@ -75,7 +74,7 @@ namespace Volo.CmsKit
IOptions<CmsKitMediaOptions> cmsMediaOptions, IOptions<CmsKitMediaOptions> cmsMediaOptions,
IOptions<CmsKitCommentOptions> commentsOptions, IOptions<CmsKitCommentOptions> commentsOptions,
IOptions<CmsKitRatingOptions> ratingOptions, IOptions<CmsKitRatingOptions> ratingOptions,
IMenuRepository menuRepository) IMenuItemRepository menuItemRepository)
{ {
_guidGenerator = guidGenerator; _guidGenerator = guidGenerator;
_cmsUserRepository = cmsUserRepository; _cmsUserRepository = cmsUserRepository;
@ -101,7 +100,7 @@ namespace Volo.CmsKit
_mediaOptions = cmsMediaOptions; _mediaOptions = cmsMediaOptions;
_commentsOptions = commentsOptions; _commentsOptions = commentsOptions;
_ratingOptions = ratingOptions; _ratingOptions = ratingOptions;
_menuRepository = menuRepository; _menuItemRepository = menuItemRepository;
} }
public async Task SeedAsync(DataSeedContext context) public async Task SeedAsync(DataSeedContext context)
@ -415,38 +414,22 @@ namespace Volo.CmsKit
private async Task SeedMenusAsync() private async Task SeedMenusAsync()
{ {
var menu = new Menu(_cmsKitTestData.Menu_1_Id, null, _cmsKitTestData.Menu_1_Name); await _menuItemRepository.InsertManyAsync(new[]
menu.IsMainMenu = true; {
menu.Items.Add(
new MenuItem( new MenuItem(
_cmsKitTestData.MenuItem_1_Id, _cmsKitTestData.MenuItem_1_Id,
menu.Id,
_cmsKitTestData.MenuItem_1_Name, _cmsKitTestData.MenuItem_1_Name,
_cmsKitTestData.MenuItem_1_Url)); _cmsKitTestData.MenuItem_1_Url),
menu.Items.Add(
new MenuItem( new MenuItem(
_cmsKitTestData.MenuItem_2_Id, _cmsKitTestData.MenuItem_2_Id,
menu.Id,
_cmsKitTestData.MenuItem_2_Name, _cmsKitTestData.MenuItem_2_Name,
_cmsKitTestData.MenuItem_2_Url)); _cmsKitTestData.MenuItem_2_Url),
await _menuRepository.InsertAsync(menu);
var menu2 = new Menu(
_cmsKitTestData.Menu_2_Id,
null,
_cmsKitTestData.Menu_2_Name);
menu2.Items.Add(
new MenuItem( new MenuItem(
_cmsKitTestData.MenuItem_3_Id, _cmsKitTestData.MenuItem_3_Id,
menu2.Id,
_cmsKitTestData.MenuItem_3_Name, _cmsKitTestData.MenuItem_3_Name,
_cmsKitTestData.MenuItem_3_Url)); _cmsKitTestData.MenuItem_3_Url)
await _menuRepository.InsertAsync(menu2); });
} }
} }
} }

9
modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs

@ -110,10 +110,6 @@ namespace Volo.CmsKit
public string Media_1_ContentType { get; } = "text/plain"; public string Media_1_ContentType { get; } = "text/plain";
public Guid Menu_1_Id { get; } = Guid.NewGuid();
public string Menu_1_Name { get; } = "MainMenu";
public Guid MenuItem_1_Id { get; } = Guid.NewGuid(); public Guid MenuItem_1_Id { get; } = Guid.NewGuid();
public string MenuItem_1_Name { get; } = "About Us"; public string MenuItem_1_Name { get; } = "About Us";
@ -126,11 +122,6 @@ namespace Volo.CmsKit
public string MenuItem_2_Url { get; } = "/team"; public string MenuItem_2_Url { get; } = "/team";
public Guid Menu_2_Id { get; } = Guid.NewGuid();
public string Menu_2_Name { get; } = "DraftMenu";
public Guid MenuItem_3_Id { get; } = Guid.NewGuid(); public Guid MenuItem_3_Id { get; } = Guid.NewGuid();
public string MenuItem_3_Name { get; } = "Products"; public string MenuItem_3_Name { get; } = "Products";

21
modules/cms-kit/test/Volo.CmsKit.TestBase/Menus/MenuItemRepository_Test.cs

@ -0,0 +1,21 @@
using System;
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.Modularity;
namespace Volo.CmsKit.Menus
{
public abstract class MenuItemRepository_Test<TStartupModule> : CmsKitTestBase<TStartupModule>
where TStartupModule : IAbpModule
{
private readonly CmsKitTestData testData;
private readonly IMenuItemRepository menuItemRepository;
public MenuItemRepository_Test()
{
testData = GetRequiredService<CmsKitTestData>();
menuItemRepository = GetRequiredService<IMenuItemRepository>();
}
}
}

51
modules/cms-kit/test/Volo.CmsKit.TestBase/Menus/MenuRepository_Test.cs

@ -1,51 +0,0 @@
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.Modularity;
using Xunit;
namespace Volo.CmsKit.Menus
{
public abstract class MenuRepository_Test<TStartupModule> : CmsKitTestBase<TStartupModule>
where TStartupModule : IAbpModule
{
private readonly CmsKitTestData testData;
private readonly IMenuRepository menuRepository;
public MenuRepository_Test()
{
testData = GetRequiredService<CmsKitTestData>();
menuRepository = GetRequiredService<IMenuRepository>();
}
[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);
}
[Fact]
public async Task GetCurrentAndNextMainMenusAsync_ShouldWorkProperly()
{
var menus = await menuRepository.GetCurrentAndNextMainMenusAsync(
testData.Menu_2_Id);
menus.ShouldNotBeEmpty();
menus.Count.ShouldBe(2);
}
}
}
Loading…
Cancel
Save