diff --git a/src/Umbraco.Core/Composing/Composers/ServicesComposer.cs b/src/Umbraco.Core/Composing/Composers/ServicesComposer.cs index 0b83373d99..3f1bc1df5e 100644 --- a/src/Umbraco.Core/Composing/Composers/ServicesComposer.cs +++ b/src/Umbraco.Core/Composing/Composers/ServicesComposer.cs @@ -73,7 +73,6 @@ namespace Umbraco.Core.Composing.Composers factory.GetInstance(), factory.GetInstance(), new DirectoryInfo(IOHelper.GetRootDirectorySafe()))); - return composition; } @@ -84,7 +83,7 @@ namespace Umbraco.Core.Composing.Composers /// /// private static PackagesRepository CreatePackageRepository(IFactory factory, string packageRepoFileName) - => new PackagesRepository( + => new PackagesRepository( factory.GetInstance(), factory.GetInstance(), factory.GetInstance(), factory.GetInstance(), factory.GetInstance(), factory.GetInstance(), factory.GetInstance(), factory.GetInstance(), packageRepoFileName); diff --git a/src/Umbraco.Core/Manifest/ManifestBackOfficeSection.cs b/src/Umbraco.Core/Manifest/ManifestBackOfficeSection.cs new file mode 100644 index 0000000000..a1b89d9a01 --- /dev/null +++ b/src/Umbraco.Core/Manifest/ManifestBackOfficeSection.cs @@ -0,0 +1,15 @@ +using System.Runtime.Serialization; +using Umbraco.Core.Models.Trees; + +namespace Umbraco.Core.Manifest +{ + [DataContract(Name = "section", Namespace = "")] + public class ManifestBackOfficeSection : IBackOfficeSection + { + [DataMember(Name = "alias")] + public string Alias { get; set; } + + [DataMember(Name = "name")] + public string Name { get; set; } + } +} diff --git a/src/Umbraco.Core/Manifest/ManifestParser.cs b/src/Umbraco.Core/Manifest/ManifestParser.cs index 28493fe20f..c471bbcf2e 100644 --- a/src/Umbraco.Core/Manifest/ManifestParser.cs +++ b/src/Umbraco.Core/Manifest/ManifestParser.cs @@ -9,6 +9,7 @@ using Umbraco.Core.Exceptions; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models.ContentEditing; +using Umbraco.Core.Models.Trees; using Umbraco.Core.PropertyEditors; namespace Umbraco.Core.Manifest @@ -101,7 +102,7 @@ namespace Umbraco.Core.Manifest var gridEditors = new List(); var contentApps = new List(); var dashboards = new List(); - var sections = new Dictionary(); + var sections = new List(); foreach (var manifest in manifests) { @@ -112,9 +113,7 @@ namespace Umbraco.Core.Manifest if (manifest.GridEditors != null) gridEditors.AddRange(manifest.GridEditors); if (manifest.ContentApps != null) contentApps.AddRange(manifest.ContentApps); if (manifest.Dashboards != null) dashboards.AddRange(manifest.Dashboards); - if (manifest.Sections != null) - foreach (var (key, value) in manifest.Sections) - sections[key] = value; + if (manifest.Sections != null) sections.AddRange(manifest.Sections.DistinctBy(x => x.Alias.ToLowerInvariant())); } return new PackageManifest @@ -126,7 +125,7 @@ namespace Umbraco.Core.Manifest GridEditors = gridEditors.ToArray(), ContentApps = contentApps.ToArray(), Dashboards = dashboards.ToArray(), - Sections = sections + Sections = sections.ToArray() }; } diff --git a/src/Umbraco.Core/Manifest/PackageManifest.cs b/src/Umbraco.Core/Manifest/PackageManifest.cs index a0546f3629..b29a28ab06 100644 --- a/src/Umbraco.Core/Manifest/PackageManifest.cs +++ b/src/Umbraco.Core/Manifest/PackageManifest.cs @@ -1,7 +1,5 @@ using System; -using System.Collections.Generic; using Newtonsoft.Json; -using Umbraco.Core.Models.ContentEditing; using Umbraco.Core.PropertyEditors; namespace Umbraco.Core.Manifest @@ -11,31 +9,52 @@ namespace Umbraco.Core.Manifest /// public class PackageManifest { + /// + /// Gets or sets the scripts listed in the manifest. + /// [JsonProperty("javascript")] public string[] Scripts { get; set; } = Array.Empty(); + /// + /// Gets or sets the stylesheets listed in the manifest. + /// [JsonProperty("css")] - public string[] Stylesheets { get; set; }= Array.Empty(); + public string[] Stylesheets { get; set; } = Array.Empty(); + /// + /// Gets or sets the property editors listed in the manifest. + /// [JsonProperty("propertyEditors")] public IDataEditor[] PropertyEditors { get; set; } = Array.Empty(); + /// + /// Gets or sets the parameter editors listed in the manifest. + /// [JsonProperty("parameterEditors")] public IDataEditor[] ParameterEditors { get; set; } = Array.Empty(); + /// + /// Gets or sets the grid editors listed in the manifest. + /// [JsonProperty("gridEditors")] public GridEditor[] GridEditors { get; set; } = Array.Empty(); + /// + /// Gets or sets the content apps listed in the manifest. + /// [JsonProperty("contentApps")] public ManifestContentAppDefinition[] ContentApps { get; set; } = Array.Empty(); + /// + /// Gets or sets the dashboards listed in the manifest. + /// [JsonProperty("dashboards")] public ManifestDashboardDefinition[] Dashboards { get; set; } = Array.Empty(); /// - /// Declares the back office sections that this package installs + /// Gets or sets the sections listed in the manifest. /// [JsonProperty("sections")] - public IReadOnlyDictionary Sections { get; set; } = new Dictionary(); + public ManifestBackOfficeSection[] Sections { get; set; } = Array.Empty(); } } diff --git a/src/Umbraco.Core/Models/Trees/IBackOfficeSection.cs b/src/Umbraco.Core/Models/Trees/IBackOfficeSection.cs new file mode 100644 index 0000000000..86e2a18fd5 --- /dev/null +++ b/src/Umbraco.Core/Models/Trees/IBackOfficeSection.cs @@ -0,0 +1,18 @@ +namespace Umbraco.Core.Models.Trees +{ + /// + /// Defines a back office section. + /// + public interface IBackOfficeSection + { + /// + /// Gets the alias of the section. + /// + string Alias { get; } + + /// + /// Gets the name of the section. + /// + string Name { get; } + } +} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 5c0c870d15..6c2b359684 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -355,6 +355,7 @@ + @@ -449,6 +450,7 @@ + diff --git a/src/Umbraco.Tests/Manifest/ManifestParserTests.cs b/src/Umbraco.Tests/Manifest/ManifestParserTests.cs index 9970d5f6b0..e77b9a6e10 100644 --- a/src/Umbraco.Tests/Manifest/ManifestParserTests.cs +++ b/src/Umbraco.Tests/Manifest/ManifestParserTests.cs @@ -433,19 +433,17 @@ javascript: ['~/test.js',/*** some note about stuff asd09823-4**09234*/ '~/test2 [Test] public void CanParseManifest_Sections() { - const string json = @"{'sections': { - 'content': 'Content', - 'hello': 'World' - } -}"; + const string json = @"{'sections': [ + { ""alias"": ""content"", ""name"": ""Content"" }, + { ""alias"": ""hello"", ""name"": ""World"" } +]}"; var manifest = _parser.ParseManifest(json); - Assert.AreEqual(2, manifest.Sections.Count); - Assert.AreEqual("content", manifest.Sections.Keys.ElementAt(0)); - Assert.AreEqual("hello", manifest.Sections.Keys.ElementAt(1)); - Assert.AreEqual("Content", manifest.Sections["content"]); - Assert.AreEqual("World", manifest.Sections["hello"]); - + Assert.AreEqual(2, manifest.Sections.Length); + Assert.AreEqual("content", manifest.Sections[0].Alias); + Assert.AreEqual("hello", manifest.Sections[1].Alias); + Assert.AreEqual("Content", manifest.Sections[0].Name); + Assert.AreEqual("World", manifest.Sections[1].Name); } } } diff --git a/src/Umbraco.Tests/Services/SectionServiceTests.cs b/src/Umbraco.Tests/Services/SectionServiceTests.cs index 87fcde34ad..84eb0d1cbc 100644 --- a/src/Umbraco.Tests/Services/SectionServiceTests.cs +++ b/src/Umbraco.Tests/Services/SectionServiceTests.cs @@ -17,7 +17,7 @@ namespace Umbraco.Tests.Services public class SectionServiceTests : TestWithSomeContentBase { private ISectionService SectionService => Factory.GetInstance(); - + [Test] public void SectionService_Can_Get_Allowed_Sections_For_User() { diff --git a/src/Umbraco.Web/Models/Mapping/SectionMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/SectionMapperProfile.cs index 5aa99e4652..7e727a3752 100644 --- a/src/Umbraco.Web/Models/Mapping/SectionMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/SectionMapperProfile.cs @@ -1,9 +1,8 @@ using System.Collections.Generic; using AutoMapper; -using Umbraco.Core.Models.ContentEditing; +using Umbraco.Core.Models.Trees; using Umbraco.Core.Services; using Umbraco.Web.Models.ContentEditing; -using Umbraco.Web.Models.Trees; namespace Umbraco.Web.Models.Mapping { diff --git a/src/Umbraco.Web/Models/Trees/IBackOfficeSection.cs b/src/Umbraco.Web/Models/Trees/IBackOfficeSection.cs deleted file mode 100644 index 0cc505fb19..0000000000 --- a/src/Umbraco.Web/Models/Trees/IBackOfficeSection.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Umbraco.Web.Models.Trees -{ - - /// - /// Defines a back office section - /// - public interface IBackOfficeSection - { - string Alias { get; } - string Name { get; } - } -} diff --git a/src/Umbraco.Web/Services/ISectionService.cs b/src/Umbraco.Web/Services/ISectionService.cs index f0a16dc965..1cb8b6d450 100644 --- a/src/Umbraco.Web/Services/ISectionService.cs +++ b/src/Umbraco.Web/Services/ISectionService.cs @@ -1,8 +1,5 @@ using System.Collections.Generic; -using Umbraco.Core.Models; -using Umbraco.Core.Models.ContentEditing; -using Umbraco.Web.Models.ContentEditing; -using Umbraco.Web.Models.Trees; +using Umbraco.Core.Models.Trees; namespace Umbraco.Web.Services { @@ -26,7 +23,5 @@ namespace Umbraco.Web.Services /// The application alias. /// IBackOfficeSection GetByAlias(string appAlias); - } - } diff --git a/src/Umbraco.Web/Services/SectionService.cs b/src/Umbraco.Web/Services/SectionService.cs index 089bdc5bd3..0be28b0294 100644 --- a/src/Umbraco.Web/Services/SectionService.cs +++ b/src/Umbraco.Web/Services/SectionService.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; using System.Linq; +using Umbraco.Core.Models.Trees; using Umbraco.Core.Services; -using Umbraco.Web.Models.Trees; using Umbraco.Web.Trees; namespace Umbraco.Web.Services @@ -19,11 +19,12 @@ namespace Umbraco.Web.Services _userService = userService ?? throw new ArgumentNullException(nameof(userService)); _sectionCollection = sectionCollection ?? throw new ArgumentNullException(nameof(sectionCollection)); } - + /// /// The cache storage for all applications /// - public IEnumerable GetSections() => _sectionCollection; + public IEnumerable GetSections() + => _sectionCollection; /// public IEnumerable GetAllowedSections(int userId) @@ -36,7 +37,7 @@ namespace Umbraco.Web.Services } /// - public IBackOfficeSection GetByAlias(string appAlias) => GetSections().FirstOrDefault(t => t.Alias == appAlias); - + public IBackOfficeSection GetByAlias(string appAlias) + => GetSections().FirstOrDefault(t => t.Alias == appAlias); } } diff --git a/src/Umbraco.Web/Trees/BackOfficeSectionCollection.cs b/src/Umbraco.Web/Trees/BackOfficeSectionCollection.cs index fdeb812363..f604fa1124 100644 --- a/src/Umbraco.Web/Trees/BackOfficeSectionCollection.cs +++ b/src/Umbraco.Web/Trees/BackOfficeSectionCollection.cs @@ -1,8 +1,6 @@ using System.Collections.Generic; using Umbraco.Core.Composing; -using Umbraco.Core.Models.ContentEditing; -using Umbraco.Web.Models.ContentEditing; -using Umbraco.Web.Models.Trees; +using Umbraco.Core.Models.Trees; namespace Umbraco.Web.Trees { @@ -11,6 +9,5 @@ namespace Umbraco.Web.Trees public BackOfficeSectionCollection(IEnumerable items) : base(items) { } - } } diff --git a/src/Umbraco.Web/Trees/BackOfficeSectionCollectionBuilder.cs b/src/Umbraco.Web/Trees/BackOfficeSectionCollectionBuilder.cs index 3228cd309f..452ac02f38 100644 --- a/src/Umbraco.Web/Trees/BackOfficeSectionCollectionBuilder.cs +++ b/src/Umbraco.Web/Trees/BackOfficeSectionCollectionBuilder.cs @@ -2,12 +2,10 @@ using System.Linq; using Umbraco.Core.Composing; using Umbraco.Core.Manifest; -using Umbraco.Core.Models.ContentEditing; -using Umbraco.Web.Models.Trees; +using Umbraco.Core.Models.Trees; namespace Umbraco.Web.Trees { - //fixme: how can a developer re-sort the items in this collection ? public class BackOfficeSectionCollectionBuilder : OrderedCollectionBuilderBase { protected override BackOfficeSectionCollectionBuilder This => this; @@ -19,20 +17,7 @@ namespace Umbraco.Web.Trees // its dependencies too, and that can create cycles or other oddities var manifestParser = factory.GetInstance(); - return base.CreateItems(factory) - .Concat(manifestParser.Manifest.Sections.Select(x => new ManifestBackOfficeSection(x.Key, x.Value))); - } - - private class ManifestBackOfficeSection : IBackOfficeSection - { - public ManifestBackOfficeSection(string @alias, string name) - { - Alias = alias; - Name = name; - } - - public string Alias { get; } - public string Name { get; } + return base.CreateItems(factory).Concat(manifestParser.Manifest.Sections); } } } diff --git a/src/Umbraco.Web/Trees/ContentBackOfficeSection.cs b/src/Umbraco.Web/Trees/ContentBackOfficeSection.cs index 0109a6916d..8b37ce0e12 100644 --- a/src/Umbraco.Web/Trees/ContentBackOfficeSection.cs +++ b/src/Umbraco.Web/Trees/ContentBackOfficeSection.cs @@ -1,6 +1,5 @@ using Umbraco.Core; -using Umbraco.Web.Models.ContentEditing; -using Umbraco.Web.Models.Trees; +using Umbraco.Core.Models.Trees; namespace Umbraco.Web.Trees { @@ -9,7 +8,10 @@ namespace Umbraco.Web.Trees /// public class ContentBackOfficeSection : IBackOfficeSection { + /// public string Alias => Constants.Applications.Content; + + /// public string Name => "Content"; } } diff --git a/src/Umbraco.Web/Trees/MediaBackOfficeSection.cs b/src/Umbraco.Web/Trees/MediaBackOfficeSection.cs index aac4fd036f..34ce6b89a9 100644 --- a/src/Umbraco.Web/Trees/MediaBackOfficeSection.cs +++ b/src/Umbraco.Web/Trees/MediaBackOfficeSection.cs @@ -1,6 +1,5 @@ using Umbraco.Core; -using Umbraco.Web.Models.ContentEditing; -using Umbraco.Web.Models.Trees; +using Umbraco.Core.Models.Trees; namespace Umbraco.Web.Trees { @@ -12,4 +11,4 @@ namespace Umbraco.Web.Trees public string Alias => Constants.Applications.Media; public string Name => "Media"; } -} \ No newline at end of file +} diff --git a/src/Umbraco.Web/Trees/MembersBackOfficeSection.cs b/src/Umbraco.Web/Trees/MembersBackOfficeSection.cs index bfaead33d5..1d1f66835c 100644 --- a/src/Umbraco.Web/Trees/MembersBackOfficeSection.cs +++ b/src/Umbraco.Web/Trees/MembersBackOfficeSection.cs @@ -1,6 +1,5 @@ using Umbraco.Core; -using Umbraco.Web.Models.ContentEditing; -using Umbraco.Web.Models.Trees; +using Umbraco.Core.Models.Trees; namespace Umbraco.Web.Trees { @@ -9,7 +8,10 @@ namespace Umbraco.Web.Trees /// public class MembersBackOfficeSection : IBackOfficeSection { + /// public string Alias => Constants.Applications.Members; + + /// public string Name => "Members"; } -} \ No newline at end of file +} diff --git a/src/Umbraco.Web/Trees/PackagesBackOfficeSection.cs b/src/Umbraco.Web/Trees/PackagesBackOfficeSection.cs index 41f049c092..f59d368d91 100644 --- a/src/Umbraco.Web/Trees/PackagesBackOfficeSection.cs +++ b/src/Umbraco.Web/Trees/PackagesBackOfficeSection.cs @@ -1,6 +1,5 @@ using Umbraco.Core; -using Umbraco.Web.Models.ContentEditing; -using Umbraco.Web.Models.Trees; +using Umbraco.Core.Models.Trees; namespace Umbraco.Web.Trees { @@ -9,7 +8,10 @@ namespace Umbraco.Web.Trees /// public class PackagesBackOfficeSection : IBackOfficeSection { + /// public string Alias => Constants.Applications.Packages; + + /// public string Name => "Packages"; } -} \ No newline at end of file +} diff --git a/src/Umbraco.Web/Trees/SettingsBackOfficeSection.cs b/src/Umbraco.Web/Trees/SettingsBackOfficeSection.cs index 623f593c30..71b9781cd1 100644 --- a/src/Umbraco.Web/Trees/SettingsBackOfficeSection.cs +++ b/src/Umbraco.Web/Trees/SettingsBackOfficeSection.cs @@ -1,6 +1,5 @@ using Umbraco.Core; -using Umbraco.Web.Models.ContentEditing; -using Umbraco.Web.Models.Trees; +using Umbraco.Core.Models.Trees; namespace Umbraco.Web.Trees { @@ -9,7 +8,10 @@ namespace Umbraco.Web.Trees /// public class SettingsBackOfficeSection : IBackOfficeSection { + /// public string Alias => Constants.Applications.Settings; + + /// public string Name => "Settings"; } -} \ No newline at end of file +} diff --git a/src/Umbraco.Web/Trees/TranslationBackOfficeSection.cs b/src/Umbraco.Web/Trees/TranslationBackOfficeSection.cs index 41254b3179..bba1f5d8a3 100644 --- a/src/Umbraco.Web/Trees/TranslationBackOfficeSection.cs +++ b/src/Umbraco.Web/Trees/TranslationBackOfficeSection.cs @@ -1,6 +1,5 @@ using Umbraco.Core; -using Umbraco.Web.Models.ContentEditing; -using Umbraco.Web.Models.Trees; +using Umbraco.Core.Models.Trees; namespace Umbraco.Web.Trees { @@ -9,7 +8,10 @@ namespace Umbraco.Web.Trees /// public class TranslationBackOfficeSection : IBackOfficeSection { + /// public string Alias => Constants.Applications.Translation; + + /// public string Name => "Translation"; } -} \ No newline at end of file +} diff --git a/src/Umbraco.Web/Trees/UsersBackOfficeSection.cs b/src/Umbraco.Web/Trees/UsersBackOfficeSection.cs index 90a65cb508..0096b2abbb 100644 --- a/src/Umbraco.Web/Trees/UsersBackOfficeSection.cs +++ b/src/Umbraco.Web/Trees/UsersBackOfficeSection.cs @@ -1,6 +1,5 @@ using Umbraco.Core; -using Umbraco.Web.Models.ContentEditing; -using Umbraco.Web.Models.Trees; +using Umbraco.Core.Models.Trees; namespace Umbraco.Web.Trees { @@ -9,7 +8,10 @@ namespace Umbraco.Web.Trees /// public class UsersBackOfficeSection : IBackOfficeSection { + /// public string Alias => Constants.Applications.Users; + + /// public string Name => "Users"; } -} \ No newline at end of file +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 23cbb7a416..71b0631c4f 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -175,7 +175,6 @@ -