diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenu.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenu.cs
index fce412c22f..a40c67cdf6 100644
--- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenu.cs
+++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenu.cs
@@ -1,5 +1,5 @@
-using System.Collections.Generic;
using JetBrains.Annotations;
+using Volo.Abp.Ui.Navigation;
namespace Volo.Abp.UI.Navigation
{
@@ -29,11 +29,11 @@ namespace Volo.Abp.UI.Navigation
///
[NotNull]
- public IList Items { get; } //TODO: Create a specialized collection (that can contain AddAfter for example)
+ public ApplicationMenuItemList Items { get; }
///
/// Can be used to store a custom object related to this menu.
- /// TODO: Conver to dictionary!
+ /// TODO: Convert to dictionary!
///
[CanBeNull]
public object CustomData { get; set; }
@@ -47,7 +47,7 @@ namespace Volo.Abp.UI.Navigation
Name = name;
DisplayName = displayName ?? Name;
- Items = new List();
+ Items = new ApplicationMenuItemList();
}
///
@@ -60,5 +60,10 @@ namespace Volo.Abp.UI.Navigation
Items.Add(menuItem);
return this;
}
+
+ public override string ToString()
+ {
+ return $"[ApplicationMenu] Name = {Name}";
+ }
}
}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuExtensions.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuExtensions.cs
index 4c24027a1e..e69471e15d 100644
--- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuExtensions.cs
+++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuExtensions.cs
@@ -1,5 +1,5 @@
-using System.Linq;
using JetBrains.Annotations;
+using System.Linq;
using Volo.Abp.Ui.Navigation;
namespace Volo.Abp.UI.Navigation
@@ -7,13 +7,18 @@ namespace Volo.Abp.UI.Navigation
public static class ApplicationMenuExtensions
{
[NotNull]
- public static ApplicationMenuItem GetAdministration(this ApplicationMenu applicationMenu)
+ public static ApplicationMenuItem GetAdministration(
+ [NotNull] this ApplicationMenu applicationMenu)
{
- return applicationMenu.GetMenuItem(DefaultMenuNames.Application.Main.Administration);
+ return applicationMenu.GetMenuItem(
+ DefaultMenuNames.Application.Main.Administration
+ );
}
[NotNull]
- public static ApplicationMenuItem GetMenuItem(this IHasMenuItems menuWithItems, string menuItemName)
+ public static ApplicationMenuItem GetMenuItem(
+ [NotNull] this IHasMenuItems menuWithItems,
+ string menuItemName)
{
var menuItem = menuWithItems.GetMenuItemOrNull(menuItemName);
if (menuItem == null)
@@ -26,10 +31,29 @@ namespace Volo.Abp.UI.Navigation
[CanBeNull]
public static ApplicationMenuItem GetMenuItemOrNull(
- this IHasMenuItems menuWithItems,
+ [NotNull] this IHasMenuItems menuWithItems,
string menuItemName)
{
+ Check.NotNull(menuWithItems, nameof(menuWithItems));
+
return menuWithItems.Items.FirstOrDefault(mi => mi.Name == menuItemName);
}
+
+ [NotNull]
+ public static IHasMenuItems SetSubItemOrder(
+ [NotNull] this IHasMenuItems menuWithItems,
+ string menuItemName,
+ int order)
+ {
+ Check.NotNull(menuWithItems, nameof(menuWithItems));
+
+ var menuItem = menuWithItems.GetMenuItemOrNull(menuItemName);
+ if (menuItem != null)
+ {
+ menuItem.Order = order;
+ }
+
+ return menuWithItems;
+ }
}
}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs
index de19f6db7b..e09c065b00 100644
--- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs
+++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using JetBrains.Annotations;
+using Volo.Abp.Ui.Navigation;
namespace Volo.Abp.UI.Navigation
{
@@ -68,7 +69,7 @@ namespace Volo.Abp.UI.Navigation
///
[NotNull]
- public IList Items { get; }
+ public ApplicationMenuItemList Items { get; }
///
/// Can be used to store a custom object related to this menu item. Optional.
@@ -109,7 +110,7 @@ namespace Volo.Abp.UI.Navigation
ElementId = elementId ?? GetDefaultElementId();
CssClass = cssClass;
- Items = new List();
+ Items = new ApplicationMenuItemList();
}
///
@@ -127,5 +128,10 @@ namespace Volo.Abp.UI.Navigation
{
return "MenuItem_" + Name;
}
+
+ public override string ToString()
+ {
+ return $"[ApplicationMenuItem] Name = {Name}";
+ }
}
}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItemList.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItemList.cs
new file mode 100644
index 0000000000..0e9c845664
--- /dev/null
+++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItemList.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Volo.Abp.UI.Navigation;
+
+namespace Volo.Abp.Ui.Navigation
+{
+ public class ApplicationMenuItemList : List
+ {
+ public ApplicationMenuItemList()
+ {
+
+ }
+
+ public ApplicationMenuItemList(int capacity)
+ : base(capacity)
+ {
+
+ }
+
+ public ApplicationMenuItemList(IEnumerable collection)
+ : base(collection)
+ {
+
+ }
+
+ public void Normalize()
+ {
+ RemoveEmptyItems();
+ Order();
+ }
+
+ private void RemoveEmptyItems()
+ {
+ RemoveAll(item => item.IsLeaf && item.Url.IsNullOrEmpty());
+ }
+
+ private void Order()
+ {
+ //TODO: Is there any way that is more performant?
+ var orderedItems = this.OrderBy(item => item.Order).ToArray();
+ Clear();
+ AddRange(orderedItems);
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/IHasMenuItems.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/IHasMenuItems.cs
index adfa8f2f40..f33ddcd4c2 100644
--- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/IHasMenuItems.cs
+++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/IHasMenuItems.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using Volo.Abp.Ui.Navigation;
namespace Volo.Abp.UI.Navigation
{
@@ -7,6 +7,6 @@ namespace Volo.Abp.UI.Navigation
///
/// Menu items.
///
- IList Items { get; }
+ ApplicationMenuItemList Items { get; }
}
}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs
index ada287ff87..9c96006b02 100644
--- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs
+++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
@@ -38,10 +39,14 @@ namespace Volo.Abp.UI.Navigation
return menu;
}
- protected virtual void NormalizeMenu(ApplicationMenu menu)
+ protected virtual void NormalizeMenu(IHasMenuItems menuWithItems)
{
- //TODO: Should also consider sub menus, recursively, bottom to top!
- menu.Items.RemoveAll(item => item.IsLeaf && item.Url.IsNullOrEmpty());
+ foreach (var menuItem in menuWithItems.Items)
+ {
+ NormalizeMenu(menuItem);
+ }
+
+ menuWithItems.Items.Normalize();
}
}
}
\ No newline at end of file
diff --git a/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs
index 0b2d5db4a0..77203962ae 100644
--- a/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs
+++ b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs
@@ -29,6 +29,9 @@ namespace Volo.Abp.UI.Navigation
mainMenu.Items[1].Items[0].Name.ShouldBe("Administration.UserManagement");
mainMenu.Items[1].Items[1].Name.ShouldBe("Administration.RoleManagement");
mainMenu.Items[1].Items[2].Name.ShouldBe("Administration.DashboardSettings");
+ mainMenu.Items[1].Items[3].Name.ShouldBe("Administration.SubMenu1");
+ mainMenu.Items[1].Items[3].Items[0].Name.ShouldBe("Administration.SubMenu1.1");
+ mainMenu.Items[1].Items[3].Items[1].Name.ShouldBe("Administration.SubMenu1.2");
}
[DependsOn(typeof(AbpUiNavigationModule))]
@@ -89,6 +92,12 @@ namespace Volo.Abp.UI.Navigation
administration.AddItem(new ApplicationMenuItem("Administration.DashboardSettings", "Dashboard Settings", url: "/admin/settings/dashboard"));
+ administration.AddItem(
+ new ApplicationMenuItem("Administration.SubMenu1", "Sub menu 1")
+ .AddItem(new ApplicationMenuItem("Administration.SubMenu1.1", "Sub menu 1.1", url: "/submenu1/submenu1_1"))
+ .AddItem(new ApplicationMenuItem("Administration.SubMenu1.2", "Sub menu 1.2", url: "/submenu1/submenu1_2"))
+ );
+
return Task.CompletedTask;
}
}
diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Navigation/SettingManagementMainMenuContributor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Navigation/SettingManagementMainMenuContributor.cs
index c6ff751d57..1fbd519bfd 100644
--- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Navigation/SettingManagementMainMenuContributor.cs
+++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Navigation/SettingManagementMainMenuContributor.cs
@@ -25,7 +25,16 @@ namespace Volo.Abp.SettingManagement.Web.Navigation
//TODO: Localize
//var l = context.ServiceProvider.GetRequiredService>();
- context.Menu.AddItem(new ApplicationMenuItem(SettingManagementMenuNames.GroupName, "Settings", "/SettingManagement", icon: "fa fa-cog", order: int.MaxValue - 1000));
+ context.Menu
+ .GetAdministration()
+ .AddItem(
+ new ApplicationMenuItem(
+ SettingManagementMenuNames.GroupName,
+ "Settings",
+ "/SettingManagement",
+ icon: "fa fa-cog"
+ )
+ );
return Task.CompletedTask;
}
diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Navigation/SettingManagementMenuNames.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Navigation/SettingManagementMenuNames.cs
index 67678f5b9e..4c5af73abe 100644
--- a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Navigation/SettingManagementMenuNames.cs
+++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Navigation/SettingManagementMenuNames.cs
@@ -1,14 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace Volo.Abp.SettingManagement.Web.Navigation
+namespace Volo.Abp.SettingManagement.Web.Navigation
{
public class SettingManagementMenuNames
{
public const string GroupName = "SettingManagement";
-
- public const string Settings = GroupName + ".Settings";
}
}