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