Merge remote-tracking branch 'origin/temp8' into temp8-3130-examine-indexing-variant-switching
# Conflicts: # src/Umbraco.Tests/Services/ContentServiceTests.cs
This commit is contained in:
@@ -1,35 +0,0 @@
|
||||
using System;
|
||||
using Umbraco.Core.Exceptions;
|
||||
|
||||
namespace Umbraco.Core.CodeAnnotations
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
internal class ActionMetadataAttribute : Attribute
|
||||
{
|
||||
public string Category { get; }
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor used to assign a Category, since no name is assigned it will try to be translated from the language files based on the action's alias
|
||||
/// </summary>
|
||||
/// <param name="category"></param>
|
||||
public ActionMetadataAttribute(string category)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(category)) throw new ArgumentNullOrEmptyException(nameof(category));
|
||||
Category = category;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor used to assign an explicit name and category
|
||||
/// </summary>
|
||||
/// <param name="category"></param>
|
||||
/// <param name="name"></param>
|
||||
public ActionMetadataAttribute(string category, string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(category)) throw new ArgumentNullOrEmptyException(nameof(category));
|
||||
if (string.IsNullOrWhiteSpace(name)) throw new ArgumentNullOrEmptyException(nameof(name));
|
||||
Category = category;
|
||||
Name = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,26 +44,6 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string DateTime = "Umbraco.DateTime";
|
||||
|
||||
/// <summary>
|
||||
/// DropDown List.
|
||||
/// </summary>
|
||||
public const string DropDownList = "Umbraco.DropDown";
|
||||
|
||||
/// <summary>
|
||||
/// DropDown List, Publish Keys.
|
||||
/// </summary>
|
||||
public const string DropdownlistPublishKeys = "Umbraco.DropdownlistPublishingKeys";
|
||||
|
||||
/// <summary>
|
||||
/// DropDown List Multiple.
|
||||
/// </summary>
|
||||
public const string DropDownListMultiple = "Umbraco.DropDownMultiple";
|
||||
|
||||
/// <summary>
|
||||
/// DropDown List Multiple, Publish Keys.
|
||||
/// </summary>
|
||||
public const string DropdownlistMultiplePublishKeys = "Umbraco.DropdownlistMultiplePublishKeys";
|
||||
|
||||
/// <summary>
|
||||
/// DropDown List.
|
||||
/// </summary>
|
||||
|
||||
@@ -117,7 +117,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DropDownMultiple, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DropDownMultiple}", SortOrder = 2, UniqueId = new Guid("0b6a45e7-44ba-430d-9da5-4e46060b9e03"), Text = "Dropdown", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -41, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-41", SortOrder = 2, UniqueId = new Guid("5046194e-4237-453c-a547-15db3a07c4e1"), Text = "Date Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -40, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-40", SortOrder = 2, UniqueId = new Guid("bb5f57c9-ce2b-4bb9-b697-4caca783a805"), Text = "Radiobox", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -39, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-39", SortOrder = 2, UniqueId = new Guid("f38f0ac7-1d27-439c-9f3f-089cd8825a53"), Text = "Dropdown multiple", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DropDownSingle, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DropDownSingle}", SortOrder = 2, UniqueId = new Guid("f38f0ac7-1d27-439c-9f3f-089cd8825a53"), Text = "Dropdown multiple", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -37, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-37", SortOrder = 2, UniqueId = new Guid("0225af17-b302-49cb-9176-b9f35cab9c17"), Text = "Approved Color", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -36, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-36", SortOrder = 2, UniqueId = new Guid("e4d66c0f-b935-4200-81f0-025f7256b89a"), Text = "Date Picker with time", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultContentListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultContentListView}", SortOrder = 2, UniqueId = new Guid("C0808DD3-8133-4E4B-8CE8-E2BEA84A96A4"), Text = Constants.Conventions.DataTypes.ListViewPrefix + "Content", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
|
||||
@@ -139,6 +139,8 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
Chain<DropTaskTables>("{6A2C7C1B-A9DB-4EA9-B6AB-78E7D5B722A7}");
|
||||
Chain<FixLockTablePrimaryKey>("{77874C77-93E5-4488-A404-A630907CEEF0}");
|
||||
Chain<AddLogTableColumns>("{8804D8E8-FE62-4E3A-B8A2-C047C2118C38}");
|
||||
Chain<DropPreValueTable>("{23275462-446E-44C7-8C2C-3B8C1127B07D}");
|
||||
Chain<DropDownPropertyEditorsMigration>("{6B251841-3069-4AD5-8AE9-861F9523E8DA}");
|
||||
|
||||
//FINAL
|
||||
|
||||
|
||||
@@ -7,10 +7,11 @@ using NPoco;
|
||||
using Umbraco.Core.Migrations.Install;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
{
|
||||
|
||||
public class DataTypeMigration : MigrationBase
|
||||
{
|
||||
public DataTypeMigration(IMigrationContext context)
|
||||
@@ -79,10 +80,6 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
|
||||
Database.Update(dataType);
|
||||
}
|
||||
|
||||
// drop preValues table
|
||||
// FIXME keep it around for now
|
||||
//Delete.Table("cmsDataTypePreValues");
|
||||
}
|
||||
|
||||
[TableName("cmsDataTypePreValues")]
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
{
|
||||
public class DropDownPropertyEditorsMigration : MigrationBase
|
||||
{
|
||||
public DropDownPropertyEditorsMigration(IMigrationContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
//need to convert the old drop down data types to use the new one
|
||||
var oldDropDowns = Database.Fetch<DataTypeDto>(Sql()
|
||||
.Select<DataTypeDto>()
|
||||
.From<DataTypeDto>()
|
||||
.Where<DataTypeDto>(x => x.EditorAlias.Contains(".DropDown")));
|
||||
foreach (var dd in oldDropDowns)
|
||||
{
|
||||
//nothing to change if there is no config
|
||||
if (dd.Configuration.IsNullOrWhiteSpace()) continue;
|
||||
|
||||
ValueListConfiguration config;
|
||||
try
|
||||
{
|
||||
config = JsonConvert.DeserializeObject<ValueListConfiguration>(dd.Configuration);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error<DropDownPropertyEditorsMigration>(
|
||||
ex, "Invalid drop down configuration detected: \"{Configuration}\", cannot convert editor, values will be cleared",
|
||||
dd.Configuration);
|
||||
dd.Configuration = null;
|
||||
Database.Update(dd);
|
||||
continue;
|
||||
}
|
||||
|
||||
var propDataSql = Sql().Select<PropertyDataDto>().From<PropertyDataDto>()
|
||||
.InnerJoin<PropertyTypeDto>().On<PropertyTypeDto, PropertyDataDto>(x => x.Id, x => x.PropertyTypeId)
|
||||
.InnerJoin<DataTypeDto>().On<DataTypeDto, PropertyTypeDto>(x => x.NodeId, x => x.DataTypeId)
|
||||
.Where<PropertyTypeDto>(x => x.DataTypeId == dd.NodeId);
|
||||
|
||||
var propDatas = Database.Query<PropertyDataDto>(propDataSql);
|
||||
var toUpdate = new List<PropertyDataDto>();
|
||||
foreach (var propData in propDatas)
|
||||
{
|
||||
if (UpdatePropertyDataDto(propData, config))
|
||||
{
|
||||
//update later, we are iterating all values right now so no SQL can be run inside of this iteration (i.e. Query<T>)
|
||||
toUpdate.Add(propData);
|
||||
}
|
||||
}
|
||||
|
||||
//run the property data updates
|
||||
foreach (var propData in toUpdate)
|
||||
{
|
||||
Database.Update(propData);
|
||||
}
|
||||
|
||||
var requiresCacheRebuild = false;
|
||||
switch (dd.EditorAlias)
|
||||
{
|
||||
case string ea when ea.InvariantEquals("Umbraco.DropDown"):
|
||||
UpdateDataType(dd, config, false);
|
||||
break;
|
||||
case string ea when ea.InvariantEquals("Umbraco.DropdownlistPublishingKeys"):
|
||||
UpdateDataType(dd, config, false);
|
||||
requiresCacheRebuild = true;
|
||||
break;
|
||||
case string ea when ea.InvariantEquals("Umbraco.DropDownMultiple"):
|
||||
UpdateDataType(dd, config, true);
|
||||
break;
|
||||
case string ea when ea.InvariantEquals("Umbraco.DropdownlistMultiplePublishKeys"):
|
||||
UpdateDataType(dd, config, true);
|
||||
requiresCacheRebuild = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (requiresCacheRebuild)
|
||||
{
|
||||
//TODO: How to force rebuild the cache?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateDataType(DataTypeDto dataType, ValueListConfiguration config, bool isMultiple)
|
||||
{
|
||||
dataType.EditorAlias = Constants.PropertyEditors.Aliases.DropDownListFlexible;
|
||||
var flexConfig = new
|
||||
{
|
||||
multiple = isMultiple,
|
||||
items = config.Items
|
||||
};
|
||||
dataType.DbType = ValueStorageType.Nvarchar.ToString();
|
||||
dataType.Configuration = JsonConvert.SerializeObject(flexConfig);
|
||||
Database.Update(dataType);
|
||||
}
|
||||
|
||||
private bool UpdatePropertyDataDto(PropertyDataDto propData, ValueListConfiguration config)
|
||||
{
|
||||
//Get the INT ids stored for this property/drop down
|
||||
int[] ids = null;
|
||||
if (!propData.VarcharValue.IsNullOrWhiteSpace())
|
||||
{
|
||||
ids = ConvertStringValues(propData.VarcharValue);
|
||||
}
|
||||
else if (!propData.TextValue.IsNullOrWhiteSpace())
|
||||
{
|
||||
ids = ConvertStringValues(propData.TextValue);
|
||||
}
|
||||
else if (propData.IntegerValue.HasValue)
|
||||
{
|
||||
ids = new[] { propData.IntegerValue.Value };
|
||||
}
|
||||
|
||||
//if there are INT ids, convert them to values based on the configured pre-values
|
||||
if (ids != null && ids.Length > 0)
|
||||
{
|
||||
//map the ids to values
|
||||
var vals = new List<string>();
|
||||
var canConvert = true;
|
||||
foreach (var id in ids)
|
||||
{
|
||||
var val = config.Items.FirstOrDefault(x => x.Id == id);
|
||||
if (val != null)
|
||||
vals.Add(val.Value);
|
||||
else
|
||||
{
|
||||
Logger.Warn<DropDownPropertyEditorsMigration>(
|
||||
"Could not find associated data type configuration for stored Id {DataTypeId}", id);
|
||||
canConvert = false;
|
||||
}
|
||||
}
|
||||
if (canConvert)
|
||||
{
|
||||
propData.VarcharValue = string.Join(",", vals);
|
||||
propData.TextValue = null;
|
||||
propData.IntegerValue = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private int[] ConvertStringValues(string val)
|
||||
{
|
||||
var splitVals = val.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
var intVals = splitVals
|
||||
.Select(x => int.TryParse(x, out var i) ? i : int.MinValue)
|
||||
.Where(x => x != int.MinValue)
|
||||
.ToArray();
|
||||
|
||||
//only return if the number of values are the same (i.e. All INTs)
|
||||
if (splitVals.Length == intVals.Length)
|
||||
return intVals;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
{
|
||||
public class DropPreValueTable : MigrationBase
|
||||
{
|
||||
public DropPreValueTable(IMigrationContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
// drop preValues table
|
||||
if (TableExists("cmsDataTypePreValues"))
|
||||
Delete.Table("cmsDataTypePreValues").Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
{
|
||||
[DefaultPropertyValueConverter]
|
||||
public class DropdownListMultipleValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
=> propertyType.EditorAlias.InvariantEquals(Constants.PropertyEditors.Aliases.DropDownListMultiple);
|
||||
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
=> typeof (IEnumerable<string>);
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
=> PropertyCacheLevel.Element;
|
||||
|
||||
public override object ConvertIntermediateToObject(IPublishedElement owner, PublishedPropertyType propertyType, PropertyCacheLevel cacheLevel, object source, bool preview)
|
||||
{
|
||||
var sourceString = (source ?? "").ToString();
|
||||
|
||||
if (string.IsNullOrEmpty(sourceString))
|
||||
return Enumerable.Empty<string>();
|
||||
|
||||
var values =
|
||||
sourceString.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => v.Trim());
|
||||
|
||||
return values;
|
||||
}
|
||||
}
|
||||
}
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
{
|
||||
[DefaultPropertyValueConverter]
|
||||
public class DropdownListMultipleWithKeysValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
=> propertyType.EditorAlias.InvariantEquals(Constants.PropertyEditors.Aliases.DropdownlistMultiplePublishKeys);
|
||||
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
=> typeof (IEnumerable<int>);
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
=> PropertyCacheLevel.Element;
|
||||
|
||||
public override object ConvertSourceToIntermediate(IPublishedElement owner, PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
if (source == null)
|
||||
return new int[] { };
|
||||
|
||||
var prevalueIds = source.ToString()
|
||||
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(p => p.Trim())
|
||||
.Select(int.Parse)
|
||||
.ToArray();
|
||||
|
||||
return prevalueIds;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
{
|
||||
[DefaultPropertyValueConverter]
|
||||
public class DropdownListValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
=> propertyType.EditorAlias.InvariantEquals(Constants.PropertyEditors.Aliases.DropDownList);
|
||||
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
=> typeof (string);
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
=> PropertyCacheLevel.Element;
|
||||
|
||||
public override object ConvertSourceToIntermediate(IPublishedElement owner, PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
return source?.ToString() ?? string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
{
|
||||
[DefaultPropertyValueConverter]
|
||||
public class DropdownListWithKeysValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
=> propertyType.EditorAlias.InvariantEquals(Constants.PropertyEditors.Aliases.DropdownlistPublishKeys);
|
||||
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
=> typeof (int);
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
=> PropertyCacheLevel.Element;
|
||||
|
||||
public override object ConvertSourceToIntermediate(IPublishedElement owner, PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
var intAttempt = source.TryConvertTo<int>();
|
||||
if (intAttempt.Success)
|
||||
return intAttempt.Result;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -143,7 +143,6 @@
|
||||
<Compile Include="Cache\SingleItemsOnlyRepositoryCachePolicy.cs" />
|
||||
<Compile Include="Cache\StaticCacheProvider.cs" />
|
||||
<Compile Include="Cache\TypedCacheRefresherBase.cs" />
|
||||
<Compile Include="CodeAnnotations\ActionMetadataAttribute.cs" />
|
||||
<Compile Include="CodeAnnotations\FriendlyNameAttribute.cs" />
|
||||
<Compile Include="CodeAnnotations\UmbracoObjectTypeAttribute.cs" />
|
||||
<Compile Include="CodeAnnotations\UmbracoUdiTypeAttribute.cs" />
|
||||
@@ -357,6 +356,8 @@
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\AddVariationTables1A.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\AddVariationTables2.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypeMigration.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\DropDownPropertyEditorsMigration.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\DropPreValueTable.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\DropTaskTables.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\FixLockTablePrimaryKey.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\LanguageColumns.cs" />
|
||||
@@ -1242,10 +1243,6 @@
|
||||
<Compile Include="PropertyEditors\ValueConverters\ColorPickerValueConverter.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\DatePickerValueConverter.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\DecimalValueConverter.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\DropdownListMultipleValueConverter.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\DropdownListMultipleWithKeysValueConverter.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\DropdownListValueConverter.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\DropdownListWithKeysValueConverter.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\EmailAddressValueConverter.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\GridValueConverter.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\ImageCropperValueConverter.cs" />
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
namespace Umbraco.Tests.Composing
|
||||
{
|
||||
[TestFixture]
|
||||
public class ActionCollectionTests : ComposingTestBase
|
||||
{
|
||||
[Test]
|
||||
public void ActionCollectionBuilderWorks()
|
||||
{
|
||||
var collectionBuilder = new ActionCollectionBuilder();
|
||||
collectionBuilder.SetProducer(() => TypeLoader.GetActions());
|
||||
|
||||
var actions = collectionBuilder.CreateCollection();
|
||||
Assert.AreEqual(2, actions.Count());
|
||||
|
||||
// order is unspecified, but both must be there
|
||||
var hasAction1 = actions.ElementAt(0) is SingletonAction || actions.ElementAt(1) is SingletonAction;
|
||||
var hasAction2 = actions.ElementAt(0) is NonSingletonAction || actions.ElementAt(1) is NonSingletonAction;
|
||||
Assert.IsTrue(hasAction1);
|
||||
Assert.IsTrue(hasAction2);
|
||||
|
||||
var singletonAction = (SingletonAction) (actions.ElementAt(0) is SingletonAction ? actions.ElementAt(0) : actions.ElementAt(1));
|
||||
|
||||
// ensure it is a singleton
|
||||
Assert.AreSame(SingletonAction.Instance, singletonAction);
|
||||
}
|
||||
|
||||
#region Test Objects
|
||||
|
||||
public class SingletonAction : IAction
|
||||
{
|
||||
public static SingletonAction Instance { get; } = new SingletonAction();
|
||||
|
||||
public char Letter => 'I';
|
||||
|
||||
public string JsFunctionName => $"{ClientTools.Scripts.GetAppActions}.actionAssignDomain()";
|
||||
|
||||
public string JsSource => null;
|
||||
|
||||
public string Alias => "assignDomain";
|
||||
|
||||
public string Icon => ".sprDomain";
|
||||
|
||||
public bool ShowInNotifier => false;
|
||||
|
||||
public bool CanBePermissionAssigned => true;
|
||||
|
||||
public bool OpensDialog => true;
|
||||
}
|
||||
|
||||
public class NonSingletonAction : IAction
|
||||
{
|
||||
public char Letter => 'Q';
|
||||
|
||||
public string JsFunctionName => $"{ClientTools.Scripts.GetAppActions}.actionAssignDomain()";
|
||||
|
||||
public string JsSource => null;
|
||||
|
||||
public string Alias => "asfasdf";
|
||||
|
||||
public string Icon => ".sprDomain";
|
||||
|
||||
public bool ShowInNotifier => false;
|
||||
|
||||
public bool CanBePermissionAssigned => true;
|
||||
|
||||
public bool OpensDialog => true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -268,18 +268,11 @@ AnotherContentFinder
|
||||
Assert.AreEqual(2, foundTypes1.Count());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Resolves_Actions()
|
||||
{
|
||||
var actions = _typeLoader.GetActions();
|
||||
Assert.AreEqual(33, actions.Count());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetDataEditors()
|
||||
{
|
||||
var types = _typeLoader.GetDataEditors();
|
||||
Assert.AreEqual(43, types.Count());
|
||||
Assert.AreEqual(39, types.Count());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -21,28 +21,15 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
/// Tests for the base classes of ValueEditors and PreValueEditors that are used for Property Editors that edit
|
||||
/// multiple values such as the drop down list, check box list, color picker, etc....
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Mostly this used to test the we'd store INT Ids in the Db but publish STRING values or sometimes the INT values
|
||||
/// to cache. Now we always just deal with strings and we'll keep the tests that show that.
|
||||
/// </remarks>
|
||||
[TestFixture]
|
||||
public class MultiValuePropertyEditorTests
|
||||
{
|
||||
//TODO: Test the other formatting methods for the drop down classes
|
||||
|
||||
[Test]
|
||||
public void DropDownMultipleValueEditor_With_Keys_Format_Data_For_Cache()
|
||||
{
|
||||
var dataTypeServiceMock = new Mock<IDataTypeService>();
|
||||
var editor = new PublishValuesMultipleValueEditor(true, Mock.Of<ILogger>(), new DataEditorAttribute("key", "nam", "view"));
|
||||
|
||||
var dataType = new DataType(new CheckBoxListPropertyEditor(Mock.Of<ILogger>(), Mock.Of<ILocalizedTextService>()));
|
||||
var prop = new Property(1, new PropertyType(dataType));
|
||||
prop.SetValue("1234,4567,8910");
|
||||
|
||||
var result = editor.ConvertDbToString(prop.PropertyType, prop.GetValue(), new Mock<IDataTypeService>().Object);
|
||||
|
||||
Assert.AreEqual("1234,4567,8910", result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DropDownMultipleValueEditor_No_Keys_Format_Data_For_Cache()
|
||||
public void DropDownMultipleValueEditor_Format_Data_For_Cache()
|
||||
{
|
||||
var dataType = new DataType(new CheckBoxListPropertyEditor(Mock.Of<ILogger>(), Mock.Of<ILocalizedTextService>()))
|
||||
{
|
||||
@@ -61,7 +48,7 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
var dataTypeService = new TestObjects.TestDataTypeService(dataType);
|
||||
|
||||
var prop = new Property(1, new PropertyType(dataType));
|
||||
prop.SetValue("1234,4567,8910");
|
||||
prop.SetValue("Value 1,Value 2,Value 3");
|
||||
|
||||
var valueEditor = dataType.Editor.GetValueEditor();
|
||||
((DataValueEditor) valueEditor).Configuration = dataType.Configuration;
|
||||
@@ -90,7 +77,7 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
var dataTypeService = new TestObjects.TestDataTypeService(dataType);
|
||||
|
||||
var prop = new Property(1, new PropertyType(dataType));
|
||||
prop.SetValue("1234");
|
||||
prop.SetValue("Value 2");
|
||||
|
||||
var result = dataType.Editor.GetValueEditor().ConvertDbToString(prop.PropertyType, prop.GetValue(), dataTypeService);
|
||||
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.PropertyEditors.ValueConverters;
|
||||
using Umbraco.Web.PropertyEditors;
|
||||
using Umbraco.Web.PropertyEditors.ValueConverters;
|
||||
|
||||
namespace Umbraco.Tests.PropertyEditors
|
||||
{
|
||||
@@ -79,27 +85,26 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
[TestCase(null, new string[] { })]
|
||||
public void CanConvertDropdownListMultiplePropertyEditor(object value, IEnumerable<string> expected)
|
||||
{
|
||||
var converter = new DropdownListMultipleValueConverter();
|
||||
var inter = converter.ConvertSourceToIntermediate(null, null, value, false);
|
||||
var result = converter.ConvertIntermediateToObject(null, null, PropertyCacheLevel.Unknown, inter, false);
|
||||
var mockPublishedContentTypeFactory = new Mock<IPublishedContentTypeFactory>();
|
||||
mockPublishedContentTypeFactory.Setup(x => x.GetDataType(123))
|
||||
.Returns(new PublishedDataType(123, "test", new Lazy<object>(() => new DropDownFlexibleConfiguration
|
||||
{
|
||||
Multiple = true
|
||||
})));
|
||||
|
||||
var publishedPropType = new PublishedPropertyType(
|
||||
new PublishedContentType(1234, "test", PublishedItemType.Content, Enumerable.Empty<string>(), Enumerable.Empty<PublishedPropertyType>(), ContentVariation.Nothing),
|
||||
new PropertyType("test", ValueStorageType.Nvarchar) { DataTypeId = 123 },
|
||||
new PropertyValueConverterCollection(Enumerable.Empty<IPropertyValueConverter>()),
|
||||
Mock.Of<IPublishedModelFactory>(), mockPublishedContentTypeFactory.Object);
|
||||
|
||||
var converter = new FlexibleDropdownPropertyValueConverter();
|
||||
var inter = converter.ConvertSourceToIntermediate(null, publishedPropType, value, false);
|
||||
var result = converter.ConvertIntermediateToObject(null, publishedPropType, PropertyCacheLevel.Unknown, inter, false);
|
||||
|
||||
Assert.AreEqual(expected, result);
|
||||
}
|
||||
|
||||
[TestCase("100", new[] { 100 })]
|
||||
[TestCase("100,200", new[] { 100, 200 })]
|
||||
[TestCase("100 , 200, 300 ", new[] { 100, 200, 300 })]
|
||||
[TestCase("", new int[] { })]
|
||||
[TestCase(null, new int[] { })]
|
||||
public void CanConvertDropdownListMultipleWithKeysPropertyEditor(object value, IEnumerable<int> expected)
|
||||
{
|
||||
var converter = new DropdownListMultipleWithKeysValueConverter();
|
||||
var inter = converter.ConvertSourceToIntermediate(null, null, value, false);
|
||||
var result = converter.ConvertIntermediateToObject(null, null, PropertyCacheLevel.Unknown, inter, false);
|
||||
|
||||
Assert.AreEqual(expected, result);
|
||||
}
|
||||
|
||||
|
||||
[TestCase("1", 1)]
|
||||
[TestCase("1", 1)]
|
||||
[TestCase("0", 0)]
|
||||
|
||||
@@ -1265,11 +1265,11 @@ namespace Umbraco.Tests.Services
|
||||
{
|
||||
// Arrange
|
||||
|
||||
var langUk = new Language("en-GB") { IsDefault = true };
|
||||
var langGB = new Language("en-GB") { IsDefault = true };
|
||||
var langFr = new Language("fr-FR");
|
||||
|
||||
ServiceContext.LocalizationService.Save(langFr);
|
||||
ServiceContext.LocalizationService.Save(langUk);
|
||||
ServiceContext.LocalizationService.Save(langGB);
|
||||
|
||||
var contentType = MockedContentTypes.CreateBasicContentType();
|
||||
contentType.Variations = ContentVariation.Culture;
|
||||
@@ -1285,8 +1285,8 @@ namespace Umbraco.Tests.Services
|
||||
|
||||
//re-get
|
||||
content = ServiceContext.ContentService.GetById(content.Id);
|
||||
content.SetCultureName("content-en", langUk.IsoCode);
|
||||
content.PublishCulture(langUk.IsoCode);
|
||||
content.SetCultureName("content-en", langGB.IsoCode);
|
||||
content.PublishCulture(langGB.IsoCode);
|
||||
published = ServiceContext.ContentService.SavePublishing(content);
|
||||
//audit log will only show that english was published
|
||||
lastLog = ServiceContext.AuditService.GetLogs(content.Id).Last();
|
||||
|
||||
@@ -14,7 +14,8 @@ using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Services.Implement;
|
||||
using Umbraco.Tests.Testing;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
|
||||
namespace Umbraco.Tests.Services
|
||||
{
|
||||
@@ -70,12 +71,12 @@ namespace Umbraco.Tests.Services
|
||||
MockedContent.CreateSimpleContent(contentType)
|
||||
};
|
||||
ServiceContext.ContentService.Save(content);
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionMove.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[2], ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionMove.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[2], ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
|
||||
// Act
|
||||
var permissions = userService.GetPermissions(user, content[0].Id, content[1].Id, content[2].Id).ToArray();
|
||||
@@ -103,12 +104,12 @@ namespace Umbraco.Tests.Services
|
||||
MockedContent.CreateSimpleContent(contentType)
|
||||
};
|
||||
ServiceContext.ContentService.Save(content);
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(0), ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(0), ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(0), ActionMove.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(1), ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(1), ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(2), ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(0), ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(0), ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(0), ActionMove.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(1), ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(1), ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(2), ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
|
||||
// Act
|
||||
var permissions = userService.GetPermissions(userGroup, false, content[0].Id, content[1].Id, content[2].Id).ToArray();
|
||||
@@ -136,11 +137,11 @@ namespace Umbraco.Tests.Services
|
||||
MockedContent.CreateSimpleContent(contentType)
|
||||
};
|
||||
ServiceContext.ContentService.Save(content);
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionMove.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionMove.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
|
||||
// Act
|
||||
var permissions = userService.GetPermissions(userGroup, true, content[0].Id, content[1].Id, content[2].Id)
|
||||
@@ -180,12 +181,12 @@ namespace Umbraco.Tests.Services
|
||||
};
|
||||
ServiceContext.ContentService.Save(content);
|
||||
//assign permissions - we aren't assigning anything explicit for group3 and nothing explicit for content[2] /w group2
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionBrowse.Instance.Letter, new int[] { userGroup1.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionDelete.Instance.Letter, new int[] { userGroup1.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionMove.Instance.Letter, new int[] { userGroup2.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionBrowse.Instance.Letter, new int[] { userGroup1.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionDelete.Instance.Letter, new int[] { userGroup2.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[2], ActionDelete.Instance.Letter, new int[] { userGroup1.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionBrowse.ActionLetter, new int[] { userGroup1.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionDelete.ActionLetter, new int[] { userGroup1.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionMove.ActionLetter, new int[] { userGroup2.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionBrowse.ActionLetter, new int[] { userGroup1.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionDelete.ActionLetter, new int[] { userGroup2.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[2], ActionDelete.ActionLetter, new int[] { userGroup1.Id });
|
||||
|
||||
// Act
|
||||
//we don't pass in any nodes so it will return all of them
|
||||
@@ -249,12 +250,12 @@ namespace Umbraco.Tests.Services
|
||||
MockedContent.CreateSimpleContent(contentType)
|
||||
};
|
||||
ServiceContext.ContentService.Save(content);
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionMove.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[2], ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionMove.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[2], ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
|
||||
// Act
|
||||
//we don't pass in any nodes so it will return all of them
|
||||
@@ -412,11 +413,11 @@ namespace Umbraco.Tests.Services
|
||||
var child2 = MockedContent.CreateSimpleContent(contentType, "child2", child1);
|
||||
ServiceContext.ContentService.Save(child2);
|
||||
|
||||
ServiceContext.ContentService.SetPermission(parent, ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(parent, ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(parent, ActionMove.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(parent, ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(parent, ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(parent, ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(parent, ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(parent, ActionMove.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(parent, ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(parent, ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
|
||||
// Act
|
||||
var permissions = userService.GetPermissionsForPath(userGroup, child2.Path);
|
||||
|
||||
@@ -362,12 +362,10 @@ namespace Umbraco.Tests.TestHelpers.Entities
|
||||
contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.NoEdit, ValueStorageType.Nvarchar) { Alias = "label", Name = "Label", Mandatory = false, SortOrder = 7, DataTypeId = -92 });
|
||||
contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.DateTime, ValueStorageType.Date) { Alias = "dateTime", Name = "Date Time", Mandatory = false, SortOrder = 8, DataTypeId = -36 });
|
||||
contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.ColorPicker, ValueStorageType.Nvarchar) { Alias = "colorPicker", Name = "Color Picker", Mandatory = false, SortOrder = 9, DataTypeId = -37 });
|
||||
//that one is gone in 7.4
|
||||
//contentCollection.Add(new PropertyType(Constants.PropertyEditors.FolderBrowserAlias, DataTypeDatabaseType.Nvarchar) { Alias = "folderBrowser", Name = "Folder Browser", Mandatory = false, SortOrder = 10, DataTypeDefinitionId = -38 });
|
||||
contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.DropDownListMultiple, ValueStorageType.Nvarchar) { Alias = "ddlMultiple", Name = "Dropdown List Multiple", Mandatory = false, SortOrder = 11, DataTypeId = -39 });
|
||||
contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.DropDownListFlexible, ValueStorageType.Nvarchar) { Alias = "ddlMultiple", Name = "Dropdown List Multiple", Mandatory = false, SortOrder = 11, DataTypeId = -39 });
|
||||
contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.RadioButtonList, ValueStorageType.Nvarchar) { Alias = "rbList", Name = "Radio Button List", Mandatory = false, SortOrder = 12, DataTypeId = -40 });
|
||||
contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.Date, ValueStorageType.Date) { Alias = "date", Name = "Date", Mandatory = false, SortOrder = 13, DataTypeId = -41 });
|
||||
contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.DropDownList, ValueStorageType.Integer) { Alias = "ddl", Name = "Dropdown List", Mandatory = false, SortOrder = 14, DataTypeId = -42 });
|
||||
contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.DropDownListFlexible, ValueStorageType.Integer) { Alias = "ddl", Name = "Dropdown List", Mandatory = false, SortOrder = 14, DataTypeId = -42 });
|
||||
contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.CheckBoxList, ValueStorageType.Nvarchar) { Alias = "chklist", Name = "Checkbox List", Mandatory = false, SortOrder = 15, DataTypeId = -43 });
|
||||
contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.ContentPicker, ValueStorageType.Integer) { Alias = "contentPicker", Name = "Content Picker", Mandatory = false, SortOrder = 16, DataTypeId = 1046 });
|
||||
contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.MediaPicker, ValueStorageType.Integer) { Alias = "mediaPicker", Name = "Media Picker", Mandatory = false, SortOrder = 17, DataTypeId = 1048 });
|
||||
@@ -375,11 +373,6 @@ namespace Umbraco.Tests.TestHelpers.Entities
|
||||
contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.RelatedLinks, ValueStorageType.Ntext) { Alias = "relatedLinks", Name = "Related Links", Mandatory = false, SortOrder = 21, DataTypeId = 1050 });
|
||||
contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.Tags, ValueStorageType.Ntext) { Alias = "tags", Name = "Tags", Mandatory = false, SortOrder = 22, DataTypeId = 1041 });
|
||||
|
||||
//contentCollection.Add(new PropertyType(Constants.PropertyEditors.UltraSimpleEditorAlias, DataTypeDatabaseType.Ntext) { Alias = "simpleEditor", Name = "Ultra Simple Editor", Mandatory = false, SortOrder = 19, DataTypeDefinitionId = 1038 });
|
||||
//contentCollection.Add(new PropertyType(Constants.PropertyEditors.UltimatePickerAlias, DataTypeDatabaseType.Ntext) { Alias = "ultimatePicker", Name = "Ultimate Picker", Mandatory = false, SortOrder = 20, DataTypeDefinitionId = 1039 });
|
||||
//contentCollection.Add(new PropertyType(Constants.PropertyEditors.MacroContainerAlias, DataTypeDatabaseType.Ntext) { Alias = "macroContainer", Name = "Macro Container", Mandatory = false, SortOrder = 23, DataTypeDefinitionId = 1042 });
|
||||
//contentCollection.Add(new PropertyType(Constants.PropertyEditors.ImageCropperAlias, DataTypeDatabaseType.Ntext) { Alias = "imgCropper", Name = "Image Cropper", Mandatory = false, SortOrder = 24, DataTypeDefinitionId = 1043 });
|
||||
|
||||
contentType.PropertyGroups.Add(new PropertyGroup(contentCollection) { Name = "Content", SortOrder = 1 });
|
||||
|
||||
return contentType;
|
||||
|
||||
@@ -36,9 +36,10 @@ using Umbraco.Web;
|
||||
using Umbraco.Web.Services;
|
||||
using Umbraco.Examine;
|
||||
using Umbraco.Tests.Testing.Objects.Accessors;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Composing.CompositionRoots;
|
||||
using Umbraco.Web.ContentApps;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Current = Umbraco.Core.Composing.Current;
|
||||
using Umbraco.Web.Routing;
|
||||
|
||||
@@ -205,9 +206,7 @@ namespace Umbraco.Tests.Testing
|
||||
Container.RegisterSingleton(f => runtimeStateMock.Object);
|
||||
|
||||
// ah...
|
||||
Container.RegisterCollectionBuilder<ActionCollectionBuilder>()
|
||||
.SetProducer(Enumerable.Empty<Type>);
|
||||
|
||||
Container.RegisterCollectionBuilder<ActionCollectionBuilder>();
|
||||
Container.RegisterCollectionBuilder<PropertyValueConverterCollectionBuilder>();
|
||||
Container.RegisterSingleton<IPublishedContentTypeFactory, PublishedContentTypeFactory>();
|
||||
|
||||
|
||||
@@ -406,7 +406,6 @@
|
||||
<Compile Include="Persistence\Repositories\StylesheetRepositoryTest.cs" />
|
||||
<Compile Include="PublishedContent\PublishedContentMoreTests.cs" />
|
||||
<Compile Include="Publishing\PublishingStrategyTests.cs" />
|
||||
<Compile Include="Composing\ActionCollectionTests.cs" />
|
||||
<Compile Include="TestHelpers\Entities\MockedMember.cs" />
|
||||
<Compile Include="TestHelpers\Entities\MockedUser.cs" />
|
||||
<Compile Include="TestHelpers\Stubs\TestProfiler.cs" />
|
||||
|
||||
@@ -22,20 +22,5 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
};
|
||||
|
||||
|
||||
[TestCaseSource("TestLegacyJsActionPaths")]
|
||||
public void Separates_Legacy_JsActions_By_Block_Or_Url(object[] jsActions)
|
||||
{
|
||||
var jsBlocks =
|
||||
BackOfficeController.GetLegacyActionJsForActions(BackOfficeController.LegacyJsActionType.JsBlock,
|
||||
jsActions.Select(n => n.ToString()));
|
||||
|
||||
var jsUrls =
|
||||
BackOfficeController.GetLegacyActionJsForActions(BackOfficeController.LegacyJsActionType.JsUrl,
|
||||
jsActions.Select(n => n.ToString()));
|
||||
|
||||
Assert.That(jsBlocks.Count() == 4);
|
||||
Assert.That(jsUrls.Count() == 3);
|
||||
Assert.That(jsUrls.Last().StartsWith("~/") == false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ using Umbraco.Web;
|
||||
using Umbraco.Web.Editors;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Task = System.Threading.Tasks.Task;
|
||||
using Umbraco.Core.Dictionary;
|
||||
using Umbraco.Web.PropertyEditors;
|
||||
@@ -30,6 +30,7 @@ using System;
|
||||
using Umbraco.Web.WebApi;
|
||||
using Umbraco.Web.Trees;
|
||||
using System.Globalization;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
namespace Umbraco.Tests.Web.Controllers
|
||||
{
|
||||
@@ -53,10 +54,10 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
{
|
||||
new EntityPermission(0, 123, new[]
|
||||
{
|
||||
ActionBrowse.Instance.Letter.ToString(),
|
||||
ActionUpdate.Instance.Letter.ToString(),
|
||||
ActionPublish.Instance.Letter.ToString(),
|
||||
ActionNew.Instance.Letter.ToString()
|
||||
ActionBrowse.ActionLetter.ToString(),
|
||||
ActionUpdate.ActionLetter.ToString(),
|
||||
ActionPublish.ActionLetter.ToString(),
|
||||
ActionNew.ActionLetter.ToString()
|
||||
}),
|
||||
})));
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ Umbraco.Sys.registerNamespace("Umbraco.Application");
|
||||
* Returns the root angular scope
|
||||
*/
|
||||
function getRootScope() {
|
||||
return angular.element(document.getElementById("umbracoMainPageBody")).scope();
|
||||
return top.$("#umbracoMainPageBody").scope();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,7 +46,7 @@ Umbraco.Sys.registerNamespace("Umbraco.Application");
|
||||
* Returns the root angular injector
|
||||
*/
|
||||
function getRootInjector() {
|
||||
return angular.element(document.getElementById("umbracoMainPageBody")).injector();
|
||||
return top.$("#umbracoMainPageBody").injector();
|
||||
}
|
||||
|
||||
|
||||
@@ -327,7 +327,7 @@ Umbraco.Sys.registerNamespace("Umbraco.Application");
|
||||
//add the callback to the jquery data for the modal so we can call it on close to support the legacy way dialogs worked.
|
||||
dialog.element.data("modalCb", onCloseCallback);
|
||||
//add the close triggers
|
||||
if (angular.isArray(closeTriggers)) {
|
||||
if (top.angular.isArray(closeTriggers)) {
|
||||
for (var i = 0; i < closeTriggers.length; i++) {
|
||||
var e = dialog.find(closeTriggers[i]);
|
||||
if (e.length > 0) {
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* </pre>
|
||||
**/
|
||||
|
||||
function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
function contentResource($q, $http, $routeParams, umbDataFormatter, umbRequestHelper) {
|
||||
|
||||
/** internal method process the saving of data and post processing the result */
|
||||
function saveContentItem(content, action, files, restApiUrl, showNotifications) {
|
||||
@@ -607,7 +607,10 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
else if (options.orderDirection === "desc") {
|
||||
options.orderDirection = "Descending";
|
||||
}
|
||||
|
||||
if (!options.cultureName) {
|
||||
// must send a culture to the content API to handle variant data correctly
|
||||
options.cultureName = $routeParams.mculture;
|
||||
}
|
||||
//converts the value to a js bool
|
||||
function toBool(v) {
|
||||
if (angular.isNumber(v)) {
|
||||
|
||||
@@ -402,21 +402,34 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS
|
||||
throw "Cannot get a descendant node from a section container node without a treeAlias specified";
|
||||
}
|
||||
|
||||
//if it is a section container, we need to find the tree to be searched
|
||||
if (treeNode.isContainer) {
|
||||
var foundRoot = null;
|
||||
for (var c = 0; c < treeNode.children.length; c++) {
|
||||
if (this.getTreeAlias(treeNode.children[c]) === treeAlias) {
|
||||
foundRoot = treeNode.children[c];
|
||||
break;
|
||||
//the treeNode passed in could be a section container, or it could be a section group
|
||||
//in either case we need to go through the children until we can find the actual tree root with the treeAlias
|
||||
var self = this;
|
||||
function getTreeRoot(tn) {
|
||||
//if it is a section container, we need to find the tree to be searched
|
||||
if (tn.isContainer) {
|
||||
for (var c = 0; c < tn.children.length; c++) {
|
||||
if (tn.children[c].isContainer) {
|
||||
//recurse
|
||||
return getTreeRoot(tn.children[c]);
|
||||
}
|
||||
else if (self.getTreeAlias(tn.children[c]) === treeAlias) {
|
||||
return tn.children[c];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (!foundRoot) {
|
||||
throw "Could not find a tree in the current section with alias " + treeAlias;
|
||||
else {
|
||||
return tn;
|
||||
}
|
||||
treeNode = foundRoot;
|
||||
}
|
||||
|
||||
var foundRoot = getTreeRoot(treeNode);
|
||||
if (!foundRoot) {
|
||||
throw "Could not find a tree in the current section with alias " + treeAlias;
|
||||
}
|
||||
treeNode = foundRoot;
|
||||
|
||||
//check this node
|
||||
if (treeNode.id === id) {
|
||||
return treeNode;
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name Umbraco.Dialogs.LegacyDeleteController
|
||||
* @function
|
||||
*
|
||||
* @description
|
||||
* The controller for deleting content
|
||||
*/
|
||||
function LegacyDeleteController($scope, legacyResource, treeService, navigationService) {
|
||||
|
||||
$scope.performDelete = function () {
|
||||
|
||||
//mark it for deletion (used in the UI)
|
||||
$scope.currentNode.loading = true;
|
||||
|
||||
legacyResource.deleteItem({
|
||||
nodeId: $scope.currentNode.id,
|
||||
nodeType: $scope.currentNode.nodeType,
|
||||
alias: $scope.currentNode.name
|
||||
}).then(function () {
|
||||
$scope.currentNode.loading = false;
|
||||
//TODO: Need to sync tree, etc...
|
||||
treeService.removeNode($scope.currentNode);
|
||||
navigationService.hideMenu();
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$scope.cancel = function () {
|
||||
navigationService.hideDialog();
|
||||
};
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.Dialogs.LegacyDeleteController", LegacyDeleteController);
|
||||
@@ -0,0 +1,14 @@
|
||||
<div class="umb-dialog" ng-controller="Umbraco.Dialogs.LegacyDeleteController">
|
||||
<div class="umb-dialog-body" >
|
||||
|
||||
<div class="umb-pane">
|
||||
<p>
|
||||
<localize key="defaultdialogs_confirmdelete">Are you sure you want to delete</localize> <strong>{{currentNode.name}}</strong> ?
|
||||
</p>
|
||||
|
||||
|
||||
<umb-confirm on-confirm="performDelete" on-cancel="cancel">
|
||||
</umb-confirm>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,70 +0,0 @@
|
||||
angular.module("umbraco").controller("Umbraco.PropertyEditors.DropdownController",
|
||||
function($scope) {
|
||||
|
||||
//setup the default config
|
||||
var config = {
|
||||
items: [],
|
||||
multiple: false
|
||||
};
|
||||
|
||||
//map the user config
|
||||
angular.extend(config, $scope.model.config);
|
||||
|
||||
//map back to the model
|
||||
$scope.model.config = config;
|
||||
|
||||
function convertArrayToDictionaryArray(model){
|
||||
//now we need to format the items in the dictionary because we always want to have an array
|
||||
var newItems = [];
|
||||
for (var i = 0; i < model.length; i++) {
|
||||
newItems.push({ id: model[i], sortOrder: 0, value: model[i] });
|
||||
}
|
||||
|
||||
return newItems;
|
||||
}
|
||||
|
||||
|
||||
function convertObjectToDictionaryArray(model){
|
||||
//now we need to format the items in the dictionary because we always want to have an array
|
||||
var newItems = [];
|
||||
var vals = _.values($scope.model.config.items);
|
||||
var keys = _.keys($scope.model.config.items);
|
||||
|
||||
for (var i = 0; i < vals.length; i++) {
|
||||
var label = vals[i].value ? vals[i].value : vals[i];
|
||||
newItems.push({ id: keys[i], sortOrder: vals[i].sortOrder, value: label });
|
||||
}
|
||||
|
||||
return newItems;
|
||||
}
|
||||
|
||||
if (angular.isArray($scope.model.config.items)) {
|
||||
//PP: I dont think this will happen, but we have tests that expect it to happen..
|
||||
//if array is simple values, convert to array of objects
|
||||
if(!angular.isObject($scope.model.config.items[0])){
|
||||
$scope.model.config.items = convertArrayToDictionaryArray($scope.model.config.items);
|
||||
}
|
||||
}
|
||||
else if (angular.isObject($scope.model.config.items)) {
|
||||
$scope.model.config.items = convertObjectToDictionaryArray($scope.model.config.items);
|
||||
}
|
||||
else {
|
||||
throw "The items property must be either an array or a dictionary";
|
||||
}
|
||||
|
||||
|
||||
//sort the values
|
||||
$scope.model.config.items.sort(function (a, b) { return (a.sortOrder > b.sortOrder) ? 1 : ((b.sortOrder > a.sortOrder) ? -1 : 0); });
|
||||
|
||||
//now we need to check if the value is null/undefined, if it is we need to set it to "" so that any value that is set
|
||||
// to "" gets selected by default
|
||||
if ($scope.model.value === null || $scope.model.value === undefined) {
|
||||
if ($scope.model.config.multiple) {
|
||||
$scope.model.value = [];
|
||||
}
|
||||
else {
|
||||
$scope.model.value = "";
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
@@ -1,20 +0,0 @@
|
||||
<div ng-controller="Umbraco.PropertyEditors.DropdownController" ng-switch="model.config.multiple">
|
||||
|
||||
<select name="dropDownList"
|
||||
class="umb-property-editor umb-dropdown"
|
||||
ng-switch-default
|
||||
ng-model="model.value"
|
||||
ng-options="item.id as item.value for item in model.config.items">
|
||||
<option></option>
|
||||
</select>
|
||||
|
||||
<!--NOTE: This ng-switch is required because ng-multiple doesn't actually support dynamic bindings with multi-select lists -->
|
||||
<select name="dropDownList"
|
||||
class="umb-property-editor umb-dropdown"
|
||||
ng-switch-when="1"
|
||||
multiple
|
||||
ng-model="model.value"
|
||||
ng-options="item.id as item.value for item in model.config.items">
|
||||
</select>
|
||||
|
||||
</div>
|
||||
+5
-2
@@ -12,7 +12,10 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.DropdownFlexibleCo
|
||||
|
||||
//map back to the model
|
||||
$scope.model.config = config;
|
||||
|
||||
|
||||
//ensure this is a bool, old data could store zeros/ones or string versions
|
||||
$scope.model.config.multiple = Object.toBoolean($scope.model.config.multiple);
|
||||
|
||||
function convertArrayToDictionaryArray(model){
|
||||
//now we need to format the items in the dictionary because we always want to have an array
|
||||
var newItems = [];
|
||||
@@ -74,7 +77,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.DropdownFlexibleCo
|
||||
// if we run in single mode we'll store the value in a local variable
|
||||
// so we can pass an array as the model as our PropertyValueEditor expects that
|
||||
$scope.model.singleDropdownValue = "";
|
||||
if ($scope.model.config.multiple === "0") {
|
||||
if (!Object.toBoolean($scope.model.config.multiple)) {
|
||||
$scope.model.singleDropdownValue = Array.isArray($scope.model.value) ? $scope.model.value[0] : $scope.model.value;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -5,15 +5,15 @@
|
||||
ng-switch-default
|
||||
ng-change="updateSingleDropdownValue()"
|
||||
ng-model="model.singleDropdownValue"
|
||||
ng-options="item.id as item.value for item in model.config.items">
|
||||
ng-options="item.value as item.value for item in model.config.items">
|
||||
<option></option>
|
||||
</select>
|
||||
|
||||
<!--NOTE: This ng-switch is required because ng-multiple doesn't actually support dynamic bindings with multi-select lists -->
|
||||
<select name="dropDownList"
|
||||
class="umb-property-editor umb-dropdown"
|
||||
ng-switch-when="1"
|
||||
ng-switch-when="true"
|
||||
multiple
|
||||
ng-model="model.value"
|
||||
ng-options="item.id as item.value for item in model.config.items"></select>
|
||||
ng-options="item.value as item.value for item in model.config.items"></select>
|
||||
</div>
|
||||
|
||||
@@ -324,8 +324,6 @@
|
||||
<Content Include="Umbraco\Developer\RelationTypes\Images\Refresh.gif" />
|
||||
<Content Include="Umbraco\Developer\RelationTypes\NewRelationType.aspx" />
|
||||
<Content Include="Umbraco\Developer\RelationTypes\RelationTypesWebService.asmx" />
|
||||
<Content Include="Umbraco\Developer\RelationTypes\TreeMenu\ActionDeleteRelationType.js" />
|
||||
<Content Include="Umbraco\Developer\RelationTypes\TreeMenu\ActionNewRelationType.js" />
|
||||
<Content Include="Umbraco\Dialogs\ChangeDocType.aspx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Content>
|
||||
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
function actionDeleteRelationType(relationTypeId, relationTypeName) {
|
||||
|
||||
if (confirm('Are you sure you want to delete "' + relationTypeName + '"?')) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "developer/RelationTypes/RelationTypesWebService.asmx/DeleteRelationType",
|
||||
data: "{ 'relationTypeId' : '" + relationTypeId + "' }",
|
||||
contentType: "application/json; charset=utf-8",
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
UmbClientMgr.mainTree().refreshTree('relationTypes');
|
||||
UmbClientMgr.appActions().openDashboard('developer');
|
||||
},
|
||||
error: function (data) { }
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
function actionNewRelationType() {
|
||||
UmbClientMgr.openModalWindow('developer/RelationTypes/NewRelationType.aspx', 'Create New RelationType', true, 400, 300, 0, 0);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when a domain is being assigned to a document
|
||||
/// </summary>
|
||||
public class ActionAssignDomain : IAction
|
||||
{
|
||||
public const char ActionLetter = 'I';
|
||||
|
||||
public char Letter => ActionLetter;
|
||||
public string Alias => "assignDomain";
|
||||
public string Category => Constants.Conventions.PermissionCategories.AdministrationCategory;
|
||||
public string Icon => "home";
|
||||
public bool ShowInNotifier => false;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is used as a security constraint that grants a user the ability to view nodes in a tree
|
||||
/// that has permissions applied to it.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This action should not be invoked. It is used as the minimum required permission to view nodes in the content tree. By
|
||||
/// granting a user this permission, the user is able to see the node in the tree but not edit the document. This may be used by other trees
|
||||
/// that support permissions in the future.
|
||||
/// </remarks>
|
||||
public class ActionBrowse : IAction
|
||||
{
|
||||
public const char ActionLetter = 'F';
|
||||
|
||||
public char Letter => ActionLetter;
|
||||
public bool ShowInNotifier => false;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
public string Icon => "";
|
||||
public string Alias => "browse";
|
||||
public string Category => Constants.Conventions.PermissionCategories.ContentCategory;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when the document type of a piece of content is changed
|
||||
/// </summary>
|
||||
public class ActionChangeDocType : IAction
|
||||
{
|
||||
public char Letter => '7';
|
||||
public string Alias => "changeDocType";
|
||||
public string Category => Constants.Conventions.PermissionCategories.AdministrationCategory;
|
||||
public string Icon => "axis-rotation-2";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
+14
-2
@@ -3,8 +3,10 @@ using System.Globalization;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
|
||||
namespace Umbraco.Web._Legacy.Actions
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
public class ActionCollection : BuilderCollectionBase<IAction>
|
||||
{
|
||||
@@ -15,7 +17,7 @@ namespace Umbraco.Web._Legacy.Actions
|
||||
internal T GetAction<T>()
|
||||
where T : IAction
|
||||
{
|
||||
return this.OfType<T>().SingleOrDefault();
|
||||
return this.OfType<T>().FirstOrDefault();
|
||||
}
|
||||
|
||||
internal IEnumerable<IAction> GetByLetters(IEnumerable<string> letters)
|
||||
@@ -25,5 +27,15 @@ namespace Umbraco.Web._Legacy.Actions
|
||||
.WhereNotNull()
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
internal IReadOnlyList<IAction> FromEntityPermission(EntityPermission entityPermission)
|
||||
{
|
||||
return entityPermission.AssignedPermissions
|
||||
.Where(x => x.Length == 1)
|
||||
.Select(x => x.ToCharArray()[0])
|
||||
.SelectMany(c => this.Where(x => x.Letter == c))
|
||||
.Where(action => action != null)
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using LightInject;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
internal class ActionCollectionBuilder : LazyCollectionBuilderBase<ActionCollectionBuilder, ActionCollection, IAction>
|
||||
{
|
||||
public ActionCollectionBuilder(IServiceContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override ActionCollectionBuilder This => this;
|
||||
|
||||
protected override IEnumerable<IAction> CreateItems(params object[] args)
|
||||
{
|
||||
var items = base.CreateItems(args).ToList();
|
||||
//validate the items, no actions should exist that do not either expose notifications or permissions
|
||||
var invalid = items.Where(x => !x.CanBePermissionAssigned && !x.ShowInNotifier).ToList();
|
||||
if (invalid.Count > 0)
|
||||
{
|
||||
throw new InvalidOperationException($"Invalid actions '{string.Join(", ", invalid.Select(x => x.Alias))}'. All {typeof(IAction)} implementations must be true for either {nameof(IAction.CanBePermissionAssigned)} or {nameof(IAction.ShowInNotifier)}");
|
||||
}
|
||||
return items;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when copying a document, media, member
|
||||
/// </summary>
|
||||
public class ActionCopy : IAction
|
||||
{
|
||||
public char Letter => 'O';
|
||||
public string Alias => "copy";
|
||||
public string Category => Constants.Conventions.PermissionCategories.StructureCategory;
|
||||
public string Icon => "documents";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
public class ActionCreateBlueprintFromContent : IAction
|
||||
{
|
||||
public char Letter => 'ï';
|
||||
public bool ShowInNotifier => false;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
public string Icon => "blueprint";
|
||||
public string Alias => "createblueprint";
|
||||
public string Category => Constants.Conventions.PermissionCategories.ContentCategory;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when a document, media, member is deleted
|
||||
/// </summary>
|
||||
public class ActionDelete : IAction
|
||||
{
|
||||
public const string ActionAlias = "delete";
|
||||
public const char ActionLetter = 'D';
|
||||
|
||||
public char Letter => ActionLetter;
|
||||
public string Alias => ActionAlias;
|
||||
public string Category => Constants.Conventions.PermissionCategories.ContentCategory;
|
||||
public string Icon => "delete";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked upon creation of a document, media, member
|
||||
/// </summary>
|
||||
public class ActionMove : IAction
|
||||
{
|
||||
public const char ActionLetter = 'M';
|
||||
|
||||
public char Letter => ActionLetter;
|
||||
public string Alias => "move";
|
||||
public string Category => Constants.Conventions.PermissionCategories.StructureCategory;
|
||||
public string Icon => "enter";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked upon creation of a document
|
||||
/// </summary>
|
||||
public class ActionNew : IAction
|
||||
{
|
||||
public const string ActionAlias = "create";
|
||||
public const char ActionLetter = 'C';
|
||||
|
||||
public char Letter => ActionLetter;
|
||||
public string Alias => ActionAlias;
|
||||
public string Icon => "add";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
public string Category => Constants.Conventions.PermissionCategories.ContentCategory;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when a document is protected or unprotected
|
||||
/// </summary>
|
||||
public class ActionProtect : IAction
|
||||
{
|
||||
public char Letter => 'P';
|
||||
public string Alias => "protect";
|
||||
public string Category => Constants.Conventions.PermissionCategories.AdministrationCategory;
|
||||
public string Icon => "lock";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when a document is being published
|
||||
/// </summary>
|
||||
public class ActionPublish : IAction
|
||||
{
|
||||
public const char ActionLetter = 'U';
|
||||
|
||||
public char Letter => ActionLetter;
|
||||
public string Alias => "publish";
|
||||
public string Category => Constants.Conventions.PermissionCategories.ContentCategory;
|
||||
public string Icon => string.Empty;
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when the content/media item is to be restored from the recycle bin
|
||||
/// </summary>
|
||||
public class ActionRestore : IAction
|
||||
{
|
||||
public const string ActionAlias = "restore";
|
||||
|
||||
public char Letter => 'V';
|
||||
public string Alias => ActionAlias;
|
||||
public string Category => null;
|
||||
public string Icon => "undo";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => false;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when rights are changed on a document
|
||||
/// </summary>
|
||||
public class ActionRights : IAction
|
||||
{
|
||||
public char Letter => 'R';
|
||||
public string Alias => "rights";
|
||||
public string Category => Constants.Conventions.PermissionCategories.ContentCategory;
|
||||
public string Icon => "vcard";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when copying a document is being rolled back
|
||||
/// </summary>
|
||||
public class ActionRollback : IAction
|
||||
{
|
||||
public const char ActionLetter = 'K';
|
||||
|
||||
public char Letter => ActionLetter;
|
||||
public string Alias => "rollback";
|
||||
public string Category => Constants.Conventions.PermissionCategories.AdministrationCategory;
|
||||
public string Icon => "undo";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when children to a document, media, member is being sorted
|
||||
/// </summary>
|
||||
public class ActionSort : IAction
|
||||
{
|
||||
public char Letter => 'S';
|
||||
public string Alias => "sort";
|
||||
public string Category => Constants.Conventions.PermissionCategories.StructureCategory;
|
||||
public string Icon => "navigation-vertical";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when children to a document is being sent to published (by an editor without publishrights)
|
||||
/// </summary>
|
||||
public class ActionToPublish : IAction
|
||||
{
|
||||
public const char ActionLetter = 'H';
|
||||
|
||||
public char Letter => ActionLetter;
|
||||
public string Alias => "sendtopublish";
|
||||
public string Category => Constants.Conventions.PermissionCategories.ContentCategory;
|
||||
public string Icon => "outbox";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// This action is invoked when a document is being unpublished
|
||||
/// </summary>
|
||||
public class ActionUnpublish : IAction
|
||||
{
|
||||
public char Letter => 'Z';
|
||||
public string Alias => "unpublish";
|
||||
public string Category => Constants.Conventions.PermissionCategories.ContentCategory;
|
||||
public string Icon => "circle-dotted";
|
||||
public bool ShowInNotifier => false;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when copying a document or media
|
||||
/// </summary>
|
||||
public class ActionUpdate : IAction
|
||||
{
|
||||
public const char ActionLetter = 'A';
|
||||
|
||||
public char Letter => ActionLetter;
|
||||
public string Alias => "update";
|
||||
public string Category => Constants.Conventions.PermissionCategories.ContentCategory;
|
||||
public string Icon => "save";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a back office action that can be permission assigned or subscribed to for notifications
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If an IAction returns false for both ShowInNotifier and CanBePermissionAssigned then the IAction should not exist
|
||||
/// </remarks>
|
||||
public interface IAction : IDiscoverable
|
||||
{
|
||||
/// <summary>
|
||||
/// The letter used to assign a permission (must be unique)
|
||||
/// </summary>
|
||||
char Letter { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to allow subscribing to notifications for this action
|
||||
/// </summary>
|
||||
bool ShowInNotifier { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to allow assigning permissions based on this action
|
||||
/// </summary>
|
||||
bool CanBePermissionAssigned { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The icon to display for this action
|
||||
/// </summary>
|
||||
string Icon { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The alias for this action (must be unique)
|
||||
/// </summary>
|
||||
string Alias { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The category used for this action
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Used in the UI when assigning permissions
|
||||
/// </remarks>
|
||||
string Category { get; }
|
||||
}
|
||||
}
|
||||
@@ -5,23 +5,24 @@ using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Services.Implement;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Components
|
||||
{
|
||||
[RuntimeLevel(MinLevel = RuntimeLevel.Run)]
|
||||
public sealed class NotificationsComponent : UmbracoComponentBase, IUmbracoCoreComponent
|
||||
{
|
||||
public void Initialize(INotificationService notificationService)
|
||||
public void Initialize(INotificationService notificationService, ActionCollection actions)
|
||||
{
|
||||
ContentService.SentToPublish += (sender, args) =>
|
||||
notificationService.SendNotification(args.Entity, ActionToPublish.Instance);
|
||||
notificationService.SendNotification(args.Entity, actions.GetAction<ActionToPublish>());
|
||||
|
||||
//Send notifications for the published action
|
||||
ContentService.Published += (sender, args) =>
|
||||
{
|
||||
foreach (var content in args.PublishedEntities)
|
||||
notificationService.SendNotification(content, ActionPublish.Instance);
|
||||
notificationService.SendNotification(content, actions.GetAction<ActionToPublish>());
|
||||
};
|
||||
|
||||
//Send notifications for the update and created actions
|
||||
@@ -45,22 +46,22 @@ namespace Umbraco.Web.Components
|
||||
updatedEntities.Add(entity);
|
||||
}
|
||||
}
|
||||
notificationService.SendNotification(newEntities, ActionNew.Instance);
|
||||
notificationService.SendNotification(updatedEntities, ActionUpdate.Instance);
|
||||
notificationService.SendNotification(newEntities, actions.GetAction<ActionNew>());
|
||||
notificationService.SendNotification(updatedEntities, actions.GetAction<ActionUpdate>());
|
||||
};
|
||||
|
||||
//Send notifications for the delete action
|
||||
ContentService.Deleted += (sender, args) =>
|
||||
{
|
||||
foreach (var content in args.DeletedEntities)
|
||||
notificationService.SendNotification(content, ActionDelete.Instance);
|
||||
notificationService.SendNotification(content, actions.GetAction<ActionDelete>());
|
||||
};
|
||||
|
||||
//Send notifications for the unpublish action
|
||||
ContentService.Unpublished += (sender, args) =>
|
||||
{
|
||||
foreach (var content in args.PublishedEntities)
|
||||
notificationService.SendNotification(content, ActionUnpublish.Instance);
|
||||
notificationService.SendNotification(content, actions.GetAction<ActionUnpublish>());
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Core.Sync;
|
||||
using Umbraco.Core._Legacy.PackageActions;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Cache;
|
||||
using Umbraco.Web.Editors;
|
||||
using Umbraco.Web.HealthCheck;
|
||||
@@ -27,7 +28,7 @@ using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
using Umbraco.Web.Routing;
|
||||
using Umbraco.Web.WebApi;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using CoreCurrent = Umbraco.Core.Composing.Current;
|
||||
|
||||
namespace Umbraco.Web.Composing
|
||||
|
||||
@@ -3,13 +3,13 @@ using LightInject;
|
||||
using Umbraco.Core.Composing;
|
||||
using Current = Umbraco.Web.Composing.Current;
|
||||
using Umbraco.Core.Macros;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Editors;
|
||||
using Umbraco.Web.HealthCheck;
|
||||
using Umbraco.Web.Media;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
using Umbraco.Web.Routing;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.ContentApps;
|
||||
|
||||
// the namespace here is intentional - although defined in Umbraco.Web assembly,
|
||||
|
||||
@@ -3,18 +3,15 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.UI;
|
||||
using LightInject;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Microsoft.AspNet.Identity.Owin;
|
||||
using Microsoft.Owin.Security;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Configuration;
|
||||
@@ -22,18 +19,13 @@ using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Manifest;
|
||||
using Umbraco.Core.Models.Identity;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.Mvc;
|
||||
|
||||
using Umbraco.Web.Trees;
|
||||
using Umbraco.Web.UI.JavaScript;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Features;
|
||||
using Umbraco.Web.Security;
|
||||
using Action = Umbraco.Web._Legacy.Actions.Action;
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
using JArray = Newtonsoft.Json.Linq.JArray;
|
||||
|
||||
@@ -197,11 +189,8 @@ namespace Umbraco.Web.Editors
|
||||
{
|
||||
var initJs = new JsInitialization(_manifestParser);
|
||||
var initCss = new CssInitialization(_manifestParser);
|
||||
|
||||
//get the legacy ActionJs file references to append as well
|
||||
var legacyActionJsRef = GetLegacyActionJs(LegacyJsActionType.JsUrl);
|
||||
|
||||
var files = initJs.OptimizeBackOfficeScriptFiles(HttpContext, JsInitialization.GetDefaultInitialization(), legacyActionJsRef);
|
||||
|
||||
var files = initJs.OptimizeBackOfficeScriptFiles(HttpContext, JsInitialization.GetDefaultInitialization());
|
||||
var result = JsInitialization.GetJavascriptInitialization(HttpContext, files, "umbraco");
|
||||
result += initCss.GetStylesheetInitialization(HttpContext);
|
||||
|
||||
@@ -519,50 +508,7 @@ namespace Umbraco.Web.Editors
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static IEnumerable<string> GetLegacyActionJsForActions(LegacyJsActionType type, IEnumerable<string> values)
|
||||
{
|
||||
var blockList = new List<string>();
|
||||
var urlList = new List<string>();
|
||||
foreach (var jsFile in values)
|
||||
{
|
||||
var isJsPath = jsFile.DetectIsJavaScriptPath();
|
||||
if (isJsPath.Success)
|
||||
|
||||
{
|
||||
urlList.Add(isJsPath.Result);
|
||||
}
|
||||
else
|
||||
{
|
||||
blockList.Add(isJsPath.Result);
|
||||
}
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case LegacyJsActionType.JsBlock:
|
||||
return blockList;
|
||||
case LegacyJsActionType.JsUrl:
|
||||
return urlList;
|
||||
}
|
||||
|
||||
return blockList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders out all JavaScript references that have been declared in IActions
|
||||
/// </summary>
|
||||
private static IEnumerable<string> GetLegacyActionJs(LegacyJsActionType type)
|
||||
{
|
||||
return GetLegacyActionJsForActions(type, Action.GetJavaScriptFileReferences());
|
||||
}
|
||||
|
||||
internal enum LegacyJsActionType
|
||||
{
|
||||
JsBlock,
|
||||
JsUrl
|
||||
}
|
||||
|
||||
|
||||
private ActionResult RedirectToLocal(string returnUrl)
|
||||
{
|
||||
if (Url.IsLocalUrl(returnUrl))
|
||||
|
||||
@@ -30,10 +30,11 @@ using Umbraco.Core.Models.Validation;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.WebServices;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
using Language = Umbraco.Web.Models.ContentEditing.Language;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.ContentApps;
|
||||
using Umbraco.Web.Editors.Binders;
|
||||
using Umbraco.Web.Editors.Filters;
|
||||
@@ -932,14 +933,14 @@ namespace Umbraco.Web.Editors
|
||||
var errMsg = Services.TextService.Localize(localizationKey, new[] { _allLangs.Value[culture].CultureName });
|
||||
ModelState.AddModelError(key, errMsg);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Publishes a document with a given ID
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// The CanAccessContentAuthorize attribute will deny access to this method if the current user
|
||||
/// The EnsureUserPermissionForContent attribute will deny access to this method if the current user
|
||||
/// does not have Publish access to this node.
|
||||
/// </remarks>
|
||||
///
|
||||
@@ -1077,7 +1078,7 @@ namespace Umbraco.Web.Editors
|
||||
|
||||
if (sorted.ParentId > 0)
|
||||
{
|
||||
Services.NotificationService.SendNotification(contentService.GetById(sorted.ParentId), ActionSort.Instance, UmbracoContext, Services.TextService, GlobalSettings);
|
||||
Services.NotificationService.SendNotification(contentService.GetById(sorted.ParentId), Current.Actions.GetAction<ActionSort>(), UmbracoContext, Services.TextService, GlobalSettings);
|
||||
}
|
||||
|
||||
return Request.CreateResponse(HttpStatusCode.OK);
|
||||
@@ -1224,7 +1225,7 @@ namespace Umbraco.Web.Editors
|
||||
|
||||
var permission = Services.UserService.GetPermissions(Security.CurrentUser, node.Path);
|
||||
|
||||
if (permission.AssignedPermissions.Contains(ActionAssignDomain.Instance.Letter.ToString(), StringComparer.Ordinal) == false)
|
||||
if (permission.AssignedPermissions.Contains(ActionAssignDomain.ActionLetter.ToString(), StringComparer.Ordinal) == false)
|
||||
{
|
||||
var response = Request.CreateResponse(HttpStatusCode.BadRequest);
|
||||
response.Content = new StringContent("You do not have permission to assign domains on that node.");
|
||||
@@ -1761,6 +1762,7 @@ namespace Umbraco.Web.Editors
|
||||
: content.Variants.FirstOrDefault(x => x.Language.IsoCode == culture);
|
||||
}
|
||||
|
||||
[EnsureUserPermissionForContent("contentId", ActionRollback.ActionLetter)]
|
||||
[HttpPost]
|
||||
public HttpResponseMessage PostRollbackContent(int contentId, int versionId, string culture = "*")
|
||||
{
|
||||
|
||||
@@ -9,11 +9,12 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Security;
|
||||
using Umbraco.Web.WebApi;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Editors.Filters
|
||||
{
|
||||
@@ -94,24 +95,24 @@ namespace Umbraco.Web.Editors.Filters
|
||||
switch (contentItem.Action)
|
||||
{
|
||||
case ContentSaveAction.Save:
|
||||
permissionToCheck.Add(ActionUpdate.Instance.Letter);
|
||||
permissionToCheck.Add(ActionUpdate.ActionLetter);
|
||||
contentToCheck = contentItem.PersistedContent;
|
||||
contentIdToCheck = contentToCheck.Id;
|
||||
break;
|
||||
case ContentSaveAction.Publish:
|
||||
permissionToCheck.Add(ActionPublish.Instance.Letter);
|
||||
permissionToCheck.Add(ActionPublish.ActionLetter);
|
||||
contentToCheck = contentItem.PersistedContent;
|
||||
contentIdToCheck = contentToCheck.Id;
|
||||
break;
|
||||
case ContentSaveAction.SendPublish:
|
||||
permissionToCheck.Add(ActionToPublish.Instance.Letter);
|
||||
permissionToCheck.Add(ActionToPublish.ActionLetter);
|
||||
contentToCheck = contentItem.PersistedContent;
|
||||
contentIdToCheck = contentToCheck.Id;
|
||||
break;
|
||||
case ContentSaveAction.SaveNew:
|
||||
//Save new requires ActionNew
|
||||
|
||||
permissionToCheck.Add(ActionNew.Instance.Letter);
|
||||
permissionToCheck.Add(ActionNew.ActionLetter);
|
||||
|
||||
if (contentItem.ParentId != Constants.System.Root)
|
||||
{
|
||||
@@ -126,8 +127,8 @@ namespace Umbraco.Web.Editors.Filters
|
||||
case ContentSaveAction.SendPublishNew:
|
||||
//Send new requires both ActionToPublish AND ActionNew
|
||||
|
||||
permissionToCheck.Add(ActionNew.Instance.Letter);
|
||||
permissionToCheck.Add(ActionToPublish.Instance.Letter);
|
||||
permissionToCheck.Add(ActionNew.ActionLetter);
|
||||
permissionToCheck.Add(ActionToPublish.ActionLetter);
|
||||
if (contentItem.ParentId != Constants.System.Root)
|
||||
{
|
||||
contentToCheck = _contentService.GetById(contentItem.ParentId);
|
||||
@@ -142,8 +143,8 @@ namespace Umbraco.Web.Editors.Filters
|
||||
//Publish new requires both ActionNew AND ActionPublish
|
||||
//TODO: Shoudn't publish also require ActionUpdate since it will definitely perform an update to publish but maybe that's just implied
|
||||
|
||||
permissionToCheck.Add(ActionNew.Instance.Letter);
|
||||
permissionToCheck.Add(ActionPublish.Instance.Letter);
|
||||
permissionToCheck.Add(ActionNew.ActionLetter);
|
||||
permissionToCheck.Add(ActionPublish.ActionLetter);
|
||||
|
||||
if (contentItem.ParentId != Constants.System.Root)
|
||||
{
|
||||
|
||||
@@ -6,8 +6,9 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Models.Mapping
|
||||
{
|
||||
@@ -37,13 +38,11 @@ namespace Umbraco.Web.Models.Mapping
|
||||
private Permission GetPermission(IAction action, IUserGroup source)
|
||||
{
|
||||
var result = new Permission();
|
||||
var attribute = action.GetType().GetCustomAttribute<ActionMetadataAttribute>(false);
|
||||
result.Category = attribute == null
|
||||
|
||||
result.Category = action.Category.IsNullOrWhiteSpace()
|
||||
? _textService.Localize($"actionCategories/{Constants.Conventions.PermissionCategories.OtherCategory}")
|
||||
: _textService.Localize($"actionCategories/{attribute.Category}");
|
||||
result.Name = attribute == null || attribute.Name.IsNullOrWhiteSpace()
|
||||
? _textService.Localize($"actions/{action.Alias}")
|
||||
: attribute.Name;
|
||||
: _textService.Localize($"actionCategories/{action.Category}");
|
||||
result.Name = _textService.Localize($"actions/{action.Alias}");
|
||||
result.Description = _textService.Localize($"actionDescriptions/{action.Alias}");
|
||||
result.Icon = action.Icon;
|
||||
result.Checked = source.Permissions != null && source.Permissions.Contains(action.Letter.ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
@@ -11,7 +11,8 @@ using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Models.Mapping
|
||||
{
|
||||
|
||||
@@ -1,41 +1,55 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
{
|
||||
/// <summary>
|
||||
/// A menu item that represents some JS that needs to execute when the menu item is clicked.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These types of menu items are rare but they do exist. Things like refresh node simply execute
|
||||
/// JS and don't launch a dialog.
|
||||
///
|
||||
/// Each action menu item describes what angular service that it's method exists in and what the method name is.
|
||||
///
|
||||
/// An action menu item must describe the angular service name for which it's method exists. It may also define what the
|
||||
/// method name is that will be called in this service but if one is not specified then we will assume the method name is the
|
||||
/// same as the Type name of the current action menu class.
|
||||
/// </remarks>
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// A menu item that represents some JS that needs to execute when the menu item is clicked.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These types of menu items are rare but they do exist. Things like refresh node simply execute
|
||||
/// JS and don't launch a dialog.
|
||||
/// Each action menu item describes what angular service that it's method exists in and what the method name is.
|
||||
/// An action menu item must describe the angular service name for which it's method exists. It may also define what the
|
||||
/// method name is that will be called in this service but if one is not specified then we will assume the method name is the
|
||||
/// same as the Type name of the current action menu class.
|
||||
/// </remarks>
|
||||
public abstract class ActionMenuItem : MenuItem
|
||||
{
|
||||
protected ActionMenuItem()
|
||||
: base()
|
||||
{
|
||||
var attribute = GetType().GetCustomAttribute<ActionMenuItemAttribute>(false);
|
||||
if (attribute == null)
|
||||
{
|
||||
throw new InvalidOperationException("All " + typeof (ActionMenuItem).FullName + " instances must be attributed with " + typeof (ActionMenuItemAttribute).FullName);
|
||||
}
|
||||
/// <summary>
|
||||
/// The angular service name containing the <see cref="AngularServiceMethodName"/>
|
||||
/// </summary>
|
||||
public abstract string AngularServiceName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The angular service method name to call for this menu item
|
||||
/// </summary>
|
||||
public virtual string AngularServiceMethodName { get; } = null;
|
||||
|
||||
protected ActionMenuItem(string alias, string name) : base(alias, name)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
protected ActionMenuItem(string alias, ILocalizedTextService textService) : base(alias, textService)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
//add the current type to the metadata
|
||||
if (attribute.MethodName.IsNullOrWhiteSpace())
|
||||
if (AngularServiceMethodName.IsNullOrWhiteSpace())
|
||||
{
|
||||
//if no method name is supplied we will assume that the menu action is the type name of the current menu class
|
||||
AdditionalData.Add("jsAction", string.Format("{0}.{1}", attribute.ServiceName, this.GetType().Name));
|
||||
ExecuteJsMethod($"{AngularServiceName}.{this.GetType().Name}");
|
||||
}
|
||||
else
|
||||
{
|
||||
AdditionalData.Add("jsAction", string.Format("{0}.{1}", attribute.ServiceName, attribute.MethodName));
|
||||
ExecuteJsMethod($"{AngularServiceName}.{AngularServiceMethodName}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
using System;
|
||||
using Umbraco.Core.Exceptions;
|
||||
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
{
|
||||
/// <summary>
|
||||
/// The attribute to assign to any ActionMenuItem objects.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public sealed class ActionMenuItemAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// This constructor defines both the angular service and method name to use
|
||||
/// </summary>
|
||||
/// <param name="serviceName"></param>
|
||||
/// <param name="methodName"></param>
|
||||
public ActionMenuItemAttribute(string serviceName, string methodName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(serviceName)) throw new ArgumentNullOrEmptyException(nameof(serviceName));
|
||||
if (string.IsNullOrWhiteSpace(methodName)) throw new ArgumentNullOrEmptyException(nameof(methodName));
|
||||
MethodName = methodName;
|
||||
ServiceName = serviceName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This constructor will assume that the method name equals the type name of the action menu class
|
||||
/// </summary>
|
||||
/// <param name="serviceName"></param>
|
||||
public ActionMenuItemAttribute(string serviceName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(serviceName)) throw new ArgumentNullOrEmptyException(nameof(serviceName));
|
||||
MethodName = "";
|
||||
ServiceName = serviceName;
|
||||
}
|
||||
|
||||
public string MethodName { get; }
|
||||
public string ServiceName { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,27 @@
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the refresh node menu item
|
||||
/// </summary>
|
||||
[ActionMenuItem("umbracoMenuActions")]
|
||||
public sealed class CreateChildEntity : ActionMenuItem
|
||||
{
|
||||
public override string AngularServiceName => "umbracoMenuActions";
|
||||
|
||||
public CreateChildEntity(string name, bool seperatorBefore = false)
|
||||
: base(ActionNew.ActionAlias, name)
|
||||
{
|
||||
Icon = "add"; Name = name;
|
||||
SeperatorBefore = seperatorBefore;
|
||||
}
|
||||
|
||||
public CreateChildEntity(ILocalizedTextService textService, bool seperatorBefore = false)
|
||||
: base(ActionNew.ActionAlias, textService)
|
||||
{
|
||||
Icon = "add";
|
||||
SeperatorBefore = seperatorBefore;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the disable user menu item
|
||||
/// </summary>
|
||||
[ActionMenuItem("umbracoMenuActions")]
|
||||
public sealed class DisableUser : ActionMenuItem
|
||||
{
|
||||
public DisableUser()
|
||||
{
|
||||
Alias = "disable";
|
||||
Icon = "remove";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,17 @@
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the export member menu item
|
||||
/// </summary>
|
||||
[ActionMenuItem("umbracoMenuActions")]
|
||||
public sealed class ExportMember : ActionMenuItem
|
||||
{ }
|
||||
{
|
||||
public override string AngularServiceName => "umbracoMenuActions";
|
||||
|
||||
public ExportMember(ILocalizedTextService textService) : base("export", textService)
|
||||
{
|
||||
Icon = "download-alt";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,9 @@ using System.Collections.Generic;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
{
|
||||
@@ -30,15 +31,27 @@ namespace Umbraco.Web.Models.Trees
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public MenuItem(IAction legacyMenu, string name = "")
|
||||
|
||||
public MenuItem(string alias, ILocalizedTextService textService)
|
||||
: this()
|
||||
{
|
||||
Name = name.IsNullOrWhiteSpace() ? legacyMenu.Alias : name;
|
||||
Alias = legacyMenu.Alias;
|
||||
Alias = alias;
|
||||
Name = textService.Localize($"actions/{Alias}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a menu item based on an <see cref="IAction"/> definition
|
||||
/// </summary>
|
||||
/// <param name="action"></param>
|
||||
/// <param name="name"></param>
|
||||
public MenuItem(IAction action, string name = "")
|
||||
: this()
|
||||
{
|
||||
Name = name.IsNullOrWhiteSpace() ? action.Alias : name;
|
||||
Alias = action.Alias;
|
||||
SeperatorBefore = false;
|
||||
Icon = legacyMenu.Icon;
|
||||
Action = legacyMenu;
|
||||
OpensDialog = legacyMenu.OpensDialog;
|
||||
Icon = action.Icon;
|
||||
Action = action;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -73,6 +86,9 @@ namespace Umbraco.Web.Models.Trees
|
||||
[DataMember(Name = "cssclass")]
|
||||
public string Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Used in the UI to inform the user that the menu item will open a dialog/confirmation
|
||||
/// </summary>
|
||||
[DataMember(Name = "opensDialog")]
|
||||
public bool OpensDialog { get; set; }
|
||||
|
||||
@@ -128,7 +144,7 @@ namespace Umbraco.Web.Models.Trees
|
||||
/// Adds the required meta data to the menu item so that angular knows to attempt to call the Js method.
|
||||
/// </summary>
|
||||
/// <param name="jsToExecute"></param>
|
||||
public void ExecuteLegacyJs(string jsToExecute)
|
||||
public void ExecuteJsMethod(string jsToExecute)
|
||||
{
|
||||
SetJsAction(jsToExecute);
|
||||
}
|
||||
@@ -206,7 +222,7 @@ namespace Umbraco.Web.Models.Trees
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
{
|
||||
@@ -24,7 +26,7 @@ namespace Umbraco.Web.Models.Trees
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a menu item
|
||||
/// Adds a menu item based on a <see cref="IAction"/>
|
||||
/// </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>
|
||||
@@ -32,78 +34,20 @@ namespace Umbraco.Web.Models.Trees
|
||||
{
|
||||
var item = new MenuItem(action, name);
|
||||
|
||||
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.Name,
|
||||
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)
|
||||
/// <param name="name">The text to display for the menu item, will default to the IAction alias if not specified</param>
|
||||
public MenuItem Add<T>(string name, bool hasSeparator = false)
|
||||
where T : IAction
|
||||
{
|
||||
var item = CreateMenuItem<T>(name, hasSeparator, additionalData);
|
||||
var item = CreateMenuItem<T>(name, hasSeparator);
|
||||
if (item != null)
|
||||
{
|
||||
Add(item);
|
||||
@@ -113,69 +57,51 @@ namespace Umbraco.Web.Models.Trees
|
||||
}
|
||||
|
||||
/// <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>
|
||||
/// <returns></returns>
|
||||
internal MenuItem CreateMenuItem<T>(string name, bool hasSeparator = false, IDictionary<string, object> additionalData = null)
|
||||
/// <param name="textService">The <see cref="ILocalizedTextService"/> used to localize the action name based on it's alias</param>
|
||||
/// <param name="opensDialog"></param>
|
||||
public MenuItem Add<T>(ILocalizedTextService textService, bool hasSeparator = false, bool opensDialog = false)
|
||||
where T : IAction
|
||||
{
|
||||
var item = Current.Actions.GetAction<T>();
|
||||
var item = CreateMenuItem<T>(textService, hasSeparator);
|
||||
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;
|
||||
Add(item);
|
||||
return item;
|
||||
}
|
||||
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)
|
||||
|
||||
internal MenuItem CreateMenuItem<T>(string name, bool hasSeparator = false)
|
||||
where T : IAction
|
||||
{
|
||||
//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)
|
||||
var item = Current.Actions.GetAction<T>();
|
||||
if (item == null) return null;
|
||||
var menuItem = new MenuItem(item, name)
|
||||
{
|
||||
//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(MenuItem.JsActionKey, string.Format("{0}.{1}", attribute.ServiceName, this.GetType().Name));
|
||||
}
|
||||
else
|
||||
{
|
||||
menuItem.AdditionalData.Add(MenuItem.JsActionKey, string.Format("{0}.{1}", attribute.ServiceName, attribute.MethodName));
|
||||
}
|
||||
}
|
||||
SeperatorBefore = hasSeparator
|
||||
};
|
||||
|
||||
return menuItem;
|
||||
}
|
||||
|
||||
internal MenuItem CreateMenuItem<T>(ILocalizedTextService textService, bool hasSeparator = false, bool opensDialog = false)
|
||||
where T : IAction
|
||||
{
|
||||
var item = Current.Actions.GetAction<T>();
|
||||
if (item == null) return null;
|
||||
|
||||
var menuItem = new MenuItem(item, textService.Localize($"actions/{item.Alias}"))
|
||||
{
|
||||
SeperatorBefore = hasSeparator,
|
||||
OpensDialog = opensDialog
|
||||
};
|
||||
|
||||
return menuItem;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,27 @@
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Represents the refresh node menu item
|
||||
/// </summary>
|
||||
[ActionMenuItem("umbracoMenuActions")]
|
||||
public sealed class RefreshNode : ActionMenuItem
|
||||
{
|
||||
public override string AngularServiceName => "umbracoMenuActions";
|
||||
|
||||
public RefreshNode(string name, bool seperatorBefore = false)
|
||||
: base("refreshNode", name)
|
||||
{
|
||||
Icon = "refresh";
|
||||
SeperatorBefore = seperatorBefore;
|
||||
}
|
||||
|
||||
public RefreshNode(ILocalizedTextService textService, bool seperatorBefore = false)
|
||||
: base("refreshNode", textService)
|
||||
{
|
||||
Icon = "refresh";
|
||||
SeperatorBefore = seperatorBefore;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,10 @@ using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Composing;
|
||||
|
||||
namespace Umbraco.Web
|
||||
|
||||
@@ -31,6 +31,6 @@ namespace Umbraco.Web.PropertyEditors
|
||||
protected override IConfigurationEditor CreateConfigurationEditor() => new ValueListConfigurationEditor(_textService);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IDataValueEditor CreateValueEditor() => new PublishValuesMultipleValueEditor(false, Attribute);
|
||||
protected override IDataValueEditor CreateValueEditor() => new PublishValuesMultipleValueEditor(Logger, Attribute);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
|
||||
protected override IDataValueEditor CreateValueEditor()
|
||||
{
|
||||
return new PublishValuesMultipleValueEditor(false, Attribute);
|
||||
return new PublishValuesMultipleValueEditor(Logger, Attribute);
|
||||
}
|
||||
|
||||
protected override IConfigurationEditor CreateConfigurationEditor() => new DropDownFlexibleConfigurationEditor(_textService);
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a configuration editor for the "drop down list multiple" property editor.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Ensures that 'multiple' is saved for the config in the db but is not a configuration field.</para>
|
||||
/// <para>This is mostly to maintain backwards compatibility with old property editors. Devs can now simply
|
||||
/// use the "drop down" property editor and check the "multiple" configuration checkbox</para>
|
||||
/// <para>fixme what is multiple exactly?!</para>
|
||||
/// </remarks>
|
||||
internal class DropDownMultipleConfigurationEditor : ValueListConfigurationEditor
|
||||
{
|
||||
public DropDownMultipleConfigurationEditor(ILocalizedTextService textService)
|
||||
: base(textService)
|
||||
{
|
||||
Fields.Add(new ConfigurationField
|
||||
{
|
||||
Key = "multiple",
|
||||
Name = "multiple",
|
||||
View = "hidden", // so it does not show in the configuration editor
|
||||
HideLabel = true
|
||||
});
|
||||
}
|
||||
|
||||
// editor...
|
||||
//
|
||||
// receives:
|
||||
// "preValues":[
|
||||
// {
|
||||
// "label":"Add prevalue",
|
||||
// "description":"Add and remove values for the list",
|
||||
// "hideLabel":false,
|
||||
// "view":"multivalues",
|
||||
// "config":{},
|
||||
// "key":"items",
|
||||
// "value":{"169":{"value":"a","sortOrder":1},"170":{"value":"b","sortOrder":2},"171":{"value":"c","sortOrder":3}}
|
||||
// },
|
||||
// {
|
||||
// "label":"multiple",
|
||||
// "description":null,
|
||||
// "hideLabel":true,
|
||||
// "view":"hidden",
|
||||
// "config":{},
|
||||
// "key":"multiple",
|
||||
// "value":"1"
|
||||
// }]
|
||||
//
|
||||
// posts ('d' being a new value):
|
||||
// [{key: "items", value: [{value: "a", sortOrder: 1, id: "169"}, {value: "c", sortOrder: 3, id: "171"}, {value: "d"}]}, {key: "multiple", value: "1"}]
|
||||
//
|
||||
// the 'multiple' thing never goes to DB
|
||||
// values go to DB with alias 0, 1, 2 + their ID + value
|
||||
// the sort order that comes back makes no sense
|
||||
//
|
||||
// FromEditor can totally ignore 'multiple'
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Dictionary<string, object> ToConfigurationEditor(ValueListConfiguration configuration)
|
||||
{
|
||||
var dictionary = base.ToConfigurationEditor(configuration);
|
||||
|
||||
// always add the multiple field, as 'true'
|
||||
dictionary["multiple"] = 1;
|
||||
|
||||
return dictionary;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// A property editor to allow multiple selection of pre-defined items
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Due to maintaining backwards compatibility this data type stores the value as a string which is a comma separated value of the
|
||||
/// ids of the individual items so we have logic in here to deal with that.
|
||||
/// </remarks>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.DropDownListMultiple, "Dropdown list multiple", "dropdown", Group = "lists", Icon="icon-bulleted-list", IsDeprecated = true)]
|
||||
public class DropDownMultiplePropertyEditor : DropDownMultipleWithKeysPropertyEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// The constructor will setup the property editor based on the attribute if one is found
|
||||
/// </summary>
|
||||
public DropDownMultiplePropertyEditor(ILogger logger, ILocalizedTextService textService)
|
||||
: base(logger, textService)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IDataValueEditor CreateValueEditor() => new PublishValuesMultipleValueEditor(false, Attribute);
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a property editor that allows multiple selection of pre-defined items.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Due to backwards compatibility, this editor stores the value as a CSV string listing
|
||||
/// the ids of individual items.
|
||||
/// </remarks>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.DropdownlistMultiplePublishKeys, "Dropdown list multiple, publish keys", "dropdown", Group = "lists", Icon = "icon-bulleted-list", IsDeprecated = true)]
|
||||
public class DropDownMultipleWithKeysPropertyEditor : DropDownPropertyEditor
|
||||
{
|
||||
private readonly ILocalizedTextService _textService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DropDownMultiplePropertyEditor"/> class.
|
||||
/// </summary>
|
||||
public DropDownMultipleWithKeysPropertyEditor(ILogger logger, ILocalizedTextService textService)
|
||||
: base(logger, textService)
|
||||
{
|
||||
_textService = textService;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IDataValueEditor CreateValueEditor() => new PublishValuesMultipleValueEditor(true, Attribute);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IConfigurationEditor CreateConfigurationEditor() => new DropDownMultipleConfigurationEditor(_textService);
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using umbraco;
|
||||
using ClientDependency.Core;
|
||||
using Umbraco.Core.Services;
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// A property editor to allow the individual selection of pre-defined items.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Due to remaining backwards compatible, this stores the id of the drop down item in the database which is why it is marked
|
||||
/// as INT and we have logic in here to ensure it is formatted correctly including ensuring that the string value is published
|
||||
/// in cache and not the int ID.
|
||||
/// </remarks>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.DropDownList, "Dropdown list", "dropdown", ValueType = ValueTypes.String, Group = "lists", Icon = "icon-indent", IsDeprecated = true)]
|
||||
public class DropDownPropertyEditor : DropDownWithKeysPropertyEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// The constructor will setup the property editor based on the attribute if one is found
|
||||
/// </summary>
|
||||
public DropDownPropertyEditor(ILogger logger, ILocalizedTextService textService)
|
||||
: base(logger, textService)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// We need to override the value editor so that we can ensure the string value is published in cache and not the integer ID value.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override IDataValueEditor CreateValueEditor() => new PublishValueValueEditor(Attribute, Logger);
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// A property editor to allow the individual selection of pre-defined items.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Due to remaining backwards compatible, this stores the id of the drop down item in the database which is why it is marked
|
||||
/// as INT and we have logic in here to ensure it is formatted correctly including ensuring that the INT ID value is published
|
||||
/// in cache and not the string value.
|
||||
/// </remarks>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.DropdownlistPublishKeys, "Dropdown list, publishing keys", "dropdown", ValueType = ValueTypes.Integer, Group = "lists", Icon = "icon-indent", IsDeprecated = true)]
|
||||
public class DropDownWithKeysPropertyEditor : DataEditor
|
||||
{
|
||||
private readonly ILocalizedTextService _textService;
|
||||
|
||||
/// <summary>
|
||||
/// The constructor will setup the property editor based on the attribute if one is found
|
||||
/// </summary>
|
||||
public DropDownWithKeysPropertyEditor(ILogger logger, ILocalizedTextService textService)
|
||||
: base(logger)
|
||||
{
|
||||
_textService = textService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a custom pre-value editor
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override IConfigurationEditor CreateConfigurationEditor() => new ValueListConfigurationEditor(_textService);
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Composing;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// A custom value editor for any property editor that stores a pre-value int id so that we can ensure that the 'value' not the ID get's put into cache
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is required for legacy/backwards compatibility, otherwise we'd just store the string version and cache the string version without
|
||||
/// needing additional lookups.
|
||||
/// </remarks>
|
||||
internal class PublishValueValueEditor : DataValueEditor
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
internal PublishValueValueEditor(DataEditorAttribute attribute, ILogger logger)
|
||||
: base(attribute)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ConvertDbToString(PropertyType propertyType, object value, IDataTypeService dataTypeService)
|
||||
{
|
||||
if (value == null)
|
||||
return null;
|
||||
|
||||
// get the configuration items
|
||||
// if none, fallback to base
|
||||
var configuration = dataTypeService.GetDataType(propertyType.DataTypeId).ConfigurationAs<ValueListConfiguration>();
|
||||
if (configuration == null)
|
||||
return base.ConvertDbToString(propertyType, value, dataTypeService);
|
||||
|
||||
var items = configuration.Items;
|
||||
|
||||
var idAttempt = value.TryConvertTo<int>();
|
||||
if (idAttempt.Success)
|
||||
{
|
||||
var itemId = idAttempt.Result;
|
||||
var item = items.FirstOrDefault(x => x.Id == itemId);
|
||||
if (item != null) return item.Value;
|
||||
|
||||
_logger.Warn<PublishValueValueEditor>("Could not find a configuration item with ID " + itemId + " for property alias " + propertyType.Alias);
|
||||
}
|
||||
|
||||
// fallback to default
|
||||
return base.ConvertDbToString(propertyType, value, dataTypeService);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,58 +11,19 @@ using Umbraco.Web.Composing;
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// Custom value editor to handle posted json data and to return json data for the multiple selected items as well as ensuring
|
||||
/// that the multiple selected int IDs are published to cache as a delimited string (values)
|
||||
/// Custom value editor to handle posted json data and to return json data for the multiple selected items
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is re-used by editors such as the multiple drop down list or check box list
|
||||
/// </remarks>
|
||||
internal class PublishValuesMultipleValueEditor : PublishValueValueEditor
|
||||
internal class PublishValuesMultipleValueEditor : DataValueEditor
|
||||
{
|
||||
private readonly bool _publishIds;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
internal PublishValuesMultipleValueEditor(bool publishIds, ILogger logger, DataEditorAttribute attribute)
|
||||
: base(attribute, logger)
|
||||
internal PublishValuesMultipleValueEditor(ILogger logger, DataEditorAttribute attribute)
|
||||
: base(attribute)
|
||||
{
|
||||
_publishIds = publishIds;
|
||||
}
|
||||
|
||||
public PublishValuesMultipleValueEditor(bool publishIds, DataEditorAttribute attribute)
|
||||
: this(publishIds, Current.Logger, attribute)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// If publishing ids, we don't need to do anything, otherwise we need to look up the pre-values and get the string values
|
||||
/// </summary>
|
||||
/// <param name="propertyType"></param>
|
||||
/// <param name="propertyValue"></param>
|
||||
/// <param name="dataTypeService"></param>
|
||||
/// <returns></returns>
|
||||
public override string ConvertDbToString(PropertyType propertyType, object propertyValue, IDataTypeService dataTypeService)
|
||||
{
|
||||
if (propertyValue == null)
|
||||
return null;
|
||||
|
||||
//publishing ids, so just need to return the value as-is
|
||||
if (_publishIds)
|
||||
{
|
||||
return propertyValue.ToString();
|
||||
}
|
||||
|
||||
// get the multiple ids
|
||||
// if none, fallback to base
|
||||
var selectedIds = propertyValue.ToString().Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (selectedIds.Any() == false)
|
||||
return base.ConvertDbToString(propertyType, propertyValue, dataTypeService);
|
||||
|
||||
// get the configuration items
|
||||
// if none, fallback to base
|
||||
var configuration = dataTypeService.GetDataType(propertyType.DataTypeId).ConfigurationAs<ValueListConfiguration>();
|
||||
if (configuration == null)
|
||||
return base.ConvertDbToString(propertyType, propertyValue, dataTypeService);
|
||||
|
||||
var items = configuration.Items.Where(x => selectedIds.Contains(x.Id.ToInvariantString())).Select(x => x.Value);
|
||||
return string.Join(",", items);
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -81,7 +42,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
|
||||
/// <summary>
|
||||
/// When multiple values are selected a json array will be posted back so we need to format for storage in
|
||||
/// the database which is a comma separated ID value
|
||||
/// the database which is a comma separated string value
|
||||
/// </summary>
|
||||
/// <param name="editorValue"></param>
|
||||
/// <param name="currentValue"></param>
|
||||
|
||||
@@ -8,19 +8,24 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// A property editor to allow the individual selection of pre-defined items.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Due to remaining backwards compatible, this stores the id of the item in the database which is why it is marked
|
||||
/// as INT and we have logic in here to ensure it is formatted correctly including ensuring that the INT ID value is published
|
||||
/// in cache and not the string value.
|
||||
/// </remarks>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.RadioButtonList, "Radio button list", "radiobuttons", ValueType = ValueTypes.Integer, Group="lists", Icon="icon-target")]
|
||||
public class RadioButtonsPropertyEditor : DropDownWithKeysPropertyEditor
|
||||
public class RadioButtonsPropertyEditor : DataEditor
|
||||
{
|
||||
private readonly ILocalizedTextService _textService;
|
||||
|
||||
/// <summary>
|
||||
/// The constructor will setup the property editor based on the attribute if one is found
|
||||
/// </summary>
|
||||
public RadioButtonsPropertyEditor(ILogger logger, ILocalizedTextService textService)
|
||||
: base(logger, textService)
|
||||
{ }
|
||||
: base(logger)
|
||||
{
|
||||
_textService = textService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a custom pre-value editor
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override IConfigurationEditor CreateConfigurationEditor() => new ValueListConfigurationEditor(_textService);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
@@ -16,7 +17,8 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
|
||||
public override object ConvertSourceToIntermediate(IPublishedElement owner, PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
return source?.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
return source?.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => v.Trim()).ToArray()
|
||||
?? Enumerable.Empty<string>();
|
||||
}
|
||||
|
||||
public override object ConvertIntermediateToObject(IPublishedElement owner, PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
|
||||
@@ -31,6 +31,7 @@ using Umbraco.Core.PropertyEditors.ValueConverters;
|
||||
using Umbraco.Core.Runtime;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Examine;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Cache;
|
||||
using Umbraco.Web.Composing.CompositionRoots;
|
||||
using Umbraco.Web.ContentApps;
|
||||
@@ -53,7 +54,7 @@ using Umbraco.Web.Tour;
|
||||
using Umbraco.Web.Trees;
|
||||
using Umbraco.Web.UI.JavaScript;
|
||||
using Umbraco.Web.WebApi;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Current = Umbraco.Web.Composing.Current;
|
||||
|
||||
namespace Umbraco.Web.Runtime
|
||||
@@ -139,7 +140,7 @@ namespace Umbraco.Web.Runtime
|
||||
Current.DefaultRenderMvcControllerType = typeof(RenderMvcController); // fixme WRONG!
|
||||
|
||||
composition.Container.RegisterCollectionBuilder<ActionCollectionBuilder>()
|
||||
.SetProducer(() => typeLoader.GetActions());
|
||||
.Add(() => typeLoader.GetTypes<IAction>());
|
||||
|
||||
var surfaceControllerTypes = new SurfaceControllerTypeCollection(typeLoader.GetSurfaceControllers());
|
||||
composition.Container.RegisterInstance(surfaceControllerTypes);
|
||||
|
||||
@@ -4,10 +4,11 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
@@ -92,9 +93,8 @@ namespace Umbraco.Web.Trees
|
||||
if (id == Constants.System.Root.ToInvariantString())
|
||||
{
|
||||
// root actions
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"));
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(
|
||||
$"actions/{ActionRefresh.Instance.Alias}"), true);
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
var cte = Services.EntityService.Get(int.Parse(id), UmbracoObjectTypes.DocumentType);
|
||||
@@ -102,15 +102,15 @@ namespace Umbraco.Web.Trees
|
||||
if (cte != null)
|
||||
{
|
||||
var ct = Services.ContentTypeService.Get(cte.Id);
|
||||
var createItem = menu.Items.Add<ActionCreateBlueprintFromContent>(Services.TextService.Localize($"actions/{ActionCreateBlueprintFromContent.Instance.Alias}"));
|
||||
var createItem = menu.Items.Add<ActionCreateBlueprintFromContent>(Services.TextService, opensDialog: true);
|
||||
createItem.NavigateToRoute("/settings/contentBlueprints/edit/-1?create=true&doctype=" + ct.Alias);
|
||||
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize($"actions/{ActionRefresh.Instance.Alias}"), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}"));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -8,11 +8,12 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Search;
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
@@ -114,23 +115,21 @@ namespace Umbraco.Web.Trees
|
||||
// if the user's start node is not the root then the only menu item to display is refresh
|
||||
if (UserStartNodes.Contains(Constants.System.Root) == false)
|
||||
{
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(
|
||||
Services.TextService.Localize(string.Concat("actions/", ActionRefresh.Instance.Alias)),
|
||||
true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
|
||||
// we need to get the default permissions as you can't set permissions on the very root node
|
||||
var permission = Services.UserService.GetPermissions(Security.CurrentUser, Constants.System.Root).First();
|
||||
var nodeActions = global::Umbraco.Web._Legacy.Actions.Action.FromEntityPermission(permission)
|
||||
var nodeActions = Current.Actions.FromEntityPermission(permission)
|
||||
.Select(x => new MenuItem(x));
|
||||
|
||||
//these two are the standard items
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize("actions", ActionNew.Instance.Alias));
|
||||
menu.Items.Add<ActionSort>(Services.TextService.Localize("actions", ActionSort.Instance.Alias), true);
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add<ActionSort>(Services.TextService, true);
|
||||
|
||||
//filter the standard items
|
||||
FilterUserAllowedMenuItems(menu, nodeActions);
|
||||
@@ -143,7 +142,7 @@ namespace Umbraco.Web.Trees
|
||||
// add default actions for *all* users
|
||||
// fixme - temp disable RePublish as the page itself (republish.aspx) has been temp disabled
|
||||
//menu.Items.Add<ActionRePublish>(Services.TextService.Localize("actions", ActionRePublish.Instance.Alias)).ConvertLegacyMenuItem(null, "content", "content");
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
@@ -165,9 +164,7 @@ namespace Umbraco.Web.Trees
|
||||
if (Security.CurrentUser.HasPathAccess(item, Services.EntityService, RecycleBinId) == false)
|
||||
{
|
||||
var menu = new MenuItemCollection();
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(
|
||||
Services.TextService.Localize(string.Concat("actions/", ActionRefresh.Instance.Alias)),
|
||||
true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -182,7 +179,7 @@ namespace Umbraco.Web.Trees
|
||||
else
|
||||
{
|
||||
//set the default to create
|
||||
nodeMenu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
nodeMenu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
}
|
||||
|
||||
var allowedMenuItems = GetAllowedUserMenuItemsForNode(item);
|
||||
@@ -228,25 +225,25 @@ namespace Umbraco.Web.Trees
|
||||
protected MenuItemCollection GetAllNodeMenuItems(IUmbracoEntity item)
|
||||
{
|
||||
var menu = new MenuItemCollection();
|
||||
AddActionNode<ActionNew>(item, menu);
|
||||
AddActionNode<ActionDelete>(item, menu);
|
||||
|
||||
AddActionNode<ActionCreateBlueprintFromContent>(item, menu);
|
||||
|
||||
//need to ensure some of these are converted to the legacy system - until we upgrade them all to be angularized.
|
||||
AddActionNode<ActionMove>(item, menu, true);
|
||||
AddActionNode<ActionCopy>(item, menu);
|
||||
|
||||
AddActionNode<ActionNew>(item, menu, opensDialog: true);
|
||||
AddActionNode<ActionDelete>(item, menu, opensDialog: true);
|
||||
AddActionNode<ActionCreateBlueprintFromContent>(item, menu, opensDialog: true);
|
||||
AddActionNode<ActionMove>(item, menu, true, opensDialog: true);
|
||||
AddActionNode<ActionCopy>(item, menu, opensDialog: true);
|
||||
AddActionNode<ActionSort>(item, menu, true);
|
||||
AddActionNode<ActionAssignDomain>(item, menu, opensDialog: true);
|
||||
AddActionNode<ActionRights>(item, menu, opensDialog: true);
|
||||
//fixme - conver this editor to angular
|
||||
AddActionNode<ActionProtect>(item, menu, true, convert: true, opensDialog: true);
|
||||
|
||||
AddActionNode<ActionToPublish>(item, menu, convert: true);
|
||||
AddActionNode<ActionAssignDomain>(item, menu);
|
||||
AddActionNode<ActionRights>(item, menu, convert: true);
|
||||
AddActionNode<ActionProtect>(item, menu, true, true);
|
||||
|
||||
AddActionNode<ActionNotify>(item, menu, true);
|
||||
menu.Items.Add(new MenuItem("notify", Services.TextService)
|
||||
{
|
||||
Icon = "megaphone",
|
||||
SeperatorBefore = true,
|
||||
OpensDialog = true
|
||||
});
|
||||
|
||||
AddActionNode<RefreshNode, ActionRefresh>(item, menu, true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
@@ -259,10 +256,10 @@ namespace Umbraco.Web.Trees
|
||||
protected MenuItemCollection GetNodeMenuItemsForDeletedContent(IUmbracoEntity item)
|
||||
{
|
||||
var menu = new MenuItemCollection();
|
||||
menu.Items.Add<ActionRestore>(Services.TextService.Localize("actions", ActionRestore.Instance.Alias));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize("actions", ActionDelete.Instance.Alias));
|
||||
menu.Items.Add<ActionRestore>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
@@ -306,19 +303,14 @@ namespace Umbraco.Web.Trees
|
||||
entity.Name = "[[" + entity.Id + "]]";
|
||||
}
|
||||
|
||||
private void AddActionNode<TAction>(IUmbracoEntity item, MenuItemCollection menu, bool hasSeparator = false, bool convert = false)
|
||||
//fixme: Remove the need for converting to legacy
|
||||
private void AddActionNode<TAction>(IUmbracoEntity item, MenuItemCollection menu, bool hasSeparator = false, bool convert = false, bool opensDialog = false)
|
||||
where TAction : IAction
|
||||
{
|
||||
//fixme: Inject
|
||||
var menuItem = menu.Items.Add<TAction>(Services.TextService.Localize("actions", Current.Actions.GetAction<TAction>().Alias), hasSeparator);
|
||||
if (convert) menuItem.ConvertLegacyMenuItem(item, "content", "content");
|
||||
}
|
||||
|
||||
private void AddActionNode<TItem, TAction>(IUmbracoEntity item, MenuItemCollection menu, bool hasSeparator = false, bool convert = false)
|
||||
where TItem : MenuItem, new()
|
||||
where TAction : IAction
|
||||
{
|
||||
var menuItem = menu.Items.Add<TItem, TAction>(Services.TextService.Localize("actions", Current.Actions.GetAction<TAction>().Alias), hasSeparator);
|
||||
if (convert) menuItem.ConvertLegacyMenuItem(item, "content", "content");
|
||||
menuItem.OpensDialog = opensDialog;
|
||||
}
|
||||
|
||||
public IEnumerable<SearchResultItem> Search(string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null)
|
||||
|
||||
@@ -14,7 +14,9 @@ using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using System.Globalization;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Composing;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
{
|
||||
@@ -347,8 +349,12 @@ namespace Umbraco.Web.Trees
|
||||
if (RecycleBinId.ToInvariantString() == id)
|
||||
{
|
||||
var menu = new MenuItemCollection();
|
||||
menu.Items.Add<ActionEmptyTranscan>(Services.TextService.Localize("actions/emptyTrashcan"));
|
||||
menu.Items.Add<ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add(new MenuItem("emptyRecycleBin", Services.TextService)
|
||||
{
|
||||
Icon = "trash",
|
||||
OpensDialog = true
|
||||
});
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -381,13 +387,16 @@ namespace Umbraco.Web.Trees
|
||||
internal IEnumerable<MenuItem> GetAllowedUserMenuItemsForNode(IUmbracoEntity dd)
|
||||
{
|
||||
var permission = Services.UserService.GetPermissions(Security.CurrentUser, dd.Path);
|
||||
var actions = global::Umbraco.Web._Legacy.Actions.Action.FromEntityPermission(permission)
|
||||
//fixme: inject
|
||||
var actions = Current.Actions.FromEntityPermission(permission)
|
||||
.ToList();
|
||||
|
||||
var actionDelete = Current.Actions.GetAction<ActionDelete>();
|
||||
|
||||
// A user is allowed to delete their own stuff
|
||||
var tryGetCurrentUserId = Security.GetUserId();
|
||||
if (tryGetCurrentUserId && dd.CreatorId == tryGetCurrentUserId.Result && actions.Contains(ActionDelete.Instance) == false)
|
||||
actions.Add(ActionDelete.Instance);
|
||||
if (tryGetCurrentUserId && dd.CreatorId == tryGetCurrentUserId.Result && actions.Contains(actionDelete) == false)
|
||||
actions.Add(actionDelete);
|
||||
|
||||
return actions.Select(x => new MenuItem(x));
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
@@ -77,12 +78,18 @@ namespace Umbraco.Web.Trees
|
||||
if (id == Constants.System.Root.ToInvariantString())
|
||||
{
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
|
||||
// root actions
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
|
||||
menu.Items.Add<ActionImport>(Services.TextService.Localize(string.Format("actions/{0}", ActionImport.Instance.Alias)), true);
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add(new MenuItem("importDocumentType", Services.TextService)
|
||||
{
|
||||
Icon = "page-up",
|
||||
SeperatorBefore = true,
|
||||
OpensDialog = true
|
||||
});
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -90,11 +97,11 @@ namespace Umbraco.Web.Trees
|
||||
if (container != null)
|
||||
{
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
|
||||
menu.Items.Add(new MenuItem("rename", Services.TextService.Localize(String.Format("actions/{0}", "rename")))
|
||||
menu.Items.Add(new MenuItem("rename", Services.TextService)
|
||||
{
|
||||
Icon = "icon icon-edit"
|
||||
});
|
||||
@@ -102,11 +109,9 @@ namespace Umbraco.Web.Trees
|
||||
if (container.HasChildren == false)
|
||||
{
|
||||
//can delete doc type
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)), true);
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, true, opensDialog: true);
|
||||
}
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
|
||||
|
||||
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -115,18 +120,23 @@ namespace Umbraco.Web.Trees
|
||||
|
||||
if (enableInheritedDocumentTypes)
|
||||
{
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
}
|
||||
//no move action if this is a child doc type
|
||||
if (parent == null)
|
||||
{
|
||||
menu.Items.Add<ActionMove>(Services.TextService.Localize(string.Format("actions/{0}", ActionMove.Instance.Alias)), true);
|
||||
menu.Items.Add<ActionMove>(Services.TextService, true, opensDialog: true);
|
||||
}
|
||||
menu.Items.Add<ActionCopy>(Services.TextService.Localize(string.Format("actions/{0}", ActionCopy.Instance.Alias)));
|
||||
menu.Items.Add<ActionExport>(Services.TextService.Localize(string.Format("actions/{0}", ActionExport.Instance.Alias)), true);
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)), true);
|
||||
menu.Items.Add<ActionCopy>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add(new MenuItem("export", Services.TextService)
|
||||
{
|
||||
Icon = "download-alt",
|
||||
SeperatorBefore = true,
|
||||
OpensDialog = true
|
||||
});
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, true, opensDialog: true);
|
||||
if (enableInheritedDocumentTypes)
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
}
|
||||
|
||||
return menu;
|
||||
|
||||
@@ -9,9 +9,10 @@ using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Search;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
@@ -100,11 +101,11 @@ namespace Umbraco.Web.Trees
|
||||
if (id == Constants.System.Root.ToInvariantString())
|
||||
{
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
|
||||
// root actions
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"));
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -112,9 +113,9 @@ namespace Umbraco.Web.Trees
|
||||
if (container != null)
|
||||
{
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"));
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
|
||||
menu.Items.Add(new MenuItem("rename", Services.TextService.Localize("actions/rename"))
|
||||
{
|
||||
@@ -124,19 +125,18 @@ namespace Umbraco.Web.Trees
|
||||
if (container.HasChildren == false)
|
||||
{
|
||||
//can delete data type
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}"));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
}
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(
|
||||
$"actions/{ActionRefresh.Instance.Alias}"), hasSeparator: true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
var nonDeletableSystemDataTypeIds = GetNonDeletableSystemDataTypeIds();
|
||||
|
||||
if (nonDeletableSystemDataTypeIds.Contains(int.Parse(id)) == false)
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}"));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
|
||||
menu.Items.Add<ActionMove>(Services.TextService.Localize($"actions/{ActionMove.Instance.Alias}"), hasSeparator: true);
|
||||
menu.Items.Add<ActionMove>(Services.TextService, hasSeparator: true, opensDialog: true);
|
||||
}
|
||||
|
||||
return menu;
|
||||
|
||||
@@ -3,7 +3,8 @@ using System.Linq;
|
||||
using System.Net.Http.Formatting;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
|
||||
@@ -95,14 +96,12 @@ namespace Umbraco.Web.Trees
|
||||
{
|
||||
var menu = new MenuItemCollection();
|
||||
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"));
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
|
||||
if (id != Constants.System.Root.ToInvariantString())
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize(
|
||||
$"actions/{ActionDelete.Instance.Alias}"), true);
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, true, opensDialog: true);
|
||||
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(
|
||||
$"actions/{ActionRefresh.Instance.Alias}"), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -7,8 +7,9 @@ using System.Web;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
@@ -79,11 +80,11 @@ namespace Umbraco.Web.Trees
|
||||
var menu = new MenuItemCollection();
|
||||
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
//create action
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
//refresh action
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
@@ -93,9 +94,9 @@ namespace Umbraco.Web.Trees
|
||||
var menu = new MenuItemCollection();
|
||||
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
//create action
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
|
||||
var hasChildren = FileSystem.GetFiles(path).Any() || FileSystem.GetDirectories(path).Any();
|
||||
|
||||
@@ -103,11 +104,11 @@ namespace Umbraco.Web.Trees
|
||||
if (hasChildren == false)
|
||||
{
|
||||
//delete action
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)), true);
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, true, opensDialog: true);
|
||||
}
|
||||
|
||||
//refresh action
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
@@ -117,7 +118,7 @@ namespace Umbraco.Web.Trees
|
||||
var menu = new MenuItemCollection();
|
||||
|
||||
//if it's not a directory then we only allow to delete the item
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ using System.Web.Http.Routing;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
|
||||
@@ -17,6 +18,8 @@ namespace Umbraco.Web.Trees
|
||||
/// </summary>
|
||||
internal class LegacyTreeDataConverter
|
||||
{
|
||||
//fixme: remove this whole class when everything is angularized
|
||||
|
||||
/// <summary>
|
||||
/// This will look at the legacy IAction's JsFunctionName and convert it to a confirmation dialog view if possible
|
||||
/// </summary>
|
||||
@@ -24,14 +27,9 @@ namespace Umbraco.Web.Trees
|
||||
/// <returns></returns>
|
||||
internal static Attempt<string> GetLegacyConfirmView(IAction action)
|
||||
{
|
||||
if (action.JsFunctionName.IsNullOrWhiteSpace())
|
||||
switch (action)
|
||||
{
|
||||
return Attempt<string>.Fail();
|
||||
}
|
||||
|
||||
switch (action.JsFunctionName)
|
||||
{
|
||||
case "UmbClientMgr.appActions().actionDelete()":
|
||||
case ActionDelete actionDelete:
|
||||
return Attempt.Succeed(
|
||||
UmbracoConfig.For.GlobalSettings().Path.EnsureEndsWith('/') + "views/common/dialogs/legacydelete.html");
|
||||
}
|
||||
@@ -49,64 +47,18 @@ namespace Umbraco.Web.Trees
|
||||
/// <param name="nodeType"></param>
|
||||
internal static Attempt<LegacyUrlAction> GetUrlAndTitleFromLegacyAction(IAction action, string nodeId, string nodeType, string nodeName, string currentSection)
|
||||
{
|
||||
if (action.JsFunctionName.IsNullOrWhiteSpace())
|
||||
switch (action)
|
||||
{
|
||||
return Attempt<LegacyUrlAction>.Fail();
|
||||
}
|
||||
|
||||
switch (action.JsFunctionName)
|
||||
{
|
||||
case "UmbClientMgr.appActions().actionNew()":
|
||||
case ActionNew actionNew:
|
||||
return Attempt.Succeed(
|
||||
new LegacyUrlAction(
|
||||
"create.aspx?nodeId=" + nodeId + "&nodeType=" + nodeType + "&nodeName=" + nodeName + "&rnd=" + DateTime.UtcNow.Ticks,
|
||||
Current.Services.TextService.Localize("actions/create")));
|
||||
case "UmbClientMgr.appActions().actionNewFolder()":
|
||||
return Attempt.Succeed(
|
||||
new LegacyUrlAction(
|
||||
"createFolder.aspx?nodeId=" + nodeId + "&nodeType=" + nodeType + "&nodeName=" + nodeName + "&rnd=" + DateTime.UtcNow.Ticks,
|
||||
Current.Services.TextService.Localize("actions/create")));
|
||||
case "UmbClientMgr.appActions().actionProtect()":
|
||||
case ActionProtect actionProtect:
|
||||
return Attempt.Succeed(
|
||||
new LegacyUrlAction(
|
||||
"dialogs/protectPage.aspx?mode=cut&nodeId=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks,
|
||||
Current.Services.TextService.Localize("actions/protect")));
|
||||
case "UmbClientMgr.appActions().actionRollback()":
|
||||
return Attempt.Succeed(
|
||||
new LegacyUrlAction(
|
||||
"dialogs/rollback.aspx?nodeId=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks,
|
||||
Current.Services.TextService.Localize("actions/rollback")));
|
||||
case "UmbClientMgr.appActions().actionNotify()":
|
||||
return Attempt.Succeed(
|
||||
new LegacyUrlAction(
|
||||
"dialogs/notifications.aspx?id=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks,
|
||||
Current.Services.TextService.Localize("actions/notify")));
|
||||
case "UmbClientMgr.appActions().actionPublish()":
|
||||
return Attempt.Succeed(
|
||||
new LegacyUrlAction(
|
||||
"dialogs/publish.aspx?id=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks,
|
||||
Current.Services.TextService.Localize("actions/publish")));
|
||||
case "UmbClientMgr.appActions().actionChangeDocType()":
|
||||
return Attempt.Succeed(
|
||||
new LegacyUrlAction(
|
||||
"dialogs/ChangeDocType.aspx?id=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks,
|
||||
Current.Services.TextService.Localize("actions/changeDocType")));
|
||||
case "UmbClientMgr.appActions().actionToPublish()":
|
||||
return Attempt.Succeed(
|
||||
new LegacyUrlAction(
|
||||
"dialogs/SendPublish.aspx?id=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks,
|
||||
Current.Services.TextService.Localize("actions/sendtopublish")));
|
||||
case "UmbClientMgr.appActions().actionRePublish()":
|
||||
return Attempt.Succeed(
|
||||
new LegacyUrlAction(
|
||||
"dialogs/republish.aspx?rnd=" + DateTime.UtcNow.Ticks,
|
||||
Current.Services.TextService.Localize("actions/republish")));
|
||||
case "UmbClientMgr.appActions().actionSendToTranslate()":
|
||||
return Attempt.Succeed(
|
||||
new LegacyUrlAction(
|
||||
"dialogs/sendToTranslation.aspx?id=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks,
|
||||
Current.Services.TextService.Localize("actions/sendToTranslate")));
|
||||
|
||||
}
|
||||
return Attempt<LegacyUrlAction>.Fail();
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
@@ -58,13 +59,13 @@ namespace Umbraco.Web.Trees
|
||||
if (id == Constants.System.Root.ToInvariantString())
|
||||
{
|
||||
//Create the normal create action
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize("actions", ActionNew.Instance.Alias))
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true)
|
||||
//Since we haven't implemented anything for macros in angular, this needs to be converted to
|
||||
//use the legacy format
|
||||
.ConvertLegacyMenuItem(null, "initmacros", queryStrings.GetValue<string>("application"));
|
||||
|
||||
//refresh action
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
@@ -74,7 +75,7 @@ namespace Umbraco.Web.Trees
|
||||
if (macro == null) return new MenuItemCollection();
|
||||
|
||||
//add delete option for all macros
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize("actions", ActionDelete.Instance.Alias))
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true)
|
||||
//Since we haven't implemented anything for macros in angular, this needs to be converted to
|
||||
//use the legacy format
|
||||
.ConvertLegacyMenuItem(new EntitySlim
|
||||
|
||||
@@ -8,10 +8,12 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Search;
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
@@ -81,28 +83,25 @@ namespace Umbraco.Web.Trees
|
||||
var menu = new MenuItemCollection();
|
||||
|
||||
//set the default
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
|
||||
if (id == Constants.System.Root.ToInvariantString())
|
||||
{
|
||||
// if the user's start node is not the root then the only menu item to display is refresh
|
||||
if (UserStartNodes.Contains(Constants.System.Root) == false)
|
||||
{
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(
|
||||
Services.TextService.Localize(string.Concat("actions/", ActionRefresh.Instance.Alias)),
|
||||
true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
|
||||
// root actions
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize("actions", ActionNew.Instance.Alias));
|
||||
menu.Items.Add<ActionSort>(Services.TextService.Localize("actions", ActionSort.Instance.Alias), true);
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add<ActionSort>(Services.TextService, true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
|
||||
int iid;
|
||||
if (int.TryParse(id, out iid) == false)
|
||||
if (int.TryParse(id, out var iid) == false)
|
||||
{
|
||||
throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||
}
|
||||
@@ -115,29 +114,30 @@ namespace Umbraco.Web.Trees
|
||||
//if the user has no path access for this node, all they can do is refresh
|
||||
if (Security.CurrentUser.HasPathAccess(item, Services.EntityService, RecycleBinId) == false)
|
||||
{
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(
|
||||
Services.TextService.Localize(string.Concat("actions/", ActionRefresh.Instance.Alias)),
|
||||
true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
|
||||
//return a normal node menu:
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize("actions", ActionNew.Instance.Alias));
|
||||
menu.Items.Add<ActionMove>(Services.TextService.Localize("actions", ActionMove.Instance.Alias));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize("actions", ActionDelete.Instance.Alias));
|
||||
menu.Items.Add<ActionSort>(Services.TextService.Localize("actions", ActionSort.Instance.Alias));
|
||||
menu.Items.Add<ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add<ActionMove>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add<ActionSort>(Services.TextService);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
//if the media item is in the recycle bin, don't have a default menu, just show the regular menu
|
||||
if (item.Path.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Contains(RecycleBinId.ToInvariantString()))
|
||||
{
|
||||
menu.DefaultMenuAlias = null;
|
||||
menu.Items.Insert(2, new MenuItem(ActionRestore.Instance, Services.TextService.Localize("actions", ActionRestore.Instance.Alias)));
|
||||
menu.Items.Insert(2, new MenuItem(ActionRestore.ActionAlias, Services.TextService)
|
||||
{
|
||||
OpensDialog = true
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
}
|
||||
|
||||
return menu;
|
||||
|
||||
@@ -9,8 +9,9 @@ using Umbraco.Core.Models;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Umbraco.Web.Search;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
@@ -70,12 +71,11 @@ namespace Umbraco.Web.Trees
|
||||
if (id == Constants.System.Root.ToInvariantString())
|
||||
{
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
|
||||
// root actions
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"));
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(
|
||||
$"actions/{ActionRefresh.Instance.Alias}"));
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService));
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -83,9 +83,9 @@ namespace Umbraco.Web.Trees
|
||||
if (container != null)
|
||||
{
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"));
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
|
||||
menu.Items.Add(new MenuItem("rename", Services.TextService.Localize("actions/rename"))
|
||||
{
|
||||
@@ -95,10 +95,9 @@ namespace Umbraco.Web.Trees
|
||||
if (container.HasChildren == false)
|
||||
{
|
||||
//can delete doc type
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}"));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
}
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(
|
||||
$"actions/{ActionRefresh.Instance.Alias}"), hasSeparator: true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -107,29 +106,28 @@ namespace Umbraco.Web.Trees
|
||||
|
||||
if (enableInheritedMediaTypes)
|
||||
{
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"));
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
|
||||
//no move action if this is a child doc type
|
||||
if (parent == null)
|
||||
{
|
||||
menu.Items.Add<ActionMove>(Services.TextService.Localize($"actions/{ActionMove.Instance.Alias}"), true);
|
||||
menu.Items.Add<ActionMove>(Services.TextService, true, opensDialog: true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
menu.Items.Add<ActionMove>(Services.TextService.Localize($"actions/{ActionMove.Instance.Alias}"));
|
||||
menu.Items.Add<ActionMove>(Services.TextService, opensDialog: true);
|
||||
//no move action if this is a child doc type
|
||||
if (parent == null)
|
||||
{
|
||||
menu.Items.Add<ActionMove>(Services.TextService.Localize($"actions/{ActionMove.Instance.Alias}"), true);
|
||||
menu.Items.Add<ActionMove>(Services.TextService, true, opensDialog: true);
|
||||
}
|
||||
}
|
||||
|
||||
menu.Items.Add<ActionCopy>(Services.TextService.Localize($"actions/{ActionCopy.Instance.Alias}"));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}"));
|
||||
menu.Items.Add<ActionCopy>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
if (enableInheritedMediaTypes)
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(
|
||||
$"actions/{ActionRefresh.Instance.Alias}"), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
}
|
||||
|
||||
return menu;
|
||||
|
||||
@@ -10,10 +10,11 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Search;
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
@@ -155,36 +156,35 @@ namespace Umbraco.Web.Trees
|
||||
if (_provider.IsUmbracoMembershipProvider())
|
||||
{
|
||||
//set default
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
|
||||
//Create the normal create action
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize("actions", ActionNew.Instance.Alias));
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Create a custom create action - this does not launch a dialog, it just navigates to the create screen
|
||||
// we'll create it based on the ActionNew so it maintains the same icon properties, name, etc...
|
||||
var createMenuItem = new MenuItem(ActionNew.Instance);
|
||||
var createMenuItem = new MenuItem(ActionNew.ActionAlias, Services.TextService)
|
||||
{
|
||||
Icon = "add",
|
||||
OpensDialog = true
|
||||
};
|
||||
//we want to go to this route: /member/member/edit/-1?create=true
|
||||
createMenuItem.NavigateToRoute("/member/member/edit/-1?create=true");
|
||||
menu.Items.Add(createMenuItem);
|
||||
}
|
||||
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
|
||||
//add delete option for all members
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize("actions", ActionDelete.Instance.Alias));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
|
||||
if (Security.CurrentUser.HasAccessToSensitiveData())
|
||||
{
|
||||
menu.Items.Add(new ExportMember
|
||||
{
|
||||
Name = Services.TextService.Localize("actions/export"),
|
||||
Icon = "download-alt",
|
||||
Alias = "export"
|
||||
});
|
||||
menu.Items.Add(new ExportMember(Services.TextService));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
using System.Net.Http.Formatting;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
using Umbraco.Web.Models.Trees;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
@@ -25,14 +26,14 @@ namespace Umbraco.Web.Trees
|
||||
if (id == Constants.System.Root.ToInvariantString())
|
||||
{
|
||||
// root actions
|
||||
menu.Items.Add<CreateChildEntity, ActionNew>(Services.TextService.Localize("actions", ActionNew.Instance.Alias));
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add(new CreateChildEntity(Services.TextService));
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
else
|
||||
{
|
||||
//delete member type/group
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize("actions", ActionDelete.Instance.Alias));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
}
|
||||
|
||||
return menu;
|
||||
|
||||
@@ -8,7 +8,8 @@ using Umbraco.Web.WebApi.Filters;
|
||||
using umbraco;
|
||||
using umbraco.cms.businesslogic.packager;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
@@ -83,21 +84,20 @@ namespace Umbraco.Web.Trees
|
||||
// Root actions
|
||||
if (id == "-1")
|
||||
{
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"))
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true)
|
||||
.ConvertLegacyMenuItem(null, Constants.Trees.Packages, queryStrings.GetValue<string>("application"));
|
||||
}
|
||||
else if (id == "created")
|
||||
{
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"))
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true)
|
||||
.ConvertLegacyMenuItem(null, Constants.Trees.Packages, queryStrings.GetValue<string>("application"));
|
||||
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(
|
||||
Services.TextService.Localize($"actions/{ActionRefresh.Instance.Alias}"), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
//it's a package node
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize("actions", ActionDelete.Instance.Alias));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
}
|
||||
|
||||
return menu;
|
||||
|
||||
@@ -4,10 +4,11 @@ using System.Net.Http.Formatting;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
{
|
||||
@@ -24,12 +25,10 @@ namespace Umbraco.Web.Trees
|
||||
if (id == Constants.System.Root.ToInvariantString())
|
||||
{
|
||||
//Create the normal create action
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize("actions", ActionNew.Instance.Alias))
|
||||
//Since we haven't implemented anything for relationtypes in angular, this needs to be converted to
|
||||
//use the legacy format
|
||||
.ConvertLegacyMenuItem(null, "initrelationTypes", queryStrings.GetValue<string>("application"));
|
||||
var addMenuItem = menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
addMenuItem.LaunchDialogUrl("developer/RelationTypes/NewRelationType.aspx", "Create New RelationType");
|
||||
//refresh action
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
@@ -38,7 +37,7 @@ namespace Umbraco.Web.Trees
|
||||
if (relationType == null) return new MenuItemCollection();
|
||||
|
||||
//add delete option for all macros
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize("actions", ActionDelete.Instance.Alias))
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true)
|
||||
//Since we haven't implemented anything for relationtypes in angular, this needs to be converted to
|
||||
//use the legacy format
|
||||
.ConvertLegacyMenuItem(new EntitySlim
|
||||
|
||||
@@ -8,12 +8,13 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.Search;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
@@ -69,13 +70,13 @@ namespace Umbraco.Web.Trees
|
||||
var menu = new MenuItemCollection();
|
||||
|
||||
//Create the normal create action
|
||||
var item = menu.Items.Add<ActionNew>(Services.TextService.Localize("actions", ActionNew.Instance.Alias));
|
||||
var item = menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
item.NavigateToRoute($"{queryStrings.GetValue<string>("application")}/templates/edit/{id}?create=true");
|
||||
|
||||
if (id == Constants.System.Root.ToInvariantString())
|
||||
{
|
||||
//refresh action
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
@@ -88,11 +89,11 @@ namespace Umbraco.Web.Trees
|
||||
if (template.IsMasterTemplate == false)
|
||||
{
|
||||
//add delete option if it doesn't have children
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize("actions", ActionDelete.Instance.Alias), true);
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, true, opensDialog: true);
|
||||
}
|
||||
|
||||
//add refresh
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
|
||||
return menu;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user