Browse Source

Merge pull request #23576 from abpframework/EngincanV/cms-kit-enh

CMS Kit: Fix dynamic menu item sorting
pull/23586/head
oykuermann 1 year ago
committed by GitHub
parent
commit
2f05557a0c
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 48
      modules/cms-kit/host/Volo.CmsKit.Web.Unified/Program.cs
  2. 19
      modules/cms-kit/host/Volo.CmsKit.Web.Unified/Startup.cs
  3. 2
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/IMenuItemAdminAppService.cs
  4. 8
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Menus/MenuItemAdminAppService.cs
  5. 8
      modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Menus/MenuItemAdminClientProxy.Generated.cs
  6. 54
      modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/cms-kit-admin-generate-proxy.json
  7. 9
      modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Menus/MenuItemAdminController.cs
  8. 2
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/GlobalResources/index.js
  9. 2
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/CreateModal.cshtml.cs
  10. 20
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/index.js
  11. 29
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/wwwroot/client-proxies/cms-kit-admin-proxy.js
  12. 6
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/IMenuItemRepository.cs
  13. 22
      modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Menus/EfCoreMenuItemRepository.cs
  14. 22
      modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Menus/MongoMenuItemRepository.cs
  15. 2
      modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Menus/MenuItemPublicAppService.cs
  16. 18
      modules/cms-kit/test/Volo.CmsKit.Application.Tests/Menus/MenuItemAdminAppService_Tests.cs
  17. 17
      modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs
  18. 12
      modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs

48
modules/cms-kit/host/Volo.CmsKit.Web.Unified/Program.cs

@ -1,7 +1,10 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;
using Serilog.Events;
@ -10,7 +13,7 @@ namespace Volo.CmsKit;
public class Program
{
public static int Main(string[] args)
public static async Task Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
@ -23,33 +26,34 @@ public class Program
try
{
Log.Information("Starting web host.");
CreateHostBuilder(args).Build().Run();
return 0;
var builder = WebApplication.CreateBuilder(args);
builder.Host
#if MongoDB
.ConfigureAppConfiguration(options =>
{
options.AddJsonFile("appsettings.MongoDB.json");
})
#endif
.UseAutofac()
.UseSerilog();
await builder.AddApplicationAsync<CmsKitWebUnifiedModule>();
var app = builder.Build();
await app.InitializeApplicationAsync();
await app.RunAsync();
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly!");
return 1;
}
finally
{
Log.CloseAndFlush();
await Log.CloseAndFlushAsync();
}
}
internal static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.AddAppSettingsSecretsJson()
#if MongoDB
.ConfigureAppConfiguration(options =>
{
options.AddJsonFile("appsettings.MongoDB.json");
})
#endif
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseAutofac()
.UseSerilog();
}
}

19
modules/cms-kit/host/Volo.CmsKit.Web.Unified/Startup.cs

@ -1,19 +0,0 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace Volo.CmsKit;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddApplication<CmsKitWebUnifiedModule>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
app.InitializeApplication();
}
}

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

@ -23,4 +23,6 @@ public interface IMenuItemAdminAppService : IApplicationService
Task<PagedResultDto<PageLookupDto>> GetPageLookupAsync(PageLookupInputDto input);
Task<ListResultDto<PermissionLookupDto>> GetPermissionLookupAsync(PermissionLookupInputDto inputDto);
Task<int> GetAvailableMenuOrderAsync(Guid? parentId = null);
}

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

@ -41,7 +41,7 @@ public class MenuItemAdminAppService : CmsKitAdminAppServiceBase, IMenuItemAdmin
public virtual async Task<ListResultDto<MenuItemDto>> GetListAsync()
{
var menuItems = await MenuItemRepository.GetListAsync();
var menuItems = await MenuItemRepository.GetOrderedListAsync();
return new ListResultDto<MenuItemDto>(
ObjectMapper.Map<List<MenuItem>, List<MenuItemDto>>(menuItems)
@ -162,4 +162,10 @@ public class MenuItemAdminAppService : CmsKitAdminAppServiceBase, IMenuItemAdmin
permissionLookupDtos
);
}
public virtual async Task<int> GetAvailableMenuOrderAsync(Guid? parentId = null)
{
var highestOrder = await MenuItemRepository.GetHighestMenuOrderAsync(parentId);
return highestOrder + 1;
}
}

8
modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/Volo/CmsKit/Admin/Menus/MenuItemAdminClientProxy.Generated.cs

@ -80,4 +80,12 @@ public partial class MenuItemAdminClientProxy : ClientProxyBase<IMenuItemAdminAp
{ typeof(PermissionLookupInputDto), inputDto }
});
}
public virtual async Task<int> GetAvailableMenuOrderAsync(Guid? parentId)
{
return await RequestAsync<int>(nameof(GetAvailableMenuOrderAsync), new ClientProxyRequestTypeValue
{
{ typeof(Guid?), parentId }
});
}
}

54
modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/cms-kit-admin-generate-proxy.json

@ -2184,6 +2184,23 @@
"type": "Volo.Abp.Application.Dtos.ListResultDto<Volo.CmsKit.Admin.Menus.PermissionLookupDto>",
"typeSimple": "Volo.Abp.Application.Dtos.ListResultDto<Volo.CmsKit.Admin.Menus.PermissionLookupDto>"
}
},
{
"name": "GetAvailableMenuOrderAsync",
"parametersOnMethod": [
{
"name": "parentId",
"typeAsString": "System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib",
"type": "System.Guid?",
"typeSimple": "string?",
"isOptional": true,
"defaultValue": null
}
],
"returnValue": {
"type": "System.Int32",
"typeSimple": "number"
}
}
]
}
@ -2538,6 +2555,43 @@
},
"allowAnonymous": false,
"implementFrom": "Volo.CmsKit.Admin.Menus.IMenuItemAdminAppService"
},
"GetAvailableMenuOrderAsyncByParentId": {
"uniqueName": "GetAvailableMenuOrderAsyncByParentId",
"name": "GetAvailableMenuOrderAsync",
"httpMethod": "GET",
"url": "api/cms-kit-admin/menu-items/available-order",
"supportedVersions": [],
"parametersOnMethod": [
{
"name": "parentId",
"typeAsString": "System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib",
"type": "System.Guid?",
"typeSimple": "string?",
"isOptional": true,
"defaultValue": null
}
],
"parameters": [
{
"nameOnMethod": "parentId",
"name": "parentId",
"jsonName": null,
"type": "System.Guid?",
"typeSimple": "string?",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": ""
}
],
"returnValue": {
"type": "System.Int32",
"typeSimple": "number"
},
"allowAnonymous": false,
"implementFrom": "Volo.CmsKit.Admin.Menus.IMenuItemAdminAppService"
}
}
},

9
modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Menus/MenuItemAdminController.cs

@ -81,8 +81,15 @@ public class MenuItemAdminController : CmsKitAdminController, IMenuItemAdminAppS
[HttpGet]
[Route("lookup/permissions")]
public Task<ListResultDto<PermissionLookupDto>> GetPermissionLookupAsync(PermissionLookupInputDto inputDto)
public virtual Task<ListResultDto<PermissionLookupDto>> GetPermissionLookupAsync(PermissionLookupInputDto inputDto)
{
return MenuItemAdminAppService.GetPermissionLookupAsync(inputDto);
}
[HttpGet]
[Route("available-order")]
public virtual Task<int> GetAvailableMenuOrderAsync(Guid? parentId = null)
{
return MenuItemAdminAppService.GetAvailableMenuOrderAsync(parentId);
}
}

2
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/GlobalResources/index.js

@ -25,7 +25,7 @@ $(function (){
script: scriptEditor.getValue()
}
).then(function () {
abp.message.success(l("SavedSuccessfully"));
abp.notify.success(l("SavedSuccessfully"));
});
});
});

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

@ -39,6 +39,8 @@ public class CreateModalModel : CmsKitAdminPageModel
public virtual async Task<IActionResult> OnPostAsync()
{
ViewModel.Order = await MenuAdminAppService.GetAvailableMenuOrderAsync(ViewModel.ParentId);
var input = ObjectMapper.Map<MenuItemCreateViewModel, MenuItemCreateInput>(ViewModel);
var dto = await MenuAdminAppService.CreateAsync(input);

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

@ -263,11 +263,21 @@ $(function () {
},
sort: function (node1, node2) {
if (this.get_node(node2).original.order < this.get_node(node1).original.order) {
return 1;
}
return -1;
const node1Data = this.get_node(node1).original;
const node2Data = this.get_node(node2).original;
if (node1Data.parentId === null && node2Data.parentId !== null) {
return -1;
}
if (node1Data.parentId !== null && node2Data.parentId === null) {
return 1;
}
if (node1Data.order < node2Data.order) {
return -1;
}
if (node1Data.order > node2Data.order) {
return 1;
}
return 0;
},
plugins: [

29
modules/cms-kit/src/Volo.CmsKit.Admin.Web/wwwroot/client-proxies/cms-kit-admin-proxy.js

@ -49,6 +49,21 @@
}, ajaxParams));
};
volo.cmsKit.admin.blogs.blogAdmin.getAllList = function(ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/cms-kit-admin/blogs/all',
type: 'GET'
}, ajaxParams));
};
volo.cmsKit.admin.blogs.blogAdmin.moveAllBlogPosts = function(blogId, assignToBlogId, id, ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/cms-kit-admin/blogs/' + id + '/move-all-blog-posts' + abp.utils.buildQueryString([{ name: 'blogId', value: blogId }, { name: 'assignToBlogId', value: assignToBlogId }]) + '',
type: 'PUT',
dataType: null
}, ajaxParams));
};
})();
// controller volo.cmsKit.admin.blogs.blogFeatureAdmin
@ -330,6 +345,20 @@
}, ajaxParams));
};
volo.cmsKit.admin.menus.menuItemAdmin.getPermissionLookup = function(inputDto, ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/cms-kit-admin/menu-items/lookup/permissions' + abp.utils.buildQueryString([{ name: 'filter', value: inputDto.filter }]) + '',
type: 'GET'
}, ajaxParams));
};
volo.cmsKit.admin.menus.menuItemAdmin.getAvailableMenuOrder = function(parentId, ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/cms-kit-admin/menu-items/available-order' + abp.utils.buildQueryString([{ name: 'parentId', value: parentId }]) + '',
type: 'GET'
}, ajaxParams));
};
})();
// controller volo.cmsKit.admin.pages.pageAdmin

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

@ -1,8 +1,14 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace Volo.CmsKit.Menus;
public interface IMenuItemRepository : IBasicRepository<MenuItem, Guid>
{
Task<List<MenuItem>> GetOrderedListAsync(bool includeDetails = false, CancellationToken cancellationToken = default);
Task<int> GetHighestMenuOrderAsync(Guid? parentId = null, CancellationToken cancellationToken = default);
}

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

@ -1,4 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
using Volo.CmsKit.EntityFrameworkCore;
@ -10,4 +15,21 @@ public class EfCoreMenuItemRepository : EfCoreRepository<ICmsKitDbContext, MenuI
public EfCoreMenuItemRepository(IDbContextProvider<ICmsKitDbContext> dbContextProvider) : base(dbContextProvider)
{
}
public virtual async Task<int> GetHighestMenuOrderAsync(Guid? parentId = null, CancellationToken cancellationToken = default)
{
return await (await GetDbSetAsync())
.WhereIf(parentId.HasValue, x => x.ParentId == parentId)
.OrderByDescending(x => x.Order)
.Select(x => x.Order)
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task<List<MenuItem>> GetOrderedListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
{
return await (await GetDbSetAsync())
.OrderBy(x => x.Order)
.ThenBy(x => x.CreationTime)
.ToListAsync(GetCancellationToken(cancellationToken));
}
}

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

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MongoDB.Driver;
@ -17,4 +16,25 @@ public class MongoMenuItemRepository : MongoDbRepository<ICmsKitMongoDbContext,
public MongoMenuItemRepository(IMongoDbContextProvider<ICmsKitMongoDbContext> dbContextProvider) : base(dbContextProvider)
{
}
public virtual async Task<int> GetHighestMenuOrderAsync(Guid? parentId = null, CancellationToken cancellationToken = default)
{
cancellationToken = GetCancellationToken(cancellationToken);
return await (await GetQueryableAsync(cancellationToken))
.WhereIf(parentId.HasValue, x => x.ParentId == parentId)
.OrderByDescending(x => x.Order)
.Select(x => x.Order)
.FirstOrDefaultAsync(cancellationToken);
}
public virtual async Task<List<MenuItem>> GetOrderedListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
{
cancellationToken = GetCancellationToken(cancellationToken);
return await (await GetQueryableAsync(cancellationToken))
.OrderBy(x => x.Order)
.ThenBy(x => x.CreationTime)
.ToListAsync(cancellationToken);
}
}

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

@ -30,7 +30,7 @@ public class MenuItemPublicAppService : CmsKitPublicAppServiceBase, IMenuItemPub
MenuApplicationConsts.MainMenuCacheKey,
async () =>
{
var menuItems = await MenuItemRepository.GetListAsync();
var menuItems = await MenuItemRepository.GetOrderedListAsync();
if (menuItems == null)
{

18
modules/cms-kit/test/Volo.CmsKit.Application.Tests/Menus/MenuItemAdminAppService_Tests.cs

@ -48,7 +48,7 @@ public class MenuItemAdminAppService_Tests : CmsKitApplicationTestBase
result.ShouldNotBeNull();
result.Items.ShouldNotBeEmpty();
result.Items.Count.ShouldBe(4);
result.Items.Count.ShouldBe(6);
}
[Fact]
@ -118,4 +118,20 @@ public class MenuItemAdminAppService_Tests : CmsKitApplicationTestBase
menu.ShouldBeNull();
}
[Fact]
public async Task GetAvailableMenuOrderAsync_ShouldWorkProperly_WithParentId()
{
var order = await MenuAdminAppService.GetAvailableMenuOrderAsync(TestData.MenuItem_1_Id);
order.ShouldBe(2); //has two items with order 0 and 1, so the next available order is 2
}
[Fact]
public async Task GetAvailableMenuOrderAsync_ShouldWorkProperly_WithoutParentId()
{
var order = await MenuAdminAppService.GetAvailableMenuOrderAsync();
order.ShouldBe(TestData.HighestMenuItemOrder + 1);
}
}

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

@ -442,7 +442,8 @@ public class CmsKitDataSeedContributor : IDataSeedContributor, ITransientDepende
new MenuItem(
_cmsKitTestData.MenuItem_1_Id,
_cmsKitTestData.MenuItem_1_Name,
_cmsKitTestData.MenuItem_1_Url),
_cmsKitTestData.MenuItem_1_Url,
order: _cmsKitTestData.HighestMenuItemOrder),
new MenuItem(
_cmsKitTestData.MenuItem_2_Id,
_cmsKitTestData.MenuItem_2_Name,
@ -451,7 +452,19 @@ public class CmsKitDataSeedContributor : IDataSeedContributor, ITransientDepende
_cmsKitTestData.MenuItem_3_Id,
_cmsKitTestData.MenuItem_3_Name,
_cmsKitTestData.MenuItem_3_Url),
menuItem4
menuItem4,
new MenuItem(
_cmsKitTestData.MenuItem_5_Id,
_cmsKitTestData.MenuItem_5_Name,
_cmsKitTestData.MenuItem_5_Url,
order: 0,
parentId: _cmsKitTestData.MenuItem_1_Id),
new MenuItem(
_cmsKitTestData.MenuItem_6_Id,
_cmsKitTestData.MenuItem_6_Name,
_cmsKitTestData.MenuItem_6_Url,
order: 1,
parentId: _cmsKitTestData.MenuItem_1_Id)
});
}

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

@ -132,6 +132,18 @@ public class CmsKitTestData : ISingletonDependency
public string MenuItem_4_With_Page_1_Name { get; } = "Products";
public Guid MenuItem_5_Id { get; } = Guid.NewGuid();
public string MenuItem_5_Name { get; } = "FAQ";
public string MenuItem_5_Url { get; } = "/faq";
public Guid MenuItem_6_Id { get; } = Guid.NewGuid();
public string MenuItem_6_Name { get; } = "Contact Us";
public string MenuItem_6_Url { get; } = "/contact-us";
public int HighestMenuItemOrder { get; } = 2;
public string PollName { get; } = "Poll";
public string WidgetName { get; } = "CmsPollByCode";

Loading…
Cancel
Save