Browse Source

CmsKit - Implement MenuManagement with jstree

pull/9261/head
enisn 5 years ago
parent
commit
9d841a16fc
  1. 8638
      modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/jstree.js
  2. 6
      modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/jstree.min.js
  3. BIN
      modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/themes/default-dark/32px.png
  4. BIN
      modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/themes/default-dark/40px.png
  5. 1146
      modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/themes/default-dark/style.css
  6. 1
      modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/themes/default-dark/style.min.css
  7. BIN
      modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/themes/default-dark/throbber.gif
  8. BIN
      modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/themes/default/32px.png
  9. BIN
      modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/themes/default/40px.png
  10. 1102
      modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/themes/default/style.css
  11. 1
      modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/themes/default/style.min.css
  12. BIN
      modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/themes/default/throbber.gif
  13. 6
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Menus/IMenuAdminAppService.cs
  14. 10
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Menus/MenuAdminAppService.cs
  15. 27
      modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Menus/MenuAdminController.cs
  16. 30
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/CmsKitAdminWebModule.cs
  17. 8
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenuContributor.cs
  18. 4
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Menus/CmsKitAdminMenus.cs
  19. 4
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/UpdateModal.cshtml.cs
  20. 23
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/CreateModal.cshtml
  21. 44
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/CreateModal.cshtml.cs
  22. 34
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/Index.cshtml
  23. 13
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/Index.cshtml.cs
  24. 23
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/CreateModal.cshtml
  25. 76
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/CreateModal.cshtml.cs
  26. 47
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/Index.cshtml
  27. 15
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/Index.cshtml.cs
  28. 415
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/MenuItems/index.js
  29. 23
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/UpdateModal.cshtml
  30. 53
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/UpdateModal.cshtml.cs
  31. 1
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/createModal.js
  32. 76
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/index.js
  33. 1
      modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Menus/updateModal.js
  34. 9
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json
  35. 10
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json
  36. 2
      modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Menus/MenuConsts.cs
  37. 29
      modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Menus/MenuManager.cs
  38. 3
      npm/packs/cms-kit.admin/package.json

8638
modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/jstree.js

File diff suppressed because it is too large

6
modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/jstree.min.js

File diff suppressed because one or more lines are too long

BIN
modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/themes/default-dark/32px.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/themes/default-dark/40px.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

1146
modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/themes/default-dark/style.css

File diff suppressed because it is too large

1
modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/themes/default-dark/style.min.css

File diff suppressed because one or more lines are too long

BIN
modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/themes/default-dark/throbber.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/themes/default/32px.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/themes/default/40px.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

1102
modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/themes/default/style.css

File diff suppressed because it is too large

1
modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/themes/default/style.min.css

File diff suppressed because one or more lines are too long

BIN
modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/jstree/themes/default/throbber.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

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

@ -1,10 +1,14 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace Volo.CmsKit.Admin.Menus
{
public interface IMenuAdminAppService
public interface IMenuAdminAppService : IApplicationService
{
Task<PagedResultDto<MenuDto>> GetListAsync(PagedAndSortedResultRequestDto input);
Task<MenuWithDetailsDto> GetAsync(Guid id);
Task<MenuDto> CreateAsync(MenuCreateInput input);

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

@ -33,6 +33,16 @@ namespace Volo.CmsKit.Admin.Menus
PageRepository = pageRepository;
}
public async Task<PagedResultDto<MenuDto>> GetListAsync(PagedAndSortedResultRequestDto input)
{
var menus = await MenuRepository.GetPagedListAsync(input.SkipCount, input.MaxResultCount, input.Sorting);
return new PagedResultDto<MenuDto>(
await MenuRepository.GetCountAsync(),
ObjectMapper.Map<List<Menu>, List<MenuDto>>(menus)
);
}
public async Task<MenuWithDetailsDto> GetAsync(Guid id)
{
var menu = await MenuRepository.GetAsync(id, includeDetails: true);

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

@ -6,6 +6,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.GlobalFeatures;
using Volo.CmsKit.GlobalFeatures;
using Volo.CmsKit.Permissions;
@ -25,48 +26,68 @@ namespace Volo.CmsKit.Admin.Menus
{
MenuAdminAppService = menuAdminAppService;
}
[HttpPost]
[Authorize(CmsKitAdminPermissions.Menus.Create)]
public Task<MenuDto> CreateAsync(MenuCreateInput input)
{
return MenuAdminAppService.CreateAsync(input);
}
[Route("{menuId}/menu-items")]
[HttpPost]
[Authorize(CmsKitAdminPermissions.Menus.MenuItems.Create)]
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);
}
[Route("{menuId}/menu-items/{menuItemId}")]
[HttpDelete]
[Authorize(CmsKitAdminPermissions.Menus.MenuItems.Delete)]
public Task DeleteMenuItemAsync(Guid menuId, Guid menuItemId)
{
return MenuAdminAppService.DeleteMenuItemAsync(menuId, menuItemId);
}
public Task<MenuWithDetailsDto> GetAsync(Guid id)
[Route("{menuId}")]
[HttpGet]
public Task<MenuWithDetailsDto> GetAsync(Guid menuId)
{
return MenuAdminAppService.GetAsync(menuId);
}
[HttpGet]
public Task<PagedResultDto<MenuDto>> GetListAsync(PagedAndSortedResultRequestDto input)
{
return MenuAdminAppService.GetAsync(id);
return MenuAdminAppService.GetListAsync(input);
}
[Route("{menuId}/menu-items/{menuItemId}/move")]
[HttpPut]
[Authorize(CmsKitAdminPermissions.Menus.MenuItems.Update)]
public Task MoveMenuItemAsync(Guid menuId, Guid menuItemId, MenuItemMoveInput input)
{
return MenuAdminAppService.MoveMenuItemAsync(menuId, menuItemId, input);
}
[Route("{menuId}")]
[HttpPut]
[Authorize(CmsKitAdminPermissions.Menus.Update)]
public Task<MenuDto> UpdateAsync(Guid menuId, MenuUpdateInput input)
{
return MenuAdminAppService.UpdateAsync(menuId, input);
}
[Route("{menuId}/menu-items/{menuItemId}")]
[HttpPut]
[Authorize(CmsKitAdminPermissions.Menus.MenuItems.Update)]
public Task<MenuItemDto> UpdateMenuItemAsync(Guid menuId, Guid menuItemId, MenuItemUpdateInput input)
{

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

@ -69,6 +69,10 @@ namespace Volo.CmsKit.Admin.Web
options.Conventions.AuthorizeFolder("/CmsKit/BlogPosts/Update", CmsKitAdminPermissions.BlogPosts.Update);
options.Conventions.AuthorizeFolder("/CmsKit/Comments/", CmsKitAdminPermissions.Comments.Default);
options.Conventions.AuthorizeFolder("/CmsKit/Comments/Details", CmsKitAdminPermissions.Comments.Default);
options.Conventions.AuthorizeFolder("/CmsKit/Menus", CmsKitAdminPermissions.Menus.Default);
options.Conventions.AuthorizePage("/CmsKit/Menus/CreateModal", CmsKitAdminPermissions.Menus.Create);
options.Conventions.AuthorizePage("/CmsKit/Menus/UpdateModal", CmsKitAdminPermissions.Menus.Update);
options.Conventions.AuthorizeFolder("/CmsKit/Menus/MenuItems", CmsKitAdminPermissions.Menus.MenuItems.Default);
});
Configure<RazorPagesOptions>(options =>
@ -83,6 +87,8 @@ namespace Volo.CmsKit.Admin.Web
options.Conventions.AddPageRoute("/CmsKit/BlogPosts/Update", "/Cms/BlogPosts/Update/{Id}");
options.Conventions.AddPageRoute("/CmsKit/Comments/Index", "/Cms/Comments");
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/{Id}/menu-items");
});
Configure<AbpPageToolbarOptions>(options =>
@ -134,6 +140,30 @@ namespace Volo.CmsKit.Admin.Web
requiredPolicyName: CmsKitAdminPermissions.BlogPosts.Create
);
});
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>(
toolbar =>
{
toolbar.AddButton(
LocalizableString.Create<CmsKitResource>("NewMenuItem"),
icon: "plus",
name: "CreateMenuItem",
id: "CreateMenuItem",
requiredPolicyName: CmsKitAdminPermissions.Menus.MenuItems.Create
);
});
});
}
}

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

@ -71,6 +71,14 @@ namespace Volo.CmsKit.Admin.Web.Menus
.RequireGlobalFeatures(typeof(CommentsFeature))
.RequirePermissions(CmsKitAdminPermissions.Comments.Default));
cmsMenus.Add(new ApplicationMenuItem(
CmsKitAdminMenus.Menus.MenusMenu,
l["Menus"],
"/Cms/Menus",
"fa fa-bars")
.RequireGlobalFeatures(typeof(MenuFeature))
.RequirePermissions(CmsKitAdminPermissions.Menus.Default));
if (cmsMenus.Any())
{
var cmsMenu = context.Menu.FindMenuItem(CmsKitAdminMenus.GroupName);

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

@ -29,5 +29,9 @@
public const string BlogPostsMenu = GroupName + ".BlogPosts";
}
public static class Menus
{
public const string MenusMenu = GroupName + ".Menus";
}
}
}

4
modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/UpdateModal.cshtml.cs

@ -1,11 +1,7 @@
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Validation;
using Volo.CmsKit.Admin.Blogs;

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

@ -0,0 +1,23 @@
@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

@ -0,0 +1,44 @@
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

@ -0,0 +1,34 @@
@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["Blogs"].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

@ -0,0 +1,13 @@
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
{
}
}

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

@ -0,0 +1,23 @@
@page
@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems
@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/MenuItems/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>

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

@ -0,0 +1,76 @@
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.CmsKit.Admin.Menus;
namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems
{
public class CreateModalModel : CmsKitAdminPageModel
{
protected IMenuAdminAppService MenuAdminAppService { get; }
[BindProperty]
public MenuItemCreateViewModel ViewModel { get; set; }
public CreateModalModel(IMenuAdminAppService menuAdminAppService)
{
MenuAdminAppService = menuAdminAppService;
ViewModel = new MenuItemCreateViewModel();
}
public virtual Task OnGetAsync(Guid menuId, Guid? parentId)
{
ViewModel.MenuId = menuId;
ViewModel.ParentId = parentId;
return Task.CompletedTask;
}
public virtual async Task<IActionResult> OnPostAsync()
{
var input = ObjectMapper.Map<MenuItemCreateViewModel, MenuItemCreateInput>(ViewModel);
var dto = await MenuAdminAppService.CreateMenuItemAsync(ViewModel.MenuId, input);
return new OkObjectResult(dto);
}
[AutoMap(typeof(MenuItemCreateInput), ReverseMap = true)]
public class MenuItemCreateViewModel
{
[HiddenInput]
public Guid MenuId { get; set; }
[HiddenInput]
public Guid? ParentId { get; set; }
[Required]
public string DisplayName { get; set; }
public bool IsActive { get; set; }
[Required]
public string Url { get; set; }
public Guid? PageId { get; set; }
public string Icon { get; set; }
public int Order { get; set; }
public string Target { get; set; }
public string ElementId { get; set; }
public string CssClass { get; set; }
public string RequiredPermissionName { get; set; }
}
}
}

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

@ -0,0 +1,47 @@
@page
@using Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems
@using Volo.CmsKit.Admin.Web.Pages
@using Volo.CmsKit.Admin.Web.Menus
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageToolbar
@using Volo.Abp.AspNetCore.Mvc.UI.Packages.JsTree
@inherits CmsKitAdminPageBase
@model IndexModel
@{
PageLayout.Content.Title = L["Blogs"].Value;
PageLayout.Content.BreadCrumb.Add(L["Menu:CMS"].Value);
PageLayout.Content.BreadCrumb.Add(L["Menu:Menus"].Value, "/Cms/Menus");
PageLayout.Content.MenuItemName = CmsKitAdminMenus.Menus.MenusMenu;
}
@section styles {
<abp-style-bundle name="@typeof(IndexModel).FullName">
<abp-style type="typeof(JsTreeStyleContributor)" />
</abp-style-bundle>
}
@section scripts {
<abp-script-bundle name="@typeof(IndexModel).FullName">
<abp-style type="typeof(JsTreeScriptContributor)" />
<abp-script src="/Pages/CmsKit/Menus/MenuItems/index.js" />
</abp-script-bundle>
}
@section content_toolbar {
@await Component.InvokeAsync(typeof(AbpPageToolbarViewComponent), new { pageName = typeof(IndexModel).FullName })
}
<div id="CmsKitMenuItemsWrapper" data-menu-id="@Model.Id">
<abp-card>
<abp-card-body>
<abp-card-title>
@L["MenuItems"]
</abp-card-title>
<div id="MenuItemsEditTree"></div>
<div id="MenuItemsTreeEmptyInfo" class="text-muted">@L["NoMenuItems"]</div>
</abp-card-body>
</abp-card>
</div>

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

@ -0,0 +1,15 @@
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Volo.CmsKit.Admin.Web.Pages.CmsKit.Menus.MenuItems
{
public class IndexModel : CmsKitAdminPageModel
{
[BindProperty(SupportsGet = true)]
public Guid Id { get; set; }
}
}

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

@ -0,0 +1,415 @@
var _menuItem = {};
$(function () {
var l = abp.localization.getResource("CmsKit");
var menuId = $('#CmsKitMenuItemsWrapper').data('menu-id');
var menuService = volo.cmsKit.admin.menus.menuAdmin;
var createModal = new abp.ModalManager(abp.appPath + 'CmsKit/Menus/MenuItems/CreateModal');
var updateModal = new abp.ModalManager(abp.appPath + 'CmsKit/Menus/MenuItems/UpdateModal');
var menuTree = {
$tree: $('#MenuItemsEditTree'),
$emptyInfo: $('#MenuItemsTreeEmptyInfo'),
show: function () {
menuTree.$emptyInfo.hide();
menuTree.$tree.show();
},
hide: function () {
menuTree.$emptyInfo.show();
menuTree.$tree.hide();
},
itemCount: 0,
setItemCount: function (itemCount) {
menuTree.itemCount = itemCount;
if (itemCount) {
menuTree.show();
} else {
menuTree.hide();
}
},
refreshItemCount: function () {
menuTree.setItemCount(menuTree.$tree.jstree('get_json').length);
},
selectedMenuItem: {
id: null,
displayName: null,
code: null,
set: function (menuItemOnTree) {
if (!menuItemOnTree) {
menuTree.selectedMenuItem.id = null;
menuTree.selectedMenuItem.displayName = null;
menuTree.selectedMenuItem.IsActive = true;
menuTree.selectedMenuItem.Url = null;
menuTree.selectedMenuItem.Icon = null;
menuTree.selectedMenuItem.Order = 1;
menuTree.selectedMenuItem.Target = null;
menuTree.selectedMenuItem.ElementId = null;
menuTree.selectedMenuItem.CssClass = null;
menuTree.selectedMenuItem.RequiredPermissionName = null;
menuTree.selectedMenuItem.PageId = null;
} else {
menuTree.selectedMenuItem.id = menuItemOnTree.id;
menuTree.selectedMenuItem.displayName = menuItemOnTree.original.displayName;
menuTree.selectedMenuItem.IsActive = menuItemOnTree.original.IsActive;
menuTree.selectedMenuItem.Url = menuItemOnTree.original.Url;
menuTree.selectedMenuItem.Icon = menuItemOnTree.original.Icon;
menuTree.selectedMenuItem.Order = menuItemOnTree.original.Order;
menuTree.selectedMenuItem.Target = menuItemOnTree.original.Target;
menuTree.selectedMenuItem.ElementId = menuItemOnTree.original.ElementId;
menuTree.selectedMenuItem.CssClass = menuItemOnTree.original.CssClass;
menuTree.selectedMenuItem.RequiredPermissionName = menuItemOnTree.original.RequiredPermissionName;
menuTree.selectedMenuItem.PageId = menuItemOnTree.original.PageId;
}
_menuItem.checkbox.setSelectedItem({
id: menuTree.selectedMenuItem.id,
displayName: menuTree.selectedMenuItem.displayName,
isActive: menuTree.selectedMenuItem.IsActive,
url: menuTree.selectedMenuItem.Url,
icon: menuTree.selectedMenuItem.Icon,
order: menuTree.selectedMenuItem.Order,
target: menuTree.selectedMenuItem.Target,
elementId: menuTree.selectedMenuItem.ElementId,
cssClass: menuTree.selectedMenuItem.CssClass,
requiredPermissionName: menuTree.selectedMenuItem.RequiredPermissionName,
pageId: menuTree.selectedMenuItem.PageId
});
}
},
contextMenu: function (node) {
var items = {
edit: {
label: l('Edit'),
icon: 'fa fa-pencil',
_disabled: abp.auth.isGranted('CmsKit.Menus.Items.Update'),
action: function (data) {
var instance = $.jstree.reference(data.reference);
updateModal.open({
id: node.id,
menuId: menuId
})
}
},
addSubMenuItem: {
label: l('AddSubMenuItem'),
icon: 'fa fa-plus',
_disabled: abp.auth.isGranted('CmsKit.Menus.Items.Create'),
action: function () {
menuTree.addItem(node.id);
}
},
'delete': {
label: l('Delete'),
icon: 'fa fa-remove',
_disabled: abp.auth.isGranted('CmsKit.Menus.Items.Delete'),
action: function (data) {
var instance = $.jstree.reference(data.reference);
abp.message.confirm(
l('MenuItemDeletionConfirmationMessage', node.original.displayName),
l('AreYouSure'),
function (isConfirmed) {
if (isConfirmed) {
menuService
.deleteMenuItem(menuId, node.id)
.done(function () {
instance.delete_node(node);
menuTree.refreshItemCount();
})
.fail(function (err) {
setTimeout(function () {
abp.message.error(err.message);
}, 500);
});
}
}
)
}
}
}
return items;
},
addItem: function (parentId) {
var instance = $.jstree.reference(menuTree.$tree);
createModal.open({
menuId: menuId,
parentId: parentId,
}, function (newMenuItem) {
instance.create_node(
parentId ? instance.get_node(parentId) : '#',
{
id: newMenuItem.id,
parent: newMenuItem.parentId ? newMenuItem.parentId : '#',
isActive: newMenuItem.isActive,
displayName: $.fn.dataTable.render.text().display(newMenuItem.displayName),
text: menuTree.generateTextOnTree(newMenuItem),
url: newMenuItem.url,
icon: newMenuItem.icon,
order: newMenuItem.order,
target: newMenuItem.target,
elementId: newMenuItem.elementId,
cssClass: newMenuItem.cssClass,
requiredPermissionName: newMenuItem.requiredPermissionName,
pageId: newMenuItem.pageId,
state: {
opened: true
}
});
menuTree.refreshItemCount();
});
},
generateTextOnTree: function (item) {
var itemClass = ' ou-text-no-members';
return '<span title="' + item.displayName + '" class="ou-text text-dark' + itemClass + '" data-menuitem-id="' + item.id + '">' +
$.fn.dataTable.render.text().display(item.displayName) +
' <i class="fa fa-caret-down text-muted"></i></span > ';
},
getTreeDataFromServer: function (callback) {
menuService.get(menuId).done(function (result) {
var treeData = _.map(result.items, function (item) {
return {
id: item.id,
parent: item.parentId ? item.parentId : '#',
isActive: item.isActive,
displayName: $.fn.dataTable.render.text().display(item.displayName),
url: item.url,
icon: item.icon,
order: item.order,
target: item.target,
elementId: item.elementId,
cssClass: item.cssClass,
requiredPermissionName: item.requiredPermissionName,
pageId: item.pageId,
text: menuTree.generateTextOnTree(item),
state: {
opened: true
}
};
});
callback(treeData);
});
},
init: function () {
menuTree.getTreeDataFromServer(function (treeData) {
menuTree.setItemCount(treeData.length);
menuTree.$tree
.on('changed.jstree', function (e, data) {
if (data.selected.length != 1) {
menuTree.selectedMenuItem.set(null);
} else {
var selectedNode = data.instance.get_node(data.selected[0]);
menuTree.selectedMenuItem.set(selectedNode);
}
})
.on('move_node.jstree', function (e, data) {
var parentNodeName = (!data.parent || data.parent == '#')
? l('Root')
: menuTree.$tree.jstree('get_node', data.parent).original.displayName;
abp.message.confirm(
l('MenuItemMoveConfirmMessage', data.node.original.displayName, parentNodeName),
l('AreYouSure'),
function (isConfirmed) {
if (isConfirmed) {
menuService
.moveMenuItem(menuId, data.node.id, {
newParentId: data.parent === '#' ? null : data.parent
})
.done(function () {
menuTree.reload();
})
.fail(function (err) {
menuTree.$tree.jstree('refresh'); //rollback
setTimeout(function () {
abp.message.error(err.message);
}, 500);
});
} else {
menuTree.$tree.jstree('refresh'); //rollback
}
}
);
})
.jstree({
'core': {
data: treeData,
multiple: false,
check_callback: function (operation, node, node_parent, node_position, more) {
return true;
},
contextmenu: {
items: menuTree.contextMenu,
'select_node': false
},
//sort: function (node1, node2) {
// if (this.get_node(node2).original.displayName < this.get_node(node1).original.displayName) {
// return 1;
// }
// return -1;
//},
plugins: [
'types',
'contextmenu',
'wholerow',
'sort',
'dnd'
]
}
});
$('button[name=CreateMenuItem]').click(function (e) {
e.preventDefault();
createModal.open({ menuId: menuId });
});
createModal.onResult(function () {
menuTree.reload();
});
updateModal.onResult(function (item) {
menuTree.reload();
});
//menuTree.$tree.on('click', '.ou-text .fa-caret-down', function (e) {
// e.preventDefault();
// debugger;
// var id = $(this).closest('.ou-text').attr('data-menuitem-id');
// setTimeout(function () {
// debugger;
// menuTree.$tree.jstree('show_contextmenu', id);
// }, 100);
//});
});
},
reload: function () {
menuTree.getTreeDataFromServer(function (treeData) {
menuTree.setItemCount(treeData.length);
menuTree.$tree.jstree(true).settings.core.data = treeData;
menuTree.$tree.jstree('refresh');
});
}
};
menuTree.init();
let selectedIds = [];
let selectedItem = {};
let selectedCheckboxNames;
let selectAllHeaderTitle = '<div class="custom-checkbox custom-control no-height">' +
'<input type="checkbox" id="select_all" name="select-all" class="custom-control-input custom-selectbox" value="false" data-val="false">' +
'<label class="custom-control-label" for="select_all"></label></div>';
_menuItem.checkbox = {
initialize: function (selectedCbNames) {
selectedIds = [];
selectedCheckboxNames = selectedCbNames;
},
getSelectedIds: function () {
return selectedIds;
},
setSelectedItem: function (item) {
selectedItem = item;
},
getSelectedItem: function () {
return selectedItem;
},
getSelectAllHeaderTitle: function () {
return selectAllHeaderTitle;
}
};
$(document).on('click', '.custom-selectbox', function (el) {
el.stopPropagation();
if (!$(el.target).is(':checkbox')) {
return;
}
if ($(el.target).prop("checked") == true) {
checkAndAddAll();
} else if ($(el.target).prop("checked") == false) {
uncheckAndRemoveAll();
}
});
$(document).on('click', '.selectable', function (el) {
el.stopPropagation();
selectDeselect(el);
});
const checkAndAddAll = function () {
$('table>tbody>').find('input[type="checkbox"]').prop("checked", true);
let selectedItems = $(`input[name="${selectedCheckboxNames}"]:checked`);
selectedIds = [];
for (var i = 0; typeof (selectedItems[i]) != 'undefined'; selectedIds.push(selectedItems[i++].getAttribute('id')));
};
const uncheckAndRemoveAll = function () {
$('table>tbody>').find('input[type="checkbox"]').prop("checked", false);
selectedIds = [];
};
const addId = function (id) {
selectedIds.push(id);
};
const removeId = function (id) {
selectedIds = selectedIds.filter(function (e) {
return e !== id;
});
};
const selectDeselect = function (el) {
$el = $(el);
if ($(el.target).is(':checkbox')) {
el.preventDefault();
return;
}
if (!$(el.target).is(':checkbox')) {
$el = $(el.target).parent().closest('tr').find('[type=checkbox]');
if ($el.prop("checked") == true) {
$el.prop("checked", false);
} else if ($el.prop("checked") == false) {
$el.prop("checked", true);
}
}
if ($el.prop("checked") == true) {
addId($el.attr('id'));
} else if ($el.prop("checked") == false) {
removeId($el.attr('id'));
}
}
});

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

@ -0,0 +1,23 @@
@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

@ -0,0 +1,53 @@
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

@ -0,0 +1 @@


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

@ -0,0 +1,76 @@
$(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.Items'),
action: function (data) {
location.href = "/Cms/Menus/" + data.record.id + "/menu-items"
}
},
{
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"
}
]
}));
$('#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

@ -0,0 +1 @@


9
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json

@ -1,6 +1,8 @@
{
"culture": "en",
"texts": {
"AddSubMenuItem": "Add sub menu item",
"AreYouSure": "Are You Sure?",
"BlogDeletionConfirmationMessage": "The blog '{0}' will be deleted. Are you sure?",
"BlogFeatureNotAvailable": "This feature is not available now. Enable with 'GlobalFeatureManager' to use it.",
"BlogId": "Blog",
@ -51,12 +53,19 @@
"LoginToReact": "Login to react",
"LoginToReply": "Login to reply",
"Menu:CMS": "CMS",
"Menu:Menus": "Menus",
"MenuDeletionConfirmationMessage": "The menu '{0}' will be deleted. Are you sure?",
"MenuItemDeletionConfirmationMessage": "Are sure to delete this menu item?",
"MenuItemMoveConfirmMessage": "Are you sure you want to move '{0}' under '{1}'?",
"MenuItems": "Menu Items",
"Message": "Message",
"MessageDeletionConfirmationMessage": "This comment will be deleted completely.",
"NewBlog": "New Blog",
"NewBlogPost": "New Blog Post",
"NewMenu": "New Menu",
"NewPage": "New Page",
"NewTag": "New Tag",
"NoMenuItems": "There is no menu item yet!",
"OK": "OK",
"PageDeletionConfirmationMessage": "Are you sure to delete this page?",
"Pages": "Pages",

10
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json

@ -1,6 +1,8 @@
{
"culture": "tr",
"texts": {
"AddSubMenuItem": "Alt menü elemanı ekle",
"AreYouSure": "Emin Misiniz?",
"BlogDeletionConfirmationMessage": "'{0}' adlı blog silinecek. Emin misiniz?",
"BlogFeatureNotAvailable": "Bu özellik kullanılabilir değil. 'GlobalFeatureManager' ile aktif ederek kullanabilisiniz.",
"BlogId": "Blog",
@ -50,13 +52,21 @@
"LoginToReact": "Reaksiyon vermek için giriş yap",
"LoginToReply": "Cevap vermek için giriş yap",
"Menu:CMS": "CMS",
"Menu:Menus": "Menüler",
"MenuDeletionConfirmationMessage": "'{0}' isimli menü silinecek. Emin misiniz?",
"MenuItemDeletionConfirmationMessage": "Bu menü elemanını silmek istediğinize emin misiniz?",
"MenuItems": "Menü Elemanları",
"Message": "Mesaj",
"MenuItemMoveConfirmMessage": "'{0}' ögesini '{1}' ögesinin altına taşımak istediğinize emin misiniz?",
"MessageDeletionConfirmationMessage": "Bu yorum tamamen silinecektir",
"Name": "Ad",
"NewBlog": "Yeni Blog",
"NewBlogPost": "Yeni Blog Yazısı",
"NewMenu": "Yeni Menü",
"NewPage": "Yeni Sayfa",
"NewTag": "Yeni Etiket",
"NoMenuItems": "Herhangi bir menü elemanı bulunmuyor.",
"OK": "Tamam",
"PageDeletionConfirmationMessage": "Bu sayfayı silmek istediğinize emin misiniz?",
"PageSlugInformation": "Etiket URL'de kullanılır. Url şöyle görünür: '/pages/{{slug}}'.",

2
modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Menus/MenuConsts.cs

@ -8,6 +8,6 @@ namespace Volo.CmsKit.Menus
{
public static class MenuConsts
{
public const int MaxNameLength = 128;
public static int MaxNameLength { get; set; } = 128;
}
}

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

@ -3,23 +3,44 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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 : DomainService
public class MenuManager : CmsKitDomainServiceBase
{
protected IMenuRepository MenuRepository { get; }
public MenuManager(IMenuRepository menuRepository)
{
MenuRepository = menuRepository;
}
public virtual void SetPageUrl(MenuItem menuItem, Page page)
{
menuItem.SetPageId(page.Id);
menuItem.SetUrl(page.Slug.EnsureStartsWith('/'));
}
public virtual Task MoveAsync(Guid menuId, Guid menuItemId, Guid newParentId)
[UnitOfWork]
public virtual async Task MoveAsync(Guid menuId, Guid menuItemId, Guid newParentId)
{
// TODO: Implement move method
throw new NotImplementedException();
var menu = await MenuRepository.GetAsync(menuId, includeDetails: true);
var menuItem = menu.Items.FirstOrDefault(x => x.Id == menuItemId)
?? throw new EntityNotFoundException(typeof(MenuItem), menuItemId);
if (!menu.Items.Any(a => a.Id == newParentId))
{
throw new EntityNotFoundException(typeof(MenuItem), newParentId);
}
menuItem.ParentId = newParentId;
await MenuRepository.UpdateAsync(menu);
}
}
}

3
npm/packs/cms-kit.admin/package.json

@ -7,7 +7,8 @@
"dependencies": {
"@abp/slugify": "~4.3.2",
"@abp/tui-editor": "~4.3.2",
"@abp/uppy": "~4.3.2"
"@abp/uppy": "~4.3.2",
"@abp/jstree": "~4.3.2"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"
}

Loading…
Cancel
Save