diff --git a/src/Umbraco.Core/CodeAnnotations/ActionMetadataAttribute.cs b/src/Umbraco.Core/CodeAnnotations/ActionMetadataAttribute.cs deleted file mode 100644 index 9ef87e9a5f..0000000000 --- a/src/Umbraco.Core/CodeAnnotations/ActionMetadataAttribute.cs +++ /dev/null @@ -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; } - - /// - /// 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 - /// - /// - public ActionMetadataAttribute(string category) - { - if (string.IsNullOrWhiteSpace(category)) throw new ArgumentNullOrEmptyException(nameof(category)); - Category = category; - } - - /// - /// Constructor used to assign an explicit name and category - /// - /// - /// - 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; - } - } -} diff --git a/src/Umbraco.Core/Constants-PropertyEditors.cs b/src/Umbraco.Core/Constants-PropertyEditors.cs index 126613cdb3..b09987ad90 100644 --- a/src/Umbraco.Core/Constants-PropertyEditors.cs +++ b/src/Umbraco.Core/Constants-PropertyEditors.cs @@ -44,26 +44,6 @@ namespace Umbraco.Core /// public const string DateTime = "Umbraco.DateTime"; - /// - /// DropDown List. - /// - public const string DropDownList = "Umbraco.DropDown"; - - /// - /// DropDown List, Publish Keys. - /// - public const string DropdownlistPublishKeys = "Umbraco.DropdownlistPublishingKeys"; - - /// - /// DropDown List Multiple. - /// - public const string DropDownListMultiple = "Umbraco.DropDownMultiple"; - - /// - /// DropDown List Multiple, Publish Keys. - /// - public const string DropdownlistMultiplePublishKeys = "Umbraco.DropdownlistMultiplePublishKeys"; - /// /// DropDown List. /// diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs index c4ebfb664b..eb7cafcb01 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs @@ -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 }); diff --git a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs index fd1e9bec9c..fb0f18700c 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs @@ -139,6 +139,8 @@ namespace Umbraco.Core.Migrations.Upgrade Chain("{6A2C7C1B-A9DB-4EA9-B6AB-78E7D5B722A7}"); Chain("{77874C77-93E5-4488-A404-A630907CEEF0}"); Chain("{8804D8E8-FE62-4E3A-B8A2-C047C2118C38}"); + Chain("{23275462-446E-44C7-8C2C-3B8C1127B07D}"); + Chain("{6B251841-3069-4AD5-8AE9-861F9523E8DA}"); //FINAL diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypeMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypeMigration.cs index eb39f37112..d7180385f0 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypeMigration.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypeMigration.cs @@ -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")] diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs new file mode 100644 index 0000000000..e5cda85168 --- /dev/null +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs @@ -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(Sql() + .Select() + .From() + .Where(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(dd.Configuration); + } + catch (Exception ex) + { + Logger.Error( + 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().From() + .InnerJoin().On(x => x.Id, x => x.PropertyTypeId) + .InnerJoin().On(x => x.NodeId, x => x.DataTypeId) + .Where(x => x.DataTypeId == dd.NodeId); + + var propDatas = Database.Query(propDataSql); + var toUpdate = new List(); + 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) + 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(); + 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( + "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; + } + + } +} diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs new file mode 100644 index 0000000000..fa6e47fac7 --- /dev/null +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs @@ -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(); + } + } +} diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleValueConverter.cs deleted file mode 100644 index d91f45292c..0000000000 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleValueConverter.cs +++ /dev/null @@ -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); - - 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(); - - var values = - sourceString.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => v.Trim()); - - return values; - } - } -} diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleWithKeysValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleWithKeysValueConverter.cs deleted file mode 100644 index bceebc232b..0000000000 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleWithKeysValueConverter.cs +++ /dev/null @@ -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); - - 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; - } - } -} diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListValueConverter.cs deleted file mode 100644 index 5fe1967f32..0000000000 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListValueConverter.cs +++ /dev/null @@ -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; - } - } -} diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListWithKeysValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListWithKeysValueConverter.cs deleted file mode 100644 index 960cd4afa6..0000000000 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListWithKeysValueConverter.cs +++ /dev/null @@ -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(); - if (intAttempt.Success) - return intAttempt.Result; - - return null; - } - } -} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index e0aa93efec..acda9ef589 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -143,7 +143,6 @@ - @@ -357,6 +356,8 @@ + + @@ -1242,10 +1243,6 @@ - - - - diff --git a/src/Umbraco.Tests/Composing/ActionCollectionTests.cs b/src/Umbraco.Tests/Composing/ActionCollectionTests.cs deleted file mode 100644 index 46e4eee765..0000000000 --- a/src/Umbraco.Tests/Composing/ActionCollectionTests.cs +++ /dev/null @@ -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 - } -} diff --git a/src/Umbraco.Tests/Composing/TypeLoaderTests.cs b/src/Umbraco.Tests/Composing/TypeLoaderTests.cs index a7b3d0f446..07625db9bf 100644 --- a/src/Umbraco.Tests/Composing/TypeLoaderTests.cs +++ b/src/Umbraco.Tests/Composing/TypeLoaderTests.cs @@ -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()); } /// diff --git a/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs b/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs index 9ba5ccf6f2..129116bf61 100644 --- a/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs +++ b/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs @@ -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.... /// + /// + /// 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. + /// [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(); - var editor = new PublishValuesMultipleValueEditor(true, Mock.Of(), new DataEditorAttribute("key", "nam", "view")); - - var dataType = new DataType(new CheckBoxListPropertyEditor(Mock.Of(), Mock.Of())); - var prop = new Property(1, new PropertyType(dataType)); - prop.SetValue("1234,4567,8910"); - - var result = editor.ConvertDbToString(prop.PropertyType, prop.GetValue(), new Mock().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(), Mock.Of())) { @@ -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); diff --git a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs index 2c3a2d1583..7ec23158f6 100644 --- a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs +++ b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs @@ -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 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(); + mockPublishedContentTypeFactory.Setup(x => x.GetDataType(123)) + .Returns(new PublishedDataType(123, "test", new Lazy(() => new DropDownFlexibleConfiguration + { + Multiple = true + }))); + + var publishedPropType = new PublishedPropertyType( + new PublishedContentType(1234, "test", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing), + new PropertyType("test", ValueStorageType.Nvarchar) { DataTypeId = 123 }, + new PropertyValueConverterCollection(Enumerable.Empty()), + Mock.Of(), 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 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)] diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index b22a1dfd6a..d5d74ee754 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -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(); diff --git a/src/Umbraco.Tests/Services/UserServiceTests.cs b/src/Umbraco.Tests/Services/UserServiceTests.cs index 117b0f9103..cce54c81a4 100644 --- a/src/Umbraco.Tests/Services/UserServiceTests.cs +++ b/src/Umbraco.Tests/Services/UserServiceTests.cs @@ -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); diff --git a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs index 752d0ac97e..42beea7df3 100644 --- a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs +++ b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs @@ -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; diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs index 7f68f22a27..d80802b1cf 100644 --- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs +++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs @@ -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() - .SetProducer(Enumerable.Empty); - + Container.RegisterCollectionBuilder(); Container.RegisterCollectionBuilder(); Container.RegisterSingleton(); diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index c62e79b4ef..156bc06a14 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -406,7 +406,6 @@ - diff --git a/src/Umbraco.Tests/Web/Controllers/BackOfficeControllerUnitTests.cs b/src/Umbraco.Tests/Web/Controllers/BackOfficeControllerUnitTests.cs index 850870f395..fa9335bc3f 100644 --- a/src/Umbraco.Tests/Web/Controllers/BackOfficeControllerUnitTests.cs +++ b/src/Umbraco.Tests/Web/Controllers/BackOfficeControllerUnitTests.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); - } } } diff --git a/src/Umbraco.Tests/Web/Controllers/ContentControllerTests.cs b/src/Umbraco.Tests/Web/Controllers/ContentControllerTests.cs index f75371d203..26a7403dac 100644 --- a/src/Umbraco.Tests/Web/Controllers/ContentControllerTests.cs +++ b/src/Umbraco.Tests/Web/Controllers/ContentControllerTests.cs @@ -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() }), }))); diff --git a/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js b/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js index bd7cf964d0..fbe73c4085 100644 --- a/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js +++ b/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js @@ -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) { diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js index 64c2b127e9..2475353d94 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js @@ -23,7 +23,7 @@ * **/ -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)) { diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tree.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tree.service.js index 3b605453c3..50a8760585 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tree.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tree.service.js @@ -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; diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/legacydelete.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/legacydelete.controller.js new file mode 100644 index 0000000000..ed1af5af6c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/legacydelete.controller.js @@ -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); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/legacydelete.html b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/legacydelete.html new file mode 100644 index 0000000000..dda8f23b7d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/legacydelete.html @@ -0,0 +1,14 @@ + + + + + + Are you sure you want to delete {{currentNode.name}} ? + + + + + + + + diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.controller.js deleted file mode 100644 index bcbd13f860..0000000000 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.controller.js +++ /dev/null @@ -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 = ""; - } - } - - }); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.html deleted file mode 100644 index 663373c8eb..0000000000 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js index c7a472d80e..f8e02a240a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js @@ -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; } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html index 5edbab4f30..3239e64acc 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html @@ -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"> + ng-options="item.value as item.value for item in model.config.items"> diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 3dc5cd053a..d2867acfc9 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -324,8 +324,6 @@ - - ASPXCodeBehind diff --git a/src/Umbraco.Web.UI/Umbraco/developer/RelationTypes/TreeMenu/ActionDeleteRelationType.js b/src/Umbraco.Web.UI/Umbraco/developer/RelationTypes/TreeMenu/ActionDeleteRelationType.js deleted file mode 100644 index 30d6611ba9..0000000000 --- a/src/Umbraco.Web.UI/Umbraco/developer/RelationTypes/TreeMenu/ActionDeleteRelationType.js +++ /dev/null @@ -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) { } - }); - - } - -} - - diff --git a/src/Umbraco.Web.UI/Umbraco/developer/RelationTypes/TreeMenu/ActionNewRelationType.js b/src/Umbraco.Web.UI/Umbraco/developer/RelationTypes/TreeMenu/ActionNewRelationType.js deleted file mode 100644 index 322e4b9ace..0000000000 --- a/src/Umbraco.Web.UI/Umbraco/developer/RelationTypes/TreeMenu/ActionNewRelationType.js +++ /dev/null @@ -1,3 +0,0 @@ -function actionNewRelationType() { - UmbClientMgr.openModalWindow('developer/RelationTypes/NewRelationType.aspx', 'Create New RelationType', true, 400, 300, 0, 0); -} \ No newline at end of file diff --git a/src/Umbraco.Web/Actions/ActionAssignDomain.cs b/src/Umbraco.Web/Actions/ActionAssignDomain.cs new file mode 100644 index 0000000000..7dc3668e5d --- /dev/null +++ b/src/Umbraco.Web/Actions/ActionAssignDomain.cs @@ -0,0 +1,21 @@ +using Umbraco.Core; +using Umbraco.Core.CodeAnnotations; + + +namespace Umbraco.Web.Actions +{ + /// + /// This action is invoked when a domain is being assigned to a document + /// + 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; + } +} diff --git a/src/Umbraco.Web/Actions/ActionBrowse.cs b/src/Umbraco.Web/Actions/ActionBrowse.cs new file mode 100644 index 0000000000..64882c142a --- /dev/null +++ b/src/Umbraco.Web/Actions/ActionBrowse.cs @@ -0,0 +1,27 @@ +using Umbraco.Core; +using Umbraco.Core.CodeAnnotations; + + +namespace Umbraco.Web.Actions +{ + /// + /// 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. + /// + /// + /// 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. + /// + 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; + } +} diff --git a/src/Umbraco.Web/Actions/ActionChangeDocType.cs b/src/Umbraco.Web/Actions/ActionChangeDocType.cs new file mode 100644 index 0000000000..73772699d0 --- /dev/null +++ b/src/Umbraco.Web/Actions/ActionChangeDocType.cs @@ -0,0 +1,20 @@ +using Umbraco.Core; +using Umbraco.Core.CodeAnnotations; +using Umbraco.Web.UI.Pages; + + +namespace Umbraco.Web.Actions +{ + /// + /// This action is invoked when the document type of a piece of content is changed + /// + 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; + } +} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionCollection.cs b/src/Umbraco.Web/Actions/ActionCollection.cs similarity index 57% rename from src/Umbraco.Web/_Legacy/Actions/ActionCollection.cs rename to src/Umbraco.Web/Actions/ActionCollection.cs index 849fb3b619..64cf950c60 100644 --- a/src/Umbraco.Web/_Legacy/Actions/ActionCollection.cs +++ b/src/Umbraco.Web/Actions/ActionCollection.cs @@ -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 { @@ -15,7 +17,7 @@ namespace Umbraco.Web._Legacy.Actions internal T GetAction() where T : IAction { - return this.OfType().SingleOrDefault(); + return this.OfType().FirstOrDefault(); } internal IEnumerable GetByLetters(IEnumerable letters) @@ -25,5 +27,15 @@ namespace Umbraco.Web._Legacy.Actions .WhereNotNull() .ToArray(); } + + internal IReadOnlyList 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(); + } } } diff --git a/src/Umbraco.Web/Actions/ActionCollectionBuilder.cs b/src/Umbraco.Web/Actions/ActionCollectionBuilder.cs new file mode 100644 index 0000000000..6002c8d2b0 --- /dev/null +++ b/src/Umbraco.Web/Actions/ActionCollectionBuilder.cs @@ -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 + { + public ActionCollectionBuilder(IServiceContainer container) + : base(container) + { } + + protected override ActionCollectionBuilder This => this; + + protected override IEnumerable 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; + } + } +} diff --git a/src/Umbraco.Web/Actions/ActionCopy.cs b/src/Umbraco.Web/Actions/ActionCopy.cs new file mode 100644 index 0000000000..3e4b2ddc31 --- /dev/null +++ b/src/Umbraco.Web/Actions/ActionCopy.cs @@ -0,0 +1,20 @@ +using Umbraco.Core; +using Umbraco.Core.CodeAnnotations; +using Umbraco.Web.UI.Pages; + + +namespace Umbraco.Web.Actions +{ + /// + /// This action is invoked when copying a document, media, member + /// + 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; + } +} diff --git a/src/Umbraco.Web/Actions/ActionCreateBlueprintFromContent.cs b/src/Umbraco.Web/Actions/ActionCreateBlueprintFromContent.cs new file mode 100644 index 0000000000..0a46393a81 --- /dev/null +++ b/src/Umbraco.Web/Actions/ActionCreateBlueprintFromContent.cs @@ -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; + } +} diff --git a/src/Umbraco.Web/Actions/ActionDelete.cs b/src/Umbraco.Web/Actions/ActionDelete.cs new file mode 100644 index 0000000000..0cf2e60c5a --- /dev/null +++ b/src/Umbraco.Web/Actions/ActionDelete.cs @@ -0,0 +1,23 @@ +using Umbraco.Core; +using Umbraco.Core.CodeAnnotations; +using Umbraco.Web.UI.Pages; + + +namespace Umbraco.Web.Actions +{ + /// + /// This action is invoked when a document, media, member is deleted + /// + 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; + } +} diff --git a/src/Umbraco.Web/Actions/ActionMove.cs b/src/Umbraco.Web/Actions/ActionMove.cs new file mode 100644 index 0000000000..7ae8474965 --- /dev/null +++ b/src/Umbraco.Web/Actions/ActionMove.cs @@ -0,0 +1,22 @@ +using Umbraco.Core; +using Umbraco.Core.CodeAnnotations; +using Umbraco.Web.UI.Pages; + + +namespace Umbraco.Web.Actions +{ + /// + /// This action is invoked upon creation of a document, media, member + /// + 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; + } +} diff --git a/src/Umbraco.Web/Actions/ActionNew.cs b/src/Umbraco.Web/Actions/ActionNew.cs new file mode 100644 index 0000000000..c07580b42a --- /dev/null +++ b/src/Umbraco.Web/Actions/ActionNew.cs @@ -0,0 +1,23 @@ +using Umbraco.Core; +using Umbraco.Core.CodeAnnotations; +using Umbraco.Web.UI.Pages; + + +namespace Umbraco.Web.Actions +{ + /// + /// This action is invoked upon creation of a document + /// + 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; + } +} diff --git a/src/Umbraco.Web/Actions/ActionProtect.cs b/src/Umbraco.Web/Actions/ActionProtect.cs new file mode 100644 index 0000000000..0e5f9f8433 --- /dev/null +++ b/src/Umbraco.Web/Actions/ActionProtect.cs @@ -0,0 +1,20 @@ +using Umbraco.Core; +using Umbraco.Core.CodeAnnotations; +using Umbraco.Web.UI.Pages; + + +namespace Umbraco.Web.Actions +{ + /// + /// This action is invoked when a document is protected or unprotected + /// + 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; + } +} diff --git a/src/Umbraco.Web/Actions/ActionPublish.cs b/src/Umbraco.Web/Actions/ActionPublish.cs new file mode 100644 index 0000000000..5c9ce08c35 --- /dev/null +++ b/src/Umbraco.Web/Actions/ActionPublish.cs @@ -0,0 +1,21 @@ +using Umbraco.Core; +using Umbraco.Core.CodeAnnotations; + + +namespace Umbraco.Web.Actions +{ + /// + /// This action is invoked when a document is being published + /// + 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; + } +} diff --git a/src/Umbraco.Web/Actions/ActionRestore.cs b/src/Umbraco.Web/Actions/ActionRestore.cs new file mode 100644 index 0000000000..aa309131f2 --- /dev/null +++ b/src/Umbraco.Web/Actions/ActionRestore.cs @@ -0,0 +1,20 @@ + + +namespace Umbraco.Web.Actions +{ + /// + /// This action is invoked when the content/media item is to be restored from the recycle bin + /// + 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; + + } +} diff --git a/src/Umbraco.Web/Actions/ActionRights.cs b/src/Umbraco.Web/Actions/ActionRights.cs new file mode 100644 index 0000000000..0d9ace918e --- /dev/null +++ b/src/Umbraco.Web/Actions/ActionRights.cs @@ -0,0 +1,20 @@ +using Umbraco.Core; +using Umbraco.Core.CodeAnnotations; +using Umbraco.Web.UI.Pages; + + +namespace Umbraco.Web.Actions +{ + /// + /// This action is invoked when rights are changed on a document + /// + 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; + } +} diff --git a/src/Umbraco.Web/Actions/ActionRollback.cs b/src/Umbraco.Web/Actions/ActionRollback.cs new file mode 100644 index 0000000000..96ce1e7767 --- /dev/null +++ b/src/Umbraco.Web/Actions/ActionRollback.cs @@ -0,0 +1,22 @@ +using Umbraco.Core; +using Umbraco.Core.CodeAnnotations; +using Umbraco.Web.UI.Pages; + + +namespace Umbraco.Web.Actions +{ + /// + /// This action is invoked when copying a document is being rolled back + /// + 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; + } +} diff --git a/src/Umbraco.Web/Actions/ActionSort.cs b/src/Umbraco.Web/Actions/ActionSort.cs new file mode 100644 index 0000000000..8b4e01823e --- /dev/null +++ b/src/Umbraco.Web/Actions/ActionSort.cs @@ -0,0 +1,19 @@ +using Umbraco.Core; +using Umbraco.Core.CodeAnnotations; + + +namespace Umbraco.Web.Actions +{ + /// + /// This action is invoked when children to a document, media, member is being sorted + /// + 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; + } +} diff --git a/src/Umbraco.Web/Actions/ActionToPublish.cs b/src/Umbraco.Web/Actions/ActionToPublish.cs new file mode 100644 index 0000000000..518c82ab87 --- /dev/null +++ b/src/Umbraco.Web/Actions/ActionToPublish.cs @@ -0,0 +1,22 @@ +using Umbraco.Core; +using Umbraco.Core.CodeAnnotations; +using Umbraco.Web.UI.Pages; + + +namespace Umbraco.Web.Actions +{ + /// + /// This action is invoked when children to a document is being sent to published (by an editor without publishrights) + /// + 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; + } +} diff --git a/src/Umbraco.Web/Actions/ActionUnpublish.cs b/src/Umbraco.Web/Actions/ActionUnpublish.cs new file mode 100644 index 0000000000..8ece4c008e --- /dev/null +++ b/src/Umbraco.Web/Actions/ActionUnpublish.cs @@ -0,0 +1,21 @@ +using Umbraco.Core; +using Umbraco.Core.CodeAnnotations; + + +namespace Umbraco.Web.Actions +{ + + /// + /// This action is invoked when a document is being unpublished + /// + 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; + } + +} diff --git a/src/Umbraco.Web/Actions/ActionUpdate.cs b/src/Umbraco.Web/Actions/ActionUpdate.cs new file mode 100644 index 0000000000..a2fba0fd89 --- /dev/null +++ b/src/Umbraco.Web/Actions/ActionUpdate.cs @@ -0,0 +1,22 @@ +using Umbraco.Core; +using Umbraco.Core.CodeAnnotations; +using Umbraco.Web.UI.Pages; + + +namespace Umbraco.Web.Actions +{ + /// + /// This action is invoked when copying a document or media + /// + 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; + } +} diff --git a/src/Umbraco.Web/Actions/IAction.cs b/src/Umbraco.Web/Actions/IAction.cs new file mode 100644 index 0000000000..986ed9b509 --- /dev/null +++ b/src/Umbraco.Web/Actions/IAction.cs @@ -0,0 +1,46 @@ +using Umbraco.Core.Composing; + +namespace Umbraco.Web.Actions +{ + /// + /// Defines a back office action that can be permission assigned or subscribed to for notifications + /// + /// + /// If an IAction returns false for both ShowInNotifier and CanBePermissionAssigned then the IAction should not exist + /// + public interface IAction : IDiscoverable + { + /// + /// The letter used to assign a permission (must be unique) + /// + char Letter { get; } + + /// + /// Whether to allow subscribing to notifications for this action + /// + bool ShowInNotifier { get; } + + /// + /// Whether to allow assigning permissions based on this action + /// + bool CanBePermissionAssigned { get; } + + /// + /// The icon to display for this action + /// + string Icon { get; } + + /// + /// The alias for this action (must be unique) + /// + string Alias { get; } + + /// + /// The category used for this action + /// + /// + /// Used in the UI when assigning permissions + /// + string Category { get; } + } +} diff --git a/src/Umbraco.Web/Components/NotificationsComponent.cs b/src/Umbraco.Web/Components/NotificationsComponent.cs index 27fc604d29..79f5ee9f6d 100644 --- a/src/Umbraco.Web/Components/NotificationsComponent.cs +++ b/src/Umbraco.Web/Components/NotificationsComponent.cs @@ -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()); //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()); }; //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()); + notificationService.SendNotification(updatedEntities, actions.GetAction()); }; //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()); }; //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()); }; } } diff --git a/src/Umbraco.Web/Composing/Current.cs b/src/Umbraco.Web/Composing/Current.cs index 3e3f6c75a6..839254f03c 100644 --- a/src/Umbraco.Web/Composing/Current.cs +++ b/src/Umbraco.Web/Composing/Current.cs @@ -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 diff --git a/src/Umbraco.Web/CompositionExtensions.cs b/src/Umbraco.Web/CompositionExtensions.cs index f33c8e98a8..38b0be3103 100644 --- a/src/Umbraco.Web/CompositionExtensions.cs +++ b/src/Umbraco.Web/CompositionExtensions.cs @@ -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, diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs index 15554b7f50..7d0cc26d15 100644 --- a/src/Umbraco.Web/Editors/BackOfficeController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeController.cs @@ -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 GetLegacyActionJsForActions(LegacyJsActionType type, IEnumerable values) - { - var blockList = new List(); - var urlList = new List(); - 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; - } - - /// - /// Renders out all JavaScript references that have been declared in IActions - /// - private static IEnumerable GetLegacyActionJs(LegacyJsActionType type) - { - return GetLegacyActionJsForActions(type, Action.GetJavaScriptFileReferences()); - } - - internal enum LegacyJsActionType - { - JsBlock, - JsUrl - } - + private ActionResult RedirectToLocal(string returnUrl) { if (Url.IsLocalUrl(returnUrl)) diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index ed87f770ca..03bfc78204 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -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); } - + /// /// Publishes a document with a given ID /// /// /// /// - /// 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. /// /// @@ -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(), 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 = "*") { diff --git a/src/Umbraco.Web/Editors/Filters/ContentSaveValidationAttribute.cs b/src/Umbraco.Web/Editors/Filters/ContentSaveValidationAttribute.cs index ed6e15ed09..2698986bcd 100644 --- a/src/Umbraco.Web/Editors/Filters/ContentSaveValidationAttribute.cs +++ b/src/Umbraco.Web/Editors/Filters/ContentSaveValidationAttribute.cs @@ -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) { diff --git a/src/Umbraco.Web/Models/Mapping/UserGroupDefaultPermissionsResolver.cs b/src/Umbraco.Web/Models/Mapping/UserGroupDefaultPermissionsResolver.cs index 89144084e2..b13b5cda10 100644 --- a/src/Umbraco.Web/Models/Mapping/UserGroupDefaultPermissionsResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/UserGroupDefaultPermissionsResolver.cs @@ -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(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)); diff --git a/src/Umbraco.Web/Models/Mapping/UserMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/UserMapperProfile.cs index 213a1a5e3a..8261dda0d4 100644 --- a/src/Umbraco.Web/Models/Mapping/UserMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/UserMapperProfile.cs @@ -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 { diff --git a/src/Umbraco.Web/Models/Trees/ActionMenuItem.cs b/src/Umbraco.Web/Models/Trees/ActionMenuItem.cs index b2fb479771..9354417155 100644 --- a/src/Umbraco.Web/Models/Trees/ActionMenuItem.cs +++ b/src/Umbraco.Web/Models/Trees/ActionMenuItem.cs @@ -1,41 +1,55 @@ using System; +using System.Diagnostics.CodeAnalysis; using Umbraco.Core; +using Umbraco.Core.Services; namespace Umbraco.Web.Models.Trees { - /// - /// A menu item that represents some JS that needs to execute when the menu item is clicked. - /// - /// - /// 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. - /// + /// + /// + /// A menu item that represents some JS that needs to execute when the menu item is clicked. + /// + /// + /// 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. + /// public abstract class ActionMenuItem : MenuItem { - protected ActionMenuItem() - : base() - { - var attribute = GetType().GetCustomAttribute(false); - if (attribute == null) - { - throw new InvalidOperationException("All " + typeof (ActionMenuItem).FullName + " instances must be attributed with " + typeof (ActionMenuItemAttribute).FullName); - } + /// + /// The angular service name containing the + /// + public abstract string AngularServiceName { get; } + /// + /// The angular service method name to call for this menu item + /// + 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}"); } } } diff --git a/src/Umbraco.Web/Models/Trees/ActionMenuItemAttribute.cs b/src/Umbraco.Web/Models/Trees/ActionMenuItemAttribute.cs deleted file mode 100644 index 64558b8727..0000000000 --- a/src/Umbraco.Web/Models/Trees/ActionMenuItemAttribute.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using Umbraco.Core.Exceptions; - -namespace Umbraco.Web.Models.Trees -{ - /// - /// The attribute to assign to any ActionMenuItem objects. - /// - [AttributeUsage(AttributeTargets.Class)] - public sealed class ActionMenuItemAttribute : Attribute - { - /// - /// This constructor defines both the angular service and method name to use - /// - /// - /// - 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; - } - - /// - /// This constructor will assume that the method name equals the type name of the action menu class - /// - /// - public ActionMenuItemAttribute(string serviceName) - { - if (string.IsNullOrWhiteSpace(serviceName)) throw new ArgumentNullOrEmptyException(nameof(serviceName)); - MethodName = ""; - ServiceName = serviceName; - } - - public string MethodName { get; } - public string ServiceName { get; } - } -} diff --git a/src/Umbraco.Web/Models/Trees/CreateChildEntity.cs b/src/Umbraco.Web/Models/Trees/CreateChildEntity.cs index ca89851beb..022056c35d 100644 --- a/src/Umbraco.Web/Models/Trees/CreateChildEntity.cs +++ b/src/Umbraco.Web/Models/Trees/CreateChildEntity.cs @@ -1,10 +1,27 @@ -namespace Umbraco.Web.Models.Trees +using Umbraco.Core.Services; +using Umbraco.Web.Actions; + +namespace Umbraco.Web.Models.Trees { /// /// Represents the refresh node menu item /// - [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; + } } } diff --git a/src/Umbraco.Web/Models/Trees/DisableUser.cs b/src/Umbraco.Web/Models/Trees/DisableUser.cs deleted file mode 100644 index 3602897ac2..0000000000 --- a/src/Umbraco.Web/Models/Trees/DisableUser.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Umbraco.Web.Models.Trees -{ - /// - /// Represents the disable user menu item - /// - [ActionMenuItem("umbracoMenuActions")] - public sealed class DisableUser : ActionMenuItem - { - public DisableUser() - { - Alias = "disable"; - Icon = "remove"; - } - } -} diff --git a/src/Umbraco.Web/Models/Trees/ExportMember.cs b/src/Umbraco.Web/Models/Trees/ExportMember.cs index 66a10da007..558f7c1fa1 100644 --- a/src/Umbraco.Web/Models/Trees/ExportMember.cs +++ b/src/Umbraco.Web/Models/Trees/ExportMember.cs @@ -1,9 +1,17 @@ -namespace Umbraco.Web.Models.Trees +using Umbraco.Core.Services; + +namespace Umbraco.Web.Models.Trees { /// /// Represents the export member menu item /// - [ActionMenuItem("umbracoMenuActions")] public sealed class ExportMember : ActionMenuItem - { } + { + public override string AngularServiceName => "umbracoMenuActions"; + + public ExportMember(ILocalizedTextService textService) : base("export", textService) + { + Icon = "download-alt"; + } + } } diff --git a/src/Umbraco.Web/Models/Trees/MenuItem.cs b/src/Umbraco.Web/Models/Trees/MenuItem.cs index 412cd9106d..4170cdb73f 100644 --- a/src/Umbraco.Web/Models/Trees/MenuItem.cs +++ b/src/Umbraco.Web/Models/Trees/MenuItem.cs @@ -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}"); + } + + /// + /// Create a menu item based on an definition + /// + /// + /// + 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; } + /// + /// Used in the UI to inform the user that the menu item will open a dialog/confirmation + /// [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. /// /// - public void ExecuteLegacyJs(string jsToExecute) + public void ExecuteJsMethod(string jsToExecute) { SetJsAction(jsToExecute); } @@ -206,7 +222,7 @@ namespace Umbraco.Web.Models.Trees } } } - + #endregion } diff --git a/src/Umbraco.Web/Models/Trees/MenuItemList.cs b/src/Umbraco.Web/Models/Trees/MenuItemList.cs index 170042b151..b34f0b4444 100644 --- a/src/Umbraco.Web/Models/Trees/MenuItemList.cs +++ b/src/Umbraco.Web/Models/Trees/MenuItemList.cs @@ -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 } /// - /// Adds a menu item + /// Adds a menu item based on a /// /// /// The text to display for the menu item, will default to the IAction alias if not specified @@ -32,78 +34,20 @@ namespace Umbraco.Web.Models.Trees { var item = new MenuItem(action, name); - DetectLegacyActionMenu(action.GetType(), item); - Add(item); return item; } - /// - /// Adds a menu item - /// - /// - /// - /// - /// The text to display for the menu item, will default to the IAction alias if not specified - /// - /// - public TMenuItem Add(string name, bool hasSeparator = false, IDictionary additionalData = null) - where TAction : IAction - where TMenuItem : MenuItem, new() - { - var item = CreateMenuItem(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; - } - - /// - /// Adds a menu item - /// - /// The text to display for the menu item, will default to the IAction alias if not specified - /// - public MenuItem Add(string name) - where T : IAction - { - return Add(name, false, null); - } - - /// - /// Adds a menu item with a key value pair which is merged to the AdditionalData bag - /// - /// - /// - /// - /// The text to display for the menu item, will default to the IAction alias if not specified - /// - public MenuItem Add(string name, string key, string value, bool hasSeparator = false) - where T : IAction - { - return Add(name, hasSeparator, new Dictionary { { key, value } }); - } - /// /// Adds a menu item with a dictionary which is merged to the AdditionalData bag /// /// /// - /// /// The text to display for the menu item, will default to the IAction alias if not specified - /// - public MenuItem Add(string name, bool hasSeparator = false, IDictionary additionalData = null) + /// The text to display for the menu item, will default to the IAction alias if not specified + public MenuItem Add(string name, bool hasSeparator = false) where T : IAction { - var item = CreateMenuItem(name, hasSeparator, additionalData); + var item = CreateMenuItem(name, hasSeparator); if (item != null) { Add(item); @@ -113,69 +57,51 @@ namespace Umbraco.Web.Models.Trees } /// - /// + /// Adds a menu item with a dictionary which is merged to the AdditionalData bag /// /// /// - /// The text to display for the menu item, will default to the IAction alias if not specified - /// - /// - internal MenuItem CreateMenuItem(string name, bool hasSeparator = false, IDictionary additionalData = null) + /// The used to localize the action name based on it's alias + /// + public MenuItem Add(ILocalizedTextService textService, bool hasSeparator = false, bool opensDialog = false) where T : IAction { - var item = Current.Actions.GetAction(); + var item = CreateMenuItem(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; } - - /// - /// Checks if the IAction type passed in is attributed with LegacyActionMenuItemAttribute and if so - /// ensures that the correct action metadata is added. - /// - /// - /// - private void DetectLegacyActionMenu(Type actionType, MenuItem menuItem) + + internal MenuItem CreateMenuItem(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(false); - if (attribute != null) + var item = Current.Actions.GetAction(); + 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(ILocalizedTextService textService, bool hasSeparator = false, bool opensDialog = false) + where T : IAction + { + var item = Current.Actions.GetAction(); + if (item == null) return null; + + var menuItem = new MenuItem(item, textService.Localize($"actions/{item.Alias}")) + { + SeperatorBefore = hasSeparator, + OpensDialog = opensDialog + }; + + return menuItem; + } + } } diff --git a/src/Umbraco.Web/Models/Trees/RefreshNode.cs b/src/Umbraco.Web/Models/Trees/RefreshNode.cs index 7f20562962..2641baa34f 100644 --- a/src/Umbraco.Web/Models/Trees/RefreshNode.cs +++ b/src/Umbraco.Web/Models/Trees/RefreshNode.cs @@ -1,10 +1,27 @@ -namespace Umbraco.Web.Models.Trees +using Umbraco.Core.Services; + +namespace Umbraco.Web.Models.Trees { + /// /// /// Represents the refresh node menu item /// - [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; + } } } diff --git a/src/Umbraco.Web/NotificationServiceExtensions.cs b/src/Umbraco.Web/NotificationServiceExtensions.cs index 1fb229a66e..4be7b4f091 100644 --- a/src/Umbraco.Web/NotificationServiceExtensions.cs +++ b/src/Umbraco.Web/NotificationServiceExtensions.cs @@ -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 diff --git a/src/Umbraco.Web/PropertyEditors/CheckBoxListPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/CheckBoxListPropertyEditor.cs index 53de8460f2..7f8dc3f03a 100644 --- a/src/Umbraco.Web/PropertyEditors/CheckBoxListPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/CheckBoxListPropertyEditor.cs @@ -31,6 +31,6 @@ namespace Umbraco.Web.PropertyEditors protected override IConfigurationEditor CreateConfigurationEditor() => new ValueListConfigurationEditor(_textService); /// - protected override IDataValueEditor CreateValueEditor() => new PublishValuesMultipleValueEditor(false, Attribute); + protected override IDataValueEditor CreateValueEditor() => new PublishValuesMultipleValueEditor(Logger, Attribute); } } diff --git a/src/Umbraco.Web/PropertyEditors/DropDownFlexiblePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownFlexiblePropertyEditor.cs index 6acbedef63..4424e1d245 100644 --- a/src/Umbraco.Web/PropertyEditors/DropDownFlexiblePropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DropDownFlexiblePropertyEditor.cs @@ -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); diff --git a/src/Umbraco.Web/PropertyEditors/DropDownMultipleConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownMultipleConfigurationEditor.cs deleted file mode 100644 index a8956f9c4f..0000000000 --- a/src/Umbraco.Web/PropertyEditors/DropDownMultipleConfigurationEditor.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System.Collections.Generic; -using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Services; - -namespace Umbraco.Web.PropertyEditors -{ - /// - /// Represents a configuration editor for the "drop down list multiple" property editor. - /// - /// - /// Ensures that 'multiple' is saved for the config in the db but is not a configuration field. - /// 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 - /// fixme what is multiple exactly?! - /// - 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' - - /// - public override Dictionary ToConfigurationEditor(ValueListConfiguration configuration) - { - var dictionary = base.ToConfigurationEditor(configuration); - - // always add the multiple field, as 'true' - dictionary["multiple"] = 1; - - return dictionary; - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/PropertyEditors/DropDownMultiplePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownMultiplePropertyEditor.cs deleted file mode 100644 index 5992090a62..0000000000 --- a/src/Umbraco.Web/PropertyEditors/DropDownMultiplePropertyEditor.cs +++ /dev/null @@ -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 -{ - /// - /// A property editor to allow multiple selection of pre-defined items - /// - /// - /// 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. - /// - [DataEditor(Constants.PropertyEditors.Aliases.DropDownListMultiple, "Dropdown list multiple", "dropdown", Group = "lists", Icon="icon-bulleted-list", IsDeprecated = true)] - public class DropDownMultiplePropertyEditor : DropDownMultipleWithKeysPropertyEditor - { - /// - /// The constructor will setup the property editor based on the attribute if one is found - /// - public DropDownMultiplePropertyEditor(ILogger logger, ILocalizedTextService textService) - : base(logger, textService) - { } - - /// - protected override IDataValueEditor CreateValueEditor() => new PublishValuesMultipleValueEditor(false, Attribute); - } -} diff --git a/src/Umbraco.Web/PropertyEditors/DropDownMultipleWithKeysPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownMultipleWithKeysPropertyEditor.cs deleted file mode 100644 index 0b882c6b8d..0000000000 --- a/src/Umbraco.Web/PropertyEditors/DropDownMultipleWithKeysPropertyEditor.cs +++ /dev/null @@ -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 -{ - /// - /// Represents a property editor that allows multiple selection of pre-defined items. - /// - /// - /// Due to backwards compatibility, this editor stores the value as a CSV string listing - /// the ids of individual items. - /// - [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; - - /// - /// Initializes a new instance of the class. - /// - public DropDownMultipleWithKeysPropertyEditor(ILogger logger, ILocalizedTextService textService) - : base(logger, textService) - { - _textService = textService; - } - - /// - protected override IDataValueEditor CreateValueEditor() => new PublishValuesMultipleValueEditor(true, Attribute); - - /// - protected override IConfigurationEditor CreateConfigurationEditor() => new DropDownMultipleConfigurationEditor(_textService); - } -} diff --git a/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs deleted file mode 100644 index f4736ab63f..0000000000 --- a/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs +++ /dev/null @@ -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 -{ - /// - /// A property editor to allow the individual selection of pre-defined items. - /// - /// - /// 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. - /// - [DataEditor(Constants.PropertyEditors.Aliases.DropDownList, "Dropdown list", "dropdown", ValueType = ValueTypes.String, Group = "lists", Icon = "icon-indent", IsDeprecated = true)] - public class DropDownPropertyEditor : DropDownWithKeysPropertyEditor - { - /// - /// The constructor will setup the property editor based on the attribute if one is found - /// - public DropDownPropertyEditor(ILogger logger, ILocalizedTextService textService) - : base(logger, textService) - { } - - /// - /// 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. - /// - /// - protected override IDataValueEditor CreateValueEditor() => new PublishValueValueEditor(Attribute, Logger); - } -} diff --git a/src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs deleted file mode 100644 index 72d4b8c95f..0000000000 --- a/src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Umbraco.Core; -using Umbraco.Core.Logging; -using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Services; - -namespace Umbraco.Web.PropertyEditors -{ - /// - /// A property editor to allow the individual selection of pre-defined items. - /// - /// - /// 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. - /// - [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; - - /// - /// The constructor will setup the property editor based on the attribute if one is found - /// - public DropDownWithKeysPropertyEditor(ILogger logger, ILocalizedTextService textService) - : base(logger) - { - _textService = textService; - } - - /// - /// Return a custom pre-value editor - /// - /// - protected override IConfigurationEditor CreateConfigurationEditor() => new ValueListConfigurationEditor(_textService); - } -} diff --git a/src/Umbraco.Web/PropertyEditors/PublishValueValueEditor.cs b/src/Umbraco.Web/PropertyEditors/PublishValueValueEditor.cs deleted file mode 100644 index 49ed34ffef..0000000000 --- a/src/Umbraco.Web/PropertyEditors/PublishValueValueEditor.cs +++ /dev/null @@ -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 -{ - /// - /// 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 - /// - /// - /// This is required for legacy/backwards compatibility, otherwise we'd just store the string version and cache the string version without - /// needing additional lookups. - /// - internal class PublishValueValueEditor : DataValueEditor - { - private readonly ILogger _logger; - - internal PublishValueValueEditor(DataEditorAttribute attribute, ILogger logger) - : base(attribute) - { - _logger = logger; - } - - /// - 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(); - if (configuration == null) - return base.ConvertDbToString(propertyType, value, dataTypeService); - - var items = configuration.Items; - - var idAttempt = value.TryConvertTo(); - if (idAttempt.Success) - { - var itemId = idAttempt.Result; - var item = items.FirstOrDefault(x => x.Id == itemId); - if (item != null) return item.Value; - - _logger.Warn("Could not find a configuration item with ID " + itemId + " for property alias " + propertyType.Alias); - } - - // fallback to default - return base.ConvertDbToString(propertyType, value, dataTypeService); - } - } -} diff --git a/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs b/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs index 0276bdc0a4..8e0737dedd 100644 --- a/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs @@ -11,58 +11,19 @@ using Umbraco.Web.Composing; namespace Umbraco.Web.PropertyEditors { /// - /// 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 /// /// /// This is re-used by editors such as the multiple drop down list or check box list /// - 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) - { } - - /// - /// If publishing ids, we don't need to do anything, otherwise we need to look up the pre-values and get the string values - /// - /// - /// - /// - /// - 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(); - 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; } /// @@ -81,7 +42,7 @@ namespace Umbraco.Web.PropertyEditors /// /// 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 /// /// /// diff --git a/src/Umbraco.Web/PropertyEditors/RadioButtonsPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RadioButtonsPropertyEditor.cs index e5d9e4d4e8..46069fec79 100644 --- a/src/Umbraco.Web/PropertyEditors/RadioButtonsPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/RadioButtonsPropertyEditor.cs @@ -8,19 +8,24 @@ namespace Umbraco.Web.PropertyEditors /// /// A property editor to allow the individual selection of pre-defined items. /// - /// - /// 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. - /// [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; + /// /// The constructor will setup the property editor based on the attribute if one is found /// public RadioButtonsPropertyEditor(ILogger logger, ILocalizedTextService textService) - : base(logger, textService) - { } + : base(logger) + { + _textService = textService; + } + + /// + /// Return a custom pre-value editor + /// + /// + protected override IConfigurationEditor CreateConfigurationEditor() => new ValueListConfigurationEditor(_textService); } } diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/FlexibleDropdownPropertyValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/FlexibleDropdownPropertyValueConverter.cs index 521817a7de..d470f54662 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/FlexibleDropdownPropertyValueConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/FlexibleDropdownPropertyValueConverter.cs @@ -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(); } public override object ConvertIntermediateToObject(IPublishedElement owner, PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) diff --git a/src/Umbraco.Web/Runtime/WebRuntimeComponent.cs b/src/Umbraco.Web/Runtime/WebRuntimeComponent.cs index 028f1bf728..1af24db636 100644 --- a/src/Umbraco.Web/Runtime/WebRuntimeComponent.cs +++ b/src/Umbraco.Web/Runtime/WebRuntimeComponent.cs @@ -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() - .SetProducer(() => typeLoader.GetActions()); + .Add(() => typeLoader.GetTypes()); var surfaceControllerTypes = new SurfaceControllerTypeCollection(typeLoader.GetSurfaceControllers()); composition.Container.RegisterInstance(surfaceControllerTypes); diff --git a/src/Umbraco.Web/Trees/ContentBlueprintTreeController.cs b/src/Umbraco.Web/Trees/ContentBlueprintTreeController.cs index 5b45888dca..364c9c391f 100644 --- a/src/Umbraco.Web/Trees/ContentBlueprintTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentBlueprintTreeController.cs @@ -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(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}")); - menu.Items.Add(Services.TextService.Localize( - $"actions/{ActionRefresh.Instance.Alias}"), true); + menu.Items.Add(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(Services.TextService.Localize($"actions/{ActionCreateBlueprintFromContent.Instance.Alias}")); + var createItem = menu.Items.Add(Services.TextService, opensDialog: true); createItem.NavigateToRoute("/settings/contentBlueprints/edit/-1?create=true&doctype=" + ct.Alias); - menu.Items.Add(Services.TextService.Localize($"actions/{ActionRefresh.Instance.Alias}"), true); + menu.Items.Add(new RefreshNode(Services.TextService, true)); return menu; } - menu.Items.Add(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}")); + menu.Items.Add(Services.TextService, opensDialog: true); return menu; } diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs index 4a0589cce4..04c356a4fd 100644 --- a/src/Umbraco.Web/Trees/ContentTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentTreeController.cs @@ -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( - 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(Services.TextService.Localize("actions", ActionNew.Instance.Alias)); - menu.Items.Add(Services.TextService.Localize("actions", ActionSort.Instance.Alias), true); + menu.Items.Add(Services.TextService, opensDialog: true); + menu.Items.Add(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(Services.TextService.Localize("actions", ActionRePublish.Instance.Alias)).ConvertLegacyMenuItem(null, "content", "content"); - menu.Items.Add(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( - 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(item, menu); - AddActionNode(item, menu); - - AddActionNode(item, menu); - - //need to ensure some of these are converted to the legacy system - until we upgrade them all to be angularized. - AddActionNode(item, menu, true); - AddActionNode(item, menu); - + AddActionNode(item, menu, opensDialog: true); + AddActionNode(item, menu, opensDialog: true); + AddActionNode(item, menu, opensDialog: true); + AddActionNode(item, menu, true, opensDialog: true); + AddActionNode(item, menu, opensDialog: true); AddActionNode(item, menu, true); + AddActionNode(item, menu, opensDialog: true); + AddActionNode(item, menu, opensDialog: true); + //fixme - conver this editor to angular + AddActionNode(item, menu, true, convert: true, opensDialog: true); - AddActionNode(item, menu, convert: true); - AddActionNode(item, menu); - AddActionNode(item, menu, convert: true); - AddActionNode(item, menu, true, true); - - AddActionNode(item, menu, true); + menu.Items.Add(new MenuItem("notify", Services.TextService) + { + Icon = "megaphone", + SeperatorBefore = true, + OpensDialog = true + }); - AddActionNode(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(Services.TextService.Localize("actions", ActionRestore.Instance.Alias)); - menu.Items.Add(Services.TextService.Localize("actions", ActionDelete.Instance.Alias)); + menu.Items.Add(Services.TextService, opensDialog: true); + menu.Items.Add(Services.TextService, opensDialog: true); - menu.Items.Add(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(IUmbracoEntity item, MenuItemCollection menu, bool hasSeparator = false, bool convert = false) + //fixme: Remove the need for converting to legacy + private void AddActionNode(IUmbracoEntity item, MenuItemCollection menu, bool hasSeparator = false, bool convert = false, bool opensDialog = false) where TAction : IAction { + //fixme: Inject var menuItem = menu.Items.Add(Services.TextService.Localize("actions", Current.Actions.GetAction().Alias), hasSeparator); if (convert) menuItem.ConvertLegacyMenuItem(item, "content", "content"); - } - - private void AddActionNode(IUmbracoEntity item, MenuItemCollection menu, bool hasSeparator = false, bool convert = false) - where TItem : MenuItem, new() - where TAction : IAction - { - var menuItem = menu.Items.Add(Services.TextService.Localize("actions", Current.Actions.GetAction().Alias), hasSeparator); - if (convert) menuItem.ConvertLegacyMenuItem(item, "content", "content"); + menuItem.OpensDialog = opensDialog; } public IEnumerable Search(string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null) diff --git a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs index 4d4f1be483..646f47068b 100644 --- a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs +++ b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs @@ -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(Services.TextService.Localize("actions/emptyTrashcan")); - menu.Items.Add(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 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(); + // 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)); } diff --git a/src/Umbraco.Web/Trees/ContentTypeTreeController.cs b/src/Umbraco.Web/Trees/ContentTypeTreeController.cs index a2179be75f..43e5b03f2f 100644 --- a/src/Umbraco.Web/Trees/ContentTypeTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentTypeTreeController.cs @@ -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(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias))); - menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionImport.Instance.Alias)), true); - menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true); + menu.Items.Add(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(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias))); + menu.Items.Add(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(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)), true); + menu.Items.Add(Services.TextService, true, opensDialog: true); } - menu.Items.Add(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(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias))); + menu.Items.Add(Services.TextService, opensDialog: true); } //no move action if this is a child doc type if (parent == null) { - menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionMove.Instance.Alias)), true); + menu.Items.Add(Services.TextService, true, opensDialog: true); } - menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionCopy.Instance.Alias))); - menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionExport.Instance.Alias)), true); - menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)), true); + menu.Items.Add(Services.TextService, opensDialog: true); + menu.Items.Add(new MenuItem("export", Services.TextService) + { + Icon = "download-alt", + SeperatorBefore = true, + OpensDialog = true + }); + menu.Items.Add(Services.TextService, true, opensDialog: true); if (enableInheritedDocumentTypes) - menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true); + menu.Items.Add(new RefreshNode(Services.TextService, true)); } return menu; diff --git a/src/Umbraco.Web/Trees/DataTypeTreeController.cs b/src/Umbraco.Web/Trees/DataTypeTreeController.cs index 3087808f10..6c89f4a1dc 100644 --- a/src/Umbraco.Web/Trees/DataTypeTreeController.cs +++ b/src/Umbraco.Web/Trees/DataTypeTreeController.cs @@ -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(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}")); - menu.Items.Add(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true); + menu.Items.Add(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(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}")); + menu.Items.Add(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(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}")); + menu.Items.Add(Services.TextService, opensDialog: true); } - menu.Items.Add(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(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}")); + menu.Items.Add(Services.TextService, opensDialog: true); - menu.Items.Add(Services.TextService.Localize($"actions/{ActionMove.Instance.Alias}"), hasSeparator: true); + menu.Items.Add(Services.TextService, hasSeparator: true, opensDialog: true); } return menu; diff --git a/src/Umbraco.Web/Trees/DictionaryTreeController.cs b/src/Umbraco.Web/Trees/DictionaryTreeController.cs index 3043377d65..d0a7fce3ad 100644 --- a/src/Umbraco.Web/Trees/DictionaryTreeController.cs +++ b/src/Umbraco.Web/Trees/DictionaryTreeController.cs @@ -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(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}")); + menu.Items.Add(Services.TextService, opensDialog: true); if (id != Constants.System.Root.ToInvariantString()) - menu.Items.Add(Services.TextService.Localize( - $"actions/{ActionDelete.Instance.Alias}"), true); + menu.Items.Add(Services.TextService, true, opensDialog: true); - menu.Items.Add(Services.TextService.Localize( - $"actions/{ActionRefresh.Instance.Alias}"), true); + menu.Items.Add(new RefreshNode(Services.TextService, true)); return menu; } diff --git a/src/Umbraco.Web/Trees/FileSystemTreeController.cs b/src/Umbraco.Web/Trees/FileSystemTreeController.cs index 21e81a58af..f1e53ed5d4 100644 --- a/src/Umbraco.Web/Trees/FileSystemTreeController.cs +++ b/src/Umbraco.Web/Trees/FileSystemTreeController.cs @@ -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(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias))); + menu.Items.Add(Services.TextService, opensDialog: true); //refresh action - menu.Items.Add(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(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias))); + menu.Items.Add(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(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)), true); + menu.Items.Add(Services.TextService, true, opensDialog: true); } //refresh action - menu.Items.Add(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(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias))); + menu.Items.Add(Services.TextService, opensDialog: true); return menu; } diff --git a/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs b/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs index 131c7954c8..d0bfa360fa 100644 --- a/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs +++ b/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs @@ -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 /// internal class LegacyTreeDataConverter { + //fixme: remove this whole class when everything is angularized + /// /// This will look at the legacy IAction's JsFunctionName and convert it to a confirmation dialog view if possible /// @@ -24,14 +27,9 @@ namespace Umbraco.Web.Trees /// internal static Attempt GetLegacyConfirmView(IAction action) { - if (action.JsFunctionName.IsNullOrWhiteSpace()) + switch (action) { - return Attempt.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 /// internal static Attempt GetUrlAndTitleFromLegacyAction(IAction action, string nodeId, string nodeType, string nodeName, string currentSection) { - if (action.JsFunctionName.IsNullOrWhiteSpace()) + switch (action) { - return Attempt.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.Fail(); } diff --git a/src/Umbraco.Web/Trees/MacrosTreeController.cs b/src/Umbraco.Web/Trees/MacrosTreeController.cs index a4f486661e..3f925eef8d 100644 --- a/src/Umbraco.Web/Trees/MacrosTreeController.cs +++ b/src/Umbraco.Web/Trees/MacrosTreeController.cs @@ -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(Services.TextService.Localize("actions", ActionNew.Instance.Alias)) + menu.Items.Add(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("application")); //refresh action - menu.Items.Add(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(Services.TextService.Localize("actions", ActionDelete.Instance.Alias)) + menu.Items.Add(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 diff --git a/src/Umbraco.Web/Trees/MediaTreeController.cs b/src/Umbraco.Web/Trees/MediaTreeController.cs index 8eb37e6224..0292a907fc 100644 --- a/src/Umbraco.Web/Trees/MediaTreeController.cs +++ b/src/Umbraco.Web/Trees/MediaTreeController.cs @@ -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( - 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(Services.TextService.Localize("actions", ActionNew.Instance.Alias)); - menu.Items.Add(Services.TextService.Localize("actions", ActionSort.Instance.Alias), true); - menu.Items.Add(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true); + menu.Items.Add(Services.TextService, opensDialog: true); + menu.Items.Add(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( - 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(Services.TextService.Localize("actions", ActionNew.Instance.Alias)); - menu.Items.Add(Services.TextService.Localize("actions", ActionMove.Instance.Alias)); - menu.Items.Add(Services.TextService.Localize("actions", ActionDelete.Instance.Alias)); - menu.Items.Add(Services.TextService.Localize("actions", ActionSort.Instance.Alias)); - menu.Items.Add(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true); + menu.Items.Add(Services.TextService, opensDialog: true); + menu.Items.Add(Services.TextService, opensDialog: true); + menu.Items.Add(Services.TextService, opensDialog: true); + menu.Items.Add(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; diff --git a/src/Umbraco.Web/Trees/MediaTypeTreeController.cs b/src/Umbraco.Web/Trees/MediaTypeTreeController.cs index 7b346c6871..547199676a 100644 --- a/src/Umbraco.Web/Trees/MediaTypeTreeController.cs +++ b/src/Umbraco.Web/Trees/MediaTypeTreeController.cs @@ -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(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}")); - menu.Items.Add(Services.TextService.Localize( - $"actions/{ActionRefresh.Instance.Alias}")); + menu.Items.Add(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(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}")); + menu.Items.Add(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(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}")); + menu.Items.Add(Services.TextService, opensDialog: true); } - menu.Items.Add(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(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}")); + menu.Items.Add(Services.TextService, opensDialog: true); //no move action if this is a child doc type if (parent == null) { - menu.Items.Add(Services.TextService.Localize($"actions/{ActionMove.Instance.Alias}"), true); + menu.Items.Add(Services.TextService, true, opensDialog: true); } } else { - menu.Items.Add(Services.TextService.Localize($"actions/{ActionMove.Instance.Alias}")); + menu.Items.Add(Services.TextService, opensDialog: true); //no move action if this is a child doc type if (parent == null) { - menu.Items.Add(Services.TextService.Localize($"actions/{ActionMove.Instance.Alias}"), true); + menu.Items.Add(Services.TextService, true, opensDialog: true); } } - menu.Items.Add(Services.TextService.Localize($"actions/{ActionCopy.Instance.Alias}")); - menu.Items.Add(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}")); + menu.Items.Add(Services.TextService, opensDialog: true); + menu.Items.Add(Services.TextService, opensDialog: true); if (enableInheritedMediaTypes) - menu.Items.Add(Services.TextService.Localize( - $"actions/{ActionRefresh.Instance.Alias}"), true); + menu.Items.Add(new RefreshNode(Services.TextService, true)); } return menu; diff --git a/src/Umbraco.Web/Trees/MemberTreeController.cs b/src/Umbraco.Web/Trees/MemberTreeController.cs index f3ca0c9a02..68819351c0 100644 --- a/src/Umbraco.Web/Trees/MemberTreeController.cs +++ b/src/Umbraco.Web/Trees/MemberTreeController.cs @@ -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(Services.TextService.Localize("actions", ActionNew.Instance.Alias)); + menu.Items.Add(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(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(Services.TextService.Localize("actions", ActionDelete.Instance.Alias)); + menu.Items.Add(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)); } diff --git a/src/Umbraco.Web/Trees/MemberTypeAndGroupTreeControllerBase.cs b/src/Umbraco.Web/Trees/MemberTypeAndGroupTreeControllerBase.cs index a710b52595..9ea5908891 100644 --- a/src/Umbraco.Web/Trees/MemberTypeAndGroupTreeControllerBase.cs +++ b/src/Umbraco.Web/Trees/MemberTypeAndGroupTreeControllerBase.cs @@ -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(Services.TextService.Localize("actions", ActionNew.Instance.Alias)); - menu.Items.Add(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(Services.TextService.Localize("actions", ActionDelete.Instance.Alias)); + menu.Items.Add(Services.TextService, opensDialog: true); } return menu; diff --git a/src/Umbraco.Web/Trees/PackagesTreeController.cs b/src/Umbraco.Web/Trees/PackagesTreeController.cs index 31f577ad85..8158b47985 100644 --- a/src/Umbraco.Web/Trees/PackagesTreeController.cs +++ b/src/Umbraco.Web/Trees/PackagesTreeController.cs @@ -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(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}")) + menu.Items.Add(Services.TextService, opensDialog: true) .ConvertLegacyMenuItem(null, Constants.Trees.Packages, queryStrings.GetValue("application")); } else if (id == "created") { - menu.Items.Add(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}")) + menu.Items.Add(Services.TextService, opensDialog: true) .ConvertLegacyMenuItem(null, Constants.Trees.Packages, queryStrings.GetValue("application")); - menu.Items.Add( - 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(Services.TextService.Localize("actions", ActionDelete.Instance.Alias)); + menu.Items.Add(Services.TextService, opensDialog: true); } return menu; diff --git a/src/Umbraco.Web/Trees/RelationTypeTreeController.cs b/src/Umbraco.Web/Trees/RelationTypeTreeController.cs index 4930b4dc5e..33ccc152c5 100644 --- a/src/Umbraco.Web/Trees/RelationTypeTreeController.cs +++ b/src/Umbraco.Web/Trees/RelationTypeTreeController.cs @@ -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(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("application")); + var addMenuItem = menu.Items.Add(Services.TextService, opensDialog: true); + addMenuItem.LaunchDialogUrl("developer/RelationTypes/NewRelationType.aspx", "Create New RelationType"); //refresh action - menu.Items.Add(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(Services.TextService.Localize("actions", ActionDelete.Instance.Alias)) + menu.Items.Add(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 diff --git a/src/Umbraco.Web/Trees/TemplatesTreeController.cs b/src/Umbraco.Web/Trees/TemplatesTreeController.cs index 768768f888..2339d92d96 100644 --- a/src/Umbraco.Web/Trees/TemplatesTreeController.cs +++ b/src/Umbraco.Web/Trees/TemplatesTreeController.cs @@ -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(Services.TextService.Localize("actions", ActionNew.Instance.Alias)); + var item = menu.Items.Add(Services.TextService, opensDialog: true); item.NavigateToRoute($"{queryStrings.GetValue("application")}/templates/edit/{id}?create=true"); if (id == Constants.System.Root.ToInvariantString()) { //refresh action - menu.Items.Add(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(Services.TextService.Localize("actions", ActionDelete.Instance.Alias), true); + menu.Items.Add(Services.TextService, true, opensDialog: true); } //add refresh - menu.Items.Add(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true); + menu.Items.Add(new RefreshNode(Services.TextService, true)); return menu; diff --git a/src/Umbraco.Web/Trees/UserPermissionsTreeController.cs b/src/Umbraco.Web/Trees/UserPermissionsTreeController.cs index e381c7ec0f..479cc20083 100644 --- a/src/Umbraco.Web/Trees/UserPermissionsTreeController.cs +++ b/src/Umbraco.Web/Trees/UserPermissionsTreeController.cs @@ -3,10 +3,11 @@ using System.Linq; using System.Net.Http.Formatting; using Umbraco.Core; using Umbraco.Core.Services; +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 @@ -43,7 +44,7 @@ namespace Umbraco.Web.Trees if (id == Constants.System.Root.ToInvariantString()) { // root actions - menu.Items.Add(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true); + menu.Items.Add(new RefreshNode(Services.TextService, true)); return menu; } diff --git a/src/Umbraco.Web/Trees/UserTreeController.cs b/src/Umbraco.Web/Trees/UserTreeController.cs index 8ae5b002c6..f029a929de 100644 --- a/src/Umbraco.Web/Trees/UserTreeController.cs +++ b/src/Umbraco.Web/Trees/UserTreeController.cs @@ -4,7 +4,7 @@ using Umbraco.Core.Services; 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 diff --git a/src/Umbraco.Web/TypeLoaderExtensions.cs b/src/Umbraco.Web/TypeLoaderExtensions.cs index 710c342115..4d09783ca9 100644 --- a/src/Umbraco.Web/TypeLoaderExtensions.cs +++ b/src/Umbraco.Web/TypeLoaderExtensions.cs @@ -5,7 +5,7 @@ using Umbraco.Web.Mvc; using Umbraco.Web.Trees; using Umbraco.Web.WebApi; using Umbraco.Core.Composing; -using Umbraco.Web._Legacy.Actions; + namespace Umbraco.Web { @@ -14,15 +14,6 @@ namespace Umbraco.Web /// public static class TypeLoaderExtensions { - /// - /// Returns all available IAction in application - /// - /// - internal static IEnumerable GetActions(this TypeLoader mgr) - { - return mgr.GetTypes(); - } - /// /// Returns all available TreeApiController's in application that are attribute with TreeAttribute /// @@ -43,15 +34,5 @@ namespace Umbraco.Web return mgr.GetTypes(); } - /// - /// Returns all available ISearchableTrees in application - /// - /// - /// - internal static IEnumerable GetSearchableTrees(this TypeLoader mgr) - { - return mgr.GetTypes(); - } - } } diff --git a/src/Umbraco.Web/UI/Pages/UmbracoEnsuredPage.cs b/src/Umbraco.Web/UI/Pages/UmbracoEnsuredPage.cs index 30adf2cc3d..9f13939bac 100644 --- a/src/Umbraco.Web/UI/Pages/UmbracoEnsuredPage.cs +++ b/src/Umbraco.Web/UI/Pages/UmbracoEnsuredPage.cs @@ -11,9 +11,10 @@ using Umbraco.Core.Exceptions; using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; using Umbraco.Core.Security; +using Umbraco.Web.Actions; using Umbraco.Web.Composing; using Umbraco.Web.Security; -using Umbraco.Web._Legacy.Actions; + namespace Umbraco.Web.UI.Pages { diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 656bbd29c5..f17f6daf72 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -360,7 +360,6 @@ - @@ -428,7 +427,6 @@ - @@ -531,39 +529,26 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + @@ -813,11 +798,9 @@ - - @@ -827,9 +810,6 @@ - - - @@ -953,7 +933,6 @@ - @@ -1269,12 +1248,6 @@ NewRelationType.aspx - - RelationTypesWebService.asmx - Component - - - insertMasterpageContent.aspx ASPXCodeBehind @@ -1378,7 +1351,6 @@ ASPXCodeBehind - ASPXCodeBehind diff --git a/src/Umbraco.Web/WebApi/Filters/EnsureUserPermissionForContentAttribute.cs b/src/Umbraco.Web/WebApi/Filters/EnsureUserPermissionForContentAttribute.cs index 4d9a6db129..5d71992b74 100644 --- a/src/Umbraco.Web/WebApi/Filters/EnsureUserPermissionForContentAttribute.cs +++ b/src/Umbraco.Web/WebApi/Filters/EnsureUserPermissionForContentAttribute.cs @@ -5,9 +5,10 @@ using System.Web.Http.Filters; using Umbraco.Core.Exceptions; using Umbraco.Web.Composing; using Umbraco.Web.Editors; -using Umbraco.Web._Legacy.Actions; + using Umbraco.Core; using Umbraco.Core.Models; +using Umbraco.Web.Actions; namespace Umbraco.Web.WebApi.Filters { @@ -39,7 +40,7 @@ namespace Umbraco.Web.WebApi.Filters { if (string.IsNullOrEmpty(paramName)) throw new ArgumentNullOrEmptyException(nameof(paramName)); _paramName = paramName; - _permissionToCheck = ActionBrowse.Instance.Letter; + _permissionToCheck = ActionBrowse.ActionLetter; } public EnsureUserPermissionForContentAttribute(string paramName, char permissionToCheck) diff --git a/src/Umbraco.Web/WebApi/Filters/FilterAllowedOutgoingContentAttribute.cs b/src/Umbraco.Web/WebApi/Filters/FilterAllowedOutgoingContentAttribute.cs index 748e0e8a7d..31e0b22ce1 100644 --- a/src/Umbraco.Web/WebApi/Filters/FilterAllowedOutgoingContentAttribute.cs +++ b/src/Umbraco.Web/WebApi/Filters/FilterAllowedOutgoingContentAttribute.cs @@ -8,7 +8,8 @@ using Umbraco.Core.Services; using Umbraco.Core; using Umbraco.Web.Composing; using Umbraco.Core.Models; -using Umbraco.Web._Legacy.Actions; +using Umbraco.Web.Actions; + namespace Umbraco.Web.WebApi.Filters { @@ -25,7 +26,7 @@ namespace Umbraco.Web.WebApi.Filters public FilterAllowedOutgoingContentAttribute(Type outgoingType) : this(outgoingType, Current.Services.UserService, Current.Services.EntityService) { - _permissionToCheck = ActionBrowse.Instance.Letter; + _permissionToCheck = ActionBrowse.ActionLetter; } public FilterAllowedOutgoingContentAttribute(Type outgoingType, char permissionToCheck) @@ -37,7 +38,7 @@ namespace Umbraco.Web.WebApi.Filters public FilterAllowedOutgoingContentAttribute(Type outgoingType, string propertyName) : this(outgoingType, propertyName, Current.Services.UserService, Current.Services.EntityService) { - _permissionToCheck = ActionBrowse.Instance.Letter; + _permissionToCheck = ActionBrowse.ActionLetter; } public FilterAllowedOutgoingContentAttribute(Type outgoingType, IUserService userService, IEntityService entityService) @@ -45,7 +46,7 @@ namespace Umbraco.Web.WebApi.Filters { _userService = userService ?? throw new ArgumentNullException(nameof(userService)); _entityService = entityService ?? throw new ArgumentNullException(nameof(entityService)); - _permissionToCheck = ActionBrowse.Instance.Letter; + _permissionToCheck = ActionBrowse.ActionLetter; } public FilterAllowedOutgoingContentAttribute(Type outgoingType, char permissionToCheck, IUserService userService, IEntityService entityService) @@ -65,7 +66,7 @@ namespace Umbraco.Web.WebApi.Filters _entityService = entityService ?? throw new ArgumentNullException(nameof(entityService)); _userService = userService; _entityService = entityService; - _permissionToCheck = ActionBrowse.Instance.Letter; + _permissionToCheck = ActionBrowse.ActionLetter; } protected override void FilterItems(IUser user, IList items) diff --git a/src/Umbraco.Web/_Legacy/Actions/Action.cs b/src/Umbraco.Web/_Legacy/Actions/Action.cs deleted file mode 100644 index 241218ddb7..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/Action.cs +++ /dev/null @@ -1,193 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text.RegularExpressions; -using Umbraco.Core.Logging; -using Umbraco.Core.Models.Membership; -using Umbraco.Web.Composing; -using Umbraco.Core.Services; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// Actions and Actionhandlers are a key concept to umbraco and a developer whom wish to apply - /// businessrules whenever data is changed within umbraco, by implementing the IActionHandler - /// interface it's possible to invoke methods (foreign to umbraco) - this can be used whenever - /// there is a specific rule which needs to be applied to content. - /// - /// The Action class itself has responsibility for registering actions and actionhandlers, - /// and contains methods which will be invoked whenever a change is made to ex. a document, media or member - /// - /// An action/actionhandler will automatically be registered, using reflection - /// which is enabling thirdparty developers to extend the core functionality of - /// umbraco without changing the codebase. - /// - [Obsolete("Actions and ActionHandlers are obsolete and should no longer be used")] - public class Action - { - private static readonly Dictionary ActionJs = new Dictionary(); - - /// - /// Jacascript for the contextmenu - /// Suggestion: this method should be moved to the presentation layer. - /// - /// - /// String representation - public string ReturnJavascript(string language) - { - return findActions(language); - } - - /// - /// Returns a list of JavaScript file paths. - /// - /// - public static List GetJavaScriptFileReferences() - { - return Current.Actions - .Where(x => !string.IsNullOrWhiteSpace(x.JsSource)) - .Select(x => x.JsSource).ToList(); - //return ActionJsReference; - } - - /// - /// Javascript menuitems - tree contextmenu - /// Umbraco console - /// - /// Suggestion: this method should be moved to the presentation layer. - /// - /// - /// - private static string findActions(string language) - { - if (!ActionJs.ContainsKey(language)) - { - string _actionJsList = ""; - - foreach (IAction action in Current.Actions) - { - // Adding try/catch so this rutine doesn't fail if one of the actions fail - // Add to language JsList - try - { - // NH: Add support for css sprites - string icon = action.Icon; - if (!string.IsNullOrEmpty(icon) && icon.StartsWith(".")) - icon = icon.Substring(1, icon.Length - 1); - else - icon = "images/" + icon; - - _actionJsList += string.Format(",\n\tmenuItem(\"{0}\", \"{1}\", \"{2}\", \"{3}\")", - action.Letter, icon, Current.Services.TextService.Localize("actions/"+ action.Alias, new[] { language }), action.JsFunctionName); - } - catch (Exception ex) - { - Current.Logger.Error(ex, "Error registrering action to javascript"); - } - } - - if (_actionJsList.Length > 0) - _actionJsList = _actionJsList.Substring(2, _actionJsList.Length - 2); - - _actionJsList = "\nvar menuMethods = new Array(\n" + _actionJsList + "\n)\n"; - ActionJs.Add(language, _actionJsList); - } - - return ActionJs[language]; - - } - - internal static List FromEntityPermission(EntityPermission entityPermission) - { - List list = new List(); - foreach (var c in entityPermission.AssignedPermissions.Where(x => x.Length == 1).Select(x => x.ToCharArray()[0])) - { - IAction action = Current.Actions.ToList().Find( - delegate (IAction a) - { - return a.Letter == c; - } - ); - if (action != null) - list.Add(action); - } - return list; - } - - /// - /// Returns a list of IActions that are permission assignable - /// - /// - public static List GetPermissionAssignable() - { - return Current.Actions.ToList().FindAll(x => x.CanBePermissionAssigned); - } - - /// - /// Check if the current IAction is using legacy javascript methods - /// - /// - /// false if the Iaction is incompatible with 4.5 - public static bool ValidateActionJs(IAction action) - { - return !action.JsFunctionName.Contains("+"); - } - - /// - /// Method to convert the old modal calls to the new ones - /// - /// - /// - public static string ConvertLegacyJs(string javascript) - { - MatchCollection tags = - Regex.Matches(javascript, "openModal[^;]*;", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); - foreach (Match tag in tags) - { - string[] function = tag.Value.Split(','); - if (function.Length > 0) - { - string newFunction = "UmbClientMgr.openModalWindow" + function[0].Substring(9).Replace("parent.nodeID", "UmbClientMgr.mainTree().getActionNode().nodeId").Replace("nodeID", "UmbClientMgr.mainTree().getActionNode().nodeId").Replace("parent.returnRandom()", "'" + Guid.NewGuid().ToString() + "'"); - newFunction += ", " + function[1]; - newFunction += ", true"; - newFunction += ", " + function[2]; - newFunction += ", " + function[3]; - javascript = javascript.Replace(tag.Value, newFunction); - } - } - - return javascript; - } - } - - /// - /// This class is used to manipulate IActions that are implemented in a wrong way - /// For instance incompatible trees with 4.0 vs 4.5 - /// - public class PlaceboAction : IAction - { - public char Letter { get; set; } - public bool ShowInNotifier { get; set; } - public bool CanBePermissionAssigned { get; set; } - public string Icon { get; set; } - public string Alias { get; set; } - public string JsFunctionName { get; set; } - public string JsSource { get; set; } - public bool OpensDialog { get; set; } - - public PlaceboAction() { } - public PlaceboAction(IAction legacyAction) - { - Letter = legacyAction.Letter; - ShowInNotifier = legacyAction.ShowInNotifier; - CanBePermissionAssigned = legacyAction.CanBePermissionAssigned; - Icon = legacyAction.Icon; - Alias = legacyAction.Alias; - JsFunctionName = legacyAction.JsFunctionName; - JsSource = legacyAction.JsSource; - OpensDialog = legacyAction.OpensDialog; - } - } - -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionAssignDomain.cs b/src/Umbraco.Web/_Legacy/Actions/ActionAssignDomain.cs deleted file mode 100644 index c313f282ad..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionAssignDomain.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when a domain is being assigned to a document - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.AdministrationCategory)] - public class ActionAssignDomain : IAction - { - public static ActionAssignDomain Instance { get; } = new ActionAssignDomain(); - - #region IAction Members - - public char Letter - { - get - { - return 'I'; - } - } - - public string JsFunctionName - { - get - { - return null; - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "assignDomain"; - } - } - - public string Icon - { - get - { - return "home"; - } - } - - public bool ShowInNotifier - { - get - { - return false; - } - } - public bool CanBePermissionAssigned - { - get - { - return true; - } - } - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionBrowse.cs b/src/Umbraco.Web/_Legacy/Actions/ActionBrowse.cs deleted file mode 100644 index 20dc331516..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionBrowse.cs +++ /dev/null @@ -1,67 +0,0 @@ -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// 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. - /// - /// - /// 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. - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.ContentCategory)] - public class ActionBrowse : IAction - { - //create singleton - private static readonly ActionBrowse instance = new ActionBrowse(); - private ActionBrowse() { } - public static ActionBrowse Instance - { - get { return instance; } - } - - #region IAction Members - - public char Letter - { - get { return 'F'; } - } - - public bool ShowInNotifier - { - get { return false; } - } - - public bool CanBePermissionAssigned - { - get { return true; } - } - - public string Icon - { - get { return ""; } - } - - public string Alias - { - get { return "browse"; } - } - - public string JsFunctionName - { - get { return ""; } - } - - public string JsSource - { - get { return ""; } - } - - public bool OpensDialog => false; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionChangeDocType.cs b/src/Umbraco.Web/_Legacy/Actions/ActionChangeDocType.cs deleted file mode 100644 index b68627c38c..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionChangeDocType.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when the document type of a piece of content is changed - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.AdministrationCategory)] - public class ActionChangeDocType : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionChangeDocType m_instance = new ActionChangeDocType(); -#pragma warning restore 612,618 - - public static ActionChangeDocType Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - - return '7'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionChangeDocType()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - - return null; - } - } - - public string Alias - { - get - { - - return "changeDocType"; - } - } - - public string Icon - { - get - { - - return "axis-rotation-2"; - } - } - - public bool ShowInNotifier - { - get - { - - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - - return true; - } - } - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionCollectionBuilder.cs b/src/Umbraco.Web/_Legacy/Actions/ActionCollectionBuilder.cs deleted file mode 100644 index 39058d6836..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionCollectionBuilder.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using LightInject; -using Umbraco.Core.Composing; - -namespace Umbraco.Web._Legacy.Actions -{ - internal class ActionCollectionBuilder : ICollectionBuilder - { - private static Func> _producer; - - // for tests only - does not register the collection - public ActionCollectionBuilder() - { } - - public ActionCollectionBuilder(IServiceContainer container) - { - var collectionLifetime = CollectionLifetime; - - // register the collection - special lifetime - // the lifetime here is custom ResettablePerContainerLifetime which will manage one - // single instance of the collection (much alike PerContainerLifetime) but can be resetted - // to force a new collection to be created. - // this is needed because of the weird things we do during install, where we'd use the - // infamous DirtyBackdoorToConfiguration to reset the ActionResolver way after Resolution - // had frozen. This has been replaced by the possibility here to set the producer at any - // time - but the builder is internal - and all this will be gone eventually. - container.Register(factory => factory.GetInstance().CreateCollection(), collectionLifetime); - } - - public ActionCollection CreateCollection() - { - var actions = new List(); - foreach (var type in _producer()) - { - var getter = type.GetProperty("Instance", BindingFlags.Public | BindingFlags.Static); - var instance = getter == null - ? Activator.CreateInstance(type) as IAction - : getter.GetValue(null, null) as IAction; - if (instance == null) continue; - actions.Add(instance); - } - return new ActionCollection(actions); - } - - public void SetProducer(Func> producer) - { - _producer = producer; - CollectionLifetime.Reset(); - } - - private ResettablePerContainerLifetime CollectionLifetime { get; } = new ResettablePerContainerLifetime(); - - private class ResettablePerContainerLifetime : ILifetime - { - private object _instance; - - public object GetInstance(Func createInstance, Scope scope) - { - // not dealing with disposable instances, actions are not disposable - return _instance ?? (_instance = createInstance()); - } - - public void Reset() - { - _instance = null; - } - } - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionCopy.cs b/src/Umbraco.Web/_Legacy/Actions/ActionCopy.cs deleted file mode 100644 index 5addcec99f..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionCopy.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when copying a document, media, member - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.StructureCategory)] - public class ActionCopy : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionCopy m_instance = new ActionCopy(); -#pragma warning restore 612,618 - - public static ActionCopy Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - - return 'O'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionCopy()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - - return null; - } - } - - public string Alias - { - get - { - - return "copy"; - } - } - - public string Icon - { - get - { - - return "documents"; - } - } - - public bool ShowInNotifier - { - get - { - - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - - return true; - } - } - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionCreateBlueprintFromContent.cs b/src/Umbraco.Web/_Legacy/Actions/ActionCreateBlueprintFromContent.cs deleted file mode 100644 index 0d028c35b4..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionCreateBlueprintFromContent.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - [ActionMetadata(Constants.Conventions.PermissionCategories.ContentCategory)] - public class ActionCreateBlueprintFromContent : IAction - { - private static readonly ActionCreateBlueprintFromContent instance = new ActionCreateBlueprintFromContent(); - - public static ActionCreateBlueprintFromContent Instance - { - get { return instance; } - } - - public char Letter { get; private set; } - public bool ShowInNotifier { get; private set; } - public bool CanBePermissionAssigned { get; private set; } - public string Icon { get; private set; } - public string Alias { get; private set; } - public string JsFunctionName { get; private set; } - public string JsSource { get; private set; } - public bool OpensDialog => true; - - public ActionCreateBlueprintFromContent() - { - Letter = 'ï'; - CanBePermissionAssigned = true; - Icon = "blueprint"; - Alias = "createblueprint"; - } - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionDelete.cs b/src/Umbraco.Web/_Legacy/Actions/ActionDelete.cs deleted file mode 100644 index 53f7822d47..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionDelete.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when a document, media, member is deleted - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.ContentCategory)] - public class ActionDelete : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionDelete m_instance = new ActionDelete(); -#pragma warning restore 612,618 - - public static ActionDelete Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - return 'D'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionDelete()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "delete"; - } - } - - public string Icon - { - get - { - return "delete"; - } - } - - public bool ShowInNotifier - { - get - { - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - return true; - } - } - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionEmptyTranscan.cs b/src/Umbraco.Web/_Legacy/Actions/ActionEmptyTranscan.cs deleted file mode 100644 index f0da5323b9..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionEmptyTranscan.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when the trash can is emptied - /// - public class ActionEmptyTranscan : IAction - { - //create singleton - private static readonly ActionEmptyTranscan InnerInstance = new ActionEmptyTranscan(); - - public static ActionEmptyTranscan Instance - { - get { return InnerInstance; } - } - - #region IAction Members - - public char Letter - { - get - { - return 'N'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionEmptyTranscan()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "emptyRecycleBin"; - } - } - - public string Icon - { - get - { - return "trash"; - } - } - - public bool ShowInNotifier - { - get - { - return false; - } - } - public bool CanBePermissionAssigned - { - get - { - return false; - } - } - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionExport.cs b/src/Umbraco.Web/_Legacy/Actions/ActionExport.cs deleted file mode 100644 index 56b98c02f2..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionExport.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when exporting a document type - /// - public class ActionExport : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionExport m_instance = new ActionExport(); -#pragma warning restore 612,618 - - public static ActionExport Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - return '9'; - } - } - - public string JsFunctionName - { - get { return ""; } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "export"; - } - } - - public string Icon - { - get - { - return "download-alt"; - } - } - - public bool ShowInNotifier - { - get - { - return false; - } - } - public bool CanBePermissionAssigned - { - get - { - return false; - } - } - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionImport.cs b/src/Umbraco.Web/_Legacy/Actions/ActionImport.cs deleted file mode 100644 index 52f163ee6b..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionImport.cs +++ /dev/null @@ -1,79 +0,0 @@ -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when importing a document type - /// - public class ActionImport : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionImport m_instance = new ActionImport(); -#pragma warning restore 612,618 - - public static ActionImport Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - return '8'; - } - } - - public string JsFunctionName - { - get - { - return ""; - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "importDocumentType"; - } - } - - public string Icon - { - get - { - return "page-up"; - } - } - - public bool ShowInNotifier - { - get - { - return false; - } - } - public bool CanBePermissionAssigned - { - get - { - return false; - } - } - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionMove.cs b/src/Umbraco.Web/_Legacy/Actions/ActionMove.cs deleted file mode 100644 index 81d1803679..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionMove.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked upon creation of a document, media, member - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.StructureCategory)] - public class ActionMove : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionMove m_instance = new ActionMove(); -#pragma warning restore 612,618 - - public static ActionMove Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - - return 'M'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionMove()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - - return null; - } - } - - public string Alias - { - get - { - - return "move"; - } - } - - public string Icon - { - get - { - - return "enter"; - } - } - - public bool ShowInNotifier - { - get - { - - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - - return true; - } - } - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionNew.cs b/src/Umbraco.Web/_Legacy/Actions/ActionNew.cs deleted file mode 100644 index ef1b61efc5..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionNew.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked upon creation of a document - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.ContentCategory)] - public class ActionNew : IAction - { - public static ActionNew Instance { get; } = new ActionNew(); - - #region IAction Members - - public char Letter - { - get - { - return 'C'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionNew()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "create"; - } - } - - public string Icon - { - get - { - return "add"; - } - } - - public bool ShowInNotifier - { - get - { - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - return true; - } - } - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionNotify.cs b/src/Umbraco.Web/_Legacy/Actions/ActionNotify.cs deleted file mode 100644 index fd6bc3d61a..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionNotify.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when a notification is sent - /// - public class ActionNotify : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionNotify m_instance = new ActionNotify(); -#pragma warning restore 612,618 - - public static ActionNotify Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - - return 'T'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionNotify()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - - return null; - } - } - - public string Alias - { - get - { - return "notify"; - } - } - - public string Icon - { - get - { - return "megaphone"; - } - } - - public bool ShowInNotifier - { - get - { - return false; - } - } - public bool CanBePermissionAssigned - { - get - { - return false; - } - } - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionNull.cs b/src/Umbraco.Web/_Legacy/Actions/ActionNull.cs deleted file mode 100644 index 3344560c3f..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionNull.cs +++ /dev/null @@ -1,58 +0,0 @@ -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This permission is assigned to a node when there are no permissions assigned to the node. - /// This is used internally to assign no permissions to a node for a user and shouldn't be used in code. - /// - public class ActionNull : IAction - { - //create singleton - private static readonly ActionNull instance = new ActionNull(); - private ActionNull() { } - public static ActionNull Instance - { - get { return instance; } - } - - #region IAction Members - - public char Letter - { - get { return '-'; } - } - - public bool ShowInNotifier - { - get { return false; } - } - - public bool CanBePermissionAssigned - { - get { return false; } - } - - public string Icon - { - get { return string.Empty; } - } - - public string Alias - { - get { return string.Empty; } - } - - public string JsFunctionName - { - get { return string.Empty; } - } - - public string JsSource - { - get { return string.Empty; } - } - - public bool OpensDialog => false; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionPackage.cs b/src/Umbraco.Web/_Legacy/Actions/ActionPackage.cs deleted file mode 100644 index fa17b87073..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionPackage.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked upon creation of a document, media, member - /// - public class ActionPackage : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionPackage m_instance = new ActionPackage(); -#pragma warning restore 612,618 - - public static ActionPackage Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - return 'X'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionPackage()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - return ""; - } - } - - public string Alias - { - get - { - return "importPackage"; - } - } - - public string Icon - { - get - { - return "gift"; - } - } - - public bool ShowInNotifier - { - get - { - return false; - } - } - public bool CanBePermissionAssigned - { - get - { - return false; - } - } - - public bool OpensDialog => false; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionPackageCreate.cs b/src/Umbraco.Web/_Legacy/Actions/ActionPackageCreate.cs deleted file mode 100644 index fdec43e810..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionPackageCreate.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked upon creation of a document, media, member - /// - public class ActionPackageCreate : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionPackageCreate m_instance = new ActionPackageCreate(); -#pragma warning restore 612,618 - - public static ActionPackageCreate Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - return 'Y'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionPackageCreate()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "createPackage"; - } - } - - public string Icon - { - get - { - return "gift"; - } - } - - public bool ShowInNotifier - { - get - { - return false; - } - } - public bool CanBePermissionAssigned - { - get - { - return false; - } - } - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionProtect.cs b/src/Umbraco.Web/_Legacy/Actions/ActionProtect.cs deleted file mode 100644 index 65e9d7128e..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionProtect.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when a document is protected or unprotected - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.AdministrationCategory)] - public class ActionProtect : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionProtect m_instance = new ActionProtect(); -#pragma warning restore 612,618 - - public static ActionProtect Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - - return 'P'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionProtect()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - - return null; - } - } - - public string Alias - { - get - { - - return "protect"; - } - } - - public string Icon - { - get - { - - return "lock"; - } - } - - public bool ShowInNotifier - { - get - { - - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - - return true; - } - } - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionPublish.cs b/src/Umbraco.Web/_Legacy/Actions/ActionPublish.cs deleted file mode 100644 index 70c7735572..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionPublish.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when a document is being published - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.ContentCategory)] - public class ActionPublish : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionPublish m_instance = new ActionPublish(); -#pragma warning restore 612,618 - - public static ActionPublish Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - return 'U'; - } - } - - public string JsFunctionName - { - get - { - return string.Empty; - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "publish"; - } - } - - public string Icon - { - get - { - return string.Empty; - } - } - - public bool ShowInNotifier - { - get - { - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - return true; - } - } - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionRePublish.cs b/src/Umbraco.Web/_Legacy/Actions/ActionRePublish.cs deleted file mode 100644 index 312ae80825..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionRePublish.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when all documents are being republished - /// - public class ActionRePublish : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionRePublish m_instance = new ActionRePublish(); -#pragma warning restore 612,618 - - public static ActionRePublish Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - return 'B'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionRePublish()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "republish"; - } - } - - public string Icon - { - get - { - return "globe"; - } - } - - public bool ShowInNotifier - { - get - { - return false; - } - } - public bool CanBePermissionAssigned - { - get - { - return false; - } - } - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionRefresh.cs b/src/Umbraco.Web/_Legacy/Actions/ActionRefresh.cs deleted file mode 100644 index 0abf4fcac5..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionRefresh.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when a node reloads its children - /// Concerns only the tree itself and thus you should not handle - /// this action from without umbraco. - /// - [LegacyActionMenuItem("umbracoMenuActions", "RefreshNode")] - public class ActionRefresh : IAction - { - //create singleton - private static readonly ActionRefresh InnerInstance = new ActionRefresh(); - - public static ActionRefresh Instance - { - get { return InnerInstance; } - } - - #region IAction Members - - public char Letter - { - get - { - - return 'L'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionRefresh()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - - return null; - } - } - - public string Alias - { - get - { - - return "refreshNode"; - } - } - - public string Icon - { - get - { - - return "refresh"; - } - } - - public bool ShowInNotifier - { - get - { - - return false; - } - } - public bool CanBePermissionAssigned - { - get - { - - return false; - } - } - - public bool OpensDialog => false; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionRestore.cs b/src/Umbraco.Web/_Legacy/Actions/ActionRestore.cs deleted file mode 100644 index 2a2baac070..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionRestore.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when the content/media item is to be restored from the recycle bin - /// - public class ActionRestore : IAction - { - //create singleton - - private ActionRestore() { } - - public static ActionRestore Instance { get; } = new ActionRestore(); - - #region IAction Members - - public char Letter => 'V'; - - public string JsFunctionName => null; - - public string JsSource => null; - - public string Alias => "restore"; - - public string Icon => "undo"; - - public bool ShowInNotifier => true; - - public bool CanBePermissionAssigned => false; - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionRights.cs b/src/Umbraco.Web/_Legacy/Actions/ActionRights.cs deleted file mode 100644 index beb3b06ddf..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionRights.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when rights are changed on a document - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.ContentCategory)] - public class ActionRights : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionRights m_instance = new ActionRights(); -#pragma warning restore 612,618 - - public static ActionRights Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - - return 'R'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionRights()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - - return null; - } - } - - public string Alias - { - get - { - - return "rights"; - } - } - - public string Icon - { - get - { - - return "vcard"; - } - } - - public bool ShowInNotifier - { - get - { - - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - - return true; - } - } - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionRollback.cs b/src/Umbraco.Web/_Legacy/Actions/ActionRollback.cs deleted file mode 100644 index 3179dc9fb5..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionRollback.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when copying a document is being rolled back - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.AdministrationCategory)] - public class ActionRollback : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionRollback m_instance = new ActionRollback(); -#pragma warning restore 612,618 - - public static ActionRollback Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - - return 'K'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionRollback()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - return ""; - } - } - - public string Alias - { - get - { - - return "rollback"; - } - } - - public string Icon - { - get - { - - return "undo"; - } - } - - public bool ShowInNotifier - { - get - { - - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - - return true; - } - } - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionSort.cs b/src/Umbraco.Web/_Legacy/Actions/ActionSort.cs deleted file mode 100644 index 48f6b8d1e9..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionSort.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when children to a document, media, member is being sorted - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.StructureCategory)] - public class ActionSort : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionSort m_instance = new ActionSort(); -#pragma warning restore 612,618 - - public static ActionSort Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - - return 'S'; - } - } - - public string JsFunctionName - { - get - { - return null; - } - } - - public string JsSource - { - get - { - - return null; - } - } - - public string Alias - { - get - { - - return "sort"; - } - } - - public string Icon - { - get - { - - return "navigation-vertical"; - } - } - - public bool ShowInNotifier - { - get - { - - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - - return true; - } - } - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionToPublish.cs b/src/Umbraco.Web/_Legacy/Actions/ActionToPublish.cs deleted file mode 100644 index a04a24f4a3..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionToPublish.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when children to a document is being sent to published (by an editor without publishrights) - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.ContentCategory)] - public class ActionToPublish : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionToPublish m_instance = new ActionToPublish(); -#pragma warning restore 612,618 - - public static ActionToPublish Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - return 'H'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionToPublish()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "sendtopublish"; - } - } - - public string Icon - { - get - { - return "outbox"; - } - } - - public bool ShowInNotifier - { - get - { - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - //SD: Changed this to true so that any user may be able to perform this action, not just a writer - return true; - } - } - - public bool OpensDialog => false; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionTranslate.cs b/src/Umbraco.Web/_Legacy/Actions/ActionTranslate.cs deleted file mode 100644 index 157fd827a6..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionTranslate.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when a translation occurs - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.AdministrationCategory)] - public class ActionTranslate : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionTranslate m_instance = new ActionTranslate(); -#pragma warning restore 612,618 - - public static ActionTranslate Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - return '4'; - } - } - - public string JsFunctionName - { - get - { - return ""; - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "translate"; - } - } - - public string Icon - { - get - { - return "comments"; - } - } - - public bool ShowInNotifier - { - get - { - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - return true; - } - } - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionUnPublish.cs b/src/Umbraco.Web/_Legacy/Actions/ActionUnPublish.cs deleted file mode 100644 index 11225add1d..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionUnPublish.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - - /// - /// This action is invoked when a document is being unpublished - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.ContentCategory)] - public class ActionUnpublish : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionUnpublish m_instance = new ActionUnpublish(); -#pragma warning restore 612,618 - - public static ActionUnpublish Instance => m_instance; - - public char Letter => 'Z'; - public string JsFunctionName => ""; - public string JsSource => null; - public string Alias => "unpublish"; - public string Icon => "circle-dotted"; - public bool ShowInNotifier => false; - public bool CanBePermissionAssigned => true; - public bool OpensDialog => false; - - } - -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionUpdate.cs b/src/Umbraco.Web/_Legacy/Actions/ActionUpdate.cs deleted file mode 100644 index 5621d505a9..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionUpdate.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when copying a document or media - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.ContentCategory)] - public class ActionUpdate : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionUpdate m_instance = new ActionUpdate(); -#pragma warning restore 612,618 - - public static ActionUpdate Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - return 'A'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionUpdate()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "update"; - } - } - - public string Icon - { - get - { - return "save"; - } - } - - public bool ShowInNotifier - { - get - { - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - return true; - } - } - - public bool OpensDialog => false; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ContextMenuSeperator.cs b/src/Umbraco.Web/_Legacy/Actions/ContextMenuSeperator.cs deleted file mode 100644 index 45a1d0e1c5..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ContextMenuSeperator.cs +++ /dev/null @@ -1,53 +0,0 @@ -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// Used simply to define context menu seperator items. - /// This should not be used directly in any code except for creating menus. - /// - public class ContextMenuSeperator : IAction - { - //create singleton - private static readonly ContextMenuSeperator instance = new ContextMenuSeperator(); - private ContextMenuSeperator() { } - public static ContextMenuSeperator Instance - { - get { return instance; } - } - - #region IAction Members - - public char Letter - { - get { return ','; } - } - - public string JsFunctionName - { - get { return string.Empty; } - } - public string JsSource - { - get { return string.Empty; } - } - public string Alias - { - get { return string.Empty; } - } - public string Icon - { - get { return string.Empty; } - } - public bool ShowInNotifier - { - get { return false; } - } - public bool CanBePermissionAssigned - { - get { return false; } - } - - public bool OpensDialog => false; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/IAction.cs b/src/Umbraco.Web/_Legacy/Actions/IAction.cs deleted file mode 100644 index 48a752e7da..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/IAction.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Umbraco.Core.Composing; - -namespace Umbraco.Web._Legacy.Actions -{ - public interface IAction : IDiscoverable - { - char Letter { get; } - bool ShowInNotifier { get; } - bool CanBePermissionAssigned { get; } - string Icon { get; } - string Alias { get; } - string JsFunctionName { get; } - /// - /// A path to a supporting JavaScript file for the IAction. A script tag will be rendered out with the reference to the JavaScript file. - /// - string JsSource { get; } - /// - /// Whether or not the action opens a dialog when invoked - /// - bool OpensDialog { get; } - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/LegacyActionMenuItemAttribute.cs b/src/Umbraco.Web/_Legacy/Actions/LegacyActionMenuItemAttribute.cs deleted file mode 100644 index ca9ace9630..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/LegacyActionMenuItemAttribute.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using Umbraco.Core; -using Umbraco.Core.Exceptions; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// The attribute to assign to any IAction objects. - /// - /// - /// This is purely used for compatibility reasons for old IActions used in v7 that haven't been upgraded to - /// the new format. - /// - [AttributeUsage(AttributeTargets.Class)] - internal sealed class LegacyActionMenuItemAttribute : Attribute - { - /// - /// This constructor defines both the angular service and method name to use - /// - /// - /// - public LegacyActionMenuItemAttribute(string serviceName, string methodName) - { - if (string.IsNullOrEmpty(serviceName)) throw new ArgumentNullOrEmptyException(nameof(serviceName)); - if (string.IsNullOrEmpty(methodName)) throw new ArgumentNullOrEmptyException(nameof(methodName)); - - MethodName = methodName; - ServiceName = serviceName; - } - - /// - /// This constructor will assume that the method name equals the type name of the action menu class - /// - /// - public LegacyActionMenuItemAttribute(string serviceName) - { - if (string.IsNullOrEmpty(serviceName)) throw new ArgumentNullOrEmptyException(nameof(serviceName)); - - MethodName = ""; - ServiceName = serviceName; - } - - public string MethodName { get; } - public string ServiceName { get; } - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/RelationTypesWebService.asmx b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/RelationTypesWebService.asmx deleted file mode 100644 index 160745ca2d..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/RelationTypesWebService.asmx +++ /dev/null @@ -1 +0,0 @@ -<%@ WebService Language="C#" CodeBehind="RelationTypesWebService.asmx.cs" Class="umbraco.cms.presentation.developer.RelationTypes.RelationTypesWebService" %> diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/RelationTypesWebService.asmx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/RelationTypesWebService.asmx.cs deleted file mode 100644 index 0f8ca29c94..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/RelationTypesWebService.asmx.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Web.Services; -using Umbraco.Core; -using Umbraco.Core.Models; -using Umbraco.Web; -using Umbraco.Web.Composing; - -namespace umbraco.cms.presentation.developer.RelationTypes -{ - /// - /// Webservice to delete relation types, this allows deletion via a javacscript call hooked into the tree UI - /// - [WebService(Namespace = "http://tempuri.org/")] - [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] - [System.ComponentModel.ToolboxItem(false)] - [System.Web.Script.Services.ScriptService] // Allows this Web Service to be called from script, using ASP.NET AJAX - public class RelationTypesWebService : WebService - { - /// - /// Delete an Umbraco RelationType and all it's associated Relations - /// - /// database id of the relation type to delete - [WebMethod] - public void DeleteRelationType(int relationTypeId) - { - var user = UmbracoContext.Current.Security.CurrentUser; - - if (user.IsAdmin()) - { - var relationService = Current.Services.RelationService; - var relationType = relationService.GetRelationTypeById(relationTypeId); - relationService.Delete(relationType); - } - } - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/TreeMenu/ActionDeleteRelationType.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/TreeMenu/ActionDeleteRelationType.cs deleted file mode 100644 index 5526a3d9a3..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/TreeMenu/ActionDeleteRelationType.cs +++ /dev/null @@ -1,85 +0,0 @@ -using Umbraco.Web._Legacy.Actions; - -namespace umbraco.cms.presentation.developer.RelationTypes.TreeMenu -{ - /// - /// Delete a Relation Type - an Umbraco tree context menu action - /// - public class ActionDeleteRelationType : IAction - { - /// - /// Private field for the singleton instance - /// - private static readonly ActionDeleteRelationType instance = new ActionDeleteRelationType(); - - /// - /// Gets a singleton instance of this action - /// - public static ActionDeleteRelationType Instance - { - get { return instance; } - } - - #region IAction Members - - /// - /// Gets a string alias used to identify this action - /// - public string Alias - { - get { return "delete"; } - } - - /// - /// Gets a unique char to associate with this action - /// - public char Letter - { - get { return '¤'; } - } - - /// - /// Gets a value indicating whether the Umbraco notification area is used ? - /// - public bool ShowInNotifier - { - get { return false; } - } - - /// - /// Gets a value indicating whether this action can be configured for use only by specific members - /// - public bool CanBePermissionAssigned - { - get { return false; } // Since this tree is in the developer section, no further granular permissions are required - } - - /// - /// Gets an icon to be used for the right click action - /// - public string Icon - { - get { return "delete"; } // delete refers to an existing sprite - } - - /// - /// Gets a string for the javascript source - /// - public string JsSource - { - get { return "developer/RelationTypes/TreeMenu/ActionDeleteRelationType.js"; } - } - - /// - /// Gets a javascript string to execute when this action is fired - /// - public string JsFunctionName - { - get { return "javascript:actionDeleteRelationType(UmbClientMgr.mainTree().getActionNode().nodeId,UmbClientMgr.mainTree().getActionNode().nodeName);"; } - } - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/TreeMenu/ActionNewRelationType.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/TreeMenu/ActionNewRelationType.cs deleted file mode 100644 index cb776d5246..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/TreeMenu/ActionNewRelationType.cs +++ /dev/null @@ -1,85 +0,0 @@ -using Umbraco.Web._Legacy.Actions; - -namespace umbraco.cms.presentation.developer.RelationTypes.TreeMenu -{ - /// - /// Create new Relation Type - an Umbraco tree context menu action - /// - public class ActionNewRelationType : IAction - { - /// - /// Private field for the singleton instance - /// - private static readonly ActionNewRelationType instance = new ActionNewRelationType(); - - /// - /// Gets a singleton instance of this action - /// - public static ActionNewRelationType Instance - { - get { return instance; } - } - - #region IAction Members - - /// - /// Gets a string alias used to identify this action - /// - public string Alias - { - get { return "create"; } - } - - /// - /// Gets a unique char to associate with this action - /// - public char Letter - { - get { return '®'; } - } - - /// - /// Gets a value indicating whether the Umbraco notification area is used ? - /// - public bool ShowInNotifier - { - get { return false; } - } - - /// - /// Gets a value indicating whether this action can be configured for use only by specific members - /// - public bool CanBePermissionAssigned - { - get { return false; } // Since this tree is in the developer section, no further granular permissions are required - } - - /// - /// Gets an icon to be used for the right click action - /// - public string Icon - { - get { return "add"; } // add refers to an existing sprite - } - - /// - /// Gets a string for the javascript source - /// - public string JsSource - { - get { return "developer/RelationTypes/TreeMenu/ActionNewRelationType.js"; } - } - - /// - /// Gets a javascript string to execute when this action is fired - /// - public string JsFunctionName - { - get { return "javascript:actionNewRelationType();"; } - } - - public bool OpensDialog => true; - - #endregion - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/SendPublish.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/SendPublish.aspx.cs index 727af897ca..1f4ba277b5 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/SendPublish.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/SendPublish.aspx.cs @@ -1,7 +1,9 @@ using System; using Umbraco.Web; using Umbraco.Core; -using Umbraco.Web._Legacy.Actions; +using Umbraco.Web.Actions; +using Umbraco.Web.Composing; + namespace umbraco.dialogs { @@ -25,7 +27,7 @@ namespace umbraco.dialogs { //send notifications! TODO: This should be put somewhere centralized instead of hard coded directly here Services.NotificationService.SendNotification( - Services.ContentService.GetById(docId), ActionToPublish.Instance); + Services.ContentService.GetById(docId), Current.Actions.GetAction()); } } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/templateControls/Item.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/templateControls/Item.cs index 89a03a1437..8473341ca8 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/templateControls/Item.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/templateControls/Item.cs @@ -11,9 +11,10 @@ using Umbraco.Core.Services; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Web; +using Umbraco.Web.Actions; using Umbraco.Web.Composing; using Umbraco.Web.Macros; -using Umbraco.Web._Legacy.Actions; + namespace umbraco.presentation.templateControls { @@ -276,7 +277,7 @@ namespace umbraco.presentation.templateControls if (u == null) return false; var permission = Current.Services.UserService.GetPermissions(u, PageElements["path"].ToString()); - return permission.AssignedPermissions.Contains(ActionUpdate.Instance.Letter.ToString(CultureInfo.InvariantCulture), StringComparer.Ordinal); + return permission.AssignedPermissions.Contains(ActionUpdate.ActionLetter.ToString(CultureInfo.InvariantCulture), StringComparer.Ordinal); } #endregion diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs index f82587a413..5e0cb289f0 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs @@ -9,8 +9,9 @@ using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Web; +using Umbraco.Web.Actions; using Umbraco.Web.Composing; -using Umbraco.Web._Legacy.Actions; + namespace umbraco.presentation.webservices { @@ -186,7 +187,7 @@ namespace umbraco.presentation.webservices //send notifications! TODO: This should be put somewhere centralized instead of hard coded directly here if (parentId > 0) { - Services.NotificationService.SendNotification(contentService.GetById(parentId), ActionSort.Instance, UmbracoContext, Services.TextService, GlobalSettings); + Services.NotificationService.SendNotification(contentService.GetById(parentId), Current.Actions.GetAction(), UmbracoContext, Services.TextService, GlobalSettings); } }
+ Are you sure you want to delete {{currentNode.name}} ? +