mirror of https://github.com/abpframework/abp
#75: Added menu manager, tests and a simple renderer.
parent
a39630674f
commit
8042e1f882
@ -0,0 +1,22 @@
|
|||||||
|
@using System.Threading.Tasks
|
||||||
|
@model Volo.Abp.Ui.Navigation.ApplicationMenu
|
||||||
|
<h2>@Model.DisplayName</h2>
|
||||||
|
<ul>
|
||||||
|
@foreach (var menuItem in Model.Items)
|
||||||
|
{
|
||||||
|
<li>
|
||||||
|
<a href="@menuItem.Url">@menuItem.DisplayName</a>
|
||||||
|
@if (menuItem.Items.Any())
|
||||||
|
{
|
||||||
|
<ul>
|
||||||
|
@foreach (var childMenuItem in menuItem.Items)
|
||||||
|
{
|
||||||
|
<li>
|
||||||
|
<a href="@childMenuItem.Url">@childMenuItem.DisplayName</a>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
}
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
@ -0,0 +1,63 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
namespace Volo.Abp.Ui.Navigation
|
||||||
|
{
|
||||||
|
public class ApplicationMenu : IHasMenuItems
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Unique name of the menu in the application.
|
||||||
|
/// </summary>
|
||||||
|
[NotNull]
|
||||||
|
public string Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Display name of the menu.
|
||||||
|
/// Default value is the <see cref="Name"/>.
|
||||||
|
/// </summary>
|
||||||
|
[NotNull]
|
||||||
|
public string DisplayName
|
||||||
|
{
|
||||||
|
get { return _displayName; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Check.NotNullOrWhiteSpace(value, nameof(value));
|
||||||
|
_displayName = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private string _displayName;
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IHasMenuItems.Items"/>
|
||||||
|
[NotNull]
|
||||||
|
public IList<ApplicationMenuItem> Items { get; } //TODO: Create a specialized collection (that can contain AddAfter for example)
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Can be used to store a custom object related to this menu.
|
||||||
|
/// </summary>
|
||||||
|
[CanBeNull]
|
||||||
|
public object CustomData { get; set; }
|
||||||
|
|
||||||
|
public ApplicationMenu(
|
||||||
|
[NotNull] string name,
|
||||||
|
string displayName = null)
|
||||||
|
{
|
||||||
|
Check.NotNullOrWhiteSpace(name, nameof(name));
|
||||||
|
|
||||||
|
Name = name;
|
||||||
|
DisplayName = displayName ?? Name;
|
||||||
|
|
||||||
|
Items = new List<ApplicationMenuItem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a <see cref="ApplicationMenuItem"/> to <see cref="Items"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="menuItem"><see cref="ApplicationMenuItem"/> to be added</param>
|
||||||
|
/// <returns>This <see cref="ApplicationMenu"/> object</returns>
|
||||||
|
public ApplicationMenu AddItem([NotNull] ApplicationMenuItem menuItem)
|
||||||
|
{
|
||||||
|
Items.Add(menuItem);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,108 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Volo.ExtensionMethods.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Volo.Abp.Ui.Navigation
|
||||||
|
{
|
||||||
|
public class ApplicationMenuItem : IHasMenuItems
|
||||||
|
{
|
||||||
|
private string _displayName;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default <see cref="Order"/> value of a menu item.
|
||||||
|
/// </summary>
|
||||||
|
public const int DefaultOrder = 1000;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unique name of the menu in the application.
|
||||||
|
/// </summary>
|
||||||
|
[NotNull]
|
||||||
|
public string Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Display name of the menu item.
|
||||||
|
/// </summary>
|
||||||
|
[NotNull]
|
||||||
|
public string DisplayName
|
||||||
|
{
|
||||||
|
get { return _displayName; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Check.NotNullOrWhiteSpace(value, nameof(value));
|
||||||
|
_displayName = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Display order of the menu.
|
||||||
|
/// Default value: 1000.
|
||||||
|
/// </summary>
|
||||||
|
public int Order { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The URL to navigate when this menu item is selected.
|
||||||
|
/// </summary>
|
||||||
|
[CanBeNull]
|
||||||
|
public string Url { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Icon of the menu item if exists.
|
||||||
|
/// </summary>
|
||||||
|
[CanBeNull]
|
||||||
|
public string Icon { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if this menu item has no child <see cref="Items"/>.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsLeaf => Items.IsNullOrEmpty();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Target of the menu item. Can be null, "_blank", "_self", "_parent", "_top" or a frame name for web applications.
|
||||||
|
/// </summary>
|
||||||
|
[CanBeNull]
|
||||||
|
public string Target { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IHasMenuItems.Items"/>
|
||||||
|
[NotNull]
|
||||||
|
public IList<ApplicationMenuItem> Items { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Can be used to store a custom object related to this menu item. Optional.
|
||||||
|
/// </summary>
|
||||||
|
public object CustomData { get; set; }
|
||||||
|
|
||||||
|
public ApplicationMenuItem(
|
||||||
|
[NotNull] string name,
|
||||||
|
[NotNull] string displayName,
|
||||||
|
string url = null,
|
||||||
|
string icon = null,
|
||||||
|
int order = DefaultOrder,
|
||||||
|
object customData = null,
|
||||||
|
string target = null)
|
||||||
|
{
|
||||||
|
Check.NotNullOrWhiteSpace(name, nameof(name));
|
||||||
|
Check.NotNullOrWhiteSpace(displayName, nameof(displayName));
|
||||||
|
|
||||||
|
Name = name;
|
||||||
|
DisplayName = displayName;
|
||||||
|
Url = url;
|
||||||
|
Icon = icon;
|
||||||
|
Order = order;
|
||||||
|
CustomData = customData;
|
||||||
|
Target = target;
|
||||||
|
|
||||||
|
Items = new List<ApplicationMenuItem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a <see cref="ApplicationMenuItem"/> to <see cref="Items"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="menuItem"><see cref="ApplicationMenuItem"/> to be added</param>
|
||||||
|
/// <returns>This <see cref="ApplicationMenuItem"/> object</returns>
|
||||||
|
public ApplicationMenuItem AddItem([NotNull] ApplicationMenuItem menuItem)
|
||||||
|
{
|
||||||
|
Items.Add(menuItem);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Volo.Abp.Ui.Navigation
|
||||||
|
{
|
||||||
|
public interface IHasMenuItems
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Menu items.
|
||||||
|
/// </summary>
|
||||||
|
IList<ApplicationMenuItem> Items { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
using Volo.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Volo.Abp.Ui.Navigation
|
||||||
|
{
|
||||||
|
public interface IMenuConfigurationContext : IServiceProviderAccessor
|
||||||
|
{
|
||||||
|
ApplicationMenu Menu { get; set; }
|
||||||
|
|
||||||
|
//TODO: Add Localization, Authorization components since they are most used components on menu creation!
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Volo.Abp.Ui.Navigation
|
||||||
|
{
|
||||||
|
public interface IMenuContributor
|
||||||
|
{
|
||||||
|
Task ConfigureMenuAsync(MenuConfigurationContext context);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Volo.Abp.Ui.Navigation
|
||||||
|
{
|
||||||
|
public class MenuConfigurationContext : IMenuConfigurationContext
|
||||||
|
{
|
||||||
|
public ApplicationMenu Menu { get; set; }
|
||||||
|
|
||||||
|
public IServiceProvider ServiceProvider { get; }
|
||||||
|
|
||||||
|
public MenuConfigurationContext(ApplicationMenu menu, IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
Menu = menu;
|
||||||
|
ServiceProvider = serviceProvider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Volo.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Volo.Abp.Ui.Navigation
|
||||||
|
{
|
||||||
|
public class MenuManager : IMenuManager, ITransientDependency
|
||||||
|
{
|
||||||
|
private readonly NavigationOptions _options;
|
||||||
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
|
||||||
|
public MenuManager(
|
||||||
|
IOptions<NavigationOptions> options,
|
||||||
|
IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
_serviceProvider = serviceProvider;
|
||||||
|
_options = options.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ApplicationMenu> GetAsync(string name)
|
||||||
|
{
|
||||||
|
var menu = new ApplicationMenu(name);
|
||||||
|
|
||||||
|
using (var scope = _serviceProvider.CreateScope())
|
||||||
|
{
|
||||||
|
var context = new MenuConfigurationContext(menu, scope.ServiceProvider);
|
||||||
|
|
||||||
|
foreach (var contributor in _options.MenuContributors)
|
||||||
|
{
|
||||||
|
await contributor.ConfigureMenuAsync(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
namespace Volo.Abp.Ui.Navigation
|
||||||
|
{
|
||||||
|
public class NavigationOptions
|
||||||
|
{
|
||||||
|
[NotNull]
|
||||||
|
public List<IMenuContributor> MenuContributors { get; }
|
||||||
|
|
||||||
|
public NavigationOptions()
|
||||||
|
{
|
||||||
|
MenuContributors = new List<IMenuContributor>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
namespace Volo.Abp.Ui.Navigation
|
||||||
|
{
|
||||||
|
public static class StandardMenus
|
||||||
|
{
|
||||||
|
public const string Main = "Main";
|
||||||
|
public const string User = "User";
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in new issue