181 lines
6.9 KiB
C#
181 lines
6.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Umbraco.Core;
|
|
using umbraco.BusinessLogic.Actions;
|
|
using umbraco.interfaces;
|
|
|
|
namespace Umbraco.Web.Models.Trees
|
|
{
|
|
/// <summary>
|
|
/// A custom menu list
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// NOTE: We need a sub collection to the MenuItemCollection object due to how json serialization works.
|
|
/// </remarks>
|
|
public class MenuItemList : List<MenuItem>
|
|
{
|
|
public MenuItemList()
|
|
{
|
|
}
|
|
|
|
public MenuItemList(IEnumerable<MenuItem> items)
|
|
: base(items)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a menu item
|
|
/// </summary>
|
|
/// <param name="action"></param>
|
|
/// <param name="name">The text to display for the menu item, will default to the IAction alias if not specified</param>
|
|
internal MenuItem Add(IAction action, string name)
|
|
{
|
|
var item = new MenuItem(action);
|
|
|
|
DetectLegacyActionMenu(action.GetType(), item);
|
|
|
|
Add(item);
|
|
return item;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a menu item
|
|
/// </summary>
|
|
/// <typeparam name="TMenuItem"></typeparam>
|
|
/// <typeparam name="TAction"></typeparam>
|
|
/// <param name="hasSeparator"></param>
|
|
/// <param name="name">The text to display for the menu item, will default to the IAction alias if not specified</param>
|
|
/// <param name="additionalData"></param>
|
|
/// <returns></returns>
|
|
public TMenuItem Add<TMenuItem, TAction>(string name, bool hasSeparator = false, IDictionary<string, object> additionalData = null)
|
|
where TAction : IAction
|
|
where TMenuItem : MenuItem, new()
|
|
{
|
|
var item = CreateMenuItem<TAction>(name, hasSeparator, additionalData);
|
|
if (item == null) return null;
|
|
|
|
var customMenuItem = new TMenuItem
|
|
{
|
|
Name = item.Alias,
|
|
Alias = item.Alias,
|
|
SeperatorBefore = hasSeparator,
|
|
Icon = item.Icon,
|
|
Action = item.Action
|
|
};
|
|
|
|
Add(customMenuItem);
|
|
|
|
return customMenuItem;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a menu item
|
|
/// </summary>
|
|
/// <param name="name">The text to display for the menu item, will default to the IAction alias if not specified</param>
|
|
/// <typeparam name="T"></typeparam>
|
|
public MenuItem Add<T>(string name)
|
|
where T : IAction
|
|
{
|
|
return Add<T>(name, false, null);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a menu item with a key value pair which is merged to the AdditionalData bag
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="key"></param>
|
|
/// <param name="value"></param>
|
|
/// <param name="name">The text to display for the menu item, will default to the IAction alias if not specified</param>
|
|
/// <param name="hasSeparator"></param>
|
|
public MenuItem Add<T>(string name, string key, string value, bool hasSeparator = false)
|
|
where T : IAction
|
|
{
|
|
return Add<T>(name, hasSeparator, new Dictionary<string, object> { { key, value } });
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a menu item with a dictionary which is merged to the AdditionalData bag
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="hasSeparator"></param>
|
|
/// /// <param name="name">The text to display for the menu item, will default to the IAction alias if not specified</param>
|
|
/// <param name="additionalData"></param>
|
|
public MenuItem Add<T>(string name, bool hasSeparator = false, IDictionary<string, object> additionalData = null)
|
|
where T : IAction
|
|
{
|
|
var item = CreateMenuItem<T>(name, hasSeparator, additionalData);
|
|
if (item != null)
|
|
{
|
|
Add(item);
|
|
return item;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="hasSeparator"></param>
|
|
/// <param name="name">The text to display for the menu item, will default to the IAction alias if not specified</param>
|
|
/// <param name="additionalData"></param>
|
|
/// <returns></returns>
|
|
internal MenuItem CreateMenuItem<T>(string name, bool hasSeparator = false, IDictionary<string, object> additionalData = null)
|
|
where T : IAction
|
|
{
|
|
var item = ActionsResolver.Current.GetAction<T>();
|
|
if (item != null)
|
|
{
|
|
var menuItem = new MenuItem(item, name)
|
|
{
|
|
SeperatorBefore = hasSeparator
|
|
};
|
|
|
|
if (additionalData != null)
|
|
{
|
|
foreach (var i in additionalData)
|
|
{
|
|
menuItem.AdditionalData[i.Key] = i.Value;
|
|
}
|
|
}
|
|
|
|
DetectLegacyActionMenu(typeof(T), menuItem);
|
|
|
|
//TODO: Once we implement 'real' menu items, not just IActions we can implement this since
|
|
// people may need to pass specific data to their menu items
|
|
|
|
////validate the data in the meta data bag
|
|
//item.ValidateRequiredData(AdditionalData);
|
|
|
|
return menuItem;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks if the IAction type passed in is attributed with LegacyActionMenuItemAttribute and if so
|
|
/// ensures that the correct action metadata is added.
|
|
/// </summary>
|
|
/// <param name="actionType"></param>
|
|
/// <param name="menuItem"></param>
|
|
private void DetectLegacyActionMenu(Type actionType, MenuItem menuItem)
|
|
{
|
|
//This checks for legacy IActions that have the LegacyActionMenuItemAttribute which is a legacy hack
|
|
// to make old IAction actions work in v7 by mapping to the JS used by the new menu items
|
|
var attribute = actionType.GetCustomAttribute<LegacyActionMenuItemAttribute>(false);
|
|
if (attribute != null)
|
|
{
|
|
//add the current type to the metadata
|
|
if (attribute.MethodName.IsNullOrWhiteSpace())
|
|
{
|
|
//if no method name is supplied we will assume that the menu action is the type name of the current menu class
|
|
menuItem.AdditionalData.Add("jsAction", string.Format("{0}.{1}", attribute.ServiceName, this.GetType().Name));
|
|
}
|
|
else
|
|
{
|
|
menuItem.AdditionalData.Add("jsAction", string.Format("{0}.{1}", attribute.ServiceName, attribute.MethodName));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |