Browse Source

Define groups for menu items

pull/15908/head
liangshiwei 3 years ago
parent
commit
2899ecac8c
  1. 19
      framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenu.cs
  2. 50
      framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuExtensions.cs
  3. 67
      framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuGroup.cs
  4. 36
      framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuGroupList.cs
  5. 7
      framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs
  6. 9
      framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/IHasMenuGroups.cs
  7. 18
      framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs
  8. 1
      framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/AbpUiNavigationTestModule.cs
  9. 46
      framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs

19
framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenu.cs

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using Volo.Abp.Data;
@ -5,7 +6,7 @@ using Volo.Abp.UI.Navigation;
namespace Volo.Abp.UI.Navigation;
public class ApplicationMenu : IHasMenuItems
public class ApplicationMenu : IHasMenuItems, IHasMenuGroups
{
/// <summary>
/// Unique name of the menu in the application.
@ -31,6 +32,10 @@ public class ApplicationMenu : IHasMenuItems
[NotNull]
public ApplicationMenuItemList Items { get; }
/// <inheritdoc cref="IHasMenuGroups.Groups"/>
[NotNull]
public ApplicationMenuGroupList Groups { get; }
/// <summary>
/// Can be used to store a custom object related to this menu.
/// </summary>
@ -47,6 +52,7 @@ public class ApplicationMenu : IHasMenuItems
DisplayName = displayName ?? Name;
Items = new ApplicationMenuItemList();
Groups = new ApplicationMenuGroupList();
}
/// <summary>
@ -60,6 +66,17 @@ public class ApplicationMenu : IHasMenuItems
return this;
}
/// <summary>
/// Adds a <see cref="ApplicationMenuGroup"/> to <see cref="Groups"/>.
/// </summary>
/// <param name="group"><see cref="ApplicationMenuGroup"/> to be added</param>
/// <returns>This <see cref="ApplicationMenu"/> object</returns>
public ApplicationMenu AddGroup([NotNull] ApplicationMenuGroup group)
{
Groups.Add(group);
return this;
}
/// <summary>
/// Adds a custom data item to <see cref="CustomData"/> with given key &amp; value.
/// </summary>

50
framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuExtensions.cs

@ -64,4 +64,54 @@ public static class ApplicationMenuExtensions
return menuWithItems;
}
[NotNull]
public static ApplicationMenuGroup GetMenuGroup(
[NotNull] this IHasMenuGroups menuWithGroups,
string groupName)
{
var menuGroup = menuWithGroups.GetMenuGroupOrNull(groupName);
if (menuGroup == null)
{
throw new AbpException($"Could not find a group item with given name: {groupName}");
}
return menuGroup;
}
[CanBeNull]
public static ApplicationMenuGroup GetMenuGroupOrNull(
[NotNull] this IHasMenuGroups menuWithGroups,
string menuGroupName)
{
Check.NotNull(menuWithGroups, nameof(menuWithGroups));
return menuWithGroups.Groups.FirstOrDefault(group => group.Name == menuGroupName);
}
public static bool TryRemoveMenuGroup(
[NotNull] this IHasMenuGroups menuWithGroups,
string menuGroupName)
{
Check.NotNull(menuWithGroups, nameof(menuWithGroups));
return menuWithGroups.Groups.RemoveAll(group => group.Name == menuGroupName) > 0;
}
[NotNull]
public static IHasMenuGroups SetMenuGroupOrder(
[NotNull] this IHasMenuGroups menuWithGroups,
string menuGroupName,
int order)
{
Check.NotNull(menuWithGroups, nameof(menuWithGroups));
var menuGroup = menuWithGroups.GetMenuGroupOrNull(menuGroupName);
if (menuGroup != null)
{
menuGroup.Order = order;
}
return menuWithGroups;
}
}

67
framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuGroup.cs

@ -0,0 +1,67 @@
using JetBrains.Annotations;
namespace Volo.Abp.UI.Navigation;
public class ApplicationMenuGroup
{
private string _displayName;
/// <summary>
/// Default <see cref="Order"/> value of a group item.
/// </summary>
public const int DefaultOrder = 1000;
/// <summary>
/// Unique name of the group in the application.
/// </summary>
[NotNull]
public string Name { get; }
/// <summary>
/// Display name of the group.
/// </summary>
[NotNull]
public string DisplayName {
get { return _displayName; }
set {
Check.NotNullOrWhiteSpace(value, nameof(value));
_displayName = value;
}
}
/// <summary>
/// Can be used to render the element with a specific Id for DOM selections.
/// </summary>
public string ElementId { get; set; }
/// <summary>
/// The Display order of the group.
/// Default value: 1000.
/// </summary>
public int Order { get; set; }
public ApplicationMenuGroup(
[NotNull] string name,
[NotNull] string displayName,
string elementId = null,
int order = DefaultOrder)
{
Check.NotNullOrWhiteSpace(name, nameof(name));
Check.NotNullOrWhiteSpace(displayName, nameof(displayName));
Name = name;
DisplayName = displayName;
ElementId = elementId;
Order = order;
}
private string GetDefaultElementId()
{
return "MenuGroup_" + Name;
}
public override string ToString()
{
return $"[ApplicationMenuGroup] Name = {Name}";
}
}

36
framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuGroupList.cs

@ -0,0 +1,36 @@
using System.Collections.Generic;
using System.Linq;
namespace Volo.Abp.UI.Navigation;
public class ApplicationMenuGroupList: List<ApplicationMenuGroup>
{
public ApplicationMenuGroupList()
{
}
public ApplicationMenuGroupList(int capacity)
: base(capacity)
{
}
public ApplicationMenuGroupList(IEnumerable<ApplicationMenuGroup> collection)
: base(collection)
{
}
public void Normalize()
{
Order();
}
private void Order()
{
var orderedItems = this.OrderBy(item => item.Order).ToArray();
Clear();
AddRange(orderedItems);
}
}

7
framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs

@ -92,6 +92,11 @@ public class ApplicationMenuItem : IHasMenuItems, IHasSimpleStateCheckers<Applic
/// </summary>
public string CssClass { get; set; }
/// <summary>
/// Can be used to group menu items.
/// </summary>
public string GroupName { get; set; }
public ApplicationMenuItem(
[NotNull] string name,
[NotNull] string displayName,
@ -101,6 +106,7 @@ public class ApplicationMenuItem : IHasMenuItems, IHasSimpleStateCheckers<Applic
string target = null,
string elementId = null,
string cssClass = null,
string groupName = null,
string requiredPermissionName = null)
{
Check.NotNullOrWhiteSpace(name, nameof(name));
@ -114,6 +120,7 @@ public class ApplicationMenuItem : IHasMenuItems, IHasSimpleStateCheckers<Applic
Target = target;
ElementId = elementId ?? GetDefaultElementId();
CssClass = cssClass;
GroupName = groupName;
RequiredPermissionName = requiredPermissionName;
StateCheckers = new List<ISimpleStateChecker<ApplicationMenuItem>>();
Items = new ApplicationMenuItemList();

9
framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/IHasMenuGroups.cs

@ -0,0 +1,9 @@
namespace Volo.Abp.UI.Navigation;
public interface IHasMenuGroups
{
/// <summary>
/// Menu groups.
/// </summary>
ApplicationMenuGroupList Groups { get; }
}

18
framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs

@ -96,6 +96,7 @@ public class MenuManager : IMenuManager, ITransientDependency
}
NormalizeMenu(menu);
NormalizeMenuGroup(menu);
return menu;
}
@ -159,4 +160,21 @@ public class MenuManager : IMenuManager, ITransientDependency
menuWithItems.Items.Normalize();
}
protected virtual void NormalizeMenuGroup(ApplicationMenu applicationMenu)
{
foreach (var menuGroup in applicationMenu.Items.Where(x => !x.GroupName.IsNullOrWhiteSpace()).GroupBy(x => x.GroupName))
{
var group = applicationMenu.GetMenuGroupOrNull(menuGroup.First().GroupName);
if (group != null)
{
continue;
}
foreach (var menuItem in menuGroup)
{
menuItem.GroupName = null;
}
}
}
}

1
framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/AbpUiNavigationTestModule.cs

@ -16,6 +16,7 @@ public class AbpUiNavigationTestModule : AbpModule
options.MenuContributors.Add(new MenuManager_Tests.TestMenuContributor1());
options.MenuContributors.Add(new MenuManager_Tests.TestMenuContributor2());
options.MenuContributors.Add(new MenuManager_Tests.TestMenuContributor3());
options.MenuContributors.Add(new MenuManager_Tests.TestMenuContributor4());
options.MainMenuNames.Add(MenuManager_Tests.TestMenuContributor3.MenuName);
});

46
framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs

@ -46,7 +46,7 @@ public class MenuManager_Tests : AbpIntegratedTest<AbpUiNavigationTestModule>
mainMenu.Name.ShouldBe(StandardMenus.Main);
mainMenu.DisplayName.ShouldBe("Main Menu");
mainMenu.Items.Count.ShouldBe(2);
mainMenu.Items.Count.ShouldBe(5);
mainMenu.Items[0].Name.ShouldBe("Dashboard");
mainMenu.Items[1].Name.ShouldBe(DefaultMenuNames.Application.Main.Administration);
mainMenu.Items[1].Items[0].Name.ShouldBe("Administration.UserManagement");
@ -63,12 +63,29 @@ public class MenuManager_Tests : AbpIntegratedTest<AbpUiNavigationTestModule>
mainMenu.Name.ShouldBe(StandardMenus.Main);
mainMenu.Items.Count.ShouldBe(3);
mainMenu.Items.Count.ShouldBe(6);
mainMenu.Items.ShouldContain(x => x.Name == "Products");
mainMenu.Items.ShouldContain(x => x.Name == "Dashboard");
}
[Fact]
public async Task GetMainMenuAsync_GroupMenuItems()
{
var mainMenu = await _menuManager.GetMainMenuAsync();
mainMenu.Name.ShouldBe(StandardMenus.Main);
mainMenu.Items.Count.ShouldBe(6);
mainMenu.Items[2].GroupName.ShouldBe("Layouts");
mainMenu.Items[3].GroupName.ShouldBe("Layouts");
mainMenu.Items[4].GroupName.ShouldBe(null); // No group defined
var layoutsGroup = mainMenu.GetMenuGroup("Layouts");
layoutsGroup.Name.ShouldBe("Layouts");
layoutsGroup.DisplayName.ShouldBe("Layouts");
}
/* Adds menu items:
* - Administration
* - User Management
@ -149,4 +166,29 @@ public class MenuManager_Tests : AbpIntegratedTest<AbpUiNavigationTestModule>
return Task.CompletedTask;
}
}
/* Adds group and menu items:
* - Layouts
* - Toolbars
* - Page Header
*/
public class TestMenuContributor4 : IMenuContributor
{
public Task ConfigureMenuAsync(MenuConfigurationContext context)
{
if (context.Menu.Name != StandardMenus.Main)
{
return Task.CompletedTask;
}
context.Menu.AddGroup(new ApplicationMenuGroup("Layouts", "Layouts"));
context.Menu.AddItem(new ApplicationMenuItem("Toolbars", "Toolbars", url: "/layouts/toolbars", groupName: "Layouts"));
context.Menu.AddItem(new ApplicationMenuItem("PageHeader", "Page Header", url: "/layouts/page-header", groupName: "Layouts"));
context.Menu.AddItem(new ApplicationMenuItem("Branding", "Branding", url: "/layouts/branding", groupName: "NotDefinedGroup"));
return Task.CompletedTask;
}
}
}

Loading…
Cancel
Save